X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=cgi.c;h=ef98085e5f0cb2d3456736a353834723a61514ab;hb=d22dbb3eb435d1bc265318b6fb3325e934a48f87;hp=bd0c8f6f7c529c13a3577da983e1f4bf6321e9ba;hpb=f08e3d0ab8d466e41e4f7be61dce8e4f8b869d79;p=privoxy.git diff --git a/cgi.c b/cgi.c index bd0c8f6f..ef98085e 100644 --- a/cgi.c +++ b/cgi.c @@ -1,4 +1,4 @@ -const char cgi_rcs[] = "$Id: cgi.c,v 1.101 2008/02/03 15:45:06 fabiankeil Exp $"; +const char cgi_rcs[] = "$Id: cgi.c,v 1.113 2008/09/04 08:13:58 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgi.c,v $ @@ -11,7 +11,7 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.101 2008/02/03 15:45:06 fabiankeil Exp $" * Functions declared include: * * - * Copyright : Written by and Copyright (C) 2001-2004, 2006-2007 + * Copyright : Written by and Copyright (C) 2001-2004, 2006-2008 * the SourceForge Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -38,6 +38,56 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.101 2008/02/03 15:45:06 fabiankeil Exp $" * * Revisions : * $Log: cgi.c,v $ + * Revision 1.113 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.112 2008/08/31 16:08:12 fabiankeil + * "View the request headers" isn't more equal than the other + * menu items and thus doesn't need a trailing dot either. + * + * Revision 1.111 2008/08/31 15:59:02 fabiankeil + * There's no reason to let remote toggling support depend + * on FEATURE_CGI_EDIT_ACTIONS, so make sure it doesn't. + * + * Revision 1.110 2008/08/31 14:55:43 fabiankeil + * Add a @date@ symbol to include a date(1)-like time string + * in templates. Modified version of the patch Endre Szabo + * submitted in #2026468. + * + * Revision 1.109 2008/07/26 09:40:27 fabiankeil + * Remove the unconditional block in get_http_time(). + * It's pointless now that it's no longer used to limit + * dummy's scope. While at it, remove obvious comments + * and a trailing space. + * + * Revision 1.108 2008/05/26 17:30:53 fabiankeil + * Provide an OpenSearch Description to access the + * show-url-info page through "search engine plugins". + * + * Revision 1.107 2008/05/26 16:23:19 fabiankeil + * - Fix spelling in template-not-found message. + * - Declare referrer_is_safe()'s alternative_prefix[] static. + * + * Revision 1.106 2008/05/21 15:24:38 fabiankeil + * Mark csp as immutable for a bunch of functions. + * + * Revision 1.105 2008/04/17 14:40:47 fabiankeil + * Provide get_http_time() with the buffer size so it doesn't + * have to blindly assume that the buffer is big enough. + * + * Revision 1.104 2008/03/26 18:07:06 fabiankeil + * Add hostname directive. Closes PR#1918189. + * + * Revision 1.103 2008/03/21 11:13:57 fabiankeil + * Only gather host information if it's actually needed. + * Also move the code out of accept_connection() so it's less likely + * to delay other incoming connections if the host is misconfigured. + * + * Revision 1.102 2008/02/23 16:33:43 fabiankeil + * Let forward_url() use the standard parameter ordering + * and mark its second parameter immutable. + * * Revision 1.101 2008/02/03 15:45:06 fabiankeil * Add SOCKS5 support for "Forwarding failure" CGI page. * @@ -608,9 +658,10 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.101 2008/02/03 15:45:06 fabiankeil Exp $" #include "filters.h" #include "miscutil.h" #include "cgisimple.h" -#ifdef FEATURE_CGI_EDIT_ACTIONS +#include "jbsockets.h" +#if defined(FEATURE_CGI_EDIT_ACTIONS) || defined(FEATURE_TOGGLE) #include "cgiedit.h" -#endif /* def FEATURE_CGI_EDIT_ACTIONS */ +#endif /* defined(FEATURE_CGI_EDIT_ACTIONS) || defined (FEATURE_TOGGLE) */ #include "loadcfg.h" /* loadcfg.h is for global_toggle_state only */ #ifdef FEATURE_PTHREAD @@ -650,19 +701,19 @@ static const struct cgi_dispatcher cgi_dispatchers[] = { TRUE }, { "show-request", cgi_show_request, - "View the request headers.", + "View the request headers", TRUE }, { "show-url-info", cgi_show_url_info, "Look up which actions apply to a URL and why", TRUE }, -#ifdef FEATURE_CGI_EDIT_ACTIONS #ifdef FEATURE_TOGGLE { "toggle", cgi_toggle, "Toggle Privoxy on or off", FALSE }, #endif /* def FEATURE_TOGGLE */ +#ifdef FEATURE_CGI_EDIT_ACTIONS { "edit-actions", /* Edit the actions list */ cgi_edit_actions, NULL, FALSE }, @@ -748,6 +799,9 @@ static const struct cgi_dispatcher cgi_dispatchers[] = { { "t", cgi_transparent_image, NULL, TRUE /* Send a transparent image (short name) */ }, + { "url-info-osd.xml", + cgi_send_url_info_osd, + NULL, TRUE /* Send templates/url-info-osd.xml */ }, { "user-manual", cgi_send_user_manual, NULL, TRUE /* Send user-manual */ }, @@ -946,7 +1000,7 @@ static char *grep_cgi_referrer(const struct client_state *csp) static int referrer_is_safe(const struct client_state *csp) { char *referrer; - const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/"; + static const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/"; referrer = grep_cgi_referrer(csp); @@ -1538,7 +1592,7 @@ struct http_response *error_response(struct client_state *csp, * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_disabled(struct client_state *csp, +jb_err cgi_error_disabled(const struct client_state *csp, struct http_response *rsp) { struct map *exports; @@ -1641,7 +1695,7 @@ struct http_response *cgi_error_memory(void) * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_no_template(struct client_state *csp, +jb_err cgi_error_no_template(const struct client_state *csp, struct http_response *rsp, const char *template_name) { @@ -1658,7 +1712,7 @@ jb_err cgi_error_no_template(struct client_state *csp, "
Privoxy encountered an error while processing your request:
\r\n" "Could not load template file ";
static const char body_suffix[] =
- "
or one of it's included components.
Please contact your proxy administrator.
\r\n" "If you are the proxy administrator, please put the required file(s)"
"in the (confdir)/templates
directory. The "
@@ -1728,7 +1782,7 @@ jb_err cgi_error_no_template(struct client_state *csp,
* JB_ERR_MEMORY on out-of-memory error.
*
*********************************************************************/
-jb_err cgi_error_unknown(struct client_state *csp,
+jb_err cgi_error_unknown(const struct client_state *csp,
struct http_response *rsp,
jb_err error_to_report)
{
@@ -1807,7 +1861,7 @@ jb_err cgi_error_unknown(struct client_state *csp,
* JB_ERR_MEMORY on out-of-memory error.
*
*********************************************************************/
-jb_err cgi_error_bad_param(struct client_state *csp,
+jb_err cgi_error_bad_param(const struct client_state *csp,
struct http_response *rsp)
{
struct map *exports;
@@ -1919,19 +1973,18 @@ char *add_help_link(const char *item,
* HTTP header - e.g.:
* "Sun, 06 Nov 1994 08:49:37 GMT"
*
- * XXX: Should probably get a third parameter for
- * the buffer size.
- *
* Parameters :
* 1 : time_offset = Time returned will be current time
* plus this number of seconds.
- * 2 : buf = Destination for result. Must be long enough
- * to hold 29 characters plus a trailing zero.
+ * 2 : buf = Destination for result.
+ * 3 : buffer_size = Size of the buffer above. Must be big
+ * enough to hold 29 characters plus a
+ * trailing zero.
*
* Returns : N/A
*
*********************************************************************/
-void get_http_time(int time_offset, char *buf)
+void get_http_time(int time_offset, char *buf, size_t buffer_size)
{
static const char day_names[7][4] =
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
@@ -1942,36 +1995,29 @@ void get_http_time(int time_offset, char *buf)
struct tm *t;
time_t current_time;
#if defined(HAVE_GMTIME_R)
- /*
- * Declare dummy up here (instead of inside get/set gmt block) so it
- * doesn't go out of scope before it's potentially used in snprintf later.
- * Wrapping declaration inside HAVE_GMTIME_R keeps the compiler quiet when
- * !defined HAVE_GMTIME_R.
- */
- struct tm dummy;
+ struct tm dummy;
#endif
assert(buf);
+ assert(buffer_size > (size_t)29);
- time(¤t_time); /* get current time */
+ time(¤t_time);
current_time += time_offset;
/* get and save the gmt */
- {
#if HAVE_GMTIME_R
- t = gmtime_r(¤t_time, &dummy);
+ t = gmtime_r(¤t_time, &dummy);
#elif FEATURE_PTHREAD
- pthread_mutex_lock(&gmtime_mutex);
- t = gmtime(¤t_time);
- pthread_mutex_unlock(&gmtime_mutex);
+ privoxy_mutex_lock(&gmtime_mutex);
+ t = gmtime(¤t_time);
+ privoxy_mutex_unlock(&gmtime_mutex);
#else
- t = gmtime(¤t_time);
+ t = gmtime(¤t_time);
#endif
- }
/* Format: "Sun, 06 Nov 1994 08:49:37 GMT" */
- snprintf(buf, 30,
+ snprintf(buf, buffer_size,
"%s, %02d %s %4d %02d:%02d:%02d GMT",
day_names[t->tm_wday],
t->tm_mday,
@@ -1984,6 +2030,51 @@ void get_http_time(int time_offset, char *buf)
}
+/*********************************************************************
+ *
+ * Function : get_locale_time
+ *
+ * Description : Get the time in a date(1)-like format
+ * according to the current locale - e.g.:
+ * "Fri Aug 29 19:37:12 CEST 2008"
+ *
+ * XXX: Should we allow the user to change the format?
+ *
+ * Parameters :
+ * 1 : buf = Destination for result.
+ * 2 : buffer_size = Size of the buffer above. Must be big
+ * enough to hold 29 characters plus a
+ * trailing zero.
+ *
+ * Returns : N/A
+ *
+ *********************************************************************/
+static void get_locale_time(char *buf, size_t buffer_size)
+{
+ struct tm *timeptr;
+ time_t current_time;
+#if defined(HAVE_LOCALTIME_R)
+ struct tm dummy;
+#endif
+
+ assert(buf);
+ assert(buffer_size > (size_t)29);
+
+ time(¤t_time);
+
+#if HAVE_LOCALTIME_R
+ timeptr = localtime_r(¤t_time, &dummy);
+#elif FEATURE_PTHREAD
+ privoxy_mutex_lock(&localtime_mutex);
+ timeptr = localtime(¤t_time);
+ privoxy_mutex_unlock(&localtime_mutex);
+#else
+ timeptr = localtime(¤t_time);
+#endif
+
+ strftime(buf, buffer_size, "%a %b %d %X %Z %Y", timeptr);
+
+}
/*********************************************************************
*
@@ -2083,7 +2174,7 @@ struct http_response *finish_http_response(const struct client_state *csp, struc
if (!err)
{
- get_http_time(0, buf);
+ get_http_time(0, buf, sizeof(buf));
err = enlist_unique_header(rsp->headers, "Date", buf);
}
@@ -2092,13 +2183,13 @@ struct http_response *finish_http_response(const struct client_state *csp, struc
if (!err)
{
- get_http_time(10 * 60, buf); /* 10 * 60sec = 10 minutes */
+ get_http_time(10 * 60, buf, sizeof(buf)); /* 10 * 60sec = 10 minutes */
err = enlist_unique_header(rsp->headers, "Expires", buf);
}
}
else if (!strncmpic(rsp->status, "302", 3))
{
- get_http_time(0, buf);
+ get_http_time(0, buf, sizeof(buf));
if (!err) err = enlist_unique_header(rsp->headers, "Date", buf);
}
else
@@ -2124,7 +2215,7 @@ struct http_response *finish_http_response(const struct client_state *csp, struc
*/
if (!err) err = enlist_unique_header(rsp->headers, "Cache-Control", "no-cache");
- get_http_time(0, buf);
+ get_http_time(0, buf, sizeof(buf));
if (!err) err = enlist_unique_header(rsp->headers, "Date", buf);
if (!strncmpic(rsp->status, "403", 3)
|| !strncmpic(rsp->status, "404", 3)
@@ -2232,7 +2323,7 @@ void free_http_response(struct http_response *rsp)
* JB_ERR_FILE if the template file cannot be read
*
*********************************************************************/
-jb_err template_load(struct client_state *csp, char **template_ptr,
+jb_err template_load(const struct client_state *csp, char **template_ptr,
const char *templatename, int recursive)
{
jb_err err;
@@ -2511,7 +2602,7 @@ jb_err template_fill(char **template_ptr, const struct map *exports)
* JB_ERR_MEMORY on out-of-memory error
*
*********************************************************************/
-jb_err template_fill_for_cgi(struct client_state *csp,
+jb_err template_fill_for_cgi(const struct client_state *csp,
const char *templatename,
struct map *exports,
struct http_response *rsp)
@@ -2557,10 +2648,12 @@ jb_err template_fill_for_cgi(struct client_state *csp,
*********************************************************************/
struct map *default_exports(const struct client_state *csp, const char *caller)
{
- char buf[20];
+ char buf[30];
jb_err err;
struct map * exports;
int local_help_exists = 0;
+ char *ip_address = NULL;
+ char *hostname = NULL;
assert(csp);
@@ -2570,9 +2663,23 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
return NULL;
}
+ if (csp->config->hostname)
+ {
+ get_host_information(csp->cfd, &ip_address, NULL);
+ hostname = strdup(csp->config->hostname);
+ }
+ else
+ {
+ get_host_information(csp->cfd, &ip_address, &hostname);
+ }
+
err = map(exports, "version", 1, html_encode(VERSION), 0);
- if (!err) err = map(exports, "my-ip-address", 1, html_encode(csp->my_ip_addr_str ? csp->my_ip_addr_str : "unknown"), 0);
- if (!err) err = map(exports, "my-hostname", 1, html_encode(csp->my_hostname ? csp->my_hostname : "unknown"), 0);
+ get_locale_time(buf, sizeof(buf));
+ if (!err) err = map(exports, "time", 1, html_encode(buf), 0);
+ if (!err) err = map(exports, "my-ip-address", 1, html_encode(ip_address ? ip_address : "unknown"), 0);
+ freez(ip_address);
+ if (!err) err = map(exports, "my-hostname", 1, html_encode(hostname ? hostname : "unknown"), 0);
+ freez(hostname);
if (!err) err = map(exports, "homepage", 1, html_encode(HOME_PAGE_URL), 0);
if (!err) err = map(exports, "default-cgi", 1, html_encode(CGI_PREFIX), 0);
if (!err) err = map(exports, "menu", 1, make_menu(caller, csp->config->feature_flags), 0);
@@ -2662,7 +2769,7 @@ jb_err map_block_killer(struct map *exports, const char *name)
assert(exports);
assert(name);
- assert(strlen(name) < 490);
+ assert(strlen(name) < (size_t)490);
snprintf(buf, sizeof(buf), "if-%s-start.*if-%s-end", name, name);
return map(exports, buf, 1, "", 1);
@@ -2692,7 +2799,7 @@ jb_err map_block_keep(struct map *exports, const char *name)
assert(exports);
assert(name);
- assert(strlen(name) < 490);
+ assert(strlen(name) < (size_t)490);
snprintf(buf, sizeof(buf), "if-%s-start", name);
err = map(exports, buf, 1, "", 1);
@@ -2739,7 +2846,7 @@ jb_err map_conditional(struct map *exports, const char *name, int choose_first)
assert(exports);
assert(name);
- assert(strlen(name) < 480);
+ assert(strlen(name) < (size_t)480);
snprintf(buf, sizeof(buf), (choose_first
? "else-not-%s@.*@endif-%s"