Annotation of embedaddon/libiconv/srclib/relocwrapper.c, revision 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>