+++ /dev/null
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/actionlist.h,v $
- *
- * Purpose : Master list of supported actions.
- * Not really a header, since it generates code.
- * This is included (3 times!) from actions.c
- * Each time, the following macros are defined to
- * suitable values beforehand:
- * DEFINE_ACTION_MULTI()
- * DEFINE_ACTION_STRING()
- * DEFINE_ACTION_BOOL()
- * DEFINE_ACTION_ALIAS
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: actionlist.h,v $
- * Revision 1.16 2002/04/24 02:15:18 oes
- * Renamed actions as discussed, Aliased old action names to new ones.
- *
- * Revision 1.15 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.14 2002/03/24 16:32:08 jongfoster
- * Removing logo option
- *
- * Revision 1.13 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.12 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.11 2002/03/12 01:42:49 oes
- * Introduced modular filters
- *
- * Revision 1.10 2002/03/08 18:19:14 jongfoster
- * Adding +image-blocker{pattern} option to edit interface
- *
- * Revision 1.9 2001/11/22 21:58:41 jongfoster
- * Adding action +no-cookies-keep
- *
- * Revision 1.8 2001/10/10 16:42:52 oes
- * Fixed a bug, Added +limit-connect string action
- *
- * Revision 1.7 2001/10/07 15:33:59 oes
- * Introduced a +no-compression action
- * Introduced a +downgrade action
- *
- * Revision 1.6 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- * Revision 1.5 2001/07/18 12:27:03 oes
- * Changed deanimate-gifs to string action
- *
- * Revision 1.4 2001/07/13 13:52:12 oes
- * - Formatting
- * - Introduced new action ACTION_DEANIMATE
- *
- * Revision 1.3 2001/06/07 23:03:56 jongfoster
- * Added standard comment at top of file.
- *
- *
- *********************************************************************/
-\f
-
-#if !(defined(DEFINE_ACTION_BOOL) && defined(DEFINE_ACTION_MULTI) && defined(DEFINE_ACTION_STRING))
-#error Please define lots of macros before including "actionlist.h".
-#endif /* !defined(all the DEFINE_ACTION_xxx macros) */
-
-#ifndef DEFINE_CGI_PARAM_RADIO
-#define DEFINE_CGI_PARAM_RADIO(name, bit, index, value, is_default)
-#define DEFINE_CGI_PARAM_CUSTOM(name, bit, index, default_val)
-#define DEFINE_CGI_PARAM_NO_RADIO(name, bit, index, default_val)
-#endif /* ndef DEFINE_CGI_PARAM_RADIO */
-
-DEFINE_ACTION_MULTI ("add-header", ACTION_MULTI_ADD_HEADER)
-DEFINE_ACTION_BOOL ("block", ACTION_BLOCK)
-DEFINE_ACTION_BOOL ("crunch-incoming-cookies", ACTION_NO_COOKIE_SET)
-DEFINE_ACTION_BOOL ("crunch-outgoing-cookies", ACTION_NO_COOKIE_READ)
-DEFINE_ACTION_STRING ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE)
-DEFINE_CGI_PARAM_RADIO ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE, "first", 0)
-DEFINE_CGI_PARAM_RADIO ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE, "last", 1)
-DEFINE_ACTION_BOOL ("downgrade-http-version", ACTION_DOWNGRADE)
-DEFINE_ACTION_BOOL ("fast-redirects", ACTION_FAST_REDIRECTS)
-DEFINE_ACTION_MULTI ("filter", ACTION_MULTI_FILTER)
-DEFINE_ACTION_BOOL ("handle-as-image", ACTION_IMAGE)
-DEFINE_ACTION_BOOL ("hide-forwarded-for-headers", ACTION_HIDE_FORWARDED)
-DEFINE_ACTION_STRING ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM)
-DEFINE_CGI_PARAM_RADIO ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "block", 1)
-DEFINE_CGI_PARAM_CUSTOM ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "spam_me_senseless@sittingduck.xyz")
-DEFINE_ACTION_STRING ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER)
-DEFINE_CGI_PARAM_RADIO ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "forge", 1)
-DEFINE_CGI_PARAM_RADIO ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "block", 0)
-DEFINE_CGI_PARAM_CUSTOM ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "http://www.google.com/")
-DEFINE_ACTION_STRING ("hide-user-agent", ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT)
-DEFINE_CGI_PARAM_NO_RADIO("hide-user-agent", ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT, "Privoxy/3.0 (Anonymous)")
-DEFINE_ACTION_BOOL ("kill-popups", ACTION_NO_POPUPS)
-DEFINE_ACTION_STRING ("limit-connect", ACTION_LIMIT_CONNECT, ACTION_STRING_LIMIT_CONNECT)
-DEFINE_CGI_PARAM_NO_RADIO("limit-connect", ACTION_LIMIT_CONNECT, ACTION_STRING_LIMIT_CONNECT, "443")
-DEFINE_ACTION_BOOL ("prevent-compression", ACTION_NO_COMPRESSION)
-DEFINE_ACTION_BOOL ("send-vanilla-wafer", ACTION_VANILLA_WAFER)
-DEFINE_ACTION_MULTI ("send-wafer", ACTION_MULTI_WAFER)
-DEFINE_ACTION_BOOL ("session-cookies-only", ACTION_NO_COOKIE_KEEP)
-DEFINE_ACTION_STRING ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER)
-DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "pattern", 1)
-DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "blank", 0)
-DEFINE_CGI_PARAM_CUSTOM ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, CGI_PREFIX "show-banner?type=pattern")
-
-
-#if DEFINE_ACTION_ALIAS
-
-/*
- * Alternative spellings
- */
-DEFINE_ACTION_BOOL ("kill-popup", ACTION_NO_POPUPS)
-DEFINE_ACTION_STRING ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER)
-DEFINE_ACTION_BOOL ("prevent-keeping-cookies", ACTION_NO_COOKIE_KEEP)
-
-/*
- * Pre-3.0 compatibility
- */
-DEFINE_ACTION_BOOL ("prevent-reading-cookies", ACTION_NO_COOKIE_READ)
-DEFINE_ACTION_BOOL ("prevent-setting-cookies", ACTION_NO_COOKIE_SET)
-DEFINE_ACTION_BOOL ("downgrade", ACTION_DOWNGRADE)
-DEFINE_ACTION_BOOL ("hide-forwarded", ACTION_HIDE_FORWARDED)
-DEFINE_ACTION_STRING ("hide-from", ACTION_HIDE_FROM, ACTION_STRING_FROM)
-DEFINE_ACTION_BOOL ("image", ACTION_IMAGE)
-DEFINE_ACTION_STRING ("image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER)
-DEFINE_ACTION_BOOL ("no-compression", ACTION_NO_COMPRESSION)
-DEFINE_ACTION_BOOL ("no-cookies-keep", ACTION_NO_COOKIE_KEEP)
-DEFINE_ACTION_BOOL ("no-cookies-read", ACTION_NO_COOKIE_READ)
-DEFINE_ACTION_BOOL ("no-cookies-set", ACTION_NO_COOKIE_SET)
-DEFINE_ACTION_BOOL ("no-popups", ACTION_NO_POPUPS)
-#endif /* if DEFINE_ACTION_ALIAS */
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-#undef DEFINE_CGI_PARAM_CUSTOM
-#undef DEFINE_CGI_PARAM_RADIO
-#undef DEFINE_CGI_PARAM_NO_RADIO
-
+++ /dev/null
-const char actions_rcs[] = "$Id: actions.c,v 1.32 2002/05/12 21:36:29 jongfoster 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.32 2002/05/12 21:36:29 jongfoster
- * Correcting function comments
- *
- * Revision 1.31 2002/05/06 07:56:50 oes
- * Made actions_to_html independent of FEATURE_CGI_EDIT_ACTIONS
- *
- * Revision 1.30 2002/04/30 11:14:52 oes
- * Made csp the first parameter in *action_to_html
- *
- * Revision 1.29 2002/04/26 19:30:54 jongfoster
- * - current_action_to_html(): Adding help link for the "-" form of
- * one-string actions.
- * - Some actions had "<br>-", some "<br> -" (note the space).
- * Standardizing on no space.
- * - Greatly simplifying some of the code by using string_join()
- * where appropriate.
- *
- * Revision 1.28 2002/04/26 12:53:15 oes
- * - CGI AF editor now writes action lines split into
- * single lines with line continuation
- * - actions_to_html now embeds each action name in
- * link to chapter
- * - current_action_to_text is now called current_action_to_html
- * and acts like actions_to_html
- *
- * Revision 1.27 2002/04/24 02:10:31 oes
- * - Jon's patch for multiple AFs:
- * - split load_actions_file, add load_one_actions_file
- * - make csp->actions_list files an array
- * - remember file id with each action
- * - Copy_action now frees dest action before copying
- *
- * Revision 1.26 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.25 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.24 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.23 2002/03/07 03:46:16 oes
- * Fixed compiler warnings
- *
- * Revision 1.22 2002/01/21 00:27:02 jongfoster
- * Allowing free_action(NULL).
- * Moving the functions that #include actionlist.h to the end of the file,
- * because the Visual C++ 97 debugger gets extremely confused if you try
- * to debug any code that comes after them in the file.
- *
- * Revision 1.21 2002/01/17 20:54:44 jongfoster
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Revision 1.20 2001/11/22 21:56:49 jongfoster
- * Making action_spec->flags into an unsigned long rather than just an
- * unsigned int.
- * Fixing a bug in the display of -add-header and -wafer
- *
- * Revision 1.19 2001/11/13 00:14:07 jongfoster
- * Fixing stupid bug now I've figured out what || means.
- * (It always returns 0 or 1, not one of it's paramaters.)
- *
- * Revision 1.18 2001/11/07 00:06:06 steudten
- * Add line number in error output for lineparsing for
- * actionsfile.
- *
- * Revision 1.17 2001/10/25 03:40:47 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.16 2001/10/23 21:30:30 jongfoster
- * Adding error-checking to selected functions.
- *
- * Revision 1.15 2001/10/14 21:58:22 jongfoster
- * Adding support for the CGI-based editor:
- * - Exported get_actions()
- * - Added new function free_alias_list()
- * - Added support for {{settings}} and {{description}} blocks
- * in the actions file. They are currently ignored.
- * - Added restriction to only one {{alias}} block which must appear
- * first in the file, to simplify the editor's rewriting rules.
- * - Note that load_actions_file() is no longer used by the CGI-based
- * editor, but some of the other routines in this file are.
- *
- * Revision 1.14 2001/09/22 16:36:59 jongfoster
- * Removing unused parameter fs from read_config_line()
- *
- * Revision 1.13 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- * Revision 1.12 2001/09/16 13:21:27 jongfoster
- * Changes to use new list functions.
- *
- * Revision 1.11 2001/09/14 00:17:32 jongfoster
- * Tidying up memory allocation. New function init_action().
- *
- * Revision 1.10 2001/09/10 10:14:34 oes
- * Removing unused variable
- *
- * Revision 1.9 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.8 2001/06/29 13:19:52 oes
- * Removed logentry from cancelled commit
- *
- * Revision 1.7 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.6 2001/06/07 23:04:34 jongfoster
- * Made get_actions() static.
- *
- * Revision 1.5 2001/06/03 19:11:48 oes
- * adapted to new enlist_unique arg format
- *
- * Revision 1.4 2001/06/01 20:03:42 jongfoster
- * Better memory management - current_action->strings[] now
- * contains copies of the strings, not the original.
- *
- * Revision 1.3 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.2 2001/05/31 21:40:00 jongfoster
- * Removing some commented out, obsolete blocks of code.
- *
- * Revision 1.1 2001/05/31 21:16:46 jongfoster
- * Moved functions to process the action list into this new file.
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#include "project.h"
-#include "jcc.h"
-#include "list.h"
-#include "actions.h"
-#include "miscutil.h"
-#include "errlog.h"
-#include "loaders.h"
-#include "encode.h"
-#include "urlmatch.h"
-#include "cgi.h"
-
-const char actions_h_rcs[] = ACTIONS_H_VERSION;
-
-
-/*
- * We need the main list of options.
- *
- * First, we need a way to tell between boolean, string, and multi-string
- * options. For string and multistring options, we also need to be
- * able to tell the difference between a "+" and a "-". (For bools,
- * the "+"/"-" information is encoded in "add" and "mask"). So we use
- * an enumerated type (well, the preprocessor equivalent). Here are
- * the values:
- */
-#define AV_NONE 0 /* +opt -opt */
-#define AV_ADD_STRING 1 /* +stropt{string} */
-#define AV_REM_STRING 2 /* -stropt */
-#define AV_ADD_MULTI 3 /* +multiopt{string} +multiopt{string2} */
-#define AV_REM_MULTI 4 /* -multiopt{string} -multiopt */
-
-/*
- * We need a structure to hold the name, flag changes,
- * type, and string index.
- */
-struct action_name
-{
- const char * name;
- unsigned long mask; /* a bit set to "0" = remove action */
- unsigned long add; /* a bit set to "1" = add action */
- int takes_value; /* an AV_... constant */
- int index; /* index into strings[] or multi[] */
-};
-
-/*
- * And with those building blocks in place, here's the array.
- */
-static const struct action_name action_names[] =
-{
- /*
- * Well actually there's no data here - it's in actionlist.h
- * This keeps it together to make it easy to change.
- *
- * Here's the macros used to format it:
- */
-#define DEFINE_ACTION_MULTI(name,index) \
- { "+" name, ACTION_MASK_ALL, 0, AV_ADD_MULTI, index }, \
- { "-" name, ACTION_MASK_ALL, 0, AV_REM_MULTI, index },
-#define DEFINE_ACTION_STRING(name,flag,index) \
- { "+" name, ACTION_MASK_ALL, flag, AV_ADD_STRING, index }, \
- { "-" name, ~flag, 0, AV_REM_STRING, index },
-#define DEFINE_ACTION_BOOL(name,flag) \
- { "+" name, ACTION_MASK_ALL, flag }, \
- { "-" name, ~flag, 0 },
-#define DEFINE_ACTION_ALIAS 1 /* Want aliases please */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-
- { NULL, 0, 0 } /* End marker */
-};
-
-
-static int load_one_actions_file(struct client_state *csp, int fileid);
-
-
-/*********************************************************************
- *
- * Function : merge_actions
- *
- * Description : Merge two actions together.
- * Similar to "dest += src".
- *
- * Parameters :
- * 1 : dest = Actions to modify.
- * 2 : src = Action to add.
- *
- * Returns : JB_ERR_OK or JB_ERR_MEMORY
- *
- *********************************************************************/
-jb_err merge_actions (struct action_spec *dest,
- const struct action_spec *src)
-{
- int i;
- jb_err err;
-
- dest->mask &= src->mask;
- dest->add &= src->mask;
- dest->add |= src->add;
-
- for (i = 0; i < ACTION_STRING_COUNT; i++)
- {
- char * str = src->string[i];
- if (str)
- {
- freez(dest->string[i]);
- dest->string[i] = strdup(str);
- if (NULL == dest->string[i])
- {
- return JB_ERR_MEMORY;
- }
- }
- }
-
- for (i = 0; i < ACTION_MULTI_COUNT; i++)
- {
- if (src->multi_remove_all[i])
- {
- /* Remove everything from dest */
- list_remove_all(dest->multi_remove[i]);
- dest->multi_remove_all[i] = 1;
-
- err = list_duplicate(dest->multi_add[i], src->multi_add[i]);
- }
- else if (dest->multi_remove_all[i])
- {
- /*
- * dest already removes everything, so we only need to worry
- * about what we add.
- */
- list_remove_list(dest->multi_add[i], src->multi_remove[i]);
- err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
- }
- else
- {
- /* No "remove all"s to worry about. */
- list_remove_list(dest->multi_add[i], src->multi_remove[i]);
- err = list_append_list_unique(dest->multi_remove[i], src->multi_remove[i]);
- if (!err) err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
- }
-
- if (err)
- {
- return err;
- }
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : copy_action
- *
- * Description : Copy an action_specs.
- * Similar to "dest = src".
- *
- * Parameters :
- * 1 : dest = Destination of copy.
- * 2 : src = Source for copy.
- *
- * Returns : N/A
- *
- *********************************************************************/
-jb_err copy_action (struct action_spec *dest,
- const struct action_spec *src)
-{
- int i;
- jb_err err = JB_ERR_OK;
-
- free_action(dest);
- memset(dest, '\0', sizeof(*dest));
-
- dest->mask = src->mask;
- dest->add = src->add;
-
- for (i = 0; i < ACTION_STRING_COUNT; i++)
- {
- char * str = src->string[i];
- if (str)
- {
- str = strdup(str);
- if (!str)
- {
- return JB_ERR_MEMORY;
- }
- dest->string[i] = str;
- }
- }
-
- for (i = 0; i < ACTION_MULTI_COUNT; i++)
- {
- dest->multi_remove_all[i] = src->multi_remove_all[i];
- err = list_duplicate(dest->multi_remove[i], src->multi_remove[i]);
- if (err)
- {
- return err;
- }
- err = list_duplicate(dest->multi_add[i], src->multi_add[i]);
- if (err)
- {
- return err;
- }
- }
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : free_action
- *
- * Description : Destroy an action_spec. Frees memory used by it,
- * except for the memory used by the struct action_spec
- * itself.
- *
- * Parameters :
- * 1 : src = Source to free.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_action (struct action_spec *src)
-{
- int i;
-
- if (src == NULL)
- {
- return;
- }
-
- for (i = 0; i < ACTION_STRING_COUNT; i++)
- {
- freez(src->string[i]);
- }
-
- for (i = 0; i < ACTION_MULTI_COUNT; i++)
- {
- destroy_list(src->multi_remove[i]);
- destroy_list(src->multi_add[i]);
- }
-
- memset(src, '\0', sizeof(*src));
-}
-
-
-/*********************************************************************
- *
- * Function : get_action_token
- *
- * Description : Parses a line for the first action.
- * Modifies it's input array, doesn't allocate memory.
- * e.g. given:
- * *line=" +abc{def} -ghi "
- * Returns:
- * *line=" -ghi "
- * *name="+abc"
- * *value="def"
- *
- * Parameters :
- * 1 : line = [in] The line containing the action.
- * [out] Start of next action on line, or
- * NULL if we reached the end of line before
- * we found an action.
- * 2 : name = [out] Start of action name, null
- * terminated. NULL on EOL
- * 3 : value = [out] Start of action value, null
- * terminated. NULL if none or EOL.
- *
- * Returns : JB_ERR_OK => Ok
- * JB_ERR_PARSE => Mismatched {} (line was trashed anyway)
- *
- *********************************************************************/
-jb_err get_action_token(char **line, char **name, char **value)
-{
- char * str = *line;
- char ch;
-
- /* set default returns */
- *line = NULL;
- *name = NULL;
- *value = NULL;
-
- /* Eat any leading whitespace */
- while ((*str == ' ') || (*str == '\t'))
- {
- str++;
- }
-
- if (*str == '\0')
- {
- return 0;
- }
-
- if (*str == '{')
- {
- /* null name, just value is prohibited */
- return JB_ERR_PARSE;
- }
-
- *name = str;
-
- /* parse option */
- while (((ch = *str) != '\0') &&
- (ch != ' ') && (ch != '\t') && (ch != '{'))
- {
- if (ch == '}')
- {
- /* error, '}' without '{' */
- return JB_ERR_PARSE;
- }
- str++;
- }
- *str = '\0';
-
- if (ch != '{')
- {
- /* no value */
- if (ch == '\0')
- {
- /* EOL - be careful not to run off buffer */
- *line = str;
- }
- else
- {
- /* More to parse next time. */
- *line = str + 1;
- }
- return JB_ERR_OK;
- }
-
- str++;
- *value = str;
-
- str = strchr(str, '}');
- if (str == NULL)
- {
- /* error */
- *value = NULL;
- return JB_ERR_PARSE;
- }
-
- /* got value */
- *str = '\0';
- *line = str + 1;
-
- chomp(*value);
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : get_actions
- *
- * Description : Parses a list of actions.
- *
- * Parameters :
- * 1 : line = The string containing the actions.
- * Will be written to by this function.
- * 2 : alias_list = Custom alias list, or NULL for none.
- * 3 : cur_action = Where to store the action. Caller
- * allocates memory.
- *
- * Returns : JB_ERR_OK => Ok
- * JB_ERR_PARSE => Parse error (line was trashed anyway)
- * nonzero => Out of memory (line was trashed anyway)
- *
- *********************************************************************/
-jb_err get_actions(char *line,
- struct action_alias * alias_list,
- struct action_spec *cur_action)
-{
- jb_err err;
- init_action(cur_action);
- cur_action->mask = ACTION_MASK_ALL;
-
- while (line)
- {
- char * option = NULL;
- char * value = NULL;
-
- err = get_action_token(&line, &option, &value);
- if (err)
- {
- return err;
- }
-
- if (option)
- {
- /* handle option in 'option' */
-
- /* Check for standard action name */
- const struct action_name * action = action_names;
-
- while ( (action->name != NULL) && (0 != strcmpic(action->name, option)) )
- {
- action++;
- }
- if (action->name != NULL)
- {
- /* Found it */
- cur_action->mask &= action->mask;
- cur_action->add &= action->mask;
- cur_action->add |= action->add;
-
- switch (action->takes_value)
- {
- case AV_NONE:
- /* ignore any option. */
- break;
- case AV_ADD_STRING:
- {
- /* add single string. */
-
- if ((value == NULL) || (*value == '\0'))
- {
- return JB_ERR_PARSE;
- }
- /* FIXME: should validate option string here */
- freez (cur_action->string[action->index]);
- cur_action->string[action->index] = strdup(value);
- if (NULL == cur_action->string[action->index])
- {
- return JB_ERR_MEMORY;
- }
- break;
- }
- case AV_REM_STRING:
- {
- /* remove single string. */
-
- freez (cur_action->string[action->index]);
- break;
- }
- case AV_ADD_MULTI:
- {
- /* append multi string. */
-
- struct list * remove_p = cur_action->multi_remove[action->index];
- struct list * add_p = cur_action->multi_add[action->index];
-
- if ((value == NULL) || (*value == '\0'))
- {
- return JB_ERR_PARSE;
- }
-
- list_remove_item(remove_p, value);
- err = enlist_unique(add_p, value, 0);
- if (err)
- {
- return err;
- }
- break;
- }
- case AV_REM_MULTI:
- {
- /* remove multi string. */
-
- struct list * remove_p = cur_action->multi_remove[action->index];
- struct list * add_p = cur_action->multi_add[action->index];
-
- if ( (value == NULL) || (*value == '\0')
- || ((*value == '*') && (value[1] == '\0')) )
- {
- /*
- * no option, or option == "*".
- *
- * Remove *ALL*.
- */
- list_remove_all(remove_p);
- list_remove_all(add_p);
- cur_action->multi_remove_all[action->index] = 1;
- }
- else
- {
- /* Valid option - remove only 1 option */
-
- if ( !cur_action->multi_remove_all[action->index] )
- {
- /* there isn't a catch-all in the remove list already */
- err = enlist_unique(remove_p, value, 0);
- if (err)
- {
- return err;
- }
- }
- list_remove_item(add_p, value);
- }
- break;
- }
- default:
- /* Shouldn't get here unless there's memory corruption. */
- assert(0);
- return JB_ERR_PARSE;
- }
- }
- else
- {
- /* try user aliases. */
- const struct action_alias * alias = alias_list;
-
- while ( (alias != NULL) && (0 != strcmpic(alias->name, option)) )
- {
- alias = alias->next;
- }
- if (alias != NULL)
- {
- /* Found it */
- merge_actions(cur_action, alias->action);
- }
- else
- {
- /* Bad action name */
- return JB_ERR_PARSE;
- }
- }
- }
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : init_current_action
- *
- * Description : Zero out an action.
- *
- * Parameters :
- * 1 : dest = An uninitialized current_action_spec.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void init_current_action (struct current_action_spec *dest)
-{
- memset(dest, '\0', sizeof(*dest));
-
- dest->flags = ACTION_MOST_COMPATIBLE;
-}
-
-
-/*********************************************************************
- *
- * Function : init_action
- *
- * Description : Zero out an action.
- *
- * Parameters :
- * 1 : dest = An uninitialized action_spec.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void init_action (struct action_spec *dest)
-{
- memset(dest, '\0', sizeof(*dest));
-}
-
-
-/*********************************************************************
- *
- * Function : merge_current_action
- *
- * Description : Merge two actions together.
- * Similar to "dest += src".
- * Differences between this and merge_actions()
- * is that this one doesn't allocate memory for
- * strings (so "src" better be in memory for at least
- * as long as "dest" is, and you'd better free
- * "dest" using "free_current_action").
- * Also, there is no mask or remove lists in dest.
- * (If we're applying it to a URL, we don't need them)
- *
- * Parameters :
- * 1 : dest = Current actions, to modify.
- * 2 : src = Action to add.
- *
- * Returns 0 : no error
- * !=0 : error, probably JB_ERR_MEMORY.
- *
- *********************************************************************/
-jb_err merge_current_action (struct current_action_spec *dest,
- const struct action_spec *src)
-{
- int i;
- jb_err err = JB_ERR_OK;
-
- dest->flags &= src->mask;
- dest->flags |= src->add;
-
- for (i = 0; i < ACTION_STRING_COUNT; i++)
- {
- char * str = src->string[i];
- if (str)
- {
- str = strdup(str);
- if (!str)
- {
- return JB_ERR_MEMORY;
- }
- freez(dest->string[i]);
- dest->string[i] = str;
- }
- }
-
- for (i = 0; i < ACTION_MULTI_COUNT; i++)
- {
- if (src->multi_remove_all[i])
- {
- /* Remove everything from dest, then add src->multi_add */
- err = list_duplicate(dest->multi[i], src->multi_add[i]);
- if (err)
- {
- return err;
- }
- }
- else
- {
- list_remove_list(dest->multi[i], src->multi_remove[i]);
- err = list_append_list_unique(dest->multi[i], src->multi_add[i]);
- if (err)
- {
- return err;
- }
- }
- }
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : free_current_action
- *
- * Description : Free memory used by a current_action_spec.
- * Does not free the current_action_spec itself.
- *
- * Parameters :
- * 1 : src = Source to free.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_current_action (struct current_action_spec *src)
-{
- int i;
-
- for (i = 0; i < ACTION_STRING_COUNT; i++)
- {
- freez(src->string[i]);
- }
-
- for (i = 0; i < ACTION_MULTI_COUNT; i++)
- {
- destroy_list(src->multi[i]);
- }
-
- memset(src, '\0', sizeof(*src));
-}
-
-
-static struct file_list *current_actions_file[MAX_ACTION_FILES] = {
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL
-};
-
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-/*********************************************************************
- *
- * Function : unload_current_actions_file
- *
- * Description : Unloads current actions file - reset to state at
- * beginning of program.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void unload_current_actions_file(void)
-{
- if (current_actions_file)
- {
- current_actions_file->unloader = unload_actions_file;
- current_actions_file = NULL;
- }
-}
-#endif /* FEATURE_GRACEFUL_TERMINATION */
-
-
-/*********************************************************************
- *
- * Function : unload_actions_file
- *
- * Description : Unloads an actions module.
- *
- * Parameters :
- * 1 : file_data = the data structure associated with the
- * actions file.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void unload_actions_file(void *file_data)
-{
- struct url_actions * next;
- struct url_actions * cur = (struct url_actions *)file_data;
- while (cur != NULL)
- {
- next = cur->next;
- free_url_spec(cur->url);
- free_action(cur->action);
- freez(cur);
- cur = next;
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : free_alias_list
- *
- * Description : Free memory used by a list of aliases.
- *
- * Parameters :
- * 1 : alias_list = Linked list to free.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_alias_list(struct action_alias *alias_list)
-{
- while (alias_list != NULL)
- {
- struct action_alias * next = alias_list->next;
- alias_list->next = NULL;
- freez(alias_list->name);
- free_action(alias_list->action);
- free(alias_list);
- alias_list = next;
- }
-}
-
-
-/*********************************************************************
- *
- * Function : load_actions_file
- *
- * Description : Read and parse all the action files and add to files
- * list.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : 0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int load_actions_file(struct client_state *csp)
-{
- int i;
- int result;
-
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (csp->config->actions_file[i])
- {
- result = load_one_actions_file(csp, i);
- if (result)
- {
- return result;
- }
- }
- else if (current_actions_file[i])
- {
- current_actions_file[i]->unloader = unload_actions_file;
- current_actions_file[i] = NULL;
- }
- }
-
- return 0;
-}
-
-/*********************************************************************
- *
- * Function : load_one_actions_file
- *
- * Description : Read and parse a action file and add to files
- * list.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : fileid = File index to load.
- *
- * Returns : 0 => Ok, everything else is an error.
- *
- *********************************************************************/
-static int load_one_actions_file(struct client_state *csp, int fileid)
-{
-
- /*
- * Parser mode.
- * Note: Keep these in the order they occur in the file, they are
- * sometimes tested with <=
- */
-#define MODE_START_OF_FILE 1
-#define MODE_SETTINGS 2
-#define MODE_DESCRIPTION 3
-#define MODE_ALIAS 4
-#define MODE_ACTIONS 5
-
- int mode = MODE_START_OF_FILE;
-
- FILE *fp;
- struct url_actions *last_perm;
- struct url_actions *perm;
- char buf[BUFFER_SIZE];
- struct file_list *fs;
- struct action_spec * cur_action = NULL;
- int cur_action_used = 0;
- struct action_alias * alias_list = NULL;
- unsigned long linenum = 0;
-
- if (!check_file_changed(current_actions_file[fileid], csp->config->actions_file[fileid], &fs))
- {
- /* No need to load */
- csp->actions_list[fileid] = current_actions_file[fileid];
- return 0;
- }
- if (!fs)
- {
- log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error finding file: %E",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
-
- fs->f = last_perm = (struct url_actions *)zalloc(sizeof(*last_perm));
- if (last_perm == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': out of memory!",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
-
- if ((fp = fopen(csp->config->actions_file[fileid], "r")) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error opening file: %E",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
-
- while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
- {
- if (*buf == '{')
- {
- /* It's a header block */
- if (buf[1] == '{')
- {
- /* It's {{settings}} or {{alias}} */
- int len = strlen(buf);
- char * start = buf + 2;
- char * end = buf + len - 1;
- if ((len < 5) || (*end-- != '}') || (*end-- != '}'))
- {
- /* too short */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid line (%lu): %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
-
- /* Trim leading and trailing whitespace. */
- end[1] = '\0';
- chomp(start);
-
- if (*start == '\0')
- {
- /* too short */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid line (%lu): {{ }}",
- csp->config->actions_file[fileid], linenum);
- return 1; /* never get here */
- }
-
- /*
- * An actionsfile can optionally contain the following blocks.
- * They *MUST* be in this order, to simplify processing:
- *
- * {{settings}}
- * name=value...
- *
- * {{description}}
- * ...free text, format TBD, but no line may start with a '{'...
- *
- * {{alias}}
- * name=actions...
- *
- * The actual actions must be *after* these special blocks.
- * None of these special blocks may be repeated.
- *
- */
- if (0 == strcmpic(start, "settings"))
- {
- /* it's a {{settings}} block */
- if (mode >= MODE_SETTINGS)
- {
- /* {{settings}} must be first thing in file and must only
- * appear once.
- */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': line %lu: {{settings}} must only appear once, and it must be before anything else.",
- csp->config->actions_file[fileid], linenum);
- }
- mode = MODE_SETTINGS;
- }
- else if (0 == strcmpic(start, "description"))
- {
- /* it's a {{description}} block */
- if (mode >= MODE_DESCRIPTION)
- {
- /* {{description}} is a singleton and only {{settings}} may proceed it
- */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': line %lu: {{description}} must only appear once, and only a {{settings}} block may be above it.",
- csp->config->actions_file[fileid], linenum);
- }
- mode = MODE_DESCRIPTION;
- }
- else if (0 == strcmpic(start, "alias"))
- {
- /* it's an {{alias}} block */
- if (mode >= MODE_ALIAS)
- {
- /* {{alias}} must be first thing in file, possibly after
- * {{settings}} and {{description}}
- *
- * {{alias}} must only appear once.
- *
- * Note that these are new restrictions introduced in
- * v2.9.10 in order to make actionsfile editing simpler.
- * (Otherwise, reordering actionsfile entries without
- * completely rewriting the file becomes non-trivial)
- */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': line %lu: {{alias}} must only appear once, and it must be before all actions.",
- csp->config->actions_file[fileid], linenum);
- }
- mode = MODE_ALIAS;
- }
- else
- {
- /* invalid {{something}} block */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid line (%lu): {{%s}}",
- csp->config->actions_file[fileid], linenum, start);
- return 1; /* never get here */
- }
- }
- else
- {
- /* It's an actions block */
-
- char actions_buf[BUFFER_SIZE];
- char * end;
-
- /* set mode */
- mode = MODE_ACTIONS;
-
- /* free old action */
- if (cur_action)
- {
- if (!cur_action_used)
- {
- free_action(cur_action);
- free(cur_action);
- }
- cur_action = NULL;
- }
- cur_action_used = 0;
- cur_action = (struct action_spec *)zalloc(sizeof(*cur_action));
- if (cur_action == NULL)
- {
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': out of memory",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
- init_action(cur_action);
-
- /* trim { */
- strcpy(actions_buf, buf + 1);
-
- /* check we have a trailing } and then trim it */
- end = actions_buf + strlen(actions_buf) - 1;
- if (*end != '}')
- {
- /* No closing } */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid line (%lu): %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
- *end = '\0';
-
- /* trim any whitespace immediately inside {} */
- chomp(actions_buf);
-
- if (get_actions(actions_buf, alias_list, cur_action))
- {
- /* error */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid line (%lu): %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
- }
- }
- else if (mode == MODE_SETTINGS)
- {
- /*
- * Part of the {{settings}} block.
- * Ignore for now, but we may want to read & check permissions
- * when we go multi-user.
- */
- }
- else if (mode == MODE_DESCRIPTION)
- {
- /*
- * Part of the {{description}} block.
- * Ignore for now.
- */
- }
- else if (mode == MODE_ALIAS)
- {
- /*
- * define an alias
- */
- char actions_buf[BUFFER_SIZE];
- struct action_alias * new_alias;
-
- char * start = strchr(buf, '=');
- char * end = start;
-
- if ((start == NULL) || (start == buf))
- {
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid alias line (%lu): %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
-
- if ((new_alias = zalloc(sizeof(*new_alias))) == NULL)
- {
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': out of memory!",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
-
- /* Eat any the whitespace before the '=' */
- end--;
- while ((*end == ' ') || (*end == '\t'))
- {
- /*
- * we already know we must have at least 1 non-ws char
- * at start of buf - no need to check
- */
- end--;
- }
- end[1] = '\0';
-
- /* Eat any the whitespace after the '=' */
- start++;
- while ((*start == ' ') || (*start == '\t'))
- {
- start++;
- }
- if (*start == '\0')
- {
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid alias line (%lu): %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
-
- new_alias->name = strdup(buf);
-
- strcpy(actions_buf, start);
-
- if (get_actions(actions_buf, alias_list, new_alias->action))
- {
- /* error */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': invalid alias line (%lu): %s = %s",
- csp->config->actions_file[fileid], linenum, buf, start);
- return 1; /* never get here */
- }
-
- /* add to list */
- new_alias->next = alias_list;
- alias_list = new_alias;
- }
- else if (mode == MODE_ACTIONS)
- {
- /* it's a URL pattern */
-
- /* allocate a new node */
- if ((perm = zalloc(sizeof(*perm))) == NULL)
- {
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': out of memory!",
- csp->config->actions_file[fileid]);
- return 1; /* never get here */
- }
-
- /* Save flags */
- copy_action (perm->action, cur_action);
-
- /* Save the URL pattern */
- if (create_url_spec(perm->url, buf))
- {
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': line %lu: cannot create URL pattern from: %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
-
- /* add it to the list */
- last_perm->next = perm;
- last_perm = perm;
- }
- else if (mode == MODE_START_OF_FILE)
- {
- /* oops - please have a {} line as 1st line in file. */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': first needed line (%lu) is invalid: %s",
- csp->config->actions_file[fileid], linenum, buf);
- return 1; /* never get here */
- }
- else
- {
- /* How did we get here? This is impossible! */
- fclose(fp);
- log_error(LOG_LEVEL_FATAL,
- "can't load actions file '%s': INTERNAL ERROR - mode = %d",
- csp->config->actions_file[fileid], mode);
- return 1; /* never get here */
- }
- }
-
- fclose(fp);
-
- free_action(cur_action);
-
- free_alias_list(alias_list);
-
- /* the old one is now obsolete */
- if (current_actions_file[fileid])
- {
- current_actions_file[fileid]->unloader = unload_actions_file;
- }
-
- fs->next = files->next;
- files->next = fs;
- current_actions_file[fileid] = fs;
-
- csp->actions_list[fileid] = fs;
-
- return(0);
-
-}
-
-
-/*********************************************************************
- *
- * Function : actions_to_text
- *
- * Description : Converts a actionsfile entry from the internal
- * structurt into a text line. The output is split
- * into one line for each action with line continuation.
- *
- * Parameters :
- * 1 : action = The action to format.
- *
- * Returns : A string. Caller must free it.
- * NULL on out-of-memory error.
- *
- *********************************************************************/
-char * actions_to_text(struct action_spec *action)
-{
- unsigned mask = action->mask;
- unsigned add = action->add;
- char * result = strdup("");
- struct list_entry * lst;
-
- /* sanity - prevents "-feature +feature" */
- mask |= add;
-
-
-#define DEFINE_ACTION_BOOL(__name, __bit) \
- if (!(mask & __bit)) \
- { \
- string_append(&result, " -" __name " \\\n"); \
- } \
- else if (add & __bit) \
- { \
- string_append(&result, " +" __name " \\\n"); \
- }
-
-#define DEFINE_ACTION_STRING(__name, __bit, __index) \
- if (!(mask & __bit)) \
- { \
- string_append(&result, " -" __name " \\\n"); \
- } \
- else if (add & __bit) \
- { \
- string_append(&result, " +" __name "{"); \
- string_append(&result, action->string[__index]); \
- string_append(&result, "} \\\n"); \
- }
-
-#define DEFINE_ACTION_MULTI(__name, __index) \
- if (action->multi_remove_all[__index]) \
- { \
- string_append(&result, " -" __name " \\\n"); \
- } \
- else \
- { \
- lst = action->multi_remove[__index]->first; \
- while (lst) \
- { \
- string_append(&result, " -" __name "{"); \
- string_append(&result, lst->str); \
- string_append(&result, "} \\\n"); \
- lst = lst->next; \
- } \
- } \
- lst = action->multi_add[__index]->first; \
- while (lst) \
- { \
- string_append(&result, " +" __name "{"); \
- string_append(&result, lst->str); \
- string_append(&result, "} \\\n"); \
- lst = lst->next; \
- }
-
-#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-
- return result;
-}
-
-
-/*********************************************************************
- *
- * Function : actions_to_html
- *
- * Description : Converts a actionsfile entry from numeric form
- * ("mask" and "add") to a <br>-seperated HTML string
- * in which each action is linked to its chapter in
- * the user manual.
- *
- * Parameters :
- * 1 : csp = Client state (for config)
- * 2 : action = Action spec to be converted
- *
- * Returns : A string. Caller must free it.
- * NULL on out-of-memory error.
- *
- *********************************************************************/
-char * actions_to_html(struct client_state *csp,
- struct action_spec *action)
-{
- unsigned mask = action->mask;
- unsigned add = action->add;
- char * result = strdup("");
- struct list_entry * lst;
-
- /* sanity - prevents "-feature +feature" */
- mask |= add;
-
-
-#define DEFINE_ACTION_BOOL(__name, __bit) \
- if (!(mask & __bit)) \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- } \
- else if (add & __bit) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- }
-
-#define DEFINE_ACTION_STRING(__name, __bit, __index) \
- if (!(mask & __bit)) \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- } \
- else if (add & __bit) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- string_append(&result, "{"); \
- string_join(&result, html_encode(action->string[__index])); \
- string_append(&result, "}"); \
- }
-
-#define DEFINE_ACTION_MULTI(__name, __index) \
- if (action->multi_remove_all[__index]) \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- } \
- else \
- { \
- lst = action->multi_remove[__index]->first; \
- while (lst) \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- string_append(&result, "{"); \
- string_join(&result, html_encode(lst->str)); \
- string_append(&result, "}"); \
- lst = lst->next; \
- } \
- } \
- lst = action->multi_add[__index]->first; \
- while (lst) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- string_append(&result, "{"); \
- string_join(&result, html_encode(lst->str)); \
- string_append(&result, "}"); \
- lst = lst->next; \
- }
-
-#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-
- /* trim leading <br> */
- if (result && *result)
- {
- char * s = result;
- result = strdup(result + 5);
- free(s);
- }
-
- return result;
-}
-
-
-/*********************************************************************
- *
- * Function : current_actions_to_html
- *
- * Description : Converts a curren action spec to a <br> seperated HTML
- * text in which each action is linked to its chapter in
- * the user manual.
- *
- * Parameters :
- * 1 : csp = Client state (for config)
- * 2 : action = Current action spec to be converted
- *
- * Returns : A string. Caller must free it.
- * NULL on out-of-memory error.
- *
- *********************************************************************/
-char *current_action_to_html(struct client_state *csp,
- struct current_action_spec *action)
-{
- unsigned long flags = action->flags;
- char * result = strdup("");
- struct list_entry * lst;
-
-#define DEFINE_ACTION_BOOL(__name, __bit) \
- if (flags & __bit) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- } \
- else \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- }
-
-#define DEFINE_ACTION_STRING(__name, __bit, __index) \
- if (flags & __bit) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- string_append(&result, "{"); \
- string_join(&result, html_encode(action->string[__index])); \
- string_append(&result, "}"); \
- } \
- else \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- }
-
-#define DEFINE_ACTION_MULTI(__name, __index) \
- lst = action->multi[__index]->first; \
- if (lst == NULL) \
- { \
- string_append(&result, "\n<br>-"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- } \
- else \
- { \
- while (lst) \
- { \
- string_append(&result, "\n<br>+"); \
- string_join(&result, add_help_link(__name, csp->config)); \
- string_append(&result, "{"); \
- string_join(&result, html_encode(lst->str)); \
- string_append(&result, "}"); \
- lst = lst->next; \
- } \
- }
-
-#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-
- return result;
-}
+++ /dev/null
-#ifndef ACTIONS_H_INCLUDED
-#define ACTIONS_H_INCLUDED
-#define ACTIONS_H_VERSION "$Id: actions.h,v 1.11 2002/04/30 11:14:52 oes Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/actions.h,v $
- *
- * Purpose : Declares functions to work with actions files
- * Functions declared include: FIXME
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: actions.h,v $
- * Revision 1.11 2002/04/30 11:14:52 oes
- * Made csp the first parameter in *action_to_html
- *
- * Revision 1.10 2002/04/26 12:53:33 oes
- * - actions_to_html signature change
- * - current_action_to_text: renamed to current_action_to_html
- * and signature change
- *
- * Revision 1.9 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.8 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.7 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.6 2001/10/23 21:30:30 jongfoster
- * Adding error-checking to selected functions.
- *
- * Revision 1.5 2001/10/14 21:58:22 jongfoster
- * Adding support for the CGI-based editor:
- * - Exported get_actions()
- * - Added new function free_alias_list()
- * - Added support for {{settings}} and {{description}} blocks
- * in the actions file. They are currently ignored.
- * - Added restriction to only one {{alias}} block which must appear
- * first in the file, to simplify the editor's rewriting rules.
- * - Note that load_actions_file() is no longer used by the CGI-based
- * editor, but some of the other routines in this file are.
- *
- * Revision 1.4 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- * Revision 1.3 2001/09/14 00:17:32 jongfoster
- * Tidying up memory allocation. New function init_action().
- *
- * Revision 1.2 2001/07/29 19:01:11 jongfoster
- * Changed _FILENAME_H to FILENAME_H_INCLUDED.
- * Added forward declarations for needed structures.
- *
- * Revision 1.1 2001/05/31 21:16:46 jongfoster
- * Moved functions to process the action list into this new file.
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct action_spec;
-struct current_action_spec;
-struct client_state;
-
-
-
-/* This structure is used to hold user-defined aliases */
-struct action_alias
-{
- const char * name;
- struct action_spec action[1];
- struct action_alias * next;
-};
-
-
-extern jb_err get_actions (char *line,
- struct action_alias * alias_list,
- struct action_spec *cur_action);
-extern void free_alias_list(struct action_alias *alias_list);
-
-extern void init_action(struct action_spec *dest);
-extern void free_action(struct action_spec *src);
-extern jb_err merge_actions (struct action_spec *dest,
- const struct action_spec *src);
-extern jb_err copy_action (struct action_spec *dest,
- const struct action_spec *src);
-extern char * actions_to_text (struct action_spec *action);
-extern char * actions_to_html (struct client_state *csp,
- struct action_spec *action);
-extern void init_current_action (struct current_action_spec *dest);
-extern void free_current_action (struct current_action_spec *src);
-extern jb_err merge_current_action (struct current_action_spec *dest,
- const struct action_spec *src);
-extern char * current_action_to_html(struct client_state *csp,
- struct current_action_spec *action);
-
-extern jb_err get_action_token(char **line, char **name, char **value);
-extern void unload_actions_file(void *file_data);
-extern int load_actions_file(struct client_state *csp);
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-void unload_current_actions_file(void);
-#endif
-
-
-/* Revision control strings from this header and associated .c file */
-extern const char actions_rcs[];
-extern const char actions_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef ACTIONS_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
-
+++ /dev/null
-const char amiga_rcs[] = "$Id: amiga.c,v 1.8 2002/03/25 19:32:15 joergs Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/amiga.c,v $
- *
- * Purpose : Amiga-specific declarations.
- *
- * Copyright : 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.
- *
- * Revisions :
- * $Log: amiga.c,v $
- * Revision 1.8 2002/03/25 19:32:15 joergs
- * Name in version string changed from junkbuster to Privoxy.
- *
- * Revision 1.7 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.6 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.5 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.4 2001/10/07 15:35:13 oes
- * Replaced 6 boolean members of csp with one bitmap (csp->flags)
- *
- * Revision 1.3 2001/09/12 22:54:51 joergs
- * Stacksize of main thread increased.
- *
- * Revision 1.2 2001/05/23 00:13:58 joergs
- * AmigaOS support fixed.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:46 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#ifdef AMIGA
-
-#include <stdio.h>
-#include <signal.h>
-
-#include "project.h"
-
-const char amiga_h_rcs[] = AMIGA_H_VERSION;
-
-unsigned long __stack = 100*1024;
-static char ver[] = "$VER: Privoxy " __AMIGAVERSION__ " (" __AMIGADATE__ ")";
-struct Task *main_task = NULL;
-int childs = 0;
-
-void serve(struct client_state *csp);
-
-__saveds ULONG server_thread(void)
-{
- struct client_state *local_csp;
- struct UserData UserData;
- struct Task *me=FindTask(NULL);
-
- Wait(SIGF_SINGLE);
- local_csp=(struct client_state *)(me->tc_UserData);
- me->tc_UserData=&UserData;
- SocketBase=(APTR)OpenLibrary("bsdsocket.library",3);
- if(SocketBase)
- {
- SetErrnoPtr(&(UserData.eno),sizeof(int));
- local_csp->cfd=ObtainSocket(local_csp->cfd, AF_INET, SOCK_STREAM, 0);
- if(JB_INVALID_SOCKET!=local_csp->cfd)
- {
- Signal(main_task,SIGF_SINGLE);
- serve((struct client_state *) local_csp);
- } else {
- local_csp->flags &= ~CSP_FLAG_ACTIVE;
- Signal(main_task,SIGF_SINGLE);
- }
- CloseLibrary(SocketBase);
- } else {
- 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;
-static struct SignalSemaphore *memsemptr = NULL;
-static struct UserData GlobalUserData;
-
-void InitAmiga(void)
-{
- main_task = FindTask(NULL);
- main_task->tc_UserData = &GlobalUserData;
-
- if (((struct Library *)SysBase)->lib_Version < 39)
- {
- exit(RETURN_FAIL);
- }
-
- signal(SIGINT,SIG_IGN);
- SocketBase = (APTR)OpenLibrary("bsdsocket.library",3);
- if (!SocketBase)
- {
- fprintf(stderr, "Can't open bsdsocket.library V3+\n");
- exit(RETURN_ERROR);
- }
- SetErrnoPtr(&(GlobalUserData.eno),sizeof(int));
- InitSemaphore(&memsem);
- memsemptr = &memsem;
-
- olddir=CurrentDir(GetProgramDir());
- atexit(amiga_exit);
-}
-
-#ifdef __GNUC__
-#ifdef libnix
-/* multithreadingsafe libnix replacements */
-static void *memPool=NULL;
-
-void *malloc (size_t s)
-{
- ULONG *mem;
- LONG size = s;
-
- if (size<=0)
- {
- return NULL;
- }
- if (!memPool)
- {
- if (!(memPool=CreatePool(MEMF_ANY,32*1024,8*1024)))
- {
- return NULL;
- }
- }
- size += sizeof(ULONG) + MEM_BLOCKMASK;
- size &= ~MEM_BLOCKMASK;
- if (memsemptr)
- {
- ObtainSemaphore(memsemptr);
- }
- if ((mem=AllocPooled(memPool,size)))
- {
- *mem++=size;
- }
- if (memsemptr)
- {
- ReleaseSemaphore(memsemptr);
- }
- return mem;
-}
-
-void free (void *m)
-{
- ULONG *mem = m;
-
- if(mem && memPool)
- {
- ULONG size=*--mem;
-
- if (memsemptr)
- {
- ObtainSemaphore(memsemptr);
- }
- FreePooled(memPool,mem,size);
- if (memsemptr)
- {
- ReleaseSemaphore(memsemptr);
- }
- }
-}
-
-void *realloc (void *old, size_t ns)
-{
- void *new;
- LONG osize, *o = old;
- LONG nsize = ns;
-
- if (!old)
- {
- return malloc(nsize);
- }
- osize = (*(o-1)) - sizeof(ULONG);
- if (nsize <= osize)
- {
- return old;
- }
- if ((new = malloc(nsize)))
- {
- ULONG *n = new;
-
- osize >>= 2;
- while(osize--)
- {
- *n++ = *o++;
- }
- free(old);
- }
- return new;
-}
-
-void __memCleanUp (void)
-{
- if (memsemptr)
- {
- ObtainSemaphore(memsemptr);
- }
- if (memPool)
- {
- DeletePool(memPool);
- }
- if (memsemptr)
- {
- ReleaseSemaphore(memsemptr);
- }
-}
-
-#define ADD2LIST(a,b,c) asm(".stabs \"_" #b "\"," #c ",0,0,_" #a )
-#define ADD2EXIT(a,pri) ADD2LIST(a,__EXIT_LIST__,22); \
- asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri "+128")
-ADD2EXIT(__memCleanUp,-50);
-#elif !defined(ixemul)
-#error No libnix and no ixemul!?
-#endif /* libnix */
-#else
-#error Only GCC is supported, multithreading safe malloc/free required.
-#endif /* __GNUC__ */
-
-#endif /* def AMIGA */
+++ /dev/null
-#ifdef AMIGA
-#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: /cvsroot/ijbswa/current/amiga.h,v $
- *
- * Purpose : Amiga-specific declarations.
- *
- * Copyright : 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.
- *
- * Revisions :
- * $Log: amiga.h,v $
- * Revision 1.8 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.7 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.6 2001/10/13 12:46:08 joergs
- * Added #undef EINTR to avoid warnings
- *
- * Revision 1.5 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.4 2001/05/29 20:05:06 joergs
- * Fixed exit() macro not exiting if called before InitAmiga()
- * (junkbuster --help and --version).
- *
- * Revision 1.3 2001/05/25 21:53:27 jongfoster
- * Fixing indentation
- *
- * Revision 1.2 2001/05/23 00:13:58 joergs
- * AmigaOS support fixed.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:46 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#define _KERNEL
-#include <sys/socket.h>
-#undef _KERNEL
-
-#define __NOLIBBASE__
-#include <proto/socket.h>
-#undef __NOLIBBASE__
-
-#define __CONSTLIBBASEDECL__ const
-#define DEVICES_TIMER_H
-#include <proto/exec.h>
-#include <exec/tasks.h>
-#include <proto/dos.h>
-#include <dos/dostags.h>
-
-struct UserData
-{
- struct Library *sb;
- int eno;
-};
-
-#define SocketBase ((struct Library *)(((struct UserData *)(FindTask(NULL)->tc_UserData))->sb))
-#define errno (((struct UserData *)(FindTask(NULL)->tc_UserData))->eno)
-#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,NULL)
-#define inet_ntoa(x) Inet_NtoA(x.s_addr)
-
-extern int childs;
-extern struct Task *main_task;
-
-void InitAmiga(void);
-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); \
- } \
- } \
- else \
- { \
- exit(x); \
- } \
-}
-
-#undef EINTR
-#define EINTR 0
-
-#endif /* ndef AMIGA_H_INCLUDED */
-#endif /* def AMIGA */
+++ /dev/null
-const char cgi_rcs[] = "$Id: cgi.c,v 1.69 2002/05/14 21:28:40 oes Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgi.c,v $
- *
- * Purpose : Declares functions to intercept request, generate
- * html or gif answers, and to compose HTTP resonses.
- * This only contains the framework functions, the
- * actual handler functions are declared elsewhere.
- *
- * Functions declared include:
- *
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgi.c,v $
- * Revision 1.69 2002/05/14 21:28:40 oes
- * - Fixed add_help_link to link to the (now split) actions
- * part of the config chapter
- * - Renamed helplink export to actions-help-prefix
- *
- * Revision 1.68 2002/05/12 21:36:29 jongfoster
- * Correcting function comments
- *
- * Revision 1.67 2002/04/30 12:02:07 oes
- * Nit: updated a comment
- *
- * Revision 1.66 2002/04/26 18:32:57 jongfoster
- * Fixing a memory leak on error
- *
- * Revision 1.65 2002/04/26 12:53:51 oes
- * - New function add_help_link
- * - default_exports now exports links to the user manual
- * and a prefix for links into the config chapter
- *
- * Revision 1.64 2002/04/24 02:17:21 oes
- * - Better descriptions for CGIs
- * - Hide edit-actions, more shortcuts
- * - Moved get_char_param, get_string_param and get_number_param here
- * from cgiedit.c
- *
- * Revision 1.63 2002/04/15 19:06:43 jongfoster
- * Typos
- *
- * Revision 1.62 2002/04/10 19:59:46 jongfoster
- * Fixes to #include in templates:
- * - Didn't close main file if loading an included template fails.
- * - I'm paranoid and want to disallow "#include /etc/passwd".
- *
- * Revision 1.61 2002/04/10 13:37:48 oes
- * Made templates modular: template_load now recursive with max depth 1
- *
- * Revision 1.60 2002/04/08 20:50:25 swa
- * fixed JB spelling
- *
- * Revision 1.59 2002/04/05 15:51:51 oes
- * - added send-stylesheet CGI
- * - bugfix: error-pages now get correct request protocol
- * - fixed
- * - kludged CGI descriptions and menu not to break JS syntax
- *
- * Revision 1.58 2002/03/29 03:33:13 david__schmidt
- * Fix Mac OSX compiler warnings
- *
- * Revision 1.57 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.56 2002/03/24 17:50:46 jongfoster
- * Fixing compile error if actions file editor disabled
- *
- * Revision 1.55 2002/03/24 16:55:06 oes
- * Making GIF checkerboard transparent
- *
- * Revision 1.54 2002/03/24 16:18:15 jongfoster
- * Removing old logo
- *
- * Revision 1.53 2002/03/24 16:06:00 oes
- * Correct transparency for checkerboard PNG. Thanks, Magnus!
- *
- * Revision 1.52 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.51 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.50 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.49 2002/03/13 00:27:04 jongfoster
- * Killing warnings
- *
- * Revision 1.48 2002/03/08 17:47:07 jongfoster
- * Adding comments
- *
- * Revision 1.47 2002/03/08 16:41:33 oes
- * Added GIF images again
- *
- * Revision 1.46 2002/03/07 03:48:38 oes
- * - Changed built-in images from GIF to PNG
- * (with regard to Unisys patent issue)
- * - Added a 4x4 pattern PNG which is less intrusive
- * than the logo but also clearly marks the deleted banners
- *
- * Revision 1.45 2002/03/06 22:54:35 jongfoster
- * Automated function-comment nitpicking.
- *
- * Revision 1.44 2002/03/05 22:43:45 david__schmidt
- * - Better error reporting on OS/2
- * - Fix double-slash comment (oops)
- *
- * Revision 1.43 2002/03/05 21:33:45 david__schmidt
- * - Re-enable OS/2 building after new parms were added
- * - Fix false out of memory report when resolving CGI templates when no IP
- * address is available of failed attempt (a la no such domain)
- *
- * Revision 1.42 2002/01/21 00:33:20 jongfoster
- * Replacing strsav() with the safer string_append() or string_join().
- * Adding map_block_keep() to save a few bytes in the edit-actions-list HTML.
- * Adding missing html_encode() to error message generators.
- * Adding edit-actions-section-swap and many "shortcuts" to the list of CGIs.
- *
- * Revision 1.41 2002/01/17 20:56:22 jongfoster
- * Replacing hard references to the URL of the config interface
- * with #defines from project.h
- *
- * Revision 1.40 2002/01/09 14:26:46 oes
- * Added support for thread-safe gmtime_r call.
- *
- * Revision 1.39 2001/11/16 00:48:13 jongfoster
- * Fixing a compiler warning
- *
- * Revision 1.38 2001/11/13 00:31:21 jongfoster
- * - Adding new CGIs for use by non-JavaScript browsers:
- * edit-actions-url-form
- * edit-actions-add-url-form
- * edit-actions-remove-url-form
- * - Fixing make_menu()'s HTML generation - it now quotes the href parameter.
- * - Fixing || bug.
- *
- * Revision 1.37 2001/11/01 14:28:47 david__schmidt
- * Show enablement/disablement status in almost all templates.
- * There is a little trickiness here: apparent recursive resolution of
- * @if-enabled-then@ caused the toggle template to show status out-of-phase with
- * the actual enablement status. So a similar construct,
- * @if-enabled-display-then@, is used to resolve the status display on non-'toggle'
- * templates.
- *
- * Revision 1.36 2001/10/26 17:33:27 oes
- * marginal bugfix
- *
- * Revision 1.35 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle Junkbuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.34 2001/10/18 22:22:09 david__schmidt
- * Only show "Local support" on templates conditionally:
- * - if either 'admin-address' or 'proxy-info-url' are uncommented in config
- * - if not, no Local support section appears
- *
- * Revision 1.33 2001/10/14 22:28:41 jongfoster
- * Fixing stupid typo.
- *
- * Revision 1.32 2001/10/14 22:20:18 jongfoster
- * - Changes to CGI dispatching method to match CGI names exactly,
- * rather than doing a prefix match.
- * - No longer need to count the length of the CGI handler names by hand.
- * - Adding new handler for 404 error when disptching a CGI, if none of
- * the handlers match.
- * - Adding new handlers for CGI actionsfile editor.
- *
- * Revision 1.31 2001/10/10 10:56:39 oes
- * Failiure to load template now fatal. Before, the user got a hard-to-understand assertion failure from cgi.c
- *
- * Revision 1.30 2001/10/02 15:30:57 oes
- * Introduced show-request cgi
- *
- * Revision 1.29 2001/09/20 15:47:44 steudten
- *
- * Fix BUG: Modify int size to size_t size in fill_template()
- * - removes big trouble on machines where sizeof(int) != sizeof(size_t).
- *
- * Revision 1.28 2001/09/19 18:00:37 oes
- * - Deletef time() FIXME (Can't fail under Linux either, if
- * the argument is guaranteed to be in out address space,
- * which it is.)
- * - Fixed comments
- * - Pointer notation cosmetics
- * - Fixed a minor bug in template_fill(): Failiure of
- * pcrs_execute() now secure.
- *
- * Revision 1.27 2001/09/16 17:08:54 jongfoster
- * Moving simple CGI functions from cgi.c to new file cgisimple.c
- *
- * Revision 1.26 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- * Revision 1.25 2001/09/16 15:02:35 jongfoster
- * Adding i.j.b/robots.txt.
- * Inlining add_stats() since it's only ever called from one place.
- *
- * Revision 1.24 2001/09/16 11:38:01 jongfoster
- * Splitting fill_template() into 2 functions:
- * template_load() loads the file
- * template_fill() performs the PCRS regexps.
- * This is because the CGI edit interface has a "table row"
- * template which is used many times in the page - this
- * change means it's only loaded from disk once.
- *
- * Revision 1.23 2001/09/16 11:16:05 jongfoster
- * Better error handling in dispatch_cgi() and parse_cgi_parameters()
- *
- * Revision 1.22 2001/09/16 11:00:10 jongfoster
- * New function alloc_http_response, for symmetry with free_http_response
- *
- * Revision 1.21 2001/09/13 23:53:03 jongfoster
- * Support for both static and dynamically generated CGI pages.
- * Correctly setting Last-Modified: and Expires: HTTP headers.
- *
- * Revision 1.20 2001/09/13 23:40:36 jongfoster
- * (Cosmetic only) Indentation correction
- *
- * Revision 1.19 2001/09/13 23:31:25 jongfoster
- * Moving image data to cgi.c rather than cgi.h.
- *
- * Revision 1.18 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.17 2001/08/05 15:57:38 oes
- * Adapted finish_http_response to new list_to_text
- *
- * Revision 1.16 2001/08/01 21:33:18 jongfoster
- * Changes to fill_template() that reduce memory usage without having
- * an impact on performance. I also renamed some variables so as not
- * to clash with the C++ keywords "new" and "template".
- *
- * Revision 1.15 2001/08/01 21:19:22 jongfoster
- * Moving file version information to a separate CGI page.
- *
- * Revision 1.14 2001/08/01 00:19:03 jongfoster
- * New function: map_conditional() for an if-then-else syntax.
- * Changing to use new version of show_defines()
- *
- * Revision 1.13 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.12 2001/07/29 18:47:05 jongfoster
- * Adding missing #include "loadcfg.h"
- *
- * Revision 1.11 2001/07/18 17:24:37 oes
- * Changed to conform to new pcrs interface
- *
- * Revision 1.10 2001/07/13 13:53:13 oes
- * Removed all #ifdef PCRS and related code
- *
- * Revision 1.9 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.8 2001/06/29 13:21:46 oes
- * - Cosmetics: renamed and reordered functions, variables,
- * texts, improved comments etc
- *
- * - Removed ij_untrusted_url() The relevant
- * info is now part of the "untrusted" page,
- * which is generated by filters.c:trust_url()
- *
- * - Generators of content now call finish_http_response()
- * themselves, making jcc.c:chat() a little less
- * cluttered
- *
- * - Removed obsolete "Pragma: no-cache" from our headers
- *
- * - http_responses now know their head length
- *
- * - fill_template now uses the new interface to pcrs, so that
- * - long jobs (like whole files) no longer have to be assembled
- * in a fixed size buffer
- * - the new T (trivial) option is used, and the replacement may
- * contain Perl syntax backrefs without confusing pcrs
- *
- * - Introduced default_exports() which generates a set of exports
- * common to all CGIs and other content generators
- *
- * - Introduced convenience function map_block_killer()
- *
- * - Introduced convenience function make_menu()
- *
- * - Introduced CGI-like function error_response() which generates
- * the "No such domain" and "Connect failed" messages using the
- * CGI platform
- *
- * - cgi_show_url_info:
- * - adapted to new CGI features
- * - form and answers now generated from same template
- * - http:// prefix in URL now OK
- *
- * - cgi_show_status:
- * - adapted to new CGI features
- * - no longer uses csp->init_proxy_args
- *
- * - cgi_default:
- * - moved menu generation to make_menu()
- *
- * - add_stats now writes single export map entries instead
- * of a fixed string
- *
- * - Moved redirect_url() to filters.c
- *
- * - Fixed mem leak in free_http_response(), map_block_killer(),
- *
- * - Removed logentry from cancelled commit
- *
- * Revision 1.7 2001/06/09 10:51:58 jongfoster
- * Changing "show URL info" handler to new style.
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.6 2001/06/07 23:05:19 jongfoster
- * Removing code related to old forward and ACL files.
- *
- * Revision 1.5 2001/06/05 19:59:16 jongfoster
- * Fixing multiline character string (a GCC-only "feature"), and snprintf (it's _snprintf under VC++).
- *
- * Revision 1.4 2001/06/04 10:41:52 swa
- * show version string of cgi.h and cgi.c
- *
- * Revision 1.3 2001/06/03 19:12:16 oes
- * introduced new cgi handling
- *
- * No revisions before 1.3
- *
- **********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <limits.h>
-#include <assert.h>
-
-#ifdef _WIN32
-#define snprintf _snprintf
-#endif /* def _WIN32 */
-
-#include "project.h"
-#include "cgi.h"
-#include "list.h"
-#include "encode.h"
-#include "ssplit.h"
-#include "errlog.h"
-#include "miscutil.h"
-#include "cgisimple.h"
-#ifdef FEATURE_CGI_EDIT_ACTIONS
-#include "cgiedit.h"
-#endif /* def FEATURE_CGI_EDIT_ACTIONS */
-#include "loadcfg.h"
-/* loadcfg.h is for g_bToggleIJB only */
-
-const char cgi_h_rcs[] = CGI_H_VERSION;
-
-/*
- * List of CGI functions: name, handler, description
- * Note: Do NOT use single quotes in the description;
- * this will break the dynamic "blocked" template!
- */
-static const struct cgi_dispatcher cgi_dispatchers[] = {
- { "",
- cgi_default,
- "Privoxy main page" },
-#ifdef FEATURE_GRACEFUL_TERMINATION
- { "die",
- cgi_die,
- "<b>Shut down</b> - <em class=\"warning\">Do not deploy this build in a production environment, "
- "this is a one click Denial Of Service attack!!!</em>" },
-#endif
- { "show-status",
- cgi_show_status,
- "View & change the current configuration" },
- { "show-version",
- cgi_show_version,
- "View the source code version numbers" },
- { "show-request",
- cgi_show_request,
- "View the request headers." },
- { "show-url-info",
- cgi_show_url_info,
- "Look up which actions apply to a URL and why" },
-#ifdef FEATURE_CGI_EDIT_ACTIONS
- { "toggle",
- cgi_toggle,
- "Toggle Privoxy on or off" },
-
- { "edit-actions", /* Edit the actions list */
- cgi_edit_actions,
- NULL },
- { "eaa", /* Shortcut for edit-actions-add-url-form */
- cgi_edit_actions_add_url_form,
- NULL },
- { "eau", /* Shortcut for edit-actions-url-form */
- cgi_edit_actions_url_form,
- NULL },
- { "ear", /* Shortcut for edit-actions-remove-url-form */
- cgi_edit_actions_remove_url_form,
- NULL },
- { "eafu", /* Shortcut for edit-actions-for-url */
- cgi_edit_actions_for_url,
- NULL },
- { "eas", /* Shortcut for edit-actions-submit */
- cgi_edit_actions_submit,
- NULL },
- { "easa", /* Shortcut for edit-actions-section-add */
- cgi_edit_actions_section_add,
- NULL },
- { "easr", /* Shortcut for edit-actions-section-remove */
- cgi_edit_actions_section_remove,
- NULL },
- { "eass", /* Shortcut for edit-actions-section-swap */
- cgi_edit_actions_section_swap,
- NULL },
- { "edit-actions-for-url",
- cgi_edit_actions_for_url,
- NULL /* Edit the actions for (a) specified URL(s) */ },
- { "edit-actions-list",
- cgi_edit_actions_list,
- NULL /* Edit the actions list */ },
- { "edit-actions-submit",
- cgi_edit_actions_submit,
- NULL /* Change the actions for (a) specified URL(s) */ },
- { "edit-actions-url",
- cgi_edit_actions_url,
- NULL /* Change a URL pattern in the actionsfile */ },
- { "edit-actions-url-form",
- cgi_edit_actions_url_form,
- NULL /* Form to change a URL pattern in the actionsfile */ },
- { "edit-actions-add-url",
- cgi_edit_actions_add_url,
- NULL /* Add a URL pattern to the actionsfile */ },
- { "edit-actions-add-url-form",
- cgi_edit_actions_add_url_form,
- NULL /* Form to add a URL pattern to the actionsfile */ },
- { "edit-actions-remove-url",
- cgi_edit_actions_remove_url,
- NULL /* Remove a URL pattern from the actionsfile */ },
- { "edit-actions-remove-url-form",
- cgi_edit_actions_remove_url_form,
- NULL /* Form to remove a URL pattern from the actionsfile */ },
- { "edit-actions-section-add",
- cgi_edit_actions_section_add,
- NULL /* Remove a section from the actionsfile */ },
- { "edit-actions-section-remove",
- cgi_edit_actions_section_remove,
- NULL /* Remove a section from the actionsfile */ },
- { "edit-actions-section-swap",
- cgi_edit_actions_section_swap,
- NULL /* Swap two sections in the actionsfile */ },
-#endif /* def FEATURE_CGI_EDIT_ACTIONS */
- { "robots.txt",
- cgi_robots_txt,
- NULL /* Sends a robots.txt file to tell robots to go away. */ },
- { "send-banner",
- cgi_send_banner,
- NULL /* Send a built-in image */ },
- { "send-stylesheet",
- cgi_send_stylesheet,
- NULL /* Send templates/cgi-style.css */ },
- { "t",
- cgi_transparent_image,
- NULL /* Send a transparent image (short name) */ },
- { NULL, /* NULL Indicates end of list and default page */
- cgi_error_404,
- NULL /* Unknown CGI page */ }
-};
-
-
-/*
- * Bulit-in images for ad replacement
- *
- * Hint: You can encode your own images like this:
- * cat your-image | perl -e 'while (read STDIN, $c, 1) { printf("\\%.3o", unpack("C", $c)); }'
- */
-
-#ifdef FEATURE_NO_GIFS
-
-/*
- * Checkerboard pattern, as a PNG.
- */
-const char image_pattern_data[] =
- "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104"
- "\122\000\000\000\004\000\000\000\004\010\002\000\000\000\046"
- "\223\011\051\000\000\000\006\142\113\107\104\000\310\000\310"
- "\000\310\052\045\225\037\000\000\000\032\111\104\101\124\170"
- "\332\143\070\161\342\304\377\377\377\041\044\003\234\165\342"
- "\304\011\006\234\062\000\125\200\052\251\125\174\360\223\000"
- "\000\000\000\111\105\116\104\256\102\140\202";
-
-/*
- * 1x1 transparant PNG.
- */
-const char image_blank_data[] =
- "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104\122"
- "\000\000\000\004\000\000\000\004\010\006\000\000\000\251\361\236"
- "\176\000\000\000\007\164\111\115\105\007\322\003\013\020\073\070"
- "\013\025\036\203\000\000\000\011\160\110\131\163\000\000\013\022"
- "\000\000\013\022\001\322\335\176\374\000\000\000\004\147\101\115"
- "\101\000\000\261\217\013\374\141\005\000\000\000\033\111\104\101"
- "\124\170\332\143\070\161\342\304\207\377\377\377\347\302\150\006"
- "\144\016\210\146\040\250\002\000\042\305\065\221\270\027\131\110"
- "\000\000\000\000\111\105\116\104\256\102\140\202";
-#else
-
-/*
- * Checkerboard pattern, as a GIF.
- */
-const char image_pattern_data[] =
- "\107\111\106\070\071\141\004\000\004\000\200\000\000\310\310"
- "\310\377\377\377\041\376\016\111\040\167\141\163\040\141\040"
- "\142\141\156\156\145\162\000\041\371\004\001\012\000\001\000"
- "\054\000\000\000\000\004\000\004\000\000\002\005\104\174\147"
- "\270\005\000\073";
-
-/*
- * 1x1 transparant GIF.
- */
-const char image_blank_data[] =
- "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
- "\000!\371\004\001\000\000\000\000,\000\000\000\000\001"
- "\000\001\000\000\002\002D\001\000;";
-#endif
-
-const size_t image_pattern_length = sizeof(image_pattern_data) - 1;
-const size_t image_blank_length = sizeof(image_blank_data) - 1;
-
-
-static struct http_response cgi_error_memory_response[1];
-
-static struct http_response *dispatch_known_cgi(struct client_state * csp,
- const char * path);
-static struct map *parse_cgi_parameters(char *argstring);
-
-
-/*********************************************************************
- *
- * Function : dispatch_cgi
- *
- * Description : Checks if a request URL has either the magical
- * hostname CGI_SITE_1_HOST (usually http://p.p/) or
- * matches CGI_SITE_2_HOST CGI_SITE_2_PATH (usually
- * http://config.privoxy.org/). If so, it passes
- * the (rest of the) path onto dispatch_known_cgi, which
- * calls the relevant CGI handler function.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : http_response if match, NULL if nonmatch or handler fail
- *
- *********************************************************************/
-struct http_response *dispatch_cgi(struct client_state *csp)
-{
- const char *host = csp->http->host;
- const char *path = csp->http->path;
-
- /*
- * Should we intercept ?
- */
-
- /* Note: "example.com" and "example.com." are equivalent hostnames. */
-
- /* Either the host matches CGI_SITE_1_HOST ..*/
- if ( ( (0 == strcmpic(host, CGI_SITE_1_HOST))
- || (0 == strcmpic(host, CGI_SITE_1_HOST ".")))
- && (path[0] == '/') )
- {
- /* ..then the path will all be for us. Remove leading '/' */
- path++;
- }
- /* Or it's the host part CGI_SITE_2_HOST, and the path CGI_SITE_2_PATH */
- else if ( ( (0 == strcmpic(host, CGI_SITE_2_HOST ))
- || (0 == strcmpic(host, CGI_SITE_2_HOST ".")) )
- && (0 == strncmpic(path, CGI_SITE_2_PATH, strlen(CGI_SITE_2_PATH))) )
- {
- /* take everything following CGI_SITE_2_PATH */
- path += strlen(CGI_SITE_2_PATH);
- if (*path == '/')
- {
- /* skip the forward slash after CGI_SITE_2_PATH */
- path++;
- }
- else if (*path != '\0')
- {
- /*
- * wierdness: URL is /configXXX, where XXX is some string
- * Do *NOT* intercept.
- */
- return NULL;
- }
- }
- else
- {
- /* Not a CGI */
- return NULL;
- }
-
- /*
- * This is a CGI call.
- */
-
- return dispatch_known_cgi(csp, path);
-}
-
-
-/*********************************************************************
- *
- * Function : dispatch_known_cgi
- *
- * Description : Processes a CGI once dispatch_cgi has determined that
- * it matches one of the magic prefixes. Parses the path
- * as a cgi name plus query string, prepares a map that
- * maps CGI parameter names to their values, initializes
- * the http_response struct, and calls the relevant CGI
- * handler function.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : path = Path of CGI, with the CGI prefix removed.
- * Should not have a leading "/".
- *
- * Returns : http_response, or NULL on handler failure or out of
- * memory.
- *
- *********************************************************************/
-static struct http_response *dispatch_known_cgi(struct client_state * csp,
- const char * path)
-{
- const struct cgi_dispatcher *d;
- struct map *param_list;
- struct http_response *rsp;
- char *query_args_start;
- char *path_copy;
- jb_err err;
-
- if (NULL == (path_copy = strdup(path)))
- {
- return cgi_error_memory();
- }
-
- query_args_start = path_copy;
- while (*query_args_start && *query_args_start != '?')
- {
- query_args_start++;
- }
- if (*query_args_start == '?')
- {
- *query_args_start++ = '\0';
- }
-
- if (NULL == (param_list = parse_cgi_parameters(query_args_start)))
- {
- free(path_copy);
- return cgi_error_memory();
- }
-
-
- /*
- * At this point:
- * path_copy = CGI call name
- * param_list = CGI params, as map
- */
-
- /* Get mem for response or fail*/
- if (NULL == (rsp = alloc_http_response()))
- {
- free(path_copy);
- free_map(param_list);
- return cgi_error_memory();
- }
-
- log_error(LOG_LEVEL_GPC, "%s%s cgi call", csp->http->hostport, csp->http->path);
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 3",
- csp->ip_addr_str, csp->http->cmd);
-
- /* Find and start the right CGI function*/
- d = cgi_dispatchers;
- for (;;)
- {
- if ((d->name == NULL) || (strcmp(path_copy, d->name) == 0))
- {
- err = (d->handler)(csp, rsp, param_list);
- free(path_copy);
- free_map(param_list);
- if (err == JB_ERR_CGI_PARAMS)
- {
- err = cgi_error_bad_param(csp, rsp);
- }
- if (err && (err != JB_ERR_MEMORY))
- {
- /* Unexpected error! Shouldn't get here */
- log_error(LOG_LEVEL_ERROR, "Unexpected CGI error %d in top-level handler. Please file a bug report!", err);
- err = cgi_error_unknown(csp, rsp, err);
- }
- if (!err)
- {
- /* It worked */
- return finish_http_response(rsp);
- }
- else
- {
- /* Error in handler, probably out-of-memory */
- free_http_response(rsp);
- return cgi_error_memory();
- }
- }
- d++;
- }
-}
-
-
-/*********************************************************************
- *
- * Function : parse_cgi_parameters
- *
- * Description : Parse a URL-encoded argument string into name/value
- * pairs and store them in a struct map list.
- *
- * Parameters :
- * 1 : argstring = string to be parsed. Will be trashed.
- *
- * Returns : pointer to param list, or NULL if out of memory.
- *
- *********************************************************************/
-static struct map *parse_cgi_parameters(char *argstring)
-{
- char *p;
- char *vector[BUFFER_SIZE];
- int pairs, i;
- struct map *cgi_params;
-
- if (NULL == (cgi_params = new_map()))
- {
- return NULL;
- }
-
- pairs = ssplit(argstring, "&", vector, SZ(vector), 1, 1);
-
- for (i = 0; i < pairs; i++)
- {
- if ((NULL != (p = strchr(vector[i], '='))) && (*(p+1) != '\0'))
- {
- *p = '\0';
- if (map(cgi_params, url_decode(vector[i]), 0, url_decode(++p), 0))
- {
- free_map(cgi_params);
- return NULL;
- }
- }
- }
-
- return cgi_params;
-
-}
-
-
-/*********************************************************************
- *
- * Function : get_char_param
- *
- * Description : Get a single-character parameter passed to a CGI
- * function.
- *
- * Parameters :
- * 1 : parameters = map of cgi parameters
- * 2 : param_name = The name of the parameter to read
- *
- * Returns : Uppercase character on success, '\0' on error.
- *
- *********************************************************************/
-char get_char_param(const struct map *parameters,
- const char *param_name)
-{
- char ch;
-
- assert(parameters);
- assert(param_name);
-
- ch = *(lookup(parameters, param_name));
- if ((ch >= 'a') && (ch <= 'z'))
- {
- ch = ch - 'a' + 'A';
- }
-
- return ch;
-}
-
-
-/*********************************************************************
- *
- * Function : get_string_param
- *
- * Description : Get a string paramater, to be used as an
- * ACTION_STRING or ACTION_MULTI paramater.
- * Validates the input to prevent stupid/malicious
- * users from corrupting their action file.
- *
- * Parameters :
- * 1 : parameters = map of cgi parameters
- * 2 : param_name = The name of the parameter to read
- * 3 : pparam = destination for paramater. Allocated as
- * part of the map "parameters", so don't free it.
- * Set to NULL if not specified.
- *
- * Returns : JB_ERR_OK on success, or if the paramater
- * was not specified.
- * JB_ERR_MEMORY on out-of-memory.
- * JB_ERR_CGI_PARAMS if the paramater is not valid.
- *
- *********************************************************************/
-jb_err get_string_param(const struct map *parameters,
- const char *param_name,
- const char **pparam)
-{
- const char *param;
- const char *s;
- char ch;
-
- assert(parameters);
- assert(param_name);
- assert(pparam);
-
- *pparam = NULL;
-
- param = lookup(parameters, param_name);
- if (!*param)
- {
- return JB_ERR_OK;
- }
-
- if (strlen(param) >= CGI_PARAM_LEN_MAX)
- {
- /*
- * Too long.
- *
- * Note that the length limit is arbitrary, it just seems
- * sensible to limit it to *something*. There's no
- * technical reason for any limit at all.
- */
- return JB_ERR_CGI_PARAMS;
- }
-
- /* Check every character to see if it's legal */
- s = param;
- while ((ch = *s++) != '\0')
- {
- if ( ((unsigned char)ch < (unsigned char)' ')
- || (ch == '}') )
- {
- /* Probable hack attempt, or user accidentally used '}'. */
- return JB_ERR_CGI_PARAMS;
- }
- }
-
- /* Success */
- *pparam = param;
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : get_number_param
- *
- * Description : Get a non-negative integer from the parameters
- * passed to a CGI function.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : parameters = map of cgi parameters
- * 3 : name = Name of CGI parameter to read
- * 4 : pvalue = destination for value.
- * Set to -1 on error.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the parameter was not specified
- * or is not valid.
- *
- *********************************************************************/
-jb_err get_number_param(struct client_state *csp,
- const struct map *parameters,
- char *name,
- unsigned *pvalue)
-{
- const char *param;
- char ch;
- unsigned value;
-
- assert(csp);
- assert(parameters);
- assert(name);
- assert(pvalue);
-
- *pvalue = 0;
-
- param = lookup(parameters, name);
- if (!*param)
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- /* We don't use atoi because I want to check this carefully... */
-
- value = 0;
- while ((ch = *param++) != '\0')
- {
- if ((ch < '0') || (ch > '9'))
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- ch -= '0';
-
- /* Note:
- *
- * <limits.h> defines UINT_MAX
- *
- * (UINT_MAX - ch) / 10 is the largest number that
- * can be safely multiplied by 10 then have ch added.
- */
- if (value > ((UINT_MAX - (unsigned)ch) / 10U))
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- value = value * 10 + ch;
- }
-
- /* Success */
- *pvalue = value;
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : error_response
- *
- * Description : returns an http_response that explains the reason
- * why a request failed.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : templatename = Which template should be used for the answer
- * 3 : sys_err = system error number
- *
- * Returns : A http_response. If we run out of memory, this
- * will be cgi_error_memory().
- *
- *********************************************************************/
-struct http_response *error_response(struct client_state *csp,
- const char *templatename,
- int sys_err)
-{
- jb_err err;
- struct http_response *rsp;
- struct map * exports = default_exports(csp, NULL);
- if (exports == NULL)
- {
- return cgi_error_memory();
- }
-
- if (NULL == (rsp = alloc_http_response()))
- {
- free_map(exports);
- return cgi_error_memory();
- }
-
- err = map(exports, "host", 1, html_encode(csp->http->host), 0);
- if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0);
- if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0);
- if (!err) err = map(exports, "error", 1, html_encode_and_free_original(safe_strerror(sys_err)), 0);
- if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1);
- if (!err)
- {
- err = map(exports, "host-ip", 1, html_encode(csp->http->host_ip_addr_str), 0);
- if (err)
- {
- /* Some failures, like "404 no such domain", don't have an IP address. */
- err = map(exports, "host-ip", 1, html_encode(csp->http->host), 0);
- }
- }
-
-
- if (err)
- {
- free_map(exports);
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- if (!strcmp(templatename, "no-such-domain"))
- {
- rsp->status = strdup("404 No such domain");
- if (rsp->status == NULL)
- {
- free_map(exports);
- free_http_response(rsp);
- return cgi_error_memory();
- }
- }
- else if (!strcmp(templatename, "connect-failed"))
- {
- rsp->status = strdup("503 Connect failed");
- if (rsp->status == NULL)
- {
- free_map(exports);
- free_http_response(rsp);
- return cgi_error_memory();
- }
- }
-
- err = template_fill_for_cgi(csp, templatename, exports, rsp);
- if (err)
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- return finish_http_response(rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_init_error_messages
- *
- * Description : Call at the start of the program to initialize
- * the error message used by cgi_error_memory().
- *
- * Parameters : N/A
- *
- * Returns : N/A
- *
- *********************************************************************/
-void cgi_init_error_messages(void)
-{
- memset(cgi_error_memory_response, '\0', sizeof(*cgi_error_memory_response));
- cgi_error_memory_response->head =
- "HTTP/1.0 500 Internal Privoxy Error\r\n"
- "Content-Type: text/html\r\n"
- "\r\n";
- cgi_error_memory_response->body =
- "<html>\r\n"
- "<head><title>500 Internal Privoxy Error</title></head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy <b>ran out of memory</b> while processing your request.</p>\r\n"
- "<p>Please contact your proxy administrator, or try again later</p>\r\n"
- "</body>\r\n"
- "</html>\r\n";
-
- cgi_error_memory_response->head_length =
- strlen(cgi_error_memory_response->head);
- cgi_error_memory_response->content_length =
- strlen(cgi_error_memory_response->body);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_memory
- *
- * Description : Called if a CGI function runs out of memory.
- * Returns a statically-allocated error response.
- *
- * Parameters : N/A
- *
- * Returns : http_response data structure for output. This is
- * statically allocated, for obvious reasons.
- *
- *********************************************************************/
-struct http_response *cgi_error_memory(void)
-{
- /* assert that it's been initialized. */
- assert(cgi_error_memory_response->head);
-
- return cgi_error_memory_response;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_no_template
- *
- * Description : Almost-CGI function that is called if a template
- * cannot be loaded. Note this is not a true CGI,
- * it takes a template name rather than a map of
- * parameters.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : template_name = Name of template that could not
- * be loaded.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_no_template(struct client_state *csp,
- struct http_response *rsp,
- const char *template_name)
-{
- static const char status[] =
- "500 Internal Privoxy Error";
- static const char body_prefix[] =
- "<html>\r\n"
- "<head><title>500 Internal Privoxy Error</title></head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy encountered an error while processing your request:</p>\r\n"
- "<p><b>Could not load template file <code>";
- static const char body_suffix[] =
- "</code> or one of it's included components.</b></p>\r\n"
- "<p>Please contact your proxy administrator.</p>\r\n"
- "<p>If you are the proxy administrator, please put the required file(s)"
- "in the <code><i>(confdir)</i>/templates</code> directory. The "
- "location of the <code><i>(confdir)</i></code> directory "
- "is specified in the main Privoxy <code>config</code> "
- "file. (It's typically the Privoxy install directory"
-#ifndef _WIN32
- ", or <code>/etc/privoxy/</code>"
-#endif /* ndef _WIN32 */
- ").</p>\r\n"
- "</body>\r\n"
- "</html>\r\n";
-
- assert(csp);
- assert(rsp);
- assert(template_name);
-
- /* Reset rsp, if needed */
- freez(rsp->status);
- freez(rsp->head);
- freez(rsp->body);
- rsp->content_length = 0;
- rsp->head_length = 0;
- rsp->is_static = 0;
-
- rsp->body = malloc(strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1);
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
- strcpy(rsp->body, body_prefix);
- strcat(rsp->body, template_name);
- strcat(rsp->body, body_suffix);
-
- rsp->status = strdup(status);
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_unknown
- *
- * Description : Almost-CGI function that is called if an unexpected
- * error occurs in the top-level CGI dispatcher.
- * In this context, "unexpected" means "anything other
- * than JB_ERR_MEMORY or JB_ERR_CGI_PARAMS" - CGIs are
- * expected to handle all other errors internally,
- * since they can give more relavent error messages
- * that way.
- *
- * Note this is not a true CGI, it takes an error
- * code rather than a map of parameters.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : error_to_report = Error code to report.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_unknown(struct client_state *csp,
- struct http_response *rsp,
- jb_err error_to_report)
-{
- static const char status[] =
- "500 Internal Privoxy Error";
- static const char body_prefix[] =
- "<html>\r\n"
- "<head><title>500 Internal Privoxy Error</title></head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy encountered an error while processing your request:</p>\r\n"
- "<p><b>Unexpected internal error: ";
- static const char body_suffix[] =
- "</b></p>\r\n"
- "<p>Please "
- "<a href=\"http://sourceforge.net/tracker/?group_id=11118&atid=111118\">"
- "file a bug report</a>.</p>\r\n"
- "</body>\r\n"
- "</html>\r\n";
- char errnumbuf[30];
- assert(csp);
- assert(rsp);
-
- /* Reset rsp, if needed */
- freez(rsp->status);
- freez(rsp->head);
- freez(rsp->body);
- rsp->content_length = 0;
- rsp->head_length = 0;
- rsp->is_static = 0;
-
- sprintf(errnumbuf, "%d", error_to_report);
-
- rsp->body = malloc(strlen(body_prefix) + strlen(errnumbuf) + strlen(body_suffix) + 1);
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
- strcpy(rsp->body, body_prefix);
- strcat(rsp->body, errnumbuf);
- strcat(rsp->body, body_suffix);
-
- rsp->status = strdup(status);
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_bad_param
- *
- * Description : CGI function that is called if the parameters
- * (query string) for a CGI were wrong.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_bad_param(struct client_state *csp,
- struct http_response *rsp)
-{
- struct map *exports;
-
- assert(csp);
- assert(rsp);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-bad-param", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : add_help_link
- *
- * Description : Produce a copy of the string given as item,
- * embedded in an HTML link to its corresponding
- * section (item name in uppercase) in the actions
- * chapter of the user manual, (whose URL is given in
- * the config and defaults to our web site).
- *
- * FIXME: I currently only work for actions, and would
- * like to be generalized for other topics.
- *
- * Parameters :
- * 1 : item = item (will NOT be free()d.)
- * It is assumed to be HTML-safe.
- * 2 : config = The current configuration.
- *
- * Returns : String with item embedded in link, or NULL on
- * out-of-memory
- *
- *********************************************************************/
-char *add_help_link(const char *item,
- struct configuration_spec *config)
-{
- char *result;
-
- if (!item) return NULL;
-
- result = strdup("<a href=\"");
- string_append(&result, config->usermanual);
- string_append(&result, ACTIONS_HELP_PREFIX);
- string_join (&result, string_toupper(item));
- string_append(&result, "\">");
- string_append(&result, item);
- string_append(&result, "</a> ");
-
- return result;
-}
-
-
-/*********************************************************************
- *
- * Function : get_http_time
- *
- * Description : Get the time in a format suitable for use in a
- * HTTP header - e.g.:
- * "Sun, 06 Nov 1994 08:49:37 GMT"
- *
- * Parameters :
- * 1 : time_offset = Time returned will be current time
- * plus this number of seconds.
- * 2 : buf = Destination for result. Must be long enough
- * to hold 29 characters plus a trailing zero.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void get_http_time(int time_offset, char *buf)
-{
- static const char day_names[7][4] =
- { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
- static const char month_names[12][4] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- struct tm *t;
- time_t current_time;
-
- assert(buf);
-
- time(¤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 <name>, i.e. a substitution of the regex
- * "if-<name>-start.*if-<name>-end" to the given
- * export list.
- *
- * Parameters :
- * 1 : exports = map to extend
- * 2 : name = name of conditional block
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err map_block_killer(struct map *exports, const char *name)
-{
- char buf[1000]; /* Will do, since the names are hardwired */
-
- assert(exports);
- assert(name);
- assert(strlen(name) < 490);
-
- snprintf(buf, 1000, "if-%s-start.*if-%s-end", name, name);
- return map(exports, buf, 1, "", 1);
-}
-
-
-/*********************************************************************
- *
- * Function : map_block_keep
- *
- * Description : Convenience function. Removes the markers used
- * by map-block-killer, to save a few bytes.
- * i.e. removes "@if-<name>-start@" and "@if-<name>-end@"
- *
- * Parameters :
- * 1 : exports = map to extend
- * 2 : name = name of conditional block
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err map_block_keep(struct map *exports, const char *name)
-{
- jb_err err;
- char buf[500]; /* Will do, since the names are hardwired */
-
- assert(exports);
- assert(name);
- assert(strlen(name) < 490);
-
- snprintf(buf, 500, "if-%s-start", name);
- err = map(exports, buf, 1, "", 1);
-
- if (err)
- {
- return err;
- }
-
- snprintf(buf, 500, "if-%s-end", name);
- return map(exports, buf, 1, "", 1);
-}
-
-
-/*********************************************************************
- *
- * Function : map_conditional
- *
- * Description : Convenience function.
- * Adds an "if-then-else" for the conditional HTML-template
- * block <name>, i.e. a substitution of the form:
- * @if-<name>-then@
- * True text
- * @else-not-<name>@
- * False text
- * @endif-<name>@
- *
- * The control structure and one of the alternatives
- * will be hidden.
- *
- * Parameters :
- * 1 : exports = map to extend
- * 2 : name = name of conditional block
- * 3 : choose_first = nonzero for first, zero for second.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err map_conditional(struct map *exports, const char *name, int choose_first)
-{
- char buf[1000]; /* Will do, since the names are hardwired */
- jb_err err;
-
- assert(exports);
- assert(name);
- assert(strlen(name) < 480);
-
- snprintf(buf, 1000, (choose_first
- ? "else-not-%s@.*@endif-%s"
- : "if-%s-then@.*@else-not-%s"),
- name, name);
-
- err = map(exports, buf, 1, "", 1);
- if (err)
- {
- return err;
- }
-
- snprintf(buf, 1000, (choose_first ? "if-%s-then" : "endif-%s"), name);
- return map(exports, buf, 1, "", 1);
-}
-
-
-/*********************************************************************
- *
- * Function : make_menu
- *
- * Description : Returns an HTML-formatted menu of the available
- * unhidden CGIs, excluding the one given in <self>
- *
- * Parameters : self = name of CGI to leave out, can be NULL for
- * complete listing.
- *
- * Returns : menu string, or NULL on out-of-memory error.
- *
- *********************************************************************/
-char *make_menu(const char *self)
-{
- const struct cgi_dispatcher *d;
- char *result = strdup("");
-
- if (self == NULL)
- {
- self = "NO-SUCH-CGI!";
- }
-
- /* List available unhidden CGI's and export as "other-cgis" */
- for (d = cgi_dispatchers; d->name; d++)
- {
- if (d->description && strcmp(d->name, self))
- {
- string_append(&result, "<li><a href=\"" CGI_PREFIX);
- string_append(&result, d->name);
- string_append(&result, "\">");
- string_append(&result, d->description);
- string_append(&result, "</a></li>");
- }
- }
-
- return result;
-}
-
-
-/*********************************************************************
- *
- * Function : dump_map
- *
- * Description : HTML-dump a map for debugging (as table)
- *
- * Parameters :
- * 1 : the_map = map to dump
- *
- * Returns : string with HTML
- *
- *********************************************************************/
-char *dump_map(const struct map *the_map)
-{
- struct map_entry *cur_entry;
- char *ret = strdup("");
-
- string_append(&ret, "<table>\n");
-
- for (cur_entry = the_map->first;
- (cur_entry != NULL) && (ret != NULL);
- cur_entry = cur_entry->next)
- {
- string_append(&ret, "<tr><td><b>");
- string_join (&ret, html_encode(cur_entry->name));
- string_append(&ret, "</b></td><td>");
- string_join (&ret, html_encode(cur_entry->value));
- string_append(&ret, "</td></tr>\n");
- }
-
- string_append(&ret, "</table>\n");
- return ret;
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef CGI_H_INCLUDED
-#define CGI_H_INCLUDED
-#define CGI_H_VERSION "$Id: cgi.h,v 1.28 2002/04/26 12:54:03 oes Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgi.h,v $
- *
- * Purpose : Declares functions to intercept request, generate
- * html or gif answers, and to compose HTTP resonses.
- *
- * Functions declared include:
- *
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgi.h,v $
- * Revision 1.28 2002/04/26 12:54:03 oes
- * New function add_help_link
- *
- * Revision 1.27 2002/04/24 02:16:51 oes
- * Moved get_char_param, get_string_param and get_number_param here from cgiedit.c
- *
- * Revision 1.26 2002/04/10 13:38:35 oes
- * load_template signature changed
- *
- * Revision 1.25 2002/04/08 20:50:25 swa
- * fixed JB spelling
- *
- * Revision 1.24 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.23 2002/03/24 16:18:15 jongfoster
- * Removing old logo
- *
- * Revision 1.22 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.21 2002/03/07 03:48:38 oes
- * - Changed built-in images from GIF to PNG
- * (with regard to Unisys patent issue)
- * - Added a 4x4 pattern PNG which is less intrusive
- * than the logo but also clearly marks the deleted banners
- *
- * Revision 1.20 2002/03/04 17:53:22 oes
- * Fixed compiled warning
- *
- * Revision 1.19 2002/01/21 00:33:52 jongfoster
- * Adding map_block_keep() to save a few bytes in the edit-actions-list HTML.
- *
- * Revision 1.18 2001/11/16 00:46:31 jongfoster
- * Fixing compiler warnings
- *
- * Revision 1.17 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle Junkbuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.16 2001/09/16 17:08:54 jongfoster
- * Moving simple CGI functions from cgi.c to new file cgisimple.c
- *
- * Revision 1.15 2001/09/16 15:02:35 jongfoster
- * Adding i.j.b/robots.txt.
- * Inlining add_stats() since it's only ever called from one place.
- *
- * Revision 1.14 2001/09/16 11:38:02 jongfoster
- * Splitting fill_template() into 2 functions:
- * template_load() loads the file
- * template_fill() performs the PCRS regexps.
- * This is because the CGI edit interface has a "table row"
- * template which is used many times in the page - this
- * change means it's only loaded from disk once.
- *
- * Revision 1.13 2001/09/16 11:00:10 jongfoster
- * New function alloc_http_response, for symmetry with free_http_response
- *
- * Revision 1.12 2001/09/13 23:31:25 jongfoster
- * Moving image data to cgi.c rather than cgi.h.
- *
- * Revision 1.11 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.10 2001/08/01 21:19:22 jongfoster
- * Moving file version information to a separate CGI page.
- *
- * Revision 1.9 2001/08/01 00:17:54 jongfoster
- * Adding prototype for map_conditional
- *
- * Revision 1.8 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.7 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.6 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.5 2001/06/29 13:22:44 oes
- * - Cleaned up
- * - Added new functions: default_exports(), make_menu(),
- * error_response() etc, ranamed others and changed
- * param and return types.
- * - Removed HTTP/HTML snipplets
- * - Removed logentry from cancelled commit
- *
- * Revision 1.4 2001/06/09 10:50:58 jongfoster
- * Changing "show URL info" handler to new style.
- * Adding "extern" to some function prototypes.
- *
- * Revision 1.3 2001/06/03 19:12:16 oes
- * introduced new cgi handling
- *
- * No revisions before 1.3
- *
- **********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Main dispatch function
- */
-extern struct http_response *dispatch_cgi(struct client_state *csp);
-
-/* Not exactly a CGI */
-extern struct http_response * error_response(struct client_state *csp,
- const char *templatename,
- int err);
-
-/*
- * CGI support functions
- */
-extern struct http_response * alloc_http_response(void);
-extern void free_http_response(struct http_response *rsp);
-
-extern struct http_response *finish_http_response(struct http_response *rsp);
-
-extern struct map * default_exports(const struct client_state *csp, const char *caller);
-
-extern jb_err map_block_killer (struct map *exports, const char *name);
-extern jb_err map_block_keep (struct map *exports, const char *name);
-extern jb_err map_conditional (struct map *exports, const char *name, int choose_first);
-
-extern jb_err template_load(struct client_state *csp, char ** template_ptr,
- const char *templatename, int recursive);
-extern jb_err template_fill(char ** template_ptr, const struct map *exports);
-extern jb_err template_fill_for_cgi(struct client_state *csp,
- const char *templatename,
- struct map *exports,
- struct http_response *rsp);
-
-extern void cgi_init_error_messages(void);
-extern struct http_response *cgi_error_memory(void);
-extern jb_err cgi_error_no_template(struct client_state *csp,
- struct http_response *rsp,
- const char *template_name);
-extern jb_err cgi_error_bad_param(struct client_state *csp,
- struct http_response *rsp);
-jb_err cgi_error_unknown(struct client_state *csp,
- struct http_response *rsp,
- jb_err error_to_report);
-
-extern jb_err get_number_param(struct client_state *csp,
- const struct map *parameters,
- char *name,
- unsigned *pvalue);
-extern jb_err get_string_param(const struct map *parameters,
- const char *param_name,
- const char **pparam);
-extern char get_char_param(const struct map *parameters,
- const char *param_name);
-
-/*
- * Text generators
- */
-extern void get_http_time(int time_offset, char * buf);
-extern char *add_help_link(const char *item, struct configuration_spec *config);
-extern char *make_menu(const char *self);
-extern char *dump_map(const struct map *the_map);
-
-/*
- * Ad replacement images
- */
-extern const char image_pattern_data[];
-extern const size_t image_pattern_length;
-extern const char image_blank_data[];
-extern const size_t image_blank_length;
-
-/* Revision control strings from this header and associated .c file */
-extern const char cgi_rcs[];
-extern const char cgi_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef CGI_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.40 2002/05/19 11:34:35 jongfoster Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $
- *
- * Purpose : CGI-based actionsfile editor.
- *
- * Functions declared include: cgi_edit_*
- *
- * NOTE: The CGIs in this file use parameter names
- * such as "f" and "s" which are really *BAD* choices.
- * However, I'm trying to save bytes in the
- * edit-actions-list HTML page - the standard actions
- * file generated a 550kbyte page, which is ridiculous.
- *
- * Stick to the short names in this file for consistency.
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgiedit.c,v $
- * Revision 1.40 2002/05/19 11:34:35 jongfoster
- * Handling read-only actions files better - report the actual
- * error, not "Out of memory"!
- *
- * Bug report:
- * http://sourceforge.net/tracker/index.php?func=detail
- * &aid=557905&group_id=11118&atid=111118
- *
- * Revision 1.39 2002/05/12 21:39:15 jongfoster
- * - Adding Doxygen-style comments to structures and #defines.
- * - Correcting function comments
- *
- * Revision 1.38 2002/05/03 23:00:38 jongfoster
- * Support for templates for "standard actions" buttons.
- * See bug #549871
- *
- * Revision 1.37 2002/04/30 11:14:52 oes
- * Made csp the first parameter in *action_to_html
- *
- * Revision 1.36 2002/04/26 21:53:30 jongfoster
- * Fixing a memory leak. (Near, but not caused by, my earlier commit).
- *
- * Revision 1.35 2002/04/26 21:50:02 jongfoster
- * Honouring default exports in edit-actions-for-url-filter template.
- *
- * Revision 1.34 2002/04/26 12:54:17 oes
- * Adaptions to changes in actions.c
- *
- * Revision 1.33 2002/04/24 02:17:47 oes
- * - Moved get_char_param, get_string_param and get_number_param to cgi.c
- * - Comments
- * - Activated Jon's code for editing multiple AFs
- * - cgi_edit_list_actions now provides context-sensitive
- * help, looks up all action sets from standard.action and
- * makes buttons for them in the catchall section
- * - cgi_edit_action_submit now honors a p parameter, looks up
- * the corresponding action set, and sets the catchall pattern's
- * actions accordingly.
- *
- * Revision 1.32 2002/04/19 16:55:31 jongfoster
- * Fixing newline problems. If we do our own text file newline
- * mangling, we don't want the library to do any, so we need to
- * open the files in *binary* mode.
- *
- * Revision 1.31 2002/04/18 19:21:08 jongfoster
- * Added code to detect "conventional" action files, that start
- * with a set of actions for all URLs (the pattern "/").
- * These are special-cased in the "edit-actions-list" CGI, so
- * that a special UI can be written for them.
- *
- * Revision 1.30 2002/04/10 13:38:35 oes
- * load_template signature changed
- *
- * Revision 1.29 2002/04/08 16:59:08 oes
- * Fixed comment
- *
- * Revision 1.28 2002/03/27 12:30:29 oes
- * Deleted unsused variable
- *
- * Revision 1.27 2002/03/26 23:06:04 jongfoster
- * Removing duplicate @ifs on the toggle page
- *
- * Revision 1.26 2002/03/26 22:59:17 jongfoster
- * Fixing /toggle to display status consistently.
- *
- * Revision 1.25 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.24 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.23 2002/03/24 13:32:41 swa
- * name change related issues
- *
- * Revision 1.22 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.21 2002/03/22 18:02:48 jongfoster
- * Fixing remote toggle
- *
- * Revision 1.20 2002/03/16 20:28:34 oes
- * Added descriptions to the filters so users will know what they select in the cgi editor
- *
- * Revision 1.19 2002/03/16 18:38:14 jongfoster
- * Stopping stupid or malicious users from breaking the actions
- * file using the web-based editor.
- *
- * Revision 1.18 2002/03/16 14:57:44 jongfoster
- * Full support for enabling/disabling modular filters.
- *
- * Revision 1.17 2002/03/16 14:26:42 jongfoster
- * First version of modular filters support - READ ONLY!
- * Fixing a double-free bug in the out-of-memory handling in map_radio().
- *
- * Revision 1.16 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.15 2002/03/06 22:54:35 jongfoster
- * Automated function-comment nitpicking.
- *
- * Revision 1.14 2002/03/05 00:24:51 jongfoster
- * Patch to always edit the current actions file.
- *
- * Revision 1.13 2002/03/04 02:07:59 david__schmidt
- * Enable web editing of actions file on OS/2 (it had been broken all this time!)
- *
- * Revision 1.12 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.11 2002/01/23 01:03:31 jongfoster
- * Fixing gcc [CygWin] compiler warnings
- *
- * Revision 1.10 2002/01/23 00:22:59 jongfoster
- * Adding new function cgi_edit_actions_section_swap(), to reorder
- * the actions file.
- *
- * Adding get_url_spec_param() to get a validated URL pattern.
- *
- * Moving edit_read_line() out of this file and into loaders.c.
- *
- * Adding missing html_encode() to many CGI functions.
- *
- * Moving the functions that #include actionlist.h to the end of the file,
- * because the Visual C++ 97 debugger gets extremely confused if you try
- * to debug any code that comes after them in the file.
- *
- * Major optimizations in cgi_edit_actions_list() to reduce the size of
- * the generated HTML (down 40% from 550k to 304k), with major side-effects
- * throughout the editor and templates. In particular, the length of the
- * URLs throughout the editor has been drastically reduced, by cutting
- * paramater names down to 1 character and CGI names down to 3-4
- * characters, by removing all non-essential CGI paramaters even at the
- * expense of having to re-read the actions file for the most trivial
- * page, and by using relative rather than absolute URLs. This means
- * that this (typical example):
- *
- * <a href="http://ijbswa.sourceforge.net/config/edit-actions-url-form?
- * filename=ijb&ver=1011487572&section=12&pattern=13
- * &oldval=www.oesterhelt.org%2Fdeanimate-demo">
- *
- * is now this:
- *
- * <a href="eau?f=ijb&v=1011487572&p=13">
- *
- * Revision 1.9 2002/01/17 20:56:22 jongfoster
- * Replacing hard references to the URL of the config interface
- * with #defines from project.h
- *
- * Revision 1.8 2001/11/30 23:35:51 jongfoster
- * Renaming actionsfile to ijb.action
- *
- * Revision 1.7 2001/11/13 00:28:24 jongfoster
- * - Renaming parameters from edit-actions-for-url so that they only
- * contain legal JavaScript characters. If we wanted to write
- * JavaScript that worked with Netscape 4, this is nessacery.
- * (Note that at the moment the JavaScript doesn't actually work
- * with Netscape 4, but now this is purely a template issue, not
- * one affecting code).
- * - Adding new CGIs for use by non-JavaScript browsers:
- * edit-actions-url-form
- * edit-actions-add-url-form
- * edit-actions-remove-url-form
- * - Fixing || bug.
- *
- * Revision 1.6 2001/10/29 03:48:09 david__schmidt
- * OS/2 native needed a snprintf() routine. Added one to miscutil, brackedted
- * by and __OS2__ ifdef.
- *
- * Revision 1.5 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.4 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle JunkBuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.3 2001/10/14 22:12:49 jongfoster
- * New version of CGI-based actionsfile editor.
- * Major changes, including:
- * - Completely new file parser and file output routines
- * - edit-actions CGI renamed edit-actions-for-url
- * - All CGIs now need a filename parameter, except for...
- * - New CGI edit-actions which doesn't need a filename,
- * to allow you to start the editor up.
- * - edit-actions-submit now works, and now automatically
- * redirects you back to the main edit-actions-list handler.
- *
- * Revision 1.2 2001/09/16 17:05:14 jongfoster
- * Removing unused #include showarg.h
- *
- * Revision 1.1 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- *
- **********************************************************************/
-\f
-
-#include "config.h"
-
-/*
- * FIXME: Following includes copied from cgi.c - which are actually needed?
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/stat.h>
-
-#ifdef _WIN32
-#define snprintf _snprintf
-#endif /* def _WIN32 */
-
-#include "project.h"
-#include "cgi.h"
-#include "cgiedit.h"
-#include "cgisimple.h"
-#include "list.h"
-#include "encode.h"
-#include "actions.h"
-#include "miscutil.h"
-#include "errlog.h"
-#include "loaders.h"
-#include "loadcfg.h"
-/* loadcfg.h is for g_bToggleIJB only */
-#include "urlmatch.h"
-
-const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION;
-
-
-#ifdef FEATURE_CGI_EDIT_ACTIONS
-
-/**
- * A line in an editable_file.
- */
-struct file_line
-{
- /** Next entry in the linked list */
- struct file_line * next;
-
- /** The raw data, to write out if this line is unmodified. */
- char * raw;
-
- /** Comments and/or whitespace to put before this line if it's modified
- and then written out. */
- char * prefix;
-
- /** The actual data, as a string. Line continuation and comment removal
- are performed on the data read from file before it's stored here, so
- it will be a single line of data. */
- char * unprocessed;
-
- /** The type of data on this line. One of the FILE_LINE_xxx constants. */
- int type;
-
- /** The actual data, processed into some sensible data type. */
- union
- {
-
- /** An action specification. */
- struct action_spec action[1];
-
- /** A name=value pair. */
- struct
- {
-
- /** The name in the name=value pair. */
- char * name;
-
- /** The value in the name=value pair, as a string. */
- char * svalue;
-
- /** The value in the name=value pair, as an integer. */
- int ivalue;
-
- } setting;
-
- /* Add more data types here... e.g.
-
-
- struct url_spec url[1];
-
- struct
- {
- struct action_spec action[1];
- const char * name;
- } alias;
-
- */
-
- } data;
-
-};
-
-/** This file_line has not been processed yet. */
-#define FILE_LINE_UNPROCESSED 1
-
-/** This file_line is blank. Can only appear at the end of a file, due to
- the way the parser works. */
-#define FILE_LINE_BLANK 2
-
-/** This file_line says {{alias}}. */
-#define FILE_LINE_ALIAS_HEADER 3
-
-/** This file_line defines an alias. */
-#define FILE_LINE_ALIAS_ENTRY 4
-
-/** This file_line defines an {action}. */
-#define FILE_LINE_ACTION 5
-
-/** This file_line specifies a URL pattern. */
-#define FILE_LINE_URL 6
-
-/** This file_line says {{settings}}. */
-#define FILE_LINE_SETTINGS_HEADER 7
-
-/** This file_line is in a {{settings}} block. */
-#define FILE_LINE_SETTINGS_ENTRY 8
-
-/** This file_line says {{description}}. */
-#define FILE_LINE_DESCRIPTION_HEADER 9
-
-/** This file_line is in a {{description}} block. */
-#define FILE_LINE_DESCRIPTION_ENTRY 10
-
-
-/**
- * A configuration file, in a format that can be edited and written back to
- * disk.
- */
-struct editable_file
-{
- struct file_line * lines; /**< The contents of the file. A linked list of lines. */
- const char * filename; /**< Full pathname - e.g. "/etc/privoxy/wibble.action". */
- const char * identifier; /**< Filename stub - e.g. "wibble". Use for CGI param. */
- /**< Pre-encoded with url_encode() for ease of use. */
- const char * version_str; /**< Last modification time, as a string. For CGI param. */
- /**< Can be used in URL without using url_param(). */
- unsigned version; /**< Last modification time - prevents chaos with
- the browser's "back" button. Note that this is a
- time_t cast to an unsigned. When comparing, always
- cast the time_t to an unsigned, and *NOT* vice-versa.
- This may lose the top few bits, but they're not
- significant anyway. */
- int newline; /**< Newline convention - one of the NEWLINE_xxx constants.
- Note that changing this after the file has been
- read in will cause a mess. */
- struct file_line * parse_error; /**< On parse error, this is the offending line. */
- const char * parse_error_text; /**< On parse error, this is the problem.
- (Statically allocated) */
-};
-
-/* FIXME: Following non-static functions should be prototyped in .h or made static */
-
-/* Functions to read and write arbitrary config files */
-jb_err edit_read_file(struct client_state *csp,
- const struct map *parameters,
- int require_version,
- const char *suffix,
- struct editable_file **pfile);
-jb_err edit_write_file(struct editable_file * file);
-void edit_free_file(struct editable_file * file);
-
-/* Functions to read and write actions files */
-jb_err edit_parse_actions_file(struct editable_file * file);
-jb_err edit_read_actions_file(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters,
- int require_version,
- struct editable_file **pfile);
-
-/* Error handlers */
-jb_err cgi_error_modified(struct client_state *csp,
- struct http_response *rsp,
- const char *filename);
-jb_err cgi_error_parse(struct client_state *csp,
- struct http_response *rsp,
- struct editable_file *file);
-jb_err cgi_error_file(struct client_state *csp,
- struct http_response *rsp,
- const char *filename);
-jb_err cgi_error_file_read_only(struct client_state *csp,
- struct http_response *rsp,
- const char *filename);
-jb_err cgi_error_disabled(struct client_state *csp,
- struct http_response *rsp);
-
-/* Internal arbitrary config file support functions */
-static jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline);
-static void edit_free_file_lines(struct file_line * first_line);
-
-/* Internal actions file support functions */
-static int match_actions_file_header_line(const char * line, const char * name);
-static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue);
-
-/* Internal parameter parsing functions */
-static jb_err get_file_name_param(struct client_state *csp,
- const struct map *parameters,
- const char *param_name,
- const char *suffix,
- char **pfilename,
- const char **pparam);
-
-static jb_err get_url_spec_param(struct client_state *csp,
- const struct map *parameters,
- const char *name,
- char **pvalue);
-
-
-/* Internal actionsfile <==> HTML conversion functions */
-static jb_err map_radio(struct map * exports,
- const char * optionname,
- const char * values,
- int value);
-static jb_err actions_to_radio(struct map * exports,
- const struct action_spec *action);
-static jb_err actions_from_radio(const struct map * parameters,
- struct action_spec *action);
-
-
-static jb_err map_copy_parameter_html(struct map *out,
- const struct map *in,
- const char *name);
-#if 0 /* unused function */
-static jb_err map_copy_parameter_url(struct map *out,
- const struct map *in,
- const char *name);
-#endif /* unused function */
-
-/* Internal convenience functions */
-static char *section_target(const unsigned sectionid);
-
-/*********************************************************************
- *
- * Function : section_target
- *
- * Description : Given an unsigned (section id) n, produce a dynamically
- * allocated string of the form #l<n>, for use in link
- * targets.
- *
- * Parameters :
- * 1 : sectionid = start line number of section
- *
- * Returns : String with link target, or NULL if out of
- * memory
- *
- *********************************************************************/
-static char *section_target(const unsigned sectionid)
-{
- char buf[30];
-
- snprintf(buf, 30, "#l%d", sectionid);
- return(strdup(buf));
-
-}
-
-
-/*********************************************************************
- *
- * Function : map_copy_parameter_html
- *
- * Description : Copy a CGI parameter from one map to another, HTML
- * encoding it.
- *
- * Parameters :
- * 1 : out = target map
- * 2 : in = source map
- * 3 : name = name of cgi parameter to copy
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the parameter doesn't exist
- * in the source map
- *
- *********************************************************************/
-static jb_err map_copy_parameter_html(struct map *out,
- const struct map *in,
- const char *name)
-{
- const char * value;
- jb_err err;
-
- assert(out);
- assert(in);
- assert(name);
-
- value = lookup(in, name);
- err = map(out, name, 1, html_encode(value), 0);
-
- if (err)
- {
- /* Out of memory */
- return err;
- }
- else if (*value == '\0')
- {
- return JB_ERR_CGI_PARAMS;
- }
- else
- {
- return JB_ERR_OK;
- }
-}
-
-
-#if 0 /* unused function */
-/*********************************************************************
- *
- * Function : map_copy_parameter_url
- *
- * Description : Copy a CGI parameter from one map to another, URL
- * encoding it.
- *
- * Parameters :
- * 1 : out = target map
- * 2 : in = source map
- * 3 : name = name of cgi parameter to copy
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the parameter doesn't exist
- * in the source map
- *
- *********************************************************************/
-static jb_err map_copy_parameter_url(struct map *out,
- const struct map *in,
- const char *name)
-{
- const char * value;
- jb_err err;
-
- assert(out);
- assert(in);
- assert(name);
-
- value = lookup(in, name);
- err = map(out, name, 1, url_encode(value), 0);
-
- if (err)
- {
- /* Out of memory */
- return err;
- }
- else if (*value == '\0')
- {
- return JB_ERR_CGI_PARAMS;
- }
- else
- {
- return JB_ERR_OK;
- }
-}
-#endif /* 0 - unused function */
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_url_form
- *
- * Description : CGI function that displays a form for
- * edit-actions-url
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * p : (pattern) Line number of pattern to edit
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map * exports;
- unsigned patternid;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- unsigned section_start_line_number = 0;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "p", &patternid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- cur_line = file->lines;
-
- for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
- {
- if (cur_line->type == FILE_LINE_ACTION)
- {
- section_start_line_number = line_number;
- }
- cur_line = cur_line->next;
- }
-
- if ( (cur_line == NULL)
- || (line_number != patternid)
- || (patternid < 1)
- || (cur_line->type != FILE_LINE_URL))
- {
- /* Invalid "patternid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, file->identifier, 1);
- if (!err) err = map(exports, "v", 1, file->version_str, 1);
- if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
- if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
- if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
-
- edit_free_file(file);
-
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "edit-actions-url-form", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_add_url_form
- *
- * Description : CGI function that displays a form for
- * edit-actions-url
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * s : (section) Line number of section to edit
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_add_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map *exports;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- err = map_copy_parameter_html(exports, parameters, "f");
- if (!err) err = map_copy_parameter_html(exports, parameters, "v");
- if (!err) err = map_copy_parameter_html(exports, parameters, "s");
-
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "edit-actions-add-url-form", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_remove_url_form
- *
- * Description : CGI function that displays a form for
- * edit-actions-url
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * p : (pattern) Line number of pattern to edit
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map * exports;
- unsigned patternid;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- unsigned section_start_line_number = 0;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "p", &patternid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- cur_line = file->lines;
-
- for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
- {
- if (cur_line->type == FILE_LINE_ACTION)
- {
- section_start_line_number = line_number;
- }
- cur_line = cur_line->next;
- }
-
- if ( (cur_line == NULL)
- || (line_number != patternid)
- || (patternid < 1)
- || (cur_line->type != FILE_LINE_URL))
- {
- /* Invalid "patternid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, file->identifier, 1);
- if (!err) err = map(exports, "v", 1, file->version_str, 1);
- if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
- if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
- if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
-
- edit_free_file(file);
-
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "edit-actions-remove-url-form", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : edit_write_file
- *
- * Description : Write a complete file to disk.
- *
- * Parameters :
- * 1 : file = File to write.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_FILE on error writing to file.
- * JB_ERR_MEMORY on out of memory
- *
- *********************************************************************/
-jb_err edit_write_file(struct editable_file * file)
-{
- FILE * fp;
- struct file_line * cur_line;
- struct stat statbuf[1];
- char version_buf[22]; /* 22 = ceil(log10(2^64)) + 2 = max number of
- digits in time_t, assuming this is a 64-bit
- machine, plus null terminator, plus one
- for paranoia */
-
- assert(file);
- assert(file->filename);
-
- if (NULL == (fp = fopen(file->filename, "wb")))
- {
- return JB_ERR_FILE;
- }
-
- cur_line = file->lines;
- while (cur_line != NULL)
- {
- if (cur_line->raw)
- {
- if (fputs(cur_line->raw, fp) < 0)
- {
- fclose(fp);
- return JB_ERR_FILE;
- }
- }
- else
- {
- if (cur_line->prefix)
- {
- if (fputs(cur_line->prefix, fp) < 0)
- {
- fclose(fp);
- return JB_ERR_FILE;
- }
- }
- if (cur_line->unprocessed)
- {
-
- if (NULL != strchr(cur_line->unprocessed, '#'))
- {
- /* Must quote '#' characters */
- int numhash = 0;
- int len;
- char * src;
- char * dest;
- char * str;
-
- /* Count number of # characters, so we know length of output string */
- src = cur_line->unprocessed;
- while (NULL != (src = strchr(src, '#')))
- {
- numhash++;
- src++;
- }
- assert(numhash > 0);
-
- /* Allocate new memory for string */
- len = strlen(cur_line->unprocessed);
- if (NULL == (str = malloc((size_t) len + 1 + numhash)))
- {
- /* Uh oh, just trashed file! */
- fclose(fp);
- return JB_ERR_MEMORY;
- }
-
- /* Loop through string from end */
- src = cur_line->unprocessed + len;
- dest = str + len + numhash;
- for ( ; len >= 0; len--)
- {
- if ((*dest-- = *src--) == '#')
- {
- *dest-- = '\\';
- numhash--;
- assert(numhash >= 0);
- }
- }
- assert(numhash == 0);
- assert(src + 1 == cur_line->unprocessed);
- assert(dest + 1 == str);
-
- if (fputs(str, fp) < 0)
- {
- free(str);
- fclose(fp);
- return JB_ERR_FILE;
- }
-
- free(str);
- }
- else
- {
- /* Can write without quoting '#' characters. */
- if (fputs(cur_line->unprocessed, fp) < 0)
- {
- fclose(fp);
- return JB_ERR_FILE;
- }
- }
- if (fputs(NEWLINE(file->newline), fp) < 0)
- {
- fclose(fp);
- return JB_ERR_FILE;
- }
- }
- else
- {
- /* FIXME: Write data from file->data->whatever */
- assert(0);
- }
- }
- cur_line = cur_line->next;
- }
-
- fclose(fp);
-
-
- /* Update the version stamp in the file structure, since we just
- * wrote to the file & changed it's date.
- */
- if (stat(file->filename, statbuf) < 0)
- {
- /* Error, probably file not found. */
- return JB_ERR_FILE;
- }
- file->version = (unsigned)statbuf->st_mtime;
-
- /* Correct file->version_str */
- freez(file->version_str);
- snprintf(version_buf, 22, "%u", file->version);
- version_buf[21] = '\0';
- file->version_str = strdup(version_buf);
- if (version_buf == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : edit_free_file
- *
- * Description : Free a complete file in memory.
- *
- * Parameters :
- * 1 : file = Data structure to free.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void edit_free_file(struct editable_file * file)
-{
- if (!file)
- {
- /* Silently ignore NULL pointer */
- return;
- }
-
- edit_free_file_lines(file->lines);
- freez(file->filename);
- freez(file->identifier);
- freez(file->version_str);
- file->version = 0;
- file->parse_error_text = NULL; /* Statically allocated */
- file->parse_error = NULL;
-
- free(file);
-}
-
-
-/*********************************************************************
- *
- * Function : edit_free_file_lines
- *
- * Description : Free an entire linked list of file lines.
- *
- * Parameters :
- * 1 : first_line = Data structure to free.
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void edit_free_file_lines(struct file_line * first_line)
-{
- struct file_line * next_line;
-
- while (first_line != NULL)
- {
- next_line = first_line->next;
- first_line->next = NULL;
- freez(first_line->raw);
- freez(first_line->prefix);
- freez(first_line->unprocessed);
- switch(first_line->type)
- {
- case 0: /* special case if memory zeroed */
- case FILE_LINE_UNPROCESSED:
- case FILE_LINE_BLANK:
- case FILE_LINE_ALIAS_HEADER:
- case FILE_LINE_SETTINGS_HEADER:
- case FILE_LINE_DESCRIPTION_HEADER:
- case FILE_LINE_DESCRIPTION_ENTRY:
- case FILE_LINE_ALIAS_ENTRY:
- case FILE_LINE_URL:
- /* No data is stored for these */
- break;
-
- case FILE_LINE_ACTION:
- free_action(first_line->data.action);
- break;
-
- case FILE_LINE_SETTINGS_ENTRY:
- freez(first_line->data.setting.name);
- freez(first_line->data.setting.svalue);
- break;
- default:
- /* Should never happen */
- assert(0);
- break;
- }
- first_line->type = 0; /* paranoia */
- free(first_line);
- first_line = next_line;
- }
-}
-
-
-/*********************************************************************
- *
- * Function : match_actions_file_header_line
- *
- * Description : Match an actions file {{header}} line
- *
- * Parameters :
- * 1 : line = String from file
- * 2 : name = Header to match against
- *
- * Returns : 0 iff they match.
- *
- *********************************************************************/
-static int match_actions_file_header_line(const char * line, const char * name)
-{
- size_t len;
-
- assert(line);
- assert(name);
-
- /* Look for "{{" */
- if ((line[0] != '{') || (line[1] != '{'))
- {
- return 1;
- }
- line += 2;
-
- /* Look for optional whitespace */
- while ( (*line == ' ') || (*line == '\t') )
- {
- line++;
- }
-
- /* Look for the specified name (case-insensitive) */
- len = strlen(name);
- if (0 != strncmpic(line, name, len))
- {
- return 1;
- }
- line += len;
-
- /* Look for optional whitespace */
- while ( (*line == ' ') || (*line == '\t') )
- {
- line++;
- }
-
- /* Look for "}}" and end of string*/
- if ((line[0] != '}') || (line[1] != '}') || (line[2] != '\0'))
- {
- return 1;
- }
-
- /* It matched!! */
- return 0;
-}
-
-
-/*********************************************************************
- *
- * Function : match_actions_file_header_line
- *
- * Description : Match an actions file {{header}} line
- *
- * Parameters :
- * 1 : line = String from file. Must not start with
- * whitespace (else infinite loop!)
- * 2 : pname = Destination for name
- * 2 : pvalue = Destination for value
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_PARSE if there's no "=" sign, or if there's
- * nothing before the "=" sign (but empty
- * values *after* the "=" sign are legal).
- *
- *********************************************************************/
-static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue)
-{
- const char * name_end;
- const char * value_start;
- size_t name_len;
-
- assert(line);
- assert(pname);
- assert(pvalue);
- assert(*line != ' ');
- assert(*line != '\t');
-
- *pname = NULL;
- *pvalue = NULL;
-
- value_start = strchr(line, '=');
- if ((value_start == NULL) || (value_start == line))
- {
- return JB_ERR_PARSE;
- }
-
- name_end = value_start - 1;
-
- /* Eat any whitespace before the '=' */
- while ((*name_end == ' ') || (*name_end == '\t'))
- {
- /*
- * we already know we must have at least 1 non-ws char
- * at start of buf - no need to check
- */
- name_end--;
- }
-
- name_len = name_end - line + 1; /* Length excluding \0 */
- if (NULL == (*pname = (char *) malloc(name_len + 1)))
- {
- return JB_ERR_MEMORY;
- }
- strncpy(*pname, line, name_len);
- (*pname)[name_len] = '\0';
-
- /* Eat any the whitespace after the '=' */
- value_start++;
- while ((*value_start == ' ') || (*value_start == '\t'))
- {
- value_start++;
- }
-
- if (NULL == (*pvalue = strdup(value_start)))
- {
- free(*pname);
- *pname = NULL;
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : edit_parse_actions_file
- *
- * Description : Parse an actions file in memory.
- *
- * Passed linked list must have the "data" member
- * zeroed, and must contain valid "next" and
- * "unprocessed" fields. The "raw" and "prefix"
- * fields are ignored, and "type" is just overwritten.
- *
- * Note that on error the file may have been
- * partially parsed.
- *
- * Parameters :
- * 1 : file = Actions file to be parsed in-place.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_PARSE on error
- *
- *********************************************************************/
-jb_err edit_parse_actions_file(struct editable_file * file)
-{
- struct file_line * cur_line;
- size_t len;
- const char * text; /* Text from a line */
- char * name; /* For lines of the form name=value */
- char * value; /* For lines of the form name=value */
- struct action_alias * alias_list = NULL;
- jb_err err = JB_ERR_OK;
-
- /* alias_list contains the aliases defined in this file.
- * It might be better to use the "file_line.data" fields
- * in the relavent places instead.
- */
-
- cur_line = file->lines;
-
- /* A note about blank line support: Blank lines should only
- * ever occur as the last line in the file. This function
- * is more forgiving than that - FILE_LINE_BLANK can occur
- * anywhere.
- */
-
- /* Skip leading blanks. Should only happen if file is
- * empty (which is valid, but pointless).
- */
- while ( (cur_line != NULL)
- && (cur_line->unprocessed[0] == '\0') )
- {
- /* Blank line */
- cur_line->type = FILE_LINE_BLANK;
- cur_line = cur_line->next;
- }
-
- if ( (cur_line != NULL)
- && (cur_line->unprocessed[0] != '{') )
- {
- /* File doesn't start with a header */
- file->parse_error = cur_line;
- file->parse_error_text = "First (non-comment) line of the file must contain a header.";
- return JB_ERR_PARSE;
- }
-
- if ( (cur_line != NULL) && (0 ==
- match_actions_file_header_line(cur_line->unprocessed, "settings") ) )
- {
- cur_line->type = FILE_LINE_SETTINGS_HEADER;
-
- cur_line = cur_line->next;
- while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
- {
- if (cur_line->unprocessed[0])
- {
- cur_line->type = FILE_LINE_SETTINGS_ENTRY;
-
- err = split_line_on_equals(cur_line->unprocessed,
- &cur_line->data.setting.name,
- &cur_line->data.setting.svalue);
- if (err == JB_ERR_MEMORY)
- {
- return err;
- }
- else if (err != JB_ERR_OK)
- {
- /* Line does not contain a name=value pair */
- file->parse_error = cur_line;
- file->parse_error_text = "Expected a name=value pair on this {{description}} line, but couldn't find one.";
- return JB_ERR_PARSE;
- }
- }
- else
- {
- cur_line->type = FILE_LINE_BLANK;
- }
- cur_line = cur_line->next;
- }
- }
-
- if ( (cur_line != NULL) && (0 ==
- match_actions_file_header_line(cur_line->unprocessed, "description") ) )
- {
- cur_line->type = FILE_LINE_DESCRIPTION_HEADER;
-
- cur_line = cur_line->next;
- while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
- {
- if (cur_line->unprocessed[0])
- {
- cur_line->type = FILE_LINE_DESCRIPTION_ENTRY;
- }
- else
- {
- cur_line->type = FILE_LINE_BLANK;
- }
- cur_line = cur_line->next;
- }
- }
-
- if ( (cur_line != NULL) && (0 ==
- match_actions_file_header_line(cur_line->unprocessed, "alias") ) )
- {
- cur_line->type = FILE_LINE_ALIAS_HEADER;
-
- cur_line = cur_line->next;
- while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
- {
- if (cur_line->unprocessed[0])
- {
- /* define an alias */
- struct action_alias * new_alias;
-
- cur_line->type = FILE_LINE_ALIAS_ENTRY;
-
- err = split_line_on_equals(cur_line->unprocessed, &name, &value);
- if (err == JB_ERR_MEMORY)
- {
- return err;
- }
- else if (err != JB_ERR_OK)
- {
- /* Line does not contain a name=value pair */
- file->parse_error = cur_line;
- file->parse_error_text = "Expected a name=value pair on this {{alias}} line, but couldn't find one.";
- return JB_ERR_PARSE;
- }
-
- if ((new_alias = zalloc(sizeof(*new_alias))) == NULL)
- {
- /* Out of memory */
- free(name);
- free(value);
- free_alias_list(alias_list);
- return JB_ERR_MEMORY;
- }
-
- err = get_actions(value, alias_list, new_alias->action);
- if (err)
- {
- /* Invalid action or out of memory */
- free(name);
- free(value);
- free(new_alias);
- free_alias_list(alias_list);
- if (err == JB_ERR_MEMORY)
- {
- return err;
- }
- else
- {
- /* Line does not contain a name=value pair */
- file->parse_error = cur_line;
- file->parse_error_text = "This alias does not specify a valid set of actions.";
- return JB_ERR_PARSE;
- }
- }
-
- free(value);
-
- new_alias->name = name;
-
- /* add to list */
- new_alias->next = alias_list;
- alias_list = new_alias;
- }
- else
- {
- cur_line->type = FILE_LINE_BLANK;
- }
- cur_line = cur_line->next;
- }
- }
-
- /* Header done, process the main part of the file */
- while (cur_line != NULL)
- {
- /* At this point, (cur_line->unprocessed[0] == '{') */
- assert(cur_line->unprocessed[0] == '{');
- text = cur_line->unprocessed + 1;
- len = strlen(text) - 1;
- if (text[len] != '}')
- {
- /* No closing } on header */
- free_alias_list(alias_list);
- file->parse_error = cur_line;
- file->parse_error_text = "Headers starting with '{' must have a "
- "closing bracket ('}'). Headers starting with two brackets ('{{') "
- "must close with two brackets ('}}').";
- return JB_ERR_PARSE;
- }
-
- if (text[0] == '{')
- {
- /* An invalid {{ header. */
- free_alias_list(alias_list);
- file->parse_error = cur_line;
- file->parse_error_text = "Unknown or unexpected two-bracket header. "
- "Please remember that the system (two-bracket) headers must "
- "appear in the order {{settings}}, {{description}}, {{alias}}, "
- "and must appear before any actions (one-bracket) headers. "
- "Also note that system headers may not be repeated.";
- return JB_ERR_PARSE;
- }
-
- while ( (*text == ' ') || (*text == '\t') )
- {
- text++;
- len--;
- }
- while ( (len > 0)
- && ( (text[len - 1] == ' ')
- || (text[len - 1] == '\t') ) )
- {
- len--;
- }
-
- cur_line->type = FILE_LINE_ACTION;
-
- /* Remove {} and make copy */
- if (NULL == (value = (char *) malloc(len + 1)))
- {
- /* Out of memory */
- free_alias_list(alias_list);
- return JB_ERR_MEMORY;
- }
- strncpy(value, text, len);
- value[len] = '\0';
-
- /* Get actions */
- err = get_actions(value, alias_list, cur_line->data.action);
- if (err)
- {
- /* Invalid action or out of memory */
- free(value);
- free_alias_list(alias_list);
- if (err == JB_ERR_MEMORY)
- {
- return err;
- }
- else
- {
- /* Line does not contain a name=value pair */
- file->parse_error = cur_line;
- file->parse_error_text = "This header does not specify a valid set of actions.";
- return JB_ERR_PARSE;
- }
- }
-
- /* Done with string - it was clobbered anyway */
- free(value);
-
- /* Process next line */
- cur_line = cur_line->next;
-
- /* Loop processing URL patterns */
- while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
- {
- if (cur_line->unprocessed[0])
- {
- /* Could parse URL here, but this isn't currently needed */
-
- cur_line->type = FILE_LINE_URL;
- }
- else
- {
- cur_line->type = FILE_LINE_BLANK;
- }
- cur_line = cur_line->next;
- }
- } /* End main while(cur_line != NULL) loop */
-
- free_alias_list(alias_list);
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : edit_read_file_lines
- *
- * Description : Read all the lines of a file into memory.
- * Handles whitespace, comments and line continuation.
- *
- * Parameters :
- * 1 : fp = File to read from. On return, this will be
- * at EOF but it will not have been closed.
- * 2 : pfile = Destination for a linked list of file_lines.
- * Will be set to NULL on error.
- * 3 : newline = How to handle newlines.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline)
-{
- struct file_line * first_line; /* Keep for return value or to free */
- struct file_line * cur_line; /* Current line */
- struct file_line * prev_line; /* Entry with prev_line->next = cur_line */
- jb_err rval;
-
- assert(fp);
- assert(pfile);
-
- *pfile = NULL;
-
- cur_line = first_line = zalloc(sizeof(struct file_line));
- if (cur_line == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- cur_line->type = FILE_LINE_UNPROCESSED;
-
- rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL);
- if (rval)
- {
- /* Out of memory or empty file. */
- /* Note that empty file is not an error we propogate up */
- free(cur_line);
- return ((rval == JB_ERR_FILE) ? JB_ERR_OK : rval);
- }
-
- do
- {
- prev_line = cur_line;
- cur_line = prev_line->next = zalloc(sizeof(struct file_line));
- if (cur_line == NULL)
- {
- /* Out of memory */
- edit_free_file_lines(first_line);
- return JB_ERR_MEMORY;
- }
-
- cur_line->type = FILE_LINE_UNPROCESSED;
-
- rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL);
- if ((rval != JB_ERR_OK) && (rval != JB_ERR_FILE))
- {
- /* Out of memory */
- edit_free_file_lines(first_line);
- return JB_ERR_MEMORY;
- }
-
- }
- while (rval != JB_ERR_FILE);
-
- /* EOF */
-
- /* We allocated one too many - free it */
- prev_line->next = NULL;
- free(cur_line);
-
- *pfile = first_line;
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : edit_read_file
- *
- * Description : Read a complete file into memory.
- * Handles CGI parameter parsing. If requested, also
- * checks the file's modification timestamp.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : parameters = map of cgi parameters.
- * 3 : require_version = true to check "ver" parameter.
- * 4 : suffix = File extension, e.g. ".action".
- * 5 : pfile = Destination for the file. Will be set
- * to NULL on error.
- *
- * CGI Parameters :
- * filename : The name of the file to read, without the
- * path or ".action" extension.
- * ver : (Only if require_version is nonzero)
- * Timestamp of the actions file. If wrong, this
- * function fails with JB_ERR_MODIFIED.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if "filename" was not specified
- * or is not valid.
- * JB_ERR_FILE if the file cannot be opened or
- * contains no data
- * JB_ERR_MODIFIED if version checking was requested and
- * failed - the file was modified outside
- * of this CGI editor instance.
- *
- *********************************************************************/
-jb_err edit_read_file(struct client_state *csp,
- const struct map *parameters,
- int require_version,
- const char *suffix,
- struct editable_file **pfile)
-{
- struct file_line * lines;
- FILE * fp;
- jb_err err;
- char * filename;
- const char * identifier;
- struct editable_file * file;
- unsigned version = 0;
- struct stat statbuf[1];
- char version_buf[22];
- int newline = NEWLINE_UNKNOWN;
-
- assert(csp);
- assert(parameters);
- assert(pfile);
-
- *pfile = NULL;
-
- err = get_file_name_param(csp, parameters, "f", suffix,
- &filename, &identifier);
- if (err)
- {
- return err;
- }
-
- if (stat(filename, statbuf) < 0)
- {
- /* Error, probably file not found. */
- free(filename);
- return JB_ERR_FILE;
- }
- version = (unsigned) statbuf->st_mtime;
-
- if (require_version)
- {
- unsigned specified_version;
- err = get_number_param(csp, parameters, "v", &specified_version);
- if (err)
- {
- free(filename);
- return err;
- }
-
- if (version != specified_version)
- {
- return JB_ERR_MODIFIED;
- }
- }
-
- if (NULL == (fp = fopen(filename,"rb")))
- {
- free(filename);
- return JB_ERR_FILE;
- }
-
- err = edit_read_file_lines(fp, &lines, &newline);
-
- fclose(fp);
-
- if (err)
- {
- free(filename);
- return err;
- }
-
- file = (struct editable_file *) zalloc(sizeof(*file));
- if (err)
- {
- free(filename);
- edit_free_file_lines(lines);
- return err;
- }
-
- file->lines = lines;
- file->newline = newline;
- file->filename = filename;
- file->version = version;
- file->identifier = url_encode(identifier);
-
- if (file->identifier == NULL)
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- /* Correct file->version_str */
- freez(file->version_str);
- snprintf(version_buf, 22, "%u", file->version);
- version_buf[21] = '\0';
- file->version_str = strdup(version_buf);
- if (version_buf == NULL)
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- *pfile = file;
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : edit_read_actions_file
- *
- * Description : Read a complete actions file into memory.
- * Handles CGI parameter parsing. If requested, also
- * checks the file's modification timestamp.
- *
- * If this function detects an error in the categories
- * JB_ERR_FILE, JB_ERR_MODIFIED, or JB_ERR_PARSE,
- * then it handles it by filling in the specified
- * response structure and returning JB_ERR_FILE.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = HTTP response. Only filled in on error.
- * 2 : parameters = map of cgi parameters.
- * 3 : require_version = true to check "ver" parameter.
- * 4 : pfile = Destination for the file. Will be set
- * to NULL on error.
- *
- * CGI Parameters :
- * filename : The name of the actions file to read, without the
- * path or ".action" extension.
- * ver : (Only if require_version is nonzero)
- * Timestamp of the actions file. If wrong, this
- * function fails with JB_ERR_MODIFIED.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if "filename" was not specified
- * or is not valid.
- * JB_ERR_FILE if the file does not contain valid data,
- * or if file cannot be opened or
- * contains no data, or if version
- * checking was requested and failed.
- *
- *********************************************************************/
-jb_err edit_read_actions_file(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters,
- int require_version,
- struct editable_file **pfile)
-{
- jb_err err;
- struct editable_file *file;
-
- assert(csp);
- assert(parameters);
- assert(pfile);
-
- *pfile = NULL;
-
- err = edit_read_file(csp, parameters, require_version, ".action", &file);
- if (err)
- {
- /* Try to handle if possible */
- if (err == JB_ERR_FILE)
- {
- err = cgi_error_file(csp, rsp, lookup(parameters, "f"));
- }
- else if (err == JB_ERR_MODIFIED)
- {
- err = cgi_error_modified(csp, rsp, lookup(parameters, "f"));
- }
- if (err == JB_ERR_OK)
- {
- /*
- * Signal to higher-level CGI code that there was a problem but we
- * handled it, they should just return JB_ERR_OK.
- */
- err = JB_ERR_FILE;
- }
- return err;
- }
-
- err = edit_parse_actions_file(file);
- if (err)
- {
- if (err == JB_ERR_PARSE)
- {
- err = cgi_error_parse(csp, rsp, file);
- if (err == JB_ERR_OK)
- {
- /*
- * Signal to higher-level CGI code that there was a problem but we
- * handled it, they should just return JB_ERR_OK.
- */
- err = JB_ERR_FILE;
- }
- }
- edit_free_file(file);
- return err;
- }
-
- *pfile = file;
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : get_file_name_param
- *
- * Description : Get the name of the file to edit from the parameters
- * passed to a CGI function. This function handles
- * security checks such as blocking urls containing
- * "/" or ".", prepending the config file directory,
- * and adding the specified suffix.
- *
- * (This is an essential security check, otherwise
- * users may be able to pass "../../../etc/passwd"
- * and overwrite the password file [linux], "prn:"
- * and print random data [Windows], etc...)
- *
- * This function only allows filenames contining the
- * characters '-', '_', 'A'-'Z', 'a'-'z', and '0'-'9'.
- * That's probably too restrictive but at least it's
- * secure.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : parameters = map of cgi parameters
- * 3 : param_name = The name of the parameter to read
- * 4 : suffix = File extension, e.g. ".actions"
- * 5 : pfilename = destination for full filename. Caller
- * free()s. Set to NULL on error.
- * 6 : pparam = destination for partial filename,
- * suitable for use in another URL. Allocated as part
- * of the map "parameters", so don't free it.
- * Set to NULL if not specified.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if "filename" was not specified
- * or is not valid.
- *
- *********************************************************************/
-static jb_err get_file_name_param(struct client_state *csp,
- const struct map *parameters,
- const char *param_name,
- const char *suffix,
- char **pfilename,
- const char **pparam)
-{
- const char *param;
- const char *s;
- char *name;
- char *fullpath;
- char ch;
- int len;
-
- assert(csp);
- assert(parameters);
- assert(suffix);
- assert(pfilename);
- assert(pparam);
-
- *pfilename = NULL;
- *pparam = NULL;
-
- param = lookup(parameters, param_name);
- if (!*param)
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- *pparam = param;
-
- len = strlen(param);
- if (len >= FILENAME_MAX)
- {
- /* Too long. */
- return JB_ERR_CGI_PARAMS;
- }
-
- /* Check every character to see if it's legal */
- s = param;
- while ((ch = *s++) != '\0')
- {
- if ( ((ch < 'A') || (ch > 'Z'))
- && ((ch < 'a') || (ch > 'z'))
- && ((ch < '0') || (ch > '9'))
- && (ch != '-')
- && (ch != '_') )
- {
- /* Probable hack attempt. */
- return JB_ERR_CGI_PARAMS;
- }
- }
-
- /* Append extension */
- name = malloc(len + strlen(suffix) + 1);
- if (name == NULL)
- {
- return JB_ERR_MEMORY;
- }
- strcpy(name, param);
- strcpy(name + len, suffix);
-
- /* Prepend path */
- fullpath = make_path(csp->config->confdir, name);
- free(name);
-
- if (fullpath == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- /* Success */
- *pfilename = fullpath;
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : get_url_spec_param
- *
- * Description : Get a URL pattern from the parameters
- * passed to a CGI function. Removes leading/trailing
- * spaces and validates it.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : parameters = map of cgi parameters
- * 3 : name = Name of CGI parameter to read
- * 4 : pvalue = destination for value. Will be malloc()'d.
- * Set to NULL on error.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the parameter was not specified
- * or is not valid.
- *
- *********************************************************************/
-static jb_err get_url_spec_param(struct client_state *csp,
- const struct map *parameters,
- const char *name,
- char **pvalue)
-{
- const char *orig_param;
- char *param;
- char *s;
- struct url_spec compiled[1];
- jb_err err;
-
- assert(csp);
- assert(parameters);
- assert(name);
- assert(pvalue);
-
- *pvalue = NULL;
-
- orig_param = lookup(parameters, name);
- if (!*orig_param)
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- /* Copy and trim whitespace */
- param = strdup(orig_param);
- if (param == NULL)
- {
- return JB_ERR_MEMORY;
- }
- chomp(param);
-
- /* Must be non-empty, and can't allow 1st character to be '{' */
- if (param[0] == '\0' || param[0] == '{')
- {
- free(param);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* Check for embedded newlines */
- for (s = param; *s != '\0'; s++)
- {
- if ((*s == '\r') || (*s == '\n'))
- {
- free(param);
- return JB_ERR_CGI_PARAMS;
- }
- }
-
- /* Check that regex is valid */
- s = strdup(param);
- if (s == NULL)
- {
- free(param);
- return JB_ERR_MEMORY;
- }
- err = create_url_spec(compiled, s);
- free(s);
- if (err)
- {
- free(param);
- return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
- }
- free_url_spec(compiled);
-
- if (param[strlen(param) - 1] == '\\')
- {
- /*
- * Must protect trailing '\\' from becoming line continuation character.
- * Two methods: 1) If it's a domain only, add a trailing '/'.
- * 2) For path, add the do-nothing PCRE expression (?:) to the end
- */
- if (strchr(param, '/') == NULL)
- {
- err = string_append(¶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:
- * <option type="radio" name="xyz" @xyz-a@>
- * <option type="radio" name="xyz" @xyz-b@>
- * <option type="radio" name="xyz" @xyz-c@>
- * Then map one of the @xyz-?@ variables to "checked"
- * and all the others to empty by calling:
- * map_radio(exports, "xyz", "abc", sel)
- * Where 'sel' is 'a', 'b', or 'c'.
- *
- * Parameters :
- * 1 : exports = Exports map to modify.
- * 2 : optionname = name for map
- * 3 : values = null-terminated list of values;
- * 4 : value = Selected value.
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-static jb_err map_radio(struct map * exports,
- const char * optionname,
- const char * values,
- int value)
-{
- size_t len;
- char * buf;
- char * p;
- char c;
-
- assert(exports);
- assert(optionname);
- assert(values);
-
- len = strlen(optionname);
- buf = malloc(len + 3);
- if (buf == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- strcpy(buf, optionname);
- p = buf + len;
- *p++ = '-';
- p[1] = '\0';
-
- while ((c = *values++) != '\0')
- {
- if (c != value)
- {
- *p = c;
- if (map(exports, buf, 1, "", 1))
- {
- return JB_ERR_MEMORY;
- }
- }
- }
-
- *p = value;
- return map(exports, buf, 0, "checked", 1);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_modified
- *
- * Description : CGI function that is called when a file is modified
- * outside the CGI editor.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : filename = The file that was modified.
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_modified(struct client_state *csp,
- struct http_response *rsp,
- const char *filename)
-{
- struct map *exports;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(filename);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, html_encode(filename), 0);
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-modified", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_parse
- *
- * Description : CGI function that is called when a file cannot
- * be parsed by the CGI editor.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : file = The file that was modified.
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_parse(struct client_state *csp,
- struct http_response *rsp,
- struct editable_file *file)
-{
- struct map *exports;
- jb_err err;
- struct file_line *cur_line;
-
- assert(csp);
- assert(rsp);
- assert(file);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, file->identifier, 1);
- if (!err) err = map(exports, "parse-error", 1, html_encode(file->parse_error_text), 0);
-
- cur_line = file->parse_error;
- assert(cur_line);
-
- if (!err) err = map(exports, "line-raw", 1, html_encode(cur_line->raw), 0);
- if (!err) err = map(exports, "line-data", 1, html_encode(cur_line->unprocessed), 0);
-
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-parse", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_file
- *
- * Description : CGI function that is called when a file cannot be
- * opened by the CGI editor.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : filename = The file that was modified.
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_file(struct client_state *csp,
- struct http_response *rsp,
- const char *filename)
-{
- struct map *exports;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(filename);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, html_encode(filename), 0);
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-file", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_file
- *
- * Description : CGI function that is called when a file cannot be
- * opened for writing by the CGI editor.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : filename = The file that we can't write to
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_file_read_only(struct client_state *csp,
- struct http_response *rsp,
- const char *filename)
-{
- struct map *exports;
- jb_err err;
-
- assert(csp);
- assert(rsp);
- assert(filename);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, html_encode(filename), 0);
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-file-read-only", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_disabled
- *
- * Description : CGI function that is called if the actions editor
- * is called although it's disabled in config
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_disabled(struct client_state *csp,
- struct http_response *rsp)
-{
- struct map *exports;
-
- assert(csp);
- assert(rsp);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-disabled", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions
- *
- * Description : CGI function that allows the user to choose which
- * actions file to edit.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error
- *
- *********************************************************************/
-jb_err cgi_edit_actions(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- /* FIXME: Incomplete */
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- return JB_ERR_MEMORY;
- }
- if (enlist_unique_header(rsp->headers, "Location",
- CGI_PREFIX "edit-actions-list?f=default"))
- {
- free(rsp->status);
- rsp->status = NULL;
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_list
- *
- * Description : CGI function that edits the actions list.
- * FIXME: This function shouldn't FATAL ever.
- * FIXME: This function doesn't check the retval of map()
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : filename
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_FILE if the file cannot be opened or
- * contains no data
- * JB_ERR_CGI_PARAMS if "filename" was not specified
- * or is not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_list(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char * section_template;
- char * url_template;
- char * sections;
- char * urls;
- char buf[150];
- char * s;
- struct map * exports;
- struct map * section_exports;
- struct map * url_exports;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number = 0;
- unsigned prev_section_line_number = ((unsigned) (-1));
- int i, url_1_2;
- struct file_list * fl;
- struct url_actions * b;
- char * buttons = NULL;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- /* Load actions file */
- err = edit_read_actions_file(csp, rsp, parameters, 0, &file);
- if (err)
- {
- /* No filename specified, can't read file, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- /* Find start of actions in file */
- cur_line = file->lines;
- line_number = 1;
- while ((cur_line != NULL) && (cur_line->type != FILE_LINE_ACTION))
- {
- cur_line = cur_line->next;
- line_number++;
- }
-
- /*
- * Conventional actions files should have a match all block
- * at the start:
- * cur_line = {...global actions...}
- * cur_line->next = /
- * cur_line->next->next = {...actions...} or EOF
- */
- if ( (cur_line != NULL)
- && (cur_line->type == FILE_LINE_ACTION)
- && (cur_line->next != NULL)
- && (cur_line->next->type == FILE_LINE_URL)
- && (0 == strcmp(cur_line->next->unprocessed, "/"))
- && ( (cur_line->next->next == NULL)
- || (cur_line->next->next->type != FILE_LINE_URL)
- ) )
- {
- /*
- * Generate string with buttons to set actions for "/" to
- * any predefined set of actions (named standard.*, probably
- * residing in standard.action).
- */
-
- err = template_load(csp, §ion_template, "edit-actions-list-button", 0);
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- if (err == JB_ERR_FILE)
- {
- return cgi_error_no_template(csp, rsp, "edit-actions-list-button");
- }
- return err;
- }
-
- err = template_fill(§ion_template, exports);
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- return err;
- }
-
- buttons = strdup("");
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
- {
- for (b = b->next; NULL != b; b = b->next)
- {
- if (!strncmp(b->url->spec, "standard.", 9) && *(b->url->spec + 9) != '\0')
- {
- if (err || (NULL == (section_exports = new_map())))
- {
- freez(buttons);
- free(section_template);
- edit_free_file(file);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- err = map(section_exports, "button-name", 1, b->url->spec + 9, 1);
-
- if (err || (NULL == (s = strdup(section_template))))
- {
- free_map(section_exports);
- freez(buttons);
- free(section_template);
- edit_free_file(file);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- if (!err) err = template_fill(&s, section_exports);
- free_map(section_exports);
- if (!err) err = string_join(&buttons, s);
- }
- }
- }
- }
- freez(section_template);
- if (!err) err = map(exports, "all-urls-buttons", 1, buttons, 0);
-
- /*
- * Conventional actions file, supply extra editing help.
- * (e.g. don't allow them to make it an unconventional one).
- */
- if (!err) err = map_conditional(exports, "all-urls-present", 1);
-
- snprintf(buf, 150, "%d", line_number);
- if (!err) err = map(exports, "all-urls-s", 1, buf, 1);
- snprintf(buf, 150, "%d", line_number + 2);
- if (!err) err = map(exports, "all-urls-s-next", 1, buf, 1);
- if (!err) err = map(exports, "all-urls-actions", 1,
- actions_to_html(csp, cur_line->data.action), 0);
-
- /* Skip the 2 lines */
- cur_line = cur_line->next->next;
- line_number += 2;
-
- /*
- * Note that prev_section_line_number is NOT set here.
- * This is deliberate and not a bug. It stops a "Move up"
- * option appearing on the next section. Clicking "Move
- * up" would make the actions file unconventional, which
- * we don't want, so we hide this option.
- */
- }
- else
- {
- /*
- * Non-standard actions file - does not begin with
- * the "All URLs" section.
- */
- if (!err) err = map_conditional(exports, "all-urls-present", 0);
- }
-
- /* Set up global exports */
-
- if (!err) err = map(exports, "f", 1, file->identifier, 1);
- if (!err) err = map(exports, "v", 1, file->version_str, 1);
-
- /* Discourage private additions to default.action */
-
- if (!err) err = map_conditional(exports, "default-action",
- (strcmp("default", lookup(parameters, "f")) == 0));
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- return err;
- }
-
- /* Should do all global exports above this point */
-
- /* Load templates */
-
- err = template_load(csp, §ion_template, "edit-actions-list-section", 0);
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- if (err == JB_ERR_FILE)
- {
- return cgi_error_no_template(csp, rsp, "edit-actions-list-section");
- }
- return err;
- }
-
- err = template_load(csp, &url_template, "edit-actions-list-url", 0);
- if (err)
- {
- free(section_template);
- edit_free_file(file);
- free_map(exports);
- if (err == JB_ERR_FILE)
- {
- return cgi_error_no_template(csp, rsp, "edit-actions-list-url");
- }
- return err;
- }
-
- err = template_fill(§ion_template, exports);
- if (err)
- {
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free(url_template);
- return err;
- }
-
- err = template_fill(&url_template, exports);
- if (err)
- {
- free(section_template);
- edit_free_file(file);
- free_map(exports);
- return err;
- }
-
- if (NULL == (sections = strdup("")))
- {
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- while ((cur_line != NULL) && (cur_line->type == FILE_LINE_ACTION))
- {
- if (NULL == (section_exports = new_map()))
- {
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- snprintf(buf, 150, "%d", line_number);
- err = map(section_exports, "s", 1, buf, 1);
- if (!err) err = map(section_exports, "actions", 1,
- actions_to_html(csp, cur_line->data.action), 0);
-
- if ( (!err)
- && (cur_line->next != NULL)
- && (cur_line->next->type == FILE_LINE_URL))
- {
- /* This section contains at least one URL, don't allow delete */
- err = map_block_killer(section_exports, "empty-section");
- }
- else
- {
- if (!err) err = map_block_keep(section_exports, "empty-section");
- }
-
- if (prev_section_line_number != ((unsigned)(-1)))
- {
- /* Not last section */
- snprintf(buf, 150, "%d", prev_section_line_number);
- if (!err) err = map(section_exports, "s-prev", 1, buf, 1);
- if (!err) err = map_block_keep(section_exports, "s-prev-exists");
- }
- else
- {
- /* Last section */
- if (!err) err = map_block_killer(section_exports, "s-prev-exists");
- }
- prev_section_line_number = line_number;
-
- if (err)
- {
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return err;
- }
-
- /* Should do all section-specific exports above this point */
-
- if (NULL == (urls = strdup("")))
- {
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return JB_ERR_MEMORY;
- }
-
- url_1_2 = 2;
-
- cur_line = cur_line->next;
- line_number++;
-
- while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL))
- {
- if (NULL == (url_exports = new_map()))
- {
- free(urls);
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return JB_ERR_MEMORY;
- }
-
- snprintf(buf, 150, "%d", line_number);
- err = map(url_exports, "p", 1, buf, 1);
-
- snprintf(buf, 150, "%d", url_1_2);
- if (!err) err = map(url_exports, "url-1-2", 1, buf, 1);
-
- if (!err) err = map(url_exports, "url-html", 1,
- html_encode(cur_line->unprocessed), 0);
- if (!err) err = map(url_exports, "url", 1,
- url_encode(cur_line->unprocessed), 0);
-
- if (err)
- {
- free(urls);
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- free_map(url_exports);
- return err;
- }
-
- if (NULL == (s = strdup(url_template)))
- {
- free(urls);
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- free_map(url_exports);
- return JB_ERR_MEMORY;
- }
-
- err = template_fill(&s, section_exports);
- if (!err) err = template_fill(&s, url_exports);
- if (!err) err = string_append(&urls, s);
-
- free_map(url_exports);
- freez(s);
-
- if (err)
- {
- freez(urls);
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return err;
- }
-
- url_1_2 = 3 - url_1_2;
-
- cur_line = cur_line->next;
- line_number++;
- }
-
- err = map(section_exports, "urls", 1, urls, 0);
-
- /* Could also do section-specific exports here, but it wouldn't be as fast */
-
- if ( (cur_line != NULL)
- && (cur_line->type == FILE_LINE_ACTION))
- {
- /* Not last section */
- snprintf(buf, 150, "%d", line_number);
- if (!err) err = map(section_exports, "s-next", 1, buf, 1);
- if (!err) err = map_block_keep(section_exports, "s-next-exists");
- }
- else
- {
- /* Last section */
- if (!err) err = map_block_killer(section_exports, "s-next-exists");
- }
-
- if (err)
- {
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return err;
- }
-
- if (NULL == (s = strdup(section_template)))
- {
- free(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- free_map(section_exports);
- return JB_ERR_MEMORY;
- }
-
- err = template_fill(&s, section_exports);
- if (!err) err = string_append(§ions, s);
-
- freez(s);
- free_map(section_exports);
-
- if (err)
- {
- freez(sections);
- free(section_template);
- free(url_template);
- edit_free_file(file);
- free_map(exports);
- return err;
- }
- }
-
- edit_free_file(file);
- free(section_template);
- free(url_template);
-
- err = map(exports, "sections", 1, sections, 0);
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- /* Could also do global exports here, but it wouldn't be as fast */
-
- return template_fill_for_cgi(csp, "edit-actions-list", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_for_url
- *
- * Description : CGI function that edits the Actions list.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_for_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map * exports;
- unsigned sectionid;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- jb_err err;
- struct file_list *filter_file;
- struct re_filterfile_spec *filter_group;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s", §ionid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- cur_line = file->lines;
-
- for (line_number = 1; (cur_line != NULL) && (line_number < sectionid); line_number++)
- {
- cur_line = cur_line->next;
- }
-
- if ( (cur_line == NULL)
- || (line_number != sectionid)
- || (sectionid < 1)
- || (cur_line->type != FILE_LINE_ACTION))
- {
- /* Invalid "sectionid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- err = map(exports, "f", 1, file->identifier, 1);
- if (!err) err = map(exports, "v", 1, file->version_str, 1);
- if (!err) err = map(exports, "s", 1, url_encode(lookup(parameters, "s")), 0);
-
- if (!err) err = actions_to_radio(exports, cur_line->data.action);
-
- filter_file = csp->rlist;
- filter_group = ((filter_file != NULL) ? filter_file->f : NULL);
-
- if (!err) err = map_conditional(exports, "any-filters-defined", (filter_group != NULL));
-
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- return err;
- }
-
- if (filter_group == NULL)
- {
- err = map(exports, "filter-params", 1, "", 1);
- }
- else
- {
- /* We have some entries in the filter list */
- char * result;
- int index = 0;
- char * filter_template;
-
- err = template_load(csp, &filter_template, "edit-actions-for-url-filter", 0);
- if (err)
- {
- edit_free_file(file);
- free_map(exports);
- if (err == JB_ERR_FILE)
- {
- return cgi_error_no_template(csp, rsp, "edit-actions-for-url-filter");
- }
- return err;
- }
-
- err = template_fill(&filter_template, exports);
-
- result = strdup("");
-
- for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
- {
- char current_mode = 'x';
- struct list_entry *filter_name;
- char * this_line;
- struct map *line_exports;
- char number[20];
-
- filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first;
- while ((filter_name != NULL)
- && (0 != strcmp(filter_group->name, filter_name->str)))
- {
- filter_name = filter_name->next;
- }
-
- if (filter_name != NULL)
- {
- current_mode = 'y';
- }
- else
- {
- filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first;
- while ((filter_name != NULL)
- && (0 != strcmp(filter_group->name, filter_name->str)))
- {
- filter_name = filter_name->next;
- }
- if (filter_name != NULL)
- {
- current_mode = 'n';
- }
- }
-
- /* Generate a unique serial number */
- snprintf(number, sizeof(number), "%x", index++);
- number[sizeof(number) - 1] = '\0';
-
- line_exports = new_map();
- if (line_exports == NULL)
- {
- err = JB_ERR_MEMORY;
- freez(result);
- }
- else
- {
- if (!err) err = map(line_exports, "index", 1, number, 1);
- if (!err) err = map(line_exports, "name", 1, filter_group->name, 1);
- if (!err) err = map(line_exports, "description", 1, filter_group->description, 1);
- if (!err) err = map_radio(line_exports, "this-filter", "ynx", current_mode);
-
- this_line = NULL;
- if (!err)
- {
- this_line = strdup(filter_template);
- if (this_line == NULL) err = JB_ERR_MEMORY;
- }
- if (!err) err = template_fill(&this_line, line_exports);
- string_join(&result, this_line);
-
- free_map(line_exports);
- }
- }
-
- freez(filter_template);
-
- if (!err)
- {
- err = map(exports, "filter-params", 1, result, 0);
- }
- else
- {
- freez(result);
- }
- }
-
- if (!err) err = map_radio(exports, "filter-all", "nx",
- (cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] ? 'n' : 'x'));
-
- edit_free_file(file);
-
- if (err)
- {
- free_map(exports);
- return err;
- }
-
- return template_fill_for_cgi(csp, "edit-actions-for-url", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_submit
- *
- * Description : CGI function that actually edits the Actions list.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_submit(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned sectionid;
- char * actiontext;
- char * newtext;
- size_t len;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- char * target;
- jb_err err;
- int index;
- const char * action_set_name;
- char ch;
- struct file_list * fl;
- struct url_actions * b;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s", §ionid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- cur_line = file->lines;
-
- for (line_number = 1; (cur_line != NULL) && (line_number < sectionid); line_number++)
- {
- cur_line = cur_line->next;
- }
-
- if ( (cur_line == NULL)
- || (line_number != sectionid)
- || (sectionid < 1)
- || (cur_line->type != FILE_LINE_ACTION))
- {
- /* Invalid "sectionid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- get_string_param(parameters, "p", &action_set_name);
- if (action_set_name != NULL)
- {
- for (index = 0; index < MAX_ACTION_FILES; index++)
- {
- if (((fl = csp->actions_list[index]) != NULL) && ((b = fl->f) != NULL))
- {
- for (b = b->next; NULL != b; b = b->next)
- {
- if (!strncmp(b->url->spec, "standard.", 9) && !strcmp(b->url->spec + 9, action_set_name))
- {
- copy_action(cur_line->data.action, b->action);
- goto found;
- }
- }
- }
- }
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
-
- found: ;
- }
- else
- {
- err = actions_from_radio(parameters, cur_line->data.action);
- }
-
- if(err)
- {
- /* Out of memory */
- edit_free_file(file);
- return err;
- }
-
- ch = get_char_param(parameters, "filter_all");
- if (ch == 'N')
- {
- list_remove_all(cur_line->data.action->multi_add[ACTION_MULTI_FILTER]);
- list_remove_all(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]);
- cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 1;
- }
- else if (ch == 'X')
- {
- cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 0;
- }
-
- for (index = 0; !err; index++)
- {
- char key_value[30];
- char key_name[30];
- const char *name;
- char value;
-
- /* Generate the keys */
- snprintf(key_value, sizeof(key_value), "filter_r%x", index);
- key_value[sizeof(key_value) - 1] = '\0';
- snprintf(key_name, sizeof(key_name), "filter_n%x", index);
- key_name[sizeof(key_name) - 1] = '\0';
-
- err = get_string_param(parameters, key_name, &name);
- if (err) break;
-
- if (name == NULL)
- {
- /* End of list */
- break;
- }
-
- value = get_char_param(parameters, key_value);
- if (value == 'Y')
- {
- list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
- if (!err) err = enlist(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
- list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
- }
- else if (value == 'N')
- {
- list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
- if (!cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER])
- {
- list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
- if (!err) err = enlist(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
- }
- }
- else if (value == 'X')
- {
- list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
- list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
- }
- }
-
- if(err)
- {
- /* Out of memory */
- edit_free_file(file);
- return err;
- }
-
- if (NULL == (actiontext = actions_to_text(cur_line->data.action)))
- {
- /* Out of memory */
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- len = strlen(actiontext);
- if (len == 0)
- {
- /*
- * Empty action - must special-case this.
- * Simply setting len to 1 is sufficient...
- */
- len = 1;
- }
-
- if (NULL == (newtext = malloc(len + 2)))
- {
- /* Out of memory */
- free(actiontext);
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
- strcpy(newtext, actiontext);
- free(actiontext);
- newtext[0] = '{';
- newtext[len] = '}';
- newtext[len + 1] = '\0';
-
- freez(cur_line->raw);
- freez(cur_line->unprocessed);
- cur_line->unprocessed = newtext;
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
- string_join(&target, section_target(sectionid));
-
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_url
- *
- * Description : CGI function that actually edits a URL pattern in
- * an actions file.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * filename : Identifies the file to edit
- * ver : File's last-modified time
- * section : Line number of section to edit
- * pattern : Line number of pattern to edit
- * newval : New value for pattern
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned patternid;
- char * new_pattern;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- unsigned section_start_line_number = 0;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "p", &patternid);
- if (err)
- {
- return err;
- }
- if (patternid < 1U)
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- err = get_url_spec_param(csp, parameters, "u", &new_pattern);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- free(new_pattern);
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- line_number = 1;
- cur_line = file->lines;
-
- while ((cur_line != NULL) && (line_number < patternid))
- {
- if (cur_line->type == FILE_LINE_ACTION)
- {
- section_start_line_number = line_number;
- }
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_URL))
- {
- /* Invalid "patternid" parameter */
- free(new_pattern);
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* At this point, the line to edit is in cur_line */
-
- freez(cur_line->raw);
- freez(cur_line->unprocessed);
- cur_line->unprocessed = new_pattern;
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
- string_join(&target, section_target(section_start_line_number));
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_add_url
- *
- * Description : CGI function that actually adds a URL pattern to
- * an actions file.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * filename : Identifies the file to edit
- * ver : File's last-modified time
- * section : Line number of section to edit
- * newval : New pattern
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_add_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned sectionid;
- char * new_pattern;
- struct file_line * new_line;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s", §ionid);
- if (err)
- {
- return err;
- }
- if (sectionid < 1U)
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- err = get_url_spec_param(csp, parameters, "u", &new_pattern);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- free(new_pattern);
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- line_number = 1;
- cur_line = file->lines;
-
- while ((cur_line != NULL) && (line_number < sectionid))
- {
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_ACTION))
- {
- /* Invalid "sectionid" parameter */
- free(new_pattern);
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* At this point, the section header is in cur_line - add after this. */
-
- /* Allocate the new line */
- new_line = (struct file_line *)zalloc(sizeof(*new_line));
- if (new_line == NULL)
- {
- free(new_pattern);
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- /* Fill in the data members of the new line */
- new_line->raw = NULL;
- new_line->prefix = NULL;
- new_line->unprocessed = new_pattern;
- new_line->type = FILE_LINE_URL;
-
- /* Link new_line into the list, after cur_line */
- new_line->next = cur_line->next;
- cur_line->next = new_line;
-
- /* Done making changes, now commit */
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
- string_join(&target, section_target(sectionid));
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_remove_url
- *
- * Description : CGI function that actually removes a URL pattern from
- * the actions file.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * p : (pattern) Line number of pattern to remove
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_remove_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned patternid;
- struct editable_file * file;
- struct file_line * cur_line;
- struct file_line * prev_line;
- unsigned line_number;
- unsigned section_start_line_number = 0;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "p", &patternid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- line_number = 1;
- prev_line = NULL;
- cur_line = file->lines;
-
- while ((cur_line != NULL) && (line_number < patternid))
- {
- if (cur_line->type == FILE_LINE_ACTION)
- {
- section_start_line_number = line_number;
- }
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (prev_line == NULL)
- || (cur_line->type != FILE_LINE_URL))
- {
- /* Invalid "patternid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* At this point, the line to remove is in cur_line, and the previous
- * one is in prev_line
- */
-
- /* Unlink cur_line */
- prev_line->next = cur_line->next;
- cur_line->next = NULL;
-
- /* Free cur_line */
- edit_free_file_lines(cur_line);
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
- string_join(&target, section_target(section_start_line_number));
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_section_remove
- *
- * Description : CGI function that actually removes a whole section from
- * the actions file. The section must be empty first
- * (else JB_ERR_CGI_PARAMS).
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * s : (section) Line number of section to edit
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_section_remove(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned sectionid;
- struct editable_file * file;
- struct file_line * cur_line;
- struct file_line * prev_line;
- unsigned line_number;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s", §ionid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- line_number = 1;
- cur_line = file->lines;
-
- prev_line = NULL;
- while ((cur_line != NULL) && (line_number < sectionid))
- {
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_ACTION) )
- {
- /* Invalid "sectionid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- if ( (cur_line->next != NULL)
- && (cur_line->next->type == FILE_LINE_URL) )
- {
- /* Section not empty. */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* At this point, the line to remove is in cur_line, and the previous
- * one is in prev_line
- */
-
- /* Unlink cur_line */
- if (prev_line == NULL)
- {
- /* Removing the first line from the file */
- file->lines = cur_line->next;
- }
- else
- {
- prev_line->next = cur_line->next;
- }
- cur_line->next = NULL;
-
- /* Free cur_line */
- edit_free_file_lines(cur_line);
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_section_add
- *
- * Description : CGI function that adds a new empty section to
- * an actions file.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * s : (section) Line number of section to add after, 0 for
- * start of file.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_section_add(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned sectionid;
- struct file_line * new_line;
- char * new_text;
- struct editable_file * file;
- struct file_line * cur_line;
- unsigned line_number;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s", §ionid);
- if (err)
- {
- return err;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- line_number = 1;
- cur_line = file->lines;
-
- if (sectionid < 1U)
- {
- /* Add to start of file */
- if (cur_line != NULL)
- {
- /* There's something in the file, find the line before the first
- * action.
- */
- while ( (cur_line->next != NULL)
- && (cur_line->next->type != FILE_LINE_ACTION) )
- {
- cur_line = cur_line->next;
- line_number++;
- }
- }
- }
- else
- {
- /* Add after stated section. */
- while ((cur_line != NULL) && (line_number < sectionid))
- {
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_ACTION))
- {
- /* Invalid "sectionid" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* Skip through the section to find the last line in it. */
- while ( (cur_line->next != NULL)
- && (cur_line->next->type != FILE_LINE_ACTION) )
- {
- cur_line = cur_line->next;
- line_number++;
- }
- }
-
- /* At this point, the last line in the previous section is in cur_line
- * - add after this. (Or if we need to add as the first line, cur_line
- * will be NULL).
- */
-
- new_text = strdup("{}");
- if (NULL == new_text)
- {
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- /* Allocate the new line */
- new_line = (struct file_line *)zalloc(sizeof(*new_line));
- if (new_line == NULL)
- {
- free(new_text);
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
-
- /* Fill in the data members of the new line */
- new_line->raw = NULL;
- new_line->prefix = NULL;
- new_line->unprocessed = new_text;
- new_line->type = FILE_LINE_ACTION;
-
- if (cur_line != NULL)
- {
- /* Link new_line into the list, after cur_line */
- new_line->next = cur_line->next;
- cur_line->next = new_line;
- }
- else
- {
- /* Link new_line into the list, as first line */
- new_line->next = file->lines;
- file->lines = new_line;
- }
-
- /* Done making changes, now commit */
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_edit_actions_section_swap
- *
- * Description : CGI function that swaps the order of two sections
- * in the actions file. Note that this CGI can actually
- * swap any two arbitrary sections, but the GUI interface
- * currently only allows consecutive sections to be
- * specified.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * f : (filename) Identifies the file to edit
- * v : (version) File's last-modified time
- * s1 : (section1) Line number of first section to swap
- * s2 : (section2) Line number of second section to swap
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- * JB_ERR_CGI_PARAMS if the CGI parameters are not
- * specified or not valid.
- *
- *********************************************************************/
-jb_err cgi_edit_actions_section_swap(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- unsigned section1;
- unsigned section2;
- struct editable_file * file;
- struct file_line * cur_line;
- struct file_line * prev_line;
- struct file_line * line_before_section1;
- struct file_line * line_start_section1;
- struct file_line * line_end_section1;
- struct file_line * line_after_section1;
- struct file_line * line_before_section2;
- struct file_line * line_start_section2;
- struct file_line * line_end_section2;
- struct file_line * line_after_section2;
- unsigned line_number;
- char * target;
- jb_err err;
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- err = get_number_param(csp, parameters, "s1", §ion1);
- if (!err) err = get_number_param(csp, parameters, "s2", §ion2);
- if (err)
- {
- return err;
- }
-
- if (section1 > section2)
- {
- unsigned temp = section2;
- section2 = section1;
- section1 = temp;
- }
-
- err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
- if (err)
- {
- /* No filename specified, can't read file, modified, or out of memory. */
- return (err == JB_ERR_FILE ? JB_ERR_OK : err);
- }
-
- /* Start at the beginning... */
- line_number = 1;
- cur_line = file->lines;
- prev_line = NULL;
-
- /* ... find section1 ... */
- while ((cur_line != NULL) && (line_number < section1))
- {
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_ACTION) )
- {
- /* Invalid "section1" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* If no-op, we've validated params and can skip the rest. */
- if (section1 != section2)
- {
- /* ... find the end of section1 ... */
- line_before_section1 = prev_line;
- line_start_section1 = cur_line;
- do
- {
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
- while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL));
- line_end_section1 = prev_line;
- line_after_section1 = cur_line;
-
- /* ... find section2 ... */
- while ((cur_line != NULL) && (line_number < section2))
- {
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
-
- if ( (cur_line == NULL)
- || (cur_line->type != FILE_LINE_ACTION) )
- {
- /* Invalid "section2" parameter */
- edit_free_file(file);
- return JB_ERR_CGI_PARAMS;
- }
-
- /* ... find the end of section2 ... */
- line_before_section2 = prev_line;
- line_start_section2 = cur_line;
- do
- {
- prev_line = cur_line;
- cur_line = cur_line->next;
- line_number++;
- }
- while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL));
- line_end_section2 = prev_line;
- line_after_section2 = cur_line;
-
- /* Now have all the pointers we need. Do the swap. */
-
- /* Change the pointer to section1 to point to section2 instead */
- if (line_before_section1 == NULL)
- {
- file->lines = line_start_section2;
- }
- else
- {
- line_before_section1->next = line_start_section2;
- }
-
- if (line_before_section2 == line_end_section1)
- {
- /* Consecutive sections */
- line_end_section2->next = line_start_section1;
- }
- else
- {
- line_end_section2->next = line_after_section1;
- line_before_section2->next = line_start_section1;
- }
-
- /* Set the pointer from the end of section1 to the rest of the file */
- line_end_section1->next = line_after_section2;
-
- err = edit_write_file(file);
- if (err)
- {
- /* Error writing file */
- if (err == JB_ERR_FILE)
- {
- /* Read-only file. */
- err = cgi_error_file_read_only(csp, rsp, file->identifier);
- }
- edit_free_file(file);
- return err;
- }
- } /* END if (section1 != section2) */
-
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
-
- edit_free_file(file);
-
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_toggle
- *
- * Description : CGI function that adds a new empty section to
- * an actions file.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * set : If present, how to change toggle setting:
- * "enable", "disable", "toggle", or none (default).
- * mini : If present, use mini reply template.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-jb_err cgi_toggle(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map *exports;
- char mode;
- const char *template_name;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_TOGGLE))
- {
- return cgi_error_disabled(csp, rsp);
- }
-
- mode = get_char_param(parameters, "set");
-
- if (mode == 'E')
- {
- /* Enable */
- g_bToggleIJB = 1;
- }
- else if (mode == 'D')
- {
- /* Disable */
- g_bToggleIJB = 0;
- }
- else if (mode == 'T')
- {
- /* Toggle */
- g_bToggleIJB = !g_bToggleIJB;
- }
-
- if (NULL == (exports = default_exports(csp, "toggle")))
- {
- return JB_ERR_MEMORY;
- }
-
- template_name = (get_char_param(parameters, "mini")
- ? "toggle-mini"
- : "toggle");
-
- return template_fill_for_cgi(csp, template_name, exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : javascriptify
- *
- * Description : Converts a string into a form JavaScript will like.
- *
- * Netscape 4's JavaScript sucks - it doesn't use
- * "id" parameters, so you have to set the "name"
- * used to submit a form element to something JavaScript
- * will like. (Or access the elements by index in an
- * array. That array contains >60 elements and will
- * be changed whenever we add a new action to the
- * editor, so I'm NOT going to use indexes that have
- * to be figured out by hand.)
- *
- * Currently the only thing we have to worry about
- * is "-" ==> "_" conversion.
- *
- * This is a length-preserving operation so it is
- * carried out in-place, no memory is allocated
- * or freed.
- *
- * Parameters :
- * 1 : identifier = String to make JavaScript-friendly.
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void javascriptify(char * identifier)
-{
- char * p = identifier;
- while (NULL != (p = strchr(p, '-')))
- {
- *p++ = '_';
- }
-}
-
-
-/*********************************************************************
- *
- * Function : actions_to_radio
- *
- * Description : Converts a actionsfile entry into settings for
- * radio buttons and edit boxes on a HTML form.
- *
- * Parameters :
- * 1 : exports = List of substitutions to add to.
- * 2 : action = Action to read
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-static jb_err actions_to_radio(struct map * exports,
- const struct action_spec *action)
-{
- unsigned mask = action->mask;
- unsigned add = action->add;
- int mapped_param;
- int checked;
- char current_mode;
-
- assert(exports);
- assert(action);
-
- mask = action->mask;
- add = action->add;
-
- /* sanity - prevents "-feature +feature" */
- mask |= add;
-
-
-#define DEFINE_ACTION_BOOL(name, bit) \
- if (!(mask & bit)) \
- { \
- current_mode = 'n'; \
- } \
- else if (add & bit) \
- { \
- current_mode = 'y'; \
- } \
- else \
- { \
- current_mode = 'x'; \
- } \
- if (map_radio(exports, name, "ynx", current_mode)) \
- { \
- return JB_ERR_MEMORY; \
- }
-
-#define DEFINE_ACTION_STRING(name, bit, index) \
- DEFINE_ACTION_BOOL(name, bit); \
- mapped_param = 0;
-
-#define DEFINE_CGI_PARAM_RADIO(name, bit, index, value, is_default) \
- if (add & bit) \
- { \
- checked = !strcmp(action->string[index], value); \
- } \
- else \
- { \
- checked = is_default; \
- } \
- mapped_param |= checked; \
- if (map(exports, name "-param-" value, 1, (checked ? "checked" : ""), 1)) \
- { \
- return JB_ERR_MEMORY; \
- }
-
-#define DEFINE_CGI_PARAM_CUSTOM(name, bit, index, default_val) \
- if (map(exports, name "-param-custom", 1, \
- ((!mapped_param) ? "checked" : ""), 1)) \
- { \
- return JB_ERR_MEMORY; \
- } \
- if (map(exports, name "-param", 1, \
- (((add & bit) && !mapped_param) ? \
- action->string[index] : default_val), 1)) \
- { \
- return JB_ERR_MEMORY; \
- }
-
-#define DEFINE_CGI_PARAM_NO_RADIO(name, bit, index, default_val) \
- if (map(exports, name "-param", 1, \
- ((add & bit) ? action->string[index] : default_val), 1)) \
- { \
- return JB_ERR_MEMORY; \
- }
-
-#define DEFINE_ACTION_MULTI(name, index) \
- if (action->multi_add[index]->first) \
- { \
- current_mode = 'y'; \
- } \
- else if (action->multi_remove_all[index]) \
- { \
- current_mode = 'n'; \
- } \
- else if (action->multi_remove[index]->first) \
- { \
- current_mode = 'y'; \
- } \
- else \
- { \
- current_mode = 'x'; \
- } \
- if (map_radio(exports, name, "ynx", current_mode)) \
- { \
- return JB_ERR_MEMORY; \
- }
-
-#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-#undef DEFINE_CGI_PARAM_CUSTOM
-#undef DEFINE_CGI_PARAM_RADIO
-#undef DEFINE_CGI_PARAM_NO_RADIO
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : actions_from_radio
- *
- * Description : Converts a map of parameters passed to a CGI function
- * into an actionsfile entry.
- *
- * Parameters :
- * 1 : parameters = parameters to the CGI call
- * 2 : action = Action to change. Must be valid before
- * the call, actions not specified will be
- * left unchanged.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-static jb_err actions_from_radio(const struct map * parameters,
- struct action_spec *action)
-{
- static int first_time = 1;
- const char * param;
- char * param_dup;
- char ch;
- const char * js_name;
- jb_err err = JB_ERR_OK;
-
- assert(parameters);
- assert(action);
-
- /* Statics are generally a potential race condition,
- * but in this case we're safe and don't need semaphores.
- * Be careful if you modify this function.
- * - Jon
- */
-
-#define JAVASCRIPTIFY(dest_var, string) \
- { \
- static char js_name_arr[] = string; \
- if (first_time) \
- { \
- javascriptify(js_name_arr); \
- } \
- dest_var = js_name_arr; \
- } \
-
-#define DEFINE_ACTION_BOOL(name, bit) \
- JAVASCRIPTIFY(js_name, name); \
- ch = get_char_param(parameters, js_name); \
- if (ch == 'Y') \
- { \
- action->add |= bit; \
- action->mask |= bit; \
- } \
- else if (ch == 'N') \
- { \
- action->add &= ~bit; \
- action->mask &= ~bit; \
- } \
- else if (ch == 'X') \
- { \
- action->add &= ~bit; \
- action->mask |= bit; \
- } \
-
-#define DEFINE_ACTION_STRING(name, bit, index) \
- JAVASCRIPTIFY(js_name, name); \
- ch = get_char_param(parameters, js_name); \
- if (ch == 'Y') \
- { \
- param = NULL; \
- JAVASCRIPTIFY(js_name, name "-mode"); \
- if (!err) err = get_string_param(parameters, js_name, ¶m); \
- if ((param == NULL) || (0 == strcmp(param, "CUSTOM"))) \
- { \
- JAVASCRIPTIFY(js_name, name "-param"); \
- if (!err) err = get_string_param(parameters, js_name, ¶m); \
- } \
- if (param != NULL) \
- { \
- if (NULL == (param_dup = strdup(param))) \
- { \
- return JB_ERR_MEMORY; \
- } \
- freez(action->string[index]); \
- action->add |= bit; \
- action->mask |= bit; \
- action->string[index] = param_dup; \
- } \
- } \
- else if (ch == 'N') \
- { \
- if (action->add & bit) \
- { \
- freez(action->string[index]); \
- } \
- action->add &= ~bit; \
- action->mask &= ~bit; \
- } \
- else if (ch == 'X') \
- { \
- if (action->add & bit) \
- { \
- freez(action->string[index]); \
- } \
- action->add &= ~bit; \
- action->mask |= bit; \
- } \
-
-#define DEFINE_ACTION_MULTI(name, index) \
- JAVASCRIPTIFY(js_name, name); \
- ch = get_char_param(parameters, js_name); \
- if (ch == 'Y') \
- { \
- /* FIXME */ \
- } \
- else if (ch == 'N') \
- { \
- list_remove_all(action->multi_add[index]); \
- list_remove_all(action->multi_remove[index]); \
- action->multi_remove_all[index] = 1; \
- } \
- else if (ch == 'X') \
- { \
- list_remove_all(action->multi_add[index]); \
- list_remove_all(action->multi_remove[index]); \
- action->multi_remove_all[index] = 0; \
- } \
-
-#define DEFINE_ACTION_ALIAS 0 /* No aliases for URL parsing */
-
-#include "actionlist.h"
-
-#undef DEFINE_ACTION_MULTI
-#undef DEFINE_ACTION_STRING
-#undef DEFINE_ACTION_BOOL
-#undef DEFINE_ACTION_ALIAS
-#undef JAVASCRIPTIFY
-
- first_time = 0;
-
- return err;
-}
-
-
-#endif /* def FEATURE_CGI_EDIT_ACTIONS */
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef CGIEDIT_H_INCLUDED
-#define CGIEDIT_H_INCLUDED
-#define CGIEDIT_H_VERSION "$Id: cgiedit.h,v 1.6 2002/03/24 13:25:43 swa Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgiedit.h,v $
- *
- * Purpose : CGI-based actionsfile editor.
- *
- * Functions declared include:
- *
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgiedit.h,v $
- * Revision 1.6 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.5 2002/01/22 23:24:48 jongfoster
- * Adding edit-actions-section-swap
- *
- * Revision 1.4 2001/11/13 00:28:51 jongfoster
- * Adding new CGIs for use by non-JavaScript browsers:
- * edit-actions-url-form
- * edit-actions-add-url-form
- * edit-actions-remove-url-form
- *
- * Revision 1.3 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle JunkBuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.2 2001/10/14 22:12:49 jongfoster
- * New version of CGI-based actionsfile editor.
- * Major changes, including:
- * - Completely new file parser and file output routines
- * - edit-actions CGI renamed edit-actions-for-url
- * - All CGIs now need a filename parameter, except for...
- * - New CGI edit-actions which doesn't need a filename,
- * to allow you to start the editor up.
- * - edit-actions-submit now works, and now automatically
- * redirects you back to the main edit-actions-list handler.
- *
- * Revision 1.1 2001/09/16 15:47:37 jongfoster
- * First version of CGI-based edit interface. This is very much a
- * work-in-progress, and you can't actually use it to edit anything
- * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
- * to have any effect.
- *
- *
- **********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * CGI functions
- */
-#ifdef FEATURE_CGI_EDIT_ACTIONS
-extern jb_err cgi_edit_actions (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_for_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_list (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_submit (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_url (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_add_url(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_add_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_remove_url (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_section_remove(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_section_add (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_edit_actions_section_swap (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_toggle(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-#endif /* def FEATURE_CGI_EDIT_ACTIONS */
-
-
-/* Revision control strings from this header and associated .c file */
-extern const char cgiedit_rcs[];
-extern const char cgiedit_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef CGI_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.34 2002/04/30 12:06:12 oes Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
- *
- * Purpose : Simple CGIs to get information about Privoxy's
- * status.
- *
- * Functions declared include:
- *
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgisimple.c,v $
- * Revision 1.34 2002/04/30 12:06:12 oes
- * Deleted unused code from default_cgi
- *
- * Revision 1.33 2002/04/30 11:14:52 oes
- * Made csp the first parameter in *action_to_html
- *
- * Revision 1.32 2002/04/26 18:29:13 jongfoster
- * Fixing this Visual C++ warning:
- * cgisimple.c(775) : warning C4018: '<' : signed/unsigned mismatch
- *
- * Revision 1.31 2002/04/26 12:54:36 oes
- * - Kill obsolete REDIRECT_URL code
- * - Error handling fixes
- * - Style sheet related HTML snipplet changes
- * - cgi_show_url_info:
- * - Matches now in table, actions on single lines,
- * linked to help
- * - standard.action suppressed
- * - Buttons to View and Edit AFs
- *
- * Revision 1.30 2002/04/24 02:18:08 oes
- * - show-status is now the starting point for editing
- * the actions files, generate list of all AFs with buttons
- * for viewing and editing, new look for file list (Jon:
- * buttons now aligned ;-P ), view mode now supports multiple
- * AFs, name changes, no view links for unspecified files,
- * no edit link for standard.action.
- *
- * - Jon's multiple AF patch: cgi_show_url_info now uses all
- * AFs and marks the output accordingly
- *
- * Revision 1.29 2002/04/10 13:38:35 oes
- * load_template signature changed
- *
- * Revision 1.28 2002/04/07 15:42:12 jongfoster
- * Fixing send-banner?type=auto when the image-blocker is
- * a redirect to send-banner
- *
- * Revision 1.27 2002/04/05 15:50:48 oes
- * added send-stylesheet CGI
- *
- * Revision 1.26 2002/04/04 00:36:36 gliptak
- * always use pcre for matching
- *
- * Revision 1.25 2002/04/03 22:28:03 gliptak
- * Removed references to gnu_regex
- *
- * Revision 1.24 2002/04/02 16:12:47 oes
- * Fix: moving misplaced lines into #ifdef FEATURE_FORCE
- *
- * Revision 1.23 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.22 2002/03/24 16:18:15 jongfoster
- * Removing old logo
- *
- * Revision 1.21 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.20 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.19 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.18 2002/03/12 01:44:49 oes
- * Changed default for "blocked" image from jb logo to checkboard pattern
- *
- * Revision 1.17 2002/03/08 16:43:18 oes
- * Added choice beween GIF and PNG built-in images
- *
- * Revision 1.16 2002/03/07 03:48:38 oes
- * - Changed built-in images from GIF to PNG
- * (with regard to Unisys patent issue)
- * - Added a 4x4 pattern PNG which is less intrusive
- * than the logo but also clearly marks the deleted banners
- *
- * Revision 1.15 2002/03/06 22:54:35 jongfoster
- * Automated function-comment nitpicking.
- *
- * Revision 1.14 2002/03/02 04:14:50 david__schmidt
- * Clean up a little CRLF unpleasantness that suddenly appeared
- *
- * Revision 1.13 2002/02/21 00:10:37 jongfoster
- * Adding send-banner?type=auto option
- *
- * Revision 1.12 2002/01/23 01:03:32 jongfoster
- * Fixing gcc [CygWin] compiler warnings
- *
- * Revision 1.11 2002/01/23 00:01:04 jongfoster
- * Adding cgi_transparent_gif() for http://i.j.b/t
- * Adding missing html_encode() to many CGI functions.
- * Adding urlmatch.[ch] to http://i.j.b/show-version
- *
- * Revision 1.10 2002/01/17 21:10:37 jongfoster
- * Changes to cgi_show_url_info to use new matching code from urlmatch.c.
- * Also fixing a problem in the same function with improperly quoted URLs
- * in output HTML, and adding code to handle https:// URLs correctly.
- *
- * Revision 1.9 2001/11/30 23:09:15 jongfoster
- * Now reports on FEATURE_CGI_EDIT_ACTIONS
- * Removing FEATURE_DENY_GZIP from template
- *
- * Revision 1.8 2001/11/13 00:14:07 jongfoster
- * Fixing stupid bug now I've figured out what || means.
- * (It always returns 0 or 1, not one of it's paramaters.)
- *
- * Revision 1.7 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle JunkBuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.6 2001/10/14 22:00:32 jongfoster
- * Adding support for a 404 error when an invalid CGI page is requested.
- *
- * Revision 1.5 2001/10/07 15:30:41 oes
- * Removed FEATURE_DENY_GZIP
- *
- * Revision 1.4 2001/10/02 15:31:12 oes
- * Introduced show-request cgi
- *
- * Revision 1.3 2001/09/22 16:34:44 jongfoster
- * Removing unneeded #includes
- *
- * Revision 1.2 2001/09/19 18:01:11 oes
- * Fixed comments; cosmetics
- *
- * Revision 1.1 2001/09/16 17:08:54 jongfoster
- * Moving simple CGI functions from cgi.c to new file cgisimple.c
- *
- *
- **********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-
-#ifdef _WIN32
-#define snprintf _snprintf
-#endif /* def _WIN32 */
-
-#include "project.h"
-#include "cgi.h"
-#include "cgisimple.h"
-#include "list.h"
-#include "encode.h"
-#include "jcc.h"
-#include "filters.h"
-#include "actions.h"
-#include "miscutil.h"
-#include "loadcfg.h"
-#include "parsers.h"
-#include "urlmatch.h"
-#include "errlog.h"
-
-const char cgisimple_h_rcs[] = CGISIMPLE_H_VERSION;
-
-
-static char *show_rcs(void);
-static jb_err show_defines(struct map *exports);
-
-
-/*********************************************************************
- *
- * Function : cgi_default
- *
- * Description : CGI function that is called for the CGI_SITE_1_HOST
- * and CGI_SITE_2_HOST/CGI_SITE_2_PATH base URLs.
- * Boring - only exports the default exports.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory
- *
- *********************************************************************/
-jb_err cgi_default(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map *exports;
-
- assert(csp);
- assert(rsp);
-
- if (NULL == (exports = default_exports(csp, "")))
- {
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "default", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_error_404
- *
- * Description : CGI function that is called if an unknown action was
- * given.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_error_404(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map *exports;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (NULL == (exports = default_exports(csp, NULL)))
- {
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("404 Privoxy configuration page not found");
- if (rsp->status == NULL)
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "cgi-error-404", exports, rsp);
-}
-
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-/*********************************************************************
- *
- * Function : cgi_die
- *
- * Description : CGI function to shut down Privoxy.
- * NOTE: Turning this on in a production build
- * would be a BAD idea. An EXTREMELY BAD idea.
- * In short, don't do it.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_die (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- /* quit */
- g_terminate = 1;
-
- /*
- * I don't really care what gets sent back to the browser.
- * Take the easy option - "out of memory" page.
- */
-
- return JB_ERR_MEMORY;
-}
-#endif /* def FEATURE_GRACEFUL_TERMINATION */
-
-
-/*********************************************************************
- *
- * Function : cgi_show_request
- *
- * Description : Show the client's request and what sed() would have
- * made of it.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_show_request(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char *p;
- struct map *exports;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (NULL == (exports = default_exports(csp, "show-request")))
- {
- return JB_ERR_MEMORY;
- }
-
- /*
- * Repair the damage done to the IOB by get_header()
- */
- for (p = csp->iob->buf; p < csp->iob->eod; p++)
- {
- if (*p == '\0') *p = '\n';
- }
-
- /*
- * Export the original client's request and the one we would
- * be sending to the server if this wasn't a CGI call
- */
-
- if (map(exports, "client-request", 1, html_encode(csp->iob->buf), 0))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- if (map(exports, "processed-request", 1, html_encode_and_free_original(
- sed(client_patterns, add_client_headers, csp)), 0))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "show-request", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_send_banner
- *
- * Description : CGI function that returns a banner.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * type : Selects the type of banner between "trans", "logo",
- * and "auto". Defaults to "logo" if absent or invalid.
- * "auto" means to select as if we were image-blocking.
- * (Only the first character really counts).
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_send_banner(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char imagetype = lookup(parameters, "type")[0];
-
- if (imagetype == 'a') /* auto */
- {
- /* Default to pattern */
- imagetype = 'p';
-#ifdef FEATURE_IMAGE_BLOCKING
- if ((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0)
- {
- static const char prefix1[] = CGI_PREFIX "send-banner?type=";
- static const char prefix2[] = "http://" CGI_SITE_1_HOST "/send-banner?type=";
-
- /* determine HOW images should be blocked */
- const char * p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];
-
- /* and handle accordingly: */
- if (p == NULL)
- {
- /* Use default - nothing to do here. */
- }
- else if (0 == strcmpic(p, "blank"))
- {
- imagetype = 'b';
- }
- else if (0 == strcmpic(p, "pattern"))
- {
- imagetype = 'p';
- }
- else if (0 == strncmpic(p, prefix1, sizeof(prefix1) - 1))
- {
- imagetype = p[sizeof(prefix1) - 1];
- }
- else if (0 == strncmpic(p, prefix2, sizeof(prefix2) - 1))
- {
- imagetype = p[sizeof(prefix2) - 1];
- }
- }
-#endif /* def FEATURE_IMAGE_BLOCKING */
- }
-
- if ((imagetype == 'b') || (imagetype == 't')) /* blank / transparent */
- {
- rsp->body = bindup(image_blank_data, image_blank_length);
- rsp->content_length = image_blank_length;
-
- }
- else /* pattern */
- {
- rsp->body = bindup(image_pattern_data, image_pattern_length);
- rsp->content_length = image_pattern_length;
- }
-
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- if (enlist(rsp->headers, "Content-Type: " BUILTIN_IMAGE_MIMETYPE))
- {
- return JB_ERR_MEMORY;
- }
-
- rsp->is_static = 1;
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_transparent_image
- *
- * Description : CGI function that sends a 1x1 transparent image.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_transparent_image(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- rsp->body = bindup(image_blank_data, image_blank_length);
- rsp->content_length = image_blank_length;
-
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- if (enlist(rsp->headers, "Content-Type: " BUILTIN_IMAGE_MIMETYPE))
- {
- return JB_ERR_MEMORY;
- }
-
- rsp->is_static = 1;
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_send_stylesheet
- *
- * Description : CGI function that sends a css stylesheet found
- * in the cgi-style.css template
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_send_stylesheet(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- jb_err err;
-
- assert(csp);
- assert(rsp);
-
- err = template_load(csp, &rsp->body, "cgi-style.css", 0);
-
- if (err == JB_ERR_FILE)
- {
- /*
- * No way to tell user; send empty stylesheet
- */
- log_error(LOG_LEVEL_ERROR, "Could not find cgi-style.css template");
- }
- else if (err)
- {
- return err; /* JB_ERR_MEMORY */
- }
-
- if (enlist(rsp->headers, "Content-Type: text/css"))
- {
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_show_version
- *
- * Description : CGI function that returns a a web page describing the
- * file versions of Privoxy.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : none
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_show_version(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- struct map *exports;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (NULL == (exports = default_exports(csp, "show-version")))
- {
- return JB_ERR_MEMORY;
- }
-
- if (map(exports, "sourceversions", 1, show_rcs(), 0))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "show-version", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_show_status
- *
- * Description : CGI function that returns a a web page describing the
- * current status of Privoxy.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * file : Which file to show. Only first letter is checked,
- * valid values are:
- * - "p"ermissions (actions) file
- * - "r"egex
- * - "t"rust
- * Default is to show menu and other information.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_show_status(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char *s = NULL;
- unsigned i;
- int j;
-
- FILE * fp;
- char buf[BUFFER_SIZE];
- const char * filename = NULL;
- char * file_description = NULL;
-#ifdef FEATURE_STATISTICS
- float perc_rej; /* Percentage of http requests rejected */
- int local_urls_read;
- int local_urls_rejected;
-#endif /* ndef FEATURE_STATISTICS */
- struct file_list * fl;
- struct url_actions * b;
- jb_err err = JB_ERR_OK;
-
- struct map *exports;
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (NULL == (exports = default_exports(csp, "show-status")))
- {
- return JB_ERR_MEMORY;
- }
-
- switch (*(lookup(parameters, "file")))
- {
- case 'a':
- if (!get_number_param(csp, parameters, "index", &i) && i < MAX_ACTION_FILES && csp->actions_list[i])
- {
- filename = csp->actions_list[i]->filename;
- file_description = "Actions File";
- }
- break;
-
- case 'f':
- if (csp->rlist)
- {
- filename = csp->rlist->filename;
- file_description = "Filter File";
- }
- break;
-
-#ifdef FEATURE_TRUST
- case 't':
- if (csp->tlist)
- {
- filename = csp->tlist->filename;
- file_description = "Trust File";
- }
- break;
-#endif /* def FEATURE_TRUST */
- }
-
- if (NULL != filename)
- {
- if ( map(exports, "file-description", 1, file_description, 1)
- || map(exports, "filepath", 1, html_encode(filename), 0) )
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- if ((fp = fopen(filename, "r")) == NULL)
- {
- if (map(exports, "content", 1, "<h1>ERROR OPENING FILE!</h1>", 1))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- }
- else
- {
- s = strdup("");
- while ((s != NULL) && fgets(buf, sizeof(buf), fp))
- {
- string_join (&s, html_encode(buf));
- }
- fclose(fp);
-
- if (map(exports, "contents", 1, s, 0))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- }
-
- return template_fill_for_cgi(csp, "show-status-file", exports, rsp);
- }
-
- s = strdup("");
- for (j = 0; (s != NULL) && (j < Argc); j++)
- {
- if (!err) err = string_join (&s, html_encode(Argv[j]));
- if (!err) err = string_append(&s, " ");
- }
- if (!err) err = map(exports, "invocation", 1, s, 0);
-
- if (!err) err = map(exports, "options", 1, csp->config->proxy_args, 1);
- if (!err) err = show_defines(exports);
-
- if (err)
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
-#ifdef FEATURE_STATISTICS
- local_urls_read = urls_read;
- local_urls_rejected = urls_rejected;
-
- /*
- * Need to alter the stats not to include the fetch of this
- * page.
- *
- * Can't do following thread safely! doh!
- *
- * urls_read--;
- * urls_rejected--; * This will be incremented subsequently *
- */
-
- if (local_urls_read == 0)
- {
- if (!err) err = map_block_killer(exports, "have-stats");
- }
- else
- {
- if (!err) err = map_block_killer(exports, "have-no-stats");
-
- perc_rej = (float)local_urls_rejected * 100.0F /
- (float)local_urls_read;
-
- sprintf(buf, "%d", local_urls_read);
- if (!err) err = map(exports, "requests-received", 1, buf, 1);
-
- sprintf(buf, "%d", local_urls_rejected);
- if (!err) err = map(exports, "requests-blocked", 1, buf, 1);
-
- sprintf(buf, "%6.2f", perc_rej);
- if (!err) err = map(exports, "percent-blocked", 1, buf, 1);
- }
-
-#else /* ndef FEATURE_STATISTICS */
- err = err || map_block_killer(exports, "statistics");
-#endif /* ndef FEATURE_STATISTICS */
-
- /*
- * List all action files in use, together with view and edit links,
- * except for standard.action, which should only be viewable. (Not
- * enforced in the editor itself)
- * FIXME: Shouldn't include hardwired HTML here, use line template instead!
- */
- s = strdup("");
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
- {
- if (!err) err = string_append(&s, "<tr><td>");
- if (!err) err = string_join(&s, html_encode(csp->actions_list[i]->filename));
- snprintf(buf, 100, "</td><td class=\"buttons\"><a href=\"/show-status?file=actions&index=%d\">View</a> ", i);
- if (!err) err = string_append(&s, buf);
-
- if (NULL == strstr(csp->actions_list[i]->filename, "standard.action") && NULL != csp->config->actions_file_short[i])
- {
- snprintf(buf, 100, "<a href=\"/edit-actions-list?f=%s\">Edit</a>", csp->config->actions_file_short[i]);
- if (!err) err = string_append(&s, buf);
- }
-
- if (!err) err = string_append(&s, "</td></tr>\n");
- }
- }
- if (*s != '\0')
- {
- if (!err) err = map(exports, "actions-filenames", 1, s, 0);
- }
- else
- {
- if (!err) err = map(exports, "actions-filenames", 1, "<tr><td>None specified</td></tr>", 1);
- }
-
- if (csp->rlist)
- {
- if (!err) err = map(exports, "re-filter-filename", 1, html_encode(csp->rlist->filename), 0);
- }
- else
- {
- if (!err) err = map(exports, "re-filter-filename", 1, "None specified", 1);
- if (!err) err = map_block_killer(exports, "have-filterfile");
- }
-
-#ifdef FEATURE_TRUST
- if (csp->tlist)
- {
- if (!err) err = map(exports, "trust-filename", 1, html_encode(csp->tlist->filename), 0);
- }
- else
- {
- if (!err) err = map(exports, "trust-filename", 1, "None specified", 1);
- if (!err) err = map_block_killer(exports, "have-trustfile");
- }
-#else
- if (!err) err = map_block_killer(exports, "trust-support");
-#endif /* ndef FEATURE_TRUST */
-
- if (err)
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "show-status", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_show_url_info
- *
- * Description : CGI function that determines and shows which actions
- * Privoxy will perform for a given url, and which
- * matches starting from the defaults have lead to that.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters :
- * url : The url whose actions are to be determined.
- * If url is unset, the url-given conditional will be
- * set, so that all but the form can be suppressed in
- * the template.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_show_url_info(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char *url_param;
- struct map *exports;
- char buf[150];
-
- assert(csp);
- assert(rsp);
- assert(parameters);
-
- if (NULL == (exports = default_exports(csp, "show-url-info")))
- {
- return JB_ERR_MEMORY;
- }
-
- /*
- * Get the url= parameter (if present) and remove any leading/trailing spaces.
- */
- url_param = strdup(lookup(parameters, "url"));
- if (url_param == NULL)
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- chomp(url_param);
-
- /*
- * Handle prefixes. 4 possibilities:
- * 1) "http://" or "https://" prefix present and followed by URL - OK
- * 2) Only the "http://" or "https://" part is present, no URL - change
- * to empty string so it will be detected later as "no URL".
- * 3) Parameter specified but doesn't contain "http(s?)://" - add a
- * "http://" prefix.
- * 4) Parameter not specified or is empty string - let this fall through
- * for now, next block of code will handle it.
- */
- if (0 == strncmp(url_param, "http://", 7))
- {
- if (url_param[7] == '\0')
- {
- /*
- * Empty URL (just prefix).
- * Make it totally empty so it's caught by the next if()
- */
- url_param[0] = '\0';
- }
- }
- else if (0 == strncmp(url_param, "https://", 8))
- {
- if (url_param[8] == '\0')
- {
- /*
- * Empty URL (just prefix).
- * Make it totally empty so it's caught by the next if()
- */
- url_param[0] = '\0';
- }
- }
- else if (url_param[0] != '\0')
- {
- /*
- * Unknown prefix - assume http://
- */
- char * url_param_prefixed = malloc(7 + 1 + strlen(url_param));
- if (NULL == url_param_prefixed)
- {
- free(url_param);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- strcpy(url_param_prefixed, "http://");
- strcpy(url_param_prefixed + 7, url_param);
- free(url_param);
- url_param = url_param_prefixed;
- }
-
-
- if (url_param[0] == '\0')
- {
- /* URL paramater not specified, display query form only. */
- free(url_param);
- if (map_block_killer(exports, "url-given")
- || map(exports, "url", 1, "", 1))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- }
- else
- {
- /* Given a URL, so query it. */
- jb_err err;
- char *matches;
- char *s;
- int hits = 0;
- struct file_list *fl;
- struct url_actions *b;
- struct http_request url_to_query[1];
- struct current_action_spec action[1];
- int i;
-
- if (map(exports, "url", 1, html_encode(url_param), 0))
- {
- free(url_param);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- init_current_action(action);
-
- if (map(exports, "default", 1, current_action_to_html(csp, action), 0))
- {
- free_current_action(action);
- free(url_param);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- err = parse_http_url(url_param, url_to_query, csp);
-
- free(url_param);
-
- if (err == JB_ERR_MEMORY)
- {
- free_current_action(action);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- else if (err)
- {
- /* Invalid URL */
-
- err = map(exports, "matches", 1, "<b>[Invalid URL specified!]</b>" , 1);
- if (!err) err = map(exports, "final", 1, lookup(exports, "default"), 1);
-
- free_current_action(action);
-
- if (err)
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
- }
-
- /*
- * We have a warning about SSL paths. Hide it for insecure sites.
- */
- if (!url_to_query->ssl)
- {
- if (map_block_killer(exports, "https"))
- {
- free_current_action(action);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- }
-
- matches = strdup("<table class=\"transparent\">");
-
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (NULL == csp->config->actions_file_short[i]
- || !strcmp(csp->config->actions_file_short[i], "standard")) continue;
-
- b = NULL;
- hits = 1;
- if ((fl = csp->actions_list[i]) != NULL)
- {
- if ((b = fl->f) != NULL)
- {
- /* FIXME: Hardcoded HTML! */
- string_append(&matches, "<tr><th>In file: ");
- string_join (&matches, html_encode(csp->config->actions_file_short[i]));
- snprintf(buf, 150, ".action <a class=\"cmd\" href=\"/show-status?file=actions&index=%d\">", i);
- string_append(&matches, buf);
- string_append(&matches, "View</a> <a class=\"cmd\" href=\"/edit-actions-list?f=");
- string_join (&matches, html_encode(csp->config->actions_file_short[i]));
- string_append(&matches, "\">Edit</a></th></tr>\n");
-
- hits = 0;
- b = b->next;
- }
- }
-
- for (; (b != NULL) && (matches != NULL); b = b->next)
- {
- if (url_match(b->url, url_to_query))
- {
- string_append(&matches, "<tr><td>{");
- string_join (&matches, actions_to_html(csp, b->action));
- string_append(&matches, " }</b><br>\n<code>");
- string_join (&matches, html_encode(b->url->spec));
- string_append(&matches, "</code></td></tr>\n");
-
- if (merge_current_action(action, b->action))
- {
- freez(matches);
- free_http_request(url_to_query);
- free_current_action(action);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- hits++;
- }
- }
-
- if (!hits)
- {
- string_append(&matches, "<tr><td>(no matches in this file)</td></tr>\n");
- }
- }
- string_append(&matches, "</table>\n");
-
- free_http_request(url_to_query);
-
- if (matches == NULL)
- {
- free_current_action(action);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- if (map(exports, "matches", 1, matches , 0))
- {
- free_current_action(action);
- free_map(exports);
- return JB_ERR_MEMORY;
- }
-
- s = current_action_to_html(csp, action);
-
- free_current_action(action);
-
- if (map(exports, "final", 1, s, 0))
- {
- free_map(exports);
- return JB_ERR_MEMORY;
- }
- }
-
- return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
-}
-
-
-/*********************************************************************
- *
- * Function : cgi_robots_txt
- *
- * Description : CGI function to return "/robots.txt".
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : rsp = http_response data structure for output
- * 3 : parameters = map of cgi parameters
- *
- * CGI Parameters : None
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err cgi_robots_txt(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters)
-{
- char buf[100];
- jb_err err;
-
- rsp->body = strdup(
- "# This is the Privoxy control interface.\n"
- "# It isn't very useful to index it, and you're likely to break stuff.\n"
- "# So go away!\n"
- "\n"
- "User-agent: *\n"
- "Disallow: /\n"
- "\n");
- if (rsp->body == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- err = enlist_unique(rsp->headers, "Content-Type: text/plain", 13);
-
- rsp->is_static = 1;
-
- get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */
- if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf);
-
- return (err ? JB_ERR_MEMORY : JB_ERR_OK);
-}
-
-
-/*********************************************************************
- *
- * Function : show_defines
- *
- * Description : Add to a map the state od all conditional #defines
- * used when building
- *
- * Parameters :
- * 1 : exports = map to extend
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-static jb_err show_defines(struct map *exports)
-{
- jb_err err = JB_ERR_OK;
-
-#ifdef FEATURE_ACL
- if (!err) err = map_conditional(exports, "FEATURE_ACL", 1);
-#else /* ifndef FEATURE_ACL */
- if (!err) err = map_conditional(exports, "FEATURE_ACL", 0);
-#endif /* ndef FEATURE_ACL */
-
-#ifdef FEATURE_CGI_EDIT_ACTIONS
- if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 1);
-#else /* ifndef FEATURE_COOKIE_JAR */
- if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 0);
-#endif /* ndef FEATURE_COOKIE_JAR */
-
-#ifdef FEATURE_COOKIE_JAR
- if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 1);
-#else /* ifndef FEATURE_COOKIE_JAR */
- if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 0);
-#endif /* ndef FEATURE_COOKIE_JAR */
-
-#ifdef FEATURE_FAST_REDIRECTS
- if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1);
-#else /* ifndef FEATURE_FAST_REDIRECTS */
- if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 0);
-#endif /* ndef FEATURE_FAST_REDIRECTS */
-
-#ifdef FEATURE_FORCE_LOAD
- if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 1);
- if (!err) err = map(exports, "FORCE_PREFIX", 1, FORCE_PREFIX, 1);
-#else /* ifndef FEATURE_FORCE_LOAD */
- if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 0);
- if (!err) err = map(exports, "FORCE_PREFIX", 1, "(none - disabled)", 1);
-#endif /* ndef FEATURE_FORCE_LOAD */
-
-#ifdef FEATURE_IMAGE_BLOCKING
- if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 1);
-#else /* ifndef FEATURE_IMAGE_BLOCKING */
- if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 0);
-#endif /* ndef FEATURE_IMAGE_BLOCKING */
-
-#ifdef FEATURE_IMAGE_DETECT_MSIE
- if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 1);
-#else /* ifndef FEATURE_IMAGE_DETECT_MSIE */
- if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 0);
-#endif /* ndef FEATURE_IMAGE_DETECT_MSIE */
-
-#ifdef FEATURE_KILL_POPUPS
- if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 1);
-#else /* ifndef FEATURE_KILL_POPUPS */
- if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 0);
-#endif /* ndef FEATURE_KILL_POPUPS */
-
-#ifdef FEATURE_NO_GIFS
- if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 1);
-#else /* ifndef FEATURE_NO_GIFS */
- if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 0);
-#endif /* ndef FEATURE_NO_GIFS */
-
-#ifdef FEATURE_PTHREAD
- if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 1);
-#else /* ifndef FEATURE_PTHREAD */
- if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 0);
-#endif /* ndef FEATURE_PTHREAD */
-
-#ifdef FEATURE_STATISTICS
- if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 1);
-#else /* ifndef FEATURE_STATISTICS */
- if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 0);
-#endif /* ndef FEATURE_STATISTICS */
-
-#ifdef FEATURE_TOGGLE
- if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 1);
-#else /* ifndef FEATURE_TOGGLE */
- if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 0);
-#endif /* ndef FEATURE_TOGGLE */
-
-#ifdef FEATURE_TRUST
- if (!err) err = map_conditional(exports, "FEATURE_TRUST", 1);
-#else /* ifndef FEATURE_TRUST */
- if (!err) err = map_conditional(exports, "FEATURE_TRUST", 0);
-#endif /* ndef FEATURE_TRUST */
-
-#ifdef STATIC_PCRE
- if (!err) err = map_conditional(exports, "STATIC_PCRE", 1);
-#else /* ifndef STATIC_PCRE */
- if (!err) err = map_conditional(exports, "STATIC_PCRE", 0);
-#endif /* ndef STATIC_PCRE */
-
-#ifdef STATIC_PCRS
- if (!err) err = map_conditional(exports, "STATIC_PCRS", 1);
-#else /* ifndef STATIC_PCRS */
- if (!err) err = map_conditional(exports, "STATIC_PCRS", 0);
-#endif /* ndef STATIC_PCRS */
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : show_rcs
- *
- * Description : Create a string with the rcs info for all sourcefiles
- *
- * Parameters : None
- *
- * Returns : A string, or NULL on out-of-memory.
- *
- *********************************************************************/
-static char *show_rcs(void)
-{
- char *result = strdup("");
- char buf[BUFFER_SIZE];
-
- /* Instead of including *all* dot h's in the project (thus creating a
- * tremendous amount of dependencies), I will concede to declaring them
- * as extern's. This forces the developer to add to this list, but oh well.
- */
-
-#define SHOW_RCS(__x) \
- { \
- extern const char __x[]; \
- sprintf(buf, "%s\n", __x); \
- string_append(&result, buf); \
- }
-
- /* In alphabetical order */
- SHOW_RCS(actions_h_rcs)
- SHOW_RCS(actions_rcs)
-#ifdef AMIGA
- SHOW_RCS(amiga_h_rcs)
- SHOW_RCS(amiga_rcs)
-#endif /* def AMIGA */
- SHOW_RCS(cgi_h_rcs)
- SHOW_RCS(cgi_rcs)
-#ifdef FEATURE_CGI_EDIT_ACTIONS
- SHOW_RCS(cgiedit_h_rcs)
- SHOW_RCS(cgiedit_rcs)
-#endif /* def FEATURE_CGI_EDIT_ACTIONS */
- SHOW_RCS(cgisimple_h_rcs)
- SHOW_RCS(cgisimple_rcs)
-#ifdef __MINGW32__
- SHOW_RCS(cygwin_h_rcs)
-#endif
- SHOW_RCS(deanimate_h_rcs)
- SHOW_RCS(deanimate_rcs)
- SHOW_RCS(encode_h_rcs)
- SHOW_RCS(encode_rcs)
- SHOW_RCS(errlog_h_rcs)
- SHOW_RCS(errlog_rcs)
- SHOW_RCS(filters_h_rcs)
- SHOW_RCS(filters_rcs)
- SHOW_RCS(gateway_h_rcs)
- SHOW_RCS(gateway_rcs)
- SHOW_RCS(jbsockets_h_rcs)
- SHOW_RCS(jbsockets_rcs)
- SHOW_RCS(jcc_h_rcs)
- SHOW_RCS(jcc_rcs)
-#ifdef FEATURE_KILL_POPUPS
- SHOW_RCS(killpopup_h_rcs)
- SHOW_RCS(killpopup_rcs)
-#endif /* def FEATURE_KILL_POPUPS */
- SHOW_RCS(list_h_rcs)
- SHOW_RCS(list_rcs)
- SHOW_RCS(loadcfg_h_rcs)
- SHOW_RCS(loadcfg_rcs)
- SHOW_RCS(loaders_h_rcs)
- SHOW_RCS(loaders_rcs)
- SHOW_RCS(miscutil_h_rcs)
- SHOW_RCS(miscutil_rcs)
- SHOW_RCS(parsers_h_rcs)
- SHOW_RCS(parsers_rcs)
- SHOW_RCS(pcrs_rcs)
- SHOW_RCS(pcrs_h_rcs)
- SHOW_RCS(project_h_rcs)
- SHOW_RCS(ssplit_h_rcs)
- SHOW_RCS(ssplit_rcs)
- SHOW_RCS(urlmatch_h_rcs)
- SHOW_RCS(urlmatch_rcs)
-#ifdef _WIN32
-#ifndef _WIN_CONSOLE
- SHOW_RCS(w32log_h_rcs)
- SHOW_RCS(w32log_rcs)
- SHOW_RCS(w32res_h_rcs)
- SHOW_RCS(w32taskbar_h_rcs)
- SHOW_RCS(w32taskbar_rcs)
-#endif /* ndef _WIN_CONSOLE */
- SHOW_RCS(win32_h_rcs)
- SHOW_RCS(win32_rcs)
-#endif /* def _WIN32 */
-
-#undef SHOW_RCS
-
- return result;
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef CGISIMPLE_H_INCLUDED
-#define CGISIMPLE_H_INCLUDED
-#define CGISIMPLE_H_VERSION "$Id: cgisimple.h,v 1.10 2002/03/26 22:29:54 swa Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/cgisimple.h,v $
- *
- * Purpose : Declares functions to intercept request, generate
- * html or gif answers, and to compose HTTP resonses.
- *
- * Functions declared include:
- *
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: cgisimple.h,v $
- * Revision 1.10 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.9 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.8 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.7 2002/03/08 16:43:59 oes
- * Renamed cgi_transparent_png to cgi_transparent_image
- *
- * Revision 1.6 2002/03/07 03:48:59 oes
- * - Changed built-in images from GIF to PNG
- * (with regard to Unisys patent issue)
- *
- * Revision 1.5 2002/01/22 23:26:03 jongfoster
- * Adding cgi_transparent_gif() for http://i.j.b/t
- *
- * Revision 1.4 2001/10/23 21:48:19 jongfoster
- * Cleaning up error handling in CGI functions - they now send back
- * a HTML error page and should never cause a FATAL error. (Fixes one
- * potential source of "denial of service" attacks).
- *
- * CGI actions file editor that works and is actually useful.
- *
- * Ability to toggle JunkBuster remotely using a CGI call.
- *
- * You can turn off both the above features in the main configuration
- * file, e.g. if you are running a multi-user proxy.
- *
- * Revision 1.3 2001/10/14 22:00:32 jongfoster
- * Adding support for a 404 error when an invalid CGI page is requested.
- *
- * Revision 1.2 2001/10/02 15:31:20 oes
- * Introduced show-request cgi
- *
- * Revision 1.1 2001/09/16 17:08:54 jongfoster
- * Moving simple CGI functions from cgi.c to new file cgisimple.c
- *
- *
- **********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * CGI functions
- */
-extern jb_err cgi_default (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_error_404 (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_robots_txt (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_send_banner (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_show_status (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_show_url_info(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_show_version (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_show_request (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_transparent_image (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-extern jb_err cgi_send_stylesheet(struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-extern jb_err cgi_die (struct client_state *csp,
- struct http_response *rsp,
- const struct map *parameters);
-#endif
-
-/* Revision control strings from this header and associated .c file */
-extern const char cgisimple_rcs[];
-extern const char cgisimple_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef CGISIMPLE_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: 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
- *
- *
- *********************************************************************/
-
-/* Conditionally include this whole file. */
-#ifdef __MINGW32__
-
-/* Hmmm, seems to be overlooked. */
-#define _RICHEDIT_VER 0x0300
-
-/*
- * Named slightly different ... but not in Cygwin v1.3.1 ...
- *
- * #define LVITEM LV_ITEM
- * #define LVCOLUMN LV_COLUMN
- */
-
-#endif /* def __MINGW32__ */
-#endif /* ndef CYGWIN_H_INCLUDED */
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char deanimate_rcs[] = "$Id: deanimate.c,v 1.11 2002/03/26 22:29:54 swa Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/deanimate.c,v $
- *
- * Purpose : Declares functions to deanimate GIF images on the fly.
- *
- * Functions declared include: gif_deanimate, buf_free,
- * buf_copy, buf_getbyte, gif_skip_data_block, and
- * gif_extract_image
- *
- * Copyright : Written by and Copyright (C) 2001 by the the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the GIF file format specification (see
- * http://tronche.com/computer-graphics/gif/gif89a.html)
- * and ideas from the Image::DeAnim Perl module by
- * Ken MacFarlane, <ksm+cpan@universal.dca.net>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: deanimate.c,v $
- * Revision 1.11 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.10 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.9 2002/03/13 00:27:04 jongfoster
- * Killing warnings
- *
- * Revision 1.8 2002/03/09 19:42:47 jongfoster
- * Fixing more warnings
- *
- * Revision 1.7 2002/03/08 17:46:04 jongfoster
- * Fixing int/size_t warnings
- *
- * Revision 1.6 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.5 2001/09/10 10:16:06 oes
- * Silenced compiler warnings
- *
- * Revision 1.4 2001/07/18 12:28:49 oes
- * - Added feature for extracting the first frame
- * to gif_deanimate
- * - Separated image buffer extension into buf_extend
- * - Extended gif deanimation to GIF87a (untested!)
- * - Cosmetics
- *
- * Revision 1.3 2001/07/15 13:57:50 jongfoster
- * Adding #includes string.h and miscutil.h
- *
- * Revision 1.2 2001/07/13 13:46:20 oes
- * Introduced GIF deanimation feature
- *
- *
- **********************************************************************/
-\f
-
-#include "config.h"
-
-#include <string.h>
-#include <fcntl.h>
-
-#include "project.h"
-#include "deanimate.h"
-#include "miscutil.h"
-
-const char deanimate_h_rcs[] = DEANIMATE_H_VERSION;
-
-/*********************************************************************
- *
- * Function : buf_free
- *
- * Description : Safely frees a struct binbuffer
- *
- * Parameters :
- * 1 : buf = Pointer to the binbuffer to be freed
- *
- * Returns : N/A
- *
- *********************************************************************/
-void buf_free(struct binbuffer *buf)
-{
- if (buf == NULL) return;
-
- if (buf->buffer != NULL)
- {
- free(buf->buffer);
- }
-
- free(buf);
-
-}
-
-
-/*********************************************************************
- *
- * Function : buf_extend
- *
- * Description : Ensure that a given binbuffer can hold a given amount
- * of bytes, by reallocating its buffer if necessary.
- * Allocate new mem in chunks of 1024 bytes, so we don't
- * have to realloc() too often.
- *
- * Parameters :
- * 1 : buf = Pointer to the binbuffer
- * 2 : length = Desired minimum size
- *
- *
- * Returns : 0 on success, 1 on failiure.
- *
- *********************************************************************/
-int buf_extend(struct binbuffer *buf, size_t length)
-{
- char *newbuf;
-
- if (buf->offset + length > buf->size)
- {
- buf->size = ((buf->size + length + (size_t)1023) & ~(size_t)1023);
- newbuf = (char *)realloc(buf->buffer, buf->size);
-
- if (newbuf == NULL)
- {
- freez(buf->buffer);
- return 1;
- }
- else
- {
- buf->buffer = newbuf;
- return 0;
- }
- }
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : buf_copy
- *
- * Description : Safely copies a given amount of bytes from one
- * struct binbuffer to another, advancing the
- * offsets appropriately.
- *
- * Parameters :
- * 1 : src = Pointer to the source binbuffer
- * 2 : dst = Pointer to the destination binbuffer
- * 3 : length = Number of bytes to be copied
- *
- * Returns : 0 on success, 1 on failiure.
- *
- *********************************************************************/
-int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
-{
-
- /*
- * Sanity check: Can't copy more data than we have
- */
- if (src->offset + length > src->size)
- {
- return 1;
- }
-
- /*
- * Ensure that dst can hold the new data
- */
- if (buf_extend(dst, length))
- {
- return 1;
- }
-
- /*
- * Now that it's safe, memcpy() the desired amount of
- * data from src to dst and adjust the offsets
- */
- memcpy(dst->buffer + dst->offset, src->buffer + src->offset, length);
- src->offset += length;
- dst->offset += length;
-
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : buf_getbyte
- *
- * Description : Safely gets a byte from a given binbuffer at a
- * given offset
- *
- * Parameters :
- * 1 : src = Pointer to the source binbuffer
- * 2 : offset = Offset to the desired byte
- *
- * Returns : The byte on success, or 0 on failiure
- *
- *********************************************************************/
-unsigned char buf_getbyte(struct binbuffer *src, size_t offset)
-{
- if (src->offset + offset < src->size)
- {
- return (unsigned char)*(src->buffer + src->offset + offset);
- }
- else
- {
- return '\0';
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : gif_skip_data_block
- *
- * Description : Safely advances the offset of a given struct binbuffer
- * that contains a GIF image and whose offset is
- * positioned at the start of a data block, behind
- * that block.
- *
- * Parameters :
- * 1 : buf = Pointer to the binbuffer
- *
- * Returns : 0 on success, or 1 on failiure
- *
- *********************************************************************/
-int gif_skip_data_block(struct binbuffer *buf)
-{
- unsigned char c;
-
- /*
- * Data blocks are sequences of chunks, which are headed
- * by a one-byte length field, with the last chunk having
- * zero length.
- */
- while((c = buf_getbyte(buf, 0)) != '\0')
- {
- if ((buf->offset += c + 1) >= buf->size - 1)
- {
- return 1;
- }
- }
- buf->offset++;
-
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : gif_extract_image
- *
- * Description : Safely extracts an image data block from a given
- * struct binbuffer that contains a GIF image and whose
- * offset is positioned at the start of a data block
- * into a given destination binbuffer.
- *
- * Parameters :
- * 1 : src = Pointer to the source binbuffer
- * 2 : dst = Pointer to the destination binbuffer
- *
- * Returns : 0 on success, or 1 on failiure
- *
- *********************************************************************/
-int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
-{
- unsigned char c;
-
- /*
- * Remember the colormap flag and copy the image head
- */
- c = buf_getbyte(src, 9);
- if (buf_copy(src, dst, 10))
- {
- return 1;
- }
-
- /*
- * If the image has a local colormap, copy it.
- */
- if (c & 0x80)
- {
- if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
- {
- return 1;
- }
- }
- if (buf_copy(src, dst, 1)) return 1;
-
- /*
- * Copy the image chunk by chunk.
- */
- while((c = buf_getbyte(src, 0)) != '\0')
- {
- if (buf_copy(src, dst, 1 + (size_t) c)) return 1;
- }
- if (buf_copy(src, dst, 1)) return 1;
-
- /*
- * Trim and rewind the dst buffer
- */
- if (NULL == (dst->buffer = (char *)realloc(dst->buffer, dst->offset))) return 1;
- dst->size = dst->offset;
- dst->offset = 0;
-
- return(0);
-
-}
-
-/*********************************************************************
- *
- * Function : gif_deanimate
- *
- * Description : Deanimate a given GIF image, i.e. given a GIF with
- * an (optional) image block and an arbitrary number
- * of image extension blocks, produce an output GIF with
- * only one image block that contains the last image
- * (extenstion) block of the original.
- * Also strip Comments, Application extenstions, etc.
- *
- * Parameters :
- * 1 : src = Pointer to the source binbuffer
- * 2 : dst = Pointer to the destination binbuffer
- * 3 : get_first_image = Flag: If set, get the first image
- * If unset (default), get the last
- *
- * Returns : 0 on success, or 1 on failiure
- *
- *********************************************************************/
-int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image)
-{
- unsigned char c;
- struct binbuffer *image;
-
- if (NULL == src || NULL == dst)
- {
- return 1;
- }
-
- c = buf_getbyte(src, 10);
-
- /*
- * Check & copy GIF header
- */
- if (strncmp(src->buffer, "GIF89a", 6) && strncmp(src->buffer, "GIF87a", 6))
- {
- return 1;
- }
- else
- {
- if (buf_copy(src, dst, 13))
- {
- return 1;
- }
- }
-
- /*
- * Look for global colormap and copy if found.
- */
- if(c & 0x80)
- {
- if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
- {
- return 1;
- }
- }
-
- /*
- * Reserve a buffer for the current image block
- */
- if (NULL == (image = (struct binbuffer *)zalloc(sizeof(*image))))
- {
- return 1;
- }
-
- /*
- * Parse the GIF block by block and copy the relevant
- * parts to dst
- */
- while(src->offset < src->size)
- {
- switch(buf_getbyte(src, 0))
- {
- /*
- * End-of-GIF Marker: Append current image and return
- */
- case 0x3b:
- goto write;
-
- /*
- * Image block: Extract to current image buffer.
- */
- case 0x2c:
- image->offset = 0;
- if (gif_extract_image(src, image)) goto failed;
- if (get_first_image) goto write;
- continue;
-
- /*
- * Extension block: Look at next byte and decide
- */
- case 0x21:
- switch (buf_getbyte(src, 1))
- {
- /*
- * Image extension: Copy extension header and image
- * to the current image buffer
- */
- case 0xf9:
- image->offset = 0;
- if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed;
- if (gif_extract_image(src, image)) goto failed;
- if (get_first_image) goto write;
- continue;
-
- /*
- * Application extension: Skip
- */
- case 0xff:
- if ((src->offset += 14) >= src->size || gif_skip_data_block(src)) goto failed;
- continue;
-
- /*
- * Comment extension: Skip
- */
- case 0xfe:
- if ((src->offset += 2) >= src->size || gif_skip_data_block(src)) goto failed;
- continue;
-
- /*
- * Plain text extension: Skip
- */
- case 0x01:
- if ((src->offset += 15) >= src->size || gif_skip_data_block(src)) goto failed;
- continue;
-
- /*
- * Ooops, what type of extension is that?
- */
- default:
- goto failed;
-
- }
-
- /*
- * Ooops, what type of block is that?
- */
- default:
- goto failed;
-
- }
- } /* -END- while src */
-
- /*
- * Either we got here by goto, or because the GIF is
- * bogus and EOF was reached before an end-of-gif marker
- * was found.
- */
-
-failed:
- buf_free(image);
- return 1;
-
- /*
- * Append the current image to dst and return
- */
-
-write:
- if (buf_copy(image, dst, image->size)) goto failed;
- if (buf_extend(dst, 1)) goto failed;
- *(dst->buffer + dst->offset++) = 0x3b;
- buf_free(image);
- return 0;
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef DEANIMATE_H_INCLUDED
-#define DEANIMATE_H_INCLUDED
-#define DEANIMATE_H_VERSION "$Id: deanimate.h,v 1.7 2002/03/24 13:25:43 swa Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/deanimate.h,v $
- *
- * Purpose : Declares functions to deanimate GIF images on the fly.
- *
- * Functions declared include: gif_deanimate, buf_free
- *
- *
- * Copyright : Written by and Copyright (C) 2001 Andreas S. Oesterhelt
- * for the Privoxy team. http://www.privoxy.org/
- *
- * Based on ideas from the Image::DeAnim Perl module by
- * Ken MacFarlane, <ksm+cpan@universal.dca.net>
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: deanimate.h,v $
- * Revision 1.7 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.6 2002/03/08 17:46:04 jongfoster
- * Fixing int/size_t warnings
- *
- * Revision 1.5 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.4 2001/07/29 18:50:04 jongfoster
- * Fixing "extern C" block, and renaming #define _DEANIMATE_H
- *
- * Revision 1.3 2001/07/18 12:29:05 oes
- * Updated prototype for gif_deanimate
- *
- * Revision 1.2 2001/07/13 13:46:20 oes
- * Introduced GIF deanimation feature
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * A struct that holds a buffer, a read/write offset,
- * and the buffer's capacity.
- */
-struct binbuffer
-{
- char *buffer;
- size_t offset;
- size_t size;
-};
-
-/*
- * Function prototypes
- */
-extern int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image);
-extern void buf_free(struct binbuffer *buf);
-
-/*
- * Revision control strings from this header and associated .c file
- */
-extern const char deanimate_rcs[];
-extern const char deanimate_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef DEANIMATE_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char encode_rcs[] = "$Id: encode.c,v 1.7 2002/03/24 13:25:43 swa Exp $";
-/*********************************************************************
- *
- * 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
- * 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: encode.c,v $
- * Revision 1.7 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.6 2002/03/13 00:27:04 jongfoster
- * Killing warnings
- *
- * Revision 1.5 2002/03/07 03:46:53 oes
- * Fixed compiler warnings etc
- *
- * Revision 1.4 2002/01/22 23:28:07 jongfoster
- * Adding convenience function html_encode_and_free_original()
- * Making all functions accept NULL paramaters - in this case, they
- * simply return NULL. This allows error-checking to be deferred.
- *
- * Revision 1.3 2001/11/13 00:16:40 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.2 2001/05/17 22:52:35 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:58:51 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "encode.h"
-
-const char encode_h_rcs[] = ENCODE_H_VERSION;
-
-/* Maps special characters in a URL to their equivalent % codes. */
-static const char * const url_code_map[256] = {
- NULL, "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09",
- "%0A", "%0B", "%0C", "%0D", "%0E", "%0F", "%10", "%11", "%12", "%13",
- "%14", "%15", "%16", "%17", "%18", "%19", "%1A", "%1B", "%1C", "%1D",
- "%1E", "%1F", "+", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
- "%28", "%29", NULL, "%2B", "%2C", NULL, NULL, "%2F", NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "%3A", "%3B",
- "%3C", "%3D", "%3E", "%3F", NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, "%5B", "%5C", "%5D", "%5E", NULL, "%60", NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, "%7B", "%7C", "%7D", "%7E", "%7F", "%80", "%81",
- "%82", "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8A", "%8B",
- "%8C", "%8D", "%8E", "%8F", "%90", "%91", "%92", "%93", "%94", "%95",
- "%96", "%97", "%98", "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F",
- "%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7", "%A8", "%A9",
- "%AA", "%AB", "%AC", "%AD", "%AE", "%AF", "%B0", "%B1", "%B2", "%B3",
- "%B4", "%B5", "%B6", "%B7", "%B8", "%B9", "%BA", "%BB", "%BC", "%BD",
- "%BE", "%BF", "%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7",
- "%C8", "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF", "%D0", "%D1",
- "%D2", "%D3", "%D4", "%D5", "%D6", "%D7", "%D8", "%D9", "%DA", "%DB",
- "%DC", "%DD", "%DE", "%DF", "%E0", "%E1", "%E2", "%E3", "%E4", "%E5",
- "%E6", "%E7", "%E8", "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF",
- "%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7", "%F8", "%F9",
- "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"
-};
-
-/* Maps special characters in HTML to their equivalent entites. */
-static const char * const html_code_map[256] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,""",NULL,NULL,NULL,"&",NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- "<",NULL,">",NULL,NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-/* Maps special characters in a cookie to their equivalent % codes. */
-static const char * const cookie_code_map[256] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, "+", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, "%2C",NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "%3B",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-
-/*********************************************************************
- *
- * Function : html_encode
- *
- * Description : Encodes a string so it's not interpreted as
- * containing HTML tags or entities.
- * Replaces <, >, &, and " with the appropriate HTML
- * entities.
- *
- * 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(const char *s)
-{
- char * buf;
-
- if (s == NULL)
- {
- return NULL;
- }
-
- /* each input char can expand to at most 6 chars */
- buf = (char *) malloc((strlen(s) * 6) + 1);
-
- if (buf)
- {
- char c;
- char * p = buf;
- while ( (c = *s++) != '\0')
- {
- const char * replace_with = html_code_map[(unsigned char) c];
- if(replace_with != NULL)
- {
- strcpy(p, replace_with);
- p += strlen(replace_with);
- }
- else
- {
- *p++ = c;
- }
- }
-
- *p = '\0';
- }
-
- 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
- *
- * Description : Encodes a string so it can be used in a cookie.
- * Replaces " ", ",", and ";" with the appropriate
- * codes.
- *
- * 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 * cookie_encode(const char *s)
-{
- 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')
- {
- const char * replace_with = cookie_code_map[(unsigned char) c];
- if (replace_with != NULL)
- {
- strcpy(p, replace_with);
- p += strlen(replace_with);
- }
- else
- {
- *p++ = c;
- }
- }
-
- *p = '\0';
- }
-
- return(buf);
-}
-
-/*********************************************************************
- *
- * Function : url_encode
- *
- * Description : Encodes a string so it can be used in a URL
- * query string. Replaces special characters with
- * the appropriate %xx codes.
- *
- * 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 * url_encode(const char *s)
-{
- 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')
- {
- const char * replace_with = url_code_map[(unsigned char) c];
- if (replace_with != NULL)
- {
- strcpy(p, replace_with);
- p += strlen(replace_with);
- }
- else
- {
- *p++ = c;
- }
- }
-
- *p = '\0';
-
- }
-
- return(buf);
-}
-
-
-/*********************************************************************
- *
- * Function : xdtoi
- *
- * Description : Converts a single hex digit to an integer.
- *
- * Parameters :
- * 1 : d = in the range of ['0'..'9', 'A'..'F', 'a'..'f']
- *
- * Returns : The integer value, or -1 for non-hex characters.
- *
- *********************************************************************/
-static int xdtoi(const int d)
-{
- if ((d >= '0') && (d <= '9'))
- {
- return(d - '0');
- }
- else if ((d >= 'a') && (d <= 'f'))
- {
- return(d - 'a' + 10);
- }
- else if ((d >= 'A') && (d <= 'F'))
- {
- return(d - 'A' + 10);
- }
- else
- {
- return(-1);
- }
-}
-
-
-/*********************************************************************
- *
- * Function : xtoi
- *
- * Description : Hex string to integer conversion.
- *
- * Parameters :
- * 1 : s = a 2 digit hex string (e.g. "1f"). Only the
- * first two characters will be looked at.
- *
- * Returns : The integer value, or 0 for non-hex strings.
- *
- *********************************************************************/
-static int xtoi(const char *s)
-{
- int d1, d2;
-
- d1 = xdtoi(*s);
- if(d1 >= 0)
- {
- d2 = xdtoi(*(s+1));
- if(d2 >= 0)
- {
- return (d1 << 4) + d2;
- }
- }
-
- return 0;
-}
-
-
-/*********************************************************************
- *
- * Function : url_decode
- *
- * Description : Decodes a URL query string, replacing %xx codes
- * with their decoded form.
- *
- * Parameters :
- * 1 : s = String to decode. Null-terminated.
- *
- * Returns : Decoded string, newly allocated on the heap.
- * Caller is responsible for freeing it with free().
- *
- *********************************************************************/
-char *url_decode(const char * s)
-{
- char *buf = malloc(strlen(s) + 1);
- char *q = buf;
-
- if (buf)
- {
- while (*s)
- {
- switch (*s)
- {
- case '+':
- s++;
- *q++ = ' ';
- break;
-
- case '%':
- if ((*q = xtoi(s + 1)) != '\0')
- {
- s += 3;
- q++;
- }
- else
- {
- /* malformed, just use it */
- *q++ = *s++;
- }
- break;
-
- default:
- *q++ = *s++;
- break;
- }
- }
- *q = '\0';
- }
-
- return(buf);
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: encode.h,v $
- * Revision 1.4 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.3 2002/01/22 23:28:07 jongfoster
- * Adding convenience function html_encode_and_free_original()
- * Making all functions accept NULL paramaters - in this case, they
- * simply return NULL. This allows error-checking to be deferred.
- *
- * Revision 1.2 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:51 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char * html_encode(const char *s);
-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[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef ENCODE_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char errlog_rcs[] = "$Id: errlog.c,v 1.39 2002/04/03 17:15:27 gliptak Exp $";
-/*********************************************************************
- *
- * 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
- * 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: errlog.c,v $
- * Revision 1.39 2002/04/03 17:15:27 gliptak
- * zero padding thread ids in log
- *
- * Revision 1.38 2002/03/31 17:18:59 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.37 2002/03/27 14:32:43 david__schmidt
- * More compiler warning message maintenance
- *
- * Revision 1.36 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.35 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.34 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.33 2002/03/13 00:27:04 jongfoster
- * Killing warnings
- *
- * Revision 1.32 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.31 2002/03/06 23:02:57 jongfoster
- * Removing tabs
- *
- * Revision 1.30 2002/03/05 22:43:45 david__schmidt
- * - Better error reporting on OS/2
- * - Fix double-slash comment (oops)
- *
- * Revision 1.29 2002/03/04 23:45:13 jongfoster
- * Printing thread ID if using Win32 native threads
- *
- * Revision 1.28 2002/03/04 17:59:59 oes
- * Deleted deletePidFile(), cosmetics
- *
- * Revision 1.27 2002/03/04 02:08:01 david__schmidt
- * Enable web editing of actions file on OS/2 (it had been broken all this time!)
- *
- * Revision 1.26 2002/01/09 19:05:45 steudten
- * Fix big memory leak.
- *
- * Revision 1.25 2002/01/09 14:32:08 oes
- * Added support for gmtime_r and localtime_r.
- *
- * Revision 1.24 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.23 2001/11/07 00:02:13 steudten
- * Add line number in error output for lineparsing for
- * actionsfile and configfile.
- * Special handling for CLF added.
- *
- * Revision 1.22 2001/11/05 23:43:05 steudten
- * Add time+date to log files.
- *
- * Revision 1.21 2001/10/25 03:40:47 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.20 2001/09/16 23:04:34 jongfoster
- * Fixing a warning
- *
- * Revision 1.19 2001/09/13 20:08:06 jongfoster
- * Adding support for LOG_LEVEL_CGI
- *
- * Revision 1.18 2001/09/10 11:27:24 oes
- * Declaration of w32_socket_strerr now conditional
- *
- * Revision 1.17 2001/09/10 10:17:13 oes
- * Removed unused variable; Fixed sprintf format
- *
- * Revision 1.16 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.15 2001/07/29 17:41:10 jongfoster
- * Now prints thread ID for each message (pthreads only)
- *
- * Revision 1.14 2001/07/19 19:03:48 haroon
- * - Added case for LOG_LEVEL_POPUPS
- *
- * Revision 1.13 2001/07/13 13:58:58 oes
- * - Added case for LOG_LEVEL_DEANIMATE
- * - Removed all #ifdef PCRS
- *
- * Revision 1.12 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.11 2001/06/01 18:14:49 jongfoster
- * Changing the calls to strerr() to check HAVE_STRERR (which is defined
- * in config.h if appropriate) rather than the NO_STRERR macro.
- *
- * Revision 1.10 2001/05/29 11:52:21 oes
- * Conditional compilation of w32_socket_error
- *
- * Revision 1.9 2001/05/28 16:15:17 jongfoster
- * Improved reporting of errors under Win32.
- *
- * Revision 1.8 2001/05/26 17:25:14 jongfoster
- * Added support for CLF (Common Log Format) and fixed LOG_LEVEL_LOG
- *
- * Revision 1.7 2001/05/26 15:21:28 jongfoster
- * Activity animation in Win32 GUI now works even if debug==0
- *
- * Revision 1.6 2001/05/25 21:55:08 jongfoster
- * Now cleans up properly on FATAL (removes taskbar icon etc)
- *
- * Revision 1.5 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.4 2001/05/21 19:32:54 jongfoster
- * Added another #ifdef _WIN_CONSOLE
- *
- * Revision 1.3 2001/05/20 01:11:40 jongfoster
- * Added support for LOG_LEVEL_FATAL
- * Renamed LOG_LEVEL_FRC to LOG_LEVEL_FORCE,
- * and LOG_LEVEL_REF to LOG_LEVEL_RE_FILTER
- *
- * Revision 1.2 2001/05/17 22:42:01 oes
- * - Cleaned CRLF's from the sources and related files
- * - Repaired logging for REF and FRC
- *
- * Revision 1.1.1.1 2001/05/15 13:58:51 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-#include "miscutil.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif /* !defined(_WIN32) && !defined(__OS2__) */
-
-#include <errno.h>
-#include <assert.h>
-#ifdef FEATURE_PTHREAD
-#include <pthread.h>
-#endif /* def FEATURE_PTHREAD */
-
-#ifdef _WIN32
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-#ifndef _WIN_CONSOLE
-#include "w32log.h"
-#endif /* ndef _WIN_CONSOLE */
-#endif /* def _WIN32 */
-
-#ifdef __OS2__
-#include <sys/socket.h> /* For sock_errno */
-#define INCL_DOS
-#include <os2.h>
-#endif
-
-#include "errlog.h"
-#include "project.h"
-#include "jcc.h"
-
-const char errlog_h_rcs[] = ERRLOG_H_VERSION;
-
-
-/*
- * LOG_LEVEL_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;
-
-/* logging detail level. */
-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_error_log
- *
- * Description : Initializes the logging module. Must call before
- * calling log_error.
- *
- * Parameters :
- * 1 : prog_name = The program name.
- * 2 : logfname = The logfile name, or NULL for stderr.
- * 3 : debuglevel = The debugging level.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void init_error_log(const char *prog_name, const char *logfname, int debuglevel)
-{
- FILE *fp;
-
- /* FIXME RACE HAZARD: should start critical section error_log_use here */
-
- /* set the logging detail level */
- debug = debuglevel | LOG_LEVEL_MINIMUM;
-
- if ((logfp != NULL) && (logfp != stderr))
- {
- log_error(LOG_LEVEL_INFO, "(Re-)Open logfile %s", logfname ? logfname : "none");
- fclose(logfp);
- }
- logfp = stderr;
-
- /* set the designated log file */
- if( logfname )
- {
- if( NULL == (fp = fopen(logfname, "a")) )
- {
- log_error(LOG_LEVEL_FATAL, "init_error_log(): can't open logfile: %s", logfname);
- }
-
- /* set logging to be completely unbuffered */
- setbuf(fp, NULL);
-
- logfp = fp;
- }
-
- log_error(LOG_LEVEL_INFO, "Privoxy version " VERSION);
- if (prog_name != NULL)
- {
- log_error(LOG_LEVEL_INFO, "Program name: %s", prog_name);
- }
-
- /* FIXME RACE HAZARD: should end critical section error_log_use here */
-
-} /* init_error_log */
-
-
-/*********************************************************************
- *
- * Function : log_error
- *
- * Description : This is the error-reporting and logging function.
- *
- * Parameters :
- * 1 : loglevel = the type of message to be logged
- * 2 : fmt = the main string we want logged, printf-like
- * 3 : ... = arguments to be inserted in fmt (printf-like).
- *
- * Returns : N/A
- *
- *********************************************************************/
-void log_error(int loglevel, char *fmt, ...)
-{
- va_list ap;
- 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) == 0)
- {
- return;
- }
-
- /* FIXME get current thread id */
-#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, "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, "Privoxy(%05ld) Request: ", this_thread);
- break;
- case LOG_LEVEL_CONNECT:
- 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, "Privoxy(%05ld) Header: ", this_thread);
- break;
- case LOG_LEVEL_INFO:
- 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, "Privoxy(%05ld) UNKNOWN LOG TYPE(%d): ", this_thread, loglevel);
- break;
- }
-
- /* get ready to scan var. args. */
- va_start( ap, fmt );
-
- /* build formatted message from fmt and var-args */
- while ((*src) && (outc < BUFFER_SIZE-2))
- {
- char tempbuf[BUFFER_SIZE];
- char *sval = NULL;
- int ival;
- unsigned uval;
- long lval;
- unsigned long ulval;
- int oldoutc;
- char ch;
-
- ch = *src++;
- if( ch != '%' )
- {
- outbuf[outc++] = ch;
- continue;
- }
-
- ch = *src++;
- switch (ch) {
- case '%':
- outbuf[outc++] = '%';
- break;
- case 'd':
- ival = va_arg( ap, int );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%d", ival);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'u':
- uval = va_arg( ap, unsigned );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%u", uval);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'l':
- /* this is a modifier that must be followed by u or d */
- ch = *src++;
- if (ch == 'd')
- {
- lval = va_arg( ap, long );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%ld", lval);
- }
- else if (ch == 'u')
- {
- ulval = va_arg( ap, unsigned long );
- oldoutc = outc;
- outc += sprintf(tempbuf, "%lu", ulval);
- }
- else
- {
- /* Error */
- 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 */
- if( !logfp )
- {
- logfp = stderr;
- }
- fputs(outbuf, logfp);
- /* FIXME RACE HAZARD: should end critical section error_log_use here */
- fatal_error(outbuf);
- /* Never get here */
- break;
- }
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, tempbuf);
- }
- else
- {
- outbuf[oldoutc] = '\0';
- }
- break;
- case 'c':
- /*
- * Note that char paramaters are converted to int, so we need to
- * pass "int" to va_arg. (See K&R, 2nd ed, section A7.3.2, page 202)
- */
- outbuf[outc++] = (char) va_arg( ap, int );
- break;
- case 's':
- sval = va_arg( ap, char * );
- oldoutc = outc;
- outc += strlen(sval);
- if (outc < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, sval);
- }
- else
- {
- 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 */
-#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 /* 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 < BUFFER_SIZE-1)
- {
- strcpy(outbuf + oldoutc, sval);
- }
- else
- {
- 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, "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 */
- if( !logfp )
- {
- logfp = stderr;
- }
- fputs(outbuf_save, logfp);
- /* FIXME RACE HAZARD: should end critical section error_log_use here */
- fatal_error(outbuf_save);
- /* Never get here */
- break;
-
- } /* switch( p ) */
-
- } /* for( p ... ) */
-
- /* done with var. args */
- va_end( ap );
-
- if (outc >= BUFFER_SIZE-2)
- {
- /* insufficient room for newline and trailing null. */
-
- static const char warning[] = "... [too long, truncated]\n";
-
- if (outc < BUFFER_SIZE)
- {
- /* Need to add terminating null in this case. */
- outbuf[outc] = '\0';
- }
-
- /* Truncate output */
- outbuf[BUFFER_SIZE - sizeof(warning)] = '\0';
-
- /* Append warning */
- strcat(outbuf, warning);
- }
- else
- {
- /* Add terminating newline and null */
- outbuf[outc++] = '\n';
- outbuf[outc] = '\0';
- }
-
- /* FIXME RACE HAZARD: should start critical section error_log_use here */
-
- /* deal with glibc stupidity - it won't let you initialize logfp */
- if( !logfp )
- {
- logfp = stderr;
- }
-
- 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_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:
-*/
+++ /dev/null
-#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: /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
- * 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: errlog.h,v $
- * Revision 1.12 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.11 2002/03/06 23:02:57 jongfoster
- * Removing tabs
- *
- * Revision 1.10 2001/09/13 20:08:06 jongfoster
- * Adding support for LOG_LEVEL_CGI
- *
- * Revision 1.9 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.8 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.7 2001/07/19 19:02:53 haroon
- * Added define for LOG_LEVEL_POPUPS
- *
- * Revision 1.6 2001/07/13 13:59:22 oes
- * - Added LOG_LEVEL_DEANIMATE
- * - Changed LOG_LEVEL_CLF
- * - Removed all #ifdef PCRS
- *
- * Revision 1.5 2001/05/26 17:25:14 jongfoster
- * Added support for CLF (Common Log Format) and fixed LOG_LEVEL_LOG
- *
- * Revision 1.4 2001/05/25 21:56:06 jongfoster
- * Added FIXME comment to (broken) LOG_LEVEL_LOG
- *
- * Revision 1.3 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.2 2001/05/20 01:11:40 jongfoster
- * Added support for LOG_LEVEL_FATAL
- * Renamed LOG_LEVEL_FRC to LOG_LEVEL_FORCE,
- * and LOG_LEVEL_REF to LOG_LEVEL_RE_FILTER
- *
- * Revision 1.1.1.1 2001/05/15 13:58:51 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 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 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_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, ...);
-
-/* Revision control strings from this header and associated .c file */
-extern const char errlog_rcs[];
-extern const char errlog_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef ERRLOG_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
-
+++ /dev/null
-const char filters_rcs[] = "$Id: filters.c,v 1.57 2002/04/08 20:38:34 swa Exp $";
-/*********************************************************************
- *
- * 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', `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
- * 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: filters.c,v $
- * Revision 1.57 2002/04/08 20:38:34 swa
- * fixed JB spelling
- *
- * Revision 1.56 2002/04/05 15:51:24 oes
- * - bugfix: error-pages now get correct request protocol
- * - fix for invalid HTML in trust info
- *
- * Revision 1.55 2002/04/02 16:13:51 oes
- * Fix: No "Go there anyway" for SSL
- *
- * Revision 1.54 2002/04/02 14:55:56 oes
- * Bugfix: is_untrusted_url() now depends on FEATURE_TRUST, not FEATURE_COOKIE_JAR
- *
- * Revision 1.53 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.52 2002/03/24 16:35:57 jongfoster
- * Removing logo
- *
- * Revision 1.51 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.50 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.49 2002/03/16 20:29:14 oes
- * Cosmetics
- *
- * Revision 1.48 2002/03/13 20:25:34 oes
- * Better logging for content filters
- *
- * Revision 1.47 2002/03/13 00:30:52 jongfoster
- * Killing warnings
- * Added option of always sending redirect for imageblock,
- * currently disabled with #if 0.
- *
- * Revision 1.46 2002/03/12 01:42:49 oes
- * Introduced modular filters
- *
- * Revision 1.45 2002/03/08 16:47:50 oes
- * Added choice beween GIF and PNG built-in images
- *
- * Revision 1.44 2002/03/07 03:49:31 oes
- * - Fixed compiler warnings etc
- * - Changed built-in images from GIF to PNG
- * (with regard to Unisys patent issue)
- * - Added a 4x4 pattern PNG which is less intrusive
- * than the logo but also clearly marks the deleted banners
- *
- * Revision 1.43 2002/01/22 23:51:59 jongfoster
- * Replacing strsav() with the safer string_append().
- *
- * Adding missing html_encode() to error message generators. Where encoded
- * and unencoded versions of a string were provided, removing the unencoded
- * one.
- *
- * Revision 1.42 2002/01/17 21:00:32 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Using a single, simple url_match(pattern,url) function - rather than
- * the 3-line match routine which was repeated all over the place.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Using parse_http_url() to parse URLs without faking a HTTP
- * request line for parse_http_request().
- *
- * Revision 1.41 2001/11/13 00:14:07 jongfoster
- * Fixing stupid bug now I've figured out what || means.
- * (It always returns 0 or 1, not one of it's paramaters.)
- *
- * Revision 1.40 2001/10/26 17:37:55 oes
- * - Re-enabled Netscape 200/404 bug workaround in block_url():
- * - Removed OS/2 special case
- * - Made block_url() independant from sed() having been run
- * - Made trust_url independant from sed() having been run
- * - Made is_imageurl independant from sed() having been run.
- * It now checks User-Agent: and Accept: by itself.
- *
- *
- * Revision 1.39 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.38 2001/10/23 21:32:33 jongfoster
- * Adding error-checking to selected functions
- *
- * Revision 1.37 2001/10/22 15:33:56 david__schmidt
- * Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
- * filters.c. Added a FIXME in front of the offending code. I'll gladly
- * put in a better/more robust fix for all parties if one is presented...
- * It seems that just returning 200 instead of 404 would pretty much fix
- * it for everyone, but I don't know all the history of the problem.
- *
- * Revision 1.36 2001/10/10 16:44:16 oes
- * Added match_portlist function
- *
- * Revision 1.35 2001/10/07 15:41:23 oes
- * Replaced 6 boolean members of csp with one bitmap (csp->flags)
- *
- * New function remove_chunked_transfer_coding that strips chunked
- * transfer coding to plain and is called by pcrs_filter_response
- * and gif_deanimate_response if neccessary
- *
- * Improved handling of zero-change re_filter runs
- *
- * pcrs_filter_response and gif_deanimate_response now remove
- * chunked transfer codeing before processing the body.
- *
- * Revision 1.34 2001/09/20 15:49:36 steudten
- *
- * Fix BUG: Change int size to size_t size in pcrs_filter_response().
- * See cgi.c fill_template().
- *
- * Revision 1.33 2001/09/16 17:05:14 jongfoster
- * Removing unused #include showarg.h
- *
- * Revision 1.32 2001/09/16 13:21:27 jongfoster
- * Changes to use new list functions.
- *
- * Revision 1.31 2001/09/16 11:38:02 jongfoster
- * Splitting fill_template() into 2 functions:
- * template_load() loads the file
- * template_fill() performs the PCRS regexps.
- * This is because the CGI edit interface has a "table row"
- * template which is used many times in the page - this
- * change means it's only loaded from disk once.
- *
- * Revision 1.30 2001/09/16 11:00:10 jongfoster
- * New function alloc_http_response, for symmetry with free_http_response
- *
- * Revision 1.29 2001/09/13 23:32:40 jongfoster
- * Moving image data to cgi.c rather than cgi.h
- * Fixing a GPF under Win32 (and any other OS that protects global
- * constants from being written to).
- *
- * Revision 1.28 2001/09/10 10:18:51 oes
- * Silenced compiler warnings
- *
- * Revision 1.27 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.26 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.25 2001/07/26 10:09:46 oes
- * Made browser detection a little less naive
- *
- * Revision 1.24 2001/07/25 17:22:51 oes
- * Added workaround for Netscape bug that prevents display of page when loading a component fails.
- *
- * Revision 1.23 2001/07/23 13:40:12 oes
- * Fixed bug that caused document body to be dropped when pcrs joblist was empty.
- *
- * Revision 1.22 2001/07/18 12:29:34 oes
- * - Made gif_deanimate_response respect
- * csp->action->string[ACTION_STRING_DEANIMATE]
- * - Logging cosmetics
- *
- * Revision 1.21 2001/07/13 13:59:53 oes
- * - Introduced gif_deanimate_response which shares the
- * generic content modification interface of pcrs_filter_response
- * and acts as a wrapper to deanimate.c:gif_deanimate()
- * - Renamed re_process_buffer to pcrs_filter_response
- * - pcrs_filter_response now returns NULL on failiure
- * - Removed all #ifdef PCRS
- *
- * Revision 1.20 2001/07/01 17:01:04 oes
- * Added comments and missing return statement in is_untrusted_url()
- *
- * Revision 1.19 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.18 2001/06/29 13:27:38 oes
- * - Cleaned up, renamed and reorderd functions
- * and improved comments
- *
- * - block_url:
- * - Ported to CGI platform. Now delivers
- * http_response or NULL
- * - Unified HTML and GIF generation (moved image detection
- * and GIF generation here from jcc.c:chat())
- * - Fixed HTTP status to:
- * - 403 (Forbidden) for the "blocked" HTML message
- * - 200 (OK) for GIF answers
- * - 302 (Redirect) for redirect to GIF
- *
- * - trust_url:
- * - Ported to CGI platform. Now delivers
- * http_response or NULL
- * - Separated detection of untrusted URL into
- * (bool)is_untrusted_url
- * - Added enforcement of untrusted requests
- *
- * - Moved redirect_url() from cgi.c to here
- * and ported it to the CGI platform
- *
- * - Removed logentry from cancelled commit
- *
- * Revision 1.17 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.16 2001/06/07 23:10:26 jongfoster
- * Allowing unanchored domain patterns to back off and retry
- * if they partially match. Optimized right-anchored patterns.
- * Moving ACL and forward files into config file.
- * Replacing struct gateway with struct forward_spec
- *
- * Revision 1.15 2001/06/03 19:12:00 oes
- * extracted-CGI relevant stuff
- *
- * Revision 1.14 2001/06/01 10:30:55 oes
- * Added optional left-anchoring to domaincmp
- *
- * Revision 1.13 2001/05/31 21:21:30 jongfoster
- * Permissionsfile / actions file changes:
- * - Changed "permission" to "action" throughout
- * - changes to file format to allow string parameters
- * - Moved helper functions to actions.c
- *
- * Revision 1.12 2001/05/31 17:35:20 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.11 2001/05/29 11:53:23 oes
- * "See why" link added to "blocked" page
- *
- * Revision 1.10 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.9 2001/05/27 22:17:04 oes
- *
- * - re_process_buffer no longer writes the modified buffer
- * to the client, which was very ugly. It now returns the
- * buffer, which it is then written by chat.
- *
- * - content_length now adjusts the Content-Length: header
- * for modified documents rather than crunch()ing it.
- * (Length info in csp->content_length, which is 0 for
- * unmodified documents)
- *
- * - For this to work, sed() is called twice when filtering.
- *
- * Revision 1.8 2001/05/26 17:13:28 jongfoster
- * Filled in a function comment.
- *
- * Revision 1.7 2001/05/26 15:26:15 jongfoster
- * ACL feature now provides more security by immediately dropping
- * connections from untrusted hosts.
- *
- * Revision 1.6 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.5 2001/05/25 22:34:30 jongfoster
- * Hard tabs->Spaces
- *
- * Revision 1.4 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.3 2001/05/20 16:44:47 jongfoster
- * Removing last hardcoded Junkbusters.com URLs.
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:52 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-
-#ifndef _WIN32
-#ifndef __OS2__
-#include <unistd.h>
-#endif /* ndef __OS2__ */
-#include <netinet/in.h>
-#else
-#include <winsock2.h>
-#endif /* ndef _WIN32 */
-
-#ifdef __OS2__
-#include <utils.h>
-#endif /* def __OS2__ */
-
-#include "project.h"
-#include "filters.h"
-#include "encode.h"
-#include "parsers.h"
-#include "ssplit.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"
-#endif
-
-const char filters_h_rcs[] = FILTERS_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_isdigit(__X) isdigit((int)(unsigned char)(__X))
-
-
-#ifdef FEATURE_ACL
-/*********************************************************************
- *
- * Function : block_acl
- *
- * Description : Block this request?
- * Decide yes or no based on ACL file.
- *
- * Parameters :
- * 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 *dst, struct client_state *csp)
-{
- struct access_control_list *acl = csp->config->acl;
-
- /* if not using an access control list, then permit the connection */
- if (acl == NULL)
- {
- return(0);
- }
-
- /* search the list */
- while (acl != NULL)
- {
- if ((csp->ip_addr_long & acl->src->mask) == acl->src->addr)
- {
- if (dst == NULL)
- {
- /* Just want to check if they have any access */
- if (acl->action == ACL_PERMIT)
- {
- return(0);
- }
- }
- else if ( ((dst->addr & acl->dst->mask) == acl->dst->addr)
- && ((dst->port == acl->dst->port) || (acl->dst->port == 0)))
- {
- if (acl->action == ACL_PERMIT)
- {
- return(0);
- }
- else
- {
- return(1);
- }
- }
- }
- acl = acl->next;
- }
-
- return(1);
-
-}
-
-
-/*********************************************************************
- *
- * Function : acl_addr
- *
- * Description : Called from `load_config' to parse an ACL address.
- *
- * Parameters :
- * 1 : aspec = String specifying ACL address.
- * 2 : aca = struct access_control_addr to fill in.
- *
- * Returns : 0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int acl_addr(char *aspec, struct access_control_addr *aca)
-{
- int i, masklength, port;
- char *p;
-
- masklength = 32;
- port = 0;
-
- if ((p = strchr(aspec, '/')) != NULL)
- {
- *p++ = '\0';
-
- if (ijb_isdigit(*p) == 0)
- {
- return(-1);
- }
- masklength = atoi(p);
- }
-
- if ((masklength < 0) || (masklength > 32))
- {
- return(-1);
- }
-
- if ((p = strchr(aspec, ':')) != NULL)
- {
- *p++ = '\0';
-
- if (ijb_isdigit(*p) == 0)
- {
- return(-1);
- }
- port = atoi(p);
- }
-
- aca->port = port;
-
- aca->addr = ntohl(resolve_hostname_to_ip(aspec));
-
- if (aca->addr == INADDR_NONE)
- {
- return(-1);
- }
-
- /* build the netmask */
- aca->mask = 0;
- for (i=1; i <= masklength ; i++)
- {
- aca->mask |= (1 << (32 - i));
- }
-
- /* now mask off the host portion of the ip address
- * (i.e. save on the network portion of the address).
- */
- aca->addr = aca->addr & aca->mask;
-
- return(0);
-
-}
-#endif /* def FEATURE_ACL */
-
-
-/*********************************************************************
- *
- * Function : match_portlist
- *
- * Description : Check if a given number is covered by a comma
- * separated list of numbers and ranges (a,b-c,d,..)
- *
- * Parameters :
- * 1 : portlist = String with list
- * 2 : port = port to check
- *
- * Returns : 0 => no match
- * 1 => match
- *
- *********************************************************************/
-int match_portlist(const char *portlist, int port)
-{
- char *min, *max, *next, *portlist_copy;
-
- min = next = portlist_copy = strdup(portlist);
-
- /*
- * Zero-terminate first item and remember offset for next
- */
- if (NULL != (next = strchr(portlist_copy, (int) ',')))
- {
- *next++ = '\0';
- }
-
- /*
- * Loop through all items, checking for match
- */
- while(min)
- {
- if (NULL == (max = strchr(min, (int) '-')))
- {
- /*
- * No dash, check for equality
- */
- if (port == atoi(min))
- {
- 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);
- }
-
- }
-
- /*
- * Jump to next item
- */
- min = next;
-
- /*
- * Zero-terminate next item and remember offset for n+1
- */
- if ((NULL != next) && (NULL != (next = strchr(next, (int) ','))))
- {
- *next++ = '\0';
- }
- }
-
- free(portlist_copy);
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : block_url
- *
- * Description : Called from `chat'. Check to see if we need to block this.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : NULL => unblocked, else HTTP block response
- *
- *********************************************************************/
-struct http_response *block_url(struct client_state *csp)
-{
-#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 NULL;
- }
-
- /*
- * Else, prepare a response
- */
- if (NULL == (rsp = alloc_http_response()))
- {
- return cgi_error_memory();
- }
-
- /*
- * 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: */
-
- /* 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 (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
- }
-
- 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 (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
- }
-
- 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 (rsp->status == NULL)
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- exports = default_exports(csp, NULL);
- if (exports == NULL)
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
-#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();
- }
- }
-
- return finish_http_response(rsp);
-
-}
-
-
-#ifdef FEATURE_TRUST
-/*********************************************************************
- *
- * Function : trust_url FIXME: I should be called distrust_url
- *
- * 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 : NULL => trusted, else http_response.
- *
- *********************************************************************/
-struct http_response *trust_url(struct client_state *csp)
-{
- struct http_response *rsp;
- struct map * exports;
- char buf[BUFFER_SIZE];
- char *p;
- struct url_spec **tl;
- struct url_spec *t;
- jb_err err;
-
- /*
- * Don't bother to work on trusted URLs
- */
- if (!is_untrusted_url(csp))
- {
- return NULL;
- }
-
- /*
- * Else, prepare a response:
- */
- if (NULL == (rsp = alloc_http_response()))
- {
- return cgi_error_memory();
- }
-
- exports = default_exports(csp, NULL);
- if (exports == NULL)
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- /*
- * 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();
- }
-
- /*
- * Export the trust list
- */
- p = strdup("");
- for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++)
- {
- sprintf(buf, "<li>%s</li>\n", t->spec);
- string_append(&p, buf);
- }
- err = map(exports, "trusted-referrers", 1, p, 0);
-
- if (err)
- {
- free_map(exports);
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- /*
- * Export the trust info, if available
- */
- if (csp->config->trust_info->first)
- {
- struct list_entry *l;
-
- p = strdup("");
- for (l = csp->config->trust_info->first; l ; l = l->next)
- {
- sprintf(buf, "<li> <a href=\"%s\">%s</a><br>\n",l->str, l->str);
- string_append(&p, buf);
- }
- err = map(exports, "trust-info", 1, p, 0);
- }
- else
- {
- err = map_block_killer(exports, "have-trust-info");
- }
-
- 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 FEATURE_TRUST */
-
-
-#ifdef FEATURE_FAST_REDIRECTS
-/*********************************************************************
- *
- * Function : redirect_url
- *
- * Description : Checks for redirection URLs and returns a HTTP redirect
- * to the destination URL, if necessary
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : NULL if URL was clean, HTTP redirect otherwise.
- *
- *********************************************************************/
-struct http_response *redirect_url(struct client_state *csp)
-{
- char *p, *q;
- struct http_response *rsp;
-
- 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)
- {
- q = p++;
- }
-
- /*
- * if there was any, generate and return a HTTP redirect
- */
- if (q != csp->http->path)
- {
- log_error(LOG_LEVEL_REDIRECTS, "redirecting to: %s", q);
-
- if (NULL == (rsp = alloc_http_response()))
- {
- return cgi_error_memory();
- }
-
- if ( enlist_unique_header(rsp->headers, "Location", q)
- || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy"))) )
- {
- free_http_response(rsp);
- return cgi_error_memory();
- }
-
- return finish_http_response(rsp);
- }
- else
- {
- return NULL;
- }
-
-}
-#endif /* def FEATURE_FAST_REDIRECTS */
-
-
-#ifdef FEATURE_IMAGE_BLOCKING
-/*********************************************************************
- *
- * Function : is_imageurl
- *
- * 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 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : True (nonzero) if URL is an image, false (0)
- * otherwise
- *
- *********************************************************************/
-int is_imageurl(struct client_state *csp)
-{
-#ifdef FEATURE_IMAGE_DETECT_MSIE
- char *tmp;
-
- tmp = get_header_value(csp->headers, "User-Agent:");
- if (tmp && strstr(tmp, "MSIE"))
- {
- tmp = get_header_value(csp->headers, "Accept:");
- if (tmp && strstr(tmp, "image/gif"))
- {
- /* Client will accept HTML. If this seems counterintuitive,
- * blame Microsoft.
- */
- return(0);
- }
- else
- {
- return(1);
- }
- }
-#endif /* def FEATURE_IMAGE_DETECT_MSIE */
-
- return ((csp->action->flags & ACTION_IMAGE) != 0);
-
-}
-#endif /* def FEATURE_IMAGE_BLOCKING */
-
-
-#ifdef FEATURE_TRUST
-/*********************************************************************
- *
- * Function : is_untrusted_url
- *
- * Description : Should we "distrust" this URL (and block it)?
- *
- * 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 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : 0 => trusted, 1 => untrusted
- *
- *********************************************************************/
-int is_untrusted_url(struct client_state *csp)
-{
- struct file_list *fl;
- struct block_spec *b;
- struct url_spec **trusted_url;
- struct http_request rhttp[1];
- const char * referer;
- jb_err err;
-
- /*
- * If we don't have a trustlist, we trust everybody
- */
- if (((fl = csp->tlist) == NULL) || ((b = fl->f) == NULL))
- {
- return 0;
- }
-
- memset(rhttp, '\0', sizeof(*rhttp));
-
- /*
- * 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;
- }
- }
-
- 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 (url_match(*trusted_url, rhttp))
- {
- /* 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")))
- {
- 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
- {
- /* 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;
- }
- }
- return 1;
-}
-#endif /* def FEATURE_TRUST */
-
-
-/*********************************************************************
- *
- * Function : pcrs_filter_response
- *
- * 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 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : a pointer to the (newly allocated) modified buffer.
- * or NULL if there were no hits or something went wrong
- *
- *********************************************************************/
-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 re_filterfile_spec *b;
- struct list_entry *filtername;
-
- /*
- * Sanity first
- */
- if (csp->iob->cur >= csp->iob->eod)
- {
- return(NULL);
- }
- size = csp->iob->eod - csp->iob->cur;
-
- if ( ( NULL == (fl = csp->rlist) ) || ( NULL == fl->f) )
- {
- log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
- return(NULL);
- }
-
- /*
- * 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 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)
- {
- for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first;
- filtername ; filtername = filtername->next)
- {
- if (strcmp(b->name, filtername->str) == 0)
- {
- int current_hits = 0;
-
- if ( NULL == b->joblist )
- {
- 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;
- }
- }
- }
-
- /*
- * 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 : gif_deanimate_response
- *
- * 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 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : a pointer to the (newly allocated) modified buffer.
- * or NULL in case something went wrong.
- *
- *********************************************************************/
-char *gif_deanimate_response(struct client_state *csp)
-{
- struct binbuffer *in, *out;
- char *p;
- size_t size = csp->iob->eod - csp->iob->cur;
-
- /*
- * 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_DEANIMATE, "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;
- }
-
- if ( (NULL == (in = (struct binbuffer *)zalloc(sizeof *in )))
- || (NULL == (out = (struct binbuffer *)zalloc(sizeof *out))) )
- {
- log_error(LOG_LEVEL_DEANIMATE, "failed! (no mem)");
- return NULL;
- }
-
- in->buffer = csp->iob->cur;
- in->size = size;
-
- if (gif_deanimate(in, out, strncmp("last", csp->action->string[ACTION_STRING_DEANIMATE], 4)))
- {
- 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);
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : remove_chunked_transfer_coding
- *
- * Description : In-situ remove the "chunked" transfer coding as defined
- * in rfc2616 from a buffer.
- *
- * Parameters :
- * 1 : buffer = Pointer to the text buffer
- * 2 : size = Number of bytes to be processed
- *
- * 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 remove_chunked_transfer_coding(char *buffer, const size_t size)
-{
- size_t newsize = 0;
- unsigned int chunksize = 0;
- char *from_p, *to_p;
-
- assert(buffer);
- from_p = to_p = buffer;
-
- if (sscanf(buffer, "%x", &chunksize) != 1)
- {
- log_error(LOG_LEVEL_ERROR, "Invalid first chunksize while stripping \"chunked\" transfer coding");
- return(0);
- }
-
- while (chunksize > 0)
- {
- if (NULL == (from_p = strstr(from_p, "\r\n")))
- {
- log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
- return(0);
- }
- newsize += chunksize;
- from_p += 2;
-
- memmove(to_p, from_p, (size_t) chunksize);
- to_p = buffer + newsize;
- from_p += chunksize + 2;
-
- if (sscanf(from_p, "%x", &chunksize) != 1)
- {
- log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
- 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);
-
-}
-
-
-/*********************************************************************
- *
- * Function : url_actions
- *
- * Description : Gets the actions for this URL.
- *
- * Parameters :
- * 1 : http = http_request request for blocked URLs
- * 2 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : N/A
- *
- *********************************************************************/
-void url_actions(struct http_request *http,
- struct client_state *csp)
-{
- struct file_list *fl;
- struct url_actions *b;
- int i;
-
- init_current_action(csp->action);
-
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
- {
- return;
- }
-
- apply_url_actions(csp->action, http, b);
- }
-
- return;
-}
-
-
-/*********************************************************************
- *
- * Function : apply_url_actions
- *
- * Description : Applies a list of URL actions.
- *
- * Parameters :
- * 1 : action = Destination.
- * 2 : http = Current URL
- * 3 : b = list of URL actions to apply
- *
- * Returns : N/A
- *
- *********************************************************************/
-void apply_url_actions(struct current_action_spec *action,
- struct http_request *http,
- struct url_actions *b)
-{
- if (b == NULL)
- {
- /* Should never happen */
- return;
- }
-
- for (b = b->next; NULL != b; b = b->next)
- {
- if (url_match(b->url, http))
- {
- merge_current_action(action, b->action);
- }
- }
-}
-
-
-/*********************************************************************
- *
- * Function : forward_url
- *
- * Description : Should we forward this to another proxy?
- *
- * Parameters :
- * 1 : http = http_request request for current URL
- * 2 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : Pointer to forwarding information.
- *
- *********************************************************************/
-const struct forward_spec * forward_url(struct http_request *http,
- struct client_state *csp)
-{
- static const struct forward_spec fwd_default[1] = { FORWARD_SPEC_INITIALIZER };
- struct forward_spec *fwd = csp->config->forward;
-
- if (fwd == NULL)
- {
- return fwd_default;
- }
-
- while (fwd != NULL)
- {
- if (url_match(fwd->url, http))
- {
- return fwd;
- }
- fwd = fwd->next;
- }
-
- return fwd_default;
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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', `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
- * 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: filters.h,v $
- * Revision 1.19 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.18 2002/03/25 22:12:45 oes
- * Added fix for undefined INADDR_NONE on Solaris by Bart Schelstraete
- *
- * Revision 1.17 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.16 2002/01/17 21:01:02 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Revision 1.15 2001/10/10 16:44:16 oes
- * Added match_portlist function
- *
- * Revision 1.14 2001/10/07 15:41:40 oes
- * Added prototype for remove_chunked_transfer_coding
- *
- * Revision 1.13 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.12 2001/07/29 19:01:11 jongfoster
- * Changed _FILENAME_H to FILENAME_H_INCLUDED.
- * Added forward declarations for needed structures.
- *
- * Revision 1.11 2001/07/13 14:00:18 oes
- * - Introduced gif_deanimate_response
- * - Renamed re_process_buffer to pcrs_filter_response
- * - Removed all #ifdef PCRS
- *
- * Revision 1.10 2001/06/29 13:29:01 oes
- * Cleaned up and updated to reflect the changesin
- * filters.c
- *
- * Revision 1.9 2001/06/07 23:10:53 jongfoster
- * Replacing struct gateway with struct forward_spec
- *
- * Revision 1.8 2001/06/03 19:12:00 oes
- * extracted-CGI relevant stuff
- *
- * Revision 1.7 2001/05/31 21:21:30 jongfoster
- * Permissionsfile / actions file changes:
- * - Changed "permission" to "action" throughout
- * - changes to file format to allow string parameters
- * - Moved helper functions to actions.c
- *
- * Revision 1.6 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.5 2001/05/27 22:17:04 oes
- *
- * - re_process_buffer no longer writes the modified buffer
- * to the client, which was very ugly. It now returns the
- * buffer, which it is then written by chat.
- *
- * - content_length now adjusts the Content-Length: header
- * for modified documents rather than crunch()ing it.
- * (Length info in csp->content_length, which is 0 for
- * unmodified documents)
- *
- * - For this to work, sed() is called twice when filtering.
- *
- * Revision 1.4 2001/05/26 15:26:15 jongfoster
- * ACL feature now provides more security by immediately dropping
- * connections from untrusted hosts.
- *
- * Revision 1.3 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:52 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct access_control_addr;
-struct client_state;
-struct http_request;
-struct http_response;
-struct current_action_spec;
-struct url_actions;
-struct url_spec;
-
-
-/*
- * 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);
-
-/*
- * 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 */
-
-/*
- * 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 */
-
-/*
- * 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);
-
-/*
- * 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);
-
-/*
- * Solaris fix:
- */
-#ifndef INADDR_NONE
-#define INADDR_NONE -1
-#endif
-
-/*
- * Revision control strings from this header and associated .c file
- */
-extern const char filters_rcs[];
-extern const char filters_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef FILTERS_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char gateway_rcs[] = "$Id: gateway.c,v 1.15 2002/03/26 22:29:54 swa Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $
- *
- * Purpose : Contains functions to connect to a server, possibly
- * using a "forwarder" (i.e. HTTP proxy and/or a SOCKS4
- * proxy).
- *
- * 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: gateway.c,v $
- * Revision 1.15 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.14 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.13 2002/03/13 00:29:59 jongfoster
- * Killing warnings
- *
- * Revision 1.12 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.11 2002/03/08 17:46:04 jongfoster
- * Fixing int/size_t warnings
- *
- * Revision 1.10 2002/03/07 03:50:19 oes
- * - Improved handling of failed DNS lookups
- * - Fixed compiler warnings
- *
- * Revision 1.9 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.8 2001/09/13 20:10:12 jongfoster
- * Fixing missing #include under Windows
- *
- * Revision 1.7 2001/09/12 17:58:26 steudten
- *
- * add #include <string.h>
- *
- * Revision 1.6 2001/09/10 10:41:16 oes
- * Added #include in.h
- *
- * Revision 1.5 2001/07/29 18:47:57 jongfoster
- * Adding missing #include project.h
- *
- * Revision 1.4 2001/07/24 12:47:06 oes
- * Applied BeOS support update by Eugenia
- *
- * Revision 1.3 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.2 2001/06/07 23:11:38 jongfoster
- * Removing gateways[] list - no longer used.
- * Replacing function pointer in struct gateway with a directly
- * called function forwarded_connect(), which can do the common
- * task of deciding whether to connect to the web server or HTTP
- * proxy.
- * Replacing struct gateway with struct forward_spec
- * Fixing bug with SOCKS4A and HTTP proxy server in combination.
- * It was a bug which led to the connection being made to the web
- * server rather than the HTTP proxy, and also a buffer overrun.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:54 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifndef _WIN32
-#include <netinet/in.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#endif /* def _WIN32 */
-
-#ifdef __BEOS__
-#include <netdb.h>
-#endif /* def __BEOS__ */
-
-#ifdef __OS2__
-#include <utils.h>
-#endif /* def __OS2__ */
-
-#include "project.h"
-#include "jcc.h"
-#include "errlog.h"
-#include "jbsockets.h"
-#include "gateway.h"
-
-const char gateway_h_rcs[] = GATEWAY_H_VERSION;
-
-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
-#define SOCKS_REQUEST_REJECT 91
-#define SOCKS_REQUEST_IDENT_FAILED 92
-#define SOCKS_REQUEST_IDENT_CONFLICT 93
-
-/* structure of a socks client operation */
-struct socks_op {
- unsigned char vn; /* socks version number */
- unsigned char cd; /* command code */
- unsigned char dstport[2]; /* destination port */
- unsigned char dstip[4]; /* destination address */
- unsigned char userid; /* first byte of userid */
- /* more bytes of the userid follow, terminated by a NULL */
-};
-
-/* structure of a socks server reply */
-struct socks_reply {
- unsigned char vn; /* socks version number */
- unsigned char cd; /* command code */
- unsigned char dstport[2]; /* destination port */
- unsigned char dstip[4]; /* destination address */
-};
-
-static const char socks_userid[] = "anonymous";
-
-
-/*********************************************************************
- *
- * Function : forwarded_connect
- *
- * Description : Connect to a specified web server, possibly via
- * a HTTP proxy and/or a SOCKS proxy.
- *
- * Parameters :
- * 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 : JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
- *
- *********************************************************************/
-jb_socket forwarded_connect(const struct forward_spec * fwd,
- struct http_request *http,
- struct client_state *csp)
-{
- 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)
- {
- /* HTTP proxy */
- dest_host = fwd->forward_host;
- dest_port = fwd->forward_port;
- }
- else
- {
- /* 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);
- }
-}
-
-
-/*********************************************************************
- *
- * Function : socks4_connect
- *
- * Description : Connect to the SOCKS server, and connect through
- * 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 : 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 : JB_INVALID_SOCKET => failure, else a socket file descriptor.
- *
- *********************************************************************/
-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;
- char cbuf[BUFFER_SIZE];
- char sbuf[BUFFER_SIZE];
- struct socks_op *c = (struct socks_op *)cbuf;
- struct socks_reply *s = (struct socks_reply *)sbuf;
- size_t n;
- size_t csiz;
- jb_socket sfd;
- int err = 0;
- char *errstr;
-
- if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0'))
- {
- log_error(LOG_LEVEL_CONNECT, "socks4_connect: NULL gateway host specified");
- err = 1;
- }
-
- if (fwd->gateway_port <= 0)
- {
- log_error(LOG_LEVEL_CONNECT, "socks4_connect: invalid gateway port specified");
- err = 1;
- }
-
- if (err)
- {
- errno = EINVAL;
- return(JB_INVALID_SOCKET);
- }
-
- /* build a socks request for connection to the web server */
-
- strcpy((char *)&(c->userid), socks_userid);
-
- csiz = sizeof(*c) + sizeof(socks_userid) - 1;
-
- 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;
- n = csiz + strlen(target_host) + 1;
- if (n > sizeof(cbuf))
- {
- errno = EINVAL;
- return(JB_INVALID_SOCKET);
- }
- strcpy(cbuf + csiz, target_host);
- csiz = n;
- break;
- default:
- /* Should never get here */
- log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
- errno = EINVAL;
- return(JB_INVALID_SOCKET);
- }
-
- c->vn = 4;
- c->cd = 1;
- c->dstport[0] = (target_port >> 8 ) & 0xff;
- c->dstport[1] = (target_port ) & 0xff;
- c->dstip[0] = (web_server_addr >> 24 ) & 0xff;
- c->dstip[1] = (web_server_addr >> 16 ) & 0xff;
- c->dstip[2] = (web_server_addr >> 8 ) & 0xff;
- c->dstip[3] = (web_server_addr ) & 0xff;
-
- /* pass the request to the socks server */
- sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp);
-
- if (sfd == JB_INVALID_SOCKET)
- {
- return(JB_INVALID_SOCKET);
- }
-
- if (write_socket(sfd, (char *)c, csiz))
- {
- log_error(LOG_LEVEL_CONNECT, "SOCKS4 negotiation write failed...");
- close_socket(sfd);
- return(JB_INVALID_SOCKET);
- }
-
- if (read_socket(sfd, sbuf, sizeof(sbuf)) != sizeof(*s))
- {
- log_error(LOG_LEVEL_CONNECT, "SOCKS4 negotiation read failed...");
- close_socket(sfd);
- return(JB_INVALID_SOCKET);
- }
-
- switch (s->cd)
- {
- case SOCKS_REQUEST_GRANTED:
- return(sfd);
- break;
- case SOCKS_REQUEST_REJECT:
- errstr = "SOCKS request rejected or failed";
- errno = EINVAL;
- break;
- case SOCKS_REQUEST_IDENT_FAILED:
- errstr = "SOCKS request rejected because "
- "SOCKS server cannot connect to identd on the client";
- errno = EACCES;
- break;
- case SOCKS_REQUEST_IDENT_CONFLICT:
- errstr = "SOCKS request rejected because "
- "the client program and identd report "
- "different user-ids";
- errno = EACCES;
- break;
- default:
- errstr = cbuf;
- errno = ENOENT;
- sprintf(errstr,
- "SOCKS request rejected for reason code %d\n", s->cd);
- }
-
- log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s ...", errstr);
-
- close_socket(sfd);
- return(JB_INVALID_SOCKET);
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: gateway.h,v $
- * Revision 1.6 2002/03/25 22:12:45 oes
- * Added fix for undefined INADDR_NONE on Solaris by Bart Schelstraete
- *
- * Revision 1.5 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.4 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.3 2001/07/29 18:58:15 jongfoster
- * Removing nested #includes, adding forward declarations for needed
- * structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
- *
- * Revision 1.2 2001/06/07 23:12:14 jongfoster
- * Removing gateways[] list - no longer used.
- * Replacing function pointer in struct gateway with a directly
- * called function forwarded_connect(), which can do the common
- * task of deciding whether to connect to the web server or HTTP
- * proxy.
- * Replacing struct gateway with struct forward_spec
- *
- * Revision 1.1.1.1 2001/05/15 13:58:54 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct forward_spec;
-struct http_request;
-struct client_state;
-
-extern jb_socket forwarded_connect(const struct forward_spec * fwd,
- struct http_request *http,
- struct client_state *csp);
-
-/*
- * 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[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef GATEWAY_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.35 2002/04/26 15:50:04 joergs Exp $";
-/*********************************************************************
- *
- * 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
- * OS-independent. Contains #ifdefs to make this work
- * on many platforms.
- *
- * 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: jbsockets.c,v $
- * Revision 1.35 2002/04/26 15:50:04 joergs
- * AmigaOS: No socklen_t, added AMIGA to the systems using int instead.
- *
- * Revision 1.34 2002/04/08 20:31:41 swa
- * fixed JB spelling
- *
- * Revision 1.33 2002/04/03 16:02:18 gliptak
- * Correcting compile warning with older gcc
- *
- * Revision 1.32 2002/03/31 17:18:59 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.31 2002/03/29 03:33:13 david__schmidt
- * Fix Mac OSX compiler warnings
- *
- * Revision 1.30 2002/03/27 14:32:43 david__schmidt
- * More compiler warning message maintenance
- *
- * Revision 1.29 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.28 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.27 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.26 2002/03/11 22:07:02 david__schmidt
- * OS/2 port maintenance:
- * - Fixed EMX build - it had decayed a little
- * - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
- * substituted a memset for now.
- *
- * Revision 1.25 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.24 2002/03/07 03:51:36 oes
- * - Improved handling of failed DNS lookups
- * - Fixed compiler warnings etc
- *
- * Revision 1.23 2002/03/05 00:36:01 jongfoster
- * Fixing bug 514988 - unable to restart Junkbuster
- *
- * Revision 1.22 2002/03/04 02:08:02 david__schmidt
- * Enable web editing of actions file on OS/2 (it had been broken all this time!)
- *
- * Revision 1.21 2002/01/09 14:32:33 oes
- * Added support for gethostbyname_r and gethostbyaddr_r.
- *
- * Revision 1.20 2001/11/16 00:48:48 jongfoster
- * Enabling duplicate-socket detection for all platforms, not
- * just Win32.
- *
- * Revision 1.19 2001/10/25 03:40:47 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.18 2001/09/21 23:02:02 david__schmidt
- * Cleaning up 2 compiler warnings on OS/2.
- *
- * Revision 1.17 2001/09/13 20:11:46 jongfoster
- * Fixing 2 compiler warnings under Win32
- *
- * Revision 1.16 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.15 2001/07/29 17:40:43 jongfoster
- * Fixed compiler warning by adding a cast
- *
- * Revision 1.14 2001/07/18 13:47:59 oes
- * Eliminated dirty hack for getsockbyname()
- *
- * Revision 1.13 2001/07/15 13:56:57 jongfoster
- * Removing unused local variable.
- *
- * Revision 1.12 2001/07/01 17:04:11 oes
- * Bugfix: accept_connection no longer uses the obsolete hstrerror() function
- *
- * Revision 1.11 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.10 2001/06/29 13:29:15 oes
- * - Added remote (server) host IP to csp->http->host_ip_addr_str
- * - Added detection of local socket IP and fqdn
- * - Removed logentry from cancelled commit
- *
- * Revision 1.9 2001/06/07 23:06:09 jongfoster
- * The host parameter to connect_to() is now const.
- *
- * Revision 1.8 2001/06/03 19:12:07 oes
- * filled comment
- *
- * Revision 1.7 2001/05/28 16:14:00 jongfoster
- * Fixing bug in LOG_LEVEL_LOG
- *
- * Revision 1.6 2001/05/26 17:28:32 jongfoster
- * Fixed LOG_LEVEL_LOG
- *
- * Revision 1.5 2001/05/26 15:26:15 jongfoster
- * ACL feature now provides more security by immediately dropping
- * connections from untrusted hosts.
- *
- * Revision 1.4 2001/05/26 00:37:42 jongfoster
- * Cosmetic indentation correction.
- *
- * Revision 1.3 2001/05/25 21:57:54 jongfoster
- * Now gives a warning under Windows if you try to bind
- * it to a port that's already in use.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:58:54 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-
-#ifdef _WIN32
-
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-#include <sys/timeb.h>
-#include <io.h>
-
-#else
-
-#ifndef __OS2__
-#include <unistd.h>
-#endif
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-#include <netdb.h>
-#include <sys/socket.h>
-
-#ifndef __BEOS__
-#include <netinet/tcp.h>
-#ifndef __OS2__
-#include <arpa/inet.h>
-#endif
-#else
-#include <socket.h>
-#endif
-
-#if defined(__EMX__) || defined (__OS2__)
-#include <sys/select.h> /* OS/2/EMX needs a little help with select */
-#ifdef __OS2__
-#include <nerrno.h>
-#endif
-#endif
-
-#endif
-
-#include "project.h"
-#include "jbsockets.h"
-#include "filters.h"
-#include "errlog.h"
-
-const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
-
-
-/*********************************************************************
- *
- * Function : connect_to
- *
- * Description : Open a socket and connect to it. Will check
- * that this is allowed according to ACL.
- *
- * Parameters :
- * 1 : host = hostname to connect to
- * 2 : portnum = port to connent on
- * 3 : csp = Current client state (buffers, headers, etc...)
- * Not modified, only used for source IP and ACL.
- *
- * Returns : JB_INVALID_SOCKET => failure, else it is the socket
- * file descriptor.
- *
- *********************************************************************/
-jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
-{
- struct sockaddr_in inaddr;
- 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 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)) == INADDR_NONE)
- {
- csp->http->host_ip_addr_str = strdup("unknown");
- return(JB_INVALID_SOCKET);
- }
-
-#ifdef FEATURE_ACL
- dst->addr = ntohl((unsigned long) addr);
- dst->port = portnum;
-
- if (block_acl(dst, csp))
- {
-#ifdef __OS2__
- errno = SOCEPERM;
-#else
- errno = EPERM;
-#endif
- return(JB_INVALID_SOCKET);
- }
-#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((unsigned short) portnum);
- }
-#ifndef _WIN32
- else
- {
- 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(JB_INVALID_SOCKET);
- }
-
-#ifdef TCP_NODELAY
- { /* turn off TCP coalescence */
- int mi = 1;
- setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
- }
-#endif /* def TCP_NODELAY */
-
-#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) && !defined(__OS2__) */
-
- 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 || __OS2__ */
- {
- break;
- }
-
-#ifdef __OS2__
- if (sock_errno() != EINTR)
-#else
- if (errno != EINTR)
-#endif /* __OS2__ */
- {
- close_socket(fd);
- return(JB_INVALID_SOCKET);
- }
- }
-
-#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) && !defined(__OS2__) */
-
- /* wait for connection to complete */
- FD_ZERO(&wfds);
- FD_SET(fd, &wfds);
-
- tv->tv_sec = 30;
- tv->tv_usec = 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(JB_INVALID_SOCKET);
- }
- return(fd);
-
-}
-
-
-/*********************************************************************
- *
- * Function : write_socket
- *
- * Description : Write the contents of buf (for n bytes) to socket fd.
- *
- * Parameters :
- * 1 : fd = file descriptor (aka. handle) of socket to write to.
- * 2 : buf = pointer to data to be written.
- * 3 : len = length of data to be written to the socket "fd".
- *
- * Returns : 0 on success (entire buffer sent).
- * nonzero on error.
- *
- *********************************************************************/
-#ifdef AMIGA
-int write_socket(jb_socket fd, const char *buf, ssize_t len)
-#else
-int write_socket(jb_socket fd, const char *buf, size_t len)
-#endif
-{
- if (len == 0)
- {
- return 0;
- }
-
- if (len < 0)
- {
- return 1;
- }
-
- 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) != len);
-#endif
-
-}
-
-
-/*********************************************************************
- *
- * Function : read_socket
- *
- * Description : Read from a TCP/IP socket in a platform independent way.
- *
- * Parameters :
- * 1 : fd = file descriptor of the socket to read
- * 2 : buf = pointer to buffer where data will be written
- * Must be >= len bytes long.
- * 3 : len = maximum number of bytes to read
- *
- * Returns : On success, the number of bytes read is returned (zero
- * indicates end of file), and the file position is advanced
- * by this number. It is not an error if this number is
- * 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,
- * -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(jb_socket fd, char *buf, int len)
-{
- if (len <= 0)
- {
- return(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, (size_t)len));
-#endif
-}
-
-
-/*********************************************************************
- *
- * Function : close_socket
- *
- * Description : Closes a TCP/IP socket
- *
- * Parameters :
- * 1 : fd = file descriptor of socket to be closed
- *
- * Returns : void
- *
- *********************************************************************/
-void close_socket(jb_socket fd)
-{
-#if defined(_WIN32) || defined(__BEOS__)
- closesocket(fd);
-#elif defined(AMIGA)
- CloseSocket(fd);
-#elif defined(__OS2__)
- soclose(fd);
-#else
- close(fd);
-#endif
-
-}
-
-
-/*********************************************************************
- *
- * Function : bind_port
- *
- * Description : Call socket, set socket options, and listen.
- * Called by listen_loop to "boot up" our proxy address.
- *
- * 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, 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, jb_socket *pfd)
-{
- struct sockaddr_in inaddr;
- 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((unsigned short) portnum);
- }
-#ifndef _WIN32
- else
- {
- 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)
- {
- close_socket (fd);
-#ifdef _WIN32
- if (errno == WSAEADDRINUSE)
-#else
- if (errno == EADDRINUSE)
-#endif
- {
- return(-3);
- }
- else
- {
- return(-1);
- }
- }
-
- while (listen(fd, 5) == -1)
- {
- if (errno != EINTR)
- {
- return(-1);
- }
- }
-
- *pfd = fd;
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : accept_connection
- *
- * Description : Accepts a connection on a socket. Socket must have
- * been created using bind_port().
- *
- * Parameters :
- * 1 : csp = Client state, cfd, ip_addr_str, and
- * ip_addr_long will be set by this routine.
- * 2 : fd = file descriptor returned from bind_port
- *
- * Returns : when a connection is accepted, it returns 1 (TRUE).
- * On an error it returns 0 (FALSE).
- *
- *********************************************************************/
-int accept_connection(struct client_state * csp, jb_socket fd)
-{
- 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 */
-
- 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, (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(client.sin_addr));
- csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
-
- return 1;
-
-}
-
-
-/*********************************************************************
- *
- * Function : resolve_hostname_to_ip
- *
- * Description : Resolve a hostname to an internet tcp/ip address.
- * NULL or an empty string resolve to INADDR_ANY.
- *
- * Parameters :
- * 1 : host = hostname to resolve
- *
- * Returns : INADDR_NONE => failure, INADDR_ANY or tcp/ip address if succesful.
- *
- *********************************************************************/
-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'))
- {
- return(INADDR_ANY);
- }
-
- memset((char *) &inaddr, 0, sizeof inaddr);
-
- if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
- {
-#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;
- log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
- return(INADDR_NONE);
- }
- if (hostp->h_addrtype != AF_INET)
- {
-#ifdef _WIN32
- errno = WSAEPROTOTYPE;
-#else
- errno = EPROTOTYPE;
-#endif
- log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
- return(INADDR_NONE);
- }
- memcpy(
- (char *) &inaddr.sin_addr,
- (char *) hostp->h_addr,
- sizeof(inaddr.sin_addr)
- );
- }
- return(inaddr.sin_addr.s_addr);
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef JBSOCKETS_H_INCLUDED
-#define JBSOCKETS_H_INCLUDED
-#define JBSOCKETS_H_VERSION "$Id: jbsockets.h,v 1.9 2002/04/08 20:31:41 swa Exp $"
-/*********************************************************************
- *
- * 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
- * OS-independent. Contains #ifdefs to make this work
- * on many platforms.
- *
- * 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: jbsockets.h,v $
- * Revision 1.9 2002/04/08 20:31:41 swa
- * fixed JB spelling
- *
- * Revision 1.8 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.7 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.6 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.5 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.4 2002/03/07 03:51:36 oes
- * - Improved handling of failed DNS lookups
- * - Fixed compiler warnings etc
- *
- * Revision 1.3 2001/07/29 19:01:11 jongfoster
- * Changed _FILENAME_H to FILENAME_H_INCLUDED.
- * Added forward declarations for needed structures.
- *
- * Revision 1.2 2001/06/07 23:06:09 jongfoster
- * The host parameter to connect_to() is now const.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:54 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct client_state;
-
-extern jb_socket connect_to(const char *host, int portnum, struct client_state *csp);
-#ifdef AMIGA
-extern int write_socket(jb_socket fd, const char *buf, ssize_t n);
-#else
-extern int write_socket(jb_socket fd, const char *buf, size_t n);
-#endif
-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, jb_socket *pfd);
-extern int accept_connection(struct client_state * csp, jb_socket fd);
-
-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[];
-extern const char jbsockets_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef JBSOCKETS_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char jcc_rcs[] = "$Id: jcc.c,v 1.91 2002/04/08 20:35:58 swa Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $
- *
- * Purpose : Main file. Contains main() method, main loop, and
- * the main connection-handling function.
- *
- * 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: jcc.c,v $
- * Revision 1.91 2002/04/08 20:35:58 swa
- * fixed JB spelling
- *
- * Revision 1.90 2002/04/02 14:57:28 oes
- * Made sending wafers independent of FEATURE_COOKIE_JAR
- *
- * Revision 1.89 2002/03/31 17:18:59 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.88 2002/03/27 14:32:43 david__schmidt
- * More compiler warning message maintenance
- *
- * Revision 1.87 2002/03/26 22:29:54 swa
- * we have a new homepage!
- *
- * Revision 1.86 2002/03/25 17:04:55 david__schmidt
- * Workaround for closing the jarfile before load_config() comes around again
- *
- * Revision 1.85 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.84 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.83 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.82 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.81 2002/03/12 01:42:50 oes
- * Introduced modular filters
- *
- * Revision 1.80 2002/03/11 22:07:05 david__schmidt
- * OS/2 port maintenance:
- * - Fixed EMX build - it had decayed a little
- * - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
- * substituted a memset for now.
- *
- * Revision 1.79 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.78 2002/03/08 21:35:04 oes
- * Added optional group supplement to --user option. Will now use default group of user if no group given
- *
- * Revision 1.77 2002/03/07 03:52:06 oes
- * - Fixed compiler warnings etc
- * - Improved handling of failed DNS lookups
- *
- * Revision 1.76 2002/03/06 22:54:35 jongfoster
- * Automated function-comment nitpicking.
- *
- * Revision 1.75 2002/03/06 10:02:19 oes
- * Fixed stupid bug when --user was not given
- *
- * Revision 1.74 2002/03/06 00:49:31 jongfoster
- * Fixing warning on Windows
- * Making #ifdefs that refer to the same variable consistently
- * use #ifdef unix rather than mixing #ifdef unix & #ifndef OS2
- *
- * Revision 1.73 2002/03/05 23:57:30 hal9
- * Stray character 's' on line 1618 was breaking build.
- *
- * Revision 1.72 2002/03/05 21:33:45 david__schmidt
- * - Re-enable OS/2 building after new parms were added
- * - Fix false out of memory report when resolving CGI templates when no IP
- * address is available of failed attempt (a la no such domain)
- *
- * Revision 1.71 2002/03/05 18:13:56 oes
- * Added --user option
- *
- * Revision 1.70 2002/03/05 04:52:42 oes
- * Deleted non-errlog debugging code
- *
- * Revision 1.69 2002/03/04 23:50:00 jongfoster
- * Splitting off bind_port() call into bind_port_helper(), with
- * improved logging.
- *
- * Revision 1.68 2002/03/04 20:17:32 oes
- * Fixed usage info
- *
- * Revision 1.67 2002/03/04 18:18:57 oes
- * - Removed _DEBUG mode
- * - Cleand up cmdline parsing
- * - Introduced --no-daemon, --pidfile options
- * - Cleaned up signal handling:
- * - Terminate cleanly on INT, TERM and ABRT
- * - Schedule logfile for re-opening on HUP
- * - Ignore CHLD and PIPE
- * - Leave the rest with their default handlers
- * - Uniform handler registration
- * - Added usage() function
- * - Played styleguide police
- *
- * Revision 1.66 2002/03/03 15:06:55 oes
- * Re-enabled automatic config reloading
- *
- * Revision 1.65 2002/03/03 14:49:11 oes
- * Fixed CLF logging: Now uses client's original HTTP request
- *
- * Revision 1.64 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.63 2002/03/02 04:14:50 david__schmidt
- * Clean up a little CRLF unpleasantness that suddenly appeared
- *
- * Revision 1.62 2002/02/20 23:17:23 jongfoster
- * Detecting some out-of memory conditions and exiting with a log message.
- *
- * Revision 1.61 2002/01/17 21:01:52 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Revision 1.60 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.59 2001/12/13 14:07:18 oes
- * Fixed Bug: 503 error page now sent OK
- *
- * Revision 1.58 2001/11/30 23:37:24 jongfoster
- * Renaming the Win32 config file to config.txt - this is almost the
- * same as the corresponding UNIX name "config"
- *
- * Revision 1.57 2001/11/16 00:47:43 jongfoster
- * Changing the tty-disconnection code to use setsid().
- *
- * Revision 1.56 2001/11/13 20:20:54 jongfoster
- * Tabs->spaces, fixing a bug with missing {} around an if()
- *
- * Revision 1.55 2001/11/13 20:14:53 jongfoster
- * Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
- *
- * Revision 1.54 2001/11/07 00:03:14 steudten
- * Give reliable return value if an error
- * occurs not just 0 with new daemon mode.
- *
- * Revision 1.53 2001/11/05 21:41:43 steudten
- * Add changes to be a real daemon just for unix os.
- * (change cwd to /, detach from controlling tty, set
- * process group and session leader to the own process.
- * Add DBG() Macro.
- * Add some fatal-error log message for failed malloc().
- * Add '-d' if compiled with 'configure --with-debug' to
- * enable debug output.
- *
- * Revision 1.52 2001/10/26 20:11:20 jongfoster
- * Fixing type mismatch
- *
- * Revision 1.51 2001/10/26 17:38:28 oes
- * Cosmetics
- *
- * Revision 1.50 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.49 2001/10/23 21:41:35 jongfoster
- * Added call to initialize the (statically-allocated of course)
- * "out of memory" CGI response.
- *
- * Revision 1.48 2001/10/10 19:56:46 jongfoster
- * Moving some code that wasn't cookie-related out of an #ifdef
- * FEATURE_COOKIE_JAR
- *
- * Revision 1.47 2001/10/10 16:44:36 oes
- * Added CONNECT destination port limitation check
- *
- * Revision 1.46 2001/10/08 15:17:41 oes
- * Re-enabled SSL forwarding
- *
- * Revision 1.45 2001/10/07 15:42:11 oes
- * Replaced 6 boolean members of csp with one bitmap (csp->flags)
- *
- * Moved downgrading of the HTTP version from parse_http_request to
- * chat(), since we can't decide if it is necessary before we have
- * determined the actions for the URL. The HTTP command is now
- * *always* re-built so the repairs need no longer be special-cased.
- *
- * filter_popups now gets a csp pointer so it can raise the new
- * CSP_FLAG_MODIFIED flag.
- *
- * Bugfix
- *
- * Added configurable size limit for the IOB. If the IOB grows so
- * large that the next read would exceed the limit, the header
- * is generated, and the header & unfiltered buffer are flushed
- * to the client. Chat then continues in non-buffering,
- * non-filtering body mode.
- *
- * Revision 1.44 2001/10/02 18:13:57 oes
- * Ooops
- *
- * Revision 1.43 2001/10/02 15:32:13 oes
- * Moved generation of hdr
- *
- * Revision 1.42 2001/09/21 23:02:02 david__schmidt
- * Cleaning up 2 compiler warnings on OS/2.
- *
- * Revision 1.41 2001/09/16 17:05:14 jongfoster
- * Removing unused #include showarg.h
- *
- * Revision 1.40 2001/09/16 15:41:45 jongfoster
- * Fixing signed/unsigned comparison warning.
- *
- * Revision 1.39 2001/09/16 13:21:27 jongfoster
- * Changes to use new list functions.
- *
- * Revision 1.38 2001/09/16 13:01:46 jongfoster
- * Removing redundant function call that zeroed zalloc()'d memory.
- *
- * Revision 1.37 2001/09/10 11:12:24 oes
- * Deleted unused variable
- *
- * Revision 1.36 2001/09/10 10:56:15 oes
- * Silenced compiler warnings
- *
- * Revision 1.35 2001/07/31 14:44:22 oes
- * Deleted unused size parameter from filter_popups()
- *
- * Revision 1.34 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.33 2001/07/29 19:32:00 jongfoster
- * Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
- *
- * Revision 1.32 2001/07/29 18:47:05 jongfoster
- * Adding missing #include "loadcfg.h"
- *
- * Revision 1.31 2001/07/29 12:17:48 oes
- * Applied pthread fix by Paul Lieverse
- *
- * Revision 1.30 2001/07/25 22:57:13 jongfoster
- * __BEOS__ no longer overrides FEATURE_PTHREAD.
- * This is because FEATURE_PTHREAD will soon be widely used, so I
- * want to keep it simple.
- *
- * Revision 1.29 2001/07/24 12:47:06 oes
- * Applied BeOS support update by Eugenia
- *
- * Revision 1.28 2001/07/23 13:26:12 oes
- * Fixed bug in popup-killing for the first read that caused binary garbage to be sent between headers and body
- *
- * Revision 1.27 2001/07/19 19:09:47 haroon
- * - Added code to take care of the situation where while processing the first
- * server response (which includes the server header), after finding the end
- * of the headers we were not looking past the end of the headers for
- * content modification. I enabled it for filter_popups.
- * Someone else should look to see if other similar operations should be
- * done to the discarded portion of the buffer.
- *
- * Note 2001/07/20: No, the other content modification mechanisms will process
- * the whole iob later anyway. --oes
- *
- * Revision 1.26 2001/07/18 12:31:36 oes
- * cosmetics
- *
- * Revision 1.25 2001/07/15 19:43:49 jongfoster
- * Supports POSIX threads.
- * Also removed some unused #includes.
- *
- * Revision 1.24 2001/07/13 14:00:40 oes
- * - Generic content modification scheme:
- * Each feature has its own applicability flag that is set
- * from csp->action->flags.
- * Replaced the "filtering" int flag , by a function pointer
- * "content_filter" to the function that will do the content
- * modification. If it is != NULL, the document will be buffered
- * and processed through *content_filter, which must set
- * csp->content_length and return a modified copy of the body
- * or return NULL (on failiure).
- * - Changed csp->is_text to the more generic bitmap csp->content_type
- * which can currently take the valued CT_TEXT or CT_GIF
- * - Reformatting etc
- * - Removed all #ifdef PCRS
- *
- * Revision 1.23 2001/07/02 02:28:25 iwanttokeepanon
- * Added "#ifdef ACL_FILES" conditional compilation to line 1291 to exclude
- * the `block_acl' call. This prevents a compilation error when the user
- * does not wish to use the "ACL" feature.
- *
- * Revision 1.22 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.21 2001/06/29 13:29:36 oes
- * - Cleaned up, improved comments
- * - Unified all possible interceptors (CGI,
- * block, trust, fast_redirect) in one
- * place, with one (CGI) answer generation
- * mechansim. Much clearer now.
- * - Removed the GIF image generation, which
- * is now done in filters.c:block_url()
- * - Made error conditions like domain lookup
- * failiure or (various) problems while talking
- * to the server use cgi.c:error_response()
- * instead of generating HTML/HTTP in chat() (yuck!)
- * - Removed logentry from cancelled commit
- *
- * Revision 1.20 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.19 2001/06/07 23:12:52 jongfoster
- * Replacing function pointer in struct gateway with a directly
- * called function forwarded_connect().
- * Replacing struct gateway with struct forward_spec
- *
- * Revision 1.18 2001/06/03 19:12:16 oes
- * introduced new cgi handling
- *
- * Revision 1.17 2001/06/01 20:07:23 jongfoster
- * Now uses action +image-blocker{} rather than config->tinygif
- *
- * Revision 1.16 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.15 2001/05/31 21:24:47 jongfoster
- * Changed "permission" to "action" throughout.
- * Removed DEFAULT_USER_AGENT - it must now be specified manually.
- * Moved vanilla wafer check into chat(), since we must now
- * decide whether or not to add it based on the URL.
- *
- * Revision 1.14 2001/05/29 20:14:01 joergs
- * AmigaOS bugfix: PCRS needs a lot of stack, stacksize for child threads
- * increased.
- *
- * Revision 1.13 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.12 2001/05/27 22:17:04 oes
- *
- * - re_process_buffer no longer writes the modified buffer
- * to the client, which was very ugly. It now returns the
- * buffer, which it is then written by chat.
- *
- * - content_length now adjusts the Content-Length: header
- * for modified documents rather than crunch()ing it.
- * (Length info in csp->content_length, which is 0 for
- * unmodified documents)
- *
- * - For this to work, sed() is called twice when filtering.
- *
- * Revision 1.11 2001/05/26 17:27:53 jongfoster
- * Added support for CLF and fixed LOG_LEVEL_LOG.
- * Also did CRLF->LF fix of my previous patch.
- *
- * Revision 1.10 2001/05/26 15:26:15 jongfoster
- * ACL feature now provides more security by immediately dropping
- * connections from untrusted hosts.
- *
- * Revision 1.9 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.8 2001/05/25 22:43:18 jongfoster
- * Fixing minor memory leak and buffer overflow.
- *
- * Revision 1.7 2001/05/25 22:34:30 jongfoster
- * Hard tabs->Spaces
- *
- * Revision 1.6 2001/05/23 00:13:58 joergs
- * AmigaOS support fixed.
- *
- * Revision 1.5 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.4 2001/05/21 19:34:01 jongfoster
- * Made failure to bind() a fatal error.
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 22:34:44 oes
- * - Added hint on GIF char array generation to jcc.c
- * - Cleaned CRLF's from the sources and related files
- * - Repaired logging for REF and FRC
- *
- * Revision 1.1.1.1 2001/05/15 13:58:56 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#ifdef FEATURE_PTHREAD
-#include <pthread.h>
-#endif /* def FEATURE_PTHREAD */
-
-#ifdef _WIN32
-# ifndef FEATURE_PTHREAD
-# ifndef STRICT
-# define STRICT
-# endif
-# include <windows.h>
-# include <process.h>
-# endif /* ndef FEATURE_PTHREAD */
-
-# include "win32.h"
-# ifndef _WIN_CONSOLE
-# include "w32log.h"
-# endif /* ndef _WIN_CONSOLE */
-
-#else /* ifndef _WIN32 */
-
-# if !defined (__OS2__)
-# include <unistd.h>
-# include <sys/wait.h>
-# endif /* ndef __OS2__ */
-# include <sys/time.h>
-# include <sys/stat.h>
-# include <sys/ioctl.h>
-
-#ifdef sun
-#include <sys/termios.h>
-#endif /* sun */
-
-#ifdef unix
-#include <pwd.h>
-#include <grp.h>
-#endif
-
-# include <signal.h>
-
-# ifdef __BEOS__
-# include <socket.h> /* BeOS has select() for sockets only. */
-# include <OS.h> /* declarations for threads and stuff. */
-# endif
-
-# if defined(__EMX__) || defined(__OS2__)
-# include <sys/select.h> /* OS/2/EMX needs a little help with select */
-# endif
-# ifdef __OS2__
-#define INCL_DOS
-# include <os2.h>
-#define bzero(B,N) memset(B,0x00,n)
-# endif
-
-# ifndef FD_ZERO
-# include <select.h>
-# endif
-
-#endif
-
-#include "project.h"
-#include "list.h"
-#include "jcc.h"
-#include "filters.h"
-#include "loaders.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;
-
-int no_daemon = 0;
-struct client_state clients[1];
-struct file_list files[1];
-
-#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 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__ */
-
-#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
-
-
-/*********************************************************************
- *
- * Function : chat
- *
- * 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
- * function returns, the caller must close the client
- * socket handle.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : On success, the number of bytes written are returned (zero
- * indicates nothing was written). On error, -1 is returned,
- * and errno is set appropriately. If count is zero and the
- * file descriptor refers to a regular file, 0 will be
- * returned without causing any other effect. For a special
- * file, the results are not portable.
- *
- *********************************************************************/
-static void chat(struct client_state *csp)
-{
-/*
- * 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;
- jb_socket maxfd;
- int server_body;
- int ms_iis5_hack = 0;
- int byte_count = 0;
- const struct forward_spec * fwd;
- struct http_request *http;
- 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;
-
- /*
- * Read the client's request. Note that since we're not using select() we
- * could get blocked here if a client connected, then didn't say anything!
- */
-
- for (;;)
- {
- len = read_socket(csp->cfd, buf, sizeof(buf));
-
- 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 == '\0')
- {
- continue; /* more to come! */
- }
-
-#ifdef FEATURE_FORCE_LOAD
- /* If this request contains the FORCE_PREFIX,
- * better get rid of it now and set the force flag --oes
- */
-
- if (strstr(req, FORCE_PREFIX))
- {
- 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;
- }
-
- if (http->cmd == NULL)
- {
- 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 ((fwd = forward_url(http, csp)) == NULL)
- {
- 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 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.
- *
- * 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 | connect|
- * | w/path | |
- * Forwarding +--------+--------+
- * | | |
- * 1 | create | pass |
- * | w/url | |
- * +--------+--------+
- *
- */
-
- /*
- * Determine the actions for this URL
- */
-#ifdef FEATURE_TOGGLE
- if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
- {
- /* Most compatible set of actions (i.e. none) */
- init_current_action(csp->action);
- }
- else
-#endif /* ndef FEATURE_TOGGLE */
- {
- 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)) )
- {
- 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;
- }
- }
-
-
- /*
- * Downgrade http version from 1.1 to 1.0 if +downgrade
- * action applies
- */
- if ( (http->ssl == 0)
- && (!strcmpic(http->ver, "HTTP/1.1"))
- && (csp->action->flags & ACTION_DOWNGRADE))
- {
- freez(http->ver);
- http->ver = strdup("HTTP/1.0");
-
- if (http->ver == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
- }
- }
-
- /*
- * Save a copy of the original request for logging
- */
- http->ocmd = strdup(http->cmd);
-
- if (http->ocmd == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory copying HTTP request line");
- }
-
- /*
- * (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))
- {
- 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 */
-
- for (;;)
- {
- if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
- {
- len = read_socket(csp->cfd, buf, sizeof(buf));
- if (len <= 0)
- {
- log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
- return;
- }
-
- /*
- * 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;
- }
-
- if (p == NULL) break;
-
- enlist(csp->headers, p);
- freez(p);
- }
- /*
- * We have a request. Now, check to see if we need to
- * intercept it, i.e. If ..
- */
-
- if (
- /* a CGI call was detected and answered */
- (NULL != (rsp = dispatch_cgi(csp)))
-
- /* or we are enabled and... */
- || (IS_ENABLED_AND (
-
- /* ..the request was blocked */
- ( NULL != (rsp = block_url(csp)))
-
- /* ..or untrusted */
-#ifdef FEATURE_TRUST
- || ( NULL != (rsp = trust_url(csp)))
-#endif /* def FEATURE_TRUST */
-
- /* ..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 */
- ))
- )
- {
- /* 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))
- {
- log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
- }
-
-#ifdef FEATURE_STATISTICS
- /* Count as a rejected request */
- csp->flags |= CSP_FLAG_REJECTED;
-#endif /* def FEATURE_STATISTICS */
-
- /* 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 (fwd->forward_host)
- {
- log_error(LOG_LEVEL_CONNECT, "via %s:%d to: %s",
- fwd->forward_host, fwd->forward_port, http->hostport);
- }
- else
- {
- log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
- }
-
- /* here we connect to the server, gateway, or the forwarder */
-
- csp->sfd = forwarded_connect(fwd, http, csp);
-
- if (csp->sfd == JB_INVALID_SOCKET)
- {
- log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E",
- http->hostport);
-
- if (errno == EINVAL)
- {
- 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
- {
- rsp = error_response(csp, "connect-failed", errno);
-
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
- csp->ip_addr_str, http->ocmd);
- }
-
-
- /* 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);
- }
- }
-
- free_http_response(rsp);
- return;
- }
-
- log_error(LOG_LEVEL_CONNECT, "OK");
-
- 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)
- */
-
- 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);
-
- 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);
- freez(hdr);
- return;
- }
- }
- else
- {
- /*
- * We're running an SSL tunnel and we're not forwarding,
- * so just send the "connect succeeded" message to the
- * client, flush the rest, and get out of the way.
- */
- 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;
- }
- IOB_RESET(csp);
- }
-
- /* we're finished with the client's header */
- freez(hdr);
-
- maxfd = ( csp->cfd > csp->sfd ) ? csp->cfd : csp->sfd;
-
- /* pass data between the client and server
- * until one or the other shuts down the connection.
- */
-
- server_body = 0;
-
- 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((int)maxfd+1, &rfds, NULL, NULL, NULL);
-
- if (n < 0)
- {
- log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
- return;
- }
-
- /* this is the body of the browser's request
- * just read it and write it.
- */
-
- if (FD_ISSET(csp->cfd, &rfds))
- {
- len = read_socket(csp->cfd, buf, sizeof(buf));
-
- if (len <= 0)
- {
- break; /* "game over, man" */
- }
-
- if (write_socket(csp->sfd, buf, (size_t)len))
- {
- log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
- return;
- }
- continue;
- }
-
- /*
- * 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'? No.
- */
-
-
- if (FD_ISSET(csp->sfd, &rfds))
- {
- fflush( 0 );
- len = read_socket(csp->sfd, buf, sizeof(buf) - 1);
-
- if (len < 0)
- {
- log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
-
- 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[len] = '\0';
-
-#ifdef FEATURE_KILL_POPUPS
- /* Filter the popups on this read. */
- if (block_popups_now)
- {
- filter_popups(buf, csp);
- }
-#endif /* def FEATURE_KILL_POPUPS */
-
- /* Normally, this would indicate that we've read
- * as much as the server has sent us and we can
- * close the client connection. However, Microsoft
- * in its wisdom has released IIS/5 with a bug that
- * prevents it from sending the trailing \r\n in
- * a 302 redirect header (and possibly other headers).
- * To work around this if we've haven't parsed
- * a full header we'll append a trailing \r\n
- * and see if this now generates a valid one.
- *
- * This hack shouldn't have any impacts. If we've
- * already transmitted the header or if this is a
- * SSL connection, then we won't bother with this
- * hack. So we only work on partially received
- * headers. If we append a \r\n and this still
- * doesn't generate a valid header, then we won't
- * transmit anything to the client.
- */
- if (len == 0)
- {
-
- if (server_body || http->ssl)
- {
- /*
- * 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)
- {
- /*
- * 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);
- }
- }
-
- break; /* "game over, man" */
- }
-
- /*
- * 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
- * job. If it fails, we'll exit instead of continuing.
- */
-
- ms_iis5_hack = 1;
- }
-
- /*
- * If this is an SSL connection or we're in the body
- * 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)
- {
- if (content_filter)
- {
- /*
- * 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
- {
- 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
- {
- /* we're still looking for the end of the
- * server's header ... (does that make header
- * parsing an "out of body experience" ?
- */
-
- /*
- * 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)) != NULL)
- {
- if (*p == '\0')
- {
- /* see following note */
- break;
- }
- enlist(csp->headers, p);
- freez(p);
- }
-
- /* NOTE: there are no "empty" headers so
- * if the pointer `p' is not NULL we must
- * assume that we reached the end of the
- * buffer before we hit the end of the header.
- */
-
- if (p)
- {
- if (ms_iis5_hack)
- {
- /* Well, we tried our MS IIS/5
- * hack and it didn't work.
- * The header is incomplete
- * and there isn't anything
- * we can do about it.
- */
- break;
- }
- else
- {
- /* Since we have to wait for
- * more from the server before
- * we can parse the headers
- * we just continue here.
- */
- continue;
- }
- }
-
- /* we have now received the entire header.
- * filter it and send the result to the client
- */
-
- 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");
- }
-
-#ifdef FEATURE_KILL_POPUPS
- /* Start blocking popups if appropriate. */
-
- if ((csp->content_type & CT_TEXT) && /* It's a text / * MIME-Type */
- !http->ssl && /* We talk plaintext */
- block_popups) /* Policy allows */
- {
- 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);
- }
-
-#endif /* def FEATURE_KILL_POPUPS */
-
- /* Buffer and pcrs filter this if appropriate. */
-
- 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;
- }
-
- /*
- * 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");
-
- /* 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 */
-
- freez(hdr);
- server_body = 1;
-
- /* If this was a MS IIS/5 hack then it means
- * the server has already closed the
- * connection. Nothing more to read. Time
- * to bail.
- */
- if (ms_iis5_hack)
- {
- break;
- }
- }
- continue;
- }
-
- 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);
-}
-
-
-/*********************************************************************
- *
- * Function : serve
- *
- * Description : This is little more than chat. We only "serve" to
- * to close any socket that chat may have opened.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * 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 != JB_INVALID_SOCKET)
- {
- close_socket(csp->sfd);
- }
-
- csp->flags &= ~CSP_FLAG_ACTIVE;
-
-}
-
-
-#ifdef __BEOS__
-/*********************************************************************
- *
- * Function : server_thread
- *
- * Description : We only exist to call `serve' in a threaded environment.
- *
- * Parameters :
- * 1 : data = Current client state (buffers, headers, etc...)
- *
- * Returns : Always 0.
- *
- *********************************************************************/
-static int32 server_thread(void *data)
-{
- serve((struct client_state *) 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
- *
- * Description : Load the config file and start the listen loop.
- * This function is a lot more *sane* with the `load_config'
- * and `listen_loop' functions; although it stills does
- * a *little* too much for my taste.
- *
- * Parameters :
- * 1 : argc = Number of parameters (including $0).
- * 2 : argv = Array of (char *)'s to the parameters.
- *
- * Returns : 1 if : can't open config file, unrecognized directive,
- * stats requested in multi-thread mode, can't open the
- * log file, can't open the jar file, listen port is invalid,
- * 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
- * "File", "Exit" menu option.
- *
- *********************************************************************/
-#ifdef __MINGW32__
-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 =
-#if !defined(_WIN32)
- "config"
-#else
- "config.txt"
-#endif
- ;
-
- /*
- * Parse the command line arguments
- */
- while (++argc_pos < argc)
- {
-#if !defined(_WIN32) || defined(_WIN_CONSOLE)
-
- 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];
- }
-
- } /* -END- while (more arguments) */
-
-#if defined(unix)
- if ( *configfile != '/' )
- {
- 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 */
-
-
- files->next = NULL;
-
-#ifdef AMIGA
- InitAmiga();
-#elif defined(_WIN32)
- InitWin32();
-#endif
-
- /*
- * 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 !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++)
- {
- 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]);
- }
- }
-
- 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
- /*
- * We *are* in a windows console app.
- * Print a verbose messages about FAQ's and such
- */
- printf(win32_blurb);
-# endif /* def _WIN_CONSOLE */
-#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 */
- return(-1);
-
-}
-
-
-/*********************************************************************
- *
- * 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
- *
- * Description : bind the listen port and enter a "FOREVER" listening loop.
- *
- * Parameters : N/A
- *
- * Returns : Never.
- *
- *********************************************************************/
-static void listen_loop(void)
-{
- struct client_state *csp = NULL;
- jb_socket bfd;
- struct configuration_spec * config;
-
- config = load_config();
-
- bfd = bind_port_helper(config);
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
- while (!g_terminate)
-#else
- for (;;)
-#endif
- {
-#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
- while (waitpid(-1, NULL, WNOHANG) > 0)
- {
- /* zombie children */
- }
-#endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
-
- /*
- * Free data that was used by died threads
- */
- sweep();
-
-#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_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
- continue;
- }
-
- csp->flags |= CSP_FLAG_ACTIVE;
- csp->sfd = JB_INVALID_SOCKET;
-
- csp->config = config = load_config();
-
- if ( config->need_bind )
- {
- /*
- * Since we were listening to the "old port", we will not see
- * a "listen" param change until the next IJB request. So, at
- * least 1 more request must be made for us to find the new
- * setting. I am simply closing the old socket and binding the
- * new one.
- *
- * Which-ever is correct, we will serve 1 more page via the
- * old settings. This should probably be a "show-proxy-args"
- * request. This should not be a so common of an operation
- * that this will hurt people's feelings.
- */
-
- close_socket(bfd);
-
- bfd = bind_port_helper(config);
- }
-
- log_error(LOG_LEVEL_CONNECT, "accept connection ... ");
-
- if (!accept_connection(csp, bfd))
- {
- log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
-
-#ifdef AMIGA
- if(!childs)
- {
- exit(1);
- }
-#endif
- freez(csp);
- continue;
- }
- else
- {
- log_error(LOG_LEVEL_CONNECT, "OK");
- }
-
-#ifdef FEATURE_TOGGLE
- if (g_bToggleIJB)
- {
- csp->flags |= CSP_FLAG_TOGGLED_ON;
- }
-#endif /* def FEATURE_TOGGLE */
-
- if (run_loader(csp))
- {
- 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 (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 (*)(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
-
-#if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION)
-#define SELECTED_ONE_OPTION
- {
- thread_id tid = spawn_thread
- (server_thread, "server", B_NORMAL_PRIORITY, csp);
-
- if ((tid >= 0) && (resume_thread(tid) == B_OK))
- {
- child_id = (int) tid;
- }
- else
- {
- child_id = -1;
- }
- }
-#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)"privoxy child",
- NP_StackSize, 200*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();
-
- /* This block is only needed when using fork().
- * When using threads, the server thread was
- * created and run by the call to _beginthread().
- */
- if (child_id == 0) /* child */
- {
- serve(csp);
- _exit(0);
-
- }
- else if (child_id > 0) /* parent */
- {
- /* in a fork()'d environment, the parent's
- * copy of the client socket and the CSP
- * are not used.
- */
-
-#if !defined(_WIN32) && defined(__CYGWIN__)
- wait( NULL );
-#endif /* !defined(_WIN32) && defined(__CYGWIN__) */
- close_socket(csp->cfd);
- 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;
- }
- }
- else
- {
- serve(csp);
- }
- }
-
- /* 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 */
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: jcc.h,v $
- * Revision 1.11 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.10 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.9 2002/03/07 03:52:44 oes
- * Set logging to tty for --no-daemon mode
- *
- * Revision 1.8 2002/03/04 18:19:49 oes
- * Added extern const char *pidfile
- *
- * Revision 1.7 2001/11/05 21:41:43 steudten
- * Add changes to be a real daemon just for unix os.
- * (change cwd to /, detach from controlling tty, set
- * process group and session leader to the own process.
- * Add DBG() Macro.
- * Add some fatal-error log message for failed malloc().
- * Add '-d' if compiled with 'configure --with-debug' to
- * enable debug output.
- *
- * Revision 1.6 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.5 2001/07/29 19:32:00 jongfoster
- * Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
- *
- * Revision 1.4 2001/07/29 18:58:15 jongfoster
- * Removing nested #includes, adding forward declarations for needed
- * structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
- *
- * Revision 1.3 2001/07/18 12:31:58 oes
- * moved #define freez from jcc.h to project.h
- *
- * Revision 1.2 2001/05/31 21:24:47 jongfoster
- * Changed "permission" to "action" throughout.
- * Removed DEFAULT_USER_AGENT - it must now be specified manually.
- * Moved vanilla wafer check into chat(), since we must now
- * decide whether or not to add it based on the URL.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:56 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct client_state;
-struct file_list;
-
-/* Global variables */
-
-#ifdef FEATURE_STATISTICS
-extern int urls_read;
-extern int urls_rejected;
-#endif /*def FEATURE_STATISTICS*/
-
-extern struct client_state clients[];
-extern struct file_list files[];
-
-#ifdef unix
-extern const char *pidfile;
-#endif
-extern int no_daemon;
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-extern int g_terminate;
-#endif
-
-/* Functions */
-
-#ifdef __MINGW32__
-int real_main(int argc, const char *argv[]);
-#else
-int main(int argc, const char *argv[]);
-#endif
-
-/* Revision control strings from this header and associated .c file */
-extern const char jcc_rcs[];
-extern const char jcc_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef JCC_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char killpopup_rcs[] = "$Id: killpopup.c,v 1.15 2002/03/24 13:25:43 swa Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/killpopup.c,v $
- *
- * Purpose : Handles the filtering of popups.
- *
- * 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: killpopup.c,v $
- * Revision 1.15 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.14 2002/03/07 03:46:53 oes
- * Fixed compiler warnings etc
- *
- * Revision 1.13 2001/11/13 00:16:40 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.12 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.11 2001/10/07 15:42:41 oes
- * filter_popups now gets a csp pointer so it can raise the new
- * CSP_FLAG_MODIFIED flag.
- *
- * Revision 1.10 2001/09/22 16:34:44 jongfoster
- * Removing unneeded #includes
- *
- * Revision 1.9 2001/07/31 14:44:22 oes
- * Deleted unused size parameter from filter_popups()
- *
- * Revision 1.8 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.7 2001/07/20 19:29:25 haroon
- * - In v1.5 forgot to add that I implemented LOG_LEVEL_POPUPS in errlog.c,
- * errlog.h and killpopup.c. In that case, it is superfluous to have define for
- * POPUP_VERBOSE, so I removed the defines and logging is now done
- * via log_error(LOG_LEVEL_POPUPS, ....)
- *
- * Revision 1.6 2001/07/19 19:11:35 haroon
- * - Implemented Guy's idea of replacing window.open( with 1;''.concat(
- * - Implemented Guy's idea of replacing .resizeTo( with .scrollTo(
- *
- * Revision 1.5 2001/07/18 15:02:52 haroon
- * improved nuking of window.open
- *
- * Revision 1.4 2001/06/29 13:29:55 oes
- * Added FIXMEs (and didn't repair, hehe)
- *
- * Revision 1.3 2001/05/22 18:56:28 oes
- * CRLF -> LF
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:58 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <ctype.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif
-
-#include "project.h"
-#include "killpopup.h"
-#include "errlog.h"
-
-const char killpopup_h_rcs[] = KILLPOPUP_H_VERSION;
-
-#ifdef FEATURE_KILL_POPUPS
-
-/*********************************************************************
- *
- * Function : filter_popups
- *
- * 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 : buff = Buffer to scan and modify. Null terminated.
- * 2 : csp = Client state pointer
- *
- * Returns : void
- *
- *********************************************************************/
-void filter_popups(char *buff, struct client_state *csp)
-{
- char *start_p = NULL;
- char *close_p = NULL;
- char *p = NULL;
-
- /*
- * replace the window.open( with a harmless JavaScript replacement
- * (notice the two single quotes)
- */
- while ((start_p = strstr(buff, "window.open(")) != NULL)
- {
- if (start_p)
- {
- strncpy(start_p, "1;''.concat(", 12);
- log_error(LOG_LEVEL_POPUPS, "Blocked popup window open");
- csp->flags |= CSP_FLAG_MODIFIED;
- }
- }
-
- /*
- * replace the .resizeTo( with a harmless JavaScript replacement
- */
- while ((start_p = strstr(buff, ".resizeTo(")) != NULL)
- {
- if (start_p)
- {
- strncpy(start_p, ".scrollTo(", 10);
- log_error(LOG_LEVEL_POPUPS, "Blocked popup window resize");
- csp->flags |= CSP_FLAG_MODIFIED;
- }
- }
-
- /*
- * Filter onUnload and onExit
- */
- start_p = strstr(buff, "<body");
- if (!start_p) start_p = strstr(buff, "<BODY");
- if (!start_p) start_p = strstr(buff, "<Body");
- if (!start_p) start_p = strstr(buff, "<BOdy");
- if (start_p)
- {
- close_p = strchr(start_p, '>');
- if (close_p)
- {
- /* we are now between <body and the ending > */
- p = strstr(start_p, "onUnload");
- if (p)
- {
- strncpy(p, "_nU_", 4);
- csp->flags |= CSP_FLAG_MODIFIED;
- }
- p = strstr(start_p, "onExit");
- if (p)
- {
- strncpy(p, "_nE_", 4);
- csp->flags |= CSP_FLAG_MODIFIED;
- }
- }
- }
-
-}
-
-#endif /* def FEATURE_KILL_POPUPS */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/killpopup.h,v $
- *
- * Purpose : Handles the filtering of popups.
- *
- * 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: killpopup.h,v $
- * Revision 1.7 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.6 2001/10/07 15:42:41 oes
- * filter_popups now gets a csp pointer so it can raise the new
- * CSP_FLAG_MODIFIED flag.
- *
- * Revision 1.5 2001/07/31 14:44:22 oes
- * Deleted unused size parameter from filter_popups()
- *
- * Revision 1.4 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.3 2001/07/29 18:59:21 jongfoster
- * - Changing #define _KILLPOPUP_H to KILLPOPUP_H_INCLUDED
- * - Adding extern "C" {}
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:58:58 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef FEATURE_KILL_POPUPS
-
-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[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef KILLPOPUP_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char list_rcs[] = "$Id: list.c,v 1.14 2002/03/24 13:25:43 swa Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/list.c,v $
- *
- * Purpose : Declares functions to handle lists.
- * Functions declared include:
- * `destroy_list', `enlist' and `list_to_text'
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: list.c,v $
- * Revision 1.14 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.13 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.12 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.11 2001/10/23 21:21:03 jongfoster
- * New error handling - error codes are now jb_errs, not ints.
- * Changed the way map() handles out-of-memory, to dramatically
- * reduce the amount of error-checking clutter needed.
- *
- * Revision 1.10 2001/09/16 17:30:24 jongfoster
- * Fixing a compiler warning.
- *
- * Revision 1.9 2001/09/16 13:20:29 jongfoster
- * Rewrite of list library. Now has seperate header and list_entry
- * structures. Also added a large sprinking of assert()s to the list
- * code.
- *
- * Revision 1.8 2001/08/07 14:00:20 oes
- * Fixed comment
- *
- * Revision 1.7 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.6 2001/07/31 14:44:51 oes
- * list_to_text() now appends empty line at end
- *
- * Revision 1.5 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.4 2001/06/29 13:30:22 oes
- * - Added Convenience function enlist_unique_header(),
- * which takes the Header name and value as separate
- * arguments and thus saves the pain of sprintf()ing
- * and determining the Header name length to enlist_unique
- * - Improved comments
- * - Removed logentry from cancelled commit
- *
- * Revision 1.3 2001/06/03 19:12:24 oes
- * functions for new struct map, extended enlist_unique
- *
- * Revision 1.2 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.1 2001/05/31 21:11:53 jongfoster
- * - Moved linked list support to new "list.c" file.
- * Structure definitions are still in project.h,
- * function prototypes are now in "list.h".
- * - Added support for "struct list_share", which is identical
- * to "struct list" except it saves memory by not duplicating
- * the strings. Obviously, this only works if there is some
- * other way of managing the memory used by the strings.
- * (These list_share lists are used for lists which last
- * for only 1 request, and where all the list entries are
- * just coming directly from entries in the actionsfile.)
- * Note that you still need to destroy list_share lists
- * properly to free the nodes - it's only the strings
- * which are shared.
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#ifndef _WIN32
-/* FIXME: The following headers are not needed for Win32. Are they
- * needed on other platforms?
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-#endif
-#include <string.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif
-
-#include <assert.h>
-
-#include "project.h"
-#include "list.h"
-#include "miscutil.h"
-
-const char list_h_rcs[] = LIST_H_VERSION;
-
-
-static int list_is_valid (const struct list *the_list);
-
-
-/*********************************************************************
- *
- * Function : list_init
- *
- * Description : Create a new, empty list in user-allocated memory.
- * Caller should allocate a "struct list" variable,
- * then pass it to this function.
- * (Implementation note: Rather than calling this
- * function, you can also just memset the memory to
- * zero, e.g. if you have a larger structure you
- * want to initialize quickly. However, that isn't
- * really good design.)
- *
- * Parameters :
- * 1 : the_list = pointer to list
- *
- * Returns : N/A
- *
- *********************************************************************/
-void init_list(struct list *the_list)
-{
- memset(the_list, '\0', sizeof(*the_list));
-}
-
-
-/*********************************************************************
- *
- * Function : destroy_list
- *
- * Description : Destroy a string list (opposite of list_init).
- * On return, the memory used by the list entries has
- * been freed, but not the memory used by the_list
- * itself. You should not re-use the_list without
- * calling list_init().
- *
- * (Implementation note: You *can* reuse the_list
- * without calling list_init(), but please don't.
- * If you want to remove all entries from a list
- * and still have a usable list, then use
- * list_remove_all().)
- *
- * Parameters :
- * 1 : the_list = pointer to list
- *
- * Returns : N/A
- *
- *********************************************************************/
-void destroy_list (struct list *the_list)
-{
- struct list_entry *cur_entry, *next_entry;
-
- assert(the_list);
-
- for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
- {
- next_entry = cur_entry->next;
- freez(cur_entry->str);
- free(cur_entry);
- }
-
- the_list->first = NULL;
- the_list->last = NULL;
-}
-
-
-/*********************************************************************
- *
- * Function : list_is_valid
- *
- * Description : Check that a string list is valid. The intended
- * usage is "assert(list_is_valid(the_list))".
- * Currently this checks that "the_list->last"
- * is correct, and that the list dosn't contain
- * circular references. It is likely to crash if
- * it's passed complete garbage.
- *
- * Parameters :
- * 1 : the_list = pointer to list. Must be non-null.
- *
- * Returns : 1 if list is valid, 0 otherwise.
- *
- *********************************************************************/
-static int list_is_valid (const struct list *the_list)
-{
- /*
- * If you don't want this check, just change the line below
- * from "#if 1" to "#if 0".
- */
-#if 1
- const struct list_entry *cur_entry;
- const struct list_entry *last_entry = NULL;
- int length = 0;
-
- assert(the_list);
-
- for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
- {
- last_entry = cur_entry;
-
- if (cur_entry->str)
- {
- /*
- * Just check that this string can be accessed - i.e. it's a valid
- * pointer.
- */
- strlen(cur_entry->str);
- }
-
- /*
- * Check for looping back to first
- */
- if ((length != 0) && (cur_entry == the_list->first))
- {
- return 0;
- }
-
- /*
- * Arbitrarily limit length to prevent infinite loops.
- */
- if (++length > 1000)
- {
- return 0;
- }
-
- /*
- * Check this isn't marked as the last entry, unless of course it's
- * *really* the last entry.
- */
- if ((the_list->last == cur_entry) && (cur_entry->next != NULL))
- {
- /* This is the last entry, but there's data after it !!?? */
- return 0;
- }
- }
-
- return (the_list->last == last_entry);
-#else
- return 1;
-#endif
-}
-
-/*********************************************************************
- *
- * Function : enlist
- *
- * Description : Append a string into a specified string list.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- * 2 : str = string to add to the list (maybe NULL)
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, the_list will be unchanged.
- *
- *********************************************************************/
-jb_err enlist(struct list *the_list, const char *str)
-{
- struct list_entry *cur;
-
- assert(the_list);
- assert(list_is_valid(the_list));
-
- if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
- {
- return JB_ERR_MEMORY;
- }
-
- if (str)
- {
- if (NULL == (cur->str = strdup(str)))
- {
- free(cur);
- return JB_ERR_MEMORY;
- }
- }
- /* else { cur->str = NULL; } - implied by zalloc */
-
- /* cur->next = NULL; - implied by zalloc */
-
- if (the_list->last)
- {
- the_list->last->next = cur;
- the_list->last = cur;
- }
- else
- {
- the_list->first = cur;
- the_list->last = cur;
- }
-
- assert(list_is_valid(the_list));
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : enlist_first
- *
- * Description : Append a string as first element into a specified
- * string list.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- * 2 : str = string to add to the list (maybe NULL)
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, the_list will be unchanged.
- *
- *********************************************************************/
-jb_err enlist_first(struct list *the_list, const char *str)
-{
- struct list_entry *cur;
-
- assert(the_list);
- assert(list_is_valid(the_list));
-
- if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
- {
- return JB_ERR_MEMORY;
- }
-
- if (str)
- {
- if (NULL == (cur->str = strdup(str)))
- {
- free(cur);
- return JB_ERR_MEMORY;
- }
- }
- /* else { cur->str = NULL; } - implied by zalloc */
-
- cur->next = the_list->first;
-
- the_list->first = cur;
- if (the_list->last == NULL)
- {
- the_list->last = cur;
- }
-
- assert(list_is_valid(the_list));
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : enlist_unique
- *
- * Description : Append a string into a specified string list,
- * if & only if it's not there already.
- * If the num_significant_chars argument is nonzero,
- * only compare up to the nth character.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- * 2 : str = string to add to the list
- * 3 : num_significant_chars = number of chars to use
- * for uniqueness test, or 0 to require an exact match.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, the_list will be unchanged.
- * "Success" does not indicate whether or not the
- * item was already in the list.
- *
- *********************************************************************/
-jb_err enlist_unique(struct list *the_list, const char *str,
- size_t num_significant_chars)
-{
- struct list_entry *cur_entry;
-
- assert(the_list);
- assert(list_is_valid(the_list));
- assert(str);
- assert(num_significant_chars >= 0);
- assert(num_significant_chars <= strlen(str));
-
- if (num_significant_chars > 0)
- {
- for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
- {
- if ( (cur_entry->str != NULL)
- && (0 == strncmp(str, cur_entry->str, num_significant_chars)))
- {
- /* Already there */
- return JB_ERR_OK;
- }
- }
- }
- else
- {
- /* Test whole string */
- for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
- {
- if ( (cur_entry->str != NULL) && (0 == strcmp(str, cur_entry->str)))
- {
- /* Already there */
- return JB_ERR_OK;
- }
- }
- }
-
- return enlist(the_list, str);
-}
-
-
-/*********************************************************************
- *
- * Function : enlist_unique_header
- *
- * Description : Make a HTTP header from the two strings name and value,
- * and append the result into a specified string list,
- * if & only if there isn't already a header with that name.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- * 2 : name = HTTP header name (e.g. "Content-type")
- * 3 : value = HTTP header value (e.g. "text/html")
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, the_list will be unchanged.
- * "Success" does not indicate whether or not the
- * header was already in the list.
- *
- *********************************************************************/
-jb_err enlist_unique_header(struct list *the_list, const char *name,
- const char *value)
-{
- size_t length;
- jb_err result;
- char *str;
-
- assert(the_list);
- assert(list_is_valid(the_list));
- assert(name);
- assert(value);
-
- length = strlen(name) + 2;
- if (NULL == (str = (char *)malloc(length + strlen(value) + 1)))
- {
- return JB_ERR_MEMORY;
- }
- strcpy(str, name);
- str[length - 2] = ':';
- str[length - 1] = ' ';
- strcpy(str + length, value);
-
- result = enlist_unique(the_list, str, length);
-
- free(str);
-
- assert(list_is_valid(the_list));
-
- return result;
-
-}
-
-
-/*********************************************************************
- *
- * Function : list_remove_all
- *
- * Description : Remove all entries from a list. On return, the_list
- * is a valid, empty list. Note that this is similar
- * to destroy_list(), but the difference is that this
- * function guarantees that the list structure is still
- * valid after the call.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- *
- * Returns : N/A
- *
- *********************************************************************/
-void list_remove_all(struct list *the_list)
-{
- struct list_entry *cur_entry;
- struct list_entry *next_entry;
-
- assert(the_list);
- assert(list_is_valid(the_list));
-
- for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
- {
- next_entry = cur_entry->next;
- freez(cur_entry->str);
- free(cur_entry);
- }
-
- the_list->first = the_list->last = NULL;
-
- assert(list_is_valid(the_list));
-}
-
-
-/*********************************************************************
- *
- * Function : list_to_text
- *
- * Description : "Flatten" a string list into 1 long \r\n delimited string,
- * adding an empty line at the end. NULL entries are ignored.
- * This function does not change the_list.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- *
- * Returns : NULL on malloc error, else new long string.
- * Caller must free() it.
- *
- *********************************************************************/
-char *list_to_text(const struct list *the_list)
-{
- struct list_entry *cur_entry;
- char *ret = NULL;
- char *s;
- size_t size = 2;
-
- assert(the_list);
- assert(list_is_valid(the_list));
-
- for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
- {
- if (cur_entry->str)
- {
- size += strlen(cur_entry->str) + 2;
- }
- }
-
- if ((ret = (char *)malloc(size + 1)) == NULL)
- {
- return NULL;
- }
-
- ret[size] = '\0';
-
- s = ret;
-
- for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
- {
- if (cur_entry->str)
- {
- strcpy(s, cur_entry->str);
- s += strlen(s);
- *s++ = '\r'; *s++ = '\n';
- }
- }
- *s++ = '\r'; *s++ = '\n';
-
- return ret;
-}
-
-
-/*********************************************************************
- *
- * Function : list_remove_item
- *
- * Description : Remove a string from a specified string list.
- *
- * Parameters :
- * 1 : the_list = pointer to list
- * 2 : str = string to remove from the list - non-NULL
- *
- * Returns : Number of times it was removed.
- *
- *********************************************************************/
-int list_remove_item(struct list *the_list, const char *str)
-{
- struct list_entry *prev = NULL;
- struct list_entry *cur;
- struct list_entry *next;
- int count = 0;
-
- assert(the_list);
- assert(list_is_valid(the_list));
- assert(str);
-
- cur = the_list->first;
-
- while (cur != NULL)
- {
- next = cur->next;
-
- if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
- {
- count++;
-
- if (prev != NULL)
- {
- prev->next = next;
- }
- else
- {
- the_list->first = next;
- }
- free((char *)cur->str);
- free(cur);
- }
- else
- {
- prev = cur;
- }
- cur = next;
- }
-
- the_list->last = prev;
-
- assert(list_is_valid(the_list));
-
- return count;
-}
-
-
-/*********************************************************************
- *
- * Function : list_remove_list
- *
- * Description : Remove all strings in one list from another list.
- * This is currently a brute-force algorithm
- * (it compares every pair of strings).
- *
- * Parameters :
- * 1 : dest = list to change
- * 2 : src = list of strings to remove
- *
- * Returns : Total number of strings removed.
- *
- *********************************************************************/
-int list_remove_list(struct list *dest, const struct list *src)
-{
- struct list_entry *cur;
- int count = 0;
-
- assert(src);
- assert(dest);
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- for (cur = src->first; cur != NULL; cur = cur->next)
- {
- if (cur->str != NULL)
- {
- count += list_remove_item(dest, cur->str);
- }
- }
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return count;
-}
-
-
-/*********************************************************************
- *
- * Function : list_duplicate
- *
- * Description : Copy a string list
- *
- * Parameters :
- * 1 : dest = Destination list. Must be a valid list.
- * All existing entries will be removed.
- * 1 : src = pointer to source list for copy.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, dest will be empty.
- *
- *********************************************************************/
-jb_err list_duplicate(struct list *dest, const struct list *src)
-{
- struct list_entry * cur_src;
- struct list_entry * cur_dest;
-
- assert(src);
- assert(dest);
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- list_remove_all(dest);
-
- /* Need to process first entry specially so we can set dest->first */
- cur_src = src->first;
- if (cur_src)
- {
- cur_dest = dest->first = (struct list_entry *)zalloc(sizeof(*cur_dest));
- if (cur_dest == NULL)
- {
- destroy_list(dest);
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_MEMORY;
- }
-
- if (cur_src->str)
- {
- cur_dest->str = strdup(cur_src->str);
- if (cur_dest->str == NULL)
- {
- destroy_list(dest);
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_MEMORY;
- }
- }
- /* else { cur_dest->str = NULL; } - implied by zalloc */
-
- /* Now process the rest */
- for (cur_src = cur_src->next; cur_src; cur_src = cur_src->next)
- {
- cur_dest = cur_dest->next = (struct list_entry *)zalloc(sizeof(*cur_dest));
- if (cur_dest == NULL)
- {
- destroy_list(dest);
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_MEMORY;
- }
- if (cur_src->str)
- {
- cur_dest->str = strdup(cur_src->str);
- if (cur_dest->str == NULL)
- {
- destroy_list(dest);
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_MEMORY;
- }
- }
- /* else { cur_dest->str = NULL; } - implied by zalloc */
- }
-
- dest->last = cur_dest;
- }
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : list_append_list_unique
- *
- * Description : Append a string list to another list.
- * Duplicate items are not added.
- *
- * Parameters :
- * 1 : dest = pointer to destination list for merge.
- * 2 : src = pointer to source for merge.
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- * On error, some (but not all) of src might have
- * been copied into dest.
- *
- *********************************************************************/
-jb_err list_append_list_unique(struct list *dest, const struct list *src)
-{
- struct list_entry * cur;
-
- assert(src);
- assert(dest);
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- for (cur = src->first; cur; cur = cur->next)
- {
- if (cur->str)
- {
- if (enlist_unique(dest, cur->str, 0))
- {
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_MEMORY;
- }
- }
- }
-
- assert(list_is_valid(src));
- assert(list_is_valid(dest));
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : list_is_empty
- *
- * Description : Test whether a list is empty. Does not change the list.
- *
- * Parameters :
- * 1 : the_list = pointer to list to test.
- *
- * Returns : Nonzero iff the list contains no entries.
- *
- *********************************************************************/
-int list_is_empty(const struct list *the_list)
-{
- assert(the_list);
- assert(list_is_valid(the_list));
-
- return (the_list->first == NULL);
-}
-
-
-/*********************************************************************
- *
- * Function : new_map
- *
- * Description : Create a new, empty map.
- *
- * Parameters : N/A
- *
- * Returns : A new, empty map, or NULL if out of memory.
- *
- *********************************************************************/
-struct map *new_map(void)
-{
- return (struct map *) zalloc(sizeof(struct map));
-}
-
-
-/*********************************************************************
- *
- * Function : free_map
- *
- * Description : Free the memory occupied by a map and its
- * depandant strings
- *
- * Parameters :
- * 1 : the_map = map to be freed. May be NULL.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_map(struct map *the_map)
-{
- struct map_entry *cur_entry;
- struct map_entry *next_entry;
-
- if (the_map == NULL)
- {
- return;
- }
-
- for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry)
- {
- freez(cur_entry->name);
- freez(cur_entry->value);
-
- next_entry = cur_entry->next;
- free(cur_entry);
- }
-
- the_map->first = the_map->last = NULL;
-
- free(the_map);
-}
-
-
-/*********************************************************************
- *
- * Function : map
- *
- * Description : Add a mapping from given name to given value to a
- * given map.
- *
- * Note: Since all strings will be free()d in free_map()
- * later, set the copy flags for constants or
- * strings that will be independantly free()d.
- *
- * Note2: This function allows NULL parameters - it
- * returns JB_ERR_MEMORY in that case.
- *
- * Note3: If this function returns JB_ERR_MEMORY,
- * it will free(name) unless you specify
- * name_needs_copying, and similarly it will
- * free(value) unless you specify
- * value_needs_copying.
- *
- * Due to Note2 and Note3 above, the following code
- * is legal, and will never crash or leak memory even
- * if the system runs out of memory:
- *
- * err = map(mymap, "xyz", 1, html_encode(somestring), 0);
- *
- * err will be set to JB_ERR_MEMORY if either call runs
- * out-of-memory. Without these features, you would
- * need to check the return value of html_encode in the
- * above example for NULL, which (at least) doubles the
- * amount of error-checking code needed.
- *
- * Parameters :
- * 1 : the_map = map to add to
- * 2 : name = name to add
- * 3 : name_needs_copying = flag set if a copy of name should be used
- * 4 : value = value to add
- * 5 : value_needs_copying = flag set if a copy of value should be used
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err map(struct map *the_map,
- const char *name, int name_needs_copying,
- const char *value, int value_needs_copying)
-{
- struct map_entry *new_entry;
-
- assert(the_map);
-
- if ( (NULL == value)
- || (NULL == name)
- || (NULL == (new_entry = zalloc(sizeof(*new_entry)))) )
- {
- if ((name != NULL) && (!name_needs_copying))
- {
- free((char *)name);
- }
- if ((value != NULL) && (!value_needs_copying))
- {
- free((char *)value);
- }
- return JB_ERR_MEMORY;
- }
-
- if (name_needs_copying)
- {
- if (NULL == (name = strdup(name)))
- {
- free(new_entry);
- if (!value_needs_copying)
- {
- free((char *)value);
- }
- return JB_ERR_MEMORY;
- }
- }
-
- if (value_needs_copying)
- {
- if (NULL == (value = strdup(value)))
- {
- free((char *)name);
- free(new_entry);
- return JB_ERR_MEMORY;
- }
- }
-
- new_entry->name = name;
- new_entry->value = value;
- /* new_entry->next = NULL; - implied by zalloc */
-
- if (the_map->last)
- {
- the_map->last->next = new_entry;
- the_map->last = new_entry;
- }
- else
- {
- the_map->first = new_entry;
- the_map->last = new_entry;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : lookup
- *
- * Description : Look up an item with a given name in a map, and
- * return its value
- *
- * Parameters :
- * 1 : the_map = map to look in
- * 2 : name = name parameter to look for
- *
- * Returns : the value if found, else the empty string.
- * Return value is alloced as part of the map, so
- * it is freed when the map is destroyed. Caller
- * must not free or modify it.
- *
- *********************************************************************/
-const char *lookup(const struct map *the_map, const char *name)
-{
- const struct map_entry *cur_entry;
-
- assert(the_map);
- assert(name);
-
- for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
- {
- if (!strcmp(name, cur_entry->name))
- {
- return cur_entry->value;
- }
- }
- return "";
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef LIST_H_INCLUDED
-#define LIST_H_INCLUDED
-#define LIST_H_VERSION "$Id: list.h,v 1.11 2002/03/24 13:25:43 swa Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/list.h,v $
- *
- * Purpose : Declares functions to handle lists.
- * Functions declared include:
- * `destroy_list', `enlist' and `list_to_text'
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: list.h,v $
- * Revision 1.11 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.10 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.9 2001/10/23 21:21:03 jongfoster
- * New error handling - error codes are now jb_errs, not ints.
- * Changed the way map() handles out-of-memory, to dramatically
- * reduce the amount of error-checking clutter needed.
- *
- * Revision 1.8 2001/09/16 17:30:24 jongfoster
- * Fixing a compiler warning.
- *
- * Revision 1.7 2001/09/16 13:20:29 jongfoster
- * Rewrite of list library. Now has seperate header and list_entry
- * structures. Also added a large sprinking of assert()s to the list
- * code.
- *
- * Revision 1.6 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.5 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.4 2001/06/29 13:30:37 oes
- * - Introduced enlist_unique_header()
- * - Removed logentry from cancelled commit
- *
- * Revision 1.3 2001/06/03 11:03:48 oes
- * introduced functions for new list type "map": map(), lookup(),
- * free_map(), and extended enlist_unique
- *
- * Revision 1.2 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.1 2001/05/31 21:11:53 jongfoster
- * - Moved linked list support to new "list.c" file.
- * Structure definitions are still in project.h,
- * function prototypes are now in "list.h".
- * - Added support for "struct list_share", which is identical
- * to "struct list" except it saves memory by not duplicating
- * the strings. Obviously, this only works if there is some
- * other way of managing the memory used by the strings.
- * (These list_share lists are used for lists which last
- * for only 1 request, and where all the list entries are
- * just coming directly from entries in the actionsfile.)
- * Note that you still need to destroy list_share lists
- * properly to free the nodes - it's only the strings
- * which are shared.
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * struct list
- *
- * A linked list class.
- */
-
-extern void init_list (struct list *the_list);
-extern void destroy_list (struct list *the_list);
-
-extern jb_err enlist (struct list *the_list, const char *str);
-extern jb_err enlist_unique (struct list *the_list, const char *str, size_t num_significant_chars);
-extern jb_err enlist_unique_header (struct list *the_list, const char *name, const char *value);
-extern jb_err enlist_first (struct list *the_list, const char *str);
-extern jb_err list_append_list_unique(struct list *dest, const struct list *src);
-extern jb_err list_duplicate (struct list *dest, const struct list *src);
-
-extern int list_remove_item(struct list *the_list, const char *str);
-extern int list_remove_list(struct list *dest, const struct list *src);
-extern void list_remove_all (struct list *the_list);
-
-extern int list_is_empty(const struct list *the_list);
-
-extern char * list_to_text(const struct list *the_list);
-
-
-/*
- * struct map
- *
- * A class which maps names to values.
- *
- * Note: You must allocate this through new_map() and free it
- * through free_map().
- */
-
-extern struct map * new_map (void);
-extern void free_map (struct map * the_map);
-
-extern int map (struct map * the_map,
- const char * name, int name_needs_copying,
- const char * value, int value_needs_copying);
-extern const char * lookup (const struct map * the_map, const char * name);
-
-
-/* Revision control strings from this header and associated .c file */
-extern const char list_rcs[];
-extern const char list_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef LIST_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.47 2002/05/12 21:36:29 jongfoster Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
- *
- * Purpose : Loads settings from the configuration file into
- * 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
- * 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: loadcfg.c,v $
- * Revision 1.47 2002/05/12 21:36:29 jongfoster
- * Correcting function comments
- *
- * Revision 1.46 2002/04/26 12:55:14 oes
- * - New option "user-manual", defaults to our site
- * via project.h #define
- * - savearg now embeds option names in help links
- *
- * Revision 1.45 2002/04/24 02:11:54 oes
- * Jon's multiple AF patch: Allow up to MAX_ACTION_FILES actionsfile options
- *
- * Revision 1.44 2002/04/08 20:37:13 swa
- * fixed JB spelling
- *
- * Revision 1.43 2002/04/08 20:36:50 swa
- * fixed JB spelling
- *
- * Revision 1.42 2002/04/05 15:50:15 oes
- * fix for invalid HTML proxy_args
- *
- * Revision 1.41 2002/03/31 17:19:00 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.40 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.39 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.38 2002/03/24 13:05:48 jongfoster
- * Renaming re_filterfile to filterfile
- *
- * Revision 1.37 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.36 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.35 2002/03/07 03:52:44 oes
- * Set logging to tty for --no-daemon mode
- *
- * Revision 1.34 2002/03/06 23:14:35 jongfoster
- * Trivial cosmetic changes to make function comments easier to find.
- *
- * Revision 1.33 2002/03/05 04:52:42 oes
- * Deleted non-errlog debugging code
- *
- * Revision 1.32 2002/03/04 18:24:53 oes
- * Re-enabled output of unknown config directive hash
- *
- * Revision 1.31 2002/03/03 15:07:20 oes
- * Re-enabled automatic config reloading
- *
- * Revision 1.30 2002/01/22 23:31:43 jongfoster
- * Replacing strsav() with string_append()
- *
- * Revision 1.29 2002/01/17 21:02:30 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Revision 1.28 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.27 2001/11/07 00:02:13 steudten
- * Add line number in error output for lineparsing for
- * actionsfile and configfile.
- * Special handling for CLF added.
- *
- * Revision 1.26 2001/11/05 21:41:43 steudten
- * Add changes to be a real daemon just for unix os.
- * (change cwd to /, detach from controlling tty, set
- * process group and session leader to the own process.
- * Add DBG() Macro.
- * Add some fatal-error log message for failed malloc().
- * Add '-d' if compiled with 'configure --with-debug' to
- * enable debug output.
- *
- * Revision 1.25 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.24 2001/10/23 21:40:30 jongfoster
- * Added support for enable-edit-actions and enable-remote-toggle config
- * file options.
- *
- * Revision 1.23 2001/10/07 15:36:00 oes
- * Introduced new config option "buffer-limit"
- *
- * Revision 1.22 2001/09/22 16:36:59 jongfoster
- * Removing unused parameter fs from read_config_line()
- *
- * Revision 1.21 2001/09/16 17:10:43 jongfoster
- * Moving function savearg() here, since it was the only thing left in
- * showargs.c.
- *
- * Revision 1.20 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.19 2001/07/15 17:45:16 jongfoster
- * Removing some unused #includes
- *
- * Revision 1.18 2001/07/13 14:01:14 oes
- * - Removed all #ifdef PCRS
- * - Removed vim-settings
- *
- * Revision 1.17 2001/06/29 13:31:03 oes
- * - Improved comments
- * - Fixed (actionsfile) and sorted hashes
- * - Introduced admin_address and proxy-info-url
- * as config parameters
- * - Renamed config->proxy_args_invocation (which didn't have
- * the invocation but the options!) to config->proxy_args
- * - Various adaptions
- * - Removed logentry from cancelled commit
- *
- * Revision 1.16 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.15 2001/06/07 23:13:40 jongfoster
- * Merging ACL and forward files into config file.
- * Cosmetic: Sorting config file options alphabetically.
- * Cosmetic: Adding brief syntax comments to config file options.
- *
- * Revision 1.14 2001/06/07 14:46:25 joergs
- * Missing make_path() added for re_filterfile.
- *
- * Revision 1.13 2001/06/05 22:33:54 jongfoster
- *
- * Fixed minor memory leak.
- * Also now uses make_path to prepend the pathnames.
- *
- * Revision 1.12 2001/06/05 20:04:09 jongfoster
- * Now uses _snprintf() in place of snprintf() under Win32.
- *
- * Revision 1.11 2001/06/04 18:31:58 swa
- * files are now prefixed with either `confdir' or `logdir'.
- * `make redhat-dist' replaces both entries confdir and logdir
- * with redhat values
- *
- * Revision 1.10 2001/06/03 19:11:54 oes
- * introduced confdir option
- *
- * Revision 1.9 2001/06/01 20:06:24 jongfoster
- * Removed support for "tinygif" option - moved to actions file.
- *
- * Revision 1.8 2001/05/31 21:27:13 jongfoster
- * Removed many options from the config file and into the
- * "actions" file: add_forwarded, suppress_vanilla_wafer,
- * wafer, add_header, user_agent, referer, from
- * Also globally replaced "permission" with "action".
- *
- * Revision 1.7 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.6 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.5 2001/05/25 22:34:30 jongfoster
- * Hard tabs->Spaces
- *
- * Revision 1.4 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:58:58 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef _WIN32
-
-# ifndef STRICT
-# define STRICT
-# endif
-# include <windows.h>
-
-# include "win32.h"
-# ifndef _WIN_CONSOLE
-# include "w32log.h"
-# endif /* ndef _WIN_CONSOLE */
-
-/* VC++ has "_snprintf", not "snprintf" */
-#define snprintf _snprintf
-
-#else /* ifndef _WIN32 */
-
-#ifndef __OS2__
-# include <unistd.h>
-# include <sys/wait.h>
-#endif
-# include <sys/time.h>
-# include <sys/stat.h>
-# include <signal.h>
-
-#endif
-
-#include "loadcfg.h"
-#include "list.h"
-#include "jcc.h"
-#include "filters.h"
-#include "loaders.h"
-#include "miscutil.h"
-#include "errlog.h"
-#include "ssplit.h"
-#include "encode.h"
-#include "urlmatch.h"
-#include "cgi.h"
-
-const char loadcfg_h_rcs[] = LOADCFG_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_isupper(__X) isupper((int)(unsigned char)(__X))
-#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
-
-#ifdef FEATURE_TOGGLE
-/* by haroon - indicates if ijb is enabled */
-int g_bToggleIJB = 1; /* Privoxy is enabled by default. */
-#endif /* def FEATURE_TOGGLE */
-
-/* The filename of the configfile */
-const char *configfile = NULL;
-
-/*
- * 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;
-
-static struct file_list *current_configfile = NULL;
-
-
-/*
- * 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).
- */
-
-#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);
-
-/*********************************************************************
- *
- * 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;
-
- 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 */
-
- while (cur_fwd != NULL)
- {
- struct forward_spec * next_fwd = cur_fwd->next;
- free_url_spec(cur_fwd->url);
-
- freez(cur_fwd->gateway_host);
- freez(cur_fwd->forward_host);
- free(cur_fwd);
- cur_fwd = next_fwd;
- }
- config->forward = NULL;
-
-#ifdef FEATURE_COOKIE_JAR
- if ( NULL != config->jar )
- {
- fclose( config->jar );
- config->jar = NULL;
- }
-#endif /* def FEATURE_COOKIE_JAR */
-
- freez(config->confdir);
- freez(config->logdir);
-
- freez(config->haddr);
- freez(config->logfile);
-
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- freez(config->actions_file_short[i]);
- freez(config->actions_file[i]);
- }
-
- 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 */
-
- freez(config->re_filterfile);
-
-}
-
-
-#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
-
-
-/*********************************************************************
- *
- * Function : load_config
- *
- * Description : Load the config file and all parameters.
- *
- * Parameters : None
- *
- * Returns : The configuration_spec, or NULL on error.
- *
- *********************************************************************/
-struct configuration_spec * load_config(void)
-{
- 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;
-
- 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);
-
-#ifdef FEATURE_TOGGLE
- g_bToggleIJB = 1;
-#endif /* def FEATURE_TOGGLE */
-
- fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
-
- 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 */
- }
-
- /*
- * 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;
-
- /*
- * 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("");
-
- if ((configfp = fopen(configfile, "r")) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "can't open configuration file '%s': %E",
- configfile);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
-
- 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';
-
- /* Skip over the whitespace in buf */
- while (*p && ((*p == ' ') || (*p == '\t')))
- {
- p++;
- }
-
- /* Copy the argument into arg */
- strcpy(arg, p);
-
- /* Should never happen, but check this anyway */
- if (*cmd == '\0')
- {
- continue;
- }
-
- /* Make sure the command field is lower case */
- for (p=cmd; *p; p++)
- {
- if (ijb_isupper(*p))
- {
- *p = ijb_tolower(*p);
- }
- }
-
- /* Save the argument for show-proxy-args */
- savearg(cmd, arg, config);
-
-
- 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++;
- }
-
- 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;
-
-/* *************************************************************************
- * 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;
-
-/* *************************************************************************
- * confdir directory-name
- * *************************************************************************/
- case hash_confdir :
- freez(config->confdir);
- config->confdir = make_path( NULL, arg);
- continue;
-
-/* *************************************************************************
- * debug n
- * Specifies debug level, multiple values are ORed together.
- * *************************************************************************/
- case hash_debug :
- config->debug |= atoi(arg);
- continue;
-
-/* *************************************************************************
- * 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);
-
- if ((vec_count != 1) && (vec_count != 2))
- {
- log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
- "deny-access directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Wrong number of parameters for "
- "deny-access directive in configuration file.<br><br>\n");
- continue;
- }
-
- /* allocate a new node */
- cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
-
- 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;
-
- if (acl_addr(vec[0], cur_acl->src) < 0)
- {
- log_error(LOG_LEVEL_ERROR, "Invalid source IP for deny-access "
- "directive in configuration file: \"%s\"", vec[0]);
- string_append(&config->proxy_args,
- "<br>\nWARNING: Invalid source IP for deny-access directive"
- " in configuration file: \"");
- string_append(&config->proxy_args,
- vec[0]);
- string_append(&config->proxy_args,
- "\"<br><br>\n");
- freez(cur_acl);
- continue;
- }
- if (vec_count == 2)
- {
- if (acl_addr(vec[1], cur_acl->dst) < 0)
- {
- log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access "
- "directive in configuration file: \"%s\"", vec[0]);
- string_append(&config->proxy_args,
- "<br>\nWARNING: Invalid destination IP for deny-access directive"
- " in configuration file: \"");
- string_append(&config->proxy_args,
- vec[0]);
- string_append(&config->proxy_args,
- "\"<br><br>\n");
- freez(cur_acl);
- continue;
- }
- }
-
- /*
- * 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 */
-
-/* *************************************************************************
- * 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 */
-
-/* *************************************************************************
- * forward url-pattern (.|http-proxy-host[:port])
- * *************************************************************************/
- case hash_forward:
- vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
-
- if (vec_count != 2)
- {
- log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for forward "
- "directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Wrong number of parameters for "
- "forward directive in configuration file.");
- continue;
- }
-
- /* 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;
- }
-
- cur_fwd->type = SOCKS_NONE;
-
- /* Save the URL pattern */
- if (create_url_spec(cur_fwd->url, vec[0]))
- {
- log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward "
- "directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Bad URL specifier for "
- "forward directive in configuration file.");
- continue;
- }
-
- /* Parse the parent HTTP proxy host:port */
- p = vec[1];
-
- if (strcmp(p, ".") != 0)
- {
- cur_fwd->forward_host = strdup(p);
-
- 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;
- }
- }
-
- /* Add to list. */
- cur_fwd->next = config->forward;
- config->forward = cur_fwd;
-
- 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 (vec_count != 3)
- {
- log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
- "forward-socks4 directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Wrong number of parameters for "
- "forward-socks4 directive in configuration file.");
- continue;
- }
-
- /* 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;
- }
-
- cur_fwd->type = SOCKS_4;
-
- /* Save the URL pattern */
- if (create_url_spec(cur_fwd->url, vec[0]))
- {
- log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4 "
- "directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Bad URL specifier for "
- "forward-socks4 directive in configuration file.");
- continue;
- }
-
- /* Parse the SOCKS proxy host[:port] */
- p = vec[1];
-
- if (strcmp(p, ".") != 0)
- {
- cur_fwd->gateway_host = strdup(p);
-
- 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;
- }
- }
-
- /* Parse the parent HTTP proxy host[:port] */
- p = vec[2];
-
- if (strcmp(p, ".") != 0)
- {
- cur_fwd->forward_host = strdup(p);
-
- 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;
- }
- }
-
- /* Add to list. */
- cur_fwd->next = config->forward;
- config->forward = cur_fwd;
-
- continue;
-
-/* *************************************************************************
- * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port])
- * *************************************************************************/
- case hash_forward_socks4a:
- vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
-
- if (vec_count != 3)
- {
- log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
- "forward-socks4a directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Wrong number of parameters for "
- "forward-socks4a directive in configuration file.");
- continue;
- }
-
- /* 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;
- }
-
- cur_fwd->type = SOCKS_4A;
-
- /* Save the URL pattern */
- if (create_url_spec(cur_fwd->url, vec[0]))
- {
- log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4a "
- "directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Bad URL specifier for "
- "forward-socks4a directive in configuration file.");
- continue;
- }
-
- /* Parse the SOCKS proxy host[:port] */
- p = vec[1];
-
- cur_fwd->gateway_host = strdup(p);
-
- 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;
- }
-
- /* Parse the parent HTTP proxy host[:port] */
- p = vec[2];
-
- if (strcmp(p, ".") != 0)
- {
- cur_fwd->forward_host = strdup(p);
-
- 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;
- }
- }
-
- /* Add to list. */
- cur_fwd->next = config->forward;
- config->forward = cur_fwd;
-
- 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;
-
-/* *************************************************************************
- * logdir directory-name
- * *************************************************************************/
- case hash_logdir :
- freez(config->logdir);
- config->logdir = make_path(NULL, 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;
-
-/* *************************************************************************
- * 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);
-
- if ((vec_count != 1) && (vec_count != 2))
- {
- log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
- "permit-access directive in configuration file.");
- string_append(&config->proxy_args,
- "<br>\nWARNING: Wrong number of parameters for "
- "permit-access directive in configuration file.<br><br>\n");
-
- continue;
- }
-
- /* allocate a new node */
- cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
-
- 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;
-
- if (acl_addr(vec[0], cur_acl->src) < 0)
- {
- log_error(LOG_LEVEL_ERROR, "Invalid source IP for permit-access "
- "directive in configuration file: \"%s\"", vec[0]);
- string_append(&config->proxy_args,
- "<br>\nWARNING: Invalid source IP for permit-access directive"
- " in configuration file: \"");
- string_append(&config->proxy_args,
- vec[0]);
- string_append(&config->proxy_args,
- "\"<br><br>\n");
- freez(cur_acl);
- continue;
- }
- if (vec_count == 2)
- {
- if (acl_addr(vec[1], cur_acl->dst) < 0)
- {
- log_error(LOG_LEVEL_ERROR, "Invalid destination IP for "
- "permit-access directive in configuration file: \"%s\"",
- vec[0]);
- string_append(&config->proxy_args,
- "<br>\nWARNING: Invalid destination IP for permit-access directive"
- " in configuration file: \"");
- string_append(&config->proxy_args,
- vec[0]);
- string_append(&config->proxy_args,
- "\"<br><br>\n");
- freez(cur_acl);
- continue;
- }
- }
-
- /*
- * Add it to the list. Note we reverse the list to get the
- * behaviour the user expects. With both the ACL and
- * actions file, the last match wins. However, the internal
- * implementations are different: The actions file is stored
- * in the same order as the file, and scanned completely.
- * With the ACL, we reverse the order as we load it, then
- * when we scan it we stop as soon as we get a match.
- */
- cur_acl->next = config->acl;
- config->acl = cur_acl;
-
- continue;
-#endif /* def FEATURE_ACL */
-
-/* *************************************************************************
- * proxy-info-url url
- * *************************************************************************/
- case hash_proxy_info_url :
- freez(config->proxy_info_url);
- config->proxy_info_url = strdup(arg);
- continue;
-
-/* *************************************************************************
- * re_filterfile file-name
- * In confdir by default.
- * *************************************************************************/
- case hash_filterfile :
- freez(config->re_filterfile);
- config->re_filterfile = make_path(config->confdir, arg);
- continue;
-
-/* *************************************************************************
- * single-threaded
- * *************************************************************************/
- case hash_single_threaded :
- config->multi_threaded = 0;
- continue;
-
-/* *************************************************************************
- * toggle (0|1)
- * *************************************************************************/
-#ifdef FEATURE_TOGGLE
- case hash_toggle :
- g_bToggleIJB = atoi(arg);
- continue;
-#endif /* def FEATURE_TOGGLE */
-
-/* *************************************************************************
- * trust-info-url url
- * *************************************************************************/
-#ifdef FEATURE_TRUST
- case hash_trust_info_url :
- enlist(config->trust_info, arg);
- continue;
-#endif /* def FEATURE_TRUST */
-
-/* *************************************************************************
- * trustfile filename
- * (In confdir by default.)
- * *************************************************************************/
-#ifdef FEATURE_TRUST
- case hash_trustfile :
- freez(config->trustfile);
- config->trustfile = make_path(config->confdir, arg);
- continue;
-#endif /* def FEATURE_TRUST */
-
-/* *************************************************************************
- * usermanual url
- * *************************************************************************/
- case hash_usermanual :
- freez(config->usermanual);
- config->usermanual = strdup(arg);
- continue;
-
-/* *************************************************************************
- * Win32 Console options:
- * *************************************************************************/
-
-/* *************************************************************************
- * hide-console
- * *************************************************************************/
-#ifdef _WIN_CONSOLE
- case hash_hide_console :
- hideConsole = 1;
- continue;
-#endif /*def _WIN_CONSOLE*/
-
-
-/* *************************************************************************
- * Win32 GUI options:
- * *************************************************************************/
-
-#if defined(_WIN32) && ! defined(_WIN_CONSOLE)
-/* *************************************************************************
- * activity-animation (0|1)
- * *************************************************************************/
- case hash_activity_animation :
- g_bShowActivityAnimation = atoi(arg);
- continue;
-
-/* *************************************************************************
- * close-button-minimizes (0|1)
- * *************************************************************************/
- case hash_close_button_minimizes :
- g_bCloseHidesWindow = atoi(arg);
- continue;
-
-/* *************************************************************************
- * log-buffer-size (0|1)
- * *************************************************************************/
- case hash_log_buffer_size :
- g_bLimitBufferSize = atoi(arg);
- continue;
-
-/* *************************************************************************
- * log-font-name fontnane
- * *************************************************************************/
- case hash_log_font_name :
- strcpy( g_szFontFaceName, arg );
- continue;
-
-/* *************************************************************************
- * log-font-size n
- * *************************************************************************/
- case hash_log_font_size :
- g_nFontSize = atoi(arg);
- continue;
-
-/* *************************************************************************
- * log-highlight-messages (0|1)
- * *************************************************************************/
- case hash_log_highlight_messages :
- g_bHighlightMessages = atoi(arg);
- continue;
-
-/* *************************************************************************
- * log-max-lines n
- * *************************************************************************/
- case hash_log_max_lines :
- g_nMaxBufferLines = atoi(arg);
- continue;
-
-/* *************************************************************************
- * log-messages (0|1)
- * *************************************************************************/
- case hash_log_messages :
- g_bLogMessages = atoi(arg);
- continue;
-
-/* *************************************************************************
- * show-on-task-bar (0|1)
- * *************************************************************************/
- case hash_show_on_task_bar :
- g_bShowOnTaskBar = atoi(arg);
- continue;
-
-#endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
-
-
-/* *************************************************************************
- * Warnings about unsupported features
- * *************************************************************************/
-#ifndef 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 :
-#endif /* ndef _WIN_CONSOLE */
-
-#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;
-
-/* *************************************************************************/
- default :
-/* *************************************************************************/
- /*
- * I decided that I liked this better as a warning than an
- * error. To change back to an error, just change log level
- * to LOG_LEVEL_FATAL.
- */
- log_error(LOG_LEVEL_ERROR, "Unrecognized directive '%s' (%luul) in line %lu in "
- "configuration file (%s).", buf, hash_string(cmd), linenum, configfile);
- string_append(&config->proxy_args, "<br>\nWARNING: unrecognized directive : ");
- string_append(&config->proxy_args, buf);
- string_append(&config->proxy_args, "<br><br>\n");
- continue;
-
-/* *************************************************************************/
- } /* end switch( hash_string(cmd) ) */
- } /* end while ( read_config_line(...) ) */
-
- fclose(configfp);
-
- if (NULL == config->proxy_args)
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory loading config - insufficient memory for config->proxy_args");
- }
-
- init_error_log(Argv[0], config->logfile, config->debug);
-
- if (config->actions_file[0])
- {
- add_loader(load_actions_file, config);
- }
-
- if (config->re_filterfile)
- {
- add_loader(load_re_filterfile, config);
- }
-
-#ifdef FEATURE_TRUST
- if (config->trustfile)
- {
- add_loader(load_trustfile, config);
- }
-#endif /* def FEATURE_TRUST */
-
-#ifdef FEATURE_COOKIE_JAR
- if ( NULL != config->jarfile )
- {
- if ( NULL == (config->jar = fopen(config->jarfile, "a")) )
- {
- log_error(LOG_LEVEL_FATAL, "can't open jarfile '%s': %E", config->jarfile);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
- setbuf(config->jar, NULL);
- }
-#endif /* def FEATURE_COOKIE_JAR */
-
- if ( NULL == config->haddr )
- {
- config->haddr = strdup( HADDR_DEFAULT );
- }
-
- if ( NULL != config->haddr )
- {
- if (NULL != (p = strchr(config->haddr, ':')))
- {
- *p++ = '\0';
- if (*p)
- {
- config->hport = atoi(p);
- }
- }
-
- if (config->hport <= 0)
- {
- *--p = ':';
- log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
- if (*config->haddr == '\0')
- {
- config->haddr = 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))
- {
- 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;
- }
-
- 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);
-
- /*
- * Add config option name embedded in
- * link to it's section in the user-manual
- */
- buf = strdup("<a href=\"");
- string_append(&buf, config->usermanual);
- string_append(&buf, CONFIG_HELP_PREFIX);
- string_join (&buf, string_toupper(command));
- string_append(&buf, "\">");
- string_append(&buf, command);
- string_append(&buf, "</a> ");
-
- if (NULL == buf)
- {
- freez(config->proxy_args);
- return;
- }
-
- if ( (NULL != argument) && ('\0' != *argument) )
- {
- s = html_encode(argument);
- if (NULL == s)
- {
- freez(buf);
- freez(config->proxy_args);
- return;
- }
-
- if (strncmpic(argument, "http://", 7) == 0)
- {
- string_append(&buf, "<a href=\"");
- string_append(&buf, s);
- string_append(&buf, "\">");
- string_join (&buf, s);
- string_append(&buf, "</a>");
- }
- else
- {
- string_join (&buf, s);
- }
- }
-
- string_append(&buf, "<br>\n");
-
- string_join(&config->proxy_args, buf);
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/loadcfg.h,v $
- *
- * Purpose : Loads settings from the configuration file into
- * 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
- * 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: loadcfg.h,v $
- * Revision 1.10 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.9 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.8 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.7 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.6 2001/07/29 18:58:15 jongfoster
- * Removing nested #includes, adding forward declarations for needed
- * structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
- *
- * Revision 1.5 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.4 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:58:58 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Don't need project.h, only this: */
-struct configuration_spec;
-
-/* Global variables */
-
-#ifdef FEATURE_TOGGLE
-/* indicates if ijb is enabled */
-extern int g_bToggleIJB;
-#endif /* def FEATURE_TOGGLE */
-
-extern const char *configfile;
-
-
-/* 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.
- */
-extern int Argc;
-extern const char **Argv;
-extern short int MustReload;
-
-
-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[];
-extern const char loadcfg_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef LOADCFG_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char loaders_rcs[] = "$Id: loaders.c,v 1.49 2002/04/19 16:53:25 jongfoster Exp $";
-/*********************************************************************
- *
- * 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
- * unload files that are no longer in use.
- *
- * 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: loaders.c,v $
- * Revision 1.49 2002/04/19 16:53:25 jongfoster
- * Optimize away a function call by using an equivalent macro
- *
- * Revision 1.48 2002/04/05 00:56:09 gliptak
- * Correcting typo to clean up on realloc failure
- *
- * Revision 1.47 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.46 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.45 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.44 2002/03/16 21:51:00 jongfoster
- * Fixing free(NULL).
- *
- * Revision 1.43 2002/03/16 20:28:34 oes
- * Added descriptions to the filters so users will know what they select in the cgi editor
- *
- * Revision 1.42 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.41 2002/03/12 01:42:50 oes
- * Introduced modular filters
- *
- * Revision 1.40 2002/03/08 17:46:04 jongfoster
- * Fixing int/size_t warnings
- *
- * Revision 1.39 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.38 2002/03/06 22:54:35 jongfoster
- * Automated function-comment nitpicking.
- *
- * Revision 1.37 2002/03/03 15:07:49 oes
- * Re-enabled automatic config reloading
- *
- * Revision 1.36 2002/01/22 23:46:18 jongfoster
- * Moving edit_read_line() and simple_read_line() to loaders.c, and
- * extending them to support reading MS-DOS, Mac and UNIX style files
- * on all platforms.
- *
- * Modifying read_config_line() (without changing it's prototype) to
- * be a trivial wrapper for edit_read_line(). This means that we have
- * one function to read a line and handle comments, which is common
- * between the initialization code and the edit interface.
- *
- * Revision 1.35 2002/01/17 21:03:08 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Revision 1.34 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.33 2001/11/13 00:16:38 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.32 2001/11/07 00:02:13 steudten
- * Add line number in error output for lineparsing for
- * actionsfile and configfile.
- * Special handling for CLF added.
- *
- * Revision 1.31 2001/10/26 17:39:01 oes
- * Removed csp->referrer
- * Moved ijb_isspace and ijb_tolower to project.h
- *
- * Revision 1.30 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.29 2001/10/23 21:38:53 jongfoster
- * Adding error-checking to create_url_spec()
- *
- * Revision 1.28 2001/10/07 15:40:39 oes
- * Replaced 6 boolean members of csp with one bitmap (csp->flags)
- *
- * Revision 1.27 2001/09/22 16:36:59 jongfoster
- * Removing unused parameter fs from read_config_line()
- *
- * Revision 1.26 2001/09/22 14:05:22 jongfoster
- * Bugfix: Multiple escaped "#" characters in a configuration
- * file are now permitted.
- * Also removing 3 unused headers.
- *
- * Revision 1.25 2001/09/13 22:44:03 jongfoster
- * Adding {} to an if statement
- *
- * Revision 1.24 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.23 2001/07/20 15:51:54 oes
- * Fixed indentation of prepocessor commands
- *
- * Revision 1.22 2001/07/20 15:16:17 haroon
- * - per Guy's suggestion, added a while loop in sweep() to catch not just
- * the last inactive CSP but all other consecutive inactive CSPs after that
- * as well
- *
- * Revision 1.21 2001/07/18 17:26:24 oes
- * Changed to conform to new pcrs interface
- *
- * Revision 1.20 2001/07/17 13:07:01 oes
- * Fixed segv when last line in config files
- * lacked a terminating (\r)\n
- *
- * Revision 1.19 2001/07/13 14:01:54 oes
- * Removed all #ifdef PCRS
- *
- * Revision 1.18 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.17 2001/06/29 13:31:51 oes
- * Various adaptions
- *
- * Revision 1.16 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.15 2001/06/07 23:14:14 jongfoster
- * Removing ACL and forward file loaders - these
- * files have been merged into the config file.
- * Cosmetic: Moving unloader funcs next to their
- * respective loader funcs
- *
- * Revision 1.14 2001/06/01 03:27:04 oes
- * Fixed line continuation problem
- *
- * Revision 1.13 2001/05/31 21:28:49 jongfoster
- * Removed all permissionsfile code - it's now called the actions
- * file, and (almost) all the code is in actions.c
- *
- * Revision 1.12 2001/05/31 17:32:31 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.11 2001/05/29 23:25:24 oes
- *
- * - load_config_line() and load_permissions_file() now use chomp()
- *
- * Revision 1.10 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.9 2001/05/26 17:12:07 jongfoster
- * Fatal errors loading configuration files now give better error messages.
- *
- * Revision 1.8 2001/05/26 00:55:20 jongfoster
- * Removing duplicated code. load_forwardfile() now uses create_url_spec()
- *
- * Revision 1.7 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.6 2001/05/23 12:27:33 oes
- *
- * Fixed ugly indentation of my last changes
- *
- * Revision 1.5 2001/05/23 10:39:05 oes
- * - Added support for escaping the comment character
- * in config files by a backslash
- * - Added support for line continuation in config
- * files
- * - Fixed a buffer overflow bug with long config lines
- *
- * Revision 1.4 2001/05/22 18:56:28 oes
- * CRLF -> LF
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:58:59 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <assert.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif
-
-#include "project.h"
-#include "list.h"
-#include "loaders.h"
-#include "filters.h"
-#include "parsers.h"
-#include "jcc.h"
-#include "miscutil.h"
-#include "errlog.h"
-#include "actions.h"
-#include "urlmatch.h"
-
-const char loaders_h_rcs[] = LOADERS_H_VERSION;
-
-/*
- * Currently active files.
- * These are also entered in the main linked list of files.
- */
-
-#ifdef FEATURE_TRUST
-static struct file_list *current_trustfile = NULL;
-#endif /* def FEATURE_TRUST */
-
-static struct file_list *current_re_filterfile = NULL;
-
-
-
-/*********************************************************************
- *
- * Function : sweep
- *
- * Description : Basically a mark and sweep garbage collector, it is run
- * (by the parent thread) every once in a while to reclaim memory.
- *
- * It uses a mark and sweep strategy:
- * 1) mark all files as inactive
- *
- * 2) check with each client:
- * if it is active, mark its files as active
- * if it is inactive, free its resources
- *
- * 3) free the resources of all of the files that
- * are still marked as inactive (and are obsolete).
- *
- * N.B. files that are not obsolete don't have an unloader defined.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-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 )
- {
- fl->active = 0;
- }
-
- for (csp = clients; csp && (NULL != (ncsp = csp->next)) ; csp = csp->next)
- {
- if (ncsp->flags & CSP_FLAG_ACTIVE)
- {
- /* mark this client's files as active */
-
- /*
- * Always have a configuration file.
- * (Also note the slightly non-standard extra
- * indirection here.)
- */
- ncsp->config->config_file_list->active = 1;
-
- for (i = 0; i < MAX_ACTION_FILES; i++)
- {
- if (ncsp->actions_list[i]) /* actions files */
- {
- ncsp->actions_list[i]->active = 1;
- }
- }
-
- if (ncsp->rlist) /* pcrsjob files */
- {
- ncsp->rlist->active = 1;
- }
-
-#ifdef FEATURE_TRUST
- if (ncsp->tlist) /* trust files */
- {
- ncsp->tlist->active = 1;
- }
-#endif /* def FEATURE_TRUST */
-
- }
- else
- /*
- * this client is not active, release its resources
- * and the ones of all inactive clients that might
- * follow it
- */
- {
- while (!(ncsp->flags & CSP_FLAG_ACTIVE))
- {
- csp->next = ncsp->next;
-
- 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);
-
- destroy_list(ncsp->headers);
- destroy_list(ncsp->cookie_list);
-
- free_current_action(ncsp->action);
-
-#ifdef FEATURE_STATISTICS
- urls_read++;
- if (ncsp->flags & CSP_FLAG_REJECTED)
- {
- urls_rejected++;
- }
-#endif /* def FEATURE_STATISTICS */
-
- freez(ncsp);
-
- /* are there any more in sequence after it? */
- if( (ncsp = csp->next) == NULL)
- break;
- }
- }
- }
-
- for (fl = files; fl && ((nfl = fl->next) != NULL) ; fl = fl->next)
- {
- if ( ( 0 == nfl->active ) && ( NULL != nfl->unloader ) )
- {
- fl->next = nfl->next;
-
- (nfl->unloader)(nfl->f);
-
- freez(nfl->filename);
-
- freez(nfl);
- }
- }
-
-}
-
-
-/*********************************************************************
- *
- * 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
- * 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.
- * May be NULL (which is treated as out of
- * date).
- * 2 : filename = Name of file to check.
- * 3 : newfl = New file list. [Output only]
- * This will be set to NULL, OR a struct
- * file_list newly allocated on the
- * heap, with the filename and lastmodified
- * 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
- *
- *********************************************************************/
-int check_file_changed(const struct file_list * current,
- const char * filename,
- struct file_list ** newfl)
-{
- struct file_list *fs;
- struct stat statbuf[1];
-
- *newfl = NULL;
-
- if (stat(filename, statbuf) < 0)
- {
- /* Error, probably file not found. */
- return 1;
- }
-
- if (current
- && (current->lastmodified == statbuf->st_mtime)
- && (0 == strcmp(current->filename, filename)))
- {
- return 0;
- }
-
- fs = (struct file_list *)zalloc(sizeof(struct file_list));
- if (fs == NULL)
- {
- /* Out of memory error */
- return 1;
- }
-
- fs->filename = strdup(filename);
- fs->lastmodified = statbuf->st_mtime;
-
- if (fs->filename == NULL)
- {
- /* Out of memory error */
- freez (fs);
- return 1;
- }
- *newfl = fs;
- return 1;
-}
-
-
-/*********************************************************************
- *
- * Function : simple_read_line
- *
- * 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 : 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.
- *
- *********************************************************************/
-jb_err simple_read_line(FILE *fp, char **dest, int *newline)
-{
- size_t len = 0;
- size_t buflen = BUFFER_SIZE;
- char * buf;
- char * p;
- int ch;
- int realnewline = NEWLINE_UNKNOWN;
-
- if (NULL == (buf = malloc(buflen)))
- {
- return JB_ERR_MEMORY;
- }
-
- 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)
- {
- if (len > 0)
- {
- *p = '\0';
- *dest = buf;
- return JB_ERR_OK;
- }
- else
- {
- free(buf);
- *dest = NULL;
- return JB_ERR_FILE;
- }
- }
- else if (ch == CHAR_CR)
- {
- ch = getc(fp);
- if (ch == CHAR_LF)
- {
- if (*newline == NEWLINE_UNKNOWN)
- {
- *newline = NEWLINE_DOS;
- }
- }
- 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)
- {
- *newline = NEWLINE_UNIX;
- }
- return JB_ERR_OK;
- }
- else if (ch == 0)
- {
- *p = '\0';
- *dest = buf;
- return JB_ERR_OK;
- }
-
- *p++ = ch;
-
- if (++len >= buflen)
- {
- buflen += BUFFER_SIZE;
- if (NULL == (p = realloc(buf, buflen)))
- {
- free(buf);
- return JB_ERR_MEMORY;
- }
- buf = p;
- p = buf + len;
- }
- }
-}
-
-
-/*********************************************************************
- *
- * Function : edit_read_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.
- * 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 : 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.
- *
- *********************************************************************/
-jb_err edit_read_line(FILE *fp,
- char **raw_out,
- char **prefix_out,
- char **data_out,
- int *newline,
- unsigned long *line_number)
-{
- 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;
-
- assert(fp);
- assert(raw_out || data_out);
- assert(newline == NULL
- || *newline == NEWLINE_UNKNOWN
- || *newline == NEWLINE_UNIX
- || *newline == NEWLINE_DOS
- || *newline == NEWLINE_MAC);
-
- if (newline == NULL)
- {
- scrapnewline = NEWLINE_UNKNOWN;
- newline = &scrapnewline;
- }
-
- /* Set output parameters to NULL */
- if (raw_out)
- {
- *raw_out = NULL;
- }
- if (prefix_out)
- {
- *prefix_out = NULL;
- }
- if (data_out)
- {
- *data_out = NULL;
- }
-
- /* Set string variables to new, empty strings. */
-
- if (raw_out)
- {
- if ((raw = malloc(1)) == NULL)
- {
- return JB_ERR_MEMORY;
- }
- *raw = '\0';
- }
- if (prefix_out)
- {
- if ((prefix = malloc(1)) == NULL)
- {
- freez(raw);
- return JB_ERR_MEMORY;
- }
- *prefix = '\0';
- }
- if (data_out)
- {
- if ((data = malloc(1)) == NULL)
- {
- freez(raw);
- freez(prefix);
- return JB_ERR_MEMORY;
- }
- *data = '\0';
- }
-
- /* Main loop. Loop while we need more data & it's not EOF. */
-
- while ( (contflag || is_empty)
- && (JB_ERR_OK == (rval = simple_read_line(fp, &linebuf, newline))))
- {
- if (line_number)
- {
- (*line_number)++;
- }
- if (raw)
- {
- string_append(&raw,linebuf);
- if (string_append(&raw,NEWLINE(*newline)))
- {
- freez(prefix);
- freez(data);
- free(linebuf);
- return JB_ERR_MEMORY;
- }
- }
-
- /* Line continuation? Trim escape and set flag. */
- p = linebuf + strlen(linebuf) - 1;
- contflag = ((*linebuf != '\0') && (*p == '\\'));
- if (contflag)
- {
- *p = '\0';
- }
-
- /* Trim leading spaces if we're at the start of the line */
- linestart = linebuf;
- if (*data == '\0')
- {
- /* Trim leading spaces */
- while (*linestart && isspace((int)(unsigned char)*linestart))
- {
- linestart++;
- }
- }
-
- /* Handle comment characters. */
- p = linestart;
- while ((p = strchr(p, '#')) != NULL)
- {
- /* 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;
- }
- }
-
- /* ... and chop off the rest of the line */
- *p = '\0';
- }
- } /* END while (there's a # character) */
-
- /* Write to the buffer */
- if (*linestart)
- {
- is_empty = 0;
- if (data)
- {
- if (string_append(&data, linestart))
- {
- freez(raw);
- freez(prefix);
- free(linebuf);
- return JB_ERR_MEMORY;
- }
- }
- }
-
- free(linebuf);
- } /* END while(we need more data) */
-
- /* 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 (raw ? (*raw == '\0') : is_empty)
- {
- /* EOF and no data there. (Definition of "data" depends on whether
- * the caller cares about "raw" or just "data").
- */
-
- freez(raw);
- freez(prefix);
- freez(data);
-
- return JB_ERR_FILE;
- }
- else
- {
- /* Got at least some data */
-
- /* Remove trailing whitespace */
- chomp(data);
-
- if (raw_out)
- {
- *raw_out = raw;
- }
- else
- {
- freez(raw);
- }
- if (prefix_out)
- {
- *prefix_out = prefix;
- }
- else
- {
- freez(prefix);
- }
- if (data_out)
- {
- *data_out = data;
- }
- else
- {
- freez(data);
- }
- return JB_ERR_OK;
- }
-}
-
-
-/*********************************************************************
- *
- * 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)
- {
- if (err == JB_ERR_MEMORY)
- {
- log_error(LOG_LEVEL_FATAL, "Out of memory loading a config file");
- }
- return NULL;
- }
- else
- {
- assert(buf2);
- assert(strlen(buf2) + 1U < buflen);
- strncpy(buf, buf2, buflen - 1);
- free(buf2);
- buf[buflen - 1] = '\0';
- return buf;
- }
-}
-
-
-#ifdef FEATURE_TRUST
-/*********************************************************************
- *
- * 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 *cur = (struct block_spec *)f;
- struct block_spec *next;
-
- while (cur != NULL)
- {
- next = cur->next;
-
- free_url_spec(cur->url);
- free(cur);
-
- cur = next;
- }
-
-}
-
-
-#ifdef FEATURE_GRACEFUL_TERMINATION
-/*********************************************************************
- *
- * Function : unload_current_trust_file
- *
- * Description : Unloads current trust file - reset to state at
- * beginning of program.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void unload_current_trust_file(void)
-{
- if (current_trustfile)
- {
- current_trustfile->unloader = unload_trustfile;
- current_trustfile = NULL;
- }
-}
-#endif /* FEATURE_GRACEFUL_TERMINATION */
-
-
-/*********************************************************************
- *
- * Function : load_trustfile
- *
- * Description : Read and parse a trustfile and add to files list.
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : 0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int load_trustfile(struct client_state *csp)
-{
- FILE *fp;
-
- struct block_spec *b, *bl;
- struct url_spec **tl;
-
- char buf[BUFFER_SIZE], *p, *q;
- int reject, trusted;
- struct file_list *fs;
- unsigned long linenum = 0;
-
- if (!check_file_changed(current_trustfile, csp->config->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(csp->config->trustfile, "r")) == NULL)
- {
- goto load_trustfile_error;
- }
-
- tl = csp->config->trust_list;
-
- while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
- {
- trusted = 0;
- reject = 1;
-
- if (*buf == '+')
- {
- trusted = 1;
- *buf = '~';
- }
-
- if (*buf == '~')
- {
- reject = 0;
- p = buf;
- q = p+1;
- while ((*p++ = *q++) != '\0')
- {
- /* nop */
- }
- }
-
- /* skip blank lines */
- if (*buf == '\0')
- {
- continue;
- }
-
- /* allocate a new node */
- if ((b = zalloc(sizeof(*b))) == NULL)
- {
- fclose(fp);
- goto load_trustfile_error;
- }
-
- /* add it to the list */
- b->next = bl->next;
- bl->next = b;
-
- b->reject = reject;
-
- /* Save the URL pattern */
- if (create_url_spec(b->url, buf))
- {
- fclose(fp);
- goto load_trustfile_error;
- }
-
- /*
- * save a pointer to URL's spec in the list of trusted URL's, too
- */
- if (trusted)
- {
- *tl++ = b->url;
- /* FIXME BUFFER OVERFLOW if >=64 entries */
- }
- }
-
- *tl = NULL;
-
- fclose(fp);
-
- /* the old one is now obsolete */
- if (current_trustfile)
- {
- current_trustfile->unloader = unload_trustfile;
- }
-
- fs->next = files->next;
- files->next = fs;
- current_trustfile = fs;
-
- if (csp)
- {
- csp->tlist = fs;
- }
-
- return(0);
-
-load_trustfile_error:
- log_error(LOG_LEVEL_FATAL, "can't load trustfile '%s': %E",
- csp->config->trustfile);
- return(-1);
-
-}
-#endif /* def FEATURE_TRUST */
-
-
-/*********************************************************************
- *
- * Function : unload_re_filterfile
- *
- * Description : Unload the re_filter list by freeing all chained
- * re_filterfile specs and their data.
- *
- * Parameters :
- * 1 : f = the data structure associated with the filterfile.
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void unload_re_filterfile(void *f)
-{
- struct re_filterfile_spec *a, *b = (struct re_filterfile_spec *)f;
-
- while (b != NULL)
- {
- a = b->next;
-
- destroy_list(b->patterns);
- pcrs_free_joblist(b->joblist);
- freez(b->name);
- freez(b->description);
- freez(b);
-
- b = a;
- }
-
- return;
-}
-
-
-#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;
- }
-}
-#endif
-
-
-/*********************************************************************
- *
- * Function : load_re_filterfile
- *
- * 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 => Ok, everything else is an error.
- *
- *********************************************************************/
-int load_re_filterfile(struct client_state *csp)
-{
- FILE *fp;
-
- struct re_filterfile_spec *new_bl, *bl = NULL;
- struct file_list *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))
- {
- if (csp)
- {
- csp->rlist = current_re_filterfile;
- }
- return(0);
- }
- if (!fs)
- {
- goto load_re_filterfile_error;
- }
-
- /*
- * Open the file or fail
- */
- if ((fp = fopen(csp->config->re_filterfile, "r")) == NULL)
- {
- goto load_re_filterfile_error;
- }
-
- /*
- * Read line by line
- */
- while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
- {
- /*
- * 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)
- {
- new_bl = (struct re_filterfile_spec *)zalloc(sizeof(*bl));
- if (new_bl == NULL)
- {
- goto load_re_filterfile_error;
- }
-
- new_bl->name = chomp(buf + 7);
-
- if (NULL != (new_bl->description = strchr(new_bl->name, ' ')))
- {
- *new_bl->description++ = '\0';
- new_bl->description = strdup(chomp(new_bl->description));
- }
- else
- {
- new_bl->description = strdup("No description available for this filter");
- }
-
- 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
- {
- bl->next = new_bl;
- }
- bl = new_bl;
-
- log_error(LOG_LEVEL_RE_FILTER, "Reading in filter \"%s\" (\"%s\")", bl->name, bl->description);
-
- continue;
- }
-
- /*
- * 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);
-
- 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);
- }
- }
-
- fclose(fp);
-
- /*
- * Schedule the now-obsolete old data for unloading
- */
- if ( NULL != current_re_filterfile )
- {
- 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_re_filterfile = fs;
-
- if (csp)
- {
- csp->rlist = fs;
- }
-
- return( 0 );
-
-load_re_filterfile_error:
- log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
- csp->config->re_filterfile);
- return(-1);
-
-}
-
-
-/*********************************************************************
- *
- * Function : add_loader
- *
- * Description : Called from `load_config'. Called once for each input
- * file found in config.
- *
- * 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 *),
- struct configuration_spec * config)
-{
- int i;
-
- for (i=0; i < NLOADERS; i++)
- {
- if (config->loaders[i] == NULL)
- {
- config->loaders[i] = loader;
- break;
- }
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : run_loader
- *
- * Description : Called from `load_config' and `listen_loop'. This
- * function keeps the "csp" current with any file mods
- * since the last loop. If a file is unchanged, the
- * loader functions do NOT reload the file.
- *
- * 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.
- *
- *********************************************************************/
-int run_loader(struct client_state *csp)
-{
- int ret = 0;
- int i;
-
- for (i=0; i < NLOADERS; i++)
- {
- if (csp->config->loaders[i] == NULL)
- {
- break;
- }
- ret |= (csp->config->loaders[i])(csp);
- }
- return(ret);
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/loaders.h,v $
- *
- * Purpose : Functions to load and unload the various
- * configuration files. Also contains code to manage
- * 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
- * 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: loaders.h,v $
- * Revision 1.18 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.17 2002/03/16 23:54:06 jongfoster
- * Adding graceful termination feature, to help look for memory leaks.
- * If you enable this (which, by design, has to be done by hand
- * editing config.h) and then go to http://i.j.b/die, then the program
- * will exit cleanly after the *next* request. It should free all the
- * memory that was used.
- *
- * Revision 1.16 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.15 2002/01/22 23:46:18 jongfoster
- * Moving edit_read_line() and simple_read_line() to loaders.c, and
- * extending them to support reading MS-DOS, Mac and UNIX style files
- * on all platforms.
- *
- * Modifying read_config_line() (without changing it's prototype) to
- * be a trivial wrapper for edit_read_line(). This means that we have
- * one function to read a line and handle comments, which is common
- * between the initialization code and the edit interface.
- *
- * Revision 1.14 2002/01/17 21:03:08 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Revision 1.13 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.12 2001/11/07 00:02:13 steudten
- * Add line number in error output for lineparsing for
- * actionsfile and configfile.
- * Special handling for CLF added.
- *
- * Revision 1.11 2001/10/23 21:38:53 jongfoster
- * Adding error-checking to create_url_spec()
- *
- * Revision 1.10 2001/09/22 16:36:59 jongfoster
- * Removing unused parameter fs from read_config_line()
- *
- * Revision 1.9 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.8 2001/07/29 18:58:15 jongfoster
- * Removing nested #includes, adding forward declarations for needed
- * structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
- *
- * Revision 1.7 2001/07/13 14:01:54 oes
- * Removed all #ifdef PCRS
- *
- * Revision 1.6 2001/06/07 23:14:38 jongfoster
- * Removing ACL and forward file loaders - these files have
- * been merged into the config file.
- *
- * Revision 1.5 2001/05/31 21:28:49 jongfoster
- * Removed all permissionsfile code - it's now called the actions
- * file, and (almost) all the code is in actions.c
- *
- * Revision 1.4 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.3 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:00 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#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, 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);
-
-extern jb_err edit_read_line(FILE *fp,
- char **raw_out,
- char **prefix_out,
- char **data_out,
- int *newline,
- unsigned long *line_number);
-
-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) */
-
-/*
- * 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);
-
-#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[];
-extern const char loaders_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef LOADERS_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char miscutil_rcs[] = "$Id: miscutil.c,v 1.36 2002/04/26 12:55:38 oes Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/miscutil.c,v $
- *
- * Purpose : zalloc, hash_string, safe_strerror, strcmpic,
- * 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
- * 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: miscutil.c,v $
- * Revision 1.36 2002/04/26 12:55:38 oes
- * New function string_toupper
- *
- * Revision 1.35 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.34 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.33 2002/03/07 03:46:53 oes
- * Fixed compiler warnings etc
- *
- * Revision 1.32 2002/03/06 23:02:57 jongfoster
- * Removing tabs
- *
- * Revision 1.31 2002/03/05 04:52:42 oes
- * Deleted non-errlog debugging code
- *
- * Revision 1.30 2002/03/04 18:27:42 oes
- * - Deleted deletePidFile
- * - Made write_pid_file use the --pidfile option value
- * (or no PID file, if the option was absent)
- * - Played styleguide police
- *
- * Revision 1.29 2002/03/04 02:08:02 david__schmidt
- * Enable web editing of actions file on OS/2 (it had been broken all this time!)
- *
- * Revision 1.28 2002/03/03 09:18:03 joergs
- * Made jumbjuster work on AmigaOS again.
- *
- * Revision 1.27 2002/01/21 00:52:32 jongfoster
- * Adding string_join()
- *
- * Revision 1.26 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.25 2001/11/13 00:16:38 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.24 2001/11/05 21:41:43 steudten
- * Add changes to be a real daemon just for unix os.
- * (change cwd to /, detach from controlling tty, set
- * process group and session leader to the own process.
- * Add DBG() Macro.
- * Add some fatal-error log message for failed malloc().
- * Add '-d' if compiled with 'configure --with-debug' to
- * enable debug output.
- *
- * Revision 1.23 2001/10/29 03:48:10 david__schmidt
- * OS/2 native needed a snprintf() routine. Added one to miscutil, brackedted
- * by and __OS2__ ifdef.
- *
- * Revision 1.22 2001/10/26 17:39:38 oes
- * Moved ijb_isspace and ijb_tolower to project.h
- *
- * Revision 1.21 2001/10/23 21:27:50 jongfoster
- * Standardising error codes in string_append
- * make_path() no longer adds '\\' if the dir already ends in '\\' (this
- * is just copying a UNIX-specific fix to the Windows-specific part)
- *
- * Revision 1.20 2001/10/22 15:33:56 david__schmidt
- * Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
- * filters.c. Added a FIXME in front of the offending code. I'll gladly
- * put in a better/more robust fix for all parties if one is presented...
- * It seems that just returning 200 instead of 404 would pretty much fix
- * it for everyone, but I don't know all the history of the problem.
- *
- * Revision 1.19 2001/10/14 22:02:57 jongfoster
- * New function string_append() which is like strsav(), but running
- * out of memory isn't automatically FATAL.
- *
- * Revision 1.18 2001/09/20 13:33:43 steudten
- *
- * change long to int as return value in hash_string(). Remember the wraparound
- * for int = long = sizeof(4) - thats maybe not what we want.
- *
- * Revision 1.17 2001/09/13 20:51:29 jongfoster
- * Fixing potential problems with characters >=128 in simplematch()
- * This was also a compiler warning.
- *
- * Revision 1.16 2001/09/10 10:56:59 oes
- * Silenced compiler warnings
- *
- * Revision 1.15 2001/07/13 14:02:24 oes
- * Removed vim-settings
- *
- * Revision 1.14 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.13 2001/06/29 13:32:14 oes
- * Removed logentry from cancelled commit
- *
- * Revision 1.12 2001/06/09 10:55:28 jongfoster
- * Changing BUFSIZ ==> BUFFER_SIZE
- *
- * Revision 1.11 2001/06/07 23:09:19 jongfoster
- * Cosmetic indentation changes.
- *
- * Revision 1.10 2001/06/07 14:51:38 joergs
- * make_path() no longer adds '/' if the dir already ends in '/'.
- *
- * Revision 1.9 2001/06/07 14:43:17 swa
- * slight mistake in make_path, unix path style is /.
- *
- * Revision 1.8 2001/06/05 22:32:01 jongfoster
- * New function make_path() to splice directory and file names together.
- *
- * Revision 1.7 2001/06/03 19:12:30 oes
- * introduced bindup()
- *
- * Revision 1.6 2001/06/01 18:14:49 jongfoster
- * Changing the calls to strerr() to check HAVE_STRERR (which is defined
- * in config.h if appropriate) rather than the NO_STRERR macro.
- *
- * Revision 1.5 2001/06/01 10:31:51 oes
- * Added character class matching to trivimatch; renamed to simplematch
- *
- * Revision 1.4 2001/05/31 17:32:31 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.3 2001/05/29 23:10:09 oes
- *
- *
- * - Introduced chomp()
- * - Moved strsav() from showargs to miscutil
- *
- * Revision 1.2 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.1.1.1 2001/05/15 13:59:00 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif /* #if !defined(_WIN32) && !defined(__OS2__) */
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "project.h"
-#include "miscutil.h"
-#include "errlog.h"
-#include "jcc.h"
-
-const char miscutil_h_rcs[] = MISCUTIL_H_VERSION;
-
-/*********************************************************************
- *
- * Function : zalloc
- *
- * Description : Malloc some memory and set it to '\0'.
- * The way calloc() ought to be -acjc
- *
- * Parameters :
- * 1 : size = Size of memory chunk to return.
- *
- * Returns : Pointer to newly malloc'd memory chunk.
- *
- *********************************************************************/
-void *zalloc(size_t size)
-{
- void * ret;
-
- if ((ret = (void *)malloc(size)) != NULL)
- {
- memset(ret, 0, 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
- *
- * Description : Take a string and compute a (hopefuly) unique numeric
- * integer value. This has several uses, but being able
- * to "switch" a string the one of my favorites.
- *
- * Parameters :
- * 1 : s : string to be hashed.
- *
- * Returns : an unsigned long variable with the hashed value.
- *
- *********************************************************************/
-unsigned int hash_string( const char* s )
-{
- unsigned int h = 0;
-
- for ( ; *s; ++s )
- {
- h = 5 * h + *s;
- }
-
- return (h);
-
-}
-
-
-#ifdef __MINGW32__
-/*********************************************************************
- *
- * Function : strdup
- *
- * Description : For some reason (which is beyond me), gcc and WIN32
- * don't like strdup. When a "free" is executed on a
- * strdup'd ptr, it can at times freez up! So I just
- * replaced it and problem was solved.
- *
- * Parameters :
- * 1 : s = string to duplicate
- *
- * Returns : Pointer to newly malloc'ed copy of the string.
- *
- *********************************************************************/
-char *strdup( const char *s )
-{
- char * result = (char *)malloc( strlen(s)+1 );
-
- if (result != NULL)
- {
- strcpy( result, s );
- }
-
- return( result );
-}
-
-#endif /* def __MINGW32__ */
-
-
-
-/*********************************************************************
- *
- * Function : safe_strerror
- *
- * Description : Variant of the library routine strerror() which will
- * work on systems without the library routine, and
- * which should never return NULL.
- *
- * Parameters :
- * 1 : err = the `errno' of the last operation.
- *
- * Returns : An "English" string of the last `errno'. Allocated
- * with strdup(), so caller frees. May be NULL if the
- * system is out of memory.
- *
- *********************************************************************/
-char *safe_strerror(int err)
-{
- char *s = NULL;
- char buf[BUFFER_SIZE];
-
-
-#ifdef HAVE_STRERROR
- s = strerror(err);
-#endif /* HAVE_STRERROR */
-
- if (s == NULL)
- {
- sprintf(buf, "(errno = %d)", err);
- s = buf;
- }
-
- return(strdup(s));
-
-}
-
-
-/*********************************************************************
- *
- * Function : strcmpic
- *
- * Description : Case insensitive string comparison
- *
- * Parameters :
- * 1 : s1 = string 1 to compare
- * 2 : s2 = string 2 to compare
- *
- * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
- *
- *********************************************************************/
-int strcmpic(const char *s1, const char *s2)
-{
- while (*s1 && *s2)
- {
- if ( ( *s1 != *s2 ) && ( ijb_tolower(*s1) != ijb_tolower(*s2) ) )
- {
- break;
- }
- s1++, s2++;
- }
- return(ijb_tolower(*s1) - ijb_tolower(*s2));
-
-}
-
-
-/*********************************************************************
- *
- * Function : strncmpic
- *
- * Description : Case insensitive string comparison (upto n characters)
- *
- * Parameters :
- * 1 : s1 = string 1 to compare
- * 2 : s2 = string 2 to compare
- * 3 : n = maximum characters to compare
- *
- * Returns : 0 if s1==s2, Negative if s1<s2, Positive if s1>s2
- *
- *********************************************************************/
-int strncmpic(const char *s1, const char *s2, size_t n)
-{
- if (n <= 0) return(0);
-
- while (*s1 && *s2)
- {
- if ( ( *s1 != *s2 ) && ( ijb_tolower(*s1) != ijb_tolower(*s2) ) )
- {
- break;
- }
-
- if (--n <= 0) break;
-
- s1++, s2++;
- }
- return(ijb_tolower(*s1) - ijb_tolower(*s2));
-
-}
-
-
-/*********************************************************************
- *
- * Function : chomp
- *
- * Description : In-situ-eliminate all leading and trailing whitespace
- * from a string.
- *
- * Parameters :
- * 1 : s : string to be chomped.
- *
- * Returns : chomped string
- *
- *********************************************************************/
-char *chomp(char *string)
-{
- char *p, *q, *r;
-
- /*
- * strip trailing whitespace
- */
- p = string + strlen(string);
- while (p > string && ijb_isspace(*(p-1)))
- {
- p--;
- }
- *p = '\0';
-
- /*
- * find end of leading whitespace
- */
- q = r = string;
- while (*q && ijb_isspace(*q))
- {
- q++;
- }
-
- /*
- * if there was any, move the rest forwards
- */
- if (q != string)
- {
- while (q <= p)
- {
- *r++ = *q++;
- }
- }
-
- return(string);
-
-}
-
-
-/*********************************************************************
- *
- * Function : strsav
- *
- * Description : Reallocate "old" and append text to it. This makes
- * it easier to append to malloc'd strings.
- * Running out of memory is a FATAL error.
- *
- * Parameters :
- * 1 : old = Old text that is to be extended. Will be
- * free()d by this routine. May be NULL.
- * 2 : text_to_append = Text to be appended to old.
- * May be NULL.
- *
- * Returns : Pointer to newly malloc'ed appended string.
- * If there is no text to append, return old. Caller
- * must free().
- *
- *********************************************************************/
-char *strsav(char *old, const char *text_to_append)
-{
- size_t old_len, new_len = 0;
- char *p;
-
- if ((text_to_append == NULL) || (*text_to_append == '\0'))
- {
- return(old);
- }
-
- if (NULL == old)
- {
- if ((p = strdup(text_to_append)) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "strdup() failed!");
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
- return p;
- }
-
- old_len = strlen(old);
- new_len = old_len + strlen(text_to_append) + 1;
-
- if ((p = realloc(old, new_len)) == NULL)
- {
- log_error(LOG_LEVEL_FATAL, "realloc(%d) bytes failed!", new_len);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
-
- strcpy(p + old_len, text_to_append);
- return(p);
-}
-
-
-/*********************************************************************
- *
- * Function : string_append
- *
- * Description : Reallocate target_string and append text to it.
- * This makes it easier to append to malloc'd strings.
- * This is similar to the (removed) strsav(), but
- * running out of memory isn't catastrophic.
- *
- * Programming style:
- *
- * The following style provides sufficient error
- * checking for this routine, with minimal clutter
- * in the source code. It is recommended if you
- * have many calls to this function:
- *
- * char * s = strdup(...); // don't check for error
- * string_append(&s, ...); // don't check for error
- * string_append(&s, ...); // don't check for error
- * string_append(&s, ...); // don't check for error
- * if (NULL == s) { ... handle error ... }
- *
- * OR, equivalently:
- *
- * char * s = strdup(...); // don't check for error
- * string_append(&s, ...); // don't check for error
- * string_append(&s, ...); // don't check for error
- * if (string_append(&s, ...)) {... handle error ...}
- *
- * Parameters :
- * 1 : target_string = Pointer to old text that is to be
- * extended. *target_string will be free()d by this
- * routine. target_string must be non-NULL.
- * If *target_string is NULL, this routine will
- * do nothing and return with an error - this allows
- * you to make many calls to this routine and only
- * check for errors after the last one.
- * 2 : text_to_append = Text to be appended to old.
- * Must not be NULL.
- *
- * Returns : JB_ERR_OK on success, and sets *target_string
- * to newly malloc'ed appended string. Caller
- * must free(*target_string).
- * JB_ERR_MEMORY on out-of-memory. (And free()s
- * *target_string and sets it to NULL).
- * JB_ERR_MEMORY if *target_string is NULL.
- *
- *********************************************************************/
-jb_err string_append(char **target_string, const char *text_to_append)
-{
- size_t old_len;
- char *new_string;
-
- assert(target_string);
- assert(text_to_append);
-
- if (*target_string == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- if (*text_to_append == '\0')
- {
- return JB_ERR_OK;
- }
-
- old_len = strlen(*target_string);
-
- if (NULL == (new_string = realloc(*target_string,
- strlen(text_to_append) + old_len + 1)))
- {
- free(*target_string);
-
- *target_string = NULL;
- return JB_ERR_MEMORY;
- }
-
- strcpy(new_string + old_len, text_to_append);
-
- *target_string = new_string;
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : string_join
- *
- * Description : Join two strings together. Frees BOTH the original
- * strings. If either or both input strings are NULL,
- * fails as if it had run out of memory.
- *
- * For comparison, string_append requires that the
- * second string is non-NULL, and doesn't free it.
- *
- * Rationale: Too often, we want to do
- * string_append(s, html_encode(s2)). That assert()s
- * if s2 is NULL or if html_encode() runs out of memory.
- * It also leaks memory. Proper checking is cumbersome.
- * The solution: string_join(s, html_encode(s2)) is safe,
- * and will free the memory allocated by html_encode().
- *
- * Parameters :
- * 1 : target_string = Pointer to old text that is to be
- * extended. *target_string will be free()d by this
- * routine. target_string must be non-NULL.
- * 2 : text_to_append = Text to be appended to old.
- *
- * Returns : JB_ERR_OK on success, and sets *target_string
- * to newly malloc'ed appended string. Caller
- * must free(*target_string).
- * JB_ERR_MEMORY on out-of-memory, or if
- * *target_string or text_to_append is NULL. (In
- * this case, frees *target_string and text_to_append,
- * sets *target_string to NULL).
- *
- *********************************************************************/
-jb_err string_join(char **target_string, char *text_to_append)
-{
- jb_err err;
-
- assert(target_string);
-
- if (text_to_append == NULL)
- {
- freez(*target_string);
- return JB_ERR_MEMORY;
- }
-
- err = string_append(target_string, text_to_append);
-
- free(text_to_append);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : string_toupper
- *
- * Description : Produce a copy of string with all convertible
- * characters converted to uppercase.
- *
- * Parameters :
- * 1 : string = string to convert
- *
- * Returns : Uppercase copy of string if possible,
- * NULL on out-of-memory or if string was NULL.
- *
- *********************************************************************/
-char *string_toupper(const char *string)
-{
- char *result, *p;
- const char *q;
-
- if (!string || ((result = (char *) zalloc(strlen(string) + 1)) == NULL))
- {
- return NULL;
- }
-
- q = string;
- p = result;
-
- while (*q != '\0')
- {
- *p++ = toupper(*q++);
- }
-
- return result;
-
-}
-
-
-/*********************************************************************
- *
- * Function : simplematch
- *
- * Description : String matching, with a (greedy) '*' wildcard that
- * stands for zero or more arbitrary characters and
- * character classes in [], which take both enumerations
- * and ranges.
- *
- * Parameters :
- * 1 : pattern = pattern for matching
- * 2 : text = text to be matched
- *
- * Returns : 0 if match, else nonzero
- *
- *********************************************************************/
-int simplematch(char *pattern, char *text)
-{
- unsigned char *pat = (unsigned char *) pattern;
- unsigned char *txt = (unsigned char *) text;
- unsigned char *fallback = pat;
- int wildcard = 0;
-
- unsigned char lastchar = 'a';
- unsigned i;
- unsigned char charmap[32];
-
-
- while (*txt)
- {
-
- /* EOF pattern but !EOF text? */
- if (*pat == '\0')
- {
- return 1;
- }
-
- /* '*' in the pattern? */
- if (*pat == '*')
- {
-
- /* The pattern ends afterwards? Speed up the return. */
- if (*++pat == '\0')
- {
- return 0;
- }
-
- /* Else, set wildcard mode and remember position after '*' */
- wildcard = 1;
- fallback = pat;
- }
-
- /* Character range specification? */
- if (*pat == '[')
- {
- memset(charmap, '\0', sizeof(charmap));
-
- while (*++pat != ']')
- {
- if (!*pat)
- {
- return 1;
- }
- else if (*pat == '-')
- {
- if ((*++pat == ']') || *pat == '\0')
- {
- return(1);
- }
- for(i = lastchar; i <= *pat; i++)
- {
- charmap[i / 8] |= (1 << (i % 8));
- }
- }
- else
- {
- charmap[*pat / 8] |= (1 << (*pat % 8));
- lastchar = *pat;
- }
- }
- } /* -END- if Character range specification */
-
-
- /* Compare: Char match, or char range match*/
- if ((*pat == *txt)
- || ((*pat == ']') && (charmap[*txt / 8] & (1 << (*txt % 8)))) )
- {
- /* Sucess, go ahead */
- pat++;
- }
- else
- {
- /* In wildcard mode, just try again after failiure */
- if(wildcard)
- {
- pat = fallback;
- }
-
- /* Else, bad luck */
- else
- {
- return 1;
- }
- }
- txt++;
- }
-
- /* Cut off extra '*'s */
- if(*pat == '*') pat++;
-
- /* If this is the pattern's end, fine! */
- return(*pat);
-
-}
-
-
-/*********************************************************************
- *
- * Function : bindup
- *
- * Description : Duplicate the first n characters of a string that may
- * contain '\0' characters.
- *
- * Parameters :
- * 1 : string = string to be duplicated
- * 2 : len = number of bytes to duplicate
- *
- * Returns : pointer to copy, or NULL if failiure
- *
- *********************************************************************/
-char *bindup(const char *string, size_t len)
-{
- char *duplicate;
-
- if (NULL == (duplicate = (char *)malloc(len)))
- {
- return NULL;
- }
- else
- {
- memcpy(duplicate, string, len);
- }
-
- return duplicate;
-
-}
-
-
-/*********************************************************************
- *
- * Function : make_path
- *
- * Description : Takes a directory name and a file name, returns
- * the complete path. Handles windows/unix differences.
- * If the file name is already an absolute path, or if
- * the directory name is NULL or empty, it returns
- * the filename.
- *
- * Parameters :
- * 1 : dir: Name of directory or NULL for none.
- * 2 : file: Name of file. Should not be NULL or empty.
- *
- * Returns : "dir/file" (Or on windows, "dir\file").
- * It allocates the string on the heap. Caller frees.
- * Returns NULL in error (i.e. NULL file or out of
- * memory)
- *
- *********************************************************************/
-char * make_path(const char * dir, const char * file)
-{
-#ifdef AMIGA
- char path[512];
-
- if(dir)
- {
- if(dir[0] == '.')
- {
- if(dir[1] == '/')
- {
- strncpy(path,dir+2,512);
- }
- else
- {
- strncpy(path,dir+1,512);
- }
- }
- else
- {
- strncpy(path,dir,512);
- }
- path[511]=0;
- } else {
- path[0]=0;
- }
- if(AddPart(path,file,512))
- {
- return strdup(path);
- } else {
- return NULL;
- }
-#else /* ndef AMIGA */
-
- if ((file == NULL) || (*file == '\0'))
- {
- return NULL; /* Error */
- }
-
- if ((dir == NULL) || (*dir == '\0') /* No directory specified */
-#if defined(_WIN32) || defined(__OS2__)
- || (*file == '\\') || (file[1] == ':') /* Absolute path (DOS) */
-#else /* ifndef _WIN32 || __OS2__ */
- || (*file == '/') /* Absolute path (U*ix) */
-#endif /* ifndef _WIN32 || __OS2__ */
- )
- {
- return strdup(file);
- }
- else
- {
- char * path;
-
-#if defined(unix)
- if ( *dir != '/' && basedir && *basedir )
- {
- path = malloc( strlen( basedir ) + strlen(dir) + strlen(file) + 3);
- if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
- strcpy(path, basedir);
- strcat(path, "/");
- strcat(path, dir);
- }
- else
- {
- path = malloc(strlen(dir) + strlen(file) + 2);
- if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
- strcpy(path, dir);
- }
-#else
-
- path = malloc(strlen(dir) + strlen(file) + 2);
- if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
- strcpy(path, dir);
-
-#endif /* defined unix */
-
-#if defined(_WIN32) || defined(__OS2__)
- if(path[strlen(path)-1] != '\\')
- {
- strcat(path, "\\");
- }
-#else /* ifndef _WIN32 || __OS2__ */
- if(path[strlen(path)-1] != '/')
- {
- strcat(path, "/");
- }
-#endif /* ifndef _WIN32 || __OS2__ */
- strcat(path, file);
-
- return path;
- }
-#endif /* ndef AMIGA */
-}
-
-
-/*
- * What follows is a portable snprintf routine, written by Mark Martinec.
- * See: http://www.ijs.si/software/snprintf/
- * Anyone who needs it can add a define for themselves... so far, only
- * OS/2 (native) lacks snprintf.
-
- snprintf.c
- - a portable implementation of snprintf,
- including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf
-
- snprintf is a routine to convert numeric and string arguments to
- formatted strings. It is similar to sprintf(3) provided in a system's
- C library, yet it requires an additional argument - the buffer size -
- and it guarantees never to store anything beyond the given buffer,
- regardless of the format or arguments to be formatted. Some newer
- operating systems do provide snprintf in their C library, but many do
- not or do provide an inadequate (slow or idiosyncratic) version, which
- calls for a portable implementation of this routine.
-
-Author
-
- Mark Martinec <mark.martinec@ijs.si>, April 1999, June 2000
- Copyright © 1999, Mark Martinec
-
- */
-
-#ifdef __OS2__
-
-#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
-#define PORTABLE_SNPRINTF_VERSION_MINOR 2
-
-#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF)
-# if defined(NEED_SNPRINTF_ONLY)
-# undef NEED_SNPRINTF_ONLY
-# endif
-# if !defined(PREFER_PORTABLE_SNPRINTF)
-# define PREFER_PORTABLE_SNPRINTF
-# endif
-#endif
-
-#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE)
-#define SOLARIS_COMPATIBLE
-#endif
-
-#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
-#define HPUX_COMPATIBLE
-#endif
-
-#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE)
-#define DIGITAL_UNIX_COMPATIBLE
-#endif
-
-#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE)
-#define PERL_COMPATIBLE
-#endif
-
-#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE)
-#define LINUX_COMPATIBLE
-#endif
-
-#include <sys/types.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <errno.h>
-
-#ifdef isdigit
-#undef isdigit
-#endif
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-
-/* For copying strings longer or equal to 'breakeven_point'
- * it is more efficient to call memcpy() than to do it inline.
- * The value depends mostly on the processor architecture,
- * but also on the compiler and its optimization capabilities.
- * The value is not critical, some small value greater than zero
- * will be just fine if you don't care to squeeze every drop
- * of performance out of the code.
- *
- * Small values favor memcpy, large values favor inline code.
- */
-#if defined(__alpha__) || defined(__alpha)
-# define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */
-#endif
-#if defined(__i386__) || defined(__i386)
-# define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */
-#endif
-#if defined(__hppa)
-# define breakeven_point 10 /* HP-PA - gcc */
-#endif
-#if defined(__sparc__) || defined(__sparc)
-# define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */
-#endif
-
-/* some other values of possible interest: */
-/* #define breakeven_point 8 */ /* VAX 4000 - vaxc */
-/* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */
-
-#ifndef breakeven_point
-# define breakeven_point 6 /* some reasonable one-size-fits-all value */
-#endif
-
-#define fast_memcpy(d,s,n) \
- { register size_t nn = (size_t)(n); \
- if (nn >= breakeven_point) memcpy((d), (s), nn); \
- else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
- register char *dd; register const char *ss; \
- for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }
-
-#define fast_memset(d,c,n) \
- { register size_t nn = (size_t)(n); \
- if (nn >= breakeven_point) memset((d), (int)(c), nn); \
- else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
- register char *dd; register const int cc=(int)(c); \
- for (dd=(d); nn>0; nn--) *dd++ = cc; } }
-
-/* prototypes */
-
-#if defined(NEED_ASPRINTF)
-int asprintf (char **ptr, const char *fmt, /*args*/ ...);
-#endif
-#if defined(NEED_VASPRINTF)
-int vasprintf (char **ptr, const char *fmt, va_list ap);
-#endif
-#if defined(NEED_ASNPRINTF)
-int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
-#endif
-#if defined(NEED_VASNPRINTF)
-int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap);
-#endif
-
-#if defined(HAVE_SNPRINTF)
-/* declare our portable snprintf routine under name portable_snprintf */
-/* declare our portable vsnprintf routine under name portable_vsnprintf */
-#else
-/* declare our portable routines under names snprintf and vsnprintf */
-#define portable_snprintf snprintf
-#if !defined(NEED_SNPRINTF_ONLY)
-#define portable_vsnprintf vsnprintf
-#endif
-#endif
-
-#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
-int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
-#if !defined(NEED_SNPRINTF_ONLY)
-int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
-#endif
-#endif
-
-/* declarations */
-
-static char credits[] = "\n\
-@(#)snprintf.c, v2.2: Mark Martinec, <mark.martinec@ijs.si>\n\
-@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\
-@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n";
-
-#if defined(NEED_ASPRINTF)
-int asprintf(char **ptr, const char *fmt, /*args*/ ...) {
- va_list ap;
- size_t str_m;
- int str_l;
-
- *ptr = NULL;
- va_start(ap, fmt); /* measure the required size */
- str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
- va_end(ap);
- assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */
- *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
- if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
- else {
- int str_l2;
- va_start(ap, fmt);
- str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
- va_end(ap);
- assert(str_l2 == str_l);
- }
- return str_l;
-}
-#endif
-
-#if defined(NEED_VASPRINTF)
-int vasprintf(char **ptr, const char *fmt, va_list ap) {
- size_t str_m;
- int str_l;
-
- *ptr = NULL;
- { va_list ap2;
- va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */
- str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
- va_end(ap2);
- }
- assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */
- *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
- if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
- else {
- int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
- assert(str_l2 == str_l);
- }
- return str_l;
-}
-#endif
-
-#if defined(NEED_ASNPRINTF)
-int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {
- va_list ap;
- int str_l;
-
- *ptr = NULL;
- va_start(ap, fmt); /* measure the required size */
- str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
- va_end(ap);
- assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */
- if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */
- /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
- if (str_m == 0) { /* not interested in resulting string, just return size */
- } else {
- *ptr = (char *) malloc(str_m);
- if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
- else {
- int str_l2;
- va_start(ap, fmt);
- str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
- va_end(ap);
- assert(str_l2 == str_l);
- }
- }
- return str_l;
-}
-#endif
-
-#if defined(NEED_VASNPRINTF)
-int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {
- int str_l;
-
- *ptr = NULL;
- { va_list ap2;
- va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */
- str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
- va_end(ap2);
- }
- assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */
- if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */
- /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
- if (str_m == 0) { /* not interested in resulting string, just return size */
- } else {
- *ptr = (char *) malloc(str_m);
- if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
- else {
- int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
- assert(str_l2 == str_l);
- }
- }
- return str_l;
-}
-#endif
-
-/*
- * If the system does have snprintf and the portable routine is not
- * specifically required, this module produces no code for snprintf/vsnprintf.
- */
-#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
-
-#if !defined(NEED_SNPRINTF_ONLY)
-int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
- va_list ap;
- int str_l;
-
- va_start(ap, fmt);
- str_l = portable_vsnprintf(str, str_m, fmt, ap);
- va_end(ap);
- return str_l;
-}
-#endif
-
-#if defined(NEED_SNPRINTF_ONLY)
-int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
-#else
-int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {
-#endif
-
-#if defined(NEED_SNPRINTF_ONLY)
- va_list ap;
-#endif
- size_t str_l = 0;
- const char *p = fmt;
-
-/* In contrast with POSIX, the ISO C99 now says
- * that str can be NULL and str_m can be 0.
- * This is more useful than the old: if (str_m < 1) return -1; */
-
-#if defined(NEED_SNPRINTF_ONLY)
- va_start(ap, fmt);
-#endif
- if (!p) p = "";
- while (*p) {
- if (*p != '%') {
- /* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */
- /* but the following code achieves better performance for cases
- * where format string is long and contains few conversions */
- const char *q = strchr(p+1,'%');
- size_t n = !q ? strlen(p) : (q-p);
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memcpy(str+str_l, p, (n>avail?avail:n));
- }
- p += n; str_l += n;
- } else {
- const char *starting_p;
- size_t min_field_width = 0, precision = 0;
- int zero_padding = 0, precision_specified = 0, justify_left = 0;
- int alternate_form = 0, force_sign = 0;
- int space_for_positive = 1; /* If both the ' ' and '+' flags appear,
- the ' ' flag should be ignored. */
- char length_modifier = '\0'; /* allowed values: \0, h, l, L */
- char tmp[32];/* temporary buffer for simple numeric->string conversion */
-
- const char *str_arg; /* string address in case of string argument */
- size_t str_arg_l; /* natural field width of arg without padding
- and sign */
- unsigned char uchar_arg;
- /* unsigned char argument value - only defined for c conversion.
- N.B. standard explicitly states the char argument for
- the c conversion is unsigned */
-
- size_t number_of_zeros_to_pad = 0;
- /* number of zeros to be inserted for numeric conversions
- as required by the precision or minimal field width */
-
- size_t zero_padding_insertion_ind = 0;
- /* index into tmp where zero padding is to be inserted */
-
- char fmt_spec = '\0';
- /* current conversion specifier character */
-
- str_arg = credits;/* just to make compiler happy (defined but not used)*/
- str_arg = NULL;
- starting_p = p; p++; /* skip '%' */
- /* parse flags */
- while (*p == '0' || *p == '-' || *p == '+' ||
- *p == ' ' || *p == '#' || *p == '\'') {
- switch (*p) {
- case '0': zero_padding = 1; break;
- case '-': justify_left = 1; break;
- case '+': force_sign = 1; space_for_positive = 0; break;
- case ' ': force_sign = 1;
- /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */
-#ifdef PERL_COMPATIBLE
- /* ... but in Perl the last of ' ' and '+' applies */
- space_for_positive = 1;
-#endif
- break;
- case '#': alternate_form = 1; break;
- case '\'': break;
- }
- p++;
- }
- /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */
-
- /* parse field width */
- if (*p == '*') {
- int j;
- p++; j = va_arg(ap, int);
- if (j >= 0) min_field_width = j;
- else { min_field_width = -j; justify_left = 1; }
- } else if (isdigit((int)(*p))) {
- /* size_t could be wider than unsigned int;
- make sure we treat argument like common implementations do */
- unsigned int uj = *p++ - '0';
- while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
- min_field_width = uj;
- }
- /* parse precision */
- if (*p == '.') {
- p++; precision_specified = 1;
- if (*p == '*') {
- int j = va_arg(ap, int);
- p++;
- if (j >= 0) precision = j;
- else {
- precision_specified = 0; precision = 0;
- /* NOTE:
- * Solaris 2.6 man page claims that in this case the precision
- * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page
- * claim that this case should be treated as unspecified precision,
- * which is what we do here.
- */
- }
- } else if (isdigit((int)(*p))) {
- /* size_t could be wider than unsigned int;
- make sure we treat argument like common implementations do */
- unsigned int uj = *p++ - '0';
- while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
- precision = uj;
- }
- }
- /* parse 'h', 'l' and 'll' length modifiers */
- if (*p == 'h' || *p == 'l') {
- length_modifier = *p; p++;
- if (length_modifier == 'l' && *p == 'l') { /* double l = long long */
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- length_modifier = '2'; /* double l encoded as '2' */
-#else
- length_modifier = 'l'; /* treat it as a single 'l' */
-#endif
- p++;
- }
- }
- fmt_spec = *p;
- /* common synonyms: */
- switch (fmt_spec) {
- case 'i': fmt_spec = 'd'; break;
- case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
- case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
- case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
- default: break;
- }
- /* get parameter value, do initial processing */
- switch (fmt_spec) {
- case '%': /* % behaves similar to 's' regarding flags and field widths */
- case 'c': /* c behaves similar to 's' regarding flags and field widths */
- case 's':
- length_modifier = '\0'; /* wint_t and wchar_t not supported */
- /* the result of zero padding flag with non-numeric conversion specifier*/
- /* is undefined. Solaris and HPUX 10 does zero padding in this case, */
- /* Digital Unix and Linux does not. */
-#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
- zero_padding = 0; /* turn zero padding off for string conversions */
-#endif
- str_arg_l = 1;
- switch (fmt_spec) {
- case '%':
- str_arg = p; break;
- case 'c': {
- int j = va_arg(ap, int);
- uchar_arg = (unsigned char) j; /* standard demands unsigned char */
- str_arg = (const char *) &uchar_arg;
- break;
- }
- case 's':
- str_arg = va_arg(ap, const char *);
- if (!str_arg) str_arg_l = 0;
- /* make sure not to address string beyond the specified precision !!! */
- else if (!precision_specified) str_arg_l = strlen(str_arg);
- /* truncate string if necessary as requested by precision */
- else if (precision == 0) str_arg_l = 0;
- else {
- /* memchr on HP does not like n > 2^31 !!! */
- const char *q = memchr(str_arg, '\0',
- precision <= 0x7fffffff ? precision : 0x7fffffff);
- str_arg_l = !q ? precision : (q-str_arg);
- }
- break;
- default: break;
- }
- break;
- case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {
- /* NOTE: the u, o, x, X and p conversion specifiers imply
- the value is unsigned; d implies a signed value */
-
- int arg_sign = 0;
- /* 0 if numeric argument is zero (or if pointer is NULL for 'p'),
- +1 if greater than zero (or nonzero for unsigned arguments),
- -1 if negative (unsigned argument is never negative) */
-
- int int_arg = 0; unsigned int uint_arg = 0;
- /* only defined for length modifier h, or for no length modifiers */
-
- long int long_arg = 0; unsigned long int ulong_arg = 0;
- /* only defined for length modifier l */
-
- void *ptr_arg = NULL;
- /* pointer argument value -only defined for p conversion */
-
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- long long int long_long_arg = 0;
- unsigned long long int ulong_long_arg = 0;
- /* only defined for length modifier ll */
-#endif
- if (fmt_spec == 'p') {
- /* HPUX 10: An l, h, ll or L before any other conversion character
- * (other than d, i, u, o, x, or X) is ignored.
- * Digital Unix:
- * not specified, but seems to behave as HPUX does.
- * Solaris: If an h, l, or L appears before any other conversion
- * specifier (other than d, i, u, o, x, or X), the behavior
- * is undefined. (Actually %hp converts only 16-bits of address
- * and %llp treats address as 64-bit data which is incompatible
- * with (void *) argument on a 32-bit system).
- */
-#ifdef SOLARIS_COMPATIBLE
-# ifdef SOLARIS_BUG_COMPATIBLE
- /* keep length modifiers even if it represents 'll' */
-# else
- if (length_modifier == '2') length_modifier = '\0';
-# endif
-#else
- length_modifier = '\0';
-#endif
- ptr_arg = va_arg(ap, void *);
- if (ptr_arg != NULL) arg_sign = 1;
- } else if (fmt_spec == 'd') { /* signed */
- switch (length_modifier) {
- case '\0':
- case 'h':
- /* It is non-portable to specify a second argument of char or short
- * to va_arg, because arguments seen by the called function
- * are not char or short. C converts char and short arguments
- * to int before passing them to a function.
- */
- int_arg = va_arg(ap, int);
- if (int_arg > 0) arg_sign = 1;
- else if (int_arg < 0) arg_sign = -1;
- break;
- case 'l':
- long_arg = va_arg(ap, long int);
- if (long_arg > 0) arg_sign = 1;
- else if (long_arg < 0) arg_sign = -1;
- break;
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- case '2':
- long_long_arg = va_arg(ap, long long int);
- if (long_long_arg > 0) arg_sign = 1;
- else if (long_long_arg < 0) arg_sign = -1;
- break;
-#endif
- }
- } else { /* unsigned */
- switch (length_modifier) {
- case '\0':
- case 'h':
- uint_arg = va_arg(ap, unsigned int);
- if (uint_arg) arg_sign = 1;
- break;
- case 'l':
- ulong_arg = va_arg(ap, unsigned long int);
- if (ulong_arg) arg_sign = 1;
- break;
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- case '2':
- ulong_long_arg = va_arg(ap, unsigned long long int);
- if (ulong_long_arg) arg_sign = 1;
- break;
-#endif
- }
- }
- str_arg = tmp; str_arg_l = 0;
- /* NOTE:
- * For d, i, u, o, x, and X conversions, if precision is specified,
- * the '0' flag should be ignored. This is so with Solaris 2.6,
- * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
- */
-#ifndef PERL_COMPATIBLE
- if (precision_specified) zero_padding = 0;
-#endif
- if (fmt_spec == 'd') {
- if (force_sign && arg_sign >= 0)
- tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
- /* leave negative numbers for sprintf to handle,
- to avoid handling tricky cases like (short int)(-32768) */
-#ifdef LINUX_COMPATIBLE
- } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) {
- tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
-#endif
- } else if (alternate_form) {
- if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') )
- { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; }
- /* alternate form should have no effect for p conversion, but ... */
-#ifdef HPUX_COMPATIBLE
- else if (fmt_spec == 'p'
- /* HPUX 10: for an alternate form of p conversion,
- * a nonzero result is prefixed by 0x. */
-#ifndef HPUX_BUG_COMPATIBLE
- /* Actually it uses 0x prefix even for a zero value. */
- && arg_sign != 0
-#endif
- ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; }
-#endif
- }
- zero_padding_insertion_ind = str_arg_l;
- if (!precision_specified) precision = 1; /* default precision is 1 */
- if (precision == 0 && arg_sign == 0
-#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE)
- && fmt_spec != 'p'
- /* HPUX 10 man page claims: With conversion character p the result of
- * converting a zero value with a precision of zero is a null string.
- * Actually HP returns all zeroes, and Linux returns "(nil)". */
-#endif
- ) {
- /* converted to null string */
- /* When zero value is formatted with an explicit precision 0,
- the resulting formatted string is empty (d, i, u, o, x, X, p). */
- } else {
- char f[5]; int f_l = 0;
- f[f_l++] = '%'; /* construct a simple format string for sprintf */
- if (!length_modifier) { }
- else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; }
- else f[f_l++] = length_modifier;
- f[f_l++] = fmt_spec; f[f_l++] = '\0';
- if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg);
- else if (fmt_spec == 'd') { /* signed */
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break;
- case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break;
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break;
-#endif
- }
- } else { /* unsigned */
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break;
- case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break;
-#ifdef SNPRINTF_LONGLONG_SUPPORT
- case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break;
-#endif
- }
- }
- /* include the optional minus sign and possible "0x"
- in the region before the zero padding insertion point */
- if (zero_padding_insertion_ind < str_arg_l &&
- tmp[zero_padding_insertion_ind] == '-') {
- zero_padding_insertion_ind++;
- }
- if (zero_padding_insertion_ind+1 < str_arg_l &&
- tmp[zero_padding_insertion_ind] == '0' &&
- (tmp[zero_padding_insertion_ind+1] == 'x' ||
- tmp[zero_padding_insertion_ind+1] == 'X') ) {
- zero_padding_insertion_ind += 2;
- }
- }
- { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
- if (alternate_form && fmt_spec == 'o'
-#ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */
- && (str_arg_l > 0)
-#endif
-#ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */
-#else
- /* unless zero is already the first character */
- && !(zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0')
-#endif
- ) { /* assure leading zero for alternate-form octal numbers */
- if (!precision_specified || precision < num_of_digits+1) {
- /* precision is increased to force the first character to be zero,
- except if a zero value is formatted with an explicit precision
- of zero */
- precision = num_of_digits+1; precision_specified = 1;
- }
- }
- /* zero padding to specified precision? */
- if (num_of_digits < precision)
- number_of_zeros_to_pad = precision - num_of_digits;
- }
- /* zero padding to specified minimal field width? */
- if (!justify_left && zero_padding) {
- int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
- if (n > 0) number_of_zeros_to_pad += n;
- }
- break;
- }
- default: /* unrecognized conversion specifier, keep format string as-is*/
- zero_padding = 0; /* turn zero padding off for non-numeric convers. */
-#ifndef DIGITAL_UNIX_COMPATIBLE
- justify_left = 1; min_field_width = 0; /* reset flags */
-#endif
-#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE)
- /* keep the entire format string unchanged */
- str_arg = starting_p; str_arg_l = p - starting_p;
- /* well, not exactly so for Linux, which does something inbetween,
- * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */
-#else
- /* discard the unrecognized conversion, just keep *
- * the unrecognized conversion character */
- str_arg = p; str_arg_l = 0;
-#endif
- if (*p) str_arg_l++; /* include invalid conversion specifier unchanged
- if not at end-of-string */
- break;
- }
- if (*p) p++; /* step over the just processed conversion specifier */
- /* insert padding to the left as requested by min_field_width;
- this does not include the zero padding in case of numerical conversions*/
- if (!justify_left) { /* left padding with blank or zero */
- int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
- if (n > 0) {
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n));
- }
- str_l += n;
- }
- }
- /* zero padding as requested by the precision or by the minimal field width
- * for numeric conversions required? */
- if (number_of_zeros_to_pad <= 0) {
- /* will not copy first part of numeric right now, *
- * force it to be copied later in its entirety */
- zero_padding_insertion_ind = 0;
- } else {
- /* insert first part of numerics (sign or '0x') before zero padding */
- int n = zero_padding_insertion_ind;
- if (n > 0) {
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memcpy(str+str_l, str_arg, (n>avail?avail:n));
- }
- str_l += n;
- }
- /* insert zero padding as requested by the precision or min field width */
- n = number_of_zeros_to_pad;
- if (n > 0) {
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memset(str+str_l, '0', (n>avail?avail:n));
- }
- str_l += n;
- }
- }
- /* insert formatted string
- * (or as-is conversion specifier for unknown conversions) */
- { int n = str_arg_l - zero_padding_insertion_ind;
- if (n > 0) {
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind,
- (n>avail?avail:n));
- }
- str_l += n;
- }
- }
- /* insert right padding */
- if (justify_left) { /* right blank padding to the field width */
- int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
- if (n > 0) {
- if (str_l < str_m) {
- size_t avail = str_m-str_l;
- fast_memset(str+str_l, ' ', (n>avail?avail:n));
- }
- str_l += n;
- }
- }
- }
- }
-#if defined(NEED_SNPRINTF_ONLY)
- va_end(ap);
-#endif
- if (str_m > 0) { /* make sure the string is null-terminated
- even at the expense of overwriting the last character
- (shouldn't happen, but just in case) */
- str[str_l <= str_m-1 ? str_l : str_m-1] = '\0';
- }
- /* Return the number of characters formatted (excluding trailing null
- * character), that is, the number of characters that would have been
- * written to the buffer if it were large enough.
- *
- * The value of str_l should be returned, but str_l is of unsigned type
- * size_t, and snprintf is int, possibly leading to an undetected
- * integer overflow, resulting in a negative return value, which is illegal.
- * Both XSH5 and ISO C99 (at least the draft) are silent on this issue.
- * Should errno be set to EOVERFLOW and EOF returned in this case???
- */
- return (int) str_l;
-}
-#endif
-#endif /* __OS2__ */
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/miscutil.h,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.
- *
- * 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: miscutil.h,v $
- * Revision 1.20 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.19 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.18 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.17 2002/03/04 18:28:32 oes
- * Deleted deletePidFile, played syleguide police
- *
- * Revision 1.16 2002/01/21 00:53:36 jongfoster
- * Adding string_join()
- *
- * Revision 1.15 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.14 2001/11/05 21:43:48 steudten
- * Add global var 'basedir' for unix os.
- *
- * Revision 1.13 2001/10/29 03:48:10 david__schmidt
- * OS/2 native needed a snprintf() routine. Added one to miscutil, brackedted
- * by and __OS2__ ifdef.
- *
- * Revision 1.12 2001/10/23 21:27:50 jongfoster
- * Standardising error codes in string_append
- * make_path() no longer adds '\\' if the dir already ends in '\\' (this
- * is just copying a UNIX-specific fix to the Windows-specific part)
- *
- * Revision 1.11 2001/10/14 22:02:57 jongfoster
- * New function string_append() which is like strsav(), but running
- * out of memory isn't automatically FATAL.
- *
- * Revision 1.10 2001/09/20 13:34:09 steudten
- *
- * change long to int for prototype hash_string()
- *
- * Revision 1.9 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.8 2001/06/29 13:32:14 oes
- * Removed logentry from cancelled commit
- *
- * Revision 1.7 2001/06/05 22:32:01 jongfoster
- * New function make_path() to splice directory and file names together.
- *
- * Revision 1.6 2001/06/03 19:12:30 oes
- * introduced bindup()
- *
- * Revision 1.5 2001/06/01 10:31:51 oes
- * Added character class matching to trivimatch; renamed to simplematch
- *
- * Revision 1.4 2001/05/31 17:32:31 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.3 2001/05/29 23:10:09 oes
- *
- *
- * - Introduced chomp()
- * - Moved strsav() from showargs to miscutil
- *
- * Revision 1.2 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.1.1.1 2001/05/15 13:59:00 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern const char *basedir;
-extern void *zalloc(size_t size);
-
-#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(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[];
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* ndef MISCUTIL_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char parsers_rcs[] = "$Id: parsers.c,v 1.55 2002/05/08 16:01:07 oes Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
- *
- * Purpose : Declares functions to parse/crunch headers and pages.
- * Functions declared include:
- * `add_to_iob', `client_cookie_adder', `client_from',
- * `client_referrer', `client_send_cookie', `client_ua',
- * `client_uagent', `client_x_forwarded',
- * `client_x_forwarded_adder', `client_xtra_adder',
- * `content_type', `crumble', `destroy_list', `enlist',
- * `flush_socket', ``get_header', `sed',
- * and `server_set_cookie'.
- *
- * 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: parsers.c,v $
- * Revision 1.55 2002/05/08 16:01:07 oes
- * Optimized add_to_iob:
- * - Use realloc instead of malloc(), memcpy(), free()
- * - Expand to powers of two if possible, to get
- * O(log n) reallocs instead of O(n).
- * - Moved check for buffer limit here from chat
- * - Report failure via returncode
- *
- * Revision 1.54 2002/04/02 15:03:16 oes
- * Tiny code cosmetics
- *
- * Revision 1.53 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.52 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.51 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.50 2002/03/12 01:45:35 oes
- * More verbose logging
- *
- * Revision 1.49 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.48 2002/03/07 03:46:53 oes
- * Fixed compiler warnings etc
- *
- * Revision 1.47 2002/02/20 23:15:13 jongfoster
- * Parsing functions now handle out-of-memory gracefully by returning
- * an error code.
- *
- * Revision 1.46 2002/01/17 21:03:47 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Revision 1.45 2002/01/09 14:33:03 oes
- * Added support for localtime_r.
- *
- * Revision 1.44 2001/12/14 01:22:54 steudten
- * Remove 'user:pass@' from 'proto://user:pass@host' for the
- * new added header 'Host: ..'. (See Req ID 491818)
- *
- * Revision 1.43 2001/11/23 00:26:38 jongfoster
- * Fixing two really stupid errors in my previous commit
- *
- * Revision 1.42 2001/11/22 21:59:30 jongfoster
- * Adding code to handle +no-cookies-keep
- *
- * Revision 1.41 2001/11/05 23:43:05 steudten
- * Add time+date to log files.
- *
- * Revision 1.40 2001/10/26 20:13:09 jongfoster
- * ctype.h is needed in Windows, too.
- *
- * Revision 1.39 2001/10/26 17:40:04 oes
- * Introduced get_header_value()
- * Removed http->user_agent, csp->referrer and csp->accept_types
- * Removed client_accept()
- *
- * Revision 1.38 2001/10/25 03:40:48 david__schmidt
- * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
- * threads to call select() simultaneously. So, it's time to do a real, live,
- * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
- * (native). Both versions will work, but using __OS2__ offers multi-threading.
- *
- * Revision 1.37 2001/10/23 21:36:02 jongfoster
- * Documenting sed()'s error behaviou (doc change only)
- *
- * Revision 1.36 2001/10/13 12:51:51 joergs
- * Removed client_host, (was only required for the old 2.0.2-11 http://noijb.
- * force-load), instead crumble Host: and add it (again) in client_host_adder
- * (in case we get a HTTP/1.0 request without Host: header and forward it to
- * a HTTP/1.1 server/proxy).
- *
- * Revision 1.35 2001/10/09 22:39:21 jongfoster
- * assert.h is also required under Win32, so moving out of #ifndef _WIN32
- * block.
- *
- * Revision 1.34 2001/10/07 18:50:55 oes
- * Added server_content_encoding, renamed server_transfer_encoding
- *
- * Revision 1.33 2001/10/07 18:04:49 oes
- * Changed server_http11 to server_http and its pattern to "HTTP".
- * Additional functionality: it now saves the HTTP status into
- * csp->http->status and sets CT_TABOO for Status 206 (partial range)
- *
- * Revision 1.32 2001/10/07 15:43:28 oes
- * Removed FEATURE_DENY_GZIP and replaced it with client_accept_encoding,
- * client_te and client_accept_encoding_adder, triggered by the new
- * +no-compression action. For HTTP/1.1 the Accept-Encoding header is
- * changed to allow only identity and chunked, and the TE header is
- * crunched. For HTTP/1.0, Accept-Encoding is crunched.
- *
- * parse_http_request no longer does anything than parsing. The rewriting
- * of http->cmd and version mangling are gone. It now also recognizes
- * the put and delete methods and saves the url in http->url. Removed
- * unused variable.
- *
- * renamed content_type and content_length to have the server_ prefix
- *
- * server_content_type now only works if csp->content_type != CT_TABOO
- *
- * added server_transfer_encoding, which
- * - Sets CT_TABOO to prohibit filtering if encoding compresses
- * - Raises the CSP_FLAG_CHUNKED flag if Encoding is "chunked"
- * - Change from "chunked" to "identity" if body was chunked
- * but has been de-chunked for filtering.
- *
- * added server_content_md5 which crunches any Content-MD5 headers
- * if the body was modified.
- *
- * made server_http11 conditional on +downgrade action
- *
- * Replaced 6 boolean members of csp with one bitmap (csp->flags)
- *
- * Revision 1.31 2001/10/05 14:25:02 oes
- * Crumble Keep-Alive from Server
- *
- * Revision 1.30 2001/09/29 12:56:03 joergs
- * IJB now changes HTTP/1.1 to HTTP/1.0 in requests and answers.
- *
- * Revision 1.29 2001/09/24 21:09:24 jongfoster
- * Fixing 2 memory leaks that Guy spotted, where the paramater to
- * enlist() was not being free()d.
- *
- * Revision 1.28 2001/09/22 16:32:28 jongfoster
- * Removing unused #includes.
- *
- * Revision 1.27 2001/09/20 15:45:25 steudten
- *
- * add casting from size_t to int for printf()
- * remove local variable shadow s2
- *
- * Revision 1.26 2001/09/16 17:05:14 jongfoster
- * Removing unused #include showarg.h
- *
- * Revision 1.25 2001/09/16 13:21:27 jongfoster
- * Changes to use new list functions.
- *
- * Revision 1.24 2001/09/13 23:05:50 jongfoster
- * Changing the string paramater to the header parsers a "const".
- *
- * Revision 1.23 2001/09/12 18:08:19 steudten
- *
- * In parse_http_request() header rewriting miss the host value, so
- * from http://www.mydomain.com the result was just " / " not
- * http://www.mydomain.com/ in case we forward.
- *
- * Revision 1.22 2001/09/10 10:58:53 oes
- * Silenced compiler warnings
- *
- * Revision 1.21 2001/07/31 14:46:00 oes
- * - Persistant connections now suppressed
- * - sed() no longer appends empty header to csp->headers
- *
- * Revision 1.20 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.19 2001/07/25 17:21:54 oes
- * client_uagent now saves copy of User-Agent: header value
- *
- * Revision 1.18 2001/07/13 14:02:46 oes
- * - Included fix to repair broken HTTP requests that
- * don't contain a path, not even '/'.
- * - Removed all #ifdef PCRS
- * - content_type now always inspected and classified as
- * text, gif or other.
- * - formatting / comments
- *
- * Revision 1.17 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.16 2001/06/29 13:32:42 oes
- * - Fixed a comment
- * - Adapted free_http_request
- * - Removed logentry from cancelled commit
- *
- * Revision 1.15 2001/06/03 19:12:38 oes
- * deleted const struct interceptors
- *
- * Revision 1.14 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.13 2001/05/31 21:30:33 jongfoster
- * Removed list code - it's now in list.[ch]
- * Renamed "permission" to "action", and changed many features
- * to use the actions file rather than the global config.
- *
- * Revision 1.12 2001/05/31 17:33:13 oes
- *
- * CRLF -> LF
- *
- * Revision 1.11 2001/05/29 20:11:19 joergs
- * '/ * inside comment' warning removed.
- *
- * Revision 1.10 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.9 2001/05/28 17:26:33 jongfoster
- * Fixing segfault if last header was crunched.
- * Fixing Windows build (snprintf() is _snprintf() under Win32, but we
- * can use the cross-platform sprintf() instead.)
- *
- * Revision 1.8 2001/05/27 22:17:04 oes
- *
- * - re_process_buffer no longer writes the modified buffer
- * to the client, which was very ugly. It now returns the
- * buffer, which it is then written by chat.
- *
- * - content_length now adjusts the Content-Length: header
- * for modified documents rather than crunch()ing it.
- * (Length info in csp->content_length, which is 0 for
- * unmodified documents)
- *
- * - For this to work, sed() is called twice when filtering.
- *
- * Revision 1.7 2001/05/27 13:19:06 oes
- * Patched Joergs solution for the content-length in.
- *
- * Revision 1.6 2001/05/26 13:39:32 jongfoster
- * Only crunches Content-Length header if applying RE filtering.
- * Without this fix, Microsoft Windows Update wouldn't work.
- *
- * Revision 1.5 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.4 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 23:02:36 oes
- * - Made referrer option accept 'L' as a substitute for '§'
- *
- * Revision 1.1.1.1 2001/05/15 13:59:01 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#ifndef _WIN32
-#include <stdio.h>
-#include <sys/types.h>
-#endif
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <assert.h>
-#include <string.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif
-
-#include "project.h"
-#include "list.h"
-#include "parsers.h"
-#include "encode.h"
-#include "ssplit.h"
-#include "errlog.h"
-#include "jbsockets.h"
-#include "miscutil.h"
-#include "list.h"
-
-const char parsers_h_rcs[] = PARSERS_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".
- *
- * 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))
-#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
-
-
-const struct parsers client_patterns[] = {
- { "referer:", 8, client_referrer },
- { "user-agent:", 11, client_uagent },
- { "ua-", 3, client_ua },
- { "from:", 5, client_from },
- { "cookie:", 7, client_send_cookie },
- { "x-forwarded-for:", 16, client_x_forwarded },
- { "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 parsers server_patterns[] = {
- { "HTTP", 4, server_http },
- { "set-cookie:", 11, server_set_cookie },
- { "connection:", 11, crumble },
- { "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 }
-};
-
-
-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
-};
-
-
-const add_header_func_ptr add_server_headers[] = {
- connection_close_adder,
- NULL
-};
-
-
-/*********************************************************************
- *
- * Function : flush_socket
- *
- * Description : Write any pending "buffered" content.
- *
- * Parameters :
- * 1 : fd = file descriptor of the socket to read
- * 2 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : On success, the number of bytes written are returned (zero
- * indicates nothing was written). On error, -1 is returned,
- * and errno is set appropriately. If count is zero and the
- * file descriptor refers to a regular file, 0 will be
- * returned without causing any other effect. For a special
- * file, the results are not portable.
- *
- *********************************************************************/
-int flush_socket(jb_socket fd, struct client_state *csp)
-{
- struct iob *iob = csp->iob;
- int len = iob->eod - iob->cur;
-
- if (len <= 0)
- {
- return(0);
- }
-
- if (write_socket(fd, iob->cur, (size_t)len))
- {
- return(-1);
- }
- iob->eod = iob->cur = iob->buf;
- return(len);
-
-}
-
-
-/*********************************************************************
- *
- * Function : add_to_iob
- *
- * 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 : JB_ERR_OK on success, JB_ERR_MEMORY if out-of-memory
- * or buffer limit reached.
- *
- *********************************************************************/
-jb_err add_to_iob(struct client_state *csp, char *buf, int n)
-{
- struct iob *iob = csp->iob;
- size_t used, offset, need, want;
- char *p;
-
- if (n <= 0) return JB_ERR_OK;
-
- used = iob->eod - iob->buf;
- offset = iob->cur - iob->buf;
- need = used + n + 1;
-
- /*
- * 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, "Buffer limit reached while extending the buffer (iob)");
- return JB_ERR_MEMORY;
- }
-
- if (need > iob->size)
- {
- 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;
- }
-
- /* Update the iob pointers */
- iob->cur = p + offset;
- iob->eod = p + used;
- iob->buf = p;
- }
-
- /* copy the new data into the iob buffer */
- memcpy(iob->eod, buf, (size_t)n);
-
- /* point to the end of the data */
- iob->eod += n;
-
- /* null terminate == cheap insurance */
- *iob->eod = '\0';
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : get_header
- *
- * Description : This (odd) routine will parse the csp->iob
- *
- * Parameters :
- * 1 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : Any one of the following:
- *
- * 1) a pointer to a dynamically allocated string that contains a header line
- * 2) NULL indicating that the end of the header was reached
- * 3) "" indicating that the end of the iob was reached before finding
- * a complete header line.
- *
- *********************************************************************/
-char *get_header(struct client_state *csp)
-{
- struct iob *iob;
- char *p, *q, *ret;
- iob = csp->iob;
-
- if ((iob->cur == NULL)
- || ((p = strchr(iob->cur, '\n')) == NULL))
- {
- return(""); /* couldn't find a complete header */
- }
-
- *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')) != NULL) *q = '\0';
-
- /* is this a blank line (i.e. the end of the header) ? */
- if (*ret == '\0')
- {
- freez(ret);
- return(NULL);
- }
-
- return(ret);
-
-}
-
-
-/*********************************************************************
- *
- * Function : get_header_value
- *
- * 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 : header_list = pointer to list
- * 2 : header_name = string with name of header to look for.
- * Trailing colon required, capitalization
- * doesn't matter.
- *
- * Returns : NULL if not found, else value of header
- *
- *********************************************************************/
-char *get_header_value(const struct list *header_list, const char *header_name)
-{
- struct list_entry *cur_entry;
- char *ret = NULL;
- size_t length = 0;
-
- assert(header_list);
- assert(header_name);
- length = strlen(header_name);
-
- for (cur_entry = header_list->first; cur_entry ; cur_entry = cur_entry->next)
- {
- if (cur_entry->str)
- {
- 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);
- }
- }
- }
-
- /*
- * Not found
- */
- return NULL;
-
-}
-
-/*********************************************************************
- *
- * Function : sed
- *
- * Description : add, delete or modify lines in the HTTP header streams.
- * On entry, it receives a linked list of headers space
- * that was allocated dynamically (both the list nodes
- * and the header contents).
- *
- * As a side effect it frees the space used by the original
- * header lines.
- *
- * Parameters :
- * 1 : pats = list of patterns to match against headers
- * 2 : more_headers = list of functions to add more
- * headers (client or server)
- * 3 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : Single pointer to a fully formed header, or NULL
- * on out-of-memory error.
- *
- *********************************************************************/
-char *sed(const struct parsers pats[],
- const add_header_func_ptr more_headers[],
- struct client_state *csp)
-{
- struct list_entry *p;
- const struct parsers *v;
- const add_header_func_ptr *f;
- jb_err err = JB_ERR_OK;
-
- for (v = pats; (err == JB_ERR_OK) && (v->str != NULL) ; v++)
- {
- for (p = csp->headers->first; (err == JB_ERR_OK) && (p != NULL) ; p = p->next)
- {
- /* 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; (err == JB_ERR_OK) && (*f) ; f++)
- {
- err = (*f)(csp);
- }
-
- if (err != JB_ERR_OK)
- {
- return NULL;
- }
-
- return list_to_text(csp->headers);
-}
-
-
-/* here begins the family of parser functions that reformat header lines */
-
-
-/*********************************************************************
- *
- * Function : crumble
- *
- * Description : This is called if a header matches a pattern to "crunch"
- *
- * 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 crumble(struct client_state *csp, char **header)
-{
- log_error(LOG_LEVEL_HEADER, "crunch!");
- freez(*header);
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : server_content_type
- *
- * 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 : 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_type(struct client_state *csp, char **header)
-{
- if (csp->content_type != CT_TABOO)
- {
- 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;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * 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;
- }
-
- /*
- * Raise flag if body chunked
- */
- if (strstr(*header, "chunked"))
- {
- csp->flags |= CSP_FLAG_CHUNKED;
-
- /*
- * If the body was modified, it has been
- * de-chunked first, so adjust the header:
- */
- if (csp->flags & CSP_FLAG_MODIFIED)
- {
- freez(*header);
- *header = strdup("Transfer-Encoding: identity");
- return (header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
- }
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * 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"))
- {
- csp->content_type = CT_TABOO;
- }
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * 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 */
- {
- freez(*header);
- *header = (char *) zalloc(100);
- if (*header == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- sprintf(*header, "Content-Length: %d", (int) csp->content_length);
-
- log_error(LOG_LEVEL_HEADER, "Adjust Content-Length to %d", (int) csp->content_length);
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * 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)
- {
- log_error(LOG_LEVEL_HEADER, "Crunching Content-MD5");
- freez(*header);
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : client_accept_encoding
- *
- * 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 : 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 client_accept_encoding(struct client_state *csp, char **header)
-{
- 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;
-}
-
-
-/*********************************************************************
- *
- * Function : client_te
- *
- * Description : Rewrite the client's TE header so that
- * if doesn't allow compression, if the 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 client_te(struct client_state *csp, char **header)
-{
- if ((csp->action->flags & ACTION_NO_COMPRESSION) != 0)
- {
- freez(*header);
- log_error(LOG_LEVEL_HEADER, "Supressed offer to compress transfer");
- }
-
- return JB_ERR_OK;
-}
-
-/*********************************************************************
- *
- * Function : client_referrer
- *
- * Description : Handle the "referer" config setting properly.
- * Called from `sed'.
- *
- * 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 client_referrer(struct client_state *csp, char **header)
-{
- 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
- */
- strclean(*header, FORCE_PREFIX);
-#endif /* def FEATURE_FORCE_LOAD */
-
- /*
- * Are we sending referer?
- */
- if ((csp->action->flags & ACTION_HIDE_REFERER) == 0)
- {
- return JB_ERR_OK;
- }
-
- freez(*header);
-
- newval = csp->action->string[ACTION_STRING_REFERER];
-
- if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
- {
- /*
- * 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");
-
- *header = strdup("Referer: ");
- string_append(header, newval);
-
- return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
- }
- else
- {
- /*
- * Forge a referer as http://[hostname:port of REQUEST]/
- * to fool stupid checks for in-site links
- */
- if (0 != strcmpic(newval, "forge"))
- {
- /*
- * Invalid choice - but forge is probably the best default.
- */
- log_error(LOG_LEVEL_ERROR, "Bad parameter: +referer{%s}", newval);
- }
-
- *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;
- }
-}
-
-
-/*********************************************************************
- *
- * Function : client_uagent
- *
- * Description : Handle the "user-agent" config setting properly
- * and remember its original value to enable browser
- * bug workarounds. Called from `sed'.
- *
- * 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 client_uagent(struct client_state *csp, char **header)
-{
- const char *newval;
-
- if ((csp->action->flags & ACTION_HIDE_USER_AGENT) == 0)
- {
- return JB_ERR_OK;
- }
-
- newval = csp->action->string[ACTION_STRING_USER_AGENT];
- if (newval == NULL)
- {
- return JB_ERR_OK;
- }
-
- log_error(LOG_LEVEL_HEADER, "modified");
-
- freez(*header);
- *header = strdup("User-Agent: ");
- string_append(header, newval);
-
- return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : client_ua
- *
- * Description : Handle "ua-" headers properly. Called from `sed'.
- *
- * 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 client_ua(struct client_state *csp, char **header)
-{
- if ((csp->action->flags & ACTION_HIDE_USER_AGENT) != 0)
- {
- log_error(LOG_LEVEL_HEADER, "crunch!");
- freez(*header);
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : client_from
- *
- * Description : Handle the "from" config setting properly.
- * Called from `sed'.
- *
- * 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 client_from(struct client_state *csp, char **header)
-{
- const char *newval;
-
- if ((csp->action->flags & ACTION_HIDE_FROM) == 0)
- {
- return JB_ERR_OK;
- }
-
- freez(*header);
-
- newval = csp->action->string[ACTION_STRING_FROM];
-
- /*
- * Are we blocking the e-mail address?
- */
- if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
- {
- log_error(LOG_LEVEL_HEADER, "crunch!");
- return JB_ERR_OK;
- }
-
- log_error(LOG_LEVEL_HEADER, " modified");
-
- *header = strdup("From: ");
- string_append(header, newval);
-
- return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : client_send_cookie
- *
- * Description : Handle the "cookie" header properly. Called from `sed'.
- * If cookie is accepted, add it to the cookie_list,
- * else we crunch it. Mmmmmmmmmmm ... cookie ......
- *
- * 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 client_send_cookie(struct client_state *csp, char **header)
-{
- jb_err result = JB_ERR_OK;
-
- if ((csp->action->flags & ACTION_NO_COOKIE_READ) == 0)
- {
- /* strlen("cookie: ") == 8 */
- result = enlist(csp->cookie_list, *header + 8);
- }
- else
- {
- log_error(LOG_LEVEL_HEADER, " crunch!");
- }
-
- /*
- * Always remove the cookie here. The cookie header
- * will be sent at the end of the header.
- */
- freez(*header);
-
- return result;
-}
-
-
-/*********************************************************************
- *
- * Function : client_x_forwarded
- *
- * Description : Handle the "x-forwarded-for" config setting properly,
- * also used in the add_client_headers list. Called from `sed'.
- *
- * 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 client_x_forwarded(struct client_state *csp, char **header)
-{
- if ((csp->action->flags & ACTION_HIDE_FORWARDED) == 0)
- {
- /* Save it so we can re-add it later */
- freez(csp->x_forwarded);
- csp->x_forwarded = *header;
-
- /*
- * 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;
-}
-
-/* the following functions add headers directly to the header list */
-
-/*********************************************************************
- *
- * Function : client_host_adder
- *
- * Description : (re)adds the host header. Called from `sed'.
- *
- * 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_host_adder(struct client_state *csp)
-{
- char *p;
- char *pos;
- jb_err err;
-
- if ( !csp->http->hostport || !*(csp->http->hostport))
- {
- 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
- {
- string_append(&p, csp->http->hostport);
- }
-
- if (p == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- log_error(LOG_LEVEL_HEADER, "addh: %s", p);
-
- err = enlist(csp->headers, p);
-
- freez(p);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : client_cookie_adder
- *
- * Description : Used in the add_client_headers list. Called from `sed'.
- *
- * 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_cookie_adder(struct client_state *csp)
-{
- 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 (lst = list1; lst ; lst = lst->next)
- {
- if (first_cookie)
- {
- first_cookie = 0;
- }
- else
- {
- string_append(&tmp, "; ");
- }
- string_append(&tmp, lst->str);
- }
-
- for (lst = list2; lst ; lst = lst->next)
- {
- if (first_cookie)
- {
- first_cookie = 0;
- }
- else
- {
- string_append(&tmp, "; ");
- }
- string_join(&tmp, cookie_encode(lst->str));
- }
-
- if (tmp == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- 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;
-}
-
-
-/*********************************************************************
- *
- * Function : client_xtra_adder
- *
- * Description : Used in the add_client_headers list. Called from `sed'.
- *
- * 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_xtra_adder(struct client_state *csp)
-{
- struct list_entry *lst;
- jb_err err;
-
- for (lst = csp->action->multi[ACTION_MULTI_ADD_HEADER]->first;
- lst ; lst = lst->next)
- {
- log_error(LOG_LEVEL_HEADER, "addh: %s", lst->str);
- err = enlist(csp->headers, lst->str);
- if (err)
- {
- return err;
- }
-
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : client_x_forwarded_adder
- *
- * Description : Used in the add_client_headers list. Called from `sed'.
- *
- * 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_x_forwarded_adder(struct client_state *csp)
-{
- char *p = NULL;
- jb_err err;
-
- if ((csp->action->flags & ACTION_HIDE_FORWARDED) != 0)
- {
- return JB_ERR_OK;
- }
-
- if (csp->x_forwarded)
- {
- p = strdup(csp->x_forwarded);
- string_append(&p, ", ");
- }
- else
- {
- 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);
- err = enlist(csp->headers, p);
- free(p);
-
- return err;
-}
-
-
-/*********************************************************************
- *
- * Function : connection_close_adder
- *
- * 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 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : JB_ERR_OK on success, or
- * JB_ERR_MEMORY on out-of-memory error.
- *
- *********************************************************************/
-jb_err connection_close_adder(struct client_state *csp)
-{
- 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)
- {
- csp->content_type = CT_TABOO;
- }
-
- if ((csp->action->flags & ACTION_DOWNGRADE) != 0)
- {
- (*header)[7] = '0';
- log_error(LOG_LEVEL_HEADER, "Downgraded answer to HTTP/1.0");
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : server_set_cookie
- *
- * Description : Handle the server "cookie" header properly.
- * Log cookie to the jar file. Then "crunch" it,
- * or accept it. Called from `sed'.
- *
- * 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_set_cookie(struct client_state *csp, char **header)
-{
-#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;
-}
-
-
-#ifdef FEATURE_FORCE_LOAD
-/*********************************************************************
- *
- * Function : strclean
- *
- * Description : In-Situ-Eliminate all occurances of substring in
- * string
- *
- * Parameters :
- * 1 : string = string to clean
- * 2 : substring = substring to eliminate
- *
- * Returns : Number of eliminations
- *
- *********************************************************************/
-int strclean(const char *string, const char *substring)
-{
- int hits = 0, len = strlen(substring);
- char *pos, *p;
-
- while((pos = strstr(string, substring)) != NULL)
- {
- p = pos + len;
- do
- {
- *(p - len) = *p;
- }
- while (*p++ != '\0');
-
- hits++;
- }
-
- return(hits);
-}
-#endif /* def FEATURE_FORCE_LOAD */
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/parsers.h,v $
- *
- * Purpose : Declares functions to parse/crunch headers and pages.
- * Functions declared include:
- * `add_to_iob', `client_cookie_adder', `client_from',
- * `client_referrer', `client_send_cookie', `client_ua',
- * `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', `parse_http_request', `sed',
- * and `server_set_cookie'.
- *
- * 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: parsers.h,v $
- * Revision 1.25 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.24 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.23 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.22 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.21 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.20 2002/02/20 23:15:13 jongfoster
- * Parsing functions now handle out-of-memory gracefully by returning
- * an error code.
- *
- * Revision 1.19 2002/01/17 21:03:47 jongfoster
- * Moving all our URL and URL pattern parsing code to urlmatch.c.
- *
- * Revision 1.18 2001/10/26 17:40:23 oes
- * Introduced get_header_value()
- * Removed client_accept()
- *
- * Revision 1.17 2001/10/13 12:47:32 joergs
- * Removed client_host, added client_host_adder
- *
- * Revision 1.16 2001/10/07 18:50:16 oes
- * Added server_content_encoding, renamed server_transfer_encoding
- *
- * Revision 1.15 2001/10/07 18:01:55 oes
- * Changed server_http11 to server_http
- *
- * Revision 1.14 2001/10/07 15:45:48 oes
- * added client_accept_encoding, client_te, client_accept_encoding_adder
- *
- * renamed content_type and content_length
- *
- * fixed client_host and strclean prototypes
- *
- * Revision 1.13 2001/09/29 12:56:03 joergs
- * IJB now changes HTTP/1.1 to HTTP/1.0 in requests and answers.
- *
- * Revision 1.12 2001/09/13 23:05:50 jongfoster
- * Changing the string paramater to the header parsers a "const".
- *
- * Revision 1.11 2001/07/31 14:46:53 oes
- * Added prototype for connection_close_adder
- *
- * Revision 1.10 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.9 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.8 2001/07/13 14:01:54 oes
- * Removed all #ifdef PCRS
- *
- * Revision 1.7 2001/06/29 13:32:14 oes
- * Removed logentry from cancelled commit
- *
- * Revision 1.6 2001/06/03 19:12:38 oes
- * deleted const struct interceptors
- *
- * Revision 1.5 2001/05/31 21:30:33 jongfoster
- * Removed list code - it's now in list.[ch]
- * Renamed "permission" to "action", and changed many features
- * to use the actions file rather than the global config.
- *
- * Revision 1.4 2001/05/27 13:19:06 oes
- * Patched Joergs solution for the content-length in.
- *
- * Revision 1.3 2001/05/26 13:39:32 jongfoster
- * Only crunches Content-Length header if applying RE filtering.
- * Without this fix, Microsoft Windows Update wouldn't work.
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:01 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const struct parsers client_patterns[];
-extern const struct parsers server_patterns[];
-
-extern const add_header_func_ptr add_client_headers[];
-extern const add_header_func_ptr add_server_headers[];
-
-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 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[];
-extern const char parsers_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef PARSERS_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char pcrs_rcs[] = "$Id: pcrs.c,v 1.18 2002/03/08 14:17:14 oes Exp $";
-
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/pcrs.c,v $
- *
- * Purpose : pcrs is a supplement to the pcre library by Philip Hazel
- * <ph10@cam.ac.uk> and adds Perl-style substitution. That
- * is, it mimics Perl's 's' operator. See pcrs(3) for details.
- *
- *
- * Copyright : Written and Copyright (C) 2000, 2001 by Andreas S. Oesterhelt
- * <andreas@oesterhelt.org>
- *
- * 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.
- *
- * 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.
- *
- * The GNU Lesser General Public License should be included
- * with this file. If not, you can view it at
- * http://www.gnu.org/licenses/lgpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: pcrs.c,v $
- * Revision 1.18 2002/03/08 14:17:14 oes
- * Fixing -Wconversion warnings
- *
- * Revision 1.17 2002/03/08 13:45:48 oes
- * Hiding internal functions
- *
- * Revision 1.16 2001/11/30 21:32:14 jongfoster
- * Fixing signed/unsigned comparison (Andreas please check this!)
- * One tab->space
- *
- * Revision 1.15 2001/09/20 16:11:06 steudten
- *
- * Add casting for some string functions.
- *
- * Revision 1.14 2001/09/09 21:41:57 oes
- * Fixing yet another silly bug
- *
- * Revision 1.13 2001/09/06 14:05:59 oes
- * Fixed silly bug
- *
- * Revision 1.12 2001/08/18 11:35:00 oes
- * - Introduced pcrs_strerror()
- * - made some NULL arguments non-fatal
- * - added support for \n \r \e \b \t \f \a \0 in substitute
- * - made quoting adhere to standard rules
- * - added warning for bad backrefs
- * - added pcrs_execute_list()
- * - fixed comments
- * - bugfix & cosmetics
- *
- * Revision 1.11 2001/08/15 15:32:03 oes
- * - Added support for Perl's special variables $+, $' and $`
- * - Improved the substitute parser
- * - Replaced the hard limit for the maximum number of matches
- * by dynamic reallocation
- *
- * Revision 1.10 2001/08/05 13:13:11 jongfoster
- * Making parameters "const" where possible.
- *
- * Revision 1.9 2001/07/18 17:27:00 oes
- * Changed interface; Cosmetics
- *
- * Revision 1.8 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.7 2001/06/29 13:33:04 oes
- * - Cleaned up, renamed and reordered functions,
- * improved comments
- * - Removed my_strsep
- * - Replaced globalflag with a general flags int
- * that holds PCRS_GLOBAL, PCRS_SUCCESS, and PCRS_TRIVIAL
- * - Introduced trivial option that will prevent pcrs
- * from honouring backreferences in the substitute,
- * which is useful for large substitutes that are
- * red in from somewhere and saves the pain of escaping
- * the backrefs
- * - Introduced convenience function pcrs_free_joblist()
- * - Split pcrs_make_job() into pcrs_compile(), which still
- * takes a complete s/// comand as argument and parses it,
- * and a new function pcrs_make_job, which takes the
- * three separate components. This should make for a
- * much friendlier frontend.
- * - Removed create_pcrs_job() which was useless
- * - Fixed a bug in pcrs_execute
- * - Success flag is now handled by pcrs instead of user
- *
- * Revision 1.6 2001/06/03 19:12:45 oes
- * added FIXME
- *
- * Revision 1.5 2001/05/29 09:50:24 jongfoster
- * (Fixed one int -> size_t)
- *
- * Revision 1.4 2001/05/25 14:12:40 oes
- * Fixed bug: Empty substitutes now detected
- *
- * Revision 1.3 2001/05/25 11:03:55 oes
- * Added sanity check for NULL jobs to pcrs_exec_substitution
- *
- * Revision 1.2 2001/05/22 18:46:04 oes
- *
- * Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * Revision 1.1.1.1 2001/05/15 13:59:02 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include <pcre.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "pcrs.h"
-
-const char pcrs_h_rcs[] = PCRS_H_VERSION;
-
-/*
- * Internal prototypes
- */
-
-static int pcrs_parse_perl_options(const char *optstring, int *flags);
-static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag,
- int capturecount, int *errptr);
-
-/*********************************************************************
- *
- * Function : pcrs_strerror
- *
- * Description : Return a string describing a given error code.
- *
- * Parameters :
- * 1 : error = the error code
- *
- * Returns : char * to the descriptive string
- *
- *********************************************************************/
-const char *pcrs_strerror(const int error)
-{
- if (error < 0)
- {
- switch (error)
- {
- /* 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";
- }
- }
- /* error >= 0: No error */
- return "(pcrs:) Everything's just fine. Thanks for asking.";
-
-}
-
-
-/*********************************************************************
- *
- * 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) 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 : flags = see description
- *
- * Returns : option integer suitable for pcre
- *
- *********************************************************************/
-static int pcrs_parse_perl_options(const char *optstring, int *flags)
-{
- 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; /* 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;
- case 'U': rc |= PCRE_UNGREEDY; break;
- case 'T': *flags |= PCRS_TRIVIAL; break;
- default: break;
- }
- }
- return rc;
-
-}
-
-
-/*********************************************************************
- *
- * Function : pcrs_compile_replacement
- *
- * Description : This function takes a Perl-style replacement (2nd argument
- * to the s/// operator and returns a compiled pcrs_substitute,
- * or NULL if memory allocation for the substitute structure
- * fails.
- *
- * Parameters :
- * 1 : replacement = replacement part of s/// operator
- * in perl syntax
- * 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
- * error is encountered. In that case, *errptr has
- * the reason.
- *
- *********************************************************************/
-static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag, int capturecount, int *errptr)
-{
- int i, k, l, quoted;
- size_t length;
- char *text;
- pcrs_substitute *r;
-
- i = k = l = quoted = 0;
-
- /*
- * Sanity check
- */
- if (NULL == replacement)
- {
- replacement = "";
- }
-
- /*
- * Get memory or fail
- */
- if (NULL == (r = (pcrs_substitute *)malloc(sizeof(pcrs_substitute))))
- {
- *errptr = PCRS_ERR_NOMEM;
- return NULL;
- }
- memset(r, '\0', sizeof(pcrs_substitute));
-
- length = strlen(replacement);
-
- if (NULL == (text = (char *)malloc(length + 1)))
- {
- 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;
- }
-
- /*
- * Else, parse, cut out and record all backreferences
- */
- else
- {
- while (i < (int)length)
- {
- /* Quoting */
- if (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;
- }
-
- /* Backreferences */
- if (replacement[i] == '$' && !quoted && i < (int)(length - 1))
- {
- char *symbol, symbols[] = "'`+&";
- r->block_length[l] = k - r->block_offset[l];
-
- /* Numerical backreferences */
- if (isdigit((int)replacement[i + 1]))
- {
- while (i < (int)length && isdigit((int)replacement[++i]))
- {
- r->backref[l] = r->backref[l] * 10 + replacement[i] - 48;
- }
- if (r->backref[l] > capturecount)
- {
- *errptr = PCRS_WARN_BADREF;
- }
- }
-
- /* 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
- {
- goto plainchar;
- }
-
- /* Valid and in range? -> record */
- if (r->backref[l] < PCRS_MAX_SUBMATCHES + 2)
- {
- r->backref_count[r->backref[l]] += 1;
- r->block_offset[++l] = k;
- }
- else
- {
- *errptr = PCRS_WARN_BADREF;
- }
- continue;
- }
-
-plainchar:
- /* Plain chars are copied */
- text[k++] = replacement[i++];
- quoted = 0;
- }
- } /* -END- if (!trivialflag) */
-
- /*
- * Finish & return
- */
- r->text = text;
- r->backrefs = l;
- r->block_length[l] = k - r->block_offset[l];
-
- return r;
-
-}
-
-
-/*********************************************************************
- *
- * Function : pcrs_free_job
- *
- * Description : Frees the memory used by a pcrs_job struct and its
- * 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.
- *
- *********************************************************************/
-pcrs_job *pcrs_free_job(pcrs_job *job)
-{
- pcrs_job *next;
-
- if (job == NULL)
- {
- return NULL;
- }
- else
- {
- next = job->next;
- if (job->pattern != NULL) free(job->pattern);
- if (job->hints != NULL) free(job->hints);
- if (job->substitute != NULL)
- {
- if (job->substitute->text != NULL) free(job->substitute->text);
- free(job->substitute);
- }
- free(job);
- }
- return next;
-
-}
-
-
-/*********************************************************************
- *
- * 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 : 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
- * 2 : 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_command(const char *command, int *errptr)
-{
- int i, k, l, quoted = FALSE;
- size_t limit;
- char delimiter;
- char *tokens[4];
- pcrs_job *newjob;
-
- i = k = l = 0;
-
- /*
- * Tokenize the perl command
- */
- limit = strlen(command);
- if (limit < 4)
- {
- *errptr = PCRS_ERR_CMDSYNTAX;
- return NULL;
- }
- else
- {
- delimiter = command[1];
- }
-
- tokens[l] = (char *) malloc(limit + 1);
-
- for (i = 0; i <= (int)limit; i++)
- {
-
- if (command[i] == delimiter && !quoted)
- {
- 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];
- }
-
- /*
- * 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;
-
-}
-
-
-/*********************************************************************
- *
- * 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;
-
- *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;
- }
- memset(newjob, '\0', sizeof(pcrs_job));
-
-
- /*
- * 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;
- }
-
-
- /*
- * Generate hints. This has little overhead, since the
- * hints will be NULL for a boring pattern anyway.
- */
- newjob->hints = pcre_study(newjob->pattern, 0, &error);
- if (error != NULL)
- {
- *errptr = PCRS_ERR_STUDY;
- 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;
-
-}
-
-
-/*********************************************************************
- *
- * Function : pcrs_execute_list
- *
- * 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 : 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 : 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_execute_list(pcrs_job *joblist, char *subject, size_t subject_length, char **result, size_t *result_length)
-{
- 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)
- {
- hits = pcrs_execute(job, old, *result_length, &new, result_length);
-
- if (old != subject) free(old);
-
- if (hits < 0)
- {
- return(hits);
- }
- else
- {
- total_hits += hits;
- old = new;
- }
- }
-
- *result = new;
- return(total_hits);
-
-}
-
-
-/*********************************************************************
- *
- * Function : pcrs_execute
- *
- * 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
- * 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 : 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_execute(pcrs_job *job, char *subject, size_t subject_length, char **result, size_t *result_length)
-{
- int offsets[3 * PCRS_MAX_SUBMATCHES],
- offset,
- i, k,
- matches_found,
- submatches,
- max_matches = PCRS_MAX_MATCH_INIT;
- size_t newsize;
- pcrs_match *matches, *dummy;
- char *result_offset;
-
- 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 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++)
- {
- matches[i].submatch_offset[k] = offsets[2 * k];
-
- /* 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;
- }
-
- /* Non-global search or limit reached? */
- if (!(job->flags & PCRS_GLOBAL)) break;
-
- /* Don't loop on empty matches */
- if (offsets[1] == offset)
- if ((size_t)offset < subject_length)
- offset++;
- else
- break;
- /* Go find the next one */
- else
- offset = offsets[1];
- }
- /* Pass pcre error through if (bad) failiure */
- if (submatches < PCRE_ERROR_NOMATCH)
- {
- free(matches);
- return submatches;
- }
- matches_found = i;
-
-
- /*
- * Get memory for the result
- */
- if ((*result = (char *)malloc(newsize)) == NULL) /* must be free()d by caller */
- {
- free(matches);
- return PCRS_ERR_NOMEM;
- }
-
-
- /*
- * Replace
- */
- offset = 0;
- result_offset = *result;
-
- for (i = 0; i < matches_found; i++)
- {
- /* 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++)
- {
- /* ...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.. */
- if (k != job->substitute->backrefs
- /* ..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. */
- memcpy(
- result_offset,
- subject + matches[i].submatch_offset[job->substitute->backref[k]],
- matches[i].submatch_length[job->substitute->backref[k]]
- );
- result_offset += matches[i].submatch_length[job->substitute->backref[k]];
- }
- }
- offset = matches[i].submatch_offset[0] + matches[i].submatch_length[0];
- }
-
- /* Copy the rest. */
- memcpy(result_offset, subject + offset, subject_length - offset);
-
- *result_length = newsize;
- free(matches);
- return matches_found;
-
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef PCRS_H_INCLUDED
-#define PCRS_H_INCLUDED
-
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/pcrs.h,v $
- *
- * Purpose : Header file for pcrs.c
- *
- * Copyright : see pcrs.c
- *
- * Revisions :
- * $Log: pcrs.h,v $
- * Revision 1.10 2002/03/08 13:44:48 oes
- * Hiding internal functions, preventing double inclusion of pcre.h
- *
- * Revision 1.9 2001/08/18 11:35:29 oes
- * - Introduced pcrs_strerror()
- * - added pcrs_execute_list()
- *
- * Revision 1.8 2001/08/15 15:32:50 oes
- * Replaced the hard limit for the maximum number of matches
- * by dynamic reallocation
- *
- * 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
- *
- * Revision 1.4 2001/05/11 01:57:02 rodney
- * Added new file header standard w/RCS control tags.
- *
- * revision 1.3 2001/05/08 02:38:13 rodney
- * Changed C++ "//" style comment to C style comments.
- *
- * revision 1.2 2001/04/30 02:39:24 rodney
- * Made this pcrs.h file conditionally included.
- *
- * revision 1.1 2001/04/16 21:10:38 rodney
- * Initial checkin
- *
- *********************************************************************/
-
-#define PCRS_H_VERSION "$Id: pcrs.h,v 1.10 2002/03/08 13:44:48 oes Exp $"
-\f
-
-#ifndef _PCRE_H
-#include <pcre.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Constants:
- */
-
-#define FALSE 0
-#define TRUE 1
-
-/* 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 */
-
-
-/*
- * 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;
-
-
-/*
- * 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;
-
-
-/* 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;
-
-
-/*
- * 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 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_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: project.h,v $
- * Revision 1.71 2002/05/12 21:39:36 jongfoster
- * - Adding Doxygen-style comments to structures and #defines.
- *
- * Revision 1.70 2002/05/12 16:05:50 jongfoster
- * Fixing ACTION_MASK_ALL to be unsigned long rather than
- * just unsigned int. I don't know if anyone is porting
- * Privoxy to 16-bit platforms, but if so, +limit-connect
- * wouldn't have worked because of this bug.
- *
- * Revision 1.69 2002/05/08 16:00:16 oes
- * Added size member to struct iob, so it can
- * be alloced larger than needed.
- *
- * Revision 1.68 2002/04/26 12:56:00 oes
- * Killed REDIRECT_URL, added USER_MANUAL_URL and HELP_LINK_PREFIX
- *
- * Revision 1.67 2002/04/24 02:12:43 oes
- * - Jon's multiple AF patch:
- * - Make csp->actions_list an array
- * - #define MAX_ACTION_FILES
- * - Moved CGI_PARAM_LEN_MAX (500) here
- *
- * Revision 1.66 2002/04/15 19:06:43 jongfoster
- * Typos
- *
- * Revision 1.65 2002/04/04 00:36:36 gliptak
- * always use pcre for matching
- *
- * Revision 1.64 2002/04/03 22:28:03 gliptak
- * Removed references to gnu_regex
- *
- * Revision 1.63 2002/03/31 17:19:00 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.62 2002/03/26 22:48:49 swa
- * new homepage url
- *
- * Revision 1.61 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.60 2002/03/24 15:52:17 jongfoster
- * Changing CGI URL prefixes for new name
- *
- * Revision 1.59 2002/03/24 15:23:33 jongfoster
- * Name changes
- *
- * Revision 1.58 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.57 2002/03/16 20:28:34 oes
- * Added descriptions to the filters so users will know what they select in the cgi editor
- *
- * Revision 1.56 2002/03/13 20:27:30 oes
- * Fixing bug with CT_TABOO
- *
- * Revision 1.55 2002/03/12 01:42:50 oes
- * Introduced modular filters
- *
- * Revision 1.54 2002/03/09 20:03:52 jongfoster
- * - Making various functions return int rather than size_t.
- * (Undoing a recent change). Since size_t is unsigned on
- * Windows, functions like read_socket that return -1 on
- * error cannot return a size_t.
- *
- * THIS WAS A MAJOR BUG - it caused frequent, unpredictable
- * crashes, and also frequently caused JB to jump to 100%
- * CPU and stay there. (Because it thought it had just
- * read ((unsigned)-1) == 4Gb of data...)
- *
- * - The signature of write_socket has changed, it now simply
- * returns success=0/failure=nonzero.
- *
- * - Trying to get rid of a few warnings --with-debug on
- * Windows, I've introduced a new type "jb_socket". This is
- * used for the socket file descriptors. On Windows, this
- * is SOCKET (a typedef for unsigned). Everywhere else, it's
- * an int. The error value can't be -1 any more, so it's
- * now JB_INVALID_SOCKET (which is -1 on UNIX, and in
- * Windows it maps to the #define INVALID_SOCKET.)
- *
- * - The signature of bind_port has changed.
- *
- * Revision 1.53 2002/03/08 16:48:55 oes
- * Added FEATURE_NO_GIFS and BUILTIN_IMAGE_MIMETYPE
- *
- * Revision 1.52 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.51 2002/03/05 04:52:42 oes
- * Deleted non-errlog debugging code
- *
- * Revision 1.50 2002/03/04 19:32:07 oes
- * Changed default port to 8118
- *
- * Revision 1.49 2002/03/04 18:28:55 oes
- * Deleted PID_FILE_NAME
- *
- * Revision 1.48 2002/03/03 14:50:40 oes
- * Fixed CLF logging: Added ocmd member for client's request to struct http_request
- *
- * Revision 1.47 2002/02/20 23:15:13 jongfoster
- * Parsing functions now handle out-of-memory gracefully by returning
- * an error code.
- *
- * Revision 1.46 2002/01/17 21:06:09 jongfoster
- * Now #defining the URLs of the config interface
- *
- * Minor changes to struct http_request and struct url_spec due to
- * standardizing that struct http_request is used to represent a URL, and
- * struct url_spec is used to represent a URL pattern. (Before, URLs were
- * represented as seperate variables and a partially-filled-in url_spec).
- *
- * Revision 1.45 2002/01/09 14:33:27 oes
- * Added HOSTENT_BUFFER_SIZE
- *
- * Revision 1.44 2001/12/30 14:07:32 steudten
- * - Add signal handling (unix)
- * - Add SIGHUP handler (unix)
- * - Add creation of pidfile (unix)
- * - Add action 'top' in rc file (RH)
- * - Add entry 'SIGNALS' to manpage
- * - Add exit message to logfile (unix)
- *
- * Revision 1.43 2001/11/22 21:57:51 jongfoster
- * Making action_spec->flags into an unsigned long rather than just an
- * unsigned int.
- * Adding ACTION_NO_COOKIE_KEEP
- *
- * Revision 1.42 2001/11/05 21:42:41 steudten
- * Include DBG() macro.
- *
- * Revision 1.41 2001/10/28 19:12:06 jongfoster
- * Adding ijb_toupper()
- *
- * Revision 1.40 2001/10/26 17:40:47 oes
- * Moved ijb_isspace and ijb_tolower to project.h
- * Removed http->user_agent, csp->referrer and csp->accept_types
- *
- * Revision 1.39 2001/10/25 03:45:02 david__schmidt
- * Adding a (void*) cast to freez() because Visual Age C++ won't expand the
- * macro when called with a cast; so moving the cast to the macro def'n
- * seems to both eliminate compiler warnings (on darwin and OS/2, anyway) and
- * doesn't make macro expansion complain. Hope this works for everyone else
- * too...
- *
- * Revision 1.38 2001/10/23 21:19:04 jongfoster
- * New error-handling support: jb_err type and JB_ERR_xxx constants
- * CGI functions now return a jb_err, and their parameters map is const.
- * Support for RUNTIME_FEATUREs to enable/disable config editor
- * Adding a few comments
- *
- * Revision 1.37 2001/10/14 22:14:01 jongfoster
- * Removing name_length field from struct cgi_dispatcher, as this is
- * now calculated at runtime from the "name" field.
- *
- * Revision 1.36 2001/10/10 16:45:15 oes
- * Added LIMIT_CONNECT action and string
- * Fixed HTTP message line termination
- * Added CFORBIDDEN HTTP message
- *
- * Revision 1.35 2001/10/07 18:06:43 oes
- * Added status member to struct http_request
- *
- * Revision 1.34 2001/10/07 15:45:25 oes
- * Added url member to struct http_request and commented all
- * members
- *
- * Added CT_TABOO
- *
- * Added ACTION_DOWNGRADE and ACTION_NO_COMPRESSION
- *
- * Replaced struct client_state members rejected,
- * force, active and toggled_on with "flags" bitmap.
- *
- * Added CSP_FLAG_MODIFIED and CSP_FLAG_CHUNKED
- *
- * Added buffer_limit to struct configuration_spec
- *
- * Revision 1.33 2001/09/20 13:30:08 steudten
- *
- * Make freez() more secure in case of: if (exp) { free(z) ; a=*z }
- * Last case will set z to NULL in free(z) and thats bad..
- *
- * Revision 1.32 2001/09/16 23:02:51 jongfoster
- * Fixing warning
- *
- * Revision 1.31 2001/09/16 13:20:29 jongfoster
- * Rewrite of list library. Now has seperate header and list_entry
- * structures. Also added a large sprinking of assert()s to the list
- * code.
- *
- * Revision 1.30 2001/09/13 23:52:00 jongfoster
- * Support for both static and dynamically generated CGI pages
- *
- * Revision 1.29 2001/09/13 23:29:43 jongfoster
- * Defining FORWARD_SPEC_INITIALIZER
- *
- * Revision 1.28 2001/09/13 23:05:50 jongfoster
- * Changing the string paramater to the header parsers a "const".
- *
- * Revision 1.27 2001/08/05 16:06:20 jongfoster
- * Modifiying "struct map" so that there are now separate header and
- * "map_entry" structures. This means that functions which modify a
- * map no longer need to return a pointer to the modified map.
- * Also, it no longer reverses the order of the entries (which may be
- * important with some advanced template substitutions).
- *
- * Revision 1.26 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.25 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.24 2001/07/25 17:20:27 oes
- * Introduced http->user_agent
- *
- * Revision 1.23 2001/07/18 12:32:23 oes
- * - Added ACTION_STRING_DEANIMATE
- * - moved #define freez from jcc.h to project.h
- *
- * Revision 1.22 2001/07/15 17:51:41 jongfoster
- * Renaming #define STATIC to STATIC_PCRE
- *
- * Revision 1.21 2001/07/13 14:03:19 oes
- * - Reorganized regex header inclusion and #defines to
- * comply to the scheme in configure.in
- * - Added csp->content_type and its CT_* keys
- * - Added ACTION_DEANIMATE
- * - Removed all #ifdef PCRS
- *
- * Revision 1.20 2001/06/29 21:45:41 oes
- * Indentation, CRLF->LF, Tab-> Space
- *
- * Revision 1.19 2001/06/29 13:33:36 oes
- * - Improved comments
- * - Introduced http_request.host_ip_addr_str
- * - Introduced http_response.head_length
- * - Introduced config.my_ip_addr_str, config.my_hostname,
- * config.admin_address and config.proxy_info_url
- * - Removed config.proxy_args_header and config.proxy_args_trailer,
- * renamed config.proxy_args_invocation to config.proxy_args
- * - Removed HTML snipplets and GIFs
- * - Removed logentry from cancelled commit
- *
- * Revision 1.18 2001/06/09 10:57:39 jongfoster
- * Adding definition of BUFFER_SIZE.
- * Changing struct cgi_dispatcher to use "const" strings.
- *
- * Revision 1.17 2001/06/07 23:15:09 jongfoster
- * Merging ACL and forward files into config file.
- * Moving struct gateway members into struct forward_spec
- * Removing config->proxy_args_gateways
- * Cosmetic: Adding a few comments
- *
- * Revision 1.16 2001/06/04 18:31:58 swa
- * files are now prefixed with either `confdir' or `logdir'.
- * `make redhat-dist' replaces both entries confdir and logdir
- * with redhat values
- *
- * Revision 1.15 2001/06/04 11:28:53 swa
- * redirect did not work due to missing /
- *
- * Revision 1.14 2001/06/03 11:03:48 oes
- * Added struct map,
- * added struct http_response,
- * changed struct interceptors to struct cgi_dispatcher,
- * moved HTML stuff to cgi.h
- *
- * Revision 1.13 2001/06/01 20:05:36 jongfoster
- * Support for +image-blocker{}: added ACTION_IMAGE_BLOCKER
- * constant, and removed csp->tinygif.
- *
- * Revision 1.12 2001/06/01 18:49:17 jongfoster
- * Replaced "list_share" with "list" - the tiny memory gain was not
- * worth the extra complexity.
- *
- * Revision 1.11 2001/06/01 10:32:47 oes
- * Added constants for anchoring selection bitmap
- *
- * Revision 1.10 2001/05/31 21:33:53 jongfoster
- * Changes for new actions file, replacing permissionsfile
- * and parts of the config file. Also added support for
- * list_shared.
- *
- * Revision 1.9 2001/05/31 17:32:31 oes
- *
- * - Enhanced domain part globbing with infix and prefix asterisk
- * matching and optional unanchored operation
- *
- * Revision 1.8 2001/05/29 20:09:15 joergs
- * HTTP_REDIRECT_TEMPLATE fixed.
- *
- * Revision 1.7 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/actionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.6 2001/05/27 22:17:04 oes
- *
- * - re_process_buffer no longer writes the modified buffer
- * to the client, which was very ugly. It now returns the
- * buffer, which it is then written by chat.
- *
- * - content_length now adjusts the Content-Length: header
- * for modified documents rather than crunch()ing it.
- * (Length info in csp->content_length, which is 0 for
- * unmodified documents)
- *
- * - For this to work, sed() is called twice when filtering.
- *
- * Revision 1.5 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.4 2001/05/22 18:46:04 oes
- *
- * - Enabled filtering banners by size rather than URL
- * by adding patterns that replace all standard banner
- * sizes with the "Junkbuster" gif to the re_filterfile
- *
- * - Enabled filtering WebBugs by providing a pattern
- * which kills all 1x1 images
- *
- * - Added support for PCRE_UNGREEDY behaviour to pcrs,
- * which is selected by the (nonstandard and therefore
- * capital) letter 'U' in the option string.
- * It causes the quantifiers to be ungreedy by default.
- * Appending a ? turns back to greedy (!).
- *
- * - Added a new interceptor ijb-send-banner, which
- * sends back the "Junkbuster" gif. Without imagelist or
- * MSIE detection support, or if tinygif = 1, or the
- * URL isn't recognized as an imageurl, a lame HTML
- * explanation is sent instead.
- *
- * - Added new feature, which permits blocking remote
- * script redirects and firing back a local redirect
- * to the browser.
- * The feature is conditionally compiled, i.e. it
- * can be disabled with --disable-fast-redirects,
- * plus it must be activated by a "fast-redirects"
- * line in the config file, has its own log level
- * and of course wants to be displayed by show-proxy-args
- * Note: Boy, all the #ifdefs in 1001 locations and
- * all the fumbling with configure.in and acconfig.h
- * were *way* more work than the feature itself :-(
- *
- * - Because a generic redirect template was needed for
- * this, tinygif = 3 now uses the same.
- *
- * - Moved GIFs, and other static HTTP response templates
- * to project.h
- *
- * - Some minor fixes
- *
- * - Removed some >400 CRs again (Jon, you really worked
- * a lot! ;-)
- *
- * Revision 1.3 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "actionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:59:03 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-/* Declare struct FILE for vars and funcs. */
-#include <stdio.h>
-
-/* Need time_t for file_list */
-#include <time.h>
-
-/*
- * Include appropriate regular expression libraries.
- * Note that pcrs and pcre (native) are needed for cgi
- * and are included anyway.
- */
-
-#ifdef STATIC_PCRE
-# include "pcre.h"
-#else
-# include <pcre.h>
-#endif
-
-#ifdef STATIC_PCRS
-# include "pcrs.h"
-#else
-# include <pcrs.h>
-#endif
-
-#ifdef STATIC_PCRE
-# include "pcreposix.h"
-#else
-# include <pcreposix.h>
-#endif
-
-#ifdef AMIGA
-#include "amiga.h"
-#endif /* def AMIGA */
-
-#ifdef _WIN32
-/*
- * I don't want to have to #include all this just for the declaration
- * of SOCKET. However, it looks like we have to...
- */
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _WIN32
-
-typedef SOCKET jb_socket;
-
-#define JB_INVALID_SOCKET INVALID_SOCKET
-
-#else /* ndef _WIN32 */
-
-/**
- * The type used by sockets. On UNIX it's an int. Microsoft decided to
- * make it an unsigned.
- */
-typedef int jb_socket;
-
-/**
- * The error value used for variables of type jb_socket. On UNIX this
- * is -1, however Microsoft decided to make socket handles unsigned, so
- * they use a different value.
- */
-
-#define JB_INVALID_SOCKET (-1)
-
-#endif /* ndef _WIN32 */
-
-
-/**
- * A standard error code. This should be JB_ERR_OK or one of the JB_ERR_xxx
- * series of errors.
- */
-typedef int jb_err;
-
-#define JB_ERR_OK 0 /**< Success, no error */
-#define JB_ERR_MEMORY 1 /**< Out of memory */
-#define JB_ERR_CGI_PARAMS 2 /**< Missing or corrupt CGI parameters */
-#define JB_ERR_FILE 3 /**< Error opening, reading or writing a file */
-#define JB_ERR_PARSE 4 /**< Error parsing file */
-#define JB_ERR_MODIFIED 5 /**< File has been modified outside of the
- CGI actions editor. */
-
-
-/**
- * This macro is used to free a pointer that may be NULL.
- * It also sets the variable to NULL after it's been freed.
- * The paramater should be a simple variable without side effects.
- */
-#define freez(X) { if(X) { free((void*)X); X = NULL ; } }
-
-
-/**
- * Fix a problem with Solaris. There should be no effect on other
- * platforms.
- *
- * Solaris's isspace() is a macro which uses it's argument directly
- * as an array index. Therefore we need to make sure that high-bit
- * characters generate +ve values, and ideally we also want to make
- * the argument match the declared parameter type of "int".
- *
- * Note: Remember to #include <ctype.h> if you use these macros.
- */
-#define ijb_toupper(__X) toupper((int)(unsigned char)(__X))
-#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
-#define ijb_isspace(__X) isspace((int)(unsigned char)(__X))
-
-/**
- * Use for statically allocated buffers if you have no other choice.
- * Remember to check the length of what you write into the buffer
- * - we don't want any buffer overflows!
- */
-#define BUFFER_SIZE 5000
-
-/**
- * Max length of CGI parameters (arbitrary limit).
- */
-#define CGI_PARAM_LEN_MAX 500
-
-/**
- * Buffer size for capturing struct hostent data in the
- * gethostby(name|addr)_r library calls. Since we don't
- * loop over gethostbyname_r, the buffer must be sufficient
- * to accomodate multiple IN A RRs, as used in DNS round robin
- * load balancing. W3C's wwwlib uses 1K, so that should be
- * good enough for us, too.
- */
-#define HOSTENT_BUFFER_SIZE 1024
-
-/**
- * Do not use. Originally this was so that you can
- * say "while (FOREVER) { ...do something... }".
- * However, this gives a warning with some compilers (e.g. VC++).
- * Instead, use "for (;;) { ...do something... }".
- */
-#define FOREVER 1
-
-/**
- * Default IP address to listen on, as a string.
- * Set to "127.0.0.1".
- */
-#define HADDR_DEFAULT "127.0.0.1"
-
-/**
- * Default port to listen on, as a number.
- * Set to 8118.
- */
-#define HADDR_PORT 8118
-
-
-/* Forward def for struct client_state */
-struct configuration_spec;
-
-
-/**
- * Entry in a linked list of strings.
- */
-struct list_entry
-{
- /**
- * 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;
-};
-
-/**
- * A header for a linked list of strings.
- */
-struct list
-{
- /** First entry in the list, or NULL if the list is empty. */
- struct list_entry *first;
-
- /** Last entry in the list, or NULL if the list is empty. */
- struct list_entry *last;
-};
-
-
-/**
- * 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;
-};
-
-
-/**
- * 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 *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) */
-};
-
-
-/**
- * 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
-{
- /** 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
-
-/**
- * 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 *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];
-
- /** Lists of strings for multi-string actions. */
- struct list multi[ACTION_MULTI_COUNT][1];
-};
-
-
-/**
- * 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. */
-
- /**
- * 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.
- */
-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. */
-};
-
-
-/*
- * 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 CSP_FLAG_ACTIVE 0x01
-
-/**
- * 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
-{
- /** 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;
-
- /** Our IP address. I.e. the IP address that the client used to reach us,
- as a string. */
- char *my_ip_addr_str;
-
- /** 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];
-
- /** MIME-Type key, see CT_* above */
- unsigned short int content_type;
-
- /** The "X-Forwarded-For:" header sent by the client */
- char *x_forwarded;
-
- /** Actions files associated with this client */
- struct file_list *actions_list[MAX_ACTION_FILES];
-
- /** pcrs job file. */
- struct file_list *rlist;
-
- /** Length after content modification. */
- size_t content_length;
-
-#ifdef FEATURE_TRUST
-
- /** Trust file. */
- struct file_list *tlist;
-
-#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
-{
- /** 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;
-};
-
-
-/**
- * List of available CGI functions.
- */
-struct cgi_dispatcher
-{
- /** The URL of the CGI, relative to the CGI root. */
- const char * const name;
-
- /** The handler function for the CGI */
- jb_err (* const handler)(struct client_state *csp, struct http_response *rsp, const struct map *parameters);
-
- /** 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.
- * Read-only once the structure has been created.
- */
- void *f;
-
- /**
- * 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
- * problems.
- */
- void (*unloader)(void *);
-
- /**
- * Used internally by sweep(). Do not access from elsewhere.
- */
- int active;
-
- /**
- * 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.
- * 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
- * won't be running).
- */
- struct file_list *next;
-};
-
-
-#ifdef FEATURE_TRUST
-
-/**
- * The format of a trust file when loaded into memory.
- */
-struct block_spec
-{
- 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 */
-
-
-#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];
-
- /** 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;
-};
-
-
-/**
- * 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
-{
- 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. */
-};
-
-
-#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
-{
- unsigned long addr; /**< The IP address as an integer. */
- unsigned long mask; /**< The network mask as an integer. */
- unsigned long port; /**< The port number. */
-};
-
-/**
- * An access control list (ACL) entry.
- *
- * This is a linked list.
- */
-struct access_control_list
-{
- 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 FEATURE_ACL */
-
-
-/** 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
-{
- /** 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];
-
- /** 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;
-};
-
-/** Calculates the number of elements in an array, using sizeof. */
-#define SZ(X) (sizeof(X) / sizeof(*X))
-
-#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_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char ssplit_rcs[] = "$Id: ssplit.c,v 1.5 2002/03/24 13:25:43 swa Exp $";
-/*********************************************************************
- *
- * 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
- * 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: ssplit.c,v $
- * Revision 1.5 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.4 2001/11/13 00:16:38 jongfoster
- * Replacing references to malloc.h with the standard stdlib.h
- * (See ANSI or K&R 2nd Ed)
- *
- * Revision 1.3 2001/05/29 08:54:25 jongfoster
- * Rewrote the innards of ssplit() to be easier to understand,
- * faster, and to use less memory. Didn't change the interface
- * except to give the parameters meaningful names.
- *
- * Revision 1.2 2001/05/17 23:01:01 oes
- * - Cleaned CRLF's from the sources and related files
- *
- * Revision 1.1.1.1 2001/05/15 13:59:04 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "ssplit.h"
-#include "miscutil.h"
-
-const char ssplit_h_rcs[] = SSPLIT_H_VERSION;
-
-/* Define this for lots of debugging information to stdout */
-#undef SSPLIT_VERBOSE
-/* #define SSPLIT_VERBOSE 1 */
-
-
-/*********************************************************************
- *
- * Function : ssplit
- *
- * Description : Split a string using delimiters in `delim'. Results
- * go into `vec'.
- *
- * Parameters :
- * 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 *str, const char *delim, char *vec[], int vec_len,
- int dont_save_empty_fields, int ignore_leading)
-{
- unsigned char is_delim[256];
- unsigned char char_type;
- int vec_count = 0;
-
- if (!str)
- {
- return(-1);
- }
-
-
- /* Build is_delim array */
-
- memset(is_delim, '\0', sizeof(is_delim));
-
- if (!delim)
- {
- delim = " \t"; /* default field separators */
- }
-
- while (*delim)
- {
- is_delim[(unsigned)(unsigned char)*delim++] = 1; /* separator */
- }
-
- is_delim[(unsigned)(unsigned char)'\0'] = 2; /* terminator */
- is_delim[(unsigned)(unsigned char)'\n'] = 2; /* terminator */
-
-
- /* Parse string */
-
- if (ignore_leading)
- {
- /* skip leading separators */
- while (is_delim[(unsigned)(unsigned char)*str] == 1)
- {
- str++;
- }
- }
-
- /* 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;
- }
-
- while ((char_type = is_delim[(unsigned)(unsigned char)*str]) != 2)
- {
- if (char_type == 1)
- {
- /* the char is a separator */
-
- /* null terminate the substring */
- *str++ = '\0';
-
- /* 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;
- }
- }
- else
- {
- str++;
- }
- }
- *str = '\0'; /* null terminate the substring */
-
-#ifdef SSPLIT_VERBOSE
- {
- int i;
- printf("dump %d strings\n", vec_count);
- for (i = 0; i < vec_count; i++)
- {
- printf("%d '%s'\n", i, vec[i]);
- }
- }
-#endif /* def SSPLIT_VERBOSE */
-
- return(vec_count);
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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
- * 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: ssplit.h,v $
- * Revision 1.4 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.3 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.2 2001/05/29 08:54:25 jongfoster
- * Rewrote the innards of ssplit() to be easier to understand,
- * faster, and to use less memory. Didn't change the interface
- * except to give the parameters meaningful names.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:04 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-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[];
-extern const char ssplit_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef SSPLIT_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.9 2002/04/04 00:36:36 gliptak Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/urlmatch.c,v $
- *
- * Purpose : Declares functions to match URLs against URL
- * patterns.
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: urlmatch.c,v $
- * Revision 1.9 2002/04/04 00:36:36 gliptak
- * always use pcre for matching
- *
- * Revision 1.8 2002/04/03 23:32:47 jongfoster
- * Fixing memory leak on error
- *
- * Revision 1.7 2002/03/26 22:29:55 swa
- * we have a new homepage!
- *
- * Revision 1.6 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.5 2002/03/13 00:27:05 jongfoster
- * Killing warnings
- *
- * Revision 1.4 2002/03/07 03:46:17 oes
- * Fixed compiler warnings
- *
- * Revision 1.3 2002/03/03 14:51:11 oes
- * Fixed CLF logging: Added ocmd member for client's request to struct http_request
- *
- * Revision 1.2 2002/01/21 00:14:09 jongfoster
- * Correcting comment style
- * Fixing an uninitialized memory bug in create_url_spec()
- *
- * Revision 1.1 2002/01/17 20:53:46 jongfoster
- * Moving all our URL and URL pattern parsing code to the same file - it
- * was scattered around in filters.c, loaders.c and parsers.c.
- *
- * Providing a single, simple url_match(pattern,url) function - rather than
- * the 3-line match routine which was repeated all over the place.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Providing parse_http_url() so that URLs can be parsed without faking a
- * HTTP request line for parse_http_request() or repeating the parsing
- * code (both of which were techniques that were actually in use).
- *
- * Standardizing that struct http_request is used to represent a URL, and
- * struct url_spec is used to represent a URL pattern. (Before, URLs were
- * represented as seperate variables and a partially-filled-in url_spec).
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#ifndef _WIN32
-#include <stdio.h>
-#include <sys/types.h>
-#endif
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <assert.h>
-#include <string.h>
-
-#if !defined(_WIN32) && !defined(__OS2__)
-#include <unistd.h>
-#endif
-
-#include "project.h"
-#include "urlmatch.h"
-#include "ssplit.h"
-#include "miscutil.h"
-#include "errlog.h"
-
-const char urlmatch_h_rcs[] = URLMATCH_H_VERSION;
-
-
-/*********************************************************************
- *
- * Function : free_http_request
- *
- * Description : Freez a http_request structure
- *
- * Parameters :
- * 1 : http = points to a http_request structure to free
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_http_request(struct http_request *http)
-{
- assert(http);
-
- freez(http->cmd);
- freez(http->ocmd);
- freez(http->gpc);
- freez(http->host);
- freez(http->url);
- freez(http->hostport);
- freez(http->path);
- freez(http->ver);
- freez(http->host_ip_addr_str);
- freez(http->dbuffer);
- freez(http->dvec);
- http->dcount = 0;
-}
-
-
-/*********************************************************************
- *
- * Function : parse_http_url
- *
- * Description : Parse out the host and port from the URL. Find the
- * hostname & path, port (if ':'), and/or password (if '@')
- *
- * Parameters :
- * 1 : url = URL (or is it URI?) to break down
- * 2 : http = pointer to the http structure to hold elements.
- * Will be zeroed before use. Note that this
- * function sets the http->gpc and http->ver
- * members to NULL.
- * 3 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out of memory
- * JB_ERR_CGI_PARAMS on malformed command/URL
- * or >100 domains deep.
- *
- *********************************************************************/
-jb_err parse_http_url(const char * url,
- struct http_request *http,
- struct client_state *csp)
-{
- /*
- * Zero out the results structure
- */
- memset(http, '\0', sizeof(*http));
-
-
- /*
- * Save our initial URL
- */
- http->url = strdup(url);
- if (http->url == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
-
- /*
- * Split URL into protocol,hostport,path.
- */
- {
- char *buf;
- char *url_noproto;
- char *url_path;
-
- buf = strdup(url);
- if (buf == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- /* Find the start of the URL in our scratch space */
- url_noproto = buf;
- if (strncmpic(url_noproto, "http://", 7) == 0)
- {
- url_noproto += 7;
- http->ssl = 0;
- }
- else if (strncmpic(url_noproto, "https://", 8) == 0)
- {
- url_noproto += 8;
- http->ssl = 1;
- }
- else
- {
- http->ssl = 0;
- }
-
- url_path = strchr(url_noproto, '/');
- if (url_path != NULL)
- {
- /*
- * Got a path.
- *
- * NOTE: The following line ignores the path for HTTPS URLS.
- * This means that you get consistent behaviour if you type a
- * https URL in and it's parsed by the function. (When the
- * URL is actually retrieved, SSL hides the path part).
- */
- http->path = strdup(http->ssl ? "/" : url_path);
- *url_path = '\0';
- http->hostport = strdup(url_noproto);
- }
- else
- {
- /*
- * Repair broken HTTP requests that don't contain a path,
- * or CONNECT requests
- */
- http->path = strdup("/");
- http->hostport = strdup(url_noproto);
- }
-
- free(buf);
-
- if ( (http->path == NULL)
- || (http->hostport == NULL))
- {
- free(buf);
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
- }
-
-
- /*
- * Split hostport into user/password (ignored), host, port.
- */
- {
- char *buf;
- char *host;
- char *port;
-
- buf = strdup(http->hostport);
- if (buf == NULL)
- {
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
-
- /* check if url contains username and/or password */
- host = strchr(buf, '@');
- if (host != NULL)
- {
- /* Contains username/password, skip it and the @ sign. */
- host++;
- }
- else
- {
- /* No username or password. */
- host = buf;
- }
-
- /* check if url contains port */
- port = strchr(host, ':');
- if (port != NULL)
- {
- /* Contains port */
- /* Terminate hostname and point to start of port string */
- *port++ = '\0';
- http->port = atoi(port);
- }
- else
- {
- /* No port specified. */
- http->port = (http->ssl ? 143 : 80);
- }
-
- http->host = strdup(host);
-
- free(buf);
-
- if (http->host == NULL)
- {
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
- }
-
-
- /*
- * Split domain name so we can compare it against wildcards
- */
- {
- char *vec[BUFFER_SIZE];
- size_t size;
- char *p;
-
- http->dbuffer = strdup(http->host);
- if (NULL == http->dbuffer)
- {
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
-
- /* map to lower case */
- for (p = http->dbuffer; *p ; p++)
- {
- *p = tolower((int)(unsigned char)*p);
- }
-
- /* split the domain name into components */
- http->dcount = ssplit(http->dbuffer, ".", vec, SZ(vec), 1, 1);
-
- if (http->dcount <= 0)
- {
- /*
- * Error: More than SZ(vec) components in domain
- * or: no components in domain
- */
- free_http_request(http);
- return JB_ERR_PARSE;
- }
-
- /* save a copy of the pointers in dvec */
- size = http->dcount * sizeof(*http->dvec);
-
- http->dvec = (char **)malloc(size);
- if (NULL == http->dvec)
- {
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
-
- memcpy(http->dvec, vec, size);
- }
-
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : parse_http_request
- *
- * Description : Parse out the host and port from the URL. Find the
- * hostname & path, port (if ':'), and/or password (if '@')
- *
- * Parameters :
- * 1 : req = HTTP request line to break down
- * 2 : http = pointer to the http structure to hold elements
- * 3 : csp = Current client state (buffers, headers, etc...)
- *
- * Returns : JB_ERR_OK on success
- * JB_ERR_MEMORY on out of memory
- * JB_ERR_CGI_PARAMS on malformed command/URL
- * or >100 domains deep.
- *
- *********************************************************************/
-jb_err parse_http_request(const char *req,
- struct http_request *http,
- struct client_state *csp)
-{
- char *buf;
- char *v[10];
- int n;
- jb_err err;
- int is_connect = 0;
-
- memset(http, '\0', sizeof(*http));
-
- buf = strdup(req);
- if (buf == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- n = ssplit(buf, " \r\n", v, SZ(v), 1, 1);
- if (n != 3)
- {
- free(buf);
- return JB_ERR_PARSE;
- }
-
- /* this could be a CONNECT request */
- if (strcmpic(v[0], "connect") == 0)
- {
- /* Secure */
- is_connect = 1;
- }
- /* or it could be any other basic HTTP request type */
- else if ((0 == strcmpic(v[0], "get"))
- || (0 == strcmpic(v[0], "head"))
- || (0 == strcmpic(v[0], "post"))
- || (0 == strcmpic(v[0], "put"))
- || (0 == strcmpic(v[0], "delete"))
-
- /* or a webDAV extension (RFC2518) */
- || (0 == strcmpic(v[0], "propfind"))
- || (0 == strcmpic(v[0], "proppatch"))
- || (0 == strcmpic(v[0], "move"))
- || (0 == strcmpic(v[0], "copy"))
- || (0 == strcmpic(v[0], "mkcol"))
- || (0 == strcmpic(v[0], "lock"))
- || (0 == strcmpic(v[0], "unlock"))
- )
- {
- /* Normal */
- is_connect = 0;
- }
- else
- {
- /* Unknown HTTP method */
- free(buf);
- return JB_ERR_PARSE;
- }
-
- err = parse_http_url(v[1], http, csp);
- if (err)
- {
- free(buf);
- return err;
- }
-
- /*
- * Copy the details into the structure
- */
- http->ssl = is_connect;
- http->cmd = strdup(req);
- http->gpc = strdup(v[0]);
- http->ver = strdup(v[2]);
-
- if ( (http->cmd == NULL)
- || (http->gpc == NULL)
- || (http->ver == NULL) )
- {
- free(buf);
- free_http_request(http);
- return JB_ERR_MEMORY;
- }
-
- return JB_ERR_OK;
-}
-
-
-/*********************************************************************
- *
- * Function : simple_domaincmp
- *
- * Description : Domain-wise Compare fqdn's. The comparison is
- * both left- and right-anchored. The individual
- * domain names are compared with simplematch().
- * This is only used by domain_match.
- *
- * Parameters :
- * 1 : pv = array of patterns to compare
- * 2 : fv = array of domain components to compare
- * 3 : len = length of the arrays (both arrays are the
- * same length - if they weren't, it couldn't
- * possibly be a match).
- *
- * Returns : 0 => domains are equivalent, else no match.
- *
- *********************************************************************/
-static int simple_domaincmp(char **pv, char **fv, int len)
-{
- int n;
-
- for (n = 0; n < len; n++)
- {
- if (simplematch(pv[n], fv[n]))
- {
- return 1;
- }
- }
-
- return 0;
-
-}
-
-
-/*********************************************************************
- *
- * Function : domain_match
- *
- * Description : Domain-wise Compare fqdn's. Governed by the bimap in
- * pattern->unachored, the comparison is un-, left-,
- * right-anchored, or both.
- * The individual domain names are compared with
- * simplematch().
- *
- * Parameters :
- * 1 : pattern = a domain that may contain a '*' as a wildcard.
- * 2 : fqdn = domain name against which the patterns are compared.
- *
- * Returns : 0 => domains are equivalent, else no match.
- *
- *********************************************************************/
-static int domain_match(const struct url_spec *pattern, const struct http_request *fqdn)
-{
- char **pv, **fv; /* vectors */
- int plen, flen;
- int unanchored = pattern->unanchored & (ANCHOR_RIGHT | ANCHOR_LEFT);
-
- plen = pattern->dcount;
- flen = fqdn->dcount;
-
- if (flen < plen)
- {
- /* fqdn is too short to match this pattern */
- return 1;
- }
-
- pv = pattern->dvec;
- fv = fqdn->dvec;
-
- if (unanchored == ANCHOR_LEFT)
- {
- /*
- * Right anchored.
- *
- * Convert this into a fully anchored pattern with
- * the fqdn and pattern the same length
- */
- fv += (flen - plen); /* flen - plen >= 0 due to check above */
- return simple_domaincmp(pv, fv, plen);
- }
- else if (unanchored == 0)
- {
- /* Fully anchored, check length */
- if (flen != plen)
- {
- return 1;
- }
- return simple_domaincmp(pv, fv, plen);
- }
- else if (unanchored == ANCHOR_RIGHT)
- {
- /* Left anchored, ignore all extra in fqdn */
- return simple_domaincmp(pv, fv, plen);
- }
- else
- {
- /* Unanchored */
- int n;
- int maxn = flen - plen;
- for (n = 0; n <= maxn; n++)
- {
- if (!simple_domaincmp(pv, fv, plen))
- {
- return 0;
- }
- /*
- * Doesn't match from start of fqdn
- * Try skipping first part of fqdn
- */
- fv++;
- }
- return 1;
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : create_url_spec
- *
- * Description : Creates a "url_spec" structure from a string.
- * When finished, free with unload_url().
- *
- * Parameters :
- * 1 : url = Target url_spec to be filled in. Will be
- * zeroed before use.
- * 2 : buf = Source pattern, null terminated. NOTE: The
- * contents of this buffer are destroyed by this
- * function. If this function succeeds, the
- * buffer is copied to url->spec. If this
- * function fails, the contents of the buffer
- * are lost forever.
- *
- * Returns : JB_ERR_OK - Success
- * JB_ERR_MEMORY - Out of memory
- * JB_ERR_PARSE - Cannot parse regex (Detailed message
- * written to system log)
- *
- *********************************************************************/
-jb_err create_url_spec(struct url_spec * url, const char * buf)
-{
- char *p;
-
- assert(url);
- assert(buf);
-
- /* Zero memory */
- memset(url, '\0', sizeof(*url));
-
- /* save a copy of the orignal specification */
- if ((url->spec = strdup(buf)) == NULL)
- {
- return JB_ERR_MEMORY;
- }
-
- if ((p = strchr(buf, '/')) != NULL)
- {
- if (NULL == (url->path = strdup(p)))
- {
- freez(url->spec);
- return JB_ERR_MEMORY;
- }
- url->pathlen = strlen(url->path);
- *p = '\0';
- }
- else
- {
- url->path = NULL;
- url->pathlen = 0;
- }
- if (url->path)
- {
- int errcode;
- char rebuf[BUFFER_SIZE];
-
- if (NULL == (url->preg = zalloc(sizeof(*url->preg))))
- {
- freez(url->spec);
- freez(url->path);
- return JB_ERR_MEMORY;
- }
-
- sprintf(rebuf, "^(%s)", url->path);
-
- errcode = regcomp(url->preg, rebuf,
- (REG_EXTENDED|REG_NOSUB|REG_ICASE));
- if (errcode)
- {
- size_t errlen = regerror(errcode,
- url->preg, rebuf, sizeof(rebuf));
-
- if (errlen > (sizeof(rebuf) - (size_t)1))
- {
- errlen = sizeof(rebuf) - (size_t)1;
- }
- rebuf[errlen] = '\0';
-
- log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
- url->spec, rebuf);
-
- freez(url->spec);
- freez(url->path);
- regfree(url->preg);
- freez(url->preg);
-
- return JB_ERR_PARSE;
- }
- }
- if ((p = strchr(buf, ':')) == NULL)
- {
- url->port = 0;
- }
- else
- {
- *p++ = '\0';
- url->port = atoi(p);
- }
-
- if (buf[0] != '\0')
- {
- char *v[150];
- size_t size;
-
- /* Parse domain part */
- if (buf[strlen(buf) - 1] == '.')
- {
- url->unanchored |= ANCHOR_RIGHT;
- }
- if (buf[0] == '.')
- {
- url->unanchored |= ANCHOR_LEFT;
- }
-
- /* split domain into components */
-
- url->dbuffer = strdup(buf);
- if (NULL == url->dbuffer)
- {
- freez(url->spec);
- freez(url->path);
- regfree(url->preg);
- freez(url->preg);
- return JB_ERR_MEMORY;
- }
-
- /* map to lower case */
- for (p = url->dbuffer; *p ; p++)
- {
- *p = tolower((int)(unsigned char)*p);
- }
-
- /* split the domain name into components */
- url->dcount = ssplit(url->dbuffer, ".", v, SZ(v), 1, 1);
-
- if (url->dcount < 0)
- {
- freez(url->spec);
- freez(url->path);
- regfree(url->preg);
- freez(url->preg);
- freez(url->dbuffer);
- url->dcount = 0;
- return JB_ERR_MEMORY;
- }
- else if (url->dcount != 0)
- {
-
- /* save a copy of the pointers in dvec */
- size = url->dcount * sizeof(*url->dvec);
-
- url->dvec = (char **)malloc(size);
- if (NULL == url->dvec)
- {
- freez(url->spec);
- freez(url->path);
- regfree(url->preg);
- freez(url->preg);
- freez(url->dbuffer);
- url->dcount = 0;
- return JB_ERR_MEMORY;
- }
-
- memcpy(url->dvec, v, size);
- }
- }
-
- return JB_ERR_OK;
-
-}
-
-
-/*********************************************************************
- *
- * Function : free_url_spec
- *
- * Description : Called from the "unloaders". Freez the url
- * structure elements.
- *
- * Parameters :
- * 1 : url = pointer to a url_spec structure.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void free_url_spec(struct url_spec *url)
-{
- if (url == NULL) return;
-
- freez(url->spec);
- freez(url->dbuffer);
- freez(url->dvec);
- freez(url->path);
- if (url->preg)
- {
- regfree(url->preg);
- freez(url->preg);
- }
-}
-
-
-/*********************************************************************
- *
- * Function : url_match
- *
- * Description : Compare a URL against a URL pattern.
- *
- * Parameters :
- * 1 : pattern = a URL pattern
- * 2 : url = URL to match
- *
- * Returns : 0 iff the URL matches the pattern, else nonzero.
- *
- *********************************************************************/
-int url_match(const struct url_spec *pattern,
- const struct http_request *url)
-{
- return ((pattern->port == 0) || (pattern->port == url->port))
- && ((pattern->dbuffer == NULL) || (domain_match(pattern, url) == 0))
- && ((pattern->path == NULL) ||
- (regexec(pattern->preg, url->path, 0, NULL, 0) == 0)
- );
-}
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#ifndef URLMATCH_H_INCLUDED
-#define URLMATCH_H_INCLUDED
-#define URLMATCH_H_VERSION "$Id: urlmatch.h,v 1.2 2002/03/24 13:25:43 swa Exp $"
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/urlmatch.h,v $
- *
- * Purpose : Declares functions to match URLs against URL
- * patterns.
- *
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: urlmatch.h,v $
- * Revision 1.2 2002/03/24 13:25:43 swa
- * name change related issues
- *
- * Revision 1.1 2002/01/17 20:53:46 jongfoster
- * Moving all our URL and URL pattern parsing code to the same file - it
- * was scattered around in filters.c, loaders.c and parsers.c.
- *
- * Providing a single, simple url_match(pattern,url) function - rather than
- * the 3-line match routine which was repeated all over the place.
- *
- * Renaming free_url to free_url_spec, since it frees a struct url_spec.
- *
- * Providing parse_http_url() so that URLs can be parsed without faking a
- * HTTP request line for parse_http_request() or repeating the parsing
- * code (both of which were techniques that were actually in use).
- *
- * Standardizing that struct http_request is used to represent a URL, and
- * struct url_spec is used to represent a URL pattern. (Before, URLs were
- * represented as seperate variables and a partially-filled-in url_spec).
- *
- *
- *********************************************************************/
-\f
-
-#include "project.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void free_http_request(struct http_request *http);
-extern jb_err parse_http_request(const char *req,
- struct http_request *http,
- struct client_state *csp);
-extern jb_err parse_http_url(const char * url,
- struct http_request *http,
- struct client_state *csp);
-
-extern int url_match(const struct url_spec *pattern,
- const struct http_request *url);
-
-extern jb_err create_url_spec(struct url_spec * url, const char * buf);
-extern void free_url_spec(struct url_spec *url);
-
-
-/* Revision control strings from this header and associated .c file */
-extern const char urlmatch_rcs[];
-extern const char urlmatch_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef URLMATCH_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char w32log_rcs[] = "$Id: w32log.c,v 1.24 2002/03/31 17:19:00 jongfoster Exp $";
-/*********************************************************************
- *
- * 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-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: w32log.c,v $
- * Revision 1.24 2002/03/31 17:19:00 jongfoster
- * Win32 only: Enabling STRICT to fix a VC++ compile warning.
- *
- * Revision 1.23 2002/03/26 22:57:10 jongfoster
- * Web server name should begin www.
- *
- * Revision 1.22 2002/03/24 12:48:23 jongfoster
- * Fixing doc links
- *
- * Revision 1.21 2002/03/24 12:07:35 jongfoster
- * Consistern name for filters file
- *
- * Revision 1.20 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.19 2002/01/17 21:04:17 jongfoster
- * Replacing hard references to the URL of the config interface
- * with #defines from project.h
- *
- * Revision 1.18 2001/11/30 23:37:24 jongfoster
- * Renaming the Win32 config file to config.txt - this is almost the
- * same as the corresponding UNIX name "config"
- *
- * Revision 1.17 2001/11/16 00:46:31 jongfoster
- * Fixing compiler warnings
- *
- * Revision 1.16 2001/08/01 19:58:12 jongfoster
- * Fixing documentation filenames in help menu, and making status
- * option work without needing the "Junkbuster Status.URL" file.
- *
- * Revision 1.15 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.14 2001/07/29 18:47:05 jongfoster
- * Adding missing #include "loadcfg.h"
- *
- * Revision 1.13 2001/07/19 19:15:14 haroon
- * - Added a FIXME for EditFile but didn't fix :-)
- *
- * Revision 1.12 2001/07/13 14:04:59 oes
- * Removed all #ifdef PCRS
- *
- * Revision 1.11 2001/06/07 23:08:12 jongfoster
- * Forward and ACL edit options removed.
- *
- * Revision 1.10 2001/05/31 21:37:11 jongfoster
- * GUI changes to rename "permissions file" to "actions file".
- *
- * Revision 1.9 2001/05/31 17:33:13 oes
- *
- * CRLF -> LF
- *
- * Revision 1.8 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.7 2001/05/26 01:26:34 jongfoster
- * New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
- * This #define cannot be set from ./configure - there's no point, it
- * doesn't work yet. See feature request # 425722
- *
- * Revision 1.6 2001/05/26 00:31:30 jongfoster
- * Fixing compiler warning about comparing signed/unsigned.
- *
- * Revision 1.5 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.4 2001/05/22 18:56:28 oes
- * CRLF -> LF
- *
- * Revision 1.3 2001/05/20 15:07:54 jongfoster
- * File is now ignored if _WIN_CONSOLE is defined.
- *
- * Revision 1.2 2001/05/20 01:21:20 jongfoster
- * Version 2.9.4 checkin.
- * - Merged popupfile and cookiefile, and added control over PCRS
- * filtering, in new "permissionsfile".
- * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
- * file error you now get a message box (in the Win32 GUI) rather
- * than the program exiting with no explanation.
- * - Made killpopup use the PCRS MIME-type checking and HTTP-header
- * skipping.
- * - Removed tabs from "config"
- * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
- * - Bumped up version number.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:07 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-#include <richedit.h>
-
-#include "project.h"
-#include "w32log.h"
-#include "w32taskbar.h"
-#include "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;
-
-#ifdef __MINGW32__
-#include "cygwin.h"
-const char cygwin_h_rcs[] = CYGWIN_H_VERSION;
-#endif
-
-const char w32log_h_rcs[] = W32LOG_H_VERSION;
-
-#ifndef _WIN_CONSOLE /* entire file */
-
-/*
- * Timers and the various durations
- */
-#define TIMER_ANIM_ID 1
-#define TIMER_ANIM_TIME 100
-#define TIMER_ANIMSTOP_ID 2
-#define TIMER_ANIMSTOP_TIME 1000
-#define TIMER_CLIPBUFFER_ID 3
-#define TIMER_CLIPBUFFER_TIME 1000
-#define TIMER_CLIPBUFFER_FORCE_ID 4
-#define TIMER_CLIPBUFFER_FORCE_TIME 5000
-
-/*
- * Styles of text that can be output
- */
-#define STYLE_NONE 0
-#define STYLE_HIGHLIGHT 1
-#define STYLE_LINK 2
-#define STYLE_HEADER 3
-
-/*
- * Number of frames of animation in tray activity sequence
- */
-#define ANIM_FRAMES 8
-
-#define DEFAULT_MAX_BUFFER_LINES 200
-#define DEFAULT_LOG_FONT_NAME "MS Sans Serif"
-#define DEFAULT_LOG_FONT_SIZE 8
-
-/*
- * These values affect the way the log window behaves, they should be read
- * from a file but for the moment, they are hardcoded here. Some options are
- * configurable through the UI.
- */
-
-/* Indicates whether task bar shows activity animation */
-BOOL g_bShowActivityAnimation = 1;
-
-/* Indicates if the log window appears on the task bar */
-BOOL g_bShowOnTaskBar = 0;
-
-/* Indicates whether closing the log window really just hides it */
-BOOL g_bCloseHidesWindow = 1;
-
-/* Indicates if messages are logged at all */
-BOOL g_bLogMessages = 1;
-
-/* Indicates whether log messages are highlighted */
-BOOL g_bHighlightMessages = 1;
-
-/* Indicates if buffer is limited in size */
-BOOL g_bLimitBufferSize = 1;
-
-/* Maximum number of lines allowed in buffer when limited */
-int g_nMaxBufferLines = DEFAULT_MAX_BUFFER_LINES;
-
-/* Font to use */
-char g_szFontFaceName[255] = DEFAULT_LOG_FONT_NAME;
-
-/* Size of font to use */
-int g_nFontSize = DEFAULT_LOG_FONT_SIZE;
-
-
-/* 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]*"
-
-/*
- * Regular expressions that are used to perform highlight in the log window
- */
-static struct _Pattern
-{
- const char *str;
- int style;
- regex_t buffer;
-} patterns_to_highlight[] =
-{
- /* url headers */
- { RE_URL, STYLE_LINK },
-/* { "[a-zA-Z0-9]+\\.[a-zA-Z0-9]+\\.[a-zA-Z0-9]+\\.[^ \n\r]*", STYLE_LINK }, */
- /* interesting text to highlight */
- { "crunch!", STYLE_HIGHLIGHT },
- /* http headers */
- { "referer:", STYLE_HEADER },
- { "proxy-connection:", STYLE_HEADER },
- { "proxy-agent:", STYLE_HEADER },
- { "user-agent:", STYLE_HEADER },
- { "host:", STYLE_HEADER },
- { "accept:", STYLE_HEADER },
- { "accept-encoding:", STYLE_HEADER },
- { "accept-language:", STYLE_HEADER },
- { "accept-charset:", STYLE_HEADER },
- { "accept-ranges:", STYLE_HEADER },
- { "date:", STYLE_HEADER },
- { "cache-control:", STYLE_HEADER },
- { "cache-last-checked:", STYLE_HEADER },
- { "connection:", STYLE_HEADER },
- { "content-type", STYLE_HEADER },
- { "content-length", STYLE_HEADER },
- { "cookie", STYLE_HEADER },
- { "last-modified:", STYLE_HEADER },
- { "pragma:", STYLE_HEADER },
- { "server:", STYLE_HEADER },
- { "etag:", STYLE_HEADER },
- { "expires:", STYLE_HEADER },
- { "warning:", STYLE_HEADER },
- /* this is the terminator statement - do not delete! */
- { NULL, STYLE_NONE }
-};
-
-/*
- * Public variables
- */
-HWND g_hwndLogFrame;
-
-/*
- * Private variables
- */
-static CRITICAL_SECTION g_criticalsection;
-static HWND g_hwndTray;
-static HWND g_hwndLogBox;
-static WNDPROC g_fnLogBox;
-static HICON g_hiconAnim[ANIM_FRAMES];
-static HICON g_hiconIdle;
-static HICON g_hiconApp;
-static int g_nAnimFrame;
-static BOOL g_bClipPending = FALSE;
-static int g_nRichEditVersion = 0;
-
-/*
- * Private functions
- */
-static HWND CreateLogWindow(HINSTANCE hInstance, int nCmdShow);
-static HWND CreateHiddenLogOwnerWindow(HINSTANCE hInstance);
-static LRESULT CALLBACK LogWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static LRESULT CALLBACK LogOwnerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static LRESULT CALLBACK LogRichEditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static BOOL InitRichEdit(void);
-static void LogClipBuffer(void);
-static void LogCreatePatternMatchingBuffers(void);
-static void LogDestroyPatternMatchingBuffers(void);
-static int LogPutStringNoMatch(const char *pszText, int style);
-
-
-/*********************************************************************
- *
- * Function : InitLogWindow
- *
- * Description : Initialise the log window.
- *
- * Parameters : None
- *
- * Returns : Always TRUE (there should be error checking on the resources).
- *
- *********************************************************************/
-BOOL InitLogWindow(void)
-{
- int i;
-
- /* Load the icons */
- g_hiconIdle = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IDLE));
- for (i = 0; i < ANIM_FRAMES; i++)
- {
- g_hiconAnim[i] = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ANIMATED1 + i));
- }
- 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, "Privoxy");
-
- /* Create pattern matching buffers (for highlighting */
- LogCreatePatternMatchingBuffers();
-
- /* Create a critical section to protect multi-threaded access to certain things */
- InitializeCriticalSection(&g_criticalsection);
-
- return TRUE;
-
-}
-
-
-/*********************************************************************
- *
- * Function : TermLogWindow
- *
- * Description : Cleanup the logwindow.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void TermLogWindow(void)
-{
- int i;
-
- LogDestroyPatternMatchingBuffers();
-
- TrayDeleteIcon(g_hwndTray, 1);
- DeleteObject(g_hiconApp);
- DeleteObject(g_hiconIdle);
- for (i = 0; i < ANIM_FRAMES; i++)
- {
- DeleteObject(g_hiconAnim[i]);
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogCreatePatternMatchingBuffers
- *
- * Description : Compile the pattern matching buffers.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void LogCreatePatternMatchingBuffers(void)
-{
- 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);
- }
-}
-
-
-/*********************************************************************
- *
- * Function : LogDestroyPatternMatchingBuffers
- *
- * Description : Free up the pattern matching buffers.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void LogDestroyPatternMatchingBuffers(void)
-{
- int i;
- for (i = 0; patterns_to_highlight[i].str != NULL; i++)
- {
- regfree(&patterns_to_highlight[i].buffer);
- }
-}
-
-
-/*********************************************************************
- *
- * Function : LogGetURLUnderCursor
- *
- * Description : Returns the URL from under the cursor (remember to free it!).
- *
- * Parameters : None
- *
- * Returns : NULL or a pointer to an URL string.
- *
- *********************************************************************/
-char *LogGetURLUnderCursor(void)
-{
- char *szResult = NULL;
- regex_t re;
- POINT ptCursor;
- POINTL ptl;
- DWORD nPos;
- DWORD nWordStart = 0;
- DWORD nWordEnd = 0;
-
- regcomp(&re, RE_URL, REG_ICASE);
-
- /* Get the position of the cursor over the text window */
- GetCursorPos(&ptCursor);
- ScreenToClient(g_hwndLogBox, &ptCursor);
- ptl.x = ptCursor.x;
- ptl.y = ptCursor.y;
-
- /* Search backwards and fowards to obtain the word that is highlighted */
- nPos = LOWORD(SendMessage(g_hwndLogBox, EM_CHARFROMPOS, 0, (LPARAM) &ptl));
- nWordStart = SendMessage(g_hwndLogBox, EM_FINDWORDBREAK, WB_LEFT, nPos);
- nWordEnd = SendMessage(g_hwndLogBox, EM_FINDWORDBREAK, WB_RIGHTBREAK, nPos);
-
- /* Compare the string to the pattern */
- if (nWordEnd > nWordStart)
- {
- TEXTRANGE range;
- regmatch_t match;
-
- range.chrg.cpMin = nWordStart;
- range.chrg.cpMax = nWordEnd;
- range.lpstrText = (LPSTR)zalloc(nWordEnd - nWordStart + 1);
- SendMessage(g_hwndLogBox, EM_GETTEXTRANGE, 0, (LPARAM) &range);
-
- if (regexec(&re, range.lpstrText, 1, &match, 0) == 0)
- {
- szResult = range.lpstrText;
- }
- else
- {
- free(range.lpstrText);
- }
-
- regfree(&re);
- }
- return szResult;
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogPutString
- *
- * Description : Inserts text into the logging window. This is really
- * a regexp aware wrapper function to `LogPutStringNoMatch'.
- *
- * Parameters :
- * 1 : pszText = pointer to string going to the log window
- *
- * Returns : 1 => success, else the return code from `LogPutStringNoMatch'.
- * FIXME: this is backwards to the rest of IJB and to common
- * programming practice. Please use 0 => success instead.
- *
- *********************************************************************/
-int LogPutString(const char *pszText)
-{
- int i;
- int result = 0;
-
- if (pszText == NULL || strlen(pszText) == 0)
- {
- return 1;
- }
-
- if (!g_bLogMessages)
- {
- return 1;
- }
-
- /* Critical section stops multiple threads doing nasty interactions that
- * foul up the highlighting and output.
- */
- EnterCriticalSection(&g_criticalsection);
-
- if (g_bHighlightMessages)
- {
- regmatch_t match;
-
- /* First things first, regexp scan for various things that we would like highlighted */
- for (i = 0; patterns_to_highlight[i].str != NULL; i++)
- {
- if (regexec(&patterns_to_highlight[i].buffer, pszText, 1, &match, 0) == 0)
- {
- char *pszBefore = NULL;
- char *pszMatch = NULL;
- char *pszAfter = NULL;
- int nMatchSize;
-
- /* Split the string up into pieces representing the strings, before
- at and after the matching pattern
- */
- if (match.rm_so > 0)
- {
- pszBefore = (char *)malloc((match.rm_so + 1) * sizeof(char));
- memset(pszBefore, 0, (match.rm_so + 1) * sizeof(char));
- strncpy(pszBefore, pszText, match.rm_so);
- }
- if (match.rm_eo < (regoff_t)strlen(pszText))
- {
- pszAfter = strdup(&pszText[match.rm_eo]);
- }
- nMatchSize = match.rm_eo - match.rm_so;
- pszMatch = (char *)malloc(nMatchSize + 1);
- strncpy(pszMatch, &pszText[match.rm_so], nMatchSize);
- pszMatch[nMatchSize] = '\0';
-
- /* Recursively call LogPutString */
- if (pszBefore)
- {
- LogPutString(pszBefore);
- free(pszBefore);
- }
- if (pszMatch)
- {
- LogPutStringNoMatch(pszMatch, patterns_to_highlight[i].style);
- free(pszMatch);
- }
- if (pszAfter)
- {
- LogPutString(pszAfter);
- free(pszAfter);
- }
-
- result = 1;
- goto end;
- }
- }
- }
-
- result = LogPutStringNoMatch(pszText, STYLE_NONE);
-
-end:
- LeaveCriticalSection(&g_criticalsection);
-
- return result;
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogPutStringNoMatch
- *
- * Description : Puts a string into the logging window.
- *
- * Parameters :
- * 1 : pszText = pointer to string going to the log window
- * 2 : style = STYLE_NONE, STYLE_HEADER, STYLE_HIGHLIGHT, or STYLE_LINK
- *
- * Returns : Always 1 => success.
- * FIXME: this is backwards to the rest of IJB and to common
- * programming practice. Please use 0 => success instead.
- *
- *********************************************************************/
-int LogPutStringNoMatch(const char *pszText, int style)
-{
- CHARRANGE range;
- CHARFORMAT format;
- int nTextLength;
-
- assert(g_hwndLogBox);
- if (g_hwndLogBox == NULL)
- {
- return 1;
- }
-
- /* TODO preserve existing selection */
-
- /* Go to the end of the text */
- nTextLength = GetWindowTextLength(g_hwndLogBox);
- range.cpMin = nTextLength;
- range.cpMax = nTextLength;
- SendMessage(g_hwndLogBox, EM_EXSETSEL, 0, (LPARAM) &range);
-
- /* Apply a formatting style */
- memset(&format, 0, sizeof(format));
- format.cbSize = sizeof(format);
- format.dwMask = CFM_BOLD | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_ITALIC | CFM_COLOR | CFM_FACE | CFM_SIZE;
- format.yHeight = (g_nFontSize * 1440) / 72;
- strcpy(format.szFaceName, g_szFontFaceName);
- if (style == STYLE_NONE)
- {
- /* DO NOTHING */
- format.dwEffects |= CFE_AUTOCOLOR;
- }
- else if (style == STYLE_HEADER)
- {
- format.dwEffects |= CFE_AUTOCOLOR | CFE_ITALIC;
- }
- else if (style == STYLE_HIGHLIGHT)
- {
- format.dwEffects |= CFE_AUTOCOLOR | CFE_BOLD;
- }
- else if (style == STYLE_LINK)
- {
- format.dwEffects |= CFE_UNDERLINE;
- format.crTextColor = RGB(0, 0, 255);
- }
- SendMessage(g_hwndLogBox, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &format);
-
- /* Append text to the end */
- SendMessage(g_hwndLogBox, EM_REPLACESEL, FALSE, (LPARAM) pszText);
-
- /* TODO Restore the old selection */
-
- /* Purge buffer */
- if (strchr(pszText, '\n') != NULL)
- {
- SetTimer(g_hwndLogFrame, TIMER_CLIPBUFFER_ID, TIMER_CLIPBUFFER_TIME, NULL);
- if (!g_bClipPending)
- {
- /* Set the force clip timer going. This timer ensures clipping is done
- intermittently even when there is a sustained burst of logging
- */
- SetTimer(g_hwndLogFrame, TIMER_CLIPBUFFER_FORCE_ID, TIMER_CLIPBUFFER_FORCE_TIME, NULL);
- }
- g_bClipPending = TRUE;
- }
-
- return 1;
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogShowActivity
- *
- * Description : Start the spinner.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void LogShowActivity(void)
-{
- /* Start some activity timers */
- if (g_bShowActivityAnimation)
- {
- SetTimer(g_hwndLogFrame, TIMER_ANIM_ID, TIMER_ANIM_TIME, NULL);
- SetTimer(g_hwndLogFrame, TIMER_ANIMSTOP_ID, TIMER_ANIMSTOP_TIME, NULL);
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogClipBuffer
- *
- * Description : Prunes old lines from the log.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void LogClipBuffer(void)
-{
- int nLines = SendMessage(g_hwndLogBox, EM_GETLINECOUNT, 0, 0);
- if (g_bLimitBufferSize && nLines > g_nMaxBufferLines)
- {
- /* Compute the range representing the lines to be deleted */
- LONG nLastLineToDelete = nLines - g_nMaxBufferLines;
- LONG nLastChar = SendMessage(g_hwndLogBox, EM_LINEINDEX, nLastLineToDelete, 0);
- CHARRANGE range;
- range.cpMin = 0;
- range.cpMax = nLastChar;
-
- /* TODO get current selection */
-
- /* TODO adjust and clip old selection against range to be deleted */
-
- /* Select range and erase it (turning off autoscroll to prevent
- nasty scrolling) */
- SendMessage(g_hwndLogBox, EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOVSCROLL);
- SendMessage(g_hwndLogBox, EM_EXSETSEL, 0, (LPARAM) &range);
- SendMessage(g_hwndLogBox, EM_REPLACESEL, FALSE, (LPARAM) "");
- SendMessage(g_hwndLogBox, EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOVSCROLL);
-
- /* Restore old selection */
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : CreateHiddenLogOwnerWindow
- *
- * Description : Creates a hidden owner window that stops the log
- * window appearing in the task bar.
- *
- * Parameters :
- * 1 : hInstance = application's instance handle
- *
- * Returns : Handle to newly created window.
- *
- *********************************************************************/
-HWND CreateHiddenLogOwnerWindow(HINSTANCE hInstance)
-{
- static const char *szWndName = "PrivoxyLogOwner";
- WNDCLASS wc;
- HWND hwnd;
-
- wc.style = 0;
- wc.lpfnWndProc = LogOwnerWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = 0;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = 0;
- wc.lpszClassName = szWndName;
-
- RegisterClass(&wc);
-
- hwnd = CreateWindow(szWndName, szWndName,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, NULL, hInstance, NULL );
-
- return hwnd;
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogOwnerWindowProc
- *
- * Description : Dummy procedure that does nothing special.
- *
- * Parameters :
- * 1 : hwnd = window handle
- * 2 : uMsg = message number
- * 3 : wParam = first param for this message
- * 4 : lParam = next param for this message
- *
- * Returns : Same as `DefWindowProc'.
- *
- *********************************************************************/
-LRESULT CALLBACK LogOwnerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-
-}
-
-
-/*********************************************************************
- *
- * Function : CreateLogWindow
- *
- * Description : Create the logging window.
- *
- * Parameters :
- * 1 : hInstance = application's instance handle
- * 2 : nCmdShow = window show value (MIN, MAX, NORMAL, etc...)
- *
- * Returns : Handle to newly created window.
- *
- *********************************************************************/
-HWND CreateLogWindow(HINSTANCE hInstance, int nCmdShow)
-{
- static const char *szWndName = "PrivoxyLogWindow";
- static const char *szWndTitle = "Privoxy";
-
- HWND hwnd = NULL;
- HWND hwndOwner = (g_bShowOnTaskBar) ? NULL : CreateHiddenLogOwnerWindow(hInstance);
- RECT rcClient;
- WNDCLASSEX wc;
-
- memset(&wc, 0, sizeof(wc));
- wc.cbSize = sizeof(wc);
- wc.style = CS_DBLCLKS;
- wc.lpfnWndProc = LogWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = g_hiconApp;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = MAKEINTRESOURCE(IDR_LOGVIEW);
- wc.lpszClassName = szWndName;
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- RegisterClassEx(&wc);
-
- hwnd = CreateWindowEx(WS_EX_APPWINDOW, szWndName, szWndTitle,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, hwndOwner, NULL, hInstance, NULL);
-
- /* Now create a child list box */
- GetClientRect(hwnd, &rcClient);
-
- /* Create a rich edit control */
- InitRichEdit();
- g_hwndLogBox = CreateWindowEx(0, (g_nRichEditVersion == 0x0100) ? "RichEdit" : RICHEDIT_CLASS, "",
- ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY | ES_NOHIDESEL | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
- rcClient.left, rcClient.top, rcClient.right, rcClient.bottom,
- hwnd, NULL, hInstance, NULL);
-/* SendMessage(g_hwndLogBox, EM_SETWORDWRAPMODE, 0, 0); */
-
- /* Subclass the control to catch certain messages */
- g_fnLogBox = (WNDPROC) GetWindowLong(g_hwndLogBox, GWL_WNDPROC);
- SetWindowLong(g_hwndLogBox, GWL_WNDPROC, (LONG) LogRichEditProc);
-
- /* Minimizing looks stupid when the log window is not on the task bar, so hide instead */
- if (!g_bShowOnTaskBar &&
- (nCmdShow == SW_SHOWMINIMIZED ||
- nCmdShow == SW_MINIMIZE ||
- nCmdShow == SW_SHOWMINNOACTIVE))
- {
- nCmdShow = SW_HIDE;
- }
-
- ShowWindow(hwnd, nCmdShow);
- UpdateWindow(hwnd);
-
- GetClientRect(g_hwndLogFrame, &rcClient);
- SetWindowPos(g_hwndLogBox, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_NOZORDER);
-
- return hwnd;
-
-}
-
-
-/*********************************************************************
- *
- * Function : InitRichEdit
- *
- * Description : Initialise the rich edit control library.
- *
- * Parameters : None
- *
- * Returns : TRUE => success, FALSE => failure.
- * FIXME: this is backwards to the rest of IJB and to common
- * programming practice. Please use 0 => success instead.
- *
- *********************************************************************/
-BOOL InitRichEdit(void)
-{
- static HINSTANCE hInstRichEdit;
- if (hInstRichEdit == NULL)
- {
- g_nRichEditVersion = 0;
- hInstRichEdit = LoadLibraryA("RICHED20.DLL");
- if (hInstRichEdit)
- {
- g_nRichEditVersion = _RICHEDIT_VER;
- }
- else
- {
- hInstRichEdit = LoadLibraryA("RICHED32.DLL");
- if (hInstRichEdit)
- {
- g_nRichEditVersion = 0x0100;
- }
- }
- }
- return (hInstRichEdit != NULL) ? TRUE : FALSE;
-
-}
-
-
-/*********************************************************************
- *
- * Function : ShowLogWindow
- *
- * Description : Shows or hides the log window. We will also raise the
- * window on a show command in case it is buried.
- *
- * Parameters :
- * 1 : bShow = TRUE to show, FALSE to mimize/hide
- *
- * Returns : N/A
- *
- *********************************************************************/
-void ShowLogWindow(BOOL bShow)
-{
- if (bShow)
- {
- SetForegroundWindow(g_hwndLogFrame);
- SetWindowPos(g_hwndLogFrame, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
- }
- else if (g_bShowOnTaskBar)
- {
- ShowWindow(g_hwndLogFrame, SW_MINIMIZE);
- }
- else
- {
- ShowWindow(g_hwndLogFrame, SW_HIDE);
- }
-
-}
-
-
-/*********************************************************************
- *
- * 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 config.txt) file.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void EditFile(const char *filename)
-{
- if (filename)
- {
- ShellExecute(g_hwndLogFrame, "open", filename, NULL, NULL, SW_SHOWNORMAL);
- }
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* Windows message handlers */
-/*--------------------------------------------------------------------------*/
-
-
-/*********************************************************************
- *
- * Function : OnLogRButtonUp
- *
- * Description : Handler for WM_RBUTTONUP messages.
- *
- * Parameters :
- * 1 : nModifier = wParam from mouse message (unused)
- * 2 : x = x coordinate of the mouse event
- * 3 : y = y coordinate of the mouse event
- *
- * Returns : N/A
- *
- *********************************************************************/
-void OnLogRButtonUp(int nModifier, int x, int y)
-{
- HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_POPUP_SELECTION));
- if (hMenu != NULL)
- {
- HMENU hMenuPopup = GetSubMenu(hMenu, 0);
-
- /* Check if there is a selection */
- CHARRANGE range;
- SendMessage(g_hwndLogBox, EM_EXGETSEL, 0, (LPARAM) &range);
- if (range.cpMin == range.cpMax)
- {
- EnableMenuItem(hMenuPopup, ID_EDIT_COPY, MF_BYCOMMAND | MF_GRAYED);
- }
- else
- {
- EnableMenuItem(hMenuPopup, ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED);
- }
-
- /* Display the popup */
- TrackPopupMenu(hMenuPopup, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x, y, 0, g_hwndLogFrame, NULL);
- DestroyMenu(hMenu);
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : OnLogCommand
- *
- * Description : Handler for WM_COMMAND messages.
- *
- * Parameters :
- * 1 : nCommand = the command portion of the menu selection event
- *
- * Returns : N/A
- *
- *********************************************************************/
-void OnLogCommand(int nCommand)
-{
- switch (nCommand)
- {
- case ID_SHOWWINDOW:
- ShowLogWindow(TRUE);
- break;
-
- case ID_FILE_EXIT:
- PostMessage(g_hwndLogFrame, WM_CLOSE, 0, 0);
- break;
-
- case ID_EDIT_COPY:
- SendMessage(g_hwndLogBox, WM_COPY, 0, 0);
- break;
-
- case ID_VIEW_CLEARLOG:
- SendMessage(g_hwndLogBox, WM_SETTEXT, 0, (LPARAM) "");
- break;
-
- case ID_VIEW_LOGMESSAGES:
- g_bLogMessages = !g_bLogMessages;
- /* SaveLogSettings(); */
- break;
-
- case ID_VIEW_MESSAGEHIGHLIGHTING:
- g_bHighlightMessages = !g_bHighlightMessages;
- /* SaveLogSettings(); */
- break;
-
- case ID_VIEW_LIMITBUFFERSIZE:
- g_bLimitBufferSize = !g_bLimitBufferSize;
- /* SaveLogSettings(); */
- break;
-
- case ID_VIEW_ACTIVITYANIMATION:
- g_bShowActivityAnimation = !g_bShowActivityAnimation;
- /* SaveLogSettings(); */
- break;
-
-#ifdef FEATURE_TOGGLE
- /* by haroon - change toggle to its opposite value */
- case ID_TOGGLE_ENABLED:
- g_bToggleIJB = !g_bToggleIJB;
- if (g_bToggleIJB)
- {
- log_error(LOG_LEVEL_INFO, "Now toggled ON.");
- }
- else
- {
- log_error(LOG_LEVEL_INFO, "Now toggled OFF.");
- }
- break;
-#endif /* def FEATURE_TOGGLE */
-
- case ID_TOOLS_EDITCONFIG:
- EditFile(configfile);
- break;
-
- case ID_TOOLS_EDITACTIONS:
- EditFile(g_actions_file);
- break;
-
- case ID_TOOLS_EDITFILTERS:
- EditFile(g_re_filterfile);
- break;
-
-#ifdef FEATURE_TRUST
- case ID_TOOLS_EDITTRUST:
- EditFile(g_trustfile);
- break;
-#endif /* def FEATURE_TRUST */
-
- case ID_HELP_GPL:
- ShellExecute(g_hwndLogFrame, "open", "LICENSE.txt", NULL, NULL, SW_SHOWNORMAL);
- break;
-
- case ID_HELP_FAQ:
- ShellExecute(g_hwndLogFrame, "open", "doc\\faq\\index.html", NULL, NULL, SW_SHOWNORMAL);
- break;
-
- case ID_HELP_MANUAL:
- ShellExecute(g_hwndLogFrame, "open", "doc\\user-manual\\index.html", NULL, NULL, SW_SHOWNORMAL);
- break;
-
- case ID_HELP_STATUS:
- ShellExecute(g_hwndLogFrame, "open", CGI_PREFIX "show-status", NULL, NULL, SW_SHOWNORMAL);
- break;
-
- case ID_HELP_ABOUT:
- MessageBox(g_hwndLogFrame, win32_blurb, "About Privoxy", MB_OK);
- break;
-
- default:
- /* DO NOTHING */
- break;
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : OnLogInitMenu
- *
- * Description : Handler for WM_INITMENU messages. Enable, disable,
- * check, and/or uncheck menu options as apropos.
- *
- * Parameters :
- * 1 : hmenu = handle to menu to "make current"
- *
- * Returns : N/A
- *
- *********************************************************************/
-void OnLogInitMenu(HMENU hmenu)
-{
- /* Only enable editors if there is a file to edit */
- 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 FEATURE_TOGGLE
- /* by haroon - menu item for Enable toggle on/off */
- CheckMenuItem(hmenu, ID_TOGGLE_ENABLED, MF_BYCOMMAND | (g_bToggleIJB ? MF_CHECKED : MF_UNCHECKED));
-#endif /* def FEATURE_TOGGLE */
-
-}
-
-
-/*********************************************************************
- *
- * Function : OnLogTimer
- *
- * Description : Handler for WM_TIMER messages.
- *
- * Parameters :
- * 1 : nTimer = timer id (animation start/stop or clip buffer)
- *
- * Returns : N/A
- *
- *********************************************************************/
-void OnLogTimer(int nTimer)
-{
- switch (nTimer)
- {
- case TIMER_ANIM_ID:
- TraySetIcon(g_hwndTray, 1, g_hiconAnim[g_nAnimFrame++ % ANIM_FRAMES]);
- break;
-
- case TIMER_ANIMSTOP_ID:
- g_nAnimFrame = 0;
- TraySetIcon(g_hwndTray, 1, g_hiconIdle);
- KillTimer(g_hwndLogFrame, TIMER_ANIM_ID);
- KillTimer(g_hwndLogFrame, TIMER_ANIMSTOP_ID);
- break;
-
- case TIMER_CLIPBUFFER_ID:
- case TIMER_CLIPBUFFER_FORCE_ID:
- LogClipBuffer();
- g_bClipPending = FALSE;
- KillTimer(g_hwndLogFrame, TIMER_CLIPBUFFER_ID);
- KillTimer(g_hwndLogFrame, TIMER_CLIPBUFFER_FORCE_ID);
- break;
-
- default:
- /* DO NOTHING */
- break;
- }
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogRichEditProc
- *
- * Description : Window subclass routine handles some events for the rich edit control.
- *
- * Parameters :
- * 1 : hwnd = window handle of the rich edit control
- * 2 : uMsg = message number
- * 3 : wParam = first param for this message
- * 4 : lParam = next param for this message
- *
- * Returns : Appropriate M$ window message handler codes.
- *
- *********************************************************************/
-LRESULT CALLBACK LogRichEditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_RBUTTONUP:
- {
- POINT pt;
- pt.x = LOWORD(lParam);
- pt.y = HIWORD(lParam);
- ClientToScreen(hwnd, &pt);
- OnLogRButtonUp(wParam, pt.x, pt.y);
- }
- return 0;
- }
- return CallWindowProc(g_fnLogBox, hwnd, uMsg, wParam, lParam);
-
-}
-
-
-/*********************************************************************
- *
- * Function : LogWindowProc
- *
- * Description : Windows call back routine handles events on the log window.
- *
- * Parameters :
- * 1 : hwnd = handle of the logging window
- * 2 : uMsg = message number
- * 3 : wParam = first param for this message
- * 4 : lParam = next param for this message
- *
- * Returns : Appropriate M$ window message handler codes.
- *
- *********************************************************************/
-LRESULT CALLBACK LogWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_CREATE:
- return 0;
-
- case WM_CLOSE:
- /* This is the end - beautiful friend - the end */
- DestroyWindow(g_hwndLogBox);
- DestroyWindow(g_hwndLogFrame);
- return 0;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
-
- case WM_SHOWWINDOW:
- case WM_SIZE:
- /* Resize the logging window to fit the new frame */
- if (g_hwndLogBox)
- {
- RECT rc;
- GetClientRect(g_hwndLogFrame, &rc);
- SetWindowPos(g_hwndLogBox, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER);
- }
- return 0;
-
- case WM_INITMENU:
- OnLogInitMenu((HMENU) wParam);
- return 0;
-
- case WM_TIMER:
- OnLogTimer(wParam);
- return 0;
-
- case WM_COMMAND:
- OnLogCommand(LOWORD(wParam));
- return 0;
-
- case WM_SYSCOMMAND:
- switch (wParam)
- {
- case SC_CLOSE:
- if (g_bCloseHidesWindow)
- {
- ShowLogWindow(FALSE);
- return 0;
- }
- break;
- case SC_MINIMIZE:
- ShowLogWindow(FALSE);
- return 0;
- }
- break;
- }
-
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-
-}
-
-#endif /* ndef _WIN_CONSOLE - entire file */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /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-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: w32log.h,v $
- * Revision 1.9 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.8 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.7 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.6 2001/07/13 14:04:59 oes
- * Removed all #ifdef PCRS
- *
- * Revision 1.5 2001/06/07 23:08:12 jongfoster
- * Forward and ACL edit options removed.
- *
- * Revision 1.4 2001/05/31 21:37:11 jongfoster
- * GUI changes to rename "permissions file" to "actions file".
- *
- * Revision 1.3 2001/05/29 09:50:24 jongfoster
- * Unified blocklist/imagelist/permissionslist.
- * File format is still under discussion, but the internal changes
- * are (mostly) done.
- *
- * Also modified interceptor behaviour:
- * - We now intercept all URLs beginning with one of the following
- * prefixes (and *only* these prefixes):
- * * http://i.j.b/
- * * http://ijbswa.sf.net/config/
- * * http://ijbswa.sourceforge.net/config/
- * - New interceptors "home page" - go to http://i.j.b/ to see it.
- * - Internal changes so that intercepted and fast redirect pages
- * are not replaced with an image.
- * - Interceptors now have the option to send a binary page direct
- * to the client. (i.e. ijb-send-banner uses this)
- * - Implemented show-url-info interceptor. (Which is why I needed
- * the above interceptors changes - a typical URL is
- * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
- * The previous mechanism would not have intercepted that, and
- * if it had been intercepted then it then it would have replaced
- * it with an image.)
- *
- * Revision 1.2 2001/05/26 00:28:36 jongfoster
- * Automatic reloading of config file.
- * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
- * Most of the global variables have been moved to a new
- * struct configuration_spec, accessed through csp->config->globalname
- * Most of the globals remaining are used by the Win32 GUI.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:07 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern HWND g_hwndLogFrame;
-
-/* Indicates whether task bar shows activity animation */
-extern BOOL g_bShowActivityAnimation;
-
-/* Indicates if the log window appears on the task bar */
-extern BOOL g_bShowOnTaskBar;
-
-/* Indicates whether closing the log window really just hides it */
-extern BOOL g_bCloseHidesWindow;
-
-/* Indicates if messages are logged at all */
-extern BOOL g_bLogMessages;
-
-/* Indicates whether log messages are highlighted */
-extern BOOL g_bHighlightMessages;
-
-/* Indicates if buffer is limited in size */
-extern BOOL g_bLimitBufferSize;
-
-/* Maximum number of lines allowed in buffer when limited */
-extern int g_nMaxBufferLines;
-
-/* Font to use */
-extern char g_szFontFaceName[255];
-
-/* Size of font to use */
-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);
-extern void ShowLogWindow(BOOL bShow);
-extern void LogShowActivity(void);
-
-/* Revision control strings from this header and associated .c file */
-extern const char w32log_rcs[];
-extern const char w32log_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef W32LOG_H_INCLUDED */
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/w32res.h,v $
- *
- * Purpose : Identifiers for Windows GUI resources.
- *
- * 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: 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 IDR_TRAYMENU 101
-#define IDI_IDLE 102
-#define IDR_LOGVIEW 103
-#define IDR_ACCELERATOR 104
-#define IDR_POPUP_SELECTION 105
-
-
-#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_ABOUT 4001
-#define ID_FILE_EXIT 4002
-#define ID_VIEW_CLEARLOG 4003
-#define ID_VIEW_LOGMESSAGES 4004
-#define ID_VIEW_MESSAGEHIGHLIGHTING 4005
-#define ID_VIEW_LIMITBUFFERSIZE 4006
-#define ID_VIEW_ACTIVITYANIMATION 4007
-#define ID_HELP_FAQ 4008
-#define ID_HELP_MANUAL 4009
-#define ID_HELP_GPL 4010
-#define ID_HELP_STATUS 4011
-#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_EDITCONFIG 5000
-#define ID_TOOLS_EDITACTIONS 5001
-#define ID_TOOLS_EDITFILTERS 5002
-
-#ifdef FEATURE_TRUST
-#define ID_TOOLS_EDITTRUST 5003
-#endif /* def FEATURE_TRUST */
-
-/*
- * The following symbols are declared in <afxres.h> in VC++.
- * However, mingw32 doesn't have that header. Let's
- * always declare them here, for consistency.
- * These are the VC++ values.
- */
-#define IDC_STATIC (-1)
-#define ID_EDIT_COPY 30000
-
-
-#endif /* ndef W32RES_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.6 2002/03/26 22:57:10 jongfoster Exp $";
-/*********************************************************************
- *
- * 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-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * The GNU General Public License should be included with
- * this file. If not, you can view it at
- * http://www.gnu.org/copyleft/gpl.html
- * or write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Revisions :
- * $Log: w32taskbar.c,v $
- * Revision 1.6 2002/03/26 22:57:10 jongfoster
- * Web server name should begin www.
- *
- * Revision 1.5 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.4 2001/11/16 00:46:31 jongfoster
- * Fixing compiler warnings
- *
- * Revision 1.3 2001/05/22 18:56:28 oes
- * CRLF -> LF
- *
- * Revision 1.2 2001/05/20 15:07:54 jongfoster
- * File is now ignored if _WIN_CONSOLE is defined.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:08 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#include <stdio.h>
-
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-
-#include "w32taskbar.h"
-#include "w32res.h"
-#include "w32log.h"
-
-const char w32taskbar_h_rcs[] = W32TASKBAR_H_VERSION;
-
-#ifndef _WIN_CONSOLE /* entire file */
-
-#define WM_TRAYMSG WM_USER+1
-
-static HMENU g_hmenuTray;
-static HWND g_hwndTrayX;
-
-static LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-
-/*********************************************************************
- *
- * Function : CreateTrayWindow
- *
- * Description : Creates and returns the invisible window responsible
- * for processing tray messages.
- *
- * Parameters :
- * 1 : hInstance = instance handle of this application
- *
- * Returns : Handle of the systray window.
- *
- *********************************************************************/
-HWND CreateTrayWindow(HINSTANCE hInstance)
-{
- WNDCLASS wc;
- static const char *szWndName = "PrivoxyTrayWindow";
-
- wc.style = 0;
- wc.lpfnWndProc = TrayProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = 0;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = 0;
- wc.lpszClassName = szWndName;
-
- RegisterClass(&wc);
-
- g_hwndTrayX = CreateWindow(szWndName, szWndName,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, NULL, hInstance, NULL );
-
- ShowWindow(g_hwndTrayX, SW_HIDE);
- UpdateWindow(g_hwndTrayX);
-
- g_hmenuTray = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_TRAYMENU));
-
- return g_hwndTrayX;
-
-}
-
-
-/*********************************************************************
- *
- * Function : TraySetIcon
- *
- * Description : Sets the tray icon to the specified shape.
- *
- * Parameters :
- * 1 : hwnd = handle of the systray window
- * 2 : uID = user message number to notify systray window
- * 3 : hicon = set the current icon to this handle
- *
- * Returns : Same value as `Shell_NotifyIcon'.
- *
- *********************************************************************/
-BOOL TraySetIcon(HWND hwnd, UINT uID, HICON hicon)
-{
- NOTIFYICONDATA nid;
-
- memset(&nid, 0, sizeof(nid));
-
- nid.cbSize = sizeof(nid);
- nid.hWnd = hwnd;
- nid.uID = uID;
- nid.uFlags = NIF_ICON;
- nid.uCallbackMessage = 0;
- nid.hIcon = hicon;
-
- return( Shell_NotifyIcon(NIM_MODIFY, &nid) );
-
-}
-
-
-/*********************************************************************
- *
- * Function : TrayAddIcon
- *
- * Description : Adds a tray icon.
- *
- * Parameters :
- * 1 : hwnd = handle of the systray window
- * 2 : uID = user message number to notify systray window
- * 3 : hicon = handle of icon to add to systray window
- * 4 : pszToolTip = tool tip when mouse hovers over systray window
- *
- * Returns : Same as `Shell_NotifyIcon'.
- *
- *********************************************************************/
-BOOL TrayAddIcon(HWND hwnd, UINT uID, HICON hicon, const char *pszToolTip)
-{
- NOTIFYICONDATA nid;
-
- memset(&nid, 0, sizeof(nid));
-
- nid.cbSize = sizeof(nid);
- nid.hWnd = hwnd;
- nid.uID = uID;
- nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
- nid.uCallbackMessage = WM_TRAYMSG;
- nid.hIcon = hicon;
-
- if (pszToolTip)
- {
- strcpy(nid.szTip, pszToolTip);
- }
-
- return( Shell_NotifyIcon(NIM_ADD, &nid) );
-
-}
-
-
-/*********************************************************************
- *
- * Function : TrayDeleteIcon
- *
- * Description : Deletes a tray icon.
- *
- * Parameters :
- * 1 : hwnd = handle of the systray window
- * 2 : uID = user message number to notify systray window
- *
- * Returns : Same as `Shell_NotifyIcon'.
- *
- *********************************************************************/
-BOOL TrayDeleteIcon(HWND hwnd, UINT uID)
-{
- NOTIFYICONDATA nid;
-
- memset(&nid, 0, sizeof(nid));
-
- nid.cbSize = sizeof(nid);
- nid.hWnd = hwnd;
- nid.uID = uID;
-
- return( Shell_NotifyIcon(NIM_DELETE, &nid) );
-
-}
-
-
-/*********************************************************************
- *
- * Function : TrayProc
- *
- * Description : Call back procedure processes tray messages.
- *
- * Parameters :
- * 1 : hwnd = handle of the systray window
- * 2 : msg = message number
- * 3 : wParam = first param for this message
- * 4 : lParam = next param for this message
- *
- * Returns : Appropriate M$ window message handler codes.
- *
- *********************************************************************/
-LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg)
- {
- case WM_CREATE:
- return 0;
-
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
-
- case WM_TRAYMSG:
- {
- /* UINT uID = (UINT) wParam; */
- UINT uMouseMsg = (UINT) lParam;
-
- if (uMouseMsg == WM_RBUTTONDOWN)
- {
- POINT pt;
- HMENU hmenu = GetSubMenu(g_hmenuTray,0);
- GetCursorPos(&pt);
- SetForegroundWindow(g_hwndLogFrame);
- TrackPopupMenu(hmenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, g_hwndLogFrame, NULL);
- PostMessage(g_hwndLogFrame, WM_NULL, 0, 0 ) ;
- }
- else if (uMouseMsg == WM_LBUTTONDBLCLK)
- {
- ShowLogWindow(TRUE);
- }
- }
- return 0;
-
- default:
- /* DO NOTHING */
- break;
- }
-
- return DefWindowProc(hwnd, msg, wParam, lParam);
-
-}
-
-
-#endif /* ndef _WIN_CONSOLE - entire file */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/w32taskbar.h,v $
- *
- * Purpose : Functions for creating, setting and destroying the
- * workspace tray icon
- *
- * Copyright : Written by and Copyright (C) 2001-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * 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: w32taskbar.h,v $
- * Revision 1.3 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.2 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:08 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern HWND CreateTrayWindow(HINSTANCE hInstance);
-extern BOOL TrayAddIcon(HWND hwnd, UINT uID, HICON hicon, const char *pszToolTip);
-extern BOOL TraySetIcon(HWND hwnd, UINT uID, HICON hicon);
-extern BOOL TrayDeleteIcon(HWND hwnd, UINT uID);
-
-/* Revision control strings from this header and associated .c file */
-extern const char w32taskbar_rcs[];
-extern const char w32taskbar_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef W32TASKBAR_H_INCLUDED */
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-const char win32_rcs[] = "$Id: win32.c,v 1.8 2002/03/26 22:57:10 jongfoster Exp $";
-/*********************************************************************
- *
- * File : $Source: /cvsroot/ijbswa/current/win32.c,v $
- *
- * Purpose : Win32 User Interface initialization and message loop
- *
- * Copyright : Written by and Copyright (C) 2001-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * 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: win32.c,v $
- * Revision 1.8 2002/03/26 22:57:10 jongfoster
- * Web server name should begin www.
- *
- * Revision 1.7 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.6 2002/03/16 21:53:28 jongfoster
- * VC++ Heap debug option
- *
- * Revision 1.5 2002/03/04 23:47:30 jongfoster
- * - Rewritten, simpler command-line pre-parser
- * - not using raise(SIGINT) any more
- *
- * Revision 1.4 2001/11/30 21:29:33 jongfoster
- * Fixing a warning
- *
- * Revision 1.3 2001/11/16 00:46:31 jongfoster
- * Fixing compiler warnings
- *
- * Revision 1.2 2001/07/29 19:32:00 jongfoster
- * Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:08 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#include "config.h"
-
-#ifdef _WIN32
-
-#include <stdio.h>
-
-#include "project.h"
-#include "jcc.h"
-#include "miscutil.h"
-
-/* Uncomment this if you want to build Win32 as a console app */
-/* #define _WIN_CONSOLE */
-
-#ifndef STRICT
-#define STRICT
-#endif
-#include <windows.h>
-
-#include <stdarg.h>
-#include <process.h>
-
-#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
-/* Visual C++ Heap debugging */
-#include <crtdbg.h>
-#endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
-
-#include "win32.h"
-
-const char win32_h_rcs[] = WIN32_H_VERSION;
-
-const char win32_blurb[] =
-"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"
-" " HOME_PAGE_URL "\n"
-"\n";
-
-#ifdef _WIN_CONSOLE
-
-int hideConsole = 0;
-
-#else
-
-HINSTANCE g_hInstance;
-int g_nCmdShow;
-
-static void __cdecl UserInterfaceThread(void *);
-
-#endif
-
-
-/*********************************************************************
- *
- * Function : WinMain
- *
- * 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 startup).
- *
- * Parameters :
- * 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.
- *
- *********************************************************************/
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
-{
- int i;
- int res;
- int argc = 1;
- const char *argv[3];
- char szModule[MAX_PATH+1];
-#ifndef _WIN_CONSOLE
- HANDLE hInitCompleteEvent = NULL;
-#endif
-
-
-#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
-#if 0
- /* Visual C++ Heap debugging */
-
- /* Get current flag*/
- int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
-
- /* Turn on leak-checking bit */
- tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF;
-
- /* 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)
- {
- chomp(lpCmdLine);
- i = strlen(lpCmdLine);
- if ((i >= 2) && (lpCmdLine[0] == '\"') && (lpCmdLine[i - 1] == '\"'))
- {
- lpCmdLine[i - 1] = '\0';
- lpCmdLine++;
- }
- 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 */
- hInitCompleteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- g_hInstance = hInstance;
- g_nCmdShow = nCmdShow;
- _beginthread(UserInterfaceThread, 0, &hInitCompleteEvent);
- WaitForSingleObject(hInitCompleteEvent, INFINITE);
- DeleteObject(hInitCompleteEvent);
-#endif
-
-#ifdef __MINGW32__
- res = real_main( argc, argv );
-#else
- res = main( argc, argv );
-#endif
-
- return res;
-
-}
-
-#endif
-
-/*********************************************************************
- *
- * Function : InitWin32
- *
- * Description : Initialise windows, setting up the console or windows as appropriate.
- *
- * Parameters : None
- *
- * Returns : N/A
- *
- *********************************************************************/
-void InitWin32(void)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
-
-#ifdef _WIN_CONSOLE
- SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);
- if (hideConsole)
- {
- FreeConsole();
- }
-#endif
- wVersionRequested = MAKEWORD(2, 0);
- if (WSAStartup(wVersionRequested, &wsaData) != 0)
- {
-#ifndef _WIN_CONSOLE
- MessageBox(NULL, "Cannot initialize WinSock library", "Privoxy Error",
- MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);
-#endif
- exit(1);
- }
-
-}
-
-
-#ifndef _WIN_CONSOLE
-#include <signal.h>
-#include <assert.h>
-
-#include "win32.h"
-#include "w32log.h"
-
-
-/*********************************************************************
- *
- * Function : UserInterfaceThread
- *
- * 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
- * operations.
- *
- * Parameters :
- * 1 : pData = pointer to `hInitCompleteEvent'.
- *
- * Returns : N/A
- *
- *********************************************************************/
-static void __cdecl UserInterfaceThread(void *pData)
-{
- MSG msg;
- HANDLE hInitCompleteEvent = *((HANDLE *) pData);
-
- /* Initialise */
- InitLogWindow();
- SetEvent(hInitCompleteEvent);
-
- /* Enter a message processing loop */
- while (GetMessage(&msg, (HWND) NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- /* Cleanup */
- TermLogWindow();
-
- /* Time to die... */
- exit(0);
-
-}
-
-
-#endif
-
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/
+++ /dev/null
-#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: /cvsroot/ijbswa/current/win32.h,v $
- *
- * Purpose : Win32 User Interface initialization and message loop
- *
- * Copyright : Written by and Copyright (C) 2001-2002 members of
- * the Privoxy team. http://www.privoxy.org/
- *
- * Written by and Copyright (C) 1999 Adam Lock
- * <locka@iol.ie>
- *
- * 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: win32.h,v $
- * Revision 1.4 2002/03/24 12:03:47 jongfoster
- * Name change
- *
- * Revision 1.3 2001/07/30 22:08:36 jongfoster
- * Tidying up #defines:
- * - All feature #defines are now of the form FEATURE_xxx
- * - Permanently turned off WIN_GUI_EDIT
- * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
- *
- * Revision 1.2 2001/07/29 18:43:08 jongfoster
- * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
- * ANSI C rules.
- *
- * Revision 1.1.1.1 2001/05/15 13:59:08 oes
- * Initial import of version 2.9.3 source tree
- *
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const char win32_blurb[];
-
-extern void InitWin32(void);
-
-#ifdef _WIN_CONSOLE
-extern int hideConsole;
-#endif /*def _WIN_CONSOLE */
-
-extern HINSTANCE g_hInstance;
-extern int g_nCmdShow;
-
-extern int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
-
-/* Revision control strings from this header and associated .c file */
-extern const char win32_rcs[];
-extern const char win32_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef WIN32_H_INCLUDED */
-
-/*
- Local Variables:
- tab-width: 3
- end:
-*/