-const char cgi_rcs[] = "$Id: cgi.c,v 1.22 2001/09/16 11:00:10 jongfoster Exp $";
+const char cgi_rcs[] = "$Id: cgi.c,v 1.24 2001/09/16 11:38:01 jongfoster Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgi.c,v $
*
* Revisions :
* $Log: cgi.c,v $
+ * Revision 1.24 2001/09/16 11:38:01 jongfoster
+ * Splitting fill_template() into 2 functions:
+ * template_load() loads the file
+ * template_fill() performs the PCRS regexps.
+ * This is because the CGI edit interface has a "table row"
+ * template which is used many times in the page - this
+ * change means it's only loaded from disk once.
+ *
+ * Revision 1.23 2001/09/16 11:16:05 jongfoster
+ * Better error handling in dispatch_cgi() and parse_cgi_parameters()
+ *
* Revision 1.22 2001/09/16 11:00:10 jongfoster
* New function alloc_http_response, for symmetry with free_http_response
*
const char cgi_h_rcs[] = CGI_H_VERSION;
const struct cgi_dispatcher cgi_dispatcher[] = {
+ { "robots.txt",
+ 10, cgi_robots_txt,
+ "HIDE Sends a robots.txt file to tell robots to go away." },
{ "show-status",
11, cgi_show_status,
"Show information about the current configuration" },
/* Can't get here, since cgi_default will match all requests */
free_http_response(rsp);
return(NULL);
-
}
map(exports, "cgi-parameters", 1, "", 1);
}
- rsp->body = fill_template(csp, "default", exports);
+ rsp->body = template_load(csp, "default");
+ template_fill(&rsp->body, exports);
free_map(exports);
return(0);
map(exports, "sourceversions", 1, show_rcs(), 0);
- rsp->body = fill_template(csp, "show-version", exports);
+ rsp->body = template_load(csp, "show-version");
+ template_fill(&rsp->body, exports);
free_map(exports);
return(0);
char * p;
const char * filename = NULL;
char * file_description = NULL;
+#ifdef FEATURE_STATISTICS
+ float perc_rej; /* Percentage of http requests rejected */
+ int local_urls_read;
+ int local_urls_rejected;
+#endif /* ndef FEATURE_STATISTICS */
struct map * exports = default_exports(csp, "show-status");
fclose(fp);
map(exports, "contents", 1, s, 0);
}
- rsp->body = fill_template(csp, "show-status-file", exports);
+ rsp->body = template_load(csp, "show-status-file");
+ template_fill(&rsp->body, exports);
free_map(exports);
return(0);
show_defines(exports);
#ifdef FEATURE_STATISTICS
- add_stats(exports);
+ local_urls_read = urls_read;
+ local_urls_rejected = urls_rejected;
+
+ /*
+ * Need to alter the stats not to include the fetch of this
+ * page.
+ *
+ * Can't do following thread safely! doh!
+ *
+ * urls_read--;
+ * urls_rejected--; * This will be incremented subsequently *
+ */
+
+ if (local_urls_read == 0)
+ {
+ map_block_killer(exports, "have-stats");
+ }
+ else
+ {
+ map_block_killer(exports, "have-no-stats");
+
+ perc_rej = (float)local_urls_rejected * 100.0F /
+ (float)local_urls_read;
+
+ sprintf(buf, "%d", local_urls_read);
+ map(exports, "requests-received", 1, buf, 1);
+
+ sprintf(buf, "%d", local_urls_rejected);
+ map(exports, "requests-blocked", 1, buf, 1);
+
+ sprintf(buf, "%6.2f", perc_rej);
+ map(exports, "percent-blocked", 1, buf, 1);
+ }
+
#else /* ndef FEATURE_STATISTICS */
map_block_killer(exports, "statistics");
#endif /* ndef FEATURE_STATISTICS */
map_block_killer(exports, "trust-support");
#endif /* ndef FEATURE_TRUST */
- rsp->body = fill_template(csp, "show-status", exports);
+ rsp->body = template_load(csp, "show-status");
+ template_fill(&rsp->body, exports);
free_map(exports);
return(0);
}
- /*********************************************************************
+/*********************************************************************
*
* Function : cgi_show_url_info
*
freez(url_param);
free_current_action(action);
- rsp->body = fill_template(csp, "show-url-info", exports);
+ rsp->body = template_load(csp, "show-url-info");
+ template_fill(&rsp->body, exports);
free_map(exports);
return 0;
freez(path);
free_current_action(action);
- rsp->body = fill_template(csp, "show-url-info", exports);
+ rsp->body = template_load(csp, "show-url-info");
+ template_fill(&rsp->body, exports);
free_map(exports);
return 0;
free_current_action(action);
}
- rsp->body = fill_template(csp, "show-url-info", exports);
+ rsp->body = template_load(csp, "show-url-info");
+ template_fill(&rsp->body, exports);
free_map(exports);
return 0;
if (NULL == (rsp = alloc_http_response()))
{
return NULL;
- }
+ }
map(exports, "host-html", 1, html_encode(csp->http->host), 0);
map(exports, "hostport", 1, csp->http->hostport, 1);
map(exports, "error", 1, safe_strerror(err), 0);
map(exports, "host-ip", 1, csp->http->host_ip_addr_str, 1);
- rsp->body = fill_template(csp, templatename, exports);
+ rsp->body = template_load(csp, templatename);
+ template_fill(&rsp->body, exports);
free_map(exports);
-
+
if (!strcmp(templatename, "no-such-domain"))
{
rsp->status = strdup("404 No such domain");
return(rsp);
}
-
+
/*********************************************************************
*
*********************************************************************/
void free_http_response(struct http_response *rsp)
{
- if(rsp)
+ if (rsp)
{
freez(rsp->status);
freez(rsp->head);
freez(rsp->body);
destroy_list(rsp->headers);
- freez(rsp);
+ free(rsp);
}
}
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
* 3 : template = name of the HTML template to be used
- * 2 : exports = map with fill in symbol -> name pairs
*
- * Returns : char * with filled out form, or NULL if failiure
+ * Returns : char * with loaded template, or NULL if failure
*
*********************************************************************/
-char *fill_template(struct client_state *csp, const char *templatename, struct map *exports)
+char *template_load(struct client_state *csp, const char *templatename)
{
- struct map_entry *m;
- pcrs_job *job;
char buf[BUFFER_SIZE];
- char *tmp_out_buffer;
char *file_buffer = NULL;
- int size;
- int error;
FILE *fp;
-
/*
* Open template file or fail
*/
while (fgets(buf, BUFFER_SIZE, fp))
{
/* skip lines starting with '#' */
- if(*buf == '#') continue;
+ if(*buf == '#')
+ {
+ continue;
+ }
file_buffer = strsav(file_buffer, buf);
}
fclose(fp);
+ return(file_buffer);
+}
- /*
- * Execute the jobs
- */
+
+/*********************************************************************
+ *
+ * Function : fill_template
+ *
+ * Description : CGI support function that loads a given HTML
+ * template from the confdir, and fills it in
+ * by replacing @name@ with value using pcrs,
+ * for each item in the output map.
+ *
+ * Parameters :
+ * 1 : template_ptr = IN: Template to be filled out.
+ * Will be free()d.
+ * OUT: Filled out template.
+ * Caller must free().
+ * 2 : exports = map with fill in symbol -> name pairs
+ *
+ * Returns : N/A
+ *
+ *********************************************************************/
+void template_fill(char ** template_ptr, struct map *exports)
+{
+ struct map_entry *m;
+ pcrs_job *job;
+ char buf[BUFFER_SIZE];
+ char *tmp_out_buffer;
+ char *file_buffer;
+ int size;
+ int error;
+ const char * flags;
+
+ assert(template_ptr);
+ assert(*template_ptr);
+ assert(exports);
+
+ file_buffer = *template_ptr;
size = strlen(file_buffer) + 1;
/*
*/
for (m = exports->first; m != NULL; m = m->next)
{
- /* Enclose name in @@ */
- snprintf(buf, BUFFER_SIZE, "@%s@", m->name);
+ if (*m->name == '$')
+ {
+ /*
+ * First character of name is '$', so remove this flag
+ * character and allow backreferences ($1 etc) in the
+ * "replace with" text.
+ */
+ snprintf(buf, BUFFER_SIZE, "%s", m->name + 1);
+ flags = "sigU";
+ }
+ else
+ {
+ /*
+ * Treat the "replace with" text as a literal string -
+ * no quoting needed, no backreferences allowed.
+ * ("Trivial" ['T'] flag).
+ */
+ flags = "sigTU";
+
+ /* Enclose name in @@ */
+ snprintf(buf, BUFFER_SIZE, "@%s@", m->name);
+ }
+
+
+ log_error(LOG_LEVEL_CGI, "Substituting: s/%s/%s/%s", buf, m->value, flags);
/* Make and run job. */
- job = pcrs_compile(buf, m->value, "sigTU", &error);
+ job = pcrs_compile(buf, m->value, flags, &error);
if (job == NULL)
{
log_error(LOG_LEVEL_ERROR, "Error compiling template fill job %s: %d", m->name, error);
}
}
-
/*
* Return
*/
- return(file_buffer);
-
+ *template_ptr = file_buffer;
}
}
-#ifdef FEATURE_STATISTICS
/*********************************************************************
*
- * Function : add_stats
+ * Function : cgi_robots_txt
*
- * Description : Add the blocking statistics to a given map.
+ * Description : CGI function to return "/robots.txt".
*
* Parameters :
- * 1 : exports = map to write to.
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : rsp = http_response data structure for output
+ * 3 : parameters = map of cgi parameters
*
- * Returns : pointer to extended map
+ * CGI Parameters : None
+ *
+ * Returns : 0
*
*********************************************************************/
-struct map *add_stats(struct map *exports)
+int cgi_robots_txt(struct client_state *csp, struct http_response *rsp,
+ struct map *parameters)
{
- float perc_rej; /* Percentage of http requests rejected */
- char buf[1000];
- int local_urls_read = urls_read;
- int local_urls_rejected = urls_rejected;
-
- /*
- * Need to alter the stats not to include the fetch of this
- * page.
- *
- * Can't do following thread safely! doh!
- *
- * urls_read--;
- * urls_rejected--; * This will be incremented subsequently *
- */
-
- if (local_urls_read == 0)
- {
- map_block_killer(exports, "have-stats");
- }
- else
- {
- map_block_killer(exports, "have-no-stats");
-
- perc_rej = (float)local_urls_rejected * 100.0F /
- (float)local_urls_read;
+ char buf[100];
- sprintf(buf, "%d", local_urls_read);
- map(exports, "requests-received", 1, buf, 1);
+ rsp->body = strdup(
+ "# This is the Internet Junkbuster control interface.\n"
+ "# It isn't very useful to index it, and you're likely to break stuff.\n"
+ "# So go away!\n"
+ "\n"
+ "User-agent: *\n"
+ "Disallow: /\n"
+ "\n");
- sprintf(buf, "%d", local_urls_rejected);
- map(exports, "requests-blocked", 1, buf, 1);
+ enlist_unique(rsp->headers, "Content-Type: text/plain", 13);
- sprintf(buf, "%6.2f", perc_rej);
- map(exports, "percent-blocked", 1, buf, 1);
- }
+ rsp->is_static = 1;
- return(exports);
+ get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */
+ enlist_unique_header(rsp->headers, "Expires", buf);
+ return 0;
}
-#endif /* def FEATURE_STATISTICS */
+
/*
Local Variables: