X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=644dc2d5018b7b10e5705d99d4e1e43f792a4620;hb=105aaa1d5c79461a24b21a0a50cb81bb56988981;hp=60008ac765540474f540f9b9056afcff16675713;hpb=691225fa5b164812e0c820b1b56af5204f71f9c0;p=privoxy.git diff --git a/jcc.c b/jcc.c index 60008ac7..644dc2d5 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.99 2006/09/02 15:36:42 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,38 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp * * Revisions : * $Log: jcc.c,v $ + * 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/ * @@ -642,6 +674,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.95 2006/08/03 02:46:41 david__schmidt Exp # ifndef _WIN_CONSOLE # include "w32log.h" # endif /* ndef _WIN_CONSOLE */ +# include "w32svrapi.h" #else /* ifndef _WIN32 */ @@ -736,15 +769,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; @@ -1853,6 +1891,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; @@ -1876,6 +1917,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]); @@ -1927,8 +1996,7 @@ int main(int argc, const char *argv[]) } #endif /* defined(unix) */ - - else +#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */ { configfile = argv[argc_pos]; } @@ -1970,21 +2038,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 * @@ -2104,7 +2179,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."); } @@ -2151,6 +2226,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 */