Make number of retries in case of forwarded-connect problems
[privoxy.git] / jcc.c
1 const char jcc_rcs[] = "$Id: jcc.c,v 1.100 2006/09/03 19:42:59 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
5  *
6  * Purpose     :  Main file.  Contains main() method, main loop, and
7  *                the main connection-handling function.
8  *
9  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
10  *                Privoxy team. http://www.privoxy.org/
11  *
12  *                Based on the Internet Junkbuster originally written
13  *                by and Copyright (C) 1997 Anonymous Coders and
14  *                Junkbusters Corporation.  http://www.junkbusters.com
15  *
16  *                This program is free software; you can redistribute it
17  *                and/or modify it under the terms of the GNU General
18  *                Public License as published by the Free Software
19  *                Foundation; either version 2 of the License, or (at
20  *                your option) any later version.
21  *
22  *                This program is distributed in the hope that it will
23  *                be useful, but WITHOUT ANY WARRANTY; without even the
24  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
25  *                PARTICULAR PURPOSE.  See the GNU General Public
26  *                License for more details.
27  *
28  *                The GNU General Public License should be included with
29  *                this file.  If not, you can view it at
30  *                http://www.gnu.org/copyleft/gpl.html
31  *                or write to the Free Software Foundation, Inc., 59
32  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  *
34  * Revisions   :
35  *    $Log: jcc.c,v $
36  *    Revision 1.100  2006/09/03 19:42:59  fabiankeil
37  *    Set random(3) seed.
38  *
39  *    Revision 1.99  2006/09/02 15:36:42  fabiankeil
40  *    Follow the OpenBSD port's lead and protect the resolve
41  *    functions on OpenBSD as well.
42  *
43  *    Revision 1.98  2006/08/24 11:01:34  fabiankeil
44  *    --user fix. Only use the user as group if no group is specified.
45  *    Solves BR 1492612. Thanks to Spinor S. and David Laight.
46  *
47  *    Revision 1.97  2006/08/18 15:23:17  david__schmidt
48  *    Windows service (re-)integration
49  *
50  *    The new args are:
51  *
52  *    --install[:service_name]
53  *    --uninstall[:service_name]
54  *    --service
55  *
56  *    They work as follows:
57  *    --install will create a service for you and then terminate.
58  *    By default the service name will be "privoxy" (without the quotes).
59  *    However you can run multiple services if you wish, just by adding
60  *    a colon and then a name (no spaces).
61  *
62  *    --uninstall follows the exact same rules a --install.
63  *
64  *    --service is used when the program is executed by the service
65  *    control manager, and in normal circumstances would never be
66  *    used as a command line argument.
67  *
68  *    Revision 1.96  2006/08/15 20:12:36  david__schmidt
69  *    Windows service integration
70  *
71  *    Revision 1.95  2006/08/03 02:46:41  david__schmidt
72  *    Incorporate Fabian Keil's patch work:\rhttp://www.fabiankeil.de/sourcecode/privoxy/
73  *
74  *    Revision 1.94  2006/07/18 14:48:46  david__schmidt
75  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
76  *    with what was really the latest development (the v_3_0_branch branch)
77  *
78  *    Revision 1.92.2.16  2005/04/03 20:10:50  david__schmidt
79  *    Thanks to Jindrich Makovicka for a race condition fix for the log
80  *    file.  The race condition remains for non-pthread implementations.
81  *    Reference patch #1175720.
82  *
83  *    Revision 1.92.2.15  2004/10/03 12:53:32  david__schmidt
84  *    Add the ability to check jpeg images for invalid
85  *    lengths of comment blocks.  Defensive strategy
86  *    against the exploit:
87  *       Microsoft Security Bulletin MS04-028
88  *       Buffer Overrun in JPEG Processing (GDI+) Could
89  *       Allow Code Execution (833987)
90  *    Enabled with +inspect-jpegs in actions files.
91  *
92  *    Revision 1.92.2.14  2003/12/12 12:52:53  oes
93  *    - Fixed usage info for non-unix platforms
94  *    - Fixed small cmdline parsing bug
95  *
96  *    Revision 1.92.2.13  2003/11/27 19:20:27  oes
97  *    Diagnostics: Now preserve the returncode of pthread_create
98  *    in errno. Closes BR #775721. Thanks to Geoffrey Hausheer.
99  *
100  *    Revision 1.92.2.12  2003/07/11 11:34:19  oes
101  *    No longer ignore SIGCHLD. Fixes bug #769381
102  *
103  *    Revision 1.92.2.11  2003/05/14 12:32:02  oes
104  *    Close jarfile on graceful exit, remove stray line
105  *
106  *    Revision 1.92.2.10  2003/05/08 15:13:46  oes
107  *    Cosmetics: Killed a warning, a typo and an allocation left at exit
108  *
109  *    Revision 1.92.2.9  2003/04/03 15:08:42  oes
110  *    No longer rely on non-POSIX.1 extensions of getcwd().
111  *    Fixes bug #711001
112  *
113  *    Revision 1.92.2.8  2003/03/31 13:12:32  oes
114  *    Replaced setenv() by posix-compliant putenv()
115  *    Thanks to Neil McCalden (nmcc AT users.sf.net).
116  *
117  *    Revision 1.92.2.7  2003/03/17 16:48:59  oes
118  *    Added chroot ability, thanks to patch by Sviatoslav Sviridov
119  *
120  *    Revision 1.92.2.6  2003/03/11 11:55:00  oes
121  *    Clean-up and extension of improvements for forked mode:
122  *     - Child's return code now consists of flags RC_FLAG_*
123  *     - Reporting toggle to parent now properly #ifdef'ed
124  *     - Children now report blocking to parent. This enables
125  *       statistics in forked mode
126  *
127  *    Revision 1.92.2.5  2003/03/10 23:45:32  oes
128  *    Fixed bug #700381: Non-Threaded version now capable of being toggled.
129  *    Children now report having been toggled through _exit(17), parents
130  *    watch for that code and toggle themselves if found.
131  *
132  *    Revision 1.92.2.4  2003/03/07 03:41:04  david__schmidt
133  *    Wrapping all *_r functions (the non-_r versions of them) with 
134  *    mutex semaphores for OSX.  Hopefully this will take care of all 
135  *    of those pesky crash reports.
136  *
137  *    Revision 1.92.2.3  2003/02/28 12:53:06  oes
138  *    Fixed two mostly harmless mem leaks
139  *
140  *    Revision 1.92.2.2  2002/11/20 14:37:47  oes
141  *    Fix: Head of global clients list now initialized to NULL
142  *
143  *    Revision 1.92.2.1  2002/09/25 14:52:24  oes
144  *    Added basic support for OPTIONS and TRACE HTTP methods:
145  *     - New interceptor direct_response() added in chat().
146  *     - sed() moved to earlier in the process, so that the
147  *       Host: header is evaluated before actions and forwarding
148  *       are decided on.
149  *
150  *    Revision 1.92  2002/05/08 16:00:46  oes
151  *    Chat's buffer handling:
152  *     - Fixed bug with unchecked out-of-mem conditions
153  *       while reading client request & server headers
154  *     - No longer predict if the buffer limit will be exceeded
155  *       in the next read -- check add_to_iob's new
156  *       return code. If buffer couldn't be extended
157  *       (policy or out-of-mem) while
158  *       - reading from client: abort
159  *       - reading server headers: send error page
160  *       - buffering server body for filter: flush,
161  *         and if that fails: send error page
162  *
163  *    Revision 1.91  2002/04/08 20:35:58  swa
164  *    fixed JB spelling
165  *
166  *    Revision 1.90  2002/04/02 14:57:28  oes
167  *    Made sending wafers independent of FEATURE_COOKIE_JAR
168  *
169  *    Revision 1.89  2002/03/31 17:18:59  jongfoster
170  *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
171  *
172  *    Revision 1.88  2002/03/27 14:32:43  david__schmidt
173  *    More compiler warning message maintenance
174  *
175  *    Revision 1.87  2002/03/26 22:29:54  swa
176  *    we have a new homepage!
177  *
178  *    Revision 1.86  2002/03/25 17:04:55  david__schmidt
179  *    Workaround for closing the jarfile before load_config() comes around again
180  *
181  *    Revision 1.85  2002/03/24 15:23:33  jongfoster
182  *    Name changes
183  *
184  *    Revision 1.84  2002/03/24 13:25:43  swa
185  *    name change related issues
186  *
187  *    Revision 1.83  2002/03/16 23:54:06  jongfoster
188  *    Adding graceful termination feature, to help look for memory leaks.
189  *    If you enable this (which, by design, has to be done by hand
190  *    editing config.h) and then go to http://i.j.b/die, then the program
191  *    will exit cleanly after the *next* request.  It should free all the
192  *    memory that was used.
193  *
194  *    Revision 1.82  2002/03/13 00:27:05  jongfoster
195  *    Killing warnings
196  *
197  *    Revision 1.81  2002/03/12 01:42:50  oes
198  *    Introduced modular filters
199  *
200  *    Revision 1.80  2002/03/11 22:07:05  david__schmidt
201  *    OS/2 port maintenance:
202  *    - Fixed EMX build - it had decayed a little
203  *    - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
204  *      substituted a memset for now.
205  *
206  *    Revision 1.79  2002/03/09 20:03:52  jongfoster
207  *    - Making various functions return int rather than size_t.
208  *      (Undoing a recent change).  Since size_t is unsigned on
209  *      Windows, functions like read_socket that return -1 on
210  *      error cannot return a size_t.
211  *
212  *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
213  *      crashes, and also frequently caused JB to jump to 100%
214  *      CPU and stay there.  (Because it thought it had just
215  *      read ((unsigned)-1) == 4Gb of data...)
216  *
217  *    - The signature of write_socket has changed, it now simply
218  *      returns success=0/failure=nonzero.
219  *
220  *    - Trying to get rid of a few warnings --with-debug on
221  *      Windows, I've introduced a new type "jb_socket".  This is
222  *      used for the socket file descriptors.  On Windows, this
223  *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
224  *      an int.  The error value can't be -1 any more, so it's
225  *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
226  *      Windows it maps to the #define INVALID_SOCKET.)
227  *
228  *    - The signature of bind_port has changed.
229  *
230  *    Revision 1.78  2002/03/08 21:35:04  oes
231  *    Added optional group supplement to --user option. Will now use default group of user if no group given
232  *
233  *    Revision 1.77  2002/03/07 03:52:06  oes
234  *     - Fixed compiler warnings etc
235  *     - Improved handling of failed DNS lookups
236  *
237  *    Revision 1.76  2002/03/06 22:54:35  jongfoster
238  *    Automated function-comment nitpicking.
239  *
240  *    Revision 1.75  2002/03/06 10:02:19  oes
241  *    Fixed stupid bug when --user was not given
242  *
243  *    Revision 1.74  2002/03/06 00:49:31  jongfoster
244  *    Fixing warning on Windows
245  *    Making #ifdefs that refer to the same variable consistently
246  *    use #ifdef unix rather than mixing #ifdef unix & #ifndef OS2
247  *
248  *    Revision 1.73  2002/03/05 23:57:30  hal9
249  *    Stray character 's' on line 1618 was breaking build.
250  *
251  *    Revision 1.72  2002/03/05 21:33:45  david__schmidt
252  *    - Re-enable OS/2 building after new parms were added
253  *    - Fix false out of memory report when resolving CGI templates when no IP
254  *      address is available of failed attempt (a la no such domain)
255  *
256  *    Revision 1.71  2002/03/05 18:13:56  oes
257  *    Added --user option
258  *
259  *    Revision 1.70  2002/03/05 04:52:42  oes
260  *    Deleted non-errlog debugging code
261  *
262  *    Revision 1.69  2002/03/04 23:50:00  jongfoster
263  *    Splitting off bind_port() call into bind_port_helper(), with
264  *    improved logging.
265  *
266  *    Revision 1.68  2002/03/04 20:17:32  oes
267  *    Fixed usage info
268  *
269  *    Revision 1.67  2002/03/04 18:18:57  oes
270  *    - Removed _DEBUG mode
271  *    - Cleand up cmdline parsing
272  *    - Introduced --no-daemon, --pidfile options
273  *    - Cleaned up signal handling:
274  *      - Terminate cleanly on INT, TERM and ABRT
275  *      - Schedule logfile for re-opening on HUP
276  *      - Ignore CHLD and PIPE
277  *      - Leave the rest with their default handlers
278  *      - Uniform handler registration
279  *    - Added usage() function
280  *    - Played styleguide police
281  *
282  *    Revision 1.66  2002/03/03 15:06:55  oes
283  *    Re-enabled automatic config reloading
284  *
285  *    Revision 1.65  2002/03/03 14:49:11  oes
286  *    Fixed CLF logging: Now uses client's original HTTP request
287  *
288  *    Revision 1.64  2002/03/03 09:18:03  joergs
289  *    Made jumbjuster work on AmigaOS again.
290  *
291  *    Revision 1.63  2002/03/02 04:14:50  david__schmidt
292  *    Clean up a little CRLF unpleasantness that suddenly appeared
293  *
294  *    Revision 1.62  2002/02/20 23:17:23  jongfoster
295  *    Detecting some out-of memory conditions and exiting with a log message.
296  *
297  *    Revision 1.61  2002/01/17 21:01:52  jongfoster
298  *    Moving all our URL and URL pattern parsing code to urlmatch.c.
299  *
300  *    Revision 1.60  2001/12/30 14:07:32  steudten
301  *    - Add signal handling (unix)
302  *    - Add SIGHUP handler (unix)
303  *    - Add creation of pidfile (unix)
304  *    - Add action 'top' in rc file (RH)
305  *    - Add entry 'SIGNALS' to manpage
306  *    - Add exit message to logfile (unix)
307  *
308  *    Revision 1.59  2001/12/13 14:07:18  oes
309  *    Fixed Bug: 503 error page now sent OK
310  *
311  *    Revision 1.58  2001/11/30 23:37:24  jongfoster
312  *    Renaming the Win32 config file to config.txt - this is almost the
313  *    same as the corresponding UNIX name "config"
314  *
315  *    Revision 1.57  2001/11/16 00:47:43  jongfoster
316  *    Changing the tty-disconnection code to use setsid().
317  *
318  *    Revision 1.56  2001/11/13 20:20:54  jongfoster
319  *    Tabs->spaces, fixing a bug with missing {} around an if()
320  *
321  *    Revision 1.55  2001/11/13 20:14:53  jongfoster
322  *    Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
323  *
324  *    Revision 1.54  2001/11/07 00:03:14  steudten
325  *    Give reliable return value if an error
326  *    occurs not just 0 with new daemon mode.
327  *
328  *    Revision 1.53  2001/11/05 21:41:43  steudten
329  *    Add changes to be a real daemon just for unix os.
330  *    (change cwd to /, detach from controlling tty, set
331  *    process group and session leader to the own process.
332  *    Add DBG() Macro.
333  *    Add some fatal-error log message for failed malloc().
334  *    Add '-d' if compiled with 'configure --with-debug' to
335  *    enable debug output.
336  *
337  *    Revision 1.52  2001/10/26 20:11:20  jongfoster
338  *    Fixing type mismatch
339  *
340  *    Revision 1.51  2001/10/26 17:38:28  oes
341  *    Cosmetics
342  *
343  *    Revision 1.50  2001/10/25 03:40:48  david__schmidt
344  *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
345  *    threads to call select() simultaneously.  So, it's time to do a real, live,
346  *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
347  *    (native). Both versions will work, but using __OS2__ offers multi-threading.
348  *
349  *    Revision 1.49  2001/10/23 21:41:35  jongfoster
350  *    Added call to initialize the (statically-allocated of course)
351  *    "out of memory" CGI response.
352  *
353  *    Revision 1.48  2001/10/10 19:56:46  jongfoster
354  *    Moving some code that wasn't cookie-related out of an #ifdef
355  *    FEATURE_COOKIE_JAR
356  *
357  *    Revision 1.47  2001/10/10 16:44:36  oes
358  *    Added CONNECT destination port limitation check
359  *
360  *    Revision 1.46  2001/10/08 15:17:41  oes
361  *    Re-enabled SSL forwarding
362  *
363  *    Revision 1.45  2001/10/07 15:42:11  oes
364  *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
365  *
366  *    Moved downgrading of the HTTP version from parse_http_request to
367  *      chat(), since we can't decide if it is necessary before we have
368  *      determined the actions for the URL. The HTTP command is now
369  *      *always* re-built so the repairs need no longer be special-cased.
370  *
371  *    filter_popups now gets a csp pointer so it can raise the new
372  *      CSP_FLAG_MODIFIED flag.
373  *
374  *    Bugfix
375  *
376  *    Added configurable size limit for the IOB. If the IOB grows so
377  *      large that the next read would exceed the limit, the header
378  *      is generated, and the header & unfiltered buffer are flushed
379  *      to the client. Chat then continues in non-buffering,
380  *      non-filtering body mode.
381  *
382  *    Revision 1.44  2001/10/02 18:13:57  oes
383  *    Ooops
384  *
385  *    Revision 1.43  2001/10/02 15:32:13  oes
386  *    Moved generation of hdr
387  *
388  *    Revision 1.42  2001/09/21 23:02:02  david__schmidt
389  *    Cleaning up 2 compiler warnings on OS/2.
390  *
391  *    Revision 1.41  2001/09/16 17:05:14  jongfoster
392  *    Removing unused #include showarg.h
393  *
394  *    Revision 1.40  2001/09/16 15:41:45  jongfoster
395  *    Fixing signed/unsigned comparison warning.
396  *
397  *    Revision 1.39  2001/09/16 13:21:27  jongfoster
398  *    Changes to use new list functions.
399  *
400  *    Revision 1.38  2001/09/16 13:01:46  jongfoster
401  *    Removing redundant function call that zeroed zalloc()'d memory.
402  *
403  *    Revision 1.37  2001/09/10 11:12:24  oes
404  *    Deleted unused variable
405  *
406  *    Revision 1.36  2001/09/10 10:56:15  oes
407  *    Silenced compiler warnings
408  *
409  *    Revision 1.35  2001/07/31 14:44:22  oes
410  *    Deleted unused size parameter from filter_popups()
411  *
412  *    Revision 1.34  2001/07/30 22:08:36  jongfoster
413  *    Tidying up #defines:
414  *    - All feature #defines are now of the form FEATURE_xxx
415  *    - Permanently turned off WIN_GUI_EDIT
416  *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
417  *
418  *    Revision 1.33  2001/07/29 19:32:00  jongfoster
419  *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
420  *
421  *    Revision 1.32  2001/07/29 18:47:05  jongfoster
422  *    Adding missing #include "loadcfg.h"
423  *
424  *    Revision 1.31  2001/07/29 12:17:48  oes
425  *    Applied pthread fix by Paul Lieverse
426  *
427  *    Revision 1.30  2001/07/25 22:57:13  jongfoster
428  *    __BEOS__ no longer overrides FEATURE_PTHREAD.
429  *    This is because FEATURE_PTHREAD will soon be widely used, so I
430  *    want to keep it simple.
431  *
432  *    Revision 1.29  2001/07/24 12:47:06  oes
433  *    Applied BeOS support update by Eugenia
434  *
435  *    Revision 1.28  2001/07/23 13:26:12  oes
436  *    Fixed bug in popup-killing for the first read that caused binary garbage to be sent between headers and body
437  *
438  *    Revision 1.27  2001/07/19 19:09:47  haroon
439  *    - Added code to take care of the situation where while processing the first
440  *      server response (which includes the server header), after finding the end
441  *      of the headers we were not looking past the end of the headers for
442  *      content modification. I enabled it for filter_popups.
443  *      Someone else should look to see if other similar operations should be
444  *      done to the discarded portion of the buffer.
445  *
446  *      Note 2001/07/20: No, the other content modification mechanisms will process
447  *                       the whole iob later anyway. --oes
448  *
449  *    Revision 1.26  2001/07/18 12:31:36  oes
450  *    cosmetics
451  *
452  *    Revision 1.25  2001/07/15 19:43:49  jongfoster
453  *    Supports POSIX threads.
454  *    Also removed some unused #includes.
455  *
456  *    Revision 1.24  2001/07/13 14:00:40  oes
457  *     - Generic content modification scheme:
458  *       Each feature has its own applicability flag that is set
459  *       from csp->action->flags.
460  *       Replaced the "filtering" int flag , by a function pointer
461  *       "content_filter" to the function that will do the content
462  *       modification. If it is != NULL, the document will be buffered
463  *       and processed through *content_filter, which must set
464  *       csp->content_length and return a modified copy of the body
465  *       or return NULL (on failiure).
466  *     - Changed csp->is_text to the more generic bitmap csp->content_type
467  *       which can currently take the valued CT_TEXT or CT_GIF
468  *     - Reformatting etc
469  *     - Removed all #ifdef PCRS
470  *
471  *    Revision 1.23  2001/07/02 02:28:25  iwanttokeepanon
472  *    Added "#ifdef ACL_FILES" conditional compilation to line 1291 to exclude
473  *    the `block_acl' call.  This prevents a compilation error when the user
474  *    does not wish to use the "ACL" feature.
475  *
476  *    Revision 1.22  2001/06/29 21:45:41  oes
477  *    Indentation, CRLF->LF, Tab-> Space
478  *
479  *    Revision 1.21  2001/06/29 13:29:36  oes
480  *    - Cleaned up, improved comments
481  *    - Unified all possible interceptors (CGI,
482  *      block, trust, fast_redirect) in one
483  *      place, with one (CGI) answer generation
484  *      mechansim. Much clearer now.
485  *    - Removed the GIF image generation, which
486  *      is now done in filters.c:block_url()
487  *    - Made error conditions like domain lookup
488  *      failiure or (various) problems while talking
489  *      to the server use cgi.c:error_response()
490  *      instead of generating HTML/HTTP in chat() (yuck!)
491  *    - Removed logentry from cancelled commit
492  *
493  *    Revision 1.20  2001/06/09 10:55:28  jongfoster
494  *    Changing BUFSIZ ==> BUFFER_SIZE
495  *
496  *    Revision 1.19  2001/06/07 23:12:52  jongfoster
497  *    Replacing function pointer in struct gateway with a directly
498  *    called function forwarded_connect().
499  *    Replacing struct gateway with struct forward_spec
500  *
501  *    Revision 1.18  2001/06/03 19:12:16  oes
502  *    introduced new cgi handling
503  *
504  *    Revision 1.17  2001/06/01 20:07:23  jongfoster
505  *    Now uses action +image-blocker{} rather than config->tinygif
506  *
507  *    Revision 1.16  2001/06/01 18:49:17  jongfoster
508  *    Replaced "list_share" with "list" - the tiny memory gain was not
509  *    worth the extra complexity.
510  *
511  *    Revision 1.15  2001/05/31 21:24:47  jongfoster
512  *    Changed "permission" to "action" throughout.
513  *    Removed DEFAULT_USER_AGENT - it must now be specified manually.
514  *    Moved vanilla wafer check into chat(), since we must now
515  *    decide whether or not to add it based on the URL.
516  *
517  *    Revision 1.14  2001/05/29 20:14:01  joergs
518  *    AmigaOS bugfix: PCRS needs a lot of stack, stacksize for child threads
519  *    increased.
520  *
521  *    Revision 1.13  2001/05/29 09:50:24  jongfoster
522  *    Unified blocklist/imagelist/permissionslist.
523  *    File format is still under discussion, but the internal changes
524  *    are (mostly) done.
525  *
526  *    Also modified interceptor behaviour:
527  *    - We now intercept all URLs beginning with one of the following
528  *      prefixes (and *only* these prefixes):
529  *        * http://i.j.b/
530  *        * http://ijbswa.sf.net/config/
531  *        * http://ijbswa.sourceforge.net/config/
532  *    - New interceptors "home page" - go to http://i.j.b/ to see it.
533  *    - Internal changes so that intercepted and fast redirect pages
534  *      are not replaced with an image.
535  *    - Interceptors now have the option to send a binary page direct
536  *      to the client. (i.e. ijb-send-banner uses this)
537  *    - Implemented show-url-info interceptor.  (Which is why I needed
538  *      the above interceptors changes - a typical URL is
539  *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
540  *      The previous mechanism would not have intercepted that, and
541  *      if it had been intercepted then it then it would have replaced
542  *      it with an image.)
543  *
544  *    Revision 1.12  2001/05/27 22:17:04  oes
545  *
546  *    - re_process_buffer no longer writes the modified buffer
547  *      to the client, which was very ugly. It now returns the
548  *      buffer, which it is then written by chat.
549  *
550  *    - content_length now adjusts the Content-Length: header
551  *      for modified documents rather than crunch()ing it.
552  *      (Length info in csp->content_length, which is 0 for
553  *      unmodified documents)
554  *
555  *    - For this to work, sed() is called twice when filtering.
556  *
557  *    Revision 1.11  2001/05/26 17:27:53  jongfoster
558  *    Added support for CLF and fixed LOG_LEVEL_LOG.
559  *    Also did CRLF->LF fix of my previous patch.
560  *
561  *    Revision 1.10  2001/05/26 15:26:15  jongfoster
562  *    ACL feature now provides more security by immediately dropping
563  *    connections from untrusted hosts.
564  *
565  *    Revision 1.9  2001/05/26 00:28:36  jongfoster
566  *    Automatic reloading of config file.
567  *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
568  *    Most of the global variables have been moved to a new
569  *    struct configuration_spec, accessed through csp->config->globalname
570  *    Most of the globals remaining are used by the Win32 GUI.
571  *
572  *    Revision 1.8  2001/05/25 22:43:18  jongfoster
573  *    Fixing minor memory leak and buffer overflow.
574  *
575  *    Revision 1.7  2001/05/25 22:34:30  jongfoster
576  *    Hard tabs->Spaces
577  *
578  *    Revision 1.6  2001/05/23 00:13:58  joergs
579  *    AmigaOS support fixed.
580  *
581  *    Revision 1.5  2001/05/22 18:46:04  oes
582  *
583  *    - Enabled filtering banners by size rather than URL
584  *      by adding patterns that replace all standard banner
585  *      sizes with the "Junkbuster" gif to the re_filterfile
586  *
587  *    - Enabled filtering WebBugs by providing a pattern
588  *      which kills all 1x1 images
589  *
590  *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
591  *      which is selected by the (nonstandard and therefore
592  *      capital) letter 'U' in the option string.
593  *      It causes the quantifiers to be ungreedy by default.
594  *      Appending a ? turns back to greedy (!).
595  *
596  *    - Added a new interceptor ijb-send-banner, which
597  *      sends back the "Junkbuster" gif. Without imagelist or
598  *      MSIE detection support, or if tinygif = 1, or the
599  *      URL isn't recognized as an imageurl, a lame HTML
600  *      explanation is sent instead.
601  *
602  *    - Added new feature, which permits blocking remote
603  *      script redirects and firing back a local redirect
604  *      to the browser.
605  *      The feature is conditionally compiled, i.e. it
606  *      can be disabled with --disable-fast-redirects,
607  *      plus it must be activated by a "fast-redirects"
608  *      line in the config file, has its own log level
609  *      and of course wants to be displayed by show-proxy-args
610  *      Note: Boy, all the #ifdefs in 1001 locations and
611  *      all the fumbling with configure.in and acconfig.h
612  *      were *way* more work than the feature itself :-(
613  *
614  *    - Because a generic redirect template was needed for
615  *      this, tinygif = 3 now uses the same.
616  *
617  *    - Moved GIFs, and other static HTTP response templates
618  *      to project.h
619  *
620  *    - Some minor fixes
621  *
622  *    - Removed some >400 CRs again (Jon, you really worked
623  *      a lot! ;-)
624  *
625  *    Revision 1.4  2001/05/21 19:34:01  jongfoster
626  *    Made failure to bind() a fatal error.
627  *
628  *    Revision 1.3  2001/05/20 01:21:20  jongfoster
629  *    Version 2.9.4 checkin.
630  *    - Merged popupfile and cookiefile, and added control over PCRS
631  *      filtering, in new "permissionsfile".
632  *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
633  *      file error you now get a message box (in the Win32 GUI) rather
634  *      than the program exiting with no explanation.
635  *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
636  *      skipping.
637  *    - Removed tabs from "config"
638  *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
639  *    - Bumped up version number.
640  *
641  *    Revision 1.2  2001/05/17 22:34:44  oes
642  *     - Added hint on GIF char array generation to jcc.c
643  *     - Cleaned CRLF's from the sources and related files
644  *     - Repaired logging for REF and FRC
645  *
646  *    Revision 1.1.1.1  2001/05/15 13:58:56  oes
647  *    Initial import of version 2.9.3 source tree
648  *
649  *
650  *********************************************************************/
651 \f
652
653 #include "config.h"
654
655 #include <stdio.h>
656 #include <sys/types.h>
657 #include <stdlib.h>
658 #include <string.h>
659 #include <signal.h>
660 #include <fcntl.h>
661 #include <errno.h>
662
663 #ifdef FEATURE_PTHREAD
664 #include <pthread.h>
665 #endif /* def FEATURE_PTHREAD */
666
667 #ifdef _WIN32
668 # ifndef FEATURE_PTHREAD
669 #  ifndef STRICT
670 #   define STRICT
671 #  endif
672 #  include <windows.h>
673 #  include <process.h>
674 # endif /* ndef FEATURE_PTHREAD */
675
676 # include "win32.h"
677 # ifndef _WIN_CONSOLE
678 #  include "w32log.h"
679 # endif /* ndef _WIN_CONSOLE */
680 # include "w32svrapi.h"
681
682 #else /* ifndef _WIN32 */
683
684 # if !defined (__OS2__)
685 # include <unistd.h>
686 # include <sys/wait.h>
687 # endif /* ndef __OS2__ */
688 # include <sys/time.h>
689 # include <sys/stat.h>
690 # include <sys/ioctl.h>
691
692 #ifdef sun
693 #include <sys/termios.h>
694 #endif /* sun */
695
696 #ifdef unix
697 #include <pwd.h>
698 #include <grp.h>
699 #endif
700
701 # include <signal.h>
702
703 # ifdef __BEOS__
704 #  include <socket.h>  /* BeOS has select() for sockets only. */
705 #  include <OS.h>      /* declarations for threads and stuff. */
706 # endif
707
708 # if defined(__EMX__) || defined(__OS2__)
709 #  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
710 # endif
711 # ifdef __OS2__
712 #define INCL_DOS
713 # include <os2.h>
714 #define bzero(B,N) memset(B,0x00,n)
715 # endif
716
717 # ifndef FD_ZERO
718 #  include <select.h>
719 # endif
720
721 #endif
722
723 #include "project.h"
724 #include "list.h"
725 #include "jcc.h"
726 #include "filters.h"
727 #include "loaders.h"
728 #include "parsers.h"
729 #include "killpopup.h"
730 #include "miscutil.h"
731 #include "errlog.h"
732 #include "jbsockets.h"
733 #include "gateway.h"
734 #include "actions.h"
735 #include "cgi.h"
736 #include "loadcfg.h"
737 #include "urlmatch.h"
738
739 const char jcc_h_rcs[] = JCC_H_VERSION;
740 const char project_h_rcs[] = PROJECT_H_VERSION;
741
742 int no_daemon = 0;
743 struct client_state  clients[1];
744 struct file_list     files[1];
745
746 #ifdef FEATURE_STATISTICS
747 int urls_read     = 0;     /* total nr of urls read inc rejected */
748 int urls_rejected = 0;     /* total nr of urls rejected */
749 #endif /* def FEATURE_STATISTICS */
750
751 #ifdef FEATURE_GRACEFUL_TERMINATION
752 int g_terminate = 0;
753 #endif
754
755 static void listen_loop(void);
756 static void chat(struct client_state *csp);
757 #ifdef AMIGA
758 void serve(struct client_state *csp);
759 #else /* ifndef AMIGA */
760 static void serve(struct client_state *csp);
761 #endif /* def AMIGA */
762
763 #ifdef __BEOS__
764 static int32 server_thread(void *data);
765 #endif /* def __BEOS__ */
766
767 #ifdef _WIN32
768 #define sleep(N)  Sleep(((N) * 1000))
769 #endif
770
771 #ifdef __OS2__
772 #define sleep(N)  DosSleep(((N) * 100))
773 #endif
774
775 #if defined(OSX_DARWIN) || defined(__OpenBSD__)
776 #ifdef OSX_DARWIN
777 /*
778  * Hit OSX over the head with a hammer.  Protect all *_r functions.
779  */
780 pthread_mutex_t gmtime_mutex;
781 pthread_mutex_t localtime_mutex;
782 #endif /* def OSX_DARWIN */
783 /*
784  * Protect only the resolve functions for OpenBSD.
785  */ 
786 pthread_mutex_t gethostbyaddr_mutex;
787 pthread_mutex_t gethostbyname_mutex;
788 #endif /* defined(OSX_DARWIN) || defined(__OpenBSD__) */
789
790 #ifdef FEATURE_PTHREAD
791 pthread_mutex_t log_mutex;
792 pthread_mutex_t log_init_mutex;
793 #endif /* FEATURE_PTHREAD */
794
795 #if defined(unix) || defined(__EMX__)
796 const char *basedir = NULL;
797 const char *pidfile = NULL;
798 int received_hup_signal = 0;
799 #endif /* defined unix */
800
801 /* The vanilla wafer. */
802 static const char VANILLA_WAFER[] =
803    "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
804    "Do_not_send_me_any_copyrighted_information_other_than_the_"
805    "document_that_I_am_requesting_or_any_of_its_necessary_components._"
806    "In_particular_do_not_send_me_any_cookies_that_"
807    "are_subject_to_a_claim_of_copyright_by_anybody._"
808    "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
809    "(copyright_or_otherwise)_applying_to_any_cookie._";
810
811
812 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
813 /*********************************************************************
814  *
815  * Function    :  sig_handler 
816  *
817  * Description :  Signal handler for different signals.
818  *                Exit gracefully on ABRT, TERM and  INT
819  *                or set a flag that will cause the errlog
820  *                to be reopened by the main thread on HUP.
821  *
822  * Parameters  :
823  *          1  :  the_signal = the signal cause this function to call
824  *
825  * Returns     :  - 
826  *
827  *********************************************************************/
828 static void sig_handler(int the_signal)
829 {
830    switch(the_signal)
831    {
832       case SIGABRT:
833       case SIGTERM:
834       case SIGINT:
835          log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
836 #if defined(unix)
837          unlink(pidfile);
838 #endif /* unix */
839          exit(the_signal);
840          break;
841
842       case SIGHUP:
843          received_hup_signal = 1;
844          break;         
845
846       default:
847          /* 
848           * We shouldn't be here, unless we catch signals
849           * in main() that we can't handle here!
850           */
851          log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
852    }
853    return;
854
855 }
856 #endif
857
858
859 /*********************************************************************
860  *
861  * Function    :  chat
862  *
863  * Description :  Once a connection to the client has been accepted,
864  *                this function is called (via serve()) to handle the
865  *                main business of the communication.  When this
866  *                function returns, the caller must close the client
867  *                socket handle.
868  *
869  * Parameters  :
870  *          1  :  csp = Current client state (buffers, headers, etc...)
871  *
872  * Returns     :  On success, the number of bytes written are returned (zero
873  *                indicates nothing was written).  On error, -1 is returned,
874  *                and errno is set appropriately.  If count is zero and the
875  *                file descriptor refers to a regular file, 0 will be
876  *                returned without causing any other effect.  For a special
877  *                file, the results are not portable.
878  *
879  *********************************************************************/
880 static void chat(struct client_state *csp)
881 {
882 /*
883  * This next lines are a little ugly, but they simplifies the if statements
884  * below.  Basically if TOGGLE, then we want the if to test if the
885  * CSP_FLAG_TOGGLED_ON flag ist set, else we don't.  And if FEATURE_FORCE_LOAD,
886  * then we want the if to test for CSP_FLAG_FORCED , else we don't
887  */
888 #ifdef FEATURE_TOGGLE
889 #   define IS_TOGGLED_ON_AND (csp->flags & CSP_FLAG_TOGGLED_ON) &&
890 #else /* ifndef FEATURE_TOGGLE */
891 #   define IS_TOGGLED_ON_AND
892 #endif /* ndef FEATURE_TOGGLE */
893 #ifdef FEATURE_FORCE_LOAD
894 #   define IS_NOT_FORCED_AND !(csp->flags & CSP_FLAG_FORCED) &&
895 #else /* ifndef FEATURE_FORCE_LOAD */
896 #   define IS_NOT_FORCED_AND
897 #endif /* def FEATURE_FORCE_LOAD */
898
899 #define IS_ENABLED_AND   IS_TOGGLED_ON_AND IS_NOT_FORCED_AND
900
901    char buf[BUFFER_SIZE];
902    char *hdr;
903    char *p;
904    char *req;
905    fd_set rfds;
906    int n;
907    jb_socket maxfd;
908    int server_body;
909    int ms_iis5_hack = 0;
910    int byte_count = 0;
911    unsigned int forwarded_connect_retries = 0;
912    unsigned int max_forwarded_connect_retries = csp->config->forwarded_connect_retries;
913    const struct forward_spec * fwd;
914    struct http_request *http;
915    int len; /* for buffer sizes */
916 #ifdef FEATURE_KILL_POPUPS
917    int block_popups;         /* bool, 1==will block popups */
918    int block_popups_now = 0; /* bool, 1==currently blocking popups */
919 #endif /* def FEATURE_KILL_POPUPS */
920
921    int pcrs_filter;        /* bool, 1==will filter through pcrs */
922    int gif_deanimate;      /* bool, 1==will deanimate gifs */
923    int jpeg_inspect;       /* bool, 1==will inspect jpegs */
924
925    /* Function that does the content filtering for the current request */
926    char *(*content_filter)() = NULL;
927
928    /* Skeleton for HTTP response, if we should intercept the request */
929    struct http_response *rsp;
930
931    http = csp->http;
932
933    /*
934     * Read the client's request.  Note that since we're not using select() we
935     * could get blocked here if a client connected, then didn't say anything!
936     */
937
938    for (;;)
939    {
940       len = read_socket(csp->cfd, buf, sizeof(buf));
941
942       if (len <= 0) break;      /* error! */
943       
944       /*
945        * If there is no memory left for buffering the
946        * request, there is nothing we can do but hang up
947        */
948       if (add_to_iob(csp, buf, len))
949       {
950          return;
951       }
952
953       req = get_header(csp);
954
955       if (req == NULL)
956       {
957          break;    /* no HTTP request! */
958       }
959
960       if (*req == '\0')
961       {
962          continue;   /* more to come! */
963       }
964
965 #ifdef FEATURE_FORCE_LOAD
966       /* If this request contains the FORCE_PREFIX,
967        * better get rid of it now and set the force flag --oes
968        */
969
970       if (strstr(req, FORCE_PREFIX))
971       {
972          strclean(req, FORCE_PREFIX);
973          log_error(LOG_LEVEL_FORCE, "Enforcing request \"%s\".\n", req);
974          csp->flags |= CSP_FLAG_FORCED;
975       }
976
977 #endif /* def FEATURE_FORCE_LOAD */
978
979       parse_http_request(req, http, csp);
980       freez(req);
981       break;
982    }
983
984    if (http->cmd == NULL)
985    {
986       strcpy(buf, CHEADER);
987       write_socket(csp->cfd, buf, strlen(buf));
988
989       log_error(LOG_LEVEL_CLF, "%s - - [%T] \" \" 400 0", csp->ip_addr_str);
990
991       free_http_request(http);
992       return;
993    }
994
995    /* decide how to route the HTTP request */
996
997    if ((fwd = forward_url(http, csp)) == NULL)
998    {
999       log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
1000       /* Never get here - LOG_LEVEL_FATAL causes program exit */
1001    }
1002
1003    /* build the http request to send to the server
1004     * we have to do one of the following:
1005     *
1006     * create = use the original HTTP request to create a new
1007     *          HTTP request that has either the path component
1008     *          without the http://domainspec (w/path) or the
1009     *          full orininal URL (w/url)
1010     *          Note that the path and/or the HTTP version may
1011     *          have been altered by now.
1012     *
1013     * connect = Open a socket to the host:port of the server
1014     *           and short-circuit server and client socket.
1015     *
1016     * pass =  Pass the request unchanged if forwarding a CONNECT
1017     *         request to a parent proxy. Note that we'll be sending
1018     *         the CFAIL message ourselves if connecting to the parent
1019     *         fails, but we won't send a CSUCCEED message if it works,
1020     *         since that would result in a double message (ours and the
1021     *         parent's). After sending the request to the parent, we simply
1022     *         tunnel.
1023     *
1024     * here's the matrix:
1025     *                        SSL
1026     *                    0        1
1027     *                +--------+--------+
1028     *                |        |        |
1029     *             0  | create | connect|
1030     *                | w/path |        |
1031     *  Forwarding    +--------+--------+
1032     *                |        |        |
1033     *             1  | create | pass   |
1034     *                | w/url  |        |
1035     *                +--------+--------+
1036     *
1037     */
1038
1039    /*
1040     * Determine the actions for this URL
1041     */
1042 #ifdef FEATURE_TOGGLE
1043    if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
1044    {
1045       /* Most compatible set of actions (i.e. none) */
1046       init_current_action(csp->action);
1047    }
1048    else
1049 #endif /* ndef FEATURE_TOGGLE */
1050    {
1051       url_actions(http, csp);
1052    }
1053
1054
1055    /*
1056     * Check if a CONNECT request is allowable:
1057     * In the absence of a +limit-connect action, allow only port 443.
1058     * If there is an action, allow whatever matches the specificaton.
1059     */
1060    if(http->ssl)
1061    {
1062       if(  ( !(csp->action->flags & ACTION_LIMIT_CONNECT) && csp->http->port != 443)
1063            || (csp->action->flags & ACTION_LIMIT_CONNECT
1064               && !match_portlist(csp->action->string[ACTION_STRING_LIMIT_CONNECT], csp->http->port)) )
1065       {
1066          if (csp->action->flags & ACTION_TREAT_FORBIDDEN_CONNECTS_LIKE_BLOCKS)
1067          {
1068             /* The response will violate the specs, but makes unblocking easier. */
1069             log_error(LOG_LEVEL_ERROR, "Marking suspicious CONNECT request from %s for blocking.",
1070                csp->ip_addr_str);
1071             csp->action->flags |= ACTION_BLOCK;
1072             http->ssl = 0;
1073          }
1074          else
1075          {
1076             strcpy(buf, CFORBIDDEN);
1077             write_socket(csp->cfd, buf, strlen(buf));
1078             log_error(LOG_LEVEL_CONNECT, "Denying suspicious CONNECT request from %s", csp->ip_addr_str);
1079             log_error(LOG_LEVEL_CLF, "%s - - [%T] \" \" 403 0", csp->ip_addr_str);
1080             return;
1081          }
1082       }
1083    }
1084
1085
1086    /*
1087     * Downgrade http version from 1.1 to 1.0 if +downgrade
1088     * action applies
1089     */
1090    if ( (http->ssl == 0)
1091      && (!strcmpic(http->ver, "HTTP/1.1"))
1092      && (csp->action->flags & ACTION_DOWNGRADE))
1093    {
1094       freez(http->ver);
1095       http->ver = strdup("HTTP/1.0");
1096
1097       if (http->ver == NULL)
1098       {
1099          log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
1100       }
1101    }
1102
1103    /* 
1104     * Save a copy of the original request for logging
1105     */
1106    http->ocmd = strdup(http->cmd);
1107
1108    if (http->ocmd == NULL)
1109    {
1110       log_error(LOG_LEVEL_FATAL, "Out of memory copying HTTP request line");
1111    }
1112
1113    /*
1114     * (Re)build the HTTP request for non-SSL requests.
1115     * If forwarding, use the whole URL, else, use only the path.
1116     */
1117    if (http->ssl == 0)
1118    {
1119       freez(http->cmd);
1120
1121       http->cmd = strdup(http->gpc);
1122       string_append(&http->cmd, " ");
1123
1124       if (fwd->forward_host)
1125       {
1126          string_append(&http->cmd, http->url);
1127       }
1128       else
1129       {
1130          string_append(&http->cmd, http->path);
1131       }
1132       string_append(&http->cmd, " ");
1133       string_append(&http->cmd, http->ver);
1134
1135       if (http->cmd == NULL)
1136       {
1137          log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
1138       }
1139       log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", http->cmd);
1140    }
1141    enlist(csp->headers, http->cmd);
1142
1143
1144    /*
1145     * If the user has not supplied any wafers, and the user has not
1146     * told us to suppress the vanilla wafer, then send the vanilla wafer.
1147     */
1148    if (list_is_empty(csp->action->multi[ACTION_MULTI_WAFER])
1149        && ((csp->action->flags & ACTION_VANILLA_WAFER) != 0))
1150    {
1151       enlist(csp->action->multi[ACTION_MULTI_WAFER], VANILLA_WAFER);
1152    }
1153
1154
1155 #ifdef FEATURE_KILL_POPUPS
1156    block_popups               = ((csp->action->flags & ACTION_NO_POPUPS) != 0);
1157 #endif /* def FEATURE_KILL_POPUPS */
1158
1159    pcrs_filter                = (csp->rlist != NULL) &&  /* There are expressions to be used */
1160                                 (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]));
1161
1162    gif_deanimate              = ((csp->action->flags & ACTION_DEANIMATE) != 0);
1163
1164    jpeg_inspect               = ((csp->action->flags & ACTION_JPEG_INSPECT) != 0);
1165
1166    /* grab the rest of the client's headers */
1167
1168    for (;;)
1169    {
1170       if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
1171       {
1172          len = read_socket(csp->cfd, buf, sizeof(buf));
1173          if (len <= 0)
1174          {
1175             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
1176             return;
1177          }
1178          
1179          /*
1180           * If there is no memory left for buffering the
1181           * request, there is nothing we can do but hang up
1182           */
1183          if (add_to_iob(csp, buf, len))
1184          {
1185             return;
1186          }
1187          continue;
1188       }
1189
1190       if (p == NULL) break;
1191
1192       enlist(csp->headers, p);
1193       freez(p);
1194    }
1195
1196    /*
1197     * We have a request. Now, check to see if we need to
1198     * intercept it, i.e. If ..
1199     */
1200
1201    if (
1202        /* We may not forward the request by rfc2616 sect 14.31 */
1203        (NULL != (rsp = direct_response(csp)))
1204
1205        /* or a CGI call was detected and answered */
1206        || (NULL != (rsp = dispatch_cgi(csp)))
1207
1208        /* or we are enabled and... */
1209        || (IS_ENABLED_AND (
1210
1211             /* ..the request was blocked */
1212           ( NULL != (rsp = block_url(csp)))
1213
1214           /* ..or untrusted */
1215 #ifdef FEATURE_TRUST
1216           || ( NULL != (rsp = trust_url(csp)))
1217 #endif /* def FEATURE_TRUST */
1218
1219           /* ..or a fast redirect kicked in */
1220 #ifdef FEATURE_FAST_REDIRECTS
1221           || (((csp->action->flags & ACTION_FAST_REDIRECTS) != 0) &&
1222                 (NULL != (rsp = redirect_url(csp))))
1223 #endif /* def FEATURE_FAST_REDIRECTS */
1224           ))
1225       )
1226    {
1227       /* Write the answer to the client */
1228       if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1229        || write_socket(csp->cfd, rsp->body, rsp->content_length))
1230       {
1231          log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1232       }
1233
1234 #ifdef FEATURE_STATISTICS
1235       /* Count as a rejected request */
1236       csp->flags |= CSP_FLAG_REJECTED;
1237 #endif /* def FEATURE_STATISTICS */
1238
1239       /* Log (FIXME: All intercept reasons appear as "crunch" with Status 200) */
1240       log_error(LOG_LEVEL_GPC, "%s%s crunch!", http->hostport, http->path);
1241       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 3", csp->ip_addr_str, http->ocmd);
1242
1243       /* Clean up and return */
1244       free_http_response(rsp);
1245       return;
1246    }
1247
1248    hdr = sed(client_patterns, add_client_headers, csp);
1249    if (hdr == NULL)
1250    {
1251       /* FIXME Should handle error properly */
1252       log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
1253    }
1254
1255    list_remove_all(csp->headers);
1256
1257    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
1258
1259    if (fwd->forward_host)
1260    {
1261       log_error(LOG_LEVEL_CONNECT, "via %s:%d to: %s",
1262                fwd->forward_host, fwd->forward_port, http->hostport);
1263    }
1264    else
1265    {
1266       log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
1267    }
1268
1269    /* here we connect to the server, gateway, or the forwarder */
1270
1271    while ( (csp->sfd = forwarded_connect(fwd, http, csp))
1272          && (errno == EINVAL) && (forwarded_connect_retries++ < max_forwarded_connect_retries))
1273    {
1274                 log_error(LOG_LEVEL_ERROR, "failed request #%u to connect to %s. Trying again.",
1275                 forwarded_connect_retries, http->hostport);
1276    }
1277
1278    if (csp->sfd == JB_INVALID_SOCKET)
1279    {
1280       log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E",
1281                 http->hostport);
1282
1283       if (errno == EINVAL)
1284       {
1285          rsp = error_response(csp, "no-such-domain", errno);
1286
1287          log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 404 0",
1288                    csp->ip_addr_str, http->ocmd);
1289       }
1290       else
1291       {
1292          rsp = error_response(csp, "connect-failed", errno);
1293
1294          log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
1295                    csp->ip_addr_str, http->ocmd);
1296       }
1297
1298
1299       /* Write the answer to the client */
1300       if(rsp)
1301       {
1302          if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1303           || write_socket(csp->cfd, rsp->body, rsp->content_length))
1304          {
1305             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1306          }
1307       }
1308
1309       free_http_response(rsp);
1310       freez(hdr);
1311       return;
1312    }
1313
1314    log_error(LOG_LEVEL_CONNECT, "OK");
1315
1316    if (fwd->forward_host || (http->ssl == 0))
1317    {
1318       /* write the client's (modified) header to the server
1319        * (along with anything else that may be in the buffer)
1320        */
1321
1322       if (write_socket(csp->sfd, hdr, strlen(hdr))
1323        || (flush_socket(csp->sfd, csp) <  0))
1324       {
1325          log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E",
1326                     http->hostport);
1327
1328          log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
1329                    csp->ip_addr_str, http->ocmd);
1330
1331          rsp = error_response(csp, "connect-failed", errno);
1332
1333          if(rsp)
1334          {
1335             if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1336              || write_socket(csp->cfd, rsp->body, rsp->content_length))
1337             {
1338                log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1339             }
1340          }
1341
1342          free_http_response(rsp);
1343          freez(hdr);
1344          return;
1345       }
1346    }
1347    else
1348    {
1349       /*
1350        * We're running an SSL tunnel and we're not forwarding,
1351        * so just send the "connect succeeded" message to the
1352        * client, flush the rest, and get out of the way.
1353        */
1354       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 2\n",
1355                 csp->ip_addr_str, http->ocmd);
1356
1357       if (write_socket(csp->cfd, CSUCCEED, sizeof(CSUCCEED)-1))
1358       {
1359          freez(hdr);
1360          return;
1361       }
1362       IOB_RESET(csp);
1363    }
1364
1365    /* we're finished with the client's header */
1366    freez(hdr);
1367
1368    maxfd = ( csp->cfd > csp->sfd ) ? csp->cfd : csp->sfd;
1369
1370    /* pass data between the client and server
1371     * until one or the other shuts down the connection.
1372     */
1373
1374    server_body = 0;
1375
1376    for (;;)
1377    {
1378 #ifdef __OS2__
1379       /*
1380        * FD_ZERO here seems to point to an errant macro which crashes.
1381        * So do this by hand for now...
1382        */
1383       memset(&rfds,0x00,sizeof(fd_set));
1384 #else
1385       FD_ZERO(&rfds);
1386 #endif
1387       FD_SET(csp->cfd, &rfds);
1388       FD_SET(csp->sfd, &rfds);
1389
1390       n = select((int)maxfd+1, &rfds, NULL, NULL, NULL);
1391
1392       if (n < 0)
1393       {
1394          log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
1395          return;
1396       }
1397
1398       /* this is the body of the browser's request
1399        * just read it and write it.
1400        */
1401
1402       if (FD_ISSET(csp->cfd, &rfds))
1403       {
1404          len = read_socket(csp->cfd, buf, sizeof(buf));
1405
1406          if (len <= 0)
1407          {
1408             break; /* "game over, man" */
1409          }
1410
1411          if (write_socket(csp->sfd, buf, (size_t)len))
1412          {
1413             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1414             return;
1415          }
1416          continue;
1417       }
1418
1419       /*
1420        * The server wants to talk.  It could be the header or the body.
1421        * If `hdr' is null, then it's the header otherwise it's the body.
1422        * FIXME: Does `hdr' really mean `host'? No.
1423        */
1424
1425
1426       if (FD_ISSET(csp->sfd, &rfds))
1427       {
1428          fflush( 0 );
1429          len = read_socket(csp->sfd, buf, sizeof(buf) - 1);
1430
1431          if (len < 0)
1432          {
1433             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
1434
1435             log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
1436                       csp->ip_addr_str, http->ocmd);
1437
1438             rsp = error_response(csp, "connect-failed", errno);
1439
1440             if(rsp)
1441             {
1442                if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1443                 || write_socket(csp->cfd, rsp->body, rsp->content_length))
1444                {
1445                   log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1446                }
1447             }
1448
1449             free_http_response(rsp);
1450             return;
1451          }
1452
1453          /* Add a trailing zero.  This lets filter_popups
1454           * use string operations.
1455           */
1456          buf[len] = '\0';
1457
1458 #ifdef FEATURE_KILL_POPUPS
1459          /* Filter the popups on this read. */
1460          if (block_popups_now)
1461          {
1462             filter_popups(buf, csp);
1463          }
1464 #endif /* def FEATURE_KILL_POPUPS */
1465
1466          /* Normally, this would indicate that we've read
1467           * as much as the server has sent us and we can
1468           * close the client connection.  However, Microsoft
1469           * in its wisdom has released IIS/5 with a bug that
1470           * prevents it from sending the trailing \r\n in
1471           * a 302 redirect header (and possibly other headers).
1472           * To work around this if we've haven't parsed
1473           * a full header we'll append a trailing \r\n
1474           * and see if this now generates a valid one.
1475           *
1476           * This hack shouldn't have any impacts.  If we've
1477           * already transmitted the header or if this is a
1478           * SSL connection, then we won't bother with this
1479           * hack.  So we only work on partially received
1480           * headers.  If we append a \r\n and this still
1481           * doesn't generate a valid header, then we won't
1482           * transmit anything to the client.
1483           */
1484          if (len == 0)
1485          {
1486
1487             if (server_body || http->ssl)
1488             {
1489                /*
1490                 * If we have been buffering up the document,
1491                 * now is the time to apply content modification
1492                 * and send the result to the client.
1493                 */
1494                if (content_filter)
1495                {
1496                   /*
1497                    * If the content filter fails, use the original
1498                    * buffer and length.
1499                    * (see p != NULL ? p : csp->iob->cur below)
1500                    */
1501                   if (NULL == (p = (*content_filter)(csp)))
1502                   {
1503                      csp->content_length = csp->iob->eod - csp->iob->cur;
1504                   }
1505
1506                   hdr = sed(server_patterns_light, NULL, csp);
1507
1508                   if (hdr == NULL)
1509                   {
1510                      /* FIXME Should handle error properly */
1511                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
1512                   }
1513
1514                   if (write_socket(csp->cfd, hdr, strlen(hdr))
1515                    || write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length))
1516                   {
1517                      log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
1518                      freez(hdr);
1519                      freez(p);
1520                      return;
1521                   }
1522
1523                   freez(hdr);
1524                   freez(p);
1525                }
1526
1527                break; /* "game over, man" */
1528             }
1529
1530             /*
1531              * This is NOT the body, so
1532              * Let's pretend the server just sent us a blank line.
1533              */
1534             len = sprintf(buf, "\r\n");
1535
1536             /*
1537              * Now, let the normal header parsing algorithm below do its
1538              * job.  If it fails, we'll exit instead of continuing.
1539              */
1540
1541             ms_iis5_hack = 1;
1542          }
1543
1544          /*
1545           * If this is an SSL connection or we're in the body
1546           * of the server document, just write it to the client,
1547           * unless we need to buffer the body for later content-filtering
1548           */
1549
1550          if (server_body || http->ssl)
1551          {
1552             if (content_filter)
1553             {
1554                /*
1555                 * If there is no memory left for buffering the content, or the buffer limit
1556                 * has been reached, switch to non-filtering mode, i.e. make & write the
1557                 * header, flush the iob and buf, and get out of the way.
1558                 */
1559                if (add_to_iob(csp, buf, len))
1560                {
1561                   size_t hdrlen;
1562                   int flushed;
1563
1564                   log_error(LOG_LEVEL_ERROR, "Flushing header and buffers. Stepping back from filtering.");
1565
1566                   hdr = sed(server_patterns, add_server_headers, csp);
1567                   if (hdr == NULL)
1568                   {
1569                      /* 
1570                       * Memory is too tight to even generate the header.
1571                       * Send our static "Out-of-memory" page.
1572                       */
1573                      log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
1574                      rsp = cgi_error_memory();
1575
1576                      if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1577                          || write_socket(csp->cfd, rsp->body, rsp->content_length))
1578                      {
1579                         log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1580                      }
1581                      return;
1582                   }
1583
1584                   hdrlen = strlen(hdr);
1585
1586                   if (write_socket(csp->cfd, hdr, hdrlen)
1587                    || ((flushed = flush_socket(csp->cfd, csp)) < 0)
1588                    || (write_socket(csp->cfd, buf, (size_t) len)))
1589                   {
1590                      log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E");
1591
1592                      freez(hdr);
1593                      return;
1594                   }
1595
1596                   byte_count += hdrlen + flushed + len;
1597                   freez(hdr);
1598                   content_filter = NULL;
1599                   server_body = 1;
1600
1601                }
1602             }
1603             else
1604             {
1605                if (write_socket(csp->cfd, buf, (size_t)len))
1606                {
1607                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
1608                   return;
1609                }
1610             }
1611             byte_count += len;
1612             continue;
1613          }
1614          else
1615          {
1616             /* we're still looking for the end of the
1617              * server's header ... (does that make header
1618              * parsing an "out of body experience" ?
1619              */
1620
1621             /* 
1622              * buffer up the data we just read.  If that fails, 
1623              * there's little we can do but send our static
1624              * out-of-memory page.
1625              */
1626             if (add_to_iob(csp, buf, len))
1627             {
1628                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
1629                rsp = cgi_error_memory();
1630                
1631                if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1632                    || write_socket(csp->cfd, rsp->body, rsp->content_length))
1633                {
1634                   log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
1635                }
1636                return;
1637             }
1638
1639             /* get header lines from the iob */
1640
1641             while ((p = get_header(csp)) != NULL)
1642             {
1643                if (*p == '\0')
1644                {
1645                   /* see following note */
1646                   break;
1647                }
1648                enlist(csp->headers, p);
1649                freez(p);
1650             }
1651
1652             /* NOTE: there are no "empty" headers so
1653              * if the pointer `p' is not NULL we must
1654              * assume that we reached the end of the
1655              * buffer before we hit the end of the header.
1656              */
1657
1658             if (p)
1659             {
1660                if (ms_iis5_hack)
1661                {
1662                   /* Well, we tried our MS IIS/5
1663                    * hack and it didn't work.
1664                    * The header is incomplete
1665                    * and there isn't anything
1666                    * we can do about it.
1667                    */
1668                   break;
1669                }
1670                else
1671                {
1672                   /* Since we have to wait for
1673                    * more from the server before
1674                    * we can parse the headers
1675                    * we just continue here.
1676                    */
1677                   continue;
1678                }
1679             }
1680
1681             /* we have now received the entire header.
1682              * filter it and send the result to the client
1683              */
1684
1685             hdr = sed(server_patterns, add_server_headers, csp);
1686             if (hdr == NULL)
1687             {
1688                /* FIXME Should handle error properly */
1689                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
1690             }
1691
1692 #ifdef FEATURE_KILL_POPUPS
1693             /* Start blocking popups if appropriate. */
1694
1695             if ((csp->content_type & CT_TEXT) &&  /* It's a text / * MIME-Type */
1696                 !http->ssl    &&                  /* We talk plaintext */
1697                 block_popups)                     /* Policy allows */
1698             {
1699                block_popups_now = 1;
1700                /*
1701                 * Filter the part of the body that came in the same read
1702                 * as the last headers:
1703                 */
1704                filter_popups(csp->iob->cur, csp);
1705             }
1706
1707 #endif /* def FEATURE_KILL_POPUPS */
1708
1709             /* Buffer and pcrs filter this if appropriate. */
1710
1711             if ((csp->content_type & CT_TEXT) &&  /* It's a text / * MIME-Type */
1712                 !http->ssl    &&                  /* We talk plaintext */
1713                 pcrs_filter)                      /* Policy allows */
1714             {
1715                content_filter = pcrs_filter_response;
1716             }
1717
1718             /* Buffer and gif_deanimate this if appropriate. */
1719
1720             if ((csp->content_type & CT_GIF)  &&  /* It's an image/gif MIME-Type */
1721                 !http->ssl    &&                  /* We talk plaintext */
1722                 gif_deanimate)                    /* Policy allows */
1723             {
1724                content_filter = gif_deanimate_response;
1725             }
1726
1727             /* Buffer and jpg_inspect this if appropriate. */
1728
1729             if ((csp->content_type & CT_JPEG)  &&  /* It's an image/jpeg MIME-Type */
1730                 !http->ssl    &&                   /* We talk plaintext */
1731                 jpeg_inspect)                      /* Policy allows */
1732             {
1733                content_filter = jpeg_inspect_response;
1734             }
1735
1736             /*
1737              * Only write if we're not buffering for content modification
1738              */
1739             if (!content_filter)
1740             {
1741                /* write the server's (modified) header to
1742                 * the client (along with anything else that
1743                 * may be in the buffer)
1744                 */
1745
1746                if (write_socket(csp->cfd, hdr, strlen(hdr))
1747                 || ((len = flush_socket(csp->cfd, csp)) < 0))
1748                {
1749                   log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
1750
1751                   /* the write failed, so don't bother
1752                    * mentioning it to the client...
1753                    * it probably can't hear us anyway.
1754                    */
1755                   freez(hdr);
1756                   return;
1757                }
1758
1759                byte_count += len;
1760             }
1761
1762             /* we're finished with the server's header */
1763
1764             freez(hdr);
1765             server_body = 1;
1766
1767             /* If this was a MS IIS/5 hack then it means
1768              * the server has already closed the
1769              * connection.  Nothing more to read.  Time
1770              * to bail.
1771              */
1772             if (ms_iis5_hack)
1773             {
1774                break;
1775             }
1776          }
1777          continue;
1778       }
1779
1780       return; /* huh? we should never get here */
1781    }
1782
1783    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %d",
1784              csp->ip_addr_str, http->ocmd, byte_count);
1785 }
1786
1787
1788 /*********************************************************************
1789  *
1790  * Function    :  serve
1791  *
1792  * Description :  This is little more than chat.  We only "serve" to
1793  *                to close any socket that chat may have opened.
1794  *
1795  * Parameters  :
1796  *          1  :  csp = Current client state (buffers, headers, etc...)
1797  *
1798  * Returns     :  N/A
1799  *
1800  *********************************************************************/
1801 #ifdef AMIGA
1802 void serve(struct client_state *csp)
1803 #else /* ifndef AMIGA */
1804 static void serve(struct client_state *csp)
1805 #endif /* def AMIGA */
1806 {
1807    chat(csp);
1808    close_socket(csp->cfd);
1809
1810    if (csp->sfd != JB_INVALID_SOCKET)
1811    {
1812       close_socket(csp->sfd);
1813    }
1814
1815    csp->flags &= ~CSP_FLAG_ACTIVE;
1816
1817 }
1818
1819
1820 #ifdef __BEOS__
1821 /*********************************************************************
1822  *
1823  * Function    :  server_thread
1824  *
1825  * Description :  We only exist to call `serve' in a threaded environment.
1826  *
1827  * Parameters  :
1828  *          1  :  data = Current client state (buffers, headers, etc...)
1829  *
1830  * Returns     :  Always 0.
1831  *
1832  *********************************************************************/
1833 static int32 server_thread(void *data)
1834 {
1835    serve((struct client_state *) data);
1836    return 0;
1837
1838 }
1839 #endif
1840
1841
1842 /*********************************************************************
1843  *
1844  * Function    :  usage
1845  *
1846  * Description :  Print usage info & exit.
1847  *
1848  * Parameters  :  Pointer to argv[0] for identifying ourselves
1849  *
1850  * Returns     :  No. ,-)
1851  *
1852  *********************************************************************/
1853 void usage(const char *myname)
1854 {
1855    printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
1856 #if !defined(unix)
1857            "Usage: %s [--help] [--version] [configfile]\n"
1858 #else
1859            "Usage: %s [--help] [--version] [--no-daemon] [--pidfile pidfile] [--user user[.group]] [configfile]\n"
1860 #endif
1861            "Aborting.\n", myname);
1862  
1863    exit(2);
1864
1865 }
1866
1867
1868 /*********************************************************************
1869  *
1870  * Function    :  main
1871  *
1872  * Description :  Load the config file and start the listen loop.
1873  *                This function is a lot more *sane* with the `load_config'
1874  *                and `listen_loop' functions; although it stills does
1875  *                a *little* too much for my taste.
1876  *
1877  * Parameters  :
1878  *          1  :  argc = Number of parameters (including $0).
1879  *          2  :  argv = Array of (char *)'s to the parameters.
1880  *
1881  * Returns     :  1 if : can't open config file, unrecognized directive,
1882  *                stats requested in multi-thread mode, can't open the
1883  *                log file, can't open the jar file, listen port is invalid,
1884  *                any load fails, and can't bind port.
1885  *
1886  *                Else main never returns, the process must be signaled
1887  *                to terminate execution.  Or, on Windows, use the
1888  *                "File", "Exit" menu option.
1889  *
1890  *********************************************************************/
1891 #ifdef __MINGW32__
1892 int real_main(int argc, const char *argv[])
1893 #else
1894 int main(int argc, const char *argv[])
1895 #endif
1896 {
1897    int argc_pos = 0;
1898 #ifdef HAVE_RANDOM
1899    unsigned int random_seed;
1900 #endif /* ifdef HAVE_RANDOM */
1901 #ifdef unix
1902    struct passwd *pw = NULL;
1903    struct group *grp = NULL;
1904    char *p;
1905    int do_chroot = 0;
1906 #endif
1907
1908    Argc = argc;
1909    Argv = argv;
1910
1911    configfile =
1912 #if !defined(_WIN32)
1913    "config"
1914 #else
1915    "config.txt"
1916 #endif
1917       ;
1918
1919    /*
1920     * Parse the command line arguments
1921     */
1922    while (++argc_pos < argc)
1923    {
1924 #ifdef _WIN32
1925       /* Check to see if the service must be installed or uninstalled */
1926       if (strncmp(argv[argc_pos], "--install", 9) == 0)
1927       {
1928          const char *pName = argv[argc_pos] + 9;
1929          if (*pName == ':')
1930             pName++;
1931          exit( (install_service(pName)) ? 0 : 1 );
1932       }
1933       else if (strncmp(argv[argc_pos], "--uninstall", + 11) == 0)
1934       {
1935          const char *pName = argv[argc_pos] + 11;
1936          if (*pName == ':')
1937             pName++;
1938          exit((uninstall_service(pName)) ? 0 : 1);
1939       }
1940       else if (strcmp(argv[argc_pos], "--service" ) == 0)
1941       {
1942          bRunAsService = TRUE;
1943          w32_set_service_cwd();
1944          atexit(w32_service_exit_notify);
1945       }
1946       else
1947 #endif /* defined(_WIN32) */
1948
1949
1950 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
1951
1952       if (strcmp(argv[argc_pos], "--help") == 0)
1953       {
1954          usage(argv[0]);
1955       }
1956
1957       else if(strcmp(argv[argc_pos], "--version") == 0)
1958       {
1959          printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
1960          exit(0);
1961       }
1962
1963 #if defined(unix)
1964
1965      else if (strcmp(argv[argc_pos], "--no-daemon" ) == 0)
1966       {
1967          no_daemon = 1;
1968       }
1969
1970       else if (strcmp(argv[argc_pos], "--pidfile" ) == 0)
1971       {
1972          if (++argc_pos == argc) usage(argv[0]);
1973          pidfile = strdup(argv[argc_pos]);
1974       }
1975
1976       else if (strcmp(argv[argc_pos], "--user" ) == 0)
1977       {
1978          if (++argc_pos == argc) usage(argv[argc_pos]);
1979
1980          if ((NULL != (p = strchr(argv[argc_pos], '.'))) && *(p + 1) != '0')
1981          {
1982             *p++ = '\0';
1983             if (NULL == (grp = getgrnam(p)))
1984             {
1985                log_error(LOG_LEVEL_FATAL, "Group %s not found.", p);
1986             }
1987          }
1988
1989          if (NULL == (pw = getpwnam(argv[argc_pos])))
1990          {
1991             log_error(LOG_LEVEL_FATAL, "User %s not found.", argv[argc_pos]);
1992          }
1993
1994          if (p != NULL) *--p = '\0';
1995       }
1996
1997       else if (strcmp(argv[argc_pos], "--chroot" ) == 0)
1998       {
1999          do_chroot = 1;
2000       }
2001
2002 #endif /* defined(unix) */
2003 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
2004       {
2005          configfile = argv[argc_pos];
2006       }
2007
2008    } /* -END- while (more arguments) */
2009
2010 #if defined(unix)
2011    if ( *configfile != '/' )
2012    {
2013       char *abs_file, cwd[1024];
2014
2015       /* make config-filename absolute here */
2016       if ( !(getcwd(cwd, sizeof(cwd))))
2017       {
2018          perror("get working dir failed");
2019          exit( 1 );
2020       }
2021
2022       if (!(basedir = strdup(cwd))
2023       || (!(abs_file = malloc( strlen( basedir ) + strlen( configfile ) + 5 ))))
2024       {
2025          perror("malloc failed");
2026          exit( 1 );
2027       }
2028       strcpy( abs_file, basedir );
2029       strcat( abs_file, "/" );
2030       strcat( abs_file, configfile );
2031       configfile = abs_file;
2032    }
2033 #endif /* defined unix */
2034
2035
2036    files->next = NULL;
2037    clients->next = NULL;
2038
2039 #ifdef AMIGA
2040    InitAmiga();
2041 #elif defined(_WIN32)
2042    InitWin32();
2043 #endif
2044
2045 #if defined(OSX_DARWIN) || defined(__OpenBSD__)
2046    /*
2047     * Prepare global mutex semaphores
2048     */
2049 #ifdef OSX_DARWIN
2050    pthread_mutex_init(&gmtime_mutex,0);
2051    pthread_mutex_init(&localtime_mutex,0);
2052 #endif /* def OSX_DARWIN */
2053    pthread_mutex_init(&gethostbyaddr_mutex,0);
2054    pthread_mutex_init(&gethostbyname_mutex,0);
2055 #endif /* defined(OSX_DARWIN) || defined(__OpenBSD__) */
2056
2057 #ifdef FEATURE_PTHREAD
2058    pthread_mutex_init(&log_mutex,0);
2059    pthread_mutex_init(&log_init_mutex,0);
2060 #endif /* FEATURE_PTHREAD */
2061
2062 #ifdef HAVE_RANDOM
2063    random_seed = (unsigned int)time(NULL);
2064    srandom(random_seed);
2065 #endif /* ifdef HAVE_RANDOM */
2066
2067    /*
2068     * Unix signal handling
2069     *
2070     * Catch the abort, interrupt and terminate signals for a graceful exit
2071     * Catch the hangup signal so the errlog can be reopened.
2072     * Ignore the broken pipe signals (FIXME: Why?)
2073     */
2074 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
2075 {
2076    int idx;
2077    const int catched_signals[] = { SIGABRT, SIGTERM, SIGINT, SIGHUP, 0 };
2078    const int ignored_signals[] = { SIGPIPE, 0 };
2079
2080    for (idx = 0; catched_signals[idx] != 0; idx++)
2081    {
2082       if (signal(catched_signals[idx], sig_handler) == SIG_ERR)
2083       {
2084          log_error(LOG_LEVEL_FATAL, "Can't set signal-handler for signal %d: %E", catched_signals[idx]);
2085       }
2086    }
2087
2088    for (idx = 0; ignored_signals[idx] != 0; idx++)
2089    {
2090       if (signal(ignored_signals[idx], SIG_IGN) == SIG_ERR)
2091       {
2092          log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for signal %d: %E", ignored_signals[idx]);
2093       }
2094    }
2095
2096 }
2097 #else /* ifdef _WIN32 */
2098 # ifdef _WIN_CONSOLE
2099    /*
2100     * We *are* in a windows console app.
2101     * Print a verbose messages about FAQ's and such
2102     */
2103    printf(win32_blurb);
2104 # endif /* def _WIN_CONSOLE */
2105 #endif /* def _WIN32 */
2106
2107
2108    /* Initialize the CGI subsystem */
2109    cgi_init_error_messages();
2110
2111    /*
2112     * If runnig on unix and without the --nodaemon
2113     * option, become a daemon. I.e. fork, detach
2114     * from tty and get process group leadership
2115     */
2116 #if defined(unix)
2117 {
2118    pid_t pid = 0;
2119 #if 0
2120    int   fd;
2121 #endif
2122
2123    if (!no_daemon)
2124    {
2125       pid  = fork();
2126
2127       if ( pid < 0 ) /* error */
2128       {
2129          perror("fork");
2130          exit( 3 );
2131       }
2132       else if ( pid != 0 ) /* parent */
2133       {
2134          int status;
2135          pid_t wpid;
2136          /*
2137           * must check for errors
2138           * child died due to missing files aso
2139           */
2140          sleep( 1 );
2141          wpid = waitpid( pid, &status, WNOHANG );
2142          if ( wpid != 0 )
2143          {
2144             exit( 1 );
2145          }
2146          exit( 0 );
2147       }
2148       /* child */
2149 #if 1
2150       /* Should be more portable, but not as well tested */
2151       setsid();
2152 #else /* !1 */
2153 #ifdef __FreeBSD__
2154       setpgrp(0,0);
2155 #else /* ndef __FreeBSD__ */
2156       setpgrp();
2157 #endif /* ndef __FreeBSD__ */
2158       fd = open("/dev/tty", O_RDONLY);
2159       if ( fd )
2160       {
2161          /* no error check here */
2162          ioctl( fd, TIOCNOTTY,0 );
2163          close ( fd );
2164       }
2165 #endif /* 1 */
2166       /* FIXME: should close stderr (fd 2) here too, but the test
2167        * for existence
2168        * and load config file is done in listen_loop() and puts
2169        * some messages on stderr there.
2170        */
2171
2172       close( 0 );
2173       close( 1 );
2174       chdir("/");
2175
2176    } /* -END- if (!no_daemon) */
2177
2178    /*
2179     * As soon as we have written the PID file, we can switch
2180     * to the user and group ID indicated by the --user option
2181     */
2182    write_pid_file();
2183    
2184    if (NULL != pw)
2185    {
2186       if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid))
2187       {
2188          log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
2189       }
2190       if (do_chroot)
2191       {
2192          if (!pw->pw_dir)
2193          {
2194             log_error(LOG_LEVEL_FATAL, "Home directory for %s undefined", pw->pw_name);
2195          }
2196          if (chroot(pw->pw_dir) < 0)
2197          {
2198             log_error(LOG_LEVEL_FATAL, "Cannot chroot to %s", pw->pw_dir);
2199          }
2200          if (chdir ("/"))
2201          {
2202             log_error(LOG_LEVEL_FATAL, "Cannot chdir /");
2203          }
2204       }
2205       if (setuid(pw->pw_uid))
2206       {
2207          log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
2208       }
2209       if (do_chroot)
2210       {
2211          char putenv_dummy[64];
2212
2213          strcpy(putenv_dummy, "HOME=/");
2214          if (putenv(putenv_dummy) != 0)
2215          {
2216             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): HOME");
2217          }                
2218
2219          snprintf(putenv_dummy, 64, "USER=%s", pw->pw_name);
2220          if (putenv(putenv_dummy) != 0)
2221          {
2222             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): USER");
2223          }
2224       }
2225    }
2226    else if (do_chroot)
2227    {
2228       log_error(LOG_LEVEL_FATAL, "Cannot chroot without --user argument.");
2229    }
2230 }
2231 #endif /* defined unix */
2232
2233 #ifdef _WIN32
2234    /* This will be FALSE unless the command line specified --service
2235     */
2236    if (bRunAsService)
2237    {
2238       /* Yup, so now we must attempt to establish a connection 
2239        * with the service dispatcher. This will only work if this
2240        * process was launched by the service control manager to
2241        * actually run as a service. If this isn't the case, i've
2242        * known it take around 30 seconds or so for the call to return.
2243        */
2244
2245       /* The StartServiceCtrlDispatcher won't return until the service is stopping */
2246       if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable))
2247       {
2248          /* Service has run, and at this point is now being stopped, so just return */
2249          return 0;
2250       }
2251
2252 #ifdef _WIN_CONSOLE
2253       printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n");
2254 #endif
2255       /* An error occurred. Usually it's because --service was wrongly specified
2256        * and we were unable to connect to the Service Control Dispatcher because
2257        * it wasn't expecting us and is therefore not listening.
2258        *
2259        * For now, just continue below to call the listen_loop function.
2260        */
2261    }
2262 #endif /* def _WIN32 */
2263
2264    listen_loop();
2265
2266    /* NOTREACHED */
2267    return(-1);
2268
2269 }
2270
2271
2272 /*********************************************************************
2273  *
2274  * Function    :  bind_port_helper
2275  *
2276  * Description :  Bind the listen port.  Handles logging, and aborts
2277  *                on failure.
2278  *
2279  * Parameters  :
2280  *          1  :  config = Privoxy configuration.  Specifies port
2281  *                         to bind to.
2282  *
2283  * Returns     :  Port that was opened.
2284  *
2285  *********************************************************************/
2286 static jb_socket bind_port_helper(struct configuration_spec * config)
2287 {
2288    int result;
2289    jb_socket bfd;
2290
2291    if ( (config->haddr != NULL)
2292      && (config->haddr[0] == '1')
2293      && (config->haddr[1] == '2')
2294      && (config->haddr[2] == '7')
2295      && (config->haddr[3] == '.') )
2296    {
2297       log_error(LOG_LEVEL_INFO, "Listening on port %d for local connections only",
2298                 config->hport);
2299    }
2300    else if (config->haddr == NULL)
2301    {
2302       log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
2303                 config->hport);
2304    }
2305    else
2306    {
2307       log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
2308                 config->hport, config->haddr);
2309    }
2310
2311    result = bind_port(config->haddr, config->hport, &bfd);
2312
2313    if (result < 0)
2314    {
2315       switch(result)
2316       {
2317          case -3 :
2318             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: "
2319                "There may be another Privoxy or some other "
2320                "proxy running on port %d",
2321                (NULL != config->haddr) ? config->haddr : "INADDR_ANY",
2322                       config->hport, config->hport);
2323
2324          case -2 :
2325             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: " 
2326                "The hostname is not resolvable",
2327                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
2328
2329          default :
2330             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E",
2331                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
2332       }
2333
2334       /* shouldn't get here */
2335       return JB_INVALID_SOCKET;
2336    }
2337
2338    config->need_bind = 0;
2339
2340    return bfd;
2341 }
2342
2343
2344 #ifdef _WIN32
2345 /* Without this simple workaround we get this compiler warning from _beginthread
2346  *     warning C4028: formal parameter 1 different from declaration
2347  */
2348 void w32_service_listen_loop(void *p)
2349 {
2350    listen_loop();
2351 }
2352 #endif /* def _WIN32 */
2353
2354
2355 /*********************************************************************
2356  *
2357  * Function    :  listen_loop
2358  *
2359  * Description :  bind the listen port and enter a "FOREVER" listening loop.
2360  *
2361  * Parameters  :  N/A
2362  *
2363  * Returns     :  Never.
2364  *
2365  *********************************************************************/
2366 static void listen_loop(void)
2367 {
2368    struct client_state *csp = NULL;
2369    jb_socket bfd;
2370    struct configuration_spec * config;
2371
2372    config = load_config();
2373
2374    bfd = bind_port_helper(config);
2375
2376 #ifdef FEATURE_GRACEFUL_TERMINATION
2377    while (!g_terminate)
2378 #else
2379    for (;;)
2380 #endif
2381    {
2382 #if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
2383       while (waitpid(-1, NULL, WNOHANG) > 0)
2384       {
2385          /* zombie children */
2386       }
2387 #endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
2388
2389       /*
2390        * Free data that was used by died threads
2391        */
2392       sweep();
2393
2394 #if defined(unix)
2395       /*
2396        * Re-open the errlog after HUP signal
2397        */
2398       if (received_hup_signal)
2399       {
2400          init_error_log(Argv[0], config->logfile, config->debug);
2401          received_hup_signal = 0;
2402       }
2403 #endif
2404
2405 #ifdef __OS2__
2406 #ifdef FEATURE_COOKIE_JAR
2407       /*
2408        * Need a workaround here: we have to fclose() the jarfile, or we die because it's
2409        * already open.  I think unload_configfile() is not being run, which should do
2410        * this work.  Until that can get resolved, we'll use this workaround.
2411        */
2412        if (csp)
2413          if(csp->config)
2414            if (csp->config->jar)
2415            {
2416              fclose(csp->config->jar);
2417              csp->config->jar = NULL;
2418            }
2419 #endif /* FEATURE_COOKIE_JAR */
2420 #endif /* __OS2__ */
2421
2422       if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
2423       {
2424          log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
2425          continue;
2426       }
2427
2428       csp->flags |= CSP_FLAG_ACTIVE;
2429       csp->sfd    = JB_INVALID_SOCKET;
2430
2431       csp->config = config = load_config();
2432
2433       if ( config->need_bind )
2434       {
2435          /*
2436           * Since we were listening to the "old port", we will not see
2437           * a "listen" param change until the next IJB request.  So, at
2438           * least 1 more request must be made for us to find the new
2439           * setting.  I am simply closing the old socket and binding the
2440           * new one.
2441           *
2442           * Which-ever is correct, we will serve 1 more page via the
2443           * old settings.  This should probably be a "show-proxy-args"
2444           * request.  This should not be a so common of an operation
2445           * that this will hurt people's feelings.
2446           */
2447
2448          close_socket(bfd);
2449
2450          bfd = bind_port_helper(config);
2451       }
2452
2453       log_error(LOG_LEVEL_CONNECT, "accept connection ... ");
2454
2455       if (!accept_connection(csp, bfd))
2456       {
2457          log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
2458
2459 #ifdef AMIGA
2460          if(!childs)
2461          {
2462             exit(1);
2463          }
2464 #endif
2465          freez(csp);
2466          continue;
2467       }
2468       else
2469       {
2470          log_error(LOG_LEVEL_CONNECT, "OK");
2471       }
2472
2473 #ifdef FEATURE_TOGGLE
2474       if (global_toggle_state)
2475       {
2476          csp->flags |= CSP_FLAG_TOGGLED_ON;
2477       }
2478 #endif /* def FEATURE_TOGGLE */
2479
2480       if (run_loader(csp))
2481       {
2482          log_error(LOG_LEVEL_FATAL, "a loader failed - must exit");
2483          /* Never get here - LOG_LEVEL_FATAL causes program exit */
2484       }
2485
2486 #ifdef FEATURE_ACL
2487       if (block_acl(NULL,csp))
2488       {
2489          log_error(LOG_LEVEL_CONNECT, "Connection dropped due to ACL");
2490          close_socket(csp->cfd);
2491          freez(csp);
2492          continue;
2493       }
2494 #endif /* def FEATURE_ACL */
2495
2496       /* add it to the list of clients */
2497       csp->next = clients->next;
2498       clients->next = csp;
2499
2500       if (config->multi_threaded)
2501       {
2502          int child_id;
2503
2504 /* this is a switch () statment in the C preprocessor - ugh */
2505 #undef SELECTED_ONE_OPTION
2506
2507 /* Use Pthreads in preference to native code */
2508 #if defined(FEATURE_PTHREAD) && !defined(SELECTED_ONE_OPTION)
2509 #define SELECTED_ONE_OPTION
2510          {
2511             pthread_t the_thread;
2512             pthread_attr_t attrs;
2513
2514             pthread_attr_init(&attrs);
2515             pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
2516             errno = pthread_create(&the_thread, &attrs,
2517                (void*)serve, csp);
2518             child_id = errno ? -1 : 0;
2519             pthread_attr_destroy(&attrs);
2520          }
2521 #endif
2522
2523 #if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
2524 #define SELECTED_ONE_OPTION
2525          child_id = _beginthread(
2526             (void (*)(void *))serve,
2527             64 * 1024,
2528             csp);
2529 #endif
2530
2531 #if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
2532 #define SELECTED_ONE_OPTION
2533          child_id = _beginthread(
2534             (void(* _Optlink)(void*))serve,
2535             NULL,
2536             64 * 1024,
2537             csp);
2538 #endif
2539
2540 #if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION)
2541 #define SELECTED_ONE_OPTION
2542          {
2543             thread_id tid = spawn_thread
2544                (server_thread, "server", B_NORMAL_PRIORITY, csp);
2545
2546             if ((tid >= 0) && (resume_thread(tid) == B_OK))
2547             {
2548                child_id = (int) tid;
2549             }
2550             else
2551             {
2552                child_id = -1;
2553             }
2554          }
2555 #endif
2556
2557 #if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
2558 #define SELECTED_ONE_OPTION
2559          csp->cfd = ReleaseSocket(csp->cfd, -1);
2560          
2561          if((child_id = (int)CreateNewProcTags(
2562             NP_Entry, (ULONG)server_thread,
2563             NP_Output, Output(),
2564             NP_CloseOutput, FALSE,
2565             NP_Name, (ULONG)"privoxy child",
2566             NP_StackSize, 200*1024,
2567             TAG_DONE)))
2568          {
2569             childs++;
2570             ((struct Task *)child_id)->tc_UserData = csp;
2571             Signal((struct Task *)child_id, SIGF_SINGLE);
2572             Wait(SIGF_SINGLE);
2573          }
2574 #endif
2575
2576 #if !defined(SELECTED_ONE_OPTION)
2577          child_id = fork();
2578
2579          /* This block is only needed when using fork().
2580           * When using threads, the server thread was
2581           * created and run by the call to _beginthread().
2582           */
2583          if (child_id == 0)   /* child */
2584          {
2585             int rc = 0;
2586 #ifdef FEATURE_TOGGLE
2587             int inherited_toggle_state = global_toggle_state;
2588 #endif /* def FEATURE_TOGGLE */
2589
2590             serve(csp);
2591
2592             /* 
2593              * If we've been toggled or we've blocked the request, tell Mom
2594              */
2595
2596 #ifdef FEATURE_TOGGLE
2597             if (inherited_toggle_state != global_toggle_state)
2598             {
2599                rc |= RC_FLAG_TOGGLED;
2600             }
2601 #endif /* def FEATURE_TOGGLE */
2602
2603 #ifdef FEATURE_STATISTICS  
2604             if (csp->flags & CSP_FLAG_REJECTED)
2605             {
2606                rc |= RC_FLAG_BLOCKED;
2607             }
2608 #endif /* ndef FEATURE_STATISTICS */
2609
2610             _exit(rc);
2611          }
2612          else if (child_id > 0) /* parent */
2613          {
2614             /* in a fork()'d environment, the parent's
2615              * copy of the client socket and the CSP
2616              * are not used.
2617              */
2618             int child_status;
2619 #if !defined(_WIN32) && !defined(__CYGWIN__)
2620
2621             wait( &child_status );
2622
2623             /* 
2624              * Evaluate child's return code: If the child has
2625              *  - been toggled, toggle ourselves
2626              *  - blocked its request, bump up the stats counter
2627              */
2628
2629 #ifdef FEATURE_TOGGLE
2630             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_TOGGLED))
2631             {
2632                global_toggle_state = !global_toggle_state;
2633             }
2634 #endif /* def FEATURE_TOGGLE */
2635
2636 #ifdef FEATURE_STATISTICS
2637             urls_read++;
2638             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_BLOCKED))
2639             {
2640                urls_rejected++;
2641             }
2642 #endif /* def FEATURE_STATISTICS */ 
2643
2644 #endif /* !defined(_WIN32) && defined(__CYGWIN__) */
2645             close_socket(csp->cfd);
2646             csp->flags &= ~CSP_FLAG_ACTIVE;
2647          }
2648 #endif
2649
2650 #undef SELECTED_ONE_OPTION
2651 /* end of cpp switch () */
2652
2653          if (child_id < 0) /* failed */
2654          {
2655             char buf[BUFFER_SIZE];
2656
2657             log_error(LOG_LEVEL_ERROR, "can't fork: %E");
2658
2659             sprintf(buf , "Privoxy: can't fork: errno = %d", errno);
2660
2661             write_socket(csp->cfd, buf, strlen(buf));
2662             close_socket(csp->cfd);
2663             csp->flags &= ~CSP_FLAG_ACTIVE;
2664             sleep(5);
2665             continue;
2666          }
2667       }
2668       else
2669       {
2670          serve(csp);
2671       }
2672    }
2673
2674    /* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
2675
2676    /* Clean up.  Aim: free all memory (no leaks) */
2677 #ifdef FEATURE_GRACEFUL_TERMINATION
2678
2679    log_error(LOG_LEVEL_ERROR, "Graceful termination requested");
2680
2681    unload_current_config_file();
2682    unload_current_actions_file();
2683    unload_current_re_filterfile();
2684 #ifdef FEATURE_TRUST
2685    unload_current_trust_file();
2686 #endif
2687
2688    if (config->multi_threaded)
2689    {
2690       int i = 60;
2691       do
2692       {
2693          sleep(1);
2694          sweep();
2695       } while ((clients->next != NULL) && (--i > 0));
2696
2697       if (i <= 0)
2698       {
2699          log_error(LOG_LEVEL_ERROR, "Graceful termination failed - still some live clients after 1 minute wait.");
2700       }
2701    }
2702    sweep();
2703    sweep();
2704
2705 #if defined(unix)
2706    freez(basedir);
2707 #endif
2708    freez(configfile);
2709
2710 #ifdef FEATURE_COOKIE_JAR
2711    if (NULL != config->jar)
2712    {
2713       fclose(config->jar);
2714    }
2715 #endif
2716
2717 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
2718    /* Cleanup - remove taskbar icon etc. */
2719    TermLogWindow();
2720 #endif
2721
2722    exit(0);
2723 #endif /* FEATURE_GRACEFUL_TERMINATION */
2724
2725 }
2726
2727
2728 /*
2729   Local Variables:
2730   tab-width: 3
2731   end:
2732 */