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