]> granicus.if.org Git - apache/commitdiff
Merge r1532281, r1532289, r1537718 from trunk:
authorJoe Orton <jorton@apache.org>
Fri, 9 Mar 2018 09:09:38 +0000 (09:09 +0000)
committerJoe Orton <jorton@apache.org>
Fri, 9 Mar 2018 09:09:38 +0000 (09:09 +0000)
* support/rotatelogs.c (get_now): Return the offset applied to the
  Unix time as a parameter.
  (doRotate): When exploding the time for strtfime formatting, iff in
  -l mode, subtract the offset and explode the real Unix time as a
  local time so %Z etc works correctly.

* support/rotatelogs.c (get_now): Fix the NULL ptr dereferences
  added in r1532281.

* support/rotatelogs.c: Introduce an adjusted_time_t type to store the
  weird "adjusted time since epoch" type returned by get_now().
  Switch from int to long to fix an unnecessary Y2K38 issue.  Adjust
  use throughout and clean up other type issues.  No functional change
  intended apart from fixing Y2K38.

Submitted by: jorton
Reviewed by: jorton, jim, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1826306 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
support/rotatelogs.c

diff --git a/CHANGES b/CHANGES
index f056fa3a9d64698eb9309cb2cb6e3e9383e2b84b..09923968b58f3f1ff9167afa52cc937c47c3396f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.32
 
+  *) rotatelogs: Fix expansion of %Z in localtime (-l) mode, and fix
+     Y2K38 bug.  [Joe Orton]
+
   *) mod_ssl: Support SSL DN raw variable extraction without conversion
      to UTF-8, using _RAW suffix on variable names.  [Joe Orton]
 
index c2373f56b01e2df8af878f227126c7fa25379655..b03b7dad6d54d8dd8fb5486db29cd2bd485b9ba0 100644 (file)
@@ -76,6 +76,12 @@ struct rotate_config {
 
 typedef struct rotate_status rotate_status_t;
 
+/* "adjusted_time_t" is used to store Unix time (seconds since epoch)
+ * which has been adjusted for some timezone fudge factor.  It should
+ * be used for storing the return values from get_now().  A typedef is
+ * used since this type is similar to time_t, but different. */
+typedef long adjusted_time_t;
+
 /* Structure to contain relevant logfile state: fd, pool and
  * filename. */
 struct logfile {
@@ -89,7 +95,7 @@ struct rotate_status {
     apr_pool_t *pool; /* top-level pool */
     char errbuf[ERRMSGSZ];
     int rotateReason;
-    int tLogEnd;
+    adjusted_time_t tLogEnd;
     int nMessCount;
     int fileNum;
 };
@@ -151,14 +157,14 @@ static void usage(const char *argv0, const char *reason)
     exit(1);
 }
 
-/*
- * Get the unix time with timezone corrections
- * given in the config struct.
- */
-static int get_now(rotate_config_t *config)
+/* This function returns the current Unix time (time_t) adjusted for
+ * any configured or derived local time offset.  The offset applied is
+ * returned via *offset. */
+static adjusted_time_t get_now(rotate_config_t *config, apr_int32_t *offset)
 {
     apr_time_t tNow = apr_time_now();
-    int utc_offset = config->utc_offset;
+    apr_int32_t utc_offset;
+
     if (config->use_localtime) {
         /* Check for our UTC offset before using it, since it might
          * change if there's a switch between standard and daylight
@@ -168,7 +174,14 @@ static int get_now(rotate_config_t *config)
         apr_time_exp_lt(&lt, tNow);
         utc_offset = lt.tm_gmtoff;
     }
-    return (int)apr_time_sec(tNow) + utc_offset;
+    else {
+        utc_offset = config->utc_offset;
+    }
+
+    if (offset)
+        *offset = utc_offset;
+
+    return apr_time_sec(tNow) + utc_offset;
 }
 
 /*
@@ -231,13 +244,13 @@ static void checkRotate(rotate_config_t *config, rotate_status_t *status)
             status->rotateReason = ROTATE_SIZE;
         }
         else if (config->tRotation) {
-            if (get_now(config) >= status->tLogEnd) {
+            if (get_now(config, NULL) >= status->tLogEnd) {
                 status->rotateReason = ROTATE_TIME;
             }
         }
     }
     else if (config->tRotation) {
-        if (get_now(config) >= status->tLogEnd) {
+        if (get_now(config, NULL) >= status->tLogEnd) {
             status->rotateReason = ROTATE_TIME;
         }
     }
@@ -360,17 +373,20 @@ static void truncate_and_write_error(rotate_status_t *status)
  */
 static void doRotate(rotate_config_t *config, rotate_status_t *status)
 {
-
-    int now = get_now(config);
-    int tLogStart;
+    apr_int32_t offset;
+    adjusted_time_t now, tLogStart;
     apr_status_t rv;
     struct logfile newlog;
     int thisLogNum = -1;
 
+    /* Retrieve local-time-adjusted-Unix-time. */
+    now = get_now(config, &offset);
+
     status->rotateReason = ROTATE_NONE;
 
     if (config->tRotation) {
-        int tLogEnd;
+        adjusted_time_t tLogEnd;
+
         tLogStart = (now / config->tRotation) * config->tRotation;
         tLogEnd = tLogStart + config->tRotation;
         /*
@@ -392,7 +408,13 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status)
         apr_time_exp_t e;
         apr_size_t rs;
 
-        apr_time_exp_gmt(&e, tNow);
+        /* Explode the local-time-adjusted-Unix-time into a struct tm,
+         * first *reversing* local-time-adjustment applied by
+         * get_now() if we are using localtime. */
+        if (config->use_localtime)
+            apr_time_exp_lt(&e, tNow - apr_time_from_sec(offset));
+        else
+            apr_time_exp_gmt(&e, tNow);
         apr_strftime(newlog.name, &rs, sizeof(newlog.name), config->szLogRoot, &e);
     }
     else {
@@ -410,7 +432,7 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status)
             }
         }
         else {
-            apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%010d", config->szLogRoot,
+            apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%010ld", config->szLogRoot,
                          tLogStart);
         }
     }
@@ -532,7 +554,7 @@ int main (int argc, const char * const argv[])
 #if APR_FILES_AS_SOCKETS
     apr_pollfd_t pollfd = { 0 };
     apr_status_t pollret = APR_SUCCESS;
-    int polltimeout;
+    long polltimeout;
 #endif
 
     apr_app_initialize(&argc, &argv, NULL);
@@ -660,7 +682,7 @@ int main (int argc, const char * const argv[])
         nRead = sizeof(buf);
 #if APR_FILES_AS_SOCKETS
         if (config.create_empty && config.tRotation) {
-            polltimeout = status.tLogEnd ? status.tLogEnd - get_now(&config) : config.tRotation;
+            polltimeout = status.tLogEnd ? status.tLogEnd - get_now(&config, NULL) : config.tRotation;
             if (polltimeout <= 0) {
                 pollret = APR_TIMEUP;
             }