38 #include <sys/types.h>
59 #define ENOATTR ENODATA
87 strcpy(csTab[0].
Name,
"adler32");
88 strcpy(csTab[1].
Name,
"crc32");
89 strcpy(csTab[2].
Name,
"crc32c");
90 strcpy(csTab[3].
Name,
"md5");
95 if (rdsz <= 65536) segSize = 67108864;
96 else segSize = ((rdsz/65536) + (rdsz%65536 != 0)) * 65536;
106 for (i = 0; i <= csLast; i++)
107 {
if (csTab[i].Obj && csTab[i].doDel) csTab[i].Obj->Recycle();
108 if (csTab[i].
Path) free( csTab[i].
Path);
109 if (csTab[i].Parms) free( csTab[i].Parms);
110 if (csTab[i].Plugin)
delete csTab[i].Plugin;
112 if (cksLoader)
delete cksLoader;
122 csInfo *csIP = &csTab[0];
128 if (csLast < 0)
return -ENOTSUP;
129 if (!(*Cks.
Name)) Cks.
Set(csIP->Name);
130 else if (!(csIP = Find(Cks.
Name)))
return -ENOTSUP;
137 if (!(csP = csIP->Obj->
New()))
return -ENOMEM;
141 if (!(rc =
Calc(Pfn, MTime, csP)))
143 Cks.fmTime =
static_cast<long long>(MTime);
144 Cks.
csTime =
static_cast<int>(time(0) - MTime);
149 memcpy(&
xCS.Attr.Cks, &Cks,
sizeof(
xCS.Attr.Cks));
150 if ((rc =
xCS.Set(Pfn)))
return -rc;
167 ~ioFD() {
if (FD >= 0)
close(FD);}
171 off_t Offset=0, fileSize;
172 size_t ioSize, calcSize;
177 if ((In.FD =
open(Pfn, O_RDONLY)) < 0)
return -errno;
182 if (!(
Stat.st_mode & S_IFREG))
return -EPERM;
183 calcSize = fileSize =
Stat.st_size;
184 MTime =
Stat.st_mtime;
188 ioSize = (fileSize < (off_t)segSize ? fileSize : segSize); rc = 0;
190 {
if ((inBuff = (
char *)mmap(0, ioSize, PROT_READ,
191 #
if defined(__FreeBSD__)
192 MAP_RESERVED0040|MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
193 #elif defined(__GNU__)
194 MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
196 MAP_NORESERVE|MAP_PRIVATE, In.FD, Offset)) == MAP_FAILED)
198 {rc = errno;
eDest->
Emsg(
"Cks", rc,
"memory map", Pfn);
break;}
199 madvise(inBuff, ioSize, MADV_SEQUENTIAL);
200 csP->
Update(inBuff, ioSize);
201 calcSize -= ioSize; Offset += ioSize;
202 if (munmap(inBuff, ioSize) < 0)
203 {rc = errno;
eDest->
Emsg(
"Cks",rc,
"unmap memory for",Pfn);
break;}
204 if (calcSize < (
size_t)segSize) ioSize = calcSize;
209 if (calcSize)
return (rc ? -rc : -EIO);
234 if (!(val =
Cfg.GetToken()) || !val[0])
235 {
eDest->
Emsg(
"Config",
"checksum name not specified");
return 1;}
237 {
eDest->
Emsg(
"Config",
"checksum name too long");
return 1;}
242 val =
Cfg.GetToken(&parms);
243 if (val && val[0]) path = strdup(val);
244 else {
eDest->
Emsg(
"Config",
"library path missing for ckslib digest",name);
250 for (i = 0; i < csMax; i++)
251 if (!(*csTab[i].
Name) || !strcmp(csTab[i].
Name, name))
break;
256 {
eDest->
Emsg(
"Config",
"too many checksums specified");
257 if (path) free(path);
259 }
else if (!(*csTab[i].
Name)) csLast = i;
263 strcpy(csTab[i].
Name, name);
264 if (csTab[i].
Path) free(csTab[i].
Path);
265 csTab[i].Path = path;
266 if (csTab[i].Parms) free(csTab[i].Parms);
267 csTab[i].Parms = (parms && *parms ? strdup(parms) : 0);
285 {
for (i = 0; i < csLast; i++)
if (!strcmp(csTab[i].
Name, DfltCalc))
break;
287 {
eDest->
Emsg(
"Config", DfltCalc,
"cannot be made the default; "
291 if (i) {csInfo Temp = csTab[i]; csTab[i] = csTab[0]; csTab[0] = Temp;}
297 {
eDest->
Emsg(
"Config",
"No checksums defined; cannot configure!");
303 for (i = 0; i <= csLast; i++)
304 {
if (csTab[i].
Path) {
if (!(
Config(ConfigFN, csTab[i])))
return 0;}
305 else {
if (!strcmp(
"adler32", csTab[i].
Name))
307 else if (!strcmp(
"crc32", csTab[i].
Name))
309 else if (!strcmp(
"crc32c", csTab[i].
Name))
311 else if (!strcmp(
"md5", csTab[i].
Name))
313 else {
eDest->
Emsg(
"Config",
"Invalid native checksum -",
317 csTab[i].Obj->Type(csTab[i].Len);
328 #define XRDOSSCKSLIBARGS XrdSysError *, const char *, const char *, const char *
340 (myPin.
Resolve(
"XrdCksCalcInit"))))
341 {
eDest->
Emsg(
"Config",
"Unable to configure cksum",
Info.Name);
349 {
eDest->
Emsg(
"Config",
Info.Name,
"checksum initialization failed");
356 if (strcmp(
Info.Name,
Info.Obj->Type(n)))
357 {
eDest->
Emsg(
"Config",
Info.Name,
"cksum plugin returned wrong name -",
363 {
eDest->
Emsg(
"Config",
Info.Name,
"cksum plugin has an unsupported "
380 XrdCksManager::csInfo *XrdCksManager::Find(
const char *Name)
388 for (i = 0; i <= csLast; i++)
389 if (!strcmp(
Name, csTab[i].
Name))
return &csTab[i];
393 if (!cksLoader)
return 0;
398 for (i = 0; i <= csLast; i++)
408 eDest->
Emsg(
"CksMan",
"Unable to load",
Name,
"; checksum limit reached.");
416 if (!(myCalc = cksLoader->
Load(
Name, 0, buff,
sizeof(buff),
true)))
428 csTab[i].Obj = myCalc;
432 csTab[i].doDel =
false;
433 myCalc->
Type(csTab[i].Len);
471 if (csLast < 0)
return -ENOTSUP;
473 if (!
xCS.Attr.Cks.Set(Cks.
Name))
return -ENOTSUP;
477 if ((rc =
xCS.Get(Pfn)) <= 0)
return (rc && rc != -
ENOATTR ? rc : -ESRCH);
481 nFault = strcmp(
xCS.Attr.Cks.Name, Cks.
Name);
488 else if ((rc =
ModTime(Pfn, MTime)))
return rc;
492 return (Cks.fmTime != MTime || nFault
494 ? -ESTALE :
int(Cks.
Length));
503 static const char *vPfx =
"XrdCks.";
504 static const int vPln = strlen(vPfx);
511 if (Blen < 2)
return 0;
516 {
if (csLast < 0)
return 0;
518 while(i <= csLast && Blen > 1)
519 {n = strlen(csTab[i].
Name);
520 if (n >= Blen)
break;
521 if (bP != Buff) *bP++ = Sep;
522 strcpy(bP, csTab[i].
Name); bP += n; *bP = 0;
524 return (bP == Buff ? 0 : Buff);
535 {
if (vP->
Nlen > vPln && !strncmp(vP->
Name, vPfx, vPln))
536 {n = vP->
Nlen - vPln;
537 if (n >= Blen)
break;
538 if (bP != Buff) *bP++ = Sep;
539 strcpy(bP, vP->
Name + vPln); bP += n; *bP = 0;
547 return (bP == Buff ? 0 : Buff);
558 if (
stat(Pfn, &
Stat))
return -errno;
560 MTime =
Stat.st_mtime;
571 return (seqNum < 0 || seqNum > csLast ? 0 : csTab[seqNum].
Name);
580 csInfo *csIP = &csTab[0];
584 if (name && !(csIP = Find(name)))
return 0;
585 return csIP->Obj->New();
594 csInfo *iP = (
Name != 0 ? Find(
Name) : &csTab[0]);
595 return (iP != 0 ? iP->Len : 0);
605 csInfo *csIP = &csTab[0];
609 if (csLast < 0 || (*Cks.
Name && !(csIP = Find(Cks.
Name))))
return -ENOTSUP;
610 if (Cks.
Length != csIP->Len)
return -EDOM;
611 memcpy(&
xCS.Attr.Cks, &Cks,
sizeof(
xCS.Attr.Cks));
619 xCS.Attr.Cks.fmTime =
static_cast<long long>(MTime);
620 xCS.Attr.Cks.csTime =
static_cast<int>(time(0) - MTime);
642 csInfo *csIP = &csTab[0];
647 if (csLast < 0 || (*Cks.
Name && !(csIP = Find(Cks.
Name))))
return -ENOTSUP;
648 xCS.Attr.Cks.Set(csIP->Name);
652 if ((rc =
ModTime(Pfn, MTime)))
return rc;
656 if ((rc =
xCS.Get(Pfn)) < 0)
return rc;
660 if (!rc ||
xCS.Attr.Cks.fmTime != MTime
661 || strcmp(
xCS.Attr.Cks.Name, csIP->Name)
662 ||
xCS.Attr.Cks.Length != csIP->Len)
663 {strcpy(
xCS.Attr.Cks.Name, Cks.
Name);
664 if ((rc =
Calc(Pfn,
xCS.Attr.Cks, 1)) < 0)
return rc;
669 return (
xCS.Attr.Cks.Length == Cks.
Length
670 && !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.