• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/gettext-0.17/gettext-runtime/gnulib-lib/
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        -> xreadlink
23           -> areadlink
24              -> readlink
25        -> canonicalize-lgpl
26           -> malloca
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 "setenv.h"
57#include "c-ctype.h"
58
59/* Return a copy of the filename, with an extra ".bin" at the end.
60   More generally, it replaces "${EXEEXT}" at the end with ".bin${EXEEXT}".  */
61static char *
62add_dotbin (const char *filename)
63{
64  size_t filename_len = strlen (filename);
65  char *result = (char *) malloc (filename_len + 4 + 1);
66
67  if (result != NULL)
68    {
69      if (sizeof (EXEEXT) > sizeof (""))
70	{
71	  /* EXEEXT handling.  */
72	  const size_t exeext_len = sizeof (EXEEXT) - sizeof ("");
73	  static const char exeext[] = EXEEXT;
74	  if (filename_len > exeext_len)
75	    {
76	      /* Compare using an inlined copy of c_strncasecmp(), because
77		 the filenames may have undergone a case conversion since
78		 they were packaged.  In other words, EXEEXT may be ".exe"
79		 on one system and ".EXE" on another.  */
80	      const char *s1 = filename + filename_len - exeext_len;
81	      const char *s2 = exeext;
82	      for (; *s1 != '\0'; s1++, s2++)
83		{
84		  unsigned char c1 = *s1;
85		  unsigned char c2 = *s2;
86		  if (c_tolower (c1) != c_tolower (c2))
87		    goto simple_append;
88		}
89	      /* Insert ".bin" before EXEEXT or its equivalent.  */
90	      memcpy (result, filename, filename_len - exeext_len);
91	      memcpy (result + filename_len - exeext_len, ".bin", 4);
92	      memcpy (result + filename_len - exeext_len + 4,
93		      filename + filename_len - exeext_len,
94		      exeext_len + 1);
95	      return result;
96	    }
97	}
98     simple_append:
99      /* Simply append ".bin".  */
100      memcpy (result, filename, filename_len);
101      memcpy (result + filename_len, ".bin", 4 + 1);
102      return result;
103    }
104  else
105    {
106      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
107      exit (1);
108    }
109}
110
111/* List of directories that contain the libraries.  */
112static const char *libdirs[] = { LIBDIRS NULL };
113/* Verify that at least one directory is given.  */
114typedef int verify1[2 * (sizeof (libdirs) / sizeof (libdirs[0]) > 1) - 1];
115
116/* Relocate the list of directories that contain the libraries.  */
117static void
118relocate_libdirs ()
119{
120  size_t i;
121
122  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
123    libdirs[i] = relocate (libdirs[i]);
124}
125
126/* Activate the list of directories in the LIBPATHVAR.  */
127static void
128activate_libdirs ()
129{
130  const char *old_value;
131  size_t total;
132  size_t i;
133  char *value;
134  char *p;
135
136  old_value = getenv (LIBPATHVAR);
137  if (old_value == NULL)
138    old_value = "";
139
140  total = 0;
141  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
142    total += strlen (libdirs[i]) + 1;
143  total += strlen (old_value) + 1;
144
145  value = (char *) malloc (total);
146  if (value == NULL)
147    {
148      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
149      exit (1);
150    }
151  p = value;
152  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
153    {
154      size_t len = strlen (libdirs[i]);
155      memcpy (p, libdirs[i], len);
156      p += len;
157      *p++ = ':';
158    }
159  if (old_value[0] != '\0')
160    strcpy (p, old_value);
161  else
162    p[-1] = '\0';
163
164  if (setenv (LIBPATHVAR, value, 1) < 0)
165    {
166      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
167      exit (1);
168    }
169}
170
171int
172main (int argc, char *argv[])
173{
174  char *full_program_name;
175
176  /* Set the program name and perform preparations for
177     get_full_program_name() and relocate().  */
178  set_program_name_and_installdir (argv[0], INSTALLPREFIX, INSTALLDIR);
179
180  /* Get the full program path.  (Important if accessed through a symlink.)  */
181  full_program_name = get_full_program_name ();
182  if (full_program_name == NULL)
183    full_program_name = argv[0];
184
185  /* Invoke the real program, with suffix ".bin".  */
186  argv[0] = add_dotbin (full_program_name);
187  relocate_libdirs ();
188  activate_libdirs ();
189  execv (argv[0], argv);
190  fprintf (stderr, "%s: could not execute %s: %s\n",
191	   program_name, argv[0], strerror (errno));
192  exit (127);
193}
194