Example #1
0
static char * ATTRIBUTE_WARN_UNUSED_RESULT
human_time (struct timespec t)
{
  /* STR must be at least this big, either because localtime_rz fails,
     or because the time zone is truly outlandish so that %z expands
     to a long string.  */
  enum { intmax_bufsize = INT_BUFSIZE_BOUND (intmax_t) };

  static char str[intmax_bufsize
                  + INT_STRLEN_BOUND (int) /* YYYY */
                  + 1 /* because YYYY might equal INT_MAX + 1900 */
                  + sizeof "-MM-DD HH:MM:SS.NNNNNNNNN +"];
  static timezone_t tz;
  if (!tz)
    tz = tzalloc (getenv ("TZ"));
  struct tm tm;
  int ns = t.tv_nsec;
  if (localtime_rz (tz, &t.tv_sec, &tm))
    nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", &tm, tz, ns);
  else
    {
      char secbuf[INT_BUFSIZE_BOUND (intmax_t)];
      sprintf (str, "%s.%09d", timetostr (t.tv_sec, secbuf), ns);
    }
  return str;
}
Example #2
0
static void
gmtzinit(void)
{
	if (USE_LOCALTIME_RZ) {
		static char const utc[] = "UTC0";
		gmtz = tzalloc(utc);
		if (!gmtz) {
		      err(EXIT_FAILURE, "Cannot create %s", utc);
		}
	}
}
Example #3
0
static void
gmtzinit(void)
{
  if (USE_LOCALTIME_RZ) {
    static char const utc[] = "UTC0";
    gmtz = tzalloc(utc);
    if (!gmtz) {
      perror(utc);
      exit(EXIT_FAILURE);
    }
  }
}
Example #4
0
/* Temporarily set the time zone to TZ, which must not be null.
   Return LOCAL_TZ if the time zone setting is already correct.
   Otherwise return a newly allocated time zone representing the old
   setting, or NULL (setting errno) on failure.  */
static timezone_t
set_tz (timezone_t tz)
{
  char *env_tz = getenv_TZ ();
  if (env_tz
      ? tz->tz_is_set && strcmp (tz->abbrs, env_tz) == 0
      : !tz->tz_is_set)
    return local_tz;
  else
    {
      timezone_t old_tz = tzalloc (env_tz);
      if (!old_tz)
        return old_tz;
      if (! change_env (tz))
        {
          int saved_errno = errno;
          tzfree (old_tz);
          errno = saved_errno;
          return NULL;
        }
      return old_tz;
    }
}
Example #5
0
/* Save into TZ any nontrivial time zone abbreviation used by TM, and
   update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE &&
   HAVE_TZNAME) if they use the abbreviation.  Return true if
   successful, false (setting errno) otherwise.  */
static bool
save_abbr (timezone_t tz, struct tm *tm)
{
#if HAVE_TM_ZONE || HAVE_TZNAME
  char const *zone = NULL;
  char *zone_copy = (char *) "";

# if HAVE_TZNAME
  int tzname_index = -1;
# endif

# if HAVE_TM_ZONE
  zone = tm->tm_zone;
# endif

# if HAVE_TZNAME
  if (! (zone && *zone) && 0 <= tm->tm_isdst)
    {
      tzname_index = tm->tm_isdst != 0;
      zone = tzname[tzname_index];
    }
# endif

  /* No need to replace null zones, or zones within the struct tm.  */
  if (!zone || ((char *) tm <= zone && zone < (char *) (tm + 1)))
    return true;

  if (*zone)
    {
      zone_copy = tz->abbrs;

      while (strcmp (zone_copy, zone) != 0)
        {
          if (! (*zone_copy || (zone_copy == tz->abbrs && tz->tz_is_set)))
            {
              size_t zone_size = strlen (zone) + 1;
              if (zone_size < tz->abbrs + ABBR_SIZE_MIN - zone_copy)
                extend_abbrs (zone_copy, zone, zone_size);
              else
                {
                  tz = tz->next = tzalloc (zone);
                  if (!tz)
                    return false;
                  tz->tz_is_set = 0;
                  zone_copy = tz->abbrs;
                }
              break;
            }

          zone_copy += strlen (zone_copy) + 1;
          if (!*zone_copy && tz->next)
            {
              tz = tz->next;
              zone_copy = tz->abbrs;
            }
        }
    }

  /* Replace the zone name so that its lifetime matches that of TZ.  */
# if HAVE_TM_ZONE
  tm->tm_zone = zone_copy;
# else
  if (0 <= tzname_index)
    tz->tzname_copy[tzname_index] = zone_copy;
# endif
#endif

  return true;
}
Example #6
0
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;
}
Example #7
0
static int
tzalloc_test (void)
{
    int fail = 0;
    int i;

    for (i = 0; LT[i].tza; i++)
    {
        struct tzalloc_test *tza = LT[i].tza;
        long lt = LT[i].t;
        timezone_t tz = tza->tz;
        char const *setting;
        static char const format[] = "%Y-%m-%d %H:%M:%S %z (%Z)";
        char buf[1000];
        struct tm tm;
        size_t n;

        if (!tz && tza->setting)
        {
            tz = tzalloc (tza->setting);
            if (!tz)
            {
                fail = 1;
                printf ("%s: tzalloc: %s\n", TZ[i].setting, strerror (errno));
                continue;
            }
            tza->tz = tz;
        }

        setting = tza->setting ? tza->setting : "UTC0";

        if (!localtime_rz (tz, &LT[i].t, &tm))
        {
            fail = 1;
            printf ("%s: %ld: localtime_rz: %s\n", setting, lt,
                    strerror (errno));
            continue;
        }

        n = nstrftime (buf, sizeof buf, format, &tm, tz, 0);
        if (n == 0)
        {
            fail = 1;
            printf ("%s: %ld: nstrftime failed\n", setting, lt);
            continue;
        }

        if (! (STREQ (buf, LT[i].exp)
                || (!tz && n == strlen (LT[i].exp)
                    && memcmp (buf, LT[i].exp, n - sizeof "(GMT)" + 1) == 0
                    && STREQ (buf + n - sizeof "(GMT)" + 1, "(GMT)"))))
        {
            /* Don't fail for unhandled dst in ahistorical entries,
               as gnulib doesn't currently fix that issue, seen on Darwin 14.  */
            if (!LT[i].ahistorical || tm.tm_isdst)
                fail = 1;
            printf ("%s: expected \"%s\", got \"%s\"\n",
                    setting, LT[i].exp, buf);
        }
    }

    return fail;
}