daemontool tai64nlocal パッチ

以前作ったものの備忘録。

概要

daemontool-0.70用tai64ntaiのsourceを参考にdaemontool-0.76のtai64nlocal を変更したもの。これは、qmailのログ解析qmailanalog、tcpserverのログ解析tcpanalogのmultilog版に必要なため。

  • オプションなしの場合はtai64nlocalの通常の処理を行う。
  • -tオプションでTAI形式に出力する。
  • -dオプションにYYYY-mm-dd形式で日付を指定すると、それ以降のものを出力する。
  • -vオプションでバージョンを出力する。

make方法

# zcat daemontools-0.76.tar.gz | tar xvf -
# patch -p0 < ./daemontools-0.76-tai.unoff.patch
# cd admin/daemontools-0.76
# ./package/compile
  (インストールする場合は./package/install)

パッチ内容(daemontools-0.76-tai.unoff.patch)

diff -crN admin.org/daemontools-0.76/src/tai64nlocal.c admin/daemontools-0.76/src/tai64nlocal.c
*** admin.org/daemontools-0.76/src/tai64nlocal.c        Fri Jul 13 01:49:49 2001
--- admin/daemontools-0.76/src/tai64nlocal.c    Thu Dec 19 10:25:29 2002
***************
*** 1,3 ****
--- 1,6 ----
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
  #include <sys/types.h>
  #include <time.h>
  #include <sys/time.h>
***************
*** 23,38 ****
      _exit(111);
  }

  time_t secs;
  unsigned long nanosecs;
  unsigned long u;
  struct tm *t;

! int main()
  {
    char ch;

    for (;;) {
      get(&ch);
      if (ch == '@') {
        secs = 0;
--- 26,92 ----
      _exit(111);
  }

+ void version(void) {
+   fprintf(stderr, "\
+ daemontool 0.76 + unofficial patch\n\
+ usage: tai64nlocal [-v] [-t] [-d YYYY-mm-dd]\n");
+   _exit(0);
+ }
+
+ /* char *s: YYYY-mm-dd */
+ time_t get_time(char *s) {
+   struct tm tt;
+   char t[5];
+
+   if (*(s+4) == '-' && *(s+7) == '-' && strlen(s) == 10) {
+     memset(t, '\0', 5); memcpy(t, s, 4);
+     tt.tm_year = atoi(t) - 1900;
+     memset(t, '\0', 5); memcpy(t, s+5, 2);
+     tt.tm_mon = atoi(t) - 1;
+     memset(t, '\0', 5); memcpy(t, s+8, 2);
+     tt.tm_mday = atoi(t);
+     tt.tm_hour = 0;
+     tt.tm_min = 0;
+     tt.tm_sec = 0;
+     tt.tm_isdst = 0;
+     return mktime(&tt);
+   }
+
+   return (time_t)0;
+ }
+
  time_t secs;
+ unsigned long microsecs;
  unsigned long nanosecs;
  unsigned long u;
  struct tm *t;

! int main(int argc, char *argv[])
  {
+   int tai = 0;
+   int c;
+   time_t dsec = 0;
    char ch;

    for (;;) {
+     c = getopt(argc, argv, "tvd:");
+     if (c == -1) {
+       break;
+     }
+     switch (c) {
+     case 't' :
+       tai = 1;
+       break;
+     case 'd' :
+       dsec = get_time(optarg);
+       break;
+     case 'v' :
+     default :
+       version();
+     }
+   }
+
+   for (;;) {
      get(&ch);
      if (ch == '@') {
        secs = 0;
***************
*** 52,68 ****
          nanosecs += u;
        }
        secs -= 4611686018427387914ULL;
!       t = localtime(&secs);
!       out(num,fmt_ulong(num,1900 + t->tm_year));
!       out("-",1); out(num,fmt_uint0(num,1 + t->tm_mon,2));
!       out("-",1); out(num,fmt_uint0(num,t->tm_mday,2));
!       out(" ",1); out(num,fmt_uint0(num,t->tm_hour,2));
!       out(":",1); out(num,fmt_uint0(num,t->tm_min,2));
!       out(":",1); out(num,fmt_uint0(num,t->tm_sec,2));
!       out(".",1); out(num,fmt_uint0(num,nanosecs,9));
      }
      for (;;) {
!       out(&ch,1);
        if (ch == '\n') break;
        get(&ch);
      }
--- 106,135 ----
          nanosecs += u;
        }
        secs -= 4611686018427387914ULL;
!       if (tai == 1) {
!         if (secs >= dsec) {
!           microsecs = nanosecs / 1000UL;
!           out(num,fmt_uint(num,(unsigned int) secs));
!           out(".",1);
!           out(num,fmt_uint0(num,(unsigned int) microsecs,6));
!         }
!       } else {
!         if (secs >= dsec) {
!           t = localtime(&secs);
!           out(num,fmt_ulong(num,1900 + t->tm_year));
!           out("-",1); out(num,fmt_uint0(num,1 + t->tm_mon,2));
!           out("-",1); out(num,fmt_uint0(num,t->tm_mday,2));
!           out(" ",1); out(num,fmt_uint0(num,t->tm_hour,2));
!           out(":",1); out(num,fmt_uint0(num,t->tm_min,2));
!           out(":",1); out(num,fmt_uint0(num,t->tm_sec,2));
!           out(".",1); out(num,fmt_uint0(num,nanosecs,9));
!         }
!       }
      }
      for (;;) {
!       if (secs >= dsec) {
!         out(&ch,1);
!       }
        if (ch == '\n') break;
        get(&ch);
      }