/******************************************************************************/ /* */ /* X r d C k s L o a d e r . c c */ /* */ /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include #include #include #include #include #include #include "XrdCks/XrdCksCalc.hh" #include "XrdCks/XrdCksCalcadler32.hh" #include "XrdCks/XrdCksCalccrc32.hh" #include "XrdCks/XrdCksCalcmd5.hh" #include "XrdCks/XrdCksLoader.hh" #include "XrdOuc/XrdOucPinLoader.hh" #include "XrdSys/XrdSysPlugin.hh" #include "XrdSys/XrdSysPthread.hh" #include "XrdVersion.hh" /******************************************************************************/ /* C o n s t r u c t o r */ /******************************************************************************/ XrdCksLoader::XrdCksLoader(XrdVersionInfo &vInfo, const char *libPath) { static XrdVERSIONINFODEF(myVersion, XrdCks, XrdVNUMBER, XrdVERSION); static const char libSfx[] = "/libXrdCksCalc%s.so"; int k, n; // Verify that versions are compatible. // if (vInfo.vNum != myVersion.vNum && !XrdSysPlugin::VerCmp(vInfo, myVersion, true)) {char buff[1024]; snprintf(buff, sizeof(buff), "Version %s is incompatible with %s.", vInfo.vStr, myVersion.vStr); verMsg = strdup(buff); urVersion = 0; return; } urVersion = &vInfo; verMsg = 0; // Prefill the native digests we support // csTab[0].Name = strdup("adler32"); csTab[1].Name = strdup("crc32"); csTab[2].Name = strdup("md5"); csLast = 2; // Record the over-ride loader path // if (libPath) {n = strlen(libPath); ldPath = (char *)malloc(n+sizeof(libSfx)+1); k = (libPath[n-1] == '/'); strcpy(ldPath, libPath); strcpy(ldPath+n, libSfx+k); } else ldPath = strdup(libSfx+1); } /******************************************************************************/ /* D e s t r u c t o r */ /******************************************************************************/ XrdCksLoader::~XrdCksLoader() { int i; for (i = 0; i <= csLast; i++) {if (csTab[i].Name) free( csTab[i].Name); if (csTab[i].Obj) csTab[i].Obj->Recycle(); if (csTab[i].Plugin) delete csTab[i].Plugin; } if (ldPath) free(ldPath); if (verMsg) free(verMsg); } /******************************************************************************/ /* L o a d */ /******************************************************************************/ #define XRDOSSCKSLIBARGS XrdSysError *, const char *, const char *, const char * XrdCksCalc *XrdCksLoader::Load(const char *csName, const char *csParms, char *eBuff, int eBlen, bool orig) { static XrdSysMutex myMutex; XrdSysMutexHelper ldMutex(myMutex); XrdCksCalc *(*ep)(XRDOSSCKSLIBARGS); XrdCksCalc *csObj; XrdOucPinLoader *myPin; csInfo *csIP; char ldBuff[2048]; int n; // Verify that version checking succeeded // if (verMsg) {if (eBuff) strncpy(eBuff, verMsg, eBlen); return 0;} // First check if we have loaded this before // if ((csIP = Find(csName))) {if (!(csIP->Obj)) { if (!strcmp("adler32", csIP->Name)) csIP->Obj = new XrdCksCalcadler32; else if (!strcmp("crc32", csIP->Name)) csIP->Obj = new XrdCksCalccrc32; else if (!strcmp("md5", csIP->Name)) csIP->Obj = new XrdCksCalcmd5; else {if (eBuff) snprintf(eBuff, eBlen, "Logic error configuring %s " "checksum.", csName); return 0; } } return (orig ? csIP->Obj : csIP->Obj->New()); } // Check if we can add a new entry // if (csLast+1 >= csMax) {if (eBuff) strncpy(eBuff, "Maximum number of checksums loaded.", eBlen); return 0; } // Get the path where this object lives // snprintf(ldBuff, sizeof(ldBuff), ldPath, csName); // Get the plugin loader // if (!(myPin = new XrdOucPinLoader(eBuff,eBlen,urVersion,"ckslib",ldBuff))) return 0; // Find the entry point // if (!(ep = (XrdCksCalc *(*)(XRDOSSCKSLIBARGS)) (myPin->Resolve("XrdCksCalcInit")))) {myPin->Unload(true); return 0;} // Get the initial object // if (!(csObj = ep(0, 0, csName, csParms))) {if (eBuff) snprintf(eBuff, eBlen, "%s checksum initialization failed.", csName); myPin->Unload(true); return 0; } // Verify the object // if (strcmp(csName, csObj->Type(n))) {if (eBuff) snprintf(eBuff, eBlen, "%s cksum plugin returned wrong name - %s", csName, csObj->Type(n)); delete csObj; myPin->Unload(true); return 0; } // Allocate a new entry in the table and initialize it // csLast++; csTab[csLast].Name = strdup(csName); csTab[csLast].Obj = csObj; csTab[csLast].Plugin = myPin->Export(); // Return new instance of this object // return (orig ? csObj : csObj->New()); } /******************************************************************************/ /* F i n d */ /******************************************************************************/ XrdCksLoader::csInfo *XrdCksLoader::Find(const char *Name) { int i; for (i = 0; i <= csLast; i++) if (!strcmp(Name, csTab[i].Name)) return &csTab[i]; return 0; }