1 /* progname.c: the executable name we were invoked as; general initialization.
3 Copyright 1994, 1996, 1997, 2008-2013 Karl Berry.
4 Copyright 1998-2005 Olaf Weber.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this library; if not, see <http://www.gnu.org/licenses/>. */
19 #include <kpathsea/config.h>
20 #include <kpathsea/absolute.h>
21 #include <kpathsea/c-pathch.h>
22 #include <kpathsea/c-pathmx.h>
23 #include <kpathsea/c-stat.h>
24 #include <kpathsea/pathsearch.h>
25 /* For kpse_reset_progname */
26 #include <kpathsea/tex-file.h>
29 #if defined(__i386_pc_gnu__)
31 #define _S_ISUID 04000 /* Set user ID on execution. */
34 #define _S_ISGID 02000 /* Set group ID on execution. */
37 #define _S_ISVTX 01000 /* Save swapped text after use (sticky). */
40 #define _S_IREAD 0400 /* Read by owner. */
43 #define _S_IWRITE 0200 /* Write by owner. */
46 #define _S_IEXEC 0100 /* Execute by owner. */
50 /* NeXT does not define the standard macros, but has the equivalent.
51 WIN32 doesn't define them either, and doesn't have them.
52 From: Gregor Hoffleit <flight@mathi.uni-heidelberg.de>. */
60 #endif /* not WIN32 */
61 #endif /* not S_IXUSR */
71 /* From a standalone program `ll' to expand symlinks written by Kimbo Mundy.
72 Don't bother to compile if we don't have symlinks; thus we can assume
73 / as the separator. Also don't try to use basename, etc., or
74 handle arbitrary filename length. Mixed case function names because
75 that's what kimbo liked. */
80 #define BSIZE 2048 /* sorry */
83 /* Read link FN into SYM. */
86 ReadSymLink (char *fn, char *sym)
88 register int n = readlink (fn, sym, BSIZE);
97 /* Strip first component from S, and also return it in a static buffer. */
100 StripFirst (register char *s)
102 static char buf[BSIZE];
105 /* Find the end of the first path element */
106 for (s1 = s; *s1 && (*s1 != '/' || s1 == s); s1++)
109 /* Copy it into buf and null-terminate it. */
110 strncpy (buf, s, s1 - s);
113 /* Skip over the leading / (if any) */
117 /* Squeeze out the element */
118 while ((*s++ = *s1++) != 0)
125 /* Strip last component from S, and also return it in a static buffer. */
128 StripLast (register char *s)
130 static char buf[BSIZE];
133 for (s1 = s + strlen (s); s1 > s && *s1 != '/'; s1--)
135 strcpy (buf, s1 + (*s1 == '/'));
142 /* Copy first path element from B to A, removing it from B. */
145 CopyFirst (register char *a, char *b)
147 register int length = strlen (a);
149 if (length > 0 && a[length - 1] != '/') {
153 strcat (a, StripFirst (b));
156 /* Returns NULL on error. Prints intermediate results if global
157 `ll_verbose' is nonzero. */
159 #define EX(s) (strlen (s) && strcmp (s, "/") ? "/" : "")
160 #define EXPOS EX(post)
161 #define EXPRE EX(pre)
164 expand_symlinks (kpathsea kpse, char *s)
166 static char pre[BSIZE]; /* return value */
167 char post[BSIZE], sym[BSIZE], tmp[BSIZE], before[BSIZE];
173 /* Check for symlink loops. It's difficult to check for all the
174 possibilities ourselves, so let the kernel do it. And make it
175 conditional so that people can see where the infinite loop is
176 being caused (see engtools#1536). */
177 /* There used to be a test for a variable |ll_loop| here, but
178 it was initialized to zero and never updated */
180 FILE *f = fopen (s, "r");
181 if (!f && errno == ELOOP) {
182 /* Not worried about other errors, we'll get to them in due course. */
192 while (strlen (post) != 0) {
193 CopyFirst (pre, post);
195 if (lstat (pre, &st) != 0) {
196 fprintf (stderr, "lstat(%s) failed ...\n", pre);
201 if (S_ISLNK (st.st_mode)) {
202 ReadSymLink (pre, sym);
204 if (!strncmp (sym, "/", 1)) {
205 if (kpse->ll_verbose)
206 printf ("[%s]%s%s -> [%s]%s%s\n", pre, EXPOS, post, sym, EXPOS,post);
210 a = pre[0]; /* handle links through the root */
211 strcpy (tmp, StripLast (pre));
212 if (!strlen (pre) && a == '/')
215 if (kpse->ll_verbose) {
216 sprintf (before, "%s%s[%s]%s%s", pre, EXPRE, tmp, EXPOS, post);
217 printf ("%s -> %s%s[%s]%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
220 /* Strip "../" path elements from the front of sym; print
221 new result if there were any such elements. */
223 a = pre[0]; /* handle links through the root */
224 while (!strncmp (sym, "..", 2)
225 && (sym[2] == 0 || sym[2] == '/')
228 && strcmp (pre, "..")
230 || strcmp (pre + strlen (pre) - 3, "/.."))) {
236 if (done && kpse->ll_verbose) {
237 for (cp = before; *cp;)
240 printf ("%s == %s%s%s%s%s\n", before, pre, EXPRE, sym, EXPOS,post);
242 printf ("%s == %s%s%s\n", before, pre, EXPOS, post);
244 if (!strlen (pre) && a == '/')
248 if (strlen (post) != 0 && strlen (sym) != 0)
258 #else /* not S_ISLNK */
259 #define expand_symlinks(k,s) (s)
260 #endif /* not S_ISLNK */
262 /* Remove .'s and ..'s in DIR, to avoid problems with relative symlinks
263 as the program name, etc. This does not canonicalize symlinks. */
266 remove_dots (kpathsea kpse, string dir)
275 for (c = kpathsea_filename_component (kpse, dir); c;
276 c = kpathsea_filename_component (kpse, NULL)) {
277 if (STREQ (c, ".")) {
278 /* If leading ., replace with cwd. Else ignore. */
283 } else if (STREQ (c, "..")) {
284 /* If leading .., start with xdirname (cwd). Else remove last
285 component from ret, if any. */
287 string dot = xgetcwd ();
288 ret = xdirname (dot);
292 string p = NAME_BEGINS_WITH_DEVICE (ret) ? ret + 2 : ret;
293 for (last = strlen (p); last > 0; last--) {
294 if (IS_DIR_SEP_CH (p[last - 1])) {
295 /* If we have `/../', that's the same as `/'. */
296 p[(last > 1 ? last - 1 : 1)] = 0;
303 /* Not . or ..; just append. Include a directory separator unless
304 our string already ends with one. This also changes all directory
305 separators into the canonical DIR_SEP_STRING. */
307 ret = concat (NAME_BEGINS_WITH_DEVICE (c) ? "" : DIR_SEP_STRING, c);
311 ret = concat3 (ret, ret[len - 1] == DIR_SEP ? "" : DIR_SEP_STRING, c);
318 /* Remove a trailing /, just in case it snuck in. */
320 if (len > 0 && ret[len - 1] == DIR_SEP) {
325 #endif /* not AMIGA */
328 /* Return directory ARGV0 comes from. Check PATH if ARGV0 is not
332 kpathsea_selfdir (kpathsea kpse, const_string argv0)
338 if (kpathsea_absolute_p (kpse, argv0, true)) {
339 self = xstrdup (argv0);
343 #include <proto/dos.h>
344 #include <proto/exec.h>
346 struct DosLibrary *DOSBase
347 = (struct DosLibrary *) OpenLibrary ("dos.library", 0L);
350 self = xmalloc (BUFSIZ);
351 lock = findpath (argv0);
352 if (lock != ((BPTR) -1)) {
353 if (getpath (lock, self) == -1) {
356 strcat (self,DIR_SEP_STRING);
361 CloseLibrary((struct Library *) DOSBase);
362 #else /* not AMIGA */
366 /* Have to check PATH. But don't call kpse_path_search since we don't
367 want to search any ls-R's or do anything special with //'s. */
368 for (elt = kpathsea_path_element (kpse, getenv ("PATH")); !self && elt;
369 elt = kpathsea_path_element (kpse, NULL)) {
370 /* UNIX tradition interprets the empty path element as "." */
371 if (*elt == 0) elt = ".";
373 name = concat3 (elt, DIR_SEP_STRING, argv0);
375 /* In order to do this perfectly, we'd have to check the owner bits only
376 if we are the file owner, and the group bits only if we belong
377 to the file group. That's a lot of work, though, and it's not
378 likely that kpathsea will ever be used with a program that's
379 only executable by some classes and not others. See the
380 `file_status' function in execute_cmd.c in bash for what's
381 necessary if we were to do it right. */
382 if (stat (name, &s) == 0 && s.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)
383 /* Do not stop at directories. */
384 && !S_ISDIR(s.st_mode))
389 #endif /* not AMIGA */
392 /* If argv0 is somehow dir/exename, `self' will still be NULL. */
394 self = concat3 (".", DIR_SEP_STRING, argv0);
396 name = remove_dots (kpse, expand_symlinks (kpse, self));
402 ret = xdirname (name);
409 #if defined (KPSE_COMPAT_API)
411 kpse_selfdir (const_string argv0)
413 return kpathsea_selfdir (kpse_def, argv0);
417 #endif /* not WIN32 */
419 #if defined(WIN32) || defined(__CYGWIN__)
421 /* Create a list of executable suffixes of files not to be written. */
422 #define EXE_SUFFIXES ".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.ws;.tcl;.py;.pyw"
425 mk_suffixlist (kpathsea kpse)
431 #if defined(__CYGWIN__)
432 v = xstrdup (EXE_SUFFIXES);
434 v = getenv ("PATHEXT");
435 if (v) /* strlwr() exists also in MingW */
436 v = strlwr (xstrdup (v));
438 v = xstrdup (EXE_SUFFIXES);
444 while ((r = strchr (q, ';')) != NULL) {
451 kpse->suffixlist = (char **) xmalloc ((n + 2) * sizeof (char *));
452 p = kpse->suffixlist;
453 *p = xstrdup (".dll");
456 while ((r = strchr (q, ';')) != NULL) {
470 #endif /* WIN32 || __CYGWIN__ */
472 /* On win32 SELFAUTO{LOC,DIR,PARENT} must not be just `/', otherwise,
473 e.g., $SELFAUTODIR/texmf/tex would be mistaken as UNC name. */
475 fix_selfdir (string dir)
478 if (IS_DIR_SEP_CH (*dir) && dir[1] == 0)
485 kpathsea_set_program_name (kpathsea kpse, const_string argv0,
486 const_string progname)
489 string sdir, sdir_parent, sdir_grandparent, sdir_greatgrandparent;
490 string s = getenv ("KPATHSEA_DEBUG");
492 string debug_output = getenv("KPATHSEA_DEBUG_OUTPUT");
493 string append_debug_output = getenv("KPATHSEA_DEBUG_APPEND");
497 /* Set debugging stuff first, in case we end up doing debuggable stuff
498 during this initialization. */
500 kpse->debug |= atoi (s);
504 if (!file_system_codepage)
505 file_system_codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
506 cp = file_system_codepage;
507 if (cp == 932 || cp == 936 || cp == 950) {
508 is_cp932_system = cp;
513 #if defined(__MINGW32__)
514 /* Set various info about user. Among many things,
515 ensure that HOME is set. */
517 #else /* !__MINGW32__ */
518 kpse->the_passwd.pw_name = kpse->the_passwd_name;
519 kpse->the_passwd.pw_passwd = kpse->the_passwd_passwd;
520 kpse->the_passwd.pw_uid = 0;
521 kpse->the_passwd.pw_gid = 0;
522 kpse->the_passwd.pw_quota = 0;
523 kpse->the_passwd.pw_gecos = kpse->the_passwd_gecos;
524 kpse->the_passwd.pw_dir = kpse->the_passwd_dir;
525 kpse->the_passwd.pw_shell = kpse->the_passwd_shell;
526 kpse->__system_allow_multiple_cmds = 0;
528 /* Set various info about user. Among many things,
529 ensure that HOME is set. */
530 kpathsea_init_user_info(kpse);
531 #endif /* !__MINGW32__ */
533 /* redirect stderr to debug_output. Easier to send logfiles. */
535 int flags = _O_CREAT | _O_TRUNC | _O_RDWR;
537 if (_stricmp(debug_output, "con") == 0
538 || _stricmp(debug_output, "con:") == 0) {
539 err = _fileno(stdout);
541 if (append_debug_output) {
542 flags = _O_CREAT | _O_APPEND | _O_WRONLY;
544 flags = _O_CREAT | _O_TRUNC | _O_WRONLY;
545 kpathsea_xputenv(kpse, "KPATHSEA_DEBUG_APPEND", "yes");
550 && (err = _open(debug_output, flags, _S_IREAD | _S_IWRITE)) == -1)
552 WARNING1 ("kpathsea: Can't open %s for stderr redirection!\n",
554 perror (debug_output);
555 } else if ((olderr = _dup(fileno(stderr))) == -1) {
556 WARNING ("kpathsea: Can't dup() stderr!\n");
558 } else if (_dup2(err, fileno(stderr)) == -1) {
559 WARNING1 ("kpathsea: Can't redirect stderr to %s!\n", debug_output);
567 /* Win95 always gives the short filename for argv0, not the long one.
568 There is only this way to catch it. It makes all the kpse_selfdir
569 stuff useless for win32. */
571 char short_path[PATH_MAX], path[PATH_MAX], *fp;
572 #if !defined(__MINGW32__)
577 /* SearchPath() always gives back an absolute directory */
578 if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0)
579 LIB_FATAL1("Can't determine where the executable %s is.\n", argv0);
580 #if defined(__MINGW32__)
581 if (!win32_get_long_filename(short_path, path, sizeof(path))) {
582 LIB_FATAL1("This path points to an invalid file : %s\n", short_path);
584 /* slashify the dirname */
585 for (fp = path; fp && *fp; fp++)
586 if (IS_DIR_SEP(*fp)) *fp = DIR_SEP;
587 #else /* !__MINGW32__ */
588 if (getlongpath(path, short_path, PATH_MAX) == 0)
589 FATAL1("Can't get long name for %s.\n", short_path);
590 if ((hnd = FindFirstFile(short_path, &ffd)) == INVALID_HANDLE_VALUE)
591 FATAL1("The following path points to an invalid file : %s\n", path);
593 /* dirname aleady slashified in WIN32 */
594 #endif /* !__MINGW32__ */
595 /* sdir will be the directory of the executable, ie: c:/TeX/bin */
596 sdir = xdirname(path);
597 kpse->invocation_name = xstrdup(xbasename(path));
600 #elif defined(__DJGPP__)
602 /* DJGPP programs support long filenames on Windows 95, but ARGV0 there
603 is always made with the short 8+3 aliases of all the pathname elements.
604 If long names are supported, we need to convert that to a long name.
606 All we really need is to call `_truename', but most of the code
607 below is required to deal with the special case of networked drives. */
608 if (pathconf (argv0, _PC_NAME_MAX) > 12) {
609 char long_progname[PATH_MAX];
611 if (_truename (argv0, long_progname)) {
614 if (long_progname[1] != ':') {
615 /* A complication: `_truename' returns network-specific string at
616 the beginning of `long_progname' when the program resides on a
617 networked drive, and DOS calls cannot grok such pathnames. We
618 need to convert the filesystem name back to a drive letter. */
619 char rootname[PATH_MAX], rootdir[4];
621 if (argv0[0] && argv0[1] == ':')
622 rootdir[0] = argv0[0]; /* explicit drive in `argv0' */
624 rootdir[0] = getdisk () + 'A';
628 if (_truename (rootdir, rootname)) {
629 /* Find out where `rootname' ends in `long_progname' and replace
630 it with the drive letter. */
631 int root_len = strlen (rootname);
633 if (IS_DIR_SEP (rootname[root_len - 1]))
634 root_len--; /* keep the trailing slash */
635 long_progname[0] = rootdir[0];
636 long_progname[1] = ':';
637 memmove (long_progname + 2, long_progname + root_len,
638 strlen (long_progname + root_len) + 1);
642 /* Convert everything to canonical form. */
643 if (long_progname[0] >= 'A' && long_progname[0] <= 'Z')
644 long_progname[0] += 'a' - 'A'; /* make drive lower case, for beauty */
645 for (fp = long_progname; *fp; fp++)
646 if (IS_DIR_SEP (*fp))
649 kpse->invocation_name = xstrdup (long_progname);
652 /* If `_truename' failed, God help them, because we won't... */
653 kpse->invocation_name = xstrdup (argv0);
656 kpse->invocation_name = xstrdup (argv0);
658 #else /* !WIN32 && !__DJGPP__ */
659 kpse->invocation_name = xstrdup (argv0);
662 /* We need to find SELFAUTOLOC *before* removing the ".exe" suffix from
663 the program_name, otherwise the PATH search inside kpse_selfdir will fail,
664 since `prog' doesn't exists as a file, there's `prog.exe' instead. */
666 sdir = kpathsea_selfdir (kpse, kpse->invocation_name);
668 /* SELFAUTODIR is actually the parent of the invocation directory,
669 and SELFAUTOPARENT the grandparent. This is how teTeX did it. */
670 kpathsea_xputenv (kpse, "SELFAUTOLOC", fix_selfdir (sdir));
671 sdir_parent = xdirname (sdir);
672 kpathsea_xputenv (kpse, "SELFAUTODIR", fix_selfdir (sdir_parent));
673 sdir_grandparent = xdirname (sdir_parent);
674 kpathsea_xputenv (kpse, "SELFAUTOPARENT", fix_selfdir (sdir_grandparent));
675 sdir_greatgrandparent = xdirname (sdir_grandparent);
676 kpathsea_xputenv (kpse, "SELFAUTOGRANDPARENT", fix_selfdir (sdir_greatgrandparent));
678 #if defined(WIN32) || defined(__CYGWIN__)
680 #endif /* WIN32 || __CYGWIN__ */
684 free (sdir_grandparent);
685 free (sdir_greatgrandparent);
687 kpse->invocation_short_name
688 = xstrdup (xbasename (kpse->invocation_name));
691 kpse->program_name = xstrdup (progname);
693 /* If configured --enable-shared and running from the build directory
694 with the wrapper scripts (e.g., for make check), the binaries will
695 be named foo.exe instead of foo. Or possibly if we're running on a
697 ext = find_suffix (kpse->invocation_short_name);
698 if (ext && FILESTRCASEEQ (ext, "exe")) {
699 kpse->program_name = remove_suffix (kpse->invocation_short_name);
701 kpse->program_name = xstrdup (kpse->invocation_short_name);
705 /* Runtime check that snprintf always writes a trailing NUL byte. */
708 assert (snprintf (buf, 2, "a") == 1 && buf[1] == '\0');
709 assert ((unsigned)snprintf (buf, 2, "ab") >= 2 && buf[1] == '\0');
710 assert ((unsigned)snprintf (buf, 2, "abc") >= 2 && buf[1] == '\0');
712 /* Some of the utility routines (like atou() and xfopen()) will use
713 FATAL and variations thereof (see lib.h) if there is a problem.
715 The next trick makes it possible for that message to report some useful
716 name instead of (NULL), if the backward compatible is compiled in. */
718 #if defined (KPSE_COMPAT_API)
719 if (kpse!=kpse_def) {
720 kpse_def->invocation_name = xstrdup(kpse->invocation_name);
721 kpse_def->invocation_short_name = xstrdup(kpse->invocation_short_name);
725 kpathsea_xputenv (kpse, "progname", kpse->program_name);
729 #if defined (KPSE_COMPAT_API)
731 kpse_set_program_name (const_string argv0, const_string progname)
733 kpathsea_set_program_name (kpse_def, argv0, progname);
737 /* Returns ARGV0 with any leading path and on some systems the suffix
738 for executables stripped off. This returns a new string.
739 For example, `kpse_program_basename ("/foo/bar.EXE")' returns "bar"
740 on WIndows or Cygwin and "bar.EXE" otherwise. */
743 kpse_program_basename (const_string argv0)
745 string base = xstrdup (xbasename (argv0));
747 string dot = strrchr (base, '.');
748 if (dot && FILESTRCASEEQ (dot, EXEEXT))
756 static const char *tab[] = {
768 "/te/share/texmf/../../../../bin/gnu",
773 main (int argc, char **argv)
776 kpathsea kpse = xcalloc(1, sizeof(kpathsea_instance));
778 kpathsea_set_program_name(kpse, argv[0], NULL);
781 printf("\n%s: Nothing to do for WIN32\n",
782 kpse->invocation_short_name);
784 printf("\n%s: name -> remove_dots(name)\n\n",
785 kpse->invocation_short_name);
787 for (p = tab; *p; p++) {
788 char *q = xstrdup(*p);
789 char *s = remove_dots(kpse, q);
791 printf("%s -> %s\n", q, s);