home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / time / zdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  7.1 KB  |  332 lines

  1. #ifndef lint
  2. #ifndef NOID
  3. static char    elsieid[] = "@(#)zdump.c    7.12";
  4. #endif /* !defined NOID */
  5. #endif /* !defined lint */
  6.  
  7. /*
  8. ** This code has been made independent of the rest of the time
  9. ** conversion package to increase confidence in the verification it provides.
  10. ** You can use this code to help in verifying other implementations.
  11. */
  12.  
  13. #include "stdio.h"    /* for stdout, stderr */
  14. #include "string.h"    /* for strcpy */
  15. #include "sys/types.h"    /* for time_t */
  16. #include "time.h"    /* for struct tm */
  17.  
  18. #ifndef MAX_STRING_LENGTH
  19. #define MAX_STRING_LENGTH    1024
  20. #endif /* !defined MAX_STRING_LENGTH */
  21.  
  22. #ifndef TRUE
  23. #define TRUE        1
  24. #endif /* !defined TRUE */
  25.  
  26. #ifndef FALSE
  27. #define FALSE        0
  28. #endif /* !defined FALSE */
  29.  
  30. #ifndef EXIT_SUCCESS
  31. #define EXIT_SUCCESS    0
  32. #endif /* !defined EXIT_SUCCESS */
  33.  
  34. #ifndef EXIT_FAILURE
  35. #define EXIT_FAILURE    1
  36. #endif /* !defined EXIT_FAILURE */
  37.  
  38. #ifndef SECSPERMIN
  39. #define SECSPERMIN    60
  40. #endif /* !defined SECSPERMIN */
  41.  
  42. #ifndef MINSPERHOUR
  43. #define MINSPERHOUR    60
  44. #endif /* !defined MINSPERHOUR */
  45.  
  46. #ifndef SECSPERHOUR
  47. #define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
  48. #endif /* !defined SECSPERHOUR */
  49.  
  50. #ifndef HOURSPERDAY
  51. #define HOURSPERDAY    24
  52. #endif /* !defined HOURSPERDAY */
  53.  
  54. #ifndef EPOCH_YEAR
  55. #define EPOCH_YEAR    1970
  56. #endif /* !defined EPOCH_YEAR */
  57.  
  58. #ifndef TM_YEAR_BASE
  59. #define TM_YEAR_BASE    1900
  60. #endif /* !defined TM_YEAR_BASE */
  61.  
  62. #ifndef DAYSPERNYEAR
  63. #define DAYSPERNYEAR    365
  64. #endif /* !defined DAYSPERNYEAR */
  65.  
  66. #ifndef isleap
  67. #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
  68. #endif /* !defined isleap */
  69.  
  70. #ifndef GNUC_or_lint
  71. #ifdef lint
  72. #define GNUC_or_lint
  73. #endif /* defined lint */
  74. #ifdef __GNUC__
  75. #define GNUC_or_lint
  76. #endif /* defined __GNUC__ */
  77. #endif /* !defined GNUC_or_lint */
  78.  
  79. #ifndef INITIALIZE
  80. #ifdef GNUC_or_lint
  81. #define INITIALIZE(x)    ((x) = 0)
  82. #endif /* defined GNUC_or_lint */
  83. #ifndef GNUC_or_lint
  84. #define INITIALIZE(x)
  85. #endif /* !defined GNUC_or_lint */
  86. #endif /* !defined INITIALIZE */
  87.  
  88. extern char **    environ;
  89. extern int    getopt();
  90. extern char *    optarg;
  91. extern int    optind;
  92. extern time_t    time();
  93. extern char *    tzname[2];
  94.  
  95. #ifdef USG
  96. extern void    exit();
  97. extern void    perror();
  98. #endif /* defined USG */
  99.  
  100. static char *    abbr();
  101. static long    delta();
  102. static time_t    hunt();
  103. static int    longest;
  104. static char *    progname;
  105. static void    show();
  106.  
  107. int
  108. main(argc, argv)
  109. int    argc;
  110. char *    argv[];
  111. {
  112.     register int        i, c;
  113.     register int        vflag;
  114.     register char *        cutoff;
  115.     register int        cutyear;
  116.     register long        cuttime;
  117.     char **            fakeenv;
  118.     time_t            now;
  119.     time_t            t, newt;
  120.     time_t            hibit;
  121.     struct tm        tm, newtm;
  122.  
  123.     INITIALIZE(cuttime);
  124.     progname = argv[0];
  125.     vflag = 0;
  126.     cutoff = NULL;
  127.     while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
  128.         if (c == 'v')
  129.             vflag = 1;
  130.         else    cutoff = optarg;
  131.     if (c != EOF ||
  132.         (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
  133.             (void) fprintf(stderr,
  134. "%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n",
  135.                 argv[0], argv[0]);
  136.             (void) exit(EXIT_FAILURE);
  137.     }
  138.     if (cutoff != NULL) {
  139.         int    y;
  140.  
  141.         cutyear = atoi(cutoff);
  142.         cuttime = 0;
  143.         for (y = EPOCH_YEAR; y < cutyear; ++y)
  144.             cuttime += DAYSPERNYEAR + isleap(y);
  145.         cuttime *= SECSPERHOUR * HOURSPERDAY;
  146.     }
  147.     (void) time(&now);
  148.     longest = 0;
  149.     for (i = optind; i < argc; ++i)
  150.         if (strlen(argv[i]) > longest)
  151.             longest = strlen(argv[i]);
  152.     for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
  153.         continue;
  154.     {
  155.         register int    from, to;
  156.  
  157.         for (i = 0;  environ[i] != NULL;  ++i)
  158.             continue;
  159.         fakeenv = (char **) malloc((i + 2) * sizeof *fakeenv);
  160.         if (fakeenv == NULL ||
  161.             (fakeenv[0] = (char *) malloc(longest + 4)) == NULL) {
  162.                 (void) perror(progname);
  163.                 (void) exit(EXIT_FAILURE);
  164.         }
  165.         to = 0;
  166.         (void) strcpy(fakeenv[to++], "TZ=");
  167.         for (from = 0; environ[from] != NULL; ++from)
  168.             if (strncmp(environ[from], "TZ=", 3) != 0)
  169.                 fakeenv[to++] = environ[from];
  170.         fakeenv[to] = NULL;
  171.         environ = fakeenv;
  172.     }
  173.     for (i = optind; i < argc; ++i) {
  174.         static char    buf[MAX_STRING_LENGTH];
  175.  
  176.         (void) strcpy(&fakeenv[0][3], argv[i]);
  177.         show(argv[i], now, FALSE);
  178.         if (!vflag)
  179.             continue;
  180.         /*
  181.         ** Get lowest value of t.
  182.         */
  183.         t = hibit;
  184.         if (t > 0)        /* time_t is unsigned */
  185.             t = 0;
  186.         show(argv[i], t, TRUE);
  187.         t += SECSPERHOUR * HOURSPERDAY;
  188.         show(argv[i], t, TRUE);
  189.         tm = *localtime(&t);
  190.         (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
  191.         for ( ; ; ) {
  192.             if (cutoff != NULL && t >= cuttime)
  193.                 break;
  194.             newt = t + SECSPERHOUR * 12;
  195.             if (cutoff != NULL && newt >= cuttime)
  196.                 break;
  197.             if (newt <= t)
  198.                 break;
  199.             newtm = *localtime(&newt);
  200.             if (delta(&newtm, &tm) != (newt - t) ||
  201.                 newtm.tm_isdst != tm.tm_isdst ||
  202.                 strcmp(abbr(&newtm), buf) != 0) {
  203.                     newt = hunt(argv[i], t, newt);
  204.                     newtm = *localtime(&newt);
  205.                     (void) strncpy(buf, abbr(&newtm),
  206.                         (sizeof buf) - 1);
  207.             }
  208.             t = newt;
  209.             tm = newtm;
  210.         }
  211.         /*
  212.         ** Get highest value of t.
  213.         */
  214.         t = ~((time_t) 0);
  215.         if (t < 0)        /* time_t is signed */
  216.             t &= ~hibit;
  217.         t -= SECSPERHOUR * HOURSPERDAY;
  218.         show(argv[i], t, TRUE);
  219.         t += SECSPERHOUR * HOURSPERDAY;
  220.         show(argv[i], t, TRUE);
  221.     }
  222.     if (fflush(stdout) || ferror(stdout)) {
  223.         (void) fprintf(stderr, "%s: Error writing standard output ",
  224.             argv[0]);
  225.         (void) perror("standard output");
  226.         (void) exit(EXIT_FAILURE);
  227.     }
  228.     exit(EXIT_SUCCESS);
  229.  
  230.     /* gcc -Wall pacifier */
  231.     for ( ; ; )
  232.         continue;
  233. }
  234.  
  235. static time_t
  236. hunt(name, lot, hit)
  237. char *    name;
  238. time_t    lot;
  239. time_t    hit;
  240. {
  241.     time_t        t;
  242.     struct tm    lotm;
  243.     struct tm    tm;
  244.     static char    loab[MAX_STRING_LENGTH];
  245.  
  246.     lotm = *localtime(&lot);
  247.     (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
  248.     while ((hit - lot) >= 2) {
  249.         t = lot / 2 + hit / 2;
  250.         if (t <= lot)
  251.             ++t;
  252.         else if (t >= hit)
  253.             --t;
  254.         tm = *localtime(&t);
  255.         if (delta(&tm, &lotm) == (t - lot) &&
  256.             tm.tm_isdst == lotm.tm_isdst &&
  257.             strcmp(abbr(&tm), loab) == 0) {
  258.                 lot = t;
  259.                 lotm = tm;
  260.         } else    hit = t;
  261.     }
  262.     show(name, lot, TRUE);
  263.     show(name, hit, TRUE);
  264.     return hit;
  265. }
  266.  
  267. /*
  268. ** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
  269. */
  270.  
  271. static long
  272. delta(newp, oldp)
  273. struct tm *    newp;
  274. struct tm *    oldp;
  275. {
  276.     long    result;
  277.     int    tmy;
  278.  
  279.     if (newp->tm_year < oldp->tm_year)
  280.         return -delta(oldp, newp);
  281.     result = 0;
  282.     for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
  283.         result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE);
  284.     result += newp->tm_yday - oldp->tm_yday;
  285.     result *= HOURSPERDAY;
  286.     result += newp->tm_hour - oldp->tm_hour;
  287.     result *= MINSPERHOUR;
  288.     result += newp->tm_min - oldp->tm_min;
  289.     result *= SECSPERMIN;
  290.     result += newp->tm_sec - oldp->tm_sec;
  291.     return result;
  292. }
  293.  
  294. extern struct tm *    localtime();
  295.  
  296. static void
  297. show(zone, t, v)
  298. char *    zone;
  299. time_t    t;
  300. int    v;
  301. {
  302.     struct tm *    tmp;
  303.  
  304.     (void) printf("%-*s  ", longest, zone);
  305.     if (v)
  306.         (void) printf("%.24s GMT = ", asctime(gmtime(&t)));
  307.     tmp = localtime(&t);
  308.     (void) printf("%.24s", asctime(tmp));
  309.     if (*abbr(tmp) != '\0')
  310.         (void) printf(" %s", abbr(tmp));
  311.     if (v) {
  312.         (void) printf(" isdst=%d", tmp->tm_isdst);
  313. #ifdef TM_GMTOFF
  314.         (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
  315. #endif /* defined TM_GMTOFF */
  316.     }
  317.     (void) printf("\n");
  318. }
  319.  
  320. static char *
  321. abbr(tmp)
  322. struct tm *    tmp;
  323. {
  324.     register char *    result;
  325.     static char    nada;
  326.  
  327.     if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
  328.         return &nada;
  329.     result = tzname[tmp->tm_isdst];
  330.     return (result == NULL) ? &nada : result;
  331. }
  332.