8
8
9
9
#include "postgres_fe.h"
10
10
11
+ #include <fcntl.h>
11
12
#include <locale.h>
12
13
#include <sys/stat.h>
13
14
#include <time.h>
15
+ #include <unistd.h>
14
16
15
17
#include "pg_getopt.h"
16
18
@@ -35,14 +37,24 @@ typedef int64 zic_t;
35
37
#define MKDIR_UMASK 0755
36
38
#endif
37
39
#endif
38
- #ifndef S_ISLNK
39
- #define S_ISLNK (m ) 0
40
+ #ifndef AT_SYMLINK_FOLLOW
41
+ #define linkat (fromdir , from , todir , to , flag ) \
42
+ (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))
40
43
#endif
41
44
45
+ /* The maximum ptrdiff_t value, for pre-C99 platforms. */
46
+ #ifndef PTRDIFF_MAX
47
+ static ptrdiff_t const PTRDIFF_MAX = MAXVAL (ptrdiff_t , TYPE_BIT (ptrdiff_t ));
48
+ #endif
49
+
50
+ /* The type and printf format for line numbers. */
51
+ typedef int lineno ;
52
+ #define PRIdLINENO "d"
53
+
42
54
struct rule
43
55
{
44
56
const char * r_filename ;
45
- int r_linenum ;
57
+ lineno r_linenum ;
46
58
const char * r_name ;
47
59
48
60
zic_t r_loyear ; /* for example, 1986 */
@@ -64,7 +76,7 @@ struct rule
64
76
zic_t r_stdoff ; /* offset from standard time */
65
77
const char * r_abbrvar ; /* variable part of abbreviation */
66
78
67
- int r_todo ; /* a rule to do (used in outzone) */
79
+ bool r_todo ; /* a rule to do (used in outzone) */
68
80
zic_t r_temp ; /* used in outzone */
69
81
};
70
82
@@ -79,7 +91,7 @@ struct rule
79
91
struct zone
80
92
{
81
93
const char * z_filename ;
82
- int z_linenum ;
94
+ lineno z_linenum ;
83
95
84
96
const char * z_name ;
85
97
zic_t z_gmtoff ;
@@ -90,7 +102,7 @@ struct zone
90
102
zic_t z_stdoff ;
91
103
92
104
struct rule * z_rules ;
93
- int z_nrules ;
105
+ ptrdiff_t z_nrules ;
94
106
95
107
struct rule z_untilrule ;
96
108
zic_t z_untiltime ;
@@ -119,20 +131,21 @@ static void inrule(char **fields, int nfields);
119
131
static bool inzcont (char * * fields , int nfields );
120
132
static bool inzone (char * * fields , int nfields );
121
133
static bool inzsub (char * * , int , bool );
122
- static int itsdir (const char * name );
134
+ static bool itsdir (char const * );
135
+ static bool itssymlink (char const * );
123
136
static bool is_alpha (char a );
124
137
static char lowerit (char );
125
138
static void mkdirs (char const * , bool );
126
139
static void newabbr (const char * abbr );
127
140
static zic_t oadd (zic_t t1 , zic_t t2 );
128
- static void outzone (const struct zone * zp , int ntzones );
141
+ static void outzone (const struct zone * zp , ptrdiff_t ntzones );
129
142
static zic_t rpytime (const struct rule * rp , zic_t wantedy );
130
143
static void rulesub (struct rule * rp ,
131
144
const char * loyearp , const char * hiyearp ,
132
145
const char * typep , const char * monthp ,
133
146
const char * dayp , const char * timep );
134
147
static zic_t tadd (zic_t t1 , zic_t t2 );
135
- static bool yearistype (int year , const char * type );
148
+ static bool yearistype (zic_t year , const char * type );
136
149
137
150
/* Bound on length of what %z can expand to. */
138
151
enum
@@ -156,7 +169,7 @@ static int leapcnt;
156
169
static bool leapseen ;
157
170
static zic_t leapminyear ;
158
171
static zic_t leapmaxyear ;
159
- static int linenum ;
172
+ static lineno linenum ;
160
173
static int max_abbrvar_len = PERCENT_Z_LEN_BOUND ;
161
174
static int max_format_len ;
162
175
static zic_t max_year ;
@@ -165,10 +178,10 @@ static bool noise;
165
178
static bool print_abbrevs ;
166
179
static zic_t print_cutoff ;
167
180
static const char * rfilename ;
168
- static int rlinenum ;
181
+ static lineno rlinenum ;
169
182
static const char * progname ;
170
- static int timecnt ;
171
- static int timecnt_alloc ;
183
+ static ptrdiff_t timecnt ;
184
+ static ptrdiff_t timecnt_alloc ;
172
185
static int typecnt ;
173
186
174
187
/*
@@ -253,24 +266,24 @@ static int typecnt;
253
266
#define YR_ONLY 2
254
267
255
268
static struct rule * rules ;
256
- static int nrules ; /* number of rules */
257
- static int nrules_alloc ;
269
+ static ptrdiff_t nrules ; /* number of rules */
270
+ static ptrdiff_t nrules_alloc ;
258
271
259
272
static struct zone * zones ;
260
- static int nzones ; /* number of zones */
261
- static int nzones_alloc ;
273
+ static ptrdiff_t nzones ; /* number of zones */
274
+ static ptrdiff_t nzones_alloc ;
262
275
263
276
struct link
264
277
{
265
278
const char * l_filename ;
266
- int l_linenum ;
279
+ lineno l_linenum ;
267
280
const char * l_from ;
268
281
const char * l_to ;
269
282
};
270
283
271
284
static struct link * links ;
272
- static int nlinks ;
273
- static int nlinks_alloc ;
285
+ static ptrdiff_t nlinks ;
286
+ static ptrdiff_t nlinks_alloc ;
274
287
275
288
struct lookup
276
289
{
@@ -417,17 +430,18 @@ ecpyalloc(char const * str)
417
430
}
418
431
419
432
static void *
420
- growalloc (void * ptr , size_t itemsize , int nitems , int * nitems_alloc )
433
+ growalloc (void * ptr , size_t itemsize , ptrdiff_t nitems , ptrdiff_t * nitems_alloc )
421
434
{
422
435
if (nitems < * nitems_alloc )
423
436
return ptr ;
424
437
else
425
438
{
426
- int nitems_max = INT_MAX - WORK_AROUND_QTBUG_53071 ;
439
+ ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071 ;
440
+ ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX ;
427
441
428
- if ((nitems_max - 1 ) / 3 * 2 < * nitems_alloc )
429
- memory_exhausted (_ ("int overflow" ));
430
- * nitems_alloc = * nitems_alloc + (* nitems_alloc >> 1 ) + 1 ;
442
+ if ((amax - 1 ) / 3 * 2 < * nitems_alloc )
443
+ memory_exhausted (_ ("integer overflow" ));
444
+ * nitems_alloc += (* nitems_alloc >> 1 ) + 1 ;
431
445
return erealloc (ptr , size_product (* nitems_alloc , itemsize ));
432
446
}
433
447
}
@@ -437,7 +451,7 @@ growalloc(void *ptr, size_t itemsize, int nitems, int *nitems_alloc)
437
451
*/
438
452
439
453
static void
440
- eats (const char * name , int num , const char * rname , int rnum )
454
+ eats (char const * name , lineno num , char const * rname , lineno rnum )
441
455
{
442
456
filename = name ;
443
457
linenum = num ;
@@ -446,7 +460,7 @@ eats(const char *name, int num, const char *rname, int rnum)
446
460
}
447
461
448
462
static void
449
- eat (const char * name , int num )
463
+ eat (char const * name , lineno num )
450
464
{
451
465
eats (name , num , NULL , -1 );
452
466
}
@@ -459,10 +473,10 @@ verror(const char *string, va_list args)
459
473
* "*" -v on BSD systems.
460
474
*/
461
475
if (filename )
462
- fprintf (stderr , _ ("\"%s\", line %d : " ), filename , linenum );
476
+ fprintf (stderr , _ ("\"%s\", line %" PRIdLINENO " : " ), filename , linenum );
463
477
vfprintf (stderr , string , args );
464
478
if (rfilename != NULL )
465
- fprintf (stderr , _ (" (rule from \"%s\", line %d )" ),
479
+ fprintf (stderr , _ (" (rule from \"%s\", line %" PRIdLINENO " )" ),
466
480
rfilename , rlinenum );
467
481
fprintf (stderr , "\n" );
468
482
}
@@ -553,9 +567,10 @@ static const char *yitcommand;
553
567
int
554
568
main (int argc , char * argv [])
555
569
{
556
- int i ;
557
- int j ;
558
- int c ;
570
+ int c ,
571
+ k ;
572
+ ptrdiff_t i ,
573
+ j ;
559
574
560
575
#ifndef WIN32
561
576
umask (umask (S_IWGRP | S_IWOTH ) | (S_IWGRP | S_IWOTH ));
@@ -567,14 +582,14 @@ main(int argc, char *argv[])
567
582
_ ("wild compilation-time specification of zic_t" ));
568
583
return EXIT_FAILURE ;
569
584
}
570
- for (i = 1 ; i < argc ; ++ i )
571
- if (strcmp (argv [i ], "--version" ) == 0 )
585
+ for (k = 1 ; k < argc ; k ++ )
586
+ if (strcmp (argv [k ], "--version" ) == 0 )
572
587
{
573
588
printf ("zic %s\n" , PG_VERSION );
574
589
close_file (stdout , NULL , NULL );
575
590
return EXIT_SUCCESS ;
576
591
}
577
- else if (strcmp (argv [i ], "--help" ) == 0 )
592
+ else if (strcmp (argv [k ], "--help" ) == 0 )
578
593
{
579
594
usage (stdout , EXIT_SUCCESS );
580
595
}
@@ -662,8 +677,8 @@ main(int argc, char *argv[])
662
677
adjleap ();
663
678
}
664
679
665
- for (i = optind ; i < argc ; ++ i )
666
- infile (argv [i ]);
680
+ for (k = optind ; k < argc ; k ++ )
681
+ infile (argv [k ]);
667
682
if (errors )
668
683
return EXIT_FAILURE ;
669
684
associate ();
@@ -713,7 +728,7 @@ componentcheck(char const * name, char const * component,
713
728
enum
714
729
{
715
730
component_len_max = 14 };
716
- size_t component_len = component_end - component ;
731
+ ptrdiff_t component_len = component_end - component ;
717
732
718
733
if (component_len == 0 )
719
734
{
@@ -731,8 +746,10 @@ componentcheck(char const * name, char const * component,
731
746
if (0 < component_len && component_len <= 2
732
747
&& component [0 ] == '.' && component_end [-1 ] == '.' )
733
748
{
749
+ int len = component_len ;
750
+
734
751
error (_ ("file name '%s' contains '%.*s' component" ),
735
- name , ( int ) component_len , component );
752
+ name , len , component );
736
753
return false;
737
754
}
738
755
if (noise )
@@ -823,9 +840,9 @@ relname(char const * from, char const * to)
823
840
for (i = 0 ; f [i ] && f [i ] == to [i ]; i ++ )
824
841
if (f [i ] == '/' )
825
842
dir_len = i + 1 ;
826
- for (; f [i ]; i ++ )
827
- dotdots += f [i ] == '/' && f [i - 1 ] != '/' ;
828
- taillen = i - dir_len ;
843
+ for (; to [i ]; i ++ )
844
+ dotdots += to [i ] == '/' && to [i - 1 ] != '/' ;
845
+ taillen = strlen ( f + dir_len ) ;
829
846
dotdotetcsize = 3 * dotdots + taillen + 1 ;
830
847
if (dotdotetcsize <= linksize )
831
848
{
@@ -839,28 +856,34 @@ relname(char const * from, char const * to)
839
856
}
840
857
#endif /* HAVE_SYMLINK */
841
858
859
+ /* Hard link FROM to TO, following any symbolic links.
860
+ Return 0 if successful, an error number otherwise. */
861
+ static int
862
+ hardlinkerr (char const * from , char const * to )
863
+ {
864
+ int r = linkat (AT_FDCWD , from , AT_FDCWD , to , AT_SYMLINK_FOLLOW );
865
+
866
+ return r == 0 ? 0 : errno ;
867
+ }
868
+
842
869
static void
843
870
dolink (char const * fromfield , char const * tofield , bool staysymlink )
844
871
{
845
- int fromisdir ;
846
872
bool todirs_made = false;
847
873
int link_errno ;
848
874
849
875
/*
850
876
* We get to be careful here since there's a fair chance of root running
851
877
* us.
852
878
*/
853
- fromisdir = itsdir (fromfield );
854
- if (fromisdir )
879
+ if (itsdir (fromfield ))
855
880
{
856
- char const * e = strerror (fromisdir < 0 ? errno : EPERM );
857
-
858
881
fprintf (stderr , _ ("%s: link from %s/%s failed: %s\n" ),
859
- progname , directory , fromfield , e );
882
+ progname , directory , fromfield , strerror ( EPERM ) );
860
883
exit (EXIT_FAILURE );
861
884
}
862
885
if (staysymlink )
863
- staysymlink = itsdir (tofield ) == 2 ;
886
+ staysymlink = itssymlink (tofield );
864
887
if (remove (tofield ) == 0 )
865
888
todirs_made = true;
866
889
else if (errno != ENOENT )
@@ -871,13 +894,12 @@ dolink(char const * fromfield, char const * tofield, bool staysymlink)
871
894
progname , directory , tofield , e );
872
895
exit (EXIT_FAILURE );
873
896
}
874
- link_errno = (staysymlink ? ENOTSUP
875
- : link (fromfield , tofield ) == 0 ? 0 : errno );
897
+ link_errno = staysymlink ? ENOTSUP : hardlinkerr (fromfield , tofield );
876
898
if (link_errno == ENOENT && !todirs_made )
877
899
{
878
900
mkdirs (tofield , true);
879
901
todirs_made = true;
880
- link_errno = link (fromfield , tofield ) == 0 ? 0 : errno ;
902
+ link_errno = hardlinkerr (fromfield , tofield );
881
903
}
882
904
if (link_errno != 0 )
883
905
{
@@ -987,31 +1009,42 @@ static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332
987
1009
? BIG_BANG
988
1010
: MINVAL (zic_t , TIME_T_BITS_IN_FILE ));
989
1011
990
- /* Return 1 if NAME is a directory, 2 if a symbolic link, 0 if
991
- something else, -1 (setting errno) if trouble. */
992
- static int
1012
+ /* Return true if NAME is a directory. */
1013
+ static bool
993
1014
itsdir (char const * name )
994
1015
{
995
1016
struct stat st ;
996
- int res = lstat (name , & st );
997
-
1017
+ int res = stat (name , & st );
1018
+ #ifdef S_ISDIR
998
1019
if (res == 0 )
1020
+ return S_ISDIR (st .st_mode ) != 0 ;
1021
+ #endif
1022
+ if (res == 0 || errno == EOVERFLOW )
999
1023
{
1000
- #ifdef S_ISDIR
1001
- return S_ISDIR (st .st_mode ) ? 1 : S_ISLNK (st .st_mode ) ? 2 : 0 ;
1002
- #else
1003
1024
size_t n = strlen (name );
1004
1025
char * nameslashdot = emalloc (n + 3 );
1005
1026
bool dir ;
1006
1027
1007
1028
memcpy (nameslashdot , name , n );
1008
1029
strcpy (& nameslashdot [n ], & "/." [!(n && name [n - 1 ] != '/' )]);
1009
- dir = lstat (nameslashdot , & st ) == 0 ;
1030
+ dir = stat (nameslashdot , & st ) == 0 || errno == EOVERFLOW ;
1010
1031
free (nameslashdot );
1011
1032
return dir ;
1012
- #endif
1013
1033
}
1014
- return -1 ;
1034
+ return false;
1035
+ }
1036
+
1037
+ /* Return true if NAME is a symbolic link. */
1038
+ static bool
1039
+ itssymlink (char const * name )
1040
+ {
1041
+ #ifdef HAVE_SYMLINK
1042
+ char c ;
1043
+
1044
+ return 0 <= readlink (name , & c , 1 );
1045
+ #else
1046
+ return false;
1047
+ #endif
1015
1048
}
1016
1049
1017
1050
/*
@@ -1034,10 +1067,10 @@ associate(void)
1034
1067
{
1035
1068
struct zone * zp ;
1036
1069
struct rule * rp ;
1037
- int base ,
1070
+ ptrdiff_t i ,
1071
+ j ,
1072
+ base ,
1038
1073
out ;
1039
- int i ,
1040
- j ;
1041
1074
1042
1075
if (nrules != 0 )
1043
1076
{
@@ -1124,7 +1157,7 @@ infile(const char *name)
1124
1157
const struct lookup * lp ;
1125
1158
int nfields ;
1126
1159
bool wantcont ;
1127
- int num ;
1160
+ lineno num ;
1128
1161
char buf [BUFSIZ ];
1129
1162
1130
1163
if (strcmp (name , "-" ) == 0 )
@@ -1175,7 +1208,7 @@ infile(const char *name)
1175
1208
if (lp == NULL )
1176
1209
error (_ ("input line of unknown type" ));
1177
1210
else
1178
- switch (( int ) ( lp -> l_value ) )
1211
+ switch (lp -> l_value )
1179
1212
{
1180
1213
case LC_RULE :
1181
1214
inrule (fields , nfields );
@@ -1302,7 +1335,7 @@ inrule(char **fields, int nfields)
1302
1335
static bool
1303
1336
inzone (char * * fields , int nfields )
1304
1337
{
1305
- int i ;
1338
+ ptrdiff_t i ;
1306
1339
1307
1340
if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS )
1308
1341
{
@@ -1327,8 +1360,8 @@ inzone(char **fields, int nfields)
1327
1360
if (zones [i ].z_name != NULL &&
1328
1361
strcmp (zones [i ].z_name , fields [ZF_NAME ]) == 0 )
1329
1362
{
1330
- error (
1331
- _ ( "duplicate zone name %s (file \"%s\", line %d )" ),
1363
+ error (_ ( "duplicate zone name %s"
1364
+ " (file \"%s\", line %" PRIdLINENO " )" ),
1332
1365
fields [ZF_NAME ],
1333
1366
zones [i ].z_filename ,
1334
1367
zones [i ].z_linenum );
@@ -1452,7 +1485,7 @@ inleap(char **fields, int nfields)
1452
1485
{
1453
1486
const char * cp ;
1454
1487
const struct lookup * lp ;
1455
- int i ,
1488
+ zic_t i ,
1456
1489
j ;
1457
1490
1458
1491
/* PG: make year be int not zic_t to avoid sscanf portability issues */
@@ -1659,7 +1692,7 @@ rulesub(struct rule * rp, const char *loyearp, const char *hiyearp,
1659
1692
lp = byword (cp , begin_years );
1660
1693
rp -> r_lowasnum = lp == NULL ;
1661
1694
if (!rp -> r_lowasnum )
1662
- switch (( int ) lp -> l_value )
1695
+ switch (lp -> l_value )
1663
1696
{
1664
1697
case YR_MINIMUM :
1665
1698
rp -> r_loyear = ZIC_MIN ;
@@ -1684,7 +1717,7 @@ rulesub(struct rule * rp, const char *loyearp, const char *hiyearp,
1684
1717
lp = byword (cp , end_years );
1685
1718
rp -> r_hiwasnum = lp == NULL ;
1686
1719
if (!rp -> r_hiwasnum )
1687
- switch (( int ) lp -> l_value )
1720
+ switch (lp -> l_value )
1688
1721
{
1689
1722
case YR_MINIMUM :
1690
1723
rp -> r_hiyear = ZIC_MIN ;
@@ -1834,19 +1867,19 @@ static void
1834
1867
writezone (const char * const name , const char * const string , char version )
1835
1868
{
1836
1869
FILE * fp ;
1837
- int i ,
1870
+ ptrdiff_t i ,
1838
1871
j ;
1839
1872
int leapcnt32 ,
1840
1873
leapi32 ;
1841
- int timecnt32 ,
1874
+ ptrdiff_t timecnt32 ,
1842
1875
timei32 ;
1843
1876
int pass ;
1844
1877
static const struct tzhead tzh0 ;
1845
1878
static struct tzhead tzh ;
1846
1879
bool dir_checked = false;
1847
1880
zic_t one = 1 ;
1848
1881
zic_t y2038_boundary = one << 31 ;
1849
- int nats = timecnt + WORK_AROUND_QTBUG_53071 ;
1882
+ ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071 ;
1850
1883
zic_t * ats = emalloc (size_product (nats , sizeof * ats + 1 ));
1851
1884
void * typesptr = ats + nats ;
1852
1885
unsigned char * types = typesptr ;
@@ -1861,8 +1894,8 @@ writezone(const char *const name, const char *const string, char version)
1861
1894
* Optimize.
1862
1895
*/
1863
1896
{
1864
- int fromi ;
1865
- int toi ;
1897
+ ptrdiff_t fromi ,
1898
+ toi ;
1866
1899
1867
1900
toi = 0 ;
1868
1901
fromi = 0 ;
@@ -1886,9 +1919,17 @@ writezone(const char *const name, const char *const string, char version)
1886
1919
}
1887
1920
timecnt = toi ;
1888
1921
}
1922
+
1889
1923
if (noise && timecnt > 1200 )
1890
- warning (_ ("pre-2014 clients may mishandle"
1891
- " more than 1200 transition times" ));
1924
+ {
1925
+ if (timecnt > TZ_MAX_TIMES )
1926
+ warning (_ ("reference clients mishandle"
1927
+ " more than %d transition times" ),
1928
+ TZ_MAX_TIMES );
1929
+ else
1930
+ warning (_ ("pre-2014 clients may mishandle"
1931
+ " more than 1200 transition times" ));
1932
+ }
1892
1933
1893
1934
/*
1894
1935
* Transfer.
@@ -1991,33 +2032,38 @@ writezone(const char *const name, const char *const string, char version)
1991
2032
}
1992
2033
for (pass = 1 ; pass <= 2 ; ++ pass )
1993
2034
{
1994
- int thistimei ,
1995
- thistimecnt ;
2035
+ ptrdiff_t thistimei ,
2036
+ thistimecnt ,
2037
+ thistimelim ;
1996
2038
int thisleapi ,
1997
- thisleapcnt ;
1998
- int thistimelim ,
2039
+ thisleapcnt ,
1999
2040
thisleaplim ;
2000
2041
int writetype [TZ_MAX_TYPES ];
2001
2042
int typemap [TZ_MAX_TYPES ];
2002
2043
int thistypecnt ;
2003
2044
char thischars [TZ_MAX_CHARS ];
2004
- char thischarcnt ;
2045
+ int thischarcnt ;
2046
+ bool toomanytimes ;
2005
2047
int indmap [TZ_MAX_CHARS ];
2006
2048
2007
2049
if (pass == 1 )
2008
2050
{
2009
2051
thistimei = timei32 ;
2010
2052
thistimecnt = timecnt32 ;
2053
+ toomanytimes = thistimecnt >> 31 >> 1 != 0 ;
2011
2054
thisleapi = leapi32 ;
2012
2055
thisleapcnt = leapcnt32 ;
2013
2056
}
2014
2057
else
2015
2058
{
2016
2059
thistimei = 0 ;
2017
2060
thistimecnt = timecnt ;
2061
+ toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0 ;
2018
2062
thisleapi = 0 ;
2019
2063
thisleapcnt = leapcnt ;
2020
2064
}
2065
+ if (toomanytimes )
2066
+ error (_ ("too many transition times" ));
2021
2067
thistimelim = thistimei + thistimecnt ;
2022
2068
thisleaplim = thisleapi + thisleapcnt ;
2023
2069
for (i = 0 ; i < typecnt ; ++ i )
@@ -2118,8 +2164,7 @@ writezone(const char *const name, const char *const string, char version)
2118
2164
break ;
2119
2165
if (j == thischarcnt )
2120
2166
{
2121
- strcpy (& thischars [(int ) thischarcnt ],
2122
- thisabbr );
2167
+ strcpy (& thischars [thischarcnt ], thisabbr );
2123
2168
thischarcnt += strlen (thisabbr ) + 1 ;
2124
2169
}
2125
2170
indmap [abbrinds [i ]] = j ;
@@ -2466,13 +2511,13 @@ enum
2466
2511
YEAR_BY_YEAR_ZONE = 1 };
2467
2512
2468
2513
static int
2469
- stringzone (char * result , const struct zone * const zpfirst , const int zonecount )
2514
+ stringzone (char * result , struct zone const * zpfirst , ptrdiff_t zonecount )
2470
2515
{
2471
2516
const struct zone * zp ;
2472
2517
struct rule * rp ;
2473
2518
struct rule * stdrp ;
2474
2519
struct rule * dstrp ;
2475
- int i ;
2520
+ ptrdiff_t i ;
2476
2521
const char * abbrvar ;
2477
2522
int compat = 0 ;
2478
2523
int c ;
@@ -2601,11 +2646,11 @@ stringzone(char *result, const struct zone * const zpfirst, const int zonecount)
2601
2646
}
2602
2647
2603
2648
static void
2604
- outzone (const struct zone * zpfirst , int zonecount )
2649
+ outzone (const struct zone * zpfirst , ptrdiff_t zonecount )
2605
2650
{
2606
2651
const struct zone * zp ;
2607
2652
struct rule * rp ;
2608
- int i ,
2653
+ ptrdiff_t i ,
2609
2654
j ;
2610
2655
bool usestart ,
2611
2656
useuntil ;
@@ -2627,7 +2672,7 @@ outzone(const struct zone * zpfirst, int zonecount)
2627
2672
int compat ;
2628
2673
bool do_extend ;
2629
2674
char version ;
2630
- int lastatmax = -1 ;
2675
+ ptrdiff_t lastatmax = -1 ;
2631
2676
2632
2677
max_abbr_len = 2 + max_format_len + max_abbrvar_len ;
2633
2678
max_envvar_len = 2 * max_abbr_len + 5 * 9 ;
@@ -2796,7 +2841,7 @@ outzone(const struct zone * zpfirst, int zonecount)
2796
2841
}
2797
2842
for (;;)
2798
2843
{
2799
- int k ;
2844
+ ptrdiff_t k ;
2800
2845
zic_t jtime ,
2801
2846
ktime = 0 ;
2802
2847
zic_t offset ;
@@ -3091,30 +3136,52 @@ adjleap(void)
3091
3136
}
3092
3137
}
3093
3138
3139
+ static char *
3140
+ shellquote (char * b , char const * s )
3141
+ {
3142
+ * b ++ = '\'' ;
3143
+ while (* s )
3144
+ {
3145
+ if (* s == '\'' )
3146
+ * b ++ = '\'' , * b ++ = '\\' , * b ++ = '\'' ;
3147
+ * b ++ = * s ++ ;
3148
+ }
3149
+ * b ++ = '\'' ;
3150
+ return b ;
3151
+ }
3152
+
3094
3153
static bool
3095
- yearistype (int year , const char * type )
3154
+ yearistype (zic_t year , const char * type )
3096
3155
{
3097
- static char * buf ;
3156
+ char * buf ;
3157
+ char * b ;
3098
3158
int result ;
3099
3159
3100
3160
if (type == NULL || * type == '\0' )
3101
3161
return true;
3102
- buf = erealloc (buf , 132 + strlen (yitcommand ) + strlen (type ));
3103
- sprintf (buf , "%s %d %s" , yitcommand , year , type );
3162
+ buf = emalloc (1 + 4 * strlen (yitcommand ) + 2
3163
+ + INT_STRLEN_MAXIMUM (zic_t ) + 2 + 4 * strlen (type ) + 2 );
3164
+ b = shellquote (buf , yitcommand );
3165
+ * b ++ = ' ' ;
3166
+ b += sprintf (b , INT64_FORMAT , year );
3167
+ * b ++ = ' ' ;
3168
+ b = shellquote (b , type );
3169
+ * b = '\0' ;
3104
3170
result = system (buf );
3105
3171
if (WIFEXITED (result ))
3106
- switch (WEXITSTATUS (result ))
3172
+ {
3173
+ int status = WEXITSTATUS (result );
3174
+
3175
+ if (status <= 1 )
3107
3176
{
3108
- case 0 :
3109
- return true;
3110
- case 1 :
3111
- return false;
3177
+ free (buf );
3178
+ return status == 0 ;
3112
3179
}
3180
+ }
3113
3181
error (_ ("Wild result from command execution" ));
3114
3182
fprintf (stderr , _ ("%s: command was '%s', result was %d\n" ),
3115
3183
progname , buf , result );
3116
- for (;;)
3117
- exit (EXIT_FAILURE );
3184
+ exit (EXIT_FAILURE );
3118
3185
}
3119
3186
3120
3187
/* Is A a space character in the C locale? */
@@ -3348,7 +3415,7 @@ getfields(char *cp)
3348
3415
else
3349
3416
{
3350
3417
error (_ ("Odd number of quotation marks" ));
3351
- exit (1 );
3418
+ exit (EXIT_FAILURE );
3352
3419
}
3353
3420
} while (* cp && * cp != '#' && !is_space (* cp ));
3354
3421
if (is_space (* cp ))
@@ -3537,7 +3604,8 @@ newabbr(const char *string)
3537
3604
3538
3605
/* Ensure that the directories of ARGNAME exist, by making any missing
3539
3606
ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise,
3540
- do it for ARGNAME too. Exit with failure if there is trouble. */
3607
+ do it for ARGNAME too. Exit with failure if there is trouble.
3608
+ Do not consider an existing non-directory to be trouble. */
3541
3609
static void
3542
3610
mkdirs (char const * argname , bool ancestors )
3543
3611
{
@@ -3569,7 +3637,7 @@ mkdirs(char const * argname, bool ancestors)
3569
3637
{
3570
3638
int err = errno ;
3571
3639
3572
- if (err != EEXIST && itsdir (name ) < 0 )
3640
+ if (err != EEXIST && ! itsdir (name ))
3573
3641
{
3574
3642
error (_ ("%s: Cannot create directory %s: %s" ),
3575
3643
progname , name , strerror (err ));
0 commit comments