//
// aegis - project change supervisor
// Copyright (C) 2003-2008, 2011, 2012, 2014 Peter Miller
// Copyright (C) 2007, 2008 Walter Franzini
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// .
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
bool http_fatal_noerror;
void
http_fatal(http_error_t oops, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (oops != http_error_ok && !http_fatal_noerror)
printf("Status: %d Error\n", oops);
printf("Content-Type: text/html\n\n");
printf("ErrorError
\n");
printf("The request failed because:\n");
vprintf(fmt, ap);
va_end(ap);
printf("\n\n");
exit(0);
}
const char *
http_getenv(const char *name)
{
char *result;
result = getenv(name);
if (!result)
{
http_fatal
(
http_error_internal_server,
"Environment variable $%s not set.",
name
);
}
return result;
}
static const char *
http_getenv(const char *name, const char *dflt)
{
char *result = getenv(name);
if (!result)
return dflt;
return result;
}
void
html_escape_charstar(const char *s)
{
html_escape_string(nstring(s));
}
void
html_escape_string(string_ty *s)
{
html_escape_charstar(s->str_text);
}
void
html_escape_string(const nstring &s)
{
fputs(s.url_quote().c_str(), stdout);
}
void
html_encode_charstar(const char *s)
{
html_encode_string(nstring(s));
}
void
html_encode_string(string_ty *s)
{
html_encode_charstar(s->str_text);
}
void
html_encode_string(const nstring &s)
{
fputs(s.html_quote(true).c_str(), stdout);
}
nstring
http_sanitize_content_type(const nstring &content_type)
{
const char *s = content_type.c_str();
const char *semicolon = s;
while (*semicolon && *semicolon != ';' && *semicolon != ' ')
++semicolon;
nstring left(s, semicolon - s);
if (left == "text/html")
return content_type;
while (*semicolon == ';' || *semicolon == ' ')
++semicolon;
nstring right;
if (*semicolon)
{
const char *end = s + content_type.size();
right = "; " + nstring(semicolon, end - semicolon);
}
if
(
left.starts_with("text/")
||
left == "application/x-awk"
||
left == "application/x-gawk"
||
left == "application/x-nawk"
||
left == "application/x-perl"
||
(left.starts_with("application/x-") && left.ends_with("script"))
)
{
if (right.empty())
right = "; charset=us-ascii";
return "text/plain" + right;
}
return content_type;
}
void
http_content_type_header(string_ty *filename)
{
os_become_orig();
nstring content_type = os_magic_file(filename);
os_become_undo();
content_type = http_sanitize_content_type(content_type);
assert(!content_type.empty());
printf("Content-Type: %s\n", content_type.c_str());
}
static void
emit_project_attribute(project *pp, change::pointer cp, const char *cname)
{
if (!pp && cp)
pp = cp->project_get();
if (pp && (!cp || cp->is_bogus()))
cp = pp->change_get();
if (!cp)
return;
pconf_ty *pconf_data = change_pconf_get(cp, 0);
if (!pconf_data->project_specific)
return;
string_ty *name = str_from_c(cname);
for (size_t j = 0; j < pconf_data->project_specific->length; ++j)
{
attributes_ty *ap = pconf_data->project_specific->list[j];
if
(
ap->name
&&
ap->value
&&
0 == strcasecmp(name->str_text, ap->name->str_text)
)
{
printf("%s\n", ap->value->str_text);
}
}
str_free(name);
}
void
html_header_ps(project *pp, change::pointer cp)
{
emit_project_attribute(pp, cp, "html:body-begin");
}
void
html_footer(project *pp, change::pointer cp)
{
time_t tmp = now();
printf("
\n");
printf("This page was generated by %s\n", progname_get());
printf("version %s\n", version_stamp());
char buffer[BUFSIZ];
// gcc 3.3 doesn't like %c
if (strftime(buffer, BUFSIZ, "%a %d %b %Y %H:%M:%S %Z", localtime(&tmp)))
printf("on %s.\n", buffer);
else
printf("on %.24s.\n", ctime(&tmp));
emit_project_attribute(pp, cp, "html:body-end");
printf("