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>