static void show(timezone_t tz, char *zone, time_t t, bool v) { struct tm * tmp; struct tm * gmtmp; struct tm tm, gmtm; (void) printf("%-*s ", (int) longest, zone); if (v) { gmtmp = my_gmtime_r(&t, &gmtm); if (gmtmp == NULL) { printf(tformat(), t); } else { dumptime(gmtmp); (void) printf(" UT"); } (void) printf(" = "); } tmp = my_localtime_rz(tz, &t, &tm); dumptime(tmp); if (tmp != NULL) { if (*abbr(tmp) != '\0') (void) printf(" %s", abbr(tmp)); if (v) { long off = gmtoff(tmp, NULL, gmtmp); (void) printf(" isdst=%d", tmp->tm_isdst); if (off != LONG_MIN) (void) printf(" gmtoff=%ld", off); } } (void) printf("\n"); if (tmp != NULL && *abbr(tmp) != '\0') abbrok(abbr(tmp), zone); }
static time_t hunt(timezone_t tz, char *name, time_t lot, time_t hit) { static char * loab; static size_t loabsize; char const * ab; time_t t; struct tm lotm; struct tm * lotmp; struct tm tm; struct tm * tmp; lotmp = my_localtime_rz(tz, &lot, &lotm); if (lotmp) ab = saveabbr(&loab, &loabsize, &lotm); else ab = NULL; for ( ; ; ) { time_t diff = hit - lot; if (diff < 2) break; t = lot; t += diff / 2; if (t <= lot) ++t; else if (t >= hit) --t; tmp = my_localtime_rz(tz, &t, &tm); if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) : (delta(&tm, &lotm) == (t - lot) && tm.tm_isdst == lotm.tm_isdst && strcmp(abbr(&tm), ab) == 0)) { lot = t; lotm = tm; lotmp = tmp; } else hit = t; } show(tz, name, lot, true); show(tz, name, hit, true); return hit; }
static time_t hunt(timezone_t tz, char *name, time_t lot, time_t hit) { static char * loab; static size_t loabsize; char const * ab; time_t t; struct tm lotm; struct tm tm; bool lotm_ok = my_localtime_rz(tz, &lot, &lotm) != NULL; bool tm_ok; if (lotm_ok) ab = saveabbr(&loab, &loabsize, &lotm); else ab = NULL; for ( ; ; ) { time_t diff = hit - lot; if (diff < 2) break; t = lot; t += diff / 2; if (t <= lot) ++t; else if (t >= hit) --t; tm_ok = my_localtime_rz(tz, &t, &tm) != NULL; if (lotm_ok & tm_ok ? (delta(&tm, &lotm) == t - lot && tm.tm_isdst == lotm.tm_isdst && strcmp(abbr(&tm), ab) == 0) : lotm_ok == tm_ok) { lot = t; if (tm_ok) lotm = tm; } else hit = t; } return hit; }
int main(int argc, char *argv[]) { /* These are static so that they're initially zero. */ static char * abbrev; static size_t abbrevsize; int i; bool vflag; bool Vflag; char * cutarg; char * cuttimes; time_t cutlotime; time_t cuthitime; time_t now; bool iflag = false; cutlotime = absolute_min_time; cuthitime = absolute_max_time; #if HAVE_GETTEXT (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); #endif /* HAVE_GETTEXT */ progname = argv[0]; for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { (void) printf("zdump %s%s\n", PKGVERSION, TZVERSION); return EXIT_SUCCESS; } else if (strcmp(argv[i], "--help") == 0) { usage(stdout, EXIT_SUCCESS); } vflag = Vflag = false; cutarg = cuttimes = NULL; for (;;) switch (getopt(argc, argv, "c:it:vV")) { case 'c': cutarg = optarg; break; case 't': cuttimes = optarg; break; case 'i': iflag = true; break; case 'v': vflag = true; break; case 'V': Vflag = true; break; case -1: if (! (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) goto arg_processing_done; /* Fall through. */ default: usage(stderr, EXIT_FAILURE); } arg_processing_done:; if (iflag | vflag | Vflag) { intmax_t lo; intmax_t hi; char *loend, *hiend; intmax_t cutloyear = ZDUMP_LO_YEAR; intmax_t cuthiyear = ZDUMP_HI_YEAR; if (cutarg != NULL) { lo = strtoimax(cutarg, &loend, 10); if (cutarg != loend && !*loend) { hi = lo; cuthiyear = hi; } else if (cutarg != loend && *loend == ',' && (hi = strtoimax(loend + 1, &hiend, 10), loend + 1 != hiend && !*hiend)) { cutloyear = lo; cuthiyear = hi; } else { fprintf(stderr, _("%s: wild -c argument %s\n"), progname, cutarg); return EXIT_FAILURE; } } if (cutarg != NULL || cuttimes == NULL) { cutlotime = yeartot(cutloyear); cuthitime = yeartot(cuthiyear); } if (cuttimes != NULL) { lo = strtoimax(cuttimes, &loend, 10); if (cuttimes != loend && !*loend) { hi = lo; if (hi < cuthitime) { if (hi < absolute_min_time) hi = absolute_min_time; cuthitime = hi; } } else if (cuttimes != loend && *loend == ',' && (hi = strtoimax(loend + 1, &hiend, 10), loend + 1 != hiend && !*hiend)) { if (cutlotime < lo) { if (absolute_max_time < lo) lo = absolute_max_time; cutlotime = lo; } if (hi < cuthitime) { if (hi < absolute_min_time) hi = absolute_min_time; cuthitime = hi; } } else { (void) fprintf(stderr, _("%s: wild -t argument %s\n"), progname, cuttimes); return EXIT_FAILURE; } } } gmtzinit(); INITIALIZE (now); if (! (iflag | vflag | Vflag)) now = time(NULL); longest = 0; for (i = optind; i < argc; i++) { size_t arglen = strlen(argv[i]); if (longest < arglen) longest = arglen < INT_MAX ? arglen : INT_MAX; } for (i = optind; i < argc; ++i) { timezone_t tz = tzalloc(argv[i]); char const *ab; time_t t; struct tm tm, newtm; bool tm_ok; if (!tz) { errx(EXIT_FAILURE, "%s", argv[i]); } if (! (iflag | vflag | Vflag)) { show(tz, argv[i], now, false); tzfree(tz); continue; } warned = false; t = absolute_min_time; if (! (iflag | Vflag)) { show(tz, argv[i], t, true); t += SECSPERDAY; show(tz, argv[i], t, true); } if (t < cutlotime) t = cutlotime; tm_ok = my_localtime_rz(tz, &t, &tm) != NULL; if (tm_ok) { ab = saveabbr(&abbrev, &abbrevsize, &tm); if (iflag) { showtrans("\nTZ=%f", &tm, t, ab, argv[i]); showtrans("-\t-\t%Q", &tm, t, ab, argv[i]); } } else ab = NULL; while (t < cuthitime) { time_t newt = ((t < absolute_max_time - SECSPERDAY / 2 && t + SECSPERDAY / 2 < cuthitime) ? t + SECSPERDAY / 2 : cuthitime); struct tm *newtmp = localtime_rz(tz, &newt, &newtm); bool newtm_ok = newtmp != NULL; if (! (tm_ok & newtm_ok ? (delta(&newtm, &tm) == newt - t && newtm.tm_isdst == tm.tm_isdst && strcmp(abbr(&newtm), ab) == 0) : tm_ok == newtm_ok)) { newt = hunt(tz, argv[i], t, newt); newtmp = localtime_rz(tz, &newt, &newtm); newtm_ok = newtmp != NULL; if (iflag) showtrans("%Y-%m-%d\t%L\t%Q", newtmp, newt, newtm_ok ? abbr(&newtm) : NULL, argv[i]); else { show(tz, argv[i], newt - 1, true); show(tz, argv[i], newt, true); } } t = newt; tm_ok = newtm_ok; if (newtm_ok) { ab = saveabbr(&abbrev, &abbrevsize, &newtm); tm = newtm; } } if (! (iflag | Vflag)) { t = absolute_max_time; t -= SECSPERDAY; show(tz, argv[i], t, true); t += SECSPERDAY; show(tz, argv[i], t, true); } tzfree(tz); } close_file(stdout); if (errout && (ferror(stderr) || fclose(stderr) != 0)) return EXIT_FAILURE; return EXIT_SUCCESS; }