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>