-const char jcc_rcs[] = "$Id: jcc.c,v 1.178 2008/05/10 13:23:38 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.186 2008/09/04 08:13:58 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/jcc.c,v $
*
* Revisions :
* $Log: jcc.c,v $
+ * Revision 1.186 2008/09/04 08:13:58 fabiankeil
+ * Prepare for critical sections on Windows by adding a
+ * layer of indirection before the pthread mutex functions.
+ *
+ * Revision 1.185 2008/08/30 12:03:07 fabiankeil
+ * Remove FEATURE_COOKIE_JAR.
+ *
+ * Revision 1.184 2008/08/22 15:34:45 fabiankeil
+ * - Silence LLVM/Clang complaint.
+ * - Make received_hup_signal static.
+ * - Hide definitions for basedir, pidfile and received_hup_signal
+ * from __EMX__ as they only seem to be used in case of #ifdef unix.
+ *
+ * Revision 1.183 2008/08/21 07:09:35 fabiankeil
+ * Accept Shoutcast responses again. Problem reported
+ * and fix suggested by Stefan in #2062860.
+ *
+ * Revision 1.182 2008/06/27 11:13:56 fabiankeil
+ * Fix possible NULL-pointer dereference reported
+ * by din_a4 in #2003937. Pointy hat to me.
+ *
+ * Revision 1.181 2008/05/21 15:47:15 fabiankeil
+ * Streamline sed()'s prototype and declare
+ * the header parse and add structures static.
+ *
+ * Revision 1.180 2008/05/21 15:26:32 fabiankeil
+ * - Mark csp as immutable for send_crunch_response().
+ * - Fix comment spelling.
+ *
+ * Revision 1.179 2008/05/20 20:13:32 fabiankeil
+ * Factor update_server_headers() out of sed(), ditch the
+ * first_run hack and make server_patterns_light static.
+ *
* Revision 1.178 2008/05/10 13:23:38 fabiankeil
* Don't provide get_header() with the whole client state
* structure when it only needs access to csp->iob.
static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
static jb_err get_server_headers(struct client_state *csp);
static const char *crunch_reason(const struct http_response *rsp);
-static void send_crunch_response(struct client_state *csp, struct http_response *rsp);
+static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
/*
* static int request_contains_null_bytes(const struct client_state *csp, char *buf, int len);
*/
#define sleep(N) DosSleep(((N) * 100))
#endif
-#ifdef FEATURE_PTHREAD
-pthread_mutex_t log_mutex;
-pthread_mutex_t log_init_mutex;
+#ifdef MUTEX_LOCKS_AVAILABLE
+/*
+ * XXX: Does the locking stuff really belong in this file?
+ */
+privoxy_mutex_t log_mutex;
+privoxy_mutex_t log_init_mutex;
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
-pthread_mutex_t resolver_mutex;
+privoxy_mutex_t resolver_mutex;
#endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
#ifndef HAVE_GMTIME_R
-pthread_mutex_t gmtime_mutex;
+privoxy_mutex_t gmtime_mutex;
#endif /* ndef HAVE_GMTIME_R */
#ifndef HAVE_LOCALTIME_R
-pthread_mutex_t localtime_mutex;
+privoxy_mutex_t localtime_mutex;
#endif /* ndef HAVE_GMTIME_R */
#ifndef HAVE_RANDOM
-pthread_mutex_t rand_mutex;
+privoxy_mutex_t rand_mutex;
#endif /* ndef HAVE_RANDOM */
-#endif /* FEATURE_PTHREAD */
+#endif /* def MUTEX_LOCKS_AVAILABLE */
-#if defined(unix) || defined(__EMX__)
+#if defined(unix)
const char *basedir = NULL;
const char *pidfile = NULL;
-int received_hup_signal = 0;
+static int received_hup_signal = 0;
#endif /* defined unix */
/* HTTP snipplets. */
};
+/*
+ * XXX: Don't we really mean
+ *
+ * #if defined(unix)
+ *
+ * here?
+ */
#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
/*********************************************************************
*
break;
case SIGHUP:
+#if defined(unix)
received_hup_signal = 1;
+#endif
break;
default:
{
/*
* It's a bodyless continue response, don't
- * stop header parsing after reaching it's end.
+ * stop header parsing after reaching its end.
*
* As a result Privoxy will concatenate the
* next response's head and parse and deliver
* Returns : Nothing.
*
*********************************************************************/
-static void send_crunch_response(struct client_state *csp, struct http_response *rsp)
+static void send_crunch_response(const struct client_state *csp, struct http_response *rsp)
{
const struct http_request *http = csp->http;
char status_code[4];
log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
jb_err_to_string(err));
}
- http->ocmd = strdup(http->cmd); /* XXX: ocmd is a misleading name */
- if (http->ocmd == NULL)
+ else
{
- log_error(LOG_LEVEL_FATAL, "Out of memory copying rewritten HTTP request line");
+ /* XXX: ocmd is a misleading name */
+ http->ocmd = strdup(http->cmd);
+ if (http->ocmd == NULL)
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Out of memory copying rewritten HTTP request line");
+ }
}
return err;
list_append_list_unique(csp->headers, headers);
destroy_list(headers);
- err = sed(client_patterns, add_client_headers, csp);
+ err = sed(csp, FILTER_CLIENT_HEADERS);
if (JB_ERR_OK != err)
{
assert(err == JB_ERR_PARSE);
assert(csp->headers->first->str);
assert(!http->ssl);
- if (strncmpic(csp->headers->first->str, "HTTP", 4))
+ if (strncmpic(csp->headers->first->str, "HTTP", 4) &&
+ strncmpic(csp->headers->first->str, "ICY", 3))
{
/*
- * It doesn't look like a HTTP response:
+ * It doesn't look like a HTTP (or Shoutcast) response:
* tell the client and log the problem.
*/
if (strlen(csp->headers->first->str) > 30)
return;
}
- /* we have now received the entire header.
+ /*
+ * We have now received the entire server header,
* filter it and send the result to the client
*/
- if (JB_ERR_OK != sed(server_patterns, add_server_headers, csp))
+ if (JB_ERR_OK != sed(csp, FILTER_SERVER_HEADERS))
{
log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
}
#endif /* #if !defined(_WIN32) || defined(_WIN_CONSOLE) */
+#ifdef MUTEX_LOCKS_AVAILABLE
+/*********************************************************************
+ *
+ * Function : privoxy_mutex_lock
+ *
+ * Description : Locks a mutex.
+ *
+ * Parameters :
+ * 1 : mutex = The mutex to lock.
+ *
+ * Returns : Void. May exit in case of errors.
+ *
+ *********************************************************************/
+void privoxy_mutex_lock(privoxy_mutex_t *mutex)
+{
+#ifdef FEATURE_PTHREAD
+ int err = pthread_mutex_lock(mutex);
+ if (err)
+ {
+ if (mutex != &log_mutex)
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Mutex locking failed: %s.\n", strerror(err));
+ }
+ exit(1);
+ }
+#else
+ EnterCriticalSection(mutex);
+#endif /* def FEATURE_PTHREAD */
+}
+
+
+/*********************************************************************
+ *
+ * Function : privoxy_mutex_unlock
+ *
+ * Description : Unlocks a mutex.
+ *
+ * Parameters :
+ * 1 : mutex = The mutex to unlock.
+ *
+ * Returns : Void. May exit in case of errors.
+ *
+ *********************************************************************/
+void privoxy_mutex_unlock(privoxy_mutex_t *mutex)
+{
+#ifdef FEATURE_PTHREAD
+ int err = pthread_mutex_unlock(mutex);
+ if (err)
+ {
+ if (mutex != &log_mutex)
+ {
+ log_error(LOG_LEVEL_FATAL,
+ "Mutex unlocking failed: %s.\n", strerror(err));
+ }
+ exit(1);
+ }
+#else
+ LeaveCriticalSection(mutex);
+#endif /* def FEATURE_PTHREAD */
+}
+
+
+/*********************************************************************
+ *
+ * Function : privoxy_mutex_init
+ *
+ * Description : Prepares a mutex.
+ *
+ * Parameters :
+ * 1 : mutex = The mutex to initialize.
+ *
+ * Returns : Void. May exit in case of errors.
+ *
+ *********************************************************************/
+static void privoxy_mutex_init(privoxy_mutex_t *mutex)
+{
+#ifdef FEATURE_PTHREAD
+ int err = pthread_mutex_init(mutex, 0);
+ if (err)
+ {
+ printf("Fatal error. Mutex initialization failed: %s.\n",
+ strerror(err));
+ exit(1);
+ }
+#else
+ InitializeCriticalSection(mutex);
+#endif /* def FEATURE_PTHREAD */
+}
+#endif /* def MUTEX_LOCKS_AVAILABLE */
+
/*********************************************************************
*
* Function : initialize_mutexes
*********************************************************************/
static void initialize_mutexes(void)
{
- int err = 0;
-
-#ifdef FEATURE_PTHREAD
+#ifdef MUTEX_LOCKS_AVAILABLE
/*
* Prepare global mutex semaphores
*/
- err = pthread_mutex_init(&log_mutex, 0);
+ privoxy_mutex_init(&log_mutex);
- if (!err) err = pthread_mutex_init(&log_init_mutex, 0);
+ privoxy_mutex_init(&log_init_mutex);
/*
* XXX: The assumptions below are a bit naive
* thread safe.
*/
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
- if (!err) err = pthread_mutex_init(&resolver_mutex, 0);
+ privoxy_mutex_init(&resolver_mutex);
#endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
/*
* XXX: should we use a single mutex for
* localtime() and gmtime() as well?
*/
#ifndef HAVE_GMTIME_R
- if (!err) err = pthread_mutex_init(&gmtime_mutex, 0);
+ privoxy_mutex_init(&gmtime_mutex);
#endif /* ndef HAVE_GMTIME_R */
#ifndef HAVE_LOCALTIME_R
- if (!err) err = pthread_mutex_init(&localtime_mutex, 0);
+ privoxy_mutex_init(&localtime_mutex);
#endif /* ndef HAVE_GMTIME_R */
#ifndef HAVE_RANDOM
- if (!err) err = pthread_mutex_init(&rand_mutex, 0);
+ privoxy_mutex_init(&rand_mutex);
#endif /* ndef HAVE_RANDOM */
-#endif /* FEATURE_PTHREAD */
-
- /*
- * TODO: mutex support for mingw32 would be swell.
- */
-
- if (err)
- {
- printf("Fatal error. Mutex initialization failed: %s.\n",
- strerror(err));
- exit(1);
- }
-
- return;
+#endif /* def MUTEX_LOCKS_AVAILABLE */
}
random_seed = (unsigned int)time(NULL);
#ifdef HAVE_RANDOM
srandom(random_seed);
-#elif defined (_WIN32)
- /*
- * See pick_from_range() in miscutil.c for details.
- */
- log_error(LOG_LEVEL_INFO,
- "No thread-safe PRNG implemented for your platform. "
- "Using weak \'randomization\' factor which will "
- "limit the already questionable usefulness of "
- "header-time-randomizing actions (disabled by default).");
#else
srand(random_seed);
#endif /* ifdef HAVE_RANDOM */
}
#endif
-#ifdef __OS2__
-#ifdef FEATURE_COOKIE_JAR
- /*
- * Need a workaround here: we have to fclose() the jarfile, or we die because it's
- * already open. I think unload_configfile() is not being run, which should do
- * this work. Until that can get resolved, we'll use this workaround.
- */
- if (csp)
- if(csp->config)
- if (csp->config->jar)
- {
- fclose(csp->config->jar);
- csp->config->jar = NULL;
- }
-#endif /* FEATURE_COOKIE_JAR */
-#endif /* __OS2__ */
-
if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
{
log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
#endif
freez(configfile);
-#ifdef FEATURE_COOKIE_JAR
- if (NULL != config->jar)
- {
- fclose(config->jar);
- }
-#endif
-
#if defined(_WIN32) && !defined(_WIN_CONSOLE)
/* Cleanup - remove taskbar icon etc. */
TermLogWindow();