summaryrefslogtreecommitdiff
path: root/Build/source/texk/kpathsea/win32lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/kpathsea/win32lib.c')
-rw-r--r--Build/source/texk/kpathsea/win32lib.c490
1 files changed, 490 insertions, 0 deletions
diff --git a/Build/source/texk/kpathsea/win32lib.c b/Build/source/texk/kpathsea/win32lib.c
new file mode 100644
index 00000000000..2e4f0f01493
--- /dev/null
+++ b/Build/source/texk/kpathsea/win32lib.c
@@ -0,0 +1,490 @@
+/* win32lib.c: bits and pieces for win32 and msvc.
+
+ Copyright 2006, 2011-2017 Akira Kakuto.
+ Copyright 1996, 1997, 1998, 1999 Fabrice Popineau.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>. */
+
+#include <kpathsea/config.h>
+#include <kpathsea/concatn.h>
+#include <kpathsea/variable.h>
+#include <kpathsea/c-stat.h>
+
+static int is_include_space(const char *s)
+{
+ char *p;
+ p = strchr(s, ' ');
+ if(p) return 1;
+ p = strchr(s, '\t');
+ if(p) return 1;
+ return 0;
+}
+
+double win32_floor (double x)
+{
+ return floor (x);
+}
+
+FILE * win32_popen (const char *cmd, const char *fmode)
+{
+ char mode[3];
+ char *p, *q;
+ const char *cmd2;
+ FILE *ret;
+
+ mode[0] = fmode[0];
+ mode[1] = 'b';
+ mode[2] = '\0';
+
+ if (is_include_space (cmd)) {
+ cmd2 = xmalloc (strlen (cmd) + 3);
+ q = (char *)cmd2;
+ p = (char *)cmd;
+ *q++= '\"';
+ while(*p)
+ *q++ = *p++;
+ *q++ = '\"';
+ *q = '\0';
+ ret = _popen (cmd2, mode);
+ free ((char *)cmd2);
+ return ret;
+ } else {
+ return _popen (cmd, mode);
+ }
+}
+
+int win32_pclose (FILE *f)
+{
+ return _pclose (f);
+}
+
+/* large file support */
+
+__int64
+xftell64 (FILE *f, const char *filename)
+{
+#if _MSC_VER > 1200
+ __int64 where;
+ where = _ftelli64(f);
+ if (where < (__int64)0)
+ FATAL_PERROR(filename);
+#else
+ __int64 where, filepos;
+ int fd;
+
+ fd = fileno(f);
+ if(f->_cnt < 0)
+ f->_cnt = 0;
+ if((filepos = _lseeki64(fd, (__int64)0, SEEK_CUR)) < (__int64)0) {
+ FATAL_PERROR(filename);
+ return (__int64)(-1);
+ }
+ if(filepos == (__int64)0)
+ where = (__int64)(f->_ptr - f->_base);
+ else
+ where = filepos - f->_cnt;
+#endif
+ return where;
+}
+
+void
+xfseek64 (FILE *f, __int64 offset, int wherefrom, const char *filename)
+{
+#if _MSC_VER > 1200
+ if (_fseeki64(f, offset, wherefrom) < (__int64)0)
+ FATAL_PERROR(filename);
+#else
+ if(wherefrom == SEEK_CUR) {
+ offset += xftell64(f, filename);
+ wherefrom = SEEK_SET;
+ }
+ fflush(f);
+ if (_lseeki64(fileno(f), offset, wherefrom) < (__int64)0)
+ FATAL_PERROR(filename);
+#endif
+}
+
+
+/* special TeXLive Ghostscript */
+
+static int is_dir (char *buff)
+{
+ struct stat stats;
+
+ return stat (buff, &stats) == 0 && S_ISDIR (stats.st_mode);
+}
+
+/*
+ TeXlive uses its own gs in
+ $SELFAUTOPARENT/tlpkg/tlgs
+*/
+void texlive_gs_init(void)
+{
+ char *nptr, *path;
+ char tlgsbindir[512];
+ char tlgslibdir[512];
+ char resourcedir[512];
+ nptr = kpse_var_value("TEXLIVE_WINDOWS_EXTERNAL_GS");
+ if (nptr == NULL || *nptr == '0' || *nptr == 'n' || *nptr == 'f') {
+ if (nptr)
+ free (nptr);
+ nptr = kpse_var_value("SELFAUTOPARENT");
+ if (nptr) {
+ strcpy(tlgsbindir, nptr);
+ strcat(tlgsbindir,"/tlpkg/tlgs");
+ strcpy(resourcedir, tlgsbindir);
+ strcat(resourcedir, "/Resource");
+ if(is_dir(tlgsbindir)) {
+ strcpy(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/lib;");
+ if(is_dir(resourcedir)) {
+ strcat(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/fonts;");
+ strcat(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/Resource/Init;");
+ strcat(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/Resource;");
+ strcat(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/kanji");
+ } else {
+ strcat(tlgslibdir, tlgsbindir);
+ strcat(tlgslibdir, "/fonts");
+ }
+ strcat(tlgsbindir, "/bin;");
+ free(nptr);
+ for(nptr = tlgsbindir; *nptr; nptr++) {
+ if(*nptr == '/') *nptr = '\\';
+ }
+ nptr = getenv("PATH");
+ path = (char *)malloc(strlen(nptr) + strlen(tlgsbindir) + 6);
+ strcpy(path, tlgsbindir);
+ strcat(path, nptr);
+ xputenv("PATH", path);
+ xputenv("GS_LIB", tlgslibdir);
+ }
+ }
+ } else {
+ free (nptr);
+ }
+}
+
+/*
+ path name in char *input is changed into the long
+ name format and returned in char *buff.
+ return value: 0 if failed
+ 1 if succeeded
+*/
+
+int kpathsea_getlongpath(kpathsea kpse, char *buff, char *input, int len)
+{
+ HANDLE hnd;
+ WIN32_FIND_DATA ffd;
+ int cnt = 0;
+ char *p, *q, *r;
+
+ buff[0] = '\0';
+/*
+temporarily change directory separators into back slashs
+*/
+ for(p = input; *p; p++) {
+ if(*p == '/')
+ *p = '\\';
+ }
+
+ p = q = input;
+ r = buff;
+
+/*
+UNC name
+*/
+ if(q[0] == '\\' && q[1] == '\\') {
+ cnt += 2;
+ if(cnt > len) return 0;
+ buff[0] = '/';
+ buff[1] = '/';
+ p += 2;
+ r += 2;
+ while(*p != '\\' && *p) {
+ if (kpathsea_IS_KANJI(kpse, p)) {
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = *p++;
+ }
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = *p++;
+ }
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = '/';
+ if(*p) p++;
+ while(*p != '\\' && *p) {
+ if (kpathsea_IS_KANJI(kpse, p)) {
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = *p++;
+ }
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = *p++;
+ }
+ cnt++;
+ if(cnt > len) return 0;
+ *r++ = '/';
+ *r= '\0';
+ if(*p) p++;
+/*
+drive name
+*/
+ } else if(isalpha(q[0]) && q[1] == ':' && q[2] == '\\') {
+ *r++ = q[0];
+ *r++ = ':';
+ *r++ = '/';
+ *r = '\0';
+ p += 3;
+ cnt += 3;
+ if(cnt > len) return 0;
+ }
+
+ for( ; *p; p++) {
+ if(kpathsea_IS_KANJI(kpse, p)) {
+ p++;
+ continue;
+ }
+ if(*p == '\\') {
+ *p = '\0';
+ if((*(p-2) == '\\' || p-1 == q) && *(p-1) == '.') {
+ cnt += 2;
+ if(cnt > len) return 0;
+ strcat(buff, "./");
+ } else if((*(p-3) == '\\' || p-2 == q) && *(p-2) == '.' && *(p-1) == '.') {
+ cnt += 3;
+ if(cnt > len) return 0;
+ strcat(buff, "../");
+ } else {
+ if((hnd = FindFirstFile(q, &ffd)) == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+ FindClose(hnd);
+ cnt += strlen(ffd.cFileName);
+ cnt++;
+ if(cnt > len) return 0;
+ strcat(buff, ffd.cFileName);
+ strcat(buff, "/");
+ }
+ *p = '\\';
+ }
+ }
+
+/*
+file itself
+*/
+ if((hnd = FindFirstFile(q, &ffd)) == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+ FindClose(hnd);
+ cnt += strlen(ffd.cFileName);
+ if(cnt > len) return 0;
+ strcat(buff, ffd.cFileName);
+ return 1;
+}
+
+/* user info */
+
+/* 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> */
+
+char * kpathsea_get_home_directory(kpathsea kpse)
+{
+ char *p;
+ char *home = getenv("HOME");
+ if(!home)
+ home = getenv("USERPROFILE");
+ if(home) {
+ home = xstrdup(home);
+ for(p = home; *p; p++) {
+ if(kpathsea_IS_KANJI(kpse, p)) {
+ p++;
+ continue;
+ }
+ if(*p == '\\')
+ *p = '/';
+ }
+ }
+ return home;
+}
+
+int
+kpathsea_getuid (kpathsea kpse)
+{
+ return kpse->the_passwd.pw_uid;
+}
+
+int
+kpathsea_getgid (kpathsea kpse)
+{
+ return kpse->the_passwd.pw_gid;
+}
+
+struct passwd *
+kpathsea_getpwuid (kpathsea kpse, int uid)
+{
+ if (uid == kpse->the_passwd.pw_uid)
+ return &kpse->the_passwd;
+ return NULL;
+}
+
+struct passwd *
+kpathsea_getpwnam (kpathsea kpse, char *name)
+{
+ struct passwd *pw;
+
+ pw = kpathsea_getpwuid (kpse, kpathsea_getuid (kpse));
+ if (!pw)
+ return pw;
+
+ if (stricmp (name, pw->pw_name))
+ return NULL;
+
+ return pw;
+}
+
+void
+kpathsea_init_user_info (kpathsea kpse)
+{
+ char *home;
+ DWORD nSize = 256;
+
+ if (!GetUserName (kpse->the_passwd.pw_name, &nSize))
+ strcpy (kpse->the_passwd.pw_name, "unknown");
+ kpse->the_passwd.pw_uid = 123;
+ kpse->the_passwd.pw_gid = 123;
+
+ /* Ensure HOME and SHELL are defined. */
+
+ home = kpathsea_get_home_directory(kpse);
+ if (home) {
+ putenv(concat("HOME=", home));
+ }
+ else {
+ putenv ("HOME=c:/");
+ }
+
+ if (getenv ("SHELL") == NULL)
+ putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
+
+ {
+ /* If TEXMFTEMP 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 (kpse->the_passwd.pw_dir, kpathsea_get_home_directory(kpse));
+ strcpy (kpse->the_passwd.pw_shell, getenv ("SHELL"));
+}
+
+/* win32_system */
+int win32_system(const char *cmd)
+{
+ const char *p;
+ char *q;
+ char *av[4];
+ int len, ret;
+ int spacep = 0;
+
+ if(cmd == NULL)
+ return 1;
+
+ av[0] = xstrdup("cmd.exe");
+ av[1] = xstrdup("/c");
+
+ len = strlen(cmd) + 3;
+ spacep = is_include_space(cmd);
+ av[2] = malloc(len);
+ q = av[2];
+ if(spacep)
+ *q++ = '"';
+ for(p = cmd; *p; p++, q++) {
+ if(*p == '\'')
+ *q = '"';
+ else
+ *q = *p;
+ }
+ if(spacep)
+ *q++ = '"';
+ *q = '\0';
+ av[3] = NULL;
+ ret = _spawnvp(_P_WAIT, av[0], av);
+ free(av[0]);
+ free(av[1]);
+ free(av[2]);
+ return ret;
+}
+
+#if defined (KPSE_COMPAT_API)
+int getlongpath(char *buff, char *input, int len)
+{
+ return kpathsea_getlongpath(kpse_def, buff, input, len);
+}
+
+char * get_home_directory(void)
+{
+ return kpathsea_get_home_directory(kpse_def);
+}
+
+int
+getuid (void)
+{
+ return kpathsea_getuid(kpse_def);
+}
+
+int
+geteuid (void)
+{
+ /* 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 (void)
+{
+ return kpathsea_getgid (kpse_def);
+}
+
+int
+getegid (void)
+{
+ return getgid ();
+}
+
+struct passwd *
+getpwuid (int uid)
+{
+ return kpathsea_getpwuid (kpse_def, uid);
+}
+
+struct passwd *
+getpwnam (char *name)
+{
+ return kpathsea_getpwnam (kpse_def, name);
+}
+
+#endif /* KPSE_COMPAT_API */