5991a72dc704a8068242881b3ceaeb74f56d665a
[privoxy.git] / jcc.c
1 const char jcc_rcs[] = "$Id: jcc.c,v 1.245 2009/04/24 15:29:43 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-2009 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.245  2009/04/24 15:29:43  fabiankeil
37  *    Allow to limit the number of of client connections.
38  *
39  *    Revision 1.244  2009/04/17 11:34:34  fabiankeil
40  *    Style cosmetics for the IPv6 code.
41  *
42  *    Revision 1.243  2009/04/17 11:27:49  fabiankeil
43  *    Petr Pisar's privoxy-3.0.12-ipv6-3.diff.
44  *
45  *    Revision 1.242  2009/04/11 10:44:47  fabiankeil
46  *    Update a comment. We're not in Kansas anymore.
47  *
48  *    Revision 1.241  2009/04/11 10:37:23  fabiankeil
49  *    When dropping connections due to ACL, don't leak csp->ip_addr_str.
50  *
51  *    Revision 1.240  2009/04/09 10:12:54  fabiankeil
52  *    Fix two cases in which an invalid server response would result
53  *    in the client connection being closed without sending an error
54  *    message first.
55  *
56  *    Revision 1.239  2009/04/07 11:43:50  fabiankeil
57  *    If the server rudely resets the connection directly after sending the
58  *    headers, pass the mess to the client instead of sending an incorrect
59  *    connect-failed message. Fixes #2698674 reported by mybugaccount.
60  *
61  *    Revision 1.238  2009/03/27 14:42:30  fabiankeil
62  *    Correct the status code for CONNECTION_TIMEOUT_RESPONSE.
63  *
64  *    Revision 1.237  2009/03/27 14:32:04  fabiankeil
65  *    If spawning a child in listen_loop() fails, send a real
66  *    HTTP response to the client and continue listening for
67  *    new connections without artificial delay.
68  *
69  *    Revision 1.236  2009/03/25 17:30:24  fabiankeil
70  *    In serve(), keep the client socket open until we marked the
71  *    server socket as unused. This should increase the chances
72  *    that we reuse the connection for the client's next request
73  *    to the same destination.
74  *
75  *    Revision 1.235  2009/03/18 21:01:20  fabiankeil
76  *    Comment fix. Spotted by Roland.
77  *
78  *    Revision 1.234  2009/03/18 20:48:42  fabiankeil
79  *    If the --no-daemon option is used, enable LOG_LEVEL_INFO
80  *    before the config file has been parsed (as we always did).
81  *
82  *    Revision 1.233  2009/03/13 14:10:07  fabiankeil
83  *    Fix some more harmless warnings on amd64.
84  *
85  *    Revision 1.232  2009/03/08 19:29:16  fabiankeil
86  *    Reinitialize the timeout structure every time before passing
87  *    it to select(). Apparently some implementations mess with it.
88  *    Probably fixes #2669131 reported by cyberpatrol.
89  *
90  *    Revision 1.231  2009/03/08 14:19:23  fabiankeil
91  *    Fix justified (but harmless) compiler warnings
92  *    on platforms where sizeof(int) < sizeof(long).
93  *
94  *    Revision 1.230  2009/03/07 13:09:17  fabiankeil
95  *    Change csp->expected_content and_csp->expected_content_length from
96  *    size_t to unsigned long long to reduce the likelihood of integer
97  *    overflows that would let us close the connection prematurely.
98  *    Bug found while investigating #2669131, reported by cyberpatrol.
99  *
100  *    Revision 1.229  2009/03/07 11:17:01  fabiankeil
101  *    Fix compiler warning.
102  *
103  *    Revision 1.228  2009/03/06 20:30:13  fabiankeil
104  *    Log unsigned values as such.
105  *
106  *    Revision 1.227  2009/03/02 19:18:11  fabiankeil
107  *    Streamline parse_http_request()'s prototype. As
108  *    cparser pointed out it doesn't actually use csp.
109  *
110  *    Revision 1.226  2009/03/01 18:28:24  fabiankeil
111  *    Help clang understand that we aren't dereferencing
112  *    NULL pointers here.
113  *
114  *    Revision 1.225  2009/02/19 18:09:32  fabiankeil
115  *    Unbreak build without FEATURE_CONNECTION_KEEP_ALIVE.
116  *    Noticed by David.
117  *
118  *    Revision 1.224  2009/02/14 15:32:04  fabiankeil
119  *    Add the request URL to the timeout message in chat().
120  *    Suggested by Lee.
121  *
122  *    Revision 1.223  2009/02/09 21:21:16  fabiankeil
123  *    Now that init_log_module() is called earlier, call show_version()
124  *    later on from main() directly so it doesn't get called for --help
125  *    or --version.
126  *
127  *    Revision 1.222  2009/02/08 12:56:51  fabiankeil
128  *    Call initialize_mutexes() before init_log_module() again.
129  *    Broken since r220, might be the cause of Lee's #2579448.
130  *
131  *    Revision 1.221  2009/02/06 18:02:58  fabiankeil
132  *    When dropping privileges, also give up membership in supplementary
133  *    groups. Thanks to Matthias Drochner for reporting the problem,
134  *    providing the initial patch and testing the final version.
135  *
136  *    Revision 1.220  2009/02/04 18:29:07  fabiankeil
137  *    Initialize the log module before parsing arguments.
138  *    Thanks to Matthias Drochner for the report.
139  *
140  *    Revision 1.219  2009/01/31 16:08:21  fabiankeil
141  *    Remove redundant error check in receive_client_request().
142  *
143  *    Revision 1.218  2009/01/31 12:25:54  fabiankeil
144  *    Flatten indentation in receive_client_request().
145  *
146  *    Revision 1.217  2009/01/07 19:50:09  fabiankeil
147  *    - If the socket-timeout has been reached and the client
148  *      hasn't received any data yet, send an explanation before
149  *      closing the connection.
150  *    - In get_request_line(), signal timeouts the right way.
151  *
152  *    Revision 1.216  2008/12/24 22:13:11  ler762
153  *    fix GCC 3.4.4 warning
154  *
155  *    Revision 1.215  2008/12/24 17:06:19  fabiankeil
156  *    Keep a thread around to timeout alive connections
157  *    even if no new requests are coming in.
158  *
159  *    Revision 1.214  2008/12/20 14:53:55  fabiankeil
160  *    Add config option socket-timeout to control the time
161  *    Privoxy waits for data to arrive on a socket. Useful
162  *    in case of stale ssh tunnels or when fuzz-testing.
163  *
164  *    Revision 1.213  2008/12/15 18:45:51  fabiankeil
165  *    When logging crunches, log the whole URL, so one can easily
166  *    differentiate between vanilla HTTP and CONNECT requests.
167  *
168  *    Revision 1.212  2008/12/14 15:46:22  fabiankeil
169  *    Give crunched requests their own log level.
170  *
171  *    Revision 1.211  2008/12/06 10:05:03  fabiankeil
172  *    Downgrade "Received x bytes while expecting y." message to
173  *    LOG_LEVEL_CONNECT as it doesn't necessarily indicate an error.
174  *
175  *    Revision 1.210  2008/12/02 22:03:18  fabiankeil
176  *    Don't miscalculate byte_count if we don't get all the
177  *    server headers with one read_socket() call. With keep-alive
178  *    support enabled, this caused delays until the server closed
179  *    the connection.
180  *
181  *    Revision 1.209  2008/11/27 09:44:04  fabiankeil
182  *    Cosmetics for the last commit: Don't watch out for
183  *    the last chunk if the content isn't chunk-encoded or
184  *    if we already determined the content length previously.
185  *
186  *    Revision 1.208  2008/11/26 18:24:17  fabiankeil
187  *    Recognize that the server response is complete if the
188  *    last chunk is read together with the server headers.
189  *    Reported by Lee.
190  *
191  *    Revision 1.207  2008/11/25 17:25:16  fabiankeil
192  *    Don't convert the client-header list to text until we need to.
193  *
194  *    Revision 1.206  2008/11/23 17:00:11  fabiankeil
195  *    Some more chat() cosmetics.
196  *
197  *    Revision 1.205  2008/11/16 12:43:49  fabiankeil
198  *    Turn keep-alive support into a runtime feature
199  *    that is disabled by setting keep-alive-timeout
200  *    to a negative value.
201  *
202  *    Revision 1.204  2008/11/06 19:42:17  fabiankeil
203  *    Fix last-chunk detection hack to also apply
204  *    if buf[] contains nothing but the last-chunk.
205  *
206  *    Revision 1.203  2008/11/06 18:34:35  fabiankeil
207  *    Factor receive_client_request() and
208  *    parse_client_request() out of chat().
209  *
210  *    Revision 1.202  2008/11/02 18:40:34  fabiankeil
211  *    If we received a different amount of data than we expected,
212  *    log a warning and make sure the server socket isn't reused.
213  *
214  *    Revision 1.201  2008/11/02 16:48:20  fabiankeil
215  *    Revert revision 1.195 and try again.
216  *
217  *    Revision 1.200  2008/10/26 16:53:18  fabiankeil
218  *    Fix gcc44 warning.
219  *
220  *    Revision 1.199  2008/10/26 15:36:10  fabiankeil
221  *    Remove two debug messages with LOG_LEVEL_INFO.
222  *
223  *    Revision 1.198  2008/10/22 15:19:55  fabiankeil
224  *    Once More, With Feeling: if there is no logfile
225  *    because the user didn't specify one, we shouldn't
226  *    call init_error_log() after receiving SIGHUP either.
227  *
228  *    Revision 1.197  2008/10/20 17:02:40  fabiankeil
229  *    If SIGHUP is received while we aren't running in daemon
230  *    mode, calling init_error_log() would be a mistake.
231  *
232  *    Revision 1.196  2008/10/16 09:16:41  fabiankeil
233  *    - Fix two gcc44 conversion warnings.
234  *    - Don't bother logging the last five bytes
235  *      of the 0-chunk.
236  *
237  *    Revision 1.195  2008/10/13 16:04:37  fabiankeil
238  *    Make sure we don't try to reuse tainted server sockets.
239  *
240  *    Revision 1.194  2008/10/12 18:35:18  fabiankeil
241  *    The last commit was a bit too ambitious, apparently the content
242  *    length adjustment is only necessary if we aren't buffering.
243  *
244  *    Revision 1.193  2008/10/12 15:57:35  fabiankeil
245  *    Fix content length calculation if we read headers
246  *    and the start of the body at once. Now that we have
247  *    FEATURE_CONNECTION_KEEP_ALIVE, it actually matters.
248  *
249  *    Revision 1.192  2008/10/11 18:19:14  fabiankeil
250  *    Even more chat() cosmetics.
251  *
252  *    Revision 1.191  2008/10/11 18:00:14  fabiankeil
253  *    Reformat some comments in chat().
254  *
255  *    Revision 1.190  2008/10/11 14:58:00  fabiankeil
256  *    In case of chunk-encoded content, stop reading if
257  *    the buffer looks like it ends with the last chunk.
258  *
259  *    Revision 1.189  2008/10/11 09:53:00  fabiankeil
260  *    Let server_response_is_complete() deal properly with
261  *    content that is neither buffered nor read all at once.
262  *
263  *    Revision 1.188  2008/10/09 18:21:41  fabiankeil
264  *    Flush work-in-progress changes to keep outgoing connections
265  *    alive where possible. Incomplete and mostly #ifdef'd out.
266  *
267  *    Revision 1.187  2008/09/07 12:35:05  fabiankeil
268  *    Add mutex lock support for _WIN32.
269  *
270  *    Revision 1.186  2008/09/04 08:13:58  fabiankeil
271  *    Prepare for critical sections on Windows by adding a
272  *    layer of indirection before the pthread mutex functions.
273  *
274  *    Revision 1.185  2008/08/30 12:03:07  fabiankeil
275  *    Remove FEATURE_COOKIE_JAR.
276  *
277  *    Revision 1.184  2008/08/22 15:34:45  fabiankeil
278  *    - Silence LLVM/Clang complaint.
279  *    - Make received_hup_signal static.
280  *    - Hide definitions for basedir, pidfile and received_hup_signal
281  *      from __EMX__ as they only seem to be used in case of #ifdef unix.
282  *
283  *    Revision 1.183  2008/08/21 07:09:35  fabiankeil
284  *    Accept Shoutcast responses again. Problem reported
285  *    and fix suggested by Stefan in #2062860.
286  *
287  *    Revision 1.182  2008/06/27 11:13:56  fabiankeil
288  *    Fix possible NULL-pointer dereference reported
289  *    by din_a4 in #2003937. Pointy hat to me.
290  *
291  *    Revision 1.181  2008/05/21 15:47:15  fabiankeil
292  *    Streamline sed()'s prototype and declare
293  *    the header parse and add structures static.
294  *
295  *    Revision 1.180  2008/05/21 15:26:32  fabiankeil
296  *    - Mark csp as immutable for send_crunch_response().
297  *    - Fix comment spelling.
298  *
299  *    Revision 1.179  2008/05/20 20:13:32  fabiankeil
300  *    Factor update_server_headers() out of sed(), ditch the
301  *    first_run hack and make server_patterns_light static.
302  *
303  *    Revision 1.178  2008/05/10 13:23:38  fabiankeil
304  *    Don't provide get_header() with the whole client state
305  *    structure when it only needs access to csp->iob.
306  *
307  *    Revision 1.177  2008/05/10 11:51:12  fabiankeil
308  *    Make the "read the rest of the headers" loop a bit more readable.
309  *
310  *    Revision 1.176  2008/05/10 11:37:57  fabiankeil
311  *    - Instead of logging when the IIS5 hack is enabled, log when it fails.
312  *    - Remove useless comment.
313  *
314  *    Revision 1.175  2008/05/09 18:53:59  fabiankeil
315  *    Fix comment grammar.
316  *
317  *    Revision 1.174  2008/05/07 18:05:53  fabiankeil
318  *    Remove the pointless buffer in client_protocol_is_unsupported().
319  *
320  *    Revision 1.173  2008/05/06 15:09:00  fabiankeil
321  *    Least-effort fix for bug #1821930 (reported by Lee):
322  *    If the response doesn't look like HTTP,
323  *    tell the client and log the problem.
324  *
325  *    Revision 1.172  2008/04/16 16:38:21  fabiankeil
326  *    Don't pass the whole csp structure to flush_socket()
327  *    when it only needs a file descriptor and a buffer.
328  *
329  *    Revision 1.171  2008/03/27 18:27:25  fabiankeil
330  *    Remove kill-popups action.
331  *
332  *    Revision 1.170  2008/03/06 16:33:46  fabiankeil
333  *    If limit-connect isn't used, don't limit CONNECT requests to port 443.
334  *
335  *    Revision 1.169  2008/03/04 18:30:39  fabiankeil
336  *    Remove the treat-forbidden-connects-like-blocks action. We now
337  *    use the "blocked" page for forbidden CONNECT requests by default.
338  *
339  *    Revision 1.168  2008/03/02 12:25:25  fabiankeil
340  *    Also use shiny new connect_port_is_forbidden() in jcc.c.
341  *
342  *    Revision 1.167  2008/02/23 16:57:12  fabiankeil
343  *    Rename url_actions() to get_url_actions() and let it
344  *    use the standard parameter ordering.
345  *
346  *    Revision 1.166  2008/02/23 16:33:43  fabiankeil
347  *    Let forward_url() use the standard parameter ordering
348  *    and mark its second parameter immutable.
349  *
350  *    Revision 1.165  2008/02/02 19:36:56  fabiankeil
351  *    Remove the "Listening ... for local connections only" log message.
352  *    Whether or not remote connections are able to reach Privoxy is up
353  *    to the operating system.
354  *
355  *    Revision 1.164  2007/12/16 18:32:46  fabiankeil
356  *    Prevent the log messages for CONNECT requests to unacceptable
357  *    ports from printing the limit-connect argument as [null] if
358  *    limit-connect hasn't been explicitly enabled.
359  *
360  *    Revision 1.163  2007/12/13 01:47:11  david__schmidt
361  *    Make sure all console-mode apps get a usage() instance
362  *
363  *    Revision 1.162  2007/12/06 17:54:57  fabiankeil
364  *    Reword NO_SERVER_DATA_RESPONSE to make it harder
365  *    to misunderstand what the message is all about.
366  *
367  *    Revision 1.161  2007/12/04 19:44:22  fabiankeil
368  *    Unbreak trustfile which previously didn't work without
369  *    FEATURE_TOGGLE. Fixes BR#1843585, reported by Lee.
370  *
371  *    Revision 1.160  2007/11/29 18:00:29  fabiankeil
372  *    Plug memory leak. Spotted by Valgrind, triggered by
373  *    Privoxy-Regression-Test feeding proxyfuzz.py.
374  *
375  *    Revision 1.159  2007/11/24 14:34:09  fabiankeil
376  *    In the HTTP snipplets, refer to the client as client.
377  *
378  *    Revision 1.158  2007/11/11 16:44:17  fabiankeil
379  *    Emit a log message when activating the MS IIS5 hack.
380  *
381  *    Revision 1.157  2007/11/03 17:34:49  fabiankeil
382  *    Log the "weak randomization factor" warning only
383  *    once for mingw32 and provide some more details.
384  *
385  *    Revision 1.156  2007/11/01 18:20:58  fabiankeil
386  *    Initialize log module after initializing mutexes, future
387  *    deadlocks in that code should now work cross-platform.
388  *
389  *    Revision 1.155  2007/10/23 20:12:45  fabiankeil
390  *    Fix first CSUCCEED line to end in \r\n as required by RFC1945.
391  *    Reported by Bert van Leeuwen in BR#1818808.
392  *
393  *    Revision 1.154  2007/10/19 17:00:08  fabiankeil
394  *    Downgrade "Flushing header and buffers" message to LOG_LEVEL_INFO.
395  *
396  *    Revision 1.153  2007/10/14 14:12:41  fabiankeil
397  *    When in daemon mode, close stderr after the configuration file has been
398  *    parsed the first time. If logfile isn't set, stop logging. Fixes BR#897436.
399  *
400  *    Revision 1.152  2007/10/04 18:03:34  fabiankeil
401  *    - Fix a crash when parsing invalid requests whose first header
402  *      is rejected by get_header(). Regression (re?)introduced
403  *      in r1.143 by yours truly.
404  *    - Move ACTION_VANILLA_WAFER handling into parsers.c's
405  *      client_cookie_adder() to make sure send-vanilla-wafer can be
406  *      controlled through tags (and thus regression-tested).
407  *
408  *    Revision 1.151  2007/09/29 10:21:16  fabiankeil
409  *    - Move get_filter_function() from jcc.c to filters.c
410  *      so the filter functions can be static.
411  *    - Don't bother filtering body-less responses.
412  *
413  *    Revision 1.150  2007/09/28 16:39:29  fabiankeil
414  *    Execute content filters through execute_content_filter().
415  *
416  *    Revision 1.149  2007/09/04 15:08:48  fabiankeil
417  *    Initialize req to NULL to make sure it's defined if the
418  *    first read_socket() call fails. Reported by icmp30.
419  *
420  *    Revision 1.148  2007/08/26 16:47:13  fabiankeil
421  *    Add Stephen Gildea's --pre-chroot-nslookup patch [#1276666],
422  *    extensive comments moved to user manual.
423  *
424  *    Revision 1.147  2007/08/25 14:42:40  fabiankeil
425  *    Don't crash if a broken header filter wiped out the request line.
426  *
427  *    Revision 1.146  2007/08/20 17:09:32  fabiankeil
428  *    Fix byte_count calculation in case of flushes
429  *    and don't parse the server headers a second time.
430  *
431  *    Revision 1.145  2007/08/19 13:13:31  fabiankeil
432  *    - If there's a connection problem after we already forwarded
433  *      parts of the original content, just hang up. Fixes BR#1776724.
434  *    - Fix warnings about unused code on mingw32.
435  *    - In case of flushes, calculate the byte count
436  *      less incorrectly (I think).
437  *
438  *    Revision 1.144  2007/08/11 14:43:22  fabiankeil
439  *    Add some more prototypes for static functions.
440  *
441  *    Revision 1.143  2007/08/05 13:58:19  fabiankeil
442  *    Comment out request_contains_null_bytes() until it's used again.
443  *
444  *    Revision 1.142  2007/08/05 13:50:26  fabiankeil
445  *    #1763173 from Stefan Huehner: s@const static@static const@
446  *    and declare some more functions static.
447  *
448  *    Revision 1.141  2007/08/04 09:56:23  fabiankeil
449  *    - Log rejected CONNECT requests with LOG_LEVEL_INFO
450  *      and explain why they were rejected in the first place.
451  *    - Fix the LOG_LEVEL_CLF message for crunches of unallowed
452  *      CONNECT requests. The request line was missing.
453  *    - Add two more XXX reminders as we don't have enough already.
454  *
455  *    Revision 1.140  2007/07/21 11:51:36  fabiankeil
456  *    As Hal noticed, checking dispatch_cgi() as the last cruncher
457  *    looks like a bug if CGI requests are blocked unintentionally,
458  *    so don't do it unless the user enabled the new config option
459  *    "allow-cgi-request-crunching".
460  *
461  *    Revision 1.139  2007/07/14 07:46:41  fabiankeil
462  *    - Allow to rewrite the request destination behind the client's back.
463  *    - Turn the weird-looking unconditional for loop that
464  *      reads the client request into a conditional while loop.
465  *      Move the stuff that only runs once out of the loop.
466  *    - Move parts of chat(), server_content_type() and the
467  *      necessary stuff to fix BR#1750917 into get_filter_function().
468  *
469  *    Revision 1.138  2007/06/03 18:45:18  fabiankeil
470  *    Temporary workaround for BR#1730105.
471  *
472  *    Revision 1.137  2007/06/01 18:16:36  fabiankeil
473  *    Use the same mutex for gethostbyname() and gethostbyaddr() to prevent
474  *    deadlocks and crashes on OpenBSD and possibly other OS with neither
475  *    gethostbyname_r() nor gethostaddr_r(). Closes BR#1729174.
476  *    Thanks to Ralf Horstmann for report and solution.
477  *
478  *    Revision 1.136  2007/06/01 16:41:11  fabiankeil
479  *    Add forward-override{} to change the forwarding settings through
480  *    action sections. This is mainly interesting to forward different
481  *    clients differently (for example based on User-Agent or request
482  *    origin).
483  *
484  *    Revision 1.135  2007/05/24 17:03:50  fabiankeil
485  *    - Let usage() mention the --chroot parameter.
486  *    - Use read_socket() consistently and always leave
487  *      the last buffer byte alone, even in cases where
488  *      null termination (currently) doesn't matter.
489  *
490  *    Revision 1.134  2007/05/16 14:59:46  fabiankeil
491  *    - Fix config file loading on Unix if no config file is specified.
492  *      Since r1.97 Privoxy would always interpret the last argument as
493  *      config file, even if it's a valid command line option.
494  *    - Abort in case of unrecognized command line options. Closes #1719696.
495  *    - Remove a bunch of unnecessary strcpy() calls (yay for c&p without thinking).
496  *    - Replace the remaining strcpy() and strcat() calls with strlcpy() and strcat().
497  *
498  *    Revision 1.133  2007/05/04 11:23:19  fabiankeil
499  *    - Don't rerun crunchers that only depend on the request URL.
500  *    - Don't count redirects and CGI requests as "blocked requests".
501  *
502  *    Revision 1.132  2007/04/25 15:15:17  fabiankeil
503  *    Support crunching based on tags created by server-header taggers.
504  *
505  *    Revision 1.131  2007/04/22 13:24:50  fabiankeil
506  *    Make HTTP snippets static (again). Add a Content-Type for those
507  *    with content so the browser doesn't guess it based on the URL.
508  *
509  *    Revision 1.130  2007/04/19 13:47:34  fabiankeil
510  *    Move crunching and request line rebuilding out of chat().
511  *
512  *    Revision 1.129  2007/04/15 16:39:20  fabiankeil
513  *    Introduce tags as alternative way to specify which
514  *    actions apply to a request. At the moment tags can be
515  *    created based on client and server headers.
516  *
517  *    Revision 1.128  2007/03/25 16:55:54  fabiankeil
518  *    Don't CLF-log CONNECT requests twice.
519  *
520  *    Revision 1.127  2007/03/20 13:53:17  fabiankeil
521  *    Log the source address for ACL-related connection drops.
522  *
523  *    Revision 1.126  2007/03/17 15:20:05  fabiankeil
524  *    New config option: enforce-blocks.
525  *
526  *    Revision 1.125  2007/03/09 14:12:00  fabiankeil
527  *    - Move null byte check into separate function.
528  *    - Don't confuse the client with error pages
529  *      if a CONNECT request was already confirmed.
530  *
531  *    Revision 1.124  2007/02/23 14:59:54  fabiankeil
532  *    Speed up NULL byte escaping and only log the complete
533  *    NULL byte requests with header debugging enabled.
534  *
535  *    Revision 1.123  2007/02/21 18:42:10  fabiankeil
536  *    Answer requests that contain NULL bytes with
537  *    a custom response instead of waiting for more
538  *    data until the client eventually hangs up.
539  *
540  *    Revision 1.122  2007/02/07 11:12:02  fabiankeil
541  *    - Move delivery and logging of crunched responses
542  *      from chat() into send_crunch_response().
543  *    - Display the reason for generating http_responses.
544  *    - Log the content length for LOG_LEVEL_CLF correctly
545  *      (still incorrect for some fixed responses).
546  *    - Reword an incorrect comment about
547  *      treat-forbidden-connects-like-blocks violating
548  *      the specs.
549  *    - Add some log messages.
550  *
551  *    Revision 1.121  2007/01/27 10:52:56  fabiankeil
552  *    Move mutex initialization into separate
553  *    function and exit in case of errors.
554  *
555  *    Revision 1.120  2007/01/26 14:18:42  fabiankeil
556  *    - Start to reduce chat()'s line count and move
557  *      parts of it into separate functions.
558  *    - Add "HTTP/1.1 100 Continue" hack for BR 756734.
559  *
560  *    Revision 1.119  2007/01/25 14:02:30  fabiankeil
561  *    - Add Proxy-Agent header to HTTP snippets that are
562  *      supposed to reach HTTP clients only.
563  *    - Made a few CONNECT log messages more descriptive.
564  *    - Catch completely empty server responses (as seen
565  *      with Tor's fake ".noconnect" top level domain).
566  *    - Use shiny new "forwarding-failed" template for socks errors.
567  *
568  *    Revision 1.118  2007/01/07 07:43:43  joergs
569  *    AmigaOS4 support added.
570  *
571  *    Revision 1.117  2006/12/31 17:56:37  fabiankeil
572  *    Added config option accept-intercepted-requests
573  *    and disabled it by default.
574  *
575  *    Revision 1.116  2006/12/29 19:08:22  fabiankeil
576  *    Reverted parts of my last commit
577  *    to keep error handling working.
578  *
579  *    Revision 1.115  2006/12/29 17:38:57  fabiankeil
580  *    Fixed gcc43 conversion warnings.
581  *
582  *    Revision 1.114  2006/12/27 18:52:02  fabiankeil
583  *    Fix -pedantic ISO C warning about converting
584  *    from function pointer to object pointer.
585  *
586  *    Revision 1.113  2006/12/26 17:38:50  fabiankeil
587  *    Silence compiler warning I introduced with my last commit.
588  *
589  *    Revision 1.112  2006/12/26 17:31:41  fabiankeil
590  *    Mutex protect rand() if POSIX threading
591  *    is used, warn the user if that's not possible
592  *    and stop using it on _WIN32 where it could
593  *    cause crashes.
594  *
595  *    Revision 1.111  2006/12/23 16:15:06  fabiankeil
596  *    Don't prevent core dumps by catching SIGABRT.
597  *    It's rude and makes debugging unreasonable painful.
598  *
599  *    Revision 1.110  2006/12/13 14:52:53  etresoft
600  *    Fix build failure on MacOS X. Global symbols can be either static or extern, but not both.
601  *
602  *    Revision 1.109  2006/12/06 19:41:40  fabiankeil
603  *    Privoxy is now able to run as intercepting
604  *    proxy in combination with any packet filter
605  *    that does the port redirection. The destination
606  *    is extracted from the "Host:" header which
607  *    should be available for nearly all requests.
608  *
609  *    Moved HTTP snipplets into jcc.c.
610  *    Added error message for gopher proxy requests.
611  *
612  *    Revision 1.108  2006/11/28 15:38:51  fabiankeil
613  *    Only unlink the pidfile if it's actually used.
614  *
615  *    Change order of interception checks to make
616  *    it possible to block or redirect requests for
617  *    the cgi pages.
618  *
619  *    Revision 1.107  2006/11/13 19:05:51  fabiankeil
620  *    Make pthread mutex locking more generic. Instead of
621  *    checking for OSX and OpenBSD, check for FEATURE_PTHREAD
622  *    and use mutex locking unless there is an _r function
623  *    available. Better safe than sorry.
624  *
625  *    Fixes "./configure --disable-pthread" and should result
626  *    in less threading-related problems on pthread-using platforms,
627  *    but it still doesn't fix BR#1122404.
628  *
629  *    Revision 1.106  2006/11/06 19:58:23  fabiankeil
630  *    Move pthread.h inclusion from jcc.c to jcc.h.
631  *    Fixes build on x86-freebsd1 (FreeBSD 5.4-RELEASE).
632  *
633  *    Revision 1.105  2006/11/06 14:26:02  fabiankeil
634  *    Don't exit after receiving the second SIGHUP on Solaris.
635  *
636  *    Fixes BR 1052235, but the same problem may exist on other
637  *    systems. Once 3.0.6 is out we should use sigset()
638  *    where available and see if it breaks anything.
639  *
640  *    Revision 1.104  2006/09/23 13:26:38  roro
641  *    Replace TABs by spaces in source code.
642  *
643  *    Revision 1.103  2006/09/21 12:54:43  fabiankeil
644  *    Fix +redirect{}. Didn't work with -fast-redirects.
645  *
646  *    Revision 1.102  2006/09/06 13:03:04  fabiankeil
647  *    Respond with 400 and a short text message
648  *    if the client tries to use Privoxy as FTP proxy.
649  *
650  *    Revision 1.101  2006/09/06 09:23:37  fabiankeil
651  *    Make number of retries in case of forwarded-connect problems
652  *    a config file option (forwarded-connect-retries) and use 0 as
653  *    default.
654  *
655  *    Revision 1.100  2006/09/03 19:42:59  fabiankeil
656  *    Set random(3) seed.
657  *
658  *    Revision 1.99  2006/09/02 15:36:42  fabiankeil
659  *    Follow the OpenBSD port's lead and protect the resolve
660  *    functions on OpenBSD as well.
661  *
662  *    Revision 1.98  2006/08/24 11:01:34  fabiankeil
663  *    --user fix. Only use the user as group if no group is specified.
664  *    Solves BR 1492612. Thanks to Spinor S. and David Laight.
665  *
666  *    Revision 1.97  2006/08/18 15:23:17  david__schmidt
667  *    Windows service (re-)integration
668  *
669  *    The new args are:
670  *
671  *    --install[:service_name]
672  *    --uninstall[:service_name]
673  *    --service
674  *
675  *    They work as follows:
676  *    --install will create a service for you and then terminate.
677  *    By default the service name will be "privoxy" (without the quotes).
678  *    However you can run multiple services if you wish, just by adding
679  *    a colon and then a name (no spaces).
680  *
681  *    --uninstall follows the exact same rules a --install.
682  *
683  *    --service is used when the program is executed by the service
684  *    control manager, and in normal circumstances would never be
685  *    used as a command line argument.
686  *
687  *    Revision 1.96  2006/08/15 20:12:36  david__schmidt
688  *    Windows service integration
689  *
690  *    Revision 1.95  2006/08/03 02:46:41  david__schmidt
691  *    Incorporate Fabian Keil's patch work:
692 http://www.fabiankeil.de/sourcecode/privoxy/
693  *
694  *    Revision 1.94  2006/07/18 14:48:46  david__schmidt
695  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
696  *    with what was really the latest development (the v_3_0_branch branch)
697  *
698  *    Revision 1.92.2.16  2005/04/03 20:10:50  david__schmidt
699  *    Thanks to Jindrich Makovicka for a race condition fix for the log
700  *    file.  The race condition remains for non-pthread implementations.
701  *    Reference patch #1175720.
702  *
703  *    Revision 1.92.2.15  2004/10/03 12:53:32  david__schmidt
704  *    Add the ability to check jpeg images for invalid
705  *    lengths of comment blocks.  Defensive strategy
706  *    against the exploit:
707  *       Microsoft Security Bulletin MS04-028
708  *       Buffer Overrun in JPEG Processing (GDI+) Could
709  *       Allow Code Execution (833987)
710  *    Enabled with +inspect-jpegs in actions files.
711  *
712  *    Revision 1.92.2.14  2003/12/12 12:52:53  oes
713  *    - Fixed usage info for non-unix platforms
714  *    - Fixed small cmdline parsing bug
715  *
716  *    Revision 1.92.2.13  2003/11/27 19:20:27  oes
717  *    Diagnostics: Now preserve the returncode of pthread_create
718  *    in errno. Closes BR #775721. Thanks to Geoffrey Hausheer.
719  *
720  *    Revision 1.92.2.12  2003/07/11 11:34:19  oes
721  *    No longer ignore SIGCHLD. Fixes bug #769381
722  *
723  *    Revision 1.92.2.11  2003/05/14 12:32:02  oes
724  *    Close jarfile on graceful exit, remove stray line
725  *
726  *    Revision 1.92.2.10  2003/05/08 15:13:46  oes
727  *    Cosmetics: Killed a warning, a typo and an allocation left at exit
728  *
729  *    Revision 1.92.2.9  2003/04/03 15:08:42  oes
730  *    No longer rely on non-POSIX.1 extensions of getcwd().
731  *    Fixes bug #711001
732  *
733  *    Revision 1.92.2.8  2003/03/31 13:12:32  oes
734  *    Replaced setenv() by posix-compliant putenv()
735  *    Thanks to Neil McCalden (nmcc AT users.sf.net).
736  *
737  *    Revision 1.92.2.7  2003/03/17 16:48:59  oes
738  *    Added chroot ability, thanks to patch by Sviatoslav Sviridov
739  *
740  *    Revision 1.92.2.6  2003/03/11 11:55:00  oes
741  *    Clean-up and extension of improvements for forked mode:
742  *     - Child's return code now consists of flags RC_FLAG_*
743  *     - Reporting toggle to parent now properly #ifdef'ed
744  *     - Children now report blocking to parent. This enables
745  *       statistics in forked mode
746  *
747  *    Revision 1.92.2.5  2003/03/10 23:45:32  oes
748  *    Fixed bug #700381: Non-Threaded version now capable of being toggled.
749  *    Children now report having been toggled through _exit(17), parents
750  *    watch for that code and toggle themselves if found.
751  *
752  *    Revision 1.92.2.4  2003/03/07 03:41:04  david__schmidt
753  *    Wrapping all *_r functions (the non-_r versions of them) with 
754  *    mutex semaphores for OSX.  Hopefully this will take care of all 
755  *    of those pesky crash reports.
756  *
757  *    Revision 1.92.2.3  2003/02/28 12:53:06  oes
758  *    Fixed two mostly harmless mem leaks
759  *
760  *    Revision 1.92.2.2  2002/11/20 14:37:47  oes
761  *    Fix: Head of global clients list now initialized to NULL
762  *
763  *    Revision 1.92.2.1  2002/09/25 14:52:24  oes
764  *    Added basic support for OPTIONS and TRACE HTTP methods:
765  *     - New interceptor direct_response() added in chat().
766  *     - sed() moved to earlier in the process, so that the
767  *       Host: header is evaluated before actions and forwarding
768  *       are decided on.
769  *
770  *    Revision 1.92  2002/05/08 16:00:46  oes
771  *    Chat's buffer handling:
772  *     - Fixed bug with unchecked out-of-mem conditions
773  *       while reading client request & server headers
774  *     - No longer predict if the buffer limit will be exceeded
775  *       in the next read -- check add_to_iob's new
776  *       return code. If buffer couldn't be extended
777  *       (policy or out-of-mem) while
778  *       - reading from client: abort
779  *       - reading server headers: send error page
780  *       - buffering server body for filter: flush,
781  *         and if that fails: send error page
782  *
783  *    Revision 1.91  2002/04/08 20:35:58  swa
784  *    fixed JB spelling
785  *
786  *    Revision 1.90  2002/04/02 14:57:28  oes
787  *    Made sending wafers independent of FEATURE_COOKIE_JAR
788  *
789  *    Revision 1.89  2002/03/31 17:18:59  jongfoster
790  *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
791  *
792  *    Revision 1.88  2002/03/27 14:32:43  david__schmidt
793  *    More compiler warning message maintenance
794  *
795  *    Revision 1.87  2002/03/26 22:29:54  swa
796  *    we have a new homepage!
797  *
798  *    Revision 1.86  2002/03/25 17:04:55  david__schmidt
799  *    Workaround for closing the jarfile before load_config() comes around again
800  *
801  *    Revision 1.85  2002/03/24 15:23:33  jongfoster
802  *    Name changes
803  *
804  *    Revision 1.84  2002/03/24 13:25:43  swa
805  *    name change related issues
806  *
807  *    Revision 1.83  2002/03/16 23:54:06  jongfoster
808  *    Adding graceful termination feature, to help look for memory leaks.
809  *    If you enable this (which, by design, has to be done by hand
810  *    editing config.h) and then go to http://i.j.b/die, then the program
811  *    will exit cleanly after the *next* request.  It should free all the
812  *    memory that was used.
813  *
814  *    Revision 1.82  2002/03/13 00:27:05  jongfoster
815  *    Killing warnings
816  *
817  *    Revision 1.81  2002/03/12 01:42:50  oes
818  *    Introduced modular filters
819  *
820  *    Revision 1.80  2002/03/11 22:07:05  david__schmidt
821  *    OS/2 port maintenance:
822  *    - Fixed EMX build - it had decayed a little
823  *    - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
824  *      substituted a memset for now.
825  *
826  *    Revision 1.79  2002/03/09 20:03:52  jongfoster
827  *    - Making various functions return int rather than size_t.
828  *      (Undoing a recent change).  Since size_t is unsigned on
829  *      Windows, functions like read_socket that return -1 on
830  *      error cannot return a size_t.
831  *
832  *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
833  *      crashes, and also frequently caused JB to jump to 100%
834  *      CPU and stay there.  (Because it thought it had just
835  *      read ((unsigned)-1) == 4Gb of data...)
836  *
837  *    - The signature of write_socket has changed, it now simply
838  *      returns success=0/failure=nonzero.
839  *
840  *    - Trying to get rid of a few warnings --with-debug on
841  *      Windows, I've introduced a new type "jb_socket".  This is
842  *      used for the socket file descriptors.  On Windows, this
843  *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
844  *      an int.  The error value can't be -1 any more, so it's
845  *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
846  *      Windows it maps to the #define INVALID_SOCKET.)
847  *
848  *    - The signature of bind_port has changed.
849  *
850  *    Revision 1.78  2002/03/08 21:35:04  oes
851  *    Added optional group supplement to --user option. Will now use default group of user if no group given
852  *
853  *    Revision 1.77  2002/03/07 03:52:06  oes
854  *     - Fixed compiler warnings etc
855  *     - Improved handling of failed DNS lookups
856  *
857  *    Revision 1.76  2002/03/06 22:54:35  jongfoster
858  *    Automated function-comment nitpicking.
859  *
860  *    Revision 1.75  2002/03/06 10:02:19  oes
861  *    Fixed stupid bug when --user was not given
862  *
863  *    Revision 1.74  2002/03/06 00:49:31  jongfoster
864  *    Fixing warning on Windows
865  *    Making #ifdefs that refer to the same variable consistently
866  *    use #ifdef unix rather than mixing #ifdef unix & #ifndef OS2
867  *
868  *    Revision 1.73  2002/03/05 23:57:30  hal9
869  *    Stray character 's' on line 1618 was breaking build.
870  *
871  *    Revision 1.72  2002/03/05 21:33:45  david__schmidt
872  *    - Re-enable OS/2 building after new parms were added
873  *    - Fix false out of memory report when resolving CGI templates when no IP
874  *      address is available of failed attempt (a la no such domain)
875  *
876  *    Revision 1.71  2002/03/05 18:13:56  oes
877  *    Added --user option
878  *
879  *    Revision 1.70  2002/03/05 04:52:42  oes
880  *    Deleted non-errlog debugging code
881  *
882  *    Revision 1.69  2002/03/04 23:50:00  jongfoster
883  *    Splitting off bind_port() call into bind_port_helper(), with
884  *    improved logging.
885  *
886  *    Revision 1.68  2002/03/04 20:17:32  oes
887  *    Fixed usage info
888  *
889  *    Revision 1.67  2002/03/04 18:18:57  oes
890  *    - Removed _DEBUG mode
891  *    - Cleand up cmdline parsing
892  *    - Introduced --no-daemon, --pidfile options
893  *    - Cleaned up signal handling:
894  *      - Terminate cleanly on INT, TERM and ABRT
895  *      - Schedule logfile for re-opening on HUP
896  *      - Ignore CHLD and PIPE
897  *      - Leave the rest with their default handlers
898  *      - Uniform handler registration
899  *    - Added usage() function
900  *    - Played styleguide police
901  *
902  *    Revision 1.66  2002/03/03 15:06:55  oes
903  *    Re-enabled automatic config reloading
904  *
905  *    Revision 1.65  2002/03/03 14:49:11  oes
906  *    Fixed CLF logging: Now uses client's original HTTP request
907  *
908  *    Revision 1.64  2002/03/03 09:18:03  joergs
909  *    Made jumbjuster work on AmigaOS again.
910  *
911  *    Revision 1.63  2002/03/02 04:14:50  david__schmidt
912  *    Clean up a little CRLF unpleasantness that suddenly appeared
913  *
914  *    Revision 1.62  2002/02/20 23:17:23  jongfoster
915  *    Detecting some out-of memory conditions and exiting with a log message.
916  *
917  *    Revision 1.61  2002/01/17 21:01:52  jongfoster
918  *    Moving all our URL and URL pattern parsing code to urlmatch.c.
919  *
920  *    Revision 1.60  2001/12/30 14:07:32  steudten
921  *    - Add signal handling (unix)
922  *    - Add SIGHUP handler (unix)
923  *    - Add creation of pidfile (unix)
924  *    - Add action 'top' in rc file (RH)
925  *    - Add entry 'SIGNALS' to manpage
926  *    - Add exit message to logfile (unix)
927  *
928  *    Revision 1.59  2001/12/13 14:07:18  oes
929  *    Fixed Bug: 503 error page now sent OK
930  *
931  *    Revision 1.58  2001/11/30 23:37:24  jongfoster
932  *    Renaming the Win32 config file to config.txt - this is almost the
933  *    same as the corresponding UNIX name "config"
934  *
935  *    Revision 1.57  2001/11/16 00:47:43  jongfoster
936  *    Changing the tty-disconnection code to use setsid().
937  *
938  *    Revision 1.56  2001/11/13 20:20:54  jongfoster
939  *    Tabs->spaces, fixing a bug with missing {} around an if()
940  *
941  *    Revision 1.55  2001/11/13 20:14:53  jongfoster
942  *    Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
943  *
944  *    Revision 1.54  2001/11/07 00:03:14  steudten
945  *    Give reliable return value if an error
946  *    occurs not just 0 with new daemon mode.
947  *
948  *    Revision 1.53  2001/11/05 21:41:43  steudten
949  *    Add changes to be a real daemon just for unix os.
950  *    (change cwd to /, detach from controlling tty, set
951  *    process group and session leader to the own process.
952  *    Add DBG() Macro.
953  *    Add some fatal-error log message for failed malloc().
954  *    Add '-d' if compiled with 'configure --with-debug' to
955  *    enable debug output.
956  *
957  *    Revision 1.52  2001/10/26 20:11:20  jongfoster
958  *    Fixing type mismatch
959  *
960  *    Revision 1.51  2001/10/26 17:38:28  oes
961  *    Cosmetics
962  *
963  *    Revision 1.50  2001/10/25 03:40:48  david__schmidt
964  *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
965  *    threads to call select() simultaneously.  So, it's time to do a real, live,
966  *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
967  *    (native). Both versions will work, but using __OS2__ offers multi-threading.
968  *
969  *    Revision 1.49  2001/10/23 21:41:35  jongfoster
970  *    Added call to initialize the (statically-allocated of course)
971  *    "out of memory" CGI response.
972  *
973  *    Revision 1.48  2001/10/10 19:56:46  jongfoster
974  *    Moving some code that wasn't cookie-related out of an #ifdef
975  *    FEATURE_COOKIE_JAR
976  *
977  *    Revision 1.47  2001/10/10 16:44:36  oes
978  *    Added CONNECT destination port limitation check
979  *
980  *    Revision 1.46  2001/10/08 15:17:41  oes
981  *    Re-enabled SSL forwarding
982  *
983  *    Revision 1.45  2001/10/07 15:42:11  oes
984  *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
985  *
986  *    Moved downgrading of the HTTP version from parse_http_request to
987  *      chat(), since we can't decide if it is necessary before we have
988  *      determined the actions for the URL. The HTTP command is now
989  *      *always* re-built so the repairs need no longer be special-cased.
990  *
991  *    filter_popups now gets a csp pointer so it can raise the new
992  *      CSP_FLAG_MODIFIED flag.
993  *
994  *    Bugfix
995  *
996  *    Added configurable size limit for the IOB. If the IOB grows so
997  *      large that the next read would exceed the limit, the header
998  *      is generated, and the header & unfiltered buffer are flushed
999  *      to the client. Chat then continues in non-buffering,
1000  *      non-filtering body mode.
1001  *
1002  *    Revision 1.44  2001/10/02 18:13:57  oes
1003  *    Ooops
1004  *
1005  *    Revision 1.43  2001/10/02 15:32:13  oes
1006  *    Moved generation of hdr
1007  *
1008  *    Revision 1.42  2001/09/21 23:02:02  david__schmidt
1009  *    Cleaning up 2 compiler warnings on OS/2.
1010  *
1011  *    Revision 1.41  2001/09/16 17:05:14  jongfoster
1012  *    Removing unused #include showarg.h
1013  *
1014  *    Revision 1.40  2001/09/16 15:41:45  jongfoster
1015  *    Fixing signed/unsigned comparison warning.
1016  *
1017  *    Revision 1.39  2001/09/16 13:21:27  jongfoster
1018  *    Changes to use new list functions.
1019  *
1020  *    Revision 1.38  2001/09/16 13:01:46  jongfoster
1021  *    Removing redundant function call that zeroed zalloc()'d memory.
1022  *
1023  *    Revision 1.37  2001/09/10 11:12:24  oes
1024  *    Deleted unused variable
1025  *
1026  *    Revision 1.36  2001/09/10 10:56:15  oes
1027  *    Silenced compiler warnings
1028  *
1029  *    Revision 1.35  2001/07/31 14:44:22  oes
1030  *    Deleted unused size parameter from filter_popups()
1031  *
1032  *    Revision 1.34  2001/07/30 22:08:36  jongfoster
1033  *    Tidying up #defines:
1034  *    - All feature #defines are now of the form FEATURE_xxx
1035  *    - Permanently turned off WIN_GUI_EDIT
1036  *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
1037  *
1038  *    Revision 1.33  2001/07/29 19:32:00  jongfoster
1039  *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
1040  *
1041  *    Revision 1.32  2001/07/29 18:47:05  jongfoster
1042  *    Adding missing #include "loadcfg.h"
1043  *
1044  *    Revision 1.31  2001/07/29 12:17:48  oes
1045  *    Applied pthread fix by Paul Lieverse
1046  *
1047  *    Revision 1.30  2001/07/25 22:57:13  jongfoster
1048  *    __BEOS__ no longer overrides FEATURE_PTHREAD.
1049  *    This is because FEATURE_PTHREAD will soon be widely used, so I
1050  *    want to keep it simple.
1051  *
1052  *    Revision 1.29  2001/07/24 12:47:06  oes
1053  *    Applied BeOS support update by Eugenia
1054  *
1055  *    Revision 1.28  2001/07/23 13:26:12  oes
1056  *    Fixed bug in popup-killing for the first read that caused binary garbage to be sent between headers and body
1057  *
1058  *    Revision 1.27  2001/07/19 19:09:47  haroon
1059  *    - Added code to take care of the situation where while processing the first
1060  *      server response (which includes the server header), after finding the end
1061  *      of the headers we were not looking past the end of the headers for
1062  *      content modification. I enabled it for filter_popups.
1063  *      Someone else should look to see if other similar operations should be
1064  *      done to the discarded portion of the buffer.
1065  *
1066  *      Note 2001/07/20: No, the other content modification mechanisms will process
1067  *                       the whole iob later anyway. --oes
1068  *
1069  *    Revision 1.26  2001/07/18 12:31:36  oes
1070  *    cosmetics
1071  *
1072  *    Revision 1.25  2001/07/15 19:43:49  jongfoster
1073  *    Supports POSIX threads.
1074  *    Also removed some unused #includes.
1075  *
1076  *    Revision 1.24  2001/07/13 14:00:40  oes
1077  *     - Generic content modification scheme:
1078  *       Each feature has its own applicability flag that is set
1079  *       from csp->action->flags.
1080  *       Replaced the "filtering" int flag , by a function pointer
1081  *       "content_filter" to the function that will do the content
1082  *       modification. If it is != NULL, the document will be buffered
1083  *       and processed through *content_filter, which must set
1084  *       csp->content_length and return a modified copy of the body
1085  *       or return NULL (on failiure).
1086  *     - Changed csp->is_text to the more generic bitmap csp->content_type
1087  *       which can currently take the valued CT_TEXT or CT_GIF
1088  *     - Reformatting etc
1089  *     - Removed all #ifdef PCRS
1090  *
1091  *    Revision 1.23  2001/07/02 02:28:25  iwanttokeepanon
1092  *    Added "#ifdef ACL_FILES" conditional compilation to line 1291 to exclude
1093  *    the `block_acl' call.  This prevents a compilation error when the user
1094  *    does not wish to use the "ACL" feature.
1095  *
1096  *    Revision 1.22  2001/06/29 21:45:41  oes
1097  *    Indentation, CRLF->LF, Tab-> Space
1098  *
1099  *    Revision 1.21  2001/06/29 13:29:36  oes
1100  *    - Cleaned up, improved comments
1101  *    - Unified all possible interceptors (CGI,
1102  *      block, trust, fast_redirect) in one
1103  *      place, with one (CGI) answer generation
1104  *      mechansim. Much clearer now.
1105  *    - Removed the GIF image generation, which
1106  *      is now done in filters.c:block_url()
1107  *    - Made error conditions like domain lookup
1108  *      failiure or (various) problems while talking
1109  *      to the server use cgi.c:error_response()
1110  *      instead of generating HTML/HTTP in chat() (yuck!)
1111  *    - Removed logentry from cancelled commit
1112  *
1113  *    Revision 1.20  2001/06/09 10:55:28  jongfoster
1114  *    Changing BUFSIZ ==> BUFFER_SIZE
1115  *
1116  *    Revision 1.19  2001/06/07 23:12:52  jongfoster
1117  *    Replacing function pointer in struct gateway with a directly
1118  *    called function forwarded_connect().
1119  *    Replacing struct gateway with struct forward_spec
1120  *
1121  *    Revision 1.18  2001/06/03 19:12:16  oes
1122  *    introduced new cgi handling
1123  *
1124  *    Revision 1.17  2001/06/01 20:07:23  jongfoster
1125  *    Now uses action +image-blocker{} rather than config->tinygif
1126  *
1127  *    Revision 1.16  2001/06/01 18:49:17  jongfoster
1128  *    Replaced "list_share" with "list" - the tiny memory gain was not
1129  *    worth the extra complexity.
1130  *
1131  *    Revision 1.15  2001/05/31 21:24:47  jongfoster
1132  *    Changed "permission" to "action" throughout.
1133  *    Removed DEFAULT_USER_AGENT - it must now be specified manually.
1134  *    Moved vanilla wafer check into chat(), since we must now
1135  *    decide whether or not to add it based on the URL.
1136  *
1137  *    Revision 1.14  2001/05/29 20:14:01  joergs
1138  *    AmigaOS bugfix: PCRS needs a lot of stack, stacksize for child threads
1139  *    increased.
1140  *
1141  *    Revision 1.13  2001/05/29 09:50:24  jongfoster
1142  *    Unified blocklist/imagelist/permissionslist.
1143  *    File format is still under discussion, but the internal changes
1144  *    are (mostly) done.
1145  *
1146  *    Also modified interceptor behaviour:
1147  *    - We now intercept all URLs beginning with one of the following
1148  *      prefixes (and *only* these prefixes):
1149  *        * http://i.j.b/
1150  *        * http://ijbswa.sf.net/config/
1151  *        * http://ijbswa.sourceforge.net/config/
1152  *    - New interceptors "home page" - go to http://i.j.b/ to see it.
1153  *    - Internal changes so that intercepted and fast redirect pages
1154  *      are not replaced with an image.
1155  *    - Interceptors now have the option to send a binary page direct
1156  *      to the client. (i.e. ijb-send-banner uses this)
1157  *    - Implemented show-url-info interceptor.  (Which is why I needed
1158  *      the above interceptors changes - a typical URL is
1159  *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
1160  *      The previous mechanism would not have intercepted that, and
1161  *      if it had been intercepted then it then it would have replaced
1162  *      it with an image.)
1163  *
1164  *    Revision 1.12  2001/05/27 22:17:04  oes
1165  *
1166  *    - re_process_buffer no longer writes the modified buffer
1167  *      to the client, which was very ugly. It now returns the
1168  *      buffer, which it is then written by chat.
1169  *
1170  *    - content_length now adjusts the Content-Length: header
1171  *      for modified documents rather than crunch()ing it.
1172  *      (Length info in csp->content_length, which is 0 for
1173  *      unmodified documents)
1174  *
1175  *    - For this to work, sed() is called twice when filtering.
1176  *
1177  *    Revision 1.11  2001/05/26 17:27:53  jongfoster
1178  *    Added support for CLF and fixed LOG_LEVEL_LOG.
1179  *    Also did CRLF->LF fix of my previous patch.
1180  *
1181  *    Revision 1.10  2001/05/26 15:26:15  jongfoster
1182  *    ACL feature now provides more security by immediately dropping
1183  *    connections from untrusted hosts.
1184  *
1185  *    Revision 1.9  2001/05/26 00:28:36  jongfoster
1186  *    Automatic reloading of config file.
1187  *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
1188  *    Most of the global variables have been moved to a new
1189  *    struct configuration_spec, accessed through csp->config->globalname
1190  *    Most of the globals remaining are used by the Win32 GUI.
1191  *
1192  *    Revision 1.8  2001/05/25 22:43:18  jongfoster
1193  *    Fixing minor memory leak and buffer overflow.
1194  *
1195  *    Revision 1.7  2001/05/25 22:34:30  jongfoster
1196  *    Hard tabs->Spaces
1197  *
1198  *    Revision 1.6  2001/05/23 00:13:58  joergs
1199  *    AmigaOS support fixed.
1200  *
1201  *    Revision 1.5  2001/05/22 18:46:04  oes
1202  *
1203  *    - Enabled filtering banners by size rather than URL
1204  *      by adding patterns that replace all standard banner
1205  *      sizes with the "Junkbuster" gif to the re_filterfile
1206  *
1207  *    - Enabled filtering WebBugs by providing a pattern
1208  *      which kills all 1x1 images
1209  *
1210  *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
1211  *      which is selected by the (nonstandard and therefore
1212  *      capital) letter 'U' in the option string.
1213  *      It causes the quantifiers to be ungreedy by default.
1214  *      Appending a ? turns back to greedy (!).
1215  *
1216  *    - Added a new interceptor ijb-send-banner, which
1217  *      sends back the "Junkbuster" gif. Without imagelist or
1218  *      MSIE detection support, or if tinygif = 1, or the
1219  *      URL isn't recognized as an imageurl, a lame HTML
1220  *      explanation is sent instead.
1221  *
1222  *    - Added new feature, which permits blocking remote
1223  *      script redirects and firing back a local redirect
1224  *      to the browser.
1225  *      The feature is conditionally compiled, i.e. it
1226  *      can be disabled with --disable-fast-redirects,
1227  *      plus it must be activated by a "fast-redirects"
1228  *      line in the config file, has its own log level
1229  *      and of course wants to be displayed by show-proxy-args
1230  *      Note: Boy, all the #ifdefs in 1001 locations and
1231  *      all the fumbling with configure.in and acconfig.h
1232  *      were *way* more work than the feature itself :-(
1233  *
1234  *    - Because a generic redirect template was needed for
1235  *      this, tinygif = 3 now uses the same.
1236  *
1237  *    - Moved GIFs, and other static HTTP response templates
1238  *      to project.h
1239  *
1240  *    - Some minor fixes
1241  *
1242  *    - Removed some >400 CRs again (Jon, you really worked
1243  *      a lot! ;-)
1244  *
1245  *    Revision 1.4  2001/05/21 19:34:01  jongfoster
1246  *    Made failure to bind() a fatal error.
1247  *
1248  *    Revision 1.3  2001/05/20 01:21:20  jongfoster
1249  *    Version 2.9.4 checkin.
1250  *    - Merged popupfile and cookiefile, and added control over PCRS
1251  *      filtering, in new "permissionsfile".
1252  *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
1253  *      file error you now get a message box (in the Win32 GUI) rather
1254  *      than the program exiting with no explanation.
1255  *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
1256  *      skipping.
1257  *    - Removed tabs from "config"
1258  *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
1259  *    - Bumped up version number.
1260  *
1261  *    Revision 1.2  2001/05/17 22:34:44  oes
1262  *     - Added hint on GIF char array generation to jcc.c
1263  *     - Cleaned CRLF's from the sources and related files
1264  *     - Repaired logging for REF and FRC
1265  *
1266  *    Revision 1.1.1.1  2001/05/15 13:58:56  oes
1267  *    Initial import of version 2.9.3 source tree
1268  *
1269  *
1270  *********************************************************************/
1271 \f
1272
1273 #include "config.h"
1274
1275 #include <stdio.h>
1276 #include <sys/types.h>
1277 #include <stdlib.h>
1278 #include <string.h>
1279 #include <signal.h>
1280 #include <fcntl.h>
1281 #include <errno.h>
1282 #include <assert.h>
1283
1284 #ifdef _WIN32
1285 # ifndef FEATURE_PTHREAD
1286 #  ifndef STRICT
1287 #   define STRICT
1288 #  endif
1289 #  include <windows.h>
1290 #  include <process.h>
1291 # endif /* ndef FEATURE_PTHREAD */
1292
1293 # include "win32.h"
1294 # ifndef _WIN_CONSOLE
1295 #  include "w32log.h"
1296 # endif /* ndef _WIN_CONSOLE */
1297 # include "w32svrapi.h"
1298
1299 #else /* ifndef _WIN32 */
1300
1301 # if !defined (__OS2__)
1302 # include <unistd.h>
1303 # include <sys/wait.h>
1304 # endif /* ndef __OS2__ */
1305 # include <sys/time.h>
1306 # include <sys/stat.h>
1307 # include <sys/ioctl.h>
1308
1309 #ifdef sun
1310 #include <sys/termios.h>
1311 #endif /* sun */
1312
1313 #ifdef unix
1314 #include <pwd.h>
1315 #include <grp.h>
1316 #endif
1317
1318 # include <signal.h>
1319
1320 # ifdef __BEOS__
1321 #  include <socket.h>  /* BeOS has select() for sockets only. */
1322 #  include <OS.h>      /* declarations for threads and stuff. */
1323 # endif
1324
1325 # if defined(__EMX__) || defined(__OS2__)
1326 #  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
1327 # endif
1328 # ifdef __OS2__
1329 #define INCL_DOS
1330 # include <os2.h>
1331 #define bzero(B,N) memset(B,0x00,n)
1332 # endif
1333
1334 # ifndef FD_ZERO
1335 #  include <select.h>
1336 # endif
1337
1338 #endif
1339
1340 #include "project.h"
1341 #include "list.h"
1342 #include "jcc.h"
1343 #include "filters.h"
1344 #include "loaders.h"
1345 #include "parsers.h"
1346 #include "miscutil.h"
1347 #include "errlog.h"
1348 #include "jbsockets.h"
1349 #include "gateway.h"
1350 #include "actions.h"
1351 #include "cgi.h"
1352 #include "loadcfg.h"
1353 #include "urlmatch.h"
1354
1355 const char jcc_h_rcs[] = JCC_H_VERSION;
1356 const char project_h_rcs[] = PROJECT_H_VERSION;
1357
1358 int no_daemon = 0;
1359 struct client_state  clients[1];
1360 struct file_list     files[1];
1361
1362 #ifdef FEATURE_STATISTICS
1363 int urls_read     = 0;     /* total nr of urls read inc rejected */
1364 int urls_rejected = 0;     /* total nr of urls rejected */
1365 #endif /* def FEATURE_STATISTICS */
1366
1367 #ifdef FEATURE_GRACEFUL_TERMINATION
1368 int g_terminate = 0;
1369 #endif
1370
1371 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
1372 static void sig_handler(int the_signal);
1373 #endif
1374 static int client_protocol_is_unsupported(const struct client_state *csp, char *req);
1375 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
1376 static jb_err get_server_headers(struct client_state *csp);
1377 static const char *crunch_reason(const struct http_response *rsp);
1378 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
1379 static char *get_request_line(struct client_state *csp);
1380 static jb_err receive_client_request(struct client_state *csp);
1381 static jb_err parse_client_request(struct client_state *csp);
1382 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line);
1383 static jb_err change_request_destination(struct client_state *csp);
1384 static void chat(struct client_state *csp);
1385 static void serve(struct client_state *csp);
1386 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
1387 static void usage(const char *myname);
1388 #endif
1389 static void initialize_mutexes(void);
1390 static jb_socket bind_port_helper(struct configuration_spec *config);
1391 static void listen_loop(void);
1392
1393 #ifdef AMIGA
1394 void serve(struct client_state *csp);
1395 #else /* ifndef AMIGA */
1396 static void serve(struct client_state *csp);
1397 #endif /* def AMIGA */
1398
1399 #ifdef __BEOS__
1400 static int32 server_thread(void *data);
1401 #endif /* def __BEOS__ */
1402
1403 #ifdef _WIN32
1404 #define sleep(N)  Sleep(((N) * 1000))
1405 #endif
1406
1407 #ifdef __OS2__
1408 #define sleep(N)  DosSleep(((N) * 100))
1409 #endif
1410
1411 #ifdef MUTEX_LOCKS_AVAILABLE
1412 /*
1413  * XXX: Does the locking stuff really belong in this file?
1414  */
1415 privoxy_mutex_t log_mutex;
1416 privoxy_mutex_t log_init_mutex;
1417 privoxy_mutex_t connection_reuse_mutex;
1418
1419 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
1420 privoxy_mutex_t resolver_mutex;
1421 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
1422
1423 #ifndef HAVE_GMTIME_R
1424 privoxy_mutex_t gmtime_mutex;
1425 #endif /* ndef HAVE_GMTIME_R */
1426
1427 #ifndef HAVE_LOCALTIME_R
1428 privoxy_mutex_t localtime_mutex;
1429 #endif /* ndef HAVE_GMTIME_R */
1430
1431 #ifndef HAVE_RANDOM
1432 privoxy_mutex_t rand_mutex;
1433 #endif /* ndef HAVE_RANDOM */
1434
1435 #endif /* def MUTEX_LOCKS_AVAILABLE */
1436
1437 #if defined(unix)
1438 const char *basedir = NULL;
1439 const char *pidfile = NULL;
1440 static int received_hup_signal = 0;
1441 #endif /* defined unix */
1442
1443 /* HTTP snipplets. */
1444 static const char CSUCCEED[] =
1445    "HTTP/1.0 200 Connection established\r\n"
1446    "Proxy-Agent: Privoxy/" VERSION "\r\n\r\n";
1447
1448 static const char CHEADER[] =
1449    "HTTP/1.0 400 Invalid header received from client\r\n"
1450    "Proxy-Agent: Privoxy " VERSION "\r\n"
1451    "Content-Type: text/plain\r\n"
1452    "Connection: close\r\n\r\n"
1453    "Invalid header received from client.\r\n";
1454
1455 static const char FTP_RESPONSE[] =
1456    "HTTP/1.0 400 Invalid request received from client\r\n"
1457    "Content-Type: text/plain\r\n"
1458    "Connection: close\r\n\r\n"
1459    "Invalid request. Privoxy doesn't support FTP.\r\n";
1460
1461 static const char GOPHER_RESPONSE[] =
1462    "HTTP/1.0 400 Invalid request received from client\r\n"
1463    "Content-Type: text/plain\r\n"
1464    "Connection: close\r\n\r\n"
1465    "Invalid request. Privoxy doesn't support gopher.\r\n";
1466
1467 /* XXX: should be a template */
1468 static const char MISSING_DESTINATION_RESPONSE[] =
1469    "HTTP/1.0 400 Bad request received from client\r\n"
1470    "Proxy-Agent: Privoxy " VERSION "\r\n"
1471    "Content-Type: text/plain\r\n"
1472    "Connection: close\r\n\r\n"
1473    "Bad request. Privoxy was unable to extract the destination.\r\n";
1474
1475 /* XXX: should be a template */
1476 static const char NO_SERVER_DATA_RESPONSE[] =
1477    "HTTP/1.0 502 Server or forwarder response empty\r\n"
1478    "Proxy-Agent: Privoxy " VERSION "\r\n"
1479    "Content-Type: text/plain\r\n"
1480    "Connection: close\r\n\r\n"
1481    "Empty server or forwarder response.\r\n"
1482    "The connection has been closed but Privoxy didn't receive any data.\r\n";
1483
1484 /* XXX: should be a template */
1485 static const char INVALID_SERVER_HEADERS_RESPONSE[] =
1486    "HTTP/1.0 502 Server or forwarder response invalid\r\n"
1487    "Proxy-Agent: Privoxy " VERSION "\r\n"
1488    "Content-Type: text/plain\r\n"
1489    "Connection: close\r\n\r\n"
1490    "Bad response. The server or forwarder response doesn't look like HTTP.\r\n";
1491
1492 #if 0
1493 /* XXX: should be a template */
1494 static const char NULL_BYTE_RESPONSE[] =
1495    "HTTP/1.0 400 Bad request received from client\r\n"
1496    "Proxy-Agent: Privoxy " VERSION "\r\n"
1497    "Content-Type: text/plain\r\n"
1498    "Connection: close\r\n\r\n"
1499    "Bad request. Null byte(s) before end of request.\r\n";
1500 #endif
1501
1502 /* XXX: should be a template */
1503 static const char MESSED_UP_REQUEST_RESPONSE[] =
1504    "HTTP/1.0 400 Malformed request after rewriting\r\n"
1505    "Proxy-Agent: Privoxy " VERSION "\r\n"
1506    "Content-Type: text/plain\r\n"
1507    "Connection: close\r\n\r\n"
1508    "Bad request. Messed up with header filters.\r\n";
1509
1510 static const char TOO_MANY_CONNECTIONS_RESPONSE[] =
1511    "HTTP/1.0 503 Too many open connections\r\n"
1512    "Proxy-Agent: Privoxy " VERSION "\r\n"
1513    "Content-Type: text/plain\r\n"
1514    "Connection: close\r\n\r\n"
1515    "Maximum number of open connections reached.\r\n";
1516
1517 /* XXX: should be a template */
1518 static const char CONNECTION_TIMEOUT_RESPONSE[] =
1519    "HTTP/1.0 504 Connection timeout\r\n"
1520    "Proxy-Agent: Privoxy " VERSION "\r\n"
1521    "Content-Type: text/plain\r\n"
1522    "Connection: close\r\n\r\n"
1523    "The connection timed out.\r\n";
1524
1525 /* A function to crunch a response */
1526 typedef struct http_response *(*crunch_func_ptr)(struct client_state *);
1527
1528 /* Crunch function flags */
1529 #define CF_NO_FLAGS        0
1530 /* Cruncher applies to forced requests as well */
1531 #define CF_IGNORE_FORCE    1
1532 /* Crunched requests are counted for the block statistics */
1533 #define CF_COUNT_AS_REJECT 2
1534
1535 /* A crunch function and its flags */
1536 struct cruncher
1537 {
1538    const crunch_func_ptr cruncher;
1539    const int flags;
1540 };
1541
1542 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[]);
1543
1544 /* Complete list of cruncher functions */
1545 static const struct cruncher crunchers_all[] = {
1546    { direct_response, CF_COUNT_AS_REJECT|CF_IGNORE_FORCE},
1547    { block_url,       CF_COUNT_AS_REJECT },
1548 #ifdef FEATURE_TRUST
1549    { trust_url,       CF_COUNT_AS_REJECT },
1550 #endif /* def FEATURE_TRUST */
1551    { redirect_url,    CF_NO_FLAGS  },
1552    { dispatch_cgi,    CF_IGNORE_FORCE},
1553    { NULL,            0 }
1554 };
1555
1556 /* Light version, used after tags are applied */
1557 static const struct cruncher crunchers_light[] = {
1558    { block_url,       CF_COUNT_AS_REJECT },
1559    { redirect_url,    CF_NO_FLAGS },
1560    { NULL,            0 }
1561 };
1562
1563
1564 /*
1565  * XXX: Don't we really mean
1566  *
1567  * #if defined(unix)
1568  *
1569  * here?
1570  */
1571 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
1572 /*********************************************************************
1573  *
1574  * Function    :  sig_handler 
1575  *
1576  * Description :  Signal handler for different signals.
1577  *                Exit gracefully on TERM and INT
1578  *                or set a flag that will cause the errlog
1579  *                to be reopened by the main thread on HUP.
1580  *
1581  * Parameters  :
1582  *          1  :  the_signal = the signal cause this function to call
1583  *
1584  * Returns     :  - 
1585  *
1586  *********************************************************************/
1587 static void sig_handler(int the_signal)
1588 {
1589    switch(the_signal)
1590    {
1591       case SIGTERM:
1592       case SIGINT:
1593          log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
1594 #if defined(unix)
1595          if(pidfile)
1596          {
1597             unlink(pidfile);
1598          }
1599 #endif /* unix */
1600          exit(the_signal);
1601          break;
1602
1603       case SIGHUP:
1604 #if defined(unix)
1605          received_hup_signal = 1;
1606 #endif
1607          break;         
1608
1609       default:
1610          /* 
1611           * We shouldn't be here, unless we catch signals
1612           * in main() that we can't handle here!
1613           */
1614          log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
1615    }
1616    return;
1617
1618 }
1619 #endif
1620
1621
1622 /*********************************************************************
1623  *
1624  * Function    :  client_protocol_is_unsupported
1625  *
1626  * Description :  Checks if the client used a known unsupported
1627  *                protocol and deals with it by sending an error
1628  *                response.
1629  *
1630  * Parameters  :
1631  *          1  :  csp = Current client state (buffers, headers, etc...)
1632  *          2  :  req = the first request line send by the client
1633  *
1634  * Returns     :  TRUE if an error response has been generated, or
1635  *                FALSE if the request doesn't look invalid.
1636  *
1637  *********************************************************************/
1638 static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
1639 {
1640    /*
1641     * If it's a FTP or gopher request, we don't support it.
1642     *
1643     * These checks are better than nothing, but they might
1644     * not work in all configurations and some clients might
1645     * have problems digesting the answer.
1646     *
1647     * They should, however, never cause more problems than
1648     * Privoxy's old behaviour (returning the misleading HTML
1649     * error message:
1650     *
1651     * "Could not resolve http://(ftp|gopher)://example.org").
1652     */
1653    if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
1654    {
1655       const char *response = NULL;
1656       const char *protocol = NULL;
1657
1658       if (!strncmpic(req, "GET ftp://", 10))
1659       {
1660          response = FTP_RESPONSE;
1661          protocol = "FTP";
1662       }
1663       else
1664       {
1665          response = GOPHER_RESPONSE;
1666          protocol = "GOPHER";
1667       }
1668       log_error(LOG_LEVEL_ERROR,
1669          "%s tried to use Privoxy as %s proxy: %s",
1670          csp->ip_addr_str, protocol, req);
1671       log_error(LOG_LEVEL_CLF,
1672          "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
1673       freez(req);
1674       write_socket(csp->cfd, response, strlen(response));
1675
1676       return TRUE;
1677    }
1678
1679    return FALSE;
1680 }
1681
1682
1683 /*********************************************************************
1684  *
1685  * Function    :  get_request_destination_elsewhere
1686  *
1687  * Description :  If the client's request was redirected into
1688  *                Privoxy without the client's knowledge,
1689  *                the request line lacks the destination host.
1690  *
1691  *                This function tries to get it elsewhere,
1692  *                provided accept-intercepted-requests is enabled.
1693  *
1694  *                "Elsewhere" currently only means "Host: header",
1695  *                but in the future we may ask the redirecting
1696  *                packet filter to look the destination up.
1697  *
1698  *                If the destination stays unknown, an error
1699  *                response is send to the client and headers
1700  *                are freed so that chat() can return directly.
1701  *
1702  * Parameters  :
1703  *          1  :  csp = Current client state (buffers, headers, etc...)
1704  *          2  :  headers = a header list
1705  *
1706  * Returns     :  JB_ERR_OK if the destination is now known, or
1707  *                JB_ERR_PARSE if it isn't.
1708  *
1709  *********************************************************************/
1710 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers)
1711 {
1712    char *req;
1713
1714    if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
1715    {
1716       log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
1717          " Privoxy isn't configured to accept intercepted requests.",
1718          csp->ip_addr_str, csp->http->cmd);
1719       /* XXX: Use correct size */
1720       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1721          csp->ip_addr_str, csp->http->cmd);
1722
1723       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1724       destroy_list(headers);
1725
1726       return JB_ERR_PARSE;
1727    }
1728    else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http))
1729    {
1730       /* Split the domain we just got for pattern matching */
1731       init_domain_components(csp->http);
1732
1733       return JB_ERR_OK;
1734    }
1735    else
1736    {
1737       /* We can't work without destination. Go spread the news.*/
1738
1739       req = list_to_text(headers);
1740       chomp(req);
1741       /* XXX: Use correct size */
1742       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1743          csp->ip_addr_str, csp->http->cmd);
1744       log_error(LOG_LEVEL_ERROR,
1745          "Privoxy was unable to get the destination for %s's request:\n%s\n%s",
1746          csp->ip_addr_str, csp->http->cmd, req);
1747       freez(req);
1748
1749       write_socket(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE));
1750       destroy_list(headers);
1751
1752       return JB_ERR_PARSE;
1753    }
1754    /*
1755     * TODO: If available, use PF's ioctl DIOCNATLOOK as last resort
1756     * to get the destination IP address, use it as host directly
1757     * or do a reverse DNS lookup first.
1758     */
1759 }
1760
1761
1762 /*********************************************************************
1763  *
1764  * Function    :  get_server_headers
1765  *
1766  * Description :  Parses server headers in iob and fills them
1767  *                into csp->headers so that they can later be
1768  *                handled by sed().
1769  *
1770  * Parameters  :
1771  *          1  :  csp = Current client state (buffers, headers, etc...)
1772  *
1773  * Returns     :  JB_ERR_OK if everything went fine, or
1774  *                JB_ERR_PARSE if the headers were incomplete.
1775  *
1776  *********************************************************************/
1777 static jb_err get_server_headers(struct client_state *csp)
1778 {
1779    int continue_hack_in_da_house = 0;
1780    char * header;
1781
1782    while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house)
1783    {
1784       if (header == NULL)
1785       {
1786          /*
1787           * continue hack in da house. Ignore the ending of
1788           * this head and continue enlisting header lines.
1789           * The reason is described below.
1790           */
1791          enlist(csp->headers, "");
1792          continue_hack_in_da_house = 0;
1793          continue;
1794       }
1795       else if (0 == strncmpic(header, "HTTP/1.1 100", 12))
1796       {
1797          /*
1798           * It's a bodyless continue response, don't
1799           * stop header parsing after reaching its end.
1800           *
1801           * As a result Privoxy will concatenate the
1802           * next response's head and parse and deliver
1803           * the headers as if they belonged to one request.
1804           *
1805           * The client will separate them because of the
1806           * empty line between them.
1807           *
1808           * XXX: What we're doing here is clearly against
1809           * the intended purpose of the continue header,
1810           * and under some conditions (HTTP/1.0 client request)
1811           * it's a standard violation.
1812           *
1813           * Anyway, "sort of against the spec" is preferable
1814           * to "always getting confused by Continue responses"
1815           * (Privoxy's behaviour before this hack was added)
1816           */
1817          log_error(LOG_LEVEL_HEADER, "Continue hack in da house.");
1818          continue_hack_in_da_house = 1;
1819       }
1820       else if (*header == '\0') 
1821       {
1822          /*
1823           * If the header is empty, but the Continue hack
1824           * isn't active, we can assume that we reached the
1825           * end of the buffer before we hit the end of the
1826           * head.
1827           *
1828           * Inform the caller an let it decide how to handle it.
1829           */
1830          return JB_ERR_PARSE;
1831       }
1832
1833       if (JB_ERR_MEMORY == enlist(csp->headers, header))
1834       {
1835          /*
1836           * XXX: Should we quit the request and return a
1837           * out of memory error page instead?
1838           */
1839          log_error(LOG_LEVEL_ERROR,
1840             "Out of memory while enlisting server headers. %s lost.",
1841             header);
1842       }
1843       freez(header);
1844    }
1845
1846    return JB_ERR_OK;
1847 }
1848
1849
1850 /*********************************************************************
1851  *
1852  * Function    :  crunch_reason
1853  *
1854  * Description :  Translates the crunch reason code into a string.
1855  *
1856  * Parameters  :
1857  *          1  :  rsp = a http_response
1858  *
1859  * Returns     :  A string with the crunch reason or an error description.
1860  *
1861  *********************************************************************/
1862 static const char *crunch_reason(const struct http_response *rsp)
1863 {
1864    char * reason = NULL;
1865
1866    assert(rsp != NULL);
1867    if (rsp == NULL)
1868    {
1869       return "Internal error while searching for crunch reason";
1870    }
1871
1872    switch (rsp->reason)
1873    {
1874       case RSP_REASON_UNSUPPORTED:
1875          reason = "Unsupported HTTP feature";
1876          break;
1877       case RSP_REASON_BLOCKED:
1878          reason = "Blocked";
1879          break;
1880       case RSP_REASON_UNTRUSTED:
1881          reason = "Untrusted";
1882          break;
1883       case RSP_REASON_REDIRECTED:
1884          reason = "Redirected";
1885          break;
1886       case RSP_REASON_CGI_CALL:
1887          reason = "CGI Call";
1888          break;
1889       case RSP_REASON_NO_SUCH_DOMAIN:
1890          reason = "DNS failure";
1891          break;
1892       case RSP_REASON_FORWARDING_FAILED:
1893          reason = "Forwarding failed";
1894          break;
1895       case RSP_REASON_CONNECT_FAILED:
1896          reason = "Connection failure";
1897          break;
1898       case RSP_REASON_OUT_OF_MEMORY:
1899          reason = "Out of memory (may mask other reasons)";
1900          break;
1901       default:
1902          reason = "No reason recorded";
1903          break;
1904    }
1905
1906    return reason;
1907 }
1908
1909
1910 /*********************************************************************
1911  *
1912  * Function    :  send_crunch_response
1913  *
1914  * Description :  Delivers already prepared response for
1915  *                intercepted requests, logs the interception
1916  *                and frees the response.
1917  *
1918  * Parameters  :
1919  *          1  :  csp = Current client state (buffers, headers, etc...)
1920  *          1  :  rsp = Fully prepared response. Will be freed on exit.
1921  *
1922  * Returns     :  Nothing.
1923  *
1924  *********************************************************************/
1925 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp)
1926 {
1927       const struct http_request *http = csp->http;
1928       char status_code[4];
1929
1930       assert(rsp != NULL);
1931       assert(rsp->head != NULL);
1932
1933       if (rsp == NULL)
1934       {
1935          /*
1936           * Not supposed to happen. If it does
1937           * anyway, treat it as an unknown error.
1938           */
1939          cgi_error_unknown(csp, rsp, RSP_REASON_INTERNAL_ERROR);
1940          /* return code doesn't matter */
1941       }
1942
1943       if (rsp == NULL)
1944       {
1945          /* If rsp is still NULL, we have serious internal problems. */
1946          log_error(LOG_LEVEL_FATAL,
1947             "NULL response in send_crunch_response and cgi_error_unknown failed as well.");
1948       }
1949
1950       /*
1951        * Extract the status code from the actual head
1952        * that was send to the client. It is the only
1953        * way to get it right for all requests, including
1954        * the fixed ones for out-of-memory problems.
1955        *
1956        * A head starts like this: 'HTTP/1.1 200...'
1957        *                           0123456789|11
1958        *                                     10
1959        */
1960       status_code[0] = rsp->head[9];
1961       status_code[1] = rsp->head[10];
1962       status_code[2] = rsp->head[11];
1963       status_code[3] = '\0';
1964
1965       /* Write the answer to the client */
1966       if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1967        || write_socket(csp->cfd, rsp->body, rsp->content_length))
1968       {
1969          /* There is nothing we can do about it. */
1970          log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", csp->http->host);
1971       }
1972
1973       /* Log that the request was crunched and why. */
1974       log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
1975       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
1976          csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
1977
1978       /* Clean up and return */
1979       if (cgi_error_memory() != rsp)
1980       {
1981          free_http_response(rsp);
1982       } 
1983       return;
1984 }
1985
1986
1987 #if 0
1988 /*********************************************************************
1989  *
1990  * Function    :  request_contains_null_bytes
1991  *
1992  * Description :  Checks for NULL bytes in the request and sends
1993  *                an error message to the client if any were found.
1994  *
1995  *                XXX: currently not used, see comment in chat().
1996  *
1997  * Parameters  :
1998  *          1  :  csp = Current client state (buffers, headers, etc...)
1999  *          2  :  buf = Data from the client's request to check.
2000  *          3  :  len = The data length.
2001  *
2002  * Returns     :  TRUE if the request contained one or more NULL bytes, or
2003  *                FALSE otherwise.
2004  *
2005  *********************************************************************/
2006 static int request_contains_null_bytes(const struct client_state *csp, char *buf, int len)
2007 {
2008    size_t c_len; /* Request lenght when treated as C string */
2009
2010    c_len = strlen(buf);
2011
2012    if (c_len < len)
2013    {
2014       /*
2015        * Null byte(s) found. Log the request,
2016        * return an error response and hang up.
2017        */
2018       size_t tmp_len = c_len;
2019
2020       do
2021       {
2022         /*
2023          * Replace NULL byte(s) with '°' characters
2024          * so the request can be logged as string.
2025          * XXX: Is there a better replacement character?
2026          */
2027          buf[tmp_len]='°';
2028          tmp_len += strlen(buf+tmp_len);
2029       } while (tmp_len < len);
2030
2031       log_error(LOG_LEVEL_ERROR, "%s\'s request contains at least one NULL byte "
2032          "(length=%d, strlen=%u).", csp->ip_addr_str, len, c_len);
2033       log_error(LOG_LEVEL_HEADER, 
2034          "Offending request data with NULL bytes turned into \'°\' characters: %s", buf);
2035
2036       write_socket(csp->cfd, NULL_BYTE_RESPONSE, strlen(NULL_BYTE_RESPONSE));
2037
2038       /* XXX: Log correct size */
2039       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
2040
2041       return TRUE;
2042    }
2043
2044    return FALSE;
2045 }
2046 #endif
2047
2048
2049 /*********************************************************************
2050  *
2051  * Function    :  crunch_response_triggered
2052  *
2053  * Description :  Checks if the request has to be crunched,
2054  *                and delivers the crunch response if necessary.
2055  *
2056  * Parameters  :
2057  *          1  :  csp = Current client state (buffers, headers, etc...)
2058  *          2  :  crunchers = list of cruncher functions to run
2059  *
2060  * Returns     :  TRUE if the request was answered with a crunch response
2061  *                FALSE otherwise.
2062  *
2063  *********************************************************************/
2064 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
2065 {
2066    struct http_response *rsp = NULL;
2067    const struct cruncher *c;
2068
2069    /*
2070     * If CGI request crunching is disabled,
2071     * check the CGI dispatcher out of order to
2072     * prevent unintentional blocks or redirects. 
2073     */
2074    if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_CRUNCHING)
2075        && (NULL != (rsp = dispatch_cgi(csp))))
2076    {
2077       /* Deliver, log and free the interception response. */
2078       send_crunch_response(csp, rsp);
2079       return TRUE;
2080    }
2081
2082    for (c = crunchers; c->cruncher != NULL; c++)
2083    {
2084       /*
2085        * Check the cruncher if either Privoxy is toggled
2086        * on and the request isn't forced, or if the cruncher
2087        * applies to forced requests as well.
2088        */
2089       if (((csp->flags & CSP_FLAG_TOGGLED_ON) &&
2090           !(csp->flags & CSP_FLAG_FORCED)) ||
2091           (c->flags & CF_IGNORE_FORCE))
2092       {
2093          rsp = c->cruncher(csp);
2094          if (NULL != rsp)
2095          {
2096             /* Deliver, log and free the interception response. */
2097             send_crunch_response(csp, rsp);
2098 #ifdef FEATURE_STATISTICS
2099             if (c->flags & CF_COUNT_AS_REJECT)
2100             {
2101                csp->flags |= CSP_FLAG_REJECTED;
2102             }
2103 #endif /* def FEATURE_STATISTICS */
2104
2105             return TRUE;
2106          }
2107       }
2108    }
2109
2110    return FALSE;
2111 }
2112
2113
2114 /*********************************************************************
2115  *
2116  * Function    :  build_request_line
2117  *
2118  * Description :  Builds the HTTP request line.
2119  *
2120  *                If a HTTP forwarder is used it expects the whole URL,
2121  *                web servers only get the path.
2122  *
2123  * Parameters  :
2124  *          1  :  csp = Current client state (buffers, headers, etc...)
2125  *          2  :  fwd = The forwarding spec used for the request
2126  *                XXX: Should use http->fwd instead.
2127  *          3  :  request_line = The old request line which will be replaced.
2128  *
2129  * Returns     :  Nothing. Terminates in case of memory problems.
2130  *
2131  *********************************************************************/
2132 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line)
2133 {
2134    struct http_request *http = csp->http;
2135
2136    assert(http->ssl == 0);
2137
2138    /*
2139     * Downgrade http version from 1.1 to 1.0
2140     * if +downgrade action applies.
2141     */
2142    if ( (csp->action->flags & ACTION_DOWNGRADE)
2143      && (!strcmpic(http->ver, "HTTP/1.1")))
2144    {
2145       freez(http->ver);
2146       http->ver = strdup("HTTP/1.0");
2147
2148       if (http->ver == NULL)
2149       {
2150          log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
2151       }
2152    }
2153
2154    /*
2155     * Rebuild the request line.
2156     */
2157    freez(*request_line);
2158    *request_line = strdup(http->gpc);
2159    string_append(request_line, " ");
2160
2161    if (fwd->forward_host)
2162    {
2163       string_append(request_line, http->url);
2164    }
2165    else
2166    {
2167       string_append(request_line, http->path);
2168    }
2169    string_append(request_line, " ");
2170    string_append(request_line, http->ver);
2171
2172    if (*request_line == NULL)
2173    {
2174       log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
2175    }
2176    log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", *request_line);
2177 }
2178
2179
2180 /*********************************************************************
2181  *
2182  * Function    :  change_request_destination
2183  *
2184  * Description :  Parse a (rewritten) request line and regenerate
2185  *                the http request data.
2186  *
2187  * Parameters  :
2188  *          1  :  csp = Current client state (buffers, headers, etc...)
2189  *
2190  * Returns     :  Forwards the parse_http_request() return code.
2191  *                Terminates in case of memory problems.
2192  *
2193  *********************************************************************/
2194 static jb_err change_request_destination(struct client_state *csp)
2195 {
2196    struct http_request *http = csp->http;
2197    jb_err err;
2198
2199    log_error(LOG_LEVEL_INFO, "Rewrite detected: %s", csp->headers->first->str);
2200    free_http_request(http);
2201    err = parse_http_request(csp->headers->first->str, http);
2202    if (JB_ERR_OK != err)
2203    {
2204       log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
2205          jb_err_to_string(err));
2206    }
2207    else
2208    {
2209       /* XXX: ocmd is a misleading name */
2210       http->ocmd = strdup(http->cmd);
2211       if (http->ocmd == NULL)
2212       {
2213          log_error(LOG_LEVEL_FATAL,
2214             "Out of memory copying rewritten HTTP request line");
2215       }
2216    }
2217
2218    return err;
2219 }
2220
2221
2222 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2223 /*********************************************************************
2224  *
2225  * Function    :  server_response_is_complete
2226  *
2227  * Description :  Determines whether we should stop reading
2228  *                from the server socket.
2229  *
2230  * Parameters  :
2231  *          1  :  csp = Current client state (buffers, headers, etc...)
2232  *          2  :  content_length = Length of content received so far.
2233  *
2234  * Returns     :  TRUE if the response is complete,
2235  *                FALSE otherwise.
2236  *
2237  *********************************************************************/
2238 static int server_response_is_complete(struct client_state *csp,
2239    unsigned long long content_length)
2240 {
2241    int content_length_known = !!(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET);
2242
2243    if (!strcmpic(csp->http->gpc, "HEAD"))
2244    {
2245       /*
2246        * "HEAD" implies no body, we are thus expecting
2247        * no content. XXX: incomplete "list" of methods?
2248        */
2249       csp->expected_content_length = 0;
2250       content_length_known = TRUE;
2251    }
2252
2253    if (csp->http->status == 304)
2254    {
2255       /*
2256        * Expect no body. XXX: incomplete "list" of status codes?
2257        */
2258       csp->expected_content_length = 0;
2259       content_length_known = TRUE;
2260    }
2261
2262    return (content_length_known && ((0 == csp->expected_content_length)
2263             || (csp->expected_content_length <= content_length)));
2264 }
2265
2266
2267 /*********************************************************************
2268  *
2269  * Function    :  wait_for_alive_connections
2270  *
2271  * Description :  Waits for alive connections to timeout.
2272  *
2273  * Parameters  :  N/A
2274  *
2275  * Returns     :  N/A
2276  *
2277  *********************************************************************/
2278 static void wait_for_alive_connections()
2279 {
2280    int connections_alive = close_unusable_connections();
2281
2282    while (0 < connections_alive)
2283    {
2284       log_error(LOG_LEVEL_CONNECT,
2285          "Waiting for %d connections to timeout.",
2286          connections_alive);
2287       sleep(60);
2288       connections_alive = close_unusable_connections();
2289    }
2290
2291    log_error(LOG_LEVEL_CONNECT, "No connections to wait for left.");
2292
2293 }
2294
2295
2296 /*********************************************************************
2297  *
2298  * Function    :  save_connection_destination
2299  *
2300  * Description :  Remembers a connection for reuse later on.
2301  *
2302  * Parameters  :
2303  *          1  :  sfd  = Open socket to remember.
2304  *          2  :  http = The destination for the connection.
2305  *          3  :  fwd  = The forwarder settings used.
2306  *          3  :  server_connection  = storage.
2307  *
2308  * Returns     : void
2309  *
2310  *********************************************************************/
2311 void save_connection_destination(jb_socket sfd,
2312                                  const struct http_request *http,
2313                                  const struct forward_spec *fwd,
2314                                  struct reusable_connection *server_connection)
2315 {
2316    assert(sfd != JB_INVALID_SOCKET);
2317    assert(NULL != http->host);
2318    server_connection->host = strdup(http->host);
2319    if (NULL == server_connection->host)
2320    {
2321       log_error(LOG_LEVEL_FATAL, "Out of memory saving socket.");
2322    }
2323    server_connection->port = http->port;
2324
2325    assert(NULL != fwd);
2326    assert(server_connection->gateway_host == NULL);
2327    assert(server_connection->gateway_port == 0);
2328    assert(server_connection->forwarder_type == 0);
2329    assert(server_connection->forward_host == NULL);
2330    assert(server_connection->forward_port == 0);
2331
2332    server_connection->forwarder_type = fwd->type;
2333    if (NULL != fwd->gateway_host)
2334    {
2335       server_connection->gateway_host = strdup(fwd->gateway_host);
2336       if (NULL == server_connection->gateway_host)
2337       {
2338          log_error(LOG_LEVEL_FATAL, "Out of memory saving gateway_host.");
2339       }
2340    }
2341    else
2342    {
2343       server_connection->gateway_host = NULL;
2344    }
2345    server_connection->gateway_port = fwd->gateway_port;
2346
2347    if (NULL != fwd->forward_host)
2348    {
2349       server_connection->forward_host = strdup(fwd->forward_host);
2350       if (NULL == server_connection->forward_host)
2351       {
2352          log_error(LOG_LEVEL_FATAL, "Out of memory saving forward_host.");
2353       }
2354    }
2355    else
2356    {
2357       server_connection->forward_host = NULL;
2358    }
2359    server_connection->forward_port = fwd->forward_port;
2360 }
2361 #endif /* FEATURE_CONNECTION_KEEP_ALIVE */
2362
2363
2364 /*********************************************************************
2365  *
2366  * Function    :  mark_server_socket_tainted
2367  *
2368  * Description :  Makes sure we don't reuse a server socket
2369  *                (if we didn't read everything the server sent
2370  *                us reusing the socket would lead to garbage).
2371  *
2372  * Parameters  :
2373  *          1  :  csp = Current client state (buffers, headers, etc...)
2374  *
2375  * Returns     :  void.
2376  *
2377  *********************************************************************/
2378 static void mark_server_socket_tainted(struct client_state *csp)
2379 {
2380    if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE))
2381    {
2382       log_error(LOG_LEVEL_CONNECT, "Unsetting keep-alive flag.");
2383       csp->flags &= ~CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE;
2384    }
2385 }
2386
2387 /*********************************************************************
2388  *
2389  * Function    :  get_request_line
2390  *
2391  * Description : Read the client request line.
2392  *
2393  * Parameters  :
2394  *          1  :  csp = Current client state (buffers, headers, etc...)
2395  *
2396  * Returns     :  Pointer to request line or NULL in case of errors.
2397  *
2398  *********************************************************************/
2399 static char *get_request_line(struct client_state *csp)
2400 {
2401    char buf[BUFFER_SIZE];
2402    char *request_line = NULL;
2403    int len;
2404
2405    memset(buf, 0, sizeof(buf));
2406
2407    do
2408    {
2409       if (!data_is_available(csp->cfd, csp->config->socket_timeout))
2410       {
2411          log_error(LOG_LEVEL_ERROR,
2412             "Stopped waiting for the request line.");
2413          write_socket(csp->cfd, CONNECTION_TIMEOUT_RESPONSE,
2414             strlen(CONNECTION_TIMEOUT_RESPONSE));
2415          return NULL;
2416       }
2417
2418       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
2419
2420       if (len <= 0) return NULL;
2421
2422       /*
2423        * If there is no memory left for buffering the
2424        * request, there is nothing we can do but hang up
2425        */
2426       if (add_to_iob(csp, buf, len))
2427       {
2428          return NULL;
2429       }
2430
2431       request_line = get_header(csp->iob);
2432
2433    } while ((NULL != request_line) && ('\0' == *request_line));
2434
2435    return request_line;
2436
2437 }
2438
2439
2440 /*********************************************************************
2441  *
2442  * Function    :  receive_client_request
2443  *
2444  * Description : Read the client's request (more precisely the
2445  *               client headers) and answer it if necessary.
2446  *
2447  *               Note that since we're not using select() we could get
2448  *               blocked here if a client connected, then didn't say
2449  *               anything!
2450  *
2451  * Parameters  :
2452  *          1  :  csp = Current client state (buffers, headers, etc...)
2453  *
2454  * Returns     :  JB_ERR_OK, JB_ERR_PARSE or JB_ERR_MEMORY
2455  *
2456  *********************************************************************/
2457 static jb_err receive_client_request(struct client_state *csp)
2458 {
2459    char buf[BUFFER_SIZE];
2460    char *p;
2461    char *req = NULL;
2462    struct http_request *http;
2463    int len;
2464    jb_err err;
2465
2466    /* Temporary copy of the client's headers before they get enlisted in csp->headers */
2467    struct list header_list;
2468    struct list *headers = &header_list;
2469
2470    http = csp->http;
2471
2472    memset(buf, 0, sizeof(buf));
2473
2474    req = get_request_line(csp);
2475    if (req == NULL)
2476    {
2477       return JB_ERR_PARSE;
2478    }
2479    assert(*req != '\0');
2480
2481    if (client_protocol_is_unsupported(csp, req))
2482    {
2483       return JB_ERR_PARSE;
2484    }
2485
2486 #ifdef FEATURE_FORCE_LOAD
2487    /*
2488     * If this request contains the FORCE_PREFIX and blocks
2489     * aren't enforced, get rid of it and set the force flag.
2490     */
2491    if (strstr(req, FORCE_PREFIX))
2492    {
2493       if (csp->config->feature_flags & RUNTIME_FEATURE_ENFORCE_BLOCKS)
2494       {
2495          log_error(LOG_LEVEL_FORCE,
2496             "Ignored force prefix in request: \"%s\".", req);
2497       }
2498       else
2499       {
2500          strclean(req, FORCE_PREFIX);
2501          log_error(LOG_LEVEL_FORCE, "Enforcing request: \"%s\".", req);
2502          csp->flags |= CSP_FLAG_FORCED;
2503       }
2504    }
2505 #endif /* def FEATURE_FORCE_LOAD */
2506
2507    err = parse_http_request(req, http);
2508    freez(req);
2509    if (JB_ERR_OK != err)
2510    {
2511       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
2512       /* XXX: Use correct size */
2513       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
2514       log_error(LOG_LEVEL_ERROR,
2515          "Couldn't parse request line received from %s: %s",
2516          csp->ip_addr_str, jb_err_to_string(err));
2517
2518       free_http_request(http);
2519       return JB_ERR_PARSE;
2520    }
2521
2522    /* grab the rest of the client's headers */
2523    init_list(headers);
2524    for (;;)
2525    {
2526       p = get_header(csp->iob);
2527
2528       if (p == NULL)
2529       {
2530          /* There are no additional headers to read. */
2531          break;
2532       }
2533
2534       if (*p == '\0')
2535       {
2536          /*
2537           * We didn't receive a complete header
2538           * line yet, get the rest of it.
2539           */
2540          if (!data_is_available(csp->cfd, csp->config->socket_timeout))
2541          {
2542             log_error(LOG_LEVEL_ERROR,
2543                "Stopped grabbing the client headers.");
2544             return JB_ERR_PARSE;
2545          }
2546
2547          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
2548          if (len <= 0)
2549          {
2550             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
2551             destroy_list(headers);
2552             return JB_ERR_PARSE;
2553          }
2554          
2555          if (add_to_iob(csp, buf, len))
2556          {
2557             /*
2558              * If there is no memory left for buffering the
2559              * request, there is nothing we can do but hang up
2560              */
2561             destroy_list(headers);
2562             return JB_ERR_MEMORY;
2563          }
2564       }
2565       else
2566       {
2567          /*
2568           * We were able to read a complete
2569           * header and can finaly enlist it.
2570           */
2571          enlist(headers, p);
2572          freez(p);
2573       }
2574    }
2575
2576    if (http->host == NULL)
2577    {
2578       /*
2579        * If we still don't know the request destination,
2580        * the request is invalid or the client uses
2581        * Privoxy without its knowledge.
2582        */
2583       if (JB_ERR_OK != get_request_destination_elsewhere(csp, headers))
2584       {
2585          /*
2586           * Our attempts to get the request destination
2587           * elsewhere failed or Privoxy is configured
2588           * to only accept proxy requests.
2589           *
2590           * An error response has already been send
2591           * and we're done here.
2592           */
2593          return JB_ERR_PARSE;
2594       }
2595    }
2596
2597    /*
2598     * Determine the actions for this URL
2599     */
2600 #ifdef FEATURE_TOGGLE
2601    if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
2602    {
2603       /* Most compatible set of actions (i.e. none) */
2604       init_current_action(csp->action);
2605    }
2606    else
2607 #endif /* ndef FEATURE_TOGGLE */
2608    {
2609       get_url_actions(csp, http);
2610    }
2611
2612    /* 
2613     * Save a copy of the original request for logging
2614     */
2615    http->ocmd = strdup(http->cmd);
2616    if (http->ocmd == NULL)
2617    {
2618       log_error(LOG_LEVEL_FATAL,
2619          "Out of memory copying HTTP request line");
2620    }
2621    enlist(csp->headers, http->cmd);
2622
2623    /* Append the previously read headers */
2624    list_append_list_unique(csp->headers, headers);
2625    destroy_list(headers);
2626
2627    return JB_ERR_OK;
2628
2629 }
2630
2631
2632 /*********************************************************************
2633  *
2634  * Function    : parse_client_request
2635  *
2636  * Description : Parses the client's request and decides what to do
2637  *               with it.
2638  *
2639  *               Note that since we're not using select() we could get
2640  *               blocked here if a client connected, then didn't say
2641  *               anything!
2642  *
2643  * Parameters  :
2644  *          1  :  csp = Current client state (buffers, headers, etc...)
2645  *
2646  * Returns     :  JB_ERR_OK or JB_ERR_PARSE
2647  *
2648  *********************************************************************/
2649 static jb_err parse_client_request(struct client_state *csp)
2650 {
2651    struct http_request *http = csp->http;
2652    jb_err err;
2653
2654    err = sed(csp, FILTER_CLIENT_HEADERS);
2655    if (JB_ERR_OK != err)
2656    {
2657       /* XXX: Should be handled in sed(). */
2658       assert(err == JB_ERR_PARSE);
2659       log_error(LOG_LEVEL_FATAL, "Failed to parse client headers.");
2660    }
2661    csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
2662
2663    /* Check request line for rewrites. */
2664    if ((NULL == csp->headers->first->str)
2665       || (strcmp(http->cmd, csp->headers->first->str) &&
2666          (JB_ERR_OK != change_request_destination(csp))))
2667    {
2668       /*
2669        * A header filter broke the request line - bail out.
2670        */
2671       write_socket(csp->cfd, MESSED_UP_REQUEST_RESPONSE, strlen(MESSED_UP_REQUEST_RESPONSE));
2672       /* XXX: Use correct size */
2673       log_error(LOG_LEVEL_CLF,
2674          "%s - - [%T] \"Invalid request generated\" 500 0", csp->ip_addr_str);
2675       log_error(LOG_LEVEL_ERROR,
2676          "Invalid request line after applying header filters.");
2677       free_http_request(http);
2678
2679       return JB_ERR_PARSE;
2680    }
2681
2682    return JB_ERR_OK;
2683
2684 }
2685
2686
2687 /*********************************************************************
2688  *
2689  * Function    :  chat
2690  *
2691  * Description :  Once a connection to the client has been accepted,
2692  *                this function is called (via serve()) to handle the
2693  *                main business of the communication.  When this
2694  *                function returns, the caller must close the client
2695  *                socket handle.
2696  *
2697  *                FIXME: chat is nearly thousand lines long.
2698  *                Ridiculous.
2699  *
2700  * Parameters  :
2701  *          1  :  csp = Current client state (buffers, headers, etc...)
2702  *
2703  * Returns     :  Nothing.
2704  *
2705  *********************************************************************/
2706 static void chat(struct client_state *csp)
2707 {
2708    char buf[BUFFER_SIZE];
2709    char *hdr;
2710    char *p;
2711    fd_set rfds;
2712    int n;
2713    jb_socket maxfd;
2714    int server_body;
2715    int ms_iis5_hack = 0;
2716    unsigned long long byte_count = 0;
2717    int forwarded_connect_retries = 0;
2718    int max_forwarded_connect_retries = csp->config->forwarded_connect_retries;
2719    const struct forward_spec *fwd;
2720    struct http_request *http;
2721    long len = 0; /* for buffer sizes (and negative error codes) */
2722
2723    /* Function that does the content filtering for the current request */
2724    filter_function_ptr content_filter = NULL;
2725
2726    /* Skeleton for HTTP response, if we should intercept the request */
2727    struct http_response *rsp;
2728    struct timeval timeout;
2729
2730    memset(buf, 0, sizeof(buf));
2731
2732    http = csp->http;
2733
2734    if (receive_client_request(csp) != JB_ERR_OK)
2735    {
2736       return;
2737    }
2738    if (parse_client_request(csp) != JB_ERR_OK)
2739    {
2740       return;
2741    }
2742
2743    /* decide how to route the HTTP request */
2744    fwd = forward_url(csp, http);
2745    if (NULL == fwd)
2746    {
2747       log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
2748       /* Never get here - LOG_LEVEL_FATAL causes program exit */
2749       return;
2750    }
2751
2752    /*
2753     * build the http request to send to the server
2754     * we have to do one of the following:
2755     *
2756     * create = use the original HTTP request to create a new
2757     *          HTTP request that has either the path component
2758     *          without the http://domainspec (w/path) or the
2759     *          full orininal URL (w/url)
2760     *          Note that the path and/or the HTTP version may
2761     *          have been altered by now.
2762     *
2763     * connect = Open a socket to the host:port of the server
2764     *           and short-circuit server and client socket.
2765     *
2766     * pass =  Pass the request unchanged if forwarding a CONNECT
2767     *         request to a parent proxy. Note that we'll be sending
2768     *         the CFAIL message ourselves if connecting to the parent
2769     *         fails, but we won't send a CSUCCEED message if it works,
2770     *         since that would result in a double message (ours and the
2771     *         parent's). After sending the request to the parent, we simply
2772     *         tunnel.
2773     *
2774     * here's the matrix:
2775     *                        SSL
2776     *                    0        1
2777     *                +--------+--------+
2778     *                |        |        |
2779     *             0  | create | connect|
2780     *                | w/path |        |
2781     *  Forwarding    +--------+--------+
2782     *                |        |        |
2783     *             1  | create | pass   |
2784     *                | w/url  |        |
2785     *                +--------+--------+
2786     *
2787     */
2788
2789    if (http->ssl && connect_port_is_forbidden(csp))
2790    {
2791       const char *acceptable_connect_ports =
2792          csp->action->string[ACTION_STRING_LIMIT_CONNECT];
2793       assert(NULL != acceptable_connect_ports);
2794       log_error(LOG_LEVEL_INFO, "Request from %s marked for blocking. "
2795          "limit-connect{%s} doesn't allow CONNECT requests to port %d.",
2796          csp->ip_addr_str, acceptable_connect_ports, csp->http->port);
2797       csp->action->flags |= ACTION_BLOCK;
2798       http->ssl = 0;
2799    }
2800
2801    if (http->ssl == 0)
2802    {
2803       freez(csp->headers->first->str);
2804       build_request_line(csp, fwd, &csp->headers->first->str);
2805    }
2806
2807    /*
2808     * We have a request. Check if one of the crunchers wants it.
2809     */
2810    if (crunch_response_triggered(csp, crunchers_all))
2811    {
2812       /*
2813        * Yes. The client got the crunch response
2814        * and we are done here after cleaning up.
2815        */
2816       /* XXX: why list_remove_all()? */
2817       list_remove_all(csp->headers);
2818
2819       return;
2820    }
2821
2822    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
2823
2824    if (fwd->forward_host)
2825    {
2826       log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
2827          fwd->forward_host, fwd->forward_port, http->hostport);
2828    }
2829    else
2830    {
2831       log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
2832    }
2833
2834    /* here we connect to the server, gateway, or the forwarder */
2835
2836 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2837    if ((csp->sfd != JB_INVALID_SOCKET)
2838       && socket_is_still_usable(csp->sfd)
2839       && connection_destination_matches(&csp->server_connection, http, fwd))
2840    {
2841       log_error(LOG_LEVEL_CONNECT,
2842          "Reusing server socket %u. Opened for %s.",
2843          csp->sfd, csp->server_connection.host);
2844    }
2845    else
2846    {
2847       if (csp->sfd != JB_INVALID_SOCKET)
2848       {
2849          log_error(LOG_LEVEL_CONNECT,
2850             "Closing server socket %u. Opened for %s.",
2851             csp->sfd, csp->server_connection.host);
2852          close_socket(csp->sfd);
2853          mark_connection_closed(&csp->server_connection);
2854       }
2855 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2856
2857       while ((csp->sfd = forwarded_connect(fwd, http, csp))
2858          && (errno == EINVAL)
2859          && (forwarded_connect_retries++ < max_forwarded_connect_retries))
2860       {
2861          log_error(LOG_LEVEL_ERROR,
2862             "failed request #%u to connect to %s. Trying again.",
2863             forwarded_connect_retries, http->hostport);
2864       }
2865
2866       if (csp->sfd == JB_INVALID_SOCKET)
2867       {
2868          if (fwd->type != SOCKS_NONE)
2869          {
2870             /* Socks error. */
2871             rsp = error_response(csp, "forwarding-failed", errno);
2872          }
2873          else if (errno == EINVAL)
2874          {
2875             rsp = error_response(csp, "no-such-domain", errno);
2876          }
2877          else
2878          {
2879             rsp = error_response(csp, "connect-failed", errno);
2880             log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E",
2881                http->hostport);
2882          }
2883
2884          /* Write the answer to the client */
2885          if (rsp != NULL)
2886          {
2887             send_crunch_response(csp, rsp);
2888          }
2889
2890          return;
2891       }
2892 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2893       save_connection_destination(csp->sfd, http, fwd, &csp->server_connection);
2894    }
2895 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2896
2897    hdr = list_to_text(csp->headers);
2898    if (hdr == NULL)
2899    {
2900       /* FIXME Should handle error properly */
2901       log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
2902    }
2903    list_remove_all(csp->headers);
2904
2905    if (fwd->forward_host || (http->ssl == 0))
2906    {
2907       /*
2908        * Write the client's (modified) header to the server
2909        * (along with anything else that may be in the buffer)
2910        */
2911       if (write_socket(csp->sfd, hdr, strlen(hdr))
2912        || (flush_socket(csp->sfd, csp->iob) <  0))
2913       {
2914          log_error(LOG_LEVEL_CONNECT,
2915             "write header to: %s failed: %E", http->hostport);
2916
2917          rsp = error_response(csp, "connect-failed", errno);
2918          if (rsp)
2919          {
2920             send_crunch_response(csp, rsp);
2921          }
2922
2923          freez(hdr);
2924          return;
2925       }
2926    }
2927    else
2928    {
2929       /*
2930        * We're running an SSL tunnel and we're not forwarding,
2931        * so just send the "connect succeeded" message to the
2932        * client, flush the rest, and get out of the way.
2933        */
2934       if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
2935       {
2936          freez(hdr);
2937          return;
2938       }
2939       IOB_RESET(csp);
2940    }
2941
2942    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
2943
2944    /* we're finished with the client's header */
2945    freez(hdr);
2946
2947    maxfd = (csp->cfd > csp->sfd) ? csp->cfd : csp->sfd;
2948
2949    /* pass data between the client and server
2950     * until one or the other shuts down the connection.
2951     */
2952
2953    server_body = 0;
2954
2955    for (;;)
2956    {
2957 #ifdef __OS2__
2958       /*
2959        * FD_ZERO here seems to point to an errant macro which crashes.
2960        * So do this by hand for now...
2961        */
2962       memset(&rfds,0x00,sizeof(fd_set));
2963 #else
2964       FD_ZERO(&rfds);
2965 #endif
2966       FD_SET(csp->cfd, &rfds);
2967       FD_SET(csp->sfd, &rfds);
2968
2969 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2970       if ((csp->flags & CSP_FLAG_CHUNKED)
2971          && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2972          && ((csp->iob->eod - csp->iob->cur) >= 5)
2973          && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
2974       {
2975          log_error(LOG_LEVEL_CONNECT,
2976             "Looks like we read the last chunk together with "
2977             "the server headers. We better stop reading.");
2978          byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2979          csp->expected_content_length = byte_count;
2980          csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2981       }
2982       if (server_body && server_response_is_complete(csp, byte_count))
2983       {
2984          log_error(LOG_LEVEL_CONNECT,
2985             "Done reading from server. Expected content length: %llu. "
2986             "Actual content length: %llu. Most recently received: %d.",
2987             csp->expected_content_length, byte_count, len);
2988          len = 0;
2989          /*
2990           * XXX: should not jump around,
2991           * chat() is complicated enough already.
2992           */
2993          goto reading_done;
2994       }
2995 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
2996
2997       timeout.tv_sec = csp->config->socket_timeout;
2998       timeout.tv_usec = 0;
2999       n = select((int)maxfd+1, &rfds, NULL, NULL, &timeout);
3000
3001       if (n == 0)
3002       {
3003          log_error(LOG_LEVEL_ERROR,
3004             "Didn't receive data in time: %s", http->url);
3005          if ((byte_count == 0) && (http->ssl == 0))
3006          {
3007             write_socket(csp->cfd, CONNECTION_TIMEOUT_RESPONSE,
3008                strlen(CONNECTION_TIMEOUT_RESPONSE));
3009          }
3010          mark_server_socket_tainted(csp);
3011          return;
3012       }
3013       else if (n < 0)
3014       {
3015          log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
3016          mark_server_socket_tainted(csp);
3017          return;
3018       }
3019
3020       /*
3021        * This is the body of the browser's request,
3022        * just read and write it.
3023        *
3024        * XXX: Make sure the client doesn't use pipelining
3025        * behind Privoxy's back.
3026        */
3027       if (FD_ISSET(csp->cfd, &rfds))
3028       {
3029          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
3030
3031          if (len <= 0)
3032          {
3033             /* XXX: not sure if this is necessary. */
3034             mark_server_socket_tainted(csp);
3035             break; /* "game over, man" */
3036          }
3037
3038          if (write_socket(csp->sfd, buf, (size_t)len))
3039          {
3040             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
3041             mark_server_socket_tainted(csp);
3042             return;
3043          }
3044          continue;
3045       }
3046
3047       /*
3048        * The server wants to talk. It could be the header or the body.
3049        * If `hdr' is null, then it's the header otherwise it's the body.
3050        * FIXME: Does `hdr' really mean `host'? No.
3051        */
3052       if (FD_ISSET(csp->sfd, &rfds))
3053       {
3054          fflush(0);
3055          len = read_socket(csp->sfd, buf, sizeof(buf) - 1);
3056
3057          if (len < 0)
3058          {
3059             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
3060
3061             if (http->ssl && (fwd->forward_host == NULL))
3062             {
3063                /*
3064                 * Just hang up. We already confirmed the client's CONNECT
3065                 * request with status code 200 and unencrypted content is
3066                 * no longer welcome.
3067                 */
3068                log_error(LOG_LEVEL_ERROR,
3069                   "CONNECT already confirmed. Unable to tell the client about the problem.");
3070                return;
3071             }
3072             else if (byte_count)
3073             {
3074                /*
3075                 * Just hang up. We already transmitted the original headers
3076                 * and parts of the original content and therefore missed the
3077                 * chance to send an error message (without risking data corruption).
3078                 *
3079                 * XXX: we could retry with a fancy range request here.
3080                 */
3081                log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
3082                   "Unable to tell the client about the problem.");
3083                mark_server_socket_tainted(csp);
3084                return;
3085             }
3086             /*
3087              * XXX: Consider handling the cases above the same.
3088              */
3089             mark_server_socket_tainted(csp);
3090             len = 0;
3091          }
3092
3093 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3094          if (csp->flags & CSP_FLAG_CHUNKED)
3095          {
3096             if ((len >= 5) && !memcmp(buf+len-5, "0\r\n\r\n", 5))
3097             {
3098                /* XXX: this is a temporary hack */
3099                log_error(LOG_LEVEL_CONNECT,
3100                   "Looks like we reached the end of the last chunk. "
3101                   "We better stop reading.");
3102                csp->expected_content_length = byte_count + (unsigned long long)len;
3103                csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
3104             }
3105          }
3106          reading_done:
3107 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
3108
3109          /*
3110           * Add a trailing zero to let be able to use string operations.
3111           * XXX: do we still need this with filter_popups gone?
3112           */
3113          buf[len] = '\0';
3114
3115          /*
3116           * Normally, this would indicate that we've read
3117           * as much as the server has sent us and we can
3118           * close the client connection.  However, Microsoft
3119           * in its wisdom has released IIS/5 with a bug that
3120           * prevents it from sending the trailing \r\n in
3121           * a 302 redirect header (and possibly other headers).
3122           * To work around this if we've haven't parsed
3123           * a full header we'll append a trailing \r\n
3124           * and see if this now generates a valid one.
3125           *
3126           * This hack shouldn't have any impacts.  If we've
3127           * already transmitted the header or if this is a
3128           * SSL connection, then we won't bother with this
3129           * hack.  So we only work on partially received
3130           * headers.  If we append a \r\n and this still
3131           * doesn't generate a valid header, then we won't
3132           * transmit anything to the client.
3133           */
3134          if (len == 0)
3135          {
3136
3137             if (server_body || http->ssl)
3138             {
3139                /*
3140                 * If we have been buffering up the document,
3141                 * now is the time to apply content modification
3142                 * and send the result to the client.
3143                 */
3144                if (content_filter)
3145                {
3146                   p = execute_content_filter(csp, content_filter);
3147                   /*
3148                    * If the content filter fails, use the original
3149                    * buffer and length.
3150                    * (see p != NULL ? p : csp->iob->cur below)
3151                    */
3152                   if (NULL == p)
3153                   {
3154                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
3155                   }
3156
3157                   if (JB_ERR_OK != update_server_headers(csp))
3158                   {
3159                      log_error(LOG_LEVEL_FATAL,
3160                         "Failed to update server headers. after filtering.");
3161                   }
3162
3163                   hdr = list_to_text(csp->headers);
3164                   if (hdr == NULL)
3165                   {
3166                      /* FIXME Should handle error properly */
3167                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
3168                   }
3169
3170                   if (write_socket(csp->cfd, hdr, strlen(hdr))
3171                    || write_socket(csp->cfd,
3172                          ((p != NULL) ? p : csp->iob->cur), (size_t)csp->content_length))
3173                   {
3174                      log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
3175                      freez(hdr);
3176                      freez(p);
3177                      mark_server_socket_tainted(csp);
3178                      return;
3179                   }
3180
3181                   freez(hdr);
3182                   freez(p);
3183                }
3184
3185                break; /* "game over, man" */
3186             }
3187
3188             /*
3189              * This is NOT the body, so
3190              * Let's pretend the server just sent us a blank line.
3191              */
3192             snprintf(buf, sizeof(buf), "\r\n");
3193             len = (int)strlen(buf);
3194
3195             /*
3196              * Now, let the normal header parsing algorithm below do its
3197              * job.  If it fails, we'll exit instead of continuing.
3198              */
3199
3200             ms_iis5_hack = 1;
3201          }
3202
3203          /*
3204           * If this is an SSL connection or we're in the body
3205           * of the server document, just write it to the client,
3206           * unless we need to buffer the body for later content-filtering
3207           */
3208          if (server_body || http->ssl)
3209          {
3210             if (content_filter)
3211             {
3212                /*
3213                 * If there is no memory left for buffering the content, or the buffer limit
3214                 * has been reached, switch to non-filtering mode, i.e. make & write the
3215                 * header, flush the iob and buf, and get out of the way.
3216                 */
3217                if (add_to_iob(csp, buf, len))
3218                {
3219                   size_t hdrlen;
3220                   long flushed;
3221
3222                   log_error(LOG_LEVEL_INFO,
3223                      "Flushing header and buffers. Stepping back from filtering.");
3224
3225                   hdr = list_to_text(csp->headers);
3226                   if (hdr == NULL)
3227                   {
3228                      /* 
3229                       * Memory is too tight to even generate the header.
3230                       * Send our static "Out-of-memory" page.
3231                       */
3232                      log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
3233                      rsp = cgi_error_memory();
3234                      send_crunch_response(csp, rsp);
3235                      mark_server_socket_tainted(csp);
3236                      return;
3237                   }
3238                   hdrlen = strlen(hdr);
3239
3240                   if (write_socket(csp->cfd, hdr, hdrlen)
3241                    || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0)
3242                    || (write_socket(csp->cfd, buf, (size_t)len)))
3243                   {
3244                      log_error(LOG_LEVEL_CONNECT,
3245                         "Flush header and buffers to client failed: %E");
3246                      freez(hdr);
3247                      mark_server_socket_tainted(csp);
3248                      return;
3249                   }
3250
3251                   /*
3252                    * Reset the byte_count to the amount of bytes
3253                    * we just flushed. len will be added a few lines below,
3254                    * hdrlen doesn't matter for LOG_LEVEL_CLF.
3255                    */
3256                   byte_count = (unsigned long long)flushed;
3257                   freez(hdr);
3258                   content_filter = NULL;
3259                   server_body = 1;
3260                }
3261             }
3262             else
3263             {
3264                if (write_socket(csp->cfd, buf, (size_t)len))
3265                {
3266                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
3267                   mark_server_socket_tainted(csp);
3268                   return;
3269                }
3270             }
3271             byte_count += (unsigned long long)len;
3272             continue;
3273          }
3274          else
3275          {
3276             const char *header_start;
3277             /*
3278              * We're still looking for the end of the server's header.
3279              * Buffer up the data we just read.  If that fails, there's
3280              * little we can do but send our static out-of-memory page.
3281              */
3282             if (add_to_iob(csp, buf, len))
3283             {
3284                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
3285                rsp = cgi_error_memory();
3286                send_crunch_response(csp, rsp);               
3287                mark_server_socket_tainted(csp);
3288                return;
3289             }
3290
3291             header_start = csp->iob->cur;
3292
3293             /* Convert iob into something sed() can digest */
3294             if (JB_ERR_PARSE == get_server_headers(csp))
3295             {
3296                if (ms_iis5_hack)
3297                {
3298                   /*
3299                    * Well, we tried our MS IIS/5 hack and it didn't work.
3300                    * The header is incomplete and there isn't anything
3301                    * we can do about it.
3302                    */
3303                   log_error(LOG_LEVEL_ERROR, "Invalid server headers. "
3304                      "Applying the MS IIS5 hack didn't help.");
3305                   log_error(LOG_LEVEL_CLF,
3306                      "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
3307                   write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
3308                      strlen(INVALID_SERVER_HEADERS_RESPONSE));
3309                   mark_server_socket_tainted(csp);
3310                   return;
3311                }
3312                else
3313                {
3314                   /*
3315                    * Since we have to wait for more from the server before
3316                    * we can parse the headers we just continue here.
3317                    */
3318                   long header_offset = csp->iob->cur - header_start;
3319                   assert(csp->iob->cur >= header_start);
3320                   byte_count += (unsigned long long)(len - header_offset);
3321                   log_error(LOG_LEVEL_CONNECT, "Continuing buffering headers. "
3322                      "byte_count: %llu. header_offset: %d. len: %d.",
3323                      byte_count, header_offset, len);
3324                   continue;
3325                }
3326             }
3327
3328             /* Did we actually get anything? */
3329             if (NULL == csp->headers->first)
3330             {
3331                log_error(LOG_LEVEL_ERROR, "Empty server or forwarder response.");
3332                log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
3333                write_socket(csp->cfd, NO_SERVER_DATA_RESPONSE, strlen(NO_SERVER_DATA_RESPONSE));
3334                free_http_request(http);
3335                mark_server_socket_tainted(csp);
3336                return;
3337             }
3338
3339             assert(csp->headers->first->str);
3340             assert(!http->ssl);
3341             if (strncmpic(csp->headers->first->str, "HTTP", 4) &&
3342                 strncmpic(csp->headers->first->str, "ICY", 3))
3343             {
3344                /*
3345                 * It doesn't look like a HTTP (or Shoutcast) response:
3346                 * tell the client and log the problem.
3347                 */
3348                if (strlen(csp->headers->first->str) > 30)
3349                {
3350                   csp->headers->first->str[30] = '\0';
3351                }
3352                log_error(LOG_LEVEL_ERROR,
3353                   "Invalid server or forwarder response. Starts with: %s",
3354                   csp->headers->first->str);
3355                log_error(LOG_LEVEL_CLF,
3356                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
3357                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
3358                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
3359                free_http_request(http);
3360                mark_server_socket_tainted(csp);
3361                return;
3362             }
3363
3364             /*
3365              * We have now received the entire server header,
3366              * filter it and send the result to the client
3367              */
3368             if (JB_ERR_OK != sed(csp, FILTER_SERVER_HEADERS))
3369             {
3370                log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
3371             }
3372             hdr = list_to_text(csp->headers);
3373             if (hdr == NULL)
3374             {
3375                /* FIXME Should handle error properly */
3376                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
3377             }
3378
3379             if (crunch_response_triggered(csp, crunchers_light))
3380             {
3381                /*
3382                 * One of the tags created by a server-header
3383                 * tagger triggered a crunch. We already
3384                 * delivered the crunch response to the client
3385                 * and are done here after cleaning up.
3386                 */
3387                 freez(hdr);
3388                 mark_server_socket_tainted(csp);
3389                 return;
3390             }
3391             /* Buffer and pcrs filter this if appropriate. */
3392
3393             if (!http->ssl) /* We talk plaintext */
3394             {
3395                content_filter = get_filter_function(csp);
3396             }
3397             /*
3398              * Only write if we're not buffering for content modification
3399              */
3400             if (!content_filter)
3401             {
3402                /*
3403                 * Write the server's (modified) header to
3404                 * the client (along with anything else that
3405                 * may be in the buffer)
3406                 */
3407
3408                if (write_socket(csp->cfd, hdr, strlen(hdr))
3409                 || ((len = flush_socket(csp->cfd, csp->iob)) < 0))
3410                {
3411                   log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
3412
3413                   /*
3414                    * The write failed, so don't bother mentioning it
3415                    * to the client... it probably can't hear us anyway.
3416                    */
3417                   freez(hdr);
3418                   mark_server_socket_tainted(csp);
3419                   return;
3420                }
3421
3422                byte_count += (unsigned long long)len;
3423             }
3424             else
3425             {
3426                /*
3427                 * XXX: the header lenght should probably
3428                 * be calculated by get_server_headers().
3429                 */
3430                long header_length = csp->iob->cur - header_start;
3431                assert(csp->iob->cur > header_start);
3432                byte_count += (unsigned long long)(len - header_length);
3433             }
3434
3435             /* we're finished with the server's header */
3436
3437             freez(hdr);
3438             server_body = 1;
3439
3440             /*
3441              * If this was a MS IIS/5 hack then it means the server
3442              * has already closed the connection. Nothing more to read.
3443              * Time to bail.
3444              */
3445             if (ms_iis5_hack)
3446             {
3447                log_error(LOG_LEVEL_ERROR,
3448                   "Closed server connection detected. "
3449                   "Applying the MS IIS5 hack didn't help.");
3450                log_error(LOG_LEVEL_CLF,
3451                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
3452                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
3453                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
3454                mark_server_socket_tainted(csp);
3455                return;
3456             }
3457          }
3458          continue;
3459       }
3460       mark_server_socket_tainted(csp);
3461       return; /* huh? we should never get here */
3462    }
3463
3464    if (csp->content_length == 0)
3465    {
3466       /*
3467        * If Privoxy didn't recalculate the Content-Lenght,
3468        * byte_count is still correct.
3469        */
3470       csp->content_length = byte_count;
3471    }
3472
3473 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3474    if ((csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
3475       && (csp->expected_content_length != byte_count))
3476    {
3477       log_error(LOG_LEVEL_CONNECT,
3478          "Received %llu bytes while expecting %llu.",
3479          byte_count, csp->expected_content_length);
3480       mark_server_socket_tainted(csp);
3481    }
3482 #endif
3483
3484    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
3485       csp->ip_addr_str, http->ocmd, csp->content_length);
3486 }
3487
3488
3489 /*********************************************************************
3490  *
3491  * Function    :  serve
3492  *
3493  * Description :  This is little more than chat.  We only "serve" to
3494  *                to close (or remember) any socket that chat may have
3495  *                opened.
3496  *
3497  * Parameters  :
3498  *          1  :  csp = Current client state (buffers, headers, etc...)
3499  *
3500  * Returns     :  N/A
3501  *
3502  *********************************************************************/
3503 #ifdef AMIGA
3504 void serve(struct client_state *csp)
3505 #else /* ifndef AMIGA */
3506 static void serve(struct client_state *csp)
3507 #endif /* def AMIGA */
3508 {
3509 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3510    int continue_chatting = 0;
3511    do
3512    {
3513       chat(csp);
3514
3515       continue_chatting = (csp->config->feature_flags
3516          & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
3517          && (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
3518          && (csp->cfd != JB_INVALID_SOCKET)
3519          && (csp->sfd != JB_INVALID_SOCKET)
3520          && socket_is_still_usable(csp->sfd);
3521
3522       /*
3523        * Get the csp in a mostly vergin state again.
3524        * XXX: Should be done elsewhere.
3525        */
3526       csp->content_type = 0;
3527       csp->content_length = 0;
3528       csp->expected_content_length = 0;
3529       list_remove_all(csp->headers);
3530       freez(csp->iob->buf);
3531       memset(csp->iob, 0, sizeof(csp->iob));
3532       freez(csp->error_message);
3533       free_http_request(csp->http);
3534       destroy_list(csp->headers);
3535       destroy_list(csp->tags);
3536       free_current_action(csp->action);
3537       if (NULL != csp->fwd)
3538       {
3539          unload_forward_spec(csp->fwd);
3540          csp->fwd = NULL;
3541       }
3542
3543       /* XXX: Store per-connection flags someplace else. */
3544       csp->flags = CSP_FLAG_ACTIVE | (csp->flags & CSP_FLAG_TOGGLED_ON);
3545
3546       if (continue_chatting)
3547       {
3548          log_error(LOG_LEVEL_CONNECT,
3549             "Waiting for the next client request. "
3550             "Keeping the server socket %d to %s open.",
3551             csp->sfd, csp->server_connection.host);
3552
3553          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
3554             && data_is_available(csp->cfd, csp->config->keep_alive_timeout)
3555             && socket_is_still_usable(csp->cfd))
3556          {
3557             log_error(LOG_LEVEL_CONNECT, "Client request arrived in "
3558                "time or the client closed the connection.");
3559          }
3560          else
3561          {
3562             log_error(LOG_LEVEL_CONNECT,
3563                "No additional client request received in time. "
3564                "Closing server socket %d, initially opened for %s.",
3565                csp->sfd, csp->server_connection.host);
3566             break;
3567          }
3568       }
3569       else if (csp->sfd != JB_INVALID_SOCKET)
3570       {
3571          log_error(LOG_LEVEL_CONNECT,
3572             "The connection on server socket %d to %s isn't reusable. "
3573             "Closing.", csp->sfd, csp->server_connection.host);
3574       }
3575    } while (continue_chatting);
3576 #else
3577    chat(csp);
3578 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
3579
3580    if (csp->sfd != JB_INVALID_SOCKET)
3581    {
3582       close_socket(csp->sfd);
3583    }
3584
3585    if (csp->cfd != JB_INVALID_SOCKET)
3586    {
3587       close_socket(csp->cfd);
3588    }
3589
3590    csp->flags &= ~CSP_FLAG_ACTIVE;
3591
3592 }
3593
3594
3595 #ifdef __BEOS__
3596 /*********************************************************************
3597  *
3598  * Function    :  server_thread
3599  *
3600  * Description :  We only exist to call `serve' in a threaded environment.
3601  *
3602  * Parameters  :
3603  *          1  :  data = Current client state (buffers, headers, etc...)
3604  *
3605  * Returns     :  Always 0.
3606  *
3607  *********************************************************************/
3608 static int32 server_thread(void *data)
3609 {
3610    serve((struct client_state *) data);
3611    return 0;
3612
3613 }
3614 #endif
3615
3616
3617 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3618 /*********************************************************************
3619  *
3620  * Function    :  usage
3621  *
3622  * Description :  Print usage info & exit.
3623  *
3624  * Parameters  :  Pointer to argv[0] for identifying ourselves
3625  *
3626  * Returns     :  No. ,-)
3627  *
3628  *********************************************************************/
3629 static void usage(const char *myname)
3630 {
3631    printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
3632           "Usage: %s "
3633 #if defined(unix)
3634           "[--chroot] "
3635 #endif /* defined(unix) */
3636           "[--help] "
3637 #if defined(unix)
3638           "[--no-daemon] [--pidfile pidfile] [--pre-chroot-nslookup hostname] [--user user[.group]] "
3639 #endif /* defined(unix) */
3640           "[--version] [configfile]\n"
3641           "Aborting\n", myname);
3642
3643    exit(2);
3644
3645 }
3646 #endif /* #if !defined(_WIN32) || defined(_WIN_CONSOLE) */
3647
3648
3649 #ifdef MUTEX_LOCKS_AVAILABLE
3650 /*********************************************************************
3651  *
3652  * Function    :  privoxy_mutex_lock
3653  *
3654  * Description :  Locks a mutex.
3655  *
3656  * Parameters  :
3657  *          1  :  mutex = The mutex to lock.
3658  *
3659  * Returns     :  Void. May exit in case of errors.
3660  *
3661  *********************************************************************/
3662 void privoxy_mutex_lock(privoxy_mutex_t *mutex)
3663 {
3664 #ifdef FEATURE_PTHREAD
3665    int err = pthread_mutex_lock(mutex);
3666    if (err)
3667    {
3668       if (mutex != &log_mutex)
3669       {
3670          log_error(LOG_LEVEL_FATAL,
3671             "Mutex locking failed: %s.\n", strerror(err));
3672       }
3673       exit(1);
3674    }
3675 #else
3676    EnterCriticalSection(mutex);
3677 #endif /* def FEATURE_PTHREAD */
3678 }
3679
3680
3681 /*********************************************************************
3682  *
3683  * Function    :  privoxy_mutex_unlock
3684  *
3685  * Description :  Unlocks a mutex.
3686  *
3687  * Parameters  :
3688  *          1  :  mutex = The mutex to unlock.
3689  *
3690  * Returns     :  Void. May exit in case of errors.
3691  *
3692  *********************************************************************/
3693 void privoxy_mutex_unlock(privoxy_mutex_t *mutex)
3694 {
3695 #ifdef FEATURE_PTHREAD
3696    int err = pthread_mutex_unlock(mutex);
3697    if (err)
3698    {
3699       if (mutex != &log_mutex)
3700       {
3701          log_error(LOG_LEVEL_FATAL,
3702             "Mutex unlocking failed: %s.\n", strerror(err));
3703       }
3704       exit(1);
3705    }
3706 #else
3707    LeaveCriticalSection(mutex);
3708 #endif /* def FEATURE_PTHREAD */
3709 }
3710
3711
3712 /*********************************************************************
3713  *
3714  * Function    :  privoxy_mutex_init
3715  *
3716  * Description :  Prepares a mutex.
3717  *
3718  * Parameters  :
3719  *          1  :  mutex = The mutex to initialize.
3720  *
3721  * Returns     :  Void. May exit in case of errors.
3722  *
3723  *********************************************************************/
3724 static void privoxy_mutex_init(privoxy_mutex_t *mutex)
3725 {
3726 #ifdef FEATURE_PTHREAD
3727    int err = pthread_mutex_init(mutex, 0);
3728    if (err)
3729    {
3730       printf("Fatal error. Mutex initialization failed: %s.\n",
3731          strerror(err));
3732       exit(1);
3733    }
3734 #else
3735    InitializeCriticalSection(mutex);
3736 #endif /* def FEATURE_PTHREAD */
3737 }
3738 #endif /* def MUTEX_LOCKS_AVAILABLE */
3739
3740 /*********************************************************************
3741  *
3742  * Function    :  initialize_mutexes
3743  *
3744  * Description :  Prepares mutexes if mutex support is available.
3745  *
3746  * Parameters  :  None
3747  *
3748  * Returns     :  Void, exits in case of errors.
3749  *
3750  *********************************************************************/
3751 static void initialize_mutexes(void)
3752 {
3753 #ifdef MUTEX_LOCKS_AVAILABLE
3754    /*
3755     * Prepare global mutex semaphores
3756     */
3757    privoxy_mutex_init(&log_mutex);
3758    privoxy_mutex_init(&log_init_mutex);
3759    privoxy_mutex_init(&connection_reuse_mutex);
3760
3761    /*
3762     * XXX: The assumptions below are a bit naive
3763     * and can cause locks that aren't necessary.
3764     *
3765     * For example older FreeBSD versions (< 6.x?)
3766     * have no gethostbyname_r, but gethostbyname is
3767     * thread safe.
3768     */
3769 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
3770    privoxy_mutex_init(&resolver_mutex);
3771 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
3772    /*
3773     * XXX: should we use a single mutex for
3774     * localtime() and gmtime() as well?
3775     */
3776 #ifndef HAVE_GMTIME_R
3777    privoxy_mutex_init(&gmtime_mutex);
3778 #endif /* ndef HAVE_GMTIME_R */
3779
3780 #ifndef HAVE_LOCALTIME_R
3781    privoxy_mutex_init(&localtime_mutex);
3782 #endif /* ndef HAVE_GMTIME_R */
3783
3784 #ifndef HAVE_RANDOM
3785    privoxy_mutex_init(&rand_mutex);
3786 #endif /* ndef HAVE_RANDOM */
3787 #endif /* def MUTEX_LOCKS_AVAILABLE */
3788 }
3789
3790
3791 /*********************************************************************
3792  *
3793  * Function    :  main
3794  *
3795  * Description :  Load the config file and start the listen loop.
3796  *                This function is a lot more *sane* with the `load_config'
3797  *                and `listen_loop' functions; although it stills does
3798  *                a *little* too much for my taste.
3799  *
3800  * Parameters  :
3801  *          1  :  argc = Number of parameters (including $0).
3802  *          2  :  argv = Array of (char *)'s to the parameters.
3803  *
3804  * Returns     :  1 if : can't open config file, unrecognized directive,
3805  *                stats requested in multi-thread mode, can't open the
3806  *                log file, can't open the jar file, listen port is invalid,
3807  *                any load fails, and can't bind port.
3808  *
3809  *                Else main never returns, the process must be signaled
3810  *                to terminate execution.  Or, on Windows, use the
3811  *                "File", "Exit" menu option.
3812  *
3813  *********************************************************************/
3814 #ifdef __MINGW32__
3815 int real_main(int argc, const char *argv[])
3816 #else
3817 int main(int argc, const char *argv[])
3818 #endif
3819 {
3820    int argc_pos = 0;
3821    unsigned int random_seed;
3822 #ifdef unix
3823    struct passwd *pw = NULL;
3824    struct group *grp = NULL;
3825    char *p;
3826    int do_chroot = 0;
3827    char *pre_chroot_nslookup_to_load_resolver = NULL;
3828 #endif
3829
3830    Argc = argc;
3831    Argv = argv;
3832
3833    configfile =
3834 #if !defined(_WIN32)
3835    "config"
3836 #else
3837    "config.txt"
3838 #endif
3839       ;
3840
3841    /* Prepare mutexes if supported and necessary. */
3842    initialize_mutexes();
3843
3844    /* Enable logging until further notice. */
3845    init_log_module();
3846
3847    /*
3848     * Parse the command line arguments
3849     *
3850     * XXX: simply printing usage information in case of
3851     * invalid arguments isn't particularly user friendly.
3852     */
3853    while (++argc_pos < argc)
3854    {
3855 #ifdef _WIN32
3856       /* Check to see if the service must be installed or uninstalled */
3857       if (strncmp(argv[argc_pos], "--install", 9) == 0)
3858       {
3859          const char *pName = argv[argc_pos] + 9;
3860          if (*pName == ':')
3861             pName++;
3862          exit( (install_service(pName)) ? 0 : 1 );
3863       }
3864       else if (strncmp(argv[argc_pos], "--uninstall", + 11) == 0)
3865       {
3866          const char *pName = argv[argc_pos] + 11;
3867          if (*pName == ':')
3868             pName++;
3869          exit((uninstall_service(pName)) ? 0 : 1);
3870       }
3871       else if (strcmp(argv[argc_pos], "--service" ) == 0)
3872       {
3873          bRunAsService = TRUE;
3874          w32_set_service_cwd();
3875          atexit(w32_service_exit_notify);
3876       }
3877       else
3878 #endif /* defined(_WIN32) */
3879
3880
3881 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3882
3883       if (strcmp(argv[argc_pos], "--help") == 0)
3884       {
3885          usage(argv[0]);
3886       }
3887
3888       else if(strcmp(argv[argc_pos], "--version") == 0)
3889       {
3890          printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
3891          exit(0);
3892       }
3893
3894 #if defined(unix)
3895
3896       else if (strcmp(argv[argc_pos], "--no-daemon" ) == 0)
3897       {
3898          set_debug_level(LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO);
3899          no_daemon = 1;
3900       }
3901
3902       else if (strcmp(argv[argc_pos], "--pidfile" ) == 0)
3903       {
3904          if (++argc_pos == argc) usage(argv[0]);
3905          pidfile = strdup(argv[argc_pos]);
3906       }
3907
3908       else if (strcmp(argv[argc_pos], "--user" ) == 0)
3909       {
3910          if (++argc_pos == argc) usage(argv[argc_pos]);
3911
3912          if ((NULL != (p = strchr(argv[argc_pos], '.'))) && *(p + 1) != '0')
3913          {
3914             *p++ = '\0';
3915             if (NULL == (grp = getgrnam(p)))
3916             {
3917                log_error(LOG_LEVEL_FATAL, "Group %s not found.", p);
3918             }
3919          }
3920
3921          if (NULL == (pw = getpwnam(argv[argc_pos])))
3922          {
3923             log_error(LOG_LEVEL_FATAL, "User %s not found.", argv[argc_pos]);
3924          }
3925
3926          if (p != NULL) *--p = '\0';
3927       }
3928
3929       else if (strcmp(argv[argc_pos], "--pre-chroot-nslookup" ) == 0)
3930       {
3931          if (++argc_pos == argc) usage(argv[0]);
3932          pre_chroot_nslookup_to_load_resolver = strdup(argv[argc_pos]);
3933       }
3934
3935       else if (strcmp(argv[argc_pos], "--chroot" ) == 0)
3936       {
3937          do_chroot = 1;
3938       }
3939 #endif /* defined(unix) */
3940
3941       else if (argc_pos + 1 != argc)
3942       {
3943          /*
3944           * This is neither the last command line
3945           * option, nor was it recognized before,
3946           * therefore it must be invalid.
3947           */
3948          usage(argv[0]);
3949       }
3950       else
3951
3952 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
3953       {
3954          configfile = argv[argc_pos];
3955       }
3956
3957    } /* -END- while (more arguments) */
3958
3959    show_version(Argv[0]);
3960
3961 #if defined(unix)
3962    if ( *configfile != '/' )
3963    {
3964       char cwd[BUFFER_SIZE];
3965       char *abs_file;
3966       size_t abs_file_size; 
3967
3968       /* make config-filename absolute here */
3969       if (NULL == getcwd(cwd, sizeof(cwd)))
3970       {
3971          perror("failed to get current working directory");
3972          exit( 1 );
3973       }
3974
3975       /* XXX: why + 5? */
3976       abs_file_size = strlen(cwd) + strlen(configfile) + 5;
3977       basedir = strdup(cwd);
3978
3979       if (NULL == basedir ||
3980           NULL == (abs_file = malloc(abs_file_size)))
3981       {
3982          perror("malloc failed");
3983          exit( 1 );
3984       }
3985       strlcpy(abs_file, basedir, abs_file_size);
3986       strlcat(abs_file, "/", abs_file_size );
3987       strlcat(abs_file, configfile, abs_file_size);
3988       configfile = abs_file;
3989    }
3990 #endif /* defined unix */
3991
3992
3993    files->next = NULL;
3994    clients->next = NULL;
3995
3996    /* XXX: factor out initialising after the next stable release. */
3997 #ifdef AMIGA
3998    InitAmiga();
3999 #elif defined(_WIN32)
4000    InitWin32();
4001 #endif
4002
4003    random_seed = (unsigned int)time(NULL);
4004 #ifdef HAVE_RANDOM
4005    srandom(random_seed);
4006 #else
4007    srand(random_seed);
4008 #endif /* ifdef HAVE_RANDOM */
4009
4010    /*
4011     * Unix signal handling
4012     *
4013     * Catch the abort, interrupt and terminate signals for a graceful exit
4014     * Catch the hangup signal so the errlog can be reopened.
4015     * Ignore the broken pipe signals (FIXME: Why?)
4016     */
4017 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
4018 {
4019    int idx;
4020    const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP, 0 };
4021    const int ignored_signals[] = { SIGPIPE, 0 };
4022
4023    for (idx = 0; catched_signals[idx] != 0; idx++)
4024    {
4025 #ifdef sun /* FIXME: Is it safe to check for HAVE_SIGSET instead? */ 
4026       if (sigset(catched_signals[idx], sig_handler) == SIG_ERR)
4027 #else
4028       if (signal(catched_signals[idx], sig_handler) == SIG_ERR)
4029 #endif /* ifdef sun */
4030       {
4031          log_error(LOG_LEVEL_FATAL, "Can't set signal-handler for signal %d: %E", catched_signals[idx]);
4032       }
4033    }
4034
4035    for (idx = 0; ignored_signals[idx] != 0; idx++)
4036    {
4037       if (signal(ignored_signals[idx], SIG_IGN) == SIG_ERR)
4038       {
4039          log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for signal %d: %E", ignored_signals[idx]);
4040       }
4041    }
4042
4043 }
4044 #else /* ifdef _WIN32 */
4045 # ifdef _WIN_CONSOLE
4046    /*
4047     * We *are* in a windows console app.
4048     * Print a verbose messages about FAQ's and such
4049     */
4050    printf("%s", win32_blurb);
4051 # endif /* def _WIN_CONSOLE */
4052 #endif /* def _WIN32 */
4053
4054
4055    /* Initialize the CGI subsystem */
4056    cgi_init_error_messages();
4057
4058    /*
4059     * If runnig on unix and without the --nodaemon
4060     * option, become a daemon. I.e. fork, detach
4061     * from tty and get process group leadership
4062     */
4063 #if defined(unix)
4064 {
4065    pid_t pid = 0;
4066 #if 0
4067    int   fd;
4068 #endif
4069
4070    if (!no_daemon)
4071    {
4072       pid  = fork();
4073
4074       if ( pid < 0 ) /* error */
4075       {
4076          perror("fork");
4077          exit( 3 );
4078       }
4079       else if ( pid != 0 ) /* parent */
4080       {
4081          int status;
4082          pid_t wpid;
4083          /*
4084           * must check for errors
4085           * child died due to missing files aso
4086           */
4087          sleep( 1 );
4088          wpid = waitpid( pid, &status, WNOHANG );
4089          if ( wpid != 0 )
4090          {
4091             exit( 1 );
4092          }
4093          exit( 0 );
4094       }
4095       /* child */
4096 #if 1
4097       /* Should be more portable, but not as well tested */
4098       setsid();
4099 #else /* !1 */
4100 #ifdef __FreeBSD__
4101       setpgrp(0,0);
4102 #else /* ndef __FreeBSD__ */
4103       setpgrp();
4104 #endif /* ndef __FreeBSD__ */
4105       fd = open("/dev/tty", O_RDONLY);
4106       if ( fd )
4107       {
4108          /* no error check here */
4109          ioctl( fd, TIOCNOTTY,0 );
4110          close ( fd );
4111       }
4112 #endif /* 1 */
4113       /*
4114        * stderr (fd 2) will be closed later on,
4115        * when the config file has been parsed.
4116        */
4117
4118       close( 0 );
4119       close( 1 );
4120       chdir("/");
4121
4122    } /* -END- if (!no_daemon) */
4123
4124    /*
4125     * As soon as we have written the PID file, we can switch
4126     * to the user and group ID indicated by the --user option
4127     */
4128    write_pid_file();
4129
4130    if (NULL != pw)
4131    {
4132       if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid))
4133       {
4134          log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
4135       }
4136       if (NULL != grp)
4137       {
4138          if (setgroups(1, &grp->gr_gid))
4139          {
4140             log_error(LOG_LEVEL_FATAL, "setgroups() failed: %E");
4141          }
4142       }
4143       else if (initgroups(pw->pw_name, pw->pw_gid))
4144       {
4145          log_error(LOG_LEVEL_FATAL, "initgroups() failed: %E");
4146       }
4147       if (do_chroot)
4148       {
4149          if (!pw->pw_dir)
4150          {
4151             log_error(LOG_LEVEL_FATAL, "Home directory for %s undefined", pw->pw_name);
4152          }
4153          /* Read the time zone file from /etc before doing chroot. */
4154          tzset();
4155          if (NULL != pre_chroot_nslookup_to_load_resolver
4156              && '\0' != pre_chroot_nslookup_to_load_resolver[0])
4157          {
4158             /* Initialize resolver library. */
4159             (void) resolve_hostname_to_ip(pre_chroot_nslookup_to_load_resolver);
4160          }
4161          if (chroot(pw->pw_dir) < 0)
4162          {
4163             log_error(LOG_LEVEL_FATAL, "Cannot chroot to %s", pw->pw_dir);
4164          }
4165          if (chdir ("/"))
4166          {
4167             log_error(LOG_LEVEL_FATAL, "Cannot chdir /");
4168          }
4169       }
4170       if (setuid(pw->pw_uid))
4171       {
4172          log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
4173       }
4174       if (do_chroot)
4175       {
4176          char putenv_dummy[64];
4177
4178          strlcpy(putenv_dummy, "HOME=/", sizeof(putenv_dummy));
4179          if (putenv(putenv_dummy) != 0)
4180          {
4181             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): HOME");
4182          }                
4183
4184          snprintf(putenv_dummy, sizeof(putenv_dummy), "USER=%s", pw->pw_name);
4185          if (putenv(putenv_dummy) != 0)
4186          {
4187             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): USER");
4188          }
4189       }
4190    }
4191    else if (do_chroot)
4192    {
4193       log_error(LOG_LEVEL_FATAL, "Cannot chroot without --user argument.");
4194    }
4195 }
4196 #endif /* defined unix */
4197
4198 #ifdef _WIN32
4199    /* This will be FALSE unless the command line specified --service
4200     */
4201    if (bRunAsService)
4202    {
4203       /* Yup, so now we must attempt to establish a connection 
4204        * with the service dispatcher. This will only work if this
4205        * process was launched by the service control manager to
4206        * actually run as a service. If this isn't the case, i've
4207        * known it take around 30 seconds or so for the call to return.
4208        */
4209
4210       /* The StartServiceCtrlDispatcher won't return until the service is stopping */
4211       if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable))
4212       {
4213          /* Service has run, and at this point is now being stopped, so just return */
4214          return 0;
4215       }
4216
4217 #ifdef _WIN_CONSOLE
4218       printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n");
4219 #endif
4220       /* An error occurred. Usually it's because --service was wrongly specified
4221        * and we were unable to connect to the Service Control Dispatcher because
4222        * it wasn't expecting us and is therefore not listening.
4223        *
4224        * For now, just continue below to call the listen_loop function.
4225        */
4226    }
4227 #endif /* def _WIN32 */
4228
4229    listen_loop();
4230
4231    /* NOTREACHED */
4232    return(-1);
4233
4234 }
4235
4236
4237 /*********************************************************************
4238  *
4239  * Function    :  bind_port_helper
4240  *
4241  * Description :  Bind the listen port.  Handles logging, and aborts
4242  *                on failure.
4243  *
4244  * Parameters  :
4245  *          1  :  config = Privoxy configuration.  Specifies port
4246  *                         to bind to.
4247  *
4248  * Returns     :  Port that was opened.
4249  *
4250  *********************************************************************/
4251 static jb_socket bind_port_helper(struct configuration_spec * config)
4252 {
4253    int result;
4254    jb_socket bfd;
4255
4256    if (config->haddr == NULL)
4257    {
4258       log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
4259                 config->hport);
4260    }
4261    else
4262    {
4263       log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
4264                 config->hport, config->haddr);
4265    }
4266
4267    result = bind_port(config->haddr, config->hport, &bfd);
4268
4269    if (result < 0)
4270    {
4271       switch(result)
4272       {
4273          case -3 :
4274             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: "
4275                "There may be another Privoxy or some other "
4276                "proxy running on port %d",
4277                (NULL != config->haddr) ? config->haddr : "INADDR_ANY",
4278                       config->hport, config->hport);
4279
4280          case -2 :
4281             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: " 
4282                "The hostname is not resolvable",
4283                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
4284
4285          default :
4286             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E",
4287                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
4288       }
4289
4290       /* shouldn't get here */
4291       return JB_INVALID_SOCKET;
4292    }
4293
4294    config->need_bind = 0;
4295
4296    return bfd;
4297 }
4298
4299
4300 #ifdef _WIN32
4301 /* Without this simple workaround we get this compiler warning from _beginthread
4302  *     warning C4028: formal parameter 1 different from declaration
4303  */
4304 void w32_service_listen_loop(void *p)
4305 {
4306    listen_loop();
4307 }
4308 #endif /* def _WIN32 */
4309
4310
4311 /*********************************************************************
4312  *
4313  * Function    :  listen_loop
4314  *
4315  * Description :  bind the listen port and enter a "FOREVER" listening loop.
4316  *
4317  * Parameters  :  N/A
4318  *
4319  * Returns     :  Never.
4320  *
4321  *********************************************************************/
4322 static void listen_loop(void)
4323 {
4324    struct client_state *csp = NULL;
4325    jb_socket bfd;
4326    struct configuration_spec *config;
4327    unsigned int active_threads = 0;
4328
4329    config = load_config();
4330
4331 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
4332    /*
4333     * XXX: Should be relocated once it no
4334     * longer needs to emit log messages.
4335     */
4336    initialize_reusable_connections();
4337 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
4338
4339    bfd = bind_port_helper(config);
4340
4341 #ifdef FEATURE_GRACEFUL_TERMINATION
4342    while (!g_terminate)
4343 #else
4344    for (;;)
4345 #endif
4346    {
4347 #if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
4348       while (waitpid(-1, NULL, WNOHANG) > 0)
4349       {
4350          /* zombie children */
4351       }
4352 #endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
4353
4354       /*
4355        * Free data that was used by died threads
4356        */
4357       active_threads = sweep();
4358
4359 #if defined(unix)
4360       /*
4361        * Re-open the errlog after HUP signal
4362        */
4363       if (received_hup_signal)
4364       {
4365          if (NULL != config->logfile)
4366          {
4367             init_error_log(Argv[0], config->logfile);
4368          }
4369          received_hup_signal = 0;
4370       }
4371 #endif
4372
4373       if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
4374       {
4375          log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
4376          continue;
4377       }
4378
4379       csp->flags |= CSP_FLAG_ACTIVE;
4380       csp->sfd    = JB_INVALID_SOCKET;
4381
4382       csp->config = config = load_config();
4383
4384       if ( config->need_bind )
4385       {
4386          /*
4387           * Since we were listening to the "old port", we will not see
4388           * a "listen" param change until the next request.  So, at
4389           * least 1 more request must be made for us to find the new
4390           * setting.  I am simply closing the old socket and binding the
4391           * new one.
4392           *
4393           * Which-ever is correct, we will serve 1 more page via the
4394           * old settings.  This should probably be a "show-proxy-args"
4395           * request.  This should not be a so common of an operation
4396           * that this will hurt people's feelings.
4397           */
4398
4399          close_socket(bfd);
4400
4401          bfd = bind_port_helper(config);
4402       }
4403
4404       log_error(LOG_LEVEL_CONNECT, "Listening for new connections ... ");
4405
4406       if (!accept_connection(csp, bfd))
4407       {
4408          log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
4409
4410 #ifdef AMIGA
4411          if(!childs)
4412          {
4413             exit(1);
4414          }
4415 #endif
4416          freez(csp);
4417          continue;
4418       }
4419       else
4420       {
4421          log_error(LOG_LEVEL_CONNECT, "accepted connection from %s", csp->ip_addr_str);
4422       }
4423
4424 #ifdef FEATURE_TOGGLE
4425       if (global_toggle_state)
4426 #endif /* def FEATURE_TOGGLE */
4427       {
4428          csp->flags |= CSP_FLAG_TOGGLED_ON;
4429       }
4430
4431       if (run_loader(csp))
4432       {
4433          log_error(LOG_LEVEL_FATAL, "a loader failed - must exit");
4434          /* Never get here - LOG_LEVEL_FATAL causes program exit */
4435       }
4436
4437 #ifdef FEATURE_ACL
4438       if (block_acl(NULL,csp))
4439       {
4440          log_error(LOG_LEVEL_CONNECT, "Connection from %s dropped due to ACL", csp->ip_addr_str);
4441          close_socket(csp->cfd);
4442          freez(csp->ip_addr_str);
4443          freez(csp);
4444          continue;
4445       }
4446 #endif /* def FEATURE_ACL */
4447
4448       if ((0 != config->max_client_connections)
4449          && (active_threads >= config->max_client_connections))
4450       {
4451          log_error(LOG_LEVEL_CONNECT,
4452             "Rejecting connection from %s. Maximum number of connections reached.",
4453             csp->ip_addr_str);
4454          write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
4455             strlen(TOO_MANY_CONNECTIONS_RESPONSE));
4456          close_socket(csp->cfd);
4457          freez(csp->ip_addr_str);
4458          freez(csp);
4459          continue;
4460       }
4461
4462       /* add it to the list of clients */
4463       csp->next = clients->next;
4464       clients->next = csp;
4465
4466       if (config->multi_threaded)
4467       {
4468          int child_id;
4469
4470 /* this is a switch () statment in the C preprocessor - ugh */
4471 #undef SELECTED_ONE_OPTION
4472
4473 /* Use Pthreads in preference to native code */
4474 #if defined(FEATURE_PTHREAD) && !defined(SELECTED_ONE_OPTION)
4475 #define SELECTED_ONE_OPTION
4476          {
4477             pthread_t the_thread;
4478             pthread_attr_t attrs;
4479
4480             pthread_attr_init(&attrs);
4481             pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
4482             errno = pthread_create(&the_thread, &attrs,
4483                (void * (*)(void *))serve, csp);
4484             child_id = errno ? -1 : 0;
4485             pthread_attr_destroy(&attrs);
4486          }
4487 #endif
4488
4489 #if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
4490 #define SELECTED_ONE_OPTION
4491          child_id = _beginthread(
4492             (void (*)(void *))serve,
4493             64 * 1024,
4494             csp);
4495 #endif
4496
4497 #if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
4498 #define SELECTED_ONE_OPTION
4499          child_id = _beginthread(
4500             (void(* _Optlink)(void*))serve,
4501             NULL,
4502             64 * 1024,
4503             csp);
4504 #endif
4505
4506 #if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION)
4507 #define SELECTED_ONE_OPTION
4508          {
4509             thread_id tid = spawn_thread
4510                (server_thread, "server", B_NORMAL_PRIORITY, csp);
4511
4512             if ((tid >= 0) && (resume_thread(tid) == B_OK))
4513             {
4514                child_id = (int) tid;
4515             }
4516             else
4517             {
4518                child_id = -1;
4519             }
4520          }
4521 #endif
4522
4523 #if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
4524 #define SELECTED_ONE_OPTION
4525          csp->cfd = ReleaseSocket(csp->cfd, -1);
4526          
4527 #ifdef __amigaos4__
4528          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
4529                                            NP_Output, Output(),
4530                                            NP_CloseOutput, FALSE,
4531                                            NP_Name, (ULONG)"privoxy child",
4532                                            NP_Child, TRUE,
4533                                            TAG_DONE);
4534 #else
4535          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
4536                                            NP_Output, Output(),
4537                                            NP_CloseOutput, FALSE,
4538                                            NP_Name, (ULONG)"privoxy child",
4539                                            NP_StackSize, 200*1024,
4540                                            TAG_DONE);
4541 #endif
4542          if(0 != child_id)
4543          {
4544             childs++;
4545             ((struct Task *)child_id)->tc_UserData = csp;
4546             Signal((struct Task *)child_id, SIGF_SINGLE);
4547             Wait(SIGF_SINGLE);
4548          }
4549 #endif
4550
4551 #if !defined(SELECTED_ONE_OPTION)
4552          child_id = fork();
4553
4554          /* This block is only needed when using fork().
4555           * When using threads, the server thread was
4556           * created and run by the call to _beginthread().
4557           */
4558          if (child_id == 0)   /* child */
4559          {
4560             int rc = 0;
4561 #ifdef FEATURE_TOGGLE
4562             int inherited_toggle_state = global_toggle_state;
4563 #endif /* def FEATURE_TOGGLE */
4564
4565             serve(csp);
4566
4567             /* 
4568              * If we've been toggled or we've blocked the request, tell Mom
4569              */
4570
4571 #ifdef FEATURE_TOGGLE
4572             if (inherited_toggle_state != global_toggle_state)
4573             {
4574                rc |= RC_FLAG_TOGGLED;
4575             }
4576 #endif /* def FEATURE_TOGGLE */
4577
4578 #ifdef FEATURE_STATISTICS  
4579             if (csp->flags & CSP_FLAG_REJECTED)
4580             {
4581                rc |= RC_FLAG_BLOCKED;
4582             }
4583 #endif /* ndef FEATURE_STATISTICS */
4584
4585             _exit(rc);
4586          }
4587          else if (child_id > 0) /* parent */
4588          {
4589             /* in a fork()'d environment, the parent's
4590              * copy of the client socket and the CSP
4591              * are not used.
4592              */
4593             int child_status;
4594 #if !defined(_WIN32) && !defined(__CYGWIN__)
4595
4596             wait( &child_status );
4597
4598             /* 
4599              * Evaluate child's return code: If the child has
4600              *  - been toggled, toggle ourselves
4601              *  - blocked its request, bump up the stats counter
4602              */
4603
4604 #ifdef FEATURE_TOGGLE
4605             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_TOGGLED))
4606             {
4607                global_toggle_state = !global_toggle_state;
4608             }
4609 #endif /* def FEATURE_TOGGLE */
4610
4611 #ifdef FEATURE_STATISTICS
4612             urls_read++;
4613             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_BLOCKED))
4614             {
4615                urls_rejected++;
4616             }
4617 #endif /* def FEATURE_STATISTICS */ 
4618
4619 #endif /* !defined(_WIN32) && defined(__CYGWIN__) */
4620             close_socket(csp->cfd);
4621             csp->flags &= ~CSP_FLAG_ACTIVE;
4622          }
4623 #endif
4624
4625 #undef SELECTED_ONE_OPTION
4626 /* end of cpp switch () */
4627
4628          if (child_id < 0)
4629          {
4630             /*
4631              * Spawning the child failed, assume it's because
4632              * there are too many children running already.
4633              * XXX: If you assume ...
4634              */
4635             log_error(LOG_LEVEL_ERROR,
4636                "Unable to take any additional connections: %E");
4637             write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
4638                strlen(TOO_MANY_CONNECTIONS_RESPONSE));
4639             close_socket(csp->cfd);
4640             csp->flags &= ~CSP_FLAG_ACTIVE;
4641          }
4642       }
4643       else
4644       {
4645          serve(csp);
4646       }
4647    }
4648
4649    /* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
4650
4651    /* Clean up.  Aim: free all memory (no leaks) */
4652 #ifdef FEATURE_GRACEFUL_TERMINATION
4653
4654    log_error(LOG_LEVEL_ERROR, "Graceful termination requested");
4655
4656    unload_current_config_file();
4657    unload_current_actions_file();
4658    unload_current_re_filterfile();
4659 #ifdef FEATURE_TRUST
4660    unload_current_trust_file();
4661 #endif
4662
4663    if (config->multi_threaded)
4664    {
4665       int i = 60;
4666       do
4667       {
4668          sleep(1);
4669          sweep();
4670       } while ((clients->next != NULL) && (--i > 0));
4671
4672       if (i <= 0)
4673       {
4674          log_error(LOG_LEVEL_ERROR, "Graceful termination failed - still some live clients after 1 minute wait.");
4675       }
4676    }
4677    sweep();
4678    sweep();
4679
4680 #if defined(unix)
4681    freez(basedir);
4682 #endif
4683    freez(configfile);
4684
4685 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
4686    /* Cleanup - remove taskbar icon etc. */
4687    TermLogWindow();
4688 #endif
4689
4690    exit(0);
4691 #endif /* FEATURE_GRACEFUL_TERMINATION */
4692
4693 }
4694
4695
4696 /*
4697   Local Variables:
4698   tab-width: 3
4699   end:
4700 */