XRootD
Loading...
Searching...
No Matches
XrdOucPinLoader.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O u c P i n L o a d e r . c c */
4/* */
5/* (c) 2014 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <cerrno>
31#include <cstdlib>
32#include <cstdio>
33#include <cstring>
34
35#include "XrdVersion.hh"
36
39#include "XrdSys/XrdSysError.hh"
41
42/******************************************************************************/
43/* C o n s t r u c t o r */
44/******************************************************************************/
45
47 XrdVersionInfo *vInfo,
48 const char *drctv,
49 const char *plib)
50{
51
52// Save some symbols and do common initialization
53//
54 eDest = errP;
55 viP = vInfo;
56 errBP = 0;
57 errBL = 0;
58 Init(drctv, plib);
59}
60
61/******************************************************************************/
62
64 int eBlen,
65 XrdVersionInfo *vInfo,
66 const char *drctv,
67 const char *plib)
68{
69
70// Save some symbols and do common initialization
71//
72 eDest = 0;
73 viP = vInfo;
74 errBP = (eBlen > 0 ? eBuff : 0);
75 errBL = (eBlen > 0 ? eBlen : 0);
76 frBuff= false;
77 if (errBP) *errBP = 0;
78 Init(drctv, plib);
79}
80
81/******************************************************************************/
82
84 const char *drctv,
85 const char *plib)
86{
87 static const int ebsz = 2048;
88
89// Allocate a message buffer if we need to (failure is OK)
90//
91 errBP = (char *)malloc(ebsz);
92 errBL = ebsz;
93 frBuff= true;
94
95// Save some symbols and do common initialization
96//
97 *errBP= 0;
98 eDest = 0;
99 viP = vInfo;
100 Init(drctv, plib);
101}
102
103/******************************************************************************/
104/* D e s t r u c t o r */
105/******************************************************************************/
106
108{
109
110// Releae storage
111//
112 if (theLib) free(theLib);
113 if (altLib) free(altLib);
114
115// Persist the image if we have one
116//
117 if (piP) {piP->Persist(); delete piP;}
118 if (errBP && frBuff) free(errBP);
119}
120
121/******************************************************************************/
122/* Private: I n f o r m */
123/******************************************************************************/
124
125void XrdOucPinLoader::Inform(const char *txt1, const char *txt2,
126 const char *txt3, const char *txt4,
127 const char *txt5)
128{
129
130// If we have a messaging object, use that
131//
132 if (eDest) {eDest->Say("Config ", txt1, txt2, txt3, txt4, txt5); return;}
133
134// If there is already a message in the buffer, then make sure it prints
135//
136 char *bP;
137 int bL, n , i = 0;
138
139 if (*errBP)
140 {int n = strlen(errBP);
141 if (n+16 > errBL) return;
142 errBP[n] = '\n';
143 bP = errBP + n + 1;
144 bL = errBL - n - 1;
145 } else {
146 bP = errBP;
147 bL = errBL;
148 }
149
150// Place the message in the buffer
151//
152 const char *eTxt[] = {txt1, txt2, txt3, txt4, txt5, 0};
153 while(bL > 1 && eTxt[i])
154 {n = snprintf(bP, bL, "%s", eTxt[i]);
155 bP += n; bL -= n; i++;
156 }
157}
158
159/******************************************************************************/
160/* Private: I n i t */
161/******************************************************************************/
162
163void XrdOucPinLoader::Init(const char *drctv, const char *plib)
164{
165 char *plib2 = 0, libBuf[2048];
166 int n;
167 bool noFallBack;
168
169// We have no plugin
170//
171 piP = 0;
172 dName = drctv;
173 global = false;
174 badLib = false;
175
176// Check if the path has a version in it. This is generally a no-no.
177// We Issue a warning only on servers as that is where it usually occurs.
178//
179 if ((n = XrdOucVerName::hasVersion(plib, &plib2)))
180 {if (plib2)
181 {snprintf(libBuf, sizeof(libBuf), "'%s' wrongly coerces version "
182 "'-%d'; using '%s' instead!", plib, n, plib2);
183 } else {
184 snprintf(libBuf, sizeof(libBuf), "'%s' should not use '-%d' "
185 "version syntax in its name!", plib, n);
186 }
187 if (eDest) eDest->Say("Config warning: ", dName, " path ", libBuf);
188 if (plib2) plib = plib2;
189 }
190
191// Perform versioning
192//
193 if (XrdOucVerName::Version(XRDPLUGIN_SOVERSION, plib, noFallBack,
194 libBuf, sizeof(libBuf)))
195 {theLib = strdup(libBuf);
196 altLib = (noFallBack ? 0 : strdup(plib));
197 } else {
198 theLib = 0;
199 altLib = strdup(plib);
200 }
201// Free up any allocated storage
202//
203 if (plib2) free(plib2);
204}
205
206/******************************************************************************/
207/* Private: L o a d L i b */
208/******************************************************************************/
209
210bool XrdOucPinLoader::LoadLib(int mcnt)
211{
212 bool allMsgs = altLib == 0;
213
214// Create a plugin object
215//
216 if (eDest) piP = new XrdSysPlugin(eDest, theLib, dName, viP, mcnt);
217 else piP = new XrdSysPlugin(errBP, errBL, theLib, dName, viP, mcnt);
218
219// Attempt to load the library
220//
221 if (piP->getLibrary(allMsgs, global)) return true;
222
223// We failed, so delete this plugin
224//
225 delete piP; piP = 0;
226
227// If we have an alternate unversioned name then we can try that but only
228// if the versioned wasn't found.
229//
230 if (!altLib && errno != ENOENT)
231 {badLib = true;
232 return false;
233 }
234
235// Indicate what we are doing but only for server-side plugins
236//
237 if (eDest) eDest->Say("Plugin ", dName, " ", theLib,
238 " not found; falling back to using ", altLib);
239
240// if we have an alternative, readjust library pointers
241//
242 if (altLib)
243 {free(theLib);
244 theLib = altLib;
245 altLib = 0;
246 } else {
247 badLib = true;
248 return false;
249 }
250
251// Try once more
252//
253 if (eDest) piP = new XrdSysPlugin(eDest, theLib, dName, viP, mcnt);
254 else piP = new XrdSysPlugin(errBP, errBL, theLib, dName, viP, mcnt);
255
256// Attempt to load the alternate library
257//
258 if (piP->getLibrary(true, global)) return true;
259 badLib = true;
260 return false;
261}
262
263/******************************************************************************/
264/* R e s o l v e */
265/******************************************************************************/
266
267void *XrdOucPinLoader::Resolve(const char *symP, int mcnt)
268{
269 int isOptional = 0;
270
271// Check if we couldn't create the path
272//
273 if (!theLib && !badLib)
274 {Inform("Unable to load ",dName," plugin ",altLib,"; invalid path.");
275 badLib = true;
276 return 0;
277 }
278
279// If we couldn't load the library return failure. This is likely an alternate
280// resolution as the caller is looking for an alternate symbol.
281//
282 if (badLib) return 0;
283
284// Load the library so we can get errors about the library irrespective of
285// the symbol we are trying to resolve.
286//
287 if (!piP && !LoadLib(mcnt)) return 0;
288
289// Handle optional resolution
290//
291 if (*symP == '?' || *symP == '!')
292 {symP++;
293 isOptional = (*symP == '!' ? 1 : 2);
294 }
295
296// We already have a plugin object so look up the symbol.
297//
298 return piP->getPlugin(symP, isOptional, global);
299}
300
301/******************************************************************************/
302/* U n L o a d */
303/******************************************************************************/
304
306{
307
308// Simply delete any plugin object
309//
310 if (piP) {delete piP; piP = 0;}
311 if (dodel) delete this;
312}
static XrdSysError eDest(0,"crypto_")
XrdOucPinLoader(XrdSysError *errP, XrdVersionInfo *vInfo, const char *drctv, const char *plib)
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
static int Version(const char *piVers, const char *piPath, bool &noFBK, char *buff, int blen)
static int hasVersion(const char *piPath, char **piNoVN=0)