1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1997-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22 * Glenn Fowler
23 * AT&T Research
24 */
25
26 #include "dlllib.h"
27
28 /*
29 * find and load lib plugin/module library name with optional version ver and dlopen() flags
30 * at least one dlopen() is called to initialize dlerror()
31 * if path!=0 then library path up to size chars copied to path with trailing 0
32 * if name contains a directory prefix then library search is limited to the dir and siblings
33 */
34
35 extern void*
dllplugin(const char * lib,const char * name,const char * ver,unsigned long rel,unsigned long * cur,int flags,char * path,size_t size)36 dllplugin(const char* lib, const char* name, const char* ver, unsigned long rel, unsigned long* cur, int flags, char* path, size_t size)
37 {
38 void* dll;
39 int err;
40 int hit;
41 Dllscan_t* dls;
42 Dllent_t* dle;
43
44 err = hit = 0;
45 for (;;)
46 {
47 if (dls = dllsopen(lib, name, ver))
48 {
49 while (dle = dllsread(dls))
50 {
51 hit = 1;
52 #if 0
53 again:
54 #endif
55 if (dll = dllopen(dle->path, flags|RTLD_GLOBAL|RTLD_PARENT))
56 {
57 if (!dllcheck(dll, dle->path, rel, cur))
58 {
59 err = state.error;
60 dlclose(dll);
61 dll = 0;
62 continue;
63 }
64 if (path && size)
65 strlcpy(path, dle->path, size);
66 break;
67 }
68 else
69 {
70 #if 0
71 /*
72 * dlopen() should load implicit libraries
73 * this code does that
74 * but it doesn't help on galadriel
75 */
76
77 char* s;
78 char* e;
79
80 if ((s = dllerror(1)) && (e = strchr(s, ':')))
81 {
82 *e = 0;
83 error(1, "AHA %s implicit", s);
84 dll = dllplugin(lib, s, 0, 0, 0, flags, path, size);
85 *e = ':';
86 if (dll)
87 {
88 error(1, "AHA implicit %s => %s", s, path);
89 goto again;
90 }
91 }
92 #endif
93 errorf("dll", NiL, 1, "dllplugin: %s dlopen failed: %s", dle->path, dllerror(1));
94 err = state.error;
95 }
96 }
97 dllsclose(dls);
98 }
99 if (hit)
100 {
101 if (!dll)
102 state.error = err;
103 return dll;
104 }
105 if (!lib)
106 break;
107 lib = 0;
108 }
109 if (dll = dllopen(name, flags))
110 {
111 if (!dllcheck(dll, name, rel, cur))
112 {
113 dlclose(dll);
114 dll = 0;
115 }
116 else if (path && size)
117 strlcpy(path, name, size);
118 }
119 return dll;
120 }
121
122 extern void*
dllplug(const char * lib,const char * name,const char * ver,int flags,char * path,size_t size)123 dllplug(const char* lib, const char* name, const char* ver, int flags, char* path, size_t size)
124 {
125 return dllplugin(lib, name, ver, 0, NiL, flags, path, size);
126 }
127