22 #define ZIC_VERSION_PRE_2013 '2'
23 #define ZIC_VERSION '3'
26 #define ZIC_MIN PG_INT64_MIN
27 #define ZIC_MAX PG_INT64_MAX
29 #ifndef ZIC_MAX_ABBR_LEN_WO_WARN
30 #define ZIC_MAX_ABBR_LEN_WO_WARN 6
35 #define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
37 #define MKDIR_UMASK 0755
41 #if !defined S_ISDIR && defined S_IFDIR && defined S_IFMT
42 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
114 extern int link(
const char *target,
const char *linkname);
115 #ifndef AT_SYMLINK_FOLLOW
116 #define linkat(targetdir, target, linknamedir, linkname, flag) \
117 (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
127 bool isdst,
bool ttisstd,
bool ttisut);
128 static
void leapadd(
zic_t t,
int correction,
int rolling);
131 static
void dolink(
char const *target,
char const *linkname,
134 static
zic_t gethms(const
char *
string, const
char *errstring);
136 static
void inexpires(
char **fields,
int nfields);
138 static
void inleap(
char **fields,
int nfields);
139 static
void inlink(
char **fields,
int nfields);
140 static
void inrule(
char **fields,
int nfields);
141 static
bool inzcont(
char **fields,
int nfields);
142 static
bool inzone(
char **fields,
int nfields);
143 static
bool inzsub(
char **fields,
int nfields,
bool iscont);
148 static
void mkdirs(
char const *argname,
bool ancestors);
149 static
void newabbr(const
char *
string);
151 static
void outzone(const struct
zone *zpfirst, ptrdiff_t zonecount);
154 const
char *loyearp, const
char *hiyearp,
155 const
char *typep, const
char *monthp,
156 const
char *dayp, const
char *timep);
169 #ifndef WORK_AROUND_QTBUG_53071
217 #define ZF_TILMONTH 6
220 #define ZONE_MINFIELDS 5
221 #define ZONE_MAXFIELDS 9
230 #define ZFC_TILYEAR 3
231 #define ZFC_TILMONTH 4
233 #define ZFC_TILTIME 6
234 #define ZONEC_MINFIELDS 3
235 #define ZONEC_MAXFIELDS 7
250 #define RULE_FIELDS 10
257 #define LF_LINKNAME 2
258 #define LINK_FIELDS 3
270 #define LEAP_FIELDS 7
273 #define EXPIRES_FIELDS 5
310 const struct lookup *table);
377 {
"Stationary",
false},
382 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
383 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
420 if (SIZE_MAX / itemsize <
nitems)
454 if (
nitems < *nitems_alloc)
459 ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
461 if ((amax - 1) / 3 * 2 < *nitems_alloc)
463 *nitems_alloc += (*nitems_alloc >> 1) + 1;
498 fprintf(stderr,
_(
" (rule from \"%s\", line %d)"),
529 char const *
e = (ferror(stream) ?
_(
"I/O error")
530 : fclose(stream) != 0 ?
strerror(errno) : NULL);
535 dir ? dir :
"", dir ?
"/" :
"",
546 _(
"%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n"
547 "\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]"
548 " [ -L leapseconds ] \\\n"
549 "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -t localtime-link ] \\\n"
550 "\t[ filename ... ]\n\n"
551 "Report bugs to %s.\n"),
566 int chdir_errno = errno;
568 if (chdir_errno == ENOENT)
571 chdir_errno = chdir(dir) == 0 ? 0 : errno;
573 if (chdir_errno != 0)
575 fprintf(stderr,
_(
"%s: Can't chdir to %s: %s\n"),
582 #define TIME_T_BITS_IN_FILE 64
617 if (lo_end[0] ==
'/' && lo_end[1] ==
'@')
649 #ifndef ZIC_BLOAT_DEFAULT
650 #define ZIC_BLOAT_DEFAULT "slim"
660 bool timerange_given =
false;
669 _(
"wild compilation-time specification of zic_t"));
672 for (k = 1; k < argc; k++)
673 if (strcmp(argv[k],
"--version") == 0)
675 printf(
"zic %s\n", PG_VERSION);
679 else if (strcmp(argv[k],
"--help") == 0)
683 while ((
c =
getopt(argc, argv,
"b:d:l:L:p:Pr:st:vy:")) != EOF &&
c != -1)
689 if (strcmp(
optarg,
"slim") == 0)
692 error(
_(
"incompatible -b options"));
695 else if (strcmp(
optarg,
"fat") == 0)
698 error(
_(
"incompatible -b options"));
710 _(
"%s: More than one -d option specified\n"),
721 _(
"%s: More than one -l option specified\n"),
732 _(
"%s: More than one -p option specified\n"),
741 _(
"%s: More than one -t option"
757 _(
"%s: More than one -L option specified\n"),
773 _(
"%s: More than one -r option specified\n"),
780 _(
"%s: invalid time range: %s\n"),
784 timerange_given =
true;
790 if (
optind == argc - 1 && strcmp(argv[
optind],
"=") == 0)
796 if (strcmp(bloat_default,
"slim") == 0)
798 else if (strcmp(bloat_default,
"fat") == 0)
814 for (k =
optind; k < argc; k++)
839 if (strcmp(
links[
i].l_linkname,
845 eat(
_(
"command line"), 1);
850 eat(
_(
"command line"), 1);
853 if (
warnings && (ferror(stderr) || fclose(stderr) != 0))
860 char const *component_end)
864 component_len_max = 14};
865 ptrdiff_t component_len = component_end - component;
867 if (component_len == 0)
870 error(
_(
"empty file name"));
873 ?
"file name '%s' begins with '/'"
875 ?
"file name '%s' contains '//'"
876 :
"file name '%s' ends with '/'"),
880 if (0 < component_len && component_len <= 2
881 && component[0] ==
'.' && component_end[-1] ==
'.')
883 int len = component_len;
885 error(
_(
"file name '%s' contains '%.*s' component"),
891 if (0 < component_len && component[0] ==
'-')
892 warning(
_(
"file name '%s' component contains leading '-'"),
894 if (component_len_max < component_len)
895 warning(
_(
"file name '%s' contains overlength component"
897 name, component_len_max, component);
908 static char const benign[] =
910 "abcdefghijklmnopqrstuvwxyz"
911 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
917 static char const printable_and_not_benign[] =
918 " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
920 char const *component =
name;
922 for (cp =
name; *cp; cp++)
924 unsigned char c = *cp;
926 if (
noise && !strchr(benign,
c))
928 warning((strchr(printable_and_not_benign,
c)
929 ?
_(
"file name '%s' contains byte '%c'")
930 :
_(
"file name '%s' contains byte '\\%o'")),
951 relname(
char const *target,
char const *linkname)
959 char const *f = target;
962 if (*linkname ==
'/')
968 linksize =
len + needslash + strlen(target) + 1;
969 f = result =
emalloc(linksize);
972 strcpy(result +
len + needslash, target);
974 for (
i = 0; f[
i] && f[
i] == linkname[
i];
i++)
977 for (; linkname[
i];
i++)
978 dotdots += linkname[
i] ==
'/' && linkname[
i - 1] !=
'/';
979 taillen = strlen(f + dir_len);
980 dotdotetcsize = 3 * dotdots + taillen + 1;
981 if (dotdotetcsize <= linksize)
984 result =
emalloc(dotdotetcsize);
985 for (
i = 0;
i < dotdots;
i++)
986 memcpy(result + 3 *
i,
"../", 3);
987 memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
998 int r =
linkat(AT_FDCWD, target, AT_FDCWD, linkname, AT_SYMLINK_FOLLOW);
1000 return r == 0 ? 0 : errno;
1004 dolink(
char const *target,
char const *linkname,
bool staysymlink)
1006 bool remove_only = strcmp(target,
"-") == 0;
1007 bool linkdirs_made =
false;
1014 if (!remove_only &&
itsdir(target))
1016 fprintf(stderr,
_(
"%s: linking target %s/%s failed: %s\n"),
1022 if (remove(linkname) == 0)
1023 linkdirs_made =
true;
1024 else if (errno != ENOENT)
1028 fprintf(stderr,
_(
"%s: Can't remove %s/%s: %s\n"),
1035 if (link_errno == ENOENT && !linkdirs_made)
1038 linkdirs_made =
true;
1041 if (link_errno != 0)
1044 bool absolute = *target ==
'/';
1045 char *linkalloc = absolute ? NULL :
relname(target, linkname);
1046 char const *contents = absolute ? target : linkalloc;
1047 int symlink_errno =
symlink(contents, linkname) == 0 ? 0 : errno;
1050 && (symlink_errno == ENOENT || symlink_errno ==
ENOTSUP))
1053 if (symlink_errno == ENOENT)
1054 symlink_errno =
symlink(contents, linkname) == 0 ? 0 : errno;
1057 if (symlink_errno == 0)
1060 warning(
_(
"symbolic link used because hard link failed: %s"),
1070 fp = fopen(target,
"rb");
1075 fprintf(stderr,
_(
"%s: Can't read %s/%s: %s\n"),
1079 tp = fopen(linkname,
"wb");
1084 fprintf(stderr,
_(
"%s: Can't create %s/%s: %s\n"),
1088 while ((
c = getc(fp)) != EOF)
1093 warning(
_(
"copy used because hard link failed: %s"),
1096 else if (symlink_errno !=
ENOTSUP)
1097 warning(
_(
"copy used because symbolic link failed: %s"),
1116 size_t n = strlen(
name);
1117 char *nameslashdot =
emalloc(n + 3);
1120 memcpy(nameslashdot,
name, n);
1121 strcpy(&nameslashdot[n], &
"/."[!(n &&
name[n - 1] !=
'/')]);
1153 return strcmp(((
const struct rule *) cp1)->r_name,
1154 ((
const struct rule *) cp2)->r_name);
1179 warning(
_(
"same rule name in multiple files"));
1181 warning(
_(
"same rule name in multiple files"));
1204 for (base = 0; base <
nrules; base = out)
1207 for (out = base + 1; out <
nrules; ++out)
1235 error(
"%s",
_(
"%s in ruleless zone"));
1254 if (strcmp(
name,
"-") == 0)
1256 name =
_(
"standard input");
1259 else if ((fp = fopen(
name,
"r")) == NULL)
1263 fprintf(stderr,
_(
"%s: Cannot open %s: %s\n"),
1268 for (num = 1;; ++num)
1273 cp = strchr(
buf,
'\n');
1276 error(
_(
"line too long"));
1282 while (fields[nfields] != NULL)
1286 if (strcmp(fields[nfields],
"-") == 0)
1287 fields[nfields] = &nada;
1304 sscanf(
buf,
"#expires %ld", &cl_tmp);
1310 wantcont =
inzcont(fields, nfields);
1314 struct lookup const *line_codes
1317 lp =
byword(fields[0], line_codes);
1319 error(
_(
"input line of unknown type"));
1328 wantcont =
inzone(fields, nfields);
1344 _(
"%s: panic: Invalid l_value %d\n"),
1353 error(
_(
"expected continuation line not found"));
1365 gethms(
char const *
string,
char const *errstring)
1380 if (
string == NULL || *
string ==
'\0')
1389 switch (sscanf(
string,
1390 "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
1391 &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
1397 ok =
'0' <= xr && xr <=
'9';
1402 warning(
_(
"fractional seconds rejected by"
1403 " pre-2018 versions of zic"));
1416 error(
"%s", errstring);
1423 error(
"%s", errstring);
1427 #if INT_MAX > PG_INT32_MAX
1430 error(
_(
"time overflow"));
1434 ss += 5 + ((ss ^ 1) & (xr ==
'0')) <= tenths;
1437 warning(
_(
"values over 24 hours not handled by pre-2007 versions of zic"));
1447 size_t fieldlen = strlen(field);
1451 char *ep = field + fieldlen - 1;
1465 save =
gethms(field,
_(
"invalid saved time"));
1466 *isdst = dst < 0 ? save != 0 : dst;
1473 static struct rule r;
1477 error(
_(
"wrong number of fields on Rule line"));
1524 error(
_(
"wrong number of fields on Zone line"));
1530 _(
"\"Zone %s\" line and -l option are mutually exclusive"),
1537 _(
"\"Zone %s\" line and -p option are mutually exclusive"),
1542 if (
zones[
i].z_name != NULL &&
1545 error(
_(
"duplicate zone name %s"
1546 " (file \"%s\", line %d)"),
1552 return inzsub(fields, nfields,
false);
1560 error(
_(
"wrong number of fields on Zone continuation line"));
1563 return inzsub(fields, nfields,
true);
1567 inzsub(
char **fields,
int nfields,
bool iscont)
1571 static struct zone z;
1608 if ((cp = strchr(fields[i_format],
'%')) != NULL)
1610 if ((*++cp !=
's' && *cp !=
'z') || strchr(cp,
'%')
1611 || strchr(fields[i_format],
'/'))
1613 error(
_(
"invalid abbreviation format"));
1623 warning(
_(
"format '%s' not handled by pre-2015 versions of zic"),
1625 cp1[cp - fields[i_format]] =
's';
1629 hasuntil = nfields > i_untilyear;
1635 fields[i_untilyear],
1638 (nfields > i_untilmonth) ?
1639 fields[i_untilmonth] :
"Jan",
1640 (nfields > i_untilday) ? fields[i_untilday] :
"1",
1641 (nfields > i_untiltime) ? fields[i_untiltime] :
"0");
1644 if (iscont &&
nzones > 0 &&
1651 error(
_(
"Zone continuation line end time is not after end time of previous line"));
1684 if (sscanf(cp,
"%d%c", &year, &xs) != 1)
1689 error(
_(
"invalid leaping year"));
1713 dayoff =
oadd(dayoff,
i);
1717 error(
_(
"invalid month name"));
1725 dayoff =
oadd(dayoff,
i);
1729 if (sscanf(cp,
"%d%c", &day, &xs) != 1 ||
1732 error(
_(
"invalid day of month"));
1735 dayoff =
oadd(dayoff, day - 1);
1738 error(
_(
"time too small"));
1743 error(
_(
"time too large"));
1750 error(
_(
"leap second precedes Epoch"));
1758 error(
_(
"wrong number of fields on Leap line"));
1768 error(
_(
"invalid Rolling/Stationary field on Leap line"));
1775 else if (strcmp(fields[
LP_CORR],
"+") == 0)
1778 error(
_(
"invalid CORRECTION field on Leap line"));
1790 error(
_(
"wrong number of fields on Expires line"));
1792 error(
_(
"multiple Expires lines"));
1804 error(
_(
"wrong number of fields on Link line"));
1809 error(
_(
"blank TARGET field on Link line"));
1824 const char *typep,
const char *monthp,
const char *dayp,
1838 error(
_(
"invalid month name"));
1847 ep = dp + strlen(dp) - 1;
1889 _(
"%s: panic: Invalid l_value %d\n"),
1893 else if (sscanf(cp,
"%d%c", &year_tmp, &xs) == 1)
1897 error(
_(
"invalid starting year"));
1917 _(
"%s: panic: Invalid l_value %d\n"),
1921 else if (sscanf(cp,
"%d%c", &year_tmp, &xs) == 1)
1925 error(
_(
"invalid ending year"));
1930 error(
_(
"starting year greater than ending year"));
1935 error(
_(
"year type \"%s\" is unsupported; use \"-\" instead"),
1953 if ((ep = strchr(dp,
'<')) != NULL)
1955 else if ((ep = strchr(dp,
'>')) != NULL)
1967 error(
_(
"invalid day of month"));
1973 error(
_(
"invalid weekday name"));
1983 error(
_(
"invalid day of month"));
1996 unsigned char *
const b = (
unsigned char *)
buf;
1998 for (
i = 0, shift = 24;
i < 4; ++
i, shift -= 8)
1999 b[
i] =
val >> shift;
2007 unsigned char *
const b = (
unsigned char *)
buf;
2009 for (
i = 0, shift = 56;
i < 8; ++
i, shift -= 8)
2010 b[
i] =
val >> shift;
2019 fwrite(
buf,
sizeof buf, 1, fp);
2032 fwrite(
buf,
sizeof buf, 1, fp);
2042 return (
a <
b) ? -1 : (
a >
b);
2056 zic_t const *ats,
unsigned char const *
types)
2058 while (0 < r.count && ats[r.base] < lo)
2064 while (0 < r.leapcount &&
trans[r.leapbase] < lo)
2072 while (0 < r.count && hi + 1 < ats[r.base + r.count - 1])
2074 while (0 < r.leapcount && hi + 1 <
trans[r.leapbase + r.leapcount - 1])
2089 static const struct tzhead tzh0;
2090 static struct tzhead tzh;
2091 bool dir_checked =
false;
2093 zic_t y2038_boundary = one << 31;
2101 void *typesptr = ats + nats;
2102 unsigned char *
types = typesptr;
2122 for (; fromi <
timecnt; ++fromi)
2151 warning(
_(
"reference clients mishandle"
2152 " more than %d transition times"),
2155 warning(
_(
"pre-2014 clients may mishandle"
2156 " more than 1200 transition times"));
2192 && ats[
timecnt - 1] < y2038_boundary - 1 && strchr(
string,
'<'))
2194 ats[
timecnt] = y2038_boundary - 1;
2209 if (remove(
name) == 0)
2211 else if (errno != ENOENT)
2215 fprintf(stderr,
_(
"%s: Cannot remove %s/%s: %s\n"),
2219 fp = fopen(
name,
"wb");
2222 int fopen_errno = errno;
2224 if (fopen_errno == ENOENT && !dir_checked)
2227 fp = fopen(
name,
"wb");
2228 fopen_errno = errno;
2232 fprintf(stderr,
_(
"%s: Cannot create %s/%s: %s\n"),
2237 for (pass = 1; pass <= 2; ++pass)
2239 ptrdiff_t thistimei,
2278 thistimei = range32.
base;
2279 thistimecnt = range32.
count;
2280 toomanytimes = thistimecnt >> 31 >> 1 != 0;
2289 thistimei = range64.
base;
2290 thistimecnt = range64.
count;
2291 toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
2298 error(
_(
"too many transition times"));
2308 if (0 < thistimei && ats[thistimei] !=
lo_time)
2315 thistimelim = thistimei + thistimecnt;
2316 thisleaplim = thisleapi + thisleapcnt;
2317 if (thistimecnt != 0)
2319 if (ats[thistimei] ==
lo_time)
2324 memset(omittype,
true,
typecnt);
2325 omittype[thisdefaulttype] =
false;
2326 for (
i = thistimei;
i < thistimelim;
i++)
2327 omittype[
types[
i]] =
false;
2334 old0 = strlen(omittype);
2336 #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
2352 hidst = histd = mrudst = mrustd = -1;
2353 for (
i = thistimei;
i < thistimelim; ++
i)
2360 int h = (
i == old0 ? thisdefaulttype
2361 :
i == thisdefaulttype ? old0 :
i);
2371 if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
2381 omittype[
type] =
false;
2383 if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
2393 omittype[
type] =
false;
2401 typemap[
i == old0 ? thisdefaulttype
2402 :
i == thisdefaulttype ? old0 :
i]
2405 for (
i = 0;
i <
sizeof indmap /
sizeof indmap[0]; ++
i)
2407 thischarcnt = stdcnt = utcnt = 0;
2415 stdcnt = thistypecnt;
2417 utcnt = thistypecnt;
2421 for (
j = 0;
j < thischarcnt; ++
j)
2422 if (strcmp(&thischars[
j], thisabbr) == 0)
2424 if (
j == thischarcnt)
2426 strcpy(&thischars[thischarcnt], thisabbr);
2427 thischarcnt += strlen(thisabbr) + 1;
2433 utcnt = stdcnt = thisleapcnt = 0;
2434 thistimecnt = -(locut + hicut);
2435 thistypecnt = thischarcnt = 1;
2436 thistimelim = thistimei;
2438 #define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp)
2472 for (
i = thistimei;
i < thistimelim; ++
i)
2477 char *thisabbrev = &thischars[indmap[
desigidx[
tm]]];
2486 if (thistimei >= thistimelim)
2489 char *thisabbrev = &thischars[indmap[
desigidx[
tm]]];
2506 for (
i = thistimei;
i < thistimelim; ++
i)
2508 zic_t at = ats[
i] < lo ? lo : ats[
i];
2516 putc(currenttype, fp);
2517 for (
i = thistimei;
i < thistimelim; ++
i)
2519 currenttype = typemap[
types[
i]];
2520 putc(currenttype, fp);
2523 putc(currenttype, fp);
2527 int h = (
i == old0 ? thisdefaulttype
2528 :
i == thisdefaulttype ? old0 :
i);
2537 if (thischarcnt != 0)
2538 fwrite(thischars,
sizeof thischars[0],
2540 for (
i = thisleapi;
i < thisleaplim; ++
i)
2580 fprintf(fp,
"\n%s\n",
string);
2604 error(
_(
"%%z UT offset magnitude exceeds 99:59:59"));
2612 *p++ =
'0' + offset / 10;
2613 *p++ =
'0' + offset % 10;
2614 if (minutes | seconds)
2616 *p++ =
'0' + minutes / 10;
2617 *p++ =
'0' + minutes % 10;
2620 *p++ =
'0' + seconds / 10;
2621 *p++ =
'0' + seconds % 10;
2631 bool isdst,
zic_t save,
bool doquotes)
2638 slashp = strchr(
format,
'/');
2651 strcpy(abbr, slashp + 1);
2656 abbr[slashp -
format] =
'\0';
2661 for (cp = abbr;
is_alpha(*cp); cp++)
2663 if (
len > 0 && *cp ==
'\0')
2665 abbr[
len + 2] =
'\0';
2666 abbr[
len + 1] =
'>';
2667 memmove(abbr + 1, abbr,
len);
2687 bool negative = offset < 0;
2706 if (minutes != 0 || seconds != 0)
2729 for (month = 0; month < rp->
r_month; ++month)
2770 result +=
sprintf(result,
"M%d.%d.%d",
2803 if (
a->r_hiyear !=
b->r_hiyear)
2804 return a->r_hiyear <
b->r_hiyear ? -1 : 1;
2805 if (
a->r_month -
b->r_month != 0)
2806 return a->r_month -
b->r_month;
2807 return a->r_dayofmonth -
b->r_dayofmonth;
2813 const struct zone *zp;
2818 const char *abbrvar;
2835 zp = zpfirst + zonecount - 1;
2836 stdrp = dstrp = NULL;
2857 if (stdrp == NULL && dstrp == NULL)
2863 struct rule *stdabbrrp = NULL;
2873 if (stdrp != NULL && stdrp->
r_isdst)
2892 = (stdabbrrp ? stdabbrrp->
r_abbrvar :
"");
2899 abbrvar = (stdrp == NULL) ?
"" : stdrp->
r_abbrvar;
2900 len =
doabbr(result, zp, abbrvar,
false, 0,
true);
2923 result[
len++] =
',';
2932 len += strlen(result +
len);
2933 result[
len++] =
',';
2948 const struct zone *zp;
2972 ptrdiff_t lastatmax = -1;
2974 zic_t y2038_boundary = one << 31;
2976 int defaulttype = -1;
2979 max_envvar_len = 2 * max_abbr_len + 5 * 9;
2980 startbuf =
emalloc(max_abbr_len + 1);
2981 ab =
emalloc(max_abbr_len + 1);
2982 envvar =
emalloc(max_envvar_len + 1);
2992 prodstic = zonecount == 1;
2998 startttisstd =
false;
2999 startttisut =
false;
3006 for (
i = 0;
i < zonecount; ++
i)
3009 if (
i < zonecount - 1)
3033 _(
"no POSIX environment variable for zone"),
3041 warning(
_(
"%s: pre-%d clients may mishandle"
3042 " distant timestamps"),
3097 for (
i = 0;
i < zonecount; ++
i)
3099 struct rule *prevrp = NULL;
3106 usestart =
i > 0 && (zp - 1)->z_untiltime >
min_time;
3107 useuntil =
i < (zonecount - 1);
3119 startbuf, zp->
z_isdst, startttisstd,
3151 = (rp->
r_temp < y2038_boundary
3152 || year <= max_year0);
3171 untiltime =
tadd(untiltime,
3174 untiltime =
tadd(untiltime,
3192 offset =
oadd(offset, save);
3197 jtime =
tadd(jtime, -offset);
3198 if (k < 0 || jtime < ktime)
3203 else if (jtime == ktime)
3205 char const *dup_rules_msg =
3206 _(
"two rules for same instant");
3214 error(
"%s", dup_rules_msg);
3221 if (useuntil && ktime >= untiltime)
3224 if (usestart && ktime == starttime)
3228 if (ktime < starttime)
3239 if (*startbuf ==
'\0'
3263 if (defaulttype < 0 && !rp->
r_isdst)
3275 if (*startbuf ==
'\0' &&
3277 strchr(zp->
z_format,
'%') == NULL &&
3281 if (*startbuf ==
'\0')
3282 error(
_(
"cannot determine time zone abbreviation to use just after until time"));
3285 bool isdst = startoff != zp->
z_stdoff;
3288 startttisstd, startttisut);
3289 if (defaulttype < 0 && !isdst)
3304 starttime =
tadd(starttime, -save);
3306 starttime =
tadd(starttime, -stdoff);
3309 if (defaulttype < 0)
3337 lastat ? lastat->
type : defaulttype);
3358 addtype(
zic_t utoff,
char const *abbr,
bool isdst,
bool ttisstd,
bool ttisut)
3363 if (!(-1L - 2147483647L <= utoff && utoff <= 2147483647L))
3365 error(
_(
"UT offset out of range"));
3369 ttisstd = ttisut =
false;
3372 if (strcmp(&
chars[
j], abbr) == 0)
3390 error(
_(
"too many local time types"));
3409 error(
_(
"too many leap seconds"));
3419 corr[
i] = correction;
3429 zic_t prevtrans = 0;
3438 error(
_(
"Leap seconds too close together"));
3443 last =
corr[
i] += last;
3450 warning(
_(
"\"#expires\" is obsolescent; use \"Expires\""));
3458 error(
_(
"last Leap time does not precede Expires time"));
3628 while (*++abbr !=
'\0')
3650 static const struct lookup *
3653 const struct lookup *foundlp;
3656 if (
word == NULL || table == NULL)
3667 warning(
_(
"\"%s\" is undocumented; use \"last%s\" instead"),
3679 for (lp = table; lp->
l_word != NULL; ++lp)
3687 for (lp = table; lp->
l_word != NULL; ++lp)
3690 if (foundlp == NULL)
3696 if (foundlp &&
noise)
3699 bool pre_2017c_match =
false;
3701 for (lp = table; lp->
l_word; lp++)
3704 if (pre_2017c_match)
3706 warning(
_(
"\"%s\" is ambiguous in pre-2017c zic"),
word);
3709 pre_2017c_match =
true;
3731 if (*cp ==
'\0' || *cp ==
'#')
3733 array[nsubs++] = dp = cp;
3736 if ((*dp = *cp++) !=
'"')
3739 while ((*dp = *cp++) !=
'"')
3744 error(
_(
"Odd number of quotation marks"));
3747 }
while (*cp && *cp !=
'#' && !
is_space(*cp));
3752 array[nsubs] = NULL;
3759 error(
_(
"time overflow"));
3823 else if (wantedy < 0)
3828 while (wantedy !=
y)
3840 dayoff =
oadd(dayoff,
i);
3845 dayoff =
oadd(dayoff,
i);
3855 error(
_(
"use of 2/29 in non leap-year"));
3860 dayoff =
oadd(dayoff,
i);
3865 #define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
3879 while (wday != rp->
r_wday)
3882 dayoff =
oadd(dayoff, 1);
3889 dayoff =
oadd(dayoff, -1);
3897 warning(
_(
"rule goes past start/end of month; \
3898 will not work with pre-2004 versions of zic"));
3921 while (
is_alpha(*cp) || (
'0' <= *cp && *cp <=
'9')
3922 || *cp ==
'-' || *cp ==
'+')
3924 if (
noise && cp -
string < 3)
3925 mp =
_(
"time zone abbreviation has fewer than 3 characters");
3927 mp =
_(
"time zone abbreviation has too many characters");
3929 mp =
_(
"time zone abbreviation differs from POSIX standard");
3931 warning(
"%s (%s)", mp,
string);
3933 i = strlen(
string) + 1;
3936 error(
_(
"too many, or too long, time zone abbreviations"));
3967 while (cp && ((cp = strchr(cp,
'/')) || !ancestors))
3989 error(
_(
"%s: Cannot create directory %s: %s"),
4006 link(
const char *oldpath,
const char *newpath)
4008 if (!CopyFile(oldpath, newpath,
false))
#define pg_attribute_printf(f, a)
#define pg_attribute_noreturn()
static void PGresult * res
void err(int eval, const char *fmt,...)
vfprintf(stderr, fmt, args)
int getopt(int nargc, char *const *nargv, const char *ostr)
PGDLLIMPORT char * optarg
#define qsort(a, b, c, d)
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
static pg_noinline void Size size
void _dosmaperr(unsigned long)
#define symlink(oldpath, newpath)
#define readlink(path, buf, size)
static char chars[TZ_MAX_CHARS]
static const char * leapsec
static zic_t gethms(const char *string, const char *errstring)
static ptrdiff_t const PTRDIFF_MAX
#define ZIC_BLOAT_DEFAULT
static void change_directory(char const *dir)
static struct zone * zones
static unsigned char desigidx[TZ_MAX_TYPES]
static bool print_abbrevs
static zic_t getleapdatetime(char **fields, int nfields, bool expire_line)
static zic_t tadd(zic_t t1, zic_t t2)
static char * ecpyalloc(char const *str)
static bool ttisuts[TZ_MAX_TYPES]
static int atcomp(const void *avp, const void *bvp)
static zic_t comment_leapexpires
static char isdsts[TZ_MAX_TYPES]
static struct lookup const lasts[]
static struct lookup const leap_types[]
static void convert64(const zic_t val, char *const buf)
static void verror(const char *string, va_list args) pg_attribute_printf(1
static void * erealloc(void *ptr, size_t size)
static bool itsdir(char const *name)
int main(int argc, char **argv)
static struct lookup const mon_names[]
static zic_t print_cutoff
static int hardlinkerr(char const *target, char const *linkname)
static void eat(char const *name, lineno_t num)
static void inleap(char **fields, int nfields)
static void mkdirs(char const *argname, bool ancestors)
static void puttzcodepass(zic_t val, FILE *fp, int pass)
static bool inzone(char **fields, int nfields)
static struct lookup const begin_years[]
#define ZIC_VERSION_PRE_2013
static void close_file(FILE *stream, char const *dir, char const *name)
static void outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
static bool componentcheck(char const *name, char const *component, char const *component_end)
static char * relname(char const *target, char const *linkname)
static int max_format_len
static ptrdiff_t nzones_alloc
static int max_abbrvar_len
static zic_t rpytime(const struct rule *rp, zic_t wantedy)
static bool inzcont(char **fields, int nfields)
static ptrdiff_t nlinks_alloc
#define linkat(targetdir, target, linknamedir, linkname, flag)
static const char * lcltime
static const char * rfilename
static bool ttisstds[TZ_MAX_TYPES]
static bool ciprefix(char const *abbr, char const *word)
static int stringoffset(char *result, zic_t offset)
static struct lookup const zi_line_codes[]
static void inexpires(char **fields, int nfields)
static bool want_bloat(void)
static const char * filename
static int stringrule(char *result, struct rule *const rp, zic_t save, zic_t stdoff)
static void newabbr(const char *string)
static void static void static void warning(const char *string,...) pg_attribute_printf(1
static int addtype(zic_t utoff, char const *abbr, bool isdst, bool ttisstd, bool ttisut)
static bool is_alpha(char a)
static void * emalloc(size_t size)
static const int len_months[2][MONSPERYEAR]
static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
static bool itssymlink(char const *name)
static void * growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
static bool is_space(char a)
static bool ciequal(const char *ap, const char *bp)
static void inrule(char **fields, int nfields)
static void eats(char const *name, lineno_t num, char const *rname, lineno_t rnum)
static zic_t oadd(zic_t t1, zic_t t2)
@ WORK_AROUND_QTBUG_53071
static bool timerange_option(char *timerange)
static const char * directory
static const char * psxrules
static void dolink(char const *target, char const *linkname, bool staysymlink)
static struct lookup const * byword(const char *word, const struct lookup *table)
static zic_t utoffs[TZ_MAX_TYPES]
static char roll[TZ_MAX_LEAPS]
static ptrdiff_t nrules_alloc
static void writezone(const char *const name, const char *const string, char version, int defaulttype)
static zic_t const max_time
static void static void error(const char *string,...) pg_attribute_printf(1
static char lowerit(char a)
static bool namecheck(const char *name)
static bool inzsub(char **fields, int nfields, bool iscont)
static size_t size_product(size_t nitems, size_t itemsize)
static struct rule * rules
static zic_t getsave(char *field, bool *isdst)
static ptrdiff_t timecnt_alloc
static void rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
static void convert(const int32 val, char *const buf)
static void infile(const char *name)
int link(const char *target, const char *linkname)
static bool itsabbr(const char *abbr, const char *word)
static zic_t trans[TZ_MAX_LEAPS]
static zic_t const min_time
#define ZIC_MAX_ABBR_LEN_WO_WARN
static void addtt(zic_t starttime, int type)
static const char * progname
static int rcomp(const void *cp1, const void *cp2)
static char const * abbroffset(char *buf, zic_t offset)
static void updateminmax(const zic_t x)
static struct attype * attypes
static void * memcheck(void *ptr)
static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, bool isdst, zic_t save, bool doquotes)
static void static void static void static void usage(FILE *stream, int status) pg_attribute_noreturn()
static struct lookup const wday_names[]
static char ** getfields(char *cp)
static void adjleap(void)
static struct lookup const end_years[]
static void associate(void)
static struct timerange limitrange(struct timerange r, zic_t lo, zic_t hi, zic_t const *ats, unsigned char const *types)
static void puttzcode(const int32 val, FILE *const fp)
static struct link * links
static const int len_years[2]
static void leapadd(zic_t t, int correction, int rolling)
static struct lookup const leap_line_codes[]
static void memory_exhausted(const char *msg) pg_attribute_noreturn()
#define TIME_T_BITS_IN_FILE
static const char * tzdefault
static int rule_cmp(struct rule const *a, struct rule const *b)
static void inlink(char **fields, int nfields)
static zic_t corr[TZ_MAX_LEAPS]
static void time_overflow(void)