summaryrefslogtreecommitdiff
path: root/Build/source/libs/libgnuw32
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/libgnuw32')
-rw-r--r--Build/source/libs/libgnuw32/Makefile.in88
-rw-r--r--Build/source/libs/libgnuw32/configure.in26
-rw-r--r--Build/source/libs/libgnuw32/depend.mak39
-rw-r--r--Build/source/libs/libgnuw32/dirent.c129
-rw-r--r--Build/source/libs/libgnuw32/error.c87
-rw-r--r--Build/source/libs/libgnuw32/filename.c392
-rw-r--r--Build/source/libs/libgnuw32/gnuw32.c523
-rw-r--r--Build/source/libs/libgnuw32/home.c115
-rw-r--r--Build/source/libs/libgnuw32/libgnuw32.rc36
-rw-r--r--Build/source/libs/libgnuw32/lookcmd.c778
-rwxr-xr-xBuild/source/libs/libgnuw32/lookcmd.exebin0 -> 36924 bytes
-rw-r--r--Build/source/libs/libgnuw32/oldnames.h469
-rw-r--r--Build/source/libs/libgnuw32/popen.c296
-rw-r--r--Build/source/libs/libgnuw32/stat.c248
-rw-r--r--Build/source/libs/libgnuw32/string.c100
-rw-r--r--Build/source/libs/libgnuw32/system.c307
-rw-r--r--Build/source/libs/libgnuw32/system_popen_check.c27
-rw-r--r--Build/source/libs/libgnuw32/time.c64
-rw-r--r--Build/source/libs/libgnuw32/user.c224
-rw-r--r--Build/source/libs/libgnuw32/volume.c244
-rw-r--r--Build/source/libs/libgnuw32/win32.mak82
-rw-r--r--Build/source/libs/libgnuw32/win32lib.h306
22 files changed, 4580 insertions, 0 deletions
diff --git a/Build/source/libs/libgnuw32/Makefile.in b/Build/source/libs/libgnuw32/Makefile.in
new file mode 100644
index 00000000000..38c02f34596
--- /dev/null
+++ b/Build/source/libs/libgnuw32/Makefile.in
@@ -0,0 +1,88 @@
+# Main Makefile for Gnu-win32 library
+# Copyright (C) 1999-2000 Fabrice Popineau
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+ac_include ../make/paths.mk
+ac_include ../make/makevars.mk
+ac_include ../make/common.mk
+ac_include ../make/library.mk
+ac_include ../make/programs.mk
+ac_include ../make/texi.mk
+
+# ??? replace these with your own list of files
+SOURCES=getopt.c \
+ getopt1.c \
+ popen.c \
+ stat.c \
+ system.c \
+ string.c \
+ filename.c \
+ dirent.c \
+ time.c \
+ user.c \
+ home.c \
+ volume.c \
+ lookcmd.c \
+ ghostscr.c
+
+# DOCS=
+MISC=configure mkinstalldirs install-sh aclocal.m4
+LIB_OBJS=$(SOURCES:.c=.o)
+
+# ??? replace with your targets
+all: libgnuw32.a
+
+# ??? here I make the bindir, libdir and infodir directories; you
+# might not need all of these. also, I assumed the names PROG and
+# libMYPROG.a for the program and library.
+install: all
+ $(top_srcdir)/mkinstalldirs $(bindir)
+ $(top_srcdir)/mkinstalldirs $(libdir)
+ $(top_srcdir)/mkinstalldirs $(infodir)
+ $(INSTALL) libgnuw32.a $(libdir)/libgnuw32.a
+
+uninstall:
+ /bin/rm -f $(libdir)/libgnuw32.a
+
+libgnuw32.a: $(LIB_OBJS)
+ /bin/rm -f libgnuw32.a
+ $(AR) $(AR_FLAGS) libgnuw32.a $(LIB_OBJS)
+ $(RANLIB) libgnuw32.a
+
+clean:
+ /bin/rm -f core *.o $(LIB_OBJS) libgnuw32.a
+
+distclean: clean
+ /bin/rm -f Makefile config.h config.status config.cache config.log \
+ marklib.dvi
+
+mostlyclean: clean
+
+maintainer-clean: clean
+
+# automatic re-running of configure if the ocnfigure.in file has changed
+${srcdir}/configure: configure.in
+ cd ${srcdir} && autoconf
+
+# autoheader might not change config.h.in, so touch a stamp file
+Makefile: Makefile.in config.status
+ ./config.status
+config.status: configure
+ ./config.status --recheck
+
+ac_include ../../make/rdepend.mk
+ac_include depend.mk
diff --git a/Build/source/libs/libgnuw32/configure.in b/Build/source/libs/libgnuw32/configure.in
new file mode 100644
index 00000000000..db5deebbf4b
--- /dev/null
+++ b/Build/source/libs/libgnuw32/configure.in
@@ -0,0 +1,26 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(dirent.c)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_CHECK_HEADERS(fcntl.h malloc.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_STRUCT_ST_RDEV
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_SETVBUF_REVERSED
+AC_CHECK_FUNCS(putenv strdup strtol)
+
+AC_OUTPUT(Makefile)
diff --git a/Build/source/libs/libgnuw32/depend.mak b/Build/source/libs/libgnuw32/depend.mak
new file mode 100644
index 00000000000..5d05226a364
--- /dev/null
+++ b/Build/source/libs/libgnuw32/depend.mak
@@ -0,0 +1,39 @@
+$(objdir)/popen.obj: \
+ win32lib.h
+
+$(objdir)/user.obj: \
+ win32lib.h
+
+$(objdir)/home.obj: \
+ win32lib.h
+
+$(objdir)/string.obj: \
+ win32lib.h
+
+$(objdir)/system_popen_check.obj: \
+ win32lib.h
+
+$(objdir)/stat.obj: \
+ win32lib.h
+
+$(objdir)/filename.obj: \
+ win32lib.h
+
+$(objdir)/error.obj: \
+ win32lib.h
+
+$(objdir)/dirent.obj: \
+ win32lib.h
+
+$(objdir)/volume.obj: \
+ win32lib.h
+
+$(objdir)/lookcmd.obj: \
+ win32lib.h
+
+$(objdir)/time.obj: \
+ win32lib.h
+
+$(objdir)/system.obj: \
+ win32lib.h
+
diff --git a/Build/source/libs/libgnuw32/dirent.c b/Build/source/libs/libgnuw32/dirent.c
new file mode 100644
index 00000000000..f47dfb14d2d
--- /dev/null
+++ b/Build/source/libs/libgnuw32/dirent.c
@@ -0,0 +1,129 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+#include <sys/dir.h>
+#include <win32lib.h>
+
+/* Emulate the Unix directory procedures opendir, closedir,
+ and readdir. We can't use the procedures supplied in sysdep.c,
+ so we provide them here. */
+
+struct direct dir_static; /* simulated directory contents */
+HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
+static int dir_is_fat;
+char dir_pathname[MAXPATHLEN+1];
+WIN32_FIND_DATA dir_find_data;
+
+DIR *
+opendir (const char *filename)
+{
+ DIR *dirp;
+
+ /* Opening is done by FindFirstFile. However, a read is inherent to
+ this operation, so we defer the open until read time. */
+
+ if (!(dirp = (DIR *)xmalloc(sizeof(DIR))))
+ return NULL;
+ ZeroMemory(dirp, sizeof(DIR));
+ if (dir_find_handle != INVALID_HANDLE_VALUE)
+ return NULL;
+
+ dirp->dd_fd = 0;
+ dirp->dd_loc = 0;
+ dirp->dd_size = 0;
+
+ strncpy (dir_pathname, map_win32_filename (filename, NULL), MAXPATHLEN);
+ dir_pathname[MAXPATHLEN] = '\0';
+ dir_is_fat = is_fat_volume (filename, NULL);
+
+ return dirp;
+}
+
+void
+closedir (DIR *dirp)
+{
+ /* If we have a find-handle open, close it. */
+ if (dir_find_handle != INVALID_HANDLE_VALUE)
+ {
+ FindClose (dir_find_handle);
+ dir_find_handle = INVALID_HANDLE_VALUE;
+ }
+ free (dirp);
+}
+
+struct direct *
+readdir (DIR *dirp)
+{
+ /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
+ if (dir_find_handle == INVALID_HANDLE_VALUE)
+ {
+ char filename[MAXNAMLEN + 3];
+ int ln;
+
+ strcpy (filename, dir_pathname);
+ ln = strlen (filename) - 1;
+ if (!IS_DIR_SEP (filename[ln]))
+ strcat (filename, "\\");
+ strcat (filename, "*");
+
+ dir_find_handle = FindFirstFile (filename, &dir_find_data);
+
+ if (dir_find_handle == INVALID_HANDLE_VALUE)
+ return NULL;
+ }
+ else
+ {
+ if (!FindNextFile (dir_find_handle, &dir_find_data))
+ return NULL;
+ }
+
+ /* Emacs never uses this value, so don't bother making it match
+ value returned by stat(). */
+ dir_static.d_ino = 1;
+
+ dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
+ dir_static.d_namlen - dir_static.d_namlen % 4;
+
+ dir_static.d_namlen = strlen (dir_find_data.cFileName);
+ strcpy (dir_static.d_name, dir_find_data.cFileName);
+ if (dir_is_fat)
+ _strlwr (dir_static.d_name);
+ else
+#if 0
+ if (!NILP (Vmswindows_downcase_file_names))
+#endif
+ {
+ char *p;
+ for (p = dir_static.d_name; *p; p++)
+ if (*p >= 'a' && *p <= 'z')
+ break;
+ if (!*p)
+ _strlwr (dir_static.d_name);
+ }
+
+ return &dir_static;
+}
diff --git a/Build/source/libs/libgnuw32/error.c b/Build/source/libs/libgnuw32/error.c
new file mode 100644
index 00000000000..90315c89ccc
--- /dev/null
+++ b/Build/source/libs/libgnuw32/error.c
@@ -0,0 +1,87 @@
+/*
+
+Error messages for fpTeX.
+
+Copyright (C) 1998-2000 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <win32lib.h>
+
+#ifdef MAKE_KPSE_DLL
+#include <kpathsea/progname.h>
+
+extern KPSEDLL char *kpathsea_version_string; /* from kpathsea/version.c */
+#endif
+
+/*
+ Various messages to display error messages, either from Windows
+ or on the console.
+*/
+
+/* Last error message in a MessageBox. */
+void Win32Error(char *caller)
+{
+ LPVOID lpMsgBuf;
+ DWORD errCode;
+ if (errCode = GetLastError()) {
+ if (FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ errCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ )) {
+ /* Display the string. */
+ MessageBox( NULL, lpMsgBuf, caller, MB_OK|MB_ICONINFORMATION );
+ /* Free the buffer. */
+ LocalFree( lpMsgBuf );
+ }
+ else {
+ char szBuf[24];
+ wsprintf(szBuf, "%d", errCode);
+ MessageBox( NULL, szBuf, caller, MB_OK|MB_ICONINFORMATION );
+ }
+ }
+}
+
+void Win32Msg(char *msg)
+{
+#ifdef MAKE_KPSE_DLL
+ char *program = "(unknown)";
+ char *caller = NULL;
+
+ if (kpse_program_name && *kpse_program_name) {
+ program = kpse_program_name;
+ }
+
+ caller = concat3(program, "\r\n", kpathsea_version_string);
+#else
+ char *caller = xmalloc(4096);
+
+ if (caller && GetModuleFileName(NULL, caller, sizeof(caller)) == 0) {
+ strcpy(caller, "(unknown)");
+ }
+#endif
+
+ MessageBox(NULL, msg, caller, MB_OK|MB_ICONINFORMATION);
+
+ free(caller);
+}
+
diff --git a/Build/source/libs/libgnuw32/filename.c b/Build/source/libs/libgnuw32/filename.c
new file mode 100644
index 00000000000..5aede5152f3
--- /dev/null
+++ b/Build/source/libs/libgnuw32/filename.c
@@ -0,0 +1,392 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+#include <win32lib.h>
+
+/* Normalize filename by converting all path separators to
+ the specified separator. Also conditionally convert upper
+ case path name components to lower case.
+ Returns the index of the first meaningful char in the path
+ past any drive specifier of unc name specifier.
+ Remove any multiple path separators after a leading
+ drive specifier or double path separator.
+*/
+
+int
+normalize_filename (char *fp, char path_sep)
+{
+ char *p;
+ int ret, i;
+
+ if (fp == NULL || *fp == '\0')
+ return 0;
+
+ /* Always lower-case drive letters a-z, even if the filesystem
+ preserves case in filenames.
+ This is so filenames can be compared by string comparison
+ functions that are case-sensitive. Even case-preserving filesystems
+ do not distinguish case in drive letters. */
+ if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') {
+ *fp += 'a' - 'A';
+ }
+
+ /* Remove unneeded double slashes */
+ ret = (IS_UNC_NAME(fp) ? 2 :
+ NAME_BEGINS_WITH_DEVICE(fp) ?
+ (IS_DIR_SEP(*(fp+2)) ? 3 : 2) : IS_DIR_SEP(*fp) ? 1 : 0);
+ for (i = ret, p = fp+i;
+ IS_DIR_SEP(*p);
+ i++, p++);
+ if (i > ret) {
+ int len = strlen(fp+i);
+ /* remove unneeded slashes, for the sake of win95 */
+#if 0
+ fprintf(stderr, "moving %s to %s\n", fp+ret, fp+i);
+#endif
+ memcpy(fp+ret, fp+i, len);
+ *(char *)(fp+ret+len) = '\0';
+ }
+
+ /* conditionnally rewrite to same path_sep, slash preferably */
+ if (path_sep) {
+ for (p = fp; *p; p++)
+ if (IS_DIR_SEP(*p))
+ *p = path_sep;
+ }
+
+#if 0
+ fprintf(stderr, "normalize_filename returned (%d) %s\n", ret, fp);
+#endif
+
+ return ret;
+}
+
+
+/* Destructively turn backslashes into slashes. */
+void
+dostounix_filename (char *p)
+{
+ normalize_filename (p, '/');
+}
+
+/* Destructively turn slashes into backslashes. */
+void
+unixtodos_filename (char *p)
+{
+ normalize_filename (p, '\\');
+}
+
+/* Quote file name. */
+char *
+quote_filename(char *name)
+{
+ int len = strlen(name);
+ char *quoted_name;
+ if (strchr(name, ' ') && *name != '"') {
+ quoted_name = xmalloc(len+3);
+ memcpy(quoted_name+1, name, len);
+ *quoted_name = '"';
+ *(quoted_name+len+1) = '"';
+ *(quoted_name+len+2) = '\0';
+ }
+ else {
+ quoted_name = xstrdup(name);
+ }
+ return quoted_name;
+}
+
+/* Unquote file name */
+char *
+unquote_filename(char *name)
+{
+ int len = strlen(name);
+ if (*name == '"' && *(name + len - 1) == '"') {
+ memmove(name, name+1, len-2);
+ *(name + len - 2) = '\0';
+ }
+ return name;
+}
+
+
+/* Remove all CR's that are followed by a LF.
+ (From msdos.c...probably should figure out a way to share it,
+ although this code isn't going to ever change.) */
+int
+crlf_to_lf (int n, unsigned char *buf, unsigned *lf_count)
+{
+ unsigned char *np = buf;
+ unsigned char *startp = buf;
+ unsigned char *endp = buf + n;
+
+ if (n == 0)
+ return n;
+ while (buf < endp - 1)
+ {
+ if (*buf == 0x0a)
+ (*lf_count)++;
+ if (*buf == 0x0d)
+ {
+ if (*(++buf) != 0x0a)
+ *np++ = 0x0d;
+ }
+ else
+ *np++ = *buf++;
+ }
+ if (buf < endp)
+ {
+ if (*buf == 0x0a)
+ (*lf_count)++;
+ *np++ = *buf++;
+ }
+ return np - startp;
+}
+
+/* Parse the root part of file name, if present. Return length and
+ optionally store pointer to char after root. */
+int
+_parse_root (char * name, char ** pPath)
+{
+ char * start = name;
+
+ if (name == NULL)
+ return 0;
+
+ /* find the root name of the volume if given */
+ if (isalpha (name[0]) && name[1] == ':')
+ {
+ /* skip past drive specifier */
+ name += 2;
+ if (IS_DIR_SEP (name[0]))
+ name++;
+ }
+ else if (IS_DIR_SEP (name[0]) && IS_DIR_SEP (name[1]))
+ {
+ int slashes = 2;
+ name += 2;
+ do
+ {
+ if (IS_DIR_SEP (*name) && --slashes == 0)
+ break;
+ name++;
+ }
+ while ( *name );
+ if (IS_DIR_SEP (name[0]))
+ name++;
+ }
+
+ if (pPath)
+ *pPath = name;
+
+ return name - start;
+}
+
+/* Get long base name for name; name is assumed to be absolute. */
+static int
+get_long_basename (char * name, char * buf, int size)
+{
+ WIN32_FIND_DATA find_data;
+ HANDLE dir_handle;
+ int len = 0;
+#ifdef PIGSFLY
+ char *p;
+
+ /* If the last component of NAME has a wildcard character,
+ return it as the basename. */
+ p = name + strlen (name);
+ while (*p != '\\' && *p != ':' && p > name) p--;
+ if (p > name) p++;
+ if (strchr (p, '*') || strchr (p, '?'))
+ {
+ if ((len = strlen (p)) < size)
+ memcpy (buf, p, len + 1);
+ else
+ len = 0;
+ return len;
+ }
+#endif
+
+ dir_handle = FindFirstFile (name, &find_data);
+ if (dir_handle != INVALID_HANDLE_VALUE)
+ {
+ if ((len = strlen (find_data.cFileName)) < size)
+ memcpy (buf, find_data.cFileName, len + 1);
+ else
+ len = 0;
+ FindClose (dir_handle);
+ }
+ return len;
+}
+
+/* Get long name for file, if possible (assumed to be absolute). */
+BOOL
+win32_get_long_filename (char * name, char * buf, int size)
+{
+ char * o = buf;
+ char * p;
+ char * q;
+ char full[ MAX_PATH ];
+ int len;
+
+ len = strlen (name);
+ if (len >= MAX_PATH)
+ return FALSE;
+
+ /* Use local copy for destructive modification. */
+ memcpy (full, name, len+1);
+ unixtodos_filename (full);
+
+ /* Copy root part verbatim. */
+ len = _parse_root (full, &p);
+ memcpy (o, full, len);
+ o += len;
+ size -= len;
+
+ do
+ {
+ q = p;
+ p = strchr (q, '\\');
+ if (p) *p = '\0';
+ len = get_long_basename (full, o, size);
+ if (len > 0)
+ {
+ o += len;
+ size -= len;
+ if (p != NULL)
+ {
+ *p++ = '\\';
+ if (size < 2)
+ return FALSE;
+ *o++ = '\\';
+ size--;
+ *o = '\0';
+ }
+ }
+ else
+ return FALSE;
+ }
+ while (p != NULL && *p);
+
+ return TRUE;
+}
+
+/* Map filename to a legal 8.3 name if necessary. */
+const char *
+map_win32_filename (const char * name, const char ** pPath)
+{
+ static char shortname[MAX_PATH];
+ char * str = shortname;
+ char c;
+ const char * path;
+ const char * save_name = name;
+
+ if (is_fat_volume (name, &path)) /* truncate to 8.3 */
+ {
+ register int left = 8; /* maximum number of chars in part */
+ register int extn = 0; /* extension added? */
+ register int dots = 2; /* maximum number of dots allowed */
+
+ while (name < path)
+ *str++ = *name++; /* skip past UNC header */
+
+ while ((c = *name++))
+ {
+ switch ( c )
+ {
+ case '\\':
+ case '/':
+ *str++ = '\\';
+ extn = 0; /* reset extension flags */
+ dots = 2; /* max 2 dots */
+ left = 8; /* max length 8 for main part */
+ break;
+ case ':':
+ *str++ = ':';
+ extn = 0; /* reset extension flags */
+ dots = 2; /* max 2 dots */
+ left = 8; /* max length 8 for main part */
+ break;
+ case '.':
+ if ( dots )
+ {
+ /* Convert path components of the form .xxx to _xxx,
+ but leave . and .. as they are. This allows .emacs
+ to be read as _emacs, for example. */
+
+ if (! *name ||
+ *name == '.' ||
+ IS_DIR_SEP (*name))
+ {
+ *str++ = '.';
+ dots--;
+ }
+ else
+ {
+ *str++ = '_';
+ left--;
+ dots = 0;
+ }
+ }
+ else if ( !extn )
+ {
+ *str++ = '.';
+ extn = 1; /* we've got an extension */
+ left = 3; /* 3 chars in extension */
+ }
+ else
+ {
+ /* any embedded dots after the first are converted to _ */
+ *str++ = '_';
+ }
+ break;
+ case '~':
+ case '#': /* don't lose these, they're important */
+ if ( ! left )
+ str[-1] = c; /* replace last character of part */
+ /* FALLTHRU */
+ default:
+ if ( left )
+ {
+ *str++ = tolower (c); /* map to lower case (looks nicer) */
+ left--;
+ dots = 0; /* started a path component */
+ }
+ break;
+ }
+ }
+ *str = '\0';
+ }
+ else
+ {
+ strcpy (shortname, name);
+ unixtodos_filename (shortname);
+ }
+
+ if (pPath)
+ *pPath = shortname + (path - save_name);
+
+ return shortname;
+}
diff --git a/Build/source/libs/libgnuw32/gnuw32.c b/Build/source/libs/libgnuw32/gnuw32.c
new file mode 100644
index 00000000000..abbc1c43db3
--- /dev/null
+++ b/Build/source/libs/libgnuw32/gnuw32.c
@@ -0,0 +1,523 @@
+/* Libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ This does make sense only under WIN32.
+ Functions:
+ - popen() rewritten
+ - pclose() rewritten
+ - stat() wrapper for _stat(), removing trailing slashes
+ */
+
+#ifdef 0
+
+#include <fcntl.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <direct.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <gnuw32.h>
+
+
+
+
+#if 0
+#endif
+
+
+#if 0
+
+
+Thanks. DJGPP startup code has a full-blown wildcard globber in its
+startup code as well, and it expands wildcards Unix style (i.e., it
+supports [a-z] etc.). So I don't think we need any more functionality...
+
+Here's the relevant parts from DJGPP's system.c module. I omitted some
+functions with obvious names like `emiterror', to avoid cluttering the
+code with too many irrelevant details. `system1' (also omitted) is the
+place where the command line, after being stripped from redirection and
+pipe parts, is actually broken into separate argv[] parts and passed to
+the child (via `spawnve' in the case of DJGPP); I assume that you already
+have something like that. I did include the two functions which are used
+to support quoting of command-line arguments, in case you are interested,
+but note that some of their subtleties know how the startup code on the
+child side will process quoted arguments (e.g., the case of 'foo bar'
+with single quotes), so caveat emptor.
+
+The only part that is really relevant to processing pipes and redirection
+is the loop which begins with the following lines:
+
+ tmp = alloca(L_tmpnam);
+ prog = alloca (L_tmpnam);
+
+ s = strcpy (alloca (strlen (cmdline) + 1), cmdline);
+ while (!done && result >= 0)
+ {
+
+Have fun!
+
+------------------------------------------------------------------
+/* Return a copy of a word between BEG and (excluding) END with all
+ quoting characters removed from it. */
+
+static char *
+__unquote (char *to, const char *beg, const char *end)
+{
+ const char *s = beg;
+ char *d = to;
+ int quote = 0;
+
+ while (s < end)
+ {
+ switch (*s)
+ {
+ case '"':
+ case '\'':
+ if (!quote)
+ quote = *s;
+ else if (quote == *s)
+ quote = 0;
+ s++;
+ break;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == ';'
+ && (__system_flags & __system_allow_multiple_cmds)))
+ s++;
+ /* Fall-through. */
+ default:
+ *d++ = *s++;
+ break;
+ }
+ }
+
+ *d = 0;
+ return to;
+}
+
+/* A poor-man's lexical analyzer for simplified command processing.
+
+ It only knows about these:
+
+ redirection and pipe symbols
+ semi-colon `;' (that possibly ends a command)
+ argument quoting rules with quotes and `\'
+ whitespace delimiters of words (except in quoted args)
+
+ Returns the type of next symbol and pointers to its first and (one
+ after) the last characters.
+
+ Only `get_sym' and `unquote' should know about quoting rules. */
+
+static cmd_sym_t
+get_sym (char *s, char **beg, char **end)
+{
+ int in_a_word = 0;
+
+ while (isspace (*s))
+ s++;
+
+ *beg = s;
+
+ do {
+ *end = s + 1;
+
+ if (in_a_word
+ && (!*s || strchr ("<>| \t\n", *s)
+ || ((sys_flags & __system_allow_multiple_cmds) && *s == ';')))
+ {
+ --*end;
+ return WORD;
+ }
+
+ switch (*s)
+ {
+ case '<':
+ return REDIR_INPUT;
+ case '>':
+ if (**end == '>')
+ {
+ ++*end;
+ return REDIR_APPEND;
+ }
+ return REDIR_OUTPUT;
+ case '|':
+ return PIPE;
+ case ';':
+ if (sys_flags & __system_allow_multiple_cmds)
+ return SEMICOLON;
+ else
+ in_a_word = 1;
+ break;
+ case '\0':
+ --*end;
+ return EOL;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == ';' && (sys_flags & __system_allow_multiple_cmds)))
+ s++;
+ in_a_word = 1;
+ break;
+ case '\'':
+ case '"':
+ {
+ char quote = *s++;
+
+ while (*s && *s != quote)
+ {
+ if (*s++ == '\\' && (*s == '"' || *s == '\''))
+ s++;
+ }
+ *end = s;
+ if (!*s)
+ return UNMATCHED_QUOTE;
+ in_a_word = 1;
+ break;
+ }
+ default:
+ in_a_word = 1;
+ break;
+ }
+
+ s++;
+
+ } while (1);
+}
+
+/* This function handles redirection and passes the rest to system1
+ or to the shell. */
+int
+system (const char *cmdline)
+{
+ /* Set the feature bits for this run: either from the
+ environment or from global variable. */
+ const char *envflags = getenv ("DJSYSFLAGS");
+ const char *comspec = getenv ("COMSPEC");
+ const char *shell = 0;
+ int call_shell;
+
+ sys_flags = __system_flags;
+ if (envflags && *envflags)
+ {
+ char *stop;
+ long flags = strtol (envflags, &stop, 0);
+
+ if (*stop == '\0')
+ sys_flags = flags;
+ }
+
+ if (sys_flags & __system_use_shell)
+ shell = getenv ("SHELL");
+ if (!shell)
+ shell = comspec;
+ if (!shell)
+ shell = command_com;
+
+ call_shell =
+ (sys_flags & __system_call_cmdproc)
+ || (!(sys_flags & __system_emulate_command) && _is_unixy_shell (shell));
+
+ /* Special case: NULL means return non-zero if the command
+ interpreter is available. This is ANSI C requirement.
+
+ If we will call the shell to do everything, we need to see
+ whether it exists. But if most of the work will be done by us
+ anyway (like it usually is with stock DOS shell), return non-zero
+ without checking, since our emulation is always ``available''. */
+ if (cmdline == 0)
+ {
+ if (!call_shell)
+ return 1;
+ else
+ {
+ char full_path[FILENAME_MAX];
+
+ return __dosexec_find_on_path (shell, (char **)0, full_path) ? 1 : 0;
+ }
+ }
+
+ /* Strip initial spaces (so that if the command is empty, we
+ know it right here). */
+ while (isspace(*cmdline))
+ cmdline++;
+
+ /* Call the shell if:
+
+ the command line is empty
+ or
+ they want to always do it via command processor
+ or
+ $SHELL or $COMSPEC point to a unixy shell */
+ if (!*cmdline || call_shell)
+ return _shell_command ("", cmdline);
+ else
+ {
+ char *f_in = 0, *f_out = 0;
+ int rm_in = 0, rm_out = 0;
+ /* Assigned to silence -Wall */
+ int h_in = 0, h_inbak = 0, h_out = 0, h_outbak = 0;
+ char *s, *t, *u, *v, *tmp, *cmdstart;
+ int result = 0, done = 0;
+ int append_out = 0;
+ cmd_sym_t token;
+ char *prog;
+
+ tmp = alloca(L_tmpnam);
+ prog = alloca (L_tmpnam);
+
+ s = strcpy (alloca (strlen (cmdline) + 1), cmdline);
+ while (!done && result >= 0)
+ {
+ char **fp = &f_in;
+ /* Assignments pacify -Wall */
+ int hin_err = 0, hbak_err = 0, hout_err = 0;
+ int needcmd = 1;
+ int again;
+
+ if (rm_in)
+ remove (f_in);
+ f_in = f_out; /* Piping. */
+ rm_in = rm_out;
+ f_out = 0;
+ rm_out = 0;
+ append_out = 0;
+
+ cmdstart = s;
+
+ do {
+ again = 0;
+ token = get_sym (s, &t, &u); /* get next symbol */
+
+ /* Weed out extra whitespace, leaving only a single
+ whitespace character between any two tokens.
+ This way, if we eventually pass the command to a
+ shell, it won't fail due to length > 126 chars
+ unless it really *is* that long. */
+
+ if (s == cmdstart)
+ v = s; /* don't need blank at beginning of cmdline */
+ else
+ v = s + 1;
+ if (t > v)
+ {
+ strcpy (v, t);
+ u -= t - v;
+ t = v;
+ }
+
+ switch (token)
+ {
+ case WORD:
+ /* First word we see is the program to run. */
+ if (needcmd)
+ {
+ __unquote (prog, t, u); /* unquote and copy to prog */
+ /* We can't grok commands in parentheses, so assume they
+ use a shell that knows about these, like 4DOS or `sh'.
+
+ FIXME: if the parenthesized group is NOT the first command
+ in a pipe, the commands that preceed it will be run twice. */
+ if (prog[0] == '(')
+ return _shell_command ("", cmdline);
+ strcpy (s, u); /* remove program name from cmdline */
+ needcmd = 0;
+ }
+ else
+ s = u;
+ again = 1;
+ break;
+ case REDIR_INPUT:
+ case REDIR_OUTPUT:
+ case REDIR_APPEND:
+ if (!(sys_flags & __system_redirect))
+ return _shell_command ("", cmdline);
+ if (token == REDIR_INPUT)
+ {
+ if (f_in)
+ {
+ result = emiterror ("Ambiguous input redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ fp = &f_in;
+ }
+ else if (token == REDIR_OUTPUT || token == REDIR_APPEND)
+ {
+ if (f_out)
+ {
+ result = emiterror ("Ambiguous output redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ fp = &f_out;
+ if (token == REDIR_APPEND)
+ append_out = 1;
+ }
+ if (get_sym (u, &u, &v) != WORD)
+ {
+ result = emiterror ("Target of redirect is not a filename.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ *fp = memcpy ((char *)alloca (v - u + 1), u, v - u);
+ (*fp)[v - u] = 0;
+ strcpy (t, v);
+ again = 1;
+ break;
+ case PIPE:
+ if (!(sys_flags & __system_redirect))
+ return _shell_command ("", cmdline);
+ if (f_out)
+ {
+ result = emiterror ("Ambiguous output redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+
+ /* tmpnam guarantees unique names */
+ tmpnam(tmp);
+ f_out = strcpy (alloca (L_tmpnam), tmp);
+ rm_out = 1;
+ /* Fall through. */
+ case SEMICOLON:
+ case EOL:
+ if (needcmd)
+ {
+ result = emiterror ("No command name seen.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+
+ /* Remove extra whitespace at end of command. */
+ while (s > cmdstart && isspace (s[-1])) s--;
+ while (t > s && isspace (t[-1])) t--;
+ *t = 0;
+
+#ifdef TEST
+ fprintf (stderr, "Input from: %s\nOutput%s to: %s\n",
+ f_in ? f_in : "<stdin>",
+ append_out ? " appended" : "",
+ f_out ? f_out : "<stdout>");
+ fflush (stderr);
+#endif
+ if (f_in)
+ {
+ int e = errno;
+
+ errno = 0;
+ h_in = open (f_in, O_RDONLY | O_BINARY);
+ hin_err = errno;
+ errno = 0;
+ h_inbak = dup (0);
+ hbak_err = errno;
+ dup2 (h_in, 0);
+ errno = e;
+ }
+ if (f_out)
+ {
+ int e = errno;
+
+ errno = 0;
+ h_out = open (f_out,
+ O_WRONLY | O_BINARY | O_CREAT
+ | (append_out ? O_APPEND: O_TRUNC),
+ S_IREAD | S_IWRITE);
+ hout_err = errno;
+ errno = 0;
+ h_outbak = dup (1);
+ hbak_err = errno;
+ fflush(stdout); /* so any buffered chars will be written out */
+ dup2 (h_out, 1);
+ errno = e;
+ }
+ if (f_in && h_in < 0)
+ result = emiterror ("Cannot redirect input", hin_err);
+ else if ((f_in && h_inbak < 0) || (f_out && h_outbak < 0))
+ result = emiterror ("Out of file handles in redirect", hbak_err);
+ else if (f_out && h_out < 0)
+ result = emiterror ("Cannot redirect output", hout_err);
+
+ if (!result)
+ {
+#ifdef TEST
+ fprintf (stderr, "system1 (\"%s\", \"%s\")\n", prog, cmdstart);
+ fflush (stderr);
+#endif
+ /* Tell `__spawnve' it was invoked by `system', so it would
+ know how to deal with command-line arguments' quoting. */
+ __dosexec_in_system = 1;
+ result = system1 (prog, cmdstart);
+ __dosexec_in_system = 0;
+ }
+ if (f_in)
+ {
+ dup2 (h_inbak, 0);
+ close (h_in);
+ close (h_inbak);
+ }
+ if (f_out)
+ {
+ dup2 (h_outbak, 1);
+ close (h_out);
+ close (h_outbak);
+ }
+
+ if (token == EOL)
+ done = 1;
+ else
+ {
+ if (token == SEMICOLON)
+ f_in = f_out = 0;
+ s = u;
+ }
+ break;
+ case UNMATCHED_QUOTE:
+ result = emiterror ("Unmatched quote character.", 0);
+ errno = EINVAL;
+ goto leave;
+ default:
+ result = emiterror ("I cannot grok this.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ } while (again);
+ }
+ leave:
+ if (rm_in)
+ remove (f_in);
+ if (rm_out)
+ remove (f_out);
+
+ return result;
+ }
+}
+#endif
+
+#if NEW_KPSE
+
+
+
+
+
+
+
+#endif
+#endif
+
diff --git a/Build/source/libs/libgnuw32/home.c b/Build/source/libs/libgnuw32/home.c
new file mode 100644
index 00000000000..f6f7ac52324
--- /dev/null
+++ b/Build/source/libs/libgnuw32/home.c
@@ -0,0 +1,115 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+#include <win32lib.h>
+#include <shlobj.h>
+
+char initial_directory[MAXPATHLEN];
+
+static char *cached_home_directory;
+
+void
+uncache_home_directory (void)
+{
+ cached_home_directory = NULL; /* in some cases, this may cause the leaking
+ of a few bytes */
+}
+
+int output_home_warning = 0;
+
+void
+set_home_warning() {
+ output_home_warning = 1;
+}
+
+/* Returns the home directory, in external format */
+char *
+get_home_directory (void)
+{
+
+ if (cached_home_directory != NULL)
+ goto done;
+
+ if ((cached_home_directory = getenv("HOME")) != NULL) {
+ char q[MAXPATHLEN];
+ /* In case it is %HOMEDRIVE%%HOMEPATH% */
+ if (ExpandEnvironmentStrings(cached_home_directory, q, sizeof(q)) == 0) {
+ /* Error */
+ cached_home_directory = NULL;
+ }
+ else {
+ cached_home_directory = xstrdup(q);
+ goto done;
+ }
+ }
+
+ {
+ char *homedrive, *homepath;
+ if ((homedrive = getenv("HOMEDRIVE")) != NULL &&
+ (homepath = getenv("HOMEPATH")) != NULL) {
+ cached_home_directory = concat(homedrive, homepath);
+ goto done;
+ }
+ }
+
+ /* This method is the prefered one because even if it requires a more recent shell32.dll,
+ it does not need to call SHMalloc()->Free() */
+ {
+ /* This will probably give the wrong value */
+ char q [MAXPATHLEN];
+ HINSTANCE h;
+ HRESULT (WINAPI * p1)(HWND, LPSTR, int, BOOL);
+ HWND (WINAPI * p2)(void);
+ HWND hwnd = NULL;
+
+ if (h = LoadLibrary("user32.dll")) {
+ if (p2 = GetProcAddress(h, "GetDesktopWindow"))
+ hwnd = (*p2)();
+ FreeLibrary(h);
+ }
+
+ if (hwnd && (h = LoadLibrary("shell32.dll")) != NULL) {
+ if (p1 = GetProcAddress(h, "SHGetSpecialFolderPathA"))
+ if ((*p1)(hwnd, q, CSIDL_PERSONAL, TRUE)) {
+ cached_home_directory = xstrdup(q);
+ }
+ FreeLibrary(h);
+ }
+ if (cached_home_directory) goto done;
+ }
+
+ if (output_home_warning) {
+ fprintf(stderr, "fpTeX has been unable to determine a good value for the user's $HOME\n"
+ " directory, and will be using the value:\n"
+ " %s\n"
+ " This is probably incorrect.\n",
+ cached_home_directory
+ );
+ }
+ done:
+ return cached_home_directory;
+}
diff --git a/Build/source/libs/libgnuw32/libgnuw32.rc b/Build/source/libs/libgnuw32/libgnuw32.rc
new file mode 100644
index 00000000000..1146d9d5c15
--- /dev/null
+++ b/Build/source/libs/libgnuw32/libgnuw32.rc
@@ -0,0 +1,36 @@
+/* libgnuw32.rc: libgnuw32 resources -*- C++ -*-
+
+ Copyright (C) 1996-2003 Fabrice Popineau <fabrice.popineau@supelec.fr>
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#include <texlive-version.h>
+
+#define VER_FILEVERSION TEXLIVE_MAJOR_VERSION,TEXLIVE_MINOR_VERSION,TEXLIVE_BETA_NUMBER,TEXLIVE_ALPHA_NUMBER
+#define VER_FILEVERSION_STR TEXLIVE_PRODUCTVERSION_STR " libgnuw32 0.1"
+
+#define VER_INTERNALNAME_STR "libgnuw32"
+#define VER_ORIGINALFILENAME_STR "libgnuw32.dll"
+
+#define VER_FILEDESCRIPTION_STR "Gnu Win32 compatibility DLL"
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright (c) 1999-2003 Fabrice Popineau, Supelec"
+
+#define VER_FILETYPE VFT_DLL
+
+#include <texlive.version>
+
+/* libgnuw32.rc ends here */
diff --git a/Build/source/libs/libgnuw32/lookcmd.c b/Build/source/libs/libgnuw32/lookcmd.c
new file mode 100644
index 00000000000..bd4f2d8a4b1
--- /dev/null
+++ b/Build/source/libs/libgnuw32/lookcmd.c
@@ -0,0 +1,778 @@
+/* libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ This does make sense only under WIN32.
+ Functions:
+ - look_for_cmd() : locates an executable file
+ - parse_cmd_line() : splits a command with pipes and redirections
+ - build_cmd_line() : builds a command with pipes and redirections (useful ?)
+ */
+
+/*
+ This part looks for the real location of the program invoked
+ by cmd. If it can find the program, that's good. Else
+ command processor is invoked.
+*/
+
+#include <win32lib.h>
+#include <errno.h>
+
+#undef _DEBUG
+
+#ifdef _DEBUG
+#define TRACE(x) x
+#else
+#define TRACE(x)
+#endif
+
+#define DIR_SEP '/'
+#define DIR_SEP_STRING "/"
+#define IS_DEVICE_SEP(ch) ((ch) == ':')
+#define NAME_BEGINS_WITH_DEVICE(name) (*(name) && IS_DEVICE_SEP((name)[1]))
+/* On DOS, it's good to allow both \ and / between directories. */
+#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
+/* On win32, UNC names are authorized */
+#define IS_UNC_NAME(name) (strlen(name)>=3 && IS_DIR_SEP(*name) \
+ && IS_DIR_SEP(*(name+1)) && isalnum(*(name+2)))
+
+#if (defined(_DEBUG) || defined(TEST))
+void display_cmd(char ***cmd, char *input, char *output, char *errput);
+#endif
+
+void
+free_cmd_pipe(char ***cmd_pipe, int n)
+{
+ int i,j;
+ if (cmd_pipe) {
+ for (i = 0; i < n; i++) {
+ for (j = 0; cmd_pipe[i][j]; j++) {
+ TRACE(fprintf(stderr, "freeing %x\n", cmd_pipe[i][j]));
+ free(cmd_pipe[i][j]);
+ }
+ TRACE(fprintf(stderr, "freeing %x\n", cmd_pipe[i]));
+ free(cmd_pipe[i]);
+ }
+ TRACE(fprintf(stderr, "freeing %x\n", cmd_pipe));
+ free(cmd_pipe);
+ }
+}
+
+/*
+ Return a quoted string if space is found
+ New string is allocated
+*/
+static char *
+quote_elt(char *elt)
+{
+ int len = 2*strlen(elt)*sizeof(char) + 2;
+ char *to = xmalloc(len);
+ char *p = to;
+ BOOL need_quote = FALSE;
+
+ if (strchr(elt, ' ')) {
+ *to++ = '"';
+ need_quote = TRUE;
+ }
+
+ while (*elt) {
+ switch (*elt) {
+ case '"':
+ case '\'':
+ /* case '\\': */
+ *to++ = '\\';
+ default:
+ *to++ = *elt++;
+ }
+ }
+ if (need_quote) {
+ *to++ = '"';
+ }
+
+ *to = *elt;
+ to = xstrdup(p);
+ free(p);
+
+ return to;
+}
+
+/*
+ Process an array of strings, quote them
+ an return their catenation
+*/
+char *
+quote_args(char **argv)
+{
+ int i;
+ char *line = NULL, *new_line;
+ char *new_argv_i;
+
+ if (!argv)
+ return line;
+
+ line = quote_elt(argv[0]);
+ for (i = 1; argv[i]; i++) {
+ new_argv_i = quote_elt(argv[i]);
+ new_line = concat3(line, " ", new_argv_i);
+ TRACE(fprintf(stderr, "quote_args: new_line = %s\n", new_line));
+ free(line);
+ free(new_argv_i);
+ line = new_line;
+ }
+
+ return line;
+}
+
+static BOOL
+is_absolute(const char *filename)
+{
+ BOOL absolute = IS_DIR_SEP (*filename)
+ /* Novell allows non-alphanumeric drive letters. */
+ || (*filename && IS_DEVICE_SEP (filename[1]))
+ /* UNC names */
+ || IS_UNC_NAME(filename)
+ ;
+ BOOL explicit_relative = (*filename == '.' && (IS_DIR_SEP (filename[1])
+ || (filename[1] == '.' && IS_DIR_SEP (filename[2]))));
+ /* FIXME: On UNIX an IS_DIR_SEP of any but the last character in the name
+ implies relative. */
+ return absolute || explicit_relative;
+}
+
+BOOL
+look_for_cmd(const char *cmd, char **app)
+{
+ char *env_path = NULL;
+ char *p, *q;
+ char pname[MAXPATHLEN];
+ char *suffixes[] = {".com", ".exe", ".bat", ".cmd", NULL };
+ char **s;
+ char *app_name = NULL, *bare_name = NULL;
+ int i;
+ BOOL bIsWindowsNT = (GetVersion() < 0x80000000);
+ BOOL found, has_suffix = FALSE;
+
+ *app = app_name = bare_name = NULL;
+
+ /* We should look for the application name along the PATH,
+ and decide to prepend "%COMSPEC% /c " or not to the command line.
+ Do nothing for the moment. */
+
+ /* Another way to do that would be to try CreateProcess first without
+ invoking cmd, and look at the error code. If it fails because of
+ command not found, try to prepend "cmd /c" to the cmd line.
+ */
+
+ /* Look for the application name */
+ for (p = (char *)cmd; *p && isspace(*p); p++); /* Trim spaces on the left */
+ if (*p == '"') { /* If quoted string */
+ q = ++p;
+ while(*p && *p != '"') p++; /* stop at next quote */
+ if (*p == '\0') {
+ fprintf(stderr, "Look_for_cmd: malformed command (\" not terminated)\n");
+ return FALSE;
+ }
+ }
+ else {
+ for (q = p; *p && !isspace(*p); p++); /* stop at next space */
+ }
+
+ /* q points to the beginning of appname, p to the last + 1 char */
+ if ((app_name = xmalloc(p - q + 1)) == NULL) {
+ fprintf(stderr, "Look_for_cmd: malloc(app_name) failed.\n");
+ return FALSE;
+ }
+ /* the app name has been found */
+ for (i = 0; i < p - q; i++)
+ app_name[i] = (q[i] == '/' ? '\\' : q[i]);
+ // strncpy(app_name, q, p - q );
+ app_name[p - q] = '\0';
+
+ /* First of all : if it is an absolute path ... */
+ if (is_absolute(app_name)) {
+ if (_access(app_name, 0) == 0) { /* and it exists */
+ *app = app_name;
+ found = TRUE;
+ }
+ else { /* not found */
+ found = FALSE;
+ }
+ goto exit_1;
+ }
+
+ /* pname[] will serve as full path name */
+ pname[0] = '\0';
+ /* app_name without potential extension */
+ bare_name = xstrdup(app_name);
+ has_suffix = ((p = strrchr(bare_name, '.')) != NULL);
+
+ TRACE(fprintf(stderr, "look for command: app_name = %s\n", app_name));
+
+ /* Add the current directory */
+ {
+ char *tmp = getenv("PATH");
+ env_path = xmalloc(strlen(tmp) + 3);
+ strcpy(env_path, ".;");
+ strcat(env_path, tmp);
+ }
+
+ /* Looping over directories in env_path */
+ p = strtok(env_path, ";");
+ found = FALSE;
+ while (p != NULL && ! found) {
+ /* If the file has an extension ... */
+ if (has_suffix) {
+ strcpy(pname, p);
+ strcat(pname, "\\");
+ strcat(pname, app_name);
+ TRACE(fprintf(stderr, "look for command: trying %s\n", pname));
+ if (_access(pname, 0) == 0) {
+ free(app_name);
+ app_name = xstrdup(pname);
+ found = TRUE;
+ break;
+ }
+ }
+ else {
+ /* For each suffix in the list */
+ for (s = suffixes; *s != NULL; *s++) {
+ strcpy(pname, p);
+ strcat(pname, "\\");
+ strcat(pname, bare_name);
+ strcat(pname, *s);
+ TRACE(fprintf(stderr, "look for command: trying %s\n", pname));
+ if (_access(pname, 0) == 0) {
+ free(app_name);
+ app_name = xstrdup(pname);
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ p = strtok(NULL, ";");
+ }
+
+ exit_1:
+
+ if (found == TRUE) {
+ TRACE(fprintf(stderr, "look for command: app_name = %s\n", app_name));
+ if (! bIsWindowsNT) {
+ // Fix against short pathnames vs long pathnames
+ char lpShortPathName[_MAX_PATH];
+ if (GetShortPathName((LPCTSTR)app_name, lpShortPathName, sizeof(lpShortPathName)) != 0) {
+ free(app_name);
+ app_name = xstrdup(lpShortPathName);
+ }
+ }
+ for (p = app_name; p && *p; p++) {
+ *p = (*p == '/' ? '\\' : *p);
+ }
+ TRACE(fprintf(stderr, "\n!!! Absolute path = %s\n", app_name));
+ *app = app_name;
+ }
+ else {
+ /* the app_name was not found */
+ TRACE(fprintf(stderr, "look for command: %s not found\n", app_name));
+ if (app_name) free(app_name);
+ *app = app_name = NULL;
+ }
+
+ if (env_path) free(env_path);
+ if (bare_name) free(bare_name);
+
+ return found;
+}
+
+/*
+ Command parser. Borrowed from DJGPP.
+ */
+
+static BOOL __system_allow_multiple_cmds = FALSE;
+
+typedef enum {
+ EMPTY,
+ WORDARG,
+ REDIR_INPUT,
+ REDIR_APPEND,
+ REDIR_OUTPUT,
+ PIPE,
+ SEMICOLON,
+ UNMATCHED_QUOTE,
+ EOL
+} cmd_sym_t;
+
+/* Return a copy of a word between BEG and (excluding) END with all
+ quoting characters removed from it. */
+
+static char *
+__unquote (char *to, const char *beg, const char *end)
+{
+ const char *s = beg;
+ char *d = to;
+ int quote = 0;
+
+ while (s < end)
+ {
+ switch (*s)
+ {
+ case '"':
+ case '\'':
+ if (!quote)
+ quote = *s;
+ else if (quote == *s)
+ quote = 0;
+ s++;
+ break;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == '&'
+ && (__system_allow_multiple_cmds)))
+ s++;
+ /* Fall-through. */
+ default:
+ *d++ = *s++;
+ break;
+ }
+ }
+
+ *d = 0;
+ TRACE(fprintf(stderr, "unquote returns `%s' (%x)\n", to, to));
+ return to;
+}
+
+/* A poor-man's lexical analyzer for simplified command processing.
+
+ It only knows about these:
+
+ redirection and pipe symbols
+ semi-colon `;' (that possibly ends a command)
+ argument quoting rules with quotes and `\'
+ whitespace delimiters of words (except in quoted args)
+
+ Returns the type of next symbol and pointers to its first and (one
+ after) the last characters.
+
+ Only `get_sym' and `unquote' should know about quoting rules. */
+
+static cmd_sym_t
+get_sym (char *s, char **beg, char **end)
+{
+ int in_a_word = 0;
+
+ while (isspace (*s))
+ s++;
+
+ *beg = s;
+
+ do {
+ *end = s + 1;
+
+ if (in_a_word
+ && (!*s || strchr ("<>| \t\n", *s)
+ || ((__system_allow_multiple_cmds) && *s == '&')))
+ {
+ --*end;
+ return WORDARG;
+ }
+
+ switch (*s)
+ {
+ case '<':
+ return REDIR_INPUT;
+ case '>':
+ if (**end == '>')
+ {
+ ++*end;
+ return REDIR_APPEND;
+ }
+ return REDIR_OUTPUT;
+ case '|':
+ return PIPE;
+ case '&':
+ if (__system_allow_multiple_cmds)
+ return SEMICOLON;
+ else
+ in_a_word = 1;
+ break;
+ case '\0':
+ --*end;
+ return EOL;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == '&' && (__system_allow_multiple_cmds)))
+ s++;
+ in_a_word = 1;
+ break;
+ case '\'':
+ case '"':
+ {
+ char quote = *s++;
+
+ while (*s && *s != quote)
+ {
+ if (*s++ == '\\' && (*s == '"' || *s == '\''))
+ s++;
+ }
+ *end = s;
+ if (!*s)
+ return UNMATCHED_QUOTE;
+ in_a_word = 1;
+ break;
+ }
+ default:
+ in_a_word = 1;
+ break;
+ }
+
+ s++;
+
+ } while (1);
+}
+
+/*
+ What we allow :
+ [cmd] [arg1] ... [argn] < [redinput] | [cmd2] | ... | [cmdn] > [redoutput]
+*/
+void *parse_cmdline(char *line, char **input, char **output, int *nb_cmds)
+{
+ BOOL again, needcmd = TRUE, bSuccess = TRUE, append_out = FALSE;
+ char *beg = line, *end, *new_end;
+ cmd_sym_t token = EMPTY, prev_token = EMPTY;
+ int ncmd = 0, narg = 0;
+ char **fp;
+ char ***cmd;
+ char *dummy_input; /* So that we could pass NULL */
+ char *dummy_output; /* instead of a real ??put */
+
+#if 0
+ /* if _DEBUG is not defined, these macros will result in nothing. */
+ SETUP_CRTDBG;
+ /* Set the debug-heap flag so that freed blocks are kept on the
+ linked list, to catch any inadvertent use of freed memory */
+ SET_CRT_DEBUG_FIELD( _CRTDBG_CHECK_ALWAYS_DF );
+ SET_CRT_DEBUG_FIELD( _CRTDBG_ALLOC_MEM_DF );
+#endif
+ if (input == NULL) input = &dummy_input;
+ if (output == NULL) output = &dummy_output;
+
+ *input = NULL;
+ *output = NULL;
+ cmd = xmalloc(MAX_PIPES*sizeof(char **));
+ TRACE(fprintf(stderr, "cmd = %x, size = %d\n", cmd, MAX_PIPES*sizeof(char **)));
+ cmd[ncmd] = NULL;
+
+ TRACE(fprintf(stderr, "line = %s\n", line));
+
+ do {
+ again = FALSE;
+ prev_token = token;
+ token = get_sym (beg, &beg, &end); /* get next symbol */
+
+ TRACE(fprintf(stderr, "token = %s\n", beg));
+
+ switch (token) {
+ case WORDARG:
+ TRACE(fprintf(stderr, "WORDARG: "));
+ if (prev_token == REDIR_INPUT
+ || prev_token == REDIR_OUTPUT) {
+ fprintf(stderr, "Ambigous input/output redirect.");
+ bSuccess = FALSE;
+ goto leave;
+ }
+ /* Incrementing number of arguments */
+ narg++;
+ /* First word we see is the program to run. */
+ if (needcmd) {
+ cmd[ncmd] = xmalloc(narg * sizeof(char *));
+ TRACE(fprintf(stderr, "cmd[%d] = %x, size = %d\n", ncmd, cmd[ncmd], narg*sizeof(char *)));
+ if (cmd[ncmd] == NULL) {
+ fprintf(stderr, "parse_cmdline: xmalloc(%d) failed.\n", narg * sizeof(char *));
+ }
+ needcmd = FALSE;
+ }
+ else {
+ TRACE(fprintf(stderr, "cmd[%d] = %x -> ", ncmd, cmd[ncmd]));
+ cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
+ TRACE(fprintf(stderr, "%x, size = %d\n", cmd[ncmd], narg*sizeof(char *)));
+ if (cmd[ncmd] == NULL) {
+ fprintf(stderr, "parse_cmdline: xrealloc(%d) failed.\n", narg * sizeof(char *));
+ }
+ }
+ cmd[ncmd][narg - 1] = xmalloc(end - beg + 10);
+ TRACE(fprintf(stderr, "cmd[%d][%d] = %x, size = %d\n", ncmd, narg-1, cmd[ncmd][narg-1], end-beg+1));
+ if (cmd[ncmd] == NULL) {
+ fprintf(stderr, "parse_cmdline: xmalloc(%d) failed.\n", end - beg + 1);
+ }
+ __unquote (cmd[ncmd][narg - 1], beg, end); /* unquote and copy to prog */
+ TRACE(fprintf(stderr, "parse_cmd_line: cmd[%d][%d] = %s\n", ncmd, narg - 1, cmd[ncmd][narg - 1]));
+ if (cmd[ncmd][narg - 1][0] == '(') {
+ fprintf(stderr, "parse_cmdline(%s): Parenthesized groups not allowed.\n", line);
+ bSuccess = FALSE;
+ goto leave;
+ }
+ beg = end; /* go forward */
+ again = TRUE;
+ break;
+
+ case REDIR_INPUT:
+ case REDIR_OUTPUT:
+ case REDIR_APPEND:
+ TRACE(fprintf(stderr, "REDIR: "));
+ if (token == REDIR_INPUT) {
+ if (*input) {
+ fprintf(stderr, "Ambiguous input redirect.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ }
+ fp = input;
+ }
+ else if (token == REDIR_OUTPUT || token == REDIR_APPEND) {
+ if (*output) {
+ fprintf(stderr, "Ambiguous output redirect.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ }
+ fp = output;
+ if (token == REDIR_APPEND)
+ append_out = TRUE;
+ }
+ if (get_sym (end, &end, &new_end) != WORDARG) {
+ fprintf(stderr, "Target of redirect is not a filename.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ }
+ *fp = (char *)xmalloc (new_end - end + 1);
+ if (*fp == NULL) {
+ fprintf(stderr, "parse_cmdline: xmalloc(%d) failed.\n", new_end - end + 1);
+ }
+ __unquote (*fp, end, new_end);
+ /* (*fp)[new_end - end] = '\0'; */
+ beg = new_end;
+ again = TRUE;
+ break;
+ case PIPE:
+ TRACE(fprintf(stderr, "PIPE: "));
+ if (*output) {
+ fprintf(stderr, "Ambiguous output redirect.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ }
+ narg++;
+ TRACE(fprintf(stderr, "cmd[%d] = %x -> ", ncmd, cmd[ncmd]));
+ cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
+ TRACE(fprintf(stderr, "%x, size = %d\n", cmd[ncmd], narg*sizeof(char *)));
+ cmd[ncmd][narg - 1] = NULL;
+ ncmd++;
+ needcmd = TRUE;
+ cmd[ncmd] = NULL;
+ beg = end;
+ again = TRUE;
+ break;
+ case SEMICOLON:
+ case EOL:
+ TRACE(fprintf(stderr, "SEMICOLON|EOL: "));
+ if (needcmd) {
+ fprintf(stderr, "No command name seen.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ }
+ narg++;
+ TRACE(fprintf(stderr, "cmd[%d] = %x -> ", ncmd, cmd[ncmd]));
+ cmd[ncmd] = xrealloc(cmd[ncmd], narg * sizeof(char *));
+ TRACE(fprintf(stderr, "%x, size = %d\n", cmd[ncmd], narg*sizeof(char *)));
+ cmd[ncmd][narg - 1] = NULL;
+ ncmd++;
+ cmd[ncmd] = NULL;
+ again = FALSE;
+ break;
+
+ case UNMATCHED_QUOTE:
+ fprintf(stderr, "Unmatched quote character.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+ default:
+ fprintf(stderr, "I cannot grok this.");
+ errno = EINVAL;
+ bSuccess = FALSE;
+ goto leave;
+
+ }
+
+ } while (again);
+
+ leave:
+ if (!bSuccess) {
+ int i;
+ char **p;
+ /* Need to free everything that was allocated */
+ for (i = 0; i < ncmd; i++) {
+ for (p = cmd[i]; *p; p++)
+ free(*p);
+ free(cmd[i]);
+ }
+ if (cmd[ncmd]) {
+ for (i = 0; i < narg; i++)
+ free(cmd[ncmd][i]);
+ free(cmd[ncmd]);
+ }
+ free(cmd);
+ *cmd = NULL;
+ ncmd = 0;
+ }
+
+ if (nb_cmds != NULL) *nb_cmds = ncmd;
+
+#if (defined(_DEBUG) || defined(TEST))
+ display_cmd(cmd, *input, *output, NULL);
+#endif
+ return cmd;
+}
+
+char *
+build_cmdline(char ***cmd, char *input, char *output)
+{
+ int ncmd;
+ char *line = NULL, *new_line;
+
+ if (!cmd)
+ return line;
+
+ line = quote_args(cmd[0]);
+ if (input) {
+ new_line = concat3(line, " < ", quote_elt(input));
+ free(line);
+ line = new_line;
+ }
+ for(ncmd = 1; cmd[ncmd]; ncmd++) {
+ new_line = concat3(line, " | ", quote_args(cmd[ncmd]));
+ free(line);
+ line = new_line;
+ }
+
+ if (output) {
+ new_line = concat3(line, " > ", quote_elt(output));
+ free(line);
+ line = new_line;
+ }
+
+ return line;
+}
+
+#if (defined(_DEBUG) || defined(TEST))
+void
+display_cmd(char ***cmd, char *input, char *output, char *errput)
+{
+ int ncmd = 0, narg;
+
+ if (cmd) {
+ for (ncmd = 0; cmd[ncmd]; ncmd++) {
+ printf("cmd[%d] = %s ", ncmd, cmd[ncmd][0]);
+ for(narg = 1; cmd[ncmd][narg] != NULL; narg++)
+ printf("%s ", cmd[ncmd][narg]);
+ printf("\n");
+ }
+ }
+ printf("input = %s\n", (input ? input : "<stdin>"));
+ printf("output = %s\n", (output ? output : "<stdout>"));
+ printf("errput = %s\n", (errput ? errput : "<stderr>"));
+}
+#endif
+
+#ifdef TEST
+main(int argc, char *argv[])
+{
+ char *input;
+ char *output;
+ char ***cmd;
+ char *line;
+
+ /* SETUP_CRTDBG; */
+
+ printf("%s\n", line = "foo a b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo < a > b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "filter 1 | filter 2");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo > a < b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo | a b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo a | b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo | a > b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo < a | b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo < a | b");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "foo < a | b b1 b2 | c > d");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+
+ printf("%s\n", line = "foo > a | b < c");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+ printf("%s\n", line = "\"C:\\Program Files\\WinEdt\\WinEdt.exe\" -F \"[Open('%f');SelLine(%l,8)]\"");
+ if (cmd = parse_cmdline(line, &input, &output, 0)) {
+ display_cmd(cmd, input, output, NULL);
+ }
+
+ {
+ char buf[256];
+ char *app, *cmd;
+ while (gets(buf)) {
+ look_for_cmd(buf, &app, &cmd);
+ if (app) {
+ printf("app: %s, cmd: %s\n", app, cmd);
+ }
+ else {
+ printf("app not found, cmd: %s\n", cmd);
+ }
+ if (app) free(app);
+ if (cmd) free(cmd);
+ }
+ }
+}
+#endif
diff --git a/Build/source/libs/libgnuw32/lookcmd.exe b/Build/source/libs/libgnuw32/lookcmd.exe
new file mode 100755
index 00000000000..add27d9bf17
--- /dev/null
+++ b/Build/source/libs/libgnuw32/lookcmd.exe
Binary files differ
diff --git a/Build/source/libs/libgnuw32/oldnames.h b/Build/source/libs/libgnuw32/oldnames.h
new file mode 100644
index 00000000000..6ffcd62613d
--- /dev/null
+++ b/Build/source/libs/libgnuw32/oldnames.h
@@ -0,0 +1,469 @@
+
+#ifndef _OLDNAMES_H_
+#define _OLDNAMES_H_
+
+/* These have to be defined because our compilers treat __STDC__ as being
+ defined (most of them anyway). */
+/* Non-ANSI names for compatibility. Those symbols are defined
+ in oldnames.lib .
+ However, even if it is less safe, it might be better to just
+ #define the oldnames to the new names. Use the next macro
+ to change the behaviour.
+*/
+
+#if __STDC__
+
+/* from fcntl.h */
+
+#ifndef O_RDONLY
+#define O_RDONLY _O_RDONLY
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY _O_WRONLY
+#endif
+#ifndef O_RDWR
+#define O_RDWR _O_RDWR
+#endif
+#ifndef O_APPEND
+#define O_APPEND _O_APPEND
+#endif
+#ifndef O_CREAT
+#define O_CREAT _O_CREAT
+#endif
+#ifndef O_TRUNC
+#define O_TRUNC _O_TRUNC
+#endif
+#ifndef O_EXCL
+#define O_EXCL _O_EXCL
+#endif
+#ifndef O_TEXT
+#define O_TEXT _O_TEXT
+#endif
+#ifndef O_BINARY
+#define O_BINARY _O_BINARY
+#endif
+#ifndef O_RAW
+#define O_RAW _O_BINARY
+#endif
+#ifndef O_TEMPORARY
+#define O_TEMPORARY _O_TEMPORARY
+#endif
+#ifndef O_NOINHERIT
+#define O_NOINHERIT _O_NOINHERIT
+#endif
+#ifndef O_SEQUENTIAL
+#define O_SEQUENTIAL _O_SEQUENTIAL
+#endif
+#ifndef O_RANDOM
+#define O_RANDOM _O_RANDOM
+#endif
+
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct stat {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+ };
+
+/* from io.h */
+#if OLDNAMES_WITH_MACROS
+#define access _access
+#define chmod _chmod
+#define chsize _chsize
+#define close _close
+#define creat _creat
+#define dup _dup
+#define dup2 _dup2
+#if 0
+/* This one conflicts with texk/web2/lib/eofeoln.c */
+#define eof _eof
+#endif
+#define filelength _filelength
+#define isatty _isatty
+#define locking _locking
+#define lseek _lseek
+#define mktemp _mktemp
+#define open _open
+#define read _read
+#define setmode _setmode
+#define sopen _sopen
+#define tell _tell
+#define umask _umask
+#define unlink _unlink
+#define write _write
+#else
+_CRTIMP int __cdecl access(const char *, int);
+_CRTIMP int __cdecl chmod(const char *, int);
+_CRTIMP int __cdecl chsize(int, long);
+_CRTIMP int __cdecl close(int);
+_CRTIMP int __cdecl creat(const char *, int);
+_CRTIMP int __cdecl dup(int);
+_CRTIMP int __cdecl dup2(int, int);
+#if 0
+_CRTIMP int __cdecl eof(int);
+#endif
+_CRTIMP long __cdecl filelength(int);
+_CRTIMP int __cdecl isatty(int);
+_CRTIMP int __cdecl locking(int, int, long);
+_CRTIMP long __cdecl lseek(int, long, int);
+_CRTIMP char * __cdecl mktemp(char *);
+_CRTIMP int __cdecl open(const char *, int, ...);
+_CRTIMP int __cdecl read(int, void *, unsigned int);
+_CRTIMP int __cdecl setmode(int, int);
+_CRTIMP int __cdecl sopen(const char *, int, int, ...);
+_CRTIMP long __cdecl tell(int);
+_CRTIMP int __cdecl umask(int);
+_CRTIMP int __cdecl unlink(const char *);
+_CRTIMP int __cdecl write(int, const void *, unsigned int);
+#endif
+
+/* from conio.h */
+#if OLDNAMES_WITH_MACROS
+#define cgets _cgets
+#define cprintf _cprintf
+#define cputs _cputs
+#define cscanf _cscanf
+#define inp _inp
+#define inpw _inpw
+#define getch _getch
+#define getche _getche
+#define kbhit _kbhit
+#define outp _outp
+#define outpw _outpw
+#define putch _putch
+#define ungetch _ungetch
+#else
+_CRTIMP char * __cdecl cgets(char *);
+_CRTIMP int __cdecl cprintf(const char *, ...);
+_CRTIMP int __cdecl cputs(const char *);
+_CRTIMP int __cdecl cscanf(const char *, ...);
+int __cdecl inp(unsigned short);
+unsigned short __cdecl inpw(unsigned short);
+_CRTIMP int __cdecl getch(void);
+_CRTIMP int __cdecl getche(void);
+_CRTIMP int __cdecl kbhit(void);
+int __cdecl outp(unsigned short, int);
+unsigned short __cdecl outpw(unsigned short, unsigned short);
+_CRTIMP int __cdecl putch(int);
+_CRTIMP int __cdecl ungetch(int);
+#endif
+
+/* from malloc.h */
+#define alloca _alloca
+
+/* from direct.h */
+#if OLDNAMES_WITH_MACROS
+#define chdir _chdir
+#define getcwd _getcwd
+#define mkdir _mkdir
+#define rmdir _rmdir
+#else
+_CRTIMP int __cdecl chdir(const char *);
+_CRTIMP char * __cdecl getcwd(char *, int);
+_CRTIMP int __cdecl mkdir(const char *);
+_CRTIMP int __cdecl rmdir(const char *);
+#endif
+
+/* from time.h */
+#define CLK_TCK CLOCKS_PER_SEC
+
+#if OLDNAMES_WITH_MACROS
+#define daylight _daylight
+#define timezone _timezone
+#define tzname _tzname
+
+#define tzset _tzset
+#else
+_CRTIMP extern int daylight;
+_CRTIMP extern long timezone;
+_CRTIMP extern char * tzname[2];
+
+#define tzset _tzset
+#endif
+
+/* from process.h */
+#define P_WAIT _P_WAIT
+#define P_NOWAIT _P_NOWAIT
+#define P_OVERLAY _P_OVERLAY
+#define OLD_P_OVERLAY _OLD_P_OVERLAY
+#define P_NOWAITO _P_NOWAITO
+#define P_DETACH _P_DETACH
+#define WAIT_CHILD _WAIT_CHILD
+#define WAIT_GRANDCHILD _WAIT_GRANDCHILD
+
+#if OLD_P_OVERLAY
+#define cwait _cwait
+#define execl _execl
+#define execle _execle
+#define execlp _execlp
+#define execlpe _execlpe
+#define execv _execv
+#define execve _execve
+#define execvp _execvp
+#define execvpe _execvpe
+#define spawnl _spawnl
+#define spawnle _spawnle
+#define spawnlp _spawnlp
+#define spawnlpe _spawnlpe
+#define spawnv _spawnv
+#define spawnve _spawnve
+#define spawnvp _spawnvp
+#define spawnvpe _spawnvpe
+
+#define getpid _getpid
+#else
+_CRTIMP int __cdecl cwait(int *, int, int);
+_CRTIMP int __cdecl execl(const char *, const char *, ...);
+_CRTIMP int __cdecl execle(const char *, const char *, ...);
+_CRTIMP int __cdecl execlp(const char *, const char *, ...);
+_CRTIMP int __cdecl execlpe(const char *, const char *, ...);
+_CRTIMP int __cdecl execv(const char *, const char * const *);
+_CRTIMP int __cdecl execve(const char *, const char * const *, const char * const *);
+_CRTIMP int __cdecl execvp(const char *, const char * const *);
+_CRTIMP int __cdecl execvpe(const char *, const char * const *, const char * const *);
+_CRTIMP int __cdecl spawnl(int, const char *, const char *, ...);
+_CRTIMP int __cdecl spawnle(int, const char *, const char *, ...);
+_CRTIMP int __cdecl spawnlp(int, const char *, const char *, ...);
+_CRTIMP int __cdecl spawnlpe(int, const char *, const char *, ...);
+_CRTIMP int __cdecl spawnv(int, const char *, const char * const *);
+_CRTIMP int __cdecl spawnve(int, const char *, const char * const *,
+ const char * const *);
+_CRTIMP int __cdecl spawnvp(int, const char *, const char * const *);
+_CRTIMP int __cdecl spawnvpe(int, const char *, const char * const *,
+ const char * const *);
+
+_CRTIMP int __cdecl getpid(void);
+#endif
+
+/* from stdio.h */
+#define P_tmpdir _P_tmpdir
+#define SYS_OPEN _SYS_OPEN
+
+#if OLDNAMES_WITH_MACROS
+#define fcloseall _fcloseall
+#define fdopen _fdopen
+#define fgetchar _fgetchar
+#define fileno _fileno
+#define flushall _flushall
+#define fputchar _fputchar
+#define getw _getw
+#define putw _putw
+#define rmtmp _rmtmp
+#define tempnam _tempnam
+#define unlink _unlink
+#else
+_CRTIMP int __cdecl fcloseall(void);
+_CRTIMP FILE * __cdecl fdopen(int, const char *);
+_CRTIMP int __cdecl fgetchar(void);
+_CRTIMP int __cdecl fileno(FILE *);
+_CRTIMP int __cdecl flushall(void);
+_CRTIMP int __cdecl fputchar(int);
+_CRTIMP int __cdecl getw(FILE *);
+_CRTIMP int __cdecl putw(int, FILE *);
+_CRTIMP int __cdecl rmtmp(void);
+_CRTIMP char * __cdecl tempnam(const char *, const char *);
+_CRTIMP int __cdecl unlink(const char *);
+#endif
+
+/* from stdlib.h */
+
+#define sys_errlist _sys_errlist
+#define sys_nerr _sys_nerr
+#define environ _environ
+
+#define onexit_t _onexit_t
+
+#if OLDNAMES_WITH_MACROS
+#define ecvt _ecvt
+#define fcvt _fcvt
+#define gcvt _gcvt
+#define itoa _itoa
+#define ltoa _ltoa
+#define onexit _onexit
+#define putenv _putenv
+#define swab _swab
+#define ultoa _ultoa
+#else
+_CRTIMP char * __cdecl ecvt(double, int, int *, int *);
+_CRTIMP char * __cdecl fcvt(double, int, int *, int *);
+_CRTIMP char * __cdecl gcvt(double, int, char *);
+_CRTIMP char * __cdecl itoa(int, char *, int);
+_CRTIMP char * __cdecl ltoa(long, char *, int);
+ onexit_t __cdecl onexit(onexit_t);
+_CRTIMP int __cdecl putenv(const char *);
+_CRTIMP void __cdecl swab(char *, char *, int);
+_CRTIMP char * __cdecl ultoa(unsigned long, char *, int);
+#endif
+
+/* from sys/stat.h */
+#ifndef S_IFMT
+#define S_IFMT _S_IFMT
+#endif
+#ifndef S_IFDIR
+#define S_IFDIR _S_IFDIR
+#endif
+#ifndef S_IFCHR
+#define S_IFCHR _S_IFCHR
+#endif
+#ifndef S_IFIFO
+#define S_IFIFO _S_IFIFO
+#endif
+#ifndef S_IFREG
+#define S_IFREG _S_IFREG
+#endif
+#ifndef S_IREAD
+#define S_IREAD _S_IREAD
+#endif
+#ifndef S_IWRITE
+#define S_IWRITE _S_IWRITE
+#endif
+#ifndef S_IEXEC
+#define S_IEXEC _S_IEXEC
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR _S_IEXEC
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP _S_IEXEC
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH _S_IEXEC
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR _S_IREAD
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP _S_IREAD
+#endif
+#ifndef S_IROTH
+#define S_IROTH _S_IREAD
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR _S_IWRITE
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP _S_IWRITE
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH _S_IWRITE
+#endif
+
+#if OLDNAMES_WITH_MACROS
+#define fstat _fstat
+#else
+_CRTIMP int __cdecl fstat(int, struct stat *);
+#endif
+
+/* Alternatively, we could always use the MS one.
+ Which one is the most buggy ? :-> */
+#if REPLACE_LIBC_FUNCTIONS
+# define stat(p, s) win32_stat(p, s)
+# define system(p) win32_system(p, 0)
+# define popen(cmd, mode) win32_popen(cmd, mode)
+# define pclose(file) win32_pclose(file)
+#else
+# define popen(cmd, mode) _popen(cmd, mode)
+# define pclose(file) _pclose(file)
+_CRTIMP int __cdecl system(const char *);
+_CRTIMP FILE * __cdecl _popen(const char *, const char *);
+_CRTIMP int __cdecl _pclose(FILE *);
+# if OLDNAMES_WITH_MACROS
+# define stat _stat
+# else
+_CRTIMP int __cdecl stat(const char *, struct stat *);
+# endif
+#endif
+
+/* from sys/types.h */
+typedef long off_t;
+
+/* from string.h */
+#if OLDNAMES_WITH_MACROS
+#define memccpy _memccpy
+#define memicmp _memicmp
+#define strcmpi _strcmpi
+#define stricmp _stricmp
+#define strdup _strdup
+#define strlwr _strlwr
+#define strnicmp _strnicmp
+#define strnset _strnset
+#define strrev _strrev
+#define strset _strset
+#define strupr _strupr
+#else
+_CRTIMP void * __cdecl memccpy(void *, const void *, int, unsigned int);
+_CRTIMP int __cdecl memicmp(const void *, const void *, unsigned int);
+_CRTIMP int __cdecl strcmpi(const char *, const char *);
+_CRTIMP int __cdecl stricmp(const char *, const char *);
+_CRTIMP char * __cdecl strdup(const char *);
+_CRTIMP char * __cdecl strlwr(char *);
+_CRTIMP int __cdecl strnicmp(const char *, const char *, size_t);
+_CRTIMP char * __cdecl strnset(char *, int, size_t);
+_CRTIMP char * __cdecl strrev(char *);
+ char * __cdecl strset(char *, int);
+_CRTIMP char * __cdecl strupr(char *);
+#endif
+
+/* from ctype.h */
+#if !defined(_CTYPE_DEFINED) && !defined(OLDNAMES_WITH_MACROS)
+_CRTIMP int __cdecl isascii(int);
+_CRTIMP int __cdecl toascii(int);
+_CRTIMP int __cdecl iscsymf(int);
+_CRTIMP int __cdecl iscsym(int);
+#else
+#define isascii __isascii
+#define toascii __toascii
+#define iscsymf __iscsymf
+#define iscsym __iscsym
+#endif
+
+/* from sys/time.h */
+/* Non-ANSI name for compatibility */
+
+struct timeb {
+ time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+ };
+
+#if OLDNAMES_WITH_MACROS
+#define ftime _ftime
+#else
+_CRTIMP void __cdecl ftime(struct timeb *);
+#endif
+
+/* from sys/utime.h */
+
+struct utimbuf {
+ time_t actime; /* access time */
+ time_t modtime; /* modification time */
+ };
+
+#if OLDNAMES_WITH_MACROS
+#define utime _utime
+#else
+_CRTIMP int __cdecl utime(const char *, struct utimbuf *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDC__ */
+
+#endif /* _OLDNAMES_H_ */
diff --git a/Build/source/libs/libgnuw32/popen.c b/Build/source/libs/libgnuw32/popen.c
new file mode 100644
index 00000000000..796a54eeecf
--- /dev/null
+++ b/Build/source/libs/libgnuw32/popen.c
@@ -0,0 +1,296 @@
+/* libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ This does make sense only under WIN32.
+ Functions:
+ - popen() rewritten
+ - pclose() rewritten
+
+ FIXME :
+ - exit code ?
+ - check leaks.
+*/
+
+#include <win32lib.h>
+#include <errno.h>
+
+extern void free_cmd_pipe(char ***cmd_pipe, int nCmds);
+extern char *quote_args(char **argv);
+
+#undef _DEBUG
+
+#ifdef _DEBUG
+#define TRACE(x) x
+#else
+#define TRACE(x)
+#endif
+
+#define IS_DIRECTORY_SEP(c) IS_DIR_SEP(c)
+
+struct _popen_elt {
+ FILE *f; /* File stream returned */
+ HANDLE hp; /* Handle of associated process */
+ struct _popen_elt *next; /* Next list element */
+};
+
+static struct _popen_elt _z = { NULL, 0, &_z };
+static struct _popen_elt *_popen_list = &_z;
+
+static BOOL bCriticalSectionInitialized = FALSE;
+CRITICAL_SECTION thePopenCriticalSection;
+
+void __cdecl
+popen_cleanup(void)
+{
+ if (bCriticalSectionInitialized) {
+ DeleteCriticalSection(&thePopenCriticalSection);
+ }
+}
+
+FILE * __cdecl win32_popen (const char *cmd, const char *mode)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ FILE *f = NULL;
+ int fno, i;
+ HANDLE child_in, child_out;
+ HANDLE father_in, father_out;
+ HANDLE father_in_dup, father_out_dup;
+ HANDLE current_pid;
+ int binary_mode;
+ char *new_cmd = NULL, *app_name = NULL;
+ struct _popen_elt *new_process;
+ BOOL read_mode, write_mode;
+ char ***cmd_pipe;
+ int nCmds;
+
+ /* Admittedly, the command interpreter will allways be found. */
+ if (cmd == NULL) {
+ TRACE(fprintf(stderr, "popen: (null) command.\n"));
+ return NULL;
+ }
+
+
+ cmd_pipe = parse_cmdline(cmd, NULL, NULL, &nCmds);
+
+ /* Allow only one command in the pipe */
+ if (nCmds != 1) {
+ /* Failed to find the command or malformed cmd */
+ TRACE(fprintf(stderr, "system: failed to find command.\n"));
+ return NULL;
+ }
+
+ /* First time, allow to call the command interpretor */
+ if (look_for_cmd(cmd_pipe[0][0], &app_name) == FALSE) {
+ /* releasing previous split */
+ free_cmd_pipe(cmd_pipe, nCmds);
+ TRACE(fprintf(stderr, "look for command: %s not found, concatenating comspec\n", app_name));
+ new_cmd = concatn(getenv("COMSPEC"), " /c ", cmd, NULL);
+ TRACE(fprintf(stderr, "new command is: %s\n", new_cmd));
+ cmd_pipe = parse_cmdline(new_cmd, NULL, NULL, &nCmds);
+ /* We don't need it anymore */
+ free(new_cmd);
+ if (look_for_cmd(cmd_pipe[0][0], &app_name) == FALSE) {
+ /* Failed to find the command or malformed cmd */
+ TRACE(fprintf(stderr, "system: failed to find command.\n"));
+ return NULL;
+ }
+ }
+
+ new_cmd = quote_args(cmd_pipe[0]);
+
+ TRACE(fprintf(stderr, "popen: app_name = %s\n", app_name));
+ TRACE(fprintf(stderr, "popen: cmd_line = %s\n", new_cmd));
+
+ current_pid = GetCurrentProcess();
+
+ ZeroMemory( &si, sizeof(STARTUPINFO) );
+ si.cb = sizeof(STARTUPINFO);
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW ;
+ si.wShowWindow = /* 0 */ SW_HIDE ;
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ binary_mode = (strchr(mode, 'b') ? _O_BINARY : _O_TEXT);
+
+ read_mode = (strchr(mode, 'r') != 0);
+ write_mode = (strchr(mode, 'w') != 0);
+
+ /* Opening the pipe for writing */
+ if (write_mode) {
+ binary_mode |= _O_WRONLY;
+ if (CreatePipe(&child_in, &father_out, NULL, 0) == FALSE) {
+ fprintf(stderr, "popen: error CreatePipe\n");
+ return NULL;
+ }
+
+ if (DuplicateHandle(current_pid, child_in,
+ current_pid, &father_in_dup,
+ 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) {
+ fprintf(stderr, "popen: error DuplicateHandle father_out\n");
+ return NULL;
+ }
+ si.hStdInput = father_in_dup;
+
+ CloseHandle(child_in);
+ fno = _open_osfhandle((long)father_out, binary_mode);
+ f = _fdopen(fno, mode);
+ i = setvbuf( f, NULL, _IONBF, 0 );
+ }
+ /* Opening the pipe for reading */
+ else if (read_mode) {
+ binary_mode |= _O_RDONLY;
+ if (CreatePipe(&father_in, &child_out, NULL, 0) == FALSE) {
+ fprintf(stderr, "popen: error CreatePipe\n");
+ return NULL;
+ }
+ if (DuplicateHandle(current_pid, child_out,
+ current_pid, &father_out_dup,
+ 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE) {
+ fprintf(stderr, "popen: error DuplicateHandle father_in\n");
+ return NULL;
+ }
+ CloseHandle(child_out);
+ si.hStdOutput = father_out_dup;
+ fno = _open_osfhandle((long)father_in, binary_mode);
+ f = _fdopen(fno, mode);
+ i = setvbuf( f, NULL, _IONBF, 0 );
+ }
+ else {
+ fprintf(stderr, "popen: invalid mode %s\n", mode);
+ return NULL;
+ }
+
+ /* creating child process */
+ if (CreateProcess(app_name, /* pointer to name of executable module */
+ new_cmd, /* pointer to command line string */
+ NULL, /* pointer to process security attributes */
+ NULL, /* pointer to thread security attributes */
+ TRUE, /* handle inheritance flag */
+ 0, /* creation flags */
+ NULL, /* pointer to environment */
+ NULL, /* pointer to current directory */
+ &si, /* pointer to STARTUPINFO */
+ &pi /* pointer to PROCESS_INFORMATION */
+ ) == FALSE) {
+ fprintf(stderr, "popen: CreateProcess %x\n", GetLastError());
+ return NULL;
+ }
+
+ /* Only the process handle is needed, ignore errors */
+ CloseHandle(pi.hThread);
+
+ /* Closing the unnecessary part of the pipe */
+ if (read_mode) {
+ CloseHandle(father_out_dup);
+ }
+ else if (write_mode) {
+ CloseHandle(father_in_dup);
+ }
+
+ /* Add the pair (f, pi.hProcess) to the list */
+ if ((new_process = malloc(sizeof(struct _popen_elt))) == NULL) {
+ fprintf (stderr, "popen: malloc(new_process) error\n");
+ return NULL;
+ }
+
+ if (! bCriticalSectionInitialized) {
+ InitializeCriticalSection(&thePopenCriticalSection);
+ atexit(popen_cleanup);
+ bCriticalSectionInitialized = TRUE;
+ }
+
+ EnterCriticalSection(&thePopenCriticalSection);
+
+ /* Saving the FILE * pointer, access key for retrieving the process
+ handle later on */
+ new_process->f = f;
+ /* Saving the process handle */
+ new_process->hp = pi.hProcess;
+ /* Linking it to the list of popen() processes */
+ new_process->next = _popen_list;
+ _popen_list = new_process;
+
+ LeaveCriticalSection(&thePopenCriticalSection);
+
+ free_cmd_pipe(cmd_pipe, nCmds);
+
+ if (new_cmd) free(new_cmd);
+ if (app_name) free(app_name);
+
+ return f;
+}
+
+int __cdecl win32_pclose (FILE *f)
+{
+ HANDLE h;
+ struct _popen_elt *p, *q;
+ int exit_code;
+
+ EnterCriticalSection(&thePopenCriticalSection);
+
+ /* Look for f as the access key in the linked list */
+ for (q = NULL, p = _popen_list;
+ p != &_z && p->f != f;
+ q = p, p = p->next);
+
+ /* remove the elt from the list if found */
+ if (p != &_z) {
+ if (q != NULL)
+ q->next = p->next;
+ else
+ _popen_list = p->next;
+ /* remember the handle */
+ h = p->hp;
+ /* free up the block */
+ free(p);
+ }
+
+ LeaveCriticalSection(&thePopenCriticalSection);
+
+ if (p == &_z) {
+ fprintf(stderr, "pclose: error, file not found.");
+ return -1;
+ }
+
+ /* Closing the FILE pointer */
+ fclose(f);
+
+ /* Waiting for the process to terminate */
+ if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
+ fprintf(stderr, "pclose: error, process still active\n");
+ return -1;
+ }
+
+ /* retrieving the exit code */
+ if (GetExitCodeProcess(h, &exit_code) == 0) {
+ fprintf(stderr, "pclose: can't get process exit code\n");
+ return -1;
+ }
+
+ /* Closing the process handle, this will cause the system to
+ remove the process from memory */
+ if (CloseHandle(h) == FALSE) {
+ fprintf(stderr, "pclose: error closing process handle\n");
+ return -1;
+ }
+
+ return exit_code;
+}
diff --git a/Build/source/libs/libgnuw32/stat.c b/Build/source/libs/libgnuw32/stat.c
new file mode 100644
index 00000000000..f0353bd68c3
--- /dev/null
+++ b/Build/source/libs/libgnuw32/stat.c
@@ -0,0 +1,248 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+/*
+ MSVC stat function can't cope with UNC names and has other bugs, so
+ replace it with our own. This also allows us to calculate consistent
+ inode values without hacks in the main Emacs code.
+*/
+
+#include <win32lib.h>
+#include <errno.h>
+#if 0
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#endif
+
+extern struct passwd the_passwd;
+
+extern struct direct dir_static; /* simulated directory contents */
+extern HANDLE dir_find_handle;
+extern char dir_pathname[MAXPATHLEN+1];
+extern WIN32_FIND_DATA dir_find_data;
+
+extern FILETIME utc_base_ft;
+extern volume_info_data volume_info;
+
+int __cdecl
+win32_stat (const char * path, struct stat * buf)
+{
+ char * name;
+ WIN32_FIND_DATA wfd;
+ HANDLE fh;
+ DWORD fake_inode;
+ int permission;
+ int len;
+ int rootdir = FALSE;
+
+ if (path == NULL || buf == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ name = (char *) map_win32_filename (path, &path);
+ /* must be valid filename, no wild cards */
+ if (strchr (name, '*') || strchr (name, '?'))
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ /* Remove trailing directory separator, unless name is the root
+ directory of a drive or UNC volume in which case ensure there
+ is a trailing separator. */
+ len = strlen (name);
+ rootdir = (path >= name + len - 1
+ && (IS_DIR_SEP (*path) || *path == 0));
+ name = strcpy (alloca (len + 2), name);
+
+ if (rootdir)
+ {
+ if (!IS_DIR_SEP (name[len-1]))
+ strcat (name, "\\");
+ if (GetDriveType (name) < 2)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ memset (&wfd, 0, sizeof (wfd));
+ wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+ wfd.ftCreationTime = utc_base_ft;
+ wfd.ftLastAccessTime = utc_base_ft;
+ wfd.ftLastWriteTime = utc_base_ft;
+ strcpy (wfd.cFileName, name);
+ }
+ else
+ {
+ if (IS_DIR_SEP (name[len-1]))
+ name[len - 1] = 0;
+
+#if 0
+ /* (This is hacky, but helps when doing file completions on
+ network drives.) Optimize by using information available from
+ active readdir if possible. */
+ if (dir_find_handle != INVALID_HANDLE_VALUE &&
+ (len = strlen (dir_pathname)),
+ strnicmp (name, dir_pathname, len) == 0 &&
+ IS_DIR_SEP (name[len]) &&
+ stricmp (name + len + 1, dir_static.d_name) == 0)
+ {
+ /* This was the last entry returned by readdir. */
+ wfd = dir_find_data;
+ }
+ else
+#endif
+ {
+ fh = FindFirstFile (name, &wfd);
+ if (fh == INVALID_HANDLE_VALUE)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ FindClose (fh);
+ }
+ }
+
+ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+#ifdef TRACE_STAT
+ fprintf(stderr, "stat found %s is a directory\n", name );
+#endif
+ buf->st_mode = _S_IFDIR;
+ buf->st_nlink = 2; /* doesn't really matter */
+ fake_inode = 0; /* this doesn't either I think */
+ }
+ else
+#if 0
+ if (!NILP (Vmswindows_get_true_file_attributes))
+ {
+ /* This is more accurate in terms of getting the correct number
+ of links, but is quite slow (it is noticeable when Emacs is
+ making a list of file name completions). */
+ BY_HANDLE_FILE_INFORMATION info;
+
+ /* No access rights required to get info. */
+ fh = CreateFile (name, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, 0, NULL);
+
+ if (GetFileInformationByHandle (fh, &info))
+ {
+ switch (GetFileType (fh))
+ {
+ case FILE_TYPE_DISK:
+ buf->st_mode = _S_IFREG;
+ break;
+ case FILE_TYPE_PIPE:
+ buf->st_mode = _S_IFIFO;
+ break;
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_UNKNOWN:
+ default:
+ buf->st_mode = _S_IFCHR;
+ }
+ buf->st_nlink = (short) info.nNumberOfLinks;
+ /* Might as well use file index to fake inode values, but this
+ is not guaranteed to be unique unless we keep a handle open
+ all the time (even then there are situations where it is
+ not unique). Reputedly, there are at most 48 bits of info
+ (on NTFS, presumably less on FAT). */
+ fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh;
+ CloseHandle (fh);
+ }
+ else
+ {
+ errno = EACCES;
+ return -1;
+ }
+ }
+ else
+#endif /* 0 */
+ {
+ /* Don't bother to make this information more accurate. */
+ buf->st_mode = _S_IFREG;
+ buf->st_nlink = 1;
+ fake_inode = 0;
+ }
+
+#if 0
+ /* Not sure if there is any point in this. */
+ if (!NILP (Vwin32_generate_fake_inodes))
+ fake_inode = generate_inode_val (name);
+ else if (fake_inode == 0)
+ {
+ /* For want of something better, try to make everything unique. */
+ static DWORD gen_num = 0;
+ fake_inode = ++gen_num;
+ }
+#endif
+
+ /* #### MSVC defines _ino_t to be short; other libc's might not. */
+ buf->st_ino = (unsigned short) (fake_inode ^ (fake_inode >> 16));
+
+ /* consider files to belong to current user */
+ buf->st_uid = the_passwd.pw_uid;
+ buf->st_gid = the_passwd.pw_gid;
+
+ /* volume_info is set indirectly by map_win32_filename */
+ buf->st_dev = volume_info.serialnum;
+ buf->st_rdev = volume_info.serialnum;
+
+
+ buf->st_size = wfd.nFileSizeLow;
+
+ /* Convert timestamps to Unix format. */
+ buf->st_mtime = convert_time (wfd.ftLastWriteTime);
+ buf->st_atime = convert_time (wfd.ftLastAccessTime);
+ if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
+ buf->st_ctime = convert_time (wfd.ftCreationTime);
+ if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+
+ /* determine rwx permissions */
+ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ permission = _S_IREAD;
+ else
+ permission = _S_IREAD | _S_IWRITE;
+
+ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ permission |= _S_IEXEC;
+ else
+ {
+ char * p = strrchr (name, '.');
+ if (p != NULL &&
+ (stricmp (p, ".exe") == 0 ||
+ stricmp (p, ".com") == 0 ||
+ stricmp (p, ".bat") == 0 ||
+ stricmp (p, ".cmd") == 0))
+ permission |= _S_IEXEC;
+ }
+
+ buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
+
+ return 0;
+}
diff --git a/Build/source/libs/libgnuw32/string.c b/Build/source/libs/libgnuw32/string.c
new file mode 100644
index 00000000000..774a02c3354
--- /dev/null
+++ b/Build/source/libs/libgnuw32/string.c
@@ -0,0 +1,100 @@
+/* libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <win32lib.h>
+
+char *xstrdup(const char *s)
+{
+ char *p = _strdup(s);
+ if (!p) {
+ fprintf(stderr, "strdup(%x) failed in gnuw32.c at line %d\n", s, __LINE__);
+ exit(1);
+ }
+ return p;
+}
+
+void *xmalloc(unsigned size)
+{
+ void *p = malloc(size);
+ if (!p) {
+ fprintf(stderr, "malloc(%d) failed in gnuw32.c at line %d\n", size, __LINE__);
+ exit(1);
+ }
+ return p;
+}
+
+void *xrealloc(void *p, unsigned size)
+{
+ p = realloc(p, size);
+ if (!p) {
+ fprintf(stderr, "realloc(%d) failed in gnuw32.c at line %d\n", size, __LINE__);
+ exit(1);
+ }
+ return p;
+}
+
+char *concat(const char *s1, const char *s2)
+{
+ char *answer = (char *) xmalloc (strlen (s1) + strlen (s2) + 1);
+ strcpy (answer, s1);
+ strcat (answer, s2);
+
+ return answer;
+}
+
+char *concat3(const char *s1, const char *s2, const char *s3)
+{
+ char *answer
+ = (char *) xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1);
+ strcpy (answer, s1);
+ strcat (answer, s2);
+ strcat (answer, s3);
+
+ return answer;
+}
+
+char *concatn(const char *str1, ...)
+{
+ char *arg, *ret;
+ int size = 1;
+ va_list marker;
+
+ if (!str1)
+ return NULL;
+
+ size = strlen(str1);
+
+ va_start(marker, str1);
+ while ((arg = va_arg (marker, char*)) != NULL) {
+ size += strlen(arg);
+ }
+ va_end (marker);
+
+
+ ret = xmalloc(size + 1);
+ strcpy(ret, str1);
+
+ va_start(marker, str1);
+ while ((arg = va_arg (marker, char*)) != NULL) {
+ strcat(ret, arg);
+ }
+ va_end (marker);
+
+ return ret;
+}
diff --git a/Build/source/libs/libgnuw32/system.c b/Build/source/libs/libgnuw32/system.c
new file mode 100644
index 00000000000..fbc20a8f513
--- /dev/null
+++ b/Build/source/libs/libgnuw32/system.c
@@ -0,0 +1,307 @@
+/* libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ This does make sense only under WIN32.
+ Functions:
+ - win32_system() rewritten
+ */
+
+#include <win32lib.h>
+#include <errno.h>
+
+#undef _DEBUG
+
+#ifdef _DEBUG
+#define TRACE(x) x
+#else
+#define TRACE(x)
+#endif
+
+extern char *quote_args(char **argv);
+extern void free_cmd_pipe(char ***cmd_pipe, int nCmds);
+
+/*
+ It has been proven that system() fails to retrieve exit codes
+ under Win9x. This is a workaround for this bug.
+*/
+
+int __cdecl win32_system(const char *cmd, int async)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ DWORD ret = 0, dwCode;
+ HANDLE *hIn, *hOut, *hProcess, hDummyIn, hDummyOut, hDummyErr, hCurrentProcess;
+ int i, j, nCmds;
+
+ char *app_name = NULL, *new_cmd = NULL;
+ char *red_input, *red_output, ***cmd_pipe;
+
+ /* Reset errno ??? */
+ errno = 0;
+
+ /* Admittedly, the command interpreter will allways be found. */
+ if (! cmd) {
+ TRACE(fprintf(stderr, "system: (null) command.\n"));
+ errno = 0;
+ return 1;
+ }
+
+ cmd_pipe = parse_cmdline(cmd, &red_input, &red_output, &nCmds);
+
+ if (nCmds == 0) {
+ /* Failed to find the command or malformed cmd */
+ TRACE(fprintf(stderr, "system: failed to find command.\n"));
+ errno = ENOEXEC;
+ return -1;
+ }
+
+ /* First time, allow to call the command interpretor */
+ if (look_for_cmd(cmd_pipe[0][0], &app_name) == FALSE) {
+ /* releasing previous split */
+ TRACE(fprintf(stderr, "look for command: `%s' not found, concatenating comspec\n", cmd_pipe[0][0]));
+ free_cmd_pipe(cmd_pipe, nCmds);
+ new_cmd = concatn(getenv("COMSPEC"), " /c ", cmd, NULL);
+ TRACE(fprintf(stderr, "new command is: %s\n", new_cmd));
+ cmd_pipe = parse_cmdline(new_cmd, &red_input, &red_output, &nCmds);
+ if (nCmds == 0 || look_for_cmd(cmd_pipe[0][0], &app_name) == FALSE) {
+ /* Failed to find the command or malformed cmd */
+ TRACE(fprintf(stderr, "system: failed to find command.\n"));
+ errno = ENOEXEC;
+ return -1;
+ }
+ }
+
+ /* Arrays for pipes handles and process handles */
+ hIn = malloc(nCmds * sizeof(HANDLE));
+ hOut = malloc(nCmds * sizeof(HANDLE));
+ hProcess = malloc(nCmds * sizeof(HANDLE));
+
+ for (i = 0; i < nCmds; i++) {
+ hIn[i] = hOut[i] = hProcess[i] = INVALID_HANDLE_VALUE;
+ }
+
+ /* We need this handle to duplicate other handles */
+ hCurrentProcess = GetCurrentProcess();
+
+ TRACE(fprintf(stderr, "%d cmds found\n", nCmds));
+
+ /* First time, use red_input if available */
+
+ if (red_input) {
+ hIn[0] = CreateFile(red_input,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, /* non inheritable */
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hIn[0] == INVALID_HANDLE_VALUE) {
+ TRACE(fprintf(stderr, "system: failed to open hIn (%s) with error %d.\n", red_input, GetLastError()));
+ errno = EIO;
+ return -1;
+ }
+
+ TRACE(fprintf(stderr, "First pipe input redirected to %s\n", red_input));
+
+ }
+ else {
+ hDummyIn = GetStdHandle(STD_INPUT_HANDLE);
+ DuplicateHandle(hCurrentProcess, hDummyIn,
+ hCurrentProcess, &hIn[0], 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ TRACE(fprintf(stderr, "STD_INPUT_HANDLE %x -> %x\n", hDummyIn, hIn[0]));
+ }
+
+ /* Last time, use red_output if available */
+ if (red_output) {
+ hOut[nCmds - 1] = CreateFile(red_output,
+ GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, /* non inheritable */
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hOut[nCmds - 1] == INVALID_HANDLE_VALUE) {
+
+ TRACE(fprintf(stderr, "system: failed to open hOut (%s) with error %d.\n",
+ red_output, GetLastError()));
+
+ errno = EIO;
+ return -1;
+ }
+
+ TRACE(fprintf(stderr, "Last pipe output redirected to %s\n", red_output));
+
+ }
+ else {
+ hDummyOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ DuplicateHandle(hCurrentProcess, hDummyOut,
+ hCurrentProcess, &hOut[nCmds - 1], 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ TRACE(fprintf(stderr, "STD_OUTPUT_HANDLE %x -> %x\n", hDummyOut, hOut[nCmds - 1]));
+ }
+
+ hDummyErr = GetStdHandle(STD_ERROR_HANDLE);
+
+
+ /* Loop on every command */
+ for (i = 0; i < nCmds; i++) {
+
+ /* free the cmd and build the current one */
+ if (new_cmd) {
+ free(new_cmd);
+ new_cmd = NULL;
+ }
+ if (app_name) {
+ free(app_name);
+ app_name = NULL;
+ }
+
+ /* Get the real app_name */
+ if (look_for_cmd(cmd_pipe[i][0], &app_name) == FALSE) {
+ errno = ENOEXEC;
+ ret = -1;
+ goto cleanup;
+ }
+
+ new_cmd = quote_args(cmd_pipe[i]);
+
+ TRACE(fprintf(stderr, "Cmd[%d] = %s\n", i, new_cmd));
+
+ if (i < nCmds - 1) {
+ /* Handles are created non-inheritable */
+ if (CreatePipe(&hIn[i+1], &hOut[i], NULL, 4096) == FALSE) {
+ fprintf(stderr, "win32_system(%s) call failed to create pipe (Error %d).\n", cmd, GetLastError());
+ }
+
+ TRACE(fprintf(stderr, "Creating pipe between hOut[%d] = %x and hIn[%d] = %x\n",
+ i, hOut[i], i+1, hIn[i+1]));
+
+ }
+
+ /* Enable handle inheritance for hIn[i] */
+ DuplicateHandle(hCurrentProcess, hIn[i],
+ hCurrentProcess, &hDummyIn, 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+
+ TRACE(fprintf(stderr, "Duplicating hIn %x -> %x\n", hIn[i], hDummyIn));
+
+ /* Enable handle inheritance for hOut[i] */
+ DuplicateHandle(hCurrentProcess, hOut[i],
+ hCurrentProcess, &hDummyOut, 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+
+ TRACE(fprintf(stderr, "Duplicating hOut %x -> %x\n", hOut[i], hDummyOut));
+
+ /* We don't need them anymore */
+ CloseHandle(hIn[i]);
+ CloseHandle(hOut[i]);
+ TRACE(fprintf(stderr, "Close handles hIn = %x and hOut = %x\n", hIn[i], hOut[i]));
+
+ ZeroMemory( &si, sizeof(STARTUPINFO) );
+ si.cb = sizeof(STARTUPINFO);
+ si.dwFlags = STARTF_USESTDHANDLES /* | STARTF_USESHOWWINDOW */ ;
+ si.wShowWindow = 0 /* SW_SHOWDEFAULT */ ;
+ si.hStdInput = hDummyIn;
+ si.hStdOutput = hDummyOut;
+ si.hStdError = hDummyErr;
+
+ TRACE(fprintf(stderr, "Executing: %s (app_name = %s)\n", new_cmd, app_name));
+
+ dwCode = CreateProcess(app_name,
+ new_cmd,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi);
+
+ TRACE(fprintf(stderr, "New cmd(%s), process handle %x, Id %d, ret (%d), error (%d).\n",
+ new_cmd, pi.hProcess, pi.dwProcessId, dwCode,
+ (dwCode ? 0 : GetLastError() )));
+
+ CloseHandle(hDummyIn);
+ CloseHandle(hDummyOut);
+
+ if (dwCode != 0) {
+ TRACE(fprintf(stderr, "StdIn = %x(%x), StdOut = %x(%x)\n",
+ hIn[i], hDummyIn, hOut[i], hDummyOut));
+
+ /* Only the process handle is needed */
+ CloseHandle(pi.hThread);
+ hProcess[i] = pi.hProcess;
+ }
+ else {
+ fprintf(stderr, "win32_system(%s) call failed to create process (Error %d, hProcess %d).\n", new_cmd, GetLastError(), pi.hProcess);
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+
+ for (i = 0; i < nCmds; i++) {
+ if (hProcess[i] != INVALID_HANDLE_VALUE) {
+ if (ret == -1) {
+ TerminateProcess(hProcess[i], -1);
+ }
+ else if (async == 0) {
+ DWORD dwRet = WaitForSingleObject(hProcess[i], INFINITE);
+ if (dwRet == WAIT_OBJECT_0) {
+
+ TRACE(fprintf(stderr, "Process %d exited\n", i));
+
+ }
+ else {
+ fprintf(stderr, "Failed to wait for process termination: %s (Ret %d, Error %d)\n",
+ cmd, dwRet, GetLastError());
+ ret = -1;
+ }
+ }
+ }
+ }
+
+ if (async == 0 && hProcess[nCmds - 1] != INVALID_HANDLE_VALUE) {
+ if (GetExitCodeProcess(hProcess[nCmds - 1], &ret) == 0) {
+ fprintf(stderr, "Failed to retrieve exit code: %s (Error %d)\n", cmd, GetLastError());
+ ret = -1;
+ }
+
+ TRACE(fprintf(stderr, "All processes terminated, exit code = %d\n", ret));
+
+ }
+
+ for(i = 0; i < nCmds; i++) {
+ if (hProcess[i] != INVALID_HANDLE_VALUE)
+ CloseHandle(hProcess[i]);
+ }
+ free_cmd_pipe(cmd_pipe, nCmds);
+
+ if (new_cmd) free(new_cmd);
+ if (app_name) free(app_name);
+
+ return ret;
+}
diff --git a/Build/source/libs/libgnuw32/system_popen_check.c b/Build/source/libs/libgnuw32/system_popen_check.c
new file mode 100644
index 00000000000..f8fbe62dc5f
--- /dev/null
+++ b/Build/source/libs/libgnuw32/system_popen_check.c
@@ -0,0 +1,27 @@
+#include "win32lib.h"
+
+main(int argc, char *argv[])
+{
+ int ret;
+ FILE *f;
+ int c;
+
+ if (argc != 3) {
+ exit(1);
+ }
+ if (strncmp(argv[1], "syst", 4) == 0) {
+ printf("Running cmd `%s'\n", argv[2]);
+ ret = system(argv[2]);
+ printf("return code = %d\n");
+ }
+ else if (strncmp(argv[1], "popr", 4) == 0) {
+ f = popen(argv[2], "r");
+ while ((c = fgetc(f)) != EOF) fputc(c, stdout);
+ pclose(f);
+ }
+ else if (strncmp(argv[1], "popw", 4) == 0) {
+ f = popen(argv[2], "w");
+ while ((c = fgetc(stdin)) != EOF) fputc(c, f);
+ pclose(f);
+ }
+}
diff --git a/Build/source/libs/libgnuw32/time.c b/Build/source/libs/libgnuw32/time.c
new file mode 100644
index 00000000000..747cd59d997
--- /dev/null
+++ b/Build/source/libs/libgnuw32/time.c
@@ -0,0 +1,64 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+#include <win32lib.h>
+
+FILETIME utc_base_ft;
+static long double utc_base;
+static int init = 0;
+
+time_t
+convert_time (FILETIME ft)
+{
+ long double ret;
+
+ if (!init)
+ {
+ /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
+ SYSTEMTIME st;
+
+ st.wYear = 1970;
+ st.wMonth = 1;
+ st.wDay = 1;
+ st.wHour = 0;
+ st.wMinute = 0;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+
+ SystemTimeToFileTime (&st, &utc_base_ft);
+ utc_base = (long double) utc_base_ft.dwHighDateTime
+ * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
+ init = 1;
+ }
+
+ if (CompareFileTime (&ft, &utc_base_ft) < 0)
+ return 0;
+
+ ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
+ ret -= utc_base;
+ return (time_t) (ret * 1e-7);
+}
diff --git a/Build/source/libs/libgnuw32/user.c b/Build/source/libs/libgnuw32/user.c
new file mode 100644
index 00000000000..ec870c278b4
--- /dev/null
+++ b/Build/source/libs/libgnuw32/user.c
@@ -0,0 +1,224 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+/* Emulate getpwuid, getpwnam and others. */
+
+#include <win32lib.h>
+
+#define PASSWD_FIELD_SIZE 256
+
+static char the_passwd_name[PASSWD_FIELD_SIZE];
+static char the_passwd_passwd[PASSWD_FIELD_SIZE];
+static char the_passwd_gecos[PASSWD_FIELD_SIZE];
+static char the_passwd_dir[PASSWD_FIELD_SIZE];
+static char the_passwd_shell[PASSWD_FIELD_SIZE];
+
+struct passwd the_passwd =
+{
+ the_passwd_name,
+ the_passwd_passwd,
+ 0,
+ 0,
+ 0,
+ the_passwd_gecos,
+ the_passwd_dir,
+ the_passwd_shell,
+};
+
+int
+getuid ()
+{
+ return the_passwd.pw_uid;
+}
+
+int
+geteuid ()
+{
+ /* I could imagine arguing for checking to see whether the user is
+ in the Administrators group and returning a UID of 0 for that
+ case, but I don't know how wise that would be in the long run. */
+ return getuid ();
+}
+
+int
+getgid ()
+{
+ return the_passwd.pw_gid;
+}
+
+int
+getegid ()
+{
+ return getgid ();
+}
+
+struct passwd *
+getpwuid (int uid)
+{
+ if (uid == the_passwd.pw_uid)
+ return &the_passwd;
+ return NULL;
+}
+
+struct passwd *
+getpwnam (const char *name)
+{
+ struct passwd *pw;
+
+ pw = getpwuid (getuid ());
+ if (!pw)
+ return pw;
+
+ if (stricmp (name, pw->pw_name))
+ return NULL;
+
+ return pw;
+}
+
+void
+init_user_info ()
+{
+ /* Find the user's real name by opening the process token and
+ looking up the name associated with the user-sid in that token.
+
+ Use the relative portion of the identifier authority value from
+ the user-sid as the user id value (same for group id using the
+ primary group sid from the process token). */
+#if 0
+ char user_sid[256], name[256], domain[256];
+ DWORD length = sizeof (name), dlength = sizeof (domain), trash;
+ HANDLE token = NULL;
+ SID_NAME_USE user_type;
+
+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token)
+ && GetTokenInformation (token, TokenUser,
+ (PVOID) user_sid, sizeof (user_sid), &trash)
+ && LookupAccountSid (NULL, *((PSID *) user_sid), name, &length,
+ domain, &dlength, &user_type))
+ {
+ strcpy (the_passwd.pw_name, name);
+ /* Determine a reasonable uid value. */
+ if (stricmp ("administrator", name) == 0)
+ {
+ the_passwd.pw_uid = 0;
+ the_passwd.pw_gid = 0;
+ }
+ else
+ {
+ SID_IDENTIFIER_AUTHORITY * pSIA;
+
+ pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
+ /* I believe the relative portion is the last 4 bytes (of 6)
+ with msb first. */
+ the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
+ (pSIA->Value[3] << 16) +
+ (pSIA->Value[4] << 8) +
+ (pSIA->Value[5] << 0));
+ /* restrict to conventional uid range for normal users */
+ the_passwd.pw_uid = the_passwd.pw_uid % 60001;
+
+ /* Get group id */
+ if (GetTokenInformation (token, TokenPrimaryGroup,
+ (PVOID) user_sid, sizeof (user_sid), &trash))
+ {
+ SID_IDENTIFIER_AUTHORITY * pSIA;
+
+ pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
+ the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
+ (pSIA->Value[3] << 16) +
+ (pSIA->Value[4] << 8) +
+ (pSIA->Value[5] << 0));
+ /* I don't know if this is necessary, but for safety... */
+ the_passwd.pw_gid = the_passwd.pw_gid % 60001;
+ }
+ else
+ the_passwd.pw_gid = the_passwd.pw_uid;
+ }
+ }
+ /* If security calls are not supported (presumably because we
+ are running under Windows 95), fallback to this. */
+ else
+ if (GetUserName (name, &length))
+ {
+ strcpy (the_passwd.pw_name, name);
+ if (stricmp ("administrator", name) == 0)
+ the_passwd.pw_uid = 0;
+ else
+ the_passwd.pw_uid = 123;
+ the_passwd.pw_gid = the_passwd.pw_uid;
+ }
+ else
+#else
+ {
+ strcpy (the_passwd.pw_name, "unknown");
+ the_passwd.pw_uid = 123;
+ the_passwd.pw_gid = 123;
+ }
+#endif
+
+ /* Ensure HOME and SHELL are defined. */
+#if 1
+ /*
+ * With XEmacs, setting $HOME is deprecated.
+ * But with fpTeX, it is safer to assume $HOME defined.
+ */
+ {
+ char *home = get_home_directory();
+ if (home) {
+ putenv(concat("HOME=", home));
+ }
+ else {
+ putenv ("HOME=c:/");
+ }
+ }
+#endif
+ if (getenv ("SHELL") == NULL)
+ putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
+
+ {
+ /* Win2K problem : we need a specific TEMP directory with
+ full access rights so that any user building a format file
+ or a font file will build it with full access rights. The installer
+ takes care of defining TEXMFTEMP=$SELFAUTOPARENT/tmp in the environment.
+ If it is defined, then use it as the TEMP and TMP variables.
+ */
+ char *p;
+ if ((p = getenv("TEXMFTEMP")) != NULL) {
+ putenv(concat("TEMP=", p));
+ putenv(concat("TMP=", p));
+ }
+ }
+
+ /* Set dir and shell from environment variables. */
+ strcpy (the_passwd.pw_dir, get_home_directory());
+ strcpy (the_passwd.pw_shell, getenv ("SHELL"));
+
+#if 0
+ if (token)
+ CloseHandle (token);
+#endif
+}
diff --git a/Build/source/libs/libgnuw32/volume.c b/Build/source/libs/libgnuw32/volume.c
new file mode 100644
index 00000000000..ad5e35dbc44
--- /dev/null
+++ b/Build/source/libs/libgnuw32/volume.c
@@ -0,0 +1,244 @@
+/* Utility and Unix shadow routines for XEmacs on Windows NT.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+
+ Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
+
+/* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
+/* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
+/* Adapted to fpTeX 0.4 by Fabrice Popineau <Fabrice.Popineau@supelec.fr> */
+
+#include <win32lib.h>
+
+/* #### This is an evil dirty hack. We must get rid of it.
+ Word "munging" is not in XEmacs lexicon. - kkm */
+
+/* Internal MSVC data and functions for low-level descriptor munging */
+#if (_MSC_VER == 900)
+extern char _osfile[];
+#endif
+extern int __cdecl _set_osfhnd (int fd, long h);
+extern int __cdecl _free_osfhnd (int fd);
+
+#if 0
+/* parallel array of private info on file handles */
+typedef struct
+{
+ unsigned flags;
+ HANDLE hnd;
+ child_process * cp;
+} filedesc;
+
+/* parallel array of private info on file handles */
+filedesc fd_info [ MAXDESC ];
+#endif
+
+/* Global referenced by various functions. */
+volume_info_data volume_info;
+
+/* Vector to indicate which drives are local and fixed (for which cached
+ data never expires). */
+static BOOL fixed_drives[26];
+
+/* Consider cached volume information to be stale if older than 10s,
+ at least for non-local drives. Info for fixed drives is never stale. */
+#define DRIVE_INDEX( c ) ( (c) <= 'Z' ? (c) - 'A' : (c) - 'a' )
+#define VOLINFO_STILL_VALID( root_dir, info ) \
+ ( ( isalpha (root_dir[0]) && \
+ fixed_drives[ DRIVE_INDEX (root_dir[0]) ] ) \
+ || GetTickCount () - info->timestamp < 10000 )
+
+/* Cache support functions. */
+
+/* Simple linked list with linear search is sufficient. */
+static volume_info_data *volume_cache = NULL;
+
+static volume_info_data *
+lookup_volume_info (char * root_dir)
+{
+ volume_info_data * info;
+
+ for (info = volume_cache; info; info = info->next)
+ if (stricmp (info->root_dir, root_dir) == 0)
+ break;
+ return info;
+}
+
+static void
+add_volume_info (char * root_dir, volume_info_data * info)
+{
+ info->root_dir = xstrdup (root_dir);
+ info->next = volume_cache;
+ volume_cache = info;
+}
+
+
+/* Wrapper for GetVolumeInformation, which uses caching to avoid
+ performance penalty (~2ms on 486 for local drives, 7.5ms for local
+ cdrom drive, ~5-10ms or more for remote drives on LAN). */
+volume_info_data *
+GetCachedVolumeInformation (char * root_dir)
+{
+ volume_info_data * info;
+ char default_root[ MAX_PATH ];
+
+ /* NULL for root_dir means use root from current directory. */
+ if (root_dir == NULL)
+ {
+ if (GetCurrentDirectory (MAX_PATH, default_root) == 0)
+ return NULL;
+ _parse_root (default_root, &root_dir);
+ *root_dir = 0;
+ root_dir = default_root;
+ }
+
+ /* Local fixed drives can be cached permanently. Removable drives
+ cannot be cached permanently, since the volume name and serial
+ number (if nothing else) can change. Remote drives should be
+ treated as if they are removable, since there is no sure way to
+ tell whether they are or not. Also, the UNC association of drive
+ letters mapped to remote volumes can be changed at any time (even
+ by other processes) without notice.
+
+ As a compromise, so we can benefit from caching info for remote
+ volumes, we use a simple expiry mechanism to invalidate cache
+ entries that are more than ten seconds old. */
+
+#if 0
+ /* No point doing this, because WNetGetConnection is even slower than
+ GetVolumeInformation, consistently taking ~50ms on a 486 (FWIW,
+ GetDriveType is about the only call of this type which does not
+ involve network access, and so is extremely quick). */
+
+ /* Map drive letter to UNC if remote. */
+ if ( isalpha( root_dir[0] ) && !fixed[ DRIVE_INDEX( root_dir[0] ) ] )
+ {
+ char remote_name[ 256 ];
+ char drive[3] = { root_dir[0], ':' };
+
+ if (WNetGetConnection (drive, remote_name, sizeof (remote_name))
+ == NO_ERROR)
+ /* do something */ ;
+ }
+#endif
+
+ info = lookup_volume_info (root_dir);
+
+ if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info))
+ {
+ char name[ 256 ];
+ DWORD serialnum;
+ DWORD maxcomp;
+ DWORD flags;
+ char type[ 256 ];
+
+ /* Info is not cached, or is stale. */
+ if (!GetVolumeInformation (root_dir,
+ name, sizeof (name),
+ &serialnum,
+ &maxcomp,
+ &flags,
+ type, sizeof (type)))
+ return NULL;
+
+ /* Cache the volume information for future use, overwriting existing
+ entry if present. */
+ if (info == NULL)
+ {
+ info = (volume_info_data *) xmalloc (sizeof (volume_info_data));
+ add_volume_info (root_dir, info);
+ }
+ else
+ {
+ free (info->name);
+ free (info->type);
+ }
+
+ info->name = xstrdup (name);
+ info->serialnum = serialnum;
+ info->maxcomp = maxcomp;
+ info->flags = flags;
+ info->type = xstrdup (type);
+ info->timestamp = GetTickCount ();
+ }
+
+ return info;
+}
+
+/* Get information on the volume where name is held; set path pointer to
+ start of pathname in name (past UNC header\volume header if present). */
+int
+get_volume_info (const char * name, const char ** pPath)
+{
+ char temp[MAX_PATH];
+ char *rootname = NULL; /* default to current volume */
+ volume_info_data * info;
+
+ if (name == NULL)
+ return FALSE;
+
+ /* find the root name of the volume if given */
+ if (isalpha (name[0]) && name[1] == ':')
+ {
+ rootname = temp;
+ temp[0] = *name++;
+ temp[1] = *name++;
+ temp[2] = '\\';
+ temp[3] = 0;
+ }
+ else if (IS_DIR_SEP (name[0]) && IS_DIR_SEP (name[1]))
+ {
+ char *str = temp;
+ int slashes = 4;
+ rootname = temp;
+ do
+ {
+ if (IS_DIR_SEP (*name) && --slashes == 0)
+ break;
+ *str++ = *name++;
+ }
+ while ( *name );
+
+ *str++ = '\\';
+ *str = 0;
+ }
+
+ if (pPath)
+ *pPath = name;
+
+ info = GetCachedVolumeInformation (rootname);
+ if (info != NULL)
+ {
+ /* Set global referenced by other functions. */
+ volume_info = *info;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Determine if volume is FAT format (ie. only supports short 8.3
+ names); also set path pointer to start of pathname in name. */
+int
+is_fat_volume (const char * name, const char ** pPath)
+{
+ if (get_volume_info (name, pPath))
+ return (volume_info.maxcomp == 12);
+ return FALSE;
+}
diff --git a/Build/source/libs/libgnuw32/win32.mak b/Build/source/libs/libgnuw32/win32.mak
new file mode 100644
index 00000000000..e654ab2de84
--- /dev/null
+++ b/Build/source/libs/libgnuw32/win32.mak
@@ -0,0 +1,82 @@
+################################################################################
+#
+# Makefile : Gnu Win32
+# Author : Fabrice Popineau <Fabrice.Popineau@supelec.fr>
+# Platform : Win32, Microsoft VC++ 6.0, depends upon fpTeX 0.5 sources
+# Time-stamp: <02/10/25 23:50:48 popineau>
+#
+################################################################################
+root_srcdir=..\..
+!ifdef DEVELOPMENT
+INCLUDE=$(INCLUDE);$(root_srcdir)\texk.development
+!else
+INCLUDE=$(INCLUDE);$(root_srcdir)\texk
+!endif
+
+USE_GNUW32 = 1
+MAKE_GNUW32 = 1
+
+!include <msvc/common.mak>
+
+{$(root_srcdir)/texk/kpathsea}.c{$(objdir)}.obj:
+ $(compile) $<
+
+DEFS = $(DEFS) -I$(kpathseadir)\..
+
+objects = \
+# $(objdir)\dirent.obj \
+ $(objdir)\error.obj \
+ $(objdir)\filename.obj \
+ $(objdir)\getopt.obj \
+ $(objdir)\getopt1.obj \
+ $(objdir)\home.obj \
+ $(objdir)\lookcmd.obj \
+ $(objdir)\popen.obj \
+ $(objdir)\stat.obj \
+ $(objdir)\string.obj \
+ $(objdir)\system.obj \
+ $(objdir)\time.obj \
+ $(objdir)\user.obj \
+ $(objdir)\volume.obj
+
+programs = $(gnuw32dll)
+libfiles = $(gnuw32lib)
+includefiles = win32lib.h
+
+default: all
+
+all: $(objdir) $(gnuw32)
+
+lib: $(objdir) $(gnuw32lib)
+
+!ifdef GNUW32_DLL
+DEFS= $(DEFS) -DMAKE_GNUW32_DLL
+
+$(gnuw32lib): $(objdir) $(objects)
+ $(archive) /DEF $(objects)
+
+$(gnuw32dll): $(objects) $(objdir)\libgnuw32.lib $(objdir)\libgnuw32.res
+ $(link_dll) $(**) $(gnuw32lib:.lib=.exp) $(conlibs)
+!else
+$(gnuw32lib): $(objdir) $(objects)
+ $(archive) $(objects)
+!endif
+
+check: $(objdir)\system_popen_check.exe
+
+$(objdir)\system_popen_check.exe: $(objdir)\system_popen_check.obj $(gnuw32lib)
+ $(link) $(**) $(conlibs)
+
+!include <msvc/config.mak>
+!include <msvc/install.mak>
+
+install:: install-exec install-lib install-include
+
+!include <msvc/clean.mak>
+!include <msvc/rdepend.mak>
+!include "./depend.mak"
+
+#
+# Local Variables:
+# mode: makefile
+# End: \ No newline at end of file
diff --git a/Build/source/libs/libgnuw32/win32lib.h b/Build/source/libs/libgnuw32/win32lib.h
new file mode 100644
index 00000000000..c3040d141c9
--- /dev/null
+++ b/Build/source/libs/libgnuw32/win32lib.h
@@ -0,0 +1,306 @@
+/* System description file for Windows NT.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of Web2C.
+
+Web2C is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+Web2C is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Web2C; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _GNU_W32_H_
+#define _GNU_W32_H_
+
+#pragma warning( disable : 4007 4096 4018 4244 )
+
+#if defined(WIN32)
+# if defined(KPSEDLL)
+# define GNUW32DLL KPSEDLL
+# else
+# if defined(GNUW32_DLL) || defined(KPSE_DLL)
+# if defined(MAKE_GNUW32_DLL) || defined(MAKE_KPSE_DLL)
+# define GNUW32DLL __declspec( dllexport)
+# else
+# define GNUW32DLL __declspec( dllimport)
+# endif
+# else
+# define GNUW32DLL
+# endif
+# endif
+#else /* ! WIN32 */
+# define GNUW32DLL
+#endif
+
+/*
+ * Define symbols to identify the version of Unix this is.
+ * Define all the symbols that apply correctly.
+ */
+
+#ifndef DOSISH
+#define DOSISH
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN _MAX_PATH
+#endif
+
+#define HAVE_DUP2 1
+#define HAVE_RENAME 1
+#define HAVE_RMDIR 1
+#define HAVE_MKDIR 1
+#define HAVE_GETHOSTNAME 1
+#define HAVE_RANDOM 1
+#define USE_UTIME 1
+#define HAVE_MOUSE 1
+#define HAVE_TZNAME 1
+
+typedef unsigned char boolean;
+#define HAVE_BOOLEAN 1
+#define false FALSE
+#define true TRUE
+
+#include <windows.h>
+
+#undef CDECL
+#define CDECL __cdecl
+
+/* Defines size_t and alloca (). */
+#include <malloc.h>
+
+/* For proper declaration of environ. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+#include <direct.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * pwd.h doesn't exist on NT, so we put together our own.
+ */
+
+struct passwd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ int pw_quota;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+};
+
+#ifdef FPTEX
+#define REPLACE_LIBC_FUNCTIONS 1
+#endif
+
+#if defined(__STDC__)
+/* We want to compile with __STDC__ defined, but in this
+ case, MSVC headers do not define the standard names for
+ the C library functions (_open() instead of open()) */
+#include <oldnames.h>
+#else
+# if REPLACE_LIBC_FUNCTIONS
+# define stat(p, s) win32_stat(p, s)
+# define system(p) win32_system(p, 0)
+# define popen(cmd, mode) win32_popen(cmd, mode)
+# define pclose(file) win32_pclose(file)
+# endif
+#endif
+
+#define getwd(dir) GetCurrentDirectory(MAXPATHLEN, dir)
+#ifndef index
+#define index(s, c) strchr(s, c)
+#endif
+#ifndef rindex
+#define rindex(s, c) strrchr(s, c)
+#endif
+#define pipe(fd, size, mode) _pipe(fd, size, mode)
+#define strcasecmp(s1, s2) _stricmp(s1, s2)
+#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
+#define sleep(n) Sleep((DWORD)n);
+#define vsnprintf _vsnprintf
+#define snprintf _snprintf
+
+#ifdef _MSC_VER
+
+/* Test for each symbol individually and define the ones necessary (some
+ systems claiming Posix compatibility define some but not all). */
+
+#if defined (S_IFBLK) && !defined (S_ISBLK)
+#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
+#endif
+
+#if defined (S_IFCHR) && !defined (S_ISCHR)
+#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
+#endif
+
+#if defined (S_IFDIR) && !defined (S_ISDIR)
+#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
+#endif
+
+#if defined (S_IFREG) && !defined (S_ISREG)
+#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
+#endif
+
+#if defined (S_IFIFO) && !defined (S_ISFIFO)
+#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
+#endif
+
+#if defined (S_IFLNK) && !defined (S_ISLNK)
+#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
+#endif
+
+#if defined (S_IFSOCK) && !defined (S_ISSOCK)
+#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
+#endif
+
+#endif /* _MSC_VER */
+
+/* For access. */
+#ifndef F_OK
+#define F_OK 0
+#define X_OK 1
+#define W_OK 2
+#define R_OK 4
+#endif /* not F_OK */
+
+/*
+ Path separators.
+ Redundant with <kpathsea/c-pathch.h>, but useful
+ outside of kpathsea.
+*/
+
+/* On DOS, it's good to allow both \ and / between directories. */
+#ifndef IS_DIR_SEP
+#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
+#endif
+#ifndef IS_DEVICE_SEP
+#define IS_DEVICE_SEP(ch) ((ch) == ':')
+#endif
+#ifndef NAME_BEGINS_WITH_DEVICE
+#define NAME_BEGINS_WITH_DEVICE(name) (*(name) && IS_DEVICE_SEP((name)[1]))
+#endif
+/* On win32, UNC names are authorized */
+#ifndef IS_UNC_NAME
+#define IS_UNC_NAME(name) (strlen(name)>=3 && IS_DIR_SEP(*name) \
+ && IS_DIR_SEP(*(name+1)) && isalnum(*(name+2)))
+#endif
+
+#ifndef min
+#define min(a,b) ((b) > (a) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions from popen.c */
+
+#define MAX_PIPES 128
+
+extern GNUW32DLL FILE * __cdecl win32_popen(const char *, const char *);
+extern GNUW32DLL int __cdecl win32_pclose(FILE *);
+
+/* Functions from stat.c */
+
+extern GNUW32DLL int __cdecl win32_stat(const char * path, struct stat * buf);
+
+/* Functions from system.c */
+
+extern GNUW32DLL int __cdecl win32_system(const char * cmd, int async);
+
+/* Functions from string.c */
+/*
+ Unfortunately, these functions are defined in kpathsea
+ but useful elsewhere too. As they have a small footprint,
+ they are duplicated for the moment and not exported.
+*/
+extern GNUW32DLL void *xmalloc(unsigned size);
+extern GNUW32DLL void *xrealloc(void *, unsigned size);
+extern GNUW32DLL char *xstrdup(const char *);
+extern GNUW32DLL char *concat(const char *s1, const char *s2);
+extern GNUW32DLL char *concat3(const char *s1, const char *s2, const char *s3);
+extern GNUW32DLL char * __cdecl concatn(const char *s1, ...);
+
+/* Functions from volume.c */
+
+typedef struct volume_info_data {
+ struct volume_info_data * next;
+
+ /* time when info was obtained */
+ DWORD timestamp;
+
+ /* actual volume info */
+ char * root_dir;
+ DWORD serialnum;
+ DWORD maxcomp;
+ DWORD flags;
+ char * name;
+ char * type;
+} volume_info_data;
+
+extern GNUW32DLL int is_fat_volume (const char * name, const char ** pPath);
+extern GNUW32DLL int get_volume_info (const char * name, const char ** pPath);
+
+/* Functions from filename.c */
+
+extern GNUW32DLL void dostounix_filename (char *p);
+extern GNUW32DLL void unixtodos_filename (char *p);
+extern GNUW32DLL char *quote_filename (char *p);
+extern GNUW32DLL char *unquote_filename (char *p);
+extern GNUW32DLL int crlf_to_lf (int n, unsigned char *buf, unsigned *lf_count);
+extern GNUW32DLL BOOL win32_get_long_filename (char * name, char * buf, int size);
+extern GNUW32DLL const char *map_win32_filename (const char * name, const char ** pPath);
+extern int _parse_root (char * name, char ** pPath);
+
+/* Functions from user.c */
+extern GNUW32DLL int getuid();
+extern GNUW32DLL int geteuid();
+extern GNUW32DLL int getgid();
+extern GNUW32DLL int getegid();
+extern GNUW32DLL struct passwd *getpwuid(int);
+extern GNUW32DLL struct passwd *getpwnam(const char *);
+extern GNUW32DLL void init_user_info();
+extern GNUW32DLL void init_user_info();
+
+/* Functions from home.c */
+extern GNUW32DLL void set_home_warning(void);
+extern GNUW32DLL char *get_home_directory (void);
+
+/* Functions from time.h */
+extern time_t convert_time (FILETIME ft);
+
+/* Functions from lookcmd.c */
+
+extern GNUW32DLL BOOL look_for_cmd(const char *command, char **app_name);
+
+extern GNUW32DLL void *parse_cmdline(char *line, char **input, char **output, int *nb_cmds);
+extern GNUW32DLL char *build_cmdline(char ***cmd, char *input, char *output);
+
+/* Functions from error.c */
+
+extern GNUW32DLL void Win32Error(char *caller);
+extern GNUW32DLL void Win32Msg(char *msg);
+
+/* ============================================================ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not _GNU_W32_H_ */