one of the recurring issues we've seen is with people who
want rotatelogs to do its thing at midnight *local* time.
easily enough done with the offset argument -- but that
gets messy around the daylight savings issues.
the attached patch adds the '-l' option, which causes the
interval to be interpreted as local system time without
the user having to figure out nor change the offset.
it'll probably get a little weird at the transition times,
but this is what people have wanted. *shrug*
if accepted for 1.3, i'll do the appropriate port to 2.[01].
--
#ken P-)}
Ken Coar, Sanagendamgagwedweinini http://Ken.Coar.Org/
Author, developer, opinionist http://Apache-Server.Com/
"Millennium hand and shrimp!"
Index: rotatelogs.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/support/rotatelogs.c,v
retrieving revision 1.19
diff -u -r1.19 rotatelogs.c
--- rotatelogs.c 20 Feb 2004 22:02:24 -0000 1.19
+++ rotatelogs.c 4 May 2004 09:59:34 -0000
@@ -18,6 +18,12 @@
*
* Contributed by Ben Laurie <[EMAIL PROTECTED]>
*
+ * rotatelogs [-l] logfile offsetSecs [gmtoff]
+ *
+ * -l causes the use of local time rather than GMT as the base for the
+ * interval. NB: Using -l in an environment which changes the GMT offset
+ * (such as for BST or DST) can lead to unpredictable results!
+ *
* 12 Mar 1996
*/
@@ -37,6 +43,8 @@
#define MAX_PATH 1024
#endif
+int gmtoffset(void);
+
int main (int argc, char **argv)
{
char buf[BUFSIZE], buf2[MAX_PATH], errbuf[ERRMSGSZ];
@@ -44,8 +52,13 @@
int nLogFD = -1, nLogFDprev = -1, nMessCount = 0, nRead, nWrite;
int utc_offset = 0;
int use_strftime = 0;
+ int use_localtime = 0;
time_t now;
char *szLogRoot;
+ int argBase = 0;
+ int argFile = 1;
+ int argIntv = 2;
+ int argOffset = 3;
#ifdef TPF
/* set up signal handling to avoid default OPR-I007777 dump */
@@ -53,9 +66,16 @@
signal(SIGTERM, exit);
#endif
- if (argc < 3) {
+ if ((argc > 2) && (strcmp(argv[1], "-l") == 0)) {
+ argBase++;
+ argFile += argBase;
+ argIntv += argBase;
+ argOffset += argBase;
+ use_localtime = 1;
+ }
+ if (argc < (argBase + 3)) {
fprintf(stderr,
- "Usage: %s <logfile> <rotation time in seconds> "
+ "Usage: %s [-] <logfile> <rotation time in seconds> "
"[offset minutes from UTC]\n\n",
argv[0]);
#ifdef OS2
@@ -76,11 +96,11 @@
exit(1);
}
- szLogRoot = argv[1];
- if (argc >= 4) {
- utc_offset = atoi(argv[3]) * 60;
+ szLogRoot = argv[argFile];
+ if (argc > argOffset) {
+ utc_offset = atoi(argv[argOffset]) * 60;
}
- tRotation = atoi(argv[2]);
+ tRotation = atoi(argv[argIntv]);
if (tRotation <= 0) {
fprintf(stderr, "Rotation time must be > 0\n");
exit(6);
@@ -91,6 +111,10 @@
#endif
use_strftime = (strstr(szLogRoot, "%") != NULL);
+ if (use_localtime) {
+ utc_offset = gmtoffset();
+ }
+
for (;;) {
nRead = read(0, buf, sizeof buf);
now = time(NULL) + utc_offset;
@@ -104,14 +128,15 @@
nLogFD = -1;
}
if (nLogFD < 0) {
- time_t tLogStart = (now / tRotation) * tRotation;
+ time_t tLogStart = (now / tRotation) * tRotation + utc_offset;
+ time_t tCalcStart = tLogStart - utc_offset;
if (use_strftime) {
struct tm *tm_now;
- tm_now = gmtime(&tLogStart);
+ tm_now = gmtime(&tCalcStart);
strftime(buf2, sizeof(buf2), szLogRoot, tm_now);
}
else {
- sprintf(buf2, "%s.%010d", szLogRoot, (int) tLogStart);
+ sprintf(buf2, "%s.%010d", szLogRoot, (int) tCalcStart);
}
tLogEnd = tLogStart + tRotation;
nLogFD = open(buf2, O_WRONLY | O_CREAT | O_APPEND, 0666);
@@ -166,4 +191,40 @@
}
/* We never get here, but suppress the compile warning */
return (0);
+}
+
+/*
+ * Cadged from ap_get_gmtoff() in util.c
+ */
+int gmtoffset()
+{
+ int offset;
+
+#if defined(HAVE_GMTOFF)
+
+ time_t tt = time(NULL);
+ struct tm *t;
+
+ t = localtime(&tt);
+ offset = (int) (t->tm_gmtoff / 60);
+
+#else
+
+ time_t tt = time(NULL);
+ struct tm gmt;
+ struct tm *t;
+ int days, hours, minutes;
+
+ /* Assume we are never more than 24 hours away. */
+ gmt = *gmtime(&tt); /* remember gmtime/localtime return ptr */
+ t = localtime(&tt); /* to static buffer... so be careful */
+ days = t->tm_yday - gmt.tm_yday;
+ hours = ((days < -1 ? 24 : 1 < days ? -24 : days * 24)
+ + t->tm_hour - gmt.tm_hour);
+ minutes = hours * 60 + t->tm_min - gmt.tm_min;
+ offset = minutes;
+
+#endif
+
+ return offset * 60;
}