From f3832329e0d28159bfa2ad65f22ddada1b20d926 Mon Sep 17 00:00:00 2001 From: jongfoster Date: Tue, 4 Jun 2002 14:29:35 +0000 Subject: [PATCH] Moving sources to /src --- actionlist.h | 170 -- actions.c | 1656 ------------------ actions.h | 158 -- amiga.c | 283 --- amiga.h | 123 -- cgi.c | 2166 ----------------------- cgi.h | 245 --- cgiedit.c | 4710 -------------------------------------------------- cgiedit.h | 154 -- cgisimple.c | 1416 --------------- cgisimple.h | 149 -- cygwin.h | 73 - deanimate.c | 504 ------ deanimate.h | 102 -- encode.c | 483 ------ encode.h | 82 - errlog.c | 969 ----------- errlog.h | 177 -- filters.c | 1597 ----------------- filters.h | 282 --- gateway.c | 396 ----- gateway.h | 123 -- jbsockets.c | 817 --------- jbsockets.h | 130 -- jcc.c | 2351 ------------------------- jcc.h | 140 -- killpopup.c | 213 --- killpopup.h | 103 -- list.c | 1064 ------------ list.h | 164 -- loadcfg.c | 1595 ----------------- loadcfg.h | 189 -- loaders.c | 1446 ---------------- loaders.h | 235 --- miscutil.c | 1759 ------------------- miscutil.h | 194 --- parsers.c | 1791 ------------------- parsers.h | 231 --- pcrs.c | 939 ---------- pcrs.h | 168 -- project.h | 1433 --------------- ssplit.c | 208 --- ssplit.h | 77 - urlmatch.c | 809 --------- urlmatch.h | 97 -- w32log.c | 1344 -------------- w32log.h | 161 -- w32res.h | 174 -- w32taskbar.c | 288 --- w32taskbar.h | 75 - win32.c | 311 ---- win32.h | 87 - 52 files changed, 34611 deletions(-) delete mode 100644 actionlist.h delete mode 100644 actions.c delete mode 100644 actions.h delete mode 100644 amiga.c delete mode 100644 amiga.h delete mode 100644 cgi.c delete mode 100644 cgi.h delete mode 100644 cgiedit.c delete mode 100644 cgiedit.h delete mode 100644 cgisimple.c delete mode 100644 cgisimple.h delete mode 100644 cygwin.h delete mode 100644 deanimate.c delete mode 100644 deanimate.h delete mode 100644 encode.c delete mode 100644 encode.h delete mode 100644 errlog.c delete mode 100644 errlog.h delete mode 100644 filters.c delete mode 100644 filters.h delete mode 100644 gateway.c delete mode 100644 gateway.h delete mode 100644 jbsockets.c delete mode 100644 jbsockets.h delete mode 100644 jcc.c delete mode 100644 jcc.h delete mode 100644 killpopup.c delete mode 100644 killpopup.h delete mode 100644 list.c delete mode 100644 list.h delete mode 100644 loadcfg.c delete mode 100644 loadcfg.h delete mode 100644 loaders.c delete mode 100644 loaders.h delete mode 100644 miscutil.c delete mode 100644 miscutil.h delete mode 100644 parsers.c delete mode 100644 parsers.h delete mode 100644 pcrs.c delete mode 100644 pcrs.h delete mode 100644 project.h delete mode 100644 ssplit.c delete mode 100644 ssplit.h delete mode 100644 urlmatch.c delete mode 100644 urlmatch.h delete mode 100644 w32log.c delete mode 100644 w32log.h delete mode 100644 w32res.h delete mode 100644 w32taskbar.c delete mode 100644 w32taskbar.h delete mode 100644 win32.c delete mode 100644 win32.h 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: -*/ -- 2.39.2