Annotation of embedaddon/libiconv/srclib/relocwrapper.c, revision 1.1
1.1 ! misho 1: /* Relocating wrapper program.
! 2: Copyright (C) 2003, 2005-2007 Free Software Foundation, Inc.
! 3: Written by Bruno Haible <bruno@clisp.org>, 2003.
! 4:
! 5: This program is free software: you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License as published by
! 7: the Free Software Foundation; either version 3 of the License, or
! 8: (at your option) any later version.
! 9:
! 10: This program is distributed in the hope that it will be useful,
! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 13: GNU General Public License for more details.
! 14:
! 15: You should have received a copy of the GNU General Public License
! 16: along with this program. If not, see <http://www.gnu.org/licenses/>. */
! 17:
! 18: /* Dependencies:
! 19: relocwrapper
! 20: -> progname
! 21: -> progreloc
! 22: -> areadlink
! 23: -> readlink
! 24: -> canonicalize-lgpl
! 25: -> malloca
! 26: -> readlink
! 27: -> relocatable
! 28: -> setenv
! 29: -> malloca
! 30: -> strerror
! 31: -> c-ctype
! 32:
! 33: Macros that need to be set while compiling this file:
! 34: - ENABLE_RELOCATABLE 1
! 35: - INSTALLPREFIX the base installation directory
! 36: - INSTALLDIR the directory into which this program is installed
! 37: - LIBPATHVAR the platform dependent runtime library path variable
! 38: - LIBDIRS a comma-terminated list of strings representing the list of
! 39: directories that contain the libraries at installation time
! 40:
! 41: We don't want to internationalize this wrapper because then it would
! 42: depend on libintl and therefore need relocation itself. So use only
! 43: libc functions, no gettext(), no error(), no xmalloc(), no xsetenv().
! 44: */
! 45:
! 46: #include <config.h>
! 47:
! 48: #include <stdio.h>
! 49: #include <stdlib.h>
! 50: #include <string.h>
! 51: #include <unistd.h>
! 52: #include <errno.h>
! 53:
! 54: #include "progname.h"
! 55: #include "relocatable.h"
! 56: #include "c-ctype.h"
! 57:
! 58: /* Return a copy of the filename, with an extra ".bin" at the end.
! 59: More generally, it replaces "${EXEEXT}" at the end with ".bin${EXEEXT}". */
! 60: static char *
! 61: add_dotbin (const char *filename)
! 62: {
! 63: size_t filename_len = strlen (filename);
! 64: char *result = (char *) malloc (filename_len + 4 + 1);
! 65:
! 66: if (result != NULL)
! 67: {
! 68: if (sizeof (EXEEXT) > sizeof (""))
! 69: {
! 70: /* EXEEXT handling. */
! 71: const size_t exeext_len = sizeof (EXEEXT) - sizeof ("");
! 72: static const char exeext[] = EXEEXT;
! 73: if (filename_len > exeext_len)
! 74: {
! 75: /* Compare using an inlined copy of c_strncasecmp(), because
! 76: the filenames may have undergone a case conversion since
! 77: they were packaged. In other words, EXEEXT may be ".exe"
! 78: on one system and ".EXE" on another. */
! 79: const char *s1 = filename + filename_len - exeext_len;
! 80: const char *s2 = exeext;
! 81: for (; *s1 != '\0'; s1++, s2++)
! 82: {
! 83: unsigned char c1 = *s1;
! 84: unsigned char c2 = *s2;
! 85: if (c_tolower (c1) != c_tolower (c2))
! 86: goto simple_append;
! 87: }
! 88: /* Insert ".bin" before EXEEXT or its equivalent. */
! 89: memcpy (result, filename, filename_len - exeext_len);
! 90: memcpy (result + filename_len - exeext_len, ".bin", 4);
! 91: memcpy (result + filename_len - exeext_len + 4,
! 92: filename + filename_len - exeext_len,
! 93: exeext_len + 1);
! 94: return result;
! 95: }
! 96: }
! 97: simple_append:
! 98: /* Simply append ".bin". */
! 99: memcpy (result, filename, filename_len);
! 100: memcpy (result + filename_len, ".bin", 4 + 1);
! 101: return result;
! 102: }
! 103: else
! 104: {
! 105: fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
! 106: exit (1);
! 107: }
! 108: }
! 109:
! 110: /* List of directories that contain the libraries. */
! 111: static const char *libdirs[] = { LIBDIRS NULL };
! 112: /* Verify that at least one directory is given. */
! 113: typedef int verify1[2 * (sizeof (libdirs) / sizeof (libdirs[0]) > 1) - 1];
! 114:
! 115: /* Relocate the list of directories that contain the libraries. */
! 116: static void
! 117: relocate_libdirs ()
! 118: {
! 119: size_t i;
! 120:
! 121: for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
! 122: libdirs[i] = relocate (libdirs[i]);
! 123: }
! 124:
! 125: /* Activate the list of directories in the LIBPATHVAR. */
! 126: static void
! 127: activate_libdirs ()
! 128: {
! 129: const char *old_value;
! 130: size_t total;
! 131: size_t i;
! 132: char *value;
! 133: char *p;
! 134:
! 135: old_value = getenv (LIBPATHVAR);
! 136: if (old_value == NULL)
! 137: old_value = "";
! 138:
! 139: total = 0;
! 140: for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
! 141: total += strlen (libdirs[i]) + 1;
! 142: total += strlen (old_value) + 1;
! 143:
! 144: value = (char *) malloc (total);
! 145: if (value == NULL)
! 146: {
! 147: fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
! 148: exit (1);
! 149: }
! 150: p = value;
! 151: for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
! 152: {
! 153: size_t len = strlen (libdirs[i]);
! 154: memcpy (p, libdirs[i], len);
! 155: p += len;
! 156: *p++ = ':';
! 157: }
! 158: if (old_value[0] != '\0')
! 159: strcpy (p, old_value);
! 160: else
! 161: p[-1] = '\0';
! 162:
! 163: if (setenv (LIBPATHVAR, value, 1) < 0)
! 164: {
! 165: fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
! 166: exit (1);
! 167: }
! 168: }
! 169:
! 170: int
! 171: main (int argc, char *argv[])
! 172: {
! 173: char *full_program_name;
! 174:
! 175: /* Set the program name and perform preparations for
! 176: get_full_program_name() and relocate(). */
! 177: set_program_name_and_installdir (argv[0], INSTALLPREFIX, INSTALLDIR);
! 178:
! 179: /* Get the full program path. (Important if accessed through a symlink.) */
! 180: full_program_name = get_full_program_name ();
! 181: if (full_program_name == NULL)
! 182: full_program_name = argv[0];
! 183:
! 184: /* Invoke the real program, with suffix ".bin". */
! 185: argv[0] = add_dotbin (full_program_name);
! 186: relocate_libdirs ();
! 187: activate_libdirs ();
! 188: execv (argv[0], argv);
! 189: fprintf (stderr, "%s: could not execute %s: %s\n",
! 190: program_name, argv[0], strerror (errno));
! 191: exit (127);
! 192: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>