1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2026-05-06 15:06:15 +00:00

build: port to MinGW and fix symlink bugs

MinGW problem reported by Theo Veenker in
<http://mm.icann.org/pipermail/tz/2013-September/020378.html>.
The patched code should work even on POSIXish hosts
where 'link' and 'symlink' fail for whatever reason,
e.g., if the destination file system is VFAT.
Also, the patch fixes some bugs when symlinks are used.
* Makefile (CFLAGS): Mention HAVE_LINK in the comment.
(TZDSRCS): Add asctime.o, since MinGW lacks asctime.
(TZDOBJS): Add asctime.c.
* private.h (HAVE_LINK): Default to 1.
* zic.c (link) [!HAVE_LINK]: New macro.
(symlink) [!HAVE_SYMLINK]: New macro.
(dolink): Fix some bugs when 'link' fails but 'symlink' succeeds.
Fall back on copying when both fail.
* NEWS: Document the above.
This commit is contained in:
Paul Eggert
2013-09-25 17:49:49 -07:00
parent a5851f83d3
commit dad4eed8a8
4 changed files with 69 additions and 21 deletions

View File

@@ -107,6 +107,7 @@ LDLIBS=
# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares
# ctime_r and asctime_r incompatibly with the POSIX standard (Solaris 8).
# -DHAVE_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h"
# -DHAVE_LINK=0 if your system lacks a link function
# -DHAVE_SETTIMEOFDAY=0 if settimeofday does not exist (SVR0?)
# -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4)
# -DHAVE_SETTIMEOFDAY=2 if settimeofday uses 2nd arg (4.3BSD)
@@ -299,8 +300,8 @@ CC= $(cc) -DTZDIR=\"$(TZDIR)\"
TZCSRCS= zic.c localtime.c asctime.c scheck.c ialloc.c
TZCOBJS= zic.o localtime.o asctime.o scheck.o ialloc.o
TZDSRCS= zdump.c localtime.c ialloc.c
TZDOBJS= zdump.o localtime.o ialloc.o
TZDSRCS= zdump.c localtime.c ialloc.c asctime.o
TZDOBJS= zdump.o localtime.o ialloc.o asctime.c
DATESRCS= date.c localtime.c strftime.c asctime.c
DATEOBJS= date.o localtime.o strftime.o asctime.o
LIBSRCS= localtime.c asctime.c difftime.c

6
NEWS
View File

@@ -3,6 +3,12 @@ News for the tz database
Unreleased, experimental changes
Changes affecting 'zic'
'zic' now runs on platforms that lack both hard links and symlinks.
(Thanks to Theo Veenker for reporting the problem, for MinGW.)
Also, fix some bugs on platforms that lack hard links but have symlinks.
Changes affecting the build procedure
The 'leapseconds' file is again put into the tzdata tarball.

View File

@@ -34,6 +34,10 @@
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
#ifndef HAVE_LINK
#define HAVE_LINK 1
#endif /* !defined HAVE_SYMLINK */
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */

69
zic.c
View File

@@ -107,6 +107,13 @@ extern int link(const char * fromname, const char * toname);
extern char * optarg;
extern int optind;
#if ! HAVE_LINK
# define link(from, to) (-1)
#endif
#if ! HAVE_SYMLINK
# define symlink(from, to) (-1)
#endif
static void addtt(zic_t starttime, int type);
static int addtype(zic_t gmtoff, const char * abbr, int isdst,
int ttisstd, int ttisgmt);
@@ -612,42 +619,72 @@ dolink(const char *const fromfield, const char *const tofield)
*/
if (!itsdir(toname))
(void) remove(toname);
if (link(fromname, toname) != 0) {
if (link(fromname, toname) != 0
&& access(fromname, F_OK) == 0 && !itsdir(fromname)) {
int result;
if (mkdirs(toname) != 0)
exit(EXIT_FAILURE);
result = link(fromname, toname);
#if HAVE_SYMLINK
if (result != 0 &&
access(fromname, F_OK) == 0 &&
!itsdir(fromname)) {
const char *s = tofield;
if (result != 0) {
const char *s = fromfield;
const char *t;
register char * symlinkcontents = NULL;
while ((s = strchr(s+1, '/')) != NULL)
do
t = s;
while ((s = strchr(s, '/'))
&& ! strncmp (fromfield, tofield,
++s - fromfield));
for (s = tofield + (t - fromfield);
(s = strchr(s, '/'));
s++)
symlinkcontents =
ecatalloc(symlinkcontents,
"../");
symlinkcontents =
ecatalloc(symlinkcontents,
fromname);
result = symlink(symlinkcontents,
toname);
symlinkcontents = ecatalloc(symlinkcontents, t);
result = symlink(symlinkcontents, toname);
if (result == 0)
warning(_("hard link failed, symbolic link used"));
free(symlinkcontents);
}
#endif /* HAVE_SYMLINK */
if (result != 0) {
FILE *fp, *tp;
int c;
fp = fopen(fromname, "rb");
if (!fp) {
const char *e = strerror(errno);
(void) fprintf(stderr,
_("%s: Can't link from %s to %s: %s\n"),
progname, fromname, toname, e);
_("%s: Can't read %s: %s\n"),
progname, fromname, e);
exit(EXIT_FAILURE);
}
tp = fopen(toname, "wb");
if (!tp) {
const char *e = strerror(errno);
(void) fprintf(stderr,
_("%s: Can't create %s: %s\n"),
progname, toname, e);
exit(EXIT_FAILURE);
}
while ((c = getc(fp)) != EOF)
putc(c, tp);
if (ferror(fp) || fclose(fp)) {
(void) fprintf(stderr,
_("%s: Error reading %s\n"),
progname, fromname);
exit(EXIT_FAILURE);
}
if (ferror(tp) || fclose(tp)) {
(void) fprintf(stderr,
_("%s: Error writing %s\n"),
progname, toname);
exit(EXIT_FAILURE);
}
warning(_("link failed, copy used"));
}
}
free(fromname);
free(toname);