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