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;
 }

Reply via email to