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