/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* See also support/check_forensic.
* Relate the forensic log to the transfer log by including
* %{forensic-id}n in the custom log format, for example:
*
* Credit is due to Tina Bird <tbird precision-guesswork.com>, whose
* idea this module was.
*
* Ben Laurie 29/12/2003
*/
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "apr_strings.h"
#include "apr_atomic.h"
#include "http_protocol.h"
#include "test_char.h"
#include <unistd.h>
#endif
typedef struct fcfg {
const char *logname;
} fcfg;
{
return cfg;
}
{
return cfg;
}
{
return 1;
return 0;
}
}
else {
APR_OS_DEFAULT, p)) != APR_SUCCESS) {
"could not open forensic log file %s.", fname);
return 0;
}
}
return 1;
}
server_rec *s)
{
for ( ; s ; s = s->next) {
if (!open_log(s, p)) {
return HTTP_INTERNAL_SERVER_ERROR;
}
}
return OK;
}
/* e is the first _invalid_ location in q
N.B. returns the terminating NUL.
*/
static char *log_escape(char *q, const char *e, const char *p)
{
for ( ; *p ; ++p) {
ap_assert(q < e);
if (test_char_table[*(unsigned char *)p]&T_ESCAPE_FORENSIC) {
ap_assert(q+2 < e);
*q++ = '%';
ap_bin2hex(p, 1, q);
q += 2;
}
else
*q++ = *p;
}
ap_assert(q < e);
*q = '\0';
return q;
}
typedef struct hlog {
char *log;
char *pos;
char *end;
apr_pool_t *p;
} hlog;
static int count_string(const char *p)
{
int n;
for (n = 0 ; *p ; ++p, ++n)
if (test_char_table[*(unsigned char *)p]&T_ESCAPE_FORENSIC)
n += 2;
return n;
}
{
return 1;
}
{
/* note that we don't have to check h->pos here, coz its been done
for us by log_escape */
*h->pos++ = '|';
*h->pos++ = ':';
return 1;
}
{
const char *id;
hlog h;
return DECLINED;
}
/* we make the assumption that we can't go through all the PIDs in
under 1 second */
}
h.p = r->pool;
h.count = 0;
*h.pos++ = '+';
*h.pos++ = '|';
*h.pos++ = '\n';
return OK;
}
{
char *s;
apr_size_t n;
return DECLINED;
}
n = strlen(s);
return OK;
}
{
return NULL;
}
{
"the filename of the forensic log"),
{ NULL }
};
{
}
{
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
make_forensic_log_scfg, /* server config */
merge_forensic_log_scfg, /* merge server config */
forensic_log_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};