34 #include <sys/isa_defs.h>
35 #if defined(_ILP32) && (_FILE_OFFSET_BITS != 32)
36 #undef _FILE_OFFSET_BITS
37 #define _FILE_OFFSET_BITS 32
38 #undef _LARGEFILE_SOURCE
44 #if !defined(__APPLE__) && !defined(__CYGWIN__)
49 #include <sys/types.h>
52 #include "XrdSys/XrdWin32.hh"
59 #include "XrdVersion.hh"
66 struct XrdSysPlugin::PLlist *XrdSysPlugin::plList = 0;
74 if (libHandle) dlclose(libHandle);
75 if (libPath) free(libPath);
82 XrdSysPlugin::cvResult XrdSysPlugin::badVersion(XrdVersionInfo &urInfo,
83 char mmv,
int majv,
int minv)
86 char buff1[512], buff2[128];
88 if (minv < 0) strcpy(buff2,
"y");
89 else sprintf(buff2,
"%d", minv);
91 snprintf(buff1,
sizeof(buff1),
"version %s is incompatible with %s "
92 "(must be %c= %d.%s.x)",
93 myInfo->vStr, urInfo.vStr, mmv, majv, buff2);
95 path = msgSuffix(
" in ", buff2,
sizeof(buff2));
97 Inform(buff1, buff2, path, 0, 0, 1);
106 XrdSysPlugin::cvResult XrdSysPlugin::chkVersion(XrdVersionInfo &urInfo,
113 char buff[1024], vName[256];
115 int i, n=0, pMajor, vMajor, pMinor, vMinor;
119 if (!myInfo)
return cvNone;
124 while(vInfo[i].pName && strcmp(vInfo[i].pName, pname)) i++;
129 {i = 0; n = strlen(pname);
130 while(vNote[i].pName)
131 {
if ((vNote[i].vPfxLen + vNote[i].vSfxLen <= n)
132 && !strncmp(vNote[i].pName, pname, vNote[i].vPfxLen)
133 && !strncmp(vNote[i].pName+vNote[i].vPfxLen,
134 pname + n - vNote[i].vSfxLen, vNote[i].vSfxLen))
break;
138 }
else vinP = &vInfo[i];
140 if (!(vinP->
pName))
return cvNone;
145 if (!n) n = strlen(pname);
146 if (n+
sizeof(XrdVERSIONINFOSFX) >
sizeof(vName))
147 return libMsg(
"Unable to generate version name for",
"%s in ", pname);
148 strcpy(vName, pname); strcpy(vName+n, XrdVERSIONINFOSFX);
152 if (!(vP = dlsym(lHandle, vName)))
154 return libMsg(dlerror(),
" required version information for %s in ",pname);
162 memcpy(
static_cast<void*
>( &urInfo ), vP,
sizeof(XrdVersionInfo)-1);
166 if (myInfo->vNum == urInfo.vNum)
167 if (myInfo->vNum != XrdVNUMUNK
168 || !strcmp(myInfo->vStr + (myInfo->vOpt & 0x0f)+1,
169 urInfo. vStr + (urInfo. vOpt & 0x0f)+1))
return cvClean;
173 if (myInfo->vNum == XrdVNUMUNK || urInfo.vNum == XrdVNUMUNK)
176 snprintf(buff,
sizeof(buff),
"%s%s is using %s%s version",
177 (myInfo->vNum == XrdVNUMUNK ?
"unreleased ":
""),myInfo->vStr,
178 (urInfo.vNum == XrdVNUMUNK ?
"unreleased ":
""),urInfo.vStr);
179 msgSuffix(
" in ", mBuff,
sizeof(mBuff));
180 Inform(buff, mBuff, libPath);
187 vMajor = XrdMajorVNUM(myInfo->vNum);
188 vMinor = XrdMinorVNUM(myInfo->vNum);
189 pMajor = XrdMajorVNUM(urInfo. vNum);
190 pMinor = XrdMinorVNUM(urInfo. vNum);
194 if (vinP->
vMajLow >= 0 && pMajor < vinP->vMajLow)
197 if (vinP->
vMajLow < 0 && pMajor != vMajor)
198 return badVersion(urInfo,
'=', vMajor, -1);
202 if (pMajor > vMajor || (pMajor == vMajor && pMinor > vMinor))
203 return badVersion(urInfo,
'<', vMajor, vMinor);
207 if (vinP->
vMinLow < 0)
return cvClean;
211 if (pMajor == vinP->
vMajLow && pMinor < vinP->vMinLow)
223 int XrdSysPlugin::DLflags()
225 #if defined(__APPLE__)
227 #elif defined(__linux__)
238 void *XrdSysPlugin::Find(
const char *libpath)
240 struct PLlist *plP = plList;
244 while(plP && strcmp(libpath, plP->libPath)) plP = plP->next;
248 return (plP ? plP->libHandle : 0);
262 if (!(myHandle = libHandle) && plList) myHandle = Find(libPath);
266 if (myHandle)
return myHandle;
271 if (libPath) flags = DLflags();
272 else { flags = RTLD_NOW;
274 flags|= global ? RTLD_GLOBAL : RTLD_LOCAL;
277 "request for global symbols unsupported under Windows - ignored");
283 if ((myHandle = dlopen(libPath, flags))) libHandle = myHandle;
284 else {
const char *eTxt = dlerror();
285 if (strcasestr(eTxt,
"no such file")) errno = ENOENT;
286 else errno = ENOEXEC;
287 if (allMsgs || errno != ENOENT) libMsg(eTxt,
" loading ");
301 return getPlugin(pname, optional,
false);
312 if (!(myHandle =
getLibrary(optional < 2, global)))
return 0;
317 if (!(ep = dlsym(myHandle, pname)))
318 {
if (optional < 2) libMsg(dlerror(),
" symbol %s in ", pname);
324 if ((cvRC = chkVersion(urInfo, pname, myHandle)) == cvBad)
return 0;
328 if (libPath && optional < 2 && msgCnt
329 && (cvRC == cvClean || cvRC == cvMissing))
331 msgSuffix(
" from ", buff,
sizeof(buff));
334 {
const char *wTxt=(urInfo.vNum == XrdVNUMUNK ?
"unreleased ":
"");
335 Inform(
"loaded ", wTxt, urInfo.vStr, buff, libPath);
337 else if (cvRC == cvMissing)
338 {Inform(
"loaded unversioned ", pname, buff, libPath);}
350 void XrdSysPlugin::Inform(
const char *txt1,
const char *txt2,
const char *txt3,
351 const char *txt4,
const char *txt5,
int noHush)
353 const char *eTxt[] = {
"Plugin ",txt1, txt2, txt3, txt4, txt5, 0};
359 if (!noHush && getenv(
"XRDPIHUSH"))
return;
365 i = 1; bP = buff; bL =
sizeof(buff);
366 while(bL > 1 && eTxt[i])
367 {n = snprintf(bP, bL,
"%s", eTxt[i]);
368 bP += n; bL -= n; i++;
378 while(bL > 1 && eTxt[i])
379 {n = snprintf(bP, bL,
"%s", eTxt[i]);
380 bP += n; bL -= n; i++;
389 XrdSysPlugin::cvResult XrdSysPlugin::libMsg(
const char *txt1,
const char *txt2,
392 static const char fndg[] =
"Finding";
393 static const int flen =
sizeof(
"Finding");
395 char mBuff[512], nBuff[512];
400 {
if (!txt1 || strstr(txt1,
"undefined"))
401 {txt1 =
"Unable to find";
402 snprintf(nBuff,
sizeof(nBuff), txt2, mSym);
405 snprintf(nBuff+flen-1,
sizeof(nBuff)-flen,txt2,mSym);
409 else if (!txt1) txt1 =
"Unknown system error!";
410 else if (strstr(txt1,
"No such file")) txt1 =
"No such file or directory";
415 path = msgSuffix(txt2, mBuff,
sizeof(mBuff));
416 Inform(txt1, mBuff, path, 0, 0, 1);
424 const char *XrdSysPlugin::msgSuffix(
const char *Word,
char *buff,
int bsz)
426 if (libPath) snprintf(buff, bsz,
"%s%s ", Word, libName);
427 else snprintf(buff, bsz,
"%sexecutable image", Word);
428 return (libPath ? libPath :
"");
442 if (Find(path))
return true;
446 if (!(myHandle = dlopen(path, DLflags())))
447 {
if (ebuff && eblen > 0)
448 {
const char *dlMsg = dlerror();
449 snprintf(ebuff, eblen,
"Plugin unable to load %s; %s", path,
450 (dlMsg ? dlMsg :
"unknown system error"));
458 plP->libHandle = myHandle;
459 plP->libPath = strdup(path);
473 XrdVersionInfo &vInfo2,
bool noMsg)
476 char v1buff[128], v2buff[128];
481 if (vInfo1.vNum <= 0 || vInfo1.vNum == vInfo2.vNum)
return true;
487 mTxt = (vInfo1.vNum == XrdVNUMUNK ?
"unreleased " :
"");
488 sprintf(v1buff,
" %sversion %s", mTxt, vInfo1.vStr);
491 mTxt = (vInfo2.vNum == XrdVNUMUNK ?
"unreleased " :
"");
492 sprintf(v2buff,
" %sversion %s", mTxt, vInfo2.vStr);
495 if (unRel || vInfo1.vNum/100 == vInfo2.vNum/100) mTxt =
"";
496 else mTxt =
" which is incompatible!";
499 std::cerr <<
"Plugin: " <<v1buff <<
" is using " <<v2buff <<mTxt <<std::endl;
static XrdSysError eDest(0,"crypto_")
#define XrdVERSIONPLUGINRULES
int vProcess
version: <0 skip, =0 optional, >0 required
#define XrdVERSIONPLUGIN_DoNotChk
const char * pName
-> plugin object creator function name
#define XrdVERSIONPLUGIN_Required
short vMajLow
Lowest compatible major version number.
short vMinLow
Lowest compatible minor (< 0 don't check).
#define XrdVERSIONPLUGINMAXIMS
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
void * getPlugin(const char *pname, int optional=0)
static bool Preload(const char *path, char *ebuff=0, int eblen=0)
~XrdSysPlugin()
Destructor.
void * getLibrary(bool allMsgs=true, bool global=false)
static bool VerCmp(XrdVersionInfo &vInf1, XrdVersionInfo &vInf2, bool noMsg=false)
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)