XRootD
XrdCksLoader.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C k s L o a d e r . c c */
4 /* */
5 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <cstring>
33 #include <cstdio>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 
38 #include "XrdCks/XrdCksCalc.hh"
41 #include "XrdCks/XrdCksCalcmd5.hh"
42 #include "XrdCks/XrdCksLoader.hh"
43 
45 
46 #include "XrdSys/XrdSysPlugin.hh"
47 #include "XrdSys/XrdSysPthread.hh"
48 
49 #include "XrdVersion.hh"
50 
51 /******************************************************************************/
52 /* C o n s t r u c t o r */
53 /******************************************************************************/
54 
55 XrdCksLoader::XrdCksLoader(XrdVersionInfo &vInfo, const char *libPath)
56 {
57  static XrdVERSIONINFODEF(myVersion, XrdCks, XrdVNUMBER, XrdVERSION);
58  static const char libSfx[] = "/libXrdCksCalc%s.so";
59  int k, n;
60 
61 // Verify that versions are compatible.
62 //
63  if (vInfo.vNum != myVersion.vNum
64  && !XrdSysPlugin::VerCmp(vInfo, myVersion, true))
65  {char buff[1024];
66  snprintf(buff, sizeof(buff), "Version %s is incompatible with %s.",
67  vInfo.vStr, myVersion.vStr);
68  verMsg = strdup(buff); urVersion = 0;
69  return;
70  }
71  urVersion = &vInfo;
72  verMsg = 0;
73 
74 // Prefill the native digests we support
75 //
76  csTab[0].Name = strdup("adler32");
77  csTab[1].Name = strdup("crc32");
78  csTab[2].Name = strdup("md5");
79  csLast = 2;
80 
81 // Record the over-ride loader path
82 //
83  if (libPath)
84  {n = strlen(libPath);
85  ldPath = (char *)malloc(n+sizeof(libSfx)+1);
86  k = (libPath[n-1] == '/');
87  strcpy(ldPath, libPath);
88  strcpy(ldPath+n, libSfx+k);
89  } else ldPath = strdup(libSfx+1);
90 }
91 
92 /******************************************************************************/
93 /* D e s t r u c t o r */
94 /******************************************************************************/
95 
97 {
98  int i;
99  for (i = 0; i <= csLast; i++)
100  {if (csTab[i].Name) free( csTab[i].Name);
101  if (csTab[i].Obj) csTab[i].Obj->Recycle();
102  if (csTab[i].Plugin) delete csTab[i].Plugin;
103  }
104  if (ldPath) free(ldPath);
105  if (verMsg) free(verMsg);
106 }
107 
108 /******************************************************************************/
109 /* L o a d */
110 /******************************************************************************/
111 
112 #define XRDOSSCKSLIBARGS XrdSysError *, const char *, const char *, const char *
113 
114 XrdCksCalc *XrdCksLoader::Load(const char *csName, const char *csParms,
115  char *eBuff, int eBlen, bool orig)
116 {
117  static XrdSysMutex myMutex;
118  XrdSysMutexHelper ldMutex(myMutex);
120  XrdCksCalc *csObj;
121  XrdOucPinLoader *myPin;
122  csInfo *csIP;
123  char ldBuff[2048];
124  int n;
125 
126 // Verify that version checking succeeded
127 //
128  if (verMsg) {if (eBuff) strncpy(eBuff, verMsg, eBlen); return 0;}
129 
130 // First check if we have loaded this before
131 //
132  if ((csIP = Find(csName)))
133  {if (!(csIP->Obj))
134  { if (!strcmp("adler32", csIP->Name))
135  csIP->Obj = new XrdCksCalcadler32;
136  else if (!strcmp("crc32", csIP->Name))
137  csIP->Obj = new XrdCksCalccrc32;
138  else if (!strcmp("md5", csIP->Name))
139  csIP->Obj = new XrdCksCalcmd5;
140  else {if (eBuff) snprintf(eBuff, eBlen, "Logic error configuring %s "
141  "checksum.", csName);
142  return 0;
143  }
144  }
145  return (orig ? csIP->Obj : csIP->Obj->New());
146  }
147 
148 // Check if we can add a new entry
149 //
150  if (csLast+1 >= csMax)
151  {if (eBuff) strncpy(eBuff, "Maximum number of checksums loaded.", eBlen);
152  return 0;
153  }
154 
155 // Get the path where this object lives
156 //
157  snprintf(ldBuff, sizeof(ldBuff), ldPath, csName);
158 
159 // Get the plugin loader
160 //
161  if (!(myPin = new XrdOucPinLoader(eBuff,eBlen,urVersion,"ckslib",ldBuff)))
162  return 0;
163 
164 // Find the entry point
165 //
166  if (!(ep = (XrdCksCalc *(*)(XRDOSSCKSLIBARGS))
167  (myPin->Resolve("XrdCksCalcInit"))))
168  {myPin->Unload(true); return 0;}
169 
170 // Get the initial object
171 //
172  if (!(csObj = ep(0, 0, csName, csParms)))
173  {if (eBuff)
174  snprintf(eBuff, eBlen, "%s checksum initialization failed.", csName);
175  myPin->Unload(true);
176  return 0;
177  }
178 
179 // Verify the object
180 //
181  if (strcmp(csName, csObj->Type(n)))
182  {if (eBuff)
183  snprintf(eBuff, eBlen, "%s cksum plugin returned wrong name - %s",
184  csName, csObj->Type(n));
185  delete csObj;
186  myPin->Unload(true);
187  return 0;
188  }
189 
190 // Allocate a new entry in the table and initialize it
191 //
192  csLast++;
193  csTab[csLast].Name = strdup(csName);
194  csTab[csLast].Obj = csObj;
195  csTab[csLast].Plugin = myPin->Export();
196 
197 // Return new instance of this object
198 //
199  return (orig ? csObj : csObj->New());
200 }
201 
202 /******************************************************************************/
203 /* F i n d */
204 /******************************************************************************/
205 
206 XrdCksLoader::csInfo *XrdCksLoader::Find(const char *Name)
207 {
208  int i;
209  for (i = 0; i <= csLast; i++)
210  if (!strcmp(Name, csTab[i].Name)) return &csTab[i];
211  return 0;
212 }
#define XRDOSSCKSLIBARGS
XrdCksLoader(XrdVersionInfo &vInfo, const char *libPath=0)
Definition: XrdCksLoader.cc:55
XrdCksCalc * Load(const char *csName, const char *csParms=0, char *eBuff=0, int eBlen=0, bool orig=false)
~XrdCksLoader()
Destructor.
Definition: XrdCksLoader.cc:96
Definition: XrdCks.hh:92
XrdSysPlugin * Export()
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
static bool VerCmp(XrdVersionInfo &vInf1, XrdVersionInfo &vInf2, bool noMsg=false)
XrdVersionInfo myVersion
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)