/* Show info in a tz file */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include "tzfile.h"
/* convert the bytes of a 32-bit integer to little endian */
#define BSWAP32(c) ((c>>24)&0xff)|((c>>8)&0xff00)|((c<<8)&0xff0000)|(c<<24)
struct tzhead h;
struct ttinfo ti;
int tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt, tzh_timecnt,
tzh_typecnt, tzh_charcnt;
int read_hdr(int f)
{
if ((read(f, &h, sizeof(h))) == -1) {
perror("read");
return 0;
}
tzh_ttisgmtcnt = BSWAP32(*((int *)h.tzh_ttisgmtcnt));
tzh_ttisstdcnt = BSWAP32(*((int *)h.tzh_ttisstdcnt));
tzh_leapcnt = BSWAP32(*((int *)h.tzh_leapcnt));
tzh_timecnt = BSWAP32(*((int *)h.tzh_timecnt));
tzh_typecnt = BSWAP32(*((int *)h.tzh_typecnt));
tzh_charcnt = BSWAP32(*((int *)h.tzh_charcnt));
printf("Header Values\n\n");
printf("tzh_ttisgmtcnt: %d\n", tzh_ttisgmtcnt);
printf("tzh_ttisstdcnt: %d\n", tzh_ttisstdcnt);
printf("tzh_leapcnt: %d\n", tzh_leapcnt);
printf("tzh_timecnt: %d\n", tzh_timecnt);
printf("tzh_typecnt: %d\n", tzh_typecnt);
printf("tzh_charcnt: %d\n", tzh_charcnt);
}
int main(int argc, char **argv)
{
int f, i;
char *type_ndx;
time_t *trans_time;
struct ttinfo *ti;
char *abbr;
char *is_std;
char *is_gmt;
int tmp;
char s[256];
struct tm *tm;
char *set_isdst_s[2] = {"No", "Yes"};
char *std_s[2] = {"Wall", "Std"};
char *gmt_s[2] = {"Local", "GMT"};
if (argc == 1) {
fprintf(stderr, "usage: tzshow <tzfile>\n");
exit(0);
}
if ((f = open(argv[1], O_RDONLY)) == -1) {
perror("open");
exit(1);
}
if (! read_hdr(f))
exit(1);
trans_time = (time_t *)malloc(tzh_timecnt * sizeof(time_t));
for (i = 0; i < tzh_timecnt; i++) {
read(f, &tmp, 4);
trans_time[i] = BSWAP32(tmp);
}
type_ndx = (char *)malloc(tzh_timecnt * sizeof(char));
for (i = 0; i < tzh_timecnt; i++)
read(f, &(type_ndx[i]), 1);
ti = (struct ttinfo *)malloc(tzh_typecnt * sizeof(struct ttinfo));
for (i = 0; i < tzh_typecnt; i++)
read(f, &(ti[i]), sizeof(struct ttinfo));
abbr = (char *)malloc(tzh_charcnt);
read(f, abbr, tzh_charcnt);
for (i = 0; i < tzh_leapcnt; i++) {
read(f, &tmp, sizeof(tmp));
read(f, &tmp, sizeof(tmp));
}
is_std = (char *)malloc(tzh_ttisstdcnt * sizeof(char));
for (i = 0; i < tzh_ttisstdcnt; i++)
read(f, &(is_std[i]), sizeof(char));
is_gmt = (char *)malloc(tzh_ttisgmtcnt * sizeof(char));
for (i = 0; i < tzh_ttisgmtcnt; i++)
read(f, &(is_gmt[i]), sizeof(char));
printf("\n\nTransitions\n\n");
printf("%-30s%s\n\n", "Date", "Local Time Type");
for (i = 0; i < tzh_timecnt; i++) {
tm = gmtime(&(trans_time[i]));
// strftime(s, 255, "%Y-%m-%d %H:%M", tm);
strcpy(s, asctime(tm));
s[strlen(s) - 1] = '\0';
printf("%-30s%d\n", s, type_ndx[i]);
}
printf("\n\nLocal Time Types\n\n");
printf("%-5s%-10s%-15s%-8s%-12s%s\n\n", "Nr", "GMT Off",
"Set tm_isdst", "Abbr", "Std/Wall", "GMT/Local");
for (i = 0; i < tzh_typecnt; i++) {
printf("%-5d%-10d%-15s%-8s%-12s%s\n",
i, (BSWAP32(*((int *)(ti[i].tt_gmtoff)))) / 3600,
set_isdst_s[ti[i].tt_isdst], abbr + ti[i].tt_abbrind,
std_s[is_std[i]], gmt_s[is_gmt[i]]);
}
close(f);
return 0;
}