38 #include <sys/types.h>
59 #define ENOATTR ENODATA
78 strcpy(csTab[0].
Name,
"adler32");
79 strcpy(csTab[1].
Name,
"crc32");
80 strcpy(csTab[2].
Name,
"crc32c");
81 strcpy(csTab[3].
Name,
"md5");
86 if (rdsz <= 65536) segSize = 67108864;
87 else segSize = ((rdsz/65536) + (rdsz%65536 != 0)) * 65536;
97 for (i = 0; i <= csLast; i++)
98 {
if (csTab[i].Obj && csTab[i].doDel) csTab[i].Obj->Recycle();
99 if (csTab[i].
Path) free( csTab[i].
Path);
100 if (csTab[i].Parms) free( csTab[i].Parms);
101 if (csTab[i].Plugin)
delete csTab[i].Plugin;
103 if (cksLoader)
delete cksLoader;
113 csInfo *csIP = &csTab[0];
119 if (csLast < 0)
return -ENOTSUP;
120 if (!(*Cks.
Name)) Cks.
Set(csIP->Name);
121 else if (!(csIP = Find(Cks.
Name)))
return -ENOTSUP;
128 if (!(csP = csIP->Obj->
New()))
return -ENOMEM;
132 if (!(rc =
Calc(Pfn, MTime, csP)))
134 Cks.fmTime =
static_cast<long long>(MTime);
135 Cks.
csTime =
static_cast<int>(time(0) - MTime);
140 memcpy(&
xCS.Attr.Cks, &Cks,
sizeof(
xCS.Attr.Cks));
141 if ((rc =
xCS.Set(Pfn)))
return -rc;
158 ~ioFD() {
if (FD >= 0)
close(FD);}
162 off_t Offset=0, fileSize;
163 size_t ioSize, calcSize;
168 if ((In.FD =
open(Pfn, O_RDONLY)) < 0)
return -errno;
173 if (!(
Stat.st_mode & S_IFREG))
return -EPERM;
174 calcSize = fileSize =
Stat.st_size;
175 MTime =
Stat.st_mtime;
179 ioSize = (fileSize < (off_t)segSize ? fileSize : segSize); rc = 0;
181 {
if ((inBuff = (
char *)mmap(0, ioSize, PROT_READ,
182 #
if defined(__FreeBSD__)
183 MAP_RESERVED0040|MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
184 #elif defined(__GNU__)
185 MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
187 MAP_NORESERVE|MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
189 {rc = errno;
eDest->
Emsg(
"Cks", rc,
"memory map", Pfn);
break;}
190 madvise(inBuff, ioSize, MADV_SEQUENTIAL);
191 csP->
Update(inBuff, ioSize);
192 calcSize -= ioSize; Offset += ioSize;
193 if (munmap(inBuff, ioSize) < 0)
194 {rc = errno;
eDest->
Emsg(
"Cks",rc,
"unmap memory for",Pfn);
break;}
195 if (calcSize < (
size_t)segSize) ioSize = calcSize;
200 if (calcSize)
return (rc ? -rc : -EIO);
225 if (!(val =
Cfg.GetToken()) || !val[0])
226 {
eDest->
Emsg(
"Config",
"checksum name not specified");
return 1;}
228 {
eDest->
Emsg(
"Config",
"checksum name too long");
return 1;}
233 val =
Cfg.GetToken(&parms);
234 if (val && val[0]) path = strdup(val);
235 else {
eDest->
Emsg(
"Config",
"library path missing for ckslib digest",name);
241 for (i = 0; i < csMax; i++)
242 if (!(*csTab[i].
Name) || !strcmp(csTab[i].
Name, name))
break;
247 {
eDest->
Emsg(
"Config",
"too many checksums specified");
248 if (path) free(path);
250 }
else if (!(*csTab[i].
Name)) csLast = i;
254 strcpy(csTab[i].
Name, name);
255 if (csTab[i].
Path) free(csTab[i].
Path);
256 csTab[i].Path = path;
257 if (csTab[i].Parms) free(csTab[i].Parms);
258 csTab[i].Parms = (parms && *parms ? strdup(parms) : 0);
276 {
for (i = 0; i < csLast; i++)
if (!strcmp(csTab[i].
Name, DfltCalc))
break;
278 {
eDest->
Emsg(
"Config", DfltCalc,
"cannot be made the default; "
282 if (i) {csInfo Temp = csTab[i]; csTab[i] = csTab[0]; csTab[0] = Temp;}
288 {
eDest->
Emsg(
"Config",
"No checksums defined; cannot configure!");
294 for (i = 0; i <= csLast; i++)
295 {
if (csTab[i].
Path) {
if (!(
Config(ConfigFN, csTab[i])))
return 0;}
296 else {
if (!strcmp(
"adler32", csTab[i].
Name))
298 else if (!strcmp(
"crc32", csTab[i].
Name))
300 else if (!strcmp(
"crc32c", csTab[i].
Name))
302 else if (!strcmp(
"md5", csTab[i].
Name))
304 else {
eDest->
Emsg(
"Config",
"Invalid native checksum -",
308 csTab[i].Obj->Type(csTab[i].Len);
319 #define XRDOSSCKSLIBARGS XrdSysError *, const char *, const char *, const char *
331 (myPin.
Resolve(
"XrdCksCalcInit"))))
332 {
eDest->
Emsg(
"Config",
"Unable to configure cksum",
Info.Name);
340 {
eDest->
Emsg(
"Config",
Info.Name,
"checksum initialization failed");
347 if (strcmp(
Info.Name,
Info.Obj->Type(n)))
348 {
eDest->
Emsg(
"Config",
Info.Name,
"cksum plugin returned wrong name -",
354 {
eDest->
Emsg(
"Config",
Info.Name,
"cksum plugin has an unsupported "
371 XrdCksManager::csInfo *XrdCksManager::Find(
const char *Name)
379 for (i = 0; i <= csLast; i++)
380 if (!strcmp(
Name, csTab[i].
Name))
return &csTab[i];
384 if (!cksLoader)
return 0;
389 for (i = 0; i <= csLast; i++)
399 eDest->
Emsg(
"CksMan",
"Unable to load",
Name,
"; checksum limit reached.");
407 if (!(myCalc = cksLoader->
Load(
Name, 0, buff,
sizeof(buff),
true)))
419 csTab[i].Obj = myCalc;
423 csTab[i].doDel =
false;
424 myCalc->
Type(csTab[i].Len);
462 if (csLast < 0)
return -ENOTSUP;
464 if (!
xCS.Attr.Cks.Set(Cks.
Name))
return -ENOTSUP;
468 if ((rc =
xCS.Get(Pfn)) <= 0)
return (rc && rc != -
ENOATTR ? rc : -ESRCH);
472 nFault = strcmp(
xCS.Attr.Cks.Name, Cks.
Name);
477 if ((rc =
ModTime(Pfn, MTime)))
return rc;
481 return (Cks.fmTime != MTime || nFault
483 ? -ESTALE :
int(Cks.
Length));
492 static const char *vPfx =
"XrdCks.";
493 static const int vPln = strlen(vPfx);
500 if (Blen < 2)
return 0;
505 {
if (csLast < 0)
return 0;
507 while(i <= csLast && Blen > 1)
508 {n = strlen(csTab[i].
Name);
509 if (n >= Blen)
break;
510 if (bP != Buff) *bP++ = Sep;
511 strcpy(bP, csTab[i].
Name); bP += n; *bP = 0;
513 return (bP == Buff ? 0 : Buff);
524 {
if (vP->
Nlen > vPln && !strncmp(vP->
Name, vPfx, vPln))
525 {n = vP->
Nlen - vPln;
526 if (n >= Blen)
break;
527 if (bP != Buff) *bP++ = Sep;
528 strcpy(bP, vP->
Name + vPln); bP += n; *bP = 0;
536 return (bP == Buff ? 0 : Buff);
547 if (
stat(Pfn, &
Stat))
return -errno;
549 MTime =
Stat.st_mtime;
560 return (seqNum < 0 || seqNum > csLast ? 0 : csTab[seqNum].
Name);
569 csInfo *csIP = &csTab[0];
573 if (name && !(csIP = Find(name)))
return 0;
574 return csIP->Obj->New();
583 csInfo *iP = (
Name != 0 ? Find(
Name) : &csTab[0]);
584 return (iP != 0 ? iP->Len : 0);
594 csInfo *csIP = &csTab[0];
598 if (csLast < 0 || (*Cks.
Name && !(csIP = Find(Cks.
Name))))
return -ENOTSUP;
599 if (Cks.
Length != csIP->Len)
return -EDOM;
600 memcpy(&
xCS.Attr.Cks, &Cks,
sizeof(
xCS.Attr.Cks));
608 xCS.Attr.Cks.fmTime =
static_cast<long long>(MTime);
609 xCS.Attr.Cks.csTime =
static_cast<int>(time(0) - MTime);
625 csInfo *csIP = &csTab[0];
630 if (csLast < 0 || (*Cks.
Name && !(csIP = Find(Cks.
Name))))
return -ENOTSUP;
631 xCS.Attr.Cks.Set(csIP->Name);
635 if ((rc =
ModTime(Pfn, MTime)))
return rc;
639 if ((rc =
xCS.Get(Pfn)) < 0)
return rc;
643 if (!rc ||
xCS.Attr.Cks.fmTime != MTime
644 || strcmp(
xCS.Attr.Cks.Name, csIP->Name)
645 ||
xCS.Attr.Cks.Length != csIP->Len)
646 {strcpy(
xCS.Attr.Cks.Name, Cks.
Name);
647 if ((rc =
Calc(Pfn,
xCS.Attr.Cks, 1)) < 0)
return rc;
652 return (
xCS.Attr.Cks.Length == Cks.
Length
653 && !memcmp(
xCS.Attr.Cks.Value, Cks.
Value, csIP->Len));
XrdOucXAttr< XrdCksXAttr > xCS
int stat(const char *path, struct stat *buf)
int open(const char *path, int oflag,...)
int fstat(int fildes, struct stat *buf)
virtual void Update(const char *Buff, int BLen)=0
virtual const char * Type(int &csSize)=0
virtual void Recycle()
Recycle the checksum object as it is no longer needed. A default is given.
virtual XrdCksCalc * New()=0
static const int ValuSize
int Set(const char *csName)
static const int NameSize
XrdCksCalc * Load(const char *csName, const char *csParms=0, char *eBuff=0, int eBlen=0, bool orig=false)
virtual int Config(const char *Token, char *Line)
virtual int Get(const char *Pfn, XrdCksData &Cks)
virtual int Del(const char *Pfn, XrdCksData &Cks)
virtual int Size(const char *Name=0)
virtual const char * Name(int seqNum=0)
XrdCksManager(XrdSysError *erP, int iosz, XrdVersionInfo &vInfo, bool autoload=false)
virtual int Calc(const char *Pfn, XrdCksData &Cks, int doSet=1)
virtual int ModTime(const char *Pfn, time_t &MTime)
virtual char * List(const char *Pfn, char *Buff, int Blen, char Sep=' ')
virtual XrdCksCalc * Object(const char *name)
virtual int Ver(const char *Pfn, XrdCksData &Cks)
virtual int Set(const char *Pfn, XrdCksData &Cks, int myTime=0)
virtual int Init(const char *ConfigFN, const char *AddCalc=0)
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
static void toLower(char *str)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
char Name[1]
Start of the name (size of struct is dynamic)
int Nlen
The length of the attribute name that follows.
virtual void Free(AList *aPL)=0
AList * Next
-> next element.