2012-03-07 20:55:27 -07:00
|
|
|
int
|
|
|
|
endswith(char *haystack, char *needle)
|
|
|
|
{
|
|
|
|
char *h, *n;
|
|
|
|
|
|
|
|
for (h = haystack; *h; h++);
|
|
|
|
for (n = needle; *n; n++);
|
|
|
|
|
|
|
|
if (h - haystack < n - needle) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (n >= needle) {
|
|
|
|
if (*(n--) != *(h--)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Replace whitespace with underscores for logging */
|
|
|
|
static void
|
|
|
|
sanitize(char *s)
|
|
|
|
{
|
|
|
|
if (!s) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (; *s; s += 1) {
|
|
|
|
if (isspace(*s)) {
|
|
|
|
*s = '_';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Parse a header out of a line.
|
|
|
|
*
|
|
|
|
* This capitalizes the header name, and strips trailing [\r\n]
|
|
|
|
* Returns the length of the line (after stripping)
|
|
|
|
*/
|
|
|
|
size_t
|
|
|
|
extract_header_field(char *buf, char **val, int cgi)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
*val = NULL;
|
|
|
|
|
|
|
|
for (len = 0; buf[len]; len += 1) {
|
|
|
|
if (! *val) {
|
|
|
|
if (buf[len] == '\n') {
|
|
|
|
/* Blank line or incorrectly-formatted header */
|
2012-03-08 15:29:04 -07:00
|
|
|
break;
|
2012-03-07 20:55:27 -07:00
|
|
|
} else if (buf[len] == ':') {
|
|
|
|
buf[len] = 0;
|
|
|
|
for (*val = &(buf[len+1]); **val == ' '; *val += 1);
|
|
|
|
} else if (cgi) {
|
|
|
|
switch (buf[len]) {
|
|
|
|
case 'a'...'z':
|
|
|
|
buf[len] ^= ' ';
|
|
|
|
break;
|
|
|
|
case 'A'...'Z':
|
|
|
|
case '0'...'9':
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
buf[len] = '_';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; (buf[len-1] == '\n') || (buf[len-1] == '\r'); len -= 1);
|
|
|
|
buf[len] = 0;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
fromhex(int c)
|
|
|
|
{
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
return c - '0';
|
|
|
|
else {
|
|
|
|
c |= ' ';
|
|
|
|
if (c >= 'a' && c <= 'f')
|
|
|
|
return c - 'a' + 10;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
html_esc(FILE *f, char *s)
|
|
|
|
{
|
|
|
|
for (; *s; s += 1) {
|
|
|
|
switch (*s) {
|
|
|
|
case '<':
|
|
|
|
fprintf(f, "<");
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
fprintf(f, ">");
|
|
|
|
break;
|
|
|
|
case '&':
|
|
|
|
fprintf(f, "&");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fputc(*s, f);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
url_esc(FILE *f, char *s)
|
|
|
|
{
|
|
|
|
for (; *s; s += 1) {
|
|
|
|
switch (*s) {
|
|
|
|
case '%':
|
|
|
|
case 127:
|
|
|
|
case -127 ... 31:
|
|
|
|
fprintf(f, "%%%02x", *s);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fputc(*s, f);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|