Annotation of embedaddon/libiconv/srclib/relocwrapper.c, revision 1.1.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>