-const char cgi_rcs[] = "$Id: cgi.c,v 1.103 2008/03/21 11:13:57 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 $
* 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
*
* 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
#include "miscutil.h"
#include "cgisimple.h"
#include "jbsockets.h"
-#ifdef FEATURE_CGI_EDIT_ACTIONS
+#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
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 },
{ "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 */ },
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);
* 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;
* 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)
{
"<p>Privoxy encountered an error while processing your request:</p>\r\n"
"<p><b>Could not load template file <code>";
static const char body_suffix[] =
- "</code> or one of it's included components.</b></p>\r\n"
+ "</code> or one of its included components.</b></p>\r\n"
"<p>Please contact your proxy administrator.</p>\r\n"
"<p>If you are the proxy administrator, please put the required file(s)"
"in the <code><i>(confdir)</i>/templates</code> directory. The "
* 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)
{
* 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;
* 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" };
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,
}
+/*********************************************************************
+ *
+ * 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);
+
+}
/*********************************************************************
*
if (!err)
{
- get_http_time(0, buf);
+ get_http_time(0, buf, sizeof(buf));
err = enlist_unique_header(rsp->headers, "Date", buf);
}
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
*/
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)
* 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;
* 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)
*********************************************************************/
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;
}
err = map(exports, "version", 1, html_encode(VERSION), 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);
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);
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);
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"