Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
0a19fb42
Commit
0a19fb42
authored
May 21, 2004
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pgindent timezone file, per request from Tom.
parent
63bd0db1
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
2243 additions
and
1771 deletions
+2243
-1771
src/timezone/ialloc.c
src/timezone/ialloc.c
+19
-10
src/timezone/localtime.c
src/timezone/localtime.c
+563
-428
src/timezone/pgtz.c
src/timezone/pgtz.c
+77
-55
src/timezone/pgtz.h
src/timezone/pgtz.h
+3
-3
src/timezone/private.h
src/timezone/private.h
+26
-25
src/timezone/scheck.c
src/timezone/scheck.c
+16
-12
src/timezone/strftime.c
src/timezone/strftime.c
+370
-359
src/timezone/tzfile.h
src/timezone/tzfile.h
+34
-28
src/timezone/zic.c
src/timezone/zic.c
+1135
-851
No files found.
src/timezone/ialloc.c
View file @
0a19fb42
...
...
@@ -5,54 +5,63 @@
#define nonzero(n) (((n) == 0) ? 1 : (n))
char
*
imalloc
(
const
int
n
)
char
*
imalloc
(
const
int
n
)
{
return
malloc
((
size_t
)
nonzero
(
n
));
}
char
*
icalloc
(
int
nelem
,
int
elsize
)
char
*
icalloc
(
int
nelem
,
int
elsize
)
{
if
(
nelem
==
0
||
elsize
==
0
)
nelem
=
elsize
=
1
;
return
calloc
((
size_t
)
nelem
,
(
size_t
)
elsize
);
}
void
*
irealloc
(
void
*
pointer
,
const
int
size
)
void
*
irealloc
(
void
*
pointer
,
const
int
size
)
{
if
(
pointer
==
NULL
)
return
imalloc
(
size
);
return
realloc
((
void
*
)
pointer
,
(
size_t
)
nonzero
(
size
));
}
char
*
icatalloc
(
char
*
old
,
const
char
*
new
)
char
*
icatalloc
(
char
*
old
,
const
char
*
new
)
{
register
char
*
result
;
register
int
oldsize
,
newsize
;
register
char
*
result
;
register
int
oldsize
,
newsize
;
newsize
=
(
new
==
NULL
)
?
0
:
strlen
(
new
);
if
(
old
==
NULL
)
oldsize
=
0
;
else
if
(
newsize
==
0
)
return
old
;
else
oldsize
=
strlen
(
old
);
else
oldsize
=
strlen
(
old
);
if
((
result
=
irealloc
(
old
,
oldsize
+
newsize
+
1
))
!=
NULL
)
if
(
new
!=
NULL
)
(
void
)
strcpy
(
result
+
oldsize
,
new
);
return
result
;
}
char
*
icpyalloc
(
const
char
*
string
)
char
*
icpyalloc
(
const
char
*
string
)
{
return
icatalloc
((
char
*
)
NULL
,
string
);
}
void
ifree
(
char
*
p
)
void
ifree
(
char
*
p
)
{
if
(
p
!=
NULL
)
(
void
)
free
(
p
);
}
void
icfree
(
char
*
p
)
void
icfree
(
char
*
p
)
{
if
(
p
!=
NULL
)
(
void
)
free
(
p
);
...
...
src/timezone/localtime.c
View file @
0a19fb42
...
...
@@ -54,7 +54,8 @@ static const char gmt[] = "GMT";
*/
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
struct
ttinfo
{
/* time type information */
struct
ttinfo
{
/* time type information */
long
tt_gmtoff
;
/* UTC offset in seconds */
int
tt_isdst
;
/* used to set tm_isdst */
int
tt_abbrind
;
/* abbreviation list index */
...
...
@@ -62,14 +63,16 @@ struct ttinfo { /* time type information */
int
tt_ttisgmt
;
/* TRUE if transition is UTC */
};
struct
lsinfo
{
/* leap second information */
struct
lsinfo
{
/* leap second information */
time_t
ls_trans
;
/* transition time */
long
ls_corr
;
/* correction to apply */
};
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
struct
state
{
struct
state
{
int
leapcnt
;
int
timecnt
;
int
typecnt
;
...
...
@@ -82,7 +85,8 @@ struct state {
struct
lsinfo
lsis
[
TZ_MAX_LEAPS
];
};
struct
rule
{
struct
rule
{
int
r_type
;
/* type of rule--see below */
int
r_day
;
/* day number of rule */
int
r_week
;
/* week number of rule */
...
...
@@ -92,7 +96,8 @@ struct rule {
#define JULIAN_DAY 0
/* Jn - Julian day */
#define DAY_OF_YEAR 1
/* n - day of year */
#define MONTH_NTH_DAY_OF_WEEK 2
/* Mm.n.d - month, week, day of week */
#define MONTH_NTH_DAY_OF_WEEK 2
/* Mm.n.d - month, week, day of
* week */
/*
** Prototypes for static functions.
...
...
@@ -103,29 +108,30 @@ static const char *getzname(const char *strp);
static
const
char
*
getnum
(
const
char
*
strp
,
int
*
nump
,
int
min
,
int
max
);
static
const
char
*
getsecs
(
const
char
*
strp
,
long
*
secsp
);
static
const
char
*
getoffset
(
const
char
*
strp
,
long
*
offsetp
);
static
const
char
*
getrule
(
const
char
*
strp
,
struct
rule
*
rulep
);
static
void
gmtload
(
struct
state
*
sp
);
static
void
gmtsub
(
const
time_t
*
timep
,
long
offset
,
struct
pg_tm
*
tmp
);
static
void
localsub
(
const
time_t
*
timep
,
long
offset
,
struct
pg_tm
*
tmp
);
static
const
char
*
getrule
(
const
char
*
strp
,
struct
rule
*
rulep
);
static
void
gmtload
(
struct
state
*
sp
);
static
void
gmtsub
(
const
time_t
*
timep
,
long
offset
,
struct
pg_tm
*
tmp
);
static
void
localsub
(
const
time_t
*
timep
,
long
offset
,
struct
pg_tm
*
tmp
);
static
int
increment_overflow
(
int
*
number
,
int
delta
);
static
int
normalize_overflow
(
int
*
tensptr
,
int
*
unitsptr
,
int
base
);
static
time_t
time1
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
);
static
time_t
time2
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
,
int
*
okayp
);
static
time_t
time2sub
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
,
int
*
okayp
,
int
do_norm_secs
);
static
void
timesub
(
const
time_t
*
timep
,
long
offset
,
const
struct
state
*
sp
,
struct
pg_tm
*
tmp
);
static
int
tmcomp
(
const
struct
pg_tm
*
atmp
,
const
struct
pg_tm
*
btmp
);
static
time_t
transtime
(
time_t
janfirst
,
int
year
,
const
struct
rule
*
rulep
,
long
offset
);
static
int
tzload
(
const
char
*
name
,
struct
state
*
sp
);
static
int
tzparse
(
const
char
*
name
,
struct
state
*
sp
,
int
lastditch
);
static
time_t
time1
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
);
static
time_t
time2
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
,
int
*
okayp
);
static
time_t
time2sub
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
long
offset
,
int
*
okayp
,
int
do_norm_secs
);
static
void
timesub
(
const
time_t
*
timep
,
long
offset
,
const
struct
state
*
sp
,
struct
pg_tm
*
tmp
);
static
int
tmcomp
(
const
struct
pg_tm
*
atmp
,
const
struct
pg_tm
*
btmp
);
static
time_t
transtime
(
time_t
janfirst
,
int
year
,
const
struct
rule
*
rulep
,
long
offset
);
static
int
tzload
(
const
char
*
name
,
struct
state
*
sp
);
static
int
tzparse
(
const
char
*
name
,
struct
state
*
sp
,
int
lastditch
);
static
struct
state
lclmem
;
static
struct
state
gmtmem
;
#define lclptr (&lclmem)
#define gmtptr (&gmtmem)
static
char
lcl_TZname
[
TZ_STRLEN_MAX
+
1
];
static
int
lcl_is_set
=
0
;
static
int
gmt_is_set
=
0
;
static
int
lcl_is_set
=
0
;
static
int
gmt_is_set
=
0
;
/*
** Section 4.12.3 of X3.159-1989 requires that
...
...
@@ -138,7 +144,8 @@ static int gmt_is_set=0;
static
struct
pg_tm
tm
;
static
long
detzcode
(
const
char
*
codep
)
static
long
detzcode
(
const
char
*
codep
)
{
register
long
result
;
register
int
i
;
...
...
@@ -149,9 +156,10 @@ static long detzcode(const char *codep)
return
result
;
}
static
int
tzload
(
register
const
char
*
name
,
register
struct
state
*
sp
)
static
int
tzload
(
register
const
char
*
name
,
register
struct
state
*
sp
)
{
register
const
char
*
p
;
register
const
char
*
p
;
register
int
i
;
register
int
fid
;
...
...
@@ -164,7 +172,8 @@ static int tzload(register const char *name, register struct state *sp)
if
(
name
[
0
]
==
':'
)
++
name
;
doaccess
=
name
[
0
]
==
'/'
;
if
(
!
doaccess
)
{
if
(
!
doaccess
)
{
p
=
pg_TZDIR
();
if
(
p
==
NULL
)
return
-
1
;
...
...
@@ -173,8 +182,9 @@ static int tzload(register const char *name, register struct state *sp)
(
void
)
strcpy
(
fullname
,
p
);
(
void
)
strcat
(
fullname
,
"/"
);
(
void
)
strcat
(
fullname
,
name
);
/*
*
* Set doaccess if '.' (as in "../") shows up in name.
*
* Set doaccess if '.' (as in "../") shows up in name.
*/
if
(
strchr
(
name
,
'.'
)
!=
NULL
)
doaccess
=
TRUE
;
...
...
@@ -186,8 +196,9 @@ static int tzload(register const char *name, register struct state *sp)
return
-
1
;
}
{
struct
tzhead
*
tzhp
;
union
{
struct
tzhead
*
tzhp
;
union
{
struct
tzhead
tzhead
;
char
buf
[
sizeof
*
sp
+
sizeof
*
tzhp
];
}
u
;
...
...
@@ -219,17 +230,20 @@ static int tzload(register const char *name, register struct state *sp)
ttisstdcnt
+
/* ttisstds */
ttisgmtcnt
)
/* ttisgmts */
return
-
1
;
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
sp
->
ats
[
i
]
=
detzcode
(
p
);
p
+=
4
;
}
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
sp
->
types
[
i
]
=
(
unsigned
char
)
*
p
++
;
if
(
sp
->
types
[
i
]
>=
sp
->
typecnt
)
return
-
1
;
}
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
ttisp
=
&
sp
->
ttis
[
i
];
ttisp
->
tt_gmtoff
=
detzcode
(
p
);
...
...
@@ -245,8 +259,9 @@ static int tzload(register const char *name, register struct state *sp)
for
(
i
=
0
;
i
<
sp
->
charcnt
;
++
i
)
sp
->
chars
[
i
]
=
*
p
++
;
sp
->
chars
[
i
]
=
'\0'
;
/* ensure '\0' at end */
for
(
i
=
0
;
i
<
sp
->
leapcnt
;
++
i
)
{
register
struct
lsinfo
*
lsisp
;
for
(
i
=
0
;
i
<
sp
->
leapcnt
;
++
i
)
{
register
struct
lsinfo
*
lsisp
;
lsisp
=
&
sp
->
lsis
[
i
];
lsisp
->
ls_trans
=
detzcode
(
p
);
...
...
@@ -254,26 +269,30 @@ static int tzload(register const char *name, register struct state *sp)
lsisp
->
ls_corr
=
detzcode
(
p
);
p
+=
4
;
}
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
ttisp
=
&
sp
->
ttis
[
i
];
if
(
ttisstdcnt
==
0
)
ttisp
->
tt_ttisstd
=
FALSE
;
else
{
else
{
ttisp
->
tt_ttisstd
=
*
p
++
;
if
(
ttisp
->
tt_ttisstd
!=
TRUE
&&
ttisp
->
tt_ttisstd
!=
FALSE
)
return
-
1
;
}
}
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
for
(
i
=
0
;
i
<
sp
->
typecnt
;
++
i
)
{
register
struct
ttinfo
*
ttisp
;
ttisp
=
&
sp
->
ttis
[
i
];
if
(
ttisgmtcnt
==
0
)
ttisp
->
tt_ttisgmt
=
FALSE
;
else
{
else
{
ttisp
->
tt_ttisgmt
=
*
p
++
;
if
(
ttisp
->
tt_ttisgmt
!=
TRUE
&&
ttisp
->
tt_ttisgmt
!=
FALSE
)
...
...
@@ -285,8 +304,8 @@ static int tzload(register const char *name, register struct state *sp)
}
static
const
int
mon_lengths
[
2
][
MONSPERYEAR
]
=
{
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
};
static
const
int
year_lengths
[
2
]
=
{
...
...
@@ -299,7 +318,8 @@ static const int year_lengths[2] = {
** character.
*/
static
const
char
*
getzname
(
register
const
char
*
strp
)
static
const
char
*
getzname
(
register
const
char
*
strp
)
{
register
char
c
;
...
...
@@ -316,7 +336,8 @@ static const char *getzname(register const char *strp)
** Otherwise, return a pointer to the first character not part of the number.
*/
static
const
char
*
getnum
(
register
const
char
*
strp
,
int
*
nump
,
const
int
min
,
const
int
max
)
static
const
char
*
getnum
(
register
const
char
*
strp
,
int
*
nump
,
const
int
min
,
const
int
max
)
{
register
char
c
;
register
int
num
;
...
...
@@ -324,7 +345,8 @@ static const char *getnum(register const char *strp, int *nump, const int min, c
if
(
strp
==
NULL
||
!
is_digit
(
c
=
*
strp
))
return
NULL
;
num
=
0
;
do
{
do
{
num
=
num
*
10
+
(
c
-
'0'
);
if
(
num
>
max
)
return
NULL
;
/* illegal value */
...
...
@@ -344,27 +366,30 @@ static const char *getnum(register const char *strp, int *nump, const int min, c
** of seconds.
*/
static
const
char
*
getsecs
(
register
const
char
*
strp
,
long
*
secsp
)
static
const
char
*
getsecs
(
register
const
char
*
strp
,
long
*
secsp
)
{
int
num
;
/*
** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
** "M10.4.6/26", which does not conform to Posix,
** but which specifies the equivalent of
** ``02:00 on the first Sunday on or
after 23 Oct''.
* * `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like *
* "M10.4.6/26", which does not conform to Posix, * but which
* specifies the equivalent of * ``02:00 on the first Sunday on or
*
after 23 Oct''.
*/
strp
=
getnum
(
strp
,
&
num
,
0
,
HOURSPERDAY
*
DAYSPERWEEK
-
1
);
if
(
strp
==
NULL
)
return
NULL
;
*
secsp
=
num
*
(
long
)
SECSPERHOUR
;
if
(
*
strp
==
':'
)
{
if
(
*
strp
==
':'
)
{
++
strp
;
strp
=
getnum
(
strp
,
&
num
,
0
,
MINSPERHOUR
-
1
);
if
(
strp
==
NULL
)
return
NULL
;
*
secsp
+=
num
*
SECSPERMIN
;
if
(
*
strp
==
':'
)
{
if
(
*
strp
==
':'
)
{
++
strp
;
/* `SECSPERMIN' allows for leap seconds. */
strp
=
getnum
(
strp
,
&
num
,
0
,
SECSPERMIN
);
...
...
@@ -383,14 +408,17 @@ static const char *getsecs(register const char *strp, long *secsp)
** Otherwise, return a pointer to the first character not part of the time.
*/
static
const
char
*
getoffset
(
register
const
char
*
strp
,
long
*
offsetp
)
static
const
char
*
getoffset
(
register
const
char
*
strp
,
long
*
offsetp
)
{
register
int
neg
=
0
;
if
(
*
strp
==
'-'
)
{
if
(
*
strp
==
'-'
)
{
neg
=
1
;
++
strp
;
}
else
if
(
*
strp
==
'+'
)
}
else
if
(
*
strp
==
'+'
)
++
strp
;
strp
=
getsecs
(
strp
,
offsetp
);
if
(
strp
==
NULL
)
...
...
@@ -407,18 +435,22 @@ static const char *getoffset(register const char *strp, long *offsetp)
** Otherwise, return a pointer to the first character not part of the rule.
*/
static
const
char
*
getrule
(
const
char
*
strp
,
register
struct
rule
*
rulep
)
static
const
char
*
getrule
(
const
char
*
strp
,
register
struct
rule
*
rulep
)
{
if
(
*
strp
==
'J'
)
{
if
(
*
strp
==
'J'
)
{
/*
*
* Julian day.
*
* Julian day.
*/
rulep
->
r_type
=
JULIAN_DAY
;
++
strp
;
strp
=
getnum
(
strp
,
&
rulep
->
r_day
,
1
,
DAYSPERNYEAR
);
}
else
if
(
*
strp
==
'M'
)
{
}
else
if
(
*
strp
==
'M'
)
{
/*
*
* Month, week, day.
*
* Month, week, day.
*/
rulep
->
r_type
=
MONTH_NTH_DAY_OF_WEEK
;
++
strp
;
...
...
@@ -433,22 +465,29 @@ static const char *getrule(const char *strp, register struct rule *rulep)
if
(
*
strp
++
!=
'.'
)
return
NULL
;
strp
=
getnum
(
strp
,
&
rulep
->
r_day
,
0
,
DAYSPERWEEK
-
1
);
}
else
if
(
is_digit
(
*
strp
))
{
}
else
if
(
is_digit
(
*
strp
))
{
/*
*
* Day of year.
*
* Day of year.
*/
rulep
->
r_type
=
DAY_OF_YEAR
;
strp
=
getnum
(
strp
,
&
rulep
->
r_day
,
0
,
DAYSPERLYEAR
-
1
);
}
else
return
NULL
;
/* invalid format */
}
else
return
NULL
;
/* invalid format */
if
(
strp
==
NULL
)
return
NULL
;
if
(
*
strp
==
'/'
)
{
if
(
*
strp
==
'/'
)
{
/*
*
* Time specified.
*
* Time specified.
*/
++
strp
;
strp
=
getsecs
(
strp
,
&
rulep
->
r_time
);
}
else
rulep
->
r_time
=
2
*
SECSPERHOUR
;
/* default = 2:00:00 */
}
else
rulep
->
r_time
=
2
*
SECSPERHOUR
;
/* default = 2:00:00 */
return
strp
;
}
...
...
@@ -458,23 +497,30 @@ static const char *getrule(const char *strp, register struct rule *rulep)
** calculate the Epoch-relative time that rule takes effect.
*/
static
time_t
transtime
(
const
time_t
janfirst
,
const
int
year
,
register
const
struct
rule
*
rulep
,
const
long
offset
)
static
time_t
transtime
(
const
time_t
janfirst
,
const
int
year
,
register
const
struct
rule
*
rulep
,
const
long
offset
)
{
register
int
leapyear
;
register
time_t
value
=
0
;
register
int
i
;
int
d
,
m1
,
yy0
,
yy1
,
yy2
,
dow
;
int
d
,
m1
,
yy0
,
yy1
,
yy2
,
dow
;
leapyear
=
isleap
(
year
);
switch
(
rulep
->
r_type
)
{
switch
(
rulep
->
r_type
)
{
case
JULIAN_DAY
:
/*
** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
** years.
** In non-leap years, or if the day number is 59 or less, just
** add SECSPERDAY times the day number-1 to the time of
** January 1, midnight, to get the day.
* * Jn - Julian day, 1 == January 1, 60 == March 1 even in
* leap * years. * In non-leap years, or if the day number is
* 59 or less, just * add SECSPERDAY times the day number-1 to
* the time of * January 1, midnight, to get the day.
*/
value
=
janfirst
+
(
rulep
->
r_day
-
1
)
*
SECSPERDAY
;
if
(
leapyear
&&
rulep
->
r_day
>=
60
)
...
...
@@ -482,25 +528,27 @@ static time_t transtime(const time_t janfirst, const int year, register const st
break
;
case
DAY_OF_YEAR
:
/*
** n - day of year.
** Just add SECSPERDAY times the day number to the time of
** January 1, midnight, to get the
day.
* * n - day of year. * Just add SECSPERDAY times the day
* number to the time of * January 1, midnight, to get the
*
day.
*/
value
=
janfirst
+
rulep
->
r_day
*
SECSPERDAY
;
break
;
case
MONTH_NTH_DAY_OF_WEEK
:
/*
*
* Mm.n.d - nth "dth day" of month m.
*
* Mm.n.d - nth "dth day" of month m.
*/
value
=
janfirst
;
for
(
i
=
0
;
i
<
rulep
->
r_mon
-
1
;
++
i
)
value
+=
mon_lengths
[
leapyear
][
i
]
*
SECSPERDAY
;
/*
** Use Zeller's Congruence to get day-of-week of first day of
*
* month.
* * Use Zeller's Congruence to get day-of-week of first day
* of
* month.
*/
m1
=
(
rulep
->
r_mon
+
9
)
%
12
+
1
;
yy0
=
(
rulep
->
r_mon
<=
2
)
?
(
year
-
1
)
:
year
;
...
...
@@ -512,14 +560,15 @@ static time_t transtime(const time_t janfirst, const int year, register const st
dow
+=
DAYSPERWEEK
;
/*
** "dow" is the day-of-week of the first day of the month. Get
** the day-of-month (zero-origin) of the first "dow" day of the
*
* month.
* * "dow" is the day-of-week of the first day of the month.
* Get * the day-of-month (zero-origin) of the first "dow" day
* of the
* month.
*/
d
=
rulep
->
r_day
-
dow
;
if
(
d
<
0
)
d
+=
DAYSPERWEEK
;
for
(
i
=
1
;
i
<
rulep
->
r_week
;
++
i
)
{
for
(
i
=
1
;
i
<
rulep
->
r_week
;
++
i
)
{
if
(
d
+
DAYSPERWEEK
>=
mon_lengths
[
leapyear
][
rulep
->
r_mon
-
1
])
break
;
...
...
@@ -527,17 +576,17 @@ static time_t transtime(const time_t janfirst, const int year, register const st
}
/*
*
* "d" is the day-of-month (zero-origin) of the day we want.
*
* "d" is the day-of-month (zero-origin) of the day we want.
*/
value
+=
d
*
SECSPERDAY
;
break
;
}
/*
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
** question. To get the Epoch-relative time of the specified local
** time on that day, add the transition time and the current offset
*
* from UTC.
* * "value" is the Epoch-relative time of 00:00:00 UTC on the day in *
* question. To get the Epoch-relative time of the specified local *
* time on that day, add the transition time and the current offset *
* from UTC.
*/
return
value
+
rulep
->
r_time
+
offset
;
}
...
...
@@ -547,27 +596,31 @@ static time_t transtime(const time_t janfirst, const int year, register const st
** appropriate.
*/
static
int
tzparse
(
const
char
*
name
,
register
struct
state
*
sp
,
const
int
lastditch
)
static
int
tzparse
(
const
char
*
name
,
register
struct
state
*
sp
,
const
int
lastditch
)
{
const
char
*
stdname
;
const
char
*
dstname
=
NULL
;
const
char
*
stdname
;
const
char
*
dstname
=
NULL
;
size_t
stdlen
;
size_t
dstlen
;
long
stdoffset
;
long
dstoffset
;
register
time_t
*
atp
;
register
unsigned
char
*
typep
;
register
char
*
cp
;
register
time_t
*
atp
;
register
unsigned
char
*
typep
;
register
char
*
cp
;
register
int
load_result
;
stdname
=
name
;
if
(
lastditch
)
{
if
(
lastditch
)
{
stdlen
=
strlen
(
name
);
/* length of standard zone name */
name
+=
stdlen
;
if
(
stdlen
>=
sizeof
sp
->
chars
)
stdlen
=
(
sizeof
sp
->
chars
)
-
1
;
stdoffset
=
0
;
}
else
{
}
else
{
name
=
getzname
(
name
);
stdlen
=
name
-
stdname
;
if
(
stdlen
<
3
)
...
...
@@ -581,20 +634,25 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
load_result
=
tzload
(
TZDEFRULES
,
sp
);
if
(
load_result
!=
0
)
sp
->
leapcnt
=
0
;
/* so, we're off a little */
if
(
*
name
!=
'\0'
)
{
if
(
*
name
!=
'\0'
)
{
dstname
=
name
;
name
=
getzname
(
name
);
dstlen
=
name
-
dstname
;
/* length of DST zone name */
if
(
dstlen
<
3
)
return
-
1
;
if
(
*
name
!=
'\0'
&&
*
name
!=
','
&&
*
name
!=
';'
)
{
if
(
*
name
!=
'\0'
&&
*
name
!=
','
&&
*
name
!=
';'
)
{
name
=
getoffset
(
name
,
&
dstoffset
);
if
(
name
==
NULL
)
return
-
1
;
}
else
dstoffset
=
stdoffset
-
SECSPERHOUR
;
}
else
dstoffset
=
stdoffset
-
SECSPERHOUR
;
if
(
*
name
==
'\0'
&&
load_result
!=
0
)
name
=
TZDEFRULESTRING
;
if
(
*
name
==
','
||
*
name
==
';'
)
{
if
(
*
name
==
','
||
*
name
==
';'
)
{
struct
rule
start
;
struct
rule
end
;
register
int
year
;
...
...
@@ -612,8 +670,9 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
if
(
*
name
!=
'\0'
)
return
-
1
;
sp
->
typecnt
=
2
;
/* standard time and DST */
/*
*
* Two transitions per year, from EPOCH_YEAR to 2037.
*
* Two transitions per year, from EPOCH_YEAR to 2037.
*/
sp
->
timecnt
=
2
*
(
2037
-
EPOCH_YEAR
+
1
);
if
(
sp
->
timecnt
>
TZ_MAX_TIMES
)
...
...
@@ -627,17 +686,21 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
atp
=
sp
->
ats
;
typep
=
sp
->
types
;
janfirst
=
0
;
for
(
year
=
EPOCH_YEAR
;
year
<=
2037
;
++
year
)
{
for
(
year
=
EPOCH_YEAR
;
year
<=
2037
;
++
year
)
{
starttime
=
transtime
(
janfirst
,
year
,
&
start
,
stdoffset
);
endtime
=
transtime
(
janfirst
,
year
,
&
end
,
dstoffset
);
if
(
starttime
>
endtime
)
{
if
(
starttime
>
endtime
)
{
*
atp
++
=
endtime
;
*
typep
++
=
1
;
/* DST ends */
*
atp
++
=
starttime
;
*
typep
++
=
0
;
/* DST begins */
}
else
{
}
else
{
*
atp
++
=
starttime
;
*
typep
++
=
0
;
/* DST begins */
*
atp
++
=
endtime
;
...
...
@@ -646,7 +709,9 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
janfirst
+=
year_lengths
[
isleap
(
year
)]
*
SECSPERDAY
;
}
}
else
{
}
else
{
register
long
theirstdoffset
;
register
long
theirdstoffset
;
register
long
theiroffset
;
...
...
@@ -656,60 +721,73 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
if
(
*
name
!=
'\0'
)
return
-
1
;
/*
*
* Initial values of theirstdoffset and theirdstoffset.
*
* Initial values of theirstdoffset and theirdstoffset.
*/
theirstdoffset
=
0
;
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
j
=
sp
->
types
[
i
];
if
(
!
sp
->
ttis
[
j
].
tt_isdst
)
{
if
(
!
sp
->
ttis
[
j
].
tt_isdst
)
{
theirstdoffset
=
-
sp
->
ttis
[
j
].
tt_gmtoff
;
break
;
}
}
theirdstoffset
=
0
;
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
j
=
sp
->
types
[
i
];
if
(
sp
->
ttis
[
j
].
tt_isdst
)
{
if
(
sp
->
ttis
[
j
].
tt_isdst
)
{
theirdstoffset
=
-
sp
->
ttis
[
j
].
tt_gmtoff
;
break
;
}
}
/*
*
* Initially we're assumed to be in standard time.
*
* Initially we're assumed to be in standard time.
*/
isdst
=
FALSE
;
theiroffset
=
theirstdoffset
;
/*
** Now juggle transition times and type
s
** tracking offsets
as you do.
* * Now juggle transition times and types * tracking offset
s
*
as you do.
*/
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
sp
->
timecnt
;
++
i
)
{
j
=
sp
->
types
[
i
];
sp
->
types
[
i
]
=
sp
->
ttis
[
j
].
tt_isdst
;
if
(
sp
->
ttis
[
j
].
tt_ttisgmt
)
{
if
(
sp
->
ttis
[
j
].
tt_ttisgmt
)
{
/* No adjustment to transition time */
}
else
{
}
else
{
/*
** If summer time is in effect, and the
** transition time was not specified as
** standard time, add the summer time
** offset to the transition time;
** otherwise, add the standard time
** offset to the transition time.
* * If summer time is in effect, and the * transition
* time was not specified as * standard time, add the
* summer time * offset to the transition time; *
* otherwise, add the standard time * offset to the
* transition time.
*/
/*
** Transitions from DST to DDST
** will effectively disappear since
** POSIX provides for only one DST
** offset.
* * Transitions from DST to DDST * will effectively
* disappear since * POSIX provides for only one DST *
* offset.
*/
if
(
isdst
&&
!
sp
->
ttis
[
j
].
tt_ttisstd
)
{
if
(
isdst
&&
!
sp
->
ttis
[
j
].
tt_ttisstd
)
{
sp
->
ats
[
i
]
+=
dstoffset
-
theirdstoffset
;
}
else
{
}
else
{
sp
->
ats
[
i
]
+=
stdoffset
-
theirstdoffset
;
}
...
...
@@ -717,11 +795,13 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
theiroffset
=
-
sp
->
ttis
[
j
].
tt_gmtoff
;
if
(
sp
->
ttis
[
j
].
tt_isdst
)
theirdstoffset
=
theiroffset
;
else
theirstdoffset
=
theiroffset
;
else
theirstdoffset
=
theiroffset
;
}
/*
** Finally, fill in ttis.
** ttisstd and ttisgmt need not be
handled.
* * Finally, fill in ttis. * ttisstd and ttisgmt need not be
*
handled.
*/
sp
->
ttis
[
0
].
tt_gmtoff
=
-
stdoffset
;
sp
->
ttis
[
0
].
tt_isdst
=
FALSE
;
...
...
@@ -731,7 +811,9 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
sp
->
ttis
[
1
].
tt_abbrind
=
stdlen
+
1
;
sp
->
typecnt
=
2
;
}
}
else
{
}
else
{
dstlen
=
0
;
sp
->
typecnt
=
1
;
/* only standard time */
sp
->
timecnt
=
0
;
...
...
@@ -748,21 +830,24 @@ static int tzparse(const char *name, register struct state *sp, const int lastdi
(
void
)
strncpy
(
cp
,
stdname
,
stdlen
);
cp
+=
stdlen
;
*
cp
++
=
'\0'
;
if
(
dstlen
!=
0
)
{
if
(
dstlen
!=
0
)
{
(
void
)
strncpy
(
cp
,
dstname
,
dstlen
);
*
(
cp
+
dstlen
)
=
'\0'
;
}
return
0
;
}
static
void
gmtload
(
struct
state
*
sp
)
static
void
gmtload
(
struct
state
*
sp
)
{
if
(
tzload
(
gmt
,
sp
)
!=
0
)
(
void
)
tzparse
(
gmt
,
sp
,
TRUE
);
}
bool
pg_tzset
(
const
char
*
name
)
bool
pg_tzset
(
const
char
*
name
)
{
if
(
lcl_is_set
&&
strcmp
(
lcl_TZname
,
name
)
==
0
)
return
true
;
/* no change */
...
...
@@ -770,7 +855,8 @@ bool pg_tzset(const char *name)
if
(
strlen
(
name
)
>=
sizeof
(
lcl_TZname
))
return
false
;
/* not gonna fit */
if
(
tzload
(
name
,
lclptr
)
!=
0
)
{
if
(
tzload
(
name
,
lclptr
)
!=
0
)
{
if
(
name
[
0
]
==
':'
||
tzparse
(
name
,
lclptr
,
FALSE
)
!=
0
)
{
/* Unknown timezone. Fail our call instead of loading GMT! */
...
...
@@ -793,40 +879,46 @@ bool pg_tzset(const char *name)
** The unused offset argument is for the benefit of mktime variants.
*/
static
void
localsub
(
const
time_t
*
timep
,
const
long
offset
,
struct
pg_tm
*
tmp
)
static
void
localsub
(
const
time_t
*
timep
,
const
long
offset
,
struct
pg_tm
*
tmp
)
{
register
struct
state
*
sp
;
register
const
struct
ttinfo
*
ttisp
;
register
struct
state
*
sp
;
register
const
struct
ttinfo
*
ttisp
;
register
int
i
;
const
time_t
t
=
*
timep
;
sp
=
lclptr
;
if
(
sp
->
timecnt
==
0
||
t
<
sp
->
ats
[
0
])
{
if
(
sp
->
timecnt
==
0
||
t
<
sp
->
ats
[
0
])
{
i
=
0
;
while
(
sp
->
ttis
[
i
].
tt_isdst
)
if
(
++
i
>=
sp
->
typecnt
)
{
if
(
++
i
>=
sp
->
typecnt
)
{
i
=
0
;
break
;
}
}
else
{
}
else
{
for
(
i
=
1
;
i
<
sp
->
timecnt
;
++
i
)
if
(
t
<
sp
->
ats
[
i
])
break
;
i
=
sp
->
types
[
i
-
1
];
}
ttisp
=
&
sp
->
ttis
[
i
];
/*
** To get (wrong) behavior that's compatible with System V Release 2.0
** you'd replace the statement below with
** t += ttisp->tt_gmtoff;
** timesub(&t, 0L, sp, tmp);
* * To get (wrong) behavior that's compatible with System V Release
* 2.0 * you'd replace the statement below with * t +=
* ttisp->tt_gmtoff; * timesub(&t, 0L, sp, tmp);
*/
timesub
(
&
t
,
ttisp
->
tt_gmtoff
,
sp
,
tmp
);
tmp
->
tm_isdst
=
ttisp
->
tt_isdst
;
tmp
->
tm_zone
=
&
sp
->
chars
[
ttisp
->
tt_abbrind
];
}
struct
pg_tm
*
pg_localtime
(
const
time_t
*
timep
)
struct
pg_tm
*
pg_localtime
(
const
time_t
*
timep
)
{
localsub
(
timep
,
0L
,
&
tm
);
return
&
tm
;
...
...
@@ -837,40 +929,44 @@ struct pg_tm *pg_localtime(const time_t *timep)
** gmtsub is to gmtime as localsub is to localtime.
*/
static
void
gmtsub
(
const
time_t
*
timep
,
const
long
offset
,
struct
pg_tm
*
tmp
)
static
void
gmtsub
(
const
time_t
*
timep
,
const
long
offset
,
struct
pg_tm
*
tmp
)
{
if
(
!
gmt_is_set
)
{
if
(
!
gmt_is_set
)
{
gmt_is_set
=
TRUE
;
gmtload
(
gmtptr
);
}
timesub
(
timep
,
offset
,
gmtptr
,
tmp
);
/*
** Could get fancy here and deliver something such as
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
** but this is no time for a
treasure hunt.
* * Could get fancy here and deliver something such as * "UTC+xxxx"
* or "UTC-xxxx" if offset is non-zero, * but this is no time for a
*
treasure hunt.
*/
if
(
offset
!=
0
)
tmp
->
tm_zone
=
wildabbr
;
else
{
else
tmp
->
tm_zone
=
gmtptr
->
chars
;
}
}
struct
pg_tm
*
pg_gmtime
(
const
time_t
*
timep
)
struct
pg_tm
*
pg_gmtime
(
const
time_t
*
timep
)
{
gmtsub
(
timep
,
0L
,
&
tm
);
return
&
tm
;
}
static
void
timesub
(
const
time_t
*
timep
,
const
long
offset
,
register
const
struct
state
*
sp
,
register
struct
pg_tm
*
tmp
)
static
void
timesub
(
const
time_t
*
timep
,
const
long
offset
,
register
const
struct
state
*
sp
,
register
struct
pg_tm
*
tmp
)
{
register
const
struct
lsinfo
*
lp
;
register
const
struct
lsinfo
*
lp
;
register
long
days
;
register
long
rem
;
register
int
y
;
register
int
yleap
;
register
const
int
*
ip
;
register
const
int
*
ip
;
register
long
corr
;
register
int
hit
;
register
int
i
;
...
...
@@ -878,10 +974,13 @@ static void timesub(const time_t *timep, const long offset, register const struc
corr
=
0
;
hit
=
0
;
i
=
sp
->
leapcnt
;
while
(
--
i
>=
0
)
{
while
(
--
i
>=
0
)
{
lp
=
&
sp
->
lsis
[
i
];
if
(
*
timep
>=
lp
->
ls_trans
)
{
if
(
*
timep
==
lp
->
ls_trans
)
{
if
(
*
timep
>=
lp
->
ls_trans
)
{
if
(
*
timep
==
lp
->
ls_trans
)
{
hit
=
((
i
==
0
&&
lp
->
ls_corr
>
0
)
||
lp
->
ls_corr
>
sp
->
lsis
[
i
-
1
].
ls_corr
);
if
(
hit
)
...
...
@@ -889,7 +988,8 @@ static void timesub(const time_t *timep, const long offset, register const struc
sp
->
lsis
[
i
].
ls_trans
==
sp
->
lsis
[
i
-
1
].
ls_trans
+
1
&&
sp
->
lsis
[
i
].
ls_corr
==
sp
->
lsis
[
i
-
1
].
ls_corr
+
1
)
{
sp
->
lsis
[
i
-
1
].
ls_corr
+
1
)
{
++
hit
;
--
i
;
}
...
...
@@ -901,29 +1001,33 @@ static void timesub(const time_t *timep, const long offset, register const struc
days
=
*
timep
/
SECSPERDAY
;
rem
=
*
timep
%
SECSPERDAY
;
#ifdef mc68k
if
(
*
timep
==
0x80000000
)
{
if
(
*
timep
==
0x80000000
)
{
/*
*
* A 3B1 muffs the division on the most negative number.
*
* A 3B1 muffs the division on the most negative number.
*/
days
=
-
24855
;
rem
=
-
11648
;
}
#endif
/* defined mc68k */
rem
+=
(
offset
-
corr
);
while
(
rem
<
0
)
{
while
(
rem
<
0
)
{
rem
+=
SECSPERDAY
;
--
days
;
}
while
(
rem
>=
SECSPERDAY
)
{
while
(
rem
>=
SECSPERDAY
)
{
rem
-=
SECSPERDAY
;
++
days
;
}
tmp
->
tm_hour
=
(
int
)
(
rem
/
SECSPERHOUR
);
rem
=
rem
%
SECSPERHOUR
;
tmp
->
tm_min
=
(
int
)
(
rem
/
SECSPERMIN
);
/*
** A positive leap second requires a special
** representation. This
uses "... ??:59:60" et seq.
* * A positive leap second requires a special * representation. This
*
uses "... ??:59:60" et seq.
*/
tmp
->
tm_sec
=
(
int
)
(
rem
%
SECSPERMIN
)
+
hit
;
tmp
->
tm_wday
=
(
int
)
((
EPOCH_WDAY
+
days
)
%
DAYSPERWEEK
);
...
...
@@ -931,7 +1035,8 @@ static void timesub(const time_t *timep, const long offset, register const struc
tmp
->
tm_wday
+=
DAYSPERWEEK
;
y
=
EPOCH_YEAR
;
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
while
(
days
<
0
||
days
>=
(
long
)
year_lengths
[
yleap
=
isleap
(
y
)])
{
while
(
days
<
0
||
days
>=
(
long
)
year_lengths
[
yleap
=
isleap
(
y
)])
{
register
int
newy
;
newy
=
y
+
days
/
DAYSPERNYEAR
;
...
...
@@ -968,7 +1073,8 @@ static void timesub(const time_t *timep, const long offset, register const struc
** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
*/
static
int
increment_overflow
(
int
*
number
,
int
delta
)
static
int
increment_overflow
(
int
*
number
,
int
delta
)
{
int
number0
;
...
...
@@ -977,7 +1083,8 @@ static int increment_overflow(int *number, int delta)
return
(
*
number
<
number0
)
!=
(
delta
<
0
);
}
static
int
normalize_overflow
(
int
*
tensptr
,
int
*
unitsptr
,
const
int
base
)
static
int
normalize_overflow
(
int
*
tensptr
,
int
*
unitsptr
,
const
int
base
)
{
register
int
tensdelta
;
...
...
@@ -988,7 +1095,8 @@ static int normalize_overflow(int *tensptr, int *unitsptr, const int base)
return
increment_overflow
(
tensptr
,
tensdelta
);
}
static
int
tmcomp
(
register
const
struct
pg_tm
*
atmp
,
register
const
struct
pg_tm
*
btmp
)
static
int
tmcomp
(
register
const
struct
pg_tm
*
atmp
,
register
const
struct
pg_tm
*
btmp
)
{
register
int
result
;
...
...
@@ -1001,20 +1109,23 @@ static int tmcomp(register const struct pg_tm *atmp, register const struct pg_tm
return
result
;
}
static
time_t
time2sub
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
,
int
*
okayp
,
const
int
do_norm_secs
)
static
time_t
time2sub
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
,
int
*
okayp
,
const
int
do_norm_secs
)
{
register
const
struct
state
*
sp
;
register
const
struct
state
*
sp
;
register
int
dir
;
register
int
bits
;
register
int
i
,
j
;
register
int
i
,
j
;
register
int
saved_seconds
;
time_t
newt
;
time_t
t
;
struct
pg_tm
yourtm
,
mytm
;
struct
pg_tm
yourtm
,
mytm
;
*
okayp
=
FALSE
;
yourtm
=
*
tmp
;
if
(
do_norm_secs
)
{
if
(
do_norm_secs
)
{
if
(
normalize_overflow
(
&
yourtm
.
tm_min
,
&
yourtm
.
tm_sec
,
SECSPERMIN
))
return
WRONG
;
...
...
@@ -1025,30 +1136,35 @@ static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, str
return
WRONG
;
if
(
normalize_overflow
(
&
yourtm
.
tm_year
,
&
yourtm
.
tm_mon
,
MONSPERYEAR
))
return
WRONG
;
/*
** Turn yourtm.tm_year into an actual year number for now.
** It is
converted back to an offset from TM_YEAR_BASE later.
* * Turn yourtm.tm_year into an actual year number for now. * It is
*
converted back to an offset from TM_YEAR_BASE later.
*/
if
(
increment_overflow
(
&
yourtm
.
tm_year
,
TM_YEAR_BASE
))
return
WRONG
;
while
(
yourtm
.
tm_mday
<=
0
)
{
while
(
yourtm
.
tm_mday
<=
0
)
{
if
(
increment_overflow
(
&
yourtm
.
tm_year
,
-
1
))
return
WRONG
;
i
=
yourtm
.
tm_year
+
(
1
<
yourtm
.
tm_mon
);
yourtm
.
tm_mday
+=
year_lengths
[
isleap
(
i
)];
}
while
(
yourtm
.
tm_mday
>
DAYSPERLYEAR
)
{
while
(
yourtm
.
tm_mday
>
DAYSPERLYEAR
)
{
i
=
yourtm
.
tm_year
+
(
1
<
yourtm
.
tm_mon
);
yourtm
.
tm_mday
-=
year_lengths
[
isleap
(
i
)];
if
(
increment_overflow
(
&
yourtm
.
tm_year
,
1
))
return
WRONG
;
}
for
(
;
;
)
{
for
(;;)
{
i
=
mon_lengths
[
isleap
(
yourtm
.
tm_year
)][
yourtm
.
tm_mon
];
if
(
yourtm
.
tm_mday
<=
i
)
break
;
yourtm
.
tm_mday
-=
i
;
if
(
++
yourtm
.
tm_mon
>=
MONSPERYEAR
)
{
if
(
++
yourtm
.
tm_mon
>=
MONSPERYEAR
)
{
yourtm
.
tm_mon
=
0
;
if
(
increment_overflow
(
&
yourtm
.
tm_year
,
1
))
return
WRONG
;
...
...
@@ -1058,76 +1174,86 @@ static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, str
return
WRONG
;
if
(
yourtm
.
tm_sec
>=
0
&&
yourtm
.
tm_sec
<
SECSPERMIN
)
saved_seconds
=
0
;
else
if
(
yourtm
.
tm_year
+
TM_YEAR_BASE
<
EPOCH_YEAR
)
{
else
if
(
yourtm
.
tm_year
+
TM_YEAR_BASE
<
EPOCH_YEAR
)
{
/*
** We can't set tm_sec to 0, because that might push the
** time below the minimum representable time.
** Set tm_sec to 59 instead.
** This assumes that the minimum representable time is
** not in the same minute that a leap second was deleted from,
** which is a safer assumption than using 58 would be.
* * We can't set tm_sec to 0, because that might push the * time
* below the minimum representable time. * Set tm_sec to 59
* instead. * This assumes that the minimum representable time is *
* not in the same minute that a leap second was deleted from, *
* which is a safer assumption than using 58 would be.
*/
if
(
increment_overflow
(
&
yourtm
.
tm_sec
,
1
-
SECSPERMIN
))
return
WRONG
;
saved_seconds
=
yourtm
.
tm_sec
;
yourtm
.
tm_sec
=
SECSPERMIN
-
1
;
}
else
{
}
else
{
saved_seconds
=
yourtm
.
tm_sec
;
yourtm
.
tm_sec
=
0
;
}
/*
** Divide the search space in half
** (this works whether time_t is
signed or unsigned).
* * Divide the search space in half * (this works whether time_t is
*
signed or unsigned).
*/
bits
=
TYPE_BIT
(
time_t
)
-
1
;
bits
=
TYPE_BIT
(
time_t
)
-
1
;
/*
** If time_t is signed, then 0 is just above the median,
** assuming two's complement arithmetic.
** If time_t is unsigned, then (1 <<
bits) is just above the median.
* * If time_t is signed, then 0 is just above the median, * assuming
* two's complement arithmetic. * If time_t is unsigned, then (1 <<
*
bits) is just above the median.
*/
t
=
TYPE_SIGNED
(
time_t
)
?
0
:
(((
time_t
)
1
)
<<
bits
);
for
(
;
;
)
{
(
*
funcp
)(
&
t
,
offset
,
&
mytm
);
for
(;;)
{
(
*
funcp
)
(
&
t
,
offset
,
&
mytm
);
dir
=
tmcomp
(
&
mytm
,
&
yourtm
);
if
(
dir
!=
0
)
{
if
(
dir
!=
0
)
{
if
(
bits
--
<
0
)
return
WRONG
;
if
(
bits
<
0
)
--
t
;
/* may be needed if new t is minimal */
else
if
(
dir
>
0
)
t
-=
((
time_t
)
1
)
<<
bits
;
else
t
+=
((
time_t
)
1
)
<<
bits
;
else
t
+=
((
time_t
)
1
)
<<
bits
;
continue
;
}
if
(
yourtm
.
tm_isdst
<
0
||
mytm
.
tm_isdst
==
yourtm
.
tm_isdst
)
break
;
/*
** Right time, wrong type.
** Hunt for right time, right type.
** It's okay to guess wrong since the guess
** gets checked.
* * Right time, wrong type. * Hunt for right time, right type. *
* It's okay to guess wrong since the guess * gets checked.
*/
/*
*
* The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*
* The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*/
sp
=
(
const
struct
state
*
)
(((
void
*
)
funcp
==
(
void
*
)
localsub
)
?
lclptr
:
gmtptr
);
for
(
i
=
sp
->
typecnt
-
1
;
i
>=
0
;
--
i
)
{
for
(
i
=
sp
->
typecnt
-
1
;
i
>=
0
;
--
i
)
{
if
(
sp
->
ttis
[
i
].
tt_isdst
!=
yourtm
.
tm_isdst
)
continue
;
for
(
j
=
sp
->
typecnt
-
1
;
j
>=
0
;
--
j
)
{
for
(
j
=
sp
->
typecnt
-
1
;
j
>=
0
;
--
j
)
{
if
(
sp
->
ttis
[
j
].
tt_isdst
==
yourtm
.
tm_isdst
)
continue
;
newt
=
t
+
sp
->
ttis
[
j
].
tt_gmtoff
-
sp
->
ttis
[
i
].
tt_gmtoff
;
(
*
funcp
)(
&
newt
,
offset
,
&
mytm
);
(
*
funcp
)
(
&
newt
,
offset
,
&
mytm
);
if
(
tmcomp
(
&
mytm
,
&
yourtm
)
!=
0
)
continue
;
if
(
mytm
.
tm_isdst
!=
yourtm
.
tm_isdst
)
continue
;
/*
*
* We have a match.
*
* We have a match.
*/
t
=
newt
;
goto
label
;
...
...
@@ -1140,30 +1266,32 @@ label:
if
((
newt
<
t
)
!=
(
saved_seconds
<
0
))
return
WRONG
;
t
=
newt
;
(
*
funcp
)(
&
t
,
offset
,
tmp
);
(
*
funcp
)
(
&
t
,
offset
,
tmp
);
*
okayp
=
TRUE
;
return
t
;
}
static
time_t
time2
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
,
int
*
okayp
)
static
time_t
time2
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
,
int
*
okayp
)
{
time_t
t
;
/*
** First try without normalization of seconds
** (in case tm_sec contains a value associated with a leap second).
** If that fails,
try with normalization of seconds.
* * First try without normalization of seconds * (in case tm_sec
* contains a value associated with a leap second). * If that fails,
*
try with normalization of seconds.
*/
t
=
time2sub
(
tmp
,
funcp
,
offset
,
okayp
,
FALSE
);
return
*
okayp
?
t
:
time2sub
(
tmp
,
funcp
,
offset
,
okayp
,
TRUE
);
}
static
time_t
time1
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
)
static
time_t
time1
(
struct
pg_tm
*
tmp
,
void
(
*
funcp
)
(
const
time_t
*
,
long
,
struct
pg_tm
*
),
const
long
offset
)
{
register
time_t
t
;
register
const
struct
state
*
sp
;
register
int
samei
,
otheri
;
register
int
sameind
,
otherind
;
register
const
struct
state
*
sp
;
register
int
samei
,
otheri
;
register
int
sameind
,
otherind
;
register
int
i
;
register
int
nseen
;
int
seen
[
TZ_MAX_TYPES
];
...
...
@@ -1175,14 +1303,16 @@ static time_t time1(struct pg_tm *tmp, void (*funcp)(const time_t *, long, struc
t
=
time2
(
tmp
,
funcp
,
offset
,
&
okay
);
if
(
okay
||
tmp
->
tm_isdst
<
0
)
return
t
;
/*
** We're supposed to assume that somebody took a time of one type
** and did some math on it that yielded a "struct pg_tm" that's bad.
** We try to divine the type they started from and adjust to the
*
* type they need.
* * We're supposed to assume that somebody took a time of one type *
* and did some math on it that yielded a "struct pg_tm" that's bad. *
* We try to divine the type they started from and adjust to the *
* type they need.
*/
/*
*
* The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*
* The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*/
sp
=
(
const
struct
state
*
)
(((
void
*
)
funcp
==
(
void
*
)
localsub
)
?
lclptr
:
gmtptr
);
...
...
@@ -1190,15 +1320,18 @@ static time_t time1(struct pg_tm *tmp, void (*funcp)(const time_t *, long, struc
seen
[
i
]
=
FALSE
;
nseen
=
0
;
for
(
i
=
sp
->
timecnt
-
1
;
i
>=
0
;
--
i
)
if
(
!
seen
[
sp
->
types
[
i
]])
{
if
(
!
seen
[
sp
->
types
[
i
]])
{
seen
[
sp
->
types
[
i
]]
=
TRUE
;
types
[
nseen
++
]
=
sp
->
types
[
i
];
}
for
(
sameind
=
0
;
sameind
<
nseen
;
++
sameind
)
{
for
(
sameind
=
0
;
sameind
<
nseen
;
++
sameind
)
{
samei
=
types
[
sameind
];
if
(
sp
->
ttis
[
samei
].
tt_isdst
!=
tmp
->
tm_isdst
)
continue
;
for
(
otherind
=
0
;
otherind
<
nseen
;
++
otherind
)
{
for
(
otherind
=
0
;
otherind
<
nseen
;
++
otherind
)
{
otheri
=
types
[
otherind
];
if
(
sp
->
ttis
[
otheri
].
tt_isdst
==
tmp
->
tm_isdst
)
continue
;
...
...
@@ -1216,7 +1349,8 @@ static time_t time1(struct pg_tm *tmp, void (*funcp)(const time_t *, long, struc
return
WRONG
;
}
time_t
pg_mktime
(
struct
pg_tm
*
tmp
)
time_t
pg_mktime
(
struct
pg_tm
*
tmp
)
{
return
time1
(
tmp
,
localsub
,
0L
);
}
...
...
@@ -1225,7 +1359,8 @@ time_t pg_mktime(struct pg_tm *tmp)
* Return the name of the current timezone
*/
const
char
*
pg_get_current_timezone
(
void
)
{
pg_get_current_timezone
(
void
)
{
if
(
lcl_is_set
)
return
lcl_TZname
;
return
NULL
;
...
...
src/timezone/pgtz.c
View file @
0a19fb42
...
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.1
0 2004/05/21 05:08:06 tgl
Exp $
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.1
1 2004/05/21 12:30:25 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -47,15 +47,22 @@ pg_TZDIR(void)
#define T_YEAR (60*60*24*365)
#define T_MONTH (60*60*24*30)
struct
tztry
{
time_t
std_t
,
dst_t
;
char
std_time
[
TZ_STRLEN_MAX
+
1
],
dst_time
[
TZ_STRLEN_MAX
+
1
];
int
std_ofs
,
dst_ofs
;
struct
tm
std_tm
,
dst_tm
;
struct
tztry
{
time_t
std_t
,
dst_t
;
char
std_time
[
TZ_STRLEN_MAX
+
1
],
dst_time
[
TZ_STRLEN_MAX
+
1
];
int
std_ofs
,
dst_ofs
;
struct
tm
std_tm
,
dst_tm
;
};
static
bool
compare_tm
(
struct
tm
*
s
,
struct
pg_tm
*
p
)
{
static
bool
compare_tm
(
struct
tm
*
s
,
struct
pg_tm
*
p
)
{
if
(
s
->
tm_sec
!=
p
->
tm_sec
||
s
->
tm_min
!=
p
->
tm_min
||
s
->
tm_hour
!=
p
->
tm_hour
||
...
...
@@ -69,11 +76,14 @@ static bool compare_tm(struct tm *s, struct pg_tm *p) {
return
true
;
}
static
bool
try_timezone
(
char
*
tzname
,
struct
tztry
*
tt
,
bool
checkdst
)
{
static
bool
try_timezone
(
char
*
tzname
,
struct
tztry
*
tt
,
bool
checkdst
)
{
struct
pg_tm
*
pgtm
;
if
(
!
pg_tzset
(
tzname
))
return
false
;
/* If this timezone couldn't be picked at all */
return
false
;
/* If this timezone couldn't be picked at
* all */
/* Verify standard time */
pgtm
=
pg_localtime
(
&
(
tt
->
std_t
));
...
...
@@ -95,7 +105,9 @@ static bool try_timezone(char *tzname, struct tztry *tt, bool checkdst) {
return
true
;
}
static
int
get_timezone_offset
(
struct
tm
*
tm
)
{
static
int
get_timezone_offset
(
struct
tm
*
tm
)
{
#if defined(HAVE_STRUCT_TM_TM_ZONE)
return
tm
->
tm_gmtoff
;
#elif defined(HAVE_INT_TIMEZONE)
...
...
@@ -113,12 +125,15 @@ static int get_timezone_offset(struct tm *tm) {
#ifdef WIN32
#define TZABBREV(tz) win32_get_timezone_abbrev(tz)
static
char
*
win32_get_timezone_abbrev
(
char
*
tz
)
{
static
char
w32tzabbr
[
TZ_STRLEN_MAX
+
1
];
static
char
*
win32_get_timezone_abbrev
(
char
*
tz
)
{
static
char
w32tzabbr
[
TZ_STRLEN_MAX
+
1
];
int
l
=
0
;
char
*
c
;
for
(
c
=
tz
;
*
c
;
c
++
)
{
for
(
c
=
tz
;
*
c
;
c
++
)
{
if
(
isupper
(
*
c
))
w32tzabbr
[
l
++
]
=
*
c
;
}
...
...
@@ -140,37 +155,40 @@ static char *win32_get_timezone_abbrev(char *tz) {
static
char
*
identify_system_timezone
(
void
)
{
static
char
__tzbuf
[
TZ_STRLEN_MAX
+
1
];
bool
std_found
=
false
,
dst_found
=
false
;
static
char
__tzbuf
[
TZ_STRLEN_MAX
+
1
];
bool
std_found
=
false
,
dst_found
=
false
;
time_t
tnow
=
time
(
NULL
);
time_t
t
;
struct
tztry
tt
;
char
cbuf
[
TZ_STRLEN_MAX
+
1
];
char
cbuf
[
TZ_STRLEN_MAX
+
1
];
/* Initialize OS timezone library */
tzset
();
memset
(
&
tt
,
0
,
sizeof
(
tt
));
for
(
t
=
tnow
;
t
<
tnow
+
T_YEAR
;
t
+=
T_MONTH
)
{
for
(
t
=
tnow
;
t
<
tnow
+
T_YEAR
;
t
+=
T_MONTH
)
{
struct
tm
*
tm
=
localtime
(
&
t
);
if
(
tm
->
tm_isdst
==
0
&&
!
std_found
)
{
if
(
tm
->
tm_isdst
==
0
&&
!
std_found
)
{
/* Standard time */
memcpy
(
&
tt
.
std_tm
,
tm
,
sizeof
(
struct
tm
));
memset
(
cbuf
,
0
,
sizeof
(
cbuf
));
strftime
(
cbuf
,
sizeof
(
cbuf
)
-
1
,
"%Z"
,
tm
);
/* zone abbr */
memset
(
cbuf
,
0
,
sizeof
(
cbuf
));
strftime
(
cbuf
,
sizeof
(
cbuf
)
-
1
,
"%Z"
,
tm
);
/* zone abbr */
strcpy
(
tt
.
std_time
,
TZABBREV
(
cbuf
));
tt
.
std_ofs
=
get_timezone_offset
(
tm
);
tt
.
std_t
=
t
;
std_found
=
true
;
}
else
if
(
tm
->
tm_isdst
==
1
&&
!
dst_found
)
{
else
if
(
tm
->
tm_isdst
==
1
&&
!
dst_found
)
{
/* Daylight time */
memcpy
(
&
tt
.
dst_tm
,
tm
,
sizeof
(
struct
tm
));
memset
(
cbuf
,
0
,
sizeof
(
cbuf
));
strftime
(
cbuf
,
sizeof
(
cbuf
)
-
1
,
"%Z"
,
tm
);
/* zone abbr */
memset
(
cbuf
,
0
,
sizeof
(
cbuf
));
strftime
(
cbuf
,
sizeof
(
cbuf
)
-
1
,
"%Z"
,
tm
);
/* zone abbr */
strcpy
(
tt
.
dst_time
,
TZABBREV
(
cbuf
));
tt
.
dst_ofs
=
get_timezone_offset
(
tm
);
tt
.
dst_t
=
t
;
...
...
@@ -189,20 +207,21 @@ identify_system_timezone(void)
return
NULL
;
/* go to GMT */
}
if
(
dst_found
)
{
if
(
dst_found
)
{
/* Try STD<ofs>DST */
sprintf
(
__tzbuf
,
"%s%d%s"
,
tt
.
std_time
,
-
tt
.
std_ofs
/
3600
,
tt
.
dst_time
);
sprintf
(
__tzbuf
,
"%s%d%s"
,
tt
.
std_time
,
-
tt
.
std_ofs
/
3600
,
tt
.
dst_time
);
if
(
try_timezone
(
__tzbuf
,
&
tt
,
dst_found
))
return
__tzbuf
;
}
/* Try just the STD timezone */
strcpy
(
__tzbuf
,
tt
.
std_time
);
strcpy
(
__tzbuf
,
tt
.
std_time
);
if
(
try_timezone
(
__tzbuf
,
&
tt
,
dst_found
))
return
__tzbuf
;
/* Did not find the timezone. Fallback to try a GMT zone. */
sprintf
(
__tzbuf
,
"Etc/GMT%s%d"
,
(
-
tt
.
std_ofs
<
0
)
?
"+"
:
""
,
tt
.
std_ofs
/
3600
);
sprintf
(
__tzbuf
,
"Etc/GMT%s%d"
,
(
-
tt
.
std_ofs
<
0
)
?
"+"
:
""
,
tt
.
std_ofs
/
3600
);
ereport
(
LOG
,
(
errmsg
(
"could not recognize system timezone, defaulting to
\"
%s
\"
"
,
__tzbuf
),
...
...
@@ -280,9 +299,12 @@ select_default_timezone(void)
* This is called after initial loading of postgresql.conf. If no TimeZone
* setting was found therein, we try to derive one from the environment.
*/
void
pg_timezone_initialize
(
void
)
{
void
pg_timezone_initialize
(
void
)
{
/* Do we need to try to figure the timezone? */
if
(
strcmp
(
GetConfigOption
(
"timezone"
),
"UNKNOWN"
)
==
0
)
{
if
(
strcmp
(
GetConfigOption
(
"timezone"
),
"UNKNOWN"
)
==
0
)
{
const
char
*
def_tz
;
/* Select setting */
...
...
src/timezone/pgtz.h
View file @
0a19fb42
...
...
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.h,v 1.
7 2004/05/21 05:08:06 tgl
Exp $
* $PostgreSQL: pgsql/src/timezone/pgtz.h,v 1.
8 2004/05/21 12:30:25 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
src/timezone/private.h
View file @
0a19fb42
...
...
@@ -52,21 +52,22 @@
*/
#ifndef remove
extern
int
unlink
(
const
char
*
filename
);
extern
int
unlink
(
const
char
*
filename
);
#define remove unlink
#endif
/* !defined remove */
/*
* Private function declarations.
*/
extern
char
*
icalloc
(
int
nelem
,
int
elsize
);
extern
char
*
icatalloc
(
char
*
old
,
const
char
*
new
);
extern
char
*
icpyalloc
(
const
char
*
string
);
extern
char
*
imalloc
(
int
n
);
extern
void
*
irealloc
(
void
*
pointer
,
int
size
);
extern
void
icfree
(
char
*
pointer
);
extern
void
ifree
(
char
*
pointer
);
extern
char
*
scheck
(
const
char
*
string
,
const
char
*
format
);
extern
char
*
icalloc
(
int
nelem
,
int
elsize
);
extern
char
*
icatalloc
(
char
*
old
,
const
char
*
new
);
extern
char
*
icpyalloc
(
const
char
*
string
);
extern
char
*
imalloc
(
int
n
);
extern
void
*
irealloc
(
void
*
pointer
,
int
size
);
extern
void
icfree
(
char
*
pointer
);
extern
void
ifree
(
char
*
pointer
);
extern
char
*
scheck
(
const
char
*
string
,
const
char
*
format
);
/*
...
...
src/timezone/scheck.c
View file @
0a19fb42
...
...
@@ -3,13 +3,14 @@
#include "private.h"
char
*
scheck
(
const
char
*
string
,
const
char
*
format
)
char
*
scheck
(
const
char
*
string
,
const
char
*
format
)
{
register
char
*
fbuf
;
register
const
char
*
fp
;
register
char
*
tp
;
register
char
*
fbuf
;
register
const
char
*
fp
;
register
char
*
tp
;
register
int
c
;
register
char
*
result
;
register
char
*
result
;
char
dummy
;
static
char
nada
;
...
...
@@ -21,10 +22,12 @@ char *scheck(const char *string, const char *format)
return
result
;
fp
=
format
;
tp
=
fbuf
;
while
((
*
tp
++
=
c
=
*
fp
++
)
!=
'\0'
)
{
while
((
*
tp
++
=
c
=
*
fp
++
)
!=
'\0'
)
{
if
(
c
!=
'%'
)
continue
;
if
(
*
fp
==
'%'
)
{
if
(
*
fp
==
'%'
)
{
*
tp
++
=
*
fp
++
;
continue
;
}
...
...
@@ -36,7 +39,8 @@ char *scheck(const char *string, const char *format)
if
(
*
fp
==
'l'
||
*
fp
==
'h'
)
*
tp
++
=
*
fp
++
;
else
if
(
*
fp
==
'['
)
do
*
tp
++
=
*
fp
++
;
do
*
tp
++
=
*
fp
++
;
while
(
*
fp
!=
'\0'
&&
*
fp
!=
']'
);
if
((
*
tp
++
=
*
fp
++
)
==
'\0'
)
break
;
...
...
src/timezone/strftime.c
View file @
0a19fb42
...
...
@@ -25,17 +25,18 @@
#include "tzfile.h"
struct
lc_time_T
{
const
char
*
mon
[
MONSPERYEAR
];
const
char
*
month
[
MONSPERYEAR
];
const
char
*
wday
[
DAYSPERWEEK
];
const
char
*
weekday
[
DAYSPERWEEK
];
const
char
*
X_fmt
;
const
char
*
x_fmt
;
const
char
*
c_fmt
;
const
char
*
am
;
const
char
*
pm
;
const
char
*
date_fmt
;
struct
lc_time_T
{
const
char
*
mon
[
MONSPERYEAR
];
const
char
*
month
[
MONSPERYEAR
];
const
char
*
wday
[
DAYSPERWEEK
];
const
char
*
weekday
[
DAYSPERWEEK
];
const
char
*
X_fmt
;
const
char
*
x_fmt
;
const
char
*
c_fmt
;
const
char
*
am
;
const
char
*
pm
;
const
char
*
date_fmt
;
};
#define Locale (&C_time_locale)
...
...
@@ -59,20 +60,15 @@ static const struct lc_time_T C_time_locale = {
"%H:%M:%S"
,
/*
** x_fmt
** C99 requires this format.
** Using just numbers (as here) makes Quakers happier;
** it's also compatible with SVR4.
* * x_fmt * C99 requires this format. * Using just numbers (as here)
* makes Quakers happier; * it's also compatible with SVR4.
*/
"%m/%d/%y"
,
/*
** c_fmt
** C99 requires this format.
** Previously this code used "%D %X", but we now conform to C99.
** Note that
** "%a %b %d %H:%M:%S %Y"
** is used by Solaris 2.3.
* * c_fmt * C99 requires this format. * Previously this code used "%D
* %X", but we now conform to C99. * Note that * "%a %b %d
* %H:%M:%S %Y" * is used by Solaris 2.3.
*/
"%a %b %e %T %Y"
,
...
...
@@ -86,9 +82,9 @@ static const struct lc_time_T C_time_locale = {
"%a %b %e %H:%M:%S %Z %Y"
};
static
char
*
_add
(
const
char
*
,
char
*
,
const
char
*
);
static
char
*
_conv
(
int
,
const
char
*
,
char
*
,
const
char
*
);
static
char
*
_fmt
(
const
char
*
,
const
struct
pg_tm
*
,
char
*
,
const
char
*
,
int
*
);
static
char
*
_add
(
const
char
*
,
char
*
,
const
char
*
);
static
char
*
_conv
(
int
,
const
char
*
,
char
*
,
const
char
*
);
static
char
*
_fmt
(
const
char
*
,
const
struct
pg_tm
*
,
char
*
,
const
char
*
,
int
*
);
#define IN_NONE 0
#define IN_SOME 1
...
...
@@ -96,9 +92,10 @@ static char * _fmt (const char *, const struct pg_tm *, char *, const char *, in
#define IN_ALL 3
size_t
pg_strftime
(
char
*
s
,
size_t
maxsize
,
const
char
*
format
,
const
struct
pg_tm
*
t
)
size_t
pg_strftime
(
char
*
s
,
size_t
maxsize
,
const
char
*
format
,
const
struct
pg_tm
*
t
)
{
char
*
p
;
char
*
p
;
int
warn
;
warn
=
IN_NONE
;
...
...
@@ -109,12 +106,16 @@ size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_
return
p
-
s
;
}
static
char
*
_fmt
(
const
char
*
format
,
const
struct
pg_tm
*
t
,
char
*
pt
,
const
char
*
ptlim
,
int
*
warnp
)
static
char
*
_fmt
(
const
char
*
format
,
const
struct
pg_tm
*
t
,
char
*
pt
,
const
char
*
ptlim
,
int
*
warnp
)
{
for
(
;
*
format
;
++
format
)
{
if
(
*
format
==
'%'
)
{
label:
switch
(
*++
format
)
{
for
(;
*
format
;
++
format
)
{
if
(
*
format
==
'%'
)
{
label:
switch
(
*++
format
)
{
case
'\0'
:
--
format
;
break
;
...
...
@@ -144,12 +145,11 @@ label:
pt
,
ptlim
);
continue
;
case
'C'
:
/*
** %C used to do a...
** _fmt("%a %b %e %X %Y", t);
** ...whereas now POSIX 1003.2 calls for
** something completely different.
** (ado, 1993-05-24)
* * %C used to do a... * _fmt("%a %b %e %X %Y", t); *
* ...whereas now POSIX 1003.2 calls for * something
* completely different. * (ado, 1993-05-24)
*/
pt
=
_conv
((
t
->
tm_year
+
TM_YEAR_BASE
)
/
100
,
"%02d"
,
pt
,
ptlim
);
...
...
@@ -173,14 +173,12 @@ label:
continue
;
case
'E'
:
case
'O'
:
/*
** C99 locale modifiers.
** The sequences
** %Ec %EC %Ex %EX %Ey %EY
** %Od %oe %OH %OI %Om %OM
** %OS %Ou %OU %OV %Ow %OW %Oy
** are supposed to provide alternate
** representations.
* * C99 locale modifiers. * The sequences * %Ec %EC
* %Ex %EX %Ey %EY * %Od %oe %OH %OI %Om %OM * %OS
* %Ou %OU %OV %Ow %OW %Oy * are supposed to provide
* alternate * representations.
*/
goto
label
;
case
'e'
:
...
...
@@ -201,35 +199,34 @@ label:
pt
=
_conv
(
t
->
tm_yday
+
1
,
"%03d"
,
pt
,
ptlim
);
continue
;
case
'k'
:
/*
** This used to be...
** _conv(t->tm_hour % 12 ?
** t->tm_hour % 12 : 12, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbins'
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
* * This used to be... * _conv(t->tm_hour % 12 ? *
* t->tm_hour % 12 : 12, 2, ' '); * ...and has been
* changed to the below to * match SunOS 4.1.1 and
* Arnold Robbins' * strftime version 3.0. That is,
* "%k" and * "%l" have been swapped. * (ado,
* 1993-05-24)
*/
pt
=
_conv
(
t
->
tm_hour
,
"%2d"
,
pt
,
ptlim
);
continue
;
#ifdef KITCHEN_SINK
case
'K'
:
/*
*
* After all this time, still unclaimed!
*
* After all this time, still unclaimed!
*/
pt
=
_add
(
"kitchen sink"
,
pt
,
ptlim
);
continue
;
#endif
/* defined KITCHEN_SINK */
case
'l'
:
/*
** This used to be...
** _conv(t->tm_hour, 2, ' ');
** ...and has been changed to the below to
** match SunOS 4.1.1 and Arnold Robbin's
** strftime version 3.0. That is, "%k" and
** "%l" have been swapped.
** (ado, 1993-05-24)
* * This used to be... * _conv(t->tm_hour, 2, ' '); *
* ...and has been changed to the below to * match
* SunOS 4.1.1 and Arnold Robbin's * strftime version
* 3.0. That is, "%k" and * "%l" have been swapped. *
* (ado, 1993-05-24)
*/
pt
=
_conv
((
t
->
tm_hour
%
12
)
?
(
t
->
tm_hour
%
12
)
:
12
,
...
...
@@ -262,7 +259,7 @@ label:
case
's'
:
{
struct
pg_tm
tm
;
char
buf
[
INT_STRLEN_MAXIMUM
(
time_t
)
+
1
];
char
buf
[
INT_STRLEN_MAXIMUM
(
time_t
)
+
1
];
time_t
mkt
;
tm
=
*
t
;
...
...
@@ -286,11 +283,11 @@ label:
"%02d"
,
pt
,
ptlim
);
continue
;
case
'u'
:
/*
** From Arnold Robbins' strftime version 3.0:
** "ISO 8601: Weekday as a decimal number
** [1 (Monday) - 7]"
** (ado, 1993-05-24)
* * From Arnold Robbins' strftime version 3.0: * "ISO
* 8601: Weekday as a decimal number * [1 (Monday) -
* 7]" * (ado, 1993-05-24)
*/
pt
=
_conv
((
t
->
tm_wday
==
0
)
?
DAYSPERWEEK
:
t
->
tm_wday
,
...
...
@@ -326,7 +323,8 @@ label:
year
=
t
->
tm_year
+
TM_YEAR_BASE
;
yday
=
t
->
tm_yday
;
wday
=
t
->
tm_wday
;
for
(
;
;
)
{
for
(;;)
{
int
len
;
int
bot
;
int
top
;
...
...
@@ -334,27 +332,31 @@ label:
len
=
isleap
(
year
)
?
DAYSPERLYEAR
:
DAYSPERNYEAR
;
/*
** What yday (-3 ... 3) does
** the ISO year
begin on?
* * What yday (-3 ... 3) does * the ISO year
*
begin on?
*/
bot
=
((
yday
+
11
-
wday
)
%
DAYSPERWEEK
)
-
3
;
/*
** What yday does the NEXT
** ISO year begin
on?
* * What yday does the NEXT * ISO year begin
*
on?
*/
top
=
bot
-
(
len
%
DAYSPERWEEK
);
if
(
top
<
-
3
)
top
+=
DAYSPERWEEK
;
top
+=
len
;
if
(
yday
>=
top
)
{
if
(
yday
>=
top
)
{
++
year
;
w
=
1
;
break
;
}
if
(
yday
>=
bot
)
{
if
(
yday
>=
bot
)
{
w
=
1
+
((
yday
-
bot
)
/
DAYSPERWEEK
);
break
;
...
...
@@ -367,19 +369,22 @@ label:
if
(
*
format
==
'V'
)
pt
=
_conv
(
w
,
"%02d"
,
pt
,
ptlim
);
else
if
(
*
format
==
'g'
)
{
else
if
(
*
format
==
'g'
)
{
*
warnp
=
IN_ALL
;
pt
=
_conv
(
year
%
100
,
"%02d"
,
pt
,
ptlim
);
}
else
pt
=
_conv
(
year
,
"%04d"
,
}
else
pt
=
_conv
(
year
,
"%04d"
,
pt
,
ptlim
);
}
continue
;
case
'v'
:
/*
** From Arnold Robbins' strftime version 3.0:
** "date as dd-bbb-YYYY"
** (ado, 1993-05-24)
* * From Arnold Robbins' strftime version 3.0: *
* "date as dd-bbb-YYYY" * (ado, 1993-05-24)
*/
pt
=
_fmt
(
"%e-%b-%Y"
,
t
,
pt
,
ptlim
,
warnp
);
continue
;
...
...
@@ -419,27 +424,30 @@ label:
case
'Z'
:
if
(
t
->
tm_zone
!=
NULL
)
pt
=
_add
(
t
->
tm_zone
,
pt
,
ptlim
);
/*
** C99 says that %Z must be replaced by the
** empty string if the time zone is not
** determinable.
* * C99 says that %Z must be replaced by the * empty
* string if the time zone is not * determinable.
*/
continue
;
case
'z'
:
{
int
diff
;
char
const
*
sign
;
char
const
*
sign
;
if
(
t
->
tm_isdst
<
0
)
continue
;
diff
=
t
->
tm_gmtoff
;
if
(
diff
<
0
)
{
if
(
diff
<
0
)
{
sign
=
"-"
;
diff
=
-
diff
;
}
else
sign
=
"+"
;
}
else
sign
=
"+"
;
pt
=
_add
(
sign
,
pt
,
ptlim
);
diff
/=
60
;
pt
=
_conv
((
diff
/
60
)
*
100
+
diff
%
60
,
pt
=
_conv
((
diff
/
60
)
*
100
+
diff
%
60
,
"%04d"
,
pt
,
ptlim
);
}
continue
;
...
...
@@ -448,10 +456,11 @@ label:
warnp
);
continue
;
case
'%'
:
/*
** X311J/88-090 (4.12.3.5): if conversion char is
** undefined, behavior is undefined. Print out the
*
* character itself as printf(3) also does.
* * X311J/88-090 (4.12.3.5): if conversion char is *
* undefined, behavior is undefined. Print out the *
* character itself as printf(3) also does.
*/
default:
break
;
...
...
@@ -464,15 +473,17 @@ label:
return
pt
;
}
static
char
*
_conv
(
const
int
n
,
const
char
*
format
,
char
*
pt
,
const
char
*
ptlim
)
static
char
*
_conv
(
const
int
n
,
const
char
*
format
,
char
*
pt
,
const
char
*
ptlim
)
{
char
buf
[
INT_STRLEN_MAXIMUM
(
int
)
+
1
];
char
buf
[
INT_STRLEN_MAXIMUM
(
int
)
+
1
];
(
void
)
sprintf
(
buf
,
format
,
n
);
return
_add
(
buf
,
pt
,
ptlim
);
}
static
char
*
_add
(
const
char
*
str
,
char
*
pt
,
const
char
*
ptlim
)
static
char
*
_add
(
const
char
*
str
,
char
*
pt
,
const
char
*
ptlim
)
{
while
(
pt
<
ptlim
&&
(
*
pt
=
*
str
++
)
!=
'\0'
)
++
pt
;
...
...
src/timezone/tzfile.h
View file @
0a19fb42
...
...
@@ -28,11 +28,14 @@
#define TZ_MAGIC "TZif"
struct
tzhead
{
struct
tzhead
{
char
tzh_magic
[
4
];
/* TZ_MAGIC */
char
tzh_reserved
[
16
];
/* reserved for future use */
char
tzh_ttisgmtcnt
[
4
];
/* coded number of trans. time flags */
char
tzh_ttisstdcnt
[
4
];
/* coded number of trans. time flags */
char
tzh_ttisgmtcnt
[
4
];
/* coded number of trans. time
* flags */
char
tzh_ttisstdcnt
[
4
];
/* coded number of trans. time
* flags */
char
tzh_leapcnt
[
4
];
/* coded number of leap seconds */
char
tzh_timecnt
[
4
];
/* coded number of transition times */
char
tzh_typecnt
[
4
];
/* coded number of local time types */
...
...
@@ -77,12 +80,15 @@ struct tzhead {
*/
#define TZ_MAX_TIMES 370
#define TZ_MAX_TYPES 256
/* Limited by what (unsigned char)'s can hold */
#define TZ_MAX_TYPES 256
/* Limited by what (unsigned char)'s can
* hold */
#define TZ_MAX_CHARS 50
/* Maximum number of abbreviation characters */
#define TZ_MAX_CHARS 50
/* Maximum number of abbreviation
* characters */
/* (limited by what unsigned chars can hold) */
#define TZ_MAX_LEAPS 50
/* Maximum number of leap second corrections */
#define TZ_MAX_LEAPS 50
/* Maximum number of leap second
* corrections */
#define SECSPERMIN 60
#define MINSPERHOUR 60
...
...
src/timezone/zic.c
View file @
0a19fb42
...
...
@@ -38,14 +38,15 @@ static char elsieid[] = "@(#)zic.c 7.115";
#define isascii(x) 1
#endif
struct
rule
{
const
char
*
r_filename
;
struct
rule
{
const
char
*
r_filename
;
int
r_linenum
;
const
char
*
r_name
;
const
char
*
r_name
;
int
r_loyear
;
/* for example, 1986 */
int
r_hiyear
;
/* for example, 1986 */
const
char
*
r_yrtype
;
const
char
*
r_yrtype
;
int
r_month
;
/* 0..11 */
...
...
@@ -59,7 +60,7 @@ struct rule {
int
r_todisgmt
;
/* above is GMT if TRUE */
/* or local time if FALSE */
long
r_stdoff
;
/* offset from standard time */
const
char
*
r_abbrvar
;
/* variable part of abbreviation */
const
char
*
r_abbrvar
;
/* variable part of abbreviation */
int
r_todo
;
/* a rule to do (used in outzone) */
time_t
r_temp
;
/* used in outzone */
...
...
@@ -73,79 +74,80 @@ struct rule {
#define DC_DOWGEQ 1
/* 1..31 */
/* 0..6 (Sun..Sat) */
#define DC_DOWLEQ 2
/* 1..31 */
/* 0..6 (Sun..Sat) */
struct
zone
{
const
char
*
z_filename
;
struct
zone
{
const
char
*
z_filename
;
int
z_linenum
;
const
char
*
z_name
;
const
char
*
z_name
;
long
z_gmtoff
;
const
char
*
z_rule
;
const
char
*
z_format
;
const
char
*
z_rule
;
const
char
*
z_format
;
long
z_stdoff
;
struct
rule
*
z_rules
;
struct
rule
*
z_rules
;
int
z_nrules
;
struct
rule
z_untilrule
;
time_t
z_untiltime
;
};
extern
int
link
(
const
char
*
fromname
,
const
char
*
toname
);
static
void
addtt
(
time_t
starttime
,
int
type
);
static
int
addtype
(
long
gmtoff
,
const
char
*
abbr
,
int
isdst
,
extern
int
link
(
const
char
*
fromname
,
const
char
*
toname
);
static
void
addtt
(
time_t
starttime
,
int
type
);
static
int
addtype
(
long
gmtoff
,
const
char
*
abbr
,
int
isdst
,
int
ttisstd
,
int
ttisgmt
);
static
void
leapadd
(
time_t
t
,
int
positive
,
int
rolling
,
int
count
);
static
void
adjleap
(
void
);
static
void
associate
(
void
);
static
int
ciequal
(
const
char
*
ap
,
const
char
*
bp
);
static
void
convert
(
long
val
,
char
*
buf
);
static
void
dolink
(
const
char
*
fromfile
,
const
char
*
tofile
);
static
void
doabbr
(
char
*
abbr
,
const
char
*
format
,
const
char
*
letters
,
int
isdst
);
static
void
eat
(
const
char
*
name
,
int
num
);
static
void
eats
(
const
char
*
name
,
int
num
,
const
char
*
rname
,
int
rnum
);
static
long
eitol
(
int
i
);
static
void
error
(
const
char
*
message
);
static
char
**
getfields
(
char
*
buf
);
static
long
gethms
(
const
char
*
string
,
const
char
*
errstrng
,
static
void
leapadd
(
time_t
t
,
int
positive
,
int
rolling
,
int
count
);
static
void
adjleap
(
void
);
static
void
associate
(
void
);
static
int
ciequal
(
const
char
*
ap
,
const
char
*
bp
);
static
void
convert
(
long
val
,
char
*
buf
);
static
void
dolink
(
const
char
*
fromfile
,
const
char
*
tofile
);
static
void
doabbr
(
char
*
abbr
,
const
char
*
format
,
const
char
*
letters
,
int
isdst
);
static
void
eat
(
const
char
*
name
,
int
num
);
static
void
eats
(
const
char
*
name
,
int
num
,
const
char
*
rname
,
int
rnum
);
static
long
eitol
(
int
i
);
static
void
error
(
const
char
*
message
);
static
char
**
getfields
(
char
*
buf
);
static
long
gethms
(
const
char
*
string
,
const
char
*
errstrng
,
int
signable
);
static
void
infile
(
const
char
*
filename
);
static
void
inleap
(
char
**
fields
,
int
nfields
);
static
void
inlink
(
char
**
fields
,
int
nfields
);
static
void
inrule
(
char
**
fields
,
int
nfields
);
static
int
inzcont
(
char
**
fields
,
int
nfields
);
static
int
inzone
(
char
**
fields
,
int
nfields
);
static
int
inzsub
(
char
**
fields
,
int
nfields
,
int
iscont
);
static
int
itsabbr
(
const
char
*
abbr
,
const
char
*
word
);
static
int
itsdir
(
const
char
*
name
);
static
int
lowerit
(
int
c
);
static
char
*
memcheck
(
char
*
tocheck
);
static
int
mkdirs
(
char
*
filename
);
static
void
newabbr
(
const
char
*
abbr
);
static
long
oadd
(
long
t1
,
long
t2
);
static
void
outzone
(
const
struct
zone
*
zp
,
int
ntzones
);
static
void
puttzcode
(
long
code
,
FILE
*
fp
);
static
int
rcomp
(
const
void
*
leftp
,
const
void
*
rightp
);
static
time_t
rpytime
(
const
struct
rule
*
rp
,
int
wantedy
);
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
setboundaries
(
void
);
static
time_t
tadd
(
time_t
t1
,
long
t2
);
static
void
usage
(
void
);
static
void
writezone
(
const
char
*
name
);
static
int
yearistype
(
int
year
,
const
char
*
type
);
static
void
infile
(
const
char
*
filename
);
static
void
inleap
(
char
**
fields
,
int
nfields
);
static
void
inlink
(
char
**
fields
,
int
nfields
);
static
void
inrule
(
char
**
fields
,
int
nfields
);
static
int
inzcont
(
char
**
fields
,
int
nfields
);
static
int
inzone
(
char
**
fields
,
int
nfields
);
static
int
inzsub
(
char
**
fields
,
int
nfields
,
int
iscont
);
static
int
itsabbr
(
const
char
*
abbr
,
const
char
*
word
);
static
int
itsdir
(
const
char
*
name
);
static
int
lowerit
(
int
c
);
static
char
*
memcheck
(
char
*
tocheck
);
static
int
mkdirs
(
char
*
filename
);
static
void
newabbr
(
const
char
*
abbr
);
static
long
oadd
(
long
t1
,
long
t2
);
static
void
outzone
(
const
struct
zone
*
zp
,
int
ntzones
);
static
void
puttzcode
(
long
code
,
FILE
*
fp
);
static
int
rcomp
(
const
void
*
leftp
,
const
void
*
rightp
);
static
time_t
rpytime
(
const
struct
rule
*
rp
,
int
wantedy
);
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
setboundaries
(
void
);
static
time_t
tadd
(
time_t
t1
,
long
t2
);
static
void
usage
(
void
);
static
void
writezone
(
const
char
*
name
);
static
int
yearistype
(
int
year
,
const
char
*
type
);
#ifndef HAVE_STRERROR
static
char
*
strerror
(
int
);
static
char
*
strerror
(
int
);
#endif
static
int
charcnt
;
static
int
errors
;
static
const
char
*
filename
;
static
const
char
*
filename
;
static
int
leapcnt
;
static
int
linenum
;
static
time_t
max_time
;
...
...
@@ -155,9 +157,9 @@ static time_t min_time;
static
int
min_year
;
static
int
min_year_representable
;
static
int
noise
;
static
const
char
*
rfilename
;
static
const
char
*
rfilename
;
static
int
rlinenum
;
static
const
char
*
progname
;
static
const
char
*
progname
;
static
int
timecnt
;
static
int
typecnt
;
...
...
@@ -242,105 +244,108 @@ static int typecnt;
#define YR_MAXIMUM 1
#define YR_ONLY 2
static
struct
rule
*
rules
;
static
struct
rule
*
rules
;
static
int
nrules
;
/* number of rules */
static
struct
zone
*
zones
;
static
struct
zone
*
zones
;
static
int
nzones
;
/* number of zones */
struct
link
{
const
char
*
l_filename
;
struct
link
{
const
char
*
l_filename
;
int
l_linenum
;
const
char
*
l_from
;
const
char
*
l_to
;
const
char
*
l_from
;
const
char
*
l_to
;
};
static
struct
link
*
links
;
static
struct
link
*
links
;
static
int
nlinks
;
struct
lookup
{
const
char
*
l_word
;
struct
lookup
{
const
char
*
l_word
;
const
int
l_value
;
};
static
struct
lookup
const
*
byword
(
const
char
*
string
,
static
struct
lookup
const
*
byword
(
const
char
*
string
,
const
struct
lookup
*
lp
);
static
struct
lookup
const
line_codes
[]
=
{
{
"Rule"
,
LC_RULE
},
{
"Zone"
,
LC_ZONE
},
{
"Link"
,
LC_LINK
},
{
"Leap"
,
LC_LEAP
},
{
NULL
,
0
}
{
"Rule"
,
LC_RULE
},
{
"Zone"
,
LC_ZONE
},
{
"Link"
,
LC_LINK
},
{
"Leap"
,
LC_LEAP
},
{
NULL
,
0
}
};
static
struct
lookup
const
mon_names
[]
=
{
{
"January"
,
TM_JANUARY
},
{
"February"
,
TM_FEBRUARY
},
{
"March"
,
TM_MARCH
},
{
"April"
,
TM_APRIL
},
{
"May"
,
TM_MAY
},
{
"June"
,
TM_JUNE
},
{
"July"
,
TM_JULY
},
{
"August"
,
TM_AUGUST
},
{
"September"
,
TM_SEPTEMBER
},
{
"October"
,
TM_OCTOBER
},
{
"November"
,
TM_NOVEMBER
},
{
"December"
,
TM_DECEMBER
},
{
NULL
,
0
}
{
"January"
,
TM_JANUARY
},
{
"February"
,
TM_FEBRUARY
},
{
"March"
,
TM_MARCH
},
{
"April"
,
TM_APRIL
},
{
"May"
,
TM_MAY
},
{
"June"
,
TM_JUNE
},
{
"July"
,
TM_JULY
},
{
"August"
,
TM_AUGUST
},
{
"September"
,
TM_SEPTEMBER
},
{
"October"
,
TM_OCTOBER
},
{
"November"
,
TM_NOVEMBER
},
{
"December"
,
TM_DECEMBER
},
{
NULL
,
0
}
};
static
struct
lookup
const
wday_names
[]
=
{
{
"Sunday"
,
TM_SUNDAY
},
{
"Monday"
,
TM_MONDAY
},
{
"Tuesday"
,
TM_TUESDAY
},
{
"Wednesday"
,
TM_WEDNESDAY
},
{
"Thursday"
,
TM_THURSDAY
},
{
"Friday"
,
TM_FRIDAY
},
{
"Saturday"
,
TM_SATURDAY
},
{
NULL
,
0
}
{
"Sunday"
,
TM_SUNDAY
},
{
"Monday"
,
TM_MONDAY
},
{
"Tuesday"
,
TM_TUESDAY
},
{
"Wednesday"
,
TM_WEDNESDAY
},
{
"Thursday"
,
TM_THURSDAY
},
{
"Friday"
,
TM_FRIDAY
},
{
"Saturday"
,
TM_SATURDAY
},
{
NULL
,
0
}
};
static
struct
lookup
const
lasts
[]
=
{
{
"last-Sunday"
,
TM_SUNDAY
},
{
"last-Monday"
,
TM_MONDAY
},
{
"last-Tuesday"
,
TM_TUESDAY
},
{
"last-Wednesday"
,
TM_WEDNESDAY
},
{
"last-Thursday"
,
TM_THURSDAY
},
{
"last-Friday"
,
TM_FRIDAY
},
{
"last-Saturday"
,
TM_SATURDAY
},
{
NULL
,
0
}
{
"last-Sunday"
,
TM_SUNDAY
},
{
"last-Monday"
,
TM_MONDAY
},
{
"last-Tuesday"
,
TM_TUESDAY
},
{
"last-Wednesday"
,
TM_WEDNESDAY
},
{
"last-Thursday"
,
TM_THURSDAY
},
{
"last-Friday"
,
TM_FRIDAY
},
{
"last-Saturday"
,
TM_SATURDAY
},
{
NULL
,
0
}
};
static
struct
lookup
const
begin_years
[]
=
{
{
"minimum"
,
YR_MINIMUM
},
{
"maximum"
,
YR_MAXIMUM
},
{
NULL
,
0
}
{
"minimum"
,
YR_MINIMUM
},
{
"maximum"
,
YR_MAXIMUM
},
{
NULL
,
0
}
};
static
struct
lookup
const
end_years
[]
=
{
{
"minimum"
,
YR_MINIMUM
},
{
"maximum"
,
YR_MAXIMUM
},
{
"only"
,
YR_ONLY
},
{
NULL
,
0
}
{
"minimum"
,
YR_MINIMUM
},
{
"maximum"
,
YR_MAXIMUM
},
{
"only"
,
YR_ONLY
},
{
NULL
,
0
}
};
static
struct
lookup
const
leap_types
[]
=
{
{
"Rolling"
,
TRUE
},
{
"Stationary"
,
FALSE
},
{
NULL
,
0
}
{
"Rolling"
,
TRUE
},
{
"Stationary"
,
FALSE
},
{
NULL
,
0
}
};
static
const
int
len_months
[
2
][
MONSPERYEAR
]
=
{
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
};
static
const
int
len_years
[
2
]
=
{
DAYSPERNYEAR
,
DAYSPERLYEAR
};
static
struct
attype
{
static
struct
attype
{
time_t
at
;
unsigned
char
type
;
}
attypes
[
TZ_MAX_TIMES
];
...
...
@@ -360,9 +365,10 @@ static char roll[TZ_MAX_LEAPS];
static
char
*
memcheck
(
ptr
)
char
*
const
ptr
;
char
*
const
ptr
;
{
if
(
ptr
==
NULL
)
{
if
(
ptr
==
NULL
)
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
_
(
"%s: Memory exhausted: %s
\n
"
),
...
...
@@ -382,9 +388,10 @@ char * const ptr;
*/
#ifndef HAVE_STRERROR
static
char
*
strerror
(
int
errnum
)
static
char
*
strerror
(
int
errnum
)
{
extern
char
*
sys_errlist
[];
extern
char
*
sys_errlist
[];
extern
int
sys_nerr
;
return
(
errnum
>
0
&&
errnum
<=
sys_nerr
)
?
...
...
@@ -392,7 +399,8 @@ static char *strerror(int errnum)
}
#endif
static
void
eats
(
const
char
*
name
,
const
int
num
,
const
char
*
rname
,
const
int
rnum
)
static
void
eats
(
const
char
*
name
,
const
int
num
,
const
char
*
rname
,
const
int
rnum
)
{
filename
=
name
;
linenum
=
num
;
...
...
@@ -400,17 +408,18 @@ static void eats(const char *name, const int num, const char *rname, const int r
rlinenum
=
rnum
;
}
static
void
eat
(
const
char
*
name
,
const
int
num
)
static
void
eat
(
const
char
*
name
,
const
int
num
)
{
eats
(
name
,
num
,
(
char
*
)
NULL
,
-
1
);
}
static
void
error
(
const
char
*
string
)
static
void
error
(
const
char
*
string
)
{
/*
** Match the format of "cc" to allow sh users to
** zic ... 2>&1 | error -t "*" -v
** on BSD systems.
* * Match the format of "cc" to allow sh users to * zic ... 2>&1 |
* error -t "*" -v * on BSD systems.
*/
(
void
)
fprintf
(
stderr
,
_
(
"
\"
%s
\"
, line %d: %s"
),
filename
,
linenum
,
string
);
...
...
@@ -421,9 +430,10 @@ static void error(const char *string)
++
errors
;
}
static
void
warning
(
const
char
*
string
)
static
void
warning
(
const
char
*
string
)
{
char
*
cp
;
char
*
cp
;
cp
=
ecpyalloc
(
_
(
"warning: "
));
cp
=
ecatalloc
(
cp
,
string
);
...
...
@@ -432,21 +442,23 @@ static void warning(const char *string)
--
errors
;
}
static
void
usage
(
void
)
static
void
usage
(
void
)
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ]
\\\n\t
[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]
\n
"
),
progname
,
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
static
const
char
*
psxrules
;
static
const
char
*
lcltime
;
static
const
char
*
directory
;
static
const
char
*
leapsec
;
static
const
char
*
yitcommand
;
static
const
char
*
psxrules
;
static
const
char
*
lcltime
;
static
const
char
*
directory
;
static
const
char
*
leapsec
;
static
const
char
*
yitcommand
;
static
int
sflag
=
FALSE
;
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
register
int
i
;
register
int
j
;
...
...
@@ -457,20 +469,23 @@ int main(int argc, char *argv[])
#endif
/* !WIN32 */
progname
=
argv
[
0
];
for
(
i
=
1
;
i
<
argc
;
++
i
)
if
(
strcmp
(
argv
[
i
],
"--version"
)
==
0
)
{
if
(
strcmp
(
argv
[
i
],
"--version"
)
==
0
)
{
(
void
)
printf
(
"%s
\n
"
,
elsieid
);
(
void
)
exit
(
EXIT_SUCCESS
);
}
while
((
c
=
getopt
(
argc
,
argv
,
"d:l:p:L:vsy:"
))
!=
EOF
&&
c
!=
-
1
)
switch
(
c
)
{
switch
(
c
)
{
default:
usage
();
case
'd'
:
if
(
directory
==
NULL
)
directory
=
optarg
;
else
{
else
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: More than one -d option specified
\n
"
),
_
(
"%s: More than one -d option specified
\n
"
),
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -478,9 +493,10 @@ _("%s: More than one -d option specified\n"),
case
'l'
:
if
(
lcltime
==
NULL
)
lcltime
=
optarg
;
else
{
else
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: More than one -l option specified
\n
"
),
_
(
"%s: More than one -l option specified
\n
"
),
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -488,9 +504,10 @@ _("%s: More than one -l option specified\n"),
case
'p'
:
if
(
psxrules
==
NULL
)
psxrules
=
optarg
;
else
{
else
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: More than one -p option specified
\n
"
),
_
(
"%s: More than one -p option specified
\n
"
),
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -498,9 +515,10 @@ _("%s: More than one -p option specified\n"),
case
'y'
:
if
(
yitcommand
==
NULL
)
yitcommand
=
optarg
;
else
{
else
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: More than one -y option specified
\n
"
),
_
(
"%s: More than one -y option specified
\n
"
),
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -508,9 +526,10 @@ _("%s: More than one -y option specified\n"),
case
'L'
:
if
(
leapsec
==
NULL
)
leapsec
=
optarg
;
else
{
else
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: More than one -L option specified
\n
"
),
_
(
"%s: More than one -L option specified
\n
"
),
progname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -531,7 +550,8 @@ _("%s: More than one -L option specified\n"),
setboundaries
();
if
(
optind
<
argc
&&
leapsec
!=
NULL
)
{
if
(
optind
<
argc
&&
leapsec
!=
NULL
)
{
infile
(
leapsec
);
adjleap
();
}
...
...
@@ -541,58 +561,68 @@ _("%s: More than one -L option specified\n"),
if
(
errors
)
(
void
)
exit
(
EXIT_FAILURE
);
associate
();
for
(
i
=
0
;
i
<
nzones
;
i
=
j
)
{
for
(
i
=
0
;
i
<
nzones
;
i
=
j
)
{
/*
*
* Find the next non-continuation zone entry.
*
* Find the next non-continuation zone entry.
*/
for
(
j
=
i
+
1
;
j
<
nzones
&&
zones
[
j
].
z_name
==
NULL
;
++
j
)
continue
;
outzone
(
&
zones
[
i
],
j
-
i
);
}
/*
*
* Make links.
*
* Make links.
*/
for
(
i
=
0
;
i
<
nlinks
;
++
i
)
{
for
(
i
=
0
;
i
<
nlinks
;
++
i
)
{
eat
(
links
[
i
].
l_filename
,
links
[
i
].
l_linenum
);
dolink
(
links
[
i
].
l_from
,
links
[
i
].
l_to
);
}
if
(
lcltime
!=
NULL
)
{
if
(
lcltime
!=
NULL
)
{
eat
(
"command line"
,
1
);
dolink
(
lcltime
,
TZDEFAULT
);
}
if
(
psxrules
!=
NULL
)
{
if
(
psxrules
!=
NULL
)
{
eat
(
"command line"
,
1
);
dolink
(
psxrules
,
TZDEFRULES
);
}
return
(
errors
==
0
)
?
EXIT_SUCCESS
:
EXIT_FAILURE
;
}
static
void
dolink
(
const
char
*
fromfile
,
const
char
*
tofile
)
static
void
dolink
(
const
char
*
fromfile
,
const
char
*
tofile
)
{
register
char
*
fromname
;
register
char
*
toname
;
register
char
*
fromname
;
register
char
*
toname
;
if
(
fromfile
[
0
]
==
'/'
)
fromname
=
ecpyalloc
(
fromfile
);
else
{
else
{
fromname
=
ecpyalloc
(
directory
);
fromname
=
ecatalloc
(
fromname
,
"/"
);
fromname
=
ecatalloc
(
fromname
,
fromfile
);
}
if
(
tofile
[
0
]
==
'/'
)
toname
=
ecpyalloc
(
tofile
);
else
{
else
{
toname
=
ecpyalloc
(
directory
);
toname
=
ecatalloc
(
toname
,
"/"
);
toname
=
ecatalloc
(
toname
,
tofile
);
}
/*
** We get to be careful here since
** there's a fair chance of root
running us.
* * We get to be careful here since * there's a fair chance of root
*
running us.
*/
if
(
!
itsdir
(
toname
))
(
void
)
remove
(
toname
);
if
(
link
(
fromname
,
toname
)
!=
0
)
{
if
(
link
(
fromname
,
toname
)
!=
0
)
{
int
result
;
if
(
mkdirs
(
toname
)
!=
0
)
...
...
@@ -602,20 +632,23 @@ static void dolink(const char *fromfile, const char *tofile)
#ifdef HAVE_SYMLINK
if
(
result
!=
0
&&
access
(
fromname
,
F_OK
)
==
0
&&
!
itsdir
(
fromname
))
{
!
itsdir
(
fromname
))
{
const
char
*
s
=
tofile
;
register
char
*
symlinkcontents
=
NULL
;
while
((
s
=
strchr
(
s
+
1
,
'/'
))
!=
NULL
)
register
char
*
symlinkcontents
=
NULL
;
while
((
s
=
strchr
(
s
+
1
,
'/'
))
!=
NULL
)
symlinkcontents
=
ecatalloc
(
symlinkcontents
,
"../"
);
symlinkcontents
=
ecatalloc
(
symlinkcontents
,
fromfile
);
result
=
symlink
(
symlinkcontents
,
toname
);
if
(
result
==
0
)
warning
(
_
(
"hard link failed, symbolic link used"
));
warning
(
_
(
"hard link failed, symbolic link used"
));
ifree
(
symlinkcontents
);
}
#endif
if
(
result
!=
0
)
{
if
(
result
!=
0
)
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
...
...
@@ -646,15 +679,19 @@ warning(_("hard link failed, symbolic link used"));
#define MAX_BITS_IN_FILE 32
#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
static
void
setboundaries
(
void
)
static
void
setboundaries
(
void
)
{
if
(
TYPE_SIGNED
(
time_t
))
{
min_time
=
~
(
time_t
)
0
;
if
(
TYPE_SIGNED
(
time_t
))
{
min_time
=
~
(
time_t
)
0
;
min_time
<<=
TIME_T_BITS_IN_FILE
-
1
;
max_time
=
~
(
time_t
)
0
-
min_time
;
max_time
=
~
(
time_t
)
0
-
min_time
;
if
(
sflag
)
min_time
=
0
;
}
else
{
}
else
{
min_time
=
0
;
max_time
=
2
-
sflag
;
max_time
<<=
TIME_T_BITS_IN_FILE
-
1
;
...
...
@@ -666,9 +703,10 @@ static void setboundaries(void)
max_year_representable
=
max_year
;
}
static
int
itsdir
(
const
char
*
name
)
static
int
itsdir
(
const
char
*
name
)
{
register
char
*
myname
;
register
char
*
myname
;
register
int
accres
;
myname
=
ecpyalloc
(
name
);
...
...
@@ -686,23 +724,29 @@ static int itsdir(const char *name)
** Sort by rule name.
*/
static
int
rcomp
(
const
void
*
cp1
,
const
void
*
cp2
)
static
int
rcomp
(
const
void
*
cp1
,
const
void
*
cp2
)
{
return
strcmp
(((
const
struct
rule
*
)
cp1
)
->
r_name
,
((
const
struct
rule
*
)
cp2
)
->
r_name
);
}
static
void
associate
(
void
)
static
void
associate
(
void
)
{
register
struct
zone
*
zp
;
register
struct
rule
*
rp
;
register
int
base
,
out
;
register
int
i
,
j
;
if
(
nrules
!=
0
)
{
register
struct
zone
*
zp
;
register
struct
rule
*
rp
;
register
int
base
,
out
;
register
int
i
,
j
;
if
(
nrules
!=
0
)
{
(
void
)
qsort
((
void
*
)
rules
,
(
size_t
)
nrules
,
(
size_t
)
sizeof
*
rules
,
rcomp
);
for
(
i
=
0
;
i
<
nrules
-
1
;
++
i
)
{
for
(
i
=
0
;
i
<
nrules
-
1
;
++
i
)
{
if
(
strcmp
(
rules
[
i
].
r_name
,
rules
[
i
+
1
].
r_name
)
!=
0
)
continue
;
...
...
@@ -713,7 +757,8 @@ static void associate(void)
warning
(
_
(
"same rule name in multiple files"
));
eat
(
rules
[
i
+
1
].
r_filename
,
rules
[
i
+
1
].
r_linenum
);
warning
(
_
(
"same rule name in multiple files"
));
for
(
j
=
i
+
2
;
j
<
nrules
;
++
j
)
{
for
(
j
=
i
+
2
;
j
<
nrules
;
++
j
)
{
if
(
strcmp
(
rules
[
i
].
r_name
,
rules
[
j
].
r_name
)
!=
0
)
break
;
...
...
@@ -728,17 +773,20 @@ static void associate(void)
i
=
j
-
1
;
}
}
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
zp
=
&
zones
[
i
];
zp
->
z_rules
=
NULL
;
zp
->
z_nrules
=
0
;
}
for
(
base
=
0
;
base
<
nrules
;
base
=
out
)
{
for
(
base
=
0
;
base
<
nrules
;
base
=
out
)
{
rp
=
&
rules
[
base
];
for
(
out
=
base
+
1
;
out
<
nrules
;
++
out
)
if
(
strcmp
(
rp
->
r_name
,
rules
[
out
].
r_name
)
!=
0
)
break
;
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
zp
=
&
zones
[
i
];
if
(
strcmp
(
zp
->
z_rule
,
rp
->
r_name
)
!=
0
)
continue
;
...
...
@@ -746,18 +794,21 @@ static void associate(void)
zp
->
z_nrules
=
out
-
base
;
}
}
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
for
(
i
=
0
;
i
<
nzones
;
++
i
)
{
zp
=
&
zones
[
i
];
if
(
zp
->
z_nrules
==
0
)
{
if
(
zp
->
z_nrules
==
0
)
{
/*
*
* Maybe we have a local standard time offset.
*
* Maybe we have a local standard time offset.
*/
eat
(
zp
->
z_filename
,
zp
->
z_linenum
);
zp
->
z_stdoff
=
gethms
(
zp
->
z_rule
,
_
(
"unruly zone"
),
TRUE
);
/*
** Note, though, that if there's no rule,
** a '%s' in the
format is a bad thing.
* * Note, though, that if there's no rule, * a '%s' in the
*
format is a bad thing.
*/
if
(
strchr
(
zp
->
z_format
,
'%'
)
!=
0
)
error
(
_
(
"%s in ruleless zone"
));
...
...
@@ -767,21 +818,25 @@ static void associate(void)
(
void
)
exit
(
EXIT_FAILURE
);
}
static
void
infile
(
const
char
*
name
)
static
void
infile
(
const
char
*
name
)
{
register
FILE
*
fp
;
register
char
**
fields
;
register
char
*
cp
;
register
const
struct
lookup
*
lp
;
register
FILE
*
fp
;
register
char
**
fields
;
register
char
*
cp
;
register
const
struct
lookup
*
lp
;
register
int
nfields
;
register
int
wantcont
;
register
int
num
;
char
buf
[
BUFSIZ
];
if
(
strcmp
(
name
,
"-"
)
==
0
)
{
if
(
strcmp
(
name
,
"-"
)
==
0
)
{
name
=
_
(
"standard input"
);
fp
=
stdin
;
}
else
if
((
fp
=
fopen
(
name
,
"r"
))
==
NULL
)
{
}
else
if
((
fp
=
fopen
(
name
,
"r"
))
==
NULL
)
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
_
(
"%s: Can't open %s: %s
\n
"
),
...
...
@@ -789,34 +844,42 @@ static void infile(const char *name)
(
void
)
exit
(
EXIT_FAILURE
);
}
wantcont
=
FALSE
;
for
(
num
=
1
;
;
++
num
)
{
for
(
num
=
1
;;
++
num
)
{
eat
(
name
,
num
);
if
(
fgets
(
buf
,
(
int
)
sizeof
buf
,
fp
)
!=
buf
)
break
;
cp
=
strchr
(
buf
,
'\n'
);
if
(
cp
==
NULL
)
{
if
(
cp
==
NULL
)
{
error
(
_
(
"line too long"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
*
cp
=
'\0'
;
fields
=
getfields
(
buf
);
nfields
=
0
;
while
(
fields
[
nfields
]
!=
NULL
)
{
while
(
fields
[
nfields
]
!=
NULL
)
{
static
char
nada
;
if
(
strcmp
(
fields
[
nfields
],
"-"
)
==
0
)
fields
[
nfields
]
=
&
nada
;
++
nfields
;
}
if
(
nfields
==
0
)
{
if
(
nfields
==
0
)
{
/* nothing to do */
}
else
if
(
wantcont
)
{
}
else
if
(
wantcont
)
wantcont
=
inzcont
(
fields
,
nfields
);
}
else
{
else
{
lp
=
byword
(
fields
[
0
],
line_codes
);
if
(
lp
==
NULL
)
error
(
_
(
"input line of unknown type"
));
else
switch
((
int
)
(
lp
->
l_value
))
{
else
switch
((
int
)
(
lp
->
l_value
))
{
case
LC_RULE
:
inrule
(
fields
,
nfields
);
wantcont
=
FALSE
;
...
...
@@ -831,26 +894,29 @@ static void infile(const char *name)
case
LC_LEAP
:
if
(
name
!=
leapsec
)
(
void
)
fprintf
(
stderr
,
_
(
"%s: Leap line in non leap seconds file %s
\n
"
),
_
(
"%s: Leap line in non leap seconds file %s
\n
"
),
progname
,
name
);
else
inleap
(
fields
,
nfields
);
else
inleap
(
fields
,
nfields
);
wantcont
=
FALSE
;
break
;
default:
/* "cannot happen" */
(
void
)
fprintf
(
stderr
,
_
(
"%s: panic: Invalid l_value %d
\n
"
),
_
(
"%s: panic: Invalid l_value %d
\n
"
),
progname
,
lp
->
l_value
);
(
void
)
exit
(
EXIT_FAILURE
);
}
}
ifree
((
char
*
)
fields
);
}
if
(
ferror
(
fp
))
{
if
(
ferror
(
fp
))
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: Error reading %s
\n
"
),
progname
,
filename
);
(
void
)
exit
(
EXIT_FAILURE
);
}
if
(
fp
!=
stdin
&&
fclose
(
fp
))
{
if
(
fp
!=
stdin
&&
fclose
(
fp
))
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
_
(
"%s: Error closing %s: %s
\n
"
),
...
...
@@ -869,31 +935,40 @@ _("%s: panic: Invalid l_value %d\n"),
** Call error with errstring and return zero on errors.
*/
static
long
gethms
(
const
char
*
string
,
const
char
*
errstring
,
const
int
signable
)
static
long
gethms
(
const
char
*
string
,
const
char
*
errstring
,
const
int
signable
)
{
int
hh
,
mm
,
ss
,
sign
;
int
hh
,
mm
,
ss
,
sign
;
if
(
string
==
NULL
||
*
string
==
'\0'
)
return
0
;
if
(
!
signable
)
sign
=
1
;
else
if
(
*
string
==
'-'
)
{
else
if
(
*
string
==
'-'
)
{
sign
=
-
1
;
++
string
;
}
else
sign
=
1
;
}
else
sign
=
1
;
if
(
sscanf
(
string
,
scheck
(
string
,
"%d"
),
&
hh
)
==
1
)
mm
=
ss
=
0
;
else
if
(
sscanf
(
string
,
scheck
(
string
,
"%d:%d"
),
&
hh
,
&
mm
)
==
2
)
ss
=
0
;
else
if
(
sscanf
(
string
,
scheck
(
string
,
"%d:%d:%d"
),
&
hh
,
&
mm
,
&
ss
)
!=
3
)
{
&
hh
,
&
mm
,
&
ss
)
!=
3
)
{
error
(
errstring
);
return
0
;
}
if
((
hh
<
0
||
hh
>=
HOURSPERDAY
||
mm
<
0
||
mm
>=
MINSPERHOUR
||
ss
<
0
||
ss
>
SECSPERMIN
)
&&
!
(
hh
==
HOURSPERDAY
&&
mm
==
0
&&
ss
==
0
))
{
!
(
hh
==
HOURSPERDAY
&&
mm
==
0
&&
ss
==
0
))
{
error
(
errstring
);
return
0
;
}
...
...
@@ -904,15 +979,18 @@ static long gethms(const char *string, const char *errstring, const int signable
eitol
(
SECSPERMIN
)
+
eitol
(
ss
));
}
static
void
inrule
(
register
char
**
fields
,
const
int
nfields
)
static
void
inrule
(
register
char
**
fields
,
const
int
nfields
)
{
static
struct
rule
r
;
if
(
nfields
!=
RULE_FIELDS
)
{
if
(
nfields
!=
RULE_FIELDS
)
{
error
(
_
(
"wrong number of fields on Rule line"
));
return
;
}
if
(
*
fields
[
RF_NAME
]
==
'\0'
)
{
if
(
*
fields
[
RF_NAME
]
==
'\0'
)
{
error
(
_
(
"nameless rule"
));
return
;
}
...
...
@@ -928,39 +1006,44 @@ static void inrule(register char **fields, const int nfields)
rules
[
nrules
++
]
=
r
;
}
static
int
inzone
(
register
char
**
fields
,
const
int
nfields
)
static
int
inzone
(
register
char
**
fields
,
const
int
nfields
)
{
register
int
i
;
static
char
*
buf
;
static
char
*
buf
;
if
(
nfields
<
ZONE_MINFIELDS
||
nfields
>
ZONE_MAXFIELDS
)
{
if
(
nfields
<
ZONE_MINFIELDS
||
nfields
>
ZONE_MAXFIELDS
)
{
error
(
_
(
"wrong number of fields on Zone line"
));
return
FALSE
;
}
if
(
strcmp
(
fields
[
ZF_NAME
],
TZDEFAULT
)
==
0
&&
lcltime
!=
NULL
)
{
if
(
strcmp
(
fields
[
ZF_NAME
],
TZDEFAULT
)
==
0
&&
lcltime
!=
NULL
)
{
buf
=
erealloc
(
buf
,
(
int
)
(
132
+
strlen
(
TZDEFAULT
)));
(
void
)
sprintf
(
buf
,
_
(
"
\"
Zone %s
\"
line and -l option are mutually exclusive"
),
_
(
"
\"
Zone %s
\"
line and -l option are mutually exclusive"
),
TZDEFAULT
);
error
(
buf
);
return
FALSE
;
}
if
(
strcmp
(
fields
[
ZF_NAME
],
TZDEFRULES
)
==
0
&&
psxrules
!=
NULL
)
{
if
(
strcmp
(
fields
[
ZF_NAME
],
TZDEFRULES
)
==
0
&&
psxrules
!=
NULL
)
{
buf
=
erealloc
(
buf
,
(
int
)
(
132
+
strlen
(
TZDEFRULES
)));
(
void
)
sprintf
(
buf
,
_
(
"
\"
Zone %s
\"
line and -p option are mutually exclusive"
),
_
(
"
\"
Zone %s
\"
line and -p option are mutually exclusive"
),
TZDEFRULES
);
error
(
buf
);
return
FALSE
;
}
for
(
i
=
0
;
i
<
nzones
;
++
i
)
if
(
zones
[
i
].
z_name
!=
NULL
&&
strcmp
(
zones
[
i
].
z_name
,
fields
[
ZF_NAME
])
==
0
)
{
strcmp
(
zones
[
i
].
z_name
,
fields
[
ZF_NAME
])
==
0
)
{
buf
=
erealloc
(
buf
,
(
int
)
(
132
+
strlen
(
fields
[
ZF_NAME
])
+
strlen
(
zones
[
i
].
z_filename
)));
(
void
)
sprintf
(
buf
,
_
(
"duplicate zone name %s (file
\"
%s
\"
, line %d)"
),
_
(
"duplicate zone name %s (file
\"
%s
\"
, line %d)"
),
fields
[
ZF_NAME
],
zones
[
i
].
z_filename
,
zones
[
i
].
z_linenum
);
...
...
@@ -970,25 +1053,33 @@ _("duplicate zone name %s (file \"%s\", line %d)"),
return
inzsub
(
fields
,
nfields
,
FALSE
);
}
static
int
inzcont
(
register
char
**
fields
,
const
int
nfields
)
static
int
inzcont
(
register
char
**
fields
,
const
int
nfields
)
{
if
(
nfields
<
ZONEC_MINFIELDS
||
nfields
>
ZONEC_MAXFIELDS
)
{
if
(
nfields
<
ZONEC_MINFIELDS
||
nfields
>
ZONEC_MAXFIELDS
)
{
error
(
_
(
"wrong number of fields on Zone continuation line"
));
return
FALSE
;
}
return
inzsub
(
fields
,
nfields
,
TRUE
);
}
static
int
inzsub
(
register
char
**
fields
,
const
int
nfields
,
const
int
iscont
)
static
int
inzsub
(
register
char
**
fields
,
const
int
nfields
,
const
int
iscont
)
{
register
char
*
cp
;
register
char
*
cp
;
static
struct
zone
z
;
register
int
i_gmtoff
,
i_rule
,
i_format
;
register
int
i_untilyear
,
i_untilmonth
;
register
int
i_untilday
,
i_untiltime
;
register
int
i_gmtoff
,
i_rule
,
i_format
;
register
int
i_untilyear
,
i_untilmonth
;
register
int
i_untilday
,
i_untiltime
;
register
int
hasuntil
;
if
(
iscont
)
{
if
(
iscont
)
{
i_gmtoff
=
ZFC_GMTOFF
;
i_rule
=
ZFC_RULE
;
i_format
=
ZFC_FORMAT
;
...
...
@@ -997,7 +1088,9 @@ static int inzsub(register char **fields, const int nfields, const int iscont)
i_untilday
=
ZFC_TILDAY
;
i_untiltime
=
ZFC_TILTIME
;
z
.
z_name
=
NULL
;
}
else
{
}
else
{
i_gmtoff
=
ZF_GMTOFF
;
i_rule
=
ZF_RULE
;
i_format
=
ZF_FORMAT
;
...
...
@@ -1010,8 +1103,10 @@ static int inzsub(register char **fields, const int nfields, const int iscont)
z
.
z_filename
=
filename
;
z
.
z_linenum
=
linenum
;
z
.
z_gmtoff
=
gethms
(
fields
[
i_gmtoff
],
_
(
"invalid UTC offset"
),
TRUE
);
if
((
cp
=
strchr
(
fields
[
i_format
],
'%'
))
!=
0
)
{
if
(
*++
cp
!=
's'
||
strchr
(
cp
,
'%'
)
!=
0
)
{
if
((
cp
=
strchr
(
fields
[
i_format
],
'%'
))
!=
0
)
{
if
(
*++
cp
!=
's'
||
strchr
(
cp
,
'%'
)
!=
0
)
{
error
(
_
(
"invalid abbreviation format"
));
return
FALSE
;
}
...
...
@@ -1019,7 +1114,8 @@ static int inzsub(register char **fields, const int nfields, const int iscont)
z
.
z_rule
=
ecpyalloc
(
fields
[
i_rule
]);
z
.
z_format
=
ecpyalloc
(
fields
[
i_format
]);
hasuntil
=
nfields
>
i_untilyear
;
if
(
hasuntil
)
{
if
(
hasuntil
)
{
z
.
z_untilrule
.
r_filename
=
filename
;
z
.
z_untilrule
.
r_linenum
=
linenum
;
rulesub
(
&
z
.
z_untilrule
,
...
...
@@ -1037,7 +1133,8 @@ static int inzsub(register char **fields, const int nfields, const int iscont)
z
.
z_untiltime
<
max_time
&&
zones
[
nzones
-
1
].
z_untiltime
>
min_time
&&
zones
[
nzones
-
1
].
z_untiltime
<
max_time
&&
zones
[
nzones
-
1
].
z_untiltime
>=
z
.
z_untiltime
)
{
zones
[
nzones
-
1
].
z_untiltime
>=
z
.
z_untiltime
)
{
error
(
_
(
"Zone continuation line end time is not after end time of previous line"
));
return
FALSE
;
}
...
...
@@ -1045,29 +1142,37 @@ static int inzsub(register char **fields, const int nfields, const int iscont)
zones
=
(
struct
zone
*
)
(
void
*
)
erealloc
((
char
*
)
zones
,
(
int
)
((
nzones
+
1
)
*
sizeof
*
zones
));
zones
[
nzones
++
]
=
z
;
/*
** If there was an UNTIL field on this line,
** there's more
information about the zone on the next line.
* * If there was an UNTIL field on this line, * there's more
*
information about the zone on the next line.
*/
return
hasuntil
;
}
static
void
inleap
(
register
char
**
fields
,
const
int
nfields
)
static
void
inleap
(
register
char
**
fields
,
const
int
nfields
)
{
register
const
char
*
cp
;
register
const
struct
lookup
*
lp
;
register
int
i
,
j
;
int
year
,
month
,
day
;
long
dayoff
,
tod
;
register
const
char
*
cp
;
register
const
struct
lookup
*
lp
;
register
int
i
,
j
;
int
year
,
month
,
day
;
long
dayoff
,
tod
;
time_t
t
;
if
(
nfields
!=
LEAP_FIELDS
)
{
if
(
nfields
!=
LEAP_FIELDS
)
{
error
(
_
(
"wrong number of fields on Leap line"
));
return
;
}
dayoff
=
0
;
cp
=
fields
[
LP_YEAR
];
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
year
)
!=
1
)
{
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
year
)
!=
1
)
{
/*
* Leapin' Lizards!
*/
...
...
@@ -1075,70 +1180,91 @@ static void inleap(register char **fields, const int nfields)
return
;
}
j
=
EPOCH_YEAR
;
while
(
j
!=
year
)
{
if
(
year
>
j
)
{
while
(
j
!=
year
)
{
if
(
year
>
j
)
{
i
=
len_years
[
isleap
(
j
)];
++
j
;
}
else
{
}
else
{
--
j
;
i
=
-
len_years
[
isleap
(
j
)];
}
dayoff
=
oadd
(
dayoff
,
eitol
(
i
));
}
if
((
lp
=
byword
(
fields
[
LP_MONTH
],
mon_names
))
==
NULL
)
{
if
((
lp
=
byword
(
fields
[
LP_MONTH
],
mon_names
))
==
NULL
)
{
error
(
_
(
"invalid month name"
));
return
;
}
month
=
lp
->
l_value
;
j
=
TM_JANUARY
;
while
(
j
!=
month
)
{
while
(
j
!=
month
)
{
i
=
len_months
[
isleap
(
year
)][
j
];
dayoff
=
oadd
(
dayoff
,
eitol
(
i
));
++
j
;
}
cp
=
fields
[
LP_DAY
];
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
day
)
!=
1
||
day
<=
0
||
day
>
len_months
[
isleap
(
year
)][
month
])
{
day
<=
0
||
day
>
len_months
[
isleap
(
year
)][
month
])
{
error
(
_
(
"invalid day of month"
));
return
;
}
dayoff
=
oadd
(
dayoff
,
eitol
(
day
-
1
));
if
(
dayoff
<
0
&&
!
TYPE_SIGNED
(
time_t
))
{
if
(
dayoff
<
0
&&
!
TYPE_SIGNED
(
time_t
))
{
error
(
_
(
"time before zero"
));
return
;
}
if
(
dayoff
<
min_time
/
SECSPERDAY
)
{
if
(
dayoff
<
min_time
/
SECSPERDAY
)
{
error
(
_
(
"time too small"
));
return
;
}
if
(
dayoff
>
max_time
/
SECSPERDAY
)
{
if
(
dayoff
>
max_time
/
SECSPERDAY
)
{
error
(
_
(
"time too large"
));
return
;
}
t
=
(
time_t
)
dayoff
*
SECSPERDAY
;
t
=
(
time_t
)
dayoff
*
SECSPERDAY
;
tod
=
gethms
(
fields
[
LP_TIME
],
_
(
"invalid time of day"
),
FALSE
);
cp
=
fields
[
LP_CORR
];
{
register
int
positive
;
int
count
;
if
(
strcmp
(
cp
,
""
)
==
0
)
{
/* infile() turns "-" into "" */
if
(
strcmp
(
cp
,
""
)
==
0
)
{
/* infile() turns "-" into "" */
positive
=
FALSE
;
count
=
1
;
}
else
if
(
strcmp
(
cp
,
"--"
)
==
0
)
{
}
else
if
(
strcmp
(
cp
,
"--"
)
==
0
)
{
positive
=
FALSE
;
count
=
2
;
}
else
if
(
strcmp
(
cp
,
"+"
)
==
0
)
{
}
else
if
(
strcmp
(
cp
,
"+"
)
==
0
)
{
positive
=
TRUE
;
count
=
1
;
}
else
if
(
strcmp
(
cp
,
"++"
)
==
0
)
{
}
else
if
(
strcmp
(
cp
,
"++"
)
==
0
)
{
positive
=
TRUE
;
count
=
2
;
}
else
{
}
else
{
error
(
_
(
"illegal CORRECTION field on Leap line"
));
return
;
}
if
((
lp
=
byword
(
fields
[
LP_ROLL
],
leap_types
))
==
NULL
)
{
if
((
lp
=
byword
(
fields
[
LP_ROLL
],
leap_types
))
==
NULL
)
{
error
(
_
(
"illegal Rolling/Stationary field on Leap line"
));
return
;
}
...
...
@@ -1146,19 +1272,23 @@ static void inleap(register char **fields, const int nfields)
}
}
static
void
inlink
(
register
char
**
fields
,
const
int
nfields
)
static
void
inlink
(
register
char
**
fields
,
const
int
nfields
)
{
struct
link
l
;
if
(
nfields
!=
LINK_FIELDS
)
{
if
(
nfields
!=
LINK_FIELDS
)
{
error
(
_
(
"wrong number of fields on Link line"
));
return
;
}
if
(
*
fields
[
LF_FROM
]
==
'\0'
)
{
if
(
*
fields
[
LF_FROM
]
==
'\0'
)
{
error
(
_
(
"blank FROM field on Link line"
));
return
;
}
if
(
*
fields
[
LF_TO
]
==
'\0'
)
{
if
(
*
fields
[
LF_TO
]
==
'\0'
)
{
error
(
_
(
"blank TO field on Link line"
));
return
;
}
...
...
@@ -1171,14 +1301,16 @@ static void inlink(register char **fields, const int nfields)
links
[
nlinks
++
]
=
l
;
}
static
void
rulesub
(
register
struct
rule
*
rp
,
const
char
*
loyearp
,
const
char
*
hiyearp
,
const
char
*
typep
,
const
char
*
monthp
,
const
char
*
dayp
,
const
char
*
timep
)
static
void
rulesub
(
register
struct
rule
*
rp
,
const
char
*
loyearp
,
const
char
*
hiyearp
,
const
char
*
typep
,
const
char
*
monthp
,
const
char
*
dayp
,
const
char
*
timep
)
{
register
const
struct
lookup
*
lp
;
register
const
char
*
cp
;
register
char
*
dp
;
register
char
*
ep
;
register
const
struct
lookup
*
lp
;
register
const
char
*
cp
;
register
char
*
dp
;
register
char
*
ep
;
if
((
lp
=
byword
(
monthp
,
mon_names
))
==
NULL
)
{
if
((
lp
=
byword
(
monthp
,
mon_names
))
==
NULL
)
{
error
(
_
(
"invalid month name"
));
return
;
}
...
...
@@ -1186,9 +1318,11 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
rp
->
r_todisstd
=
FALSE
;
rp
->
r_todisgmt
=
FALSE
;
dp
=
ecpyalloc
(
timep
);
if
(
*
dp
!=
'\0'
)
{
if
(
*
dp
!=
'\0'
)
{
ep
=
dp
+
strlen
(
dp
)
-
1
;
switch
(
lowerit
(
*
ep
))
{
switch
(
lowerit
(
*
ep
))
{
case
's'
:
/* Standard */
rp
->
r_todisstd
=
TRUE
;
rp
->
r_todisgmt
=
FALSE
;
...
...
@@ -1210,12 +1344,15 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
}
rp
->
r_tod
=
gethms
(
dp
,
_
(
"invalid time of day"
),
FALSE
);
ifree
(
dp
);
/*
*
* Year work.
*
* Year work.
*/
cp
=
loyearp
;
lp
=
byword
(
cp
,
begin_years
);
if
(
lp
!=
NULL
)
switch
((
int
)
lp
->
l_value
)
{
if
(
lp
!=
NULL
)
switch
((
int
)
lp
->
l_value
)
{
case
YR_MINIMUM
:
rp
->
r_loyear
=
INT_MIN
;
break
;
...
...
@@ -1227,17 +1364,23 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
_
(
"%s: panic: Invalid l_value %d
\n
"
),
progname
,
lp
->
l_value
);
(
void
)
exit
(
EXIT_FAILURE
);
}
else
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
rp
->
r_loyear
)
!=
1
)
{
}
else
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
rp
->
r_loyear
)
!=
1
)
{
error
(
_
(
"invalid starting year"
));
return
;
}
else
if
(
noise
)
{
}
else
if
(
noise
)
{
if
(
rp
->
r_loyear
<
min_year_representable
)
warning
(
_
(
"starting year too low to be represented"
));
else
if
(
rp
->
r_loyear
>
max_year_representable
)
warning
(
_
(
"starting year too high to be represented"
));
}
cp
=
hiyearp
;
if
((
lp
=
byword
(
cp
,
end_years
))
!=
NULL
)
switch
((
int
)
lp
->
l_value
)
{
if
((
lp
=
byword
(
cp
,
end_years
))
!=
NULL
)
switch
((
int
)
lp
->
l_value
)
{
case
YR_MINIMUM
:
rp
->
r_hiyear
=
INT_MIN
;
break
;
...
...
@@ -1252,23 +1395,30 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
_
(
"%s: panic: Invalid l_value %d
\n
"
),
progname
,
lp
->
l_value
);
(
void
)
exit
(
EXIT_FAILURE
);
}
else
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
rp
->
r_hiyear
)
!=
1
)
{
}
else
if
(
sscanf
(
cp
,
scheck
(
cp
,
"%d"
),
&
rp
->
r_hiyear
)
!=
1
)
{
error
(
_
(
"invalid ending year"
));
return
;
}
else
if
(
noise
)
{
}
else
if
(
noise
)
{
if
(
rp
->
r_loyear
<
min_year_representable
)
warning
(
_
(
"ending year too low to be represented"
));
else
if
(
rp
->
r_loyear
>
max_year_representable
)
warning
(
_
(
"ending year too high to be represented"
));
}
if
(
rp
->
r_loyear
>
rp
->
r_hiyear
)
{
if
(
rp
->
r_loyear
>
rp
->
r_hiyear
)
{
error
(
_
(
"starting year greater than ending year"
));
return
;
}
if
(
*
typep
==
'\0'
)
rp
->
r_yrtype
=
NULL
;
else
{
if
(
rp
->
r_loyear
==
rp
->
r_hiyear
)
{
else
{
if
(
rp
->
r_loyear
==
rp
->
r_hiyear
)
{
error
(
_
(
"typed single year"
));
return
;
}
...
...
@@ -1276,36 +1426,40 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
}
if
(
rp
->
r_loyear
<
min_year
&&
rp
->
r_loyear
>
0
)
min_year
=
rp
->
r_loyear
;
/*
** Day work.
** Accept things such as:
** 1
** last-Sunday
** Sun<=20
** Sun>=7
* * Day work. * Accept things such as: * 1 * last-Sunday * Sun<=20 *
* Sun>=7
*/
dp
=
ecpyalloc
(
dayp
);
if
((
lp
=
byword
(
dp
,
lasts
))
!=
NULL
)
{
if
((
lp
=
byword
(
dp
,
lasts
))
!=
NULL
)
{
rp
->
r_dycode
=
DC_DOWLEQ
;
rp
->
r_wday
=
lp
->
l_value
;
rp
->
r_dayofmonth
=
len_months
[
1
][
rp
->
r_month
];
}
else
{
}
else
{
if
((
ep
=
strchr
(
dp
,
'<'
))
!=
0
)
rp
->
r_dycode
=
DC_DOWLEQ
;
else
if
((
ep
=
strchr
(
dp
,
'>'
))
!=
0
)
rp
->
r_dycode
=
DC_DOWGEQ
;
else
{
else
{
ep
=
dp
;
rp
->
r_dycode
=
DC_DOM
;
}
if
(
rp
->
r_dycode
!=
DC_DOM
)
{
if
(
rp
->
r_dycode
!=
DC_DOM
)
{
*
ep
++
=
0
;
if
(
*
ep
++
!=
'='
)
{
if
(
*
ep
++
!=
'='
)
{
error
(
_
(
"invalid day of month"
));
ifree
(
dp
);
return
;
}
if
((
lp
=
byword
(
dp
,
wday_names
))
==
NULL
)
{
if
((
lp
=
byword
(
dp
,
wday_names
))
==
NULL
)
{
error
(
_
(
"invalid weekday name"
));
ifree
(
dp
);
return
;
...
...
@@ -1314,7 +1468,8 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
}
if
(
sscanf
(
ep
,
scheck
(
ep
,
"%d"
),
&
rp
->
r_dayofmonth
)
!=
1
||
rp
->
r_dayofmonth
<=
0
||
(
rp
->
r_dayofmonth
>
len_months
[
1
][
rp
->
r_month
]))
{
(
rp
->
r_dayofmonth
>
len_months
[
1
][
rp
->
r_month
]))
{
error
(
_
(
"invalid day of month"
));
ifree
(
dp
);
return
;
...
...
@@ -1323,7 +1478,8 @@ static void rulesub(register struct rule *rp, const char *loyearp, const char *h
ifree
(
dp
);
}
static
void
convert
(
const
long
val
,
char
*
buf
)
static
void
convert
(
const
long
val
,
char
*
buf
)
{
register
int
i
;
register
long
shift
;
...
...
@@ -1332,7 +1488,8 @@ static void convert(const long val, char *buf)
buf
[
i
]
=
val
>>
shift
;
}
static
void
puttzcode
(
const
long
val
,
FILE
*
fp
)
static
void
puttzcode
(
const
long
val
,
FILE
*
fp
)
{
char
buf
[
4
];
...
...
@@ -1340,32 +1497,37 @@ static void puttzcode(const long val, FILE *fp)
(
void
)
fwrite
((
void
*
)
buf
,
(
size_t
)
sizeof
buf
,
(
size_t
)
1
,
fp
);
}
static
int
atcomp
(
const
void
*
avp
,
const
void
*
bvp
)
static
int
atcomp
(
const
void
*
avp
,
const
void
*
bvp
)
{
if
(((
struct
attype
*
)
avp
)
->
at
<
((
struct
attype
*
)
bvp
)
->
at
)
return
-
1
;
else
if
(((
struct
attype
*
)
avp
)
->
at
>
((
struct
attype
*
)
bvp
)
->
at
)
return
1
;
else
return
0
;
else
return
0
;
}
static
void
writezone
(
const
char
*
name
)
static
void
writezone
(
const
char
*
name
)
{
register
FILE
*
fp
;
register
int
i
,
j
;
static
char
*
fullname
;
register
FILE
*
fp
;
register
int
i
,
j
;
static
char
*
fullname
;
static
struct
tzhead
tzh
;
time_t
ats
[
TZ_MAX_TIMES
];
unsigned
char
types
[
TZ_MAX_TIMES
];
/*
*
* Sort.
*
* Sort.
*/
if
(
timecnt
>
1
)
(
void
)
qsort
((
void
*
)
attypes
,
(
size_t
)
timecnt
,
(
size_t
)
sizeof
*
attypes
,
atcomp
);
/*
*
* Optimize.
*
* Optimize.
*/
{
int
fromi
;
...
...
@@ -1378,13 +1540,15 @@ static void writezone(const char *name)
if
(
isdsts
[
0
]
==
0
)
while
(
fromi
<
timecnt
&&
attypes
[
fromi
].
type
==
0
)
++
fromi
;
/* handled by default rule */
for
(
;
fromi
<
timecnt
;
++
fromi
)
{
for
(;
fromi
<
timecnt
;
++
fromi
)
{
if
(
toi
!=
0
&&
((
attypes
[
fromi
].
at
+
gmtoffs
[
attypes
[
toi
-
1
].
type
])
<=
(
attypes
[
toi
-
1
].
at
+
gmtoffs
[
toi
==
1
?
0
:
attypes
[
toi
-
2
].
type
])))
{
:
attypes
[
toi
-
2
].
type
])))
{
attypes
[
toi
-
1
].
type
=
attypes
[
fromi
].
type
;
continue
;
}
...
...
@@ -1394,30 +1558,36 @@ static void writezone(const char *name)
}
timecnt
=
toi
;
}
/*
*
* Transfer.
*
* Transfer.
*/
for
(
i
=
0
;
i
<
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
timecnt
;
++
i
)
{
ats
[
i
]
=
attypes
[
i
].
at
;
types
[
i
]
=
attypes
[
i
].
type
;
}
fullname
=
erealloc
(
fullname
,
(
int
)
(
strlen
(
directory
)
+
1
+
strlen
(
name
)
+
1
));
(
void
)
sprintf
(
fullname
,
"%s/%s"
,
directory
,
name
);
/*
*
* Remove old file, if any, to snap links.
*
* Remove old file, if any, to snap links.
*/
if
(
!
itsdir
(
fullname
)
&&
remove
(
fullname
)
!=
0
&&
errno
!=
ENOENT
)
{
if
(
!
itsdir
(
fullname
)
&&
remove
(
fullname
)
!=
0
&&
errno
!=
ENOENT
)
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
_
(
"%s: Can't remove %s: %s
\n
"
),
progname
,
fullname
,
e
);
(
void
)
exit
(
EXIT_FAILURE
);
}
if
((
fp
=
fopen
(
fullname
,
"wb"
))
==
NULL
)
{
if
((
fp
=
fopen
(
fullname
,
"wb"
))
==
NULL
)
{
if
(
mkdirs
(
fullname
)
!=
0
)
(
void
)
exit
(
EXIT_FAILURE
);
if
((
fp
=
fopen
(
fullname
,
"wb"
))
==
NULL
)
{
if
((
fp
=
fopen
(
fullname
,
"wb"
))
==
NULL
)
{
const
char
*
e
=
strerror
(
errno
);
(
void
)
fprintf
(
stderr
,
_
(
"%s: Can't create %s: %s
\n
"
),
...
...
@@ -1442,10 +1612,12 @@ static void writezone(const char *name)
DO
(
tzh_typecnt
);
DO
(
tzh_charcnt
);
#undef DO
for
(
i
=
0
;
i
<
timecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
timecnt
;
++
i
)
{
j
=
leapcnt
;
while
(
--
j
>=
0
)
if
(
ats
[
i
]
>=
trans
[
j
])
{
if
(
ats
[
i
]
>=
trans
[
j
])
{
ats
[
i
]
=
tadd
(
ats
[
i
],
corr
[
j
]);
break
;
}
...
...
@@ -1454,7 +1626,8 @@ static void writezone(const char *name)
if
(
timecnt
>
0
)
(
void
)
fwrite
((
void
*
)
types
,
(
size_t
)
sizeof
types
[
0
],
(
size_t
)
timecnt
,
fp
);
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
{
puttzcode
((
long
)
gmtoffs
[
i
],
fp
);
(
void
)
putc
(
isdsts
[
i
],
fp
);
(
void
)
putc
(
abbrinds
[
i
],
fp
);
...
...
@@ -1462,56 +1635,73 @@ static void writezone(const char *name)
if
(
charcnt
!=
0
)
(
void
)
fwrite
((
void
*
)
chars
,
(
size_t
)
sizeof
chars
[
0
],
(
size_t
)
charcnt
,
fp
);
for
(
i
=
0
;
i
<
leapcnt
;
++
i
)
{
if
(
roll
[
i
])
{
if
(
timecnt
==
0
||
trans
[
i
]
<
ats
[
0
])
{
for
(
i
=
0
;
i
<
leapcnt
;
++
i
)
{
if
(
roll
[
i
])
{
if
(
timecnt
==
0
||
trans
[
i
]
<
ats
[
0
])
{
j
=
0
;
while
(
isdsts
[
j
])
if
(
++
j
>=
typecnt
)
{
if
(
++
j
>=
typecnt
)
{
j
=
0
;
break
;
}
}
else
{
}
else
{
j
=
1
;
while
(
j
<
timecnt
&&
trans
[
i
]
>=
ats
[
j
])
++
j
;
j
=
types
[
j
-
1
];
}
puttzcode
((
long
)
tadd
(
trans
[
i
],
-
gmtoffs
[
j
]),
fp
);
}
else
puttzcode
((
long
)
trans
[
i
],
fp
);
}
else
puttzcode
((
long
)
trans
[
i
],
fp
);
puttzcode
((
long
)
corr
[
i
],
fp
);
}
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
(
void
)
putc
(
ttisstds
[
i
],
fp
);
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
(
void
)
putc
(
ttisgmts
[
i
],
fp
);
if
(
ferror
(
fp
)
||
fclose
(
fp
))
{
if
(
ferror
(
fp
)
||
fclose
(
fp
))
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: Error writing %s
\n
"
),
progname
,
fullname
);
(
void
)
exit
(
EXIT_FAILURE
);
}
}
static
void
doabbr
(
char
*
abbr
,
const
char
*
format
,
const
char
*
letters
,
const
int
isdst
)
static
void
doabbr
(
char
*
abbr
,
const
char
*
format
,
const
char
*
letters
,
const
int
isdst
)
{
if
(
strchr
(
format
,
'/'
)
==
NULL
)
{
if
(
strchr
(
format
,
'/'
)
==
NULL
)
{
if
(
letters
==
NULL
)
(
void
)
strcpy
(
abbr
,
format
);
else
(
void
)
sprintf
(
abbr
,
format
,
letters
);
}
else
if
(
isdst
)
else
(
void
)
sprintf
(
abbr
,
format
,
letters
);
}
else
if
(
isdst
)
(
void
)
strcpy
(
abbr
,
strchr
(
format
,
'/'
)
+
1
);
else
{
else
{
(
void
)
strcpy
(
abbr
,
format
);
*
strchr
(
abbr
,
'/'
)
=
'\0'
;
}
}
static
void
outzone
(
const
struct
zone
*
zpfirst
,
const
int
zonecount
)
static
void
outzone
(
const
struct
zone
*
zpfirst
,
const
int
zonecount
)
{
register
const
struct
zone
*
zp
;
register
struct
rule
*
rp
;
register
int
i
,
j
;
register
int
usestart
,
useuntil
;
register
const
struct
zone
*
zp
;
register
struct
rule
*
rp
;
register
int
i
,
j
;
register
int
usestart
,
useuntil
;
register
time_t
starttime
=
0
;
register
time_t
untiltime
=
0
;
register
long
gmtoff
;
...
...
@@ -1524,20 +1714,22 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
char
startbuf
[
BUFSIZ
];
/*
*
* Now. . .finally. . .generate some useful data!
*
* Now. . .finally. . .generate some useful data!
*/
timecnt
=
0
;
typecnt
=
0
;
charcnt
=
0
;
/*
** Thanks to Earl Chew (earl@dnd.icp.nec.com.au)
** for noting the
need to unconditionally initialize startttisstd.
* * Thanks to Earl Chew (earl@dnd.icp.nec.com.au) * for noting the
*
need to unconditionally initialize startttisstd.
*/
startttisstd
=
FALSE
;
startttisgmt
=
FALSE
;
for
(
i
=
0
;
i
<
zonecount
;
++
i
)
{
for
(
i
=
0
;
i
<
zonecount
;
++
i
)
{
/*
*
* A guess that may well be corrected later.
*
* A guess that may well be corrected later.
*/
stdoff
=
0
;
zp
=
&
zpfirst
[
i
];
...
...
@@ -1549,26 +1741,34 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
eat
(
zp
->
z_filename
,
zp
->
z_linenum
);
*
startbuf
=
'\0'
;
startoff
=
zp
->
z_gmtoff
;
if
(
zp
->
z_nrules
==
0
)
{
if
(
zp
->
z_nrules
==
0
)
{
stdoff
=
zp
->
z_stdoff
;
doabbr
(
startbuf
,
zp
->
z_format
,
(
char
*
)
NULL
,
stdoff
!=
0
);
type
=
addtype
(
oadd
(
zp
->
z_gmtoff
,
stdoff
),
startbuf
,
stdoff
!=
0
,
startttisstd
,
startttisgmt
);
if
(
usestart
)
{
if
(
usestart
)
{
addtt
(
starttime
,
type
);
usestart
=
FALSE
;
}
else
if
(
stdoff
!=
0
)
}
else
if
(
stdoff
!=
0
)
addtt
(
min_time
,
type
);
}
else
for
(
year
=
min_year
;
year
<=
max_year
;
++
year
)
{
}
else
for
(
year
=
min_year
;
year
<=
max_year
;
++
year
)
{
if
(
useuntil
&&
year
>
zp
->
z_untilrule
.
r_hiyear
)
break
;
/*
** Mark which rules to do in the current year.
** For
those to do, calculate rpytime(rp, year);
* * Mark which rules to do in the current year. * For
*
those to do, calculate rpytime(rp, year);
*/
for
(
j
=
0
;
j
<
zp
->
z_nrules
;
++
j
)
{
for
(
j
=
0
;
j
<
zp
->
z_nrules
;
++
j
)
{
rp
=
&
zp
->
z_rules
[
j
];
eats
(
zp
->
z_filename
,
zp
->
z_linenum
,
rp
->
r_filename
,
rp
->
r_linenum
);
...
...
@@ -1578,17 +1778,19 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
if
(
rp
->
r_todo
)
rp
->
r_temp
=
rpytime
(
rp
,
year
);
}
for
(
;
;
)
{
for
(;;)
{
register
int
k
;
register
time_t
jtime
,
ktime
=
0
;
register
time_t
jtime
,
ktime
=
0
;
register
long
offset
;
char
buf
[
BUFSIZ
];
if
(
useuntil
)
{
if
(
useuntil
)
{
/*
** Turn untiltime into UTC
** assuming the current gmtoff and
** stdoff values.
* * Turn untiltime into UTC * assuming the
* current gmtoff and * stdoff values.
*/
untiltime
=
zp
->
z_untiltime
;
if
(
!
zp
->
z_untilrule
.
r_todisgmt
)
...
...
@@ -1598,12 +1800,14 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
untiltime
=
tadd
(
untiltime
,
-
stdoff
);
}
/*
** Find the rule (of those to do, if any)
** that
takes effect earliest in the year.
* * Find the rule (of those to do, if any) * that
*
takes effect earliest in the year.
*/
k
=
-
1
;
for
(
j
=
0
;
j
<
zp
->
z_nrules
;
++
j
)
{
for
(
j
=
0
;
j
<
zp
->
z_nrules
;
++
j
)
{
rp
=
&
zp
->
z_rules
[
j
];
if
(
!
rp
->
r_todo
)
continue
;
...
...
@@ -1617,7 +1821,8 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
jtime
==
max_time
)
continue
;
jtime
=
tadd
(
jtime
,
-
offset
);
if
(
k
<
0
||
jtime
<
ktime
)
{
if
(
k
<
0
||
jtime
<
ktime
)
{
k
=
j
;
ktime
=
jtime
;
}
...
...
@@ -1631,8 +1836,10 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
stdoff
=
rp
->
r_stdoff
;
if
(
usestart
&&
ktime
==
starttime
)
usestart
=
FALSE
;
if
(
usestart
)
{
if
(
ktime
<
starttime
)
{
if
(
usestart
)
{
if
(
ktime
<
starttime
)
{
startoff
=
oadd
(
zp
->
z_gmtoff
,
stdoff
);
doabbr
(
startbuf
,
zp
->
z_format
,
...
...
@@ -1642,7 +1849,8 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
}
if
(
*
startbuf
==
'\0'
&&
startoff
==
oadd
(
zp
->
z_gmtoff
,
stdoff
))
{
stdoff
))
{
doabbr
(
startbuf
,
zp
->
z_format
,
rp
->
r_abbrvar
,
rp
->
r_stdoff
!=
0
);
...
...
@@ -1658,7 +1866,8 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
addtt
(
ktime
,
type
);
}
}
if
(
usestart
)
{
if
(
usestart
)
{
if
(
*
startbuf
==
'\0'
&&
zp
->
z_format
!=
NULL
&&
strchr
(
zp
->
z_format
,
'%'
)
==
NULL
&&
...
...
@@ -1666,17 +1875,20 @@ static void outzone(const struct zone *zpfirst, const int zonecount)
(
void
)
strcpy
(
startbuf
,
zp
->
z_format
);
eat
(
zp
->
z_filename
,
zp
->
z_linenum
);
if
(
*
startbuf
==
'\0'
)
error
(
_
(
"can't determine time zone abbreviation to use just after until time"
));
else
addtt
(
starttime
,
error
(
_
(
"can't determine time zone abbreviation to use just after until time"
));
else
addtt
(
starttime
,
addtype
(
startoff
,
startbuf
,
startoff
!=
zp
->
z_gmtoff
,
startttisstd
,
startttisgmt
));
}
/*
*
* Now we may get to set starttime for the next zone line.
*
* Now we may get to set starttime for the next zone line.
*/
if
(
useuntil
)
{
if
(
useuntil
)
{
startttisstd
=
zp
->
z_untilrule
.
r_todisstd
;
startttisgmt
=
zp
->
z_untilrule
.
r_todisgmt
;
starttime
=
zp
->
z_untiltime
;
...
...
@@ -1689,10 +1901,12 @@ error(_("can't determine time zone abbreviation to use just after until time"));
writezone
(
zpfirst
->
z_name
);
}
static
void
addtt
(
const
time_t
starttime
,
int
type
)
static
void
addtt
(
const
time_t
starttime
,
int
type
)
{
if
(
starttime
<=
min_time
||
(
timecnt
==
1
&&
attypes
[
0
].
at
<
min_time
))
{
(
timecnt
==
1
&&
attypes
[
0
].
at
<
min_time
))
{
gmtoffs
[
0
]
=
gmtoffs
[
type
];
isdsts
[
0
]
=
isdsts
[
type
];
ttisstds
[
0
]
=
ttisstds
[
type
];
...
...
@@ -1705,7 +1919,8 @@ static void addtt(const time_t starttime, int type)
timecnt
=
0
;
type
=
0
;
}
if
(
timecnt
>=
TZ_MAX_TIMES
)
{
if
(
timecnt
>=
TZ_MAX_TIMES
)
{
error
(
_
(
"too many transitions?!"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -1714,38 +1929,47 @@ static void addtt(const time_t starttime, int type)
++
timecnt
;
}
static
int
addtype
(
const
long
gmtoff
,
const
char
*
abbr
,
const
int
isdst
,
const
int
ttisstd
,
const
int
ttisgmt
)
static
int
addtype
(
const
long
gmtoff
,
const
char
*
abbr
,
const
int
isdst
,
const
int
ttisstd
,
const
int
ttisgmt
)
{
register
int
i
,
j
;
register
int
i
,
j
;
if
(
isdst
!=
TRUE
&&
isdst
!=
FALSE
)
{
if
(
isdst
!=
TRUE
&&
isdst
!=
FALSE
)
{
error
(
_
(
"internal error - addtype called with bad isdst"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
if
(
ttisstd
!=
TRUE
&&
ttisstd
!=
FALSE
)
{
if
(
ttisstd
!=
TRUE
&&
ttisstd
!=
FALSE
)
{
error
(
_
(
"internal error - addtype called with bad ttisstd"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
if
(
ttisgmt
!=
TRUE
&&
ttisgmt
!=
FALSE
)
{
if
(
ttisgmt
!=
TRUE
&&
ttisgmt
!=
FALSE
)
{
error
(
_
(
"internal error - addtype called with bad ttisgmt"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
/*
** See if there's already an entry for this zone type.
** If so, just
return its index.
* * See if there's already an entry for this zone type. * If so, just
*
return its index.
*/
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
{
for
(
i
=
0
;
i
<
typecnt
;
++
i
)
{
if
(
gmtoff
==
gmtoffs
[
i
]
&&
isdst
==
isdsts
[
i
]
&&
strcmp
(
abbr
,
&
chars
[
abbrinds
[
i
]])
==
0
&&
ttisstd
==
ttisstds
[
i
]
&&
ttisgmt
==
ttisgmts
[
i
])
return
i
;
}
/*
** There isn't one; add a new one, unless there are already too
*
* many.
* * There isn't one; add a new one, unless there are already too *
* many.
*/
if
(
typecnt
>=
TZ_MAX_TYPES
)
{
if
(
typecnt
>=
TZ_MAX_TYPES
)
{
error
(
_
(
"too many local time types"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -1764,24 +1988,31 @@ static int addtype(const long gmtoff, const char *abbr, const int isdst, const i
return
i
;
}
static
void
leapadd
(
const
time_t
t
,
const
int
positive
,
const
int
rolling
,
int
count
)
static
void
leapadd
(
const
time_t
t
,
const
int
positive
,
const
int
rolling
,
int
count
)
{
register
int
i
,
j
;
register
int
i
,
j
;
if
(
leapcnt
+
(
positive
?
count
:
1
)
>
TZ_MAX_LEAPS
)
{
if
(
leapcnt
+
(
positive
?
count
:
1
)
>
TZ_MAX_LEAPS
)
{
error
(
_
(
"too many leap seconds"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
for
(
i
=
0
;
i
<
leapcnt
;
++
i
)
if
(
t
<=
trans
[
i
])
{
if
(
t
==
trans
[
i
])
{
if
(
t
<=
trans
[
i
])
{
if
(
t
==
trans
[
i
])
{
error
(
_
(
"repeated leap second moment"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
break
;
}
do
{
for
(
j
=
leapcnt
;
j
>
i
;
--
j
)
{
do
{
for
(
j
=
leapcnt
;
j
>
i
;
--
j
)
{
trans
[
j
]
=
trans
[
j
-
1
];
corr
[
j
]
=
corr
[
j
-
1
];
roll
[
j
]
=
roll
[
j
-
1
];
...
...
@@ -1793,23 +2024,26 @@ static void leapadd(const time_t t, const int positive, const int rolling, int c
}
while
(
positive
&&
--
count
!=
0
);
}
static
void
adjleap
(
void
)
static
void
adjleap
(
void
)
{
register
int
i
;
register
long
last
=
0
;
/*
*
* propagate leap seconds forward
*
* propagate leap seconds forward
*/
for
(
i
=
0
;
i
<
leapcnt
;
++
i
)
{
for
(
i
=
0
;
i
<
leapcnt
;
++
i
)
{
trans
[
i
]
=
tadd
(
trans
[
i
],
last
);
last
=
corr
[
i
]
+=
last
;
}
}
static
int
yearistype
(
const
int
year
,
const
char
*
type
)
static
int
yearistype
(
const
int
year
,
const
char
*
type
)
{
static
char
*
buf
;
static
char
*
buf
;
int
result
;
if
(
type
==
NULL
||
*
type
==
'\0'
)
...
...
@@ -1817,7 +2051,9 @@ static int yearistype(const int year, const char *type)
buf
=
erealloc
(
buf
,
(
int
)
(
132
+
strlen
(
yitcommand
)
+
strlen
(
type
)));
(
void
)
sprintf
(
buf
,
"%s %d %s"
,
yitcommand
,
year
,
type
);
result
=
system
(
buf
);
if
(
WIFEXITED
(
result
))
switch
(
WEXITSTATUS
(
result
))
{
if
(
WIFEXITED
(
result
))
switch
(
WEXITSTATUS
(
result
))
{
case
0
:
return
TRUE
;
case
1
:
...
...
@@ -1826,17 +2062,19 @@ static int yearistype(const int year, const char *type)
error
(
_
(
"Wild result from command execution"
));
(
void
)
fprintf
(
stderr
,
_
(
"%s: command was '%s', result was %d
\n
"
),
progname
,
buf
,
result
);
for
(
;
;
)
for
(
;;
)
(
void
)
exit
(
EXIT_FAILURE
);
}
static
int
lowerit
(
int
a
)
static
int
lowerit
(
int
a
)
{
a
=
(
unsigned
char
)
a
;
return
(
isascii
(
a
)
&&
isupper
(
a
))
?
tolower
(
a
)
:
a
;
}
static
int
ciequal
(
register
const
char
*
ap
,
register
const
char
*
bp
)
static
int
ciequal
(
register
const
char
*
ap
,
register
const
char
*
bp
)
{
while
(
lowerit
(
*
ap
)
==
lowerit
(
*
bp
++
))
if
(
*
ap
++
==
'\0'
)
...
...
@@ -1844,49 +2082,57 @@ static int ciequal(register const char *ap, register const char *bp)
return
FALSE
;
}
static
int
itsabbr
(
register
const
char
*
abbr
,
register
const
char
*
word
)
static
int
itsabbr
(
register
const
char
*
abbr
,
register
const
char
*
word
)
{
if
(
lowerit
(
*
abbr
)
!=
lowerit
(
*
word
))
return
FALSE
;
++
word
;
while
(
*++
abbr
!=
'\0'
)
do
{
do
{
if
(
*
word
==
'\0'
)
return
FALSE
;
}
while
(
lowerit
(
*
word
++
)
!=
lowerit
(
*
abbr
));
return
TRUE
;
}
static
const
struct
lookup
*
byword
(
register
const
char
*
word
,
register
const
struct
lookup
*
table
)
static
const
struct
lookup
*
byword
(
register
const
char
*
word
,
register
const
struct
lookup
*
table
)
{
register
const
struct
lookup
*
foundlp
;
register
const
struct
lookup
*
lp
;
register
const
struct
lookup
*
foundlp
;
register
const
struct
lookup
*
lp
;
if
(
word
==
NULL
||
table
==
NULL
)
return
NULL
;
/*
*
* Look for exact match.
*
* Look for exact match.
*/
for
(
lp
=
table
;
lp
->
l_word
!=
NULL
;
++
lp
)
if
(
ciequal
(
word
,
lp
->
l_word
))
return
lp
;
/*
*
* Look for inexact match.
*
* Look for inexact match.
*/
foundlp
=
NULL
;
for
(
lp
=
table
;
lp
->
l_word
!=
NULL
;
++
lp
)
if
(
itsabbr
(
word
,
lp
->
l_word
))
{
if
(
itsabbr
(
word
,
lp
->
l_word
))
{
if
(
foundlp
==
NULL
)
foundlp
=
lp
;
else
return
NULL
;
/* multiple inexact matches */
else
return
NULL
;
/* multiple inexact matches */
}
return
foundlp
;
}
static
char
**
getfields
(
register
char
*
cp
)
static
char
**
getfields
(
register
char
*
cp
)
{
register
char
*
dp
;
register
char
**
array
;
register
char
*
dp
;
register
char
**
array
;
register
int
nsubs
;
if
(
cp
==
NULL
)
...
...
@@ -1894,19 +2140,23 @@ static char **getfields(register char *cp)
array
=
(
char
**
)
(
void
*
)
emalloc
((
int
)
((
strlen
(
cp
)
+
1
)
*
sizeof
*
array
));
nsubs
=
0
;
for
(
;
;
)
{
for
(;;)
{
while
(
isascii
(
*
cp
)
&&
isspace
((
unsigned
char
)
*
cp
))
++
cp
;
if
(
*
cp
==
'\0'
||
*
cp
==
'#'
)
break
;
array
[
nsubs
++
]
=
dp
=
cp
;
do
{
do
{
if
((
*
dp
=
*
cp
++
)
!=
'"'
)
++
dp
;
else
while
((
*
dp
=
*
cp
++
)
!=
'"'
)
else
while
((
*
dp
=
*
cp
++
)
!=
'"'
)
if
(
*
dp
!=
'\0'
)
++
dp
;
else
error
(
_
(
"Odd number of quotation marks"
));
else
error
(
_
(
"Odd number of quotation marks"
));
}
while
(
*
cp
!=
'\0'
&&
*
cp
!=
'#'
&&
(
!
isascii
(
*
cp
)
||
!
isspace
((
unsigned
char
)
*
cp
)));
if
(
isascii
(
*
cp
)
&&
isspace
((
unsigned
char
)
*
cp
))
...
...
@@ -1917,19 +2167,22 @@ static char **getfields(register char *cp)
return
array
;
}
static
long
oadd
(
const
long
t1
,
const
long
t2
)
static
long
oadd
(
const
long
t1
,
const
long
t2
)
{
register
long
t
;
t
=
t1
+
t2
;
if
((
t2
>
0
&&
t
<=
t1
)
||
(
t2
<
0
&&
t
>=
t1
))
{
if
((
t2
>
0
&&
t
<=
t1
)
||
(
t2
<
0
&&
t
>=
t1
))
{
error
(
_
(
"time overflow"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
return
t
;
}
static
time_t
tadd
(
const
time_t
t1
,
const
long
t2
)
static
time_t
tadd
(
const
time_t
t1
,
const
long
t2
)
{
register
time_t
t
;
...
...
@@ -1938,7 +2191,8 @@ static time_t tadd(const time_t t1, const long t2)
if
(
t1
==
min_time
&&
t2
<
0
)
return
min_time
;
t
=
t1
+
t2
;
if
((
t2
>
0
&&
t
<=
t1
)
||
(
t2
<
0
&&
t
>=
t1
))
{
if
((
t2
>
0
&&
t
<=
t1
)
||
(
t2
<
0
&&
t
>=
t1
))
{
error
(
_
(
"time overflow"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -1950,9 +2204,12 @@ static time_t tadd(const time_t t1, const long t2)
** 1970, 00:00 LOCAL time - in that year that the rule refers to.
*/
static
time_t
rpytime
(
register
const
struct
rule
*
rp
,
register
const
int
wantedy
)
static
time_t
rpytime
(
register
const
struct
rule
*
rp
,
register
const
int
wantedy
)
{
register
int
y
,
m
,
i
;
register
int
y
,
m
,
i
;
register
long
dayoff
;
/* with a nod to Margaret O. */
register
time_t
t
;
...
...
@@ -1963,60 +2220,74 @@ static time_t rpytime(register const struct rule *rp, register const int wantedy
dayoff
=
0
;
m
=
TM_JANUARY
;
y
=
EPOCH_YEAR
;
while
(
wantedy
!=
y
)
{
if
(
wantedy
>
y
)
{
while
(
wantedy
!=
y
)
{
if
(
wantedy
>
y
)
{
i
=
len_years
[
isleap
(
y
)];
++
y
;
}
else
{
}
else
{
--
y
;
i
=
-
len_years
[
isleap
(
y
)];
}
dayoff
=
oadd
(
dayoff
,
eitol
(
i
));
}
while
(
m
!=
rp
->
r_month
)
{
while
(
m
!=
rp
->
r_month
)
{
i
=
len_months
[
isleap
(
y
)][
m
];
dayoff
=
oadd
(
dayoff
,
eitol
(
i
));
++
m
;
}
i
=
rp
->
r_dayofmonth
;
if
(
m
==
TM_FEBRUARY
&&
i
==
29
&&
!
isleap
(
y
))
{
if
(
m
==
TM_FEBRUARY
&&
i
==
29
&&
!
isleap
(
y
))
{
if
(
rp
->
r_dycode
==
DC_DOWLEQ
)
--
i
;
else
{
else
{
error
(
_
(
"use of 2/29 in non leap-year"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
}
--
i
;
dayoff
=
oadd
(
dayoff
,
eitol
(
i
));
if
(
rp
->
r_dycode
==
DC_DOWGEQ
||
rp
->
r_dycode
==
DC_DOWLEQ
)
{
if
(
rp
->
r_dycode
==
DC_DOWGEQ
||
rp
->
r_dycode
==
DC_DOWLEQ
)
{
register
long
wday
;
#define LDAYSPERWEEK ((long) DAYSPERWEEK)
wday
=
eitol
(
EPOCH_WDAY
);
/*
*
* Don't trust mod of negative numbers.
*
* Don't trust mod of negative numbers.
*/
if
(
dayoff
>=
0
)
wday
=
(
wday
+
dayoff
)
%
LDAYSPERWEEK
;
else
{
else
{
wday
-=
((
-
dayoff
)
%
LDAYSPERWEEK
);
if
(
wday
<
0
)
wday
+=
LDAYSPERWEEK
;
}
while
(
wday
!=
eitol
(
rp
->
r_wday
))
if
(
rp
->
r_dycode
==
DC_DOWGEQ
)
{
if
(
rp
->
r_dycode
==
DC_DOWGEQ
)
{
dayoff
=
oadd
(
dayoff
,
(
long
)
1
);
if
(
++
wday
>=
LDAYSPERWEEK
)
wday
=
0
;
++
i
;
}
else
{
}
else
{
dayoff
=
oadd
(
dayoff
,
(
long
)
-
1
);
if
(
--
wday
<
0
)
wday
=
LDAYSPERWEEK
-
1
;
--
i
;
}
if
(
i
<
0
||
i
>=
len_months
[
isleap
(
y
)][
m
])
{
if
(
i
<
0
||
i
>=
len_months
[
isleap
(
y
)][
m
])
{
error
(
_
(
"no day in month matches rule"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -2027,16 +2298,19 @@ static time_t rpytime(register const struct rule *rp, register const int wantedy
return
min_time
;
if
(
dayoff
>
max_time
/
SECSPERDAY
)
return
max_time
;
t
=
(
time_t
)
dayoff
*
SECSPERDAY
;
t
=
(
time_t
)
dayoff
*
SECSPERDAY
;
return
tadd
(
t
,
rp
->
r_tod
);
}
static
void
newabbr
(
const
char
*
string
)
static
void
newabbr
(
const
char
*
string
)
{
register
int
i
;
i
=
strlen
(
string
)
+
1
;
if
(
charcnt
+
i
>
TZ_MAX_CHARS
)
{
if
(
charcnt
+
i
>
TZ_MAX_CHARS
)
{
error
(
_
(
"too many, or too long, time zone abbreviations"
));
(
void
)
exit
(
EXIT_FAILURE
);
}
...
...
@@ -2044,39 +2318,46 @@ static void newabbr(const char *string)
charcnt
+=
eitol
(
i
);
}
static
int
mkdirs
(
char
*
argname
)
static
int
mkdirs
(
char
*
argname
)
{
register
char
*
name
;
register
char
*
cp
;
register
char
*
name
;
register
char
*
cp
;
if
(
argname
==
NULL
||
*
argname
==
'\0'
)
return
0
;
cp
=
name
=
ecpyalloc
(
argname
);
while
((
cp
=
strchr
(
cp
+
1
,
'/'
))
!=
0
)
{
while
((
cp
=
strchr
(
cp
+
1
,
'/'
))
!=
0
)
{
*
cp
=
'\0'
;
#ifdef WIN32
/*
*
* DOS drive specifier?
*
* DOS drive specifier?
*/
if
(
isalpha
((
unsigned
char
)
name
[
0
])
&&
name
[
1
]
==
':'
&&
name
[
2
]
==
'\0'
)
{
name
[
1
]
==
':'
&&
name
[
2
]
==
'\0'
)
{
*
cp
=
'/'
;
continue
;
}
#endif
/* WIN32 */
if
(
!
itsdir
(
name
))
{
if
(
!
itsdir
(
name
))
{
/*
** It doesn't seem to exist, so we try to create it.
** Creation may fail because of the directory being
** created by some other multiprocessor, so we get
** to do extra
checking.
* * It doesn't seem to exist, so we try to create it. *
* Creation may fail because of the directory being * created
* by some other multiprocessor, so we get * to do extra
*
checking.
*/
if
(
mkdir
(
name
,
MKDIR_UMASK
)
!=
0
)
{
if
(
mkdir
(
name
,
MKDIR_UMASK
)
!=
0
)
{
const
char
*
e
=
strerror
(
errno
);
if
(
errno
!=
EEXIST
||
!
itsdir
(
name
))
{
if
(
errno
!=
EEXIST
||
!
itsdir
(
name
))
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: Can't create directory %s: %s
\n
"
),
_
(
"%s: Can't create directory %s: %s
\n
"
),
progname
,
name
,
e
);
ifree
(
name
);
return
-
1
;
...
...
@@ -2089,12 +2370,14 @@ _("%s: Can't create directory %s: %s\n"),
return
0
;
}
static
long
eitol
(
const
int
i
)
static
long
eitol
(
const
int
i
)
{
long
l
;
l
=
i
;
if
((
i
<
0
&&
l
>=
0
)
||
(
i
==
0
&&
l
!=
0
)
||
(
i
>
0
&&
l
<=
0
))
{
if
((
i
<
0
&&
l
>=
0
)
||
(
i
==
0
&&
l
!=
0
)
||
(
i
>
0
&&
l
<=
0
))
{
(
void
)
fprintf
(
stderr
,
_
(
"%s: %d did not sign extend correctly
\n
"
),
progname
,
i
);
...
...
@@ -2112,10 +2395,11 @@ static long eitol(const int i)
/*
* To run on win32
*/
int
link
(
const
char
*
oldpath
,
const
char
*
newpath
)
{
if
(
!
CopyFileEx
(
oldpath
,
newpath
,
NULL
,
NULL
,
FALSE
,
0
))
{
int
link
(
const
char
*
oldpath
,
const
char
*
newpath
)
{
if
(
!
CopyFileEx
(
oldpath
,
newpath
,
NULL
,
NULL
,
FALSE
,
0
))
return
-
1
;
}
return
0
;
}
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment