e000aa4
From 5ec0b86e5c1ff060720b5a6cd1af9d93ec993650 Mon Sep 17 00:00:00 2001
8167548
From: Martin Sehnoutka <msehnout@redhat.com>
e000aa4
Date: Thu, 29 Sep 2016 11:14:03 +0200
Ondřej Lysoněk 7c0626d
Subject: [PATCH 17/59] Fix an issue with timestamps during DST.
8167548
e000aa4
vsftpd now checks whether a file was uploaded during DST and
e000aa4
adjust the timestamp accordingly.
8167548
---
8167548
 sysutil.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++----------------
8167548
 1 file changed, 77 insertions(+), 27 deletions(-)
8167548
8167548
diff --git a/sysutil.c b/sysutil.c
e000aa4
index c848356..2abdd13 100644
8167548
--- a/sysutil.c
8167548
+++ b/sysutil.c
Jiri Skala 6666d8a
@@ -26,8 +26,10 @@
Jiri Skala 6666d8a
 /* For Linux, this adds nothing :-) */
Jiri Skala 6666d8a
 #include "port/porting_junk.h"
Jiri Skala 6666d8a
 
Jiri Skala 6666d8a
+#define F_LOCALTIME "/etc/localtime"
Jiri Skala 6666d8a
+#define BUFTZSIZ 64
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
 #include <signal.h>
Jiri Skala 6666d8a
-#include <string.h>
Jiri Skala 6666d8a
 #include <stdlib.h>
Jiri Skala 6666d8a
 #include <unistd.h>
Jiri Skala 6666d8a
 #include <sys/types.h>
e000aa4
@@ -56,6 +58,11 @@
Jiri Skala 6666d8a
 #include <netdb.h>
Jiri Skala 6666d8a
 #include <sys/resource.h>
e000aa4
 
Jiri Skala 6666d8a
+#ifndef __USE_GNU
Jiri Skala 6666d8a
+  #define __USE_GNU
Jiri Skala 6666d8a
+#endif
Jiri Skala 6666d8a
+#include <string.h>
e000aa4
+
Jiri Skala 6666d8a
 /* Private variables to this file */
Jiri Skala 6666d8a
 /* Current umask() */
e000aa4
 static unsigned int s_current_umask;
8167548
@@ -2574,49 +2581,92 @@ error:
Jiri Skala 6666d8a
   die("reopening standard file descriptors to /dev/null failed");
Jiri Skala 6666d8a
 }
Jiri Skala 6666d8a
 
Jiri Skala 6666d8a
+char* vsf_sysutil_get_tz()
Jiri Skala 6666d8a
+{
Jiri Skala 6666d8a
+  char *ret_tz = NULL;
Jiri Skala 6666d8a
+  char buff[BUFTZSIZ];
Jiri Skala 6666d8a
+  off_t s_pos, e_pos;
Jiri Skala 6666d8a
+  size_t rcnt, rest;
Jiri Skala 6666d8a
+  int fd;
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+  if ((fd = open(F_LOCALTIME, O_RDONLY)) > -1)
Jiri Skala 6666d8a
+  {
Jiri Skala 6666d8a
+    if ((e_pos = lseek(fd, 0, SEEK_END)) <= 0)
Jiri Skala 6666d8a
+    {
Jiri Skala 6666d8a
+      close(fd);
Jiri Skala 6666d8a
+      return NULL;
Jiri Skala 6666d8a
+    }
Jiri Skala 6666d8a
+    s_pos = e_pos > BUFTZSIZ ? e_pos - BUFTZSIZ : 0;
Jiri Skala 6666d8a
+    lseek(fd, s_pos, SEEK_SET);
Jiri Skala 6666d8a
+    rcnt = read(fd, buff, BUFTZSIZ);
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+    if (rcnt && buff[rcnt-1] == '\n')
Jiri Skala 6666d8a
+    {
Jiri Skala 6666d8a
+      buff[rcnt-1] = 0;
Jiri Skala 6666d8a
+      e_pos--;
Jiri Skala 6666d8a
+    }
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+    do {
Jiri Skala 6666d8a
+       char *nl = memrchr(buff, '\n', rcnt);
Jiri Skala 6666d8a
+       if (rcnt && nl)
Jiri Skala 6666d8a
+       {
Jiri Skala 6666d8a
+         int offset = (++nl) - buff;
Jiri Skala 6666d8a
+         int len = e_pos - s_pos - offset;
Jiri Skala 6666d8a
+         if (len)
Jiri Skala 6666d8a
+         {
Jiri Skala 6666d8a
+           lseek(fd, s_pos + offset, SEEK_SET);
Jiri Skala 6666d8a
+           ret_tz = calloc(1, len+4);
Jiri Skala 6666d8a
+           memcpy(ret_tz, "TZ=", 3);
Jiri Skala 6666d8a
+           rcnt = read(fd, ret_tz+3, len);
Jiri Skala 6666d8a
+         }
Jiri Skala 6666d8a
+         break;
Jiri Skala 6666d8a
+       }
Jiri Skala 6666d8a
+       if (!s_pos)
Jiri Skala 6666d8a
+       {
Jiri Skala 6666d8a
+         break;
Jiri Skala 6666d8a
+       }
Jiri Skala 6666d8a
+       rest = s_pos > BUFTZSIZ ? s_pos - BUFTZSIZ : 0;
Jiri Skala 6666d8a
+       s_pos -= rest;
Jiri Skala 6666d8a
+       lseek(fd, s_pos, SEEK_SET);
Jiri Skala 6666d8a
+       rcnt = read(fd, buff, rest);
Jiri Skala 6666d8a
+    } while (rcnt > 0);
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+    close (fd);
Jiri Skala 6666d8a
+  }
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+  return ret_tz;
Jiri Skala 6666d8a
+}
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
 void
Jiri Skala 6666d8a
 vsf_sysutil_tzset(void)
Jiri Skala 6666d8a
 {
Jiri Skala 6666d8a
   int retval;
Jiri Skala 6666d8a
-  char tzbuf[sizeof("+HHMM!")];
Jiri Skala 6666d8a
+  char *tz=NULL, tzbuf[sizeof("+HHMM!")];
Jiri Skala 6666d8a
   time_t the_time = time(NULL);
Jiri Skala 6666d8a
   struct tm* p_tm;
Jiri Skala 6666d8a
+
Jiri Skala 6666d8a
+  /* Set our timezone in the TZ environment variable to cater for the fact
Jiri Skala 6666d8a
+   * that modern glibc does not cache /etc/localtime (which becomes inaccessible
Jiri Skala 6666d8a
+   * when we chroot().
Jiri Skala 6666d8a
+   */
Jiri Skala 6666d8a
+  tz = vsf_sysutil_get_tz();;
Jiri Skala 6666d8a
+  if (tz)
Jiri Skala 6666d8a
+  {
Jiri Skala 6666d8a
+    putenv(tz);
Jiri Skala 6666d8a
+  }
Jiri Skala 6666d8a
   tzset();
Jiri Skala 6666d8a
   p_tm = localtime(&the_time);
Jiri Skala 6666d8a
   if (p_tm == NULL)
Jiri Skala 6666d8a
   {
Jiri Skala 6666d8a
     die("localtime");
Jiri Skala 6666d8a
   }
Jiri Skala 6666d8a
-  /* Set our timezone in the TZ environment variable to cater for the fact
Jiri Skala 6666d8a
-   * that modern glibc does not cache /etc/localtime (which becomes inaccessible
Jiri Skala 6666d8a
-   * when we chroot().
Jiri Skala 6666d8a
-   */
Jiri Skala 6666d8a
   retval = strftime(tzbuf, sizeof(tzbuf), "%z", p_tm);
Jiri Skala 6666d8a
   tzbuf[sizeof(tzbuf) - 1] = '\0';
Jiri Skala 6666d8a
   if (retval == 5)
Jiri Skala 6666d8a
   {
Jiri Skala 6666d8a
-    /* Static because putenv() does not copy the string. */
Jiri Skala 6666d8a
-    static char envtz[sizeof("TZ=UTC-hh:mm")];
Jiri Skala 6666d8a
-    /* Insert a colon so we have e.g. -05:00 instead of -0500 */
Jiri Skala 6666d8a
-    tzbuf[5] = tzbuf[4];
Jiri Skala 6666d8a
-    tzbuf[4] = tzbuf[3];
Jiri Skala 6666d8a
-    tzbuf[3] = ':';
Jiri Skala 6666d8a
-    /* Invert the sign - we just got the offset _from_ UTC but for TZ, we need
Jiri Skala 6666d8a
-     * the offset _to_ UTC.
Jiri Skala 6666d8a
-     */
Jiri Skala 6666d8a
-    if (tzbuf[0] == '+')
Jiri Skala 6666d8a
-    {
Jiri Skala 6666d8a
-      tzbuf[0] = '-';
Jiri Skala 6666d8a
-    }
Jiri Skala 6666d8a
-    else
Jiri Skala 6666d8a
-    {
Jiri Skala 6666d8a
-      tzbuf[0] = '+';
Jiri Skala 6666d8a
-    }
Jiri Skala 6666d8a
-    snprintf(envtz, sizeof(envtz), "TZ=UTC%s", tzbuf);
Jiri Skala 6666d8a
-    putenv(envtz);
Jiri Skala 6666d8a
     s_timezone = ((tzbuf[1] - '0') * 10 + (tzbuf[2] - '0')) * 60 * 60;
Jiri Skala 6666d8a
-    s_timezone += ((tzbuf[4] - '0') * 10 + (tzbuf[5] - '0')) * 60;
Jiri Skala 6666d8a
-    if (tzbuf[0] == '-')
Jiri Skala 6666d8a
+    s_timezone += ((tzbuf[3] - '0') * 10 + (tzbuf[4] - '0')) * 60;
Jiri Skala 6666d8a
+    if (tzbuf[0] == '+')
Jiri Skala 6666d8a
     {
Jiri Skala 6666d8a
       s_timezone *= -1;
Jiri Skala 6666d8a
     }
8167548
-- 
Ondřej Lysoněk 7c0626d
2.14.4
8167548