From: Roland Rosenfeld Date: Sat, 25 May 2002 19:17:36 +0000 (+0000) Subject: Disable edit-actions and remote-toggle in config file by default X-Git-Tag: v_2_9_16~83 X-Git-Url: http://www.privoxy.org/gitweb/?a=commitdiff_plain;h=2e43b7767721781355233b72439cb20b01b81a25;p=privoxy.git Disable edit-actions and remote-toggle in config file by default (Closes: #148125). --- diff --git a/.gitignore b/.gitignore index 40caffa8..d81f13ac 100644 --- a/.gitignore +++ b/.gitignore @@ -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 index 00000000..f6700066 --- /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/ + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..54d4e7dd --- /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 index 00000000..2429ec18 --- /dev/null +++ b/GNUmakefile.in @@ -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.txt && mv default.action.txt default.action + # LF to CRLF in default.filter + $(DOSFILTER) 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) "Privoxy Man page

NAME

" > doc/webserver/man-page/privoxy-man-page.html + man ./privoxy.1 | $(MAN2HTML) -bare >> doc/webserver/man-page/privoxy-man-page.html + $(ECHO) "" >> 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<\/HEAD/;\ + s/<\/HEAD/\n<\/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///; s//man2html/' tmp.html + $(PERL) -pi.bak -e 's/(<\/HEAD>)/<\/HEAD>/' tmp.html +# Get rid of spurious  from conversion. (How to do this with perl?) + $(SED) -e 's///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@@@' > 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/ //; 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///;\ + s///' \ + 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///;\ + s///' \ + 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///;\ + s///' \ + 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 index 6c95de6d..00000000 Binary files a/Junkbuster Status.URL and /dev/null differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..09aa295a --- /dev/null +++ b/LICENSE @@ -0,0 +1,346 @@ + Copyright (C) 2001, 2002 Privoxy Developers , + 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.) + +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. + + + Copyright (C) + + 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. + + , 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 index 00000000..5529111b --- /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 index 8c670b88..00000000 --- a/Makefile.in +++ /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 index 00000000..8f2beac5 --- /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) +Conectiva ...: Rodrigo Barbosa (morcego) +Debian ......: Roland Rosenfeld (roro) +FreeBSD .....: ? +HP-UX .......: Schelstraete Bart (bart1803) +Mac OSX .....: David Schmidt (david__schmidt) +NetBSD ......: ? +OS/2 ........: David Schmidt (david__schmidt) +RedHat ......: Rodrigo Barbosa (morcego) + Karsten Hopp (kick_) + Hal Burgiss (hal9) +RedHat 6.x ..: Karsten Hopp (kick_) +Solaris .....: Schelstraete Bart (bart1803) +SuSE ........: Stephan Waldherr (swa) +Windows .....: Jon Foster (jongfoster) + Gábor Lipták (gliptak) + + diff --git a/README b/README new file mode 100644 index 00000000..705c989c --- /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 :, 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. + diff --git a/acconfig.h b/acconfig.h index edf5c08a..fa6706b5 100644 --- a/acconfig.h +++ b/acconfig.h @@ -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 @@ -37,6 +37,168 @@ * * 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 + * * *********************************************************************/ @@ -63,62 +225,67 @@ #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) @@ -142,37 +309,120 @@ * 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 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 index 6a265a89..00000000 --- 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 index 00000000..34b824bc --- /dev/null +++ b/actionlist.h @@ -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. + * + * + *********************************************************************/ + + +#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 index 00000000..4b31f7fe --- /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 "
-", some "
-" (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. + * + * + *********************************************************************/ + + +#include "config.h" + +#include +#include +#include +#include + +#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
-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
-"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } \ + else if (add & __bit) \ + { \ + string_append(&result, "\n
+"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } + +#define DEFINE_ACTION_STRING(__name, __bit, __index) \ + if (!(mask & __bit)) \ + { \ + string_append(&result, "\n
-"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } \ + else if (add & __bit) \ + { \ + string_append(&result, "\n
+"); \ + 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
-"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } \ + else \ + { \ + lst = action->multi_remove[__index]->first; \ + while (lst) \ + { \ + string_append(&result, "\n
-"); \ + 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
+"); \ + 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
*/ + 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
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
+"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } \ + else \ + { \ + string_append(&result, "\n
-"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } + +#define DEFINE_ACTION_STRING(__name, __bit, __index) \ + if (flags & __bit) \ + { \ + string_append(&result, "\n
+"); \ + 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
-"); \ + 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
-"); \ + string_join(&result, add_help_link(__name, csp->config)); \ + } \ + else \ + { \ + while (lst) \ + { \ + string_append(&result, "\n
+"); \ + 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 index 00000000..f4365f0e --- /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. + * + * + *********************************************************************/ + + +#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 cd228986..493a00eb 100644 --- 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 + * * *********************************************************************/ @@ -39,12 +84,12 @@ const char amiga_rcs[] = "$Id: amiga.c,v 1.1 2001/05/13 21:57:06 administrator E #include #include -#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 6f132d0b..580dc32d 100644 --- 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 @@ -30,7 +30,33 @@ * 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 + * * *********************************************************************/ @@ -43,6 +69,8 @@ #include #undef __NOLIBBASE__ +#define __CONSTLIBBASEDECL__ const +#define DEVICES_TIMER_H #include #include #include @@ -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 index 7b48f3af..00000000 --- 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 . -# -# 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 -/*.*/mainos/*.*/.*\.gif -/*.*/mainos/*.*/.*\.jpe?g - -# more from a finnish friend Petri Haapio -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 -194.251.243.50/cgi-bin/banner - -www.dime.net/ad -www.iltalehti.fi/ad -www.iltalehti.fi/ilmkuvat -www.mtv3.fi/mainoskuvat - -# -/*.*/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 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 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 -# Banner.xxLINK.nl/ - -# Mark Lutz -/.*/*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 index 00000000..4a523b21 --- /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 + * + **********************************************************************/ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#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, + "Shut down - Do not deploy this build in a production environment, " + "this is a one click Denial Of Service attack!!!" }, +#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: + * + * 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 = + "\r\n" + "500 Internal Privoxy Error\r\n" + "\r\n" + "

500 Internal Privoxy Error

\r\n" + "

Privoxy ran out of memory while processing your request.

\r\n" + "

Please contact your proxy administrator, or try again later

\r\n" + "\r\n" + "\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[] = + "\r\n" + "500 Internal Privoxy Error\r\n" + "\r\n" + "

500 Internal Privoxy Error

\r\n" + "

Privoxy encountered an error while processing your request:

\r\n" + "

Could not load template file "; + static const char body_suffix[] = + " or one of it's included components.

\r\n" + "

Please contact your proxy administrator.

\r\n" + "

If you are the proxy administrator, please put the required file(s)" + "in the (confdir)/templates directory. The " + "location of the (confdir) directory " + "is specified in the main Privoxy config " + "file. (It's typically the Privoxy install directory" +#ifndef _WIN32 + ", or /etc/privoxy/" +#endif /* ndef _WIN32 */ + ").

\r\n" + "\r\n" + "\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[] = + "\r\n" + "500 Internal Privoxy Error\r\n" + "\r\n" + "

500 Internal Privoxy Error

\r\n" + "

Privoxy encountered an error while processing your request:

\r\n" + "

Unexpected internal error: "; + static const char body_suffix[] = + "

\r\n" + "

Please " + "" + "file a bug report.

\r\n" + "\r\n" + "\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("usermanual); + string_append(&result, ACTIONS_HELP_PREFIX); + string_join (&result, string_toupper(item)); + string_append(&result, "\">"); + string_append(&result, item); + string_append(&result, " "); + + 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(¤t_time); /* get current time */ + + current_time += time_offset; + + /* get and save the gmt */ + { +#ifdef HAVE_GMTIME_R + struct tm dummy; + t = gmtime_r(¤t_time, &dummy); +#else + t = gmtime(¤t_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 , i.e. a substitution of the regex + * "if--start.*if--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--start@" and "@if--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 , i.e. a substitution of the form: + * @if--then@ + * True text + * @else-not-@ + * False text + * @endif-@ + * + * 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 + * + * 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, "
  • name); + string_append(&result, "\">"); + string_append(&result, d->description); + string_append(&result, "
  • "); + } + } + + 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, "\n"); + + for (cur_entry = the_map->first; + (cur_entry != NULL) && (ret != NULL); + cur_entry = cur_entry->next) + { + string_append(&ret, "\n"); + } + + string_append(&ret, "
    "); + string_join (&ret, html_encode(cur_entry->name)); + string_append(&ret, ""); + string_join (&ret, html_encode(cur_entry->value)); + string_append(&ret, "
    \n"); + return ret; +} + + +/* + Local Variables: + tab-width: 3 + end: +*/ diff --git a/cgi.h b/cgi.h new file mode 100644 index 00000000..39c6938d --- /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 + * + **********************************************************************/ + + +#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 index 00000000..0f0e46d3 --- /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): + * + * + * + * is now this: + * + * + * + * 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. + * + * + **********************************************************************/ + + +#include "config.h" + +/* + * FIXME: Following includes copied from cgi.c - which are actually needed? + */ + +#include +#include +#include +#include +#include +#include +#include + +#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, 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(¶m, "/"); + } + else + { + err = string_append(¶m, "(?:)"); + } + 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: + * View ", 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, "Edit", csp->config->actions_file_short[i]); + if (!err) err = string_append(&s, buf); + } + + if (!err) err = string_append(&s, "\n"); + } + } + if (*s != '\0') + { + if (!err) err = map(exports, "actions-filenames", 1, s, 0); + } + else + { + if (!err) err = map(exports, "actions-filenames", 1, "None specified", 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, "[Invalid URL specified!]" , 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(""); + + 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, "\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, "\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, "\n"); + } + } + string_append(&matches, "
    In file: "); + string_join (&matches, html_encode(csp->config->actions_file_short[i])); + snprintf(buf, 150, ".action ", i); + string_append(&matches, buf); + string_append(&matches, "View config->actions_file_short[i])); + string_append(&matches, "\">Edit
    {"); + string_join (&matches, actions_to_html(csp, b->action)); + string_append(&matches, " }
    \n"); + string_join (&matches, html_encode(b->url->spec)); + string_append(&matches, "
    (no matches in this file)
    \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 index 00000000..88501d7f --- /dev/null +++ b/cgisimple.h @@ -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 + * + * + **********************************************************************/ + + +#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 3ba741b3..173b3300 100644 --- a/config +++ b/config @@ -1,207 +1,1026 @@ -# 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 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" -# -# default: Kill the referrer-header from the client -# 'text' : Always send 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 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 index 00000000..cd430f6d --- /dev/null +++ b/config.guess @@ -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 . +# Please send patches to . +# +# 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 ." + +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 <$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 /* 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 + + 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 + #include + + 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 + 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 < +#ifdef __cplusplus +#include /* 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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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 index 4d71f86b..00000000 --- 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 $ - * - *********************************************************************/ - - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define to `unsigned' if 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 index 930ca660..00000000 --- a/config.h.in +++ /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 $ - * - *********************************************************************/ - - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define to `unsigned' if 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 index 00000000..12ebc787 --- /dev/null +++ b/config.sub @@ -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 . +# +# 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 ." + +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: diff --git a/configure.in b/configure.in index 492d6edc..2b697f1a 100644 --- a/configure.in +++ b/configure.in @@ -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= + 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 ], + [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 + ], [ + 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 + ], [ + 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 + ], [ + 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 + ], [ + 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 + ], [ + 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 + ], [ + 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 + ], [ + 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 + ], [ + 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 ) +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 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 index 00000000..74d5b727 --- /dev/null +++ b/contrib.sh @@ -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 = ) +#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: +#gen_list.c: +#gen_list.c:#include +#gen_list.c:#include +#gen_list.c:#include +#gen_list.c:#include +#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:/* *********************************************************************/ +#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:/* *********************************************************************/ +#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: +#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:/* *********************************************************************/ +#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: +#isa.c: +#isa.c:#include +#isa.c:#include +#isa.c:#include +#isa.c:#include +#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: +#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: +#main.c: +#main.c:#include +#main.c:#include +#main.c:#include +#main.c:#include +#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: +#malloc_police.c: +#malloc_police.c:#include +#malloc_police.c:#include +#malloc_police.c:#include +#malloc_police.c:#include +#malloc_police.c:#include +#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: +#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: +#rec_char.c: +#rec_char.c:#include +#rec_char.c:#include +#rec_char.c:#include +#rec_char.c:#include +#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: +#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: +#rec_charptr.c: +#rec_charptr.c:#include +#rec_charptr.c:#include +#rec_charptr.c:#include +#rec_charptr.c:#include +#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: +#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: +#rec_double.c: +#rec_double.c:#include +#rec_double.c:#include +#rec_double.c:#include +#rec_double.c:#include +#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: +#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: +#rec_long.c: +#rec_long.c:#include +#rec_long.c:#include +#rec_long.c:#include +#rec_long.c:#include +#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: +#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: +#rec_malloc_police.c: +#rec_malloc_police.c:#include +#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: +#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 index f17f4b0c..00000000 --- a/cookiefile +++ /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 - - - - diff --git a/cygwin.h b/cygwin.h index 4568ea82..b28dd6a0 100644 --- 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 @@ -36,6 +36,16 @@ * * 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 index 00000000..59ed56e9 --- /dev/null +++ b/deanimate.c @@ -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, + * + * 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 + * + * + **********************************************************************/ + + +#include "config.h" + +#include +#include + +#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 index 00000000..ede98477 --- /dev/null +++ b/deanimate.h @@ -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, + * + * 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 + * + * + *********************************************************************/ + + +#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 index 00000000..ceaf32ab --- /dev/null +++ b/debian/changelog @@ -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 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 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 Thu, 23 May 2002 18:38:27 +0200 + +privoxy (2.9.14-beta-1) unstable; urgency=low + + * New upstream version. + + -- Roland Rosenfeld 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 Sun, 31 Mar 2002 23:53:28 +0200 + +privoxy (2.9.13-beta-1) unstable; urgency=low + + * Initial Release. + + -- Roland Rosenfeld Fri, 29 Mar 2002 11:52:03 +0100 + diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..2d235d7c --- /dev/null +++ b/debian/control @@ -0,0 +1,23 @@ +Source: privoxy +Section: web +Priority: optional +Maintainer: Roland Rosenfeld +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 index 00000000..2ae2775c --- /dev/null +++ b/debian/copyright @@ -0,0 +1,49 @@ +This package was debianized by Roland Rosenfeld 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 index 00000000..3414d3bc --- /dev/null +++ b/debian/dirs @@ -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 index 00000000..6a606b90 --- /dev/null +++ b/debian/doc-base.developer @@ -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 index 00000000..117c2a3b --- /dev/null +++ b/debian/doc-base.faq @@ -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 index 00000000..2a7f5e69 --- /dev/null +++ b/debian/doc-base.user @@ -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 index 00000000..2b0dd848 --- /dev/null +++ b/debian/docs @@ -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 index 00000000..cca3a8be --- /dev/null +++ b/debian/init.d @@ -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 index 00000000..d230a8b0 --- /dev/null +++ b/debian/logrotate @@ -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 index 00000000..66709657 --- /dev/null +++ b/debian/manpages @@ -0,0 +1 @@ +privoxy.1 diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 00000000..8f1028de --- /dev/null +++ b/debian/postinst @@ -0,0 +1,55 @@ +#! /bin/sh +# postinst script for privoxy +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# 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 index 00000000..2c9e371a --- /dev/null +++ b/debian/postrm @@ -0,0 +1,44 @@ +#! /bin/sh +# postrm script for privoxy +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' overwrit>r> +# 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 index 00000000..06fb8a21 --- /dev/null +++ b/debian/rules @@ -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 index 00000000..70cd2761 --- /dev/null +++ b/default.action @@ -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 /, where both the +# and 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{} with 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{}" 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 index 00000000..485033a2 --- /dev/null +++ b/default.filter @@ -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/(]+)resizable=['"]?(no|0|false)['"]?(.*>)/$1resizable="1"$3/igU +s/(]+)location=['"]?(no|0)['"]?(.*>)/$1location="1"$3/igU +s/(]+)status=['"]?(no|0)['"]?(.*>)/$1status="1"$3/igU +s/(]+)scrolling=['"]?(no|0|auto)['"]?(.*>)/$1scrolling="no"$3/igU +s/(]+)menubar=['"]?(no|0)['"]?(.*>)/$1menubar="1"$3/igU + +# The tag was a crime! +# +s*|**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|()|$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/()/$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|].*>||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/(]+)framespacing=['"]?(no|0)['"]?(.*>)/$1$3/igU +s/(]+)(frame)?border=['"]?(no|0)['"]?(.*>)/$1$4/igU + +s/(]+)frameborder=['"]?(no|0)['"]?(.*>)/$1$3/igU +s/(]+)noresize(.*>)/$1$2/igU +s/(]+)resizable=['"]?(no)['"]?(.*>)/$1$3/igU +s/(]+)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/]*?(width|height)\s*=\s*['"]?1\D[^>]*?(width|height)\s*=\s*['"]?1(\D[^>]*?)?>//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/]*)['"]?>//iU +s/].*>//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 \ +*BINGO! \ +*igx + + +################################################################################# +# +# nimda: Remove Nimda (virus) code +# +################################################################################# +FILTER: nimda Remove Nimda (virus) code + +s%%
    WARNING: This Server is infected with Nimda!%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|]*?(width=['"]?468\D)[^>]*(height=['"]?60[^>]*?)>||sig +s|]*?(width=['"]?234\D)[^>]*(height=['"]?60[^>]*?)>||sig +s|]*?(width=['"]?88\D)[^>]*(height=['"]?31[^>]*?)>||sig +s|]*?(width=['"]?120\D)[^>]*(height=['"]?90[^>]*?)>||sig +s|]*?(width=['"]?120\D)[^>]*(height=['"]?600[^>]*?)>||sig +s|]*?(width=['"]?120\D)[^>]*(height=['"]?60[^>]*?)>||sig +s|]*?(width=['"]?160\D)[^>]*(height=['"]?600[^>]*?)>||sig +s|]*?(width=['"]?125\D)[^>]*(height=['"]?125[^>]*?)>||sig +s|]*?(width=['"]?120\D)[^>]*(height=['"]?240[^>]*?)>||sig +s|]*?(width=['"]?180\D)[^>]*(height=['"]?150[^>]*?)>||sig +s|]*?(width=['"]?300\D)[^>]*(height=['"]?250[^>]*?)>||sig +s|]*?(width=['"]?250\D)[^>]*(height=['"]?250[^>]*?)>||sig +s|]*?(width=['"]?240\D)[^>]*(height=['"]?400[^>]*?)>||sig +s|]*?(width=['"]?336\D)[^>]*(height=['"]?280[^>]*?)>||sig + +# One more. (Where is 200x50 from?) +# +s|]*?(width=['"]?200\D)[^>]*(height=['"]?50[^>]*?)>||sig + + +################################################################################# +# +# shockwave-flash: Kill embedded Shockwave Flash objects +# +################################################################################# +FILTER: shockwave-flash Kill embedded Shockwave Flash objects + +s|]*application/x-shockwave-flash.*||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%^.*(?Blocked

    Blocked due to possible adult content. Please see this site.

    %is +s+^.*warez.*$+No Warez

    You're not searching for illegal stuff, are you?

    +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 index 00000000..769562fa --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +man +text diff --git a/doc/changes.txt b/doc/changes.txt deleted file mode 100644 index 6aa14820..00000000 --- a/doc/changes.txt +++ /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 (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 (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 " 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 and #include 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 * -***************************************************************************** -(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 * -***************************************************************************** - -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 * -***************************************************************************** -(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 * -***************************************************************************** -(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 * -***************************************************************************** - -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 * -***************************************************************************** - diff --git a/doc/gpl.html b/doc/gpl.html index 7f0b6107..830fa2f9 100644 --- a/doc/gpl.html +++ b/doc/gpl.html @@ -1,567 +1,560 @@ - + + + - - - - - - - - - - -The GNU General Public License - - - - - - - - - -

    - -Junkbusters -

    - -
    -

    The GNU General Public License -

    -
    - -
    -

    -We did not write the GPL: the Free Software Foundation did - -

    -
    - -

    <Feedback>  -The GPL allows copying and changing of copyrighted documents -

    -

    -The Free Software Foundation -(FSF) -is a non-profit institution -that designed the GNU General Public License (GPL) to promote the -publication of free software. -The GPL is used by thousands of programmers -who want to give others the right to copy and modify -the source code of their programs. Millions of people benefit from this. -

    -We use the GPL -to allow everyone to use, copy and modify the -Internet Junkbuster -as they wish. -Companies can use it for commercial purposes, -but they are not permitted to use it in products that they claim -as their property -without negotiating a separate agreement with us beforehand. -

    -The GPL -can also be used -on documents written in human languages. -We give everyone permission to use everything on our web site under the GPL. -This means that you do not have to break copyright laws in order -to print a page or email a screen of the text to someone, for example. -Many sites do not permit you to do these things. -

    -If you have a home page, -we recommend that you consider using the GPL to -allow others the right to copy and use all the documents you create for it. -If you just mark a page as copyright, they won't even -legally be able to print it. -If you don't state you are its copyright owner, -they could change it slightly and claim it as their own property. -By marking it with both copyright and GPL notices -you allow them to copy it but not to claim -anything derived from it as their own. -

    -The GPL protects your -JUNKBUSTERS DECLARATION, -Spam Offer, -and all documents from us that you publish on your home page -or distribute to direct marketers by any other means. -By making your -DECLARATION -available to them under the GPL, you are -permitting them use to it, but never to claim it as their property, -even if they transform it. -

    -The -remainder of this page is the text of the GPL. -As legal documents go it's relatively clear, -but unfortunately it's fairly long because it has to cover -a lot of details specific to computer programs -that may not be relevant to -DECLARATIONs. -The hypertext links are ours, and should not be misinterpreted -as an indication of emphasis by the FSF. -

    -

    --- Back to Top of Page ---

    -
    -

    -Version 2, June 1991 - -

    -
    -
    -Copyright 1989, 1991 -
    -Free Software Foundation, Inc. -
    -675 Mass Ave. -
    -Cambridge, MA 02139 -
    -USA -
    -Everyone -is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -

    <Feedback>  -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. -

    - -

    <Feedback>  -GNU General Public License: Terms and Conditions for Copying, Distribution and Modification -

    -

    -O. -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: -
        -
      1. -You must cause -the modified files to carry prominent notices -stating that you changed the files and the date of any change. -
      2. -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. -
      3. -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.) -
      -

      -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: -
        -
      1. -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, -
      2. -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, -
      3. -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 -

    - -

    <Feedback>  -Appendix: 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) 19yy -<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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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. -

    -

    --- Back to Top of Page ---

    - -Home - · - - - · Site Map - - · Legal - - · Privacy - - · Cookies - - · Banner Ads - - · Telemarketing - - · Mail - - · Spam - -
    - -
    - - -

    -Copyright © 1996-8 Junkbusters -® Corporation. -Copying and distribution permitted under -the GNU -General Public License. - - -1998/10/31 -http://www.junkbusters.com/ht/en/gpl.html - -

    webmaster@junkbusters.com
    -
    - + + The GNU General Public License + + + + + + +

    + Website · + Manual · + FAQ · GPL

    + +

    Internet JUNKBUSTER License

    + +

    This document is out of date

    + +

    Development of Junkbuster is ongoing and this document is + no longer current. However, it may provide some assistance. If + you have problems, please use the Yahoo Groups + mailing list (which includes an archive of mail), the + SourceForge.net project page, or + see the project's home + page. Please also bear in mind that versions 2.9.x of + Junkbuster are development releases, and are not production + quality.

    + +

    The GNU General Public License

    + +

    We did not write the GPL: + the Free Software + Foundation did

    + +

    +  The GPL allows copying and changing of copyrighted + documents

    + +

    The Free Software Foundation (FSF) is a non-profit + institution that designed the GNU General Public License (GPL) + to promote the publication of free software. The GPL is used by + thousands of programmers who want to give others the right to + copy and modify the source code of their programs. Millions of + people benefit from this.

    + +

    We use the GPL to allow everyone to + use, copy and modify the Internet Junkbuster as they wish. Companies can use it for commercial + purposes, but they are not permitted to use it in products + that they claim as their property.

    + +

    The GPL can also be used on documents + written in human languages. This documentation for the Internet + Junkbuster is also under the GPL. This means that you do not + have to break copyright laws in order to print a page or email + a screen of the text to someone, for example.

    + +

    The remainder of this page is the text of + the GPL. As legal documents go it's relatively clear, but + unfortunately it's fairly long because it has to cover a lot of + details. The HTML formatting is ours, and should not be + misinterpreted as changing the license in any way.

    + +

    +

    + +

    Version 2, June 1991

    + +
    + Copyright 1989, 1991
    + Free Software Foundation, Inc.
    + 675 Mass Ave.
    + Cambridge, MA 02139
    + 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

    + +

    O. 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. + +
    3. + 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:
      + + +
        +
      1. You must cause the modified + files to carry prominent notices stating that you changed + the files and the date of any change.
      2. + +
      3. 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.
      4. + +
      5. 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.)
      6. +
      + +

      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.

      +
    4. + +
    5. + 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:
      + + +
        +
      1. 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,
      2. + +
      3. 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,
      4. + +
      5. 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.)
      6. +
      + +

      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.

      +
    6. + +
    7. 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.
    8. + +
    9. 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.
    10. + +
    11. 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.
    12. + +
    13. + 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.

      +
    14. + +
    15. 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.
    16. + +
    17. 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.
    18. + +
    19. + 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

      +
    20. + +
    21. 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.
    22. + +
    23. 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.
    24. +
    + +

    END OF TERMS AND CONDITIONS
    +
    +

    + +

    *  Appendix: 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) 19yy <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., 675 Mass Ave, + Cambridge, MA 02139, 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) 19yy 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.

    + +

    +

    + +

    + Website · + Manual · + FAQ · GPL

    + +

    + Copyright © 1996-8 Junkbusters ® + Corporation. Copyright © 2001 + Jon + Foster. Copying and distribution permitted under the GNU General Public License. The text of the + GNU GPL itself is copyrighted by the FSF, and may be copied but + not modified.

    + +

    + http://sourceforge.net/projects/ijbswa/

    + + diff --git a/doc/ijbfaq.html b/doc/ijbfaq.html deleted file mode 100644 index ab7e7989..00000000 --- a/doc/ijbfaq.html +++ /dev/null @@ -1,3186 +0,0 @@ - - - - - - - - - - - - -Internet Junkbuster Frequently Asked Questions - - - - - - - - - -
    -

    Internet JUNKBUSTER Frequently Asked Questions -

    -
    - -

    -Download for UNIX - - · (Download for Windows 95/NT) - - · (Other OS) - - · Configuring Browsers - - · Installation - - · For Companies - - · Blocking - - · Cookies - - · Anonymity - - · Security - - · (Technical Manual) -

    -

    -
    -

    -The Top Ten Questions - -

    -
    -
    For a list of the questions on this page (without the answers), -see our -Table of Contents. -It also contains detailed pointers into our pages -on -cookies -and on busting -junk e-mail, -junk mail -and -telemarketing calls. - -

    <Feedback>  -What is the Internet Junkbuster Proxy and what does it do for me? -

    -

    -The -Internet Junkbuster -Proxy -TM -is -free -privacy-enhancing software that can be run on your PC or by your -ISP -or company. -It blocks requests for -URLs -(typically banner ads) -that match its -blockfile. -It also deletes unauthorized -cookies -and other -unwanted identifying -header information -that is exchanged between web servers and browsers. -These headers are not normally accessible to users -(even though they may contain information that's important to your privacy), -but with the -Internet Junkbuster -you can see almost -anything you want -and control everything you're likely to need. -You -decide what's junk. -SM -Many people -publish -their blockfiles to help others get started. -

    - -

    <Feedback>  -Is there a license fee / warranty / registration form / expiration? -

    -

    -No, none of these. -It's completely free of charge. -Junkbusters -offers you the software to copy, use, modify and distribute -as you wish, forever, at -no charge -under the -GNU General Public License. -

    -It comes with -no warranty of any kind. -

    -You don't have to register, -in fact we don't even provide a way to do so: -the practice of registering software is -usually just an -excuse -to send you solicitations and -sell your name -and information about your behavior. -You are welcome to obtain and use our software as anonymously you wish. -(Your -IP -address will naturally be -disclosed -when you download it, -so if you work for a web ad company -you might want to use a service such as the -lpwa.com -when you get it. -We -never -want to be given any information that you consider private or confidential.) -

    -We are often asked why we give away a product that many -would happily pay for. -The answer is that we are determined to carry out our -mission: -to free the world from junk communications. -

    - -

    <Feedback>  -Does it run on Windows? On a Mac? On the AOL browser? -

    -

    -For the latest information on availability, see the -Distribution Information -page. -We -don't -think it will ever run on -Windows 3.1. -But you don't need to have it running on your computer -if you get your -ISP -or Systems Administrator at -work -to run it. -

    - -

    <Feedback>  -How can I get my ISP to run the Internet Junkbuster? -

    -

    -Try their sales or support department -(depending on whether you are already a customer). -You might send them email including the following -URL: -
    -   http://www.junkbusters.com/ht/en/ijbfaq.html#isps -
    -You could mention that many -other -ISPs -provide it, -and that you regard it as an important part of your decision on -where to buy Internet service. -

    - -

    <Feedback>  -Who chooses the options that control what is blocked? -

    -

    -Whoever starts the -Internet Junkbuster -chooses the options and the blockfile. -If your -ISP -runs it for you, they have to make these decision -(though -some -may give you a choice of proxies, -and a way to suggest new -URLs -to block). -If you run it on your computer, -You -decide what's junk. -SM -

    - -

    <Feedback>  -How do I download and run the program on my computer? -

    -

    -It depends on your platform. -If you are using Windows 95 or NT, -see our separate page on -installing under Windows. -If you have a C compiler and are using almost any flavor of -UNIX ® -you -download it, compile it, start it running, -and then -configure your browser. -Several precompiled packages are also available through links in our -distribution page, -which lists all available platforms. -

    -If you are using a platform for which we have no current -availability, -you are welcome to port the code. -If you do this and you would like us to consider publishing your ported version, -please -tell us. -

    - -

    <Feedback>  -How can I tell which blockfile and options are being used? -

    -

    -Just point your browser to -http://internet.junkbuster.com/cgi-bin/show-proxy-args -or to any -URL -ending in -show-proxy-args -(even if it doesn't exist). -It needn't exist because the -Internet Junkbuster 2.0 -intercepts the request, blocks it, -and returns in its place -information about itself. -Using the -URL -above is useful for checking that your browser really is -going through an -Internet Junkbuster, -because the -junkbuster.com -server returns a warning if the request actually gets to it. -Some people set the home page of their browser to such a -URL -to be sure that it is configured to use the proxy. -

    -If you wish to check the header information -your proxy is actually sending, -a visit to -http://internet.junkbuster.com/cgi-bin/show-http-headers -will give you the more relevant ones first. -You might also like to turn the proxy -off -and compare the difference. (Don't forget to turn it back on again.) -

    - -

    <Feedback>  -My browser started giving me ``server not responding'' messages -

    -

    -Once your browser is told to use a proxy such as the -Internet Junkbuster, -it thinks of it as its server for everything, -so this message means it can't talk to the proxy. -The -Internet Junkbuster -may not be running, -or you may have specified its proxy -address -incorrectly. -Check that the details you entered are correct. -If you have -telnet -you can try connecting to the appropriate port to see if the -Internet Junkbuster -is running. -If your -ISP -is running the -Internet Junkbuster, -you may want to check with them. -If you are running it yourself under -UNIX ®, -try looking at a -ps ax -to see if it is running. -The -port -specified in its options should be the same one as your -browser has configured. -

    - -

    <Feedback>  -I've got this great idea for a new feature. Who do I tell? -

    -

    -We'd be very interested to hear it, but please bear a few things in mind. -

    -

    - -

    <Feedback>  -My question isn't listed here. Who do I ask for support? -

    -

    -If you find using our free product -harder than you're used to for consumer software, -there are many -commercial alternatives -that you could consider. -

    -The answer to detailed technical questions may be answered in -manual page, -or in the source code. -Also double-check this page for an answer: -using the ``find'' feature on your browser for likely keywords may help. -Our site also has a -search -feature. -

    -Many people post requests for help and responses on -Usenet. -

    -If your -ISP -is providing -the -Internet Junkbuster -for you, -and your question is about how to use it, -check their web page before asking them. -

    -Even though we don't offer the kind of -support you might expect if you paid a lot of money for a software product, -you can still ask us. -But before you do, please consider whether -you could ask someone closer to you. -And please be patient if we're slow to reply: we -never charge consumers -for our services, -so we have to subsidize consumers with revenue from companies, -and our resources are limited. -

    -If your company or organization -would be interested in a maintenance contract -with phone and email support, -hard copy documentation and source code and pre-compiled binaries on tape -or disk, -please -ask us -for a quote. -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Configuring your browser to talk to the Internet Junkbuster - -

    -
    -
    -

    <Feedback>  -What is the proxy address of the Internet Junkbuster? -

    -

    -If you set up -the -Internet Junkbuster -to run on the computer you browse from -(rather than your -ISP's server -or some networked computer at work), -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 -8000 -(unless you have told the -Internet Junkbuster -to -run on a different port with the -listen-address -option). -So you when -configuring your browser's proxy settings -you typically enter the word -localhost -in the two boxes next to - -HTTP -and - -Secure, -and the number -8000 -in the two boxes labelled -to the right of those boxes. -

    -If your -ISP -or company is running -the -Internet Junkbuster -for you, -they will tell you the address to use. -It will be the name of the computer it's running on -(or possibly its numeric IP address), -plus a port number. -Port 8000 is the default, so assume this number if it is not specified. -Sometimes a colon is used to glue them together, -as in -junkbuster.fictitous-pro-privacy-isp.net:8000 -but -with most browsers -you do not type the colon, -you enter the address and port number in separate boxes. -

    - -

    <Feedback>  -How do I tell the browser where to find the Internet Junkbuster? -

    -

    -All current browsers can be told the address of a proxy to use. -You enter the same information in two fields in your browser's proxy -configuration screen (see list below): one for -HTTP, -and one for the Secure Protocol (assuming your browser supports -SSL). -If you find some information already entered for your proxy, -see the -next question. -Here are the menus you go through to get to the proxy configuration settings. -(We also recommend that you -disable Java, -which is a separate operation.) -Make notes on the changes you make so you know how to undo them! -You will need to know what you did -in case you wish to -discontinue -using the proxy. -

      -
    • -For -Netscape -2.01, 2.02 and 3.0 -[Graphic Illustration]: - -Options; - -Network Preferences; - -Proxies; - -Manual Proxy Configuration View ; -enter -proxy address details -under - -HTTP -and - -Security Proxy; -click on - -OK; -click on the next - -OK. -
      -With Netscape 2.0, -follow with - -Options, - -Save Options. -
      -With Netscape 4.X series, you first have to go through - -Edit/Preferences. -[Graphic Illustration] -Then in the frame on the left, -click on triangle pointing to the right towards the word - -Advanced; -it will switch to a triangle pointing down; -and the words - -Cache, - -Proxies -and - -Disk Space -appear. -Click on - -Proxies -and the frame on the right will -display a banner saying - -Proxies Configure proxies to access the Internet. -Click the radio button labeled - -Manual proxy configuration -then click the button labeled - -View; -enter -proxy address details -under - -HTTP -and - -Security Proxy; -click on - -OK; -click on the next - -OK. -
    • -For -Internet Explorer 3.0: - -View; - -Options; - -Connections; -tick - -Connect through proxy server -box; - -Settings; -enter -proxy address details - -HTTP -Box, with port number in the second box; -same with - -Secure; -click on - -OK. -
    • -For Internet Explorer 2.0: - -View; - -Options; - -Proxy; -enter -proxy address details -click on - -OK. -
    • -On NT for MS-IE: - -Control Panel; - -Internet; - -Advanced; - -Proxy. -
    • -For MS-IE 4.0: seems to be almost the same as for -3.0, - -View; - -Internet Options; - -Connections; -tick - -Connect through proxy server -box; - -Settings; -enter -proxy address details - -HTTP -Box, with port number in the second box; -same with - -Secure; -click on - -OK. -Note that 4.0 has - -Advanced -settings to allow -HTTP -1.1 through proxies; -these must be disabled because the proxy does not currently understand -HTTP -1.1. -Please -tell us -if you see any other differences. -
    • -For NCSA Mosaic for Windows: - -Options, - -Preferences, - -Proxy; -enter -proxy address details -under - -HTTP. -
    • -For -Opera: - -Preferences, - -Proxy servers; -check the box next to HTTP; -enter the server and port number in the box on the other side; -click on - -OK. -
    • -For -Lynx, -Mosaic/X, -Grail, -and -W3O -Arena, -you can specify the proxy via environment variables -before starting the application. -This will probably be done with something like either -
      -   setenv http_proxy http://localhost:8000/ -
      -or -
      -   http_proxy=http://junkbuster.fictitous-pro-privacy-isp.net:8000/ export http_proxy -
      -depending on your shell and where the -Internet Junkbuster -lives. -
    -If your browser is not listed here, -or if you notice an error, please -tell us -the correct procedure. -

    - -

    <Feedback>  -What should I do if I find another proxy is already configured? -

    -

    -Some -ISPs -and companies require all Web traffic to go through their proxy. -In this case you would find your proxy configuration with values already set, -possibly under -Automatic Proxy Configuration -(in the case of -Netscape -and -MS-IE 3.0 -and above). -It's probably a firewall proxy between your company and the outside world, -or a -caching proxy -if you're using an -ISP. -

    -What needs to be done in this case is to -use the -forwardfile -option -to tell the -Internet Junkbuster -the address of the other proxy. -Specify a different (unused) port number -with the -listen-address -option, -and configure your browser to -use that port. -If you haven't done this kind of thing before, -it's probably best to consult your systems administrator or -ISP -about it; -check their web page first. -

    - -

    <Feedback>  -What if I want to stop using the Internet Junkbuster? -

    -

    -Just go through the same procedure you used to start your -browser using the -Internet Junkbuster, -but remove the details you put in -(or if there was something there before, restore it). -You may need to use - -Save Options -to make this change permanent. -On Netscape 3.0 you can go through - -Options; - -Network Preferences; - -Proxies -and click on - -No Proxy -to turn it off, and later click on - -Manual Proxy Configuration -if you want to start using it again. -(No need to enter the again details under - -View -as you did the -first time; -they should remain there unchanged.) -

    -This stops your browser talking to the proxy; -shutting down the proxy -is a different matter. -

    - -

    <Feedback>  -Automatic dialing isn't working any more. How do I fix it? -

    -

    -Some browsers (such as MSIE-4) can be configured to dial your -ISP -automatically when you click on a link, -but this feature gets disabled if you specify a proxy running on your -own computer -(with address -localhost -or -127.0.0.1) -because these addresses don't require dialing. -The -Internet Junkbuster -knows nothing about dialing, so it doesn't work. -To make automatic dialing work, -make up a name such as -junkbuster.ijb -and use that name in the proxy settings -instead of -localhost, -and then add the line -127.0.0.1 junkbuster.ijb -to the file -c:\windows\hosts -(if there already is a line beginning with -127.0.0.1 -just add -junkbuster.ijb -at the end of it.) -

    -This should also work Netscape Communicator 4 on -machines where IE-4 has been installed. -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Setting up the Internet Junkbuster on your local computer - -

    -
    -
    The next two sections assume you wish to compile the code -with your own C compiler. -If you just want to use the -.exe -file provided for Windows, -see the -Windows Installation page. - -

    <Feedback>  -How do I compile the code under Unix? -

    -

    -If you are running Redhat -Linux -you may prefer to use the -rpm -instead of the following procedure. -

      -
    1. -First -download the tar file -(~286k) -and -uncompress and extract the files from it with this command -
      -   uncompress -c ijb20.tar.Z | tar xf - -

      -

    2. -If your operating system is from -Sun -or -HP -examine the -Makefile -and make any changes indicated inside. -
    3. -Run -
      -
      -   make -

      -

    4. -Copy the sample configuration file -(junkbstr.ini, -previously called -sconfig.txt -and other names in earlier releases) -to some convenient place such as -/usr/local/lib/junkbuster/configfile -or whatever you choose. -The sample file has all the options commented out. -You can remove the -# -character on any that you want, but it may be better to -leave this until to later. -Run it asynchronously: -
      -
      -   junkbuster configfile & -

      -If you are running a version earlier than 2.0 you can start it with -junkbuster & -

      -

    5. -Configure your browser (described -above). -
    6. -Verify that the -Internet Junkbuster -is working (described -above). -
    7. -Decide on the options you really want, -kill -the -process -and start it again. The most popular option is -blockfile -to block ads. -A sample blockfile is provided as an illustration, -but it doesn't really stop many ads. -More comprehensive ones are available -elsewhere. -
    8. -You'll probably want to add an entry to -/etc/rc.d/rc.local -or equivalent to start it at boot time. -(Any output you specify should be redirected to a file. -And don't forget the -& -at the end to run it asynchronously or your system will seize -up after the next reboot.) -
    -

    - -

    <Feedback>  -How do I compile the code under Windows? -

    -

    -A binary is currently being supplied with the source code, -but if you prefer to compile it yourself here is the likely procedure. -Most of these steps are repeated in our checklist for -installation under Windows. -

      -
    1. -First -click here to download the zip file -called -ijb20.zip -(~208k), -then uncompress and unpack the zip archive using a tool like -WinZip. -
    2. -Now the distribution (source and sample files) -will be in a folder -called -ijb20. -Go into that folder and then edit the Makefile for -your system, -removing the comment character -(#) -in the lines related to Win32. -Then type: -
      -   nmake -
      -This should create an executable called -junkbstr.exe. -For information on issues with various compilers, see the -Distribution Information -page. -
    3. -Run the executable with the command: -
      -   junkbstr -
      -The program will produce a message -indicating that it has started and is ready to serve. -

      -(Version 2.0.1 and above uses -the file -junkbstr.ini -as the config file -if it exists and no argument was given. If you have an earlier -version or if you want it to use a different config file, -simply specify that file as the argument.) -

    4. -Configure your browser (described -above). -
    5. -Check the proxy is working (described -below). -
    6. -To have the proxy start itself automatically -when you login to Win95, -drop the ``shortcut'' to the -junkbstr -executable into the StartUp folder: -
      -   C:\Windows\Start Menu\Programs\StartUp -
      -You might want to change the shortcut's -Properties->Shortcut -to -Run: Minimized. -If you specify the -hide-console -option then the -DOS -window will vanish after it starts. -

      -WinNT users can put it into their own -StartUp folders or the Administrator -can put it into the system's global StartUp folder. -For details on how to make this a service under NT -see our -Windows page. -

    -

    - -

    <Feedback>  -How do I check that the proxy is working? -

    -

    -Pick a page from somewhere (such as your bookmarks, or just one -that your browser was pointing to) -and - -Reload -it. -If you get a message along the lines of ``server not responding, -using cached copy instead,'' see the advice -above. -If the page reloads OK, check that your browser is actually -talking to the proxy by going to -http://internet.junkbuster.com/cgi-bin/show-proxy-args -or any -URL -ending in -show-proxy-args -(as described -below, -the proxy should intercept the request.) -When you see ``Internet Junkbuster Proxy Status,'' -you'll know it's working. -

    - -

    <Feedback>  -How and why would I have this proxy chained with other proxies? -

    -

    -You may need the -forwarding -feature to ``daisy chain'' the -Internet Junkbuster -to another proxy, perhaps an -anonymizing -proxy to -conceal -your -IP -address, -or a -caching proxy -from your -ISP, -or a -firewall -proxy between your company and the outside world. -Version 2.0 -can be even configured to forward -selectively -according to the -URL -requested: -for example, connecting directly to trusted hosts, -but going through an anonymizing or firewall proxy for all other hosts. -

    -Network administrators might use it to provide -transparent access to multiple networks without -modifying browser configurations. -Most browsers also provide a way of -specifying hosts that the browser -connects to directly, bypassing the proxy. Some provide a method for -Automatic Proxy Configuration. -A well written -Internet Junkbuster -configuration can be much more flexible and powerful. -

    -An -ISP's -caching proxy -would typically be called something like -cache.your-isp.net:8080 -(as described on you -ISP's -web page); -you would put this information in your -forwardfile -as described in our manual. -Your browser would be configured to -the -Internet Junkbuster -for -HTTP -and Security Proxies as before, -but you probably want to tell it to use the caching proxy -for -FTP -and other protocols. -If your -ISP -is running -the -Internet Junkbuster -for you, -they have probably already decided whether to chain with a caching proxy. -

    - -

    <Feedback>  -How does the Internet Junkbuster work with SOCKS gateways? -

    -

    -There is support for some -gateways -in -Version 1.4 -and above. -The gateway protocol used to be specified on the command line; -it is -now specified -in the same file as -forwarding. -Note that the browser's proxy configuration must -not -specify a -SOCKS -host; -it should specify the proxy as described -above. -

    - -

    <Feedback>  -How do I configure it to be just a plain old proxy? -

    -

    -To get the proxy to do as little as possible (which means not deleting any -sensitive headers), place in your -configuration file the following three lines (each ending in a space -then a period) to stop it changing sensitive headers: -
    -   referer . -
    -   from . -
    -   user-agent . -
    -   cookiefile mycookiefile -
    -The fourth line is also needed to specify a -cookiefile -that might be called -mycookiefile -containing a single line with a -* -character, to allow all cookies through. -

    - -

    <Feedback>  -How do I shut down the proxy (to restart it)? -

    -

    -It depends on your platform. Under Windows, use - -Ctrl-Break -in the -DOS -window or -the old three-fingered salute of - -Ctrl-Alt-Delete -and select - -End Task. -Under -UNIX ® -you'll need to -kill -the -junkbuster -process. -If you don't know the process number to give to -kill, try this: -ps ax | grep junkbuster -
    -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Information for companies - -

    -
    -
    -

    <Feedback>  -What do advertising companies think of this kind of technology? -

    -

    -We've seen only a few public comments from the advertising industry on this, -other than -SEC filings. -First, the president of the Internet Advertising Bureau told -CNET -that he wasn't worried by banner blockers. -Second, after the Federal Trade Commission's -workshop -where we gave a live demonstration of our proxy before -many eminent representatives of the industry, -the -Direct Marketing Association -made the following -statement in the closing paragraphs -of their -summary comments -to the Commission. -

    -Clever shareware developers have come up with products that -can obliterate cookies and advertisements for those consumers -who have these concerns. -The Internet is a market that is so democratic and flexible -that it is easy for companies and software -developers to respond to a perceived market need. -
    -Their attitude seems to be that they would prefer that -people use technical solutions -to protect their privacy than have protections -imposed by legislation or government regulations. -So, do you perceive a market need? -Then here are some ways to flex your democratic muscles. -

    - -

    <Feedback>  -Should we provide the Internet Junkbuster for our employees? -

    -

    -That depends. Try this quick three-point test. -

      -
    1. -Do you want to spend your communications budget -on bandwidth that wastes your employees' time by forcing them to wait -for a lot of annoying distractions while they're trying to -do their jobs? -
    2. -Do you want current and potential vendors -to know quantitative details about the -software and hardware platforms -that you have? -
    3. -Do you want your competitors to be able to -track -exactly which of your -employees are checking out their web sites? -
    -If the answer to all three questions is yes, -then you probably don't have any need for this kind of product. -

    - -

    <Feedback>  -Can our company get commercial support for the software? -

    -

    -Yes, -ask us -for a quote on a maintenance contract with your choice of -phone and email support, -hard copy documentation, -source code and pre-compiled binaries on tape or disk, -and email alerting of upgrades and issues. -We also offer consulting services to help set up ``stealth browsing'' -capabilities to help reduce the footprints left while doing competitive -analysis and other Web work where confidentiality is critical. -

    - -

    <Feedback>  -I run an ISP. What issues should I consider before offering it? -

    -

    -Many -ISPs -who offer the proxy to their customers have told us that -most of their customers are -delighted with it -(although one reported that a customer complaint that without banner ads, -surfing was like reading a novel: we recommend making it optional). -Many -ISPs -like it because it reduces bandwidth requirements. -To help get you started, -here's a checklist we've developed from working with a few -ISPs. -You may think of more, -and we'd be interested if you're willing to -share them -with us. -

      -
    1. -If you get more than one request for -the -Internet Junkbuster -you may want to tell your customers on your News page that you -already -know about it and are assessing it. -
    2. -Try the software and -verify -that it performs satisfactorily. -
    3. -Determine whether your customers perceive the service as -valuable -(and therefore worth the time to set up). -We've had reports of many delighted customers. -
    4. -Assess the -level of -security -associated with the software. -If access is to be -restricted -(to just dial-in ports, for example) -how is this to be done? -
    5. -Consider -whether to expect any additional load on computing resources required, -and any change in use of bandwidth due to the blocking of large -GIFs. -
    6. -Choose the -options -you wish to provide. -
    7. -Decide whether you want -to offer a choice of configurations, such some of these four. -
        -
      1. -Banners -Blocked, -Wafer with -No-Cookie-Copyright -notice -
      2. -Cookies -not stopped -(cookiefile -with just a -* -in it), -User Agent -specified as -Lynx -
      3. -Cookies from browser -allowed, -permitting -registered services -
      4. -A proxy for -kids. -
      -If you run a -caching proxy, -decide whether the -Internet Junkbuster -will chain with it by default, -and whether to offer an alternate with no caching. -(Some -ISPs -don't, because they want to give customers an incentive to use caching -and save bandwidth.) -
    8. -Decide on a naming scheme for your -proxies. -If you're running only one -proxy on one machine, -the simplest way is to just use port 8000 on your main machine, -such as -our-isp.net. -But it would probably be safer to put an entry in your name server -and call it something like -junkbuster.our-isp.net. -If running several proxies, you could either use different ports -on the same machine, or if you have -the opportunity to distribute the load over -a few machines -you could -use different hostname aliases such as -banner.junkbuster.our-isp.net, -lynx.junkbuster.our-isp.net -and -oneway.junkbuster.our-isp.net -(corresponding to the examples in the previous point). -You may want to set up -Automatic Proxy Configuration. -
    9. -Prepare a page -explaining the -Internet Junkbuster -to your customers. -Here's are some examples from -Australia, -Germany, -Florida, -New York/New Jersey/Pennsylvania, -North Carolina, -Texas, -and -Utah. -You are welcome to copy and modify -material -from -Junkbusters -according to the -GPL. -You might want to set up a process to check this page periodically -and update it when it changes. -(A few links can probably serve as well as lot of copying however.) -A typical page would probably specify the following. -
      -
    10. -Invite a small number of technologically sophisticated -customers to beta-test the service. -
    11. -Announce general availability on your ``News'' page. -Tell us -if you would like to be included on a list of -ISPs -offering the -Internet Junkbuster. -
    -

    - -

    <Feedback>  -What's a Proxy Server Server and how can I make money as one? -

    -

    -Other organizations with web presence and some bandwidth to spare -can set up as -Proxy Server Servers - -(PS2s). -The idea here is to allow users to choose their proxy configuration, -and provide it to them on a semi-permanent basis. -Users would fill in a form specifying what options they want in -their proxy, -possibly even at a very high level, such as -``no ads'' -or ``no nudity.'' -This information is sent to a -CGI -script that -configures a proxy, starts it running, and returns its address and port number -(possibly along with configuration instructions for the browser -that the user specified.) -

    -Users -could be charged -a subscription fee, -or the service could be thrown in free in the hope of -improving customer retention for some existing business -(which is what -ISPs -are doing). -It might be possible to make money by -inserting new ads in the holes left where others were blocked, -but the original owners might object. -PS2s -could differentiate themselves -by providing frequently updated and comprehensive -blocking of ads, or of offensive material based on their own grading system. -Some content providers might do it for the chance to be the -only company that the consumer permits to set cookies. -(Identification could even be done via cookies, -but this might not be popular with the kind of user who wants a proxy.) -PS2s -might sell specific or aggregate information about their -users' browsing habits, -so the agreement with users on whether they are permitted to do this -would be important to both sides. -

    -If your organization -establishes a -Proxy Server Service -you would like publicized, -please -notify us. -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Blocking - -

    -
    -
    -

    <Feedback>  -Where can I get an example blockfile that stops most ads? -

    -

    -The sample blockfile we provide blocks almost nothing, -and we do not publish blockfiles that stop almost all banner ads. -But others have; you can find them by -asking Altavista. -You can add any part of the new file to your old one -(probably called -sblock.ini -if you haven't changed the default name in the latest version) -or your just replace it completely. -You -probably -don't need to restart the proxy. -

    -If you develop an interesting blocklist and publish it on the Web, -you might want to include the word ``junkbuster'' in it -and use the word ``blocklist'' in the file name given in the -URL -so that others can find it with the query given in the previous sentence. -

    - -

    <Feedback>  -If I see an ad I wish I hadn't, how do I stop it? -

    -

    -If your -ISP -is running the -Internet Junkbuster, -they should have a policy on whether they accept suggestions from -their customers on what to block. Consult their web page. -

    -If you are running -the -Internet Junkbuster -yourself, you have complete control over what gets through. -Just add a pattern to cover the offending -URL -to your blockfile. -Version 1.3 and later automatically rereads the blockfile when it changes, -but if you're running an earlier version you'll -have to -stop it -and restart it. -

    -To choose a pattern you'll first need to find the -URL -of the ad you want cover. -

    -Some people use the -debug -1 -option to display each -URL -in a window as the request is sent to the server. -It's then usually an easy task to pick the offending -URL -from the list of recent candidates. -

    -Alternatively, -you can use - -View Document Info -(or - -View Document Source -if your browser doesn't have that). -The - -Info -feature has the advantage of showing you the full -URL -including the host name, -which may not be specified in the source: -there you might see something like -SRC="/ads/click_here_or_die.gif" -indicating only the -path. -(The host name is assumed to be the same as the one the page came from.) -

    -But ads often -come from a different site, in which case you -might see something like -SRC="grabem.n.trackem.com/Ad/Infinitum/SpaceID=1666" -or longer. -If the company looks like a pure ad warehouse -(as in the last case), -you may want to place just its domain name in the blockfile, -which blocks all -URLs -from that site. -

    -If the ad comes from a server -that you really want some content from, -you can include enough of the path -to avoid zapping stuff you might want. -In the first example above, -/ads/ -would seem to be enough. -If you don't include the domain name, -the pattern applies to all sites, -so you don't want such patterns -to be too general: -for example -/ad -would block -/admin/salaries/ -on your company's internal site. -

    -To speed the blocking of images, some -UNIX ® -users create a -shell script called -Image: -containing a line such as -echo $1 | sed s/http:..// >> $HOME/lib/blockfile -that adds its argument to the user's blockfile. -Once an offending image has been be found using - -View Document Info -it's easy to cut-and-paste the line (or part of it) into a shell window. -The same script can be linked to a file called -Frame: -to dealing with framed documents, -and -junkbuster: -to accept the output of the -debug -option. -

    -When compiled without the -regular expressions -option, the -Internet Junkbuster -uses only very simple (and fast) matching methods. -The pattern -/banners -will not stop -/images/banners/huge.gif -getting through: you would have to include the pattern -/images/banners -or something that matches in full from the left. -So you can get what you want here, -the matcher understands -POSIX -regular expressions: -you can use -/*.*/banners -to block -and any -URL -containing -/banners -(even in the middle of the path). -(In Versions 1.1 through 1.4 -they were an option at compile time; -from Version 2.0 they have become the default.) -Regular expressions give you -many more features -than this, -but if you're not already familiar with them you probably won't -need to know anything beyond the -/*.*/ -idiom. -If you do, a -man egrep -is probably a good starting point). -

    -Don't forget the -/ -(slash) -at the beginning of the path. -If you leave it out the line will be interpreted as a domain name, -so -ad -would block all sites from Andorra -(since -.ad -is the two-letter -country code -for that principality). -

    -For a detailed technical description -of how pattern matching is done, -see the -manual. -

    - -

    <Feedback>  -How come this ad is still getting through anyway? -

    -

    -If the ad had been displayed before you included its -URL -in the blockfile, -it will probably be held in cache for some time, -so it will be displayed without the need for any request to the server. -Using the -debug -1 -option to show each -URL -as it is fetched is a good way to see exactly what is happening. -

    -If new items seem to be getting through, -check that you are -really running -the proxy with the right blockfile in the options. -Check the blockfile for -exceptions. -

    -Some sites may have different ways of inserting ads, -such as via -Java. -If you have ideas on how to block new kinds -of junk not currently covered, please -tell us. -

    - -

    <Feedback>  -How do I stop it blocking a URL that I actually want? -

    -

    -You can change the patterns so they don't cover it, -or use a simple feature in Version 1.1 and later: a line beginning with a -~ -character means that a -URL -blocked by previous patterns that matches the rest of -the line is let through. -For example, -the pattern -/ad -would block -/addasite.html -but not if followed by -~/addasite -in the blockfile. -Or suppose you want to see everything that comes from -a site you like, even if it looks like an ad: simply put -~aSiteYouLike.com -at the -end -of the blockfile. -(Order is important, because the last matching line wins.) -

    -As well as unblocking -pages that were unintentionally blocked, -this feature is useful for unblocking ads from a specific source. -This might be because you are interested in those particular ones, -or if you have an explicit agreement to accept certain ads, -such as those from a free web-based email provider. -

    - -

    <Feedback>  -Can I block sites I don't want my children to see? -

    -

    -Yes, but remember that -children who are technically sophisticated enough -to use the browsers' proxy configuration options -could of course bypass any proxy. -This kind of technology can be used as a gentle barrier to remind -or guide the child, -but nobody should expect it to replace the parent's role -in setting and enforcing standards of online behavior for their children. -

    -Some -ISPs -are starting to provide specialized proxies to protect children. -There are two basic approaches: the ``black list'' and the ``white list'' -approach. -The black list approach allows the child -to go anywhere not explicitly prohibited; the white list permits visits -only to sites explicitly designated as acceptable. -

    -It's very easy for -anyone to -compile a white list from a page of ``recommended -kids sites'' and to configure an -Internet Junkbuster -to allow access to those sites only. -If you compile with the -regex -option, -you can place a -* -(asterisk) as the first line of the blockfile (which blocks everything), -and then list -exceptions -after that. -Be careful to make the exception sufficiently broad: -for example, using -~www.uexpress.com/ups/comics/ch/ -as the exception for -Calvin and Hobbes -would block some of the graphic elements on the page; -you would probably want a wider exception such as -~www.uexpress.com/ups/ -to permit them. -

    -Version 2.0 has an experimental feature -to permit only sites mentioned in a nominated -trusted site. -This allows organizations to build lists of sites for kids to browse, -and the software automatically restricts access to those on the list. -

    -Many filtering -products -actually scan for keywords in -the text of pages they retrieve -before presenting it, -but -the -Internet Junkbuster -does not do this. -Building a perfectly reliable black list system is hard, -because it's very difficult to state -in advance -exactly -what is obscene or unsuitable. -For more info see our -links -page. -

    - -

    <Feedback>  -What do I see when a page or graphic is blocked by the proxy? -

    -

    -You usually see a broken image icon, -but it depends on several factors beyond the proxy's control. -If asked for a -URL -matching its blockfile, the proxy returns an -HTML -page containing a message identifying itself -(currently the two words ``Internet Junkbuster'') -with a status 202 (Accepted) instead of the usual 200 (OK). -(Versions 1.X returned an error 404: Forbidden, which caused -strange behavior in some cases.) -Status 202 is described in the -HTTP -RFC -as indicating that the request has been accepted but not completed, -and that it might complete successfully in the future -(in our case, if the blockfile were changed). -

    -The broken image icon is most common -because the browser is usually expecting a graphic. -But if it was expecting text, or if the page happens to be using certain -HTML -extensions -such as -layer -and your browser is a late model from Microsoft, -you may see the words ``Internet Junkbuster'' displayed as a hot link. -

    -Clicking on the link takes you to an explanation of -the pattern in the blockfile that caused the block, -so that you can edit the blockfile and go back and reload if you really -want to see what was blocked. The explanatory link is generated by -the proxy and is automatically intercepted based on its ending in -ij-blocked-url; -even though the site is specified as -http://internet.junkbuster.com -no request should actually made to that site. -If one is, it means that the proxy was been removed after it -generated the link. -

    -To summarize: -the identifying link to the blocking explanation -is usually turned into a broken image icon, -but it may be displayed on a page alone, -or they may may be restricted to the particular frame, layer or graphic area -specified in the page containing them. -The proxy has no way of knowing the context in which a -URL -will be used and cannot control how the blocking message will be rendered. -

    - -

    <Feedback>  -Why not replace blocked banners with something invisible? -

    -

    -Many users have suggested to us -that blocked banners should be replaced by a something like a -1x1 transparent -GIF -to make the page would look as if there was nothing ever there. -Apart from making it harder to catch unintended blocking, -this might also displease the owners of the page, -who could argue that such a change constitutes a copyright infringement. -We think that merely failing to allow an included graphic to be accessed -would probably not be considered an infringement: -after all this is what happens when a browser -is configured not to load images automatically. -However, we are -not -lawyers, -so anyone in doubt should take appropriate advice. -

    -In a context where the copyright issue is resolved -satisfactorily, -a proxy could simply return a status 301 or 302 and -specify a replacement -URL -in a -Location -and/or -URI -header. -An alternative would be to use inline code to return a -1 x 1 clear -GIF. -We do not publish sample code for this, -and we have no way of stopping -others -who have. -

    - -

    <Feedback>  -Why not block banners based on the dimensions of the image? -

    -

    -Many users have pointed out that most banner ads come in standard sizes, -so why not block all -GIFs -of those sizes? -This would theoretically be without fetching the object -because the dimensions are usually given in the -IMG -tag, -but it would require substantial changes in the code, -and we doubt whether it would be much more effective than a good block list. -

    - -

    <Feedback>  -What about non-graphic advertising within the pages I want? -

    -

    -The -Internet Junkbuster -deliberately -does not provide a way of automatically editing the contents of a page, -to remove textual advertising or -to repair the holes left by blocked banners. -Other packages such as -WebFilter -do. -

    -For the same reason, -it has no way of stopping a new browser -window being created, because this is done through the -target -attribute in the -<a> -and -<base> -elements, -not through headers. -Nor do we plan to add a feature to -paralyze animated -GIFs. -

    - -

    <Feedback>  -Does it block ads on the broadcasting ``push'' systems? How about pop-up ads? -

    -

    -We haven't tried it but we expect it would probably -work on image ads on push channels. -See also -adchoice. -

    -Disabling -Javascript -stops some pop-up ads. -One problem is that some advertisers throw open a new -browser window to frame the ad. The ad is easily blocked, -but the empty window remains. You can kill it easily, but this is a chore. -We don't see how to stop them other than editing the -HTML -from the parent window, which we -don't -like to do. -

    -The -TBTF -newsletter warned subscribers to push information that -in IE4, -LOGTARGET -allows -servers to determine the -URLs -viewed at their site even if accessed from cache or through a proxy. -If you use this browser see our instructions on -how to disable -this. -

    -If you find you have experience using the proxy with push, -or have any other advice about it, please -tell us. -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Cookies - -

    -
    -
    For background information on cookies see our -page describing their dangers. - -

    <Feedback>  -Might some cookies still get through? How can I stop them? -

    -

    -Yes, you should expect the occasional cookie to make it through to your browser. -We know of at least three ways this can happen; -please -tell us -if you find any others. -One way is in secure documents, which are explained -below. -

    -A -few -sites set cookies using a line such as -<META HTTP-EQUIV="Set-Cookie" CONTENT="flavor=chocolate"> -in the -HEAD -section of an -HTML -document. -Cookies can also be - -set and read -in -JavaScript. -To see if this is happening in a document, -view its source, look in the -head -for a section tagged -script language="JavaScript". -If it contains a reference to -document.cookie, -the page can manipulate your cookie file without sending any cookie headers. -The -Internet Junkbuster -does not tamper with these methods. -Fortunately they are rarely used at the moment. -If a cookie gets set, it should be stopped -by the proxy on its way back to the server when a page is requested, -but it can still be read in Javascript. -bu -

    -To prevent cookies breaking through, -always -keep -cookie alerts -turned on in your browser, -and -disable -Java and Javascript. -Making the files -hard to write -may also help. -

    - -

    <Feedback>  -Exactly how do cookies get created and stored anyway? -

    -

    -When a web site's server sends you a page it also sends -certain ``header information'' which your browser records but does not display. -One of these is a -Set-Cookie -header, which specifies the cookie information that the server wants your browser to record. -Similarly, when your browser requests a page it also sends headers, specifying -information such as the graphics formats it understands. -If a cookie has previously been set by a site that matches the -URL -it is about to request, -your browser adds a -Cookie -header quoting the previous information. -

    -For more background information on how cookies -can damage your privacy, see our -page on cookies. -For highly detailed technical information see the -RFC. -The -Internet Junkbuster -will show you all headers you use the -debug -8 -option, -or you can get a sample from our -demonstration page. -

    - -

    <Feedback>  -If cookies can't get through, will some things stop working for me? -

    -

    -Possibly. -Some personalized services including certain - -chat -rooms -require cookies. -Newspapers that require - -registration -or - -subscription -will not automatically recognize you if you don't send them the cookie they -assigned you. And there are a very small number of sites that do -strange things with cookies; they don't work for anyone that blocks -cookies by any means. -Some sites such as -Microsoft -explain that their content is so wonderfully compelling that -they will withhold it from you unless you submit to their -inserting cookies. -

    -If you want such sites to be given your cookies, -you can use the -cookiefile -option provided you are running -Version 1.2 or later -yourself. -Simply include the domain name of those sites in the -cookiefile -specified by this option. -If it still doesn't work, -the problem may be in -other headers. -

    -It's possible to let cookies out but not in, -which is enough to keep some sites happy, but not all of them: -one newspaper site seems to go into an endless frenzy -if deprived of fresh cookies. -A cookiefile containing -a single line consisting of the two characters ->* -(greater-than and star) permits server-bound cookies only. -The -* -is a -wildcard -that matches all domains. -

    -If someone else is running the -Internet Junkbuster -for you and has a version -that - -passes server-bound cookies through, -you can try editing your browser's cookie -file to contain just the ones you want, -and restart your browser. -To subscribe to a new service like this -after you have started using the -Internet Junkbuster, -you can try the following: -tell your browser to -stop using -the -Internet Junkbuster, -fill out and submit your subscription details -(allowing that web site to set a cookie), -then -reconfigure your browser to use the -Internet Junkbuster -again -(and stop more cookies being sent). -This also requires the -cookiefile -option, -and its success depends on the Web site -not wanting to change your cookies at every session. -For this reason it does not work at some major newspaper sites, for example. -But you may prefer to -look at whether other sites provide the same -or better services without demanding the opportunity -to track your behavior. -The web is a buyer's market where most prices are zero: -very few people pay -for content with money, so why should you pay with your privacy? -

    - -

    <Feedback>  -Can I control cookies on a per-site basis? -

    -

    -Yes, since version 1.2 the -Internet Junkbuster -has included advanced cookie management facilities. -Unless you specify otherwise, -cookies are discarded (``crumbled'') by the -Internet Junkbuster -whether they came from the server or the browser. -In Version 1.2 and later you can -use the -cookiefile -option -to specify when cookies are to be passed through intact. -It uses the same syntax and -matching -algorithm as the blockfile. -

    -If the -URL -matches a pattern in the -cookiefile -then cookies are let through in both the browser's request for the -URL -and in the server's response. -One-way permissions can be -specified by starting the line with the -> -or -< -character. -For example, a cookiefile consisting of the four lines -
    -   org -
    -   >send-user-cookies.org -
    -   <accept-server-cookies.org -
    -   ~block-all-cookies.org -
    -allows cookies to and from -.org -domains only, with the following exceptions: -

      -
    1. -Cookies sent from servers in the domain -send-user-cookies.org -are blocked on their way to the client, -but cookies sent by the browser to that domain are still be fed to them. -
    2. -The cookies of -accept-server-cookies.org -check in to the proxy and are passed through to the browser, -but when they come back to the proxy they never check out. -
    3. -All cookies to and from -block-all-cookies.org -are blocked. -
    -

    -If -the -junkbuster -was compiled with the regular expressions option -they may be used in paths. -Any logging to a -``cookie jar'' -is separate and not affected. -

    -It's important to give hosts you want to be able -to set cookies sufficient breadth. For example, -instead of -www.yahoo.com -use -yahoo.com -because the company uses many different hosts ending in that domain. -

    - -

    <Feedback>  -Can I make up my own fake cookies (wafers) to feed to servers? -

    -

    -Yes, -using the -wafer -option. -We coined the term -wafer -to describe cookies chosen by a user, -not the Web server. -Servers may not find wafers as tasty as the cookies -they make themselves. -But users may enjoy controlling servers' diets for various reasons, -such as the following. -

      -
    • -Users who consider cookies to -be an unwelcome intrusion and a waste -of their disk space can respond in kind. -By writing ``signature wafers'' they can -express their feelings about cookies, -in a place that the people -in charge of them are most likely to notice. -
    • -Sites running a proxy -that logs cookies to a file -(such as the -Internet Junkbuster -does with the -jarfile -option on) -may want to notify -servers that their cookies are being intercepted, -deleted or copied. -One possible reason for doing this is the uncertain copyright status -of cookie strings. -Nothing -here should be taken as legal advice: we are simply raising a question -for any interested parties to consider, -and make no representation that such measures are necessary or sufficient. -Concerned proxy sites might decide to send a wafer -(named ``NOTICE'' for example) -containing text along the lines of the following. -
      -

      -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. -
      -

      -Any company that tries to argue in court that the proxy site -was breaching their copyright in the cookies would -be met with the defense that the proxy site gave that company -the opportunity to protect its copyright by simply -not sending cookies after receiving the notice. -

      -Cookies can be as long as four thousand characters, -so there's plenty of space for lawyerly verbosity, -but white space, commas, and semi-colons are -prohibited. -Spaces can be turned into underscores. -Alternatively, -a -URL -could be sent as the cookie value, -pointing to a document containing a notice, -perhaps with a suggestive value such as -
      -http://www.junkbusters.com/ht/en/ijbfaq.html#licenses_on_cookies_refused -
      -But including the notice directly would probably be preferable -because the addressee does not have to look it up. -

      -The -Internet Junkbuster 2.0 -currently sends a full notice as a -``vanilla wafer'' -if cookies are being logged to a cookie jar -and no other wafers have been specified. -It can be suppressed with the -suppress-vanilla-wafer -option, -which might be used in situations where there is an established understanding -between the proxy and all who serve it. -

    -

    -Junkbusters provides a -CGI -script that lets you -see -your wafers as they appear to servers. -

    -Wafers confuse a few fragile servers. -If this troubles you, don't use this option. -

    -Any wafers specified are sent to -all sites regardless of the cookiefile. -They are appended after any genuine cookies, -to maintain compliance with -RFC 2109 -in the event that a path was specified for a cookie. -The -RFC's provisions regarding the -$ -character -(such as the -Version -attribute) -are transparent -to the proxy; it simply quotes what was recited by the browser. -

    -If you want to send wafers only to specific sites, -you could try putting them your browser's cookie file in a format -conforming to the Netscape -specification, -and then specify in the proxy's cookiefile that cookies are to be -sent to -but not accepted from those sites, so they can't overwrite the file. -This may work with Netscape but not all other browsers. -

    - -

    <Feedback>  -Why would anyone want to save their cookies in a ``cookie jar?'' -

    -

    -We provided this capability just in case anyone wants it. -There are a few possible reasons. -

      -
    • -It's conceivable that -marketing companies might one day -buy -history files and cookie jars from consumers -in the same way that they currently pay them to fill out survey forms. -With this information they could -gather psychographic information, -see which competitors' sites the consumer has visited, -and discover what advertising is being targeted at them. -
    • -Some consumers might -employ semi-automated means of sorting through -their cookie jars, selecting which ones to place in their cookies -file for use by their browsers. -Their decisions could be based on payments offered, -privacy rating systems such as -TRUSTe -proposes, -or their own opinion of the company. -It could be done manually or with software. -
    • -Users may even start ``sharing'' cookies among themselves, -sending back cookies that servers generated for other visitors. -Servers that aren't expecting this possibility -will be misled about their visitors' identities. -Cookies could be shared among users on a single machine, -or across continents via -FTP -and anonymous remailers. -Privacy activists may promote -cookie disinformation campaigns -as a way to defend the public against abuse. -If a significant percentage of people send disinformative cookies, -user tracking via cookies may become less reliable and less used. -
    -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Anonymity - -

    -
    -
    For details -on how your identity can be revealed while you surf, -see our page on -privacy. -Once you start using -the -Internet Junkbuster -you should find that much of the information -previously indicated on that page will no longer be provided. -If the -REMOTE HOST -indicating your IP address is too close for comfort, -see our suggestions -below -on how to -conceal -your IP address. -We also recommend that you -disable JavaScript -and -Java. - -

    <Feedback>  -If I use the Internet Junkbuster, will my anonymity be guaranteed? -

    -

    -No. Your chances of remaining anonymous are 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 attributed to you personally. -

    -The -Internet Junkbuster -removes various information about you, -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. -The -Internet Junkbuster 2.0 -does not filter the -FTP -stream. -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 downloaded 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. -

    - -

    <Feedback>  -Why should I trust my ISP or Junkbusters with my browsing data? -

    -

    -You shouldn't have to trust us, and you certainly don't have to. -We do not run the proxy as a service, -where we could observe your online behavior. -We provide source code so that everyone can see that the proxy isn't -doing anything sneaky. -

    -You are already trusting your -ISP -not to look at an awful lot of information on what you do. -They probably post a -privacy policy -on their site to reassure you. -If they run a proxy for you, using it could actually -make it slightly easier for them to monitor you, -but we doubt that any sane -ISP -would try this, -because if it were discovered customers would desert them. -

    - -

    <Feedback>  -What private information from server-bound headers is removed? -

    -

    -The -Internet Junkbuster -pounces on the following -HTTP -headers in requests to servers, -unless instructed otherwise in the options. -

      -
    • -The -FROM -header, -which a few browsers use to tell your email address to servers, -is dropped -unless the -from -option is set. -
    • -The -USER_AGENT -header -is changed to indicate that the browser is -currently Mozilla (Netscape) 3.01 Gold -with an unremarkable Macintosh configuration. -Misidentification helps resist certain -attacks. -If your browser and hardware happen to be accurately identified, -you might want to change the default. -(Earlier versions of the -Internet Junkbuster -indicated different details; -by altering them periodically we aim to hinder anyone trying to -infer -whether our proxy is present.) -If you don't like the idea -of incorrectly identifying your computer as a Mac, -set it accordingly. - -
    • -The -REFERER -header -(which indicates where the -URL -currently being requested was found) -is dropped. -A single static referer to replace all -real referers may be specified using the -referer -option. -Where no referer is provided by the browser, none is added; -the -add-header -option with arguments such as --x 'Referer: http://me.me.me' -can be used to send a bogus referer with every request. -
    -In -Version 1.4 -and later you can use the --r @ -option to selectively disclose -REFERER -and -USER_AGENT -to only those sites you nominate. -

    -Some browsers -send Referer and User-Agent information under different non-standard headers. -The -Internet Junkbuster 2.0 -stops -UA -headers, -but others may get through. -This information is also available via JavaScript, -so -disable disable -it. -Some search engines -encode the query you typed -in the -URL -that goes to advertisers to target a banner ad at you, -so you will need to block the ad as well as the referer header, -unless you want them (and anyone they might -buy data -from) -to know -everything you ever search for. -

    -If you have JavaScript enabled (the default on -most browsers) servers can use it to obtain Referer and User Agent, -as well as your plug-ins. -We recommend -disabling -JavaScript and Java. -

    -Currently no -HTTP -response headers (browser bound) -are removed, -not even the -Forwarded: -or -X-Forwarded-For: -headers. -Nor are any added, -unless requested. -We are considering a more flexible header management system for -a future version. -

    - -

    <Feedback>  -Might some things break because header information is changed? -

    -

    -Possibly. If used with a browser less advanced than Netscape 3.0 or IE-3, -indicating an advanced browser -may encourage pages containing extensions that confuse your browser. -If this becomes a problem -upgrade your browser or -use the -user-agent -option to indicate an -older browser. -In -Version 1.4 -and later you can selectively reveal your real browser -to only those sites you nominate. -

    -Because different browsers -use different encodings of Russian 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 Russian sites to be garbled; -Russian surfers should -change it -to something closer. -

    -Some -page access counters -work by looking at the referer; -they may fail or break when deprived. -

    -Some sites depend on getting a referer header, -such as -uclick.com, -which serves comic strips -for many newspaper sites, -including -Doonsbury -for the -Washington Post. -(If you click on that last link, you can then get to a page containing -the strip via the -same -URL -we've linked to under -Doonsbury, -but if you click on the -Doonsbury -link directly, it gives you an error message suggesting that you -use a browser that supports referers.) -In -Version 1.4 -and later you can use the --r @ -option -and place a line like ->uclick.com -in your cookiefile. -Wired News -used to use referer to decide whether to add a navigation column to -the page, but they have changed that. -

    -The weather maps of -Intellicast -have been blocked by their server when no referer or cookie is provided. -You can use the same countermeasure with a line such as ->208.194.150.32 -(or simply get your weather information -elsewhere). -

    -Some software vendors, including -Intuit -use -USER_AGENT -to decide which versions of their products to display to you. -With the -default -you get Mac versions. -

    -As a last resort if a site you need doesn't seem to be working, -the -proxy configuration -of many browsers allow you to specify - -No Proxy For -any hostname you want. -

    -We had reports that on some versions of Netscape the -What's New -feature did not work with the proxy, -but we think we fixed this in Version 2.0.1. -

    - -

    <Feedback>  -How is misidentifying my browser good for security and privacy? -

    -

    -Almost -every -major release of both leading browsers has contained -bugs that allow malicious servers to compromise your privacy and security. -Known bugs are quickly fixed, but millions of copies of the affected -software remain out there, and yours is probably one of them. -The -header -that normally identifies your browser tells such servers exactly which attacks -to use against you. -By misidentifying your browser you reduce the likelihood that they -will be able to mount a successful attack. -

    - -

    <Feedback>  -Does the Internet Junkbuster conceal my IP address? -

    -

    -Web sites get the IP address of any proxy or browser they serve pages to. -If you run the proxy on your own computer the IP address disclosed -is the same as your browser would, unless you use the -forwardfile -option is used to chain to another proxy, -in which case servers only get the last IP address in the chain. -Chaining slightly slows browsing of course, but it improves anonymity. -

    -One public proxy that you can -forward to is -lpwa.com -port 8000. -Read about its privacy-enhancing -features and the authentication procedures first, -and note that it blocks -referer -in almost all cases, -as well as some -other headers. -

    - -

    <Feedback>  -How can I set the proxy to remember my LPWA password? -

    -

    -After you log in to -LPWA -it tells your browser to send a -Proxy-authorization -header with each request. -Whenever you shut down the browser and start again with a new browser, -you need to log in again. -If you are the only person using the -Internet Junkbuster -proxy, you can avoid repeated logins to -LPWA -by telling the -Internet Junkbuster -to send the information by placing a line such as -
    -   add-header Proxy-authorization: Basic ZHVtbXk=. -
    -in the configuration file. -The exact example above -does not work -because the code -ZHVtbXk=. -is a bogus one that -LPWA -would never generate; -follow the procedure below to generate a valid one. -

      -
    1. -Restart your -Internet Junkbuster -with -debug 8 -so you can see the -headers. -
    2. -Log in to -LPWA -and go to any other site. -
    3. -Find the -Proxy-authorization -header from the debug output and paste it -after the word -add-header -into the config file. -Also change the debug value back again. -
    4. -Shut down your browser, start it up again, and -restart the proxy. Test that it works. -
    -This trick is convenient for sole users, but is not suitable when -more than one person uses the proxy, because they will all get the -same -LPWA -identity. -

    - -

    <Feedback>  -Does the Internet Junkbuster thwart identification by identd? -

    -

    -We think so, -provided you are not the user running the -proxy. -If your computer (or your -ISP's) -is running the -identd -demon, -servers can ask it for the identity of the -user making the request at time you request a page from them. -But if you're going through a proxy, -they will identify the user name associated with the proxy, not you. -A visit to -http://ident.junkbusters.com -lets you see what's happening. -This test is (quite rightly) blocked by many -firewalls; -just interrupt the transfer if you get an abnormal wait after clicking. -Running other applications -may also expose you via -identd; -the proxy of course doesn't help then. -

    - -

    <Feedback>  -Can web sites tell that I'm using the Internet Junkbuster? -

    -

    -With the default options the proxy doesn't announce itself. -Obvious indications such as -Keep-Alive -headers are -deleted, -but sites might notice that you can cancel cookies faster than -any human could possibly click on a mouse. -(If you want to provide a -plausible explanation for this, -change the User Agent header to a -cookie-free -or -cookie-crunching -browser). -

    -But when certain options -are used they could figure out something's going on, -even if they're not pushing cookies. -If you use blocking -they can tell from their logs that the graphics in their pages -are not being requested selectively. -The -add-forwarded-header -option explicitly announces to the server that a proxy is present, -and -sending them -wafers -is of course a dead giveaway. -

    -

    --- Back to Top of Page ---

    -
    -
    -

    -Security - -

    -
    -
    -

    <Feedback>  -What happens with Secure Documents (SSL, https:)? -

    -

    -If you enter a -``Secure Document Area,'' -cookies and other header information -such as User Agent and Referer -are sent encrypted, -so they cannot be filtered. -We recommend getting your browser to alert you when this happens. -(On Netscape: - -Options; - -Security; - -General; - -Show an alert before entering a secure document space.) -We also recommend adding the line -:443 -to the blockfile to stop all but sites specified in an exception -after that line from using SSL. -

    -It may be possible to filter encrypted cookies -by combining the blocking proxy with a cryptographic proxy along -the lines of -SafePassage, -but we have not tried this. -

    - -

    <Feedback>  -Will using this as my Security Proxy compromise security? -

    -

    -We're not security experts, but we don't think so. -The whole point of -SSL -is that the -contents of messages are - -encrypted -by the time -they leave the browser and the server. -Eavesdroppers (including proxies) can see where your messages are going -whether you are running a proxy or not, -but they only get to see the contents after they have been encrypted. -

    - -

    <Feedback>  -Can I restrict use of the proxy to a set of nominated IP addresses? -

    -

    -Yes, we added an -access control -file in Version 2.0. -But before you use it please consider why you want to do it. -If the reason is security, -it probably means you need a firewall. -

    -The -listen-address -option provides a way of binding the proxy to a single IP address/port. -The right way to do this is to choose a port inside your firewall, and -deny access to it to those outside the firewall. -The -Internet Junkbuster -is not a firewall proxy; -it should not be expected to solve security problems. -

    -For background information on firewalls, -see -Yahoo -or a -magazine article -or these well-known books: -Firewalls and Internet Security: Repelling the Wily Hacker -by -William R. Cheswick -and -Steven M. Bellovin -or -Building Internet Firewalls -by -D. Brent Chapman -and -Elizabeth D. Zwicky. -There's - -free Linux software -available, -and a large number of -commercial -products and services. -For an excellent security overview, primer, and compendium reference, see -Practical Unix and Internet Security -by -Simson Garfinkel -and -Gene Spafford. -

    - -

    <Feedback>  -Are there any security risks for ISPs or others who offer the proxy? -

    -

    -Yes. -As with any service offered over the Internet, -hackers can try to misuse it. -A well-run -ISP -will have professionals who are experienced at assessing and containing -these risks. -

    -It's possible to set up your machine so -that other people can have access to your proxy, -but if you lack expertise in computer security -you probably shouldn't have your computer configured to offer -this or any other service to the outside world. -

    -Hackers can attempt to gain access -to the machine by various attacks, -which we have tried to guard against but don't guarantee to thwart. -They can also use the ``anonymizing'' quality of proxies -to try to cover their tracks while hacking other computers. -For this reason we recommend preventing it being used -as an anonymous -telnet -by putting the pattern -:23 -in the blockfile (it's included as standard equipment). -(Actually the current implementation incidentally blocks telnet due to the -way headers are handled, but it's best not to rely on this.) -If you wish to block all ports except the default -HTTP -port 80, -you can put the lines -
    -   : -
    -   ~:80 -
    -at the beginning of the blockfile, but be aware that some servers -run on non-default ports (e.g. 8080). You might also want to add the line -~:443 -to allow -SSL. -

    -On -UNIX ® -systems it is neither necessary nor desirable for the proxy to run as root. -

    -Versions 2.0.1 and below may be vulnerable to remote -exploitation of a memory buffer bug; for security reasons all users -are encouraged to -upgrade. -

    -If you find any security holes in the code -please -tell us, -along with any suggestions you may have for fixing it. -However, we do not claim that we will be able to do so. -

    -We distribute this code in the hope that people -will find it useful, but we provide -no warranty -for it, -and we are not responsible for anyone's use or misuse of it. -

    -You may also want to check back periodically for updated versions of the code. -We do not -maintain a mailing list. -To get quick updates, bookmark our -Distribution Information -page. -

    -

    --- Back to Top of Page ---

    - -Home - · - - - · Site Map - - · Legal - - · Privacy - - · Cookies - - · Banner Ads - - · Telemarketing - - · Mail - - · Spam - -
    - -
    - - -

    -Copyright © 1996-8 Junkbusters -® Corporation. -Copying and distribution permitted under -the GNU -General Public License. - - -1998/10/31 -http://www.junkbusters.com/ht/en/ijbfaq.html - -

    webmaster@junkbusters.com
    -
    - - diff --git a/doc/ijbman.html b/doc/ijbman.html deleted file mode 100644 index 710cddb0..00000000 --- a/doc/ijbman.html +++ /dev/null @@ -1,920 +0,0 @@ - - - - - - - - - - - - -Internet Junkbuster Technical Information - - - - - - - - - -
    -

    Internet JUNKBUSTER Technical Information -

    -
    - -

    -Options - - · Checking Options - - · Installation - - · Copyright - - · (FAQ) -

    -

    -
    -

    -Manual Page - -

    -
    -
    A copy of this page -in standard -man -macro format -is included in the -tar archive. - -

    <Feedback>  -Name -

    -

    -junkbuster -- The -Internet Junkbuster -Proxy -TM -

    - -

    <Feedback>  -Synopsis -

    -

    -junkbuster -configfile -(Version 2.0 onwards) -
    -junkbstr.exe -configfile -(Windows) -
    -junkbuster -[-a] -[-y] -[-s] -[-c] -[-v] -
    -[-u user_agent] -[-r referer] -[-t from] -
    -[-b blockfile] -[-j jarfile] -[-l logfile] -
    -[-w NAME=VALUE] -[-x Header_text] -
    -[-h [bind_host_address][:bind_port]] -
    -[-f forward_host[:port]] -[-d N] -
    -[-g gw_protocol[:[gw_host][:gw_port]]] -
    -(Version 1.4 and earlier) -

    - -

    <Feedback>  -Description -

    -

    -junkbuster -is an instrumentable proxy that filters the -HTTP -stream between -web servers and browsers. -Its main purpose is to enhance privacy. -

    -Versions before 2.0 used command-line options; -Versions from 2.0 onward use a configuration file. -The following descriptions of the options first give the older -command-line usage, then the new configfile line. -

    -In Versions 2.0.1 upwards on Windows, -a start-up message is printed and the configuration is read from the file -junkbstr.ini -if it exists and no argument was given. -

    -All files except the configfile -are checked for changes before each page is fetched, -so they may edited without restarting the proxy. -

    Options -

    -

    -b blockfile
    blockfile  blockfile
    -Block -requests to -URLs -matching any pattern given in the lines of the -blockfile. -The -junkbuster -instead returns status 202, indicating that the request has been accepted -(though not completed), -and a -message identifying itself -(though the browser may -display only a broken image icon). -(Versions before 2.0 returned an error 403 (Forbidden).) -The syntax of a pattern is -[domain][:port][/path] -(the -http:// -or -https:// -protocol part is omitted). -To decide if a pattern matches a target, the domains are compared first, -then the paths. -

    -To compare the domains, -the pattern domain and the target -domain specified in the -URL -are each broken into their components. -(Components are separated by the -. -(period) character.) -Next each of the target components -is compared with the corresponding pattern component: last with last, -next-to-last with next-to-last, and so on. -(This is called -right-anchored -matching.) -If all of the pattern components find their match in the target, -then the domains are considered a match. -Case is irrelevant when comparing domain components. -

    -A successfully -matching pattern can be an anchored substring of a target, but -not vice versa. -Thus if a pattern doesn't specify a domain, -it matches all domains. -Furthermore, when comparing two components, -the components must either match in their entirety or up to a wildcard -* -(star character) in the pattern. The wildcard feature -implements only a "prefix" match capability ("abc*" vs. "abcdefg"), -not suffix matching ("*efg" vs. "abcdefg") or -infix matching ("abc*efg" vs. "abcdefg"). -The feature is restricted to the domain component; -it is unrelated to the optional -regular expression -feature in the path -(described below). -

    -If a numeric port -is specified in the pattern domain, then the target port must -match as well. The default port in a target is port 80. -

    -If the domain and port match, -then the target -URL -path is checked for -a match against the path in the pattern. -Paths are compared with a simple case-sensitive -left-anchored substring comparison. -Once again, the pattern can be an -anchored substring of the target, but not vice versa. -A path of -/ -(slash) would match all paths. Wildcards are not considered in -path comparisons. -

    -For example, the target -URL -
    -   the.yellow-brick-road.com/TinMan/has_no_brain -
    -would be matched (and blocked) by the following patterns -
    -   yellow-brick-road.com -
    -and -
    -   Yellow*.COM -
    -and -
    -   /TinM -
    -but not -
    -   follow.the.yellow-brick-road.com -
    -or -
    -   /tinman -
    -

    -Comments in a blockfile start with a -# -(hash) character and end at a new line. -Blank lines are also ignored. -

    -Lines beginning with a -~ -(tilde) character are taken to be -exceptions: -a -URL -blocked by previous patterns that matches the rest of -the line is let through. (The last match wins.) -

    -Patterns -may contain -POSIX -regular expressions -provided the -junkbuster -was compiled with this option -(the default in Version 2.0 on). -The idiom -/*.*/ad -can then be used -to match any -URL -containing -/ad -(such as -http://nomatterwhere.com/images/advert/g3487.gif -for example). -These expressions -don't work -in the domain part. -

    -In version 1.3 and later -the blockfile and cookiefile are checked for changes before each request. -

    -w NAME=VALUE
    wafer  NAME=VALUE
    -Specifies a pair to be sent as a cookie with every request -to the server. -(Such boring cookies are called -wafers.) -This option may be called more than once to generate multiple wafers. -The original -Netscape specification -prohibited -semi-colons, commas and white space; -these characters will be -URL-encoded -if used in wafers. - - -The Path and Domain attributes are not currently supported. -

    -c cookiefile
    cookiefile  cookiefile
    -Enforce the cookie management policy specified in the -cookiefile. -If this option is not used all cookies are silently crunched, -so that users who never want cookies aren't bothered by browsers -asking whether each cookie should be accepted. -However, cookies can -still get through -via -JavaScript -and -SSL, -so alerts should be left on. -

    -In Version 1.2 and later -this option must be followed by a -filename -containing instructions on which sites are allowed to -receive and set cookies. -By default cookies are dropped in both the browser's request -and the server's response, unless the -URL -requested matches an entry in the -cookiefile. -The matching algorithm is the same as for the blockfile. -A leading -> -character allows -server-bound -cookies only; -a -< -allows only browser-bound cookies; -a -~ -character stops cookies in -both directions. -Thus a cookiefile containing a single line with the two characters ->* -will pass on all cookies to servers but not give any new ones to the browser. -

    -j jarfile
    jarfile  jarfile
    -All Set-cookie attempts by the server are -logged -to -jarfile. -If no wafer is specified, -one containing a -canned notice -(the -vanilla wafer) -is added as an alert to the server -unless the -suppress-vanilla-wafer - -option is invoked. -

    -v
    suppress-vanilla-wafer
    -Suppress the vanilla wafer. -

    -t from
    from  from
    -If the browser -discloses an email address -in the -FROM -header (most don't), -replace it with -from. -If -from -is set to -. -(the period character) -the -FROM -is passed to the server unchanged. -The default is to delete the -FROM -header. -

    -r referer
    referer  referer
    -Whenever the browser discloses the -URL -that -led to -the current request, -replace it with -referer. -If -referer -is set to -. -(period) -the -URL -is passed to the server unchanged. -In -Version 1.4 -and later, if referer is set to -@ -(at) the -URL -is sent in cases where the cookiefile -specifies that a cookie would be sent. -(No way to send bogus referers selectively is provided.) -The default is to delete Referer. -

    -Version 2.0 also accepts the spelling -referrer, -which most dictionaries consider correct. -

    -u user-agent
    user-agent  user-agent
    -Information disclosed by the browser -about itself -is replaced with the value -user-agent. -If -user-agent -is set to -. -(period) -the -User-Agent -header is passed to the server unchanged, -along with any -UA -headers produced by -MS-IE -(which would otherwise be deleted). -In -Version 1.4 -and later, if -user-agent -is set to -@ -(at) these headers are sent unchanged in cases where the cookiefile -specifies that a cookie would be sent, -otherwise only default -User-Agent -header is sent. -That default -is Mozilla/3.0 (Netscape) -with an unremarkable -Macintosh -configuration. -If used with a browser less advanced than Mozilla/3.0 or IE-3, the default -may encourage pages containing extensions that confuse the browser. - -

    -h [host][:port]
    listen-address  [host][:port]
    -If -host -is specified, -bind the -junkbuster -to that -IP -address. -If a -port -is specified, use it. -The default -port -is 8000; -the default host is -localhost. -Before Version 2.0.2, -the default was to bind to all -IP -addresses -(INADDR_ANY); -but this has been restricted to -localhost -to avoid unintended security breaches. -(To open the proxy to all, use the line -
    -   listen-address :8000 -
    -in the configuration file.) -

    -f forward_host[:port]
    forwardfile  forwardfile
    -Version 1.X required all -HTTP -requests from the client to be forwarded to the same destination. -Version 2.0 takes its routing specification from a -forwardfile, -allowing selection of the proxy (a.k.a. forwarding host) and gateway -according to the -URL. -Here is a typical line. -
    -
    -*         lpwa.com:8000      .      .
    -
    -

    -Each line contains four fields: -target, -forward_to, -via_gateway_type -and -gateway. -As usual, the -last -target -domain that matches the requested -URL -wins, -and the -* -character alone matches any domain. -The target domain need not be a fully qualified -hostname; it can be a general domain such as -com -or -co.uk -or even just a port number. -For example, because -LPWA -does not handle -SSL, -the line above will typically be followed by a line such as -
    -

    -:443  .      .      .
    -
    -to allow SSL transactions to proceed directly. -The cautious would also -add an entry in their blockfile to stop transactions -to port 443 for all but specified trusted sites. -

    -If the winning -forward_to -field is -. -(the dot character) the proxy connects -directly to the server given in the -URL, -otherwise it forwards to the host and port number specified. -The default port is 8000. -The -via_gateway_type -and -gateway -fields also use a dot to indicate no gateway protocol. -The gateway protocols are explained -below. -

    -The example line above in a forwardfile alone -would send everything through port 8000 at -lpwa.com -with no gateway protocol, -and is equivalent to the old --f lpwa.com:8000 -with no --g -option. -For more information see the example file provided with the distribution. -

    -Configure with care: no loop detection is performed. -When setting up chains of proxies that might loop back, try adding -Squid. -

    -g gw_protocol[:[gw_host][:gw_port]]
    -Use -gw_protocol -as the gateway protocol. -This option was introduced in Version 1.4, -but was folded into the -forwardfile -option in Version 2.0. -The default is to use no gateway protocol; -this may be explicitly specified as -direct -on the command line -or the dot character in the forwardfile. -The -SOCKS4 -protocol may be specified as -socks -or -socks4. -The -SOCKS4A -protocol is specified as -socks4a. -The -SOCKS5 -protocol is not currently supported. -The default -SOCKS -gw_port -is 1080. -

    -The user's browser should -not -be -configured -to use -SOCKS; -the proxy conducts the negotiations, not the browser. -

    -The user identification capabilities of -SOCKS4 -are deliberately not used; -the user is always identified to the -SOCKS -server as -userid=anonymous. -If the server's policy is to reject requests from -anonymous, -the proxy will not work. -Use a -debug -value of 3 -to see the status returned by the server. -

    -d N
    debug  N
    -Set debug mode. -The most common value is 1, -to -pinpoint -offensive -URLs, -so they can be added to the blockfile. -The value of -N -is a bitwise -logical-OR -of the following values: -
    -1 = URLs (show each URL requested by the browser);
    -2 = Connections (show each connection to or from the proxy);
    -4 = I/O (log I/O errors);
    -8 = Headers (as each header is scanned, show the header and what is done to it);
    -16 = Log everything (including debugging traces and the contents of the pages).
    -Multiple -debug -lines are permitted; they are logical OR-ed together. -

    -Because most browsers send several requests in parallel -the debugging output may appear intermingled, so the -single-threaded -option is recommended when using -debug -with -N -greater than 1. - -

    -y
    add-forwarded-header
    -Add -X-Forwarded-For -headers to the server-bound -HTTP -stream -indicating the client -IP -address -to the server, -in the new style of -Squid 1.1.4. -If you want the traditional -HTTP_FORWARDED -response header, add it manually with the --x -option. - -

    -x HeaderText
    add-header  HeaderText
    -Add the -HeaderText -verbatim to requests to the server. -Typical uses include -adding old-style forwarding notices such as -Forwarded: by http://pro-privacy-isp.net -and reinstating the -Proxy-Connection: Keep-Alive -header -(which the -junkbuster -deletes so as -not -to reveal its existence). -No checking is done for correctness or plausibility, -so it can be used to throw any old trash into the server-bound -HTTP -stream. -Please don't litter. - -

    -s
    single-threaded
    -Doesn't -fork() -a separate process -(or create a separate thread) -to handle each connection. -Useful when debugging to keep the process single threaded. -

    -l logfile
    logfile  logfile
    -Write all debugging data into -logfile. -The default -logfile -is the standard output. -


    aclfile  aclfile
    -Unless this option is used, the proxy talks to anyone who can connect to it, -and everyone who can has equal permissions on where they can go. -An access file allows restrictions to be placed on these two policies, -by distinguishing some -source -IP -addresses and/or -some -destination -addresses. -(If a -forwarder or a gateway -is being used, its address is considered the destination address, -not the ultimate -IP -address of the -URL -requested.) -

    -Each line of the access file begins with -either the word -permit -or -deny -followed by source and (optionally) destination addresses -to be matched against those of the -HTTP -request. -The last matching line specifies the result: if it was a -deny -line or if no line matched, -the request will be refused. -

    -A source or destination -can be specified as a single numeric -IP -address, -or with a hostname, provided that the host's name -can be resolved to a numeric address: this cannot be used to block all -.mil -domains for example, -because there is no single address associated with that domain name. -Either form may be followed by a slash and an integer -N, -specifying a subnet mask of -N -bits. -For example, -permit 207.153.200.72/24 -matches the entire Class-C subnet from -207.153.200.0 -through 207.153.200.255. -(A netmask of 255.255.255.0 corresponds to 24 bits of -ones in the netmask, as with -*_MASKLEN=24.) -A value of 16 would be used for a Class-B subnet. -A value of zero for -N -in the subnet mask length will cause any address to match; -this can be used to express a default rule. -For more information see the example file provided with the distribution. -

    -If you like these access controls -you should probably have -firewall; -they are not intended to replace one. -


    trustfile  trustfile
    -This feature is experimental, has not been fully documented and is -very subject to change. -The goal is for parents to be able to choose a page or site whose -links they regard suitable for their -young children -and for the proxy to allow access only to sites mentioned there. -To do this the proxy examines the -referer -variable on each page request to check they resulted from -a click on the ``trusted referer'' site: if so the referred site -is added to a list of trusted sites, so that the child can -then move around that site. -There are several uncertainties in this scheme that experience may be -able to iron out; check back in the months ahead. -


    trust_info_url  trust_info_url
    -When access is denied due to lack of a trusted referer, this -URL -is displayed with a message pointing the user to it for further information. -


    hide-console
    -In the Windows version only, instructs the program -to disconnect from and hide the command console after starting. -

    -a
    -(Obsolete) Accept the server's -Set-cookie -headers, passing them through to the browser. -This option was removed in Version 1.2 -and replaced by an improvement to the --c -option. -
    -

    - -

    <Feedback>  -Installation and Use -

    -

    -Browsers must be told where to find the -junkbuster -(e.g. -localhost -port 8000). -To set the -HTTP -proxy in Netscape 3.0, -go through: - -Options; - -Network Preferences; - -Proxies; - -Manual Proxy Configuration; - -View. -See the -FAQ -for other browsers. -The -Security Proxy -should also be set to the same values, -otherwise -shttp: -URLs -won't work. -

    -Note the limitations -explained in the -FAQ. -

    - -

    <Feedback>  -Checking Options -

    -

    -To allow users to -check -that a -junkbuster -is running and how it is configured, -it intercepts requests for any -URL -ending in -/show-proxy-args -and blocks it, -returning instead returns information on its -version number and -current configuration -including the contents of its blockfile. -To get an explicit warning that no -junkbuster -intervened if the proxy was not configured, -it's best to point it to a -URL -that does this, such as -http://internet.junkbuster.com/cgi-bin/show-proxy-args -on Junkbusters's website. -

    - -

    <Feedback>  -See Also -

    -

    -http://www.junkbusters.com/ht/en/ijbfaq.html -
    -http://www.junkbusters.com/ht/en/cookies.html -
    -http://internet.junkbuster.com/cgi-bin/show-proxy-args -
    -http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html -
    -http://squid.nlanr.net/Squid/ -
    -http://www-math.uni-paderborn.de/~axel/ -

    - -

    <Feedback>  -Copyright and GPL -

    -

    -Written and copyright by the Anonymous Coders and Junkbusters Corporation -and made available under the -GNU General Public License (GPL). -This software comes with -NO WARRANTY. -Internet Junkbuster -Proxy -is a -trademark -of Junkbusters Corporation. -

    -

    --- Back to Top of Page ---

    - -Home - · - - - · Site Map - - · Legal - - · Privacy - - · Cookies - - · Banner Ads - - · Telemarketing - - · Mail - - · Spam - -
    - -
    - - -

    -Copyright © 1996-8 Junkbusters -® Corporation. -Copying and distribution permitted under -the GNU -General Public License. - - -1998/10/31 -http://www.junkbusters.com/ht/en/ijbman.html - -

    webmaster@junkbusters.com
    -
    - - diff --git a/doc/obsolete/fb.gif b/doc/obsolete/fb.gif new file mode 100755 index 00000000..43059924 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 index 00000000..3d522479 --- /dev/null +++ b/doc/obsolete/ijbfaq.html @@ -0,0 +1,1999 @@ + + + + + + Internet Junkbuster Frequently Asked Questions + + + + + + +

    + Website · + Manual · FAQ · GPL

    + +

    Internet + JUNKBUSTER + Frequently Asked Questions

    + +

    Configuring + Browsers · + IE 5.0 · + Installation · For Companies · Blocking Ads · + Cookies · Hotmail · Children · Forwarding/Chaining + · IP + · Anonymity + · Security

    + +

    This document is out of date

    + +

    Development of JunkBuster is ongoing and this document is + no longer current. However, it may provide some assistance. If + you have problems, please use the Yahoo Groups + mailing list (which includes an archive of mail), the + SourceForge.net project page, or + see the project's home + page. Please also bear in mind that versions 2.9.x of + JunkBuster are development releases, and are not production + quality.

    + +

    The Top Ten Questions

    + +

    *  What is the Internet Junkbuster + Proxy and what does it do for me?

    + +

    The Internet Junkbuster Proxy TM + is free privacy-enhancing software that can be run on your PC + or by your ISP or company. It blocks requests for URLs + (typically banner ads) that match its blockfile. It also + deletes unauthorized cookies and other unwanted identifying + header information that is exchanged between web servers and + browsers. These headers are not normally accessible to users + (even though they may contain information that's important to + your privacy), but with the Internet Junkbuster you can see + almost anything you want and + control everything you're likely to need. Many people publish + their blockfiles to help others get started.

    + +

    *  Is there a license fee / warranty + / registration form / expiration?

    + +

    No, none of these. It's completely free of charge. + Junkbusters offers you the software to copy, use, modify and + distribute as you wish, forever, at no charge under the GNU + General Public License.

    + +

    It comes with no warranty of any + kind.

    + +

    You don't have to register, in fact + we don't even provide a way to do so: the practice of + registering software is usually just an excuse to send you + solicitations and sell your name and information about your + behavior. You are welcome to obtain and use our software as + anonymously you wish. (Your IP address will naturally be + disclosed when you download it; use anonymizing software if you + want to conceal this. We never want to be given any information + that you consider private or confidential.)

    + +

    We are often asked why we give away a + product that many would happily pay for. The answer is that we + are determined to carry out our mission: to free the world from + junk communications.

    + +

    *  Does it run on Windows? On a Mac? + On the AOL browser?

    + +

    For the latest information on availability, see the + Distribution Information page. We don't think it will ever run + on Windows 3.1. But you don't need to have it running on your + computer if you get your ISP or Systems Administrator at work + to run it.

    + +

    *  How can I get my ISP to run the + Internet Junkbuster?

    + +

    Try their sales or support department (depending on whether + you are already a customer). You might + send them email including the following URL:
    +     + http://www.junkbusters.com/ht/en/ijbfaq.html#isps
    + You could mention that many other ISPs + provide it, and that you regard it as an important part of your + decision on where to buy Internet service.

    + +

    *  Who chooses the options that + control what is blocked?

    + +

    Whoever starts the Internet Junkbuster chooses the options + and the blockfile. If your ISP runs it for you, they have to + make these decision (though some may give you a choice of + proxies, and a way to suggest new URLs to block). If you run it + on your computer, you get to choose.

    + +

    *  How do I download and run the + program on my computer?

    + +

    It depends on your platform. If you are using Windows 95 or + NT, see our separate page on installing under Windows. If you + have a C compiler and are using almost any flavor of UNIX ® + you download it, compile it, start it running, and then + configure your browser. Several precompiled packages are also + available through links in our distribution page, which lists + all available platforms.

    + +

    If you are using a platform for which we + have no current availability, you are welcome to port the code. + If you do this and you would like us to consider publishing + your ported version, please tell us.

    + +

    *  How can I tell which blockfile + and options are being used?

    + +

    Just point your browser to + http://internet.junkbuster.com/cgi-bin/show-proxy-args or to + any URL ending in show-proxy-args (even if it + doesn't exist). It needn't exist because the Internet + Junkbuster intercepts the request, blocks it, and returns in + its place information about itself. Using the URL above is + useful for checking that your browser really is going through + an Internet Junkbuster, because the junkbuster.com + server returns a warning if the request actually gets to it. + Some people set the home page of their browser to such a URL to + be sure that it is configured to use the proxy.

    + +

    If you wish to check the header + information your proxy is actually sending, a visit to + http://internet.junkbuster.com/cgi-bin/show_http_headers will + give you the more relevant ones first. You might also like to + turn the proxy off and compare the difference. (Don't forget to + turn it back on again.)

    + +

    +  My browser started giving me + ``server not responding'' messages

    + +

    Once your browser is told to use a proxy such as the + Internet Junkbuster, it thinks of it as its server for + everything, so this message means it can't talk to the proxy. + The Internet Junkbuster may not be running, or you may have + specified its proxy address incorrectly. Check that the details + you entered are correct. If you have telnet you + can try connecting to the appropriate port to see if the + Internet Junkbuster is running. If your ISP is running the + Internet Junkbuster, you may want to check with them. If you + are running it yourself under UNIX ®, try looking at a + ps ax to see if it is running. The port specified in its options should be + the same one as your browser has configured.

    + +

    *  I've got this great idea for a + new feature. Who do I tell?

    + +

    We'd be very interested to hear it, but please bear a few + things in mind.

    + +
      +
    1. Please check this FAQ to see if + we've already considered the idea, such as automatic + detection of banner ads and replacing ads with something else + such as a transparent GIF.
    2. + +
    3. Don't tell us anything you + want to keep confidential or retain some right over.
    4. + +
    5. We currently have a long wish list of + things that we may or may not do in the near future, + including a version for your favorite computer and a plug-in + version.
    6. + +
    7. If you don't want to wait you're + welcome to improve on our code, publish your version on the + Web, and tell us where to find it. Projects that are + especially welcome include a port to the Mac and extensions + for HTTP 1.1. (Meanwhile, be sure your browser is configured + not to use HTTP 1.1.)
    8. +
    + +

    *  My question isn't listed here. + Who do I ask for support?

    + +

    If you find using our free product + harder than you're used to for consumer software, there are + many commercial alternatives that you could consider.

    + +

    The answer to detailed technical questions + may be answered in manual page, or in + the source code. Also double-check this page for an answer: + using the ``find'' feature on your browser for likely keywords + may help. Our site also has a search feature.

    + +

    Many people post requests for help and + responses on Usenet.

    + +

    If your ISP is providing the Internet + Junkbuster for you, and your question is about how to use it, + check their web page before asking them.

    + +

    Even though we don't offer the kind of + support you might expect if you paid a lot of money for a + software product, you can still ask us. But before you do, + please consider whether you could ask someone closer to you. + And please be patient if we're slow to reply: we never charge + consumers for our services, so we have to subsidize consumers + with revenue from companies, and our resources are limited.

    + +

    If your company or organization would be + interested in a maintenance contract with phone and email + support, hard copy documentation and source code and + pre-compiled binaries on tape or disk, please ask us for a + quote.

    + +

    --- Back to Top of Page ---

    + +

    Configuring your browser to talk to + the Internet Junkbuster

    + +

    *  What is the proxy address of the + Internet Junkbuster?

    + +

    If you set up the Internet + Junkbuster to run on the computer you browse from (rather than + your ISP's server or some networked computer at work), 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 8000 (unless you have told + the Internet Junkbuster to run on a different port with the listen-address option). + So you when configuring your browser's proxy settings you + typically enter the word localhost in the two + boxes next to HTTP and + Secure, and the number 8000 in the two boxes + labeled to the right of those boxes. The + Internet Junkbuster does not currently handle other protocols + such as Gopher, FTP, or WAIS, so leave those setting unchanged. + Nor does it handle ICQ or Instant Messenger services.

    + +

    If your ISP or company is running the + Internet Junkbuster for you, they will tell you the address to + use. It will be the name of the computer it's running on (or + possibly its numeric IP address), plus a port number. Port 8000 + is the default, so assume this number if it is not specified. + Sometimes a colon is used to glue them together, as in + junkbuster.fictitious-pro-privacy-isp.net:8000 but with + most browsers you do not type the colon, you enter the address + and port number in separate boxes.

    + +

    *  How do I tell the browser where + to find the Internet Junkbuster?

    + +

    All current browsers can be told the address of a proxy to + use. You enter the same information in two fields in your + browser's proxy configuration screen (see list below): one for + HTTP, and one for the Secure Protocol (assuming your browser + supports SSL). If you find some information already entered for + your proxy, see the next question. Here are the menus you go + through to get to the proxy configuration settings. (We also + recommend that you disable Java, which is a separate + operation.) Make notes on the changes you make so you + know how to undo them! You will need to know what you + did in case you wish to discontinue using the proxy.

    + +
      +
    1. For Netscape 2.01, 2.02 and 3.0 + [Graphic Illustration]: Options; Network Preferences; Proxies; Manual Proxy Configuration View ; enter proxy + address details under HTTP and Security Proxy; click on OK; click + on the next OK. [Return to Windows + Installation Procedure]
      + With Netscape 2.0, follow with Options, Save Options.
      + With Netscape 4.X series, you + first have to go through Edit/Preferences. + [Graphic Illustration] Then in the frame on the left, click + on triangle pointing to the right towards the word Advanced; it will switch to a triangle pointing + down; and the words Cache, + Proxies and Disk Space appear. Click on + Proxies and the frame on the right will + display a banner saying Proxies Configure + proxies to access the Internet. Click the radio button + labeled Manual proxy configuration then + click the button labeled View; enter proxy + address details under HTTP and Security Proxy; click on OK; click + on the next OK. [Return to Windows + Installation Procedure]
    2. + +
    3. For Internet Explorer 3.0 + [Graphic Illustration]: View; Options; Connections; tick Connect through proxy server box; Settings; enter proxy address details + HTTP Box, with port number in the second box; same with + Secure; click on OK. + [Return to Windows Installation Procedure]
    4. + +
    5. For Internet Explorer 2.0: View; Options; Proxy; enter proxy address details click on OK. [Return to Windows Installation + Procedure]
    6. + +
    7. On NT for MS-IE: Control + Panel; Internet; + Advanced; Proxy.
    8. + +
    9. For MS-IE 4.0: similar to 3.0: View; Internet Options; Connection; tick Access Internet using + a proxy server box; from there we have had reports of + different versions, either click on + Advanced or Settings; enter proxy + address details HTTP Box, with port number + in the second box; same with Secure; click + on OK. Note that 4.0 has + Advanced settings to allow HTTP 1.1 through proxies; + these must be disabled because the proxy does not currently + understand HTTP 1.1. Please tell us if you see any other + differences. [Return to Windows Installation Procedure]
    10. + +
    11. For MS-IE 5.0: similar to 4.0: Tools|Internet Options from the menu bar; Connections. Select either dial-up connection + or LAN (depending on how you connect to the Internet); press + Settings; and check the Use + Proxy Server box; enter proxy address details in the HTTP Box, with port number in the second box; + same with Secure; click on + OK buttons to get out. Note: You must also uncheck the HTTP 1.1 checkboxes + at the end of the Advanced options. This + seems to have been made the default in IE 5.0. [Return to + Windows Installation Procedure]
    12. + +
    13. For Netscape's level 5 browser, we + have no information. If you do, please tell us.
    14. + +
    15. For NCSA Mosaic for Windows: Options, Preferences, Proxy; enter proxy address details under HTTP.
    16. + +
    17. For Opera: + Preferences, Proxy servers; check the + box next to HTTP; enter the server and port number in the box + on the other side; click on OK.
    18. + +
    19. For Lynx, Mosaic/X, Grail, and + W3O Arena, you can specify the proxy via environment + variables before starting the application. This will probably + be done with something like either
      +    setenv http_proxy + http://localhost:8000/
      + or
      +     + http_proxy=http://junkbuster.fictitious-pro-privacy-isp.net:8000/ + export http_proxy
      + depending on your shell and where the Internet Junkbuster + lives.
    20. +
    + +

    If your browser is not listed here, or if you notice an + error, please tell us the correct procedure.

    + +

    *  What should I do if I find + another proxy is already configured?

    + +

    Some ISPs and companies require all Web traffic to go + through their proxy. In this case you would find your proxy + configuration with values already set, possibly under Automatic Proxy Configuration (in the case of + Netscape and MS-IE 3.0 and above). It's probably a firewall + proxy between your company and the outside world, or a caching proxy if you're using an ISP.

    + +

    What needs to be done in this case is to use + the forwardfile option to + tell the Internet Junkbuster the address of the other proxy. + Specify a different (unused) port number with the listen-address option, and + configure your browser to use that port. If you haven't done + this kind of thing before, it's probably best to consult your + systems administrator or ISP about it; check their web page + first.

    + +

    +  What if I want to stop using + the Internet Junkbuster?

    + +

    Just go through the same procedure you used to start your + browser using the Internet Junkbuster, but remove the details + you put in (or if there was something there before, restore + it). You may need to use Save Options to make + this change permanent. On Netscape 3.0 you can go through Options; Network Preferences; + Proxies and click on No + Proxy to turn it off, and later click on + Manual Proxy Configuration if you want to start using it + again. (No need to enter the again details under + View as you did the first time; they should remain there + unchanged.)

    + +

    This stops your browser talking to the + proxy; shutting down the proxy is a different matter.

    + +

    *  Automatic dialing isn't working + any more. How do I fix it?

    + +

    Some browsers (such as MSIE-4) can be configured to dial + your ISP automatically when you click on a link, but this + feature (called "automatically connect" or "autoconnect") gets + disabled if you specify a proxy running on your own computer + (with address localhost or 127.0.0.1) + because these addresses don't require dialing. The Internet + Junkbuster knows nothing about dialing, so it doesn't work. To + make automatic dialing work, make up a name such as + junkbuster.ijb and use that name in the proxy settings + instead of localhost, and then add the line + 127.0.0.1 junkbuster.ijb to the file + c:\windows\hosts (if there already is a line beginning + with 127.0.0.1 just add + junkbuster.ijb at the end of it.)

    + +

    This should also work Netscape + Communicator 4 on machines where IE-4 has been installed.

    + +

    --- Back to Top of Page ---

    + +

    Setting up the Internet Junkbuster on + your local computer

    + +

    The next two sections assume you wish to compile the code + with your own C compiler. If you just + want to use the .exe file provided for Windows, + see the Windows Installation page.

    + +

    *  How do I compile the code under + Unix?

    + +

    If you are running Redhat Linux you may prefer to use the + rpm instead of the following procedure.

    + +
      +
    1. First download the tar file + (~286k) and uncompress and extract the + files from it with this command
      +    uncompress -c ijb20.tar.Z | tar xf + -
    2. + +
    3. If your operating system is from Sun or + HP examine the Makefile and make any changes + indicated inside.
    4. + +
    5. Run
      +
      +    make
    6. + +
    7. + Copy the sample configuration file + (junkbstr.ini, previously called + sconfig.txt and other names in earlier releases) to + some convenient place such as + /usr/local/lib/junkbuster/configfile or whatever you + choose. The sample file has all the options commented out. + You can remove the # character on any that you + want, but it may be better to leave this until to later. + Run it asynchronously:
      +
      +    junkbuster configfile & + + +

      If you are running a version earlier than 2.0 you can + start it with junkbuster &

      +
    8. + +
    9. Configure your browser (described + above).
    10. + +
    11. Verify that the Internet Junkbuster is + working (described above).
    12. + +
    13. Decide on the options you really + want, kill the process and start it again. The + most popular option is + blockfile to block ads. A + sample blockfile is provided as an illustration, but it + doesn't really stop many ads. More comprehensive ones are + available elsewhere.
    14. + +
    15. You'll probably want to add an entry to + /etc/rc.d/rc.local or equivalent to start it at + boot time. (Any output you specify should be redirected to a + file. And don't forget the & at the end to run it + asynchronously or your system will seize up after the next + reboot.)
    16. +
    + +

    *  How do I compile the code under + Windows?

    + +

    A .exe file (binary) is supplied with the + source code, but if you prefer to compile it yourself here is + the likely procedure. Most of these steps are repeated in our + checklist for installation under Windows.

    + +
      +
    1. First click here to download the zip + file called ijb20.zip (~208k), then uncompress + and unpack the zip archive using a tool like WinZip.
    2. + +
    3. Now the distribution (source and + sample files) will be in a folder called ijb20. + Go into that folder and then edit the Makefile for your + system, removing the comment character (#) in + the lines related to Win32. Then type:
      +    nmake
      + This should create an executable called + junkbstr.exe. For information + on issues with various compilers, see the Distribution + Information page.
    4. + +
    5. + Run the executable with the + command:
      +    junkbstr
      + (Click on the icon with that name + that looks like a terminal, not like a notepad.) The + program will produce a message indicating that it has + started and is ready to serve. + +

      (Version 2.0.1 and above uses the file + junkbstr.ini as the config file if it exists + and no argument was given. If you have an earlier version + or if you want it to use a different config file, simply + specify that file as the argument.)

      +
    6. + +
    7. Configure your browser + (described above).
    8. + +
    9. Check the proxy is working (described + below).
    10. + +
    11. + To have the proxy start itself + automatically when you login to Win95, drop the + ``shortcut'' to the junkbstr executable into + the StartUp folder:
      +    C:\Windows\Start + Menu\Programs\StartUp
      + You might want to change the shortcut's + Properties->Shortcut to Run: + Minimized. If you specify the hide-console option then the + DOS window will vanish after it starts. + +

      WinNT users can put it into their own + StartUp folders or the Administrator can put it into the + system's global StartUp folder. For details on how to make + this a service under NT see our Windows page.

      +
    12. +
    + +

    *  How do I check that the proxy is + working?

    + +

    Pick a page from somewhere (such as your bookmarks, or just + one that your browser was pointing to) and + Reload it. If you get a message along the lines of ``server + not responding, using cached copy instead,'' see the advice + above. If the page reloads OK, check that your browser is + actually talking to the proxy by going to + http://internet.junkbuster.com/cgi-bin/show-proxy-args or any + URL ending in show-proxy-args (as described below, + the proxy should intercept the request.) When you see + ``Internet Junkbuster Proxy Status,'' you'll know it's + working.

    + +

    *  How and why would I have this + proxy chained with other proxies?

    + +

    You may need the + forwarding feature to ``daisy chain'' the Internet + Junkbuster to another proxy, perhaps an anonymizing proxy to + conceal your IP address, or a caching proxy from your ISP, or a + firewall proxy between your company and the outside world. + Version 2.0 and above can be even configured to forward selectively according to the + URL requested: for example, connecting directly to trusted + hosts, but going through an anonymizing or firewall proxy for + all other hosts.

    + +

    Network administrators might use + it to provide transparent access to multiple networks without + modifying browser configurations. Most + browsers also provide a way of specifying hosts that the + browser connects to directly, bypassing the proxy. Some provide + a method for Automatic Proxy Configuration. A well written + Internet Junkbuster configuration can be much more flexible and + powerful.

    + +

    An ISP's caching proxy would typically + be called something like cache.your-isp.net:8080 + (as described on you ISP's web page); you would put this + information in your + forwardfile as described in our manual. Your browser would + be configured to the Internet Junkbuster for HTTP and Security + Proxies as before, but you probably want to tell it to use the + caching proxy for FTP and other protocols. + If your ISP is running the Internet Junkbuster for you, + they have probably already decided whether to chain with a + caching proxy.

    + +

    *  How does the Internet Junkbuster + work with SOCKS gateways?

    + +

    There is support for some gateways in Version 1.4 and above. + The gateway protocol used to be specified on the command line; + it is now specified in the same file as forwarding. Note that the + browser's proxy configuration must not specify a + SOCKS host; it should specify the proxy as + described above.

    + +

    *  How do I configure it to be just + a plain old proxy?

    + +

    To get the proxy to do as little as possible (which means + not deleting any sensitive headers), place in your + configuration file the following three lines (each ending in a + space then a period) to stop it changing sensitive headers:
    +    referer .
    +    from .
    +    user-agent .
    +    cookiefile mycookiefile
    + The fourth line is also needed to specify a cookiefile that might be called + mycookiefile containing a single line with a + * character, to allow all cookies through.

    + +

    *  How do I shut down the proxy (to + restart it)?

    + +

    It depends on your platform.

    + +
      +
    1. Under Windows, you can click on the "X" + button at the top right of the DOS window (and answer Yes when Windows warns you it cannot shut down + the program automatically), or use + Ctrl-Break or the old three-fingered salute of Ctrl-Alt-Delete and select End + Task.
    2. + +
    3. Under UNIX ® you'll need to + kill the junkbuster process. If you don't know the process number to give + to kill, try this:
      +    ps ax | grep junkbuster
    4. +
    + +

    --- Back to Top of Page ---

    + +

    Information for companies

    + +

    *  What do advertising companies + think of this kind of technology?

    + +

    We've seen only a few public comments from the advertising + industry on this, other than SEC filings. First, the president + of the Internet Advertising Bureau told CNET that he wasn't + worried by banner blockers. Second, after the Federal Trade + Commission's workshop where we gave a live demonstration of our + proxy before many eminent representatives of the industry, the + Direct Marketing Association made the following statement in + the closing paragraphs of their summary comments to the + Commission.

    + +
    + Clever shareware developers have come up with products that + can obliterate cookies and advertisements for those consumers + who have these concerns. The Internet is a market that is so + democratic and flexible that it is easy for companies and + software developers to respond to a perceived market need. +
    + +

    Their attitude seems to be that they would prefer that + people use technical solutions to protect their privacy than + have protections imposed by legislation or government + regulations. So, do you perceive a market need? Then here are + some ways to flex your democratic muscles.

    + +

    +  Should we provide the + Internet Junkbuster for our employees?

    + +

    That depends. Try this quick three-point test.

    + +
      +
    1. Do you want to spend your + communications budget on bandwidth that wastes your + employees' time by forcing them to wait for a lot of annoying + distractions while they're trying to do their jobs?
    2. + +
    3. Do you want current and + potential vendors to know quantitative details about the + software and hardware platforms that you have?
    4. + +
    5. Do you want your competitors + to be able to track exactly which of your employees are + checking out their web sites?
    6. +
    + +

    If the answer to all three questions is yes, then you + probably don't have any need for this kind of product.

    + +

    +  Can our company get + commercial support for the software?

    + +

    Yes, ask us for a quote on a maintenance contract with your + choice of phone and email support, hard copy documentation, + source code and pre-compiled binaries on tape or disk, and + email alerting of upgrades and issues. We also offer consulting + services to help set up ``stealth browsing'' capabilities to + help reduce the footprints left while doing competitive + analysis and other Web work where confidentiality is + critical.

    + +

    *  I run an ISP. What issues should + I consider before offering it?

    + +

    Many ISPs who offer the proxy to their customers have told + us that most of their customers are delighted with it (although + one reported that a customer complaint that without banner ads, + surfing was like reading a novel: we recommend making it + optional). Many ISPs like it because it reduces bandwidth + requirements. To help get you started, here's a checklist we've + developed from working with a few ISPs. You may think of more, + and we'd be interested if you're willing to share them with + us.

    + +
      +
    1. If you get more than one request + for the Internet Junkbuster you may want to tell your + customers on your News page that you already know about it + and are assessing it.
    2. + +
    3. Try the software and verify that it + performs satisfactorily.
    4. + +
    5. Determine whether your customers + perceive the service as valuable (and therefore worth the + time to set up). We've had reports of many delighted + customers.
    6. + +
    7. Assess the level of security + associated with the software. If access is to be restricted + (to just dial-in ports, for example) how is this to be + done?
    8. + +
    9. Consider whether to expect any + additional load on computing resources required, and any + change in use of bandwidth due to the blocking of large + GIFs.
    10. + +
    11. Choose the + options you wish to provide.
    12. + +
    13. + Decide whether you want to offer a + choice of configurations, such some of these four. + +
        +
      1. Banners Blocked, Wafer with + No-Cookie-Copyright notice
      2. + +
      3. Cookies not stopped (cookiefile with just a + * in it), User Agent specified as Lynx
      4. + +
      5. Cookies from browser allowed, + permitting registered services
      6. + +
      7. A proxy for kids.
      8. +
      + If you run a caching proxy, decide + whether the Internet Junkbuster will chain with it by + default, and whether to offer an alternate with no caching. + (Some ISPs don't, because they want to give customers an + incentive to use caching and save bandwidth.) +
    14. + +
    15. Decide on a naming scheme for your + proxies. If you're running only one proxy on one machine, the + simplest way is to just use port 8000 on your main machine, + such as our-isp.net. But it would probably be + safer to put an entry in your name server and call it + something like junkbuster.our-isp.net. If + running several proxies, you could either use different ports + on the same machine, or if you have the opportunity to + distribute the load over a few machines you could use + different hostname aliases such as + banner.junkbuster.our-isp.net, + lynx.junkbuster.our-isp.net and + oneway.junkbuster.our-isp.net (corresponding to the + examples in the previous point). You may want to set up + Automatic Proxy Configuration.
    16. + +
    17. + Prepare a page explaining the + Internet Junkbuster to your customers. + Here's are some examples from Australia, Germany, Florida, + New York/New Jersey/Pennsylvania, North Carolina, Texas, + and Utah. You are welcome to copy and + modify material from Junkbusters according to the GPL. You + might want to set up a process to check this page + periodically and update it when it changes. (A few links + can probably serve as well as lot of copying however.) A + typical page would probably specify the following. + +
        +
      1. A brief explanation stating + what the Internet Junkbuster does, with a link to this + page.
      2. + +
      3. The addresses of the proxy or + proxies, with their port number(s).
      4. + +
      5. The options used, and how to + view the contents of the blockfile (which you can place + on your web pages, preferably in a file called + blocklist.html or + blocklist.txt).
      6. + +
      7. An indication of whether + suggestions for the blocklist are considered, and if so, + how to submit them: to a particular email address, via + web-based form, etc.
      8. + +
      9. Instructions on how to + configure a browser. You may want to include details for + only the two major browsers and leave the others to a + link.
      10. + +
      11. Procedures on how to report + problems, give feedback etc.
      12. +
      +
    18. + +
    19. Invite a small number of + technologically sophisticated customers to beta-test the + service.
    20. + +
    21. Announce general availability on + your ``News'' page. Tell us if you would like to be included + on a list of ISPs offering the Internet Junkbuster.
    22. +
    + +

    --- Back to Top of Page ---

    + +

    Blocking

    + +

    +  Where can I get an example + blockfile that stops most ads?

    + +

    The sample blockfile we provide blocks almost nothing, and + we do not publish blockfiles that stop almost all banner ads. + But others have; you can find them by asking Google. You can + add any part of the new file to your old one (probably called + sblock.ini if you haven't changed the default name + in the latest version) or your just replace it completely. You + probably don't need to restart the proxy.

    + +

    If you develop an interesting blocklist + and publish it on the Web, you might want to include the word + ``junkbuster'' in it and use the word ``blocklist'' in the file + name given in the URL so that others can find it with the query + given in the previous sentence.

    + +

    *  If I see an ad I wish I hadn't, + how do I stop it?

    + +

    If your ISP is running the Internet Junkbuster, they should + have a policy on whether they accept suggestions from their + customers on what to block. Consult their web page.

    + +

    If you are running the Internet + Junkbuster yourself, you have complete control over what gets + through. Just add a pattern to cover the offending URL to your + blockfile. Version 1.3 and later automatically rereads the + blockfile when it changes, but if you're running an earlier + version you'll have to stop it and restart it.

    + +

    To choose a pattern you'll first need + to find the URL of the ad you want cover.

    + +

    Some people use the debug 1 option to display + each URL in a window as the request is sent to the server. It's + then usually an easy task to pick the offending URL from the + list of recent candidates.

    + +

    Alternatively, you can use View Document Info (or View Document + Source if your browser doesn't have that). The Info feature has the advantage of showing you the full + URL including the host name, which may not be specified in the + source: there you might see something like + SRC="/ads/click_here_or_die.gif" indicating only the + path. (The host name is assumed to be the same + as the one the page came from.)

    + +

    But ads often come from a different + site, in which case you might see something like + SRC="grabem.n.trackem.com/Ad/Infinitum/SpaceID=1666" or + longer. If the company looks like a + pure ad warehouse (as in the last case), you may want to place + just its domain name in the blockfile, which blocks all URLs + from that site.

    + +

    If the ad comes from a server that you + really want some content from, you can include enough of the + path to avoid zapping stuff you might want. In the first + example above, /ads/ would seem to be enough. If + you don't include the domain name, the pattern applies to all + sites, so you don't want such patterns to be too general: for + example /ad would block + /admin/salaries/ on your company's internal site.

    + +

    To speed the blocking of images, some + UNIX ® users create a shell script called + Image: containing a line such as echo $1 | sed + s/http:..// >> $HOME/lib/blockfile that adds its + argument to the user's blockfile. Once an offending image has + been be found using View Document Info it's + easy to cut-and-paste the line (or part of it) into a shell + window. The same script can be linked to a file called + Frame: to dealing with framed documents, and + junkbuster: to accept the output of the debug option.

    + +

    When compiled without the + regular expressions option, the Internet Junkbuster + uses only very simple (and fast) matching methods. The pattern + /banners will not stop + /images/banners/huge.gif getting through: you would have + to include the pattern /images/banners or + something that matches in full from the left. + So you can get what you want here, the matcher understands + POSIX regular expressions: you can use + /*.*/banners to block and any URL containing + /banners (even in the middle of the path). (In Versions 1.1 through 1.4 they were an option at + compile time; from Version 2.0 they have become the default.) + Regular expressions give you many more features than this, but + if you're not already familiar with them you probably won't + need to know anything beyond the /*.*/ idiom. If + you do, a man egrep is probably a good starting + point).

    + +

    Don't forget the / (slash) + at the beginning of the path. If you leave it out the line will + be interpreted as a domain name, so ad would block + all sites from Andorra (since .ad is the + two-letter country code for that principality).

    + +

    For a detailed technical description of + how pattern matching is done, see the manual.

    + +

    *  How come this ad is still getting + through anyway?

    + +

    If the ad had been displayed before you included its URL in + the blockfile, it will probably be held in cache for some time, + so it will be displayed without the need for any request to the + server. Using the debug + 1 option to show each URL as it is fetched is a good way + to see exactly what is happening.

    + +

    If new items seem to be getting + through, check that you are really running the proxy with the + right blockfile in the options. Check the blockfile for + exceptions.

    + +

    Some sites may have different ways of + inserting ads, such as via Java. If you have ideas on how to + block new kinds of junk not currently covered, please tell + us.

    + +

    +  How do I stop it blocking a + URL that I actually want?

    + +

    You can change the patterns so they don't cover it, or use a + simple feature in Version 1.1 and later: a line beginning with + a ~ character means that a URL blocked by previous + patterns that matches the rest of the line is let through. For + example, the pattern /ad would block + /addasite.html but not if followed by + ~/addasite in the blockfile. Or suppose you want to see + everything that comes from a site you like, even if it looks + like an ad: simply put ~aSiteYouLike.com at the + end of the blockfile. (Order is important, because the + last matching line wins.)

    + +

    As well as unblocking pages that were + unintentionally blocked, this feature is useful for unblocking + ads from a specific source. This might be because you are + interested in those particular ones, or if you have an explicit + agreement to accept certain ads, such as those from a free + web-based email provider.

    + +

    If you want to find out exactly which + pattern in the blockfile a given URL matched, just click on the + words ``Internet Junkbuster'' which are displayed alone on a + page when your browser requests a blocked URL. The proxy + displays a message that pinpoints the pattern for you.

    + +

    *  Can I block sites I don't want my + children to see?

    + +

    Yes, but remember that children who are + technically sophisticated enough to use the browsers' proxy + configuration options could of course bypass any proxy. This + kind of technology can be used as a gentle barrier to remind or + guide the child, but nobody should expect it to replace the + parent's role in setting and enforcing standards of online + behavior for their children.

    + +

    Some ISPs are starting to provide + specialized proxies to protect children. There are two basic + approaches: the ``black list'' and the ``white list'' approach. + The black list approach allows the child + to go anywhere not explicitly prohibited; the white list + permits visits only to sites explicitly designated as + acceptable.

    + +

    It's very easy for anyone to compile + a white list from a page of ``recommended kids sites'' and to + configure an Internet Junkbuster to allow access to those sites + only. (If you publish such a list on the web, please tell us + its URL). Assuming your version isn't an old one without regex, + you can place a * (asterisk) as the first line of + the blockfile (which blocks everything), and then list + exceptions after that. Be careful to make the exception + sufficiently broad: for example, using + ~www.uexpress.com/ups/comics/ch/ as the exception for + Calvin and Hobbes would block some of the graphic + elements on the page; you would probably want a wider exception + such as ~www.uexpress.com/ups/ to permit them.

    + +

    Version 2.0 has an experimental feature + to permit only sites mentioned in a nominated trusted site. This allows + organizations to build lists of sites for kids to browse, and + the software automatically restricts access to those on the + list.

    + +

    Many filtering products actually scan for + keywords in the text of pages they retrieve before presenting + it, but the Internet Junkbuster does not do this. Building a + perfectly reliable black list system is hard, because it's very + difficult to state in advance exactly what is obscene or + unsuitable. For more info see our links page.

    + +

    *  What do I see when a page or + graphic is blocked by the proxy?

    + +

    You usually see a broken image icon, but it depends on + several factors beyond the proxy's control. If asked for a URL + matching its blockfile, the proxy returns an HTML page + containing a message identifying itself (currently the two + words ``Internet Junkbuster'') with a status 202 (Accepted) + instead of the usual 200 (OK). (Versions 1.X returned an error + 404: Forbidden, which caused strange behavior in some cases.) + Status 202 is described in the HTTP RFC as indicating that the + request has been accepted but not completed, and that it might + complete successfully in the future (in our case, if the + blockfile were changed).

    + +

    The broken image icon is most common + because the browser is usually expecting a graphic. But if it + was expecting text, or if the page happens to be using certain + HTML extensions such as layer and your browser is + a late model from Microsoft, you may see the words ``Internet + Junkbuster'' displayed as a hot link.

    + +

    Clicking on the link takes you to an + explanation of the pattern in the blockfile that caused the + block, so that you can edit the blockfile and go back and + reload if you really want to see what was blocked. The + explanatory link is generated by the proxy and is automatically + intercepted based on its ending in ij-blocked-url; + even though the site is specified as + http://internet.junkbuster.com no request should + actually made to that site. If one is, it means that the proxy + was been removed after it generated the link.

    + +

    To summarize: the identifying link to + the blocking explanation is usually turned into a broken image + icon, but it may be displayed on a page alone, or they may may + be restricted to the particular frame, layer or graphic area + specified in the page containing them. The proxy has no way of + knowing the context in which a URL will be used and cannot + control how the blocking message will be rendered.

    + +

    *  Why not replace blocked banners + with something invisible?

    + +

    Many users have suggested to us that + blocked banners should be replaced by a something like a 1x1 + transparent GIF to make the page would look as if there was + nothing ever there. Apart from making it harder to catch + unintended blocking, this might also displease the owners of + the page, who could argue that such a change constitutes a + copyright infringement. We think that merely failing to allow + an included graphic to be accessed would probably not be + considered an infringement: after all this is what happens when + a browser is configured not to load images automatically. + However, we are not lawyers, so anyone in doubt should take + appropriate advice.

    + +

    In a context where the copyright issue is + resolved satisfactorily, a proxy could simply return a status + 301 or 302 and specify a replacement URL in a + Location and/or URI header. An alternative + would be to use inline code to return a 1 x 1 clear GIF. We do + not publish sample code for this, and we have no way of + stopping others who have.

    + +

    *  Why not block banners based on + the dimensions of the image?

    + +

    Many users have pointed out that most banner ads come in + standard sizes, so why not block all GIFs of those sizes? This + would theoretically be without fetching the object because the + dimensions are usually given in the IMG tag, but + it would require substantial changes in the code, and we doubt + whether it would be much more effective than a good block + list.

    + +

    *  What about non-graphic + advertising within the pages I want?

    + +

    The Internet Junkbuster deliberately does not provide a way + of automatically editing the contents of a page, to remove + textual advertising or to repair the holes left by blocked + banners. Other packages such as WebFilter do.

    + +

    For the same reason, it has no way of + stopping a new browser window being created, because this is + done through the target attribute in the + <a> and <base> elements, not + through headers. Nor do we plan to add a feature to paralyze + animated GIFs.

    + +

    *  Does it block ads on the + broadcasting ``push'' systems? How about pop-up ads?

    + +

    We haven't tried it but we expect it would probably work on + image ads on push channels. See also adchoice.

    + +

    Disabling Javascript stops some pop-up + ads. One problem is that some advertisers throw open a new + browser window to frame the ad. The ad is easily blocked, but + the empty window remains. You can kill it easily, but this is a + chore. We don't see how to stop them other than editing the + HTML from the parent window, which we don't like to do.

    + +

    The TBTF newsletter warned subscribers to + push information that in IE4, LOGTARGET + allows servers to determine the URLs viewed at their site even + if accessed from cache or through a proxy. If you use this + browser see our instructions on how to disable this.

    + +

    If you find you have experience using + the proxy with push, or have any other advice about it, please + tell us.

    + +

    --- Back to Top of Page ---

    + +

    Cookies

    + +

    For background information on cookies see our page + describing their dangers.

    + +

    *  Might some cookies still + get through? How can I stop them?

    + +

    Yes, you should expect the occasional cookie to make it + through to your browser. We know of at least three ways this + can happen; please tell us if you find any others. One way is + in secure documents, which are explained below.

    + +

    A few sites set cookies using a line + such as <META HTTP-EQUIV="Set-Cookie" + CONTENT="flavor=chocolate"> in the HEAD + section of an HTML document. Cookies + can also be + + set and read in JavaScript. To see if this is happening in a + document, view its source, look in the head for a + section tagged script language="JavaScript". If it + contains a reference to document.cookie, the page + can manipulate your cookie file without sending any cookie + headers. The Internet Junkbuster does not tamper with these + methods. Fortunately they are rarely used at the moment. If a + cookie gets set, it should be stopped by the proxy on its way + back to the server when a page is requested, but it can still + be read in Javascript.

    + +

    To prevent cookies breaking through, + always keep cookie alerts turned on in your + browser, and disable Java and Javascript. Making the files hard + to write may also help.

    + +

    *  Exactly how do cookies get + created and stored anyway?

    + +

    When a web site's server sends you a page it also sends + certain ``header information'' which your browser records but + does not display. One of these is a Set-Cookie + header, which specifies the cookie information that the server + wants your browser to record. Similarly, when your browser + requests a page it also sends headers, specifying information + such as the graphics formats it understands. If a cookie has + previously been set by a site that matches the URL it is about + to request, your browser adds a Cookie header + quoting the previous information.

    + +

    For more background information on how + cookies can damage your privacy, see our page on cookies. For + highly detailed technical information see the RFC. The Internet + Junkbuster will show you all headers you use the debug 8 option, or you can + get a sample from our demonstration page.

    + +

    *  If cookies can't get through, + will some things stop working for me?

    + +

    Possibly. Some personalized services including certain + chat rooms require cookies. + Newspapers that require + + registration or + + subscription will not automatically recognize you if you don't + send them the cookie they assigned you. And there are a very + small number of sites that do strange things with cookies; they + don't work for anyone that blocks cookies by any means. Some + sites such as Microsoft explain that their content is so + wonderfully compelling that they will withhold it from you + unless you submit to their inserting cookies.

    + +

    Many free Web-based email services + require cookies. Hotmail also seems to require allowing both + msn.com and passport.com to set + cookies.

    + +

    If you want such sites to be given your + cookies, you can use the + cookiefile option provided you are running Version 1.2 or + later yourself. Simply include the domain name of those sites + in the cookiefile specified by this option. If it still + doesn't work, the problem may be in other headers.

    + +

    It's possible to let cookies out but not + in, which is enough to keep some sites happy, but not all of + them: one newspaper site seems to go into an endless frenzy if + deprived of fresh cookies. A cookiefile containing a single + line consisting of the two characters >* + (greater-than and star) permits server-bound cookies only. The + * is a wildcard + that matches all domains.

    + +

    If someone else is running the Internet + Junkbuster for you and has a version that + passes server-bound + cookies through, you can try editing your browser's cookie file + to contain just the ones you want, and restart your browser. To subscribe to a new service like this after + you have started using the Internet Junkbuster, you can try the + following: tell your browser to stop using the Internet + Junkbuster, fill out and submit your subscription details + (allowing that web site to set a cookie), then reconfigure your + browser to use the Internet Junkbuster again (and stop more + cookies being sent). This also requires the cookiefile option, and its success + depends on the Web site not wanting to change your cookies at + every session. For this reason it does not work at some major + newspaper sites, for example. But you may + prefer to look at whether other sites provide the same or + better services without demanding the opportunity to track your + behavior. The web is a buyer's market where most prices are + zero: very few people pay for content with money, so why should + you pay with your privacy?

    + +

    *  Can I control cookies on a + per-site basis?

    + +

    Yes, since version 1.2 the Internet + Junkbuster has included advanced cookie management facilities. + Unless you specify otherwise, cookies are discarded + (``crumbled'') by the Internet Junkbuster whether they came + from the server or the browser. In Version 1.2 and later you + can use the cookiefile + option to specify when cookies are to be passed through intact. + It uses the same syntax and + matching algorithm as the blockfile.

    + +

    If the URL matches a pattern in the + cookiefile then cookies are let through in both + the browser's request for the URL and in the server's response. + One-way permissions can be specified + by starting the line with the > or + < character. For example, a cookiefile consisting of + the four lines
    +    org
    +     >send-user-cookies.org
    +     + <accept-server-cookies.org
    +     ~block-all-cookies.org
    + allows cookies to and from .org domains only, + with the following exceptions:
    +

    + +
      +
    1. Cookies sent from servers in the domain + send-user-cookies.org are blocked on their way + to the client, but cookies sent by the browser to that domain + are still be fed to them.
    2. + +
    3. The cookies of + accept-server-cookies.org check in to the proxy and + are passed through to the browser, but when they come back to + the proxy they never check out.
    4. + +
    5. All cookies to and from + block-all-cookies.org are blocked.
    6. +
    + +

    If the junkbuster + was compiled with the regular expressions option they may be + used in paths. Any logging to a ``cookie jar'' is separate and + not affected.

    + +

    It's important to give hosts you want + to be able to set cookies sufficient breadth. For example, + instead of www.yahoo.com use + yahoo.com because the company uses many different hosts + ending in that domain.

    + +

    *  Can I make up my own fake cookies + (wafers) to feed to servers?

    + +

    Yes, using the wafer option. + We coined the term wafer to describe cookies + chosen by a user, not the Web server. Servers may not find + wafers as tasty as the cookies they make themselves. But users + may enjoy controlling servers' diets for various reasons, such + as the following.

    + +
      +
    1. Users who consider cookies to be + an unwelcome intrusion and a waste of their disk space can + respond in kind. By writing ``signature wafers'' they can + express their feelings about cookies, in a place that the + people in charge of them are most likely to notice.
    2. + +
    3. + Sites running a proxy that logs + cookies to a file (such as the Internet Junkbuster does + with the jarfile option + on) may want to notify servers that their cookies are being + intercepted, deleted or copied. One possible reason for + doing this is the uncertain copyright status of cookie + strings. Nothing here should be taken as legal advice: we + are simply raising a question for any interested parties to + consider, and make no representation that such measures are + necessary or sufficient. Concerned proxy sites might decide + to send a wafer (named ``NOTICE'' for example) containing + text along the lines of the following. + +
      +

      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.

      +
      + Any company that tries to argue in court that the proxy + site was breaching their copyright in the cookies would be + met with the defense that the proxy site gave that company + the opportunity to protect its copyright by simply not + sending cookies after receiving the notice. + +

      Cookies can be as long as four + thousand characters, so there's plenty of space for + lawyerly verbosity, but white space, commas, and + semi-colons are prohibited. + Spaces can be turned into underscores. Alternatively, a URL + could be sent as the cookie value, pointing to a document + containing a notice, perhaps with a suggestive value such + as
      + + http://www.junkbusters.com/ht/en/ijbfaq.html#licenses_on_cookies_refused
      + + But including the notice directly would probably be + preferable because the addressee does not have to look it + up.

      + +

      The Internet Junkbuster 2.0.2 + currently sends a full notice as a ``vanilla wafer'' if + cookies are being logged to a cookie jar and no other + wafers have been specified. It can be suppressed with the + + suppress-vanilla-wafer option, which might be used in + situations where there is an established understanding + between the proxy and all who serve it.

      +
    4. +
    + +

    Junkbusters provides a CGI script that + lets you see your wafers as they appear to servers.

    + +

    Wafers confuse a few fragile + servers. Hotmail appears to be one of them. If this troubles + you, don't use this option.

    + +

    Any wafers specified are sent to + all sites regardless of the cookiefile. + They are appended after any genuine cookies, to maintain + compliance with RFC 2109 in the event that a path was specified + for a cookie. The RFC's provisions regarding the $ + character (such as the Version attribute) are + transparent to the proxy; it simply quotes what was recited by + the browser.

    + +

    If you want to send wafers only to + specific sites, you could try putting them your browser's + cookie file in a format conforming to the Netscape + specification, and then specify in the proxy's cookiefile that + cookies are to be sent to but not accepted from those sites, so + they can't overwrite the file. This may work with Netscape but + not all other browsers.

    + +

    *  Why would anyone want to save + their cookies in a ``cookie jar?''

    + +

    We provided this capability just in case anyone wants it. + There are a few possible reasons.

    + +
      +
    1. It's conceivable that marketing + companies might one day buy history files and cookie jars + from consumers in the same way that they currently pay them + to fill out survey forms. With this information they could + gather psychographic information, see which competitors' + sites the consumer has visited, and discover what advertising + is being targeted at them.
    2. + +
    3. Some consumers might employ + semi-automated means of sorting through their cookie jars, + selecting which ones to place in their cookies file for use + by their browsers. Their decisions could be based on payments + offered, privacy rating systems such as TRUSTe proposes, or + their own opinion of the company. It could be done manually + or with software. There's an Internet Draft on trust + certification of cookies.
    4. + +
    5. Users may even start ``sharing'' + cookies among themselves, sending back cookies that servers + generated for other visitors. Servers that aren't expecting + this possibility will be misled about their visitors' + identities. Cookies could be shared among users on a single + machine, or across continents via FTP and anonymous + remailers. Privacy activists may + promote cookie disinformation campaigns as a way to defend + the public against abuse. If a significant percentage of + people send disinformative cookies, user tracking via cookies + may become less reliable and less used.
    6. +
    + +

    --- Back to Top of Page ---

    + +

    Anonymity

    + +

    For details on how your identity can be revealed while you + surf, see our page on privacy. Once you start using the + Internet Junkbuster you should find that much of the + information previously indicated on that page will no longer be + provided. If the REMOTE HOST indicating your IP + address is too close for comfort, see our suggestions below on + how to conceal your IP address. We also recommend that you + disable JavaScript and Java.

    + +

    *  If I use the Internet Junkbuster, + will my anonymity be guaranteed?

    + +

    No. Your chances of remaining anonymous are 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 + attributed to you personally.

    + +

    The Internet Junkbuster removes various + information about you, 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. The Internet Junkbuster 2.0.2 does not filter the FTP + stream. 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 downloaded 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.

    + +

    *  Why should I trust my ISP or + Junkbusters with my browsing data?

    + +

    You shouldn't have to trust us, and you certainly don't have + to. We do not run the proxy as a service, where we could + observe your online behavior. We provide source code so that + everyone can see that the proxy isn't doing anything + sneaky.

    + +

    You are already trusting your ISP not to + look at an awful lot of information on what you do. They + probably post a privacy policy on their site to reassure you. + If they run a proxy for you, using it could actually make it + slightly easier for them to monitor you, but we doubt that any + sane ISP would try this, because if it were discovered + customers would desert them.

    + +

    *  Can the proxy be used for logging + who looks at what?

    + +

    We don't want institutions to use this software as an + instrument of surveillance. We have deliberately not provided + options to add timestamps or records of which IP addresses + accessed which URLs. However, because we publish source code + anyone can modify it to do such things, and there is no way a + remote user can find out if this is happening. Again, you need + to be able to trust the entity providing your proxy service, + but you were probably in that position even before using a + proxy.

    + +

    *  What private information from + server-bound headers is removed?

    + +

    The Internet Junkbuster pounces on the following HTTP + headers in requests to servers, unless instructed otherwise in + the options.

    + +
      +
    1. The FROM header, which a + few browsers use to tell your email address to servers, is + dropped unless the from option + is set.
    2. + +
    3. The USER_AGENT header is changed to indicate that the browser is + currently Mozilla (Netscape) 3.01 Gold with an unremarkable + Macintosh configuration. Misidentification helps resist + certain attacks. If your browser and hardware happen to be + accurately identified, you might want to change the default. + (Earlier versions of the Internet Junkbuster indicated + different details; by altering them periodically we aim to + hinder anyone trying to infer whether our proxy is present.) + If you don't like the idea of incorrectly + identifying your computer as a Mac, set it accordingly. +
    4. + +
    5. The REFERER header + (which indicates where the URL currently being requested was + found) is dropped. A single static referer to replace all + real referers may be specified using the referer option. Where no referer is + provided by the browser, none is added; the add-header option with arguments + such as -x 'Referer: http://me.me.me' can be + used to send a bogus referer with every request.
    6. +
    + +

    In Version 1.4 and later you can use the -r @ option to selectively disclose + REFERER and USER_AGENT to only those + sites you nominate.

    + +

    Some browsers send Referer and User-Agent + information under different non-standard headers. The Internet + Junkbuster 2.0.2 stops UA headers, but others may + get through. This information is also available via JavaScript, + so disable it. Some search engines + encode the query you typed in the URL that goes to advertisers + to target a banner ad at you, so you will need to block the ad + as well as the referer header, unless you want them (and anyone + they might buy data from) to know everything you ever search + for.

    + +

    If you have JavaScript enabled (the + default on most browsers) servers can use it to obtain Referer + and User Agent, as well as your plug-ins. We recommend + disabling JavaScript and Java.

    + +

    Currently no HTTP response headers + (browser bound) are removed, not even the + Forwarded: or X-Forwarded-For: headers. Nor + are any added, unless requested. + We are considering a more flexible header management system for + a future version.

    + +

    *  Might some things break because + header information is changed?

    + +

    Possibly. If used with a browser less advanced than Netscape + 3.0 or IE-3, indicating an advanced browser may encourage pages + containing extensions that confuse your browser. If this + becomes a problem upgrade your browser or use the user-agent option to indicate an + older browser. In Version 1.4 and later you can selectively + reveal your real browser to only those sites you nominate.

    + +

    Because 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.

    + +

    Some page access counters work by + looking at the referer; they may fail or break when + deprived.

    + +

    Some sites depend on getting a referer + header, such as uclick.com, which serves comic + strips for many newspaper sites, including + Doonsbury for the Washington Post. (If you + click on that last link, you can then get to a page containing + the strip via the same URL we've linked to under + Doonsbury, but if you click on the + Doonsbury link directly, it gives you an error message + suggesting that you use a browser that supports referers.) In + Version 1.4 and later you can use the -r @ option and place a line like + >uclick.com in your cookiefile. Wired News used to + use referer to decide whether to add a navigation column to the + page, but they have changed that.

    + +

    The weather maps of Intellicast + have been blocked by their server when no referer or cookie is + provided. You can use the same countermeasure with a line such + as >208.194.150.32 (or simply get your weather + information elsewhere).

    + +

    Some software vendors, including + Download.com and Intuit use USER_AGENT to decide + which versions of their products to display to you. With the + default you get Mac versions.

    + +

    As a last resort if a site you need + doesn't seem to be working, the proxy configuration of many + browsers allow you to specify No Proxy For + any hostname you want.

    + +

    We had reports that on some versions of + Netscape the What's New feature did not work with the proxy, + but we think we fixed this in Version 2.0.1.

    + +

    +  How is misidentifying my + browser good for security and privacy?

    + +

    Almost every major release of both leading browsers has + contained bugs that allow malicious servers to compromise your + privacy and security. Known bugs are quickly fixed, but + millions of copies of the affected software remain out there, + and yours is probably one of them. The header that normally + identifies your browser tells such servers exactly which + attacks to use against you. By misidentifying your browser you + reduce the likelihood that they will be able to mount a + successful attack.

    + +

    *  Does the Internet Junkbuster + conceal my IP address?

    + +

    Web sites get the IP address of any proxy or browser they + serve pages to. If you run the proxy on your own computer the + IP address disclosed is the same as your browser would, unless + you use the forwardfile + option is used to chain to another proxy, in which case servers + only get the last IP address in the chain. Chaining slightly + slows browsing of course, but it improves anonymity.

    + +

    *  Does the Internet Junkbuster + thwart identification by identd?

    + +

    We think so, provided you are not the user running the + proxy. If your computer (or your ISP's) is running the + identd demon, servers can ask it for the identity of the + user making the request at time you request a page from them. + But if you're going through a proxy, they will identify the + user name associated with the proxy, not you. A visit to + http://ident.junkbusters.com lets you see what's happening. + This test is (quite rightly) blocked by many firewalls; just + interrupt the transfer if you get an abnormal wait after + clicking. Running other applications may also expose you via + identd; the proxy of course doesn't help then.

    + +

    *  Can web sites tell that I'm using + the Internet Junkbuster?

    + +

    With the default options the proxy doesn't announce itself. + Obvious indications such as Keep-Alive headers are deleted, but sites might notice that you + can cancel cookies faster than any human could possibly click + on a mouse. (If you want to provide a plausible explanation for + this, change the User Agent header to a cookie-free or + cookie-crunching browser).

    + +

    But when certain options are used they + could figure out something's going on, even if they're not + pushing cookies. If you use blocking they can tell from their + logs that the graphics in their pages are not being requested + selectively. The + add-forwarded-header option explicitly announces to the + server that a proxy is present, and sending them wafers is of + course a dead giveaway.

    + +

    --- Back to Top of Page ---

    + +

    Security

    + +

    *  What happens with Secure + Documents (SSL, https:)?

    + +

    If you enter a ``Secure Document Area,'' cookies and other + header information such as User Agent and Referer are sent + encrypted, so they cannot be filtered. We recommend getting + your browser to alert you when this happens. (On Netscape: Options; Security; General; Show an alert before entering a + secure document space.) We also recommend adding the line + :443 to the blockfile to stop all but sites + specified in an exception after that line from using SSL.

    + +

    It may be possible to filter encrypted + cookies by combining the blocking proxy with a cryptographic + proxy along the lines of SafePassage, but we have not tried + this.

    + +

    *  Will using this as my Security + Proxy compromise security?

    + +

    We're not security experts, but we don't think so. The whole + point of SSL is that the contents of messages are + + encrypted by the time they leave the browser and the server. + Eavesdroppers (including proxies) can see where your messages + are going whether you are running a proxy or not, but they only + get to see the contents after they have been encrypted.

    + +

    *  Can I restrict use of the proxy + to a set of nominated IP addresses?

    + +

    Yes, we added an access + control file in Version 2.0. But before you use it please + consider why you want to do it. If the reason is security, it + probably means you need a firewall.

    + +

    The listen-address option provides + a way of binding the proxy to a single IP address/port. The + right way to do this is to choose a port inside your firewall, + and deny access to it to those outside the firewall. The + Internet Junkbuster is not a firewall proxy; it should not be + expected to solve security problems.

    + +

    For background information on + firewalls, see Yahoo or a magazine article or these well-known + books: Firewalls and Internet Security: Repelling the + Wily Hacker by William R. Cheswick and Steven M. + Bellovin or Building Internet Firewalls by D. + Brent Chapman and Elizabeth D. Zwicky. There's + + free Linux software available, and a large number of commercial + products and services. For an excellent security overview, + primer, and compendium reference, see Practical Unix and + Internet Security by Simson Garfinkel and Gene + Spafford.

    + +

    *  Are there any security risks for + ISPs or others who offer the proxy?

    + +

    Yes. As with any service offered over the Internet, hackers + can try to misuse it. A well-run ISP will have professionals + who are experienced at assessing and containing these + risks.

    + +

    It's possible to set up your machine + so that other people can have access to your proxy, but if you + lack expertise in computer security you probably shouldn't have + your computer configured to offer this or any other service to + the outside world.

    + +

    Hackers can attempt to gain access to + the machine by various attacks, which we have tried to guard + against but don't guarantee to thwart. They can also use the + ``anonymizing'' quality of proxies to try to cover their tracks + while hacking other computers. For this reason we recommend + preventing it being used as an anonymous telnet by + putting the pattern :23 in the blockfile (it's + included as standard equipment). (Actually the current + implementation incidentally blocks telnet due to the way + headers are handled, but it's best not to rely on this.) If you + wish to block all ports except the default HTTP port 80, you + can put the lines
    +    :
    +    ~:80
    + at the beginning of the blockfile, but be aware that some + servers run on non-default ports (e.g. 8080). You might also + want to add the line ~:443 to allow SSL.

    + +

    On UNIX ® systems it is neither + necessary nor desirable for the proxy to run as root.

    + +

    Versions 2.0.1 and below may be + vulnerable to remote exploitation of a memory buffer bug; for + security reasons all users are encouraged to upgrade.

    + +

    If you find any security holes in the + code please tell us, along with any suggestions you may have + for fixing it. However, we do not claim that we will be able to + do so.

    + +

    We distribute this code in the hope + that people will find it useful, but we provide no warranty for + it, and we are not responsible for anyone's use or misuse of + it.

    + +

    You may also want to check back + periodically for updated versions of the code. We do not + currently maintain a mailing list. To get quick updates, + bookmark our Distribution Information page.

    + +

    --- Back to Top of Page ---

    + +

    + Website · + Manual · FAQ · GPL

    + +

    + Copyright © 1996-8 Junkbusters ® + Corporation. Copyright © 2001 + Jon + Foster. Copying and distribution permitted under the GNU General Public + License.

    + +

    + http://sourceforge.net/projects/ijbswa/

    + + + diff --git a/doc/obsolete/ijbman.html b/doc/obsolete/ijbman.html new file mode 100644 index 00000000..8329e572 --- /dev/null +++ b/doc/obsolete/ijbman.html @@ -0,0 +1,708 @@ + + + + + + Internet Junkbuster Technical Information + + + + + + +

    + Website · Manual · FAQ · GPL

    + +

    Internet + JUNKBUSTER + Technical Information

    + +

    + Options · + Checking Options · Installation · Copyright · (FAQ)

    + +

    This document is out of date

    + +

    Development of JunkBuster is ongoing and this document is + no longer current. However, it may provide some assistance. If + you have problems, please use the Yahoo Groups + mailing list (which includes an archive of mail), the + SourceForge.net project page, or + see the project's home + page. Please also bear in mind that versions 2.9.x of + JunkBuster are development releases, and are not production + quality.

    + +

    Manual Page

    + +

    A copy of this page in standard man macro + format is included in the tar + archive.

    + +

    *  Name

    + +

    junkbuster - The Internet Junkbuster + Proxy + TM

    + +

    *  Synopsis

    + +

    junkbuster configfile (Unix)
    + junkbstr.exe [configfile] + (Windows)

    + +

    +  Description

    + +

    junkbuster is an instrumentable proxy + that filters the HTTP stream between web servers and browsers. + Its main purposes are to block adverts and enhance privacy.

    + +

    It is configured using a configuration + file and several files listing URL patterns.  The + configuration file must be specified on the command line.  + The Windows version will default to using the configuration + file junkbstr.ini if it exists and no argument was + given.

    + +

    All files except the main configuration + file are checked for changes before each page is fetched, so + they may edited without restarting the proxy.

    + +

    Options

    + +
    +
    blockfile   + blockfile
    + +
    +

    Block requests to + URLs matching any pattern given in the lines of the + blockfile. The junkbuster instead + returns status 202, indicating that the request has been + accepted (though not completed), and a message identifying itself (though + the browser may display only a broken image icon).  + The syntax of a pattern is + [domain][:port][/path] (the http:// or + https:// protocol part is omitted). To decide + if a pattern matches a target, the domains are compared + first, then the paths.

    + +

    To compare the domains, the + pattern domain and the target domain specified in the URL + are each broken into their components. (Components are + separated by the . (period) character.) Next + each of the target components is compared with the + corresponding pattern component: last with last, + next-to-last with next-to-last, and so on. (This is called + right-anchored matching.) If all of the + pattern components find their match in the target, then the + domains are considered a match. Case is irrelevant when + comparing domain components.

    + +

    A successfully matching pattern + can be an anchored substring of a target, but not vice + versa. Thus if a pattern doesn't specify a domain, it + matches all domains. Furthermore, + when comparing two components, the components must either + match in their entirety or up to a wildcard * + (star character) in the pattern. The wildcard feature + implements only a "prefix" match capability ("abc*" vs. + "abcdefg"), not suffix matching ("*efg" vs. "abcdefg") or + infix matching ("abc*efg" vs. "abcdefg"). The feature is + restricted to the domain component; it is unrelated to the + optional regular expression feature in the path (described below).

    + +

    If a numeric port is specified in + the pattern domain, then the target port must match as + well. The default port in a target is port 80.

    + +

    If the domain and port match, then + the target URL path is checked for a match against the path + in the pattern. Paths are compared with a simple + case-sensitive left-anchored substring comparison. Once + again, the pattern can be an anchored substring of the + target, but not vice versa. A path of / + (slash) would match all paths. Wildcards are not considered + in path comparisons.

    + +

    For example, the target URL
    +     + the.yellow-brick-road.com/TinMan/has_no_brain
    + would be matched (and blocked) by the following + patterns
    +     yellow-brick-road.com
    + and
    +    Yellow*.COM
    + and
    +    /TinM
    + but not
    +     + follow.the.yellow-brick-road.com
    + or
    +    /tinman
    +

    + +

    Comments in a blockfile start + with a # (hash) character and end at a new + line. Blank lines are also ignored.

    + +

    Lines beginning with a + ~ (tilde) character are taken to be exceptions: a URL blocked by + previous patterns that matches the rest of the line is let + through. (The last match wins.)

    + +

    Patterns may contain POSIX regular expressions provided the + junkbuster was compiled with this + option (the default in Version 2.0 on). The idiom + /*.*/ad can then be used to match any URL containing + /ad (such as + http://nomatterwhere.com/images/advert/g3487.gif for + example). These expressions don't + work in the domain part.

    + +

    In version 1.3 and later the + blockfile and cookiefile are checked for changes before + each request.

    +
    + +
    wafer   + NAME=VALUE
    + +
    +

    Specifies a pair to be sent as a cookie with every + request to the server. + (Such boring cookies are called wafers.) This option + may be called more than once to generate multiple wafers. + The original Netscape specification prohibited semi-colons, + commas and white space; these characters will be + URL-encoded if used in wafers. + + + The Path and Domain attributes are not currently + supported.

    +
    + +
    cookiefile   + cookiefile
    + +
    +

    Enforce the cookie management policy specified in the + cookiefile. If this option is not + used all cookies are silently crunched, so that users who + never want cookies aren't bothered by browsers asking + whether each cookie should be accepted. However, cookies + can still get + through via + JavaScript and SSL, so alerts should be left on.

    + +

    In Version 1.2 and later this + option must be followed by a + filename containing instructions on which sites are + allowed to receive and set cookies. By + default cookies are dropped in both the browser's request + and the server's response, unless the URL requested matches + an entry in the cookiefile. The matching algorithm + is the same as for the blockfile. A leading + > character allows server-bound cookies only; a + < allows only browser-bound cookies; a + ~ character stops cookies in both directions. Thus a + cookiefile containing a single line with the two characters + >* will pass on all cookies to servers but + not give any new ones to the browser.

    +
    + +
    jarfile   + jarfile
    + +
    +

    All Set-cookie attempts by the server are logged to jarfile. If no wafer + is specified, one containing a canned notice (the vanilla + wafer) is added as an alert to the server unless the suppress-vanilla-wafer + option is invoked.

    +
    + +
    suppress-vanilla-wafer
    + +
    +

    Suppress the vanilla wafer.

    +
    + +
    from  from
    + +
    +

    If the browser discloses an + email address in the FROM header (most + don't), replace it with from. If from is set + to . (the period character) the FROM is + passed to the server unchanged. The default is to delete + the FROM header.

    +
    + +
    referer   + referer
    + +
    +

    Whenever the browser discloses the URL that led to the current request, + replace it with referer. If referer is set to + . (period) the URL is passed to the server + unchanged. If referer is set to @ (at) the URL is + sent in cases where the cookiefile specifies that a cookie + would be sent. (No way to send bogus referers selectively + is provided.) The default is to delete Referer.

    + +

    Junkbuster also accepts the + spelling referrer, which most dictionaries + consider correct.

    +
    + +
    user-agent   + user-agent
    + +
    +

    Information disclosed by the browser about itself is replaced with the + value user-agent. If user-agent is set to + . (period) the User-Agent header is passed + to the server unchanged, along with any UA + headers produced by MS-IE (which would otherwise be + deleted). If user-agent is set to @ (at) + these headers are sent unchanged in cases where the + cookiefile specifies that a cookie would be sent, otherwise + only default User-Agent header is sent. That + default is Mozilla/3.0 (Netscape) with an unremarkable Macintosh configuration. If + used with a browser less advanced than Mozilla/3.0 or IE-3, + the default may encourage pages containing extensions that + confuse the browser.

    +
    + +
    listen-address   + [host][:port]
    + +
    +

    If host is specified, bind the + junkbuster to that IP address. If a port + is specified, use it. The default port is 8000; the default + host is localhost.

    + +

    This default host setting means that you can only + connect to the proxy from ther local computer. This is a + security measure - if you allow anyone to use the proxy, + then hackers or fraudsters could use it to help hide their + identity. It also provides a lot of protection against any + undiscovered security flaws in JunkBuster - if they can't + connect to it, then they can't attack it.

    + +

    If you change this value, we recommend you either + set the host to localhost:
    +    listen-address + localhost:8080
    + or, if you want to share a single internet + connection over your internal network, then set it to the + address of your internal ethernet card:
    +    listen-address + 10.1.1.1:8080
    + (replace 10.1.1.1 with your internal IP address), + or set up an aclfile. To + make the proxy accessible from everywhere (e.g. if you're + using an access control list or if you just don't care + about security), specify just the port number - e.g:
    +    listen-address :8000
    + (This binds the proxy to all IP addresses + (INADDR_ANY)).

    +
    + +
    forwardfile   + forwardfile
    + +
    +

    Junkbuster has a flexible syntax for forwarding HTTP + requests. This is used e.g. if you are behind a firewall + and need to connect through it, or if you want to use a + cacheing proxy to speed up your web browsing.

    + +

    Every line in the forwardfile consists of four + components, seperated by whitespace. These are:
    +
    + target   forward_to   via_gateway_type +   gateway

    + +

    target is a pattern used to select which line of + the forwardfile is used. "*" is the most + commonly used value, and matches every URL. As usual, the + last matching target wins. (If no pattern matches, a + direct connection will be used)

    + +

    forward_to specifies the HTTP proxy server to + use, or "." for none. This is used to connect + to a cacheing proxy such as Squid, and for most types of + firewall. The port number defaults to 8000 if it is not + specified.

    + +

    Here is a typical line.

    +
    +*         lpwa.com:8000      .      .
    +
    + +

    The target domain need not be a fully qualified + hostname; it can be a general domain such as + com or co.uk or even just a port + number. For example, because LPWA does not handle SSL, the line above will + typically be followed by a line such as

    +
    +:443    .      .      .
    +
    + +

    to allow SSL transactions to proceed directly. The + cautious would also add an entry in their blockfile to stop + transactions to port 443 for all but specified trusted + sites.

    + +

    Configure with care: no loop + detection is performed. When setting up chains of proxies + that might loop back, try adding + Squid.

    + +

    via_gateway_type and gateway are used to + support SOCKS proxies. Some firewalls provide this type of + proxy. If you do not not want to use a SOCKS proxy, specify + both of these fields as ".".

    + +

    Note that + JunkBuster is a SOCKS client, not a SOCKS + server. The user's browser should not be configured to use + SOCKS; the proxy conducts the negotiations, not the + browser.

    + +

    The SOCKS4 protocol may be specified by + setting via_gateway_type to socks or + socks4. The SOCKS4A protocol is + specified as socks4a. The SOCKS5 + protocol is not currently supported.

    + +

    gateway should be the host and port of the SOCKS + server. If you just specify a hostname, then the port + number defaults to 1080.

    + +

    The user identification capabilities of + SOCKS4 are deliberately not used; the user is always + identified to the SOCKS server as + userid=anonymous. If the server's policy is to + reject requests from anonymous, the proxy will + not work. Use a debug value of 3 to see + the status returned by the server.

    + +

    If you specify both a HTTP proxy (with + forward_to) and a SOCKS proxy (with gateway) + then the SOCKS proxy is used to connect to the HTTP proxy. + If you just specify a SOCKS proxy, it is used to connect + directly to the websites.

    +
    + +
    debug  N
    + +
    +

    Set debug mode. The most common value is 1, to pinpoint offensive URLs, so they + can be added to the blockfile. The value of N is a + bitwise logical-OR of the following values:
    + 1 = URLs (show each URL requested by the browser);
    + 2 = Connections (show each connection to or from the + proxy);
    + 4 = I/O (log I/O errors);
    + 8 = Headers (as each header is scanned, show the header + and what is done to it);
    + 16 = Log everything (including debugging traces and the + contents of the pages).
    + 32 = Record accesses in Common Log Format, as used by most + web and proxy servers.

    + +

    Multiple debug lines are + permitted; they are logical OR-ed together.

    + +

    Because most browsers send several + requests in parallel the debugging output may appear + intermingled, so the + single-threaded option is recommended when using debug with N greater than 1. +

    +
    + +
    add-forwarded-header
    + +
    +

    Add X-Forwarded-For headers to the + server-bound HTTP stream indicating the client IP address + to the server, in the new + style of Squid 1.1.4. If you want the + traditional HTTP_FORWARDED response header, + add it manually with the -x option. This + also allows other X-Forwarded-For headers to + be transmitted - usually they are discarded.

    +
    + +
    add-header   + HeaderText
    + +
    +

    Add the HeaderText verbatim to requests to the + server. Typical uses include adding old-style forwarding + notices such as Forwarded: by + http://pro-privacy-isp.net and reinstating the + Proxy-Connection: Keep-Alive header (which the + junkbuster deletes so as not to reveal its existence). No + checking is done for correctness or plausibility, so it can + be used to throw any old trash into the server-bound HTTP + stream. Please don't litter. +

    +
    + +
    single-threaded
    + +
    +

    Doesn't fork() a separate process (or + create a separate thread) to handle each connection. Useful + when debugging to keep the process single threaded.

    +
    + +
    logfile   + logfile
    + +
    +

    Write all debugging data into logfile. The + default logfile is the standard output.

    +
    + +

    + aclfile   + aclfile
    + +
    +

    Unless this option is used, the proxy talks to anyone + who can connect to it, and everyone who can has equal + permissions on where they can go. An access file allows + restrictions to be placed on these two policies, by + distinguishing some source IP addresses + and/or some destination addresses. (If a + forwarder or a gateway is being + used, its address is considered the destination address, + not the ultimate IP address of the URL requested.)

    + +

    Each line of the access file begins + with either the word permit or + deny followed by source and (optionally) destination + addresses to be matched against those of the HTTP request. + The last matching line specifies the result: if it was a + deny line or if no line matched, the request + will be refused.

    + +

    A source or destination can be + specified as a single numeric IP address, or with a + hostname, provided that the host's name can be resolved to + a numeric address: this cannot be used to block all + .mil domains for example, because there is no single + address associated with that domain name. Either form may + be followed by a slash and an integer N, + specifying a subnet mask of N bits. For + example, permit 207.153.200.72/24 matches the + entire Class-C subnet from 207.153.200.0 through + 207.153.200.255. (A netmask of 255.255.255.0 corresponds to + 24 bits of ones in the netmask, as with + *_MASKLEN=24.) A value of 16 would be used for a + Class-B subnet. A value of zero for N in the + subnet mask length will cause any address to match; this + can be used to express a default rule. For more information + see the example file provided with the distribution.

    + +

    If you like these access controls + you should probably have + firewall; they are not intended to replace one.

    +
    + +

    + trustfile   + trustfile
    + +
    +

    This feature is experimental, has not been fully + documented and is very subject to change. The goal is for + parents to be able to choose a page or site whose links + they regard suitable for their young children and for the proxy + to allow access only to sites mentioned there. To do this + the proxy examines the referer variable + on each page request to check they resulted from a click on + the ``trusted referer'' site: if so the referred site is + added to a list of trusted sites, so that the child can + then move around that site. There are several uncertainties + in this scheme that experience may be able to iron out; + check back in the months ahead.

    +
    + +

    + + trust_info_url   + trust_info_url
    + +
    +

    When access is denied due to lack of a trusted referer, + this URL is displayed with a message pointing the user to + it for further information.

    +
    + +

    + hide-console
    + +
    +

    In the Windows command-line version only, instructs the + program to disconnect from and hide the command console + after starting.

    +
    +
    + +

    *  Installation and Use

    + +

    Browsers must be told where to find the + junkbuster (e.g. localhost port 8000). + To set the HTTP proxy in Netscape 3.0, go through: Options; Network Preferences; Proxies; Manual Proxy + Configuration; View. See the FAQ for other browsers. The Security Proxy should also be set to + the same values, otherwise shttp: URLs won't + work.

    + +

    Note the limitations explained in + the FAQ.

    + +

    *  Checking Options

    + +

    To allow users to check that + a junkbuster is running and how it is + configured, it intercepts requests for any URL ending in + /show-proxy-args and blocks it, returning instead + returns information on its version number and current + configuration including the contents of its blockfile. To get + an explicit warning that no junkbuster + intervened if the proxy was not configured, it's best to point + it to a URL that does this, such as + http://internet.junkbuster.com/cgi-bin/show-proxy-args on + Junkbusters's website.

    + +

    *  See Also

    + +

    + http://www.junkbusters.com/ht/en/ijbfaq.html
    + + http://www.junkbusters.com/ht/en/cookies.html
    + + http://internet.junkbuster.com/cgi-bin/show-proxy-args
    + http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html
    + + http://squid.nlanr.net/Squid/
    + + + http://www-math.uni-paderborn.de/~axel/

    + +

    +  Copyright and GPL

    + +

    Written and copyright by the Anonymous Coders and + Junkbusters Corporation and made available under the GNU General Public License (GPL). This software + comes with NO WARRANTY. Internet + Junkbuster Proxy is a + trademark of Junkbusters Corporation.

    + +

    --- Back to Top of Page ---

    + +

    + Website · Manual · FAQ · GPL

    + +

    + Copyright © 1996-8 Junkbusters ® + Corporation. Copyright © 2001 + Jon + Foster. Copying and distribution permitted under the GNU General Public + License.

    + +

    + http://sourceforge.net/projects/ijbswa/

    + + + diff --git a/doc/obsolete/top.gif b/doc/obsolete/top.gif new file mode 100755 index 00000000..8380083d 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 index 00000000..2a96d5a0 --- /dev/null +++ b/doc/pcrs.3 @@ -0,0 +1,479 @@ +.\" Copyright (c) 2001 Andreas S. Oesterhelt +.\" +.\" 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 " +.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 +#include + +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 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 index 00000000..76701ee8 --- /dev/null +++ b/doc/pdf/.gitignore @@ -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 index 00000000..2575a0bd 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 index 00000000..e5a458c3 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 index 00000000..012e2e43 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 index 00000000..2fa6e00e --- /dev/null +++ b/doc/source/.gitignore @@ -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 index 00000000..28691e8c --- /dev/null +++ b/doc/source/announce.sgml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + +]> + +
    + + + 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 + + +]]> + + + Announcing Privoxy + v.&p-version;, and release candidate for + v3.0 stable. + + + + &p-intro; + + + + In addition to the traditional features of Internet + Junkbuster, such as ad and banner blocking, cookie + management/protection, and HTTP header manipulation, + Privoxy + adds many enhancements, and new features in the same vein. + + + + &newfeatures; + + + + + + + + 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. + +]]> + + + Download location: + http://sourceforge.net/projects/ijbswa/ + + + + + Home Page: + http://www.privoxy.org/ + + + + +Privoxy Developers + +
    diff --git a/doc/source/authors.sgml b/doc/source/authors.sgml new file mode 100644 index 00000000..64b6728a --- /dev/null +++ b/doc/source/authors.sgml @@ -0,0 +1,67 @@ + + + + + + + + + +]> + +
    + + + + 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 + + +]]> + + + Authors of Privoxy v2.9.x and 3.x +=========================================================================== + + + + &authors; + + + + 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/doc/source/buildsource.sgml b/doc/source/buildsource.sgml new file mode 100644 index 00000000..8e4ee791 --- /dev/null +++ b/doc/source/buildsource.sgml @@ -0,0 +1,111 @@ + + + + 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-&p-version;-src* [.tgz or .tar.gz] + cd privoxy-&p-version; + + + + + 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. + +]]> diff --git a/doc/source/contacting.sgml b/doc/source/contacting.sgml new file mode 100644 index 00000000..d677c139 --- /dev/null +++ b/doc/source/contacting.sgml @@ -0,0 +1,119 @@ + + + + + + + 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: + + +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. + + + + +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. + + + +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. + + + +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. + + + +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. + + diff --git a/doc/source/copyright.sgml b/doc/source/copyright.sgml new file mode 100644 index 00000000..854d0191 --- /dev/null +++ b/doc/source/copyright.sgml @@ -0,0 +1,47 @@ + + + + + + Copyright &my-copy; 2001, 2002 by Privoxy Developers developers@privoxy.org + + + + Some source code is based on code Copyright &my-copy; 1997 by Anonymous Coders + and Junkbusters, Inc. and licensed under the GNU General Public + License. + + diff --git a/doc/source/developer-manual.sgml b/doc/source/developer-manual.sgml new file mode 100644 index 00000000..5049edd9 --- /dev/null +++ b/doc/source/developer-manual.sgml @@ -0,0 +1,2977 @@ + + + + + + + + + + + + + + + + +]> + + +
    + + Privoxy Developer Manual + + + + + Copyright &my-copy; 2001, 2002 by + Privoxy Developers + + + + + $Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $ + + + + + + + + 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 + + + ]]> + + The developer manual provides guidance on coding, testing, packaging, documentation + and other issues of importance to those involved with + Privoxy development. It is mandatory (and helpful!) reading + for anyone who wants to join the team. + + + + + + + + + + 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. + + + + + + + + + + + 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. + + + + 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. + + + + + + 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. + + + 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. + + + + 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). + + + + + + Discussing Changes First + + We don't have a too formal policy on this, just use common sense. Hints: If it is.. + + + ..a bugfix / clean-up / cosmetic thing: shoot + + + ..a new feature that can be turned off: shoot + + + ..a clear improvement w/o side effects on other parts of the code: shoot + + + ..a matter of taste: ask the list + + + ..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. + + + + + +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)? + + + + First, build the docs by running make + dok (or alternately make + redhat-dok). + + + 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). + + + + +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. + + + + + + <application>Privoxy</application> 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.) + + + + + + + + + + + + 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. &p-version;. + + + 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! + + + + + + + + + + + Coding Guidelines + + 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. ;-> + + + + Using Comments + + + 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. + + + + + + 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. + + + + + + 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 */ + + + + + 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. + + + + + + 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. + + + + + + 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 ) */ + + + + + + Naming Conventions + + + + 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; + + + + + + + + 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 ) + + + + + + + + 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 ) + + + + + + + + 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 */ + + + + + 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 + + + + + + + + + + Using Space + + + + 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 ); +} + + + + + 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. + + + + + + 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-) + + + + + + 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 ) + + + + + 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 (); + + + + + + 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. + + + + + + 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 ); + +} + + + + + + + Initializing + + + + 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. + + + + + + Functions + + + + 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(); + + + + + 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. + + + + + + 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. + + + + + + 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. + + + + + + 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 ) + + + + + + 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. + + + + + + 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 */ + + + + + 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 */ + + + + + 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. + + + + + + General Coding Practices + + + + 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. + + + + + + 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. + + + + + + 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. + + + + + + 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? + + + + + + 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. + + + + + + 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. + + + + + + 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'. + + + + + 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). + + + + + + 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. + + + + + + "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). + + + + + + + Addendum: Template for files and function + comment blocks: + + Example for file comments: + +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; + + + 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.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: +*/ + + + 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. + + + + + + + Testing Guidelines + To be filled. + + + + Testplan for releases + + Explain release numbers. major, minor. developer releases. etc. + + + +Remove any existing rpm with rpm -e + + +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* + + + +Install the rpm. Any error messages? + + start,stop,status Privoxy with the specific script + (e.g. /etc/rc.d/init/privoxy stop). Reboot your machine. Does + autostart work? + Start browsing. Does Privoxy work? Logfile written? + Remove the rpm. Any error messages? All files removed? + + + + + + 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). + + + + + + + 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. + + + + 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. + + + + + + + + + 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). + + + + + + + + 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. And details + on the Sourceforge release process below that. + + + + Note on Privoxy Packaging + + Please keep these general guidelines in mind when putting together + your package. These apply to all platforms! + + + + + + Privoxy requires + write access to: all *.action files, all + logfiles, and the trust file. You will + need to determine the best way to do this for your platform. + + + + + Please include up to date documentation. At a bare minimum: + + + + LICENSE (toplevel directory) + + + + + README (toplevel directory) + + + + + AUTHORS (toplevel directory) + + + + + man page (toplevel directory, Unix-like + platforms only) + + + + + The User Manual (doc/webserver/user-manual/) + + + + + FAQ (doc/webserver/faq/) + + + + Also suggested: Developer Manual + (doc/webserver/devel-manual) and ChangeLog + (toplevel directory). FAQ and the manuals are + HTML docs. There are also text versions in + doc/text/ which could conceivably also be + included. + + + The documentation has been designed such that the manuals are linked + to each other from parallel directories, and should be packaged + that way. index.html 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: + p_doc.css and p_web.css. + These should be in the same directory with + index.html, (i.e. one level up from the manual + directories). + + + + + user.action is designed for local preferences. + Make sure this does not get overwritten! + + + + + 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 :-) + + + + + Please check platform specific notes in this doc, if you haven't + done Privoxy 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). + + + + + + + + + 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. + + + + SuSE, Conectiva 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + 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. + + + + + + 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 + + + + + + Or use the make targets as described above. + + + 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. &p-version; + (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. + + + + + 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. + + + + + + + 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. + + + + + Contacting the developers, Bug Reporting and Feature Requests + + &contacting; + + + + + +Privoxy Copyright, License and History + + + ©right; + + + +License + + &license; + + + + + +History + + &history; + + + + + + + See also + + &seealso; + + + + + + +
    diff --git a/doc/source/faq.sgml b/doc/source/faq.sgml new file mode 100644 index 00000000..e32b52df --- /dev/null +++ b/doc/source/faq.sgml @@ -0,0 +1,1779 @@ + + + + + + + + + + + + + + + + + +]> + + + +
    + +Privoxy Frequently Asked Questions + + + + + + Copyright &my-copy; 2001, 2002 by + Privoxy Developers + + + +$Id: faq.sgml,v 1.60 2002/05/22 17:17:48 oes Exp $ + + + + + + + + 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 + + +]]> + + This FAQ gives quick answers to frequently asked questions about + Privoxy + . It can't and doesn't replace the + user manual. + + + + &p-intro; + + + + 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. + + + + + + + + + + + +General Information + +What is this new version of <application>Privoxy</application>? + + + &history; + + + + + + +Why <quote>Privoxy</quote>? Why a name change at all? + + Privoxy is the + Privacy Enhancing Proxy. Also, its content + modification and junk suppression allow you to browse your + private edition of the web. + + + Junkbusters Corporation + continues to offer their original version of the Internet + Junkbuster, so publishing our + Junkbuster-derived software under the same name + led to confusion. + + + There are also potential legal complications from the continued use of the + Junkbuster name, which is a registered trademark of + Junkbusters Corporation. + 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. + + + + +How does <application>Privoxy</application> differ +from the old <application>Junkbuster?</application> + + 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 upgrading from + Junkbuster 2.0.x. The blocklist + cookielist, imagelist and much more has been + combined into the actions files, with a completely different + syntax. See the note to + upgraders for details. + + + Privoxy's new features include: + + + + &newfeatures; + + + + +What is a <quote>proxy</quote>? How does +<application>Privoxy</application> work? + + A web proxy is a service, based on a software such as Privoxy, + 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. + + + 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. + + + Privoxy 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. + + + + + +How does <application>Privoxy</application> know what is +an ad, and what is not? + + Privoxy's approach to blocking ads is twofold: + + + First, there are certain patterns in the locations (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 banners!) + and the host (blocking the big banner hosting services like doublecklick.net + already helps a lot). Privoxy takes advantage of this + fact by using URL + patterns to sort out and block the requests for banners. + + + Second, banners tend to come in certain sizes. 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, Privoxy + 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. + + + Both of this involves a certain amount of guesswork and is, of course, freely + configurable. + + + + +Can <application>Privoxy</application> 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 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. + + + + 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.) + + + + + +My browser does the same things as +<application>Privoxy</application>. Why should I use +<application>Privoxy</application> 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. + + + + + +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! + + + + +I would like to help you, what do I do? + +Money Money Money + + We, of course, welcome donations and could use money for domain registering, + buying software to test Privoxy 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 drop us a note. + + + +Software + + If you are a vendor of a web-related software like a browser, web server + or proxy, and would like us to ensure that Privoxy + 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. + + + +You want to work with us? + + Well, helping the team is always a good idea. We welcome new developers, + packaging gurus or documentation writers. Simply get an account on SourceForge.net + and mail your id to the developers + mailing list. Then read 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. + + + + + + + + + + +Installation + + +Which browsers are supported by <application>Privoxy</application>? + + 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 + talks to the browser in the standardized HTTP protocol, just like a web server + does. + + + + +Which operating systems are supported? + +&supported; + + +Can I install + <application>Privoxy</application> over <application>Junkbuster</application>? + + We recommend you un-install Junkbuster + 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 note + to upgraders and installation + chapter in the user manual + for details. + + + Note: Some installers may automatically un-install + Junkbuster, if present! + + + + + +I just installed <application>Privoxy</application>. 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. + You should also flush your browser's memory and disk cache to get rid of any + cached junk items. + + + + + + +What is the proxy address of <application>Privoxy</application>? + + 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 127.0.0.1 + (sometimes referred to as 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 or the IP address 127.0.0.1 + 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. Note that Privoxy doesn't + listen on any LAN interfaces by default. + + + Privoxy does not currently handle + protocols such as FTP, SMTP, IM, IRC, ICQ, or other Internet + protocols. + + + + +I just installed <application>Privoxy</application>, 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://config.privoxy.org/. + This should take you to a page titled This is Privoxy.. with + access to Privoxy's internal configuration. + If you see this, then you are good to go. If you receive a page saying + Privoxy is not running, then the browser is not set up to use + your Privoxy installation. + If you receive anything else (probably nothing at all), it could either + be that the browser is not set up correctly, or that + Privoxy is not running at all. Check the log file. + + + + + + + + + + + +Configuration + +Can I use my old config files? + + The syntax, number, and purpose of configuration files has substantially + changed from Junkbuster and earlier versions + of Privoxy. The old files, like blocklist + 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. + + + + +What is an <quote>actions</quote> file? + + + Actions files + are where various actions + that Privoxy 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. + + + + Actions can be defined on a URL pattern 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 user.action + + + + + +The <quote>actions</quote> concept confuses me. Please list +some of these <quote>actions</quote>. + + For a comprehensive discussion of the actions concept, please refer + to the actions file + chapter in the user + manual. It includes a list of all actions + and an actions + file tutorial to get you started. + + + + + +How are actions files configured? What is the easiest +way to do this? + + + 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 + Privoxy's user interface with your web browser + at http://config.privoxy.org/ + (Shortcut: http://p.p/) and then select + View & + change the current configuration from the menu. + + + + + + +There are several different <quote>actions</quote> 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, the main actions file + which is actively maintained by the Privoxy + developers, user.action, where users are encouraged + to make their private customizations, and standard.action, + which is for internal Privoxy use only. + Please see the actions chapter + in the user manual for a more + detailed explanation. + + + + Earlier versions included three different versions of the + default.action file. The new scheme allows for + greater flexibility of local configuration, and for browser based + selection of pre-defined aggressiveness levels. + + + + +How can I make my Yahoo/Hotmail/GMX account work? + + 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 user.action file. An example for yahoo might + look like: + + + # Allow all cookies for Yahoo login: +# +{ -crunch-incoming-cookies -crunch-outgoing-cookies -session-cookies-only } +.login.yahoo.com + + + + + What's the difference between the +<quote>Cautious</quote>, <quote>Medium</quote> and <quote>Advenced</quote> defaults? + + Configuring Privoxy is not entirely trivial. To help you get + started, we provide you with three different default action packages in + the web based actions file editor at http://config.privoxy.org/show-status. + The following table shows you, which of the most important features are enabled in each + configuration: + + +Default Configurations + + + + + + + + Feature + Cautious + Intermadiate + Advanced + + + + + + + + + + + + + + Ad-blocking by URL + yes + yes + yes + + + + Ad-filtering by size + yes + yes + yes + + + + GIF de-animation + no + yes + yes + + + + Referer forging + no + yes + yes + + + + Cookie handling + none + session-only + kill + + + + Pop-up killing + no + no + yes + + + + Fast redirects + no + no + yes + + + + HTML taming + yes + yes + yes + + + + JavaScript taming + yes + yes + yes + + + + Web-bug killing + yes + yes + yes + + + + Fun text replacements + no + no + yes + + + + +
    +
    + + Where the defaults are likely to break some sites, exceptions for + known popular problem sites are included, but in + general, the more aggressive your default settings are, the more + exceptions you will have to make later. See the user manual for a more + deatiled discussion. + + +
    + + Why can I change the configuration +with a browser? Does that not raise security issues? + + It may seem strange that regular users can edit the config files with their + browsers, although 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 run Privoxy 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 enable-edit-actions + 0 and enable-remote-toggle + 0 in the main configuration file. + + + Note that in the default configuration, only local users (i.e. those on + localhost) can connect to Privoxy, + so this is not (normally) a security problem. + + + + + +What is the <filename>default.filter</filename> file? + + The default.filter + file is where filters are defined, which can be used to modify or + remove, web page content on the fly. This applies to anything + 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 + filter action. + + + + If you are familiar with regular expressions, and HTML, you can look at + the provided default.filter with a text editor and define + your own filters. This is potentially a very powerful feature, but + requires some expertise. + + + + 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 + default.filter file with the web-based actions file editor. + + + + + +How can I set up <application>Privoxy</application> to act as a proxy for my + LAN? + + By default, Privoxy only responds to requests + from 127.0.0.1 (localhost). To have it act as a server for + a network, this needs to be changed in the main configuration file. Look for + the listen-address + option, which 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. Assuming your LAN address is 192.168.1.1 and you + wish to run Privoxy on port 8118, this line + schould look like: + + + + + 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. + + + + If you run Privoxy on a LAN with untrusted users, + we recommend that you double-check the access control and security + options! + + + + + + +Instead of ads, now I get a checkerboard pattern. I don't want to see anything. + + The replacement for blocked images can be controlled with the set-image-blocker + action. You have the choice of a checkerboard pattern, a transparent 1x1 GIF + image (aka blank), 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 handle-as-image + and block action. + + + If you want to see nothing, then change the set-image-blocker + action to blank. This can be done by editing the + default.action file, or trough the web-based actions file editor. + + + + + +Why would anybody want to see a checkerboard pattern? + + Remember that telling which image is an ad and which + isn't, 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 don't have to see.. + + + + + + + +I see some images being replaced by a text +instead of the checkerboard image. Why and how do I get rid of this? + + 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. + + + 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. + + + 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 See why 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. + + + + + +Can <application>Privoxy</application> 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 (and its menu!) 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 the discussion + at http://sourceforge.net/tracker/?func=detail&atid=361118&aid=485617&group_id=11118, + for details, and a sample configuration. + + + + + + +How can I make <application>Privoxy</application> work with other +proxies like <application>Squid</application>? + + This can be done and is often useful to combine the benefits of + Privoxy with those of a caching proxy. + See the forwarding chapter + in the user manual which + describes how to do this. + + + + +Can <application>Privoxy</application> run as a <quote>transparent +</quote> 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 behind another proxy that has + this ability should work though. + See the forwarding chapter + in the user manual. As + a transparent proxy to be used for chaining we recommend Transproxy + (http://www.transproxy.nlc.net.au/). + + + + +
    + + + + + + +Miscellaneous + + +How much does <application>Privoxy</application> 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 content via the filter or + deanimate-gifs + actions may cause a perceived slowdown, since the entire document needs to be buffered + before displaying. See below. + + + + + +I noticed considerable +delays in page requests compared to the old Junkbuster. What's wrong? + + If you use any filter action, + such as filtering banners by size, web-bugs etc, or the deanimate-gifs + 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. + + + 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. + + + + +What are "http://config.privoxy.org/" and +"http://p.p/"? + + http://config.privoxy.org/ is the + address of Privoxy's built-in user interface, and + http://p.p/ is a shortcut for it. + + + Since Privoxy sits between your web browser and the Internet, + it can simply intercept requests for these addresses and answer them with its built-in + web server. + + + This also makes for a good test for your browser configuration: If entering the + URL http://config.privoxy.org/ + takes you to a page saying This is Privoxy.., everything is OK. + If you get a page saying Privoxy is not working instead, then + your browser didn't use Privoxy for the request, + hence it could not be intercepted, and you have accessed the real + web site at config.privoxy.org. + + + With recent versions of Privoxy (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 actions files. + + + + Note that the built-in URLs from earlier versions of Junkbuster + / Privoxy, 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;. + + + + + +Do you still maintain the blocklists? + + No. The patterns for blocking now reside (among other things) in the actions files, which are + actively maintained instead. See next question ... + + + +How can I submit new ads? + +Yes, absolutely! Please see the Contact section for +how to do that. Please note that you (technically) need the latest +Privoxy version for this to work. + + + + +How can I hide my IP address? + + If you run both the browser and the proxy locally, you cannot hide your IP + address with Privoxy or any other software. 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. A particularly interesting project is the JAP service + offered by the Technical University of Dresden (http://anon.inf.tu-dresden.de/index_en.html. + + + 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. + + + + +Can <application>Privoxy</application> 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! + + + + + +Might some things break because header information or +content 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 (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. + + + + 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. (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. + + + + Similar thoughts apply to modifying JavaScript, and, to a lesser degree, + HTML elements. + + + + 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. + + + + + + +Can <application>Privoxy</application> act as a <quote>caching</quote> 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. + See the forwarding + chapter in the user + manual for details. + + + + +What about as a firewall? Can <application>Privoxy</application> protect me? + + Not in the way you mean, or in the way a true firewall can. + Privoxy can help protect your privacy, but not + protect you from intrusion attempts. It is, of course, perfectly possible + and recommended to use both. + + + + + + +I have large empty spaces / a checkerboard pattern now where +ads used to be. Why? + + 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. + + + 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. + + + So we won't support this in the default configuration, but you can of course + define appropriate filters yourself. + + + + +How can <application>Privoxy</application> filter Secure (HTTPS) URLs? + + Since secure HTTP connections are encrypted SSL sessions between your browser + and the secure site, and are meant to be reliably secure, + there is little that Privoxy can do but hand the raw + gibberish data though from one end to the other unprocessed. + + + The only exception to this is blocking by host patterns, as the client needs + to tell Privoxy the name of the remote server, + so that Privoxy can establish the connection. + If that name matches a host-only pattern, the connection will be blocked. + + + 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 + Privoxy's ad blocking. + + + + + +<application>Privoxy</application> runs as a <quote>server</quote>. How +secure is it? Do I need to take any special precautions? + + There are no known exploits that might affect + 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 only. 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 configuration file and check all access control and security + options. All LAN hosts can then use this as their proxy address + in the browser proxy configuration, but Privoxy + 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. + + + + + +How can I temporarily disable <application>Privoxy</application>? + + The easiest way is to access Privoxy with your + browser by using the remote toggle URL: http://config.privoxy.org/toggle. + + + + +Where can I find more information about <application>Privoxy</application> +and related issues? + + &seealso; + + + + + + + + + + + +Troubleshooting + + +I just upgraded and am getting <quote>connection refused</quote> +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 the listen-address + option in Privoxy's main configuration file. + + + + + +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 it really matches your new rule. + + + + + +One of my favorite sites does not work with <application>Privoxy</application>. +What can I do? + + + First verify that it is indeed a Privoxy problem, + by toggling off Privoxy through http://config.privoxy.org/toggle, + 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). + + + + If still a problem, go to http://config.privoxy.org/show-url-info + 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 http://config.privoxy.org/show-status + and select the appropriate actions files for editing. + + + 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! + + + 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 { fragile } section in user.action, + which is an alias that turns off most dangerous + actions, but is also likely to turn off more actions then needed, and thus lower + your privacy and protection more than necessary, + + + Troubleshooting actions is discussed in more detail in the user-manual appendix. + There is also an actions tutorial. + + + + + + + + + + + + Contacting the developers, Bug Reporting and Feature Requests + + &contacting; + + + + +Privoxy Copyright, License and History + + + ©right; + + + + Portions of this document are borrowed from the original + Junkbuster (tm) FAQ, and modified as + appropriate for Privoxy. + + + + License + + &license; + + + + + + History + + &history; + + + + + + + + + + + + + + + + + +
    diff --git a/doc/source/history.sgml b/doc/source/history.sgml new file mode 100644 index 00000000..057da5e7 --- /dev/null +++ b/doc/source/history.sgml @@ -0,0 +1,72 @@ + + + + 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. + + diff --git a/doc/source/ldp.dsl.in b/doc/source/ldp.dsl.in new file mode 100644 index 00000000..67343f85 --- /dev/null +++ b/doc/source/ldp.dsl.in @@ -0,0 +1,416 @@ + + + +]]> + + +]]> +]> + + + + + + + + +;; ============================== +;; customize the print stylesheet +;; ============================== +;; +;; see http://docbook.sourceforge.net/projects/dsssl/doc/print.html +;; + +(define %indent-screen-lines% + ;; Indent lines in a 'Screen'? + #t) + +(define %callout-fancy-bug% + ;; Use fancy callout bugs? + #t) + +(define %chap-app-running-heads% + ;; Generate running headers and footers on chapter-level elements? + #t) + +(define %chap-app-running-head-autolabel% + ;; Put chapter labels in running heads? + #t) + +;; this is necessary because right now jadetex does not understand +;; symbolic entities, whereas things work well with numeric entities. +(declare-characteristic preserve-sdata? + "UNREGISTERED::James Clark//Characteristic::preserve-sdata?" + #f) + +;; put the legal notice in a separate file +(define %generate-legalnotice-link% + #t) + +;; use graphics in admonitions, and have their path be "stylesheet-images" +;; NO: they do not yet look very good +(define %admon-graphics-path% + "./stylesheet-images/") + +(define %admon-graphics% + #f) + +(define %funcsynopsis-decoration% + ;; make funcsynopsis look pretty + #t) + +;;(define %shade-verbatim% +;; #t) + +(define %section-autolabel% #t) + ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.) + +;; HB changed TOC depth to 3 levels. +(define (toc-depth nd) + 3) + +;; HB added 03/20/02, see dbparam.dsl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define %body-attr% + ;; REFENTRY body-attr + ;; PURP What attributes should be hung off of BODY? + ;; DESC + ;; A list of the the BODY attributes that should be generated. + ;; The format is a list of lists, each interior list contains the + ;; name and value of a BODY attribute. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + (list + (list "BGCOLOR" "#EEEEEE") + (list "TEXT" "#000000") + (list "LINK" "#0000FF") + (list "VLINK" "#840084") + (list "ALINK" "#0000FF"))) + +(define %stylesheet% + ;; REFENTRY stylesheet + ;; PURP Name of the stylesheet to use + ;; DESC + ;; The name of the stylesheet to place in the HTML LINK TAG, or '#f' to + ;; suppress the stylesheet LINK. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + "../p_doc.css") + +(define %stylesheet-type% + ;; REFENTRY stylesheet-type + ;; PURP The type of the stylesheet to use + ;; DESC + ;; The type of the stylesheet to place in the HTML LINK TAG. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + "text/css") + +(define %css-liststyle-alist% + ;; REFENTRY css-liststyle-alist + ;; PURP Map DocBook OVERRIDE and MARK attributes to CSS + ;; DESC + ;; If '%css-decoration%' is turned on then the list-style-type property of + ;; list items will be set to reflect the list item style selected in the + ;; DocBook instance. This associative list maps the style type names used + ;; in your instance to the appropriate CSS names. If no mapping exists, + ;; the name from the instance will be used. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + '(("bullet" "disc") + ("box" "square"))) + +(define %css-decoration% + ;; REFENTRY css-decoration + ;; PURP Enable CSS decoration of elements + ;; DESC + ;; If '%css-decoration%' is turned on then HTML elements produced by the + ;; stylesheet may be decorated with STYLE attributes. For example, the + ;; LI tags produced for list items may include a fragment of CSS in the + ;; STYLE attribute which sets the CSS property "list-style-type". + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + #t) + +;; swa1 + +(define %generate-part-toc% + #f) + +(define %generate-article-toc% + ;; Should a Table of Contents be produced for Articles? + ;; If true, a Table of Contents will be generated for each 'Article'. + #t) + +(define %generate-part-toc-on-titlepage% + ;; Should the Part TOC appear on the Part title page? + #f) + +;;Do you want a separate page for the title? +(define %generate-article-titlepage-on-separate-page% + #t) + +;;Do you want the article toc on the titlepage or separate? +(define %generate-article-toc-on-titlepage% + #f) + +;;Titlepage Separate? +;; This is the one that makes TOC only on first page!! hal. +(define (chunk-skip-first-element-list) + '()) + +(define %body-start-indent% + ;; Default indent of body text + 2pi) + +(define %para-indent-firstpara% + ;; First line start-indent for the first paragraph + 0pt) + +;; swa2 + +(define %para-indent% + ;; First line start-indent for paragraphs (other than the first) + 0pt) + +(define %block-start-indent% + ;; Extra start-indent for block-elements + 2pt) + +;;Define distance between paragraphs +(define %para-sep% + (/ %bf-size% 2.0)) + +;; with swa2 no effects + +;; swa3 + +;;Define distance between block elements (figures, tables, etc.). +(define %block-sep% + (* %para-sep% 1.0)) +;; (* %para-sep% 2.0)) + +(define %hyphenation% + ;; Allow automatic hyphenation? + #t) + +(define %left-margin% 5pi) +(define %right-margin% 5pi) +(define %top-margin% 5pi) +(define %bottom-margin% 5pi) +(define %footer-margin% 2pi) +(define %header-margin% 2pi) + +(define %line-spacing-factor% 1.3) + ;; Factor used to calculate leading + ;; The leading is calculated by multiplying the current font size by the + ;; '%line-spacing-factor%'. For example, if the font size is 10pt and + ;; the '%line-spacing-factor%' is 1.1, then the text will be + ;; printed "10-on-11". + +(define %head-before-factor% + ;; Factor used to calculate space above a title + ;; The space before a title is calculated by multiplying the font size + ;; used in the title by the '%head-before-factor%'. +;; 0.75) + 0.5) + +(define %head-after-factor% + ;; Factor used to calculate space below a title + ;; The space after a title is calculated by multiplying the font size used + ;; in the title by the '%head-after-factor%'. + 0.5) + +(define %input-whitespace-treatment% 'collapse) + +(define ($generate-article-lot-list$) + ;; Which Lists of Titles should be produced for Articles? + (list )) + + + + + + + + + + + +;; this is necessary because right now jadetex does not understand +;; symbolic entities, whereas things work well with numeric entities. +(declare-characteristic preserve-sdata? + "UNREGISTERED::James Clark//Characteristic::preserve-sdata?" + #f) + +;; put the legal notice in a separate file +(define %generate-legalnotice-link% + #t) + +;; use graphics in admonitions, and have their path be "stylesheet-images" +;; NO: they do not yet look very good +(define %admon-graphics-path% + "./stylesheet-images/") + +(define %admon-graphics% + #f) + +(define %funcsynopsis-decoration% + ;; make funcsynopsis look pretty + #t) + +(define %html-ext% + ".html") + +(define %generate-article-toc% + ;; Should a Table of Contents be produced for Articles? + ;; If true, a Table of Contents will be generated for each 'Article'. + #t) + +;; HB added next three statements 05/03/02. +;;Do you want a separate page for the title? +(define %generate-article-titlepage-on-separate-page% + #t) + +;;Do you want the article toc on the titlepage or separate? +(define %generate-article-toc-on-titlepage% + #t) + +;;Titlepage Separate? +;; This is the one that makes TOC only on first page!! hal. +(define (chunk-skip-first-element-list) + '()) + +(define %root-filename% + ;; The filename of the root HTML document (e.g, "index"). + "index") + +(define %generate-part-toc% + #t) + +(define %shade-verbatim% + #t) + +(define %use-id-as-filename% + ;; Use ID attributes as name for component HTML files? + #t) + +(define %graphic-default-extension% + "gif") + +(define %section-autolabel% #t) + ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.) + +;; HB changed TOC depth to 3 levels. +(define (toc-depth nd) + 3) + +;; HB added 03/20/02, see dbparam.dsl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define %body-attr% + ;; REFENTRY body-attr + ;; PURP What attributes should be hung off of BODY? + ;; DESC + ;; A list of the the BODY attributes that should be generated. + ;; The format is a list of lists, each interior list contains the + ;; name and value of a BODY attribute. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + (list + (list "BGCOLOR" "#EEEEEE") + (list "TEXT" "#000000") + (list "LINK" "#0000FF") + (list "VLINK" "#840084") + (list "ALINK" "#0000FF"))) + +(define %stylesheet% + ;; REFENTRY stylesheet + ;; PURP Name of the stylesheet to use + ;; DESC + ;; The name of the stylesheet to place in the HTML LINK TAG, or '#f' to + ;; suppress the stylesheet LINK. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + "../p_doc.css") + +(define %stylesheet-type% + ;; REFENTRY stylesheet-type + ;; PURP The type of the stylesheet to use + ;; DESC + ;; The type of the stylesheet to place in the HTML LINK TAG. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + "text/css") + +(define %css-liststyle-alist% + ;; REFENTRY css-liststyle-alist + ;; PURP Map DocBook OVERRIDE and MARK attributes to CSS + ;; DESC + ;; If '%css-decoration%' is turned on then the list-style-type property of + ;; list items will be set to reflect the list item style selected in the + ;; DocBook instance. This associative list maps the style type names used + ;; in your instance to the appropriate CSS names. If no mapping exists, + ;; the name from the instance will be used. + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + '(("bullet" "disc") + ("box" "square"))) + +(define %css-decoration% + ;; REFENTRY css-decoration + ;; PURP Enable CSS decoration of elements + ;; DESC + ;; If '%css-decoration%' is turned on then HTML elements produced by the + ;; stylesheet may be decorated with STYLE attributes. For example, the + ;; LI tags produced for list items may include a fragment of CSS in the + ;; STYLE attribute which sets the CSS property "list-style-type". + ;; /DESC + ;; AUTHOR N/A + ;; /REFENTRY + #t) + + + + + + + + + +;; =================================================== +;; Vairant without TOC for the Homepage --oes 24/05/02 +;; =================================================== + +(define %generate-article-toc% + ;; Should a Table of Contents be produced for Articles? + ;; If true, a Table of Contents will be generated for each 'Article'. + #f) + + + + + + + diff --git a/doc/source/license.sgml b/doc/source/license.sgml new file mode 100644 index 00000000..79df71cb --- /dev/null +++ b/doc/source/license.sgml @@ -0,0 +1,71 @@ + + + + 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
    +
    + diff --git a/doc/source/newfeatures.sgml b/doc/source/newfeatures.sgml new file mode 100644 index 00000000..65a1e073 --- /dev/null +++ b/doc/source/newfeatures.sgml @@ -0,0 +1,130 @@ + + + + + + + + + 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. + + + + + diff --git a/doc/source/p-authors.sgml b/doc/source/p-authors.sgml new file mode 100644 index 00000000..8d1c2d5a --- /dev/null +++ b/doc/source/p-authors.sgml @@ -0,0 +1,88 @@ + + + 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 + jwz + Michael T. Davis + +]]> diff --git a/doc/source/privoxy-man-page.sgml b/doc/source/privoxy-man-page.sgml new file mode 100644 index 00000000..026f511e --- /dev/null +++ b/doc/source/privoxy-man-page.sgml @@ -0,0 +1,422 @@ + + + + + + + + + + + + + + +]> + + + + 2002-05-14 + + + privoxy + 1 + + Privoxy &p-version; + + + + + privoxy + Privacy Enhancing Proxy + + + + + privoxy + + + + pidfile + user[.group] + configfile + (UNIX) + + + + privoxy.exe + configfile + (Windows) + + + + + +Options + + Privoxy may be invoked with the following command line + options: + + + + + --help + + + Print brief usage info and exit. + + + + + + --version + + + Print version info and exit. + + + + + + --no-daemon + + + 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. + + + + + + --pidfile pidfile + + + On startup, write the process ID to pidfile. + Delete the pidfile on exit. + Failiure to create or delete the pidfile + is non-fatal. If no --pidfile option is given, no PID file will be used. + + + + + + --user user[.group] + + + + + After (optionally) writing the PID file, assume the user ID of + user and the GID of + group, or, if the optional + group was not given, the default group of + user. Exit if the privileges are not + sufficient to do so. + + + + + + + If the configfile is not 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). If no + configfile is found, Privoxy will + fail to start. + + + + + + +Description + + &p-intro; + + + + + +Installation and Usage + + Browsers must be individually configured to use Privoxy 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: Edit; + Preferences; Advanced; + Proxies; Manual Proxy Configuration; + View. + + + For Internet Explorer, go through: Tools; + Internet Properties; Connections; + LAN Settings. + + + The Secure (SSL) Proxy should also be set to the same values, otherwise + https: URLs will not be proxied. + + + For other browsers, check the documentation. + + + + + +Configuration + + Privoxy can be configured with the various configuration + files. The default configuration files are: config, + default.filter, and + default.action. user.action should + be used for locally defined exceptions to the default rules of + default.action These are all well commented. On Unix + and Unix-like systems, these are located in + /etc/privoxy/ by default. On Windows, OS/2 and AmigaOS, + these files are 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. 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. + + + The actions list (ad blocks, etc) can also be configured with your + web browser at http://config.privoxy.org/. + Privoxy's configuration parameters can also be viewed at + the same page. In addition, Privoxy can be toggled on/off. + This is an internal page. + + + + + +Sample Configuration + + A brief example of what a simple default.action + configuration might look like: + + + + # 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. + + + + + Then for a user.action, we would put local, + narrowly defined exceptions: + + + + # 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 + + + + + See the comments in the configuration files themselves, or the + user-manual + for explanations of the above syntax, and other Privoxy + configuration options. + + + + + + +Files + + + /usr/sbin/privoxy + /etc/privoxy/config + /etc/privoxy/default.action + /etc/privoxy/standard.action + /etc/privoxy/user.action + /etc/privoxy/default.filter + /etc/privoxy/trust + /etc/privoxy/templates/* + /var/log/privoxy/logfile + + + + 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. + + + + + + +Signals + + + Privoxy terminates on the SIGINT, + SIGTERM and SIGABRT signals. Log + rotation scripts may cause a re-opening of the logfile by sending a + SIGHUP to Privoxy. Note that unlike + other daemons, Privoxy does not need to be made aware of + config file changes by SIGHUP -- it will detect them + automatically. + + + + + +Notes + + This is a &p-status; version of Privoxy. Not + all features are well tested. +]]> + + Please see the user-manual on how to contact the + developers for feature requests, reporting problems, and other questions. + + + + + +See Also + + &seealso; + + + + +Development Team + + &authors; + + + + +Copyright and License + +Copyright + + ©right; + + + +License + + &license; + + + + + diff --git a/doc/source/privoxy.sgml b/doc/source/privoxy.sgml new file mode 100644 index 00000000..8ecbcc39 --- /dev/null +++ b/doc/source/privoxy.sgml @@ -0,0 +1,42 @@ + + + + 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). + diff --git a/doc/source/readme.sgml b/doc/source/readme.sgml new file mode 100644 index 00000000..0970d429 --- /dev/null +++ b/doc/source/readme.sgml @@ -0,0 +1,244 @@ + + + + + + + + + + + + +]> + +
    + + + + 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 + + +]]> + + + + + +/********************************************************************* + * + * 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 + Privoxy &p-version;. See http://www.privoxy.org/ for more information. The current code + level is &p-status;. + + + + + +&p-intro; + + + +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. + + + + +INSTALL + + &buildsource; + + + + +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 + + + + +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. + +]]> + + + +DOCUMENTATION + + There should be documentation in the 'doc' subdirectory. In particular, see the user-manual there, + the faq, and those interested in Privoxy development, should look at + developer-manual. + + + The source and configuration files are all well + commented. The main configuration files are: 'config', 'default.action', and + 'default.filter'. + + + + Included documentation may vary according to platform and packager. + + + + +CONTACTING THE DEVELOPERS, BUG REPORTING AND FEATURE REQUESTS + + &contacting; + + + + + + + + + + + + + +
    diff --git a/doc/source/seealso.sgml b/doc/source/seealso.sgml new file mode 100644 index 00000000..22dc127e --- /dev/null +++ b/doc/source/seealso.sgml @@ -0,0 +1,107 @@ + + + + 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. + + + diff --git a/doc/source/supported.sgml b/doc/source/supported.sgml new file mode 100644 index 00000000..072b815e --- /dev/null +++ b/doc/source/supported.sgml @@ -0,0 +1,45 @@ + + + At present, Privoxy 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. + + + + 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. + +]]> diff --git a/doc/source/user-manual.sgml b/doc/source/user-manual.sgml new file mode 100644 index 00000000..60ab2810 --- /dev/null +++ b/doc/source/user-manual.sgml @@ -0,0 +1,7581 @@ + + + + + + + + + + + + + + + + + + + + + + + +]> + + +
    + + +Privoxy User Manual + + + + + + Copyright &my-copy; 2001, 2002 by + Privoxy Developers + + + +$Id: user-manual.sgml,v 1.122 2002/05/24 13:24:08 oes Exp $ + + + + + + + + + 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 + + +]]> + + + The User Manual gives users information on how to + install, configure and use Privoxy. + + + + &p-intro; + + + + 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. + + + + + + + + + + +Introduction + + This documentation is included with the current &p-status; version of + Privoxy, v.&p-version;soon ;-)]]>. + + + + + 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 may be bugs, though hopefully + not many! + +]]> + + +Features + + In addition to Internet Junkbuster's traditional + features of ad and banner blocking and cookie management, + Privoxy provides new features: + + + &newfeatures; + + + + + + + + + +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. + + + +Binary Packages + +How to install the binary packages depends on your operating system: + + + +Red Hat, SuSE and Conectiva RPMs + + + RPMs can be installed with rpm -Uvh privoxy-&p-version;-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-&p-version;-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. + + + + +Debian + + DEBs can be installed with dpkg -i + privoxy_&p-version;-1.deb, and will use + /etc/privoxy for the location of configuration + files. + + + + +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. + + + + +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. + + + + +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. + + + + +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. + + + + +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). + + + + + +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. + + + +&buildsource; + + + + + + + + + + +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. + + + + + + + + +Quickstart to Using <application>Privoxy</application> + + + + + + 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. + next section for a quick + introduction to how Privoxy blocks ads and + banners.]]> + + + + + + 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! + + + + + + + + + + +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 recommended. + + + 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. The + actions, together with the URL patterns are called a section. + + + When you connect to a website, the full URL will either match one or more + of the sections as defined in Privoxy's configuration, + or not. If so, then Privoxy 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. + + + + 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 and sends Privoxy's + own built-in BLOCKED page instead to let you now what has happened. + + + + + + handle-as-image - + tells Privoxy to treat this URL as an image. + Privoxy'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 + Privoxy BLOCKED page (which would only result in + a broken image 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. + + + + + + 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 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 image anywhere + 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: + + + + +
    Actions Files in Use + + + + + + [ Screenshot of Actions Files in Use ] + + +
    +
    +
    + + + + You should have a section with only + block listed under + Actions:. + If not, click a Insert new section below + button, and in the new section that just appeared, click the + Edit button right 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 (or + OK if in a pop-up window). + + + + + 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. + The ideas explained thererin also apply to the web-based editor. + + +
    + +
    + + + + + + +Starting <application>Privoxy</application> + + 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! + + + + +
    Proxy Configuration (Mozilla) + + + + + + [ Screenshot of Mozilla Proxy Configuration ] + + +
    +
    + + + With Netscape (and + Mozilla), this can be set under: + + + + + + Edit + |_ + Preferences + |_ + Advanced + |_ + Proxies + |_ + HTTP Proxy + + + + For Internet Explorer: + + + + + + Tools + |_ + Internet Properties + |_ + Connections + |_ + LAN Settings + + + + Then, check Use Proxy and fill in the appropriate info + (Address: 127.0.0.1, Port: 8118). Include HTTPS (SSL), if you want 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. + + + +RedHat and Conectiva + + 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. + + + + # /etc/rc.d/init.d/privoxy start + + + + + +Debian + + We use a script. Note that Debian starts Privoxy upon booting per + default. It will use the file + /etc/privoxy/config as its main configuration + file. + + + + # /etc/init.d/privoxy start + + + + + +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 + + + + + +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. + + + + +Solaris, NetBSD, FreeBSD, HP-UX and others + +Example Unix startup command: + + + + # /usr/sbin/privoxy /etc/privoxy/config + + + + + +OS/2 + +FIXME. + + + + +MAX OSX + +FIXME. + + + + + +AmigaOS + +FIXME. + + + + + + + +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. + + + + + + + + +
    + + + + + +<application>Privoxy</application> 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. + + + + + + +Controlling <application>Privoxy</application> 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. + + + + + + + + + + + + +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 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. + +]]> + + + + + + + + + +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). + + + + + + +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. + + +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). + + + + + + + +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 + + + + + + + +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. + + + + + + +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. + + + + + + +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). + + + + + + +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. + + + + + + +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. + + + + + + + + + + + + + + +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. + + +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-&p-version;/user-manual/ + + + Any platform, on local webserver (called local-webserver): + + + user-manual  http://local-webserver/privoxy-user-manual/ + + + + If set, this option should be the first option in the config file, because + it is used while the config file is being read. + + + + + + + +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! + + + + + + +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. + + + + + + +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 ;-) + + + + + + + + + + + + +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. + + +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. + + + + + + +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. + + + + + + + + + + + +Access Control and Security + + + This section of the config file controls the security-relevant aspects + of Privoxy's configuration. + + +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 below), and/or + a firewall. + + + If you open Privoxy to untrusted users, you will + also want to turn off the enable-edit-actions and + enable-remote-toggle + options! + + + + + 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 + + + + + + + +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. + + + + + + + +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-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. + + + + + + + +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 + + + + + + + +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. + + + + + + + + + + + + + + +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. + + +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 . + + + + + + + + +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 . + + + + + + + +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. + + + + + + + + + + + + +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 + + + + + + + + + + + + + + +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. + + + + +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 :). + + + + + +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. + + + + + +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 a regular section with + a heading line of { + +handle-as-image }, + then later another one with just { + +block }, resulting + in both actions to apply. + + + + 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. + + + + + +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. + + + + + + + +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. + + + + + + + + + + + +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. + + + + + + + + + + + +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: + + + + + + + + + + + + + +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} + + + + + + + + + +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 + + + + + + + + + + +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 + + + + + + + + + +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 + + + + + + + + + + +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} + + + + + + + + +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 + + + + + + + + + +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} + + + + + + + + + + +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" + + + + + + + + + +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 + + + + + + + + + + +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 + + + + + + + + + +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} + + + + + + + + + +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/} + + + + + + + + + +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: + + + + 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)} + + + + + + + + + +kill-popups<anchor id="kill-popup"> + + + + 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 + + + + + + + + +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!) + + + + + + + + +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 + + + + + + + + + + +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 + + + + + + + + + + +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 + + + + + + + + + +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 + + + + + + + + + +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} + + + + + + + + + +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. + + + + + + +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. + + + + + +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: + + +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. + + + + +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 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 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. + + + + + + + + + + + + + +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. + + + + +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? + + + + + + + + + + + +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. + + + + + + + + + + +Contacting the Developers, Bug Reporting and Feature +Requests + + + &contacting; + + + + + + + + +<application>Privoxy</application> Copyright, License and History + + + ©right; + + + +License + + &license; + + + + + + + +History + + &history; + + + +Authors + + &p-authors; + + + + + + + + + +See Also + + &seealso; + + + + + + +Appendix + + + + +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. + + + + + + + + +<application>Privoxy</application>'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. + + + + +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 + + + + + Privoxy - Why? + + + + + + + Credit: The site which gave us the general idea for these bookmarklets is + www.bookmarklets.com. They + have more information about bookmarklets. + + + + + +
    + + + + +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. + + + + + + + + + + + +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/source/webserver/index.sgml b/doc/source/webserver/index.sgml new file mode 100644 index 00000000..d01cf4d6 --- /dev/null +++ b/doc/source/webserver/index.sgml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + +]> + + +
    + + Privoxy - Homepage + + + + + privoxy HTTP proxy privacy + popups po-ups HTML JavaScript + cleaning blocking cleaner blocker + filter proxy junk ad + advertisement banner webbugs + web-bugs werbung junkbusters + junkbuster + + + + + + + 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 + + +]]> + + + &p-intro; + + + + The most recent release is &p-version; (&p-status;). + + + + + + + + +Download + + + + + Download recent releases + + + + + Download the latest CVS snapshot (source tarball) + + + + + Quickstart after installation + + + + + + +Documentation + + + + + User manual + + + + + Frequently Asked Questions + + + + + Developer Manual + + + + + Classic Man Page + + + + + + +More information + + + + + Support & Service + + + + + Copyright, License, History & Authors + + + + + List of (new) Features + + + + + The project page at SourceForge + + + + + Related links + + + + + Pictures of the Privoxy Team + + + + + + + + + + + + + + + + + + + Prixoxy is developed on: + + + + + + + + + + + + + + + + + + + + Copyright © 2001, 2002 by Privoxy Developers + + + + + + + +
    diff --git a/doc/text/developer-manual.txt b/doc/text/developer-manual.txt new file mode 100644 index 00000000..99df01d2 --- /dev/null +++ b/doc/text/developer-manual.txt @@ -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: My 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 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 index 00000000..5c4cbeb8 --- /dev/null +++ b/doc/text/faq.txt @@ -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 index 00000000..e3566a08 --- /dev/null +++ b/doc/text/user-manual.txt @@ -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/USER_DOC_IS_WIDELY_OBSOLETED b/doc/webserver/.gitignore similarity index 100% rename from doc/USER_DOC_IS_WIDELY_OBSOLETED rename to doc/webserver/.gitignore diff --git a/doc/webserver/.htaccess b/doc/webserver/.htaccess new file mode 100644 index 00000000..e2c3e3db --- /dev/null +++ b/doc/webserver/.htaccess @@ -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 index 00000000..4221e3a8 --- /dev/null +++ b/doc/webserver/README.txt @@ -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 index 00000000..660f7be3 --- /dev/null +++ b/doc/webserver/actions/index.php @@ -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 + + +
    +

    + Privoxy: $title +

    +
    +
    +
    + $message +
    +
    +

    Valid HTML 4.01 Transitional

    + + \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", "

    As much as we welcome your feedback, please note that + we can only accept problem reports based on: +

    +
      +
    • Privoxy version $required_privoxy_version or later
    • +
    • Actionsfile version version $required_actions_file_version
    • +
    +

    We hope you will understand that we feel unable to maintain concurrent versions of the file.

    +

    Hint: To upgrade your actions file, just right-click the above link, then save as default.action in + your Privoxy config directory +

    "); +} + +?> + + Privoxy Action List Feedback - Step 1 of 2 + + + +
    +

    + Privoxy Action List Feedback - Step 1 of 2 +

    +
    + +
    +

    + Thank you for reporting a missing or invalid action! +

    + +

    + The Privoxy team relies on your feedback to maintain an efficient actions file! +
    Please fill the below form and click to proceed to step 2. +

    + +

    + Please keep in mind that this is not the place for + support requests, +
    bug reports or + feature requests. +

    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + +
    URL: + +
    Nature of the problem: + +
      + +
    +
    +
    + +
    +
    +

    Using Bookmarklets for Feedback

    +

    + 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! +

    +

    + Please right-click the following link and choose "Add to Favorites" (IE) or "Add Bookmark for Link" (Netscape): + Privoxy - Submit Actions File Feedback +

    + +

    + 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! +

    +
    +
    + +

    Valid HTML 4.01 Transitional

    + + + diff --git a/doc/webserver/actions/results/.htaccess b/doc/webserver/actions/results/.htaccess new file mode 100644 index 00000000..210ca5cc --- /dev/null +++ b/doc/webserver/actions/results/.htaccess @@ -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 +# + + Deny from all + diff --git a/doc/webserver/actions/results/actions-feedback.txt b/doc/webserver/actions/results/actions-feedback.txt new file mode 100644 index 00000000..e69de29b diff --git a/doc/webserver/actions/step2.php b/doc/webserver/actions/step2.php new file mode 100644 index 00000000..bdc08cd3 --- /dev/null +++ b/doc/webserver/actions/step2.php @@ -0,0 +1,518 @@ + + + + + + + + + + + + + +]*?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('|]*?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 (" Privoxy: $title + + +
    +

    + Privoxy: $title +

    +
    +
    +
    + $message +
    +
    +

    Valid HTML 4.01 Transitional

    + + \n"); + exit; +} + +/* + * Cannot start with step 2: + */ +if (!isset($referrer_url)) +{ + error_abort("invalid", "When submitting your feedback please start with + step 1."); +} + + +/* + * Cannot work on unknown problem: + */ +if (!isset($problem) || $problem == "INVALID") +{ + error_abort("invalid", "You need to select the nature of the problem in + step 1."); +} + + +/* + * 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 = " +
    +

    Confirm the URL:

    +
    +
    +

    + The URL that you entered could not be retrieved. Please make sure that +

    +

    + $referrer_url +

    +

    + is correct and publicly accssible. +

    +

    + Yes, I'm sure. +

    +
    "; +} +else +{ + $url_confirm = ""; +} + +/* + * 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"; +} + +?> + + Privoxy Action List Feedback - Step 2 of 2 + + + +
    +

    + Privoxy Action List Feedback - Step 2 of 2 +

    +
    + +
    + You are about to report that on + . +
    + +
    +
    +

    + + +

    + +
    + + 0) + { + /* + * Open section in
    ; Open table: + */ + echo ("
    Choose the images you want blocked from the following list:
    +
    +

    + + \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 (" + + + + + + + \n"); + } + echo ("
    + + + $image_url: + + +
    + \"banner +
    +

    + +
    + If the banner that you saw is not listed above, enter the URL here\n"); + } + else + { + echo ("
    + URL of the advertisment image:\n"); + } +} + +?> + +
    Hint: right-click the image, select "Copy image location" and paste the URL here. +
    +
    +

    + +

    +
    + +") ?> + + + +
    +

    URL of the innocent image: +
    Hint: right-click the image, select "Copy image location" and paste the URL here. +
    This may not work if the image was blocked by size or if +image-blocker is set to redirect.
    +

    +
    +
    +

    + +

    +
    + +") ?> + +
    Severity:
    +
    +

    + +

    +
    + +
    + Remarks: (optional) +
    +
    +

    + +

    +
    + +
    + Your Name: (optional, public) +
    +
    +

    + +

    +
    + +
     
    +
    + +
    + +
    + +
    + +

    Valid HTML 4.01 Transitional

    + + + diff --git a/doc/webserver/actions/step3.php b/doc/webserver/actions/step3.php new file mode 100644 index 00000000..d3b60686 --- /dev/null +++ b/doc/webserver/actions/step3.php @@ -0,0 +1,345 @@ + + + + + + + + + + +Privoxy: $title + + +
    +

    + Privoxy: $title +

    +
    +
    +
    + $message +
    +
    +

    Valid HTML 4.01 Transitional

    + + \n"); + exit; +} + + +/* + * Cannot start with step 3: + */ +if (!isset($referrer_url)) +{ + error_abort("invalid", "When submitting your feedback please start with step 1."); +} + + +/* + * Cannot work on unknown problem: + */ +if (!isset($problem)) +{ + error_abort("invalid", "You need to select the nature of the problem in step 1."); +} + + +/* + * 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\" + step 2."); +} + + +/* + * 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 (" Internal Script Error + + +
    +

    Privoxy: Internal Script Error

    +
    +
    +
    +

    + This script was unable to open its logfile. +

    +

    + Please mail its owner! +

    +
    +
    + + "); + 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); + +?> + + Privoxy Action List Feedback - Result + + + +
    +

    + Privoxy Action List Feedback - Result +

    +
    + +
    +

    + Thank you very much for taking the time to submit your feedback! +

    + +

    + The developers will review and use your submission to improve the + distribution actions file. +

    + +

    + +

    + +
    + +

    Valid HTML 4.01 Transitional

    + + + diff --git a/doc/webserver/actions/testdrive.action b/doc/webserver/actions/testdrive.action new file mode 100644 index 00000000..7e0250b0 --- /dev/null +++ b/doc/webserver/actions/testdrive.action @@ -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 index 00000000..f7d165f0 --- /dev/null +++ b/doc/webserver/config/.htaccess @@ -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 index 00000000..f7ef30ee --- /dev/null +++ b/doc/webserver/config/index.php @@ -0,0 +1,63 @@ + + + + + +Privoxy not running + + + + + +

    Privoxy isn't working

    + +

    If you were redirected to this page, it means that you aren't using +Privoxy.   Please check your browser settings.

    + +

    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 http://config.privoxy.org/ +(Short form: p.p +[Privoxy Proxy]).

    + +

    Please see the Privoxy home page.

    + + + + diff --git a/doc/webserver/default_page.php b/doc/webserver/default_page.php new file mode 100644 index 00000000..75a4fdcc --- /dev/null +++ b/doc/webserver/default_page.php @@ -0,0 +1,69 @@ + + + +SourceForge: Welcome + + + + + + + + + + + +
       + Home | + About | + Partners | + Contact Us
    + + + + + + + + + +
    + + + VA Linux Systems +
    + + + + + + + +
    +

    +

    Welcome to http:///

    +

    We're Sorry but this Project hasn't yet uploaded their personal webpage yet.
    + Please check back soon for updates or visit SourceForge


    +
    +
    + + + + + + + +
    + 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. +
    + + + + diff --git a/doc/webserver/developer-manual/coding.html b/doc/webserver/developer-manual/coding.html new file mode 100644 index 00000000..364af8e1 --- /dev/null +++ b/doc/webserver/developer-manual/coding.html @@ -0,0 +1,2266 @@ +Coding Guidelines
    Privoxy Developer Manual
    PrevNext

    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.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;

    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.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:
    +*/

    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.


    PrevHomeNext
    Documentation Guidelines Testing Guidelines
    \ 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 index 00000000..c9112352 --- /dev/null +++ b/doc/webserver/developer-manual/contact.html @@ -0,0 +1,309 @@ +Contacting the developers, Bug Reporting and Feature Requests
    Privoxy Developer Manual
    PrevNext

    8. 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:

    8.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.

    8.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.

    8.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.

    8.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.

    8.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.


    PrevHomeNext
    Update the Webserver Privoxy Copyright, License and History
    \ 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 index 00000000..f4093413 --- /dev/null +++ b/doc/webserver/developer-manual/copyright.html @@ -0,0 +1,296 @@ +Privoxy Copyright, License and History
    Privoxy Developer Manual
    PrevNext

    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
    BostonMA 02111-1307
    USA 

    9.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.


    PrevHomeNext
    Contacting the developers, Bug Reporting and Feature Requests See also
    \ 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 index 00000000..88010541 --- /dev/null +++ b/doc/webserver/developer-manual/cvs.html @@ -0,0 +1,301 @@ +The CVS Repository
    Privoxy Developer Manual
    PrevNext

    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. +


    PrevHomeNext
    Introduction Documentation Guidelines
    \ 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 index 00000000..19ac418f --- /dev/null +++ b/doc/webserver/developer-manual/documentation.html @@ -0,0 +1,838 @@ +Documentation Guidelines
    Privoxy Developer Manual
    PrevNext

    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! +


    PrevHomeNext
    The CVS Repository Coding Guidelines
    \ 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 index 00000000..cf386de8 --- /dev/null +++ b/doc/webserver/developer-manual/index.html @@ -0,0 +1,668 @@ +Privoxy Developer Manual

    Privoxy Developer Manual

    + + Copyright © 2001, 2002 by + Privoxy Developers + +

    $Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 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. Note on Privoxy Packaging
    6.3.2. Source Tarball
    6.3.3. SuSE, Conectiva or Red Hat RPM
    6.3.4. OS/2
    6.3.5. Solaris
    6.3.6. Windows
    6.3.7. Debian
    6.3.8. Mac OSX
    6.3.9. FreeBSD
    6.3.10. HP-UX 11
    6.3.11. Amiga OS
    6.3.12. 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 Actions-Related Problems
    8.5. Other
    9. Privoxy Copyright, License and History
    9.1. License
    9.2. History
    10. See also

      Next
      Introduction
    \ 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 index 00000000..b4bcd2ba --- /dev/null +++ b/doc/webserver/developer-manual/introduction.html @@ -0,0 +1,184 @@ +Introduction
    Privoxy Developer Manual
    PrevNext

    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. +


    PrevHomeNext
    Privoxy Developer Manual The CVS Repository
    \ 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 index 00000000..5ff11fb5 --- /dev/null +++ b/doc/webserver/developer-manual/newrelease.html @@ -0,0 +1,1667 @@ +Releasing a New Version
    Privoxy Developer Manual
    PrevNext

    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. And details + on the Sourceforge release process below that. +

    6.3.1. Note on Privoxy Packaging

    Please keep these general guidelines in mind when putting together + your package. These apply to all platforms! +

    • Privoxy requires + write access to: all *.action files, all + logfiles, and the trust file. You will + need to determine the best way to do this for your platform. +

    • Please include up to date documentation. At a bare minimum: +

      LICENSE (toplevel directory) +

      README (toplevel directory) +

      AUTHORS (toplevel directory) +

      man page (toplevel directory, Unix-like + platforms only) +

      The User Manual (doc/webserver/user-manual/) +

      FAQ (doc/webserver/faq/) +

      Also suggested: Developer Manual + (doc/webserver/devel-manual) and ChangeLog + (toplevel directory). FAQ and the manuals are + HTML docs. There are also text versions in + doc/text/ which could conceivably also be + included. +

      The documentation has been designed such that the manuals are linked + to each other from parallel directories, and should be packaged + that way. index.html 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: + p_doc.css and p_web.css. + These should be in the same directory with + index.html, (i.e. one level up from the manual + directories). +

    • user.action is designed for local preferences. + Make sure this does not get overwritten! +

    • 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 :-) +

    • Please check platform specific notes in this doc, if you haven't + done "Privoxy" 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). +

    +

    6.3.2. 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.3. SuSE, Conectiva 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.4. 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.5. 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.6. 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.7. 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.8. 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.9. 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.10. 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.11. 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.12. 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: +

    +

    Or use the make targets as described above. +

    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. +


    PrevHomeNext
    Testing Guidelines Update the Webserver
    \ 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 index 00000000..ba84f139 --- /dev/null +++ b/doc/webserver/developer-manual/quickstart.html @@ -0,0 +1,150 @@ +Quickstart to Privoxy Development
    Privoxy Developer Manual
    PrevNext

    3. 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. +


    PrevHomeNext
    Introduction The CVS Repository
    \ 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 index 00000000..3c9f9e42 --- /dev/null +++ b/doc/webserver/developer-manual/seealso.html @@ -0,0 +1,385 @@ +See also
    Privoxy Developer Manual
    Prev 

    10. 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. +


    PrevHome 
    Privoxy Copyright, License and History  
    \ 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 index 00000000..d957a188 --- /dev/null +++ b/doc/webserver/developer-manual/testing.html @@ -0,0 +1,249 @@ +Testing Guidelines
    Privoxy Developer Manual
    PrevNext

    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). +


    PrevHomeNext
    Coding Guidelines Releasing a New Version
    \ 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 index 00000000..5112a56d --- /dev/null +++ b/doc/webserver/developer-manual/webserver-update.html @@ -0,0 +1,239 @@ +Update the Webserver
    Privoxy Developer Manual
    PrevNext

    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. +


    PrevHomeNext
    Releasing a New Version Contacting the developers, Bug Reporting and Feature Requests
    \ No newline at end of file diff --git a/doc/webserver/faq/configuration.html b/doc/webserver/faq/configuration.html new file mode 100644 index 00000000..506e60b2 --- /dev/null +++ b/doc/webserver/faq/configuration.html @@ -0,0 +1,808 @@ +Configuration
    Privoxy Frequently Asked Questions
    PrevNext

    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/.


    PrevHomeNext
    Installation Miscellaneous
    \ No newline at end of file diff --git a/doc/webserver/faq/contact.html b/doc/webserver/faq/contact.html new file mode 100644 index 00000000..7c8ff51b --- /dev/null +++ b/doc/webserver/faq/contact.html @@ -0,0 +1,309 @@ +Contacting the developers, Bug Reporting and Feature Requests
    Privoxy Frequently Asked Questions
    PrevNext

    6. 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:

    6.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.

    6.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.

    6.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.

    6.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.

    6.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.


    PrevHomeNext
    Troubleshooting Privoxy Copyright, License and History
    \ No newline at end of file diff --git a/doc/webserver/faq/copyright.html b/doc/webserver/faq/copyright.html new file mode 100644 index 00000000..8a79af8e --- /dev/null +++ b/doc/webserver/faq/copyright.html @@ -0,0 +1,301 @@ +Privoxy Copyright, License and History
    Privoxy Frequently Asked Questions
    Prev 

    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
    BostonMA 02111-1307
    USA 

    7.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.


    PrevHome 
    Contacting the developers, Bug Reporting and Feature Requests  
    \ No newline at end of file diff --git a/doc/webserver/faq/general.html b/doc/webserver/faq/general.html new file mode 100644 index 00000000..eadcc0ff --- /dev/null +++ b/doc/webserver/faq/general.html @@ -0,0 +1,677 @@ +General Information
    Privoxy Frequently Asked Questions
    PrevNext

    1. General Information

    1.1. What is this new version of Privoxy?

    The original Internet + Junkbuster (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 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. +

    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.


    PrevHomeNext
    Privoxy Frequently Asked Questions Installation
    \ No newline at end of file diff --git a/doc/webserver/faq/index.html b/doc/webserver/faq/index.html new file mode 100644 index 00000000..b6cba2ea --- /dev/null +++ b/doc/webserver/faq/index.html @@ -0,0 +1,682 @@ +Privoxy Frequently Asked Questions

    Privoxy Frequently Asked Questions

    Copyright © 2001, 2002 by + Privoxy Developers +

    $Id: faq.sgml,v 1.59 2002/05/15 04:03:30 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 Actions-Related Problems
    6.5. Other
    7. Privoxy Copyright, License and History
    7.1. License
    7.2. History

      Next
      General Information
    \ No newline at end of file diff --git a/doc/webserver/faq/installation.html b/doc/webserver/faq/installation.html new file mode 100644 index 00000000..87fa8c7b --- /dev/null +++ b/doc/webserver/faq/installation.html @@ -0,0 +1,375 @@ +Installation
    Privoxy Frequently Asked Questions
    PrevNext

    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.


    PrevHomeNext
    General Information Configuration
    \ No newline at end of file diff --git a/doc/webserver/faq/misc.html b/doc/webserver/faq/misc.html new file mode 100644 index 00000000..df6c40b2 --- /dev/null +++ b/doc/webserver/faq/misc.html @@ -0,0 +1,911 @@ +Miscellaneous
    Privoxy Frequently Asked Questions
    PrevNext

    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://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. +


    PrevHomeNext
    Configuration Troubleshooting
    \ No newline at end of file diff --git a/doc/webserver/faq/trouble.html b/doc/webserver/faq/trouble.html new file mode 100644 index 00000000..59af117a --- /dev/null +++ b/doc/webserver/faq/trouble.html @@ -0,0 +1,306 @@ +Troubleshooting
    Privoxy Frequently Asked Questions
    PrevNext

    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.


    PrevHomeNext
    Miscellaneous Contacting the developers, Bug Reporting and Feature Requests
    \ 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 index 00000000..207b6f74 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 index 00000000..9e80f976 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 index 00000000..b13eee82 --- /dev/null +++ b/doc/webserver/index.html @@ -0,0 +1,344 @@ +Privoxy - Homepage + +

    Privoxy - Homepage

    +

    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).

    The most recent release is 2.9.15 (beta). +



    Prixoxy is developed on:
    + +

    Copyright © 2001, 2002 by Privoxy Developers +

    \ 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 index 00000000..c874d0bd --- /dev/null +++ b/doc/webserver/man-page/privoxy-man-page.html @@ -0,0 +1,391 @@ + +Manpage of PRIVOXY + +

    PRIVOXY

    +Section: (1)
    Updated: 14 May 2002
    Index +
    + +  +

    NAME

    + +privoxy - Privacy Enhancing Proxy +  +

    SYNOPSIS

    + +

    +privoxy [--help] [--version] [--no-daemon] [--pidfile pidfile] [--user user[.group]] [configfile] (UNIX) +

    +

    +privoxy.exe [configfile] (Windows) +

    +  +

    OPTIONS

    + +

    + +Privoxy may be invoked with the following command line +options: +

    +
    --help
    +Print brief usage info and exit. +
    --version
    +Print version info and exit. +
    --no-daemon
    +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. +
    --pidfile pidfile
    +On startup, write the process ID to pidfile. +Delete the pidfile on exit. +Failiure to create or delete the pidfile +is non-fatal. If no --pidfile option is given, no PID file will be used. +
    --user user[.group]
    +After (optionally) writing the PID file, assume the user ID of +user and the GID of +group, or, if the optional +group was not given, the default group of +user. Exit if the privileges are not +sufficient to do so. +
    +

    + +If the configfile is not 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). If no +configfile is found, Privoxy will +fail to start. +  +

    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 Internet +Junkbuster (tm). +  +

    INSTALLATION AND USAGE

    + +

    + +Browsers must be individually configured to use Privoxy 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: Edit; +Preferences; Advanced; +Proxies; Manual Proxy Configuration; +View. +

    + +For Internet Explorer, go through: Tools; +Internet Properties; Connections; +LAN Settings. +

    + +The Secure (SSL) Proxy should also be set to the same values, otherwise +https: URLs will not be proxied. +

    + +For other browsers, check the documentation. +  +

    CONFIGURATION

    + +

    + +Privoxy can be configured with the various configuration +files. The default configuration files are: config, +default.filter, and +default.action. user.action should +be used for locally defined exceptions to the default rules of +default.action These are all well commented. On Unix +and Unix-like systems, these are located in +/etc/privoxy/ by default. On Windows, OS/2 and AmigaOS, +these files are 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. 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. +

    + +The actions list (ad blocks, etc) can also be configured with your +web browser at http://config.privoxy.org/. +Privoxy's configuration parameters can also be viewed at +the same page. In addition, Privoxy can be toggled on/off. +This is an internal page. +  +

    SAMPLE CONFIGURATION

    + +

    + +A brief example of what a simple default.action +configuration might look like: +

    +

    + # 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.
    +
    + +

    + +Then for a user.action, we would put local, +narrowly defined exceptions: +

    +

    + # 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
    +
    + +

    + +See the comments in the configuration files themselves, or the +user-manual +for explanations of the above syntax, and other Privoxy +configuration options. +  +

    FILES

    + +

    +

    + 
    + /usr/sbin/privoxy
    + /etc/privoxy/config
    + /etc/privoxy/default.action
    + /etc/privoxy/standard.action
    + /etc/privoxy/user.action
    + /etc/privoxy/default.filter
    + /etc/privoxy/trust
    + /etc/privoxy/templates/*
    + /var/log/privoxy/logfile
    +
    + +

    + +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. +  +

    SIGNALS

    + +

    + +Privoxy terminates on the SIGINT, +SIGTERM and SIGABRT signals. Log +rotation scripts may cause a re-opening of the logfile by sending a +SIGHUP to Privoxy. Note that unlike +other daemons, Privoxy does not need to be made aware of +config file changes by SIGHUP -- it will detect them +automatically. +  +

    NOTES

    + +

    + +This is a beta version of Privoxy. Not +all features are well tested. +

    + +Please see the user-manual on how to contact the +developers for feature requests, reporting problems, and other questions. +  +

    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/ 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/ +  +

    DEVELOPMENT TEAM

    + +

    +

    + 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
    +
    + +  +

    COPYRIGHT AND LICENSE

    + +  +

    COPYRIGHT

    + +

    + +Copyright (C) 2001, 2002 by Privoxy Developers <developers@privoxy.org> +

    + +Some source code is based on code Copyright (C) 1997 by Anonymous Coders +and Junkbusters, Inc. and licensed under the GNU General Public +License. +  +

    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 +

    + +


    + 

    Index

    +
    +
    NAME
    +
    SYNOPSIS
    +
    OPTIONS
    +
    DESCRIPTION
    +
    INSTALLATION AND USAGE
    +
    CONFIGURATION
    +
    SAMPLE CONFIGURATION
    +
    FILES
    +
    SIGNALS
    +
    NOTES
    +
    SEE ALSO
    +
    DEVELOPMENT TEAM
    +
    COPYRIGHT AND LICENSE
    +
    +
    COPYRIGHT
    +
    LICENSE
    +
    +
    +
    +This document was created by +man2html, +using the manual pages.
    +Time: 00:10:58 GMT, May 15, 2002 + + diff --git a/doc/webserver/p_doc.css b/doc/webserver/p_doc.css new file mode 100644 index 00000000..d8e0bd97 --- /dev/null +++ b/doc/webserver/p_doc.css @@ -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 index 00000000..281b047a --- /dev/null +++ b/doc/webserver/p_feedback.css @@ -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 index 00000000..8eb2159a --- /dev/null +++ b/doc/webserver/p_web.css @@ -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 index 00000000..2d33e85b --- /dev/null +++ b/doc/webserver/privoxy.css @@ -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
    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
    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 index 00000000..b00fc9c5 --- /dev/null +++ b/doc/webserver/redirect.php @@ -0,0 +1,112 @@ +"; +// print "Target \"{$to}\"
    "; + + +// 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 index 00000000..a9941dbd --- /dev/null +++ b/doc/webserver/robots.txt @@ -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 index 00000000..cfd1eaeb --- /dev/null +++ b/doc/webserver/submit/confirmad.php @@ -0,0 +1,58 @@ + + + + Privoxy|Confirm ad submission + + + +

    Privoxy Feedback

    + +

    Confirm Ad Submission

    + +

    We have detemined that ...

    + + + + + \ No newline at end of file diff --git a/doc/webserver/submit/index.php b/doc/webserver/submit/index.php new file mode 100644 index 00000000..47a76739 --- /dev/null +++ b/doc/webserver/submit/index.php @@ -0,0 +1,207 @@ + + + + Privoxy|Submit + + + +

    Privoxy Feedback

    + +

    Compared to bug +reports or feature +requests, this page is intended to optimize the blocking behavior +of Privoxy. Therefor we need your feedback.

    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.

    + +

    New Advertisement

    + + + + + 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; +} +?> + + +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Your name: + +optional
    Your email address: + +optional
    Website, where I observed an ad: + +Please change, if necessary
    How annoying is the ad: + +Please select one
    Privoxy Version: + +Automatically determined
    Action File: + +Automatically determined
    Action File Version: + +Automatically determined
    Remarks: + +Please change, if necessary
    + + +
    +
    +

    + +

    Incorrect blocking

    +

    We soon present a form where you can submit websites, where the +default action file was too agressive.

    + +

    Misc

    +

    Bla bla bla

    + + + + + \ No newline at end of file diff --git a/doc/webserver/team/01stefanw.jpg b/doc/webserver/team/01stefanw.jpg new file mode 100644 index 00000000..920dece2 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 index 00000000..5a90642b 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 index 00000000..136b2dd4 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 index 00000000..32e470b5 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 index 00000000..78dc102c 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 index 00000000..e23f5804 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 index 00000000..bb4e02d8 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 index 00000000..bba4f154 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 index 00000000..429723f1 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 index 00000000..c04aa55f 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..97042aaa 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 index 00000000..c9ffd9b5 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 index 00000000..fe12d905 --- /dev/null +++ b/doc/webserver/team/index.html @@ -0,0 +1,83 @@ + + + + + + +Privoxy - Team page + + + + +
    +

    Privoxy - Team page

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +01stefanw.jpg +02jon.jpg +03andreas.jpg +04rodney.jpg
    +05david.jpg +06member.jpg +07member.jpg +08member.jpg
    +09member.jpg +10member.jpg +11member.jpg +12member.jpg
    +13member.jpg +14member.jpg +15member.jpg +16member.jpg
    +17member.jpg +18member.jpg +19member.jpg +20member.jpg
    + +
    +Created by IrfanView +
    + + diff --git a/doc/webserver/user-manual/actions-file.html b/doc/webserver/user-manual/actions-file.html new file mode 100644 index 00000000..ca87032f --- /dev/null +++ b/doc/webserver/user-manual/actions-file.html @@ -0,0 +1,4959 @@ +Actions Files
    Privoxy User Manual
    PrevNext

    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 a regular section with + a heading line of { + +handle-as-image }, + then later another one with just { + +block }, resulting + in both actions to apply.

    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.


    PrevHomeNext
    The Main Configuration File The Filter File
    \ 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 index 00000000..9985300a --- /dev/null +++ b/doc/webserver/user-manual/appendix.html @@ -0,0 +1,1918 @@ +Appendix
    Privoxy User Manual
    Prev 

    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.

    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.

    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.


    PrevHome 
    See Also  
    \ 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 index 00000000..1e7d197d --- /dev/null +++ b/doc/webserver/user-manual/config.html @@ -0,0 +1,2959 @@ +The Main Configuration File
    Privoxy User Manual
    PrevNext

    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 below), and/or + a firewall. +

    If you open Privoxy to untrusted users, you will + also want to turn off the enable-edit-actions and + enable-remote-toggle + options! +

    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
    +   

    +


    PrevHomeNext
    Privoxy Configuration Actions Files
    \ 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 index 00000000..e4bbe096 --- /dev/null +++ b/doc/webserver/user-manual/configuration.html @@ -0,0 +1,481 @@ +Privoxy Configuration
    Privoxy User Manual
    PrevNext

    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.


    PrevHomeNext
    Starting Privoxy The Main Configuration File
    \ 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 index 00000000..8e67ad83 --- /dev/null +++ b/doc/webserver/user-manual/contact.html @@ -0,0 +1,313 @@ +Contacting the Developers, Bug Reporting and Feature +Requests
    Privoxy User Manual
    PrevNext

    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.


    PrevHomeNext
    Templates Privoxy Copyright, License and History
    \ 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 index 00000000..81cbf4ae --- /dev/null +++ b/doc/webserver/user-manual/copyright.html @@ -0,0 +1,354 @@ +Privoxy Copyright, License and History
    Privoxy User Manual
    PrevNext

    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
    BostonMA 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


    PrevHomeNext
    Contacting the Developers, Bug Reporting and Feature +Requests See Also
    \ 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 index 00000000..64b2c74f --- /dev/null +++ b/doc/webserver/user-manual/filter-file.html @@ -0,0 +1,772 @@ +The Filter File
    Privoxy User Manual
    PrevNext

    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?


    PrevHomeNext
    Actions Files Templates
    \ 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 index 00000000..ef8d46d2 --- /dev/null +++ b/doc/webserver/user-manual/index.html @@ -0,0 +1,832 @@ +Privoxy User Manual

    Privoxy User Manual

    Copyright © 2001, 2002 by + Privoxy Developers +

    $Id: user-manual.sgml,v 1.121 2002/05/23 23:20:17 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 and Conectiva
    5.2. Debian
    5.3. SuSE
    5.4. Windows
    5.5. Solaris, NetBSD, FreeBSD, HP-UX and others
    5.6. OS/2
    5.7. MAX OSX
    5.8. AmigaOS
    5.9. 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
    22
    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

      Next
      Introduction
    \ 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 index 00000000..12397cf2 --- /dev/null +++ b/doc/webserver/user-manual/installation.html @@ -0,0 +1,544 @@ +Installation
    Privoxy User Manual
    PrevNext

    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

    DEBs can be installed with dpkg -i + privoxy_2.9.15-1.deb, and will use + /etc/privoxy for the location of configuration + files.

    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.


    PrevHomeNext
    Introduction Note to Upgraders
    \ 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 index 00000000..536b4f46 --- /dev/null +++ b/doc/webserver/user-manual/introduction.html @@ -0,0 +1,270 @@ +Introduction
    Privoxy User Manual
    PrevNext

    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. +


    PrevHomeNext
    Privoxy User Manual Installation
    \ 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 index 00000000..cf3eebe6 --- /dev/null +++ b/doc/webserver/user-manual/quickstart.html @@ -0,0 +1,807 @@ +Quickstart to Using Privoxy
    Privoxy User Manual
    PrevNext

    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. The + actions, together with the URL patterns are called a section.

    When you connect to a website, the full URL will either match one or more + of the sections as defined in Privoxy's configuration, + or not. If so, then Privoxy 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.

    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 and sends Privoxy's + own built-in BLOCKED page instead to let you now what has happened. +

    • handle-as-image - + tells Privoxy to treat this URL as an image. + Privoxy'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 + "broken image" 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. +

    • 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 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 image anywhere + 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

      +

    • You should have a section with only + block listed under + "Actions:". + If not, click a "Insert new section below" + button, and in the new section that just appeared, click the + Edit button right 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" (or + "OK" if in a pop-up window). +

    • 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. + The ideas explained thererin also apply to the web-based editor.


    PrevHomeNext
    Note to Upgraders Starting Privoxy
    \ 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 index 00000000..a1fe3522 --- /dev/null +++ b/doc/webserver/user-manual/seealso.html @@ -0,0 +1,396 @@ +See Also
    Privoxy User Manual
    PrevNext

    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. +


    PrevHomeNext
    Privoxy Copyright, License and History Appendix
    \ 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 index 00000000..d7fcaefe --- /dev/null +++ b/doc/webserver/user-manual/startup.html @@ -0,0 +1,505 @@ +Starting Privoxy
    Privoxy User Manual
    PrevNext

    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 and Conectiva

    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.

     # /etc/rc.d/init.d/privoxy start

    5.2. Debian

    We use a script. Note that Debian starts Privoxy upon booting per + default. It will use the file + /etc/privoxy/config as its main configuration + file.

     # /etc/init.d/privoxy start

    5.3. 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.4. 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.5. Solaris, NetBSD, FreeBSD, HP-UX and others

    Example Unix startup command:

     # /usr/sbin/privoxy /etc/privoxy/config

    5.6. OS/2

    FIXME.

    5.9. 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. +


    PrevHomeNext
    Quickstart to Using Privoxy Privoxy Configuration
    \ 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 index 00000000..dbd8a604 --- /dev/null +++ b/doc/webserver/user-manual/templates.html @@ -0,0 +1,290 @@ +Templates
    Privoxy User Manual
    PrevNext

    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.


    PrevHomeNext
    The Filter File Contacting the Developers, Bug Reporting and Feature +Requests
    \ 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 index 00000000..6e8ea179 --- /dev/null +++ b/doc/webserver/user-manual/upgradersnote.html @@ -0,0 +1,288 @@ +Note to Upgraders
    Privoxy User Manual
    PrevNext

    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. +


    PrevHomeNext
    Installation Quickstart to Using Privoxy
    \ No newline at end of file diff --git a/encode.c b/encode.c index 42d07443..09c7b5f7 100644 --- 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 + * * *********************************************************************/ @@ -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 +#include #include -#include - + #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 + * 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) -{ - /* each input char can expand to at most 3 chars */ - char * buf = (char *) malloc((strlen(s) * 3) + 1); - +{ + 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) - { + { char c; char * p = buf; while( (c = *s++) != '\0') @@ -266,9 +349,9 @@ char * url_encode(const char *s) } *p = '\0'; - + } - + 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; - - if (buf) - { + + 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'; + *q = '\0'; } - + return(buf); } diff --git a/encode.h b/encode.h index ba0b6cf0..875b9662 100644 --- 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 @@ -35,6 +35,21 @@ * * 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 + * * *********************************************************************/ @@ -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: diff --git a/errlog.c b/errlog.c index 54b26873..4a3cfe7e 100644 --- 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 + * * *********************************************************************/ #include "config.h" +#include "miscutil.h" #include #include #include #include -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__OS2__) #include -#endif /* ndef _WIN32 */ +#endif /* !defined(_WIN32) && !defined(__OS2__) */ #include -/* #include */ +#include +#ifdef FEATURE_PTHREAD +#include +#endif /* def FEATURE_PTHREAD */ #ifdef _WIN32 +#ifndef STRICT +#define STRICT +#endif #include +#ifndef _WIN_CONSOLE #include "w32log.h" +#endif /* ndef _WIN_CONSOLE */ #endif /* def _WIN32 */ +#ifdef __OS2__ +#include /* For sock_errno */ +#define INCL_DOS +#include +#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: */ - diff --git a/errlog.h b/errlog.h index 24ce2856..c3424dd0 100644 --- 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 @@ -35,6 +35,91 @@ * * 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 + * * *********************************************************************/ @@ -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: diff --git a/filters.c b/filters.c index 29cee478..ff70ac56 100644 --- 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 + * * *********************************************************************/ @@ -49,25 +402,34 @@ const char filters_rcs[] = "$Id: filters.c,v 1.1 2001/05/13 21:57:06 administrat #include #include #include +#include #ifndef _WIN32 +#ifndef __OS2__ #include +#endif /* ndef __OS2__ */ #include #else #include -#endif +#endif /* ndef _WIN32 */ + +#ifdef __OS2__ +#include +#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" - "\n" - "\n" - "Internet Junkbuster: Request for blocked URL\n" - "\n" - WHITEBG - "

    " - BANNER - "

    \n" - "

    Your request for %s%s
    \n" - "was blocked because it matches the following pattern " - "in the blockfile: %s\n

    " -#ifdef FORCE_LOAD - "

    Go there anyway.

    " -#endif /* def FORCE_LOAD */ - "\n" - "\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" - "\n" - "\n" - "Internet Junkbuster: Request for untrusted URL\n" - "\n" - WHITEBG - "
    " - "" - BANNER - "" - "
    " - "\n" - "\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, "
  • %s
  • \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, "
  • %s
    \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" - - "" - "" - "Internet Junkbuster Proxy Status - "); - s = strsav(s, file_description); - s = strsav(s, - "" - "\n" - "\n" - "
    \n" - "

    " BANNER "\n"); - s = strsav(s, file_description); - s = strsav(s, - "

    \n" - "

    Back to proxy status

    \n" - "

    "); - s = strsav(s, file_description); - s = strsav(s, - "

    \n" - "Contents of file ""); - p = html_encode(filename); - s = strsav(s, p); - freez(p); - s = strsav(s, - "":
    \n" - "

    \n" - "
    ");
    -      
    -      if ((fp = fopen(filename, "r")) == NULL)
    +      if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
           {
    -         s = strsav(s, "

    ERROR OPENING FILE!

    ");
    +         return;
           }
    -      else
    -      {
    -         while (fgets(buf, sizeof(buf), fp))
    -         {
    -            p = html_encode(buf);
    -            if (p)
    -            {
    -               s = strsav(s, p);
    -               freez(p);
    -               s = strsav(s, "
    "); - } - } - fclose(fp); - } - - s = strsav(s, - "
    \n" - "
    \n" - "

    Back to proxy status

    \n" - "
    \n" - "

    \n" - "Code and documentation of the " BANNER " Proxy" - "TM\n" - "\n" "Copyright© 1997 Junkbusters Corporation\n" - "TM
    \n" - "Copying and distribution permitted under the" - "\n" - "GNU " - "General Public License.\n" - "
    " - "

    webmaster@junkbusters.com
    " - "
    " - "\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, - "

    The following files are in use:

    \n" - "

    (Click a filename to view it)

    \n" - ""); - -#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" - "\n" - "\n" - "Internet Junkbuster: Request for untrusted URL\n" - "\n" - BODY - "

    " - BANNER - "

    " - "The " BANNER " Proxy " - "" - "(" HOME_PAGE_URL ") " - "intercepted the request for %s%s\n" - "because the URL is not trusted.\n" - "

    \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 "); - strsav(p, refer); - strsav(p, "
    \n"); - - freez(hostport); - freez(path ); - freez(refer ); - - p = strsav(p, "

    The following referrers are trusted

    \n"); - - for (tl = trust_list; (t = *tl) ; tl++) - { - sprintf(buf, "%s
    \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, - "

    " - "You can learn more about what this means " - "and what you may be able to do about it by " - "reading the following documents:
    \n" - "

      \n" - ); - - p = strsav(p, buf); - - for (l = trust_info->next; l ; l = l->next) + if (url_match(b->url, http)) { - sprintf(buf, - "
    1. %s
      \n", - l->str, l->str); - p = strsav(p, buf); + merge_current_action(action, b->action); } - - p = strsav(p, "
    \n"); } - - p = strsav(p, "\n" "\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,"

    Statistics for this " BANNER ":

    \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 */ /* diff --git a/filters.h b/filters.h index 68af5195..75da5b1c 100644 --- 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 @@ -40,9 +39,158 @@ * * 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 + * * *********************************************************************/ - + #include "project.h" @@ -50,46 +198,74 @@ 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 index be4c7870..00000000 --- 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. - diff --git a/gateway.c b/gateway.c index 2ccf1676..7584b945 100644 --- 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 + * + * 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 + * * *********************************************************************/ @@ -42,12 +121,27 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.1 2001/05/13 21:57:06 administrat #include #include + +#ifndef _WIN32 +#include +#endif + #include +#include #ifdef _WIN32 #include #endif /* def _WIN32 */ +#ifdef __BEOS__ +#include +#endif /* def __BEOS__ */ + +#ifdef __OS2__ +#include +#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); } diff --git a/gateway.h b/gateway.h index 69145552..d96bc58d 100644 --- 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 @@ -36,23 +36,77 @@ * * 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 + * * *********************************************************************/ -#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 index 00000000..796d05fc --- /dev/null +++ b/genclspec.sh @@ -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 " +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 index e5aa2506..00000000 Binary files a/icons/denyrule.ico and /dev/null differ diff --git a/icons/icon1.ico b/icons/icon1.ico deleted file mode 100644 index b96fe7c2..00000000 Binary files a/icons/icon1.ico and /dev/null differ diff --git a/icons/idle.ico b/icons/idle.ico index 99470b54..5ef20fc1 100644 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 index 00000000..0ad4f562 Binary files /dev/null and b/icons/os2.ico differ diff --git a/icons/os20.ico b/icons/os20.ico new file mode 100644 index 00000000..ef5995b1 Binary files /dev/null and b/icons/os20.ico differ diff --git a/icons/os21.ico b/icons/os21.ico new file mode 100644 index 00000000..cc61b61d Binary files /dev/null and b/icons/os21.ico differ diff --git a/icons/os22.ico b/icons/os22.ico new file mode 100644 index 00000000..d357dfba Binary files /dev/null and b/icons/os22.ico differ diff --git a/icons/os23.ico b/icons/os23.ico new file mode 100644 index 00000000..8ac037f0 Binary files /dev/null and b/icons/os23.ico differ diff --git a/icons/os24.ico b/icons/os24.ico new file mode 100644 index 00000000..f2b87f71 Binary files /dev/null and b/icons/os24.ico differ diff --git a/icons/os25.ico b/icons/os25.ico new file mode 100644 index 00000000..5bc68b5e Binary files /dev/null and b/icons/os25.ico differ diff --git a/icons/os26.ico b/icons/os26.ico new file mode 100644 index 00000000..408d89ef Binary files /dev/null and b/icons/os26.ico differ diff --git a/icons/os27.ico b/icons/os27.ico new file mode 100644 index 00000000..00a88148 Binary files /dev/null and b/icons/os27.ico differ diff --git a/icons/os28.ico b/icons/os28.ico new file mode 100644 index 00000000..91536360 Binary files /dev/null and b/icons/os28.ico differ diff --git a/icons/junkbust.ico b/icons/privoxy.ico similarity index 59% rename from icons/junkbust.ico rename to icons/privoxy.ico index 41aafd0a..4c96d0b1 100644 Binary files a/icons/junkbust.ico and b/icons/privoxy.ico differ diff --git a/imagelist b/imagelist deleted file mode 100644 index e83fed0d..00000000 --- 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 -# -# 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 index 00000000..e9de2384 --- /dev/null +++ b/install-sh @@ -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/jbsockets.c b/jbsockets.c index c5f73c9c..a3859656 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -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 + * * *********************************************************************/ @@ -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 #include #include #else +#ifndef __OS2__ #include +#endif #include #include #include @@ -65,16 +208,26 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.1 2001/05/13 21:57:06 adminis #ifndef __BEOS__ #include +#ifndef __OS2__ #include +#endif #else #include #endif +#if defined(__EMX__) || defined (__OS2__) +#include /* OS/2/EMX needs a little help with select */ +#ifdef __OS2__ +#include +#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) +#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) - CloseSocket(fd); +#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, diff --git a/jbsockets.h b/jbsockets.h index 6d77c4c5..78f2ee0d 100644 --- a/jbsockets.h +++ b/jbsockets.h @@ -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 @@ -37,23 +37,74 @@ * * 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 + * * *********************************************************************/ +#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 e6d06bd7..62694b0c 100644 --- 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 + * * *********************************************************************/ @@ -47,15 +533,18 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $ #include #include -#ifdef _WIN32 +#ifdef FEATURE_PTHREAD +#include +#endif /* def FEATURE_PTHREAD */ -# include -# include -# include -# include -# ifdef TOGGLE -# include -# endif /* def TOGGLE */ +#ifdef _WIN32 +# ifndef FEATURE_PTHREAD +# ifndef STRICT +# define STRICT +# endif +# include +# include +# 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 -# include # include +# endif /* ndef __OS2__ */ +# include # include +# include + +#ifdef sun +#include +#endif /* sun */ + +#ifdef unix +#include +#include +#endif + # include # 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 /* declarations for threads and stuff. */ # endif +# if defined(__EMX__) || defined(__OS2__) +# include /* OS/2/EMX needs a little help with select */ +# endif +# ifdef __OS2__ +#define INCL_DOS +# include +#define bzero(B,N) memset(B,0x00,n) +# endif + # ifndef FD_ZERO # include # 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 "\n" - -static const char CFAIL[] = - "HTTP/1.0 503 Connect failed\n" - "Content-Type: text/html\n\n" - "\n" - "\n" - "Internet Junkbuster: Connect failed\n" - "\n" - BODY - "

    " - BANNER - "

    " - "TCP connection to '%s' failed: %s.\n
    " - "\n" - "\n"; - -static const char CNXDOM[] = - "HTTP/1.0 404 Non-existent domain\n" - "Content-Type: text/html\n\n" - "\n" - "\n" - "Internet Junkbuster: Non-existent domain\n" - "\n" - BODY - "

    " - BANNER - "

    " - "No such domain: %s\n" - "\n" - "\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" - "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\r\n" - "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" - "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\r\n" - "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;"; - -static const char FWGIF[] = - "HTTP/1.0 302 Blocked Advert\r\n" - "Pragma: no-cache\r\n" - "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n" - "Expires: Thu Jul 31, 1997 07:42:22 pm GMT\r\n" - "Location: "; - -#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) - { - break; /* no HTTP request! */ + if (req == NULL) + { + break; /* no HTTP request! */ } - if (*req == '\0') - { - continue; /* more to come! */ + 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)) - { - write_socket(csp->cfd, FWGIF, sizeof(FWGIF)-1); - write_socket(csp->cfd, tinygifurl, strlen(tinygifurl)); - } - 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"); - -#ifdef AMIGA - if(!childs) - { - exit(1); - } -#endif + +#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) -#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)"junkbuster child", - NP_StackSize, 20*1024, - TAG_DONE))) - { - 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(); -#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 fcafbb71..1778f1ea 100644 --- 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 @@ -35,46 +35,90 @@ * * 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 + * * *********************************************************************/ -/* Declare struct FILE for vars and funcs. */ -#include - -/* 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 index cbe21048..00000000 --- a/junkbstr.txt +++ /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 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" -# -# default: Kill the referrer-header from the client -# 'text' : Always send 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 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 index d88294da..00000000 --- a/junkbuster.1 +++ /dev/null @@ -1,871 +0,0 @@ -.TH JUNKBUSTER 1 "http://www.junkbusters.com/ht/en/ijb2.0man.html" -.SH NAME -\fBjunkbuster\fP -- The -Internet Junkbuster -Proxy -\s-2(TM)\s+2 -.SH SYNOPSIS -\fBjunkbuster\fP -\fI\&configfile\fP -(Version 2.0 onwards) -.br -\fBjunkbstr.exe\fP -\fI\&configfile\fP -(Windows) -.br -\fBjunkbuster\fP -[-a] -[-y] -[-s] -[-c] -[-v] -.br -[-u user_agent] -[-r referer] -[-t from] -.br -[-b blockfile] -[-j jarfile] -[-l logfile] -.br -[-w NAME=VALUE] -[-x Header_text] -.br -[-h [bind_host_address][:bind_port]] -.br -[-f forward_host[:port]] -[-d N] -.br -[-g gw_protocol[:[gw_host][:gw_port]]] -.br -(Version 1.4 and earlier) -.SH DESCRIPTION -\fBjunkbuster\fP -is an instrumentable proxy that filters the -\s-2HTTP\s0 -stream between -web servers and browsers. -Its main purpose is to enhance privacy. -.P -Versions before 2.0 used command-line options; -Versions from 2.0 onward use a configuration file. -The following descriptions of the options first give the older -command-line usage, then the new configfile line. -.P -In Versions 2.0.1 upwards on Windows, -a start-up message is printed and the configuration is read from the file -\fC\&junkbstr.ini\fP -if it exists and no argument was given. -.P -All files except the configfile -are checked for changes before each page is fetched, -so they may edited without restarting the proxy. -.SS OPTIONS -.TP -.\" anchor: o_b blockfile -\fI-b blockfile\fP (Old) blockfile \fIblockfile\fP (New) -Block\" ijbfaq.html#blocking -requests to -\s-2URL\s0s -matching any pattern given in the lines of the -\fI\&blockfile\fP. -The -\fBjunkbuster\fP -instead returns status 202, indicating that the request has been accepted -(though not completed), -and a -message identifying itself\" ijbfaq.html#show -(though the browser may -display only a broken image icon). -(Versions before 2.0 returned an error 403 (Forbidden).) -The syntax of a pattern is -\fB\&[domain][:port][/path]\fP -(the -\fB\&http://\fP -or -\fB\&https://\fP -protocol part is omitted). -To decide if a pattern matches a target, the domains are compared first, -then the paths. -.P -To compare the domains, -the pattern domain and the target -domain specified in the -\s-2URL\s0 -are each broken into their components. -(Components are separated by the -\fC\&.\fP -(period) character.) -Next each of the target components -is compared with the corresponding pattern component: last with last, -next-to-last with next-to-last, and so on. -(This is called -\fIright-anchored\fP -matching.) -If all of the pattern components find their match in the target, -then the domains are considered a match. -Case is irrelevant when comparing domain components. -.P -A successfully -matching pattern can be an anchored substring of a target, but -not vice versa. -Thus if a pattern doesn't specify a domain, -it matches all domains. -.\" anchor: wildcard -Furthermore, when comparing two components, -the components must either match in their entirety or up to a wildcard -\fC\&* \fP -(star character) in the pattern. The wildcard feature -implements only a "prefix" match capability ("abc*" vs. "abcdefg"), -not suffix matching ("*efg" vs. "abcdefg") or -infix matching ("abc*efg" vs. "abcdefg"). -The feature is restricted to the domain component; -it is unrelated to the optional -regular expression -feature in the path -(described below).\" ijbman.html#regex -.P -If a numeric port -is specified in the pattern domain, then the target port must -match as well. The default port in a target is port 80. -.P -If the domain and port match, -then the target -\s-2URL\s0 -path is checked for -a match against the path in the pattern. -Paths are compared with a simple case-sensitive -left-anchored substring comparison. -Once again, the pattern can be an -anchored substring of the target, but not vice versa. -A path of -\fC\&/\fP -(slash) would match all paths. Wildcards are not considered in -path comparisons. -.P -For example, the target -\s-2URL\s0 -.br -.ti +0.25i -\fB\&the.yellow-brick-road.com/TinMan/has_no_brain\fP -.br -would be matched (and blocked) by the following patterns -.br -.ti +0.25i -\fB\&yellow-brick-road.com\fP -.br -and -.br -.ti +0.25i -\fB\&Yellow*.COM\fP -.br -and -.br -.ti +0.25i -\fB\&/TinM\fP -.br -but not -.br -.ti +0.25i -\fB\&follow.the.yellow-brick-road.com\fP -.br -or -.br -.ti +0.25i -\fB\&/tinman\fP -.br -.P -Comments in a blockfile start with a -\fB\&#\fP -(hash) character and end at a new line. -Blank lines are also ignored. -.P -Lines beginning with a -\fC\&~\fP -(tilde) character are taken to be -exceptions:\" ijbfaq.html#exceptions -a -\s-2URL\s0 -blocked by previous patterns that matches the rest of -the line is let through. (The last match wins.) -.P -Patterns -may contain -\s-2POSIX\s0 -regular expressions\" ijbfaq.html#regex -provided the -\fBjunkbuster\fP -was compiled with this option -(the default in Version 2.0 on). -The idiom -\fC\&/*.*/ad\fP -can then be used -to match any -\s-2URL\s0 -containing -\fC\&/ad\fP -(such as -\fC\&http://nomatterwhere.com/images/advert/g3487.gif\fP -for example). -These expressions -don't work\" ijbman.html#substring -in the domain part. -.P -In version 1.3 and later -the blockfile and cookiefile are checked for changes before each request. -.TP -tinygif \fIN\fP -Set appearance of blocked GIFs. You can select one of the following -values: -.br -.br -\h'-\w"0 = "u'0 = Show a ``broken icon'' in the browser -.br -\h'-\w"1 = "u'1 = Show a one pixel transparent GIF -.br -\h'-\w"2 = "u'2 = Show a GIF with the word ``JUNKBUSTER'' -.TP -popupfile \fI\&popup\fP -Sets the name of the popupfile. If uncommented, the popupfile -controls on which sites Javascript popup windows are disabled. -.TP -.\" anchor: o_w wafer -\fI-w NAME=VALUE\fP (Old) wafer \fINAME=VALUE\fP (New) -Specifies a pair to be sent as a cookie with every request -to the server.\" ijbfaq.html#wafers -(Such boring cookies are called -\fI\&wafers\fP.) -This option may be called more than once to generate multiple wafers. -The original -Netscape specification -prohibited -semi-colons, commas and white space; -these characters will be -\s-2URL\s0-encoded -if used in wafers. -The Path and Domain attributes are not currently supported. -.TP -.\" anchor: o_c cookiefile -\fI-c cookiefile\fP (Old) cookiefile \fIcookiefile\fP (New) -Enforce the cookie management policy specified in the -\fI\&cookiefile.\fP -.\" anchor: java -If this option is not used all cookies are silently crunched, -so that users who never want cookies aren't bothered by browsers -asking whether each cookie should be accepted. -However, cookies can -still get through\" ijbfaq.html#breakthrough -via -JavaScript\" links.html#javascript -and -\s-2SSL\s0, -so alerts should be left on. -.P -In Version 1.2 and later -this option must be followed by a -filename\" ijbfaq.html#crumble -containing instructions on which sites are allowed to -receive and set cookies. -.\" anchor: drop -By default cookies are dropped in both the browser's request -and the server's response, unless the -\s-2URL\s0 -requested matches an entry in the -\fI\&cookiefile\fP. -The matching algorithm is the same as for the blockfile. -A leading -\fC\&>\fP -character allows -server-bound\" ijbfaq.html#directional -cookies only; -a -\fC\&<\fP -allows only browser-bound cookies; -a -\fC\&~\fP -character stops cookies in -both directions.\" ijbfaq.html#crumble -Thus a cookiefile containing a single line with the two characters -\fC\&>*\fP -will pass on all cookies to servers but not give any new ones to the browser. -.TP -.\" anchor: o_j jarfile -\fI-j jarfile\fP (Old) jarfile \fIjarfile\fP (New) -All Set-cookie attempts by the server are -logged\" ijbfaq.html#jar -to -\fI\&jarfile\fP. -If no wafer is specified, -one containing a -canned notice\" ijbfaq.html#notice -(the -\fI\&vanilla wafer\fP) -is added as an alert to the server -unless the -suppress-vanilla-wafer\" ijbman.html#suppress-vanilla-wafer -option is invoked. -.TP -.\" anchor: o_v suppress-vanilla-wafer -\fI-v\fP (Old) suppress-vanilla-wafer \fI\fP (New) -Suppress the vanilla wafer. -.TP -.\" anchor: o_t from -\fI-t from\fP (Old) from \fIfrom\fP (New) -If the browser -discloses an email address\" ijbfaq.html#from -in the -\fB\&FROM\fP -header (most don't), -replace it with -\fI\&from.\fP -If -\fI\&from\fP -is set to -\fB\&.\fP -(the period character) -the -\fB\&FROM\fP -is passed to the server unchanged. -The default is to delete the -\fB\&FROM\fP -header. -.TP -.\" anchor: o_r referer -\fI-r referer\fP (Old) referer \fIreferer\fP (New) -Whenever the browser discloses the -\s-2URL\s0 -that -led to\" ijbfaq.html#referer -the current request, -replace it with -\fI\&referer.\fP -If -\fI\&referer\fP -is set to -\fB\&.\fP -(period) -the -\s-2URL\s0 -is passed to the server unchanged. -In -Version 1.4 -and later, if referer is set to -\fB\&@\fP -(at) the -\s-2URL\s0 -is sent in cases where the cookiefile -specifies that a cookie would be sent. -(No way to send bogus referers selectively is provided.) -The default is to delete Referer. -.P -Version 2.0 also accepts the spelling -\fC\&referrer\fP, -which most dictionaries consider correct. -.TP -.\" anchor: o_u user-agent -\fI-u user-agent\fP (Old) user-agent \fIuser-agent\fP (New) -Information disclosed by the browser -about itself\" ijbfaq.html#agent -is replaced with the value -\fI\&user-agent.\fP -If -\fI\&user-agent\fP -is set to -\fB\&.\fP -(period) -the -\fB\&User-Agent\fP -header is passed to the server unchanged, -along with any -\fB\&UA\fP -headers produced by -\s-2MS-IE\s0 -(which would otherwise be deleted). -In -Version 1.4 -and later, if -\fI\&user-agent\fP -is set to -\fB\&@\fP -(at) these headers are sent unchanged in cases where the cookiefile -specifies that a cookie would be sent, -otherwise only default -\fB\&User-Agent\fP -header is sent. -That default -is Mozilla/3.0 (Netscape) -with an unremarkable -Macintosh\" ijbfaq.html#infer -configuration. -If used with a browser less advanced than Mozilla/3.0 or IE-3, the default -may encourage pages containing extensions that confuse the browser. -.TP -.\" anchor: o_h listen-address -\fI-h [host][:port]\fP (Old) listen-address \fI[host][:port]\fP (New) -If -\fI\&host\fP -is specified, -bind the -\fBjunkbuster\fP -to that -\s-2IP\s0 -address. -If a -\fI\&port\fP -is specified, use it. -The default -port -is 8000; -the default host is -\fC\&localhost\fP. -Before Version 2.0.2, -the default was to bind to all -\s-2IP\s0 -addresses -(\fB\&INADDR_ANY\fP); -but this has been restricted to -\fB\&localhost\fP -to avoid unintended security breaches. -(To open the proxy to all, use the line -.br -.ti +0.25i -\fB\&listen-address :8000\fP -.br -in the configuration file.) -.TP -.\" anchor: o_f forwardfile -\fI-f forward_host[:port]\fP (Old) forwardfile \fIforwardfile\fP (New) -Version 1.X required all -\s-2HTTP\s0 -requests from the client to be forwarded to the same destination. -Version 2.0 takes its routing specification from a -\fI\&forwardfile\fP, -allowing selection of the proxy (a.k.a. forwarding host) and gateway -according to the -\s-2URL\s0. -Here is a typical line. -.br -.ft CW -.S 8 -.nf -.sp -* lpwa.com:8000 . . -.S -.ft -.fi -.sp - -.P -Each line contains four fields: -\fB\&target\fP, -\fB\&forward_to\fP, -\fB\&via_gateway_type\fP -and -\fB\&gateway\fP. -As usual, the -last\" ijbman.html#compare -\fB\&target\fP -domain that matches the requested -\s-2URL\s0 -wins, -and the -\fC\&*\fP -character alone matches any domain. -The target domain need not be a fully qualified -hostname; it can be a general domain such as -\fC\&com\fP -or -\fC\&co.uk\fP -or even just a port number. -.\" anchor: nose -For example, because -LPWA -does not handle -SSL,\" ijbfaq.html#encrypt -the line above will typically be followed by a line such as -.br -.ft CW -.S 8 -.nf -.sp -:443 . . . -.S -.ft -.fi -.sp - -to allow SSL transactions to proceed directly. -The cautious would also -add an entry in their blockfile to stop transactions -to port 443 for all but specified trusted sites. -.P -If the winning -\fB\&forward_to\fP -field is -\fC\&.\fP -(the dot character) the proxy connects -directly to the server given in the -\s-2URL\s0, -otherwise it forwards to the host and port number specified. -The default port is 8000. -The -\fC\&via_gateway_type\fP -and -\fC\&gateway\fP -fields also use a dot to indicate no gateway protocol. -The gateway protocols are explained -below.\" ijbman.html#o_g -.P -The example line above in a forwardfile alone -would send everything through port 8000 at -\fC\&lpwa.com\fP -with no gateway protocol, -and is equivalent to the old -\fC\&-f lpwa.com:8000\fP -with no -\fC\&-g\fP -option. -For more information see the example file provided with the distribution. -.P -Configure with care: no loop detection is performed. -When setting up chains of proxies that might loop back, try adding -Squid.\" ijbman.html#squid -.TP -.\" anchor: o_g -\fI-g gw_protocol[:[gw_host][:gw_port]]\fP (Old) -Use -\fI\&gw_protocol\fP -as the gateway protocol. -This option was introduced in Version 1.4, -but was folded into the -forwardfile\" ijbman.html#forwardfile -option in Version 2.0. -The default is to use no gateway protocol; -this may be explicitly specified as -\fB\&direct\fP -on the command line -or the dot character in the forwardfile. -The -\fC\&SOCKS4\fP -protocol may be specified as -\fB\&socks\fP -or -\fB\&socks4\fP. -The -\fC\&SOCKS4A\fP -protocol is specified as -\fB\&socks4a\fP. -The -\fC\&SOCKS5\fP -protocol is not currently supported. -The default -\s-2SOCKS\s0 -\fI\&gw_port\fP -is 1080. -.P -The user's browser should -\fInot\fP -be -configured\" ijbfaq.html#socks -to use -\fC\&SOCKS\fP; -the proxy conducts the negotiations, not the browser. -.P -The user identification capabilities of -\fC\&SOCKS4\fP -are deliberately not used; -the user is always identified to the -\fC\&SOCKS\fP -server as -\fC\&userid=anonymous\fP. -If the server's policy is to reject requests from -\fC\&anonymous\fP, -the proxy will not work. -Use a -debug\" ijbman.html#o_d -value of 3 -to see the status returned by the server. -.TP -.\" anchor: o_d debug -\fI-d N\fP (Old) debug \fIN\fP (New) -Set debug mode. -The most common value is 1, -to -pinpoint\" ijbfaq.html#pinpoint -offensive -\s-2URL\s0s, -so they can be added to the blockfile. -The value of -\fB\&N\fP -is a bitwise -logical-\s-2OR\s0 -of the following values: -.br -.br -\h'-\w"1 = "u'1 = URLs (show each URL requested by the browser); -.br -\h'-\w"2 = "u'2 = Connections (show each connection to or from the proxy); -.br -\h'-\w"4 = "u'4 = I/O (log I/O errors); -.br -\h'-\w"8 = "u'8 = Headers (as each header is scanned, show the header and what is done to it); -.br -\h'-\w"16 = "u'16 = Log everything (including debugging traces and the contents of the pages). -.\" anchor: or -Multiple -\fB\&debug\fP -lines are permitted; they are logical OR-ed together. -.P -Because most browsers send several requests in parallel -the debugging output may appear intermingled, so the -single-threaded\" ijbman.html#single-threaded -option is recommended when using -debug\" ijbman.html#debug -with -\fB\&N\fP -greater than 1. -.TP -.\" anchor: o_y add-forwarded-header -\fI-y\fP (Old) add-forwarded-header \fI\fP (New) -Add -\fB\&X-Forwarded-For\fP -headers to the server-bound -\s-2HTTP\s0 -stream -indicating the client -\s-2IP\s0 -address -to the server,\" ijbfaq.html#detect -in the new style of -Squid 1.1.4.\" ijbman.html#squid -If you want the traditional -\fC\&HTTP_FORWARDED\fP -response header, add it manually with the --x\" ijbman.html#o_x -option. -.TP -.\" anchor: o_x add-header -\fI-x HeaderText\fP (Old) add-header \fIHeaderText\fP (New) -Add the -\fI\&HeaderText\fP -verbatim to requests to the server. -Typical uses include -adding old-style forwarding notices such as -\fB\&Forwarded: by http://pro-privacy-isp.net\fP -and reinstating the -\fB\&Proxy-Connection: Keep-Alive\fP -header -(which the -\fBjunkbuster\fP -deletes so as -not\" ijbfaq.html#detect -to reveal its existence). -No checking is done for correctness or plausibility, -so it can be used to throw any old trash into the server-bound -\s-2HTTP\s0 -stream. -Please don't litter. -.TP -.\" anchor: o_s single-threaded -\fI-s\fP (Old) single-threaded \fI\fP (New) -Doesn't -\fB\&fork()\fP -a separate process -(or create a separate thread) -to handle each connection. -Useful when debugging to keep the process single threaded. -.TP -.\" anchor: o_l logfile -\fI-l logfile\fP (Old) logfile \fIlogfile\fP (New) -Write all debugging data into -\fI\&logfile.\fP -The default -\fI\&logfile\fP -is the standard output. -.TP -.\" anchor: o_acl aclfile -aclfile \fIaclfile\fP (New) -Unless this option is used, the proxy talks to anyone who can connect to it, -and everyone who can has equal permissions on where they can go. -An access file allows restrictions to be placed on these two policies, -by distinguishing some -\fIsource\fP -\s-2IP\s0 -addresses and/or -some -\fIdestination\fP -addresses. -(If a -forwarder or a gateway\" ijbman.html#forwardfile -is being used, its address is considered the destination address, -not the ultimate -\s-2IP\s0 -address of the -\s-2URL\s0 -requested.) -.P -Each line of the access file begins with -either the word -\fB\&permit\fP -or -\fB\&deny\fP -followed by source and (optionally) destination addresses -to be matched against those of the -\s-2HTTP\s0 -request. -The last matching line specifies the result: if it was a -\fB\&deny\fP -line or if no line matched, -the request will be refused. -.P -A source or destination -can be specified as a single numeric -\s-2IP\s0 -address, -or with a hostname, provided that the host's name -can be resolved to a numeric address: this cannot be used to block all -\fB\&.mil \fP -domains for example, -because there is no single address associated with that domain name. -Either form may be followed by a slash and an integer -\fB\&N\fP, -specifying a subnet mask of -\fB\&N\fP -bits. -For example, -\fB\&permit 207.153.200.72/24\fP -matches the entire Class-C subnet from -207.153.200.0 -through 207.153.200.255. -(A netmask of 255.255.255.0 corresponds to 24 bits of -ones in the netmask, as with -\fC\&*_MASKLEN=24\fP.) -A value of 16 would be used for a Class-B subnet. -A value of zero for -\fB\&N\fP -in the subnet mask length will cause any address to match; -this can be used to express a default rule. -For more information see the example file provided with the distribution. -.P -If you like these access controls -you should probably have -firewall;\" ijbfaq.html#firewall -they are not intended to replace one. -.TP -.\" anchor: o_tf trustfile -trustfile \fItrustfile\fP (New) -This feature is experimental, has not been fully documented and is -very subject to change. -The goal is for parents to be able to choose a page or site whose -links they regard suitable for their -young children\" ijbfaq.html#children -and for the proxy to allow access only to sites mentioned there. -To do this the proxy examines the -referer\" ijbman.html#o_r -variable on each page request to check they resulted from -a click on the ``trusted referer'' site: if so the referred site -is added to a list of trusted sites, so that the child can -then move around that site. -There are several uncertainties in this scheme that experience may be -able to iron out; check back in the months ahead. -.TP -.\" anchor: o_ti trust_info_url -trust_info_url \fItrust_info_url\fP (New) -When access is denied due to lack of a trusted referer, this -\s-2URL\s0 -is displayed with a message pointing the user to it for further information. -.TP -.\" anchor: o_hc hide-console -hide-console \fI\fP (New) -In the Windows version only, instructs the program -to disconnect from and hide the command console after starting. -.TP -.\" anchor: o_a -\fI-a\fP (Old) -(Obsolete) Accept the server's -\fB\&Set-cookie\fP -headers, passing them through to the browser. -.\" anchor: obsolete -This option was removed in Version 1.2 -and replaced by an improvement to the --c\" ijbman.html#o_c -option. -.LE -.SH INSTALLATION AND USE -Browsers must be told where to find the -\fBjunkbuster\fP -(e.g. -\fB\&localhost\fP -port 8000). -To set the -\s-2HTTP\s0 -proxy in Netscape 3.0, -go through: -\fB\&Options\fP; -\fB\&Network Preferences\fP; -\fB\&Proxies\fP; -\fB\&Manual Proxy Configuration\fP; -\fB\&View\fP. -See the -\s-2FAQ\s0 -for other browsers. -The -Security Proxy\" ijbfaq.html#security -should also be set to the same values, -otherwise -\fB\&shttp:\fP -\s-2URL\s0s -won't work. -.P -Note the limitations -explained in the -\s-2FAQ\s0. -.SH CHECKING OPTIONS -To allow users to -check\" ijbfaq.html#show -that a -\fBjunkbuster\fP -is running and how it is configured, -it intercepts requests for any -\s-2URL\s0 -ending in -\fB\&/show-proxy-args\fP -and blocks it, -returning instead returns information on its -version number and -current configuration -including the contents of its blockfile. -To get an explicit warning that no -\fBjunkbuster\fP -intervened if the proxy was not configured, -it's best to point it to a -\s-2URL\s0 -that does this, such as -http://internet.junkbuster.com/cgi-bin/show-proxy-args -on Junkbusters's website. -.SH SEE ALSO -http://www.waldherr.org/junkbuster/\" waldherr.org# -.br -http://www.junkbusters.com/ht/en/ijbfaq.html\" ijbfaq.html# -.br -http://www.junkbusters.com/ht/en/cookies.html\" cookies.html# -.br -http://internet.junkbuster.com/cgi-bin/show-proxy-args -.br -http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html -.br -http://squid.nlanr.net/Squid/ -.br -http://www-math.uni-paderborn.de/~axel/ -.SH COPYRIGHT AND GPL -Written and copyright by the Anonymous Coders and Junkbusters Corporation -and made available under the -GNU General Public License (GPL).\" gpl.html# -This software comes with -NO WARRANTY.\" gpl.html#nowarr -Internet Junkbuster -Proxy -is a -trademark\" legal.html#marks -of Junkbusters Corporation. diff --git a/junkbuster.init b/junkbuster.init deleted file mode 100644 index c74b6b7a..00000000 --- a/junkbuster.init +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/sh -# -# $Id: junkbuster.init,v 1.2 2001/04/30 02:36:54 rodney Exp $ -# -# This is file is either -# -# /etc/rc.d/init.d/junkbuster -# -# or -# -# /sbin/init.d/junkbuster -# -# and was put here by the junkbuster rpm -# -# junkbuster This shell script takes care of starting and stopping -# junkbuster. -# -# This works only correctly if the user `nobody' is allowed -# to be in the directory where this file is called -# (for example: /root is NOT ok) -# --------------------------------------------------------------------------- -# Force /bin/sh as shell (padraic@renaghan.com). -# Augmented with help by Sterling -# Hints from mjohnson11@uswest.net -# Hints from rochedav@primenet.com -# --------------------------------------------------------------------------- -# These lines are needed so Redhat's config tools will "see" this script: -# chkconfig: 35 84 09 -# description: Blocks annoying ads from the internet, along with cookies \ -# and a few other privacy features. -# processname: junkbuster -# config: /etc/junkbuster/config - - -# --------------------------------------------------------------------------- -# -# SuSE only -# -# --------------------------------------------------------------------------- -if [ -f /etc/rc.config ]; then - -# Author: Daniel Bischof , 1999 -# Adjustment: Axel Braun , 17.08.2000 -. /etc/rc.config -#base=${0##*/} -#link=${base#*[SK][0-9][0-9]} -#test $link = $base && START_IJB=yes -#test "$START_IJB" = "yes" || exit 0 -return=$rc_done -case "$1" in - start) - echo -n "Starting The Internet Junkbuster" - su - nobody -c 'nohup /usr/sbin/junkbuster /etc/junkbuster/config < /dev/null > /dev/null &' - sleep 1 - echo -e "$return" - ;; - stop) - echo -n "Shutting down The Internet Junkbuster" - killproc -TERM /usr/sbin/junkbuster || return=$rc_failed - echo -e "$return" - ;; - restart|reload) - echo -n "Reload The Internet Junkbuster" - killproc -HUP /usr/sbin/junkbuster || return=$rc_failed - echo -e "$return" - ;; - status) - checkproc /usr/sbin/junkbuster && echo OK || echo No process - ;; - *) - echo "Usage: $0 {start|restart|status|stop}" - exit 1 -esac -test "$return" = "$rc_done" || exit 1 -exit 0 - -else -# --------------------------------------------------------------------------- -# -# RedHat only -# -# --------------------------------------------------------------------------- - -# Source function library. -if [ -f /etc/rc.d/init.d/functions ]; then -. /etc/rc.d/init.d/functions -fi - -if [ -f /etc/sysconfig/network ]; then -. /etc/sysconfig/network -fi - -# Check that networking is up. -[ ${NETWORKING} = "no" ] && exit 0 - -[ -f /etc/junkbuster/config ] || exit 0 - -[ -f /usr/sbin/junkbuster ] || exit 0 - -RETVAL=0 - -# See how we were called. -case "$1" in - - start) - # abort if already started - pid=`pidofproc junkbuster` - [ -n "$pid" ] && ps h $pid >/dev/null 2>&1 && \ - echo -n "Already started: " && status junkbuster && \ - exit 0 - - # Start daemon. - echo -n "Starting junkbuster:" && RETVAL=1 - ulimit -c 0 - su - nobody -s /bin/sh -c '/usr/sbin/junkbuster /etc/junkbuster/config' & - sleep 1 - pid=`pidofproc junkbuster` - [ -n "$pid" ] && ps h $pid >/dev/null 2>&1 && RETVAL=0 && echo_success && touch /var/lock/subsys/junkbuster - [ $RETVAL -eq 1 ] && echo_failure - echo - ;; - - stop) - # Stop daemon. - echo -n "Shutting down junkbuster:" - killproc junkbuster - RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/junkbuster - echo - ;; - - status) - status junkbuster - RETVAL=$? - ;; - - restart|reload) - $0 stop && $0 start - ;; - - *) - echo "Usage: junkbuster {start|stop|status|restart|reload}" - exit 1 -esac - -exit $RETVAL - -fi - diff --git a/junkbuster.logrotate b/junkbuster.logrotate deleted file mode 100644 index e8e8b92d..00000000 --- a/junkbuster.logrotate +++ /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 index 44ff3496..00000000 --- a/junkbuster.monthly +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh - -# $Id: junkbuster.monthly,v 1.1 2001/04/16 21:10:38 rodney Exp $ -# -# bug fixed, which downloaded all three files to the file blocklist -# -# Revised: Mon Dec 06 10:46:08 PST 1999 by Jon Hamkins -# Hints by Ulrik Haugen -# Hints by mirjamv@theochem.kun.nl -# -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/junkbuster.weekly b/junkbuster.weekly deleted file mode 100644 index bc07b231..00000000 --- a/junkbuster.weekly +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# $Id: junkbuster.weekly,v 1.1 2001/04/16 21:10:38 rodney Exp $ - -# Revised: Mon Dec 06 10:46:08 PST 1999 by Jon Hamkins -# Hints by Ulrik Haugen -# Hints by mirjamv@theochem.kun.nl - -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 diff --git a/killpopup.c b/killpopup.c index 7004962d..34653738 100644 --- a/killpopup.c +++ b/killpopup.c @@ -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 + * * *********************************************************************/ @@ -42,201 +109,102 @@ const char killpopup_rcs[] = "$Id: killpopup.c,v 1.1 2001/05/13 21:57:06 adminis #include #include #include -#include #include #include #include -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__OS2__) #include #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, "'); - if (q) + close_p = strchr(start_p, '>'); + if (close_p) { /* we are now between */ - 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: diff --git a/killpopup.h b/killpopup.h index 42602ea2..7d2eadf6 100644 --- a/killpopup.h +++ b/killpopup.h @@ -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 @@ -34,23 +34,67 @@ * * 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 + * * *********************************************************************/ #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 index 00000000..6cd7f891 --- /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. + * + * + *********************************************************************/ + + +#include "config.h" + +#ifndef _WIN32 +/* FIXME: The following headers are not needed for Win32. Are they + * needed on other platforms? + */ +#include +#include +#include +#include +#endif +#include + +#if !defined(_WIN32) && !defined(__OS2__) +#include +#endif + +#include + +#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 index 00000000..afa44238 --- /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. + * + * + *********************************************************************/ + + +#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: +*/ diff --git a/loadcfg.c b/loadcfg.c index f29d6654..1d6a10eb 100644 --- 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 + * * *********************************************************************/ @@ -49,43 +311,46 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.1 2001/05/13 21:57:06 administrat #include #include #include +#include #ifdef _WIN32 -# include +# ifndef STRICT +# define STRICT +# endif # include -# include -# include -# ifdef TOGGLE -# include -# 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 -# include # include +#endif +# include # include # include #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; -#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; - 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, + "
    \nWARNING: Wrong number of parameters for " + "deny-access directive in configuration file.

    \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, + "
    \nWARNING: Invalid source IP for deny-access directive" + " in configuration file: \""); + string_append(&config->proxy_args, + vec[0]); + string_append(&config->proxy_args, + "\"

    \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, + "
    \nWARNING: Invalid destination IP for deny-access directive" + " in configuration file: \""); + string_append(&config->proxy_args, + vec[0]); + string_append(&config->proxy_args, + "\"

    \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, + "
    \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, + "
    \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 : - 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 : - freez((char *)tinygifurl); - tinygif = atoi(arg); - if(3 == tinygif) - { - p = arg; - while((*p >= '0') && (*p <= '9')) - { - p++; - } - while((*p == ' ') || (*p == '\t')) - { - p++; - } - if (*p) - { - q = malloc(strlen(p) + 5); - if (q) - { - strcpy(q, p); - strcat(q, "\r\n\r\n"); - tinygifurl = q; - } - } - } - if ((tinygif != 1) && - (tinygif != 2) && - ((tinygif != 3) || (tinygifurl==NULL)) ) - { - log_error(LOG_LEVEL_ERROR, "tinygif setting invalid."); - } + 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, + "
    \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, + "
    \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 : - 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 : - freez((char *)logfile); - logfile = strdup(arg); - continue; + /* Parse the parent HTTP proxy host[:port] */ + p = vec[2]; - case hash_blockfile : - freez((char *)blockfile); - blockfile = strdup(arg); - continue; + if (strcmp(p, ".") != 0) + { + cur_fwd->forward_host = strdup(p); -#ifdef USE_IMAGE_LIST - case hash_imagefile : - 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 : - 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 : - freez((char *)haddr); - haddr = strdup(arg); - continue; + /* Add to list. */ + cur_fwd->next = config->forward; + config->forward = cur_fwd; - case hash_forwardfile : - freez((char *)forwardfile); - forwardfile = strdup(arg); - continue; + continue; -#ifdef ACL_FILES - case hash_aclfile : - 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 : - 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, + "
    \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 : - 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, + "
    \nWARNING: Bad URL specifier for " + "forward-socks4a directive in configuration file."); continue; -#endif /* def PCRS */ + } - case hash_user_agent : - 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 : - freez((char *)referrer); - referrer = strdup(arg); - continue; + cur_fwd->gateway_host = strdup(p); - case hash_from : - 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, + "
    \nWARNING: Wrong number of parameters for " + "permit-access directive in configuration file.

    \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, + "
    \nWARNING: Invalid source IP for permit-access directive" + " in configuration file: \""); + string_append(&config->proxy_args, + vec[0]); + string_append(&config->proxy_args, + "\"

    \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, + "
    \nWARNING: Invalid destination IP for permit-access directive" + " in configuration file: \""); + string_append(&config->proxy_args, + vec[0]); + string_append(&config->proxy_args, + "\"

    \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, "
    \nWARNING: unrecognized directive : %s

    \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, "
    \nWARNING: unrecognized directive : "); + string_append(&config->proxy_args, buf); + string_append(&config->proxy_args, "

    \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("usermanual); + string_append(&buf, CONFIG_HELP_PREFIX); + string_join (&buf, string_toupper(command)); + string_append(&buf, "\">"); + string_append(&buf, command); + string_append(&buf, " "); + + 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, ""); + string_join (&buf, s); + string_append(&buf, ""); + } + else + { + string_join (&buf, s); + } } -#endif /* def JAR_FILES */ - end_proxy_args(); + string_append(&buf, "
    \n"); + string_join(&config->proxy_args, buf); } diff --git a/loadcfg.h b/loadcfg.h index e567b7e0..3e71b752 100644 --- 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 @@ -37,107 +37,124 @@ * * 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 + * * *********************************************************************/ -/* Declare struct FILE for vars and funcs. */ -#include - -/* 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; -#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: diff --git a/loaders.c b/loaders.c index 71ff3fa0..8ebfa70a 100644 --- 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 + * * *********************************************************************/ @@ -45,74 +271,39 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.1 2001/05/13 21:57:06 administrat #include #include #include -#include #include #include #include +#include -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__OS2__) #include #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, "

    The file `"); - fs->proxy_args = strsav(fs->proxy_args, p); - fs->proxy_args = strsav(fs->proxy_args, - "' contains the following patterns

    \n"); - freez(p); - } - fs->proxy_args = strsav(fs->proxy_args, "
    ");
    -   }
    -#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, "
    "); - } -#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, "
    "); + *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, ""); - } -#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, ""); -#endif /* ndef SPLIT_PROXY_ARGS */ - - fclose(fp); - -#ifndef SPLIT_PROXY_ARGS - if (!suppress_blocklists) - { - fs->proxy_args = strsav(fs->proxy_args, ""); - } -#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, ""); - } -#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, ""); - } -#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, ""); - } -#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, ""); - } -#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, ""); + 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 diff --git a/loaders.h b/loaders.h index 0551a6e9..216c352d 100644 --- 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 @@ -37,54 +37,186 @@ * * 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 + * * *********************************************************************/ -#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: diff --git a/miscutil.c b/miscutil.c index 1257a99d..065cd5f6 100644 --- a/miscutil.c +++ b/miscutil.c @@ -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 + * * *********************************************************************/ @@ -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 +#include #include +#if !defined(_WIN32) && !defined(__OS2__) +#include +#endif /* #if !defined(_WIN32) && !defined(__OS2__) */ #include -#include #include +#include +#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 s1s2 * *********************************************************************/ -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 s1s2 * *********************************************************************/ -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 , 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 +#include +#include +#include +#include +#include +#include + +#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, \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 diff --git a/miscutil.h b/miscutil.h index 0a6b95e1..e4793c8c 100644 --- a/miscutil.h +++ b/miscutil.h @@ -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 @@ -37,27 +37,146 @@ * * 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 + * * *********************************************************************/ +#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: diff --git a/parsers.c b/parsers.c index f56c0b7c..df2ae59a 100644 --- 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 + * * *********************************************************************/ #include "config.h" +#ifndef _WIN32 #include #include +#endif + #include #include +#include #include -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__OS2__) #include #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 */ /* diff --git a/parsers.h b/parsers.h index 14025448..837bac4a 100644 --- 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: @@ -13,11 +13,11 @@ * `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 @@ -43,6 +43,125 @@ * * 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 + * * *********************************************************************/ @@ -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 index 00000000..58124c0e --- /dev/null +++ b/pcre/.gitignore @@ -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 index 00000000..94edf499 --- /dev/null +++ b/pcre/Makefile.in @@ -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 . 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 +# . 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 index 00000000..6e4eb085 --- /dev/null +++ b/pcre/RunTest.in @@ -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 index 9055da2d..00000000 --- a/pcre/chartables.c +++ /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 index 00000000..e1b58717 --- /dev/null +++ b/pcre/config.guess @@ -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 . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to . +# +# 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 <$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 + + 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 + #include + + 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 + 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 < +#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/^ //' <$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 </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 < +#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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 diff --git a/pcre/config.h b/pcre/config.h index 048b8c35..c767cbb4 100644 --- a/pcre/config.h +++ b/pcre/config.h @@ -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 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 index 00000000..02f42593 --- /dev/null +++ b/pcre/config.in @@ -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 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 index 00000000..28426bb8 --- /dev/null +++ b/pcre/config.sub @@ -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 diff --git a/configure b/pcre/configure old mode 100755 new mode 100644 similarity index 74% rename from configure rename to pcre/configure index 6c620ec3..fbd3831e --- a/configure +++ b/pcre/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 <> confdefs.h <> confdefs.h <> confdefs.h <&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 < 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 < 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 < 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 <&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 <&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 < #include @@ -1023,7 +870,7 @@ else #include 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 @@ -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 @@ -1079,7 +926,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #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 +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 <&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 <&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 < #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 <&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 @@ -1374,232 +1199,10 @@ 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 <> $CONFIG_STATUS <> $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 <> $CONFIG_STATUS <<\EOF fi @@ -1958,11 +1559,10 @@ cat >> $CONFIG_STATUS <> $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 index 00000000..c98387d2 --- /dev/null +++ b/pcre/configure.in @@ -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 index 00000000..d572dfd3 --- /dev/null +++ b/pcre/dftables.c @@ -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 + + 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 +#include +#include + +#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 index 00000000..d8b728e5 --- /dev/null +++ b/pcre/dll.mk @@ -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 index 00000000..2133dd76 --- /dev/null +++ b/pcre/doc/ChangeLog @@ -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 + $(?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 index 00000000..09a74324 --- /dev/null +++ b/pcre/doc/NON-UNIX-USE @@ -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 index 00000000..7b96e5b6 --- /dev/null +++ b/pcre/doc/Tech.Notes @@ -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 index 00000000..bfe1b5d8 --- /dev/null +++ b/pcre/doc/authors @@ -0,0 +1,6 @@ +Written by: Philip Hazel + +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 index 00000000..34d20db9 --- /dev/null +++ b/pcre/doc/copying @@ -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 + +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 index 00000000..56fccdfa --- /dev/null +++ b/pcre/doc/news @@ -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 index 00000000..bb812f47 --- /dev/null +++ b/pcre/doc/pcre.3 @@ -0,0 +1,1810 @@ +.TH PCRE 3 +.SH NAME +pcre - Perl-compatible regular expressions. +.SH SYNOPSIS +.B #include +.PP +.SM +.br +.B pcre *pcre_compile(const char *\fIpattern\fR, int \fIoptions\fR, +.ti +5n +.B const char **\fIerrptr\fR, int *\fIerroffset\fR, +.ti +5n +.B const unsigned char *\fItableptr\fR); +.PP +.br +.B pcre_extra *pcre_study(const pcre *\fIcode\fR, int \fIoptions\fR, +.ti +5n +.B const char **\fIerrptr\fR); +.PP +.br +.B int pcre_exec(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR," +.ti +5n +.B "const char *\fIsubject\fR," int \fIlength\fR, int \fIstartoffset\fR, +.ti +5n +.B int \fIoptions\fR, int *\fIovector\fR, int \fIovecsize\fR); +.PP +.br +.B int pcre_copy_substring(const char *\fIsubject\fR, int *\fIovector\fR, +.ti +5n +.B int \fIstringcount\fR, int \fIstringnumber\fR, char *\fIbuffer\fR, +.ti +5n +.B int \fIbuffersize\fR); +.PP +.br +.B int pcre_get_substring(const char *\fIsubject\fR, int *\fIovector\fR, +.ti +5n +.B int \fIstringcount\fR, int \fIstringnumber\fR, +.ti +5n +.B const char **\fIstringptr\fR); +.PP +.br +.B int pcre_get_substring_list(const char *\fIsubject\fR, +.ti +5n +.B int *\fIovector\fR, int \fIstringcount\fR, "const char ***\fIlistptr\fR);" +.PP +.br +.B void pcre_free_substring(const char *\fIstringptr\fR); +.PP +.br +.B void pcre_free_substring_list(const char **\fIstringptr\fR); +.PP +.br +.B const unsigned char *pcre_maketables(void); +.PP +.br +.B int pcre_fullinfo(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR," +.ti +5n +.B int \fIwhat\fR, void *\fIwhere\fR); +.PP +.br +.B int pcre_info(const pcre *\fIcode\fR, int *\fIoptptr\fR, int +.B *\fIfirstcharptr\fR); +.PP +.br +.B char *pcre_version(void); +.PP +.br +.B void *(*pcre_malloc)(size_t); +.PP +.br +.B void (*pcre_free)(void *); + + + +.SH DESCRIPTION +The PCRE library is a set of functions that implement regular 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 \fBpcreposix\fR documentation. + +The native API function prototypes are defined in the header file \fBpcre.h\fR, +and on Unix systems the library itself is called \fBlibpcre.a\fR, so can be +accessed by adding \fB-lpcre\fR 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 \fBpcre_compile()\fR, \fBpcre_study()\fR, and \fBpcre_exec()\fR +are used for compiling and matching regular expressions. + +The functions \fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and +\fBpcre_get_substring_list()\fR are convenience functions for extracting +captured substrings from a matched subject string; \fBpcre_free_substring()\fR +and \fBpcre_free_substring_list()\fR are also provided, to free the memory used +for extracted strings. + +The function \fBpcre_maketables()\fR is used (optionally) to build a set of +character tables in the current locale for passing to \fBpcre_compile()\fR. + +The function \fBpcre_fullinfo()\fR is used to find out information about a +compiled pattern; \fBpcre_info()\fR is an obsolete version which returns only +some of the available information, but is retained for backwards compatibility. +The function \fBpcre_version()\fR returns a pointer to a string containing the +version of PCRE and its date of release. + +The global variables \fBpcre_malloc\fR and \fBpcre_free\fR initially contain +the entry points of the standard \fBmalloc()\fR and \fBfree()\fR 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. + + +.SH MULTI-THREADING +The PCRE functions can be used in multi-threading applications, with the +proviso that the memory management functions pointed to by \fBpcre_malloc\fR +and \fBpcre_free\fR 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. + + +.SH COMPILING A PATTERN +The function \fBpcre_compile()\fR 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 \fIpattern\fR. A pointer to a single block of memory +that is obtained via \fBpcre_malloc\fR is returned. This contains the +compiled code and related data. The \fBpcre\fR type is defined for this for +convenience, but in fact \fBpcre\fR is just a typedef for \fBvoid\fR, 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. +.PP +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 replicated. +.PP +The \fIoptions\fR 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 expressions +below). For these options, the contents of the \fIoptions\fR 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. +.PP +If \fIerrptr\fR is NULL, \fBpcre_compile()\fR returns NULL immediately. +Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fR returns +NULL, and sets the variable pointed to by \fIerrptr\fR 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 +\fIerroffset\fR, which must not be NULL. If it is, an immediate error is given. +.PP +If the final argument, \fItableptr\fR, is NULL, PCRE uses a default set of +character tables which are built when it is compiled, using the default C +locale. Otherwise, \fItableptr\fR must be the result of a call to +\fBpcre_maketables()\fR. See the section on locale support below. +.PP +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 newlines). 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, newlines are excluded. This option is +equivalent to Perl's /s option. A negative class such as [^a] always matches a +newline character, independent of the setting of this option. + + PCRE_EXTENDED + +If this bit is set, whitespace data characters in the pattern are totally +ignored except when escaped or inside a character class, and characters between +an unescaped # outside 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 subpattern. + + 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 immediately before any newline in the subject +string, respectively, as well as at the very start and end. This is equivalent +to Perl's /m option. If there are no "\\n" characters 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, experimental, and incomplete. +Details of exactly what it entails are given below. + + +.SH 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 \fBpcre_study()\fR takes a pointer to a compiled pattern as its first +argument, and returns a pointer to a \fBpcre_extra\fR block (another \fBvoid\fR +typedef) containing additional information about the pattern; this can be +passed to \fBpcre_exec()\fR. If no additional information is available, NULL +is returned. + +The second argument contains option bits. At present, no options are defined +for \fBpcre_study()\fR, and this argument should always be zero. + +The third argument for \fBpcre_study()\fR 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. + + +.SH LOCALE SUPPORT +PCRE handles caseless matching, and determines whether characters 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 +compiled. This is used when the final argument of \fBpcre_compile()\fR is NULL, +and is sufficient for many applications. + +An alternative set of tables can, however, be supplied. Such tables are built +by calling the \fBpcre_maketables()\fR function, which has no arguments, in the +relevant locale. The result can then be passed to \fBpcre_compile()\fR 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 \fBpcre_malloc\fR. The +pointer that is passed to \fBpcre_compile\fR is saved with the compiled +pattern, and the same tables are used via this pointer by \fBpcre_study()\fR +and \fBpcre_exec()\fR. 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 responsibility to ensure that the +memory containing the tables remains available for as long as it is needed. + + +.SH INFORMATION ABOUT A PATTERN +The \fBpcre_fullinfo()\fR function returns information about a compiled +pattern. It replaces the obsolete \fBpcre_info()\fR function, which is +nevertheless retained for backwards compability (and is documented below). + +The first argument for \fBpcre_fullinfo()\fR is a pointer to the compiled +pattern. The second argument is the result of \fBpcre_study()\fR, 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 variable +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 \fIcode\fR was NULL + the argument \fIwhere\fR was NULL + PCRE_ERROR_BADMAGIC the "magic number" was not found + PCRE_ERROR_BADOPTION the value of \fIwhat\fR was invalid + +The possible values for the third argument are defined in \fBpcre.h\fR, and are +as follows: + + PCRE_INFO_OPTIONS + +Return a copy of the options with which the pattern was compiled. The fourth +argument should point to au \fBunsigned long int\fR variable. These option bits +are those specified in the call to \fBpcre_compile()\fR, 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 \fBpcre_malloc()\fR when PCRE was getting memory in which to +place the compiled data. The fourth argument should point to a \fBsize_t\fR +variable. + + PCRE_INFO_CAPTURECOUNT + +Return the number of capturing subpatterns in the pattern. The fourth argument +should point to an \fbint\fR variable. + + PCRE_INFO_BACKREFMAX + +Return the number of the highest back reference in the pattern. The fourth +argument should point to an \fBint\fR variable. 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 +\fIwhere\fR. 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 construction of a 256-bit +table indicating a fixed set of characters 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 \fBunsigned char *\fR +variable. + + PCRE_INFO_LASTLITERAL + +For a non-anchored pattern, return the value of the rightmost literal character +which must exist in any matched string, other than at its start. The fourth +argument should point to an \fBint\fR 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 \fBpcre_info()\fR function is now obsolete because its interface is too +restrictive to return all the available data about a compiled pattern. New +programs should use \fBpcre_fullinfo()\fR instead. The yield of +\fBpcre_info()\fR is the number of capturing subpatterns, or one of the +following negative numbers: + + PCRE_ERROR_NULL the argument \fIcode\fR was NULL + PCRE_ERROR_BADMAGIC the "magic number" was not found + +If the \fIoptptr\fR 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 \fIfirstcharptr\fR argument is not NULL, +it is used to pass back information about the first character of any matched +string (see PCRE_INFO_FIRSTCHAR above). + + +.SH MATCHING A PATTERN +The function \fBpcre_exec()\fR is called to match a subject string against a +pre-compiled pattern, which is passed in the \fIcode\fR argument. If the +pattern has been studied, the result of the study should be passed in the +\fIextra\fR argument. Otherwise this must be NULL. + +The PCRE_ANCHORED option can be passed in the \fIoptions\fR argument, 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 dollar metacharacter +should not match it nor (except in multiline 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 pattern, 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 \fBsplit()\fR 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 \fIsubject\fR, a length in +\fIlength\fR, and a starting offset in \fIstartoffset\fR. Unlike the pattern +string, it may contain binary zero characters. 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 \fBpcre_exec()\fR again after a previous success. +Setting \fIstartoffset\fR 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 \fBpcre_exec()\fR finds the first +occurrence. If \fBpcre_exec()\fR 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 +\fBpcre_exec()\fR is passed the entire string again, but with \fIstartoffset\fR +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 subject, 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 subpattern 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 \fIovector\fR. The number of elements in the vector +is passed in \fIovecsize\fR. 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 \fBpcre_exec()\fR while +matching capturing subpatterns, and is not available for passing back +information. The length passed in \fIovecsize\fR 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 \fIovector\fR, 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, \fIovector[0]\fR and \fIovector[1]\fR, 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 \fBpcre_exec()\fR +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 \fIn+1\fR to match some +part of the subject when subpattern \fIn\fR 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 substrings, 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, +\fBpcre_exec()\fR may be called with \fIovector\fR passed as NULL and +\fIovecsize\fR as zero. However, if the pattern contains back references and +the \fIovector\fR 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 \fIovector\fR. + +Note that \fBpcre_info()\fR can be used to find out how many capturing +subpatterns there are in a compiled pattern. The smallest size for +\fIovector\fR that will allow for \fIn\fR captured substrings in addition to +the offsets of the substring matched by the whole pattern is (\fIn\fR+1)*3. + +If \fBpcre_exec()\fR fails, it returns a negative number. The following are +defined in the header file: + + PCRE_ERROR_NOMATCH (-1) + +The subject string did not match the pattern. + + PCRE_ERROR_NULL (-2) + +Either \fIcode\fR or \fIsubject\fR was passed as NULL, or \fIovector\fR was +NULL and \fIovecsize\fR was not zero. + + PCRE_ERROR_BADOPTION (-3) + +An unrecognized bit was set in the \fIoptions\fR argument. + + PCRE_ERROR_BADMAGIC (-4) + +PCRE stores a 4-byte "magic number" at the start of the compiled 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 encountered 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 \fIovector\fR that is passed to +\fBpcre_exec()\fR 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 \fBpcre_malloc()\fR fails, this error is given. The memory is freed at +the end of matching. + + +.SH EXTRACTING CAPTURED SUBSTRINGS +Captured substrings can be accessed directly by using the offsets returned by +\fBpcre_exec()\fR in \fIovector\fR. For convenience, the functions +\fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and +\fBpcre_get_substring_list()\fR 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 functions: \fIsubject\fR +is the subject string which has just been successfully matched, \fIovector\fR +is a pointer to the vector of integer offsets that was passed to +\fBpcre_exec()\fR, and \fIstringcount\fR 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 \fBpcre_exec\fR if it +is greater than zero. If \fBpcre_exec()\fR returned zero, indicating that it +ran out of space in \fIovector\fR, the value passed as \fIstringcount\fR should +be the size of the vector divided by three. + +The functions \fBpcre_copy_substring()\fR and \fBpcre_get_substring()\fR +extract a single substring, whose number is given as \fIstringnumber\fR. A +value of zero extracts the substring that matched the entire pattern, while +higher values extract the captured substrings. For \fBpcre_copy_substring()\fR, +the string is placed in \fIbuffer\fR, whose length is given by +\fIbuffersize\fR, while for \fBpcre_get_substring()\fR a new block of memory is +obtained via \fBpcre_malloc\fR, and its address is returned via +\fIstringptr\fR. 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 \fBpcre_copy_substring()\fR, or the attempt to get +memory failed for \fBpcre_get_substring()\fR. + + PCRE_ERROR_NOSUBSTRING (-7) + +There is no substring whose number is \fIstringnumber\fR. + +The \fBpcre_get_substring_list()\fR function extracts all available substrings +and builds a list of pointers to them. All this is done in a single block of +memory which is obtained via \fBpcre_malloc\fR. The address of the memory block +is returned via \fIlistptr\fR, 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 \fIn+1\fR matches some part of the +subject, but subpattern \fIn\fR 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 \fIovector\fR, which is negative for unset +substrings. + +The two convenience functions \fBpcre_free_substring()\fR and +\fBpcre_free_substring_list()\fR can be used to free the memory returned by +a previous call of \fBpcre_get_substring()\fR or +\fBpcre_get_substring_list()\fR, respectively. They do nothing more than call +the function pointed to by \fBpcre_free\fR, which of course could be called +directly from a C program. However, PCRE is used in some situations where it is +linked via a special interface to another programming language which cannot use +\fBpcre_free\fR directly; it is for these cases that the functions are +provided. + + +.SH 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 +subpatterns, assertions, and other types of subpattern, is 200. + +The maximum length of a subject string is the largest positive number that an +integer variable can hold. However, PCRE uses recursion to handle subpatterns +and indefinite repetition. This means that the available stack space may limit +the size of a subject string that can be processed by certain patterns. + + +.SH 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 \fBisspace()\fR recognizes, though it is possible to compile PCRE with +alternative character type tables. Normally \fBisspace()\fR matches space, +formfeed, newline, carriage return, horizontal tab, and vertical tab. Perl 5 +no longer includes vertical tab in its set of whitespace characters. The \\v +escape that was in the Perl documentation for a long time was never in fact +recognized. However, the character 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 lookahead assertions are +counted, but their entries in the offsets vector are never set. Perl sets its +numerical variables 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 subject 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 pattern 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 experimental 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 repetition 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 +\fBpcre_exec()\fR 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.) + + +.SH REGULAR EXPRESSION DETAILS +The syntax and semantics of the regular expressions supported 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 \fBpcre_compile()\fR 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 characters 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 pattern. These are encoded in the pattern by the use of +\fImeta-characters\fR, 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. + + +.SH 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 following 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 particular, +if you want to match a backslash, you write "\\\\". + +If a pattern is compiled with the PCRE_EXTENDED option, whitespace 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 characters, 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 \fIback reference\fR. 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 following 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 introduced 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 character 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 controlled 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 character 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 assertions. 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 \fIstartoffset\fR argument of +\fBpcre_exec()\fR 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. + + +.SH 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 \fIstartoffset\fR argument of +\fBpcre_exec()\fR 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 alternatives 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 constructs 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. Consequently, patterns that are anchored in single line mode +because all branches start with "^" are not anchored in multiline mode, and a +match for circumflex is possible when the \fIstartoffset\fR argument of +\fBpcre_exec()\fR 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. + + +.SH FULL STOP (PERIOD, DOT) +Outside a character class, a dot in the pattern matches any one character in +the subject, including a non-printing character, 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. + + +.SH SQUARE BRACKETS +An opening square bracket introduces a character class, terminated 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 circumflex, 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 circumflex, 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 convenient 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 +caseful 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 interpreted 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 "-") followed 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 interpreted 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 +restricted 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. + + +.SH 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 supported 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 ^ character 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. + + +.SH 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 alternatives 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. + + +.SH 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" settings apply to the whole pattern (unless +there are other changes inside subpatterns). If there is more than one setting +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 otherwise. + +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. + + +.SH SUBPATTERNS +Subpatterns are delimited by parentheses (round brackets), which can be nested. +Marking part of a pattern as a subpattern does two things: + +1. It localizes a set of alternatives. For example, the pattern + + cat(aract|erpillar|) + +matches one of the words "cat", "cataract", or "caterpillar". 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 portion of the subject string that matched +the subpattern is passed back to the caller via the \fIovector\fR argument of +\fBpcre_exec()\fR. Opening parentheses are counted from left to right (starting +from 1) to obtain the numbers of the capturing 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 subpattern 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 pattern + + the ((?:red|white) (king|queen)) + +the captured substrings are "white queen" and "queen", and are numbered 1 and +2. The maximum number of captured substrings 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". + + +.SH 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 +quantifier, 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 permitted 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 comments 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 preferred number of matches. +Do not confuse this use of question 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 maximum, 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 +character 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 pattern +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 example, after + + (tweedle[dume]{3}\\s*)+ + +has matched "tweedledum tweedledee" the value of the captured substring is +"tweedledee". However, if there are nested capturing subpatterns, the +corresponding captured values may have been set in previous iterations. For +example, after + + /(a|(b))+/ + +matches "aba" the value of the second captured substring is "b". + + +.SH 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 handling of digits following a backslash. + +A back reference matches whatever actually matched the capturing 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 responsibility", 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 caselessly. + +There may be more than one back reference to the same subpattern. 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 pattern + + (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. + + +.SH 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 +complicated 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 assertions and (? 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 standalone 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 maximizing 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 complicated subpatterns, +and it can be nested. + +Once-only subpatterns can be used in conjunction with lookbehind 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 backtracks 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 subpattern 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 consist 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 example 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 happens quickly. + + +.SH CONDITIONAL SUBPATTERNS +It is possible to cause the matching process to obey a subpattern +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; otherwise 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 containing non-significant white space, and with the two +alternatives 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. + + +.SH COMMENTS +The sequence (?# marks the start of a comment which continues 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 continues up to the next newline +character in the pattern. + + +.SH 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 pattern 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 matching 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 subpattern 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 \fBpcre_malloc\fR, freeing it via \fBpcre_free\fR 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. + + +.SH 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 principle 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. + + +.SH 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 \fBpcre_compile()\fR with the PCRE_UTF8 option +flag. When you do this, both the pattern and any subject 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 additional 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 contents 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 follow 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 single 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 implemented: + +1. The escape sequence \\C to match a single byte. + +2. The use of Unicode tables and properties and escapes \\p, \\P, and \\X. + +.SH AUTHOR +Philip Hazel +.br +University Computing Service, +.br +New Museums Site, +.br +Cambridge CB2 3QG, England. +.br +Phone: +44 1223 334714 + +Last updated: 28 August 2000, +.br + the 250th anniversary of the death of J.S. Bach. +.br +Copyright (c) 1997-2000 University of Cambridge. diff --git a/pcre/doc/pcre.html b/pcre/doc/pcre.html new file mode 100644 index 00000000..b12b2126 --- /dev/null +++ b/pcre/doc/pcre.html @@ -0,0 +1,2397 @@ + + +pcre specification + + +

    pcre specification

    +This HTML document has been generated automatically from the original man page. +If there is any nonsense in it, please consult the man page in case the +conversion went wrong. + +
  • 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, int +*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 regular 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 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 +convenience, 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 replicated. +

    +

    +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 expressions +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 newlines). 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, newlines are excluded. This option is +equivalent to Perl's /s option. A negative class such as [^a] always matches a +newline character, independent of the setting of this option. +

    +

    +

    +  PCRE_EXTENDED
    +
    +

    +

    +If this bit is set, whitespace data characters in the pattern are totally +ignored except when escaped or inside a character class, and characters between +an unescaped # outside 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 subpattern. +

    +

    +

    +  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 immediately before any newline in the subject +string, respectively, as well as at the very start and end. This is equivalent +to Perl's /m option. If there are no "\n" characters 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, experimental, 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 pattern; 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 characters 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 +compiled. This is used when the final argument of pcre_compile() is NULL, +and is sufficient for many applications. +

    +

    +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 responsibility 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() function, which is +nevertheless retained for backwards compability (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 variable +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 compiled. 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 \fbint\fR variable. +

    +

    +

    +  PCRE_INFO_BACKREFMAX
    +
    +

    +

    +Return the number of the highest back reference in the pattern. The fourth +argument should point to an int variable. 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 construction of a 256-bit +table indicating a fixed set of characters 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 rightmost 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 interface 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 argument, 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 dollar metacharacter +should not match it nor (except in multiline 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 pattern, 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 characters. 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 subject, 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 subpattern 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 ovector[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 substrings, 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 capturing +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 following 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 compiled 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 encountered 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 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 functions: 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 ovector, 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 stringnumber. 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 available 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 negative 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. However, 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 +subpatterns, assertions, and other types of subpattern, is 200. +

    +

    +The maximum length of a subject string is the largest positive number that an +integer variable can hold. However, PCRE uses recursion to handle subpatterns +and indefinite repetition. This means that the available stack space may limit +the size of a subject string that can be processed by certain 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 characters. The \v +escape that was in the Perl documentation for a long time was never in fact +recognized. However, the character 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 lookahead assertions are +counted, but their entries in the offsets vector are never set. Perl sets its +numerical variables 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 subject 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 pattern 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 experimental 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 repetition 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 supported 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 characters 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 pattern. 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 following 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 particular, +if you want to match a backslash, you write "\\". +

    +

    +If a pattern is compiled with the PCRE_EXTENDED option, whitespace 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 characters, 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 following 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 introduced 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 character 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 controlled 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 character 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 assertions. 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 argument 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 alternatives 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 constructs 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. Consequently, patterns that are anchored in single line mode +because all branches start with "^" are not anchored in multiline 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 character, 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, terminated 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 circumflex, 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 circumflex, 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 convenient 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 +caseful 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 interpreted 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 "-") followed 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 interpreted 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 +restricted 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 supported 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 ^ character 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 alternatives 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" settings apply to the whole pattern (unless +there are other changes inside subpatterns). If there is more than one setting +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 otherwise. +

    +

    +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 subpattern does two things: +

    +

    +1. It localizes a set of alternatives. For example, the pattern +

    +

    +

    +  cat(aract|erpillar|)
    +
    +

    +

    +matches one of the words "cat", "cataract", or "caterpillar". 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 portion 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 capturing 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 subpattern 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 pattern +

    +

    +

    +  the ((?:red|white) (king|queen))
    +
    +

    +

    +the captured substrings are "white queen" and "queen", and are numbered 1 and +2. The maximum number of captured substrings 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 +quantifier, 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 permitted 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 comments 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 preferred number of matches. +Do not confuse this use of question 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 maximum, 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 +character 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 pattern +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 example, after +

    +

    +

    +  (tweedle[dume]{3}\s*)+
    +
    +

    +

    +has matched "tweedledum tweedledee" the value of the captured substring is +"tweedledee". However, if there are nested capturing subpatterns, the +corresponding captured values may have been set in previous iterations. For +example, 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 handling of digits following a backslash. +

    +

    +A back reference matches whatever actually matched the capturing 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 responsibility", 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 caselessly. +

    +

    +There may be more than one back reference to the same subpattern. 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 pattern +

    +

    +

    +  (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 +complicated 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 assertions 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 different 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 rewritten 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 matching 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 standalone 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 maximizing 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 complicated subpatterns, +and it can be nested. +

    +

    +Once-only subpatterns can be used in conjunction with lookbehind 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 backtracks 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 subpattern 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 consist 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 example 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 happens quickly. +

    +
  • CONDITIONAL SUBPATTERNS +

    +It is possible to cause the matching process to obey a subpattern +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; otherwise 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 containing non-significant white space, and with the two +alternatives 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 continues 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 continues 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 pattern 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 matching 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 subpattern 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 principle 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 subject 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 additional 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 contents 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 follow 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 single 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 implemented: +

    +

    +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/pcre.txt b/pcre/doc/pcre.txt new file mode 100644 index 00000000..1db4b537 --- /dev/null +++ b/pcre/doc/pcre.txt @@ -0,0 +1,2125 @@ +NAME + pcre - Perl-compatible regular expressions. + + + +SYNOPSIS + #include + + 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 (? 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 + 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 index 00000000..ec733fa1 --- /dev/null +++ b/pcre/doc/pcregrep.1 @@ -0,0 +1,76 @@ +.TH PCREGREP 1 +.SH NAME +pcregrep - a grep with Perl-compatible regular expressions. +.SH SYNOPSIS +.B pcregrep [-Vchilnsvx] pattern [file] ... + + +.SH DESCRIPTION +\fBpcregrep\fR searches files for character patterns, in the same way as other +grep commands do, but it uses the PCRE regular expression library to support +patterns that are compatible with the regular expressions of Perl 5. See +\fBpcre(3)\fR for a full description of syntax and semantics. + +If no files are specified, \fBpcregrep\fR reads the standard input. By default, +each line that matches the pattern is copied to the standard output, and if +there is more than one file, the file name is printed before each line of +output. However, there are options that can change how \fBpcregrep\fR behaves. + +Lines are limited to BUFSIZ characters. BUFSIZ is defined in \fB\fR. +The newline character is removed from the end of each line before it is matched +against the pattern. + + +.SH OPTIONS +.TP 10 +\fB-V\fR +Write the version number of the PCRE library being used to the standard error +stream. +.TP +\fB-c\fR +Do not print individual lines; instead just print a count of the number of +lines that would otherwise have been printed. If several files are given, a +count is printed for each of them. +.TP +\fB-h\fR +Suppress printing of filenames when searching multiple files. +.TP +\fB-i\fR +Ignore upper/lower case distinctions during comparisons. +.TP +\fB-l\fR +Instead of printing lines from the files, just print the names of the files +containing lines that would have been printed. Each file name is printed +once, on a separate line. +.TP +\fB-n\fR +Precede each line by its line number in the file. +.TP +\fB-s\fR +Work silently, that is, display nothing except error messages. +The exit status indicates whether any matches were found. +.TP +\fB-v\fR +Invert the sense of the match, so that lines which do \fInot\fR match the +pattern are now the ones that are found. +.TP +\fB-x\fR +Force the pattern to be anchored (it must start matching at the beginning of +the line) and in addition, require it to match the entire line. This is +equivalent to having ^ and $ characters at the start and end of each +alternative branch in the regular expression. + + +.SH SEE ALSO +\fBpcre(3)\fR, Perl 5 documentation + + +.SH DIAGNOSTICS +Exit status is 0 if any matches were found, 1 if no matches were found, and 2 +for syntax errors or inacessible files (even if matches were found). + + +.SH AUTHOR +Philip Hazel +.br +Copyright (c) 1997-2000 University of Cambridge. diff --git a/pcre/doc/pcregrep.html b/pcre/doc/pcregrep.html new file mode 100644 index 00000000..19f733c4 --- /dev/null +++ b/pcre/doc/pcregrep.html @@ -0,0 +1,105 @@ + + +pcregrep specification + + +

    pcregrep specification

    +This HTML document has been generated automatically from the original man page. +If there is any nonsense in it, please consult the man page in case the +conversion went wrong. + +
  • NAME +

    +pcregrep - a grep with Perl-compatible regular expressions. +

    +
  • SYNOPSIS +

    +pcregrep [-Vchilnsvx] pattern [file] ... +

    +
  • DESCRIPTION +

    +pcregrep searches files for character patterns, in the same way as other +grep commands do, but it uses the PCRE regular expression library to support +patterns that are compatible with the regular expressions of Perl 5. See +pcre(3) for a full description of syntax and semantics. +

    +

    +If no files are specified, pcregrep reads the standard input. By default, +each line that matches the pattern is copied to the standard output, and if +there is more than one file, the file name is printed before each line of +output. However, there are options that can change how pcregrep behaves. +

    +

    +Lines are limited to BUFSIZ characters. BUFSIZ is defined in <stdio.h>. +The newline character is removed from the end of each line before it is matched +against the pattern. +

    +
  • OPTIONS +

    +-V +Write the version number of the PCRE library being used to the standard error +stream. +

    +

    +-c +Do not print individual lines; instead just print a count of the number of +lines that would otherwise have been printed. If several files are given, a +count is printed for each of them. +

    +

    +-h +Suppress printing of filenames when searching multiple files. +

    +

    +-i +Ignore upper/lower case distinctions during comparisons. +

    +

    +-l +Instead of printing lines from the files, just print the names of the files +containing lines that would have been printed. Each file name is printed +once, on a separate line. +

    +

    +-n +Precede each line by its line number in the file. +

    +

    +-s +Work silently, that is, display nothing except error messages. +The exit status indicates whether any matches were found. +

    +

    +-v +Invert the sense of the match, so that lines which do not match the +pattern are now the ones that are found. +

    +

    +-x +Force the pattern to be anchored (it must start matching at the beginning of +the line) and in addition, require it to match the entire line. This is +equivalent to having ^ and $ characters at the start and end of each +alternative branch in the regular expression. +

    +
  • SEE ALSO +

    +pcre(3), Perl 5 documentation +

    +
  • DIAGNOSTICS +

    +Exit status is 0 if any matches were found, 1 if no matches were found, and 2 +for syntax errors or inacessible files (even if matches were found). +

    +
  • AUTHOR +

    +Philip Hazel <ph10@cam.ac.uk> +
    +Copyright (c) 1997-2000 University of Cambridge. diff --git a/pcre/doc/pcregrep.txt b/pcre/doc/pcregrep.txt new file mode 100644 index 00000000..871350ca --- /dev/null +++ b/pcre/doc/pcregrep.txt @@ -0,0 +1,87 @@ +NAME + pcregrep - a grep with Perl-compatible regular expressions. + + + +SYNOPSIS + pcregrep [-Vchilnsvx] pattern [file] ... + + + +DESCRIPTION + pcregrep searches files for character patterns, in the same + way as other grep commands do, but it uses the PCRE regular + expression library to support patterns that are compatible + with the regular expressions of Perl 5. See pcre(3) for a + full description of syntax and semantics. + + If no files are specified, pcregrep reads the standard + input. By default, each line that matches the pattern is + copied to the standard output, and if there is more than one + file, the file name is printed before each line of output. + However, there are options that can change how pcregrep + behaves. + + Lines are limited to BUFSIZ characters. BUFSIZ is defined in + . The newline character is removed from the end of + each line before it is matched against the pattern. + + + +OPTIONS + -V Write the version number of the PCRE library being + used to the standard error stream. + + -c Do not print individual lines; instead just print + a count of the number of lines that would other- + wise have been printed. If several files are + given, a count is printed for each of them. + + -h Suppress printing of filenames when searching mul- + tiple files. + + -i Ignore upper/lower case distinctions during com- + parisons. + + -l Instead of printing lines from the files, just + print the names of the files containing lines that + would have been printed. Each file name is printed + once, on a separate line. + + -n Precede each line by its line number in the file. + + -s Work silently, that is, display nothing except + error messages. The exit status indicates whether + any matches were found. + + -v Invert the sense of the match, so that lines which + do not match the pattern are now the ones that are + found. + + -x Force the pattern to be anchored (it must start + matching at the beginning of the line) and in + addition, require it to match the entire line. + This is equivalent to having ^ and $ characters at + the start and end of each alternative branch in + the regular expression. + + + +SEE ALSO + pcre(3), Perl 5 documentation + + + + + +DIAGNOSTICS + Exit status is 0 if any matches were found, 1 if no matches + were found, and 2 for syntax errors or inacessible files + (even if matches were found). + + + +AUTHOR + Philip Hazel + Copyright (c) 1997-2000 University of Cambridge. + diff --git a/pcre/doc/pcreposix.3 b/pcre/doc/pcreposix.3 new file mode 100644 index 00000000..4853a97f --- /dev/null +++ b/pcre/doc/pcreposix.3 @@ -0,0 +1,149 @@ +.TH PCRE 3 +.SH NAME +pcreposix - POSIX API for Perl-compatible regular expressions. +.SH SYNOPSIS +.B #include +.PP +.SM +.br +.B int regcomp(regex_t *\fIpreg\fR, const char *\fIpattern\fR, +.ti +5n +.B int \fIcflags\fR); +.PP +.br +.B int regexec(regex_t *\fIpreg\fR, const char *\fIstring\fR, +.ti +5n +.B size_t \fInmatch\fR, regmatch_t \fIpmatch\fR[], int \fIeflags\fR); +.PP +.br +.B size_t regerror(int \fIerrcode\fR, const regex_t *\fIpreg\fR, +.ti +5n +.B char *\fIerrbuf\fR, size_t \fIerrbuf_size\fR); +.PP +.br +.B void regfree(regex_t *\fIpreg\fR); + + +.SH DESCRIPTION +This set of functions provides a POSIX-style API to the PCRE regular expression +package. See the \fBpcre\fR 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 \fBpcreposix.h\fR header +file, and on Unix systems the library itself is called \fBpcreposix.a\fR, so +can be accessed by adding \fB-lpcreposix\fR to the command for linking an +application which uses them. Because the POSIX functions call the native ones, +it is also necessary to add \fR-lpcre\fR. + +I have implemented only those option bits that can be reasonably 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, subject to the setting of various PCRE options, as +described below. + +The header for these functions is supplied as \fBpcreposix.h\fR to avoid any +potential clash with other POSIX libraries. It can, of course, be renamed or +aliased as \fBregex.h\fR, which is the "correct" name. It provides two +structure types, \fIregex_t\fR for compiled internal forms, and +\fIregmatch_t\fR for returning captured substrings. It also defines some +constants whose names start with "REG_"; these are used for setting options and +identifying error codes. + + +.SH COMPILING A PATTERN + +The function \fBregcomp()\fR 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 \fIpattern\fR. The \fIpreg\fR argument is a pointer +to a regex_t structure which is used as a base for storing information about +the compiled expression. + +The argument \fIcflags\fR 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 +\fIsome\fR 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 \fBregcomp()\fR is zero on success, and non-zero otherwise. The +\fIpreg\fR structure is filled in on success, and one member of the structure +is publicized: \fIre_nsub\fR contains the number of capturing subpatterns in +the regular expression. Various error codes are defined in the header file. + + +.SH MATCHING A PATTERN +The function \fBregexec()\fR is called to match a pre-compiled pattern +\fIpreg\fR against a given \fIstring\fR, which is terminated by a zero byte, +subject to the options in \fIeflags\fR. 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 \fIpmatch\fR argument, which points to an array of +\fInmatch\fR structures of type \fIregmatch_t\fR, containing the members +\fIrm_so\fR and \fIrm_eo\fR. 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 \fIstring\fR 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. + + +.SH ERROR MESSAGES +The \fBregerror()\fR function maps a non-zero errorcode from either +\fBregcomp\fR or \fBregexec\fR to a printable message. If \fIpreg\fR is not +NULL, the error should have arisen from the use of that structure. A message +terminated by a binary zero is placed in \fIerrbuf\fR. The length of the +message, including the zero, is limited to \fIerrbuf_size\fR. The yield of the +function is the size of buffer needed to hold the whole message. + + +.SH STORAGE +Compiling a regular expression causes memory to be allocated and associated +with the \fIpreg\fR structure. The function \fBregfree()\fR frees all such +memory, after which \fIpreg\fR may no longer be used as a compiled expression. + + +.SH AUTHOR +Philip Hazel +.br +University Computing Service, +.br +New Museums Site, +.br +Cambridge CB2 3QG, England. +.br +Phone: +44 1223 334714 + +Copyright (c) 1997-2000 University of Cambridge. diff --git a/pcre/doc/pcreposix.html b/pcre/doc/pcreposix.html new file mode 100644 index 00000000..79ff544b --- /dev/null +++ b/pcre/doc/pcreposix.html @@ -0,0 +1,191 @@ + + +pcreposix specification + + +

    pcreposix specification

    +This HTML document has been generated automatically from the original man page. +If there is any nonsense in it, please consult the man page in case the +conversion went wrong. + +
  • NAME +

    +pcreposix - POSIX API for Perl-compatible regular expressions. +

    +
  • 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 \fR-lpcre\fR. +

    +

    +I have implemented only those option bits that can be reasonably 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, subject 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 expression. +

    +

    +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 otherwise. 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 regfree() 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/pcreposix.txt b/pcre/doc/pcreposix.txt new file mode 100644 index 00000000..2d76f7cd --- /dev/null +++ b/pcre/doc/pcreposix.txt @@ -0,0 +1,159 @@ +NAME + pcreposix - POSIX API for Perl-compatible regular expres- + sions. + + + +SYNOPSIS + #include + + 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 + 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 index 00000000..722e6b86 --- /dev/null +++ b/pcre/doc/pcretest.txt @@ -0,0 +1,246 @@ +The pcretest program +-------------------- + +This program is intended for testing PCRE, but it can also be used for +experimenting with regular expressions. + +If it is given two filename arguments, it reads from the first and writes to +the second. If it is given only one filename argument, it reads from that file +and writes to stdout. Otherwise, it reads from stdin and writes to stdout, and +prompts for each line of input, using "re>" to prompt for regular expressions, +and "data>" to prompt for data lines. + +The program handles any number of sets of input on a single input file. Each +set starts with a regular expression, and continues with any number of data +lines to be matched against the pattern. An empty line signals the end of the +data lines, at which point a new regular expression is read. The regular +expressions are given enclosed in any non-alphameric delimiters other than +backslash, for example + + /(a|bc)x+yz/ + +White space before the initial delimiter is ignored. A regular expression may +be continued over several input lines, in which case the newline characters are +included within it. See the test input files in the testdata directory for many +examples. It is possible to include the delimiter within the pattern by +escaping it, for example + + /abc\/def/ + +If you do so, the escape and the delimiter form part of the pattern, but since +delimiters are always non-alphameric, this does not affect its interpretation. +If the terminating delimiter is immediately followed by a backslash, for +example, + + /abc/\ + +then a backslash is added to the end of the pattern. This is done to provide a +way of testing the error condition that arises if a pattern finishes with a +backslash, because + + /abc\/ + +is interpreted as the first line of a pattern that starts with "abc/", causing +pcretest to read the next line as a continuation of the regular expression. + + +PATTERN MODIFIERS +----------------- + +The pattern may be followed by i, m, s, or x to set the PCRE_CASELESS, +PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively. For +example: + + /caseless/i + +These modifier letters have the same effect as they do in Perl. There are +others which set PCRE options that do not correspond to anything in Perl: /A, +/E, and /X set PCRE_ANCHORED, PCRE_DOLLAR_ENDONLY, and PCRE_EXTRA respectively. + +Searching for all possible matches within each subject string can be requested +by the /g or /G modifier. After finding a match, PCRE is called again to search +the remainder of the subject string. The difference between /g and /G is that +the former uses the startoffset argument to pcre_exec() to start searching at +a new point within the entire string (which is in effect what Perl does), +whereas the latter passes over a shortened substring. This makes a difference +to the matching process if the pattern begins with a lookbehind assertion +(including \b or \B). + +If any call to pcre_exec() in a /g or /G sequence matches an empty string, the +next call is done with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set in order +to search for another, non-empty, match at the same point. If this second match +fails, the start offset is advanced by one, and the normal match is retried. +This imitates the way Perl handles such cases when using the /g modifier or the +split() function. + +There are a number of other modifiers for controlling the way pcretest +operates. + +The /+ modifier requests that as well as outputting the substring that matched +the entire pattern, pcretest should in addition output the remainder of the +subject string. This is useful for tests where the subject contains multiple +copies of the same substring. + +The /L modifier must be followed directly by the name of a locale, for example, + + /pattern/Lfr + +For this reason, it must be the last modifier letter. The given locale is set, +pcre_maketables() is called to build a set of character tables for the locale, +and this is then passed to pcre_compile() when compiling the regular +expression. Without an /L modifier, NULL is passed as the tables pointer; that +is, /L applies only to the expression on which it appears. + +The /I modifier requests that pcretest output information about the compiled +expression (whether it is anchored, has a fixed first character, and so on). It +does this by calling pcre_fullinfo() after compiling an expression, and +outputting the information it gets back. If the pattern is studied, the results +of that are also output. + +The /D modifier is a PCRE debugging feature, which also assumes /I. It causes +the internal form of compiled regular expressions to be output after +compilation. + +The /S modifier causes pcre_study() to be called after the expression has been +compiled, and the results used when the expression is matched. + +The /M modifier causes the size of memory block used to hold the compiled +pattern to be output. + +The /P modifier causes pcretest to call PCRE via the POSIX wrapper API rather +than its native API. When this is done, all other modifiers except /i, /m, and +/+ are ignored. REG_ICASE is set if /i is present, and REG_NEWLINE is set if /m +is present. The wrapper functions force PCRE_DOLLAR_ENDONLY always, and +PCRE_DOTALL unless REG_NEWLINE is set. + +The /8 modifier causes pcretest to call PCRE with the PCRE_UTF8 option set. +This turns on the (currently incomplete) support for UTF-8 character handling +in PCRE, provided that it was compiled with this support enabled. This modifier +also causes any non-printing characters in output strings to be printed using +the \x{hh...} notation if they are valid UTF-8 sequences. + + +DATA LINES +---------- + +Before each data line is passed to pcre_exec(), leading and trailing whitespace +is removed, and it is then scanned for \ escapes. The following are recognized: + + \a alarm (= BEL) + \b backspace + \e escape + \f formfeed + \n newline + \r carriage return + \t tab + \v vertical tab + \nnn octal character (up to 3 octal digits) + \xhh hexadecimal character (up to 2 hex digits) + \x{hh...} hexadecimal UTF-8 character + + \A pass the PCRE_ANCHORED option to pcre_exec() + \B pass the PCRE_NOTBOL option to pcre_exec() + \Cdd call pcre_copy_substring() for substring dd after a successful + match (any decimal number less than 32) + \Gdd call pcre_get_substring() for substring dd after a successful + match (any decimal number less than 32) + \L call pcre_get_substringlist() after a successful match + \N pass the PCRE_NOTEMPTY option to pcre_exec() + \Odd set the size of the output vector passed to pcre_exec() to dd + (any number of decimal digits) + \Z pass the PCRE_NOTEOL option to pcre_exec() + +A backslash followed by anything else just escapes the anything else. If the +very last character is a backslash, it is ignored. This gives a way of passing +an empty line as data, since a real empty line terminates the data input. + +If /P was present on the regex, causing the POSIX wrapper API to be used, only +\B, and \Z have any effect, causing REG_NOTBOL and REG_NOTEOL to be passed to +regexec() respectively. + +The use of \x{hh...} to represent UTF-8 characters is not dependent on the use +of the /8 modifier on the pattern. It is recognized always. There may be any +number of hexadecimal digits inside the braces. The result is from one to six +bytes, encoded according to the UTF-8 rules. + + +OUTPUT FROM PCRETEST +-------------------- + +When a match succeeds, pcretest outputs the list of captured substrings that +pcre_exec() returns, starting with number 0 for the string that matched the +whole pattern. Here is an example of an interactive pcretest run. + + $ pcretest + PCRE version 2.06 08-Jun-1999 + + re> /^abc(\d+)/ + data> abc123 + 0: abc123 + 1: 123 + data> xyz + No match + +If the strings contain any non-printing characters, they are output as \0x +escapes, or as \x{...} escapes if the /8 modifier was present on the pattern. +If the pattern has the /+ modifier, then the output for substring 0 is followed +by the the rest of the subject string, identified by "0+" like this: + + re> /cat/+ + data> cataract + 0: cat + 0+ aract + +If the pattern has the /g or /G modifier, the results of successive matching +attempts are output in sequence, like this: + + re> /\Bi(\w\w)/g + data> Mississippi + 0: iss + 1: ss + 0: iss + 1: ss + 0: ipp + 1: pp + +"No match" is output only if the first match attempt fails. + +If any of \C, \G, or \L are present in a data line that is successfully +matched, the substrings extracted by the convenience functions are output with +C, G, or L after the string number instead of a colon. This is in addition to +the normal full list. The string length (that is, the return from the +extraction function) is given in parentheses after each string for \C and \G. + +Note that while patterns can be continued over several lines (a plain ">" +prompt is used for continuations), data lines may not. However newlines can be +included in data by means of the \n escape. + + +COMMAND LINE OPTIONS +-------------------- + +If the -p option is given to pcretest, it is equivalent to adding /P to each +regular expression: the POSIX wrapper API is used to call PCRE. None of the +following flags has any effect in this case. + +If the option -d is given to pcretest, it is equivalent to adding /D to each +regular expression: the internal form is output after compilation. + +If the option -i is given to pcretest, it is equivalent to adding /I to each +regular expression: information about the compiled pattern is given after +compilation. + +If the option -m is given to pcretest, it outputs the size of each compiled +pattern after it has been compiled. It is equivalent to adding /M to each +regular expression. For compatibility with earlier versions of pcretest, -s is +a synonym for -m. + +If the -t option is given, each compile, study, and match is run 20000 times +while being timed, and the resulting time per compile or match is output in +milliseconds. Do not set -t with -m, because you will then get the size output +20000 times and the timing will be distorted. If you want to change the number +of repetitions used for timing, edit the definition of LOOPREPEAT at the top of +pcretest.c + +Philip Hazel +August 2000 diff --git a/pcre/doc/perltest.txt b/pcre/doc/perltest.txt new file mode 100644 index 00000000..33155c1a --- /dev/null +++ b/pcre/doc/perltest.txt @@ -0,0 +1,29 @@ +The perltest program +-------------------- + +The perltest program tests Perl's regular expressions; it has the same +specification as pcretest, and so can be given identical input, except that +input patterns can be followed only by Perl's lower case modifiers and /+ (as +used by pcretest), which is recognized and handled by the program. + +The data lines are processed as Perl double-quoted strings, so if they contain +" \ $ or @ characters, these have to be escaped. For this reason, all such +characters in testinput1 and testinput3 are escaped so that they can be used +for perltest as well as for pcretest, and the special upper case modifiers such +as /A that pcretest recognizes are not used in these files. The output should +be identical, apart from the initial identifying banner. + +For testing UTF-8 features, an alternative form of perltest, called perltest8, +is supplied. This requires Perl 5.6 or higher. It recognizes the special +modifier /8 that pcretest uses to invoke UTF-8 functionality. The testinput5 +file can be fed to perltest8. + +The testinput2 and testinput4 files are not suitable for feeding to perltest, +since they do make use of the special upper case modifiers and escapes that +pcretest uses to test some features of PCRE. The first of these files also +contains malformed regular expressions, in order to check that PCRE diagnoses +them correctly. Similarly, testinput6 tests UTF-8 features that do not relate +to Perl. + +Philip Hazel +August 2000 diff --git a/pcre/doc/readme b/pcre/doc/readme new file mode 100644 index 00000000..d124ee01 --- /dev/null +++ b/pcre/doc/readme @@ -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 +August 2000 diff --git a/pcre/get.c b/pcre/get.c new file mode 100644 index 00000000..42e9bd49 --- /dev/null +++ b/pcre/get.c @@ -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 + + 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 . */ + + +/* 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 index 00000000..08802812 --- /dev/null +++ b/pcre/install @@ -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 index 00000000..e9de2384 --- /dev/null +++ b/pcre/install-sh @@ -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 index 00000000..25bb7f8f --- /dev/null +++ b/pcre/internal.h @@ -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 + + 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 +#include +#include +#include +#include +#include +#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 index 00000000..34d20db9 --- /dev/null +++ b/pcre/licence @@ -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 + +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 index 00000000..a01334f9 --- /dev/null +++ b/pcre/ltconfig @@ -0,0 +1,3078 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 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 </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 <&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 <&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 &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 <&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 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 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 <&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 <&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 < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' + + cat <> 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 <&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 <&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 < +/* 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 <&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 < +/* 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 <&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 < +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 < +#endif + +#include + +#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 < +#endif + +#include + +#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 < "$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 , 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 < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +EOF + ;; +esac + +cat <> "$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: diff --git a/pcre/ltmain.sh b/pcre/ltmain.sh index 50515ad0..ab65054f 100644 --- a/pcre/ltmain.sh +++ b/pcre/ltmain.sh @@ -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*) + *-*-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 index 00000000..c0f06c03 --- /dev/null +++ b/pcre/maketables.c @@ -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 + + 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 index 00000000..ac9ccfe9 --- /dev/null +++ b/pcre/pcre-config @@ -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 index 00000000..8daded9f --- /dev/null +++ b/pcre/pcre-config.in @@ -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 index 00000000..0e8cf3f4 --- /dev/null +++ b/pcre/pcre.def @@ -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 diff --git a/pcre/pcre.h b/pcre/pcre.h index e5a875a7..d27ba859 100644 --- a/pcre/pcre.h +++ b/pcre/pcre.h @@ -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/pcre.in b/pcre/pcre.in index 1dffb02b..d698f403 100644 --- a/pcre/pcre.in +++ b/pcre/pcre.in @@ -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 index 00000000..e8c934ef --- /dev/null +++ b/pcre/pcregrep.c @@ -0,0 +1,228 @@ +/************************************************* +* pcregrep program * +*************************************************/ + +/* This is a grep program that uses the PCRE regular expression library to do +its pattern matching. */ + +#include +#include +#include +#include +#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)? "" : 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 */ diff --git a/pcre/pcreposix.c b/pcre/pcreposix.c index 6aeb8828..519d2dd5 100644 --- a/pcre/pcreposix.c +++ b/pcre/pcreposix.c @@ -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 index 00000000..7660acbd --- /dev/null +++ b/pcre/pcreposix.h @@ -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 + +/* 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 index 00000000..ee5df5f0 --- /dev/null +++ b/pcre/pcretest.c @@ -0,0 +1,1225 @@ +/************************************************* +* PCRE testing program * +*************************************************/ + +#include +#include +#include +#include +#include +#include + +/* 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] [ []]\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: \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 index 00000000..676db946 --- /dev/null +++ b/pcre/study.c @@ -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 + + 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 index 00000000..3a579a6b --- /dev/null +++ b/pcre/vc_dftables.dsp @@ -0,0 +1,296 @@ +# Microsoft Developer Studio Project File - Name="vc_dftables" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=vc_dftables - Win32 Debug with Win32 threads +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vc_dftables.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vc_dftables.mak"\ + CFG="vc_dftables - Win32 Debug with Win32 threads" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vc_dftables - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_dftables - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_dftables - Win32 Debug with Win32 threads" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_dftables - Win32 Release with Win32 threads" (based on\ + "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vc_dftables - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "vc_dftables" +# PROP Intermediate_Dir "vc_dftables" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 +# Begin Special Build Tool +OutDir=.\vc_dftables +SOURCE=$(InputPath) +PostBuild_Desc=Running program to generate chartables.c +PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c +# End Special Build Tool + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "vc_dftables_dbg" +# PROP Intermediate_Dir "vc_dftables_dbg" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 +# Begin Special Build Tool +OutDir=.\vc_dftables_dbg +SOURCE=$(InputPath) +PostBuild_Desc=Running program to generate chartables.c +PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c +# End Special Build Tool + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "vc_dftab" +# PROP BASE Intermediate_Dir "vc_dftab" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "vc_dftables_dbg" +# PROP Intermediate_Dir "vc_dftables_dbg" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 +# Begin Special Build Tool +OutDir=.\vc_dftables_dbg +SOURCE=$(InputPath) +PostBuild_Desc=Running program to generate chartables.c +PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c +# End Special Build Tool + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "vc_dfta0" +# PROP BASE Intermediate_Dir "vc_dfta0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "vc_dftables" +# PROP Intermediate_Dir "vc_dftables" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 +# Begin Special Build Tool +OutDir=.\vc_dftables +SOURCE=$(InputPath) +PostBuild_Desc=Running program to generate chartables.c +PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "vc_dftables - Win32 Release" +# Name "vc_dftables - Win32 Debug" +# Name "vc_dftables - Win32 Debug with Win32 threads" +# Name "vc_dftables - Win32 Release with Win32 threads" +# Begin Group "File Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\vc_config_pthreads.h + +!IF "$(CFG)" == "vc_dftables - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Copying vc_config_pthreads.h +WkspDir=. +InputPath=..\vc_config_pthreads.h + +"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy "$(InputPath)" "$(WkspDir)\..\config.h" + +# End Custom Build + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Copying vc_config_pthreads.h +WkspDir=. +InputPath=..\vc_config_pthreads.h + +"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy "$(InputPath)" "$(WkspDir)\..\config.h" + +# End Custom Build + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads" + +# PROP Exclude_From_Build 1 +# PROP Ignore_Default_Tool 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads" + +# PROP Exclude_From_Build 1 +# PROP Ignore_Default_Tool 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\vc_config_winthreads.h + +!IF "$(CFG)" == "vc_dftables - Win32 Release" + +# PROP Exclude_From_Build 1 +# PROP Ignore_Default_Tool 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug" + +# PROP Exclude_From_Build 1 +# PROP Ignore_Default_Tool 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Copying vc_config_winthreads.h +WkspDir=. +InputPath=..\vc_config_winthreads.h + +"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy "$(InputPath)" "$(WkspDir)\..\config.h" + +# End Custom Build + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Copying vc_config_winthreads.h +WkspDir=. +InputPath=..\vc_config_winthreads.h + +"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy "$(InputPath)" "$(WkspDir)\..\config.h" + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=..\config.h +# End Source File +# Begin Source File + +SOURCE=.\config.h +# End Source File +# Begin Source File + +SOURCE=.\dftables.c +# End Source File +# Begin Source File + +SOURCE=.\internal.h +# End Source File +# Begin Source File + +SOURCE=.\maketables.c + +!IF "$(CFG)" == "vc_dftables - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\pcre.h +# End Source File +# End Target +# End Project diff --git a/pcrs.c b/pcrs.c index cd0c94a8..45a471b9 100644 --- a/pcrs.c +++ b/pcrs.c @@ -1,127 +1,236 @@ -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 + * 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 + * * - * 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 + * * *********************************************************************/ #include #include +#include + #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 ba77c38a..a14b8165 100644 --- 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. * @@ -40,57 +59,107 @@ * *********************************************************************/ -#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 $" - +#ifndef _PCRE_H #include +#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 index 07f0c36b..00000000 --- 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 index 00000000..994a2417 --- /dev/null +++ b/privoxy-rh.spec @@ -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 ++ privoxy-2.9.15-1 +- Add another template and alphabetize these for easier tracking. +- Add doc/images directory. + +* Wed May 15 2002 Hal Burgiss ++ privoxy-2.9.15-1 +- Add templates/edit-actions-list-button + +* Fri May 03 2002 Rodrigo Barbosa ++ 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 ++ privoxy-2.9.14-3 +- Changing Vendor to Privoxy.Org + +* Tue Apr 23 2002 Hal Burgiss ++ privoxy-2.9.14-2 +- Adjust for new *actions files. + +* Mon Apr 22 2002 Rodrigo Barbosa ++ 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 ++ privoxy-2.9.14-2 +- Using macros to define uid and gid values +- Bumping release + +* Mon Apr 22 2002 Rodrigo Barbosa ++ 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 ++ privoxy-2.9.13-6 +- Add --disable-dynamic-pcre to configure. + +* Wed Apr 10 2002 Rodrigo Barbosa ++ privoxy-2.9.13-5 +- Relisting template files on the %%files section + +* Tue Apr 09 2002 Hal Burgiss ++ privoxy-2.9.13-4 +- Removed 'make dok'. Docs are all maintained in CVS (and tarball) now. + +* Mon Apr 08 2002 Hal Burgiss ++ 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 ++ privoxy-2.9.13-3 +- Include correct documentation file. + +* Tue Mar 26 2002 Hal Burgiss ++ privoxy-2.9.13-3 +- Fix typo in Description. + +* Tue Mar 26 2002 Rodrigo Barbosa ++ privoxy-2.9.13-3 +- Added commentary asking to update the release value on the configure + script + +* Tue Mar 25 2002 Hal Burgiss ++ privoxy-2.9.13-3 +- Added the missing edit-actions-for-url-filter to templates. + +* Mon Mar 25 2002 Rodrigo Barbosa ++ privoxy-2.9.13-2 +- Fixing Release number + +* Sun Mar 24 2002 Hal Burgiss ++ privoxy-2.9.13-2 +- Added faq to docs. + +* Sun Mar 24 2002 Rodrigo Barbosa ++ 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 ++ junkbusterng-2.9.13-1 + Added autoheader. Added autoconf to buildrequires. + +* Sun Mar 24 2002 Hal Burgiss ++ 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 ++ 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 +- added ijb_docs.css to docs. + +* Mon Mar 11 2002 Hal Burgiss ++ junkbuster-2.9.11-8 +- Take out --enable-no-gifs, breaks some browsers. + +* Sun Mar 10 2002 Hal Burgiss ++ junkbuster-2.9.11-8 +- Add --enable-no-gifs to configure. + +* Fri Mar 08 2002 Rodrigo Barbosa ++ junkbuster-2.9.11-7 +- Added BuildRequires to libtool. + +* Tue Mar 06 2002 Rodrigo Barbosa ++ 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 ++ junkbuster-2.9.11-5 +- Added "make redhat-dok" to the build process +- Added docbook-utils to BuildRequires + +* Tue Mar 05 2002 Rodrigo Barbosa ++ 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 ++ junkbuster-2.9.11-3 +- Fixing permissions of the init script + +* Mon Mar 04 2002 Rodrigo Barbosa ++ 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 +- /bin/false for shell causes init script to fail. Reverting. + +* Wed Jan 09 2002 Hal Burgiss +- 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 +- add paranoia check for 'rm -rf %%{buildroot}' +- add gzip to 'BuildRequires' + +* Sat Dec 1 2001 Hal Burgiss +- actionsfile is now ijb.action. + +* Tue Nov 6 2001 Thomas Steudten +- Compress manpage +- Add more documents for installation +- Add version string to name and source + +* Wed Oct 24 2001 Hal Burigss +- Back to user 'junkbuster' and fix configure macro. + +* Wed Oct 10 2001 Hal Burigss +- More changes for user 'junkbust'. Init script had 'junkbuster'. + +* Sun Sep 23 2001 Hal Burgiss +- 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 +- 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 +- rework of RPM + +* Mon Sep 25 2000 Stefan Waldherr +- CLF Logging patch by davep@cyw.uklinux.net +- Hal DeVore fix akamaitech in blocklist + +* Sun Sep 17 2000 Stefan Waldherr +- 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 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" : 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 + Andrew 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 + 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 + Blank images are no longer cached, thanks to a hint from Markus + Breitenbach . 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 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 + . 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 + %%{_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 + Configure blank version via config file. No separate blank + version anymore. Added Roland's + patch to show a logo instead of a blank area. Added a suggestion + from Alex : %%{_localstatedir}/lock/subsys/junkbuster. + More regexps in the blocklist. Prepared the forwardfile for + squid. Extended image regexp with help from gabriel + . + +* Thu Nov 19 1998 Stefan Waldherr + 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 + 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 + Modified the blocking feature, so that only GIFs and JPEGs are + blocked and replaced but not HTML pages. Thanks to + "Gerd Flender" 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 + Moved config files to /etc/junkbuster directory, moved man page, + added BuildRoot directive (Thanks to Alexey Nogin ) + 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 +# + 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 index 00000000..cca70d00 --- /dev/null +++ b/privoxy-suse.spec @@ -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 +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 ++ privoxy-2.9.15-1 +- Add doc/images directory. + +* Fri May 03 2002 Rodrigo Barbosa ++ privoxy-suse-2.9.15-1 +- Version bump + +* Fri Apr 26 2002 Rodrigo Barbosa ++ privoxy-suse-2.9.14-3 +- Changing Vendor to Privoxy.Org + +* Mon Apr 22 2002 Rodrigo Barbosa ++ 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 ++ privoxy-2.9.13-4 +- Add LICENSE.gz, p_web.css, and index.html. Add autoconf +- to Buildrequires. + +* Wed Mar 27 2002 Hal Burgiss ++ privoxy-2.9.13-3 +- Doc css has changed names. + +* Tue Mar 25 2002 Hal Burgiss ++ privoxy-2.9.13-3 +- Minor fix to description. + +* Sun Mar 24 2002 Hal Burgiss +- added faq to docs. + +* Thu Mar 21 2002 Hal Burgiss +- added ijb_docs.css to docs. + +* Mon Mar 11 2002 Hal Burgiss +- Remove --enable-no-gifs from configure. + +* Sun Mar 03 2002 Hal Burgiss +- /bin/false for shell causes init script to fail. Reverting. + +* Wed Jan 09 2002 Hal Burgiss +- 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 +- add paranoia check for 'rm -rf $RPM_BUILD_ROOT' +- add gzip to 'BuildRequires' + +* Sat Dec 1 2001 Hal Burgiss +- actionsfile is now ijb.action. + +* Tue Nov 6 2001 Thomas Steudten +- Compress manpage +- Add more documents for installation +- Add version string to name and source + +* Wed Oct 24 2001 Hal Burigss +- Back to user 'junkbuster' and fix configure macro. + +* Wed Oct 10 2001 Hal Burigss +- More changes for user 'junkbust'. Init script had 'junkbuster'. + +* Sun Sep 23 2001 Hal Burgiss +- 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 +- 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 +- 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 index 00000000..19cc5e26 --- /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: +.\" +.\" Please send any bug reports, improvements, comments, patches, +.\" etc. to Steve Cheng . +.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 +.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 index 00000000..ff05a7ec --- /dev/null +++ b/privoxy.init @@ -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 index 00000000..7bab6def --- /dev/null +++ b/privoxy.init.suse @@ -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 +# +# 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 index 00000000..035112a5 --- /dev/null +++ b/privoxy.logrotate @@ -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 index 00000000..15734ddf --- /dev/null +++ b/privoxy.monthly @@ -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 index 00000000..81424f8d --- /dev/null +++ b/privoxy.weekly @@ -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 + + diff --git a/project.h b/project.h index 5f4324ae..43d53d61 100644 --- 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 @@ -36,6 +37,408 @@ * * 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 + * * *********************************************************************/ @@ -48,289 +451,682 @@ /* * 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 (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 -# endif -#endif /* (defined(REGEX) && defined(PCRE)) || defined(PCRS) */ -#if defined(REGEX) && defined(PCRE) -# ifdef STATIC -# include "pcreposix.h" -# else -# include -# endif -#endif /* defined(REGEX) && defined(PCRE) */ +#ifdef STATIC_PCRE +# include "pcre.h" +#else +# include +#endif -#if defined(REGEX) && !defined(PCRE) -# include "gnu_regex.h" +#ifdef STATIC_PCRS +# include "pcrs.h" +#else +# include #endif -#ifdef PCRS -#include "pcrs.h" -#endif /* def PCRS */ +#ifdef STATIC_PCRE +# include "pcreposix.h" +#else +# include +#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 +#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 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 "\n" -#define BODY "\n" -#define BANNER "Internet JUNKBUSTER" - -#ifdef FORCE_LOAD -/* - * FIXME: Unfortunately, IE lowercases the domain name. JunkBuster does - * a case-sensitive compare. JunkBuster should be modified to do a - * case-insensitive compatison. As a temporary workaround, I've lowercased - * the FORCE_PREFIX. - * - * #define FORCE_PREFIX "IJB-FORCE-LOAD-" - */ -#define FORCE_PREFIX "ijb-force-load-" -#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 index 16c073bf..00000000 --- a/re_filterfile +++ /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/()/$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/]*http-equiv[^>]*refresh[^>]*>//i -s/]*http-equiv="?page-enter"?[^>]*content=[^>]*>//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/(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%^.*(?Blocked

    Blocked due to possible adult content. Please see this site.

    %is -#s+^.*warez.*$+No Warez

    You're not searching for illegal stuff, are you?

    +is - -# http://www.farscapezone.com/wwwboard/messages/1451.html -s/(\w+) was tired/$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 index 0a7cc2c8..00000000 --- a/showargs.c +++ /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 $ - * - *********************************************************************/ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#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, "%s ", c, c); - } - freez(c); - } - if ( ( NULL != o ) && ( '\0' != *o ) ) - { - if ((o = html_encode(o))) - { - if (strncmpic(o, "http://", 7) == 0) - { - strcat(buf, ""); - strcat(buf, o); - strcat(buf, ""); - } - else - { - strcat(buf, o); - } - } - freez(o); - } - - strcat(buf, "
    \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" - - "" - "" - "Internet Junkbuster Proxy Status" - "\n" - "\n" - "
    \n" - "

    " BANNER "\n" - "Proxy Status\n" - "

    \n" - "

    You are using the " BANNER " TM

    \n" - "Version: " VERSION "\n" - "
    Home page: " HOME_PAGE_URL "\n" - "

    \n" - ); - - proxy_args->header = strsav(proxy_args->header, - "

    The program was invoked as follows

    \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, "
    \n"); - - - proxy_args->invocation = strsav( - proxy_args->invocation, - "
    \n" - "and the following options were set in the configuration file" - "

    \n" - ); - - - proxy_args->gateways = strsav(proxy_args->gateways, - "

    It supports the following gateway protocols:

    \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, "
    \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, "

    File contents

    \n"); - b = strsav(b, suppress_message); - b = strsav(b, "\n"); - } -#endif /* ndef SPLIT_PROXY_ARGS */ - - b = strsav(b, "

    Source versions:

    \n"); - b = strsav(b, "
    ");
    -
    -#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, "
    \n"); - - b = strsav(b, "

    Conditional defines:

    \n
      "); - -#ifdef REGEX - b = strsav(b, "
    • #define REGEX - Support for regular expressions in the path specs.
    • \n"); -#else /* ifndef REGEX */ - b = strsav(b, "
    • #undef REGEX - No support for regular expressions in the path specs.
    • \n"); -#endif /* ndef REGEX */ - -#ifdef PCRE - b = strsav(b, "
    • #define PCRE - Use PCRE rather than old GNU regex library.
    • \n"); -#else /* ifndef PCRE */ - b = strsav(b, "
    • #undef PCRE - Use old GNU regex library rather than PCRE.
    • \n"); -#endif /* ndef PCRE */ - -#ifdef PCRS - b = strsav(b, "
    • #define PCRS - Enables arbitrary content modification regexps.
    • \n"); -#else /* ifndef PCRS */ - b = strsav(b, "
    • #undef PCRS - Disables arbitrary content modification regexps.
    • \n"); -#endif /* ndef PCRS */ - -#ifdef TOGGLE - b = strsav(b, "
    • #define TOGGLE - Allow JunkBuster to be \"disabled\" so it is just a normal non-blocking non-anonymizing proxy.
    • \n"); -#else /* ifndef TOGGLE */ - b = strsav(b, "
    • #undef TOGGLE - Do not allow JunkBuster to be \"disabled\" so it is just a normal non-blocking non-anonymizing proxy.
    • \n"); -#endif /* ndef TOGGLE */ - -#ifdef FORCE_LOAD - b = strsav(b, "
    • #define FORCE_LOAD - Enables bypassing filtering for a single page using the prefix \"" FORCE_PREFIX "\".
    • \n"); -#else /* ifndef FORCE_LOAD */ - b = strsav(b, "
    • #undef FORCE_LOAD - Disables bypassing filtering for a single page.
    • \n"); -#endif /* ndef FORCE_LOAD */ - -#ifdef DENY_GZIP - b = strsav(b, "
    • #define DENY_GZIP - Prevents requests from being compressed - required for PCRS.
    • \n"); -#else /* ifndef DENY_GZIP */ - b = strsav(b, "
    • #undef DENY_GZIP - Allows requests to be compressed if the browser and server support it.
    • \n"); -#endif /* ndef DENY_GZIP */ - -#ifdef STATISTICS - b = strsav(b, "
    • #define STATISTICS - Enables statistics function.
    • \n"); -#else /* ifndef STATISTICS */ - b = strsav(b, "
    • #undef STATISTICS - Disables statistics function.
    • \n"); -#endif /* ndef STATISTICS */ - -#ifdef SPLIT_PROXY_ARGS - b = strsav(b, "
    • #define SPLIT_PROXY_ARGS - Split this page up by placing the configuration files on separate pages.
    • \n"); -#else /* ifndef SPLIT_PROXY_ARGS */ - b = strsav(b, "
    • #undef SPLIT_PROXY_ARGS - This page contains the text of the configuration files, they are not split onto separate pages.
    • \n"); -#endif /* ndef SPLIT_PROXY_ARGS */ - -#ifdef KILLPOPUPS - b = strsav(b, "
    • #define KILLPOPUPS - Enables killing JavaScript popups.
    • \n"); -#else /* ifndef KILLPOPUPS */ - b = strsav(b, "
    • #undef KILLPOPUPS - Disables killing JavaScript popups.
    • \n"); -#endif /* ndef KILLPOPUPS */ - -#ifdef WEBDAV - b = strsav(b, "
    • #define WEBDAV - Enables support for webDAV - e.g. stops Microsoft Outlook from accessing HotMail e-mail.
    • \n"); -#else /* ifndef WEBDAV */ - b = strsav(b, "
    • #undef WEBDAV - Disables support for webDAV - e.g. so Microsoft Outlook can access HotMail e-mail.
    • \n"); -#endif /* ndef WEBDAV */ - -#ifdef DETECT_MSIE_IMAGES - b = strsav(b, "
    • #define DETECT_MSIE_IMAGES - Enables detecting image requests automatically for MSIE.
    • \n"); -#else /* ifndef DETECT_MSIE_IMAGES */ - b = strsav(b, "
    • #undef DETECT_MSIE_IMAGES - Disables detecting image requests automatically for MSIE.
    • \n"); -#endif /* ndef DETECT_MSIE_IMAGES */ - -#ifdef USE_IMAGE_LIST - b = strsav(b, "
    • #define USE_IMAGE_LIST - Enables using image list to detect images.
    • \n"); -#else /* ifndef USE_IMAGE_LIST */ - b = strsav(b, "
    • #undef USE_IMAGE_LIST - Disables using image list to detect images.
    • \n"); -#endif /* ndef USE_IMAGE_LIST */ - -#ifdef ACL_FILES - b = strsav(b, "
    • #define ACL_FILES - Enables the use of ACL files to control access to the proxy by IP address.
    • \n"); -#else /* ifndef ACL_FILES */ - b = strsav(b, "
    • #undef ACL_FILES - Disables the use of ACL files to control access to the proxy by IP address.
    • \n"); -#endif /* ndef ACL_FILES */ - -#ifdef TRUST_FILES - b = strsav(b, "
    • #define TRUST_FILES - Enables the use of trust files.
    • \n"); -#else /* ifndef TRUST_FILES */ - b = strsav(b, "
    • #undef TRUST_FILES - Disables the use of trust files.
    • \n"); -#endif /* ndef TRUST_FILES */ - -#ifdef JAR_FILES - b = strsav(b, "
    • #define JAR_FILES - Enables the use of jar files to capture cookies.
    • \n"); -#else /* ifndef JAR_FILES */ - b = strsav(b, "
    • #undef JAR_FILES - Disables the use of jar files to capture cookies.
    • \n"); -#endif /* ndef JAR_FILES */ - - b = strsav(b, "
    \n
    \n"); - - b = strsav(b, - "

    \n" - "Code and documentation of the " BANNER " Proxy" - "TM\n" - "\n" "Copyright© 1997 Junkbusters Corporation\n" - "TM
    \n" - "Copying and distribution permitted under the" - "\n" - "GNU " - "General Public License.\n" - "
    " - "

    webmaster@junkbusters.com
    " - "
    " - "\n" - ); - - proxy_args->trailer = b; - -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/showargs.h b/showargs.h deleted file mode 100644 index 82b511c5..00000000 --- a/showargs.h +++ /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 $ - * - *********************************************************************/ - - -#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 */ diff --git a/ssplit.c b/ssplit.c index 81246fdf..ff362568 100644 --- 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 + * * *********************************************************************/ @@ -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 -#include - -#ifdef _WIN32 -#include -#endif +#include #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); } diff --git a/ssplit.h b/ssplit.h index 39bd9934..397dda2a 100644 --- 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 @@ -34,6 +34,21 @@ * * 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 + * * *********************************************************************/ @@ -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 index 00000000..7d5fd990 --- /dev/null +++ b/standard.action @@ -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 index 00000000..e323b9e3 --- /dev/null +++ b/templates/blocked @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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 +# + + + + Request blocked (Privoxy@@my-hostname@) + + + + + + + + + + +# Note: The same small version is used above via JavaScript +# If you make changes here, keep the other version in sync! + + + + + diff --git a/templates/cgi-error-404 b/templates/cgi-error-404 new file mode 100644 index 00000000..ee70d494 --- /dev/null +++ b/templates/cgi-error-404 @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + 404 - Privoxy Configuration Page not found + + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 404 + + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Privoxy Configuration page not found

    +

    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.

    +

    If you got here by clicking a link in the + configuration interface, please file a bug report!

    +

    You can use the menu below to select from the available + configuration options

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/cgi-error-bad-param b/templates/cgi-error-bad-param new file mode 100644 index 00000000..a9803dba --- /dev/null +++ b/templates/cgi-error-bad-param @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy: Bad parameter + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Bad parameter to Privoxy configuration page

    +

    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.

    +

    Possible causes:

    +
      +
    • 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.
    • +
    • 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.
    • +
    • If you got here using your browser's "back" button, then + that is deliberately disabled for this page.
    • +
    • If you got here by clicking a link in the + configuration interface, please file a bug report!
    • +
    +

    You can use the menu below to select from the available + configuration options

    +
    +

    Privoxy Menu:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/cgi-error-disabled b/templates/cgi-error-disabled new file mode 100644 index 00000000..fd7f01f9 --- /dev/null +++ b/templates/cgi-error-disabled @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Configuration Page Disabled + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Privoxy Configuration page diasabled

    +

    The Privoxy administrator has decided to disable this + feature. If you want to use it, you must ask them to + enable it.

    +

    If you are the Privoxy administrator, you can enable + this feature by changing the appropriate line in your + configuration file.

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/cgi-error-file b/templates/cgi-error-file new file mode 100644 index 00000000..dab262a5 --- /dev/null +++ b/templates/cgi-error-file @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy: Actions file not found + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Actions file not found

    +

    The actions file you are trying to edit (@f@.action) + does not exist, or cannot be read.

    +
    +

    Privoxy Menu:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + + + diff --git a/templates/cgi-error-file-read-only b/templates/cgi-error-file-read-only new file mode 100644 index 00000000..62224489 --- /dev/null +++ b/templates/cgi-error-file-read-only @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy: Cannot write to actions file + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Cannot write to actions file

    +

    The actions file you are trying to edit (@f@.action) + could not be written to.

    +

    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.

    +

    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.

    +
    +

    Privoxy Menu:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + + + diff --git a/templates/cgi-error-modified b/templates/cgi-error-modified new file mode 100644 index 00000000..c42bc691 --- /dev/null +++ b/templates/cgi-error-modified @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy: URL out of date + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    URL out of date - file has changed since it was generated

    +

    The URL you're viewing is out of date. To prevent possible + damage to your configuration file, this action has been ignored. +

    +

    Possible causes:

    +
      +
    • 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.
    • +
    • 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.
    • +
    • 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.
    • +
    +

    You can go back into the edit interface using the menu below, + or by clicking here. +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/cgi-error-parse b/templates/cgi-error-parse new file mode 100644 index 00000000..723eb677 --- /dev/null +++ b/templates/cgi-error-parse @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy: Parse error + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Parse error

    +

    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.

    +

    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!

    +

    When you've fixed the problem, you can go back into the edit + interface using the menu below, or by clicking here. +

    +
    +

    Problem description:

    +

    @parse-error@

    +
    +

    The line which caused the problem:

    +
    @line-raw@
    +
    +

    The line which caused the problem, with comments removed

    +

    @line-data@

    +
    +

    Note

    +

    Only the first error is reported - the file may contain other + errors, as well as the one reported above.

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + + + diff --git a/templates/cgi-style.css b/templates/cgi-style.css new file mode 100644 index 00000000..b3556fd8 --- /dev/null +++ b/templates/cgi-style.css @@ -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
    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
    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 index 00000000..8e6de608 --- /dev/null +++ b/templates/connect-failed @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + 503 - Connect failed (Privoxy@@my-hostname@) + + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 503 + + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Connect failed

    +

    Your request for @protocol@@hostport@@path@ could + not be fulfilled, because the connection to @host@ (@host-ip@) could not be established. +

    +

    This is often a temporary failiure, so you might just + try again. +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/default b/templates/default new file mode 100644 index 00000000..f11c3f69 --- /dev/null +++ b/templates/default @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy@@my-hostname@ + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Privoxy Menu:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/edit-actions-add-url-form b/templates/edit-actions-add-url-form new file mode 100644 index 00000000..a15bec18 --- /dev/null +++ b/templates/edit-actions-add-url-form @@ -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 +# +############################################################################# + + + + + + + + + + Privoxy@@my-hostname@: Add URL Pattern + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Add URL Pattern

    +
    +

    + + + +
    +   +   + Cancel +

    +
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + + diff --git a/templates/edit-actions-for-url b/templates/edit-actions-for-url new file mode 100644 index 00000000..40333459 --- /dev/null +++ b/templates/edit-actions-for-url @@ -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 +# +# +############################################################################# + + + + + + + + + + + Privoxy@@my-hostname@: Edit actions + + + + + + + + + + +
    + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Edit Actions + + + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@filter-params@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EnableDisableNo ChangeActionDescription
    add-headerAdds HTTP headers.
        Editing the settings for this option, or turning + it on if it was off, is not yet supported using this web-based + editor.
    blockBlock the request
    crunch-incoming-cookiesPrevent the website from setting cookies on your system.
    crunch-outgoing-cookiesPrevent the website from reading cookies from your system.
    deanimate-gifsReplace animated GIFs with their (first/last) frame.
        Use the   
    downgrade-http-versionChange HTTP/1.1 requests to HTTP/1.0. Only change if you know + what you're doing!
    fast-redirectsBypass some click-tracking URLs.
     filter *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.
    handle-as-imageRequest is for an image (only useful in conjunction with the block + and set-image-blocker actions).
    hide-forwarded-for-headersBlock any existing X-Forwarded-for header, and do not add a new one.
    hide-from-headerStop old web browsers from sending the user's e-mail address with + every request.
        
    +
    +
    hide-referrerHelps prevent tracking by not sending the URL of the previous web + page. 
         (breaks images + on some free web hosts).
    + (fools checks for in-site links.)
    +
    +
    hide-user-agentPretend to be using a different web browser.  (Breaks many web + sites).
        User Agent string to send:
    +
    kill-popupsFilter the website through a built-in filter to disable many JavaScript + pop-up windows.
    limit-connectSpecify which ports are allowed for SSL (HTTP CONNECT) access. + Note that this allows arbitrary tunnelling, so opening all + ports would be a security hole.
        Legal SSL ports (comma separated, ranges allowed):
    +
    prevent-compressionDisables compression. Compressed web pages are faster to + download, but cannot be filtered with filter + or kill-popups. + This setting only affects the few web sites which support + compression.
    send-vanilla-waferAdds a special wafer (standard cookie) to all your requests.
    send-waferAdds user-specified cookies.
        Editing the settings for this option, or turning + it on if it was off, is not yet supported using this web-based + editor.
    session-cookies-onlyAny 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 + crunch-outgoing-cookies and + crunch-incoming-cookies.
    set-image-blockerSpecifies how to block images.
        
    +
    +
    +
    + +
    +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + Valid HTML 4.01 Strict +
    +
    + + + + + + + + diff --git a/templates/edit-actions-for-url-filter b/templates/edit-actions-for-url-filter new file mode 100644 index 00000000..952ed14f --- /dev/null +++ b/templates/edit-actions-for-url-filter @@ -0,0 +1,7 @@ + + + + + filter @name@ + @description@ + diff --git a/templates/edit-actions-list b/templates/edit-actions-list new file mode 100644 index 00000000..cde66a64 --- /dev/null +++ b/templates/edit-actions-list @@ -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 +# +# +############################################################################# + + + + + + + + + + + Privoxy: Edit actions file @f@.action + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + +@sections@ + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    What is all this?

    +

    + If you haven't already done so, it is strongly recommended that you at + least skim the + chapter on actions files in the user manual + before making any changes. You will also find a comprehensive list of all available actions + there. +

    + +

    + Please note that the first section has special importance. 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. +

    + + +

    + This is the default action file. Updates for it are available from + Privoxy.org on a regular basis. + It is therefore not recommended 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 user.action instead. +

    + +
    +
    +

    Editing Actions File @f@.action

    + +

    Insert new section at top

    + +
    +
    + + + + + + + + + + + + +
    Actions:
    + Edit + @all-urls-buttons@ +
    @all-urls-actions@
    URL patterns:
    /   (Matches all requests)
    Advanced:
    + Insert new section below +
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + Valid HTML 4.01 Strict +
    + + + diff --git a/templates/edit-actions-list-button b/templates/edit-actions-list-button new file mode 100644 index 00000000..53235588 --- /dev/null +++ b/templates/edit-actions-list-button @@ -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 +# +############################################################################# +   Set to @button-name@ diff --git a/templates/edit-actions-list-section b/templates/edit-actions-list-section new file mode 100644 index 00000000..b48bcb5a --- /dev/null +++ b/templates/edit-actions-list-section @@ -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. +# +############################################################################# + + + + + + + + +@urls@ + + +
    Actions:
    Edit
    @actions@
    URL patterns:
    Add
    Advanced:
    +@if-s-prev-exists-start@Move section up   @if-s-prev-exists-end@ +@if-s-next-exists-start@Move section down   @if-s-next-exists-end@ +Insert new section below +@if-empty-section-start@   Delete whole section@if-empty-section-end@ +
    + diff --git a/templates/edit-actions-list-url b/templates/edit-actions-list-url new file mode 100644 index 00000000..f44eb589 --- /dev/null +++ b/templates/edit-actions-list-url @@ -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. +# +############################################################################# + +Remove   Edit  @url-html@ + diff --git a/templates/edit-actions-remove-url-form b/templates/edit-actions-remove-url-form new file mode 100644 index 00000000..14f5fd9e --- /dev/null +++ b/templates/edit-actions-remove-url-form @@ -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 +# +############################################################################# + + + + + + + + + + + Privoxy@@my-hostname@: Remove URL Pattern + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Remove URL Pattern

    +

    Are you sure you want to delete this URL pattern? The pattern is:

    +

    @u@

    +

    + OK +   + Cancel +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + Valid HTML 4.01 Strict +
    + + + diff --git a/templates/edit-actions-url-form b/templates/edit-actions-url-form new file mode 100644 index 00000000..1719c194 --- /dev/null +++ b/templates/edit-actions-url-form @@ -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 +# +############################################################################# + + + + + + + + + + + Privoxy@@my-hostname@: Edit URL Pattern + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Edit URL Pattern

    +
    +

    + + + +
    +   +   + Cancel +

    +
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    + Valid HTML 4.01 Strict +
    + + + diff --git a/templates/mod-local-help b/templates/mod-local-help new file mode 100644 index 00000000..21d65963 --- /dev/null +++ b/templates/mod-local-help @@ -0,0 +1,12 @@ +

    Local Privoxy support:

    + + +

    You can consult the online documentation for more information about this Privoxy installation.

    + + + +

    Address e-mail questions about this service to + @admin-address@, + who will be glad to help you. +

    + diff --git a/templates/mod-support-and-service b/templates/mod-support-and-service new file mode 100644 index 00000000..d937e16a --- /dev/null +++ b/templates/mod-support-and-service @@ -0,0 +1,22 @@ +

    Support and Service via Sourceforge:

    +

    + We value your feedback. To provide you with the best support, + we ask that you: +

    + diff --git a/templates/mod-title b/templates/mod-title new file mode 100644 index 00000000..18296044 --- /dev/null +++ b/templates/mod-title @@ -0,0 +1,4 @@ +

    + This is Privoxy @version@ on @my-hostname@ (@my-ip-address@), port @my-port@, + @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@ +

    diff --git a/templates/mod-unstable-warning b/templates/mod-unstable-warning new file mode 100644 index 00000000..bb35ccf7 --- /dev/null +++ b/templates/mod-unstable-warning @@ -0,0 +1,6 @@ +

    Warning:

    +

    + Please note that this @code-status@ release + of the proxy software is not intended for production systems! +
    Use at your own risk. See the license for details.
    +

    diff --git a/templates/no-such-domain b/templates/no-such-domain new file mode 100644 index 00000000..f220b5c9 --- /dev/null +++ b/templates/no-such-domain @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + 404 - No such Domain (Privoxy@@my-hostname@) + + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 404 + + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    No such domain

    +

    Your request for @protocol@@hostport@@path@ + could not be fulfilled, because the domain name @host@ could not be resolved. +

    +

    This is often a temporary failiure, so you might just + try again. +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/show-request b/templates/show-request new file mode 100644 index 00000000..0871a114 --- /dev/null +++ b/templates/show-request @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy@@my-hostname@ + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Show-Request

    +

    + 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. +

    + +

    Original Client Request:

    +
    @client-request@
    + +

    Processed Request:

    +
    @processed-request@
    + +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/show-status b/templates/show-status new file mode 100644 index 00000000..0ec4f2ee --- /dev/null +++ b/templates/show-status @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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 + + + + + Privoxy@@my-hostname@: Proxy Status + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    The following files are in use:

    +

    + + + + + @actions-filenames@ + + + + + + + + + + + + + + + +
    Actions Files:
    Filter File:
    + @re-filter-filename@ + + + View + +
    Trust File:
    + @trust-filename@ + + + View + +
    +

    +
    +

    Privoxy was invoked as follows:

    +

    @invocation@

    +
    +

    The following options were given in the config file:

    +

    @options@

    +
    +

    Blocking Statistics:

    +

    + + @requests-blocked@ out of @requests-received@ requests have been blocked, + which equals a block rate of @percent-blocked@%. + + + There haven't been any requests so far. + +

    +
    +

    Conditional #defines:

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #define Enabled? Effects when enabled
    FEATURE_ACL@if-FEATURE_ACL-then@ Yes @else-not-FEATURE_ACL@ No @endif-FEATURE_ACL@Allows the use of an ACL to control access to the proxy by IP address.
    FEATURE_CGI_EDIT_ACTIONS@if-FEATURE_CGI_EDIT_ACTIONS-then@ Yes @else-not-FEATURE_CGI_EDIT_ACTIONS@ No @endif-FEATURE_CGI_EDIT_ACTIONS@Allows the use of the web-based actions file + editor@if-FEATURE_CGI_EDIT_ACTIONS-then@, which is here@else-not-FEATURE_CGI_EDIT_ACTIONS@@endif-FEATURE_CGI_EDIT_ACTIONS@.
    FEATURE_COOKIE_JAR@if-FEATURE_COOKIE_JAR-then@ Yes @else-not-FEATURE_COOKIE_JAR@ No @endif-FEATURE_COOKIE_JAR@Allows the use of a "cookie jar" file to capture cookies.
    FEATURE_FAST_REDIRECTS@if-FEATURE_FAST_REDIRECTS-then@ Yes @else-not-FEATURE_FAST_REDIRECTS@ No @endif-FEATURE_FAST_REDIRECTS@Allows the +fast-redirects action, to bypass redirect and logging scripts.
    FEATURE_FORCE_LOAD@if-FEATURE_FORCE_LOAD-then@ Yes @else-not-FEATURE_FORCE_LOAD@ No @endif-FEATURE_FORCE_LOAD@Allows bypassing all filtering for a single page using the prefix "@FORCE_PREFIX@".
    FEATURE_IMAGE_BLOCKING@if-FEATURE_IMAGE_BLOCKING-then@ Yes @else-not-FEATURE_IMAGE_BLOCKING@ No @endif-FEATURE_IMAGE_BLOCKING@Allows the +image ation, to send "blocked" images instead of HTML.
    FEATURE_IMAGE_DETECT_MSIE@if-FEATURE_IMAGE_DETECT_MSIE-then@ Yes @else-not-FEATURE_IMAGE_DETECT_MSIE@ No @endif-FEATURE_IMAGE_DETECT_MSIE@Enables automatic detection of image and HTML requests from + Microsoft Internet Explorer users, overriding the setting of + +image in the actions file.
    FEATURE_KILL_POPUPS@if-FEATURE_KILL_POPUPS-then@ Yes @else-not-FEATURE_KILL_POPUPS@ No @endif-FEATURE_KILL_POPUPS@Allows the +no-popups action, to block JavaScript popups.
    FEATURE_NO_GIFS@if-FEATURE_NO_GIFS-then@ Yes @else-not-FEATURE_NO_GIFS@ No @endif-FEATURE_NO_GIFS@Use PNG instead of GIF for the built-in images.
    FEATURE_PTHREAD@if-FEATURE_PTHREAD-then@ Yes @else-not-FEATURE_PTHREAD@ No @endif-FEATURE_PTHREAD@Use POSIX threads rather than native threads
    FEATURE_STATISTICS@if-FEATURE_STATISTICS-then@ Yes @else-not-FEATURE_STATISTICS@ No @endif-FEATURE_STATISTICS@Enables the statistics function.
    FEATURE_TOGGLE@if-FEATURE_TOGGLE-then@ Yes @else-not-FEATURE_TOGGLE@ No @endif-FEATURE_TOGGLE@Allow Privoxy to be "disabled" so it is just a normal non-blocking non-anonymizing proxy.
    FEATURE_TRUST@if-FEATURE_TRUST-then@ Yes @else-not-FEATURE_TRUST@ No @endif-FEATURE_TRUST@Allows the use of trust files.
    STATIC_PCRE@if-STATIC_PCRE-then@ Yes @else-not-STATIC_PCRE@ No @endif-STATIC_PCRE@Use the supplied statically-linked PCRE library. This is set automatically + by ./configure if you do not have the libpcre installed.
    STATIC_PCRS@if-STATIC_PCRS-then@ Yes @else-not-STATIC_PCRS@ No @endif-STATIC_PCRS@Use the supplied statically-linked PCRS library. This is set automatically + by ./configure if you do not have the libpcrs installed.
    +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/show-status-file b/templates/show-status-file new file mode 100644 index 00000000..a4abf629 --- /dev/null +++ b/templates/show-status-file @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# + + + + + Privoxy@@my-hostname@: Contents of @file-description@ + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Contents of @file-description@ @filepath@

    +
    @contents@
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/show-url-info b/templates/show-url-info new file mode 100644 index 00000000..fa2e1241 --- /dev/null +++ b/templates/show-url-info @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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 +# + + + + + Privoxy@@my-hostname@ URL Info + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    + +

    NOTE:

    +

    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.

    +

     

    + +

    Matches for @url@:

    +

    @matches@

    +
    +

    Final results:

    +

    @final@

    +
    +

    Look up the actions for a +new + URL:

    +
    +

    + + +

    +
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/show-version b/templates/show-version new file mode 100644 index 00000000..bc7890a1 --- /dev/null +++ b/templates/show-version @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. + + + + + Privoxy@@my-hostname@: Detailed proxy version information + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Source code versions:

    +

    (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 @version@ + and the type of download you got.) +

    +
    @sourceversions@
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/templates/toggle b/templates/toggle new file mode 100644 index 00000000..1150dd7c --- /dev/null +++ b/templates/toggle @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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@ +# + + + + + @if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@ + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Privoxy is @if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@

    +

    When enabled, Privoxy performs its magic - blocking + adverts, filtering cookies, regex-filtering, etc.

    +

    When disabled, Privoxy behaves as a normal HTTP proxy, + and will not affect your web browsing.

    +

    Click + here to @if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@ Privoxy.

    +
    +

    Bookmarklets

    +

    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 - not by clicking the + links below (although that will 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 + 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. +

    + + + +

    + Credit: The site which gave us the general idea for these + bookmarklets is www.bookmarklets.com. + They have more information about them. +

    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + + diff --git a/templates/toggle-mini b/templates/toggle-mini new file mode 100644 index 00000000..bf06fbaf --- /dev/null +++ b/templates/toggle-mini @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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@ +# + + + + + @if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@ + + + + + + + + +

    + Privoxy is + @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@. +
    @if-enabled-display-then@[Disable]@else-not-enabled-display@[Enable]@endif-enabled-display@ | + [Close] +

    + + diff --git a/templates/untrusted b/templates/untrusted new file mode 100644 index 00000000..d9c45294 --- /dev/null +++ b/templates/untrusted @@ -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 +# is not given. Simply enclose the block between the two +# strings @if-start and if--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
  • 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. +# +# + + + + Untrusted request (Privoxy@@my-hostname@) + + + + + + + + + + + + + + + + +# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + UNTRUSTED + + +#include mod-title + +
    + +#include mod-unstable-warning + +
    +

    Request for untrusted URL

    +

    Your request for @protocol@@hostport@@path@ was blocked, + because neither the request URL itself, nor its referrer + (@referrer@) were trusted. +

    + +

    (You can go there anyway.)

    + +
    +

    The following referrers are trusted:

    +
      + @trusted-referrers@ +
    +
    +

    More information on the trust policy:

    +

    You can learn more about what this means and what you may be able to do about it by + reading the following documents: +

    +
      + @trust-info@ +
    +
    +

    More Privoxy:

    +
      @menu@
    +
    + +#include mod-support-and-service + +
    + +#include mod-local-help + +
    +

    Valid HTML 4.01 Strict

    +
    + + + diff --git a/testdrive.status b/testdrive.status new file mode 100644 index 00000000..3ab18af7 --- /dev/null +++ b/testdrive.status @@ -0,0 +1,30 @@ +CHUNK: ASSIGNED TO: RUN1: RUN2: +----------------------------------------------------------------------------- +testdrive-intl-aa +testdrive-intl-ab +testdrive-intl-ac Clifford Caoile +testdrive-intl-ad +testdrive-intl-ae bokeh 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 +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 1.2 +testdrive-us-ah Adam Jacob Muller +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 d1a9fe21..8a40dcc4 100644 --- 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 index 00000000..1b2aee86 --- /dev/null +++ b/urlmatch.c @@ -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). + * + * + *********************************************************************/ + + +#include "config.h" + +#ifndef _WIN32 +#include +#include +#endif + +#include +#include +#include +#include + +#if !defined(_WIN32) && !defined(__OS2__) +#include +#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 index 00000000..09fa6396 --- /dev/null +++ b/urlmatch.h @@ -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). + * + * + *********************************************************************/ + + +#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 index 00000000..f35a4467 --- /dev/null +++ b/user.action @@ -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 index 00000000..c4a1137b --- /dev/null +++ b/vc_config_pthreads.h @@ -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 + * + * 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 + * + * + *********************************************************************/ + + +/* + * 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 header file. */ +/* #define HAVE_INTTYPES_H 1 */ + +/* Define if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_STDINT_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the header file. */ +/* #define HAVE_STRINGS_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the 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 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 causes a warning about one of these. + * + * C4201 : nonstandard extension used : nameless struct/union + * Endemic in + * + * C4214 nonstandard extension used : bit field types other than int + * Endemic in + * + * 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 + */ + +#endif /* CONFIG_H_INCLUDED */ + diff --git a/vc_config_winthreads.h b/vc_config_winthreads.h new file mode 100644 index 00000000..396fb676 --- /dev/null +++ b/vc_config_winthreads.h @@ -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 + * + * 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 + * + * + *********************************************************************/ + + +/* + * 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 header file. */ +/* #define HAVE_INTTYPES_H 1 */ + +/* Define if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_STDINT_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the header file. */ +/* #define HAVE_STRINGS_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the 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 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 causes a warning about one of these. + * + * C4201 : nonstandard extension used : nameless struct/union + * Endemic in + * + * C4214 nonstandard extension used : bit field types other than int + * Endemic in + * + * 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 + */ + + +#endif /* CONFIG_H_INCLUDED */ + diff --git a/vc_console.dsp b/vc_console.dsp new file mode 100644 index 00000000..23d2f2a3 --- /dev/null +++ b/vc_console.dsp @@ -0,0 +1,413 @@ +# Microsoft Developer Studio Project File - Name="vc_console" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=vc_console - Win32 Debug with Win32 threads +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vc_console.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vc_console.mak"\ + CFG="vc_console - Win32 Debug with Win32 threads" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vc_console - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_console - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_console - Win32 Debug with Win32 threads" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "vc_console - Win32 Release with Win32 threads" (based on\ + "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vc_console - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "console_release" +# PROP Intermediate_Dir "console_release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# 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 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "console_debug" +# PROP Intermediate_Dir "console_debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# 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 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Debug with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "console_" +# PROP BASE Intermediate_Dir "console_" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "console_debug_winthr" +# PROP Intermediate_Dir "console_debug_winthr" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# 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 +# 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 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Release with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "console0" +# PROP BASE Intermediate_Dir "console0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "console_release_winthr" +# PROP Intermediate_Dir "console_release_winthr" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# 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 +# 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 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 + +!ENDIF + +# Begin Target + +# Name "vc_console - Win32 Release" +# Name "vc_console - Win32 Debug" +# Name "vc_console - Win32 Debug with Win32 threads" +# Name "vc_console - Win32 Release with Win32 threads" +# Begin Group "JunkBuster" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\actionlist.h +# End Source File +# Begin Source File + +SOURCE=.\actions.c +# End Source File +# Begin Source File + +SOURCE=.\actions.h +# End Source File +# Begin Source File + +SOURCE=.\cgi.c +# End Source File +# Begin Source File + +SOURCE=.\cgi.h +# End Source File +# Begin Source File + +SOURCE=.\cgiedit.c +# End Source File +# Begin Source File + +SOURCE=.\cgiedit.h +# End Source File +# Begin Source File + +SOURCE=.\cgisimple.c +# End Source File +# Begin Source File + +SOURCE=.\cgisimple.h +# End Source File +# Begin Source File + +SOURCE=.\config.h +# End Source File +# Begin Source File + +SOURCE=.\deanimate.c +# End Source File +# Begin Source File + +SOURCE=.\deanimate.h +# End Source File +# Begin Source File + +SOURCE=.\errlog.c +# End Source File +# Begin Source File + +SOURCE=.\errlog.h +# End Source File +# Begin Source File + +SOURCE=.\filters.c +# End Source File +# Begin Source File + +SOURCE=.\filters.h +# End Source File +# Begin Source File + +SOURCE=.\jcc.c +# End Source File +# Begin Source File + +SOURCE=.\jcc.h +# End Source File +# Begin Source File + +SOURCE=.\killpopup.c +# End Source File +# Begin Source File + +SOURCE=.\killpopup.h +# End Source File +# Begin Source File + +SOURCE=.\loadcfg.c +# End Source File +# Begin Source File + +SOURCE=.\loadcfg.h +# End Source File +# Begin Source File + +SOURCE=.\loaders.c +# End Source File +# Begin Source File + +SOURCE=.\loaders.h +# End Source File +# Begin Source File + +SOURCE=.\parsers.c +# End Source File +# Begin Source File + +SOURCE=.\parsers.h +# End Source File +# Begin Source File + +SOURCE=.\project.h +# End Source File +# Begin Source File + +SOURCE=.\urlmatch.c +# End Source File +# Begin Source File + +SOURCE=.\urlmatch.h +# End Source File +# End Group +# Begin Group "Win32" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\cygwin.h +# End Source File +# Begin Source File + +SOURCE=.\win32.c +# End Source File +# Begin Source File + +SOURCE=.\win32.h +# End Source File +# End Group +# Begin Group "PCRE" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\pcre\chartables.c + +!IF "$(CFG)" == "vc_console - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Debug with Win32 threads" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_console - Win32 Release with Win32 threads" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\pcre\config.h +# End Source File +# Begin Source File + +SOURCE=.\pcre\get.c +# End Source File +# Begin Source File + +SOURCE=.\pcre\internal.h +# End Source File +# Begin Source File + +SOURCE=.\pcre\maketables.c +# End Source File +# Begin Source File + +SOURCE=.\pcre\pcre.c +# End Source File +# Begin Source File + +SOURCE=.\pcre\pcre.h +# End Source File +# Begin Source File + +SOURCE=.\pcre\pcreposix.c +# End Source File +# Begin Source File + +SOURCE=.\pcre\pcreposix.h +# End Source File +# Begin Source File + +SOURCE=.\pcre\study.c +# End Source File +# End Group +# Begin Group "PCRS" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\pcrs.c +# End Source File +# Begin Source File + +SOURCE=.\pcrs.h +# End Source File +# End Group +# Begin Group "Sockets" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\gateway.c +# End Source File +# Begin Source File + +SOURCE=.\gateway.h +# End Source File +# Begin Source File + +SOURCE=.\jbsockets.c +# End Source File +# Begin Source File + +SOURCE=.\jbsockets.h +# End Source File +# End Group +# Begin Group "Utilities" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\encode.c +# End Source File +# Begin Source File + +SOURCE=.\encode.h +# End Source File +# Begin Source File + +SOURCE=.\list.c +# End Source File +# Begin Source File + +SOURCE=.\list.h +# End Source File +# Begin Source File + +SOURCE=.\miscutil.c +# End Source File +# Begin Source File + +SOURCE=.\miscutil.h +# End Source File +# Begin Source File + +SOURCE=.\ssplit.c +# End Source File +# Begin Source File + +SOURCE=.\ssplit.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vc_junkbuster.dsw b/vc_junkbuster.dsw deleted file mode 100644 index a275c02a..00000000 --- a/vc_junkbuster.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 5.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "vc_junkbuster"=".\vc_junkbuster.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/vc_junkbuster.dsp b/vc_privoxy.dsp similarity index 57% rename from vc_junkbuster.dsp rename to vc_privoxy.dsp index f9acd6b5..3a61a18f 100644 --- a/vc_junkbuster.dsp +++ b/vc_privoxy.dsp @@ -1,24 +1,29 @@ -# Microsoft Developer Studio Project File - Name="vc_junkbuster" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="vc_privoxy" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 5.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 -CFG=vc_junkbuster - Win32 Release +CFG=vc_privoxy - Win32 Debug with Win32 threads !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "vc_junkbuster.mak". +!MESSAGE NMAKE /f "vc_privoxy.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "vc_junkbuster.mak" CFG="vc_junkbuster - Win32 Release" +!MESSAGE NMAKE /f "vc_privoxy.mak"\ + CFG="vc_privoxy - Win32 Debug with Win32 threads" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "vc_junkbuster - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "vc_junkbuster - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "vc_privoxy - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "vc_privoxy - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "vc_privoxy - Win32 Release with Win32 threads" (based on\ + "Win32 (x86) Application") +!MESSAGE "vc_privoxy - Win32 Debug with Win32 threads" (based on\ + "Win32 (x86) Application") !MESSAGE # Begin Project @@ -28,7 +33,7 @@ CPP=cl.exe MTL=midl.exe RSC=rc.exe -!IF "$(CFG)" == "vc_junkbuster - Win32 Release" +!IF "$(CFG)" == "vc_privoxy - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -52,9 +57,9 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # 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 -# 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 +# 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 -!ELSEIF "$(CFG)" == "vc_junkbuster - Win32 Debug" +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -68,7 +73,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O2 /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -78,24 +83,108 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # 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 +# 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 + +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Release with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "vc_junkb" +# PROP BASE Intermediate_Dir "vc_junkb" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "vc_release_winthr" +# PROP Intermediate_Dir "vc_release_winthr" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 +# 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 + +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Debug with Win32 threads" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "vc_junk0" +# PROP BASE Intermediate_Dir "vc_junk0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "vc_debug_winthr" +# PROP Intermediate_Dir "vc_debug_winthr" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /O2 /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /YX /FD /c +# ADD CPP /nologo /MTd /W4 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# 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 # 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 !ENDIF # Begin Target -# Name "vc_junkbuster - Win32 Release" -# Name "vc_junkbuster - Win32 Debug" +# Name "vc_privoxy - Win32 Release" +# Name "vc_privoxy - Win32 Debug" +# Name "vc_privoxy - Win32 Release with Win32 threads" +# Name "vc_privoxy - Win32 Debug with Win32 threads" # Begin Group "JunkBuster" # PROP Default_Filter "" # Begin Source File -SOURCE=.\amiga.c +SOURCE=.\actionlist.h +# End Source File +# Begin Source File + +SOURCE=.\actions.c +# End Source File +# Begin Source File + +SOURCE=.\actions.h +# End Source File +# Begin Source File + +SOURCE=.\cgi.c +# End Source File +# Begin Source File + +SOURCE=.\cgi.h +# End Source File +# Begin Source File + +SOURCE=.\cgiedit.c +# End Source File +# Begin Source File + +SOURCE=.\cgiedit.h # End Source File # Begin Source File -SOURCE=.\amiga.h +SOURCE=.\cgisimple.c +# End Source File +# Begin Source File + +SOURCE=.\cgisimple.h # End Source File # Begin Source File @@ -103,6 +192,14 @@ SOURCE=.\config.h # End Source File # Begin Source File +SOURCE=.\deanimate.c +# End Source File +# Begin Source File + +SOURCE=.\deanimate.h +# End Source File +# Begin Source File + SOURCE=.\errlog.c # End Source File # Begin Source File @@ -163,11 +260,11 @@ SOURCE=.\project.h # End Source File # Begin Source File -SOURCE=.\showargs.c +SOURCE=.\urlmatch.c # End Source File # Begin Source File -SOURCE=.\showargs.h +SOURCE=.\urlmatch.h # End Source File # End Group # Begin Group "Win32" @@ -191,14 +288,6 @@ SOURCE=.\w32res.h # End Source File # Begin Source File -SOURCE=.\w32rulesdlg.c -# End Source File -# Begin Source File - -SOURCE=.\w32rulesdlg.h -# End Source File -# Begin Source File - SOURCE=.\w32taskbar.c # End Source File # Begin Source File @@ -219,10 +308,6 @@ SOURCE=.\win32.h # PROP Default_Filter "rc,ico,bmp" # Begin Source File -SOURCE=.\icons\denyrule.ico -# End Source File -# Begin Source File - SOURCE=.\icons\ico00001.ico # End Source File # Begin Source File @@ -255,15 +340,11 @@ SOURCE=.\icons\ico00008.ico # End Source File # Begin Source File -SOURCE=.\icons\icon1.ico -# End Source File -# Begin Source File - SOURCE=.\icons\idle.ico # End Source File # Begin Source File -SOURCE=.\icons\junkbust.ico +SOURCE=.\icons\privoxy.ico # End Source File # Begin Source File @@ -277,10 +358,22 @@ SOURCE=.\w32.rc SOURCE=.\pcre\chartables.c -!IF "$(CFG)" == "vc_junkbuster - Win32 Release" +!IF "$(CFG)" == "vc_privoxy - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Debug" -!ELSEIF "$(CFG)" == "vc_junkbuster - Win32 Debug" +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Release with Win32 threads" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vc_privoxy - Win32 Debug with Win32 threads" +# PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 !ENDIF @@ -368,6 +461,14 @@ SOURCE=.\encode.h # End Source File # Begin Source File +SOURCE=.\list.c +# End Source File +# Begin Source File + +SOURCE=.\list.h +# End Source File +# Begin Source File + SOURCE=.\miscutil.c # End Source File # Begin Source File diff --git a/vc_privoxy.dsw b/vc_privoxy.dsw new file mode 100644 index 00000000..3bee9279 --- /dev/null +++ b/vc_privoxy.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "vc_console"=".\vc_console.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name vc_dftables + End Project Dependency +}}} + +############################################################################### + +Project: "vc_dftables"=".\pcre\vc_dftables.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "vc_privoxy"=".\vc_privoxy.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name vc_dftables + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/w32.aps b/w32.aps deleted file mode 100644 index 85caaa5c..00000000 Binary files a/w32.aps and /dev/null differ diff --git a/w32.rc b/w32.rc index 99cdac26..20f6a932 100644 --- a/w32.rc +++ b/w32.rc @@ -1,267 +1,311 @@ -/********************************************************************* - * - * File : $Source: $ - * - * Purpose : Windows GUI resource script. - * - * 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:$ - * - *********************************************************************/ - -#include -#include "config.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_JUNKBUSTER ICON DISCARDABLE "icons/junkbust.ico" -IDI_JUNKBUSTER1 ICON DISCARDABLE "icons/ico00001.ico" -IDI_JUNKBUSTER2 ICON DISCARDABLE "icons/ico00002.ico" -IDI_JUNKBUSTER3 ICON DISCARDABLE "icons/ico00003.ico" -IDI_JUNKBUSTER4 ICON DISCARDABLE "icons/ico00004.ico" -IDI_JUNKBUSTER5 ICON DISCARDABLE "icons/ico00005.ico" -IDI_JUNKBUSTER6 ICON DISCARDABLE "icons/ico00006.ico" -IDI_JUNKBUSTER7 ICON DISCARDABLE "icons/ico00007.ico" -IDI_JUNKBUSTER8 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 //_WIN32 - -/* - * Menus - */ - -IDR_TRAYMENU MENU DISCARDABLE -BEGIN - POPUP "Popup" - BEGIN - MENUITEM "E&xit JunkBuster", ID_FILE_EXIT - MENUITEM SEPARATOR - POPUP "&Options" - BEGIN - MENUITEM "&Junkbuster...", ID_TOOLS_EDITJUNKBUSTER - MENUITEM SEPARATOR - MENUITEM "&Blockers...", ID_TOOLS_EDITBLOCKERS - MENUITEM "&Cookies...", ID_TOOLS_EDITCOOKIES - MENUITEM "&Forward...", ID_TOOLS_EDITFORWARD -#ifdef ACL_FILES - MENUITEM "&Access Control Lists...", ID_TOOLS_EDITACLS -#endif /* def ACL_FILES */ -#ifdef USE_IMAGE_LIST - MENUITEM "&Images...", ID_TOOLS_EDITIMAGE -#endif /* def USE_IMAGE_LIST */ -#ifdef KILLPOPUPS - MENUITEM "&Popups...", ID_TOOLS_EDITPOPUPS -#endif /* def KILLPOPUPS */ -#ifdef PCRS - MENUITEM "Perl &Regexps...", ID_TOOLS_EDITPERLRE -#endif /* def PCRS */ -#ifdef TRUST_FILES - MENUITEM "&Trust...", ID_TOOLS_EDITTRUST -#endif /* def TRUST_FILES */ - END - MENUITEM SEPARATOR -#ifdef TOGGLE - MENUITEM "&Enable", ID_TOGGLE_IJB, CHECKED -#endif - MENUITEM "&Reload config", ID_RELOAD_CONFIG - MENUITEM "Show &JunkBuster 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 TOGGLE - MENUITEM "&Enable", ID_TOGGLE_IJB, CHECKED - MENUITEM "&Reload config", ID_RELOAD_CONFIG - MENUITEM SEPARATOR -#endif - MENUITEM "&Junkbuster...", ID_TOOLS_EDITJUNKBUSTER - MENUITEM SEPARATOR - MENUITEM "&Blockers...", ID_TOOLS_EDITBLOCKERS - MENUITEM "&Cookies...", ID_TOOLS_EDITCOOKIES - MENUITEM "&Forward...", ID_TOOLS_EDITFORWARD -#ifdef ACL_FILES - MENUITEM "&Access Control Lists...",ID_TOOLS_EDITACLS -#endif /* def ACL_FILES */ -#ifdef USE_IMAGE_LIST - MENUITEM "&Images...", ID_TOOLS_EDITIMAGE -#endif /* def USE_IMAGE_LIST */ -#ifdef KILLPOPUPS - MENUITEM "&Popups...", ID_TOOLS_EDITPOPUPS -#endif /* def KILLPOPUPS */ -#ifdef PCRS - MENUITEM "Perl &Regexps...", ID_TOOLS_EDITPERLRE -#endif /* def PCRS */ -#ifdef TRUST_FILES - MENUITEM "&Trust...", ID_TOOLS_EDITTRUST -#endif /* def TRUST_FILES */ - END - POPUP "&Help" - BEGIN - MENUITEM "Junkbuster &FAQ", ID_HELP_FAQ - MENUITEM "Junkbuster &Manual", ID_HELP_MANUAL - MENUITEM "GNU &General Public Licence", ID_HELP_GPL - MENUITEM SEPARATOR - MENUITEM "Junkbuster Status...", ID_HELP_STATUS - MENUITEM SEPARATOR - MENUITEM "About Junkbuster...", ID_HELP_ABOUTJUNKBUSTER - 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 - -/* - * Icons - * - * Icon with lowest ID value placed first to ensure application icon - * remains consistent on all systems. - */ -IDI_DENYRULE ICON DISCARDABLE "icons/denyrule.ico" -IDI_ALLOWRULE ICON DISCARDABLE "icons/icon1.ico" - -/* - * Dialog - */ - -IDD_RULES DIALOG DISCARDABLE 0, 0, 239, 225 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Blockers" -FONT 8, "MS Sans Serif" -BEGIN - GROUPBOX "New Rule",IDC_STATIC,5,5,230,55 - LTEXT "For:",IDC_STATIC,10,15,13,8 - EDITTEXT IDC_NEW,10,25,220,12,ES_AUTOHSCROLL - COMBOBOX IDC_ACTION,10,40,75,37,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "C&reate!",IDC_CREATE,90,40,50,14 - GROUPBOX "Rules",IDC_STATIC,5,65,230,135 - CONTROL "List1",IDC_RULES,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | LVS_EDITLABELS | WS_BORDER | - WS_TABSTOP,10,75,220,100 - PUSHBUTTON "Move &Up",IDC_MOVEUP,10,180,50,14,WS_DISABLED - PUSHBUTTON "Move &Down",IDC_MOVEDOWN,65,180,50,14,WS_DISABLED - PUSHBUTTON "&Delete",IDC_DELETE,120,180,50,14,WS_DISABLED - PUSHBUTTON "&Save",IDC_SAVE,130,205,50,14 - PUSHBUTTON "&Cancel",IDCANCEL,185,205,50,14 -END - - -/* - * DESIGNINFO - */ - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_RULES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 232 - TOPMARGIN, 7 - BOTTOMMARGIN, 218 - END -END -#endif // APSTUDIO_INVOKED - - -/* - * String Table - */ - -STRINGTABLE DISCARDABLE -BEGIN - IDS_NEW_BLOCKER "Create rule for ""%s""..." -END - -#endif /* English (U.S.) resources */ +/********************************************************************* + * + * 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 + +#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 */ diff --git a/w32log.c b/w32log.c index 975c5e0f..ada06b2e 100644 --- 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 * @@ -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 + * * *********************************************************************/ @@ -41,18 +156,21 @@ const char w32log_rcs[] = "$Id: w32log.c,v 1.1 2001/05/13 21:57:07 administrator #include #include +#ifndef STRICT +#define STRICT +#endif #include #include #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: diff --git a/w32log.h b/w32log.h index 85b43754..2634a95c 100644 --- 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 * @@ -34,6 +34,61 @@ * * 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 + * * *********************************************************************/ @@ -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 */ /* diff --git a/w32res.h b/w32res.h index 7fb57b6a..62308cf2 100644 --- 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 @@ -34,42 +34,104 @@ * * 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 @@ -80,36 +142,18 @@ #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 in VC++. @@ -121,7 +165,7 @@ #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 index 845995b0..00000000 --- a/w32rulesdlg.c +++ /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 - * - * - * 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 $ - * - *********************************************************************/ - -#include "config.h" - -#include - -#include -#include - -#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 index 991a8bd0..00000000 --- a/w32rulesdlg.h +++ /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 - * - * - * 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 $ - * - *********************************************************************/ - - -#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: -*/ diff --git a/w32taskbar.c b/w32taskbar.c index 62f269d0..721ad08e 100644 --- a/w32taskbar.c +++ b/w32taskbar.c @@ -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 * @@ -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 + * * *********************************************************************/ @@ -40,6 +58,9 @@ const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.1 2001/05/13 21:57:07 admin #include +#ifndef STRICT +#define STRICT +#endif #include #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 diff --git a/w32taskbar.h b/w32taskbar.h index 9ba21fbd..19450614 100644 --- a/w32taskbar.h +++ b/w32taskbar.h @@ -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 * @@ -34,6 +34,16 @@ * * 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 + * * *********************************************************************/ @@ -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 2252dc1f..9db1ed1b 100644 --- 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 * @@ -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 + * * *********************************************************************/ @@ -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 #include #include +#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) +/* Visual C++ Heap debugging */ +#include +#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 3011f478..7c699dc3 100644 --- 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 * @@ -33,6 +33,22 @@ * * 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 + * * *********************************************************************/ @@ -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