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