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>