From: jongfoster Date: Tue, 4 Jun 2002 14:29:35 +0000 (+0000) Subject: Moving sources to /src X-Git-Tag: v_3_1_archive_branchpoint~263 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=f3832329e0d28159bfa2ad65f22ddada1b20d926 Moving sources to /src --- diff --git a/actionlist.h b/actionlist.h deleted file mode 100644 index 34b824bc..00000000 --- a/actionlist.h +++ /dev/null @@ -1,170 +0,0 @@ -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/actionlist.h,v $ - * - * Purpose : Master list of supported actions. - * Not really a header, since it generates code. - * This is included (3 times!) from actions.c - * Each time, the following macros are defined to - * suitable values beforehand: - * DEFINE_ACTION_MULTI() - * DEFINE_ACTION_STRING() - * DEFINE_ACTION_BOOL() - * DEFINE_ACTION_ALIAS - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: actionlist.h,v $ - * Revision 1.16 2002/04/24 02:15:18 oes - * Renamed actions as discussed, Aliased old action names to new ones. - * - * Revision 1.15 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.14 2002/03/24 16:32:08 jongfoster - * Removing logo option - * - * Revision 1.13 2002/03/24 15:23:33 jongfoster - * Name changes - * - * Revision 1.12 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.11 2002/03/12 01:42:49 oes - * Introduced modular filters - * - * Revision 1.10 2002/03/08 18:19:14 jongfoster - * Adding +image-blocker{pattern} option to edit interface - * - * Revision 1.9 2001/11/22 21:58:41 jongfoster - * Adding action +no-cookies-keep - * - * Revision 1.8 2001/10/10 16:42:52 oes - * Fixed a bug, Added +limit-connect string action - * - * Revision 1.7 2001/10/07 15:33:59 oes - * Introduced a +no-compression action - * Introduced a +downgrade action - * - * Revision 1.6 2001/09/16 15:47:37 jongfoster - * First version of CGI-based edit interface. This is very much a - * work-in-progress, and you can't actually use it to edit anything - * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes - * to have any effect. - * - * Revision 1.5 2001/07/18 12:27:03 oes - * Changed deanimate-gifs to string action - * - * Revision 1.4 2001/07/13 13:52:12 oes - * - Formatting - * - Introduced new action ACTION_DEANIMATE - * - * Revision 1.3 2001/06/07 23:03:56 jongfoster - * Added standard comment at top of file. - * - * - *********************************************************************/ - - -#if !(defined(DEFINE_ACTION_BOOL) && defined(DEFINE_ACTION_MULTI) && defined(DEFINE_ACTION_STRING)) -#error Please define lots of macros before including "actionlist.h". -#endif /* !defined(all the DEFINE_ACTION_xxx macros) */ - -#ifndef DEFINE_CGI_PARAM_RADIO -#define DEFINE_CGI_PARAM_RADIO(name, bit, index, value, is_default) -#define DEFINE_CGI_PARAM_CUSTOM(name, bit, index, default_val) -#define DEFINE_CGI_PARAM_NO_RADIO(name, bit, index, default_val) -#endif /* ndef DEFINE_CGI_PARAM_RADIO */ - -DEFINE_ACTION_MULTI ("add-header", ACTION_MULTI_ADD_HEADER) -DEFINE_ACTION_BOOL ("block", ACTION_BLOCK) -DEFINE_ACTION_BOOL ("crunch-incoming-cookies", ACTION_NO_COOKIE_SET) -DEFINE_ACTION_BOOL ("crunch-outgoing-cookies", ACTION_NO_COOKIE_READ) -DEFINE_ACTION_STRING ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE) -DEFINE_CGI_PARAM_RADIO ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE, "first", 0) -DEFINE_CGI_PARAM_RADIO ("deanimate-gifs", ACTION_DEANIMATE, ACTION_STRING_DEANIMATE, "last", 1) -DEFINE_ACTION_BOOL ("downgrade-http-version", ACTION_DOWNGRADE) -DEFINE_ACTION_BOOL ("fast-redirects", ACTION_FAST_REDIRECTS) -DEFINE_ACTION_MULTI ("filter", ACTION_MULTI_FILTER) -DEFINE_ACTION_BOOL ("handle-as-image", ACTION_IMAGE) -DEFINE_ACTION_BOOL ("hide-forwarded-for-headers", ACTION_HIDE_FORWARDED) -DEFINE_ACTION_STRING ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM) -DEFINE_CGI_PARAM_RADIO ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "block", 1) -DEFINE_CGI_PARAM_CUSTOM ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "spam_me_senseless@sittingduck.xyz") -DEFINE_ACTION_STRING ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER) -DEFINE_CGI_PARAM_RADIO ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "forge", 1) -DEFINE_CGI_PARAM_RADIO ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "block", 0) -DEFINE_CGI_PARAM_CUSTOM ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "http://www.google.com/") -DEFINE_ACTION_STRING ("hide-user-agent", ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT) -DEFINE_CGI_PARAM_NO_RADIO("hide-user-agent", ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT, "Privoxy/3.0 (Anonymous)") -DEFINE_ACTION_BOOL ("kill-popups", ACTION_NO_POPUPS) -DEFINE_ACTION_STRING ("limit-connect", ACTION_LIMIT_CONNECT, ACTION_STRING_LIMIT_CONNECT) -DEFINE_CGI_PARAM_NO_RADIO("limit-connect", ACTION_LIMIT_CONNECT, ACTION_STRING_LIMIT_CONNECT, "443") -DEFINE_ACTION_BOOL ("prevent-compression", ACTION_NO_COMPRESSION) -DEFINE_ACTION_BOOL ("send-vanilla-wafer", ACTION_VANILLA_WAFER) -DEFINE_ACTION_MULTI ("send-wafer", ACTION_MULTI_WAFER) -DEFINE_ACTION_BOOL ("session-cookies-only", ACTION_NO_COOKIE_KEEP) -DEFINE_ACTION_STRING ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER) -DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "pattern", 1) -DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "blank", 0) -DEFINE_CGI_PARAM_CUSTOM ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, CGI_PREFIX "show-banner?type=pattern") - - -#if DEFINE_ACTION_ALIAS - -/* - * Alternative spellings - */ -DEFINE_ACTION_BOOL ("kill-popup", ACTION_NO_POPUPS) -DEFINE_ACTION_STRING ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER) -DEFINE_ACTION_BOOL ("prevent-keeping-cookies", ACTION_NO_COOKIE_KEEP) - -/* - * Pre-3.0 compatibility - */ -DEFINE_ACTION_BOOL ("prevent-reading-cookies", ACTION_NO_COOKIE_READ) -DEFINE_ACTION_BOOL ("prevent-setting-cookies", ACTION_NO_COOKIE_SET) -DEFINE_ACTION_BOOL ("downgrade", ACTION_DOWNGRADE) -DEFINE_ACTION_BOOL ("hide-forwarded", ACTION_HIDE_FORWARDED) -DEFINE_ACTION_STRING ("hide-from", ACTION_HIDE_FROM, ACTION_STRING_FROM) -DEFINE_ACTION_BOOL ("image", ACTION_IMAGE) -DEFINE_ACTION_STRING ("image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER) -DEFINE_ACTION_BOOL ("no-compression", ACTION_NO_COMPRESSION) -DEFINE_ACTION_BOOL ("no-cookies-keep", ACTION_NO_COOKIE_KEEP) -DEFINE_ACTION_BOOL ("no-cookies-read", ACTION_NO_COOKIE_READ) -DEFINE_ACTION_BOOL ("no-cookies-set", ACTION_NO_COOKIE_SET) -DEFINE_ACTION_BOOL ("no-popups", ACTION_NO_POPUPS) -#endif /* if DEFINE_ACTION_ALIAS */ - -#undef DEFINE_ACTION_MULTI -#undef DEFINE_ACTION_STRING -#undef DEFINE_ACTION_BOOL -#undef DEFINE_ACTION_ALIAS -#undef DEFINE_CGI_PARAM_CUSTOM -#undef DEFINE_CGI_PARAM_RADIO -#undef DEFINE_CGI_PARAM_NO_RADIO - diff --git a/actions.c b/actions.c deleted file mode 100644 index 01f2c4a3..00000000 --- a/actions.c +++ /dev/null @@ -1,1656 +0,0 @@ -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 "
-", some "
-" (note the space). - * Standardizing on no space. - * - Greatly simplifying some of the code by using string_join() - * where appropriate. - * - * Revision 1.28 2002/04/26 12:53:15 oes - * - CGI AF editor now writes action lines split into - * single lines with line continuation - * - actions_to_html now embeds each action name in - * link to chapter - * - current_action_to_text is now called current_action_to_html - * and acts like actions_to_html - * - * Revision 1.27 2002/04/24 02:10:31 oes - * - Jon's patch for multiple AFs: - * - split load_actions_file, add load_one_actions_file - * - make csp->actions_list files an array - * - remember file id with each action - * - Copy_action now frees dest action before copying - * - * Revision 1.26 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.25 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.24 2002/03/16 23:54:06 jongfoster - * Adding graceful termination feature, to help look for memory leaks. - * If you enable this (which, by design, has to be done by hand - * editing config.h) and then go to http://i.j.b/die, then the program - * will exit cleanly after the *next* request. It should free all the - * memory that was used. - * - * Revision 1.23 2002/03/07 03:46:16 oes - * Fixed compiler warnings - * - * Revision 1.22 2002/01/21 00:27:02 jongfoster - * Allowing free_action(NULL). - * Moving the functions that #include actionlist.h to the end of the file, - * because the Visual C++ 97 debugger gets extremely confused if you try - * to debug any code that comes after them in the file. - * - * Revision 1.21 2002/01/17 20:54:44 jongfoster - * Renaming free_url to free_url_spec, since it frees a struct url_spec. - * - * Revision 1.20 2001/11/22 21:56:49 jongfoster - * Making action_spec->flags into an unsigned long rather than just an - * unsigned int. - * Fixing a bug in the display of -add-header and -wafer - * - * Revision 1.19 2001/11/13 00:14:07 jongfoster - * Fixing stupid bug now I've figured out what || means. - * (It always returns 0 or 1, not one of it's paramaters.) - * - * Revision 1.18 2001/11/07 00:06:06 steudten - * Add line number in error output for lineparsing for - * actionsfile. - * - * Revision 1.17 2001/10/25 03:40:47 david__schmidt - * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple - * threads to call select() simultaneously. So, it's time to do a real, live, - * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__ - * (native). Both versions will work, but using __OS2__ offers multi-threading. - * - * Revision 1.16 2001/10/23 21:30:30 jongfoster - * Adding error-checking to selected functions. - * - * Revision 1.15 2001/10/14 21:58:22 jongfoster - * Adding support for the CGI-based editor: - * - Exported get_actions() - * - Added new function free_alias_list() - * - Added support for {{settings}} and {{description}} blocks - * in the actions file. They are currently ignored. - * - Added restriction to only one {{alias}} block which must appear - * first in the file, to simplify the editor's rewriting rules. - * - Note that load_actions_file() is no longer used by the CGI-based - * editor, but some of the other routines in this file are. - * - * Revision 1.14 2001/09/22 16:36:59 jongfoster - * Removing unused parameter fs from read_config_line() - * - * Revision 1.13 2001/09/16 15:47:37 jongfoster - * First version of CGI-based edit interface. This is very much a - * work-in-progress, and you can't actually use it to edit anything - * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes - * to have any effect. - * - * Revision 1.12 2001/09/16 13:21:27 jongfoster - * Changes to use new list functions. - * - * Revision 1.11 2001/09/14 00:17:32 jongfoster - * Tidying up memory allocation. New function init_action(). - * - * Revision 1.10 2001/09/10 10:14:34 oes - * Removing unused variable - * - * Revision 1.9 2001/07/30 22:08:36 jongfoster - * Tidying up #defines: - * - All feature #defines are now of the form FEATURE_xxx - * - Permanently turned off WIN_GUI_EDIT - * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS - * - * Revision 1.8 2001/06/29 13:19:52 oes - * Removed logentry from cancelled commit - * - * Revision 1.7 2001/06/09 10:55:28 jongfoster - * Changing BUFSIZ ==> BUFFER_SIZE - * - * Revision 1.6 2001/06/07 23:04:34 jongfoster - * Made get_actions() static. - * - * Revision 1.5 2001/06/03 19:11:48 oes - * adapted to new enlist_unique arg format - * - * Revision 1.4 2001/06/01 20:03:42 jongfoster - * Better memory management - current_action->strings[] now - * contains copies of the strings, not the original. - * - * Revision 1.3 2001/06/01 18:49:17 jongfoster - * Replaced "list_share" with "list" - the tiny memory gain was not - * worth the extra complexity. - * - * Revision 1.2 2001/05/31 21:40:00 jongfoster - * Removing some commented out, obsolete blocks of code. - * - * Revision 1.1 2001/05/31 21:16:46 jongfoster - * Moved functions to process the action list into this new file. - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include - -#include "project.h" -#include "jcc.h" -#include "list.h" -#include "actions.h" -#include "miscutil.h" -#include "errlog.h" -#include "loaders.h" -#include "encode.h" -#include "urlmatch.h" -#include "cgi.h" - -const char actions_h_rcs[] = ACTIONS_H_VERSION; - - -/* - * We need the main list of options. - * - * First, we need a way to tell between boolean, string, and multi-string - * options. For string and multistring options, we also need to be - * able to tell the difference between a "+" and a "-". (For bools, - * the "+"/"-" information is encoded in "add" and "mask"). So we use - * an enumerated type (well, the preprocessor equivalent). Here are - * the values: - */ -#define AV_NONE 0 /* +opt -opt */ -#define AV_ADD_STRING 1 /* +stropt{string} */ -#define AV_REM_STRING 2 /* -stropt */ -#define AV_ADD_MULTI 3 /* +multiopt{string} +multiopt{string2} */ -#define AV_REM_MULTI 4 /* -multiopt{string} -multiopt */ - -/* - * We need a structure to hold the name, flag changes, - * type, and string index. - */ -struct action_name -{ - const char * name; - unsigned 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
-seperated HTML string - * in which each action is linked to its chapter in - * the user manual. - * - * Parameters : - * 1 : csp = Client state (for config) - * 2 : action = Action spec to be converted - * - * Returns : A string. Caller must free it. - * NULL on out-of-memory error. - * - *********************************************************************/ -char * actions_to_html(struct client_state *csp, - struct action_spec *action) -{ - unsigned mask = action->mask; - unsigned add = action->add; - char * result = strdup(""); - struct list_entry * lst; - - /* sanity - prevents "-feature +feature" */ - mask |= add; - - -#define DEFINE_ACTION_BOOL(__name, __bit) \ - if (!(mask & __bit)) \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } \ - else if (add & __bit) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } - -#define DEFINE_ACTION_STRING(__name, __bit, __index) \ - if (!(mask & __bit)) \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } \ - else if (add & __bit) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - string_append(&result, "{"); \ - string_join(&result, html_encode(action->string[__index])); \ - string_append(&result, "}"); \ - } - -#define DEFINE_ACTION_MULTI(__name, __index) \ - if (action->multi_remove_all[__index]) \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } \ - else \ - { \ - lst = action->multi_remove[__index]->first; \ - while (lst) \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - string_append(&result, "{"); \ - string_join(&result, html_encode(lst->str)); \ - string_append(&result, "}"); \ - lst = lst->next; \ - } \ - } \ - lst = action->multi_add[__index]->first; \ - while (lst) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - string_append(&result, "{"); \ - string_join(&result, html_encode(lst->str)); \ - string_append(&result, "}"); \ - lst = lst->next; \ - } - -#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */ - -#include "actionlist.h" - -#undef DEFINE_ACTION_MULTI -#undef DEFINE_ACTION_STRING -#undef DEFINE_ACTION_BOOL -#undef DEFINE_ACTION_ALIAS - - /* trim leading
*/ - if (result && *result) - { - char * s = result; - result = strdup(result + 5); - free(s); - } - - return result; -} - - -/********************************************************************* - * - * Function : current_actions_to_html - * - * Description : Converts a curren action spec to a
seperated HTML - * text in which each action is linked to its chapter in - * the user manual. - * - * Parameters : - * 1 : csp = Client state (for config) - * 2 : action = Current action spec to be converted - * - * Returns : A string. Caller must free it. - * NULL on out-of-memory error. - * - *********************************************************************/ -char *current_action_to_html(struct client_state *csp, - struct current_action_spec *action) -{ - unsigned long flags = action->flags; - char * result = strdup(""); - struct list_entry * lst; - -#define DEFINE_ACTION_BOOL(__name, __bit) \ - if (flags & __bit) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } \ - else \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } - -#define DEFINE_ACTION_STRING(__name, __bit, __index) \ - if (flags & __bit) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - string_append(&result, "{"); \ - string_join(&result, html_encode(action->string[__index])); \ - string_append(&result, "}"); \ - } \ - else \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } - -#define DEFINE_ACTION_MULTI(__name, __index) \ - lst = action->multi[__index]->first; \ - if (lst == NULL) \ - { \ - string_append(&result, "\n
-"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - } \ - else \ - { \ - while (lst) \ - { \ - string_append(&result, "\n
+"); \ - string_join(&result, add_help_link(__name, csp->config)); \ - string_append(&result, "{"); \ - string_join(&result, html_encode(lst->str)); \ - string_append(&result, "}"); \ - lst = lst->next; \ - } \ - } - -#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */ - -#include "actionlist.h" - -#undef DEFINE_ACTION_MULTI -#undef DEFINE_ACTION_STRING -#undef DEFINE_ACTION_BOOL -#undef DEFINE_ACTION_ALIAS - - return result; -} diff --git a/actions.h b/actions.h deleted file mode 100644 index f4365f0e..00000000 --- a/actions.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef ACTIONS_H_INCLUDED -#define ACTIONS_H_INCLUDED -#define ACTIONS_H_VERSION "$Id: actions.h,v 1.11 2002/04/30 11:14:52 oes Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/actions.h,v $ - * - * Purpose : Declares functions to work with actions files - * Functions declared include: FIXME - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: actions.h,v $ - * Revision 1.11 2002/04/30 11:14:52 oes - * Made csp the first parameter in *action_to_html - * - * Revision 1.10 2002/04/26 12:53:33 oes - * - actions_to_html signature change - * - current_action_to_text: renamed to current_action_to_html - * and signature change - * - * Revision 1.9 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.8 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.7 2002/03/16 23:54:06 jongfoster - * Adding graceful termination feature, to help look for memory leaks. - * If you enable this (which, by design, has to be done by hand - * editing config.h) and then go to http://i.j.b/die, then the program - * will exit cleanly after the *next* request. It should free all the - * memory that was used. - * - * Revision 1.6 2001/10/23 21:30:30 jongfoster - * Adding error-checking to selected functions. - * - * Revision 1.5 2001/10/14 21:58:22 jongfoster - * Adding support for the CGI-based editor: - * - Exported get_actions() - * - Added new function free_alias_list() - * - Added support for {{settings}} and {{description}} blocks - * in the actions file. They are currently ignored. - * - Added restriction to only one {{alias}} block which must appear - * first in the file, to simplify the editor's rewriting rules. - * - Note that load_actions_file() is no longer used by the CGI-based - * editor, but some of the other routines in this file are. - * - * Revision 1.4 2001/09/16 15:47:37 jongfoster - * First version of CGI-based edit interface. This is very much a - * work-in-progress, and you can't actually use it to edit anything - * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes - * to have any effect. - * - * Revision 1.3 2001/09/14 00:17:32 jongfoster - * Tidying up memory allocation. New function init_action(). - * - * Revision 1.2 2001/07/29 19:01:11 jongfoster - * Changed _FILENAME_H to FILENAME_H_INCLUDED. - * Added forward declarations for needed structures. - * - * Revision 1.1 2001/05/31 21:16:46 jongfoster - * Moved functions to process the action list into this new file. - * - * - *********************************************************************/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -struct action_spec; -struct current_action_spec; -struct client_state; - - - -/* This structure is used to hold user-defined aliases */ -struct action_alias -{ - const char * name; - struct action_spec action[1]; - struct action_alias * next; -}; - - -extern jb_err get_actions (char *line, - struct action_alias * alias_list, - struct action_spec *cur_action); -extern void free_alias_list(struct action_alias *alias_list); - -extern void init_action(struct action_spec *dest); -extern void free_action(struct action_spec *src); -extern jb_err merge_actions (struct action_spec *dest, - const struct action_spec *src); -extern jb_err copy_action (struct action_spec *dest, - const struct action_spec *src); -extern char * actions_to_text (struct action_spec *action); -extern char * actions_to_html (struct client_state *csp, - struct action_spec *action); -extern void init_current_action (struct current_action_spec *dest); -extern void free_current_action (struct current_action_spec *src); -extern jb_err merge_current_action (struct current_action_spec *dest, - const struct action_spec *src); -extern char * current_action_to_html(struct client_state *csp, - struct current_action_spec *action); - -extern jb_err get_action_token(char **line, char **name, char **value); -extern void unload_actions_file(void *file_data); -extern int load_actions_file(struct client_state *csp); - -#ifdef FEATURE_GRACEFUL_TERMINATION -void unload_current_actions_file(void); -#endif - - -/* Revision control strings from this header and associated .c file */ -extern const char actions_rcs[]; -extern const char actions_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef ACTIONS_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ - diff --git a/amiga.c b/amiga.c deleted file mode 100644 index 493a00eb..00000000 --- a/amiga.c +++ /dev/null @@ -1,283 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#ifdef AMIGA - -#include -#include - -#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 */ diff --git a/amiga.h b/amiga.h deleted file mode 100644 index 580dc32d..00000000 --- a/amiga.h +++ /dev/null @@ -1,123 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#define _KERNEL -#include -#undef _KERNEL - -#define __NOLIBBASE__ -#include -#undef __NOLIBBASE__ - -#define __CONSTLIBBASEDECL__ const -#define DEVICES_TIMER_H -#include -#include -#include -#include - -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 */ diff --git a/cgi.c b/cgi.c deleted file mode 100644 index 4a523b21..00000000 --- a/cgi.c +++ /dev/null @@ -1,2166 +0,0 @@ -const char cgi_rcs[] = "$Id: cgi.c,v 1.69 2002/05/14 21:28:40 oes Exp $"; -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/cgi.c,v $ - * - * Purpose : Declares functions to intercept request, generate - * html or gif answers, and to compose HTTP resonses. - * This only contains the framework functions, the - * actual handler functions are declared elsewhere. - * - * Functions declared include: - * - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: cgi.c,v $ - * Revision 1.69 2002/05/14 21:28:40 oes - * - Fixed add_help_link to link to the (now split) actions - * part of the config chapter - * - Renamed helplink export to actions-help-prefix - * - * Revision 1.68 2002/05/12 21:36:29 jongfoster - * Correcting function comments - * - * Revision 1.67 2002/04/30 12:02:07 oes - * Nit: updated a comment - * - * Revision 1.66 2002/04/26 18:32:57 jongfoster - * Fixing a memory leak on error - * - * Revision 1.65 2002/04/26 12:53:51 oes - * - New function add_help_link - * - default_exports now exports links to the user manual - * and a prefix for links into the config chapter - * - * Revision 1.64 2002/04/24 02:17:21 oes - * - Better descriptions for CGIs - * - Hide edit-actions, more shortcuts - * - Moved get_char_param, get_string_param and get_number_param here - * from cgiedit.c - * - * Revision 1.63 2002/04/15 19:06:43 jongfoster - * Typos - * - * Revision 1.62 2002/04/10 19:59:46 jongfoster - * Fixes to #include in templates: - * - Didn't close main file if loading an included template fails. - * - I'm paranoid and want to disallow "#include /etc/passwd". - * - * Revision 1.61 2002/04/10 13:37:48 oes - * Made templates modular: template_load now recursive with max depth 1 - * - * Revision 1.60 2002/04/08 20:50:25 swa - * fixed JB spelling - * - * Revision 1.59 2002/04/05 15:51:51 oes - * - added send-stylesheet CGI - * - bugfix: error-pages now get correct request protocol - * - fixed - * - kludged CGI descriptions and menu not to break JS syntax - * - * Revision 1.58 2002/03/29 03:33:13 david__schmidt - * Fix Mac OSX compiler warnings - * - * Revision 1.57 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.56 2002/03/24 17:50:46 jongfoster - * Fixing compile error if actions file editor disabled - * - * Revision 1.55 2002/03/24 16:55:06 oes - * Making GIF checkerboard transparent - * - * Revision 1.54 2002/03/24 16:18:15 jongfoster - * Removing old logo - * - * Revision 1.53 2002/03/24 16:06:00 oes - * Correct transparency for checkerboard PNG. Thanks, Magnus! - * - * Revision 1.52 2002/03/24 15:23:33 jongfoster - * Name changes - * - * Revision 1.51 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.50 2002/03/16 23:54:06 jongfoster - * Adding graceful termination feature, to help look for memory leaks. - * If you enable this (which, by design, has to be done by hand - * editing config.h) and then go to http://i.j.b/die, then the program - * will exit cleanly after the *next* request. It should free all the - * memory that was used. - * - * Revision 1.49 2002/03/13 00:27:04 jongfoster - * Killing warnings - * - * Revision 1.48 2002/03/08 17:47:07 jongfoster - * Adding comments - * - * Revision 1.47 2002/03/08 16:41:33 oes - * Added GIF images again - * - * Revision 1.46 2002/03/07 03:48:38 oes - * - Changed built-in images from GIF to PNG - * (with regard to Unisys patent issue) - * - Added a 4x4 pattern PNG which is less intrusive - * than the logo but also clearly marks the deleted banners - * - * Revision 1.45 2002/03/06 22:54:35 jongfoster - * Automated function-comment nitpicking. - * - * Revision 1.44 2002/03/05 22:43:45 david__schmidt - * - Better error reporting on OS/2 - * - Fix double-slash comment (oops) - * - * Revision 1.43 2002/03/05 21:33:45 david__schmidt - * - Re-enable OS/2 building after new parms were added - * - Fix false out of memory report when resolving CGI templates when no IP - * address is available of failed attempt (a la no such domain) - * - * Revision 1.42 2002/01/21 00:33:20 jongfoster - * Replacing strsav() with the safer string_append() or string_join(). - * Adding map_block_keep() to save a few bytes in the edit-actions-list HTML. - * Adding missing html_encode() to error message generators. - * Adding edit-actions-section-swap and many "shortcuts" to the list of CGIs. - * - * Revision 1.41 2002/01/17 20:56:22 jongfoster - * Replacing hard references to the URL of the config interface - * with #defines from project.h - * - * Revision 1.40 2002/01/09 14:26:46 oes - * Added support for thread-safe gmtime_r call. - * - * Revision 1.39 2001/11/16 00:48:13 jongfoster - * Fixing a compiler warning - * - * Revision 1.38 2001/11/13 00:31:21 jongfoster - * - Adding new CGIs for use by non-JavaScript browsers: - * edit-actions-url-form - * edit-actions-add-url-form - * edit-actions-remove-url-form - * - Fixing make_menu()'s HTML generation - it now quotes the href parameter. - * - Fixing || bug. - * - * Revision 1.37 2001/11/01 14:28:47 david__schmidt - * Show enablement/disablement status in almost all templates. - * There is a little trickiness here: apparent recursive resolution of - * @if-enabled-then@ caused the toggle template to show status out-of-phase with - * the actual enablement status. So a similar construct, - * @if-enabled-display-then@, is used to resolve the status display on non-'toggle' - * templates. - * - * Revision 1.36 2001/10/26 17:33:27 oes - * marginal bugfix - * - * Revision 1.35 2001/10/23 21:48:19 jongfoster - * Cleaning up error handling in CGI functions - they now send back - * a HTML error page and should never cause a FATAL error. (Fixes one - * potential source of "denial of service" attacks). - * - * CGI actions file editor that works and is actually useful. - * - * Ability to toggle Junkbuster remotely using a CGI call. - * - * You can turn off both the above features in the main configuration - * file, e.g. if you are running a multi-user proxy. - * - * Revision 1.34 2001/10/18 22:22:09 david__schmidt - * Only show "Local support" on templates conditionally: - * - if either 'admin-address' or 'proxy-info-url' are uncommented in config - * - if not, no Local support section appears - * - * Revision 1.33 2001/10/14 22:28:41 jongfoster - * Fixing stupid typo. - * - * Revision 1.32 2001/10/14 22:20:18 jongfoster - * - Changes to CGI dispatching method to match CGI names exactly, - * rather than doing a prefix match. - * - No longer need to count the length of the CGI handler names by hand. - * - Adding new handler for 404 error when disptching a CGI, if none of - * the handlers match. - * - Adding new handlers for CGI actionsfile editor. - * - * Revision 1.31 2001/10/10 10:56:39 oes - * Failiure to load template now fatal. Before, the user got a hard-to-understand assertion failure from cgi.c - * - * Revision 1.30 2001/10/02 15:30:57 oes - * Introduced show-request cgi - * - * Revision 1.29 2001/09/20 15:47:44 steudten - * - * Fix BUG: Modify int size to size_t size in fill_template() - * - removes big trouble on machines where sizeof(int) != sizeof(size_t). - * - * Revision 1.28 2001/09/19 18:00:37 oes - * - Deletef time() FIXME (Can't fail under Linux either, if - * the argument is guaranteed to be in out address space, - * which it is.) - * - Fixed comments - * - Pointer notation cosmetics - * - Fixed a minor bug in template_fill(): Failiure of - * pcrs_execute() now secure. - * - * Revision 1.27 2001/09/16 17:08:54 jongfoster - * Moving simple CGI functions from cgi.c to new file cgisimple.c - * - * Revision 1.26 2001/09/16 15:47:37 jongfoster - * First version of CGI-based edit interface. This is very much a - * work-in-progress, and you can't actually use it to edit anything - * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes - * to have any effect. - * - * Revision 1.25 2001/09/16 15:02:35 jongfoster - * Adding i.j.b/robots.txt. - * Inlining add_stats() since it's only ever called from one place. - * - * Revision 1.24 2001/09/16 11:38:01 jongfoster - * Splitting fill_template() into 2 functions: - * template_load() loads the file - * template_fill() performs the PCRS regexps. - * This is because the CGI edit interface has a "table row" - * template which is used many times in the page - this - * change means it's only loaded from disk once. - * - * Revision 1.23 2001/09/16 11:16:05 jongfoster - * Better error handling in dispatch_cgi() and parse_cgi_parameters() - * - * Revision 1.22 2001/09/16 11:00:10 jongfoster - * New function alloc_http_response, for symmetry with free_http_response - * - * Revision 1.21 2001/09/13 23:53:03 jongfoster - * Support for both static and dynamically generated CGI pages. - * Correctly setting Last-Modified: and Expires: HTTP headers. - * - * Revision 1.20 2001/09/13 23:40:36 jongfoster - * (Cosmetic only) Indentation correction - * - * Revision 1.19 2001/09/13 23:31:25 jongfoster - * Moving image data to cgi.c rather than cgi.h. - * - * Revision 1.18 2001/08/05 16:06:20 jongfoster - * Modifiying "struct map" so that there are now separate header and - * "map_entry" structures. This means that functions which modify a - * map no longer need to return a pointer to the modified map. - * Also, it no longer reverses the order of the entries (which may be - * important with some advanced template substitutions). - * - * Revision 1.17 2001/08/05 15:57:38 oes - * Adapted finish_http_response to new list_to_text - * - * Revision 1.16 2001/08/01 21:33:18 jongfoster - * Changes to fill_template() that reduce memory usage without having - * an impact on performance. I also renamed some variables so as not - * to clash with the C++ keywords "new" and "template". - * - * Revision 1.15 2001/08/01 21:19:22 jongfoster - * Moving file version information to a separate CGI page. - * - * Revision 1.14 2001/08/01 00:19:03 jongfoster - * New function: map_conditional() for an if-then-else syntax. - * Changing to use new version of show_defines() - * - * Revision 1.13 2001/07/30 22:08:36 jongfoster - * Tidying up #defines: - * - All feature #defines are now of the form FEATURE_xxx - * - Permanently turned off WIN_GUI_EDIT - * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS - * - * Revision 1.12 2001/07/29 18:47:05 jongfoster - * Adding missing #include "loadcfg.h" - * - * Revision 1.11 2001/07/18 17:24:37 oes - * Changed to conform to new pcrs interface - * - * Revision 1.10 2001/07/13 13:53:13 oes - * Removed all #ifdef PCRS and related code - * - * Revision 1.9 2001/06/29 21:45:41 oes - * Indentation, CRLF->LF, Tab-> Space - * - * Revision 1.8 2001/06/29 13:21:46 oes - * - Cosmetics: renamed and reordered functions, variables, - * texts, improved comments etc - * - * - Removed ij_untrusted_url() The relevant - * info is now part of the "untrusted" page, - * which is generated by filters.c:trust_url() - * - * - Generators of content now call finish_http_response() - * themselves, making jcc.c:chat() a little less - * cluttered - * - * - Removed obsolete "Pragma: no-cache" from our headers - * - * - http_responses now know their head length - * - * - fill_template now uses the new interface to pcrs, so that - * - long jobs (like whole files) no longer have to be assembled - * in a fixed size buffer - * - the new T (trivial) option is used, and the replacement may - * contain Perl syntax backrefs without confusing pcrs - * - * - Introduced default_exports() which generates a set of exports - * common to all CGIs and other content generators - * - * - Introduced convenience function map_block_killer() - * - * - Introduced convenience function make_menu() - * - * - Introduced CGI-like function error_response() which generates - * the "No such domain" and "Connect failed" messages using the - * CGI platform - * - * - cgi_show_url_info: - * - adapted to new CGI features - * - form and answers now generated from same template - * - http:// prefix in URL now OK - * - * - cgi_show_status: - * - adapted to new CGI features - * - no longer uses csp->init_proxy_args - * - * - cgi_default: - * - moved menu generation to make_menu() - * - * - add_stats now writes single export map entries instead - * of a fixed string - * - * - Moved redirect_url() to filters.c - * - * - Fixed mem leak in free_http_response(), map_block_killer(), - * - * - Removed logentry from cancelled commit - * - * Revision 1.7 2001/06/09 10:51:58 jongfoster - * Changing "show URL info" handler to new style. - * Changing BUFSIZ ==> BUFFER_SIZE - * - * Revision 1.6 2001/06/07 23:05:19 jongfoster - * Removing code related to old forward and ACL files. - * - * Revision 1.5 2001/06/05 19:59:16 jongfoster - * Fixing multiline character string (a GCC-only "feature"), and snprintf (it's _snprintf under VC++). - * - * Revision 1.4 2001/06/04 10:41:52 swa - * show version string of cgi.h and cgi.c - * - * Revision 1.3 2001/06/03 19:12:16 oes - * introduced new cgi handling - * - * No revisions before 1.3 - * - **********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#define snprintf _snprintf -#endif /* def _WIN32 */ - -#include "project.h" -#include "cgi.h" -#include "list.h" -#include "encode.h" -#include "ssplit.h" -#include "errlog.h" -#include "miscutil.h" -#include "cgisimple.h" -#ifdef FEATURE_CGI_EDIT_ACTIONS -#include "cgiedit.h" -#endif /* def FEATURE_CGI_EDIT_ACTIONS */ -#include "loadcfg.h" -/* loadcfg.h is for g_bToggleIJB only */ - -const char cgi_h_rcs[] = CGI_H_VERSION; - -/* - * List of CGI functions: name, handler, description - * Note: Do NOT use single quotes in the description; - * this will break the dynamic "blocked" template! - */ -static const struct cgi_dispatcher cgi_dispatchers[] = { - { "", - cgi_default, - "Privoxy main page" }, -#ifdef FEATURE_GRACEFUL_TERMINATION - { "die", - cgi_die, - "Shut down - Do not deploy this build in a production environment, " - "this is a one click Denial Of Service attack!!!" }, -#endif - { "show-status", - cgi_show_status, - "View & change the current configuration" }, - { "show-version", - cgi_show_version, - "View the source code version numbers" }, - { "show-request", - cgi_show_request, - "View the request headers." }, - { "show-url-info", - cgi_show_url_info, - "Look up which actions apply to a URL and why" }, -#ifdef FEATURE_CGI_EDIT_ACTIONS - { "toggle", - cgi_toggle, - "Toggle Privoxy on or off" }, - - { "edit-actions", /* Edit the actions list */ - cgi_edit_actions, - NULL }, - { "eaa", /* Shortcut for edit-actions-add-url-form */ - cgi_edit_actions_add_url_form, - NULL }, - { "eau", /* Shortcut for edit-actions-url-form */ - cgi_edit_actions_url_form, - NULL }, - { "ear", /* Shortcut for edit-actions-remove-url-form */ - cgi_edit_actions_remove_url_form, - NULL }, - { "eafu", /* Shortcut for edit-actions-for-url */ - cgi_edit_actions_for_url, - NULL }, - { "eas", /* Shortcut for edit-actions-submit */ - cgi_edit_actions_submit, - NULL }, - { "easa", /* Shortcut for edit-actions-section-add */ - cgi_edit_actions_section_add, - NULL }, - { "easr", /* Shortcut for edit-actions-section-remove */ - cgi_edit_actions_section_remove, - NULL }, - { "eass", /* Shortcut for edit-actions-section-swap */ - cgi_edit_actions_section_swap, - NULL }, - { "edit-actions-for-url", - cgi_edit_actions_for_url, - NULL /* Edit the actions for (a) specified URL(s) */ }, - { "edit-actions-list", - cgi_edit_actions_list, - NULL /* Edit the actions list */ }, - { "edit-actions-submit", - cgi_edit_actions_submit, - NULL /* Change the actions for (a) specified URL(s) */ }, - { "edit-actions-url", - cgi_edit_actions_url, - NULL /* Change a URL pattern in the actionsfile */ }, - { "edit-actions-url-form", - cgi_edit_actions_url_form, - NULL /* Form to change a URL pattern in the actionsfile */ }, - { "edit-actions-add-url", - cgi_edit_actions_add_url, - NULL /* Add a URL pattern to the actionsfile */ }, - { "edit-actions-add-url-form", - cgi_edit_actions_add_url_form, - NULL /* Form to add a URL pattern to the actionsfile */ }, - { "edit-actions-remove-url", - cgi_edit_actions_remove_url, - NULL /* Remove a URL pattern from the actionsfile */ }, - { "edit-actions-remove-url-form", - cgi_edit_actions_remove_url_form, - NULL /* Form to remove a URL pattern from the actionsfile */ }, - { "edit-actions-section-add", - cgi_edit_actions_section_add, - NULL /* Remove a section from the actionsfile */ }, - { "edit-actions-section-remove", - cgi_edit_actions_section_remove, - NULL /* Remove a section from the actionsfile */ }, - { "edit-actions-section-swap", - cgi_edit_actions_section_swap, - NULL /* Swap two sections in the actionsfile */ }, -#endif /* def FEATURE_CGI_EDIT_ACTIONS */ - { "robots.txt", - cgi_robots_txt, - NULL /* Sends a robots.txt file to tell robots to go away. */ }, - { "send-banner", - cgi_send_banner, - NULL /* Send a built-in image */ }, - { "send-stylesheet", - cgi_send_stylesheet, - NULL /* Send templates/cgi-style.css */ }, - { "t", - cgi_transparent_image, - NULL /* Send a transparent image (short name) */ }, - { NULL, /* NULL Indicates end of list and default page */ - cgi_error_404, - NULL /* Unknown CGI page */ } -}; - - -/* - * Bulit-in images for ad replacement - * - * Hint: You can encode your own images like this: - * cat your-image | perl -e 'while (read STDIN, $c, 1) { printf("\\%.3o", unpack("C", $c)); }' - */ - -#ifdef FEATURE_NO_GIFS - -/* - * Checkerboard pattern, as a PNG. - */ -const char image_pattern_data[] = - "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104" - "\122\000\000\000\004\000\000\000\004\010\002\000\000\000\046" - "\223\011\051\000\000\000\006\142\113\107\104\000\310\000\310" - "\000\310\052\045\225\037\000\000\000\032\111\104\101\124\170" - "\332\143\070\161\342\304\377\377\377\041\044\003\234\165\342" - "\304\011\006\234\062\000\125\200\052\251\125\174\360\223\000" - "\000\000\000\111\105\116\104\256\102\140\202"; - -/* - * 1x1 transparant PNG. - */ -const char image_blank_data[] = - "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104\122" - "\000\000\000\004\000\000\000\004\010\006\000\000\000\251\361\236" - "\176\000\000\000\007\164\111\115\105\007\322\003\013\020\073\070" - "\013\025\036\203\000\000\000\011\160\110\131\163\000\000\013\022" - "\000\000\013\022\001\322\335\176\374\000\000\000\004\147\101\115" - "\101\000\000\261\217\013\374\141\005\000\000\000\033\111\104\101" - "\124\170\332\143\070\161\342\304\207\377\377\377\347\302\150\006" - "\144\016\210\146\040\250\002\000\042\305\065\221\270\027\131\110" - "\000\000\000\000\111\105\116\104\256\102\140\202"; -#else - -/* - * Checkerboard pattern, as a GIF. - */ -const char image_pattern_data[] = - "\107\111\106\070\071\141\004\000\004\000\200\000\000\310\310" - "\310\377\377\377\041\376\016\111\040\167\141\163\040\141\040" - "\142\141\156\156\145\162\000\041\371\004\001\012\000\001\000" - "\054\000\000\000\000\004\000\004\000\000\002\005\104\174\147" - "\270\005\000\073"; - -/* - * 1x1 transparant GIF. - */ -const char image_blank_data[] = - "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000" - "\000!\371\004\001\000\000\000\000,\000\000\000\000\001" - "\000\001\000\000\002\002D\001\000;"; -#endif - -const size_t image_pattern_length = sizeof(image_pattern_data) - 1; -const size_t image_blank_length = sizeof(image_blank_data) - 1; - - -static struct http_response cgi_error_memory_response[1]; - -static struct http_response *dispatch_known_cgi(struct client_state * csp, - const char * path); -static struct map *parse_cgi_parameters(char *argstring); - - -/********************************************************************* - * - * Function : dispatch_cgi - * - * Description : Checks if a request URL has either the magical - * hostname CGI_SITE_1_HOST (usually http://p.p/) or - * matches CGI_SITE_2_HOST CGI_SITE_2_PATH (usually - * http://config.privoxy.org/). If so, it passes - * the (rest of the) path onto dispatch_known_cgi, which - * calls the relevant CGI handler function. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * - * Returns : http_response if match, NULL if nonmatch or handler fail - * - *********************************************************************/ -struct http_response *dispatch_cgi(struct client_state *csp) -{ - const char *host = csp->http->host; - const char *path = csp->http->path; - - /* - * Should we intercept ? - */ - - /* Note: "example.com" and "example.com." are equivalent hostnames. */ - - /* Either the host matches CGI_SITE_1_HOST ..*/ - if ( ( (0 == strcmpic(host, CGI_SITE_1_HOST)) - || (0 == strcmpic(host, CGI_SITE_1_HOST "."))) - && (path[0] == '/') ) - { - /* ..then the path will all be for us. Remove leading '/' */ - path++; - } - /* Or it's the host part CGI_SITE_2_HOST, and the path CGI_SITE_2_PATH */ - else if ( ( (0 == strcmpic(host, CGI_SITE_2_HOST )) - || (0 == strcmpic(host, CGI_SITE_2_HOST ".")) ) - && (0 == strncmpic(path, CGI_SITE_2_PATH, strlen(CGI_SITE_2_PATH))) ) - { - /* take everything following CGI_SITE_2_PATH */ - path += strlen(CGI_SITE_2_PATH); - if (*path == '/') - { - /* skip the forward slash after CGI_SITE_2_PATH */ - path++; - } - else if (*path != '\0') - { - /* - * wierdness: URL is /configXXX, where XXX is some string - * Do *NOT* intercept. - */ - return NULL; - } - } - else - { - /* Not a CGI */ - return NULL; - } - - /* - * This is a CGI call. - */ - - return dispatch_known_cgi(csp, path); -} - - -/********************************************************************* - * - * Function : dispatch_known_cgi - * - * Description : Processes a CGI once dispatch_cgi has determined that - * it matches one of the magic prefixes. Parses the path - * as a cgi name plus query string, prepares a map that - * maps CGI parameter names to their values, initializes - * the http_response struct, and calls the relevant CGI - * handler function. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : path = Path of CGI, with the CGI prefix removed. - * Should not have a leading "/". - * - * Returns : http_response, or NULL on handler failure or out of - * memory. - * - *********************************************************************/ -static struct http_response *dispatch_known_cgi(struct client_state * csp, - const char * path) -{ - const struct cgi_dispatcher *d; - struct map *param_list; - struct http_response *rsp; - char *query_args_start; - char *path_copy; - jb_err err; - - if (NULL == (path_copy = strdup(path))) - { - return cgi_error_memory(); - } - - query_args_start = path_copy; - while (*query_args_start && *query_args_start != '?') - { - query_args_start++; - } - if (*query_args_start == '?') - { - *query_args_start++ = '\0'; - } - - if (NULL == (param_list = parse_cgi_parameters(query_args_start))) - { - free(path_copy); - return cgi_error_memory(); - } - - - /* - * At this point: - * path_copy = CGI call name - * param_list = CGI params, as map - */ - - /* Get mem for response or fail*/ - if (NULL == (rsp = alloc_http_response())) - { - free(path_copy); - free_map(param_list); - return cgi_error_memory(); - } - - log_error(LOG_LEVEL_GPC, "%s%s cgi call", csp->http->hostport, csp->http->path); - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 3", - csp->ip_addr_str, csp->http->cmd); - - /* Find and start the right CGI function*/ - d = cgi_dispatchers; - for (;;) - { - if ((d->name == NULL) || (strcmp(path_copy, d->name) == 0)) - { - err = (d->handler)(csp, rsp, param_list); - free(path_copy); - free_map(param_list); - if (err == JB_ERR_CGI_PARAMS) - { - err = cgi_error_bad_param(csp, rsp); - } - if (err && (err != JB_ERR_MEMORY)) - { - /* Unexpected error! Shouldn't get here */ - log_error(LOG_LEVEL_ERROR, "Unexpected CGI error %d in top-level handler. Please file a bug report!", err); - err = cgi_error_unknown(csp, rsp, err); - } - if (!err) - { - /* It worked */ - return finish_http_response(rsp); - } - else - { - /* Error in handler, probably out-of-memory */ - free_http_response(rsp); - return cgi_error_memory(); - } - } - d++; - } -} - - -/********************************************************************* - * - * Function : parse_cgi_parameters - * - * Description : Parse a URL-encoded argument string into name/value - * pairs and store them in a struct map list. - * - * Parameters : - * 1 : argstring = string to be parsed. Will be trashed. - * - * Returns : pointer to param list, or NULL if out of memory. - * - *********************************************************************/ -static struct map *parse_cgi_parameters(char *argstring) -{ - char *p; - char *vector[BUFFER_SIZE]; - int pairs, i; - struct map *cgi_params; - - if (NULL == (cgi_params = new_map())) - { - return NULL; - } - - pairs = ssplit(argstring, "&", vector, SZ(vector), 1, 1); - - for (i = 0; i < pairs; i++) - { - if ((NULL != (p = strchr(vector[i], '='))) && (*(p+1) != '\0')) - { - *p = '\0'; - if (map(cgi_params, url_decode(vector[i]), 0, url_decode(++p), 0)) - { - free_map(cgi_params); - return NULL; - } - } - } - - return cgi_params; - -} - - -/********************************************************************* - * - * Function : get_char_param - * - * Description : Get a single-character parameter passed to a CGI - * function. - * - * Parameters : - * 1 : parameters = map of cgi parameters - * 2 : param_name = The name of the parameter to read - * - * Returns : Uppercase character on success, '\0' on error. - * - *********************************************************************/ -char get_char_param(const struct map *parameters, - const char *param_name) -{ - char ch; - - assert(parameters); - assert(param_name); - - ch = *(lookup(parameters, param_name)); - if ((ch >= 'a') && (ch <= 'z')) - { - ch = ch - 'a' + 'A'; - } - - return ch; -} - - -/********************************************************************* - * - * Function : get_string_param - * - * Description : Get a string paramater, to be used as an - * ACTION_STRING or ACTION_MULTI paramater. - * Validates the input to prevent stupid/malicious - * users from corrupting their action file. - * - * Parameters : - * 1 : parameters = map of cgi parameters - * 2 : param_name = The name of the parameter to read - * 3 : pparam = destination for paramater. Allocated as - * part of the map "parameters", so don't free it. - * Set to NULL if not specified. - * - * Returns : JB_ERR_OK on success, or if the paramater - * was not specified. - * JB_ERR_MEMORY on out-of-memory. - * JB_ERR_CGI_PARAMS if the paramater is not valid. - * - *********************************************************************/ -jb_err get_string_param(const struct map *parameters, - const char *param_name, - const char **pparam) -{ - const char *param; - const char *s; - char ch; - - assert(parameters); - assert(param_name); - assert(pparam); - - *pparam = NULL; - - param = lookup(parameters, param_name); - if (!*param) - { - return JB_ERR_OK; - } - - if (strlen(param) >= CGI_PARAM_LEN_MAX) - { - /* - * Too long. - * - * Note that the length limit is arbitrary, it just seems - * sensible to limit it to *something*. There's no - * technical reason for any limit at all. - */ - return JB_ERR_CGI_PARAMS; - } - - /* Check every character to see if it's legal */ - s = param; - while ((ch = *s++) != '\0') - { - if ( ((unsigned char)ch < (unsigned char)' ') - || (ch == '}') ) - { - /* Probable hack attempt, or user accidentally used '}'. */ - return JB_ERR_CGI_PARAMS; - } - } - - /* Success */ - *pparam = param; - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : get_number_param - * - * Description : Get a non-negative integer from the parameters - * passed to a CGI function. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : name = Name of CGI parameter to read - * 4 : pvalue = destination for value. - * Set to -1 on error. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the parameter was not specified - * or is not valid. - * - *********************************************************************/ -jb_err get_number_param(struct client_state *csp, - const struct map *parameters, - char *name, - unsigned *pvalue) -{ - const char *param; - char ch; - unsigned value; - - assert(csp); - assert(parameters); - assert(name); - assert(pvalue); - - *pvalue = 0; - - param = lookup(parameters, name); - if (!*param) - { - return JB_ERR_CGI_PARAMS; - } - - /* We don't use atoi because I want to check this carefully... */ - - value = 0; - while ((ch = *param++) != '\0') - { - if ((ch < '0') || (ch > '9')) - { - return JB_ERR_CGI_PARAMS; - } - - ch -= '0'; - - /* Note: - * - * defines UINT_MAX - * - * (UINT_MAX - ch) / 10 is the largest number that - * can be safely multiplied by 10 then have ch added. - */ - if (value > ((UINT_MAX - (unsigned)ch) / 10U)) - { - return JB_ERR_CGI_PARAMS; - } - - value = value * 10 + ch; - } - - /* Success */ - *pvalue = value; - - return JB_ERR_OK; - -} - - -/********************************************************************* - * - * Function : error_response - * - * Description : returns an http_response that explains the reason - * why a request failed. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : templatename = Which template should be used for the answer - * 3 : sys_err = system error number - * - * Returns : A http_response. If we run out of memory, this - * will be cgi_error_memory(). - * - *********************************************************************/ -struct http_response *error_response(struct client_state *csp, - const char *templatename, - int sys_err) -{ - jb_err err; - struct http_response *rsp; - struct map * exports = default_exports(csp, NULL); - if (exports == NULL) - { - return cgi_error_memory(); - } - - if (NULL == (rsp = alloc_http_response())) - { - free_map(exports); - return cgi_error_memory(); - } - - err = map(exports, "host", 1, html_encode(csp->http->host), 0); - if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0); - if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0); - if (!err) err = map(exports, "error", 1, html_encode_and_free_original(safe_strerror(sys_err)), 0); - if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); - if (!err) - { - err = map(exports, "host-ip", 1, html_encode(csp->http->host_ip_addr_str), 0); - if (err) - { - /* Some failures, like "404 no such domain", don't have an IP address. */ - err = map(exports, "host-ip", 1, html_encode(csp->http->host), 0); - } - } - - - if (err) - { - free_map(exports); - free_http_response(rsp); - return cgi_error_memory(); - } - - if (!strcmp(templatename, "no-such-domain")) - { - rsp->status = strdup("404 No such domain"); - if (rsp->status == NULL) - { - free_map(exports); - free_http_response(rsp); - return cgi_error_memory(); - } - } - else if (!strcmp(templatename, "connect-failed")) - { - rsp->status = strdup("503 Connect failed"); - if (rsp->status == NULL) - { - free_map(exports); - free_http_response(rsp); - return cgi_error_memory(); - } - } - - err = template_fill_for_cgi(csp, templatename, exports, rsp); - if (err) - { - free_http_response(rsp); - return cgi_error_memory(); - } - - return finish_http_response(rsp); -} - - -/********************************************************************* - * - * Function : cgi_init_error_messages - * - * Description : Call at the start of the program to initialize - * the error message used by cgi_error_memory(). - * - * Parameters : N/A - * - * Returns : N/A - * - *********************************************************************/ -void cgi_init_error_messages(void) -{ - memset(cgi_error_memory_response, '\0', sizeof(*cgi_error_memory_response)); - cgi_error_memory_response->head = - "HTTP/1.0 500 Internal Privoxy Error\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - cgi_error_memory_response->body = - "\r\n" - "500 Internal Privoxy Error\r\n" - "\r\n" - "

500 Internal Privoxy Error

\r\n" - "

Privoxy ran out of memory while processing your request.

\r\n" - "

Please contact your proxy administrator, or try again later

\r\n" - "\r\n" - "\r\n"; - - cgi_error_memory_response->head_length = - strlen(cgi_error_memory_response->head); - cgi_error_memory_response->content_length = - strlen(cgi_error_memory_response->body); -} - - -/********************************************************************* - * - * Function : cgi_error_memory - * - * Description : Called if a CGI function runs out of memory. - * Returns a statically-allocated error response. - * - * Parameters : N/A - * - * Returns : http_response data structure for output. This is - * statically allocated, for obvious reasons. - * - *********************************************************************/ -struct http_response *cgi_error_memory(void) -{ - /* assert that it's been initialized. */ - assert(cgi_error_memory_response->head); - - return cgi_error_memory_response; -} - - -/********************************************************************* - * - * Function : cgi_error_no_template - * - * Description : Almost-CGI function that is called if a template - * cannot be loaded. Note this is not a true CGI, - * it takes a template name rather than a map of - * parameters. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : template_name = Name of template that could not - * be loaded. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_error_no_template(struct client_state *csp, - struct http_response *rsp, - const char *template_name) -{ - static const char status[] = - "500 Internal Privoxy Error"; - static const char body_prefix[] = - "\r\n" - "500 Internal Privoxy Error\r\n" - "\r\n" - "

500 Internal Privoxy Error

\r\n" - "

Privoxy encountered an error while processing your request:

\r\n" - "

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

\r\n" - "

Please contact your proxy administrator.

\r\n" - "

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

\r\n" - "\r\n" - "\r\n"; - - assert(csp); - assert(rsp); - assert(template_name); - - /* Reset rsp, if needed */ - freez(rsp->status); - freez(rsp->head); - freez(rsp->body); - rsp->content_length = 0; - rsp->head_length = 0; - rsp->is_static = 0; - - rsp->body = malloc(strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1); - if (rsp->body == NULL) - { - return JB_ERR_MEMORY; - } - strcpy(rsp->body, body_prefix); - strcat(rsp->body, template_name); - strcat(rsp->body, body_suffix); - - rsp->status = strdup(status); - if (rsp->body == NULL) - { - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : cgi_error_unknown - * - * Description : Almost-CGI function that is called if an unexpected - * error occurs in the top-level CGI dispatcher. - * In this context, "unexpected" means "anything other - * than JB_ERR_MEMORY or JB_ERR_CGI_PARAMS" - CGIs are - * expected to handle all other errors internally, - * since they can give more relavent error messages - * that way. - * - * Note this is not a true CGI, it takes an error - * code rather than a map of parameters. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : error_to_report = Error code to report. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_error_unknown(struct client_state *csp, - struct http_response *rsp, - jb_err error_to_report) -{ - static const char status[] = - "500 Internal Privoxy Error"; - static const char body_prefix[] = - "\r\n" - "500 Internal Privoxy Error\r\n" - "\r\n" - "

500 Internal Privoxy Error

\r\n" - "

Privoxy encountered an error while processing your request:

\r\n" - "

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

\r\n" - "

Please " - "" - "file a bug report.

\r\n" - "\r\n" - "\r\n"; - char errnumbuf[30]; - assert(csp); - assert(rsp); - - /* Reset rsp, if needed */ - freez(rsp->status); - freez(rsp->head); - freez(rsp->body); - rsp->content_length = 0; - rsp->head_length = 0; - rsp->is_static = 0; - - sprintf(errnumbuf, "%d", error_to_report); - - rsp->body = malloc(strlen(body_prefix) + strlen(errnumbuf) + strlen(body_suffix) + 1); - if (rsp->body == NULL) - { - return JB_ERR_MEMORY; - } - strcpy(rsp->body, body_prefix); - strcat(rsp->body, errnumbuf); - strcat(rsp->body, body_suffix); - - rsp->status = strdup(status); - if (rsp->body == NULL) - { - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : cgi_error_bad_param - * - * Description : CGI function that is called if the parameters - * (query string) for a CGI were wrong. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * - * CGI Parameters : none - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_error_bad_param(struct client_state *csp, - struct http_response *rsp) -{ - struct map *exports; - - assert(csp); - assert(rsp); - - if (NULL == (exports = default_exports(csp, NULL))) - { - return JB_ERR_MEMORY; - } - - return template_fill_for_cgi(csp, "cgi-error-bad-param", exports, rsp); -} - - -/********************************************************************* - * - * Function : add_help_link - * - * Description : Produce a copy of the string given as item, - * embedded in an HTML link to its corresponding - * section (item name in uppercase) in the actions - * chapter of the user manual, (whose URL is given in - * the config and defaults to our web site). - * - * FIXME: I currently only work for actions, and would - * like to be generalized for other topics. - * - * Parameters : - * 1 : item = item (will NOT be free()d.) - * It is assumed to be HTML-safe. - * 2 : config = The current configuration. - * - * Returns : String with item embedded in link, or NULL on - * out-of-memory - * - *********************************************************************/ -char *add_help_link(const char *item, - struct configuration_spec *config) -{ - char *result; - - if (!item) return NULL; - - result = strdup("usermanual); - string_append(&result, ACTIONS_HELP_PREFIX); - string_join (&result, string_toupper(item)); - string_append(&result, "\">"); - string_append(&result, item); - string_append(&result, " "); - - return result; -} - - -/********************************************************************* - * - * Function : get_http_time - * - * Description : Get the time in a format suitable for use in a - * HTTP header - e.g.: - * "Sun, 06 Nov 1994 08:49:37 GMT" - * - * Parameters : - * 1 : time_offset = Time returned will be current time - * plus this number of seconds. - * 2 : buf = Destination for result. Must be long enough - * to hold 29 characters plus a trailing zero. - * - * Returns : N/A - * - *********************************************************************/ -void get_http_time(int time_offset, char *buf) -{ - static const char day_names[7][4] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static const char month_names[12][4] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - - struct tm *t; - time_t current_time; - - assert(buf); - - time(¤t_time); /* get current time */ - - current_time += time_offset; - - /* get and save the gmt */ - { -#ifdef HAVE_GMTIME_R - struct tm dummy; - t = gmtime_r(¤t_time, &dummy); -#else - t = gmtime(¤t_time); -#endif - } - - /* Format: "Sun, 06 Nov 1994 08:49:37 GMT" */ - snprintf(buf, 30, - "%s, %02d %s %4d %02d:%02d:%02d GMT", - day_names[t->tm_wday], - t->tm_mday, - month_names[t->tm_mon], - t->tm_year + 1900, - t->tm_hour, - t->tm_min, - t->tm_sec - ); - -} - - -/********************************************************************* - * - * Function : finish_http_response - * - * Description : Fill in the missing headers in an http response, - * and flatten the headers to an http head. - * - * Parameters : - * 1 : rsp = pointer to http_response to be processed - * - * Returns : A http_response, usually the rsp parameter. - * On error, free()s rsp and returns cgi_error_memory() - * - *********************************************************************/ -struct http_response *finish_http_response(struct http_response *rsp) -{ - char buf[BUFFER_SIZE]; - jb_err err; - - /* Special case - do NOT change this statically allocated response, - * which is ready for output anyway. - */ - if (rsp == cgi_error_memory_response) - { - return rsp; - } - - /* - * Fill in the HTTP Status - */ - sprintf(buf, "HTTP/1.0 %s", rsp->status ? rsp->status : "200 OK"); - err = enlist_first(rsp->headers, buf); - - /* - * Set the Content-Length - */ - if (rsp->content_length == 0) - { - rsp->content_length = rsp->body ? strlen(rsp->body) : 0; - } - if (!err) - { - sprintf(buf, "Content-Length: %d", (int)rsp->content_length); - err = enlist(rsp->headers, buf); - } - - /* - * Fill in the default headers: - * - * Content-Type: default to text/html if not already specified. - * Date: set to current date/time. - * Last-Modified: set to date/time the page was last changed. - * Expires: set to date/time page next needs reloading. - * Cache-Control: set to "no-cache" if applicable. - * - * See http://www.w3.org/Protocols/rfc2068/rfc2068 - */ - if (!err) err = enlist_unique(rsp->headers, "Content-Type: text/html", 13); - - if (rsp->is_static) - { - /* - * Set Expires to about 10 min into the future so it'll get reloaded - * occasionally, e.g. if Privoxy gets upgraded. - */ - - if (!err) - { - get_http_time(0, buf); - err = enlist_unique_header(rsp->headers, "Date", buf); - } - - /* Some date in the past. */ - if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", "Sat, 17 Jun 2000 12:00:00 GMT"); - - if (!err) - { - get_http_time(10 * 60, buf); /* 10 * 60sec = 10 minutes */ - err = enlist_unique_header(rsp->headers, "Expires", buf); - } - } - else - { - /* - * Compliant browsers should not cache this due to the "Cache-Control" - * setting. However, to be certain, we also set both "Last-Modified" - * and "Expires" to the current time. - */ - if (!err) err = enlist_unique_header(rsp->headers, "Cache-Control", "no-cache"); - - get_http_time(0, buf); - if (!err) err = enlist_unique_header(rsp->headers, "Date", buf); - if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", buf); - if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf); - } - - - /* - * Write the head - */ - if (err || (NULL == (rsp->head = list_to_text(rsp->headers)))) - { - free_http_response(rsp); - return cgi_error_memory(); - } - rsp->head_length = strlen(rsp->head); - - return rsp; - -} - - -/********************************************************************* - * - * Function : alloc_http_response - * - * Description : Allocates a new http_response structure. - * - * Parameters : N/A - * - * Returns : pointer to a new http_response, or NULL. - * - *********************************************************************/ -struct http_response *alloc_http_response(void) -{ - return (struct http_response *) zalloc(sizeof(struct http_response)); - -} - - -/********************************************************************* - * - * Function : free_http_response - * - * Description : Free the memory occupied by an http_response - * and its depandant structures. - * - * Parameters : - * 1 : rsp = pointer to http_response to be freed - * - * Returns : N/A - * - *********************************************************************/ -void free_http_response(struct http_response *rsp) -{ - /* - * Must special case cgi_error_memory_response, which is never freed. - */ - if (rsp && (rsp != cgi_error_memory_response)) - { - freez(rsp->status); - freez(rsp->head); - freez(rsp->body); - destroy_list(rsp->headers); - free(rsp); - } - -} - - -/********************************************************************* - * - * Function : template_load - * - * Description : CGI support function that loads a given HTML - * template from the confdir, ignoring comment - * lines and following #include statements up to - * a depth of 1. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : template_ptr = Destination for pointer to loaded - * template text. - * 3 : templatename = name of the HTML template to be used - * 4 : recursive = Flag set if this function calls itself - * following an #include statament - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * JB_ERR_FILE if the template file cannot be read - * - *********************************************************************/ -jb_err template_load(struct client_state *csp, char **template_ptr, - const char *templatename, int recursive) -{ - jb_err err; - char *templates_dir_path; - char *full_path; - char *file_buffer; - char *included_module; - const char *p; - FILE *fp; - char buf[BUFFER_SIZE]; - - assert(csp); - assert(template_ptr); - assert(templatename); - - *template_ptr = NULL; - - /* Validate template name. Paranoia. */ - for (p = templatename; *p != 0; p++) - { - if ( ((*p < 'a') || (*p > 'z')) - && ((*p < 'A') || (*p > 'Z')) - && ((*p < '0') || (*p > '9')) - && (*p != '-') - && (*p != '.')) - { - /* Illegal character */ - return JB_ERR_FILE; - } - } - - /* Generate full path */ - - templates_dir_path = make_path(csp->config->confdir, "templates"); - if (templates_dir_path == NULL) - { - return JB_ERR_MEMORY; - } - - full_path = make_path(templates_dir_path, templatename); - free(templates_dir_path); - if (full_path == NULL) - { - return JB_ERR_MEMORY; - } - - /* Allocate buffer */ - - file_buffer = strdup(""); - if (file_buffer == NULL) - { - free(full_path); - return JB_ERR_MEMORY; - } - - /* Open template file */ - - if (NULL == (fp = fopen(full_path, "r"))) - { - log_error(LOG_LEVEL_ERROR, "Cannot open template file %s: %E", full_path); - free(full_path); - free(file_buffer); - return JB_ERR_FILE; - } - free(full_path); - - /* - * Read the file, ignoring comments, and honoring #include - * statements, unless we're already called recursively. - * - * FIXME: The comment handling could break with lines >BUFFER_SIZE long. - * This is unlikely in practise. - */ - while (fgets(buf, BUFFER_SIZE, fp)) - { - if (!recursive && !strncmp(buf, "#include ", 9)) - { - if (JB_ERR_OK != (err = template_load(csp, &included_module, chomp(buf + 9), 1))) - { - free(file_buffer); - fclose(fp); - return err; - } - - if (string_join(&file_buffer, included_module)) - { - fclose(fp); - return JB_ERR_MEMORY; - } - - continue; - } - - /* skip lines starting with '#' */ - if (*buf == '#') - { - continue; - } - - if (string_append(&file_buffer, buf)) - { - fclose(fp); - return JB_ERR_MEMORY; - } - } - fclose(fp); - - *template_ptr = file_buffer; - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : template_fill - * - * Description : CGI support function that fills in a pre-loaded - * HTML template by replacing @name@ with value using - * pcrs, for each item in the output map. - * - * Note that a leading '$' charachter in the export map's - * values will be stripped and toggle on backreference - * interpretation. - * - * Parameters : - * 1 : template_ptr = IN: Template to be filled out. - * Will be free()d. - * OUT: Filled out template. - * Caller must free(). - * 2 : exports = map with fill in symbol -> name pairs - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error - * - *********************************************************************/ -jb_err template_fill(char **template_ptr, const struct map *exports) -{ - struct map_entry *m; - pcrs_job *job; - char buf[BUFFER_SIZE]; - char *tmp_out_buffer; - char *file_buffer; - size_t size; - int error; - const char *flags; - - assert(template_ptr); - assert(*template_ptr); - assert(exports); - - file_buffer = *template_ptr; - size = strlen(file_buffer) + 1; - - /* - * Assemble pcrs joblist from exports map - */ - for (m = exports->first; m != NULL; m = m->next) - { - if (*m->name == '$') - { - /* - * First character of name is '$', so remove this flag - * character and allow backreferences ($1 etc) in the - * "replace with" text. - */ - snprintf(buf, BUFFER_SIZE, "%s", m->name + 1); - flags = "sigU"; - } - else - { - /* - * Treat the "replace with" text as a literal string - - * no quoting needed, no backreferences allowed. - * ("Trivial" ['T'] flag). - */ - flags = "sigTU"; - - /* Enclose name in @@ */ - snprintf(buf, BUFFER_SIZE, "@%s@", m->name); - } - - - log_error(LOG_LEVEL_CGI, "Substituting: s/%s/%s/%s", buf, m->value, flags); - - /* Make and run job. */ - job = pcrs_compile(buf, m->value, flags, &error); - if (job == NULL) - { - if (error == PCRS_ERR_NOMEM) - { - free(file_buffer); - *template_ptr = NULL; - return JB_ERR_MEMORY; - } - else - { - log_error(LOG_LEVEL_ERROR, "Error compiling template fill job %s: %d", m->name, error); - /* Hope it wasn't important and silently ignore the invalid job */ - } - } - else - { - pcrs_execute(job, file_buffer, size, &tmp_out_buffer, &size); - free(file_buffer); - pcrs_free_job(job); - if (NULL == tmp_out_buffer) - { - *template_ptr = NULL; - return JB_ERR_MEMORY; - } - file_buffer = tmp_out_buffer; - } - } - - /* - * Return - */ - *template_ptr = file_buffer; - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : template_fill_for_cgi - * - * Description : CGI support function that loads a HTML template - * and fills it in. Handles file-not-found errors - * by sending a HTML error message. For convenience, - * this function also frees the passed "exports" map. - * - * Parameters : - * 1 : csp = Client state - * 2 : templatename = name of the HTML template to be used - * 3 : exports = map with fill in symbol -> name pairs. - * Will be freed by this function. - * 4 : rsp = Response structure to fill in. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error - * - *********************************************************************/ -jb_err template_fill_for_cgi(struct client_state *csp, - const char *templatename, - struct map *exports, - struct http_response *rsp) -{ - jb_err err; - - assert(csp); - assert(templatename); - assert(exports); - assert(rsp); - - err = template_load(csp, &rsp->body, templatename, 0); - if (err == JB_ERR_FILE) - { - free_map(exports); - return cgi_error_no_template(csp, rsp, templatename); - } - else if (err) - { - free_map(exports); - return err; /* JB_ERR_MEMORY */ - } - err = template_fill(&rsp->body, exports); - free_map(exports); - return err; -} - - -/********************************************************************* - * - * Function : default_exports - * - * Description : returns a struct map list that contains exports - * which are common to all CGI functions. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : caller = name of CGI who calls us and which should - * be excluded from the generated menu. May be - * NULL. - * Returns : NULL if no memory, else a new map. Caller frees. - * - *********************************************************************/ -struct map *default_exports(const struct client_state *csp, const char *caller) -{ - char buf[20]; - jb_err err; - struct map * exports; - int local_help_exists = 0; - - assert(csp); - - exports = new_map(); - if (exports == NULL) - { - return NULL; - } - - err = map(exports, "version", 1, html_encode(VERSION), 0); - if (!err) err = map(exports, "my-ip-address", 1, html_encode(csp->my_ip_addr_str ? csp->my_ip_addr_str : "unknown"), 0); - if (!err) err = map(exports, "my-hostname", 1, html_encode(csp->my_hostname ? csp->my_hostname : "unknown"), 0); - if (!err) err = map(exports, "homepage", 1, html_encode(HOME_PAGE_URL), 0); - if (!err) err = map(exports, "default-cgi", 1, html_encode(CGI_PREFIX), 0); - if (!err) err = map(exports, "menu", 1, make_menu(caller), 0); - if (!err) err = map(exports, "code-status", 1, CODE_STATUS, 1); - if (!err) err = map(exports, "user-manual", 1, csp->config->usermanual ,1); - if (!err) err = map(exports, "actions-help-prefix", 1, ACTIONS_HELP_PREFIX ,1); - if (!err) err = map_conditional(exports, "enabled-display", g_bToggleIJB); - - snprintf(buf, 20, "%d", csp->config->hport); - if (!err) err = map(exports, "my-port", 1, buf, 1); - - if(!strcmp(CODE_STATUS, "stable")) - { - if (!err) err = map_block_killer(exports, "unstable"); - } - - if (csp->config->admin_address != NULL) - { - if (!err) err = map(exports, "admin-address", 1, html_encode(csp->config->admin_address), 0); - local_help_exists = 1; - } - else - { - if (!err) err = map_block_killer(exports, "have-adminaddr-info"); - } - - if (csp->config->proxy_info_url != NULL) - { - if (!err) err = map(exports, "proxy-info-url", 1, html_encode(csp->config->proxy_info_url), 0); - local_help_exists = 1; - } - else - { - if (!err) err = map_block_killer(exports, "have-proxy-info"); - } - - if (local_help_exists == 0) - { - if (!err) err = map_block_killer(exports, "have-help-info"); - } - - if (err) - { - free_map(exports); - return NULL; - } - - return exports; -} - - -/********************************************************************* - * - * Function : map_block_killer - * - * Description : Convenience function. - * Adds a "killer" for the conditional HTML-template - * block , i.e. a substitution of the regex - * "if--start.*if--end" to the given - * export list. - * - * Parameters : - * 1 : exports = map to extend - * 2 : name = name of conditional block - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err map_block_killer(struct map *exports, const char *name) -{ - char buf[1000]; /* Will do, since the names are hardwired */ - - assert(exports); - assert(name); - assert(strlen(name) < 490); - - snprintf(buf, 1000, "if-%s-start.*if-%s-end", name, name); - return map(exports, buf, 1, "", 1); -} - - -/********************************************************************* - * - * Function : map_block_keep - * - * Description : Convenience function. Removes the markers used - * by map-block-killer, to save a few bytes. - * i.e. removes "@if--start@" and "@if--end@" - * - * Parameters : - * 1 : exports = map to extend - * 2 : name = name of conditional block - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err map_block_keep(struct map *exports, const char *name) -{ - jb_err err; - char buf[500]; /* Will do, since the names are hardwired */ - - assert(exports); - assert(name); - assert(strlen(name) < 490); - - snprintf(buf, 500, "if-%s-start", name); - err = map(exports, buf, 1, "", 1); - - if (err) - { - return err; - } - - snprintf(buf, 500, "if-%s-end", name); - return map(exports, buf, 1, "", 1); -} - - -/********************************************************************* - * - * Function : map_conditional - * - * Description : Convenience function. - * Adds an "if-then-else" for the conditional HTML-template - * block , i.e. a substitution of the form: - * @if--then@ - * True text - * @else-not-@ - * False text - * @endif-@ - * - * The control structure and one of the alternatives - * will be hidden. - * - * Parameters : - * 1 : exports = map to extend - * 2 : name = name of conditional block - * 3 : choose_first = nonzero for first, zero for second. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err map_conditional(struct map *exports, const char *name, int choose_first) -{ - char buf[1000]; /* Will do, since the names are hardwired */ - jb_err err; - - assert(exports); - assert(name); - assert(strlen(name) < 480); - - snprintf(buf, 1000, (choose_first - ? "else-not-%s@.*@endif-%s" - : "if-%s-then@.*@else-not-%s"), - name, name); - - err = map(exports, buf, 1, "", 1); - if (err) - { - return err; - } - - snprintf(buf, 1000, (choose_first ? "if-%s-then" : "endif-%s"), name); - return map(exports, buf, 1, "", 1); -} - - -/********************************************************************* - * - * Function : make_menu - * - * Description : Returns an HTML-formatted menu of the available - * unhidden CGIs, excluding the one given in - * - * Parameters : self = name of CGI to leave out, can be NULL for - * complete listing. - * - * Returns : menu string, or NULL on out-of-memory error. - * - *********************************************************************/ -char *make_menu(const char *self) -{ - const struct cgi_dispatcher *d; - char *result = strdup(""); - - if (self == NULL) - { - self = "NO-SUCH-CGI!"; - } - - /* List available unhidden CGI's and export as "other-cgis" */ - for (d = cgi_dispatchers; d->name; d++) - { - if (d->description && strcmp(d->name, self)) - { - string_append(&result, "
  • name); - string_append(&result, "\">"); - string_append(&result, d->description); - string_append(&result, "
  • "); - } - } - - return result; -} - - -/********************************************************************* - * - * Function : dump_map - * - * Description : HTML-dump a map for debugging (as table) - * - * Parameters : - * 1 : the_map = map to dump - * - * Returns : string with HTML - * - *********************************************************************/ -char *dump_map(const struct map *the_map) -{ - struct map_entry *cur_entry; - char *ret = strdup(""); - - string_append(&ret, "\n"); - - for (cur_entry = the_map->first; - (cur_entry != NULL) && (ret != NULL); - cur_entry = cur_entry->next) - { - string_append(&ret, "\n"); - } - - string_append(&ret, "
    "); - string_join (&ret, html_encode(cur_entry->name)); - string_append(&ret, ""); - string_join (&ret, html_encode(cur_entry->value)); - string_append(&ret, "
    \n"); - return ret; -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/cgi.h b/cgi.h deleted file mode 100644 index 39c6938d..00000000 --- a/cgi.h +++ /dev/null @@ -1,245 +0,0 @@ -#ifndef CGI_H_INCLUDED -#define CGI_H_INCLUDED -#define CGI_H_VERSION "$Id: cgi.h,v 1.28 2002/04/26 12:54:03 oes Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/cgi.h,v $ - * - * Purpose : Declares functions to intercept request, generate - * html or gif answers, and to compose HTTP resonses. - * - * Functions declared include: - * - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: cgi.h,v $ - * Revision 1.28 2002/04/26 12:54:03 oes - * New function add_help_link - * - * Revision 1.27 2002/04/24 02:16:51 oes - * Moved get_char_param, get_string_param and get_number_param here from cgiedit.c - * - * Revision 1.26 2002/04/10 13:38:35 oes - * load_template signature changed - * - * Revision 1.25 2002/04/08 20:50:25 swa - * fixed JB spelling - * - * Revision 1.24 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.23 2002/03/24 16:18:15 jongfoster - * Removing old logo - * - * Revision 1.22 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.21 2002/03/07 03:48:38 oes - * - Changed built-in images from GIF to PNG - * (with regard to Unisys patent issue) - * - Added a 4x4 pattern PNG which is less intrusive - * than the logo but also clearly marks the deleted banners - * - * Revision 1.20 2002/03/04 17:53:22 oes - * Fixed compiled warning - * - * Revision 1.19 2002/01/21 00:33:52 jongfoster - * Adding map_block_keep() to save a few bytes in the edit-actions-list HTML. - * - * Revision 1.18 2001/11/16 00:46:31 jongfoster - * Fixing compiler warnings - * - * Revision 1.17 2001/10/23 21:48:19 jongfoster - * Cleaning up error handling in CGI functions - they now send back - * a HTML error page and should never cause a FATAL error. (Fixes one - * potential source of "denial of service" attacks). - * - * CGI actions file editor that works and is actually useful. - * - * Ability to toggle Junkbuster remotely using a CGI call. - * - * You can turn off both the above features in the main configuration - * file, e.g. if you are running a multi-user proxy. - * - * Revision 1.16 2001/09/16 17:08:54 jongfoster - * Moving simple CGI functions from cgi.c to new file cgisimple.c - * - * Revision 1.15 2001/09/16 15:02:35 jongfoster - * Adding i.j.b/robots.txt. - * Inlining add_stats() since it's only ever called from one place. - * - * Revision 1.14 2001/09/16 11:38:02 jongfoster - * Splitting fill_template() into 2 functions: - * template_load() loads the file - * template_fill() performs the PCRS regexps. - * This is because the CGI edit interface has a "table row" - * template which is used many times in the page - this - * change means it's only loaded from disk once. - * - * Revision 1.13 2001/09/16 11:00:10 jongfoster - * New function alloc_http_response, for symmetry with free_http_response - * - * Revision 1.12 2001/09/13 23:31:25 jongfoster - * Moving image data to cgi.c rather than cgi.h. - * - * Revision 1.11 2001/08/05 16:06:20 jongfoster - * Modifiying "struct map" so that there are now separate header and - * "map_entry" structures. This means that functions which modify a - * map no longer need to return a pointer to the modified map. - * Also, it no longer reverses the order of the entries (which may be - * important with some advanced template substitutions). - * - * Revision 1.10 2001/08/01 21:19:22 jongfoster - * Moving file version information to a separate CGI page. - * - * Revision 1.9 2001/08/01 00:17:54 jongfoster - * Adding prototype for map_conditional - * - * Revision 1.8 2001/07/30 22:08:36 jongfoster - * Tidying up #defines: - * - All feature #defines are now of the form FEATURE_xxx - * - Permanently turned off WIN_GUI_EDIT - * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS - * - * Revision 1.7 2001/07/29 18:43:08 jongfoster - * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to - * ANSI C rules. - * - * Revision 1.6 2001/06/29 21:45:41 oes - * Indentation, CRLF->LF, Tab-> Space - * - * Revision 1.5 2001/06/29 13:22:44 oes - * - Cleaned up - * - Added new functions: default_exports(), make_menu(), - * error_response() etc, ranamed others and changed - * param and return types. - * - Removed HTTP/HTML snipplets - * - Removed logentry from cancelled commit - * - * Revision 1.4 2001/06/09 10:50:58 jongfoster - * Changing "show URL info" handler to new style. - * Adding "extern" to some function prototypes. - * - * Revision 1.3 2001/06/03 19:12:16 oes - * introduced new cgi handling - * - * No revisions before 1.3 - * - **********************************************************************/ - - -#include "project.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Main dispatch function - */ -extern struct http_response *dispatch_cgi(struct client_state *csp); - -/* Not exactly a CGI */ -extern struct http_response * error_response(struct client_state *csp, - const char *templatename, - int err); - -/* - * CGI support functions - */ -extern struct http_response * alloc_http_response(void); -extern void free_http_response(struct http_response *rsp); - -extern struct http_response *finish_http_response(struct http_response *rsp); - -extern struct map * default_exports(const struct client_state *csp, const char *caller); - -extern jb_err map_block_killer (struct map *exports, const char *name); -extern jb_err map_block_keep (struct map *exports, const char *name); -extern jb_err map_conditional (struct map *exports, const char *name, int choose_first); - -extern jb_err template_load(struct client_state *csp, char ** template_ptr, - const char *templatename, int recursive); -extern jb_err template_fill(char ** template_ptr, const struct map *exports); -extern jb_err template_fill_for_cgi(struct client_state *csp, - const char *templatename, - struct map *exports, - struct http_response *rsp); - -extern void cgi_init_error_messages(void); -extern struct http_response *cgi_error_memory(void); -extern jb_err cgi_error_no_template(struct client_state *csp, - struct http_response *rsp, - const char *template_name); -extern jb_err cgi_error_bad_param(struct client_state *csp, - struct http_response *rsp); -jb_err cgi_error_unknown(struct client_state *csp, - struct http_response *rsp, - jb_err error_to_report); - -extern jb_err get_number_param(struct client_state *csp, - const struct map *parameters, - char *name, - unsigned *pvalue); -extern jb_err get_string_param(const struct map *parameters, - const char *param_name, - const char **pparam); -extern char get_char_param(const struct map *parameters, - const char *param_name); - -/* - * Text generators - */ -extern void get_http_time(int time_offset, char * buf); -extern char *add_help_link(const char *item, struct configuration_spec *config); -extern char *make_menu(const char *self); -extern char *dump_map(const struct map *the_map); - -/* - * Ad replacement images - */ -extern const char image_pattern_data[]; -extern const size_t image_pattern_length; -extern const char image_blank_data[]; -extern const size_t image_blank_length; - -/* Revision control strings from this header and associated .c file */ -extern const char cgi_rcs[]; -extern const char cgi_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef CGI_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/cgiedit.c b/cgiedit.c deleted file mode 100644 index 0f0e46d3..00000000 --- a/cgiedit.c +++ /dev/null @@ -1,4710 +0,0 @@ -const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.40 2002/05/19 11:34:35 jongfoster Exp $"; -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $ - * - * Purpose : CGI-based actionsfile editor. - * - * Functions declared include: cgi_edit_* - * - * NOTE: The CGIs in this file use parameter names - * such as "f" and "s" which are really *BAD* choices. - * However, I'm trying to save bytes in the - * edit-actions-list HTML page - the standard actions - * file generated a 550kbyte page, which is ridiculous. - * - * Stick to the short names in this file for consistency. - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: cgiedit.c,v $ - * Revision 1.40 2002/05/19 11:34:35 jongfoster - * Handling read-only actions files better - report the actual - * error, not "Out of memory"! - * - * Bug report: - * http://sourceforge.net/tracker/index.php?func=detail - * &aid=557905&group_id=11118&atid=111118 - * - * Revision 1.39 2002/05/12 21:39:15 jongfoster - * - Adding Doxygen-style comments to structures and #defines. - * - Correcting function comments - * - * Revision 1.38 2002/05/03 23:00:38 jongfoster - * Support for templates for "standard actions" buttons. - * See bug #549871 - * - * Revision 1.37 2002/04/30 11:14:52 oes - * Made csp the first parameter in *action_to_html - * - * Revision 1.36 2002/04/26 21:53:30 jongfoster - * Fixing a memory leak. (Near, but not caused by, my earlier commit). - * - * Revision 1.35 2002/04/26 21:50:02 jongfoster - * Honouring default exports in edit-actions-for-url-filter template. - * - * Revision 1.34 2002/04/26 12:54:17 oes - * Adaptions to changes in actions.c - * - * Revision 1.33 2002/04/24 02:17:47 oes - * - Moved get_char_param, get_string_param and get_number_param to cgi.c - * - Comments - * - Activated Jon's code for editing multiple AFs - * - cgi_edit_list_actions now provides context-sensitive - * help, looks up all action sets from standard.action and - * makes buttons for them in the catchall section - * - cgi_edit_action_submit now honors a p parameter, looks up - * the corresponding action set, and sets the catchall pattern's - * actions accordingly. - * - * Revision 1.32 2002/04/19 16:55:31 jongfoster - * Fixing newline problems. If we do our own text file newline - * mangling, we don't want the library to do any, so we need to - * open the files in *binary* mode. - * - * Revision 1.31 2002/04/18 19:21:08 jongfoster - * Added code to detect "conventional" action files, that start - * with a set of actions for all URLs (the pattern "/"). - * These are special-cased in the "edit-actions-list" CGI, so - * that a special UI can be written for them. - * - * Revision 1.30 2002/04/10 13:38:35 oes - * load_template signature changed - * - * Revision 1.29 2002/04/08 16:59:08 oes - * Fixed comment - * - * Revision 1.28 2002/03/27 12:30:29 oes - * Deleted unsused variable - * - * Revision 1.27 2002/03/26 23:06:04 jongfoster - * Removing duplicate @ifs on the toggle page - * - * Revision 1.26 2002/03/26 22:59:17 jongfoster - * Fixing /toggle to display status consistently. - * - * Revision 1.25 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.24 2002/03/24 15:23:33 jongfoster - * Name changes - * - * Revision 1.23 2002/03/24 13:32:41 swa - * name change related issues - * - * Revision 1.22 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.21 2002/03/22 18:02:48 jongfoster - * Fixing remote toggle - * - * Revision 1.20 2002/03/16 20:28:34 oes - * Added descriptions to the filters so users will know what they select in the cgi editor - * - * Revision 1.19 2002/03/16 18:38:14 jongfoster - * Stopping stupid or malicious users from breaking the actions - * file using the web-based editor. - * - * Revision 1.18 2002/03/16 14:57:44 jongfoster - * Full support for enabling/disabling modular filters. - * - * Revision 1.17 2002/03/16 14:26:42 jongfoster - * First version of modular filters support - READ ONLY! - * Fixing a double-free bug in the out-of-memory handling in map_radio(). - * - * Revision 1.16 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.15 2002/03/06 22:54:35 jongfoster - * Automated function-comment nitpicking. - * - * Revision 1.14 2002/03/05 00:24:51 jongfoster - * Patch to always edit the current actions file. - * - * Revision 1.13 2002/03/04 02:07:59 david__schmidt - * Enable web editing of actions file on OS/2 (it had been broken all this time!) - * - * Revision 1.12 2002/03/03 09:18:03 joergs - * Made jumbjuster work on AmigaOS again. - * - * Revision 1.11 2002/01/23 01:03:31 jongfoster - * Fixing gcc [CygWin] compiler warnings - * - * Revision 1.10 2002/01/23 00:22:59 jongfoster - * Adding new function cgi_edit_actions_section_swap(), to reorder - * the actions file. - * - * Adding get_url_spec_param() to get a validated URL pattern. - * - * Moving edit_read_line() out of this file and into loaders.c. - * - * Adding missing html_encode() to many CGI functions. - * - * Moving the functions that #include actionlist.h to the end of the file, - * because the Visual C++ 97 debugger gets extremely confused if you try - * to debug any code that comes after them in the file. - * - * Major optimizations in cgi_edit_actions_list() to reduce the size of - * the generated HTML (down 40% from 550k to 304k), with major side-effects - * throughout the editor and templates. In particular, the length of the - * URLs throughout the editor has been drastically reduced, by cutting - * paramater names down to 1 character and CGI names down to 3-4 - * characters, by removing all non-essential CGI paramaters even at the - * expense of having to re-read the actions file for the most trivial - * page, and by using relative rather than absolute URLs. This means - * that this (typical example): - * - * - * - * is now this: - * - * - * - * Revision 1.9 2002/01/17 20:56:22 jongfoster - * Replacing hard references to the URL of the config interface - * with #defines from project.h - * - * Revision 1.8 2001/11/30 23:35:51 jongfoster - * Renaming actionsfile to ijb.action - * - * Revision 1.7 2001/11/13 00:28:24 jongfoster - * - Renaming parameters from edit-actions-for-url so that they only - * contain legal JavaScript characters. If we wanted to write - * JavaScript that worked with Netscape 4, this is nessacery. - * (Note that at the moment the JavaScript doesn't actually work - * with Netscape 4, but now this is purely a template issue, not - * one affecting code). - * - Adding new CGIs for use by non-JavaScript browsers: - * edit-actions-url-form - * edit-actions-add-url-form - * edit-actions-remove-url-form - * - Fixing || bug. - * - * Revision 1.6 2001/10/29 03:48:09 david__schmidt - * OS/2 native needed a snprintf() routine. Added one to miscutil, brackedted - * by and __OS2__ ifdef. - * - * Revision 1.5 2001/10/25 03:40:48 david__schmidt - * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple - * threads to call select() simultaneously. So, it's time to do a real, live, - * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__ - * (native). Both versions will work, but using __OS2__ offers multi-threading. - * - * Revision 1.4 2001/10/23 21:48:19 jongfoster - * Cleaning up error handling in CGI functions - they now send back - * a HTML error page and should never cause a FATAL error. (Fixes one - * potential source of "denial of service" attacks). - * - * CGI actions file editor that works and is actually useful. - * - * Ability to toggle JunkBuster remotely using a CGI call. - * - * You can turn off both the above features in the main configuration - * file, e.g. if you are running a multi-user proxy. - * - * Revision 1.3 2001/10/14 22:12:49 jongfoster - * New version of CGI-based actionsfile editor. - * Major changes, including: - * - Completely new file parser and file output routines - * - edit-actions CGI renamed edit-actions-for-url - * - All CGIs now need a filename parameter, except for... - * - New CGI edit-actions which doesn't need a filename, - * to allow you to start the editor up. - * - edit-actions-submit now works, and now automatically - * redirects you back to the main edit-actions-list handler. - * - * Revision 1.2 2001/09/16 17:05:14 jongfoster - * Removing unused #include showarg.h - * - * Revision 1.1 2001/09/16 15:47:37 jongfoster - * First version of CGI-based edit interface. This is very much a - * work-in-progress, and you can't actually use it to edit anything - * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes - * to have any effect. - * - * - **********************************************************************/ - - -#include "config.h" - -/* - * FIXME: Following includes copied from cgi.c - which are actually needed? - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#define snprintf _snprintf -#endif /* def _WIN32 */ - -#include "project.h" -#include "cgi.h" -#include "cgiedit.h" -#include "cgisimple.h" -#include "list.h" -#include "encode.h" -#include "actions.h" -#include "miscutil.h" -#include "errlog.h" -#include "loaders.h" -#include "loadcfg.h" -/* loadcfg.h is for g_bToggleIJB only */ -#include "urlmatch.h" - -const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION; - - -#ifdef FEATURE_CGI_EDIT_ACTIONS - -/** - * A line in an editable_file. - */ -struct file_line -{ - /** Next entry in the linked list */ - struct file_line * next; - - /** The raw data, to write out if this line is unmodified. */ - char * raw; - - /** Comments and/or whitespace to put before this line if it's modified - and then written out. */ - char * prefix; - - /** The actual data, as a string. Line continuation and comment removal - are performed on the data read from file before it's stored here, so - it will be a single line of data. */ - char * unprocessed; - - /** The type of data on this line. One of the FILE_LINE_xxx constants. */ - int type; - - /** The actual data, processed into some sensible data type. */ - union - { - - /** An action specification. */ - struct action_spec action[1]; - - /** A name=value pair. */ - struct - { - - /** The name in the name=value pair. */ - char * name; - - /** The value in the name=value pair, as a string. */ - char * svalue; - - /** The value in the name=value pair, as an integer. */ - int ivalue; - - } setting; - - /* Add more data types here... e.g. - - - struct url_spec url[1]; - - struct - { - struct action_spec action[1]; - const char * name; - } alias; - - */ - - } data; - -}; - -/** This file_line has not been processed yet. */ -#define FILE_LINE_UNPROCESSED 1 - -/** This file_line is blank. Can only appear at the end of a file, due to - the way the parser works. */ -#define FILE_LINE_BLANK 2 - -/** This file_line says {{alias}}. */ -#define FILE_LINE_ALIAS_HEADER 3 - -/** This file_line defines an alias. */ -#define FILE_LINE_ALIAS_ENTRY 4 - -/** This file_line defines an {action}. */ -#define FILE_LINE_ACTION 5 - -/** This file_line specifies a URL pattern. */ -#define FILE_LINE_URL 6 - -/** This file_line says {{settings}}. */ -#define FILE_LINE_SETTINGS_HEADER 7 - -/** This file_line is in a {{settings}} block. */ -#define FILE_LINE_SETTINGS_ENTRY 8 - -/** This file_line says {{description}}. */ -#define FILE_LINE_DESCRIPTION_HEADER 9 - -/** This file_line is in a {{description}} block. */ -#define FILE_LINE_DESCRIPTION_ENTRY 10 - - -/** - * A configuration file, in a format that can be edited and written back to - * disk. - */ -struct editable_file -{ - struct file_line * lines; /**< The contents of the file. A linked list of lines. */ - const char * filename; /**< Full pathname - e.g. "/etc/privoxy/wibble.action". */ - const char * identifier; /**< Filename stub - e.g. "wibble". Use for CGI param. */ - /**< Pre-encoded with url_encode() for ease of use. */ - const char * version_str; /**< Last modification time, as a string. For CGI param. */ - /**< Can be used in URL without using url_param(). */ - unsigned version; /**< Last modification time - prevents chaos with - the browser's "back" button. Note that this is a - time_t cast to an unsigned. When comparing, always - cast the time_t to an unsigned, and *NOT* vice-versa. - This may lose the top few bits, but they're not - significant anyway. */ - int newline; /**< Newline convention - one of the NEWLINE_xxx constants. - Note that changing this after the file has been - read in will cause a mess. */ - struct file_line * parse_error; /**< On parse error, this is the offending line. */ - const char * parse_error_text; /**< On parse error, this is the problem. - (Statically allocated) */ -}; - -/* FIXME: Following non-static functions should be prototyped in .h or made static */ - -/* Functions to read and write arbitrary config files */ -jb_err edit_read_file(struct client_state *csp, - const struct map *parameters, - int require_version, - const char *suffix, - struct editable_file **pfile); -jb_err edit_write_file(struct editable_file * file); -void edit_free_file(struct editable_file * file); - -/* Functions to read and write actions files */ -jb_err edit_parse_actions_file(struct editable_file * file); -jb_err edit_read_actions_file(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters, - int require_version, - struct editable_file **pfile); - -/* Error handlers */ -jb_err cgi_error_modified(struct client_state *csp, - struct http_response *rsp, - const char *filename); -jb_err cgi_error_parse(struct client_state *csp, - struct http_response *rsp, - struct editable_file *file); -jb_err cgi_error_file(struct client_state *csp, - struct http_response *rsp, - const char *filename); -jb_err cgi_error_file_read_only(struct client_state *csp, - struct http_response *rsp, - const char *filename); -jb_err cgi_error_disabled(struct client_state *csp, - struct http_response *rsp); - -/* Internal arbitrary config file support functions */ -static jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline); -static void edit_free_file_lines(struct file_line * first_line); - -/* Internal actions file support functions */ -static int match_actions_file_header_line(const char * line, const char * name); -static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue); - -/* Internal parameter parsing functions */ -static jb_err get_file_name_param(struct client_state *csp, - const struct map *parameters, - const char *param_name, - const char *suffix, - char **pfilename, - const char **pparam); - -static jb_err get_url_spec_param(struct client_state *csp, - const struct map *parameters, - const char *name, - char **pvalue); - - -/* Internal actionsfile <==> HTML conversion functions */ -static jb_err map_radio(struct map * exports, - const char * optionname, - const char * values, - int value); -static jb_err actions_to_radio(struct map * exports, - const struct action_spec *action); -static jb_err actions_from_radio(const struct map * parameters, - struct action_spec *action); - - -static jb_err map_copy_parameter_html(struct map *out, - const struct map *in, - const char *name); -#if 0 /* unused function */ -static jb_err map_copy_parameter_url(struct map *out, - const struct map *in, - const char *name); -#endif /* unused function */ - -/* Internal convenience functions */ -static char *section_target(const unsigned sectionid); - -/********************************************************************* - * - * Function : section_target - * - * Description : Given an unsigned (section id) n, produce a dynamically - * allocated string of the form #l, for use in link - * targets. - * - * Parameters : - * 1 : sectionid = start line number of section - * - * Returns : String with link target, or NULL if out of - * memory - * - *********************************************************************/ -static char *section_target(const unsigned sectionid) -{ - char buf[30]; - - snprintf(buf, 30, "#l%d", sectionid); - return(strdup(buf)); - -} - - -/********************************************************************* - * - * Function : map_copy_parameter_html - * - * Description : Copy a CGI parameter from one map to another, HTML - * encoding it. - * - * Parameters : - * 1 : out = target map - * 2 : in = source map - * 3 : name = name of cgi parameter to copy - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the parameter doesn't exist - * in the source map - * - *********************************************************************/ -static jb_err map_copy_parameter_html(struct map *out, - const struct map *in, - const char *name) -{ - const char * value; - jb_err err; - - assert(out); - assert(in); - assert(name); - - value = lookup(in, name); - err = map(out, name, 1, html_encode(value), 0); - - if (err) - { - /* Out of memory */ - return err; - } - else if (*value == '\0') - { - return JB_ERR_CGI_PARAMS; - } - else - { - return JB_ERR_OK; - } -} - - -#if 0 /* unused function */ -/********************************************************************* - * - * Function : map_copy_parameter_url - * - * Description : Copy a CGI parameter from one map to another, URL - * encoding it. - * - * Parameters : - * 1 : out = target map - * 2 : in = source map - * 3 : name = name of cgi parameter to copy - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the parameter doesn't exist - * in the source map - * - *********************************************************************/ -static jb_err map_copy_parameter_url(struct map *out, - const struct map *in, - const char *name) -{ - const char * value; - jb_err err; - - assert(out); - assert(in); - assert(name); - - value = lookup(in, name); - err = map(out, name, 1, url_encode(value), 0); - - if (err) - { - /* Out of memory */ - return err; - } - else if (*value == '\0') - { - return JB_ERR_CGI_PARAMS; - } - else - { - return JB_ERR_OK; - } -} -#endif /* 0 - unused function */ - -/********************************************************************* - * - * Function : cgi_edit_actions_url_form - * - * Description : CGI function that displays a form for - * edit-actions-url - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters - * - * CGI Parameters - * f : (filename) Identifies the file to edit - * v : (version) File's last-modified time - * p : (pattern) Line number of pattern to edit - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the CGI parameters are not - * specified or not valid. - * - *********************************************************************/ -jb_err cgi_edit_actions_url_form(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters) -{ - struct map * exports; - unsigned patternid; - struct editable_file * file; - struct file_line * cur_line; - unsigned line_number; - unsigned section_start_line_number = 0; - jb_err err; - - assert(csp); - assert(rsp); - assert(parameters); - - if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) - { - return cgi_error_disabled(csp, rsp); - } - - err = get_number_param(csp, parameters, "p", &patternid); - if (err) - { - return err; - } - - err = edit_read_actions_file(csp, rsp, parameters, 1, &file); - if (err) - { - /* No filename specified, can't read file, modified, or out of memory. */ - return (err == JB_ERR_FILE ? JB_ERR_OK : err); - } - - cur_line = file->lines; - - for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++) - { - if (cur_line->type == FILE_LINE_ACTION) - { - section_start_line_number = line_number; - } - cur_line = cur_line->next; - } - - if ( (cur_line == NULL) - || (line_number != patternid) - || (patternid < 1) - || (cur_line->type != FILE_LINE_URL)) - { - /* Invalid "patternid" parameter */ - edit_free_file(file); - return JB_ERR_CGI_PARAMS; - } - - if (NULL == (exports = default_exports(csp, NULL))) - { - edit_free_file(file); - return JB_ERR_MEMORY; - } - - err = map(exports, "f", 1, file->identifier, 1); - if (!err) err = map(exports, "v", 1, file->version_str, 1); - if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0); - if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0); - if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0); - - edit_free_file(file); - - if (err) - { - free_map(exports); - return err; - } - - return template_fill_for_cgi(csp, "edit-actions-url-form", exports, rsp); -} - - -/********************************************************************* - * - * Function : cgi_edit_actions_add_url_form - * - * Description : CGI function that displays a form for - * edit-actions-url - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters - * - * CGI Parameters : - * f : (filename) Identifies the file to edit - * v : (version) File's last-modified time - * s : (section) Line number of section to edit - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the CGI parameters are not - * specified or not valid. - * - *********************************************************************/ -jb_err cgi_edit_actions_add_url_form(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters) -{ - struct map *exports; - jb_err err; - - assert(csp); - assert(rsp); - assert(parameters); - - if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) - { - return cgi_error_disabled(csp, rsp); - } - - if (NULL == (exports = default_exports(csp, NULL))) - { - return JB_ERR_MEMORY; - } - - err = map_copy_parameter_html(exports, parameters, "f"); - if (!err) err = map_copy_parameter_html(exports, parameters, "v"); - if (!err) err = map_copy_parameter_html(exports, parameters, "s"); - - if (err) - { - free_map(exports); - return err; - } - - return template_fill_for_cgi(csp, "edit-actions-add-url-form", exports, rsp); -} - - -/********************************************************************* - * - * Function : cgi_edit_actions_remove_url_form - * - * Description : CGI function that displays a form for - * edit-actions-url - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters - * - * CGI Parameters : - * f : (filename) Identifies the file to edit - * v : (version) File's last-modified time - * p : (pattern) Line number of pattern to edit - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the CGI parameters are not - * specified or not valid. - * - *********************************************************************/ -jb_err cgi_edit_actions_remove_url_form(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters) -{ - struct map * exports; - unsigned patternid; - struct editable_file * file; - struct file_line * cur_line; - unsigned line_number; - unsigned section_start_line_number = 0; - jb_err err; - - assert(csp); - assert(rsp); - assert(parameters); - - if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) - { - return cgi_error_disabled(csp, rsp); - } - - err = get_number_param(csp, parameters, "p", &patternid); - if (err) - { - return err; - } - - err = edit_read_actions_file(csp, rsp, parameters, 1, &file); - if (err) - { - /* No filename specified, can't read file, modified, or out of memory. */ - return (err == JB_ERR_FILE ? JB_ERR_OK : err); - } - - cur_line = file->lines; - - for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++) - { - if (cur_line->type == FILE_LINE_ACTION) - { - section_start_line_number = line_number; - } - cur_line = cur_line->next; - } - - if ( (cur_line == NULL) - || (line_number != patternid) - || (patternid < 1) - || (cur_line->type != FILE_LINE_URL)) - { - /* Invalid "patternid" parameter */ - edit_free_file(file); - return JB_ERR_CGI_PARAMS; - } - - if (NULL == (exports = default_exports(csp, NULL))) - { - edit_free_file(file); - return JB_ERR_MEMORY; - } - - err = map(exports, "f", 1, file->identifier, 1); - if (!err) err = map(exports, "v", 1, file->version_str, 1); - if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0); - if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0); - if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0); - - edit_free_file(file); - - if (err) - { - free_map(exports); - return err; - } - - return template_fill_for_cgi(csp, "edit-actions-remove-url-form", exports, rsp); -} - - -/********************************************************************* - * - * Function : edit_write_file - * - * Description : Write a complete file to disk. - * - * Parameters : - * 1 : file = File to write. - * - * Returns : JB_ERR_OK on success - * JB_ERR_FILE on error writing to file. - * JB_ERR_MEMORY on out of memory - * - *********************************************************************/ -jb_err edit_write_file(struct editable_file * file) -{ - FILE * fp; - struct file_line * cur_line; - struct stat statbuf[1]; - char version_buf[22]; /* 22 = ceil(log10(2^64)) + 2 = max number of - digits in time_t, assuming this is a 64-bit - machine, plus null terminator, plus one - for paranoia */ - - assert(file); - assert(file->filename); - - if (NULL == (fp = fopen(file->filename, "wb"))) - { - return JB_ERR_FILE; - } - - cur_line = file->lines; - while (cur_line != NULL) - { - if (cur_line->raw) - { - if (fputs(cur_line->raw, fp) < 0) - { - fclose(fp); - return JB_ERR_FILE; - } - } - else - { - if (cur_line->prefix) - { - if (fputs(cur_line->prefix, fp) < 0) - { - fclose(fp); - return JB_ERR_FILE; - } - } - if (cur_line->unprocessed) - { - - if (NULL != strchr(cur_line->unprocessed, '#')) - { - /* Must quote '#' characters */ - int numhash = 0; - int len; - char * src; - char * dest; - char * str; - - /* Count number of # characters, so we know length of output string */ - src = cur_line->unprocessed; - while (NULL != (src = strchr(src, '#'))) - { - numhash++; - src++; - } - assert(numhash > 0); - - /* Allocate new memory for string */ - len = strlen(cur_line->unprocessed); - if (NULL == (str = malloc((size_t) len + 1 + numhash))) - { - /* Uh oh, just trashed file! */ - fclose(fp); - return JB_ERR_MEMORY; - } - - /* Loop through string from end */ - src = cur_line->unprocessed + len; - dest = str + len + numhash; - for ( ; len >= 0; len--) - { - if ((*dest-- = *src--) == '#') - { - *dest-- = '\\'; - numhash--; - assert(numhash >= 0); - } - } - assert(numhash == 0); - assert(src + 1 == cur_line->unprocessed); - assert(dest + 1 == str); - - if (fputs(str, fp) < 0) - { - free(str); - fclose(fp); - return JB_ERR_FILE; - } - - free(str); - } - else - { - /* Can write without quoting '#' characters. */ - if (fputs(cur_line->unprocessed, fp) < 0) - { - fclose(fp); - return JB_ERR_FILE; - } - } - if (fputs(NEWLINE(file->newline), fp) < 0) - { - fclose(fp); - return JB_ERR_FILE; - } - } - else - { - /* FIXME: Write data from file->data->whatever */ - assert(0); - } - } - cur_line = cur_line->next; - } - - fclose(fp); - - - /* Update the version stamp in the file structure, since we just - * wrote to the file & changed it's date. - */ - if (stat(file->filename, statbuf) < 0) - { - /* Error, probably file not found. */ - return JB_ERR_FILE; - } - file->version = (unsigned)statbuf->st_mtime; - - /* Correct file->version_str */ - freez(file->version_str); - snprintf(version_buf, 22, "%u", file->version); - version_buf[21] = '\0'; - file->version_str = strdup(version_buf); - if (version_buf == NULL) - { - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : edit_free_file - * - * Description : Free a complete file in memory. - * - * Parameters : - * 1 : file = Data structure to free. - * - * Returns : N/A - * - *********************************************************************/ -void edit_free_file(struct editable_file * file) -{ - if (!file) - { - /* Silently ignore NULL pointer */ - return; - } - - edit_free_file_lines(file->lines); - freez(file->filename); - freez(file->identifier); - freez(file->version_str); - file->version = 0; - file->parse_error_text = NULL; /* Statically allocated */ - file->parse_error = NULL; - - free(file); -} - - -/********************************************************************* - * - * Function : edit_free_file_lines - * - * Description : Free an entire linked list of file lines. - * - * Parameters : - * 1 : first_line = Data structure to free. - * - * Returns : N/A - * - *********************************************************************/ -static void edit_free_file_lines(struct file_line * first_line) -{ - struct file_line * next_line; - - while (first_line != NULL) - { - next_line = first_line->next; - first_line->next = NULL; - freez(first_line->raw); - freez(first_line->prefix); - freez(first_line->unprocessed); - switch(first_line->type) - { - case 0: /* special case if memory zeroed */ - case FILE_LINE_UNPROCESSED: - case FILE_LINE_BLANK: - case FILE_LINE_ALIAS_HEADER: - case FILE_LINE_SETTINGS_HEADER: - case FILE_LINE_DESCRIPTION_HEADER: - case FILE_LINE_DESCRIPTION_ENTRY: - case FILE_LINE_ALIAS_ENTRY: - case FILE_LINE_URL: - /* No data is stored for these */ - break; - - case FILE_LINE_ACTION: - free_action(first_line->data.action); - break; - - case FILE_LINE_SETTINGS_ENTRY: - freez(first_line->data.setting.name); - freez(first_line->data.setting.svalue); - break; - default: - /* Should never happen */ - assert(0); - break; - } - first_line->type = 0; /* paranoia */ - free(first_line); - first_line = next_line; - } -} - - -/********************************************************************* - * - * Function : match_actions_file_header_line - * - * Description : Match an actions file {{header}} line - * - * Parameters : - * 1 : line = String from file - * 2 : name = Header to match against - * - * Returns : 0 iff they match. - * - *********************************************************************/ -static int match_actions_file_header_line(const char * line, const char * name) -{ - size_t len; - - assert(line); - assert(name); - - /* Look for "{{" */ - if ((line[0] != '{') || (line[1] != '{')) - { - return 1; - } - line += 2; - - /* Look for optional whitespace */ - while ( (*line == ' ') || (*line == '\t') ) - { - line++; - } - - /* Look for the specified name (case-insensitive) */ - len = strlen(name); - if (0 != strncmpic(line, name, len)) - { - return 1; - } - line += len; - - /* Look for optional whitespace */ - while ( (*line == ' ') || (*line == '\t') ) - { - line++; - } - - /* Look for "}}" and end of string*/ - if ((line[0] != '}') || (line[1] != '}') || (line[2] != '\0')) - { - return 1; - } - - /* It matched!! */ - return 0; -} - - -/********************************************************************* - * - * Function : match_actions_file_header_line - * - * Description : Match an actions file {{header}} line - * - * Parameters : - * 1 : line = String from file. Must not start with - * whitespace (else infinite loop!) - * 2 : pname = Destination for name - * 2 : pvalue = Destination for value - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_PARSE if there's no "=" sign, or if there's - * nothing before the "=" sign (but empty - * values *after* the "=" sign are legal). - * - *********************************************************************/ -static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue) -{ - const char * name_end; - const char * value_start; - size_t name_len; - - assert(line); - assert(pname); - assert(pvalue); - assert(*line != ' '); - assert(*line != '\t'); - - *pname = NULL; - *pvalue = NULL; - - value_start = strchr(line, '='); - if ((value_start == NULL) || (value_start == line)) - { - return JB_ERR_PARSE; - } - - name_end = value_start - 1; - - /* Eat any whitespace before the '=' */ - while ((*name_end == ' ') || (*name_end == '\t')) - { - /* - * we already know we must have at least 1 non-ws char - * at start of buf - no need to check - */ - name_end--; - } - - name_len = name_end - line + 1; /* Length excluding \0 */ - if (NULL == (*pname = (char *) malloc(name_len + 1))) - { - return JB_ERR_MEMORY; - } - strncpy(*pname, line, name_len); - (*pname)[name_len] = '\0'; - - /* Eat any the whitespace after the '=' */ - value_start++; - while ((*value_start == ' ') || (*value_start == '\t')) - { - value_start++; - } - - if (NULL == (*pvalue = strdup(value_start))) - { - free(*pname); - *pname = NULL; - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : edit_parse_actions_file - * - * Description : Parse an actions file in memory. - * - * Passed linked list must have the "data" member - * zeroed, and must contain valid "next" and - * "unprocessed" fields. The "raw" and "prefix" - * fields are ignored, and "type" is just overwritten. - * - * Note that on error the file may have been - * partially parsed. - * - * Parameters : - * 1 : file = Actions file to be parsed in-place. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_PARSE on error - * - *********************************************************************/ -jb_err edit_parse_actions_file(struct editable_file * file) -{ - struct file_line * cur_line; - size_t len; - const char * text; /* Text from a line */ - char * name; /* For lines of the form name=value */ - char * value; /* For lines of the form name=value */ - struct action_alias * alias_list = NULL; - jb_err err = JB_ERR_OK; - - /* alias_list contains the aliases defined in this file. - * It might be better to use the "file_line.data" fields - * in the relavent places instead. - */ - - cur_line = file->lines; - - /* A note about blank line support: Blank lines should only - * ever occur as the last line in the file. This function - * is more forgiving than that - FILE_LINE_BLANK can occur - * anywhere. - */ - - /* Skip leading blanks. Should only happen if file is - * empty (which is valid, but pointless). - */ - while ( (cur_line != NULL) - && (cur_line->unprocessed[0] == '\0') ) - { - /* Blank line */ - cur_line->type = FILE_LINE_BLANK; - cur_line = cur_line->next; - } - - if ( (cur_line != NULL) - && (cur_line->unprocessed[0] != '{') ) - { - /* File doesn't start with a header */ - file->parse_error = cur_line; - file->parse_error_text = "First (non-comment) line of the file must contain a header."; - return JB_ERR_PARSE; - } - - if ( (cur_line != NULL) && (0 == - match_actions_file_header_line(cur_line->unprocessed, "settings") ) ) - { - cur_line->type = FILE_LINE_SETTINGS_HEADER; - - cur_line = cur_line->next; - while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{')) - { - if (cur_line->unprocessed[0]) - { - cur_line->type = FILE_LINE_SETTINGS_ENTRY; - - err = split_line_on_equals(cur_line->unprocessed, - &cur_line->data.setting.name, - &cur_line->data.setting.svalue); - if (err == JB_ERR_MEMORY) - { - return err; - } - else if (err != JB_ERR_OK) - { - /* Line does not contain a name=value pair */ - file->parse_error = cur_line; - file->parse_error_text = "Expected a name=value pair on this {{description}} line, but couldn't find one."; - return JB_ERR_PARSE; - } - } - else - { - cur_line->type = FILE_LINE_BLANK; - } - cur_line = cur_line->next; - } - } - - if ( (cur_line != NULL) && (0 == - match_actions_file_header_line(cur_line->unprocessed, "description") ) ) - { - cur_line->type = FILE_LINE_DESCRIPTION_HEADER; - - cur_line = cur_line->next; - while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{')) - { - if (cur_line->unprocessed[0]) - { - cur_line->type = FILE_LINE_DESCRIPTION_ENTRY; - } - else - { - cur_line->type = FILE_LINE_BLANK; - } - cur_line = cur_line->next; - } - } - - if ( (cur_line != NULL) && (0 == - match_actions_file_header_line(cur_line->unprocessed, "alias") ) ) - { - cur_line->type = FILE_LINE_ALIAS_HEADER; - - cur_line = cur_line->next; - while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{')) - { - if (cur_line->unprocessed[0]) - { - /* define an alias */ - struct action_alias * new_alias; - - cur_line->type = FILE_LINE_ALIAS_ENTRY; - - err = split_line_on_equals(cur_line->unprocessed, &name, &value); - if (err == JB_ERR_MEMORY) - { - return err; - } - else if (err != JB_ERR_OK) - { - /* Line does not contain a name=value pair */ - file->parse_error = cur_line; - file->parse_error_text = "Expected a name=value pair on this {{alias}} line, but couldn't find one."; - return JB_ERR_PARSE; - } - - if ((new_alias = zalloc(sizeof(*new_alias))) == NULL) - { - /* Out of memory */ - free(name); - free(value); - free_alias_list(alias_list); - return JB_ERR_MEMORY; - } - - err = get_actions(value, alias_list, new_alias->action); - if (err) - { - /* Invalid action or out of memory */ - free(name); - free(value); - free(new_alias); - free_alias_list(alias_list); - if (err == JB_ERR_MEMORY) - { - return err; - } - else - { - /* Line does not contain a name=value pair */ - file->parse_error = cur_line; - file->parse_error_text = "This alias does not specify a valid set of actions."; - return JB_ERR_PARSE; - } - } - - free(value); - - new_alias->name = name; - - /* add to list */ - new_alias->next = alias_list; - alias_list = new_alias; - } - else - { - cur_line->type = FILE_LINE_BLANK; - } - cur_line = cur_line->next; - } - } - - /* Header done, process the main part of the file */ - while (cur_line != NULL) - { - /* At this point, (cur_line->unprocessed[0] == '{') */ - assert(cur_line->unprocessed[0] == '{'); - text = cur_line->unprocessed + 1; - len = strlen(text) - 1; - if (text[len] != '}') - { - /* No closing } on header */ - free_alias_list(alias_list); - file->parse_error = cur_line; - file->parse_error_text = "Headers starting with '{' must have a " - "closing bracket ('}'). Headers starting with two brackets ('{{') " - "must close with two brackets ('}}')."; - return JB_ERR_PARSE; - } - - if (text[0] == '{') - { - /* An invalid {{ header. */ - free_alias_list(alias_list); - file->parse_error = cur_line; - file->parse_error_text = "Unknown or unexpected two-bracket header. " - "Please remember that the system (two-bracket) headers must " - "appear in the order {{settings}}, {{description}}, {{alias}}, " - "and must appear before any actions (one-bracket) headers. " - "Also note that system headers may not be repeated."; - return JB_ERR_PARSE; - } - - while ( (*text == ' ') || (*text == '\t') ) - { - text++; - len--; - } - while ( (len > 0) - && ( (text[len - 1] == ' ') - || (text[len - 1] == '\t') ) ) - { - len--; - } - - cur_line->type = FILE_LINE_ACTION; - - /* Remove {} and make copy */ - if (NULL == (value = (char *) malloc(len + 1))) - { - /* Out of memory */ - free_alias_list(alias_list); - return JB_ERR_MEMORY; - } - strncpy(value, text, len); - value[len] = '\0'; - - /* Get actions */ - err = get_actions(value, alias_list, cur_line->data.action); - if (err) - { - /* Invalid action or out of memory */ - free(value); - free_alias_list(alias_list); - if (err == JB_ERR_MEMORY) - { - return err; - } - else - { - /* Line does not contain a name=value pair */ - file->parse_error = cur_line; - file->parse_error_text = "This header does not specify a valid set of actions."; - return JB_ERR_PARSE; - } - } - - /* Done with string - it was clobbered anyway */ - free(value); - - /* Process next line */ - cur_line = cur_line->next; - - /* Loop processing URL patterns */ - while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{')) - { - if (cur_line->unprocessed[0]) - { - /* Could parse URL here, but this isn't currently needed */ - - cur_line->type = FILE_LINE_URL; - } - else - { - cur_line->type = FILE_LINE_BLANK; - } - cur_line = cur_line->next; - } - } /* End main while(cur_line != NULL) loop */ - - free_alias_list(alias_list); - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : edit_read_file_lines - * - * Description : Read all the lines of a file into memory. - * Handles whitespace, comments and line continuation. - * - * Parameters : - * 1 : fp = File to read from. On return, this will be - * at EOF but it will not have been closed. - * 2 : pfile = Destination for a linked list of file_lines. - * Will be set to NULL on error. - * 3 : newline = How to handle newlines. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * - *********************************************************************/ -jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline) -{ - struct file_line * first_line; /* Keep for return value or to free */ - struct file_line * cur_line; /* Current line */ - struct file_line * prev_line; /* Entry with prev_line->next = cur_line */ - jb_err rval; - - assert(fp); - assert(pfile); - - *pfile = NULL; - - cur_line = first_line = zalloc(sizeof(struct file_line)); - if (cur_line == NULL) - { - return JB_ERR_MEMORY; - } - - cur_line->type = FILE_LINE_UNPROCESSED; - - rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL); - if (rval) - { - /* Out of memory or empty file. */ - /* Note that empty file is not an error we propogate up */ - free(cur_line); - return ((rval == JB_ERR_FILE) ? JB_ERR_OK : rval); - } - - do - { - prev_line = cur_line; - cur_line = prev_line->next = zalloc(sizeof(struct file_line)); - if (cur_line == NULL) - { - /* Out of memory */ - edit_free_file_lines(first_line); - return JB_ERR_MEMORY; - } - - cur_line->type = FILE_LINE_UNPROCESSED; - - rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL); - if ((rval != JB_ERR_OK) && (rval != JB_ERR_FILE)) - { - /* Out of memory */ - edit_free_file_lines(first_line); - return JB_ERR_MEMORY; - } - - } - while (rval != JB_ERR_FILE); - - /* EOF */ - - /* We allocated one too many - free it */ - prev_line->next = NULL; - free(cur_line); - - *pfile = first_line; - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : edit_read_file - * - * Description : Read a complete file into memory. - * Handles CGI parameter parsing. If requested, also - * checks the file's modification timestamp. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters. - * 3 : require_version = true to check "ver" parameter. - * 4 : suffix = File extension, e.g. ".action". - * 5 : pfile = Destination for the file. Will be set - * to NULL on error. - * - * CGI Parameters : - * filename : The name of the file to read, without the - * path or ".action" extension. - * ver : (Only if require_version is nonzero) - * Timestamp of the actions file. If wrong, this - * function fails with JB_ERR_MODIFIED. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if "filename" was not specified - * or is not valid. - * JB_ERR_FILE if the file cannot be opened or - * contains no data - * JB_ERR_MODIFIED if version checking was requested and - * failed - the file was modified outside - * of this CGI editor instance. - * - *********************************************************************/ -jb_err edit_read_file(struct client_state *csp, - const struct map *parameters, - int require_version, - const char *suffix, - struct editable_file **pfile) -{ - struct file_line * lines; - FILE * fp; - jb_err err; - char * filename; - const char * identifier; - struct editable_file * file; - unsigned version = 0; - struct stat statbuf[1]; - char version_buf[22]; - int newline = NEWLINE_UNKNOWN; - - assert(csp); - assert(parameters); - assert(pfile); - - *pfile = NULL; - - err = get_file_name_param(csp, parameters, "f", suffix, - &filename, &identifier); - if (err) - { - return err; - } - - if (stat(filename, statbuf) < 0) - { - /* Error, probably file not found. */ - free(filename); - return JB_ERR_FILE; - } - version = (unsigned) statbuf->st_mtime; - - if (require_version) - { - unsigned specified_version; - err = get_number_param(csp, parameters, "v", &specified_version); - if (err) - { - free(filename); - return err; - } - - if (version != specified_version) - { - return JB_ERR_MODIFIED; - } - } - - if (NULL == (fp = fopen(filename,"rb"))) - { - free(filename); - return JB_ERR_FILE; - } - - err = edit_read_file_lines(fp, &lines, &newline); - - fclose(fp); - - if (err) - { - free(filename); - return err; - } - - file = (struct editable_file *) zalloc(sizeof(*file)); - if (err) - { - free(filename); - edit_free_file_lines(lines); - return err; - } - - file->lines = lines; - file->newline = newline; - file->filename = filename; - file->version = version; - file->identifier = url_encode(identifier); - - if (file->identifier == NULL) - { - edit_free_file(file); - return JB_ERR_MEMORY; - } - - /* Correct file->version_str */ - freez(file->version_str); - snprintf(version_buf, 22, "%u", file->version); - version_buf[21] = '\0'; - file->version_str = strdup(version_buf); - if (version_buf == NULL) - { - edit_free_file(file); - return JB_ERR_MEMORY; - } - - *pfile = file; - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : edit_read_actions_file - * - * Description : Read a complete actions file into memory. - * Handles CGI parameter parsing. If requested, also - * checks the file's modification timestamp. - * - * If this function detects an error in the categories - * JB_ERR_FILE, JB_ERR_MODIFIED, or JB_ERR_PARSE, - * then it handles it by filling in the specified - * response structure and returning JB_ERR_FILE. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = HTTP response. Only filled in on error. - * 2 : parameters = map of cgi parameters. - * 3 : require_version = true to check "ver" parameter. - * 4 : pfile = Destination for the file. Will be set - * to NULL on error. - * - * CGI Parameters : - * filename : The name of the actions file to read, without the - * path or ".action" extension. - * ver : (Only if require_version is nonzero) - * Timestamp of the actions file. If wrong, this - * function fails with JB_ERR_MODIFIED. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if "filename" was not specified - * or is not valid. - * JB_ERR_FILE if the file does not contain valid data, - * or if file cannot be opened or - * contains no data, or if version - * checking was requested and failed. - * - *********************************************************************/ -jb_err edit_read_actions_file(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters, - int require_version, - struct editable_file **pfile) -{ - jb_err err; - struct editable_file *file; - - assert(csp); - assert(parameters); - assert(pfile); - - *pfile = NULL; - - err = edit_read_file(csp, parameters, require_version, ".action", &file); - if (err) - { - /* Try to handle if possible */ - if (err == JB_ERR_FILE) - { - err = cgi_error_file(csp, rsp, lookup(parameters, "f")); - } - else if (err == JB_ERR_MODIFIED) - { - err = cgi_error_modified(csp, rsp, lookup(parameters, "f")); - } - if (err == JB_ERR_OK) - { - /* - * Signal to higher-level CGI code that there was a problem but we - * handled it, they should just return JB_ERR_OK. - */ - err = JB_ERR_FILE; - } - return err; - } - - err = edit_parse_actions_file(file); - if (err) - { - if (err == JB_ERR_PARSE) - { - err = cgi_error_parse(csp, rsp, file); - if (err == JB_ERR_OK) - { - /* - * Signal to higher-level CGI code that there was a problem but we - * handled it, they should just return JB_ERR_OK. - */ - err = JB_ERR_FILE; - } - } - edit_free_file(file); - return err; - } - - *pfile = file; - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : get_file_name_param - * - * Description : Get the name of the file to edit from the parameters - * passed to a CGI function. This function handles - * security checks such as blocking urls containing - * "/" or ".", prepending the config file directory, - * and adding the specified suffix. - * - * (This is an essential security check, otherwise - * users may be able to pass "../../../etc/passwd" - * and overwrite the password file [linux], "prn:" - * and print random data [Windows], etc...) - * - * This function only allows filenames contining the - * characters '-', '_', 'A'-'Z', 'a'-'z', and '0'-'9'. - * That's probably too restrictive but at least it's - * secure. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : param_name = The name of the parameter to read - * 4 : suffix = File extension, e.g. ".actions" - * 5 : pfilename = destination for full filename. Caller - * free()s. Set to NULL on error. - * 6 : pparam = destination for partial filename, - * suitable for use in another URL. Allocated as part - * of the map "parameters", so don't free it. - * Set to NULL if not specified. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if "filename" was not specified - * or is not valid. - * - *********************************************************************/ -static jb_err get_file_name_param(struct client_state *csp, - const struct map *parameters, - const char *param_name, - const char *suffix, - char **pfilename, - const char **pparam) -{ - const char *param; - const char *s; - char *name; - char *fullpath; - char ch; - int len; - - assert(csp); - assert(parameters); - assert(suffix); - assert(pfilename); - assert(pparam); - - *pfilename = NULL; - *pparam = NULL; - - param = lookup(parameters, param_name); - if (!*param) - { - return JB_ERR_CGI_PARAMS; - } - - *pparam = param; - - len = strlen(param); - if (len >= FILENAME_MAX) - { - /* Too long. */ - return JB_ERR_CGI_PARAMS; - } - - /* Check every character to see if it's legal */ - s = param; - while ((ch = *s++) != '\0') - { - if ( ((ch < 'A') || (ch > 'Z')) - && ((ch < 'a') || (ch > 'z')) - && ((ch < '0') || (ch > '9')) - && (ch != '-') - && (ch != '_') ) - { - /* Probable hack attempt. */ - return JB_ERR_CGI_PARAMS; - } - } - - /* Append extension */ - name = malloc(len + strlen(suffix) + 1); - if (name == NULL) - { - return JB_ERR_MEMORY; - } - strcpy(name, param); - strcpy(name + len, suffix); - - /* Prepend path */ - fullpath = make_path(csp->config->confdir, name); - free(name); - - if (fullpath == NULL) - { - return JB_ERR_MEMORY; - } - - /* Success */ - *pfilename = fullpath; - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : get_url_spec_param - * - * Description : Get a URL pattern from the parameters - * passed to a CGI function. Removes leading/trailing - * spaces and validates it. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : name = Name of CGI parameter to read - * 4 : pvalue = destination for value. Will be malloc()'d. - * Set to NULL on error. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory - * JB_ERR_CGI_PARAMS if the parameter was not specified - * or is not valid. - * - *********************************************************************/ -static jb_err get_url_spec_param(struct client_state *csp, - const struct map *parameters, - const char *name, - char **pvalue) -{ - const char *orig_param; - char *param; - char *s; - struct url_spec compiled[1]; - jb_err err; - - assert(csp); - assert(parameters); - assert(name); - assert(pvalue); - - *pvalue = NULL; - - orig_param = lookup(parameters, name); - if (!*orig_param) - { - return JB_ERR_CGI_PARAMS; - } - - /* Copy and trim whitespace */ - param = strdup(orig_param); - if (param == NULL) - { - return JB_ERR_MEMORY; - } - chomp(param); - - /* Must be non-empty, and can't allow 1st character to be '{' */ - if (param[0] == '\0' || param[0] == '{') - { - free(param); - return JB_ERR_CGI_PARAMS; - } - - /* Check for embedded newlines */ - for (s = param; *s != '\0'; s++) - { - if ((*s == '\r') || (*s == '\n')) - { - free(param); - return JB_ERR_CGI_PARAMS; - } - } - - /* Check that regex is valid */ - s = strdup(param); - if (s == NULL) - { - free(param); - return JB_ERR_MEMORY; - } - err = create_url_spec(compiled, s); - free(s); - if (err) - { - free(param); - return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS; - } - free_url_spec(compiled); - - if (param[strlen(param) - 1] == '\\') - { - /* - * Must protect trailing '\\' from becoming line continuation character. - * Two methods: 1) If it's a domain only, add a trailing '/'. - * 2) For path, add the do-nothing PCRE expression (?:) to the end - */ - if (strchr(param, '/') == NULL) - { - err = string_append(¶m, "/"); - } - else - { - err = string_append(¶m, "(?:)"); - } - if (err) - { - return err; - } - - /* Check that the modified regex is valid */ - s = strdup(param); - if (s == NULL) - { - free(param); - return JB_ERR_MEMORY; - } - err = create_url_spec(compiled, s); - free(s); - if (err) - { - free(param); - return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS; - } - free_url_spec(compiled); - } - - *pvalue = param; - return JB_ERR_OK; -} - -/********************************************************************* - * - * Function : map_radio - * - * Description : Map a set of radio button values. E.g. if you have - * 3 radio buttons, declare them as: - * View ", i); - if (!err) err = string_append(&s, buf); - - if (NULL == strstr(csp->actions_list[i]->filename, "standard.action") && NULL != csp->config->actions_file_short[i]) - { - snprintf(buf, 100, "Edit", csp->config->actions_file_short[i]); - if (!err) err = string_append(&s, buf); - } - - if (!err) err = string_append(&s, "\n"); - } - } - if (*s != '\0') - { - if (!err) err = map(exports, "actions-filenames", 1, s, 0); - } - else - { - if (!err) err = map(exports, "actions-filenames", 1, "None specified", 1); - } - - if (csp->rlist) - { - if (!err) err = map(exports, "re-filter-filename", 1, html_encode(csp->rlist->filename), 0); - } - else - { - if (!err) err = map(exports, "re-filter-filename", 1, "None specified", 1); - if (!err) err = map_block_killer(exports, "have-filterfile"); - } - -#ifdef FEATURE_TRUST - if (csp->tlist) - { - if (!err) err = map(exports, "trust-filename", 1, html_encode(csp->tlist->filename), 0); - } - else - { - if (!err) err = map(exports, "trust-filename", 1, "None specified", 1); - if (!err) err = map_block_killer(exports, "have-trustfile"); - } -#else - if (!err) err = map_block_killer(exports, "trust-support"); -#endif /* ndef FEATURE_TRUST */ - - if (err) - { - free_map(exports); - return JB_ERR_MEMORY; - } - - return template_fill_for_cgi(csp, "show-status", exports, rsp); -} - - -/********************************************************************* - * - * Function : cgi_show_url_info - * - * Description : CGI function that determines and shows which actions - * Privoxy will perform for a given url, and which - * matches starting from the defaults have lead to that. - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters - * - * CGI Parameters : - * url : The url whose actions are to be determined. - * If url is unset, the url-given conditional will be - * set, so that all but the form can be suppressed in - * the template. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_show_url_info(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters) -{ - char *url_param; - struct map *exports; - char buf[150]; - - assert(csp); - assert(rsp); - assert(parameters); - - if (NULL == (exports = default_exports(csp, "show-url-info"))) - { - return JB_ERR_MEMORY; - } - - /* - * Get the url= parameter (if present) and remove any leading/trailing spaces. - */ - url_param = strdup(lookup(parameters, "url")); - if (url_param == NULL) - { - free_map(exports); - return JB_ERR_MEMORY; - } - chomp(url_param); - - /* - * Handle prefixes. 4 possibilities: - * 1) "http://" or "https://" prefix present and followed by URL - OK - * 2) Only the "http://" or "https://" part is present, no URL - change - * to empty string so it will be detected later as "no URL". - * 3) Parameter specified but doesn't contain "http(s?)://" - add a - * "http://" prefix. - * 4) Parameter not specified or is empty string - let this fall through - * for now, next block of code will handle it. - */ - if (0 == strncmp(url_param, "http://", 7)) - { - if (url_param[7] == '\0') - { - /* - * Empty URL (just prefix). - * Make it totally empty so it's caught by the next if() - */ - url_param[0] = '\0'; - } - } - else if (0 == strncmp(url_param, "https://", 8)) - { - if (url_param[8] == '\0') - { - /* - * Empty URL (just prefix). - * Make it totally empty so it's caught by the next if() - */ - url_param[0] = '\0'; - } - } - else if (url_param[0] != '\0') - { - /* - * Unknown prefix - assume http:// - */ - char * url_param_prefixed = malloc(7 + 1 + strlen(url_param)); - if (NULL == url_param_prefixed) - { - free(url_param); - free_map(exports); - return JB_ERR_MEMORY; - } - strcpy(url_param_prefixed, "http://"); - strcpy(url_param_prefixed + 7, url_param); - free(url_param); - url_param = url_param_prefixed; - } - - - if (url_param[0] == '\0') - { - /* URL paramater not specified, display query form only. */ - free(url_param); - if (map_block_killer(exports, "url-given") - || map(exports, "url", 1, "", 1)) - { - free_map(exports); - return JB_ERR_MEMORY; - } - } - else - { - /* Given a URL, so query it. */ - jb_err err; - char *matches; - char *s; - int hits = 0; - struct file_list *fl; - struct url_actions *b; - struct http_request url_to_query[1]; - struct current_action_spec action[1]; - int i; - - if (map(exports, "url", 1, html_encode(url_param), 0)) - { - free(url_param); - free_map(exports); - return JB_ERR_MEMORY; - } - - init_current_action(action); - - if (map(exports, "default", 1, current_action_to_html(csp, action), 0)) - { - free_current_action(action); - free(url_param); - free_map(exports); - return JB_ERR_MEMORY; - } - - err = parse_http_url(url_param, url_to_query, csp); - - free(url_param); - - if (err == JB_ERR_MEMORY) - { - free_current_action(action); - free_map(exports); - return JB_ERR_MEMORY; - } - else if (err) - { - /* Invalid URL */ - - err = map(exports, "matches", 1, "[Invalid URL specified!]" , 1); - if (!err) err = map(exports, "final", 1, lookup(exports, "default"), 1); - - free_current_action(action); - - if (err) - { - free_map(exports); - return JB_ERR_MEMORY; - } - - return template_fill_for_cgi(csp, "show-url-info", exports, rsp); - } - - /* - * We have a warning about SSL paths. Hide it for insecure sites. - */ - if (!url_to_query->ssl) - { - if (map_block_killer(exports, "https")) - { - free_current_action(action); - free_map(exports); - return JB_ERR_MEMORY; - } - } - - matches = strdup(""); - - for (i = 0; i < MAX_ACTION_FILES; i++) - { - if (NULL == csp->config->actions_file_short[i] - || !strcmp(csp->config->actions_file_short[i], "standard")) continue; - - b = NULL; - hits = 1; - if ((fl = csp->actions_list[i]) != NULL) - { - if ((b = fl->f) != NULL) - { - /* FIXME: Hardcoded HTML! */ - string_append(&matches, "\n"); - - hits = 0; - b = b->next; - } - } - - for (; (b != NULL) && (matches != NULL); b = b->next) - { - if (url_match(b->url, url_to_query)) - { - string_append(&matches, "\n"); - - if (merge_current_action(action, b->action)) - { - freez(matches); - free_http_request(url_to_query); - free_current_action(action); - free_map(exports); - return JB_ERR_MEMORY; - } - hits++; - } - } - - if (!hits) - { - string_append(&matches, "\n"); - } - } - string_append(&matches, "
    In file: "); - string_join (&matches, html_encode(csp->config->actions_file_short[i])); - snprintf(buf, 150, ".action ", i); - string_append(&matches, buf); - string_append(&matches, "View config->actions_file_short[i])); - string_append(&matches, "\">Edit
    {"); - string_join (&matches, actions_to_html(csp, b->action)); - string_append(&matches, " }
    \n"); - string_join (&matches, html_encode(b->url->spec)); - string_append(&matches, "
    (no matches in this file)
    \n"); - - free_http_request(url_to_query); - - if (matches == NULL) - { - free_current_action(action); - free_map(exports); - return JB_ERR_MEMORY; - } - - if (map(exports, "matches", 1, matches , 0)) - { - free_current_action(action); - free_map(exports); - return JB_ERR_MEMORY; - } - - s = current_action_to_html(csp, action); - - free_current_action(action); - - if (map(exports, "final", 1, s, 0)) - { - free_map(exports); - return JB_ERR_MEMORY; - } - } - - return template_fill_for_cgi(csp, "show-url-info", exports, rsp); -} - - -/********************************************************************* - * - * Function : cgi_robots_txt - * - * Description : CGI function to return "/robots.txt". - * - * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters - * - * CGI Parameters : None - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err cgi_robots_txt(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters) -{ - char buf[100]; - jb_err err; - - rsp->body = strdup( - "# This is the Privoxy control interface.\n" - "# It isn't very useful to index it, and you're likely to break stuff.\n" - "# So go away!\n" - "\n" - "User-agent: *\n" - "Disallow: /\n" - "\n"); - if (rsp->body == NULL) - { - return JB_ERR_MEMORY; - } - - err = enlist_unique(rsp->headers, "Content-Type: text/plain", 13); - - rsp->is_static = 1; - - get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */ - if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf); - - return (err ? JB_ERR_MEMORY : JB_ERR_OK); -} - - -/********************************************************************* - * - * Function : show_defines - * - * Description : Add to a map the state od all conditional #defines - * used when building - * - * Parameters : - * 1 : exports = map to extend - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -static jb_err show_defines(struct map *exports) -{ - jb_err err = JB_ERR_OK; - -#ifdef FEATURE_ACL - if (!err) err = map_conditional(exports, "FEATURE_ACL", 1); -#else /* ifndef FEATURE_ACL */ - if (!err) err = map_conditional(exports, "FEATURE_ACL", 0); -#endif /* ndef FEATURE_ACL */ - -#ifdef FEATURE_CGI_EDIT_ACTIONS - if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 1); -#else /* ifndef FEATURE_COOKIE_JAR */ - if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 0); -#endif /* ndef FEATURE_COOKIE_JAR */ - -#ifdef FEATURE_COOKIE_JAR - if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 1); -#else /* ifndef FEATURE_COOKIE_JAR */ - if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 0); -#endif /* ndef FEATURE_COOKIE_JAR */ - -#ifdef FEATURE_FAST_REDIRECTS - if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1); -#else /* ifndef FEATURE_FAST_REDIRECTS */ - if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 0); -#endif /* ndef FEATURE_FAST_REDIRECTS */ - -#ifdef FEATURE_FORCE_LOAD - if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 1); - if (!err) err = map(exports, "FORCE_PREFIX", 1, FORCE_PREFIX, 1); -#else /* ifndef FEATURE_FORCE_LOAD */ - if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 0); - if (!err) err = map(exports, "FORCE_PREFIX", 1, "(none - disabled)", 1); -#endif /* ndef FEATURE_FORCE_LOAD */ - -#ifdef FEATURE_IMAGE_BLOCKING - if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 1); -#else /* ifndef FEATURE_IMAGE_BLOCKING */ - if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 0); -#endif /* ndef FEATURE_IMAGE_BLOCKING */ - -#ifdef FEATURE_IMAGE_DETECT_MSIE - if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 1); -#else /* ifndef FEATURE_IMAGE_DETECT_MSIE */ - if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 0); -#endif /* ndef FEATURE_IMAGE_DETECT_MSIE */ - -#ifdef FEATURE_KILL_POPUPS - if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 1); -#else /* ifndef FEATURE_KILL_POPUPS */ - if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 0); -#endif /* ndef FEATURE_KILL_POPUPS */ - -#ifdef FEATURE_NO_GIFS - if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 1); -#else /* ifndef FEATURE_NO_GIFS */ - if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 0); -#endif /* ndef FEATURE_NO_GIFS */ - -#ifdef FEATURE_PTHREAD - if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 1); -#else /* ifndef FEATURE_PTHREAD */ - if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 0); -#endif /* ndef FEATURE_PTHREAD */ - -#ifdef FEATURE_STATISTICS - if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 1); -#else /* ifndef FEATURE_STATISTICS */ - if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 0); -#endif /* ndef FEATURE_STATISTICS */ - -#ifdef FEATURE_TOGGLE - if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 1); -#else /* ifndef FEATURE_TOGGLE */ - if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 0); -#endif /* ndef FEATURE_TOGGLE */ - -#ifdef FEATURE_TRUST - if (!err) err = map_conditional(exports, "FEATURE_TRUST", 1); -#else /* ifndef FEATURE_TRUST */ - if (!err) err = map_conditional(exports, "FEATURE_TRUST", 0); -#endif /* ndef FEATURE_TRUST */ - -#ifdef STATIC_PCRE - if (!err) err = map_conditional(exports, "STATIC_PCRE", 1); -#else /* ifndef STATIC_PCRE */ - if (!err) err = map_conditional(exports, "STATIC_PCRE", 0); -#endif /* ndef STATIC_PCRE */ - -#ifdef STATIC_PCRS - if (!err) err = map_conditional(exports, "STATIC_PCRS", 1); -#else /* ifndef STATIC_PCRS */ - if (!err) err = map_conditional(exports, "STATIC_PCRS", 0); -#endif /* ndef STATIC_PCRS */ - - return err; -} - - -/********************************************************************* - * - * Function : show_rcs - * - * Description : Create a string with the rcs info for all sourcefiles - * - * Parameters : None - * - * Returns : A string, or NULL on out-of-memory. - * - *********************************************************************/ -static char *show_rcs(void) -{ - char *result = strdup(""); - char buf[BUFFER_SIZE]; - - /* Instead of including *all* dot h's in the project (thus creating a - * tremendous amount of dependencies), I will concede to declaring them - * as extern's. This forces the developer to add to this list, but oh well. - */ - -#define SHOW_RCS(__x) \ - { \ - extern const char __x[]; \ - sprintf(buf, "%s\n", __x); \ - string_append(&result, buf); \ - } - - /* In alphabetical order */ - SHOW_RCS(actions_h_rcs) - SHOW_RCS(actions_rcs) -#ifdef AMIGA - SHOW_RCS(amiga_h_rcs) - SHOW_RCS(amiga_rcs) -#endif /* def AMIGA */ - SHOW_RCS(cgi_h_rcs) - SHOW_RCS(cgi_rcs) -#ifdef FEATURE_CGI_EDIT_ACTIONS - SHOW_RCS(cgiedit_h_rcs) - SHOW_RCS(cgiedit_rcs) -#endif /* def FEATURE_CGI_EDIT_ACTIONS */ - SHOW_RCS(cgisimple_h_rcs) - SHOW_RCS(cgisimple_rcs) -#ifdef __MINGW32__ - SHOW_RCS(cygwin_h_rcs) -#endif - SHOW_RCS(deanimate_h_rcs) - SHOW_RCS(deanimate_rcs) - SHOW_RCS(encode_h_rcs) - SHOW_RCS(encode_rcs) - SHOW_RCS(errlog_h_rcs) - SHOW_RCS(errlog_rcs) - SHOW_RCS(filters_h_rcs) - SHOW_RCS(filters_rcs) - SHOW_RCS(gateway_h_rcs) - SHOW_RCS(gateway_rcs) - SHOW_RCS(jbsockets_h_rcs) - SHOW_RCS(jbsockets_rcs) - SHOW_RCS(jcc_h_rcs) - SHOW_RCS(jcc_rcs) -#ifdef FEATURE_KILL_POPUPS - SHOW_RCS(killpopup_h_rcs) - SHOW_RCS(killpopup_rcs) -#endif /* def FEATURE_KILL_POPUPS */ - SHOW_RCS(list_h_rcs) - SHOW_RCS(list_rcs) - SHOW_RCS(loadcfg_h_rcs) - SHOW_RCS(loadcfg_rcs) - SHOW_RCS(loaders_h_rcs) - SHOW_RCS(loaders_rcs) - SHOW_RCS(miscutil_h_rcs) - SHOW_RCS(miscutil_rcs) - SHOW_RCS(parsers_h_rcs) - SHOW_RCS(parsers_rcs) - SHOW_RCS(pcrs_rcs) - SHOW_RCS(pcrs_h_rcs) - SHOW_RCS(project_h_rcs) - SHOW_RCS(ssplit_h_rcs) - SHOW_RCS(ssplit_rcs) - SHOW_RCS(urlmatch_h_rcs) - SHOW_RCS(urlmatch_rcs) -#ifdef _WIN32 -#ifndef _WIN_CONSOLE - SHOW_RCS(w32log_h_rcs) - SHOW_RCS(w32log_rcs) - SHOW_RCS(w32res_h_rcs) - SHOW_RCS(w32taskbar_h_rcs) - SHOW_RCS(w32taskbar_rcs) -#endif /* ndef _WIN_CONSOLE */ - SHOW_RCS(win32_h_rcs) - SHOW_RCS(win32_rcs) -#endif /* def _WIN32 */ - -#undef SHOW_RCS - - return result; - -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/cgisimple.h b/cgisimple.h deleted file mode 100644 index 88501d7f..00000000 --- a/cgisimple.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef CGISIMPLE_H_INCLUDED -#define CGISIMPLE_H_INCLUDED -#define CGISIMPLE_H_VERSION "$Id: cgisimple.h,v 1.10 2002/03/26 22:29:54 swa Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/cgisimple.h,v $ - * - * Purpose : Declares functions to intercept request, generate - * html or gif answers, and to compose HTTP resonses. - * - * Functions declared include: - * - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: cgisimple.h,v $ - * Revision 1.10 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.9 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.8 2002/03/16 23:54:06 jongfoster - * Adding graceful termination feature, to help look for memory leaks. - * If you enable this (which, by design, has to be done by hand - * editing config.h) and then go to http://i.j.b/die, then the program - * will exit cleanly after the *next* request. It should free all the - * memory that was used. - * - * Revision 1.7 2002/03/08 16:43:59 oes - * Renamed cgi_transparent_png to cgi_transparent_image - * - * Revision 1.6 2002/03/07 03:48:59 oes - * - Changed built-in images from GIF to PNG - * (with regard to Unisys patent issue) - * - * Revision 1.5 2002/01/22 23:26:03 jongfoster - * Adding cgi_transparent_gif() for http://i.j.b/t - * - * Revision 1.4 2001/10/23 21:48:19 jongfoster - * Cleaning up error handling in CGI functions - they now send back - * a HTML error page and should never cause a FATAL error. (Fixes one - * potential source of "denial of service" attacks). - * - * CGI actions file editor that works and is actually useful. - * - * Ability to toggle JunkBuster remotely using a CGI call. - * - * You can turn off both the above features in the main configuration - * file, e.g. if you are running a multi-user proxy. - * - * Revision 1.3 2001/10/14 22:00:32 jongfoster - * Adding support for a 404 error when an invalid CGI page is requested. - * - * Revision 1.2 2001/10/02 15:31:20 oes - * Introduced show-request cgi - * - * Revision 1.1 2001/09/16 17:08:54 jongfoster - * Moving simple CGI functions from cgi.c to new file cgisimple.c - * - * - **********************************************************************/ - - -#include "project.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * CGI functions - */ -extern jb_err cgi_default (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_error_404 (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_robots_txt (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_send_banner (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_show_status (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_show_url_info(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_show_version (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_show_request (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_transparent_image (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -extern jb_err cgi_send_stylesheet(struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); - -#ifdef FEATURE_GRACEFUL_TERMINATION -extern jb_err cgi_die (struct client_state *csp, - struct http_response *rsp, - const struct map *parameters); -#endif - -/* Revision control strings from this header and associated .c file */ -extern const char cgisimple_rcs[]; -extern const char cgisimple_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef CGISIMPLE_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/cygwin.h b/cygwin.h deleted file mode 100644 index b28dd6a0..00000000 --- a/cygwin.h +++ /dev/null @@ -1,73 +0,0 @@ -#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: -*/ diff --git a/deanimate.c b/deanimate.c deleted file mode 100644 index 59ed56e9..00000000 --- a/deanimate.c +++ /dev/null @@ -1,504 +0,0 @@ -const char deanimate_rcs[] = "$Id: deanimate.c,v 1.11 2002/03/26 22:29:54 swa Exp $"; -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/deanimate.c,v $ - * - * Purpose : Declares functions to deanimate GIF images on the fly. - * - * Functions declared include: gif_deanimate, buf_free, - * buf_copy, buf_getbyte, gif_skip_data_block, and - * gif_extract_image - * - * Copyright : Written by and Copyright (C) 2001 by the the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the GIF file format specification (see - * http://tronche.com/computer-graphics/gif/gif89a.html) - * and ideas from the Image::DeAnim Perl module by - * Ken MacFarlane, - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: deanimate.c,v $ - * Revision 1.11 2002/03/26 22:29:54 swa - * we have a new homepage! - * - * Revision 1.10 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.9 2002/03/13 00:27:04 jongfoster - * Killing warnings - * - * Revision 1.8 2002/03/09 19:42:47 jongfoster - * Fixing more warnings - * - * Revision 1.7 2002/03/08 17:46:04 jongfoster - * Fixing int/size_t warnings - * - * Revision 1.6 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.5 2001/09/10 10:16:06 oes - * Silenced compiler warnings - * - * Revision 1.4 2001/07/18 12:28:49 oes - * - Added feature for extracting the first frame - * to gif_deanimate - * - Separated image buffer extension into buf_extend - * - Extended gif deanimation to GIF87a (untested!) - * - Cosmetics - * - * Revision 1.3 2001/07/15 13:57:50 jongfoster - * Adding #includes string.h and miscutil.h - * - * Revision 1.2 2001/07/13 13:46:20 oes - * Introduced GIF deanimation feature - * - * - **********************************************************************/ - - -#include "config.h" - -#include -#include - -#include "project.h" -#include "deanimate.h" -#include "miscutil.h" - -const char deanimate_h_rcs[] = DEANIMATE_H_VERSION; - -/********************************************************************* - * - * Function : buf_free - * - * Description : Safely frees a struct binbuffer - * - * Parameters : - * 1 : buf = Pointer to the binbuffer to be freed - * - * Returns : N/A - * - *********************************************************************/ -void buf_free(struct binbuffer *buf) -{ - if (buf == NULL) return; - - if (buf->buffer != NULL) - { - free(buf->buffer); - } - - free(buf); - -} - - -/********************************************************************* - * - * Function : buf_extend - * - * Description : Ensure that a given binbuffer can hold a given amount - * of bytes, by reallocating its buffer if necessary. - * Allocate new mem in chunks of 1024 bytes, so we don't - * have to realloc() too often. - * - * Parameters : - * 1 : buf = Pointer to the binbuffer - * 2 : length = Desired minimum size - * - * - * Returns : 0 on success, 1 on failiure. - * - *********************************************************************/ -int buf_extend(struct binbuffer *buf, size_t length) -{ - char *newbuf; - - if (buf->offset + length > buf->size) - { - buf->size = ((buf->size + length + (size_t)1023) & ~(size_t)1023); - newbuf = (char *)realloc(buf->buffer, buf->size); - - if (newbuf == NULL) - { - freez(buf->buffer); - return 1; - } - else - { - buf->buffer = newbuf; - return 0; - } - } - return 0; - -} - - -/********************************************************************* - * - * Function : buf_copy - * - * Description : Safely copies a given amount of bytes from one - * struct binbuffer to another, advancing the - * offsets appropriately. - * - * Parameters : - * 1 : src = Pointer to the source binbuffer - * 2 : dst = Pointer to the destination binbuffer - * 3 : length = Number of bytes to be copied - * - * Returns : 0 on success, 1 on failiure. - * - *********************************************************************/ -int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length) -{ - - /* - * Sanity check: Can't copy more data than we have - */ - if (src->offset + length > src->size) - { - return 1; - } - - /* - * Ensure that dst can hold the new data - */ - if (buf_extend(dst, length)) - { - return 1; - } - - /* - * Now that it's safe, memcpy() the desired amount of - * data from src to dst and adjust the offsets - */ - memcpy(dst->buffer + dst->offset, src->buffer + src->offset, length); - src->offset += length; - dst->offset += length; - - return 0; - -} - - -/********************************************************************* - * - * Function : buf_getbyte - * - * Description : Safely gets a byte from a given binbuffer at a - * given offset - * - * Parameters : - * 1 : src = Pointer to the source binbuffer - * 2 : offset = Offset to the desired byte - * - * Returns : The byte on success, or 0 on failiure - * - *********************************************************************/ -unsigned char buf_getbyte(struct binbuffer *src, size_t offset) -{ - if (src->offset + offset < src->size) - { - return (unsigned char)*(src->buffer + src->offset + offset); - } - else - { - return '\0'; - } - -} - - -/********************************************************************* - * - * Function : gif_skip_data_block - * - * Description : Safely advances the offset of a given struct binbuffer - * that contains a GIF image and whose offset is - * positioned at the start of a data block, behind - * that block. - * - * Parameters : - * 1 : buf = Pointer to the binbuffer - * - * Returns : 0 on success, or 1 on failiure - * - *********************************************************************/ -int gif_skip_data_block(struct binbuffer *buf) -{ - unsigned char c; - - /* - * Data blocks are sequences of chunks, which are headed - * by a one-byte length field, with the last chunk having - * zero length. - */ - while((c = buf_getbyte(buf, 0)) != '\0') - { - if ((buf->offset += c + 1) >= buf->size - 1) - { - return 1; - } - } - buf->offset++; - - return 0; - -} - - -/********************************************************************* - * - * Function : gif_extract_image - * - * Description : Safely extracts an image data block from a given - * struct binbuffer that contains a GIF image and whose - * offset is positioned at the start of a data block - * into a given destination binbuffer. - * - * Parameters : - * 1 : src = Pointer to the source binbuffer - * 2 : dst = Pointer to the destination binbuffer - * - * Returns : 0 on success, or 1 on failiure - * - *********************************************************************/ -int gif_extract_image(struct binbuffer *src, struct binbuffer *dst) -{ - unsigned char c; - - /* - * Remember the colormap flag and copy the image head - */ - c = buf_getbyte(src, 9); - if (buf_copy(src, dst, 10)) - { - return 1; - } - - /* - * If the image has a local colormap, copy it. - */ - if (c & 0x80) - { - if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1)))) - { - return 1; - } - } - if (buf_copy(src, dst, 1)) return 1; - - /* - * Copy the image chunk by chunk. - */ - while((c = buf_getbyte(src, 0)) != '\0') - { - if (buf_copy(src, dst, 1 + (size_t) c)) return 1; - } - if (buf_copy(src, dst, 1)) return 1; - - /* - * Trim and rewind the dst buffer - */ - if (NULL == (dst->buffer = (char *)realloc(dst->buffer, dst->offset))) return 1; - dst->size = dst->offset; - dst->offset = 0; - - return(0); - -} - -/********************************************************************* - * - * Function : gif_deanimate - * - * Description : Deanimate a given GIF image, i.e. given a GIF with - * an (optional) image block and an arbitrary number - * of image extension blocks, produce an output GIF with - * only one image block that contains the last image - * (extenstion) block of the original. - * Also strip Comments, Application extenstions, etc. - * - * Parameters : - * 1 : src = Pointer to the source binbuffer - * 2 : dst = Pointer to the destination binbuffer - * 3 : get_first_image = Flag: If set, get the first image - * If unset (default), get the last - * - * Returns : 0 on success, or 1 on failiure - * - *********************************************************************/ -int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image) -{ - unsigned char c; - struct binbuffer *image; - - if (NULL == src || NULL == dst) - { - return 1; - } - - c = buf_getbyte(src, 10); - - /* - * Check & copy GIF header - */ - if (strncmp(src->buffer, "GIF89a", 6) && strncmp(src->buffer, "GIF87a", 6)) - { - return 1; - } - else - { - if (buf_copy(src, dst, 13)) - { - return 1; - } - } - - /* - * Look for global colormap and copy if found. - */ - if(c & 0x80) - { - if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1)))) - { - return 1; - } - } - - /* - * Reserve a buffer for the current image block - */ - if (NULL == (image = (struct binbuffer *)zalloc(sizeof(*image)))) - { - return 1; - } - - /* - * Parse the GIF block by block and copy the relevant - * parts to dst - */ - while(src->offset < src->size) - { - switch(buf_getbyte(src, 0)) - { - /* - * End-of-GIF Marker: Append current image and return - */ - case 0x3b: - goto write; - - /* - * Image block: Extract to current image buffer. - */ - case 0x2c: - image->offset = 0; - if (gif_extract_image(src, image)) goto failed; - if (get_first_image) goto write; - continue; - - /* - * Extension block: Look at next byte and decide - */ - case 0x21: - switch (buf_getbyte(src, 1)) - { - /* - * Image extension: Copy extension header and image - * to the current image buffer - */ - case 0xf9: - image->offset = 0; - if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed; - if (gif_extract_image(src, image)) goto failed; - if (get_first_image) goto write; - continue; - - /* - * Application extension: Skip - */ - case 0xff: - if ((src->offset += 14) >= src->size || gif_skip_data_block(src)) goto failed; - continue; - - /* - * Comment extension: Skip - */ - case 0xfe: - if ((src->offset += 2) >= src->size || gif_skip_data_block(src)) goto failed; - continue; - - /* - * Plain text extension: Skip - */ - case 0x01: - if ((src->offset += 15) >= src->size || gif_skip_data_block(src)) goto failed; - continue; - - /* - * Ooops, what type of extension is that? - */ - default: - goto failed; - - } - - /* - * Ooops, what type of block is that? - */ - default: - goto failed; - - } - } /* -END- while src */ - - /* - * Either we got here by goto, or because the GIF is - * bogus and EOF was reached before an end-of-gif marker - * was found. - */ - -failed: - buf_free(image); - return 1; - - /* - * Append the current image to dst and return - */ - -write: - if (buf_copy(image, dst, image->size)) goto failed; - if (buf_extend(dst, 1)) goto failed; - *(dst->buffer + dst->offset++) = 0x3b; - buf_free(image); - return 0; - -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/deanimate.h b/deanimate.h deleted file mode 100644 index ede98477..00000000 --- a/deanimate.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef DEANIMATE_H_INCLUDED -#define DEANIMATE_H_INCLUDED -#define DEANIMATE_H_VERSION "$Id: deanimate.h,v 1.7 2002/03/24 13:25:43 swa Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/deanimate.h,v $ - * - * Purpose : Declares functions to deanimate GIF images on the fly. - * - * Functions declared include: gif_deanimate, buf_free - * - * - * Copyright : Written by and Copyright (C) 2001 Andreas S. Oesterhelt - * for the Privoxy team. http://www.privoxy.org/ - * - * Based on ideas from the Image::DeAnim Perl module by - * Ken MacFarlane, - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: deanimate.h,v $ - * Revision 1.7 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.6 2002/03/08 17:46:04 jongfoster - * Fixing int/size_t warnings - * - * Revision 1.5 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.4 2001/07/29 18:50:04 jongfoster - * Fixing "extern C" block, and renaming #define _DEANIMATE_H - * - * Revision 1.3 2001/07/18 12:29:05 oes - * Updated prototype for gif_deanimate - * - * Revision 1.2 2001/07/13 13:46:20 oes - * Introduced GIF deanimation feature - * - * - *********************************************************************/ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * A struct that holds a buffer, a read/write offset, - * and the buffer's capacity. - */ -struct binbuffer -{ - char *buffer; - size_t offset; - size_t size; -}; - -/* - * Function prototypes - */ -extern int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image); -extern void buf_free(struct binbuffer *buf); - -/* - * Revision control strings from this header and associated .c file - */ -extern const char deanimate_rcs[]; -extern const char deanimate_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef DEANIMATE_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/encode.c b/encode.c deleted file mode 100644 index 09c7b5f7..00000000 --- a/encode.c +++ /dev/null @@ -1,483 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include - -#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: -*/ diff --git a/encode.h b/encode.h deleted file mode 100644 index 875b9662..00000000 --- a/encode.h +++ /dev/null @@ -1,82 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/errlog.c b/errlog.c deleted file mode 100644 index 4a3cfe7e..00000000 --- a/errlog.c +++ /dev/null @@ -1,969 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" -#include "miscutil.h" - -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#endif /* !defined(_WIN32) && !defined(__OS2__) */ - -#include -#include -#ifdef FEATURE_PTHREAD -#include -#endif /* def FEATURE_PTHREAD */ - -#ifdef _WIN32 -#ifndef STRICT -#define STRICT -#endif -#include -#ifndef _WIN_CONSOLE -#include "w32log.h" -#endif /* ndef _WIN_CONSOLE */ -#endif /* def _WIN32 */ - -#ifdef __OS2__ -#include /* For sock_errno */ -#define INCL_DOS -#include -#endif - -#include "errlog.h" -#include "project.h" -#include "jcc.h" - -const char errlog_h_rcs[] = ERRLOG_H_VERSION; - - -/* - * LOG_LEVEL_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: -*/ diff --git a/errlog.h b/errlog.h deleted file mode 100644 index c3424dd0..00000000 --- a/errlog.h +++ /dev/null @@ -1,177 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ - diff --git a/filters.c b/filters.c deleted file mode 100644 index ff70ac56..00000000 --- a/filters.c +++ /dev/null @@ -1,1597 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#ifndef __OS2__ -#include -#endif /* ndef __OS2__ */ -#include -#else -#include -#endif /* ndef _WIN32 */ - -#ifdef __OS2__ -#include -#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, "
  • %s
  • \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, "
  • %s
    \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: -*/ diff --git a/filters.h b/filters.h deleted file mode 100644 index 75da5b1c..00000000 --- a/filters.h +++ /dev/null @@ -1,282 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/gateway.c b/gateway.c deleted file mode 100644 index 7584b945..00000000 --- a/gateway.c +++ /dev/null @@ -1,396 +0,0 @@ -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 - * - * 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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include - -#ifndef _WIN32 -#include -#endif - -#include -#include - -#ifdef _WIN32 -#include -#endif /* def _WIN32 */ - -#ifdef __BEOS__ -#include -#endif /* def __BEOS__ */ - -#ifdef __OS2__ -#include -#endif /* def __OS2__ */ - -#include "project.h" -#include "jcc.h" -#include "errlog.h" -#include "jbsockets.h" -#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: -*/ diff --git a/gateway.h b/gateway.h deleted file mode 100644 index d96bc58d..00000000 --- a/gateway.h +++ /dev/null @@ -1,123 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/jbsockets.c b/jbsockets.c deleted file mode 100644 index 9ee43150..00000000 --- a/jbsockets.c +++ /dev/null @@ -1,817 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - -#ifndef STRICT -#define STRICT -#endif -#include -#include -#include - -#else - -#ifndef __OS2__ -#include -#endif -#include -#include -#include -#include -#include - -#ifndef __BEOS__ -#include -#ifndef __OS2__ -#include -#endif -#else -#include -#endif - -#if defined(__EMX__) || defined (__OS2__) -#include /* OS/2/EMX needs a little help with select */ -#ifdef __OS2__ -#include -#endif -#endif - -#endif - -#include "project.h" -#include "jbsockets.h" -#include "filters.h" -#include "errlog.h" - -const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; - - -/********************************************************************* - * - * 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: -*/ diff --git a/jbsockets.h b/jbsockets.h deleted file mode 100644 index dc8f7a41..00000000 --- a/jbsockets.h +++ /dev/null @@ -1,130 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/jcc.c b/jcc.c deleted file mode 100644 index 62694b0c..00000000 --- a/jcc.c +++ /dev/null @@ -1,2351 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef FEATURE_PTHREAD -#include -#endif /* def FEATURE_PTHREAD */ - -#ifdef _WIN32 -# ifndef FEATURE_PTHREAD -# ifndef STRICT -# define STRICT -# endif -# include -# include -# endif /* ndef FEATURE_PTHREAD */ - -# include "win32.h" -# ifndef _WIN_CONSOLE -# include "w32log.h" -# endif /* ndef _WIN_CONSOLE */ - -#else /* ifndef _WIN32 */ - -# if !defined (__OS2__) -# include -# include -# endif /* ndef __OS2__ */ -# include -# include -# include - -#ifdef sun -#include -#endif /* sun */ - -#ifdef unix -#include -#include -#endif - -# include - -# ifdef __BEOS__ -# include /* BeOS has select() for sockets only. */ -# include /* declarations for threads and stuff. */ -# endif - -# if defined(__EMX__) || defined(__OS2__) -# include /* OS/2/EMX needs a little help with select */ -# endif -# ifdef __OS2__ -#define INCL_DOS -# include -#define bzero(B,N) memset(B,0x00,n) -# endif - -# ifndef FD_ZERO -# include -# endif - -#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: -*/ diff --git a/jcc.h b/jcc.h deleted file mode 100644 index 1778f1ea..00000000 --- a/jcc.h +++ /dev/null @@ -1,140 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/killpopup.c b/killpopup.c deleted file mode 100644 index 34653738..00000000 --- a/killpopup.c +++ /dev/null @@ -1,213 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#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, "'); - if (close_p) - { - /* we are now between */ - 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: -*/ diff --git a/killpopup.h b/killpopup.h deleted file mode 100644 index 7d2eadf6..00000000 --- a/killpopup.h +++ /dev/null @@ -1,103 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/list.c b/list.c deleted file mode 100644 index 6cd7f891..00000000 --- a/list.c +++ /dev/null @@ -1,1064 +0,0 @@ -const char list_rcs[] = "$Id: list.c,v 1.14 2002/03/24 13:25:43 swa Exp $"; -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/list.c,v $ - * - * Purpose : Declares functions to handle lists. - * Functions declared include: - * `destroy_list', `enlist' and `list_to_text' - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: list.c,v $ - * Revision 1.14 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.13 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.12 2001/10/25 03:40:48 david__schmidt - * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple - * threads to call select() simultaneously. So, it's time to do a real, live, - * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__ - * (native). Both versions will work, but using __OS2__ offers multi-threading. - * - * Revision 1.11 2001/10/23 21:21:03 jongfoster - * New error handling - error codes are now jb_errs, not ints. - * Changed the way map() handles out-of-memory, to dramatically - * reduce the amount of error-checking clutter needed. - * - * Revision 1.10 2001/09/16 17:30:24 jongfoster - * Fixing a compiler warning. - * - * Revision 1.9 2001/09/16 13:20:29 jongfoster - * Rewrite of list library. Now has seperate header and list_entry - * structures. Also added a large sprinking of assert()s to the list - * code. - * - * Revision 1.8 2001/08/07 14:00:20 oes - * Fixed comment - * - * Revision 1.7 2001/08/05 16:06:20 jongfoster - * Modifiying "struct map" so that there are now separate header and - * "map_entry" structures. This means that functions which modify a - * map no longer need to return a pointer to the modified map. - * Also, it no longer reverses the order of the entries (which may be - * important with some advanced template substitutions). - * - * Revision 1.6 2001/07/31 14:44:51 oes - * list_to_text() now appends empty line at end - * - * Revision 1.5 2001/06/29 21:45:41 oes - * Indentation, CRLF->LF, Tab-> Space - * - * Revision 1.4 2001/06/29 13:30:22 oes - * - Added Convenience function enlist_unique_header(), - * which takes the Header name and value as separate - * arguments and thus saves the pain of sprintf()ing - * and determining the Header name length to enlist_unique - * - Improved comments - * - Removed logentry from cancelled commit - * - * Revision 1.3 2001/06/03 19:12:24 oes - * functions for new struct map, extended enlist_unique - * - * Revision 1.2 2001/06/01 18:49:17 jongfoster - * Replaced "list_share" with "list" - the tiny memory gain was not - * worth the extra complexity. - * - * Revision 1.1 2001/05/31 21:11:53 jongfoster - * - Moved linked list support to new "list.c" file. - * Structure definitions are still in project.h, - * function prototypes are now in "list.h". - * - Added support for "struct list_share", which is identical - * to "struct list" except it saves memory by not duplicating - * the strings. Obviously, this only works if there is some - * other way of managing the memory used by the strings. - * (These list_share lists are used for lists which last - * for only 1 request, and where all the list entries are - * just coming directly from entries in the actionsfile.) - * Note that you still need to destroy list_share lists - * properly to free the nodes - it's only the strings - * which are shared. - * - * - *********************************************************************/ - - -#include "config.h" - -#ifndef _WIN32 -/* FIXME: The following headers are not needed for Win32. Are they - * needed on other platforms? - */ -#include -#include -#include -#include -#endif -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#endif - -#include - -#include "project.h" -#include "list.h" -#include "miscutil.h" - -const char list_h_rcs[] = LIST_H_VERSION; - - -static int list_is_valid (const struct list *the_list); - - -/********************************************************************* - * - * Function : list_init - * - * Description : Create a new, empty list in user-allocated memory. - * Caller should allocate a "struct list" variable, - * then pass it to this function. - * (Implementation note: Rather than calling this - * function, you can also just memset the memory to - * zero, e.g. if you have a larger structure you - * want to initialize quickly. However, that isn't - * really good design.) - * - * Parameters : - * 1 : the_list = pointer to list - * - * Returns : N/A - * - *********************************************************************/ -void init_list(struct list *the_list) -{ - memset(the_list, '\0', sizeof(*the_list)); -} - - -/********************************************************************* - * - * Function : destroy_list - * - * Description : Destroy a string list (opposite of list_init). - * On return, the memory used by the list entries has - * been freed, but not the memory used by the_list - * itself. You should not re-use the_list without - * calling list_init(). - * - * (Implementation note: You *can* reuse the_list - * without calling list_init(), but please don't. - * If you want to remove all entries from a list - * and still have a usable list, then use - * list_remove_all().) - * - * Parameters : - * 1 : the_list = pointer to list - * - * Returns : N/A - * - *********************************************************************/ -void destroy_list (struct list *the_list) -{ - struct list_entry *cur_entry, *next_entry; - - assert(the_list); - - for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry) - { - next_entry = cur_entry->next; - freez(cur_entry->str); - free(cur_entry); - } - - the_list->first = NULL; - the_list->last = NULL; -} - - -/********************************************************************* - * - * Function : list_is_valid - * - * Description : Check that a string list is valid. The intended - * usage is "assert(list_is_valid(the_list))". - * Currently this checks that "the_list->last" - * is correct, and that the list dosn't contain - * circular references. It is likely to crash if - * it's passed complete garbage. - * - * Parameters : - * 1 : the_list = pointer to list. Must be non-null. - * - * Returns : 1 if list is valid, 0 otherwise. - * - *********************************************************************/ -static int list_is_valid (const struct list *the_list) -{ - /* - * If you don't want this check, just change the line below - * from "#if 1" to "#if 0". - */ -#if 1 - const struct list_entry *cur_entry; - const struct list_entry *last_entry = NULL; - int length = 0; - - assert(the_list); - - for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next) - { - last_entry = cur_entry; - - if (cur_entry->str) - { - /* - * Just check that this string can be accessed - i.e. it's a valid - * pointer. - */ - strlen(cur_entry->str); - } - - /* - * Check for looping back to first - */ - if ((length != 0) && (cur_entry == the_list->first)) - { - return 0; - } - - /* - * Arbitrarily limit length to prevent infinite loops. - */ - if (++length > 1000) - { - return 0; - } - - /* - * Check this isn't marked as the last entry, unless of course it's - * *really* the last entry. - */ - if ((the_list->last == cur_entry) && (cur_entry->next != NULL)) - { - /* This is the last entry, but there's data after it !!?? */ - return 0; - } - } - - return (the_list->last == last_entry); -#else - return 1; -#endif -} - -/********************************************************************* - * - * Function : enlist - * - * Description : Append a string into a specified string list. - * - * Parameters : - * 1 : the_list = pointer to list - * 2 : str = string to add to the list (maybe NULL) - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, the_list will be unchanged. - * - *********************************************************************/ -jb_err enlist(struct list *the_list, const char *str) -{ - struct list_entry *cur; - - assert(the_list); - assert(list_is_valid(the_list)); - - if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur)))) - { - return JB_ERR_MEMORY; - } - - if (str) - { - if (NULL == (cur->str = strdup(str))) - { - free(cur); - return JB_ERR_MEMORY; - } - } - /* else { cur->str = NULL; } - implied by zalloc */ - - /* cur->next = NULL; - implied by zalloc */ - - if (the_list->last) - { - the_list->last->next = cur; - the_list->last = cur; - } - else - { - the_list->first = cur; - the_list->last = cur; - } - - assert(list_is_valid(the_list)); - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : enlist_first - * - * Description : Append a string as first element into a specified - * string list. - * - * Parameters : - * 1 : the_list = pointer to list - * 2 : str = string to add to the list (maybe NULL) - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, the_list will be unchanged. - * - *********************************************************************/ -jb_err enlist_first(struct list *the_list, const char *str) -{ - struct list_entry *cur; - - assert(the_list); - assert(list_is_valid(the_list)); - - if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur)))) - { - return JB_ERR_MEMORY; - } - - if (str) - { - if (NULL == (cur->str = strdup(str))) - { - free(cur); - return JB_ERR_MEMORY; - } - } - /* else { cur->str = NULL; } - implied by zalloc */ - - cur->next = the_list->first; - - the_list->first = cur; - if (the_list->last == NULL) - { - the_list->last = cur; - } - - assert(list_is_valid(the_list)); - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : enlist_unique - * - * Description : Append a string into a specified string list, - * if & only if it's not there already. - * If the num_significant_chars argument is nonzero, - * only compare up to the nth character. - * - * Parameters : - * 1 : the_list = pointer to list - * 2 : str = string to add to the list - * 3 : num_significant_chars = number of chars to use - * for uniqueness test, or 0 to require an exact match. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, the_list will be unchanged. - * "Success" does not indicate whether or not the - * item was already in the list. - * - *********************************************************************/ -jb_err enlist_unique(struct list *the_list, const char *str, - size_t num_significant_chars) -{ - struct list_entry *cur_entry; - - assert(the_list); - assert(list_is_valid(the_list)); - assert(str); - assert(num_significant_chars >= 0); - assert(num_significant_chars <= strlen(str)); - - if (num_significant_chars > 0) - { - for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next) - { - if ( (cur_entry->str != NULL) - && (0 == strncmp(str, cur_entry->str, num_significant_chars))) - { - /* Already there */ - return JB_ERR_OK; - } - } - } - else - { - /* Test whole string */ - for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next) - { - if ( (cur_entry->str != NULL) && (0 == strcmp(str, cur_entry->str))) - { - /* Already there */ - return JB_ERR_OK; - } - } - } - - return enlist(the_list, str); -} - - -/********************************************************************* - * - * Function : enlist_unique_header - * - * Description : Make a HTTP header from the two strings name and value, - * and append the result into a specified string list, - * if & only if there isn't already a header with that name. - * - * Parameters : - * 1 : the_list = pointer to list - * 2 : name = HTTP header name (e.g. "Content-type") - * 3 : value = HTTP header value (e.g. "text/html") - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, the_list will be unchanged. - * "Success" does not indicate whether or not the - * header was already in the list. - * - *********************************************************************/ -jb_err enlist_unique_header(struct list *the_list, const char *name, - const char *value) -{ - size_t length; - jb_err result; - char *str; - - assert(the_list); - assert(list_is_valid(the_list)); - assert(name); - assert(value); - - length = strlen(name) + 2; - if (NULL == (str = (char *)malloc(length + strlen(value) + 1))) - { - return JB_ERR_MEMORY; - } - strcpy(str, name); - str[length - 2] = ':'; - str[length - 1] = ' '; - strcpy(str + length, value); - - result = enlist_unique(the_list, str, length); - - free(str); - - assert(list_is_valid(the_list)); - - return result; - -} - - -/********************************************************************* - * - * Function : list_remove_all - * - * Description : Remove all entries from a list. On return, the_list - * is a valid, empty list. Note that this is similar - * to destroy_list(), but the difference is that this - * function guarantees that the list structure is still - * valid after the call. - * - * Parameters : - * 1 : the_list = pointer to list - * - * Returns : N/A - * - *********************************************************************/ -void list_remove_all(struct list *the_list) -{ - struct list_entry *cur_entry; - struct list_entry *next_entry; - - assert(the_list); - assert(list_is_valid(the_list)); - - for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry) - { - next_entry = cur_entry->next; - freez(cur_entry->str); - free(cur_entry); - } - - the_list->first = the_list->last = NULL; - - assert(list_is_valid(the_list)); -} - - -/********************************************************************* - * - * Function : list_to_text - * - * Description : "Flatten" a string list into 1 long \r\n delimited string, - * adding an empty line at the end. NULL entries are ignored. - * This function does not change the_list. - * - * Parameters : - * 1 : the_list = pointer to list - * - * Returns : NULL on malloc error, else new long string. - * Caller must free() it. - * - *********************************************************************/ -char *list_to_text(const struct list *the_list) -{ - struct list_entry *cur_entry; - char *ret = NULL; - char *s; - size_t size = 2; - - assert(the_list); - assert(list_is_valid(the_list)); - - for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next) - { - if (cur_entry->str) - { - size += strlen(cur_entry->str) + 2; - } - } - - if ((ret = (char *)malloc(size + 1)) == NULL) - { - return NULL; - } - - ret[size] = '\0'; - - s = ret; - - for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next) - { - if (cur_entry->str) - { - strcpy(s, cur_entry->str); - s += strlen(s); - *s++ = '\r'; *s++ = '\n'; - } - } - *s++ = '\r'; *s++ = '\n'; - - return ret; -} - - -/********************************************************************* - * - * Function : list_remove_item - * - * Description : Remove a string from a specified string list. - * - * Parameters : - * 1 : the_list = pointer to list - * 2 : str = string to remove from the list - non-NULL - * - * Returns : Number of times it was removed. - * - *********************************************************************/ -int list_remove_item(struct list *the_list, const char *str) -{ - struct list_entry *prev = NULL; - struct list_entry *cur; - struct list_entry *next; - int count = 0; - - assert(the_list); - assert(list_is_valid(the_list)); - assert(str); - - cur = the_list->first; - - while (cur != NULL) - { - next = cur->next; - - if ((cur->str != NULL) && (0 == strcmp(str, cur->str))) - { - count++; - - if (prev != NULL) - { - prev->next = next; - } - else - { - the_list->first = next; - } - free((char *)cur->str); - free(cur); - } - else - { - prev = cur; - } - cur = next; - } - - the_list->last = prev; - - assert(list_is_valid(the_list)); - - return count; -} - - -/********************************************************************* - * - * Function : list_remove_list - * - * Description : Remove all strings in one list from another list. - * This is currently a brute-force algorithm - * (it compares every pair of strings). - * - * Parameters : - * 1 : dest = list to change - * 2 : src = list of strings to remove - * - * Returns : Total number of strings removed. - * - *********************************************************************/ -int list_remove_list(struct list *dest, const struct list *src) -{ - struct list_entry *cur; - int count = 0; - - assert(src); - assert(dest); - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - for (cur = src->first; cur != NULL; cur = cur->next) - { - if (cur->str != NULL) - { - count += list_remove_item(dest, cur->str); - } - } - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return count; -} - - -/********************************************************************* - * - * Function : list_duplicate - * - * Description : Copy a string list - * - * Parameters : - * 1 : dest = Destination list. Must be a valid list. - * All existing entries will be removed. - * 1 : src = pointer to source list for copy. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, dest will be empty. - * - *********************************************************************/ -jb_err list_duplicate(struct list *dest, const struct list *src) -{ - struct list_entry * cur_src; - struct list_entry * cur_dest; - - assert(src); - assert(dest); - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - list_remove_all(dest); - - /* Need to process first entry specially so we can set dest->first */ - cur_src = src->first; - if (cur_src) - { - cur_dest = dest->first = (struct list_entry *)zalloc(sizeof(*cur_dest)); - if (cur_dest == NULL) - { - destroy_list(dest); - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_MEMORY; - } - - if (cur_src->str) - { - cur_dest->str = strdup(cur_src->str); - if (cur_dest->str == NULL) - { - destroy_list(dest); - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_MEMORY; - } - } - /* else { cur_dest->str = NULL; } - implied by zalloc */ - - /* Now process the rest */ - for (cur_src = cur_src->next; cur_src; cur_src = cur_src->next) - { - cur_dest = cur_dest->next = (struct list_entry *)zalloc(sizeof(*cur_dest)); - if (cur_dest == NULL) - { - destroy_list(dest); - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_MEMORY; - } - if (cur_src->str) - { - cur_dest->str = strdup(cur_src->str); - if (cur_dest->str == NULL) - { - destroy_list(dest); - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_MEMORY; - } - } - /* else { cur_dest->str = NULL; } - implied by zalloc */ - } - - dest->last = cur_dest; - } - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : list_append_list_unique - * - * Description : Append a string list to another list. - * Duplicate items are not added. - * - * Parameters : - * 1 : dest = pointer to destination list for merge. - * 2 : src = pointer to source for merge. - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * On error, some (but not all) of src might have - * been copied into dest. - * - *********************************************************************/ -jb_err list_append_list_unique(struct list *dest, const struct list *src) -{ - struct list_entry * cur; - - assert(src); - assert(dest); - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - for (cur = src->first; cur; cur = cur->next) - { - if (cur->str) - { - if (enlist_unique(dest, cur->str, 0)) - { - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_MEMORY; - } - } - } - - assert(list_is_valid(src)); - assert(list_is_valid(dest)); - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : list_is_empty - * - * Description : Test whether a list is empty. Does not change the list. - * - * Parameters : - * 1 : the_list = pointer to list to test. - * - * Returns : Nonzero iff the list contains no entries. - * - *********************************************************************/ -int list_is_empty(const struct list *the_list) -{ - assert(the_list); - assert(list_is_valid(the_list)); - - return (the_list->first == NULL); -} - - -/********************************************************************* - * - * Function : new_map - * - * Description : Create a new, empty map. - * - * Parameters : N/A - * - * Returns : A new, empty map, or NULL if out of memory. - * - *********************************************************************/ -struct map *new_map(void) -{ - return (struct map *) zalloc(sizeof(struct map)); -} - - -/********************************************************************* - * - * Function : free_map - * - * Description : Free the memory occupied by a map and its - * depandant strings - * - * Parameters : - * 1 : the_map = map to be freed. May be NULL. - * - * Returns : N/A - * - *********************************************************************/ -void free_map(struct map *the_map) -{ - struct map_entry *cur_entry; - struct map_entry *next_entry; - - if (the_map == NULL) - { - return; - } - - for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry) - { - freez(cur_entry->name); - freez(cur_entry->value); - - next_entry = cur_entry->next; - free(cur_entry); - } - - the_map->first = the_map->last = NULL; - - free(the_map); -} - - -/********************************************************************* - * - * Function : map - * - * Description : Add a mapping from given name to given value to a - * given map. - * - * Note: Since all strings will be free()d in free_map() - * later, set the copy flags for constants or - * strings that will be independantly free()d. - * - * Note2: This function allows NULL parameters - it - * returns JB_ERR_MEMORY in that case. - * - * Note3: If this function returns JB_ERR_MEMORY, - * it will free(name) unless you specify - * name_needs_copying, and similarly it will - * free(value) unless you specify - * value_needs_copying. - * - * Due to Note2 and Note3 above, the following code - * is legal, and will never crash or leak memory even - * if the system runs out of memory: - * - * err = map(mymap, "xyz", 1, html_encode(somestring), 0); - * - * err will be set to JB_ERR_MEMORY if either call runs - * out-of-memory. Without these features, you would - * need to check the return value of html_encode in the - * above example for NULL, which (at least) doubles the - * amount of error-checking code needed. - * - * Parameters : - * 1 : the_map = map to add to - * 2 : name = name to add - * 3 : name_needs_copying = flag set if a copy of name should be used - * 4 : value = value to add - * 5 : value_needs_copying = flag set if a copy of value should be used - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out-of-memory error. - * - *********************************************************************/ -jb_err map(struct map *the_map, - const char *name, int name_needs_copying, - const char *value, int value_needs_copying) -{ - struct map_entry *new_entry; - - assert(the_map); - - if ( (NULL == value) - || (NULL == name) - || (NULL == (new_entry = zalloc(sizeof(*new_entry)))) ) - { - if ((name != NULL) && (!name_needs_copying)) - { - free((char *)name); - } - if ((value != NULL) && (!value_needs_copying)) - { - free((char *)value); - } - return JB_ERR_MEMORY; - } - - if (name_needs_copying) - { - if (NULL == (name = strdup(name))) - { - free(new_entry); - if (!value_needs_copying) - { - free((char *)value); - } - return JB_ERR_MEMORY; - } - } - - if (value_needs_copying) - { - if (NULL == (value = strdup(value))) - { - free((char *)name); - free(new_entry); - return JB_ERR_MEMORY; - } - } - - new_entry->name = name; - new_entry->value = value; - /* new_entry->next = NULL; - implied by zalloc */ - - if (the_map->last) - { - the_map->last->next = new_entry; - the_map->last = new_entry; - } - else - { - the_map->first = new_entry; - the_map->last = new_entry; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : lookup - * - * Description : Look up an item with a given name in a map, and - * return its value - * - * Parameters : - * 1 : the_map = map to look in - * 2 : name = name parameter to look for - * - * Returns : the value if found, else the empty string. - * Return value is alloced as part of the map, so - * it is freed when the map is destroyed. Caller - * must not free or modify it. - * - *********************************************************************/ -const char *lookup(const struct map *the_map, const char *name) -{ - const struct map_entry *cur_entry; - - assert(the_map); - assert(name); - - for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next) - { - if (!strcmp(name, cur_entry->name)) - { - return cur_entry->value; - } - } - return ""; -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/list.h b/list.h deleted file mode 100644 index afa44238..00000000 --- a/list.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef LIST_H_INCLUDED -#define LIST_H_INCLUDED -#define LIST_H_VERSION "$Id: list.h,v 1.11 2002/03/24 13:25:43 swa Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/list.h,v $ - * - * Purpose : Declares functions to handle lists. - * Functions declared include: - * `destroy_list', `enlist' and `list_to_text' - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: list.h,v $ - * Revision 1.11 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.10 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.9 2001/10/23 21:21:03 jongfoster - * New error handling - error codes are now jb_errs, not ints. - * Changed the way map() handles out-of-memory, to dramatically - * reduce the amount of error-checking clutter needed. - * - * Revision 1.8 2001/09/16 17:30:24 jongfoster - * Fixing a compiler warning. - * - * Revision 1.7 2001/09/16 13:20:29 jongfoster - * Rewrite of list library. Now has seperate header and list_entry - * structures. Also added a large sprinking of assert()s to the list - * code. - * - * Revision 1.6 2001/08/05 16:06:20 jongfoster - * Modifiying "struct map" so that there are now separate header and - * "map_entry" structures. This means that functions which modify a - * map no longer need to return a pointer to the modified map. - * Also, it no longer reverses the order of the entries (which may be - * important with some advanced template substitutions). - * - * Revision 1.5 2001/07/29 18:43:08 jongfoster - * Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to - * ANSI C rules. - * - * Revision 1.4 2001/06/29 13:30:37 oes - * - Introduced enlist_unique_header() - * - Removed logentry from cancelled commit - * - * Revision 1.3 2001/06/03 11:03:48 oes - * introduced functions for new list type "map": map(), lookup(), - * free_map(), and extended enlist_unique - * - * Revision 1.2 2001/06/01 18:49:17 jongfoster - * Replaced "list_share" with "list" - the tiny memory gain was not - * worth the extra complexity. - * - * Revision 1.1 2001/05/31 21:11:53 jongfoster - * - Moved linked list support to new "list.c" file. - * Structure definitions are still in project.h, - * function prototypes are now in "list.h". - * - Added support for "struct list_share", which is identical - * to "struct list" except it saves memory by not duplicating - * the strings. Obviously, this only works if there is some - * other way of managing the memory used by the strings. - * (These list_share lists are used for lists which last - * for only 1 request, and where all the list entries are - * just coming directly from entries in the actionsfile.) - * Note that you still need to destroy list_share lists - * properly to free the nodes - it's only the strings - * which are shared. - * - * - *********************************************************************/ - - -#include "project.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * struct list - * - * A linked list class. - */ - -extern void init_list (struct list *the_list); -extern void destroy_list (struct list *the_list); - -extern jb_err enlist (struct list *the_list, const char *str); -extern jb_err enlist_unique (struct list *the_list, const char *str, size_t num_significant_chars); -extern jb_err enlist_unique_header (struct list *the_list, const char *name, const char *value); -extern jb_err enlist_first (struct list *the_list, const char *str); -extern jb_err list_append_list_unique(struct list *dest, const struct list *src); -extern jb_err list_duplicate (struct list *dest, const struct list *src); - -extern int list_remove_item(struct list *the_list, const char *str); -extern int list_remove_list(struct list *dest, const struct list *src); -extern void list_remove_all (struct list *the_list); - -extern int list_is_empty(const struct list *the_list); - -extern char * list_to_text(const struct list *the_list); - - -/* - * struct map - * - * A class which maps names to values. - * - * Note: You must allocate this through new_map() and free it - * through free_map(). - */ - -extern struct map * new_map (void); -extern void free_map (struct map * the_map); - -extern int map (struct map * the_map, - const char * name, int name_needs_copying, - const char * value, int value_needs_copying); -extern const char * lookup (const struct map * the_map, const char * name); - - -/* Revision control strings from this header and associated .c file */ -extern const char list_rcs[]; -extern const char list_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef LIST_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/loadcfg.c b/loadcfg.c deleted file mode 100644 index 1d6a10eb..00000000 --- a/loadcfg.c +++ /dev/null @@ -1,1595 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 - -# ifndef STRICT -# define STRICT -# endif -# include - -# include "win32.h" -# ifndef _WIN_CONSOLE -# include "w32log.h" -# endif /* ndef _WIN_CONSOLE */ - -/* VC++ has "_snprintf", not "snprintf" */ -#define snprintf _snprintf - -#else /* ifndef _WIN32 */ - -#ifndef __OS2__ -# include -# include -#endif -# include -# include -# include - -#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, - "
    \nWARNING: Wrong number of parameters for " - "deny-access directive in configuration file.

    \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, - "
    \nWARNING: Invalid source IP for deny-access directive" - " in configuration file: \""); - string_append(&config->proxy_args, - vec[0]); - string_append(&config->proxy_args, - "\"

    \n"); - freez(cur_acl); - continue; - } - if (vec_count == 2) - { - if (acl_addr(vec[1], cur_acl->dst) < 0) - { - log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access " - "directive in configuration file: \"%s\"", vec[0]); - string_append(&config->proxy_args, - "
    \nWARNING: Invalid destination IP for deny-access directive" - " in configuration file: \""); - string_append(&config->proxy_args, - vec[0]); - string_append(&config->proxy_args, - "\"

    \n"); - freez(cur_acl); - continue; - } - } - - /* - * 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, - "
    \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, - "
    \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, - "
    \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, - "
    \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, - "
    \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, - "
    \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, - "
    \nWARNING: Wrong number of parameters for " - "permit-access directive in configuration file.

    \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, - "
    \nWARNING: Invalid source IP for permit-access directive" - " in configuration file: \""); - string_append(&config->proxy_args, - vec[0]); - string_append(&config->proxy_args, - "\"

    \n"); - freez(cur_acl); - continue; - } - if (vec_count == 2) - { - if (acl_addr(vec[1], cur_acl->dst) < 0) - { - log_error(LOG_LEVEL_ERROR, "Invalid destination IP for " - "permit-access directive in configuration file: \"%s\"", - vec[0]); - string_append(&config->proxy_args, - "
    \nWARNING: Invalid destination IP for permit-access directive" - " in configuration file: \""); - string_append(&config->proxy_args, - vec[0]); - string_append(&config->proxy_args, - "\"

    \n"); - freez(cur_acl); - continue; - } - } - - /* - * Add it to the list. Note we reverse the list to get the - * behaviour the user expects. With both the ACL and - * actions file, the last match wins. However, the internal - * implementations are different: The actions file is stored - * in the same order as the file, and scanned completely. - * With the ACL, we reverse the order as we load it, then - * when we scan it we stop as soon as we get a match. - */ - cur_acl->next = config->acl; - config->acl = cur_acl; - - continue; -#endif /* def FEATURE_ACL */ - -/* ************************************************************************* - * proxy-info-url url - * *************************************************************************/ - case hash_proxy_info_url : - freez(config->proxy_info_url); - config->proxy_info_url = strdup(arg); - continue; - -/* ************************************************************************* - * re_filterfile file-name - * In confdir by default. - * *************************************************************************/ - case hash_filterfile : - freez(config->re_filterfile); - config->re_filterfile = make_path(config->confdir, arg); - continue; - -/* ************************************************************************* - * single-threaded - * *************************************************************************/ - case hash_single_threaded : - config->multi_threaded = 0; - continue; - -/* ************************************************************************* - * toggle (0|1) - * *************************************************************************/ -#ifdef FEATURE_TOGGLE - case hash_toggle : - g_bToggleIJB = atoi(arg); - continue; -#endif /* def FEATURE_TOGGLE */ - -/* ************************************************************************* - * trust-info-url url - * *************************************************************************/ -#ifdef FEATURE_TRUST - case hash_trust_info_url : - enlist(config->trust_info, arg); - continue; -#endif /* def FEATURE_TRUST */ - -/* ************************************************************************* - * trustfile filename - * (In confdir by default.) - * *************************************************************************/ -#ifdef FEATURE_TRUST - case hash_trustfile : - freez(config->trustfile); - config->trustfile = make_path(config->confdir, arg); - continue; -#endif /* def FEATURE_TRUST */ - -/* ************************************************************************* - * usermanual url - * *************************************************************************/ - case hash_usermanual : - freez(config->usermanual); - config->usermanual = strdup(arg); - continue; - -/* ************************************************************************* - * Win32 Console options: - * *************************************************************************/ - -/* ************************************************************************* - * hide-console - * *************************************************************************/ -#ifdef _WIN_CONSOLE - case hash_hide_console : - hideConsole = 1; - continue; -#endif /*def _WIN_CONSOLE*/ - - -/* ************************************************************************* - * Win32 GUI options: - * *************************************************************************/ - -#if defined(_WIN32) && ! defined(_WIN_CONSOLE) -/* ************************************************************************* - * activity-animation (0|1) - * *************************************************************************/ - case hash_activity_animation : - g_bShowActivityAnimation = atoi(arg); - continue; - -/* ************************************************************************* - * close-button-minimizes (0|1) - * *************************************************************************/ - case hash_close_button_minimizes : - g_bCloseHidesWindow = atoi(arg); - continue; - -/* ************************************************************************* - * log-buffer-size (0|1) - * *************************************************************************/ - case hash_log_buffer_size : - g_bLimitBufferSize = atoi(arg); - continue; - -/* ************************************************************************* - * log-font-name fontnane - * *************************************************************************/ - case hash_log_font_name : - strcpy( g_szFontFaceName, arg ); - continue; - -/* ************************************************************************* - * log-font-size n - * *************************************************************************/ - case hash_log_font_size : - g_nFontSize = atoi(arg); - continue; - -/* ************************************************************************* - * log-highlight-messages (0|1) - * *************************************************************************/ - case hash_log_highlight_messages : - g_bHighlightMessages = atoi(arg); - continue; - -/* ************************************************************************* - * log-max-lines n - * *************************************************************************/ - case hash_log_max_lines : - g_nMaxBufferLines = atoi(arg); - continue; - -/* ************************************************************************* - * log-messages (0|1) - * *************************************************************************/ - case hash_log_messages : - g_bLogMessages = atoi(arg); - continue; - -/* ************************************************************************* - * show-on-task-bar (0|1) - * *************************************************************************/ - case hash_show_on_task_bar : - g_bShowOnTaskBar = atoi(arg); - continue; - -#endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */ - - -/* ************************************************************************* - * Warnings about unsupported features - * *************************************************************************/ -#ifndef 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, "
    \nWARNING: unrecognized directive : "); - string_append(&config->proxy_args, buf); - string_append(&config->proxy_args, "

    \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("usermanual); - string_append(&buf, CONFIG_HELP_PREFIX); - string_join (&buf, string_toupper(command)); - string_append(&buf, "\">"); - string_append(&buf, command); - string_append(&buf, " "); - - if (NULL == buf) - { - freez(config->proxy_args); - return; - } - - if ( (NULL != argument) && ('\0' != *argument) ) - { - s = html_encode(argument); - if (NULL == s) - { - freez(buf); - freez(config->proxy_args); - return; - } - - if (strncmpic(argument, "http://", 7) == 0) - { - string_append(&buf, ""); - string_join (&buf, s); - string_append(&buf, ""); - } - else - { - string_join (&buf, s); - } - } - - string_append(&buf, "
    \n"); - - string_join(&config->proxy_args, buf); -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/loadcfg.h b/loadcfg.h deleted file mode 100644 index 3e71b752..00000000 --- a/loadcfg.h +++ /dev/null @@ -1,189 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/loaders.c b/loaders.c deleted file mode 100644 index 8ebfa70a..00000000 --- a/loaders.c +++ /dev/null @@ -1,1446 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#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: -*/ diff --git a/loaders.h b/loaders.h deleted file mode 100644 index 216c352d..00000000 --- a/loaders.h +++ /dev/null @@ -1,235 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/miscutil.c b/miscutil.c deleted file mode 100644 index 065cd5f6..00000000 --- a/miscutil.c +++ /dev/null @@ -1,1759 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include -#include -#if !defined(_WIN32) && !defined(__OS2__) -#include -#endif /* #if !defined(_WIN32) && !defined(__OS2__) */ -#include -#include -#include - -#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 s1s2 - * - *********************************************************************/ -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 s1s2 - * - *********************************************************************/ -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 , April 1999, June 2000 - Copyright © 1999, Mark Martinec - - */ - -#ifdef __OS2__ - -#define PORTABLE_SNPRINTF_VERSION_MAJOR 2 -#define PORTABLE_SNPRINTF_VERSION_MINOR 2 - -#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) -# if defined(NEED_SNPRINTF_ONLY) -# undef NEED_SNPRINTF_ONLY -# endif -# if !defined(PREFER_PORTABLE_SNPRINTF) -# define PREFER_PORTABLE_SNPRINTF -# endif -#endif - -#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) -#define SOLARIS_COMPATIBLE -#endif - -#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) -#define HPUX_COMPATIBLE -#endif - -#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) -#define DIGITAL_UNIX_COMPATIBLE -#endif - -#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) -#define PERL_COMPATIBLE -#endif - -#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) -#define LINUX_COMPATIBLE -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef isdigit -#undef isdigit -#endif -#define isdigit(c) ((c) >= '0' && (c) <= '9') - -/* For copying strings longer or equal to 'breakeven_point' - * it is more efficient to call memcpy() than to do it inline. - * The value depends mostly on the processor architecture, - * but also on the compiler and its optimization capabilities. - * The value is not critical, some small value greater than zero - * will be just fine if you don't care to squeeze every drop - * of performance out of the code. - * - * Small values favor memcpy, large values favor inline code. - */ -#if defined(__alpha__) || defined(__alpha) -# define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */ -#endif -#if defined(__i386__) || defined(__i386) -# define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */ -#endif -#if defined(__hppa) -# define breakeven_point 10 /* HP-PA - gcc */ -#endif -#if defined(__sparc__) || defined(__sparc) -# define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ -#endif - -/* some other values of possible interest: */ -/* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ -/* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ - -#ifndef breakeven_point -# define breakeven_point 6 /* some reasonable one-size-fits-all value */ -#endif - -#define fast_memcpy(d,s,n) \ - { register size_t nn = (size_t)(n); \ - if (nn >= breakeven_point) memcpy((d), (s), nn); \ - else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ - register char *dd; register const char *ss; \ - for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } - -#define fast_memset(d,c,n) \ - { register size_t nn = (size_t)(n); \ - if (nn >= breakeven_point) memset((d), (int)(c), nn); \ - else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ - register char *dd; register const int cc=(int)(c); \ - for (dd=(d); nn>0; nn--) *dd++ = cc; } } - -/* prototypes */ - -#if defined(NEED_ASPRINTF) -int asprintf (char **ptr, const char *fmt, /*args*/ ...); -#endif -#if defined(NEED_VASPRINTF) -int vasprintf (char **ptr, const char *fmt, va_list ap); -#endif -#if defined(NEED_ASNPRINTF) -int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); -#endif -#if defined(NEED_VASNPRINTF) -int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); -#endif - -#if defined(HAVE_SNPRINTF) -/* declare our portable snprintf routine under name portable_snprintf */ -/* declare our portable vsnprintf routine under name portable_vsnprintf */ -#else -/* declare our portable routines under names snprintf and vsnprintf */ -#define portable_snprintf snprintf -#if !defined(NEED_SNPRINTF_ONLY) -#define portable_vsnprintf vsnprintf -#endif -#endif - -#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); -#if !defined(NEED_SNPRINTF_ONLY) -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); -#endif -#endif - -/* declarations */ - -static char credits[] = "\n\ -@(#)snprintf.c, v2.2: Mark Martinec, \n\ -@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ -@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; - -#if defined(NEED_ASPRINTF) -int asprintf(char **ptr, const char *fmt, /*args*/ ...) { - va_list ap; - size_t str_m; - int str_l; - - *ptr = NULL; - va_start(ap, fmt); /* measure the required size */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); - va_end(ap); - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t)str_l + 1); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2; - va_start(ap, fmt); - str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - va_end(ap); - assert(str_l2 == str_l); - } - return str_l; -} -#endif - -#if defined(NEED_VASPRINTF) -int vasprintf(char **ptr, const char *fmt, va_list ap) { - size_t str_m; - int str_l; - - *ptr = NULL; - { va_list ap2; - va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ - va_end(ap2); - } - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t)str_l + 1); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - assert(str_l2 == str_l); - } - return str_l; -} -#endif - -#if defined(NEED_ASNPRINTF) -int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { - va_list ap; - int str_l; - - *ptr = NULL; - va_start(ap, fmt); /* measure the required size */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); - va_end(ap); - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ - /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ - if (str_m == 0) { /* not interested in resulting string, just return size */ - } else { - *ptr = (char *) malloc(str_m); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2; - va_start(ap, fmt); - str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - va_end(ap); - assert(str_l2 == str_l); - } - } - return str_l; -} -#endif - -#if defined(NEED_VASNPRINTF) -int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) { - int str_l; - - *ptr = NULL; - { va_list ap2; - va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ - str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ - va_end(ap2); - } - assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ - /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ - if (str_m == 0) { /* not interested in resulting string, just return size */ - } else { - *ptr = (char *) malloc(str_m); - if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } - else { - int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); - assert(str_l2 == str_l); - } - } - return str_l; -} -#endif - -/* - * If the system does have snprintf and the portable routine is not - * specifically required, this module produces no code for snprintf/vsnprintf. - */ -#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) - -#if !defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { - va_list ap; - int str_l; - - va_start(ap, fmt); - str_l = portable_vsnprintf(str, str_m, fmt, ap); - va_end(ap); - return str_l; -} -#endif - -#if defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { -#else -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { -#endif - -#if defined(NEED_SNPRINTF_ONLY) - va_list ap; -#endif - size_t str_l = 0; - const char *p = fmt; - -/* In contrast with POSIX, the ISO C99 now says - * that str can be NULL and str_m can be 0. - * This is more useful than the old: if (str_m < 1) return -1; */ - -#if defined(NEED_SNPRINTF_ONLY) - va_start(ap, fmt); -#endif - if (!p) p = ""; - while (*p) { - if (*p != '%') { - /* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */ - /* but the following code achieves better performance for cases - * where format string is long and contains few conversions */ - const char *q = strchr(p+1,'%'); - size_t n = !q ? strlen(p) : (q-p); - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memcpy(str+str_l, p, (n>avail?avail:n)); - } - p += n; str_l += n; - } else { - const char *starting_p; - size_t min_field_width = 0, precision = 0; - int zero_padding = 0, precision_specified = 0, justify_left = 0; - int alternate_form = 0, force_sign = 0; - int space_for_positive = 1; /* If both the ' ' and '+' flags appear, - the ' ' flag should be ignored. */ - char length_modifier = '\0'; /* allowed values: \0, h, l, L */ - char tmp[32];/* temporary buffer for simple numeric->string conversion */ - - const char *str_arg; /* string address in case of string argument */ - size_t str_arg_l; /* natural field width of arg without padding - and sign */ - unsigned char uchar_arg; - /* unsigned char argument value - only defined for c conversion. - N.B. standard explicitly states the char argument for - the c conversion is unsigned */ - - size_t number_of_zeros_to_pad = 0; - /* number of zeros to be inserted for numeric conversions - as required by the precision or minimal field width */ - - size_t zero_padding_insertion_ind = 0; - /* index into tmp where zero padding is to be inserted */ - - char fmt_spec = '\0'; - /* current conversion specifier character */ - - str_arg = credits;/* just to make compiler happy (defined but not used)*/ - str_arg = NULL; - starting_p = p; p++; /* skip '%' */ - /* parse flags */ - while (*p == '0' || *p == '-' || *p == '+' || - *p == ' ' || *p == '#' || *p == '\'') { - switch (*p) { - case '0': zero_padding = 1; break; - case '-': justify_left = 1; break; - case '+': force_sign = 1; space_for_positive = 0; break; - case ' ': force_sign = 1; - /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ -#ifdef PERL_COMPATIBLE - /* ... but in Perl the last of ' ' and '+' applies */ - space_for_positive = 1; -#endif - break; - case '#': alternate_form = 1; break; - case '\'': break; - } - p++; - } - /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ - - /* parse field width */ - if (*p == '*') { - int j; - p++; j = va_arg(ap, int); - if (j >= 0) min_field_width = j; - else { min_field_width = -j; justify_left = 1; } - } else if (isdigit((int)(*p))) { - /* size_t could be wider than unsigned int; - make sure we treat argument like common implementations do */ - unsigned int uj = *p++ - '0'; - while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); - min_field_width = uj; - } - /* parse precision */ - if (*p == '.') { - p++; precision_specified = 1; - if (*p == '*') { - int j = va_arg(ap, int); - p++; - if (j >= 0) precision = j; - else { - precision_specified = 0; precision = 0; - /* NOTE: - * Solaris 2.6 man page claims that in this case the precision - * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page - * claim that this case should be treated as unspecified precision, - * which is what we do here. - */ - } - } else if (isdigit((int)(*p))) { - /* size_t could be wider than unsigned int; - make sure we treat argument like common implementations do */ - unsigned int uj = *p++ - '0'; - while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); - precision = uj; - } - } - /* parse 'h', 'l' and 'll' length modifiers */ - if (*p == 'h' || *p == 'l') { - length_modifier = *p; p++; - if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ -#ifdef SNPRINTF_LONGLONG_SUPPORT - length_modifier = '2'; /* double l encoded as '2' */ -#else - length_modifier = 'l'; /* treat it as a single 'l' */ -#endif - p++; - } - } - fmt_spec = *p; - /* common synonyms: */ - switch (fmt_spec) { - case 'i': fmt_spec = 'd'; break; - case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; - case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; - case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; - default: break; - } - /* get parameter value, do initial processing */ - switch (fmt_spec) { - case '%': /* % behaves similar to 's' regarding flags and field widths */ - case 'c': /* c behaves similar to 's' regarding flags and field widths */ - case 's': - length_modifier = '\0'; /* wint_t and wchar_t not supported */ - /* the result of zero padding flag with non-numeric conversion specifier*/ - /* is undefined. Solaris and HPUX 10 does zero padding in this case, */ - /* Digital Unix and Linux does not. */ -#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) - zero_padding = 0; /* turn zero padding off for string conversions */ -#endif - str_arg_l = 1; - switch (fmt_spec) { - case '%': - str_arg = p; break; - case 'c': { - int j = va_arg(ap, int); - uchar_arg = (unsigned char) j; /* standard demands unsigned char */ - str_arg = (const char *) &uchar_arg; - break; - } - case 's': - str_arg = va_arg(ap, const char *); - if (!str_arg) str_arg_l = 0; - /* make sure not to address string beyond the specified precision !!! */ - else if (!precision_specified) str_arg_l = strlen(str_arg); - /* truncate string if necessary as requested by precision */ - else if (precision == 0) str_arg_l = 0; - else { - /* memchr on HP does not like n > 2^31 !!! */ - const char *q = memchr(str_arg, '\0', - precision <= 0x7fffffff ? precision : 0x7fffffff); - str_arg_l = !q ? precision : (q-str_arg); - } - break; - default: break; - } - break; - case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { - /* NOTE: the u, o, x, X and p conversion specifiers imply - the value is unsigned; d implies a signed value */ - - int arg_sign = 0; - /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), - +1 if greater than zero (or nonzero for unsigned arguments), - -1 if negative (unsigned argument is never negative) */ - - int int_arg = 0; unsigned int uint_arg = 0; - /* only defined for length modifier h, or for no length modifiers */ - - long int long_arg = 0; unsigned long int ulong_arg = 0; - /* only defined for length modifier l */ - - void *ptr_arg = NULL; - /* pointer argument value -only defined for p conversion */ - -#ifdef SNPRINTF_LONGLONG_SUPPORT - long long int long_long_arg = 0; - unsigned long long int ulong_long_arg = 0; - /* only defined for length modifier ll */ -#endif - if (fmt_spec == 'p') { - /* HPUX 10: An l, h, ll or L before any other conversion character - * (other than d, i, u, o, x, or X) is ignored. - * Digital Unix: - * not specified, but seems to behave as HPUX does. - * Solaris: If an h, l, or L appears before any other conversion - * specifier (other than d, i, u, o, x, or X), the behavior - * is undefined. (Actually %hp converts only 16-bits of address - * and %llp treats address as 64-bit data which is incompatible - * with (void *) argument on a 32-bit system). - */ -#ifdef SOLARIS_COMPATIBLE -# ifdef SOLARIS_BUG_COMPATIBLE - /* keep length modifiers even if it represents 'll' */ -# else - if (length_modifier == '2') length_modifier = '\0'; -# endif -#else - length_modifier = '\0'; -#endif - ptr_arg = va_arg(ap, void *); - if (ptr_arg != NULL) arg_sign = 1; - } else if (fmt_spec == 'd') { /* signed */ - switch (length_modifier) { - case '\0': - case 'h': - /* It is non-portable to specify a second argument of char or short - * to va_arg, because arguments seen by the called function - * are not char or short. C converts char and short arguments - * to int before passing them to a function. - */ - int_arg = va_arg(ap, int); - if (int_arg > 0) arg_sign = 1; - else if (int_arg < 0) arg_sign = -1; - break; - case 'l': - long_arg = va_arg(ap, long int); - if (long_arg > 0) arg_sign = 1; - else if (long_arg < 0) arg_sign = -1; - break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': - long_long_arg = va_arg(ap, long long int); - if (long_long_arg > 0) arg_sign = 1; - else if (long_long_arg < 0) arg_sign = -1; - break; -#endif - } - } else { /* unsigned */ - switch (length_modifier) { - case '\0': - case 'h': - uint_arg = va_arg(ap, unsigned int); - if (uint_arg) arg_sign = 1; - break; - case 'l': - ulong_arg = va_arg(ap, unsigned long int); - if (ulong_arg) arg_sign = 1; - break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': - ulong_long_arg = va_arg(ap, unsigned long long int); - if (ulong_long_arg) arg_sign = 1; - break; -#endif - } - } - str_arg = tmp; str_arg_l = 0; - /* NOTE: - * For d, i, u, o, x, and X conversions, if precision is specified, - * the '0' flag should be ignored. This is so with Solaris 2.6, - * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. - */ -#ifndef PERL_COMPATIBLE - if (precision_specified) zero_padding = 0; -#endif - if (fmt_spec == 'd') { - if (force_sign && arg_sign >= 0) - tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; - /* leave negative numbers for sprintf to handle, - to avoid handling tricky cases like (short int)(-32768) */ -#ifdef LINUX_COMPATIBLE - } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { - tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; -#endif - } else if (alternate_form) { - if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) - { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } - /* alternate form should have no effect for p conversion, but ... */ -#ifdef HPUX_COMPATIBLE - else if (fmt_spec == 'p' - /* HPUX 10: for an alternate form of p conversion, - * a nonzero result is prefixed by 0x. */ -#ifndef HPUX_BUG_COMPATIBLE - /* Actually it uses 0x prefix even for a zero value. */ - && arg_sign != 0 -#endif - ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } -#endif - } - zero_padding_insertion_ind = str_arg_l; - if (!precision_specified) precision = 1; /* default precision is 1 */ - if (precision == 0 && arg_sign == 0 -#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) - && fmt_spec != 'p' - /* HPUX 10 man page claims: With conversion character p the result of - * converting a zero value with a precision of zero is a null string. - * Actually HP returns all zeroes, and Linux returns "(nil)". */ -#endif - ) { - /* converted to null string */ - /* When zero value is formatted with an explicit precision 0, - the resulting formatted string is empty (d, i, u, o, x, X, p). */ - } else { - char f[5]; int f_l = 0; - f[f_l++] = '%'; /* construct a simple format string for sprintf */ - if (!length_modifier) { } - else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } - else f[f_l++] = length_modifier; - f[f_l++] = fmt_spec; f[f_l++] = '\0'; - if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); - else if (fmt_spec == 'd') { /* signed */ - switch (length_modifier) { - case '\0': - case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break; - case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; -#endif - } - } else { /* unsigned */ - switch (length_modifier) { - case '\0': - case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break; - case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; -#ifdef SNPRINTF_LONGLONG_SUPPORT - case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; -#endif - } - } - /* include the optional minus sign and possible "0x" - in the region before the zero padding insertion point */ - if (zero_padding_insertion_ind < str_arg_l && - tmp[zero_padding_insertion_ind] == '-') { - zero_padding_insertion_ind++; - } - if (zero_padding_insertion_ind+1 < str_arg_l && - tmp[zero_padding_insertion_ind] == '0' && - (tmp[zero_padding_insertion_ind+1] == 'x' || - tmp[zero_padding_insertion_ind+1] == 'X') ) { - zero_padding_insertion_ind += 2; - } - } - { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; - if (alternate_form && fmt_spec == 'o' -#ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ - && (str_arg_l > 0) -#endif -#ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ -#else - /* unless zero is already the first character */ - && !(zero_padding_insertion_ind < str_arg_l - && tmp[zero_padding_insertion_ind] == '0') -#endif - ) { /* assure leading zero for alternate-form octal numbers */ - if (!precision_specified || precision < num_of_digits+1) { - /* precision is increased to force the first character to be zero, - except if a zero value is formatted with an explicit precision - of zero */ - precision = num_of_digits+1; precision_specified = 1; - } - } - /* zero padding to specified precision? */ - if (num_of_digits < precision) - number_of_zeros_to_pad = precision - num_of_digits; - } - /* zero padding to specified minimal field width? */ - if (!justify_left && zero_padding) { - int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) number_of_zeros_to_pad += n; - } - break; - } - default: /* unrecognized conversion specifier, keep format string as-is*/ - zero_padding = 0; /* turn zero padding off for non-numeric convers. */ -#ifndef DIGITAL_UNIX_COMPATIBLE - justify_left = 1; min_field_width = 0; /* reset flags */ -#endif -#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) - /* keep the entire format string unchanged */ - str_arg = starting_p; str_arg_l = p - starting_p; - /* well, not exactly so for Linux, which does something inbetween, - * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ -#else - /* discard the unrecognized conversion, just keep * - * the unrecognized conversion character */ - str_arg = p; str_arg_l = 0; -#endif - if (*p) str_arg_l++; /* include invalid conversion specifier unchanged - if not at end-of-string */ - break; - } - if (*p) p++; /* step over the just processed conversion specifier */ - /* insert padding to the left as requested by min_field_width; - this does not include the zero padding in case of numerical conversions*/ - if (!justify_left) { /* left padding with blank or zero */ - int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) { - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); - } - str_l += n; - } - } - /* zero padding as requested by the precision or by the minimal field width - * for numeric conversions required? */ - if (number_of_zeros_to_pad <= 0) { - /* will not copy first part of numeric right now, * - * force it to be copied later in its entirety */ - zero_padding_insertion_ind = 0; - } else { - /* insert first part of numerics (sign or '0x') before zero padding */ - int n = zero_padding_insertion_ind; - if (n > 0) { - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); - } - str_l += n; - } - /* insert zero padding as requested by the precision or min field width */ - n = number_of_zeros_to_pad; - if (n > 0) { - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memset(str+str_l, '0', (n>avail?avail:n)); - } - str_l += n; - } - } - /* insert formatted string - * (or as-is conversion specifier for unknown conversions) */ - { int n = str_arg_l - zero_padding_insertion_ind; - if (n > 0) { - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, - (n>avail?avail:n)); - } - str_l += n; - } - } - /* insert right padding */ - if (justify_left) { /* right blank padding to the field width */ - int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); - if (n > 0) { - if (str_l < str_m) { - size_t avail = str_m-str_l; - fast_memset(str+str_l, ' ', (n>avail?avail:n)); - } - str_l += n; - } - } - } - } -#if defined(NEED_SNPRINTF_ONLY) - va_end(ap); -#endif - if (str_m > 0) { /* make sure the string is null-terminated - even at the expense of overwriting the last character - (shouldn't happen, but just in case) */ - str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; - } - /* Return the number of characters formatted (excluding trailing null - * character), that is, the number of characters that would have been - * written to the buffer if it were large enough. - * - * The value of str_l should be returned, but str_l is of unsigned type - * size_t, and snprintf is int, possibly leading to an undetected - * integer overflow, resulting in a negative return value, which is illegal. - * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. - * Should errno be set to EOVERFLOW and EOF returned in this case??? - */ - return (int) str_l; -} -#endif -#endif /* __OS2__ */ -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/miscutil.h b/miscutil.h deleted file mode 100644 index e4793c8c..00000000 --- a/miscutil.h +++ /dev/null @@ -1,194 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/parsers.c b/parsers.c deleted file mode 100644 index df2ae59a..00000000 --- a/parsers.c +++ /dev/null @@ -1,1791 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#ifndef _WIN32 -#include -#include -#endif - -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#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: -*/ diff --git a/parsers.h b/parsers.h deleted file mode 100644 index 837bac4a..00000000 --- a/parsers.h +++ /dev/null @@ -1,231 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/pcrs.c b/pcrs.c deleted file mode 100644 index 45a471b9..00000000 --- a/pcrs.c +++ /dev/null @@ -1,939 +0,0 @@ -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 - * 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 - * - * - * 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 - * - * - *********************************************************************/ - - -#include -#include -#include - -#include "pcrs.h" - -const char pcrs_h_rcs[] = PCRS_H_VERSION; - -/* - * Internal prototypes - */ - -static int pcrs_parse_perl_options(const char *optstring, int *flags); -static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag, - int capturecount, int *errptr); - -/********************************************************************* - * - * Function : 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: -*/ diff --git a/pcrs.h b/pcrs.h deleted file mode 100644 index a14b8165..00000000 --- a/pcrs.h +++ /dev/null @@ -1,168 +0,0 @@ -#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 $" - - -#ifndef _PCRE_H -#include -#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: -*/ diff --git a/project.h b/project.h deleted file mode 100644 index 43d53d61..00000000 --- a/project.h +++ /dev/null @@ -1,1433 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -/* Declare struct FILE for vars and funcs. */ -#include - -/* Need time_t for file_list */ -#include - -/* - * 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 -#endif - -#ifdef STATIC_PCRS -# include "pcrs.h" -#else -# include -#endif - -#ifdef STATIC_PCRE -# include "pcreposix.h" -#else -# include -#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 -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 - -typedef SOCKET jb_socket; - -#define JB_INVALID_SOCKET INVALID_SOCKET - -#else /* ndef _WIN32 */ - -/** - * The type used by sockets. On UNIX it's an int. Microsoft decided to - * make it an unsigned. - */ -typedef int jb_socket; - -/** - * The error value used for variables of type jb_socket. On UNIX this - * is -1, however Microsoft decided to make socket handles unsigned, so - * they use a different value. - */ - -#define JB_INVALID_SOCKET (-1) - -#endif /* ndef _WIN32 */ - - -/** - * A standard error code. This should be JB_ERR_OK or one of the JB_ERR_xxx - * series of errors. - */ -typedef int jb_err; - -#define JB_ERR_OK 0 /**< Success, no error */ -#define JB_ERR_MEMORY 1 /**< Out of memory */ -#define JB_ERR_CGI_PARAMS 2 /**< Missing or corrupt CGI parameters */ -#define JB_ERR_FILE 3 /**< Error opening, reading or writing a file */ -#define JB_ERR_PARSE 4 /**< Error parsing file */ -#define JB_ERR_MODIFIED 5 /**< File has been modified outside of the - CGI actions editor. */ - - -/** - * This macro is used to free a pointer that may be NULL. - * It also sets the variable to NULL after it's been freed. - * The paramater should be a simple variable without side effects. - */ -#define freez(X) { if(X) { free((void*)X); X = NULL ; } } - - -/** - * Fix a problem with Solaris. There should be no effect on other - * platforms. - * - * Solaris's isspace() is a macro which uses it's argument directly - * as an array index. Therefore we need to make sure that high-bit - * characters generate +ve values, and ideally we also want to make - * the argument match the declared parameter type of "int". - * - * Note: Remember to #include if you use these macros. - */ -#define ijb_toupper(__X) toupper((int)(unsigned char)(__X)) -#define ijb_tolower(__X) tolower((int)(unsigned char)(__X)) -#define ijb_isspace(__X) isspace((int)(unsigned char)(__X)) - -/** - * Use for statically allocated buffers if you have no other choice. - * Remember to check the length of what you write into the buffer - * - we don't want any buffer overflows! - */ -#define BUFFER_SIZE 5000 - -/** - * Max length of CGI parameters (arbitrary limit). - */ -#define CGI_PARAM_LEN_MAX 500 - -/** - * Buffer size for capturing struct hostent data in the - * gethostby(name|addr)_r library calls. Since we don't - * loop over gethostbyname_r, the buffer must be sufficient - * to accomodate multiple IN A RRs, as used in DNS round robin - * load balancing. W3C's wwwlib uses 1K, so that should be - * good enough for us, too. - */ -#define HOSTENT_BUFFER_SIZE 1024 - -/** - * Do not use. Originally this was so that you can - * say "while (FOREVER) { ...do something... }". - * However, this gives a warning with some compilers (e.g. VC++). - * Instead, use "for (;;) { ...do something... }". - */ -#define FOREVER 1 - -/** - * Default IP 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: -*/ diff --git a/ssplit.c b/ssplit.c deleted file mode 100644 index ff362568..00000000 --- a/ssplit.c +++ /dev/null @@ -1,208 +0,0 @@ -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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include - -#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: -*/ diff --git a/ssplit.h b/ssplit.h deleted file mode 100644 index 397dda2a..00000000 --- a/ssplit.h +++ /dev/null @@ -1,77 +0,0 @@ -#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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/urlmatch.c b/urlmatch.c deleted file mode 100644 index 1b2aee86..00000000 --- a/urlmatch.c +++ /dev/null @@ -1,809 +0,0 @@ -const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.9 2002/04/04 00:36:36 gliptak Exp $"; -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/urlmatch.c,v $ - * - * Purpose : Declares functions to match URLs against URL - * patterns. - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: urlmatch.c,v $ - * Revision 1.9 2002/04/04 00:36:36 gliptak - * always use pcre for matching - * - * Revision 1.8 2002/04/03 23:32:47 jongfoster - * Fixing memory leak on error - * - * Revision 1.7 2002/03/26 22:29:55 swa - * we have a new homepage! - * - * Revision 1.6 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.5 2002/03/13 00:27:05 jongfoster - * Killing warnings - * - * Revision 1.4 2002/03/07 03:46:17 oes - * Fixed compiler warnings - * - * Revision 1.3 2002/03/03 14:51:11 oes - * Fixed CLF logging: Added ocmd member for client's request to struct http_request - * - * Revision 1.2 2002/01/21 00:14:09 jongfoster - * Correcting comment style - * Fixing an uninitialized memory bug in create_url_spec() - * - * Revision 1.1 2002/01/17 20:53:46 jongfoster - * Moving all our URL and URL pattern parsing code to the same file - it - * was scattered around in filters.c, loaders.c and parsers.c. - * - * Providing a single, simple url_match(pattern,url) function - rather than - * the 3-line match routine which was repeated all over the place. - * - * Renaming free_url to free_url_spec, since it frees a struct url_spec. - * - * Providing parse_http_url() so that URLs can be parsed without faking a - * HTTP request line for parse_http_request() or repeating the parsing - * code (both of which were techniques that were actually in use). - * - * Standardizing that struct http_request is used to represent a URL, and - * struct url_spec is used to represent a URL pattern. (Before, URLs were - * represented as seperate variables and a partially-filled-in url_spec). - * - * - *********************************************************************/ - - -#include "config.h" - -#ifndef _WIN32 -#include -#include -#endif - -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__OS2__) -#include -#endif - -#include "project.h" -#include "urlmatch.h" -#include "ssplit.h" -#include "miscutil.h" -#include "errlog.h" - -const char urlmatch_h_rcs[] = URLMATCH_H_VERSION; - - -/********************************************************************* - * - * Function : free_http_request - * - * Description : Freez a http_request structure - * - * Parameters : - * 1 : http = points to a http_request structure to free - * - * Returns : N/A - * - *********************************************************************/ -void free_http_request(struct http_request *http) -{ - assert(http); - - freez(http->cmd); - freez(http->ocmd); - freez(http->gpc); - freez(http->host); - freez(http->url); - freez(http->hostport); - freez(http->path); - freez(http->ver); - freez(http->host_ip_addr_str); - freez(http->dbuffer); - freez(http->dvec); - http->dcount = 0; -} - - -/********************************************************************* - * - * Function : parse_http_url - * - * Description : Parse out the host and port from the URL. Find the - * hostname & path, port (if ':'), and/or password (if '@') - * - * Parameters : - * 1 : url = URL (or is it URI?) to break down - * 2 : http = pointer to the http structure to hold elements. - * Will be zeroed before use. Note that this - * function sets the http->gpc and http->ver - * members to NULL. - * 3 : csp = Current client state (buffers, headers, etc...) - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out of memory - * JB_ERR_CGI_PARAMS on malformed command/URL - * or >100 domains deep. - * - *********************************************************************/ -jb_err parse_http_url(const char * url, - struct http_request *http, - struct client_state *csp) -{ - /* - * Zero out the results structure - */ - memset(http, '\0', sizeof(*http)); - - - /* - * Save our initial URL - */ - http->url = strdup(url); - if (http->url == NULL) - { - return JB_ERR_MEMORY; - } - - - /* - * Split URL into protocol,hostport,path. - */ - { - char *buf; - char *url_noproto; - char *url_path; - - buf = strdup(url); - if (buf == NULL) - { - return JB_ERR_MEMORY; - } - - /* Find the start of the URL in our scratch space */ - url_noproto = buf; - if (strncmpic(url_noproto, "http://", 7) == 0) - { - url_noproto += 7; - http->ssl = 0; - } - else if (strncmpic(url_noproto, "https://", 8) == 0) - { - url_noproto += 8; - http->ssl = 1; - } - else - { - http->ssl = 0; - } - - url_path = strchr(url_noproto, '/'); - if (url_path != NULL) - { - /* - * Got a path. - * - * NOTE: The following line ignores the path for HTTPS URLS. - * This means that you get consistent behaviour if you type a - * https URL in and it's parsed by the function. (When the - * URL is actually retrieved, SSL hides the path part). - */ - http->path = strdup(http->ssl ? "/" : url_path); - *url_path = '\0'; - http->hostport = strdup(url_noproto); - } - else - { - /* - * Repair broken HTTP requests that don't contain a path, - * or CONNECT requests - */ - http->path = strdup("/"); - http->hostport = strdup(url_noproto); - } - - free(buf); - - if ( (http->path == NULL) - || (http->hostport == NULL)) - { - free(buf); - free_http_request(http); - return JB_ERR_MEMORY; - } - } - - - /* - * Split hostport into user/password (ignored), host, port. - */ - { - char *buf; - char *host; - char *port; - - buf = strdup(http->hostport); - if (buf == NULL) - { - free_http_request(http); - return JB_ERR_MEMORY; - } - - /* check if url contains username and/or password */ - host = strchr(buf, '@'); - if (host != NULL) - { - /* Contains username/password, skip it and the @ sign. */ - host++; - } - else - { - /* No username or password. */ - host = buf; - } - - /* check if url contains port */ - port = strchr(host, ':'); - if (port != NULL) - { - /* Contains port */ - /* Terminate hostname and point to start of port string */ - *port++ = '\0'; - http->port = atoi(port); - } - else - { - /* No port specified. */ - http->port = (http->ssl ? 143 : 80); - } - - http->host = strdup(host); - - free(buf); - - if (http->host == NULL) - { - free_http_request(http); - return JB_ERR_MEMORY; - } - } - - - /* - * Split domain name so we can compare it against wildcards - */ - { - char *vec[BUFFER_SIZE]; - size_t size; - char *p; - - http->dbuffer = strdup(http->host); - if (NULL == http->dbuffer) - { - free_http_request(http); - return JB_ERR_MEMORY; - } - - /* map to lower case */ - for (p = http->dbuffer; *p ; p++) - { - *p = tolower((int)(unsigned char)*p); - } - - /* split the domain name into components */ - http->dcount = ssplit(http->dbuffer, ".", vec, SZ(vec), 1, 1); - - if (http->dcount <= 0) - { - /* - * Error: More than SZ(vec) components in domain - * or: no components in domain - */ - free_http_request(http); - return JB_ERR_PARSE; - } - - /* save a copy of the pointers in dvec */ - size = http->dcount * sizeof(*http->dvec); - - http->dvec = (char **)malloc(size); - if (NULL == http->dvec) - { - free_http_request(http); - return JB_ERR_MEMORY; - } - - memcpy(http->dvec, vec, size); - } - - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : parse_http_request - * - * Description : Parse out the host and port from the URL. Find the - * hostname & path, port (if ':'), and/or password (if '@') - * - * Parameters : - * 1 : req = HTTP request line to break down - * 2 : http = pointer to the http structure to hold elements - * 3 : csp = Current client state (buffers, headers, etc...) - * - * Returns : JB_ERR_OK on success - * JB_ERR_MEMORY on out of memory - * JB_ERR_CGI_PARAMS on malformed command/URL - * or >100 domains deep. - * - *********************************************************************/ -jb_err parse_http_request(const char *req, - struct http_request *http, - struct client_state *csp) -{ - char *buf; - char *v[10]; - int n; - jb_err err; - int is_connect = 0; - - memset(http, '\0', sizeof(*http)); - - buf = strdup(req); - if (buf == NULL) - { - return JB_ERR_MEMORY; - } - - n = ssplit(buf, " \r\n", v, SZ(v), 1, 1); - if (n != 3) - { - free(buf); - return JB_ERR_PARSE; - } - - /* this could be a CONNECT request */ - if (strcmpic(v[0], "connect") == 0) - { - /* Secure */ - is_connect = 1; - } - /* or it could be any other basic HTTP request type */ - else if ((0 == strcmpic(v[0], "get")) - || (0 == strcmpic(v[0], "head")) - || (0 == strcmpic(v[0], "post")) - || (0 == strcmpic(v[0], "put")) - || (0 == strcmpic(v[0], "delete")) - - /* or a webDAV extension (RFC2518) */ - || (0 == strcmpic(v[0], "propfind")) - || (0 == strcmpic(v[0], "proppatch")) - || (0 == strcmpic(v[0], "move")) - || (0 == strcmpic(v[0], "copy")) - || (0 == strcmpic(v[0], "mkcol")) - || (0 == strcmpic(v[0], "lock")) - || (0 == strcmpic(v[0], "unlock")) - ) - { - /* Normal */ - is_connect = 0; - } - else - { - /* Unknown HTTP method */ - free(buf); - return JB_ERR_PARSE; - } - - err = parse_http_url(v[1], http, csp); - if (err) - { - free(buf); - return err; - } - - /* - * Copy the details into the structure - */ - http->ssl = is_connect; - http->cmd = strdup(req); - http->gpc = strdup(v[0]); - http->ver = strdup(v[2]); - - if ( (http->cmd == NULL) - || (http->gpc == NULL) - || (http->ver == NULL) ) - { - free(buf); - free_http_request(http); - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; -} - - -/********************************************************************* - * - * Function : simple_domaincmp - * - * Description : Domain-wise Compare fqdn's. The comparison is - * both left- and right-anchored. The individual - * domain names are compared with simplematch(). - * This is only used by domain_match. - * - * Parameters : - * 1 : pv = array of patterns to compare - * 2 : fv = array of domain components to compare - * 3 : len = length of the arrays (both arrays are the - * same length - if they weren't, it couldn't - * possibly be a match). - * - * Returns : 0 => domains are equivalent, else no match. - * - *********************************************************************/ -static int simple_domaincmp(char **pv, char **fv, int len) -{ - int n; - - for (n = 0; n < len; n++) - { - if (simplematch(pv[n], fv[n])) - { - return 1; - } - } - - return 0; - -} - - -/********************************************************************* - * - * Function : domain_match - * - * Description : Domain-wise Compare fqdn's. Governed by the bimap in - * pattern->unachored, the comparison is un-, left-, - * right-anchored, or both. - * The individual domain names are compared with - * simplematch(). - * - * Parameters : - * 1 : pattern = a domain that may contain a '*' as a wildcard. - * 2 : fqdn = domain name against which the patterns are compared. - * - * Returns : 0 => domains are equivalent, else no match. - * - *********************************************************************/ -static int domain_match(const struct url_spec *pattern, const struct http_request *fqdn) -{ - char **pv, **fv; /* vectors */ - int plen, flen; - int unanchored = pattern->unanchored & (ANCHOR_RIGHT | ANCHOR_LEFT); - - plen = pattern->dcount; - flen = fqdn->dcount; - - if (flen < plen) - { - /* fqdn is too short to match this pattern */ - return 1; - } - - pv = pattern->dvec; - fv = fqdn->dvec; - - if (unanchored == ANCHOR_LEFT) - { - /* - * Right anchored. - * - * Convert this into a fully anchored pattern with - * the fqdn and pattern the same length - */ - fv += (flen - plen); /* flen - plen >= 0 due to check above */ - return simple_domaincmp(pv, fv, plen); - } - else if (unanchored == 0) - { - /* Fully anchored, check length */ - if (flen != plen) - { - return 1; - } - return simple_domaincmp(pv, fv, plen); - } - else if (unanchored == ANCHOR_RIGHT) - { - /* Left anchored, ignore all extra in fqdn */ - return simple_domaincmp(pv, fv, plen); - } - else - { - /* Unanchored */ - int n; - int maxn = flen - plen; - for (n = 0; n <= maxn; n++) - { - if (!simple_domaincmp(pv, fv, plen)) - { - return 0; - } - /* - * Doesn't match from start of fqdn - * Try skipping first part of fqdn - */ - fv++; - } - return 1; - } - -} - - -/********************************************************************* - * - * Function : create_url_spec - * - * Description : Creates a "url_spec" structure from a string. - * When finished, free with unload_url(). - * - * Parameters : - * 1 : url = Target url_spec to be filled in. Will be - * zeroed before use. - * 2 : buf = Source pattern, null terminated. NOTE: The - * contents of this buffer are destroyed by this - * function. If this function succeeds, the - * buffer is copied to url->spec. If this - * function fails, the contents of the buffer - * are lost forever. - * - * Returns : JB_ERR_OK - Success - * JB_ERR_MEMORY - Out of memory - * JB_ERR_PARSE - Cannot parse regex (Detailed message - * written to system log) - * - *********************************************************************/ -jb_err create_url_spec(struct url_spec * url, const char * buf) -{ - char *p; - - assert(url); - assert(buf); - - /* Zero memory */ - memset(url, '\0', sizeof(*url)); - - /* save a copy of the orignal specification */ - if ((url->spec = strdup(buf)) == NULL) - { - return JB_ERR_MEMORY; - } - - if ((p = strchr(buf, '/')) != NULL) - { - if (NULL == (url->path = strdup(p))) - { - freez(url->spec); - return JB_ERR_MEMORY; - } - url->pathlen = strlen(url->path); - *p = '\0'; - } - else - { - url->path = NULL; - url->pathlen = 0; - } - if (url->path) - { - int errcode; - char rebuf[BUFFER_SIZE]; - - if (NULL == (url->preg = zalloc(sizeof(*url->preg)))) - { - freez(url->spec); - freez(url->path); - return JB_ERR_MEMORY; - } - - sprintf(rebuf, "^(%s)", url->path); - - errcode = regcomp(url->preg, rebuf, - (REG_EXTENDED|REG_NOSUB|REG_ICASE)); - if (errcode) - { - size_t errlen = regerror(errcode, - url->preg, rebuf, sizeof(rebuf)); - - if (errlen > (sizeof(rebuf) - (size_t)1)) - { - errlen = sizeof(rebuf) - (size_t)1; - } - rebuf[errlen] = '\0'; - - log_error(LOG_LEVEL_ERROR, "error compiling %s: %s", - url->spec, rebuf); - - freez(url->spec); - freez(url->path); - regfree(url->preg); - freez(url->preg); - - return JB_ERR_PARSE; - } - } - if ((p = strchr(buf, ':')) == NULL) - { - url->port = 0; - } - else - { - *p++ = '\0'; - url->port = atoi(p); - } - - if (buf[0] != '\0') - { - char *v[150]; - size_t size; - - /* Parse domain part */ - if (buf[strlen(buf) - 1] == '.') - { - url->unanchored |= ANCHOR_RIGHT; - } - if (buf[0] == '.') - { - url->unanchored |= ANCHOR_LEFT; - } - - /* split domain into components */ - - url->dbuffer = strdup(buf); - if (NULL == url->dbuffer) - { - freez(url->spec); - freez(url->path); - regfree(url->preg); - freez(url->preg); - return JB_ERR_MEMORY; - } - - /* map to lower case */ - for (p = url->dbuffer; *p ; p++) - { - *p = tolower((int)(unsigned char)*p); - } - - /* split the domain name into components */ - url->dcount = ssplit(url->dbuffer, ".", v, SZ(v), 1, 1); - - if (url->dcount < 0) - { - freez(url->spec); - freez(url->path); - regfree(url->preg); - freez(url->preg); - freez(url->dbuffer); - url->dcount = 0; - return JB_ERR_MEMORY; - } - else if (url->dcount != 0) - { - - /* save a copy of the pointers in dvec */ - size = url->dcount * sizeof(*url->dvec); - - url->dvec = (char **)malloc(size); - if (NULL == url->dvec) - { - freez(url->spec); - freez(url->path); - regfree(url->preg); - freez(url->preg); - freez(url->dbuffer); - url->dcount = 0; - return JB_ERR_MEMORY; - } - - memcpy(url->dvec, v, size); - } - } - - return JB_ERR_OK; - -} - - -/********************************************************************* - * - * Function : free_url_spec - * - * Description : Called from the "unloaders". Freez the url - * structure elements. - * - * Parameters : - * 1 : url = pointer to a url_spec structure. - * - * Returns : N/A - * - *********************************************************************/ -void free_url_spec(struct url_spec *url) -{ - if (url == NULL) return; - - freez(url->spec); - freez(url->dbuffer); - freez(url->dvec); - freez(url->path); - if (url->preg) - { - regfree(url->preg); - freez(url->preg); - } -} - - -/********************************************************************* - * - * Function : url_match - * - * Description : Compare a URL against a URL pattern. - * - * Parameters : - * 1 : pattern = a URL pattern - * 2 : url = URL to match - * - * Returns : 0 iff the URL matches the pattern, else nonzero. - * - *********************************************************************/ -int url_match(const struct url_spec *pattern, - const struct http_request *url) -{ - return ((pattern->port == 0) || (pattern->port == url->port)) - && ((pattern->dbuffer == NULL) || (domain_match(pattern, url) == 0)) - && ((pattern->path == NULL) || - (regexec(pattern->preg, url->path, 0, NULL, 0) == 0) - ); -} - - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/urlmatch.h b/urlmatch.h deleted file mode 100644 index 09fa6396..00000000 --- a/urlmatch.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef URLMATCH_H_INCLUDED -#define URLMATCH_H_INCLUDED -#define URLMATCH_H_VERSION "$Id: urlmatch.h,v 1.2 2002/03/24 13:25:43 swa Exp $" -/********************************************************************* - * - * File : $Source: /cvsroot/ijbswa/current/urlmatch.h,v $ - * - * Purpose : Declares functions to match URLs against URL - * patterns. - * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * Privoxy team. http://www.privoxy.org/ - * - * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and - * Junkbusters Corporation. http://www.junkbusters.com - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General - * Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * The GNU General Public License should be included with - * this file. If not, you can view it at - * http://www.gnu.org/copyleft/gpl.html - * or write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Revisions : - * $Log: urlmatch.h,v $ - * Revision 1.2 2002/03/24 13:25:43 swa - * name change related issues - * - * Revision 1.1 2002/01/17 20:53:46 jongfoster - * Moving all our URL and URL pattern parsing code to the same file - it - * was scattered around in filters.c, loaders.c and parsers.c. - * - * Providing a single, simple url_match(pattern,url) function - rather than - * the 3-line match routine which was repeated all over the place. - * - * Renaming free_url to free_url_spec, since it frees a struct url_spec. - * - * Providing parse_http_url() so that URLs can be parsed without faking a - * HTTP request line for parse_http_request() or repeating the parsing - * code (both of which were techniques that were actually in use). - * - * Standardizing that struct http_request is used to represent a URL, and - * struct url_spec is used to represent a URL pattern. (Before, URLs were - * represented as seperate variables and a partially-filled-in url_spec). - * - * - *********************************************************************/ - - -#include "project.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void free_http_request(struct http_request *http); -extern jb_err parse_http_request(const char *req, - struct http_request *http, - struct client_state *csp); -extern jb_err parse_http_url(const char * url, - struct http_request *http, - struct client_state *csp); - -extern int url_match(const struct url_spec *pattern, - const struct http_request *url); - -extern jb_err create_url_spec(struct url_spec * url, const char * buf); -extern void free_url_spec(struct url_spec *url); - - -/* Revision control strings from this header and associated .c file */ -extern const char urlmatch_rcs[]; -extern const char urlmatch_h_rcs[]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ndef URLMATCH_H_INCLUDED */ - -/* - Local Variables: - tab-width: 3 - end: -*/ diff --git a/w32log.c b/w32log.c deleted file mode 100644 index ada06b2e..00000000 --- a/w32log.c +++ /dev/null @@ -1,1344 +0,0 @@ -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 - * - * - * 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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include -#include - -#ifndef STRICT -#define STRICT -#endif -#include -#include - -#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: -*/ diff --git a/w32log.h b/w32log.h deleted file mode 100644 index 2634a95c..00000000 --- a/w32log.h +++ /dev/null @@ -1,161 +0,0 @@ -#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 - * - * - * 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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/w32res.h b/w32res.h deleted file mode 100644 index 62308cf2..00000000 --- a/w32res.h +++ /dev/null @@ -1,174 +0,0 @@ -#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 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: -*/ diff --git a/w32taskbar.c b/w32taskbar.c deleted file mode 100644 index 721ad08e..00000000 --- a/w32taskbar.c +++ /dev/null @@ -1,288 +0,0 @@ -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 - * - * - * 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 - * - * - *********************************************************************/ - - -#include "config.h" - -#include - -#ifndef STRICT -#define STRICT -#endif -#include - -#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: -*/ diff --git a/w32taskbar.h b/w32taskbar.h deleted file mode 100644 index 19450614..00000000 --- a/w32taskbar.h +++ /dev/null @@ -1,75 +0,0 @@ -#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 - * - * - * 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 - * - * - *********************************************************************/ - - -#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: -*/ diff --git a/win32.c b/win32.c deleted file mode 100644 index 9db1ed1b..00000000 --- a/win32.c +++ /dev/null @@ -1,311 +0,0 @@ -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 - * - * - * 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 - * - * - *********************************************************************/ - - -#include "config.h" - -#ifdef _WIN32 - -#include - -#include "project.h" -#include "jcc.h" -#include "miscutil.h" - -/* Uncomment this if you want to build Win32 as a console app */ -/* #define _WIN_CONSOLE */ - -#ifndef STRICT -#define STRICT -#endif -#include - -#include -#include - -#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) -/* Visual C++ Heap debugging */ -#include -#endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */ - -#include "win32.h" - -const char win32_h_rcs[] = WIN32_H_VERSION; - -const char win32_blurb[] = -"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 -#include - -#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: -*/ diff --git a/win32.h b/win32.h deleted file mode 100644 index 7c699dc3..00000000 --- a/win32.h +++ /dev/null @@ -1,87 +0,0 @@ -#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 - * - * - * 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 - * - * - *********************************************************************/ - - -#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: -*/