[BACK]Return to shlib.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / libexec / ld.aout_so

Annotation of src/libexec/ld.aout_so/shlib.c, Revision 1.14

1.14    ! pk          1: /*     $NetBSD: shlib.c,v 1.13 1998/04/04 01:00:29 fvdl Exp $  */
1.12      cgd         2:
1.14    ! pk          3: /*-
        !             4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
1.8       pk          5:  * All rights reserved.
                      6:  *
1.14    ! pk          7:  * This code is derived from software contributed to The NetBSD Foundation
        !             8:  * by Paul Kranenburg.
        !             9:  *
1.8       pk         10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
1.14    ! pk         20:  *        This product includes software developed by the NetBSD
        !            21:  *        Foundation, Inc. and its contributors.
        !            22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            23:  *    contributors may be used to endorse or promote products derived
        !            24:  *    from this software without specific prior written permission.
1.8       pk         25:  *
1.14    ! pk         26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            36:  * POSSIBILITY OF SUCH DAMAGE.
1.1       pk         37:  */
                     38:
1.11      pk         39: #ifdef sun
                     40: char   *strsep();
                     41: int    isdigit();
                     42: #endif
                     43:
1.1       pk         44: #include <sys/param.h>
                     45: #include <sys/types.h>
                     46: #include <sys/stat.h>
                     47: #include <sys/file.h>
                     48: #include <sys/time.h>
1.11      pk         49: #include <a.out.h>
                     50: #include <ctype.h>
                     51: #include <dirent.h>
1.10      pk         52: #include <err.h>
1.1       pk         53: #include <fcntl.h>
1.11      pk         54: #include <stdio.h>
                     55: #include <stdlib.h>
1.1       pk         56: #include <string.h>
                     57:
                     58: #include "ld.h"
                     59:
                     60: /*
                     61:  * Standard directories to search for files specified by -l.
                     62:  */
                     63: #ifndef STANDARD_SEARCH_DIRS
1.10      pk         64: #define        STANDARD_SEARCH_DIRS    "/usr/lib"
1.1       pk         65: #endif
                     66:
1.8       pk         67: /*
                     68:  * Actual vector of library search directories,
1.11      pk         69:  * including `-L'ed and LD_LIBRARY_PATH spec'd ones.
1.8       pk         70:  */
                     71: char    **search_dirs;
                     72: int    n_search_dirs;
                     73:
1.10      pk         74: char   *standard_search_dirs[] = {
1.1       pk         75:        STANDARD_SEARCH_DIRS
                     76: };
                     77:
                     78:
                     79: void
                     80: add_search_dir(name)
                     81:        char    *name;
                     82: {
                     83:        n_search_dirs++;
1.10      pk         84:        search_dirs = (char **)
1.11      pk         85:                xrealloc(search_dirs, n_search_dirs * sizeof search_dirs[0]);
1.1       pk         86:        search_dirs[n_search_dirs - 1] = strdup(name);
                     87: }
                     88:
                     89: void
1.11      pk         90: remove_search_dir(name)
                     91:        char    *name;
                     92: {
                     93:        int     n;
                     94:
                     95:        for (n = 0; n < n_search_dirs; n++) {
                     96:                if (strcmp(search_dirs[n], name))
                     97:                        continue;
                     98:                free(search_dirs[n]);
                     99:                if (n < (n_search_dirs - 1))
                    100:                        bcopy(&search_dirs[n+1], &search_dirs[n],
                    101:                              (n_search_dirs - n - 1) * sizeof search_dirs[0]);
                    102:                n_search_dirs--;
                    103:        }
                    104: }
                    105:
                    106: void
1.10      pk        107: add_search_path(path)
                    108: char   *path;
                    109: {
1.11      pk        110:        register char   *cp, *dup;
1.10      pk        111:
                    112:        if (path == NULL)
                    113:                return;
                    114:
1.11      pk        115:        /* Add search directories from `path' */
                    116:        path = dup = strdup(path);
                    117:        while ((cp = strsep(&path, ":")) != NULL)
1.10      pk        118:                add_search_dir(cp);
1.11      pk        119:        free(dup);
                    120: }
                    121:
                    122: void
                    123: remove_search_path(path)
                    124: char   *path;
                    125: {
                    126:        register char   *cp, *dup;
                    127:
                    128:        if (path == NULL)
                    129:                return;
                    130:
                    131:        /* Remove search directories from `path' */
                    132:        path = dup = strdup(path);
                    133:        while ((cp = strsep(&path, ":")) != NULL)
                    134:                remove_search_dir(cp);
                    135:        free(dup);
1.10      pk        136: }
                    137:
                    138: void
                    139: std_search_path()
1.1       pk        140: {
                    141:        int     i, n;
                    142:
                    143:        /* Append standard search directories */
                    144:        n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
                    145:        for (i = 0; i < n; i++)
                    146:                add_search_dir(standard_search_dirs[i]);
                    147: }
                    148:
                    149: /*
                    150:  * Return true if CP points to a valid dewey number.
                    151:  * Decode and leave the result in the array DEWEY.
                    152:  * Return the number of decoded entries in DEWEY.
                    153:  */
                    154:
1.2       pk        155: int
1.1       pk        156: getdewey(dewey, cp)
                    157: int    dewey[];
                    158: char   *cp;
                    159: {
                    160:        int     i, n;
                    161:
                    162:        for (n = 0, i = 0; i < MAXDEWEY; i++) {
                    163:                if (*cp == '\0')
                    164:                        break;
                    165:
                    166:                if (*cp == '.') cp++;
1.11      pk        167: #ifdef SUNOS_LIB_COMPAT
                    168:                if (!(isdigit)(*cp))
                    169: #else
1.1       pk        170:                if (!isdigit(*cp))
1.11      pk        171: #endif
1.1       pk        172:                        return 0;
                    173:
                    174:                dewey[n++] = strtol(cp, &cp, 10);
                    175:        }
                    176:
                    177:        return n;
                    178: }
                    179:
                    180: /*
1.2       pk        181:  * Compare two dewey arrays.
                    182:  * Return -1 if `d1' represents a smaller value than `d2'.
                    183:  * Return  1 if `d1' represents a greater value than `d2'.
                    184:  * Return  0 if equal.
                    185:  */
                    186: int
                    187: cmpndewey(d1, n1, d2, n2)
                    188: int    d1[], d2[];
                    189: int    n1, n2;
                    190: {
1.10      pk        191:        register int    i;
1.2       pk        192:
                    193:        for (i = 0; i < n1 && i < n2; i++) {
                    194:                if (d1[i] < d2[i])
                    195:                        return -1;
                    196:                if (d1[i] > d2[i])
                    197:                        return 1;
                    198:        }
                    199:
                    200:        if (n1 == n2)
                    201:                return 0;
                    202:
                    203:        if (i == n1)
                    204:                return -1;
                    205:
                    206:        if (i == n2)
                    207:                return 1;
1.10      pk        208:
                    209:        errx(1, "cmpndewey: cant happen");
                    210:        return 0;
1.2       pk        211: }
                    212:
                    213: /*
1.1       pk        214:  * Search directories for a shared library matching the given
                    215:  * major and minor version numbers.
                    216:  *
                    217:  * MAJOR == -1 && MINOR == -1  --> find highest version
                    218:  * MAJOR != -1 && MINOR == -1   --> find highest minor version
                    219:  * MAJOR == -1 && MINOR != -1   --> invalid
                    220:  * MAJOR != -1 && MINOR != -1   --> find highest micro version
                    221:  */
                    222:
                    223: /* Not interested in devices right now... */
                    224: #undef major
                    225: #undef minor
                    226:
                    227: char *
1.7       pk        228: findshlib(name, majorp, minorp, do_dot_a)
1.1       pk        229: char   *name;
                    230: int    *majorp, *minorp;
1.7       pk        231: int    do_dot_a;
1.1       pk        232: {
                    233:        int             dewey[MAXDEWEY];
                    234:        int             ndewey;
                    235:        int             tmp[MAXDEWEY];
                    236:        int             i;
                    237:        int             len;
                    238:        char            *lname, *path = NULL;
                    239:        int             major = *majorp, minor = *minorp;
                    240:
                    241:        len = strlen(name);
                    242:        lname = (char *)alloca(len + sizeof("lib"));
                    243:        sprintf(lname, "lib%s", name);
                    244:        len += 3;
                    245:
                    246:        ndewey = 0;
                    247:
                    248:        for (i = 0; i < n_search_dirs; i++) {
                    249:                DIR             *dd = opendir(search_dirs[i]);
                    250:                struct dirent   *dp;
1.7       pk        251:                int             found_dot_a = 0;
1.13      fvdl      252:                int             might_take_it;
1.1       pk        253:
                    254:                if (dd == NULL)
                    255:                        continue;
                    256:
1.13      fvdl      257:                might_take_it = 0;
1.1       pk        258:                while ((dp = readdir(dd)) != NULL) {
1.13      fvdl      259:                        int     n;
1.1       pk        260:
1.7       pk        261:                        if (do_dot_a && path == NULL &&
                    262:                                        dp->d_namlen == len + 2 &&
                    263:                                        strncmp(dp->d_name, lname, len) == 0 &&
                    264:                                        (dp->d_name+len)[0] == '.' &&
                    265:                                        (dp->d_name+len)[1] == 'a') {
                    266:
                    267:                                path = concat(search_dirs[i], "/", dp->d_name);
                    268:                                found_dot_a = 1;
                    269:                        }
                    270:
1.1       pk        271:                        if (dp->d_namlen < len + 4)
                    272:                                continue;
                    273:                        if (strncmp(dp->d_name, lname, len) != 0)
                    274:                                continue;
                    275:                        if (strncmp(dp->d_name+len, ".so.", 4) != 0)
                    276:                                continue;
                    277:
                    278:                        if ((n = getdewey(tmp, dp->d_name+len+4)) == 0)
                    279:                                continue;
                    280:
1.7       pk        281:                        if (major != -1 && found_dot_a) { /* XXX */
                    282:                                free(path);
                    283:                                path = NULL;
                    284:                                found_dot_a = 0;
                    285:                        }
                    286:
1.1       pk        287:                        if (major == -1 && minor == -1) {
                    288:                                might_take_it = 1;
                    289:                        } else if (major != -1 && minor == -1) {
                    290:                                if (tmp[0] == major)
                    291:                                        might_take_it = 1;
                    292:                        } else if (major != -1 && minor != -1) {
                    293:                                if (tmp[0] == major)
                    294:                                        if (n == 1 || tmp[1] >= minor)
                    295:                                                might_take_it = 1;
                    296:                        }
                    297:
                    298:                        if (!might_take_it)
                    299:                                continue;
                    300:
1.2       pk        301:                        if (cmpndewey(tmp, n, dewey, ndewey) <= 0)
1.1       pk        302:                                continue;
                    303:
                    304:                        /* We have a better version */
                    305:                        if (path)
                    306:                                free(path);
                    307:                        path = concat(search_dirs[i], "/", dp->d_name);
1.7       pk        308:                        found_dot_a = 0;
1.1       pk        309:                        bcopy(tmp, dewey, sizeof(dewey));
                    310:                        ndewey = n;
                    311:                        *majorp = dewey[0];
                    312:                        *minorp = dewey[1];
                    313:                }
                    314:                closedir(dd);
1.7       pk        315:
1.13      fvdl      316:                if (found_dot_a || might_take_it)
1.7       pk        317:                        /*
1.13      fvdl      318:                         * There's a lib in this dir; take it.
1.7       pk        319:                         */
                    320:                        return path;
1.1       pk        321:        }
                    322:
                    323:        return path;
                    324: }

CVSweb <webmaster@jp.NetBSD.org>