summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/NWGNUmakefile2
-rw-r--r--server/buildmark.c2
-rw-r--r--server/config.c3
-rw-r--r--server/core.c69
-rw-r--r--server/core_filters.c62
-rw-r--r--server/log.c51
-rw-r--r--server/main.c10
-rw-r--r--server/mpm_unix.c16
-rw-r--r--server/scoreboard.c4
-rw-r--r--server/util.c5
-rw-r--r--server/util_expr_eval.c16
-rw-r--r--server/util_expr_parse.c2
-rw-r--r--server/util_script.c54
-rw-r--r--server/util_time.c35
14 files changed, 220 insertions, 111 deletions
diff --git a/server/NWGNUmakefile b/server/NWGNUmakefile
index 7f96e81..4917811 100644
--- a/server/NWGNUmakefile
+++ b/server/NWGNUmakefile
@@ -225,7 +225,7 @@ FILES_lib_objs = \
$(EOLIST)
#
-# implement targets and dependancies (leave this section alone)
+# implement targets and dependencies (leave this section alone)
#
libs :: $(OBJDIR) $(TARGET_lib)
diff --git a/server/buildmark.c b/server/buildmark.c
index a9cd684..36bd713 100644
--- a/server/buildmark.c
+++ b/server/buildmark.c
@@ -23,7 +23,7 @@ static const char server_built[] = __DATE__ " " __TIME__;
static const char server_built[] = "unknown";
#endif
-AP_DECLARE(const char *) ap_get_server_built()
+AP_DECLARE(const char *) ap_get_server_built(void)
{
return server_built;
}
diff --git a/server/config.c b/server/config.c
index be889db..3d11ff5 100644
--- a/server/config.c
+++ b/server/config.c
@@ -2301,6 +2301,9 @@ AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
if (s == NULL) {
return s;
}
+ if (ap_server_conf == NULL) {
+ ap_server_conf = s;
+ }
init_config_globals(p);
diff --git a/server/core.c b/server/core.c
index e1493fd..e5e059e 100644
--- a/server/core.c
+++ b/server/core.c
@@ -95,6 +95,7 @@
APR_HOOK_STRUCT(
APR_HOOK_LINK(get_mgmt_items)
APR_HOOK_LINK(insert_network_bucket)
+ APR_HOOK_LINK(get_pollfd_from_conn)
)
AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items,
@@ -106,6 +107,11 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, insert_network_bucket,
apr_socket_t *socket),
(c, bb, socket), AP_DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, get_pollfd_from_conn,
+ (conn_rec *c, struct apr_pollfd_t *pfd,
+ apr_interval_time_t *ptimeout),
+ (c, pfd, ptimeout), APR_ENOTIMPL)
+
/* Server core module... This module provides support for really basic
* server operations, including options and commands which control the
* operation of other modules. Consider this the bureaucracy module.
@@ -489,6 +495,11 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s)
conf->flush_max_pipelined = AP_FLUSH_MAX_PIPELINED;
}
else {
+ /* Use main ErrorLogFormat while the vhost is loading */
+ core_server_config *main_conf =
+ ap_get_core_module_config(ap_server_conf->module_config);
+ conf->error_log_format = main_conf->error_log_format;
+
conf->flush_max_pipelined = -1;
}
@@ -3951,24 +3962,26 @@ static const char *set_recursion_limit(cmd_parms *cmd, void *dummy,
static void log_backtrace(const request_rec *r)
{
- const request_rec *top = r;
+ if (APLOGrdebug(r)) {
+ const request_rec *top = r;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00121)
- "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)");
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00121)
+ "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)");
- while (top && (top->prev || top->main)) {
- if (top->prev) {
- top = top->prev;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00122)
- "redirected from r->uri = %s",
- top->uri ? top->uri : "(unexpectedly NULL)");
- }
+ while (top && (top->prev || top->main)) {
+ if (top->prev) {
+ top = top->prev;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00122)
+ "redirected from r->uri = %s",
+ top->uri ? top->uri : "(unexpectedly NULL)");
+ }
- if (!top->prev && top->main) {
- top = top->main;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00123)
- "subrequested from r->uri = %s",
- top->uri ? top->uri : "(unexpectedly NULL)");
+ if (!top->prev && top->main) {
+ top = top->main;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00123)
+ "subrequested from r->uri = %s",
+ top->uri ? top->uri : "(unexpectedly NULL)");
+ }
}
}
}
@@ -5597,6 +5610,28 @@ static int core_upgrade_storage(request_rec *r)
return DECLINED;
}
+static apr_status_t core_get_pollfd_from_conn(conn_rec *c,
+ struct apr_pollfd_t *pfd,
+ apr_interval_time_t *ptimeout)
+{
+ if (c && !c->master) {
+ pfd->desc_type = APR_POLL_SOCKET;
+ pfd->desc.s = ap_get_conn_socket(c);
+ if (ptimeout) {
+ apr_socket_timeout_get(pfd->desc.s, ptimeout);
+ }
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
+}
+
+AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c,
+ struct apr_pollfd_t *pfd,
+ apr_interval_time_t *ptimeout)
+{
+ return ap_run_get_pollfd_from_conn(c, pfd, ptimeout);
+}
+
static void register_hooks(apr_pool_t *p)
{
errorlog_hash = apr_hash_make(p);
@@ -5640,7 +5675,9 @@ static void register_hooks(apr_pool_t *p)
ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST);
ap_hook_optional_fn_retrieve(core_optional_fn_retrieve, NULL, NULL,
APR_HOOK_MIDDLE);
-
+ ap_hook_get_pollfd_from_conn(core_get_pollfd_from_conn, NULL, NULL,
+ APR_HOOK_REALLY_LAST);
+
/* register the core's insert_filter hook and register core-provided
* filters
*/
diff --git a/server/core_filters.c b/server/core_filters.c
index d8a661f..c4ab603 100644
--- a/server/core_filters.c
+++ b/server/core_filters.c
@@ -719,41 +719,41 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
if (!nvec) {
apr_bucket_delete(bucket);
}
- continue;
}
-
- /* Make sure that these new data fit in our iovec. */
- if (nvec == ctx->nvec) {
- if (nvec == NVEC_MAX) {
- sock_nopush(s, 1);
- rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
- if (rv != APR_SUCCESS) {
- goto cleanup;
- }
- nbytes = 0;
- nvec = 0;
- }
- else {
- struct iovec *newvec;
- apr_size_t newn = nvec * 2;
- if (newn < NVEC_MIN) {
- newn = NVEC_MIN;
- }
- else if (newn > NVEC_MAX) {
- newn = NVEC_MAX;
+ else {
+ /* Make sure that these new data fit in our iovec. */
+ if (nvec == ctx->nvec) {
+ if (nvec == NVEC_MAX) {
+ sock_nopush(s, 1);
+ rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
+ if (rv != APR_SUCCESS) {
+ goto cleanup;
+ }
+ nbytes = 0;
+ nvec = 0;
}
- newvec = apr_palloc(c->pool, newn * sizeof(struct iovec));
- if (nvec) {
- memcpy(newvec, ctx->vec, nvec * sizeof(struct iovec));
+ else {
+ struct iovec *newvec;
+ apr_size_t newn = nvec * 2;
+ if (newn < NVEC_MIN) {
+ newn = NVEC_MIN;
+ }
+ else if (newn > NVEC_MAX) {
+ newn = NVEC_MAX;
+ }
+ newvec = apr_palloc(c->pool, newn * sizeof(struct iovec));
+ if (nvec) {
+ memcpy(newvec, ctx->vec, nvec * sizeof(struct iovec));
+ }
+ ctx->vec = newvec;
+ ctx->nvec = newn;
}
- ctx->vec = newvec;
- ctx->nvec = newn;
}
+ nbytes += length;
+ ctx->vec[nvec].iov_base = (void *)data;
+ ctx->vec[nvec].iov_len = length;
+ nvec++;
}
- nbytes += length;
- ctx->vec[nvec].iov_base = (void *)data;
- ctx->vec[nvec].iov_len = length;
- nvec++;
/* Flush above max threshold, unless the brigade still contains in
* memory buckets which we want to try writing in the same pass (if
@@ -762,7 +762,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
*/
if (nbytes > conf->flush_max_threshold
&& next != APR_BRIGADE_SENTINEL(bb)
- && !is_in_memory_bucket(next)) {
+ && next->length && !is_in_memory_bucket(next)) {
sock_nopush(s, 1);
rv = writev_nonblocking(s, bb, ctx, nbytes, nvec, c);
if (rv != APR_SUCCESS) {
diff --git a/server/log.c b/server/log.c
index cc04c38..22d2f8d 100644
--- a/server/log.c
+++ b/server/log.c
@@ -55,7 +55,7 @@
#include "ap_mpm.h"
#include "ap_listen.h"
-#if HAVE_GETTID
+#ifdef HAVE_SYS_GETTID
#include <sys/syscall.h>
#include <sys/types.h>
#endif
@@ -627,14 +627,18 @@ static int log_tid(const ap_errorlog_info *info, const char *arg,
#if APR_HAS_THREADS
int result;
#endif
-#if HAVE_GETTID
+#if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID)
if (arg && *arg == 'g') {
+#ifdef HAVE_GETTID
+ pid_t tid = gettid();
+#else
pid_t tid = syscall(SYS_gettid);
+#endif
if (tid == -1)
return 0;
return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid);
}
-#endif
+#endif /* HAVE_GETTID || HAVE_SYS_GETTID */
#if APR_HAS_THREADS
if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS
&& result != AP_MPMQ_NOT_SUPPORTED)
@@ -652,14 +656,32 @@ static int log_ctime(const ap_errorlog_info *info, const char *arg,
int time_len = buflen;
int option = AP_CTIME_OPTION_NONE;
- while (arg && *arg) {
- switch (*arg) {
- case 'u': option |= AP_CTIME_OPTION_USEC;
- break;
- case 'c': option |= AP_CTIME_OPTION_COMPACT;
- break;
+ if (arg) {
+ if (arg[0] == 'u' && !arg[1]) { /* no ErrorLogFormat (fast path) */
+ option |= AP_CTIME_OPTION_USEC;
+ }
+ else if (!ap_strchr_c(arg, '%')) { /* special "%{cuz}t" formats */
+ while (*arg) {
+ switch (*arg++) {
+ case 'u':
+ option |= AP_CTIME_OPTION_USEC;
+ break;
+ case 'c':
+ option |= AP_CTIME_OPTION_COMPACT;
+ break;
+ case 'z':
+ option |= AP_CTIME_OPTION_GMTOFF;
+ break;
+ }
+ }
+ }
+ else { /* "%{strftime %-format}t" */
+ apr_size_t len = 0;
+ apr_time_exp_t expt;
+ ap_explode_recent_localtime(&expt, apr_time_now());
+ apr_strftime(buf, &len, buflen, arg, &expt);
+ return (int)len;
}
- arg++;
}
ap_recent_ctime_ex(buf, apr_time_now(), option, &time_len);
@@ -1166,6 +1188,11 @@ static void log_error_core(const char *file, int line, int module_index,
#endif
logf = stderr_log;
+
+ /* Use the main ErrorLogFormat if any */
+ if (ap_server_conf) {
+ sconf = ap_get_core_module_config(ap_server_conf->module_config);
+ }
}
else {
int configured_level = r ? ap_get_request_module_loglevel(r, module_index) :
@@ -1219,6 +1246,10 @@ static void log_error_core(const char *file, int line, int module_index,
}
}
}
+ else if (ap_server_conf) {
+ /* Use the main ErrorLogFormat if any */
+ sconf = ap_get_core_module_config(ap_server_conf->module_config);
+ }
}
info.s = s;
diff --git a/server/main.c b/server/main.c
index 7da7aa2..fb23f01 100644
--- a/server/main.c
+++ b/server/main.c
@@ -678,8 +678,8 @@ int main(int argc, const char * const argv[])
if (temp_error_log) {
ap_replace_stderr_log(process->pool, temp_error_log);
}
- ap_server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
- if (!ap_server_conf) {
+ ap_server_conf = NULL; /* set early by ap_read_config() for logging */
+ if (!ap_read_config(process, ptemp, confname, &ap_conftree)) {
if (showcompile) {
/* Well, we tried. Show as much as we can, but exit nonzero to
* indicate that something's not right. The cause should have
@@ -688,6 +688,7 @@ int main(int argc, const char * const argv[])
}
destroy_and_exit_process(process, 1);
}
+ ap_assert(ap_server_conf != NULL);
apr_pool_cleanup_register(pconf, &ap_server_conf, ap_pool_cleanup_set_null,
apr_pool_cleanup_null);
@@ -785,10 +786,11 @@ int main(int argc, const char * const argv[])
apr_pool_create(&ptemp, pconf);
apr_pool_tag(ptemp, "ptemp");
ap_server_root = def_server_root;
- ap_server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
- if (!ap_server_conf) {
+ ap_server_conf = NULL; /* set early by ap_read_config() for logging */
+ if (!ap_read_config(process, ptemp, confname, &ap_conftree)) {
destroy_and_exit_process(process, 1);
}
+ ap_assert(ap_server_conf != NULL);
apr_pool_cleanup_register(pconf, &ap_server_conf,
ap_pool_cleanup_set_null, apr_pool_cleanup_null);
/* sort hooks here to make sure pre_config hooks are sorted properly */
diff --git a/server/mpm_unix.c b/server/mpm_unix.c
index 8c4d233..ed4555a 100644
--- a/server/mpm_unix.c
+++ b/server/mpm_unix.c
@@ -259,10 +259,12 @@ AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
while (cur_extra) {
ap_generation_t old_gen;
extra_process_t *next = cur_extra->next;
+ pid_t pid = cur_extra->pid;
- if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
- mpm_callback(-1, cur_extra->pid, old_gen);
+ if (reclaim_one_pid(pid, action_table[cur_action].action)) {
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
+ /* cur_extra dangling pointer from here. */
+ mpm_callback(-1, pid, old_gen);
}
else {
AP_DEBUG_ASSERT(1 == 0);
@@ -307,10 +309,12 @@ AP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callba
while (cur_extra) {
ap_generation_t old_gen;
extra_process_t *next = cur_extra->next;
+ pid_t pid = cur_extra->pid;
- if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
- mpm_callback(-1, cur_extra->pid, old_gen);
+ if (reclaim_one_pid(pid, DO_NOTHING)) {
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
+ /* cur_extra dangling pointer from here. */
+ mpm_callback(-1, pid, old_gen);
}
else {
AP_DEBUG_ASSERT(1 == 0);
diff --git a/server/scoreboard.c b/server/scoreboard.c
index 12dd56a..49d1600 100644
--- a/server/scoreboard.c
+++ b/server/scoreboard.c
@@ -653,7 +653,7 @@ AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status)
}
}
-AP_DECLARE(int) ap_update_global_status()
+AP_DECLARE(int) ap_update_global_status(void)
{
#ifdef HAVE_TIMES
if (ap_scoreboard_image == NULL) {
@@ -707,7 +707,7 @@ AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)
return &ap_scoreboard_image->parent[x];
}
-AP_DECLARE(global_score *) ap_get_scoreboard_global()
+AP_DECLARE(global_score *) ap_get_scoreboard_global(void)
{
return ap_scoreboard_image->global;
}
diff --git a/server/util.c b/server/util.c
index 2015e43..45502b8 100644
--- a/server/util.c
+++ b/server/util.c
@@ -502,6 +502,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
int ret = 1;
apr_size_t l = 1, w = 1, n;
int decode_unreserved = (flags & AP_NORMALIZE_DECODE_UNRESERVED) != 0;
+ int merge_slashes = (flags & AP_NORMALIZE_MERGE_SLASHES) != 0;
if (!IS_SLASH(path[0])) {
/* Besides "OPTIONS *", a request-target should start with '/'
@@ -546,7 +547,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags)
if (w == 0 || IS_SLASH(path[w - 1])) {
/* Collapse ///// sequences to / */
- if ((flags & AP_NORMALIZE_MERGE_SLASHES) && IS_SLASH(path[l])) {
+ if (merge_slashes && IS_SLASH(path[l])) {
do {
l++;
} while (IS_SLASH(path[l]));
@@ -3143,7 +3144,7 @@ AP_DECLARE(apr_status_t) ap_varbuf_regsub(struct ap_varbuf *vb,
static const char * const oom_message = "[crit] Memory allocation failed, "
"aborting process." APR_EOL_STR;
-AP_DECLARE(void) ap_abort_on_oom()
+AP_DECLARE(void) ap_abort_on_oom(void)
{
int written, count = strlen(oom_message);
const char *buf = oom_message;
diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c
index 7d6ae1e..db4be95 100644
--- a/server/util_expr_eval.c
+++ b/server/util_expr_eval.c
@@ -1271,7 +1271,7 @@ static int op_file_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *a
APR_DECLARE_OPTIONAL_FN(int, http2_is_h2, (conn_rec *));
static APR_OPTIONAL_FN_TYPE(http2_is_h2) *is_http2 = NULL;
-static const char *conn_var_names[] = {
+static const char *const conn_var_names[] = {
"HTTPS", /* 0 */
"IPV6", /* 1 */
"CONN_LOG_ID", /* 2 */
@@ -1321,7 +1321,7 @@ static const char *conn_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
}
}
-static const char *request_var_names[] = {
+static const char *const request_var_names[] = {
"REQUEST_METHOD", /* 0 */
"REQUEST_SCHEME", /* 1 */
"REQUEST_URI", /* 2 */
@@ -1449,7 +1449,7 @@ static const char *request_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
}
}
-static const char *req_header_var_names[] = {
+static const char *const req_header_var_names[] = {
"HTTP_USER_AGENT", /* 0 */
"HTTP_PROXY_CONNECTION", /* 1 */
"HTTP_REFERER", /* 2 */
@@ -1460,7 +1460,7 @@ static const char *req_header_var_names[] = {
NULL
};
-static const char *req_header_header_names[] = {
+static const char *const req_header_header_names[] = {
"User-Agent",
"Proxy-Connection",
"Referer",
@@ -1472,7 +1472,7 @@ static const char *req_header_header_names[] = {
static const char *req_header_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
{
- const char **varname = (const char **)data;
+ const char **const varname = (const char **)data;
int index = (varname - req_header_var_names);
const char *name;
@@ -1490,7 +1490,7 @@ static const char *req_header_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
return apr_table_get(ctx->r->headers_in, name);
}
-static const char *misc_var_names[] = {
+static const char *const misc_var_names[] = {
"TIME_YEAR", /* 0 */
"TIME_MON", /* 1 */
"TIME_DAY", /* 2 */
@@ -1647,7 +1647,7 @@ struct expr_provider_single {
struct expr_provider_multi {
const void *func;
- const char **names;
+ const char *const *names;
};
static const struct expr_provider_multi var_providers[] = {
@@ -1716,7 +1716,7 @@ static int core_expr_lookup(ap_expr_lookup_parms *parms)
case AP_EXPR_FUNC_VAR: {
const struct expr_provider_multi *prov = var_providers;
while (prov->func) {
- const char **name = prov->names;
+ const char *const *name = prov->names;
while (*name) {
if (ap_cstr_casecmp(*name, parms->name) == 0) {
*parms->func = prov->func;
diff --git a/server/util_expr_parse.c b/server/util_expr_parse.c
index bcf0173..ac4a323 100644
--- a/server/util_expr_parse.c
+++ b/server/util_expr_parse.c
@@ -1326,6 +1326,8 @@ YYSTYPE yylval;
goto yysetstate;
+ /* TODO: comppiler warning that this is unused, and it seems to */
+ (void)yynerrs;
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. |
`------------------------------------------------------------*/
diff --git a/server/util_script.c b/server/util_script.c
index 45c49d5..1fa4276 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va
}
}
-static void env2env(apr_table_t *table, const char *name)
+/* Sets variable @name in table @dest from r->subprocess_env if
+ * available, else from the environment, else from @fallback if
+ * non-NULL. */
+static void env2env(apr_table_t *dest, request_rec *r,
+ const char *name, const char *fallback)
{
- add_unless_null(table, name, getenv(name));
+ const char *val;
+
+ val = apr_table_get(r->subprocess_env, name);
+ if (!val)
+ val = apr_pstrdup(r->pool, getenv(name));
+ if (!val)
+ val = apr_pstrdup(r->pool, fallback);
+ if (val)
+ apr_table_addn(dest, name, val);
}
AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
}
- env_temp = apr_table_get(r->subprocess_env, "PATH");
- if (env_temp == NULL) {
- env_temp = getenv("PATH");
- }
- if (env_temp == NULL) {
- env_temp = DEFAULT_PATH;
- }
- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));
-
+ env2env(e, r, "PATH", DEFAULT_PATH);
#if defined(WIN32)
- env2env(e, "SystemRoot");
- env2env(e, "COMSPEC");
- env2env(e, "PATHEXT");
- env2env(e, "WINDIR");
+ env2env(e, r, "SystemRoot", NULL);
+ env2env(e, r, "COMSPEC", NULL);
+ env2env(e, r, "PATHEXT", NULL);
+ env2env(e, r, "WINDIR", NULL);
#elif defined(OS2)
- env2env(e, "COMSPEC");
- env2env(e, "ETC");
- env2env(e, "DPATH");
- env2env(e, "PERLLIB_PREFIX");
+ env2env(e, r, "COMSPEC", NULL);
+ env2env(e, r, "ETC", NULL);
+ env2env(e, r, "DPATH", NULL);
+ env2env(e, r, "PERLLIB_PREFIX", NULL);
#elif defined(BEOS)
- env2env(e, "LIBRARY_PATH");
+ env2env(e, r, "LIBRARY_PATH", NULL);
#elif defined(DARWIN)
- env2env(e, "DYLD_LIBRARY_PATH");
+ env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
#elif defined(_AIX)
- env2env(e, "LIBPATH");
+ env2env(e, r, "LIBPATH", NULL);
#elif defined(__HPUX__)
/* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
- env2env(e, "SHLIB_PATH");
- env2env(e, "LD_LIBRARY_PATH");
+ env2env(e, r, "SHLIB_PATH", NULL);
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
#else /* Some Unix */
- env2env(e, "LD_LIBRARY_PATH");
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
#endif
apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
diff --git a/server/util_time.c b/server/util_time.c
index 3632d0d..299b53c 100644
--- a/server/util_time.c
+++ b/server/util_time.c
@@ -22,9 +22,11 @@
* */
#define AP_CTIME_USEC_LENGTH 7
-/* Length of ISO 8601 date/time */
+/* Length of ISO 8601 date/time (including trailing '\0') */
#define AP_CTIME_COMPACT_LEN 20
+/* Length of timezone offset from GMT ([+-]hhmm) plus leading space */
+#define AP_CTIME_GMTOFF_LEN 6
/* Cache for exploded values of recent timestamps
*/
@@ -181,7 +183,13 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
needed += AP_CTIME_USEC_LENGTH;
}
- /* Check the provided buffer length */
+ if (option & AP_CTIME_OPTION_GMTOFF) {
+ needed += AP_CTIME_GMTOFF_LEN;
+ }
+
+ /* Check the provided buffer length (note: above AP_CTIME_COMPACT_LEN
+ * and APR_CTIME_LEN include the trailing '\0'; so does 'needed' then).
+ */
if (len && *len >= needed) {
*len = needed;
}
@@ -193,9 +201,10 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
}
/* example without options: "Wed Jun 30 21:49:08 1993" */
- /* 123456789012345678901234 */
/* example for compact format: "1993-06-30 21:49:08" */
- /* 1234567890123456789 */
+ /* example for compact+usec+gmtoff format:
+ * "1993-06-30 22:49:08.123456 +0100"
+ */
ap_explode_recent_localtime(&xt, t);
real_year = 1900 + xt.tm_year;
@@ -249,7 +258,23 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
}
- *date_str++ = 0;
+ if (option & AP_CTIME_OPTION_GMTOFF) {
+ int off = xt.tm_gmtoff, off_hh, off_mm;
+ char sign = '+';
+ if (off < 0) {
+ off = -off;
+ sign = '-';
+ }
+ off_hh = off / 3600;
+ off_mm = off % 3600 / 60;
+ *date_str++ = ' ';
+ *date_str++ = sign;
+ *date_str++ = off_hh / 10 + '0';
+ *date_str++ = off_hh % 10 + '0';
+ *date_str++ = off_mm / 10 + '0';
+ *date_str++ = off_mm % 10 + '0';
+ }
+ *date_str = 0;
return APR_SUCCESS;
}