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>