From: Yann Ylavic Date: Tue, 14 Mar 2023 11:11:24 +0000 (+0000) Subject: core: Add formats %{z} and %{strftime-format} to ErrorLogFormat. PR 62161. X-Git-Tag: 2.5.0-alpha2-ci-test-only~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5fa6ee46ec1d32aa4c85edce752905a21e0cfad;p=thirdparty%2Fapache%2Fhttpd.git core: Add formats %{z} and %{strftime-format} to ErrorLogFormat. PR 62161. %{z} prints the timezone offset (i.e. "[+-]nnnn") and %{strftime-format} allows any %-format handled by [apr_]strftime(). * include/util_time.h(): Define new AP_CTIME_OPTION_GMTOFF option for ap_recent_ctime_ex(). * server/util_time.c(ap_recent_ctime_ex): Handle AP_CTIME_OPTION_GMTOFF to print "[+-]nnnn" timezone. * server/log.c(log_ctime): If the format contains a '%' it's for strftime(), otherwise it's builtin with new 'z' as AP_CTIME_OPTION_GMTOFF. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908380 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/errorlogformat.txt b/changes-entries/errorlogformat.txt new file mode 100644 index 00000000000..4906ae599d1 --- /dev/null +++ b/changes-entries/errorlogformat.txt @@ -0,0 +1,3 @@ + *) core: Add formats %{z} and %{strftime-format} to ErrorLogFormat. + PR 62161. [Yann Ylavic] + diff --git a/include/util_time.h b/include/util_time.h index 9f54c912a3f..6ba24a2e056 100644 --- a/include/util_time.h +++ b/include/util_time.h @@ -47,6 +47,8 @@ extern "C" { #define AP_CTIME_OPTION_USEC 0x1 /* Use more compact ISO 8601 format */ #define AP_CTIME_OPTION_COMPACT 0x2 +/* Add timezone offset from GMT ([+-]hhmm) */ +#define AP_CTIME_OPTION_GMTOFF 0x4 /** diff --git a/server/log.c b/server/log.c index 6295f1a89c4..f3347d98346 100644 --- a/server/log.c +++ b/server/log.c @@ -573,14 +573,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); diff --git a/server/util_time.c b/server/util_time.c index 995716b318f..95df38d8b9f 100644 --- a/server/util_time.c +++ b/server/util_time.c @@ -16,6 +16,7 @@ #include "util_time.h" #include "apr_env.h" +#include "apr_strings.h" @@ -27,6 +28,8 @@ /* Length of ISO 8601 date/time */ #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 */ @@ -183,6 +186,10 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t, needed += AP_CTIME_USEC_LENGTH; } + if (option & AP_CTIME_OPTION_GMTOFF) { + needed += AP_CTIME_GMTOFF_LEN; + } + /* Check the provided buffer length */ if (len && *len >= needed) { *len = needed; @@ -195,9 +202,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; @@ -251,7 +259,19 @@ 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; + char sign = '+'; + if (off < 0) { + off = -off; + sign = '-'; + } + apr_snprintf(date_str, AP_CTIME_GMTOFF_LEN + 1, " %c%.2d%.2d", + sign, off / 3600, (off % 3600) / 60); + } + else { + *date_str = 0; + } return APR_SUCCESS; }