X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f X-Recipient: djgpp-workers AT delorie DOT com X-Authenticated: #27081556 X-Provags-ID: V01U2FsdGVkX1/Ng74aLg7N85fGkW47ZoeYA2m0vKi0EcU32piCqU tTBHPwTJ71LjAd Message-ID: <50BE3D72.2050701@gmx.de> Date: Tue, 04 Dec 2012 19:14:10 +0100 From: Juan Manuel Guerrero User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2 MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Re: Updating djgpp's timezone code to version 2012j References: <50BE3C71 DOT 4010708 AT gmx DOT de> In-Reply-To: <50BE3C71.4010708@gmx.de> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Y-GMX-Trusted: 0 Reply-To: djgpp-workers AT delorie DOT com Second part of patch. diff -aprNU5 djgpp.orig/zoneinfo/src/makefile djgpp/zoneinfo/src/makefile --- djgpp.orig/zoneinfo/src/makefile 2012-12-01 22:59:32 +0000 +++ djgpp/zoneinfo/src/makefile 2012-12-01 23:04:28 +0000 @@ -40,35 +40,46 @@ POSIXRULES= America/New_York # Also see TZDEFRULESTRING below, which takes effect only # if the time zone files cannot be accessed. # Everything gets put in subdirectories of. . . -TOPDIR= /usr/local +TOPDIR= ../.. # "Compiled" time zone information is placed in the "TZDIR" directory # (and subdirectories). # Use an absolute path name for TZDIR unless you're just testing the software. -TZDIR= $(TOPDIR)/etc/zoneinfo +TZDIR= $(TOPDIR)/zoneinfo # The "tzselect", "zic", and "zdump" commands get installed in. . . ETCDIR= $(TOPDIR)/etc # If you "make INSTALL", the "date" command gets installed in. . . -BINDIR= $(TOPDIR)/bin +BINDIR= $(TOPDIR)/etc # Manual pages go in subdirectories of. . . -MANDIR= $(TOPDIR)/man +SHAREDIR= $(TOPDIR)/share +MANDIR= $(SHAREDIR)/man # Library functions are put in an archive in LIBDIR. LIBDIR= $(TOPDIR)/lib TZLIB= $(LIBDIR)/libtz.a +# This defines several variables that enable zoneinfo/src/* files to be +# built both natively and with cross-tools on Unix. + +include $(TOPDIR)/src/makefile.def +export CROSS_BUILD + +# A replacement for (possibly missing) Unix programs: + +UTIL= $(TOPDIR)/src/misc.exe + # If you always want time values interpreted as "seconds since the epoch # (not counting leap seconds)", use # REDO= posix_only # below. If you always want right time values interpreted as "seconds since # the epoch" (counting leap seconds)", use @@ -81,11 +92,11 @@ TZLIB= $(LIBDIR)/libtz.a # REDO= right_posix # below. # POSIX mandates that leap seconds not be counted; for compatibility with it, # use either "posix_only" or "posix_right". -REDO= posix_right +REDO= posix_only # Since "." may not be in PATH... YEARISTYPE= ./yearistype @@ -119,11 +130,11 @@ LDLIBS= # if you do not want run time warnings about formats that may cause # year 2000 grief # -DZIC_MAX_ABBR_LEN_WO_WARN=3 # (or some other number) to set the maximum time zone abbreviation length # that zic will accept without a warning (the default is 6) -GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \ +GCC_DEBUG_FLAGS = -Dlint -g -fno-common -fstrict-aliasing \ -Wall -Wextra \ -Wbad-function-cast -Wcast-align -Wcast-qual \ -Wformat=2 -Winit-self \ -Wmissing-declarations -Wmissing-noreturn -Wmissing-prototypes \ -Wnested-externs \ @@ -223,22 +234,30 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-co # to the end of the "CFLAGS=" line. This causes "strftime" to always return # 53 as a week number (rather than 52 or 53) for those days in January that # before the first Monday in January when a "%V" format is used and January 1 # falls on a Friday, Saturday, or Sunday. -CFLAGS= +CFLAGS= -DHAVE_ADJTIME=0 -DHAVE_LONG_DOUBLE=1 -DHAVE_SETTIMEOFDAY=1 \ + -DHAVE_STRERROR=1 -DHAVE_SYMLINK=0 \ + -DSTD_INSPIRED \ + -DLOCALE_HOME=\"/dev/env/DJDIR~c:/djgpp~/share/locale\" \ + $(GCC_DEBUG_FLAGS) -O2 + +# Don't use -s here, since "gcc -s" on DJ's Irix machine dumps core +# when invoked with -s. To work around, we use strip explicitly. +LFLAGS= # Linker flags. Default to $(LFLAGS) for backwards compatibility # to tzcode2012h and earlier. LDFLAGS= $(LFLAGS) - -zic= ./zic +EXEEXT= .exe +zic= ./host-zic ZIC= $(zic) $(ZFLAGS) # The name of a Posix-compliant `awk' on your system. -AWK= awk +AWK= gawk # The full path name of a Posix-compliant shell that supports the Korn shell's # 'select' statement, as an extension. These days, Bash is the most popular. KSHELL= /bin/bash @@ -272,24 +291,24 @@ TARFLAGS= `if tar $(GNUTARFLAGS) --versi # Flags to give 'gzip' when making a distribution. GZIPFLAGS= -9n ############################################################################### -cc= cc -CC= $(cc) -DTZDIR=\"$(TZDIR)\" +cc= $(CROSS_GCC) +CC= $(cc) -DTZDIR=\"/dev/env/DJDIR~c:/djgpp~/zoneinfo\" 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 -DATESRCS= date.c localtime.c strftime.c asctime.c -DATEOBJS= date.o localtime.o strftime.o asctime.o +DATESRCS= date.c localtime.c logwtmp.c strftime.c asctime.c +DATEOBJS= date.o localtime.o logwtmp.o strftime.o asctime.o LIBSRCS= localtime.c asctime.c difftime.c LIBOBJS= localtime.o asctime.o difftime.o HEADERS= tzfile.h private.h NONLIBSRCS= zic.c zdump.c scheck.c ialloc.c -NEWUCBSRCS= date.c strftime.c +NEWUCBSRCS= date.c logwtmp.c strftime.c SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) tzselect.ksh MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \ tzfile.5 tzselect.8 zic.8 zdump.8 COMMON= Makefile DOCS= README Theory $(MANS) date.1 @@ -300,68 +319,88 @@ NDATA= systemv factory SDATA= solar87 solar88 solar89 TDATA= $(YDATA) $(NDATA) $(SDATA) TABDATA= iso3166.tab zone.tab DATA= $(YDATA) $(NDATA) $(SDATA) $(TABDATA) leapseconds yearistype.sh WEB_PAGES= tz-art.htm tz-link.htm -MISC= usno1988 usno1989 usno1989a usno1995 usno1997 usno1998 \ +MISC= usno1988 usno1989 usno1989.orig usno1995 usno1997 usno1998 \ $(WEB_PAGES) checktab.awk workman.sh \ zoneinfo2tdf.pl ENCHILADA= $(COMMON) $(DOCS) $(SOURCES) $(DATA) $(MISC) # And for the benefit of csh users on systems that assume the user # shell should be used to handle commands in Makefiles. . . SHELL= /bin/sh -all: tzselect zic zdump $(LIBOBJS) - -ALL: all date +INSTALL: ALL install date.1 + -$(UTIL) mkdir $(TOPDIR) + -$(UTIL) mkdir $(BINDIR) + $(UTIL) cp date$(EXEEXT) $(BINDIR)/date$(EXEEXT) + -$(UTIL) mkdir $(SHAREDIR) + -$(UTIL) mkdir $(MANDIR) + -$(UTIL) mkdir $(MANDIR)/man1 + -$(UTIL) rm $(MANDIR)/man1/date.1 + $(UTIL) cp date.1 $(MANDIR)/man1/date.1 install: all $(DATA) $(REDO) $(TZLIB) $(MANS) $(TABDATA) $(ZIC) -y $(YEARISTYPE) \ -d $(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES) - -rm -f $(TZDIR)/iso3166.tab $(TZDIR)/zone.tab - cp iso3166.tab zone.tab $(TZDIR)/. - -mkdir $(TOPDIR) $(ETCDIR) - cp tzselect zic zdump $(ETCDIR)/. - -mkdir $(TOPDIR) $(MANDIR) \ - $(MANDIR)/man3 $(MANDIR)/man5 $(MANDIR)/man8 - -rm -f $(MANDIR)/man3/newctime.3 \ + -$(UTIL) rm -f $(TZDIR)/iso3166.tab $(TZDIR)/zone.tab + $(UTIL) cp iso3166.tab $(TZDIR)/iso3166.tab + $(UTIL) cp zone.tab $(TZDIR)/zone.tab + -$(UTIL) mkdir $(TOPDIR) + -$(UTIL) mkdir $(ETCDIR) + $(UTIL) cp zic$(EXEEXT) $(ETCDIR)/zic$(EXEEXT) + $(UTIL) cp zdump$(EXEEXT) $(ETCDIR)/zdump$(EXEEXT) + $(UTIL) cp tzselect $(ETCDIR)/tzselect + -$(UTIL) mkdir $(SHAREDIR) + -$(UTIL) mkdir $(MANDIR) + -$(UTIL) mkdir $(MANDIR)/man3 + -$(UTIL) mkdir $(MANDIR)/man5 + -$(UTIL) mkdir $(MANDIR)/man8 + -$(UTIL) rm -f $(MANDIR)/man3/newctime.3 \ $(MANDIR)/man3/newtzset.3 \ $(MANDIR)/man5/tzfile.5 \ $(MANDIR)/man8/tzselect.8 \ $(MANDIR)/man8/zdump.8 \ $(MANDIR)/man8/zic.8 - cp newctime.3 newtzset.3 $(MANDIR)/man3/. - cp tzfile.5 $(MANDIR)/man5/. - cp tzselect.8 zdump.8 zic.8 $(MANDIR)/man8/. + $(UTIL) cp newctime.3 $(MANDIR)/man3/newctime.3 + $(UTIL) cp newtzset.3 $(MANDIR)/man3/newtzset.3 + $(UTIL) cp time2posix.3 $(MANDIR)/time2posix.3 + $(UTIL) cp tzfile.5 $(MANDIR)/man5/tzfile.5 + $(UTIL) cp tzselect.8 $(MANDIR)/man8/tzselect.8 + $(UTIL) cp zdump.8 $(MANDIR)/man8/zdump.8 + $(UTIL) cp zic.8 $(MANDIR)/man8/zic.8 -INSTALL: ALL install date.1 - -mkdir $(TOPDIR) $(BINDIR) - cp date $(BINDIR)/. - -mkdir $(TOPDIR) $(MANDIR) $(MANDIR)/man1 - -rm -f $(MANDIR)/man1/date.1 - cp date.1 $(MANDIR)/man1/. +all: host-zic zic$(EXEEXT) zdump$(EXEEXT) $(LIBOBJS) + +ALL: all date$(EXEEXT) tzselect version.h: (echo 'static char const PKGVERSION[]="($(PACKAGE)) ";' && \ echo 'static char const TZVERSION[]="$(VERSION)";') >$@ -zdump: $(TZDOBJS) +zdump$(EXEEXT): $(TZDOBJS) $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZDOBJS) $(LDLIBS) + $(CROSS_STRIP) $@ -zic: $(TZCOBJS) yearistype +host-zic: $(TZCSRCS) yearistype version.h + $(GCC) -DTZDIR=\"/dev/env/DJDIR~c:/djgpp~/zoneinfo\" \ + $(CFLAGS) $(LDFLAGS) $(TZCSRCS) $(LDLIBS) -o $@ + $(CROSS_STRIP) $@ + +zic$(EXEEXT): $(TZCOBJS) yearistype $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(TZCOBJS) $(LDLIBS) + $(CROSS_STRIP) $@ yearistype: yearistype.sh - cp yearistype.sh yearistype - chmod +x yearistype + $(UTIL) cp yearistype.sh yearistype -posix_only: zic $(TDATA) +posix_only: $(zic) $(TDATA) $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA) -right_only: zic leapseconds $(TDATA) +right_only: $(zic) leapseconds $(TDATA) $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA) # In earlier versions of this makefile, the other two directories were # subdirectories of $(TZDIR). However, this led to configuration errors. # For example, with posix_right under the earlier scheme, @@ -369,11 +408,11 @@ right_only: zic leapseconds $(TDATA) # but gmtime without leap seconds, which led to problems with applications # like sendmail that subtract gmtime from localtime. # Therefore, the other two directories are now siblings of $(TZDIR). # You must replace all of $(TZDIR) to switch from not using leap seconds # to using them, or vice versa. -other_two: zic leapseconds $(TDATA) +other_two: $(zic) leapseconds $(TDATA) $(ZIC) -y $(YEARISTYPE) -d $(TZDIR)-posix -L /dev/null $(TDATA) $(ZIC) -y $(YEARISTYPE) \ -d $(TZDIR)-leaps -L leapseconds $(TDATA) posix_right: posix_only other_two @@ -381,48 +420,52 @@ posix_right: posix_only other_two right_posix: right_only other_two zones: $(REDO) $(TZLIB): $(LIBOBJS) - -mkdir $(TOPDIR) $(LIBDIR) - ar ru $@ $(LIBOBJS) - if [ -x /usr/ucb/ranlib ] || [ -x /usr/bin/ranlib ]; \ - then ranlib $@ ; fi - -date: $(DATEOBJS) - $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(DATEOBJS) $(LDLIBS) + -$(UTIL) mkdir $(TOPDIR) + -$(UTIL) mkdir $(LIBDIR) + $(CROSS_AR) rus $@ $(LIBOBJS) + +# We use the system's logwtmp in preference to ours if available. + +date$(EXEEXT): $(DATEOBJS) + $(CROSS_AR) rs logwtmpl.a logwtmp.o + $(CC) $(CFLAGS) date.o localtime.o asctime.o strftime.o \ + $(LDLIBS) -lc logwtmpl.a -o $@ + $(CROSS_STRIP) $@ + $(UTIL) rm logwtmpl.a + $(CROSS_STRIP) $@ tzselect: tzselect.ksh sed \ - -e 's|#!/bin/bash|#!$(KSHELL)|g' \ -e 's|AWK=[^}]*|AWK=$(AWK)|g' \ -e 's|\(PKGVERSION\)=.*|\1='\''($(PACKAGE)) '\''|' \ - -e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \ + -e 's|TZDIR=[^}]*|TZDIR=/dev/env/DJDIR/zoneinfo|' \ -e 's|\(TZVERSION\)=.*|\1=$(VERSION)|' \ <$? >$@ - chmod +x $@ check: check_tables check_web check_tables: checktab.awk $(PRIMARY_YDATA) $(AWK) -f checktab.awk $(PRIMARY_YDATA) check_web: $(WEB_PAGES) $(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES) clean: - rm -f core *.o *.out \ - date tzselect version.h zdump zic yearistype - rm -f -r tzpublic + $(UTIL) rm core *.o *.out tzselect zdump$(EXEEXT) zic$(EXEEXT) \ + yearistype date$(EXEEXT) logwtmpl* *.tar.gz host-zic *.exe + $(UTIL) rm -f -r tzpublic maintainer-clean: clean @echo 'This command is intended for maintainers to use; it' @echo 'deletes files that may need special tools to rebuild.' rm -f *.[1-8].txt *.asc *.tar.gz names: - @echo $(ENCHILADA) + @$(UTIL) echo $(ENCHILADA) public: check check_public set-timestamps tarballs signatures # Set the time stamps to those of the git repository, if available, # and if the files have not changed since then. diff -aprNU5 djgpp.orig/zoneinfo/src/private.h djgpp/zoneinfo/src/private.h --- djgpp.orig/zoneinfo/src/private.h 2012-12-01 22:59:32 +0000 +++ djgpp/zoneinfo/src/private.h 2012-12-01 23:04:28 +0000 @@ -171,10 +171,30 @@ extern char * asctime_r(struct tm const char * icatalloc(char * old, const char * new); char * icpyalloc(const char * string); const char * scheck(const char * string, const char * format); /* +** Declarations for functions which shut up GCC $(GCC_DEBUG_FLAGS). +*/ +#ifndef STD_INSPIRED +static +#endif /* !defined STD_INSPIRED */ +void tzsetwall(void); +struct tm *localtime_r(const time_t * const __timep, struct tm * __tmp); +struct tm *gmtime_r(const time_t * const __tp, struct tm * __tm); +char *ctime_r(const time_t * const __tp, char * __buf); +char *asctime_r(const struct tm *, char *); +#ifdef STD_INSPIRED +struct tm *offtime(const time_t * const __tp, const long __off); +time_t timelocal(struct tm * const __tmp); +time_t timegm(struct tm * const __tmp); +time_t timeoff(struct tm * const __tmp, const long __off); +time_t time2posix(time_t); +time_t posix2time(time_t); +#endif /* defined STD_INSPIRED */ + +/* ** Finally, some convenience items. */ #ifndef TRUE #define TRUE 1 @@ -235,10 +255,20 @@ const char * scheck(const char * string, #ifndef GNUC_or_lint #define INITIALIZE(x) #endif /* !defined GNUC_or_lint */ #endif /* !defined INITIALIZE */ +#ifdef __MSDOS__ +#define IS_SLASH(c) ((c) == '/' || (c) == '\\') +#define HAS_DEVICE(n) ((n)[0] && (n)[1] == ':') +#define IS_ABSOLUTE(n) (IS_SLASH((n)[0]) || HAS_DEVICE(n)) +#undef TZDIR +#define TZDIR (getenv("TZDIR") ? getenv("TZDIR") : "/dev/env/DJDIR/zoneinfo") +#else /* !__MSDOS__ */ +#define HAS_DEVICE(n) 0 +#endif /* !__MSDOS__ */ + /* ** For the benefit of GNU folk... ** `_(MSGID)' uses the current locale's message library string for MSGID. ** The default is to use gettext if available, and use MSGID otherwise. */ diff -aprNU5 djgpp.orig/zoneinfo/src/strftime.c djgpp/zoneinfo/src/strftime.c --- djgpp.orig/zoneinfo/src/strftime.c 2012-12-01 22:59:32 +0000 +++ djgpp/zoneinfo/src/strftime.c 2012-12-01 23:04:28 +0000 @@ -1,5 +1,9 @@ +#ifndef __DJGPP__ +/* Use DJGPP's own implementation of strftime. */ + + #include "private.h" /* ** Copyright (c) 1989 The Regents of the University of California. ** All rights reserved. @@ -729,5 +733,6 @@ no_locale: localebuf = C_time_locale; locale_buf = NULL; return &localebuf; } #endif /* defined LOCALE_HOME */ +#endif /* !__DJGPP__ */ diff -aprNU5 djgpp.orig/zoneinfo/src/zdump.c djgpp/zoneinfo/src/zdump.c --- djgpp.orig/zoneinfo/src/zdump.c 2012-12-01 22:59:32 +0000 +++ djgpp/zoneinfo/src/zdump.c 2012-12-01 23:04:28 +0000 @@ -563,11 +563,11 @@ show(char *zone, time_t t, int v) if (*abbr(tmp) != '\0') (void) printf(" %s", abbr(tmp)); if (v) { (void) printf(" isdst=%d", tmp->tm_isdst); #ifdef TM_GMTOFF - (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); + (void) printf(" gmtoff=%ld", (long)tmp->TM_GMTOFF); #endif /* defined TM_GMTOFF */ } } (void) printf("\n"); if (tmp != NULL && *abbr(tmp) != '\0') diff -aprNU5 djgpp.orig/zoneinfo/src/zic.c djgpp/zoneinfo/src/zic.c --- djgpp.orig/zoneinfo/src/zic.c 2012-12-01 22:59:32 +0000 +++ djgpp/zoneinfo/src/zic.c 2012-12-01 23:04:28 +0000 @@ -17,17 +17,34 @@ typedef int_fast64_t zic_t; #endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ #if HAVE_SYS_STAT_H #include "sys/stat.h" #endif +#if HAVE_SYS_WAIT_H +#include "sys/wait.h" +#ifndef WEXITSTATUS +#define WEXITSTATUS(x) (((x) >> 8) & 0xff) +#endif +#endif #ifdef S_IRUSR #define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) #else #define MKDIR_UMASK 0755 #endif /* +** Portable testing for absolute file names. +*/ + +#ifndef IS_SLASH +#define IS_SLASH(c) ((c) == '/') +#endif +#ifndef IS_ABSOLUTE +#define IS_ABSOLUTE(n) (IS_SLASH((n)[0])) +#endif + +/* ** On some ancient hosts, predicates like `isspace(C)' are defined ** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, ** which says they are defined only if C == ((unsigned char) C) || C == EOF. ** Neither the C Standard nor Posix require that `isascii' exist. ** For portability, we check both ancient and modern requirements. @@ -580,24 +597,38 @@ static void dolink(const char *const fromfield, const char *const tofield) { register char * fromname; register char * toname; - if (fromfield[0] == '/') + if (IS_ABSOLUTE(fromfield)) fromname = ecpyalloc(fromfield); else { fromname = ecpyalloc(directory); fromname = ecatalloc(fromname, "/"); fromname = ecatalloc(fromname, fromfield); } - if (tofield[0] == '/') + if (IS_ABSOLUTE(tofield)) toname = ecpyalloc(tofield); else { toname = ecpyalloc(directory); toname = ecatalloc(toname, "/"); toname = ecatalloc(toname, tofield); } + /* Some zone names use `+' as part of their names, but DOS + doesn't allow `+' in file names. Replace with a `%'. */ + if (getenv ("COMSPEC") || getenv ("CROSS_BUILD")) + { + char *p; + + for (p = fromname; *p; p++) + if (*p == '+') + *p = '%'; + for (p = toname; *p; p++) + if (*p == '+') + *p = '%'; + } + /* ** We get to be careful here since ** there's a fair chance of root running us. */ if (!itsdir(toname)) @@ -649,17 +680,24 @@ static const zic_t min_time = (zic_t) -1 static const zic_t max_time = -1 - ((zic_t) -1 << (TIME_T_BITS_IN_FILE - 1)); static int itsdir(const char *const name) { - register char * myname; register int accres; +#ifdef D_OK + /* MS-DOS/MS-Windows normalize "foo/." to "foo" before testing, + so we think foo is a directory. Use D_OK instead. */ + accres = access(name, D_OK); +#else + register char * myname; + myname = ecpyalloc(name); myname = ecatalloc(myname, "/."); accres = access(myname, F_OK); free(myname); +#endif return accres == 0; } /* ** Associate sets of rules with zones. @@ -1469,11 +1507,26 @@ writezone(const char *const name, const --leapcnt32; ++leapi32; } fullname = erealloc(fullname, strlen(directory) + 1 + strlen(name) + 1); - (void) sprintf(fullname, "%s/%s", directory, name); + + /* Some zone names use `+' as part of their names, but DOS + doesn't allow `+' in file names. Replace with a `%'. */ + if (getenv ("COMSPEC") || getenv ("CROSS_BUILD")) + { + char new_name[FILENAME_MAX + 1], *p; + + strcpy(new_name, name); + for (p = new_name; *p; p++) + if (*p == '+') + *p = '%'; + (void) sprintf(fullname, "%s/%s", directory, new_name); + } + else + (void) sprintf(fullname, "%s/%s", directory, name); + /* ** Remove old file, if any, to snap links. */ if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT) { const char *e = strerror(errno); @@ -2573,42 +2626,40 @@ mkdirs(char *argname) register char * cp; if (argname == NULL || *argname == '\0') return 0; cp = name = ecpyalloc(argname); - while ((cp = strchr(cp + 1, '/')) != 0) { - *cp = '\0'; -#ifndef unix - /* - ** DOS drive specifier? - */ - if (isalpha((unsigned char) name[0]) && - name[1] == ':' && name[2] == '\0') { - *cp = '/'; - continue; - } -#endif /* !defined unix */ - 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. - */ - if (mkdir(name, MKDIR_UMASK) != 0) { - const char *e = strerror(errno); - - if (errno != EEXIST || !itsdir(name)) { - (void) fprintf(stderr, -_("%s: Can't create directory %s: %s\n"), - progname, name, e); - free(name); - return -1; - } - } - } - *cp = '/'; + /* + ** Get past a DOS-style drive specifier, if any. + */ + if (HAS_DEVICE(name)) + cp += 2; + while (*cp++) { + if (IS_SLASH(*cp)) { + *cp = '\0'; + 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. + */ + if (mkdir(name, MKDIR_UMASK) != 0) { + const char *e = strerror(errno); + + if (errno != EEXIST || !itsdir(name)) { + (void) fprintf(stderr, + _("%s: Can't create directory %s: %s\n"), + progname, name, e); + free(name); + return -1; + } + } + } + *cp = '/'; + } } free(name); return 0; }