X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=6184dc33c9f47121429369953b6f09b47142dfa8;hp=90802a331fd3c06e07d227d444e164f6d0523eed;hb=7537bf8433682b12ccf1099e1e30c978f4bd52a2;hpb=1b65660a5bb4e9d8511906406ebcc8a008c7baee diff --git a/jcc.c b/jcc.c index 90802a33..6184dc33 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.94 2006/07/18 14:48:46 david__schmidt Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.101 2006/09/06 09:23:37 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,49 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.94 2006/07/18 14:48:46 david__schmidt Exp * * Revisions : * $Log: jcc.c,v $ + * Revision 1.101 2006/09/06 09:23:37 fabiankeil + * Make number of retries in case of forwarded-connect problems + * a config file option (forwarded-connect-retries) and use 0 as + * default. + * + * Revision 1.100 2006/09/03 19:42:59 fabiankeil + * Set random(3) seed. + * + * Revision 1.99 2006/09/02 15:36:42 fabiankeil + * Follow the OpenBSD port's lead and protect the resolve + * functions on OpenBSD as well. + * + * Revision 1.98 2006/08/24 11:01:34 fabiankeil + * --user fix. Only use the user as group if no group is specified. + * Solves BR 1492612. Thanks to Spinor S. and David Laight. + * + * Revision 1.97 2006/08/18 15:23:17 david__schmidt + * Windows service (re-)integration + * + * The new args are: + * + * --install[:service_name] + * --uninstall[:service_name] + * --service + * + * They work as follows: + * --install will create a service for you and then terminate. + * By default the service name will be "privoxy" (without the quotes). + * However you can run multiple services if you wish, just by adding + * a colon and then a name (no spaces). + * + * --uninstall follows the exact same rules a --install. + * + * --service is used when the program is executed by the service + * control manager, and in normal circumstances would never be + * used as a command line argument. + * + * Revision 1.96 2006/08/15 20:12:36 david__schmidt + * Windows service integration + * + * Revision 1.95 2006/08/03 02:46:41 david__schmidt + * Incorporate Fabian Keil's patch work: http://www.fabiankeil.de/sourcecode/privoxy/ + * * Revision 1.94 2006/07/18 14:48:46 david__schmidt * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch) * with what was really the latest development (the v_3_0_branch branch) @@ -639,6 +682,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.94 2006/07/18 14:48:46 david__schmidt Exp # ifndef _WIN_CONSOLE # include "w32log.h" # endif /* ndef _WIN_CONSOLE */ +# include "w32svrapi.h" #else /* ifndef _WIN32 */ @@ -733,15 +777,20 @@ static int32 server_thread(void *data); #define sleep(N) DosSleep(((N) * 100)) #endif +#if defined(OSX_DARWIN) || defined(__OpenBSD__) #ifdef OSX_DARWIN /* * Hit OSX over the head with a hammer. Protect all *_r functions. */ pthread_mutex_t gmtime_mutex; pthread_mutex_t localtime_mutex; +#endif /* def OSX_DARWIN */ +/* + * Protect only the resolve functions for OpenBSD. + */ pthread_mutex_t gethostbyaddr_mutex; pthread_mutex_t gethostbyname_mutex; -#endif /* def OSX_DARWIN */ +#endif /* defined(OSX_DARWIN) || defined(__OpenBSD__) */ #ifdef FEATURE_PTHREAD pthread_mutex_t log_mutex; @@ -864,7 +913,8 @@ static void chat(struct client_state *csp) int server_body; int ms_iis5_hack = 0; int byte_count = 0; - unsigned int socks_retries = 0; + unsigned int forwarded_connect_retries = 0; + unsigned int max_forwarded_connect_retries = csp->config->forwarded_connect_retries; const struct forward_spec * fwd; struct http_request *http; int len; /* for buffer sizes */ @@ -947,6 +997,18 @@ static void chat(struct client_state *csp) return; } + if (!strncmpic(http->cmd, "GET ftp://", 10)) + { + strcpy(buf, FTP_RESPONSE); + write_socket(csp->cfd, buf, strlen(buf)); + + log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s", + csp->ip_addr_str, http->cmd); + + free_http_request(http); + return; + } + /* decide how to route the HTTP request */ if ((fwd = forward_url(http, csp)) == NULL) @@ -1224,10 +1286,10 @@ static void chat(struct client_state *csp) /* here we connect to the server, gateway, or the forwarder */ while ( (csp->sfd = forwarded_connect(fwd, http, csp)) - && (errno == EINVAL) && (socks_retries++ < 3)) + && (errno == EINVAL) && (forwarded_connect_retries++ < max_forwarded_connect_retries)) { log_error(LOG_LEVEL_ERROR, "failed request #%u to connect to %s. Trying again.", - socks_retries, http->hostport); + forwarded_connect_retries, http->hostport); } if (csp->sfd == JB_INVALID_SOCKET) @@ -1850,6 +1912,9 @@ int main(int argc, const char *argv[]) #endif { int argc_pos = 0; +#ifdef HAVE_RANDOM + unsigned int random_seed; +#endif /* ifdef HAVE_RANDOM */ #ifdef unix struct passwd *pw = NULL; struct group *grp = NULL; @@ -1873,6 +1938,34 @@ int main(int argc, const char *argv[]) */ while (++argc_pos < argc) { +#ifdef _WIN32 + /* Check to see if the service must be installed or uninstalled */ + if (strncmp(argv[argc_pos], "--install", 9) == 0) + { + const char *pName = argv[argc_pos] + 9; + if (*pName == ':') + pName++; + exit( (install_service(pName)) ? 0 : 1 ); + } + else if (strncmp(argv[argc_pos], "--uninstall", + 11) == 0) + { + const char *pName = argv[argc_pos] + 11; + if (*pName == ':') + pName++; + exit((uninstall_service(pName)) ? 0 : 1); + } + else if (strcmp(argv[argc_pos], "--service" ) == 0) + { + bRunAsService = TRUE; + w32_set_service_cwd(); + atexit(w32_service_exit_notify); + } + else +#endif /* defined(_WIN32) */ + + +#if !defined(_WIN32) || defined(_WIN_CONSOLE) + if (strcmp(argv[argc_pos], "--help") == 0) { usage(argv[0]); @@ -1924,8 +2017,7 @@ int main(int argc, const char *argv[]) } #endif /* defined(unix) */ - - else +#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */ { configfile = argv[argc_pos]; } @@ -1967,21 +2059,28 @@ int main(int argc, const char *argv[]) InitWin32(); #endif -#ifdef OSX_DARWIN +#if defined(OSX_DARWIN) || defined(__OpenBSD__) /* * Prepare global mutex semaphores */ +#ifdef OSX_DARWIN pthread_mutex_init(&gmtime_mutex,0); pthread_mutex_init(&localtime_mutex,0); +#endif /* def OSX_DARWIN */ pthread_mutex_init(&gethostbyaddr_mutex,0); pthread_mutex_init(&gethostbyname_mutex,0); -#endif /* def OSX_DARWIN */ +#endif /* defined(OSX_DARWIN) || defined(__OpenBSD__) */ #ifdef FEATURE_PTHREAD pthread_mutex_init(&log_mutex,0); pthread_mutex_init(&log_init_mutex,0); #endif /* FEATURE_PTHREAD */ +#ifdef HAVE_RANDOM + random_seed = (unsigned int)time(NULL); + srandom(random_seed); +#endif /* ifdef HAVE_RANDOM */ + /* * Unix signal handling * @@ -2101,7 +2200,7 @@ int main(int argc, const char *argv[]) if (NULL != pw) { - if (((NULL != grp) && setgid(grp->gr_gid)) || (setgid(pw->pw_gid))) + if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid)) { log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions."); } @@ -2148,6 +2247,37 @@ int main(int argc, const char *argv[]) } #endif /* defined unix */ +#ifdef _WIN32 + /* This will be FALSE unless the command line specified --service + */ + if (bRunAsService) + { + /* Yup, so now we must attempt to establish a connection + * with the service dispatcher. This will only work if this + * process was launched by the service control manager to + * actually run as a service. If this isn't the case, i've + * known it take around 30 seconds or so for the call to return. + */ + + /* The StartServiceCtrlDispatcher won't return until the service is stopping */ + if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable)) + { + /* Service has run, and at this point is now being stopped, so just return */ + return 0; + } + +#ifdef _WIN_CONSOLE + printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n"); +#endif + /* An error occurred. Usually it's because --service was wrongly specified + * and we were unable to connect to the Service Control Dispatcher because + * it wasn't expecting us and is therefore not listening. + * + * For now, just continue below to call the listen_loop function. + */ + } +#endif /* def _WIN32 */ + listen_loop(); /* NOTREACHED */ @@ -2228,6 +2358,17 @@ static jb_socket bind_port_helper(struct configuration_spec * config) } +#ifdef _WIN32 +/* Without this simple workaround we get this compiler warning from _beginthread + * warning C4028: formal parameter 1 different from declaration + */ +void w32_service_listen_loop(void *p) +{ + listen_loop(); +} +#endif /* def _WIN32 */ + + /********************************************************************* * * Function : listen_loop