+ if (rsp->status == NULL)
+ {
+ free_map(exports);
+ free_http_response(rsp);
+ return cgi_error_memory();
+ }
+ }
+
+ err = template_fill_for_cgi(csp, templatename, exports, rsp);
+ if (err)
+ {
+ free_http_response(rsp);
+ return cgi_error_memory();
+ }
+
+ return finish_http_response(rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function : cgi_init_error_messages
+ *
+ * Description : Call at the start of the program to initialize
+ * the error message used by cgi_error_memory().
+ *
+ * Parameters : N/A
+ *
+ * Returns : N/A
+ *
+ *********************************************************************/
+void cgi_init_error_messages(void)
+{
+ memset(cgi_error_memory_response, '\0', sizeof(*cgi_error_memory_response));
+ cgi_error_memory_response->head =
+ "HTTP/1.0 500 Internal JunkBuster Proxy Error\r\n"
+ "Content-Type: text/html\r\n"
+ "\r\n";
+ cgi_error_memory_response->body =
+ "<html>\r\n"
+ "<head><title>500 Internal JunkBuster Proxy Error</title></head>\r\n"
+ "<body>\r\n"
+ "<h1>500 Internal JunkBuster Proxy Error</h1>\r\n"
+ "<p>JunkBuster <b>ran out of memory</b> whilst processing your request.</p>\r\n"
+ "<p>Please contact your proxy administrator, or try again later</p>\r\n"
+ "</body>\r\n"
+ "</html>\r\n";
+
+ cgi_error_memory_response->head_length =
+ strlen(cgi_error_memory_response->head);
+ cgi_error_memory_response->content_length =
+ strlen(cgi_error_memory_response->body);
+}
+
+
+/*********************************************************************
+ *
+ * Function : cgi_error_memory
+ *
+ * Description : Called if a CGI function runs out of memory.
+ * Returns a statically-allocated error response.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : rsp = http_response data structure for output
+ * 3 : template_name = Name of template that could not
+ * be loaded.
+ *
+ * Returns : JB_ERR_OK on success
+ * JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+struct http_response *cgi_error_memory(void)
+{
+ /* assert that it's been initialized. */
+ assert(cgi_error_memory_response->head);
+
+ return cgi_error_memory_response;
+}
+
+
+/*********************************************************************
+ *
+ * Function : cgi_error_no_template
+ *
+ * Description : Almost-CGI function that is called if a templae
+ * cannot be loaded. Note this is not a true CGI,
+ * it takes a template name rather than a map of
+ * parameters.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : rsp = http_response data structure for output
+ * 3 : template_name = Name of template that could not
+ * be loaded.
+ *
+ * Returns : JB_ERR_OK on success
+ * JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_no_template(struct client_state *csp,
+ struct http_response *rsp,
+ const char *template_name)
+{
+ static const char status[] =
+ "500 Internal JunkBuster Proxy Error";
+ static const char body_prefix[] =
+ "<html>\r\n"
+ "<head><title>500 Internal JunkBuster Proxy Error</title></head>\r\n"
+ "<body>\r\n"
+ "<h1>500 Internal JunkBuster Proxy Error</h1>\r\n"
+ "<p>JunkBuster encountered an error whilst processing your request:</p>\r\n"
+ "<p><b>Could not load template file <code>";
+ static const char body_suffix[] =
+ "</code></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 "
+ "in the <code><i>(confdir)</i>/templates</code> directory. The "
+ "location of the <code><i>(confdir)</i></code> directory "
+ "is specified in the main JunkBuster <code>config</code> "
+ "file. (It's typically the JunkBuster install directory"
+#ifndef _WIN32
+ ", or <code>/etc/junkbuster/</code>"
+#endif /* ndef _WIN32 */
+ ").</p>\r\n"
+ "</body>\r\n"
+ "</html>\r\n";
+
+ assert(csp);
+ assert(rsp);
+ assert(template_name);
+
+ /* Reset rsp, if needed */
+ freez(rsp->status);
+ freez(rsp->head);
+ freez(rsp->body);
+ rsp->content_length = 0;
+ rsp->head_length = 0;
+ rsp->is_static = 0;
+
+ rsp->body = malloc(strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1);
+ if (rsp->body == NULL)
+ {
+ return JB_ERR_MEMORY;