45 #define SizeOfVec(x) sizeof(x)/sizeof(x[0])
51 unsigned int GenTmpPath()
55 snprintf(tmpPath,
sizeof(tmpPath),
"/tmp/.MetaLink%8x.%d.",
56 static_cast<int>(time(0)),
static_cast<int>(getpid()));
62 unsigned int seqNo = GenTmpPath();
78 CleanUp() : delRDR(0), delTFN(0) {}
79 ~CleanUp() {
if (delRDR) {
delete *delRDR; *delRDR = 0;}
80 if (delTFN)
unlink(delTFN);
88 vecMon(
char **vec,
int vecn)
89 : theVec(vec), vecNum(vecn) {}
90 ~vecMon() {
if (theVec)
91 for (
int i = 0; i < vecNum; i++)
92 if (theVec[i]) free(theVec[i]);
106 static const char *mlV3NS =
"http://www.metalinker.org/";
107 static const char *mlV4NS =
"urn:ietf:params:xml:ns:metalink";
108 static const char *mlV3[] = {
"metalink",
"files", 0};
109 static const char *mTag[] = {
"",
"metalink", 0};
110 static const char *mAtr[] = {
"xmlns", 0};
111 const char *scope =
"metalink";
116 char *colon, gHdr[272];
122 {
if (!PutFile(fname, blen))
return 0;
123 onReturn.delTFN = tmpFn;
129 if (rdHost && (rdProt || (prots && (colon = index(prots,
':')))))
130 {
if (!rdProt) {rdProt = prots; *(colon+1) = 0;}
132 snprintf(gHdr,
sizeof(gHdr),
"%s//%s/", rdProt, rdHost);
133 if (colon) *(colon+1) =
':';
141 snprintf(eText,
sizeof(eText),
"%s trying to read %s",
142 (errno ?
XrdSysE2T(errno) :
"Unknown error"), fname);
148 onReturn.delRDR = &reader;
153 {GetRdrError(
"looking for 'metalink' tag");
161 {strcpy(eText,
"Required metalink tag attribute 'xmlns' not found");
169 if (!strcmp(mVal[0], mlV3NS))
171 GetRdrError(
"looking for 'files' tag");
174 else if ( strcmp((
const char *)mVal[0], mlV4NS))
175 {strcpy(eText,
"Metalink format not supported");
176 eCode = EPFNOSUPPORT;
186 currFile = 0; fileCnt = 0; noUrl =
true;
187 do{
if (!GetFile(scope))
break;
189 if (GetFileInfo(
"file"))
190 {
if (lastFile) lastFile ->
nextFile = currFile;
191 else fileList = currFile;
193 if (chkG && (gLFN = currFile->
GetLfn()))
195 snprintf(lfnBuff,
sizeof(lfnBuff),
"%s%s", gHdr, gLFN);
196 currFile->
AddUrl(lfnBuff, 0, INT_MAX);
200 fileCnt++; noUrl =
true;
206 if (currFile) {
delete currFile; currFile = 0;}
211 {strcpy(eText,
"No applicable urls specified for the file entry");
212 eCode = EDESTADDRREQ;
217 fP = fileList; lastFile = fileList = 0;
218 if (doAll)
return fP;
222 if (!eCode)
return fP;
245 {
if (!PutFile(fname, blen))
return 0;
246 onReturn.delTFN = tmpFn;
252 if (!(fP =
Convert(fname)))
return 0;
268 for (
int i = 0; i < fileCnt; i++) {fvP[i] = fP; fP = fP->
nextFile;}
281 for (
int i = 0; i < vecn; i++)
293 bool XrdXmlMetaLink::GetFile(
const char *scope)
295 const char *fileElem[] = {scope,
"file", 0};
297 bool needFile = fileCnt == 0;
302 {
if ((etext = reader->
GetError(eCode)))
303 {
size_t len = strlen(etext);
304 if(len >
sizeof(eText)-1) len=
sizeof(eText)-1;
305 memcpy(eText, etext, len);
320 bool XrdXmlMetaLink::GetFileInfo(
const char *scope)
322 static const char *fileScope =
"file";
323 const char *fsubElem[] = {scope,
"url",
"hash",
"size",
324 "verification",
"resources",
"glfn", 0};
327 if(strncmp(scope, fileScope, 4) == 0) GetName();
334 {
case 1:
if (!GetUrl())
return false;
336 case 2:
if (!GetHash())
return false;
338 case 3:
if (!GetSize())
return false;
340 case 4: GetFileInfo(
"verification");
341 if (eCode)
return false;
343 case 5: GetFileInfo(
"resources");
344 if (eCode)
return false;
346 case 6:
if (!GetGLfn())
return false;
360 bool XrdXmlMetaLink::GetGLfn()
362 static const char *gAttr[] = {
"name", 0};
369 {strcpy(eText,
"Required glfn tag name attribute not found");
376 currFile->
AddLfn(gAVal[0]);
387 bool XrdXmlMetaLink::GetHash()
389 static const char *hAttr[] = {
"type", 0};
397 {strcpy(eText,
"Required hash tag type attribute not found");
404 if (!(value = reader->
GetText(
"hash",
true)))
return false;
420 void XrdXmlMetaLink::GetRdrError(
const char *why)
422 const char *etext = reader->
GetError(eCode);
425 {
size_t len = strlen(etext);
426 if(len >
sizeof(eText)-1) len =
sizeof(eText)-1;
427 memcpy(eText, etext, len);
430 else {snprintf(eText,
sizeof(eText),
"End of xml while %s", why);
439 bool XrdXmlMetaLink::GetSize()
446 if (!(value = reader->
GetText(
"size",
true)))
return false;
450 fsz = strtoll(value, &eP, 10);
451 if (fsz < 0 || *eP != 0)
452 {snprintf(eText,
sizeof(eText),
"Size tag value '%s' is invalid", value);
469 bool XrdXmlMetaLink::GetUrl()
471 static const char *uAttr[] = {
"location",
"priority",
"preference", 0};
472 char *uAVal[] = {0, 0, 0};
483 if (!(value = reader->
GetText(
"url")))
return true;
494 if (uAVal[1]) prty = atoi(uAVal[1]);
496 {prty = 100 - atoi(uAVal[2]);
497 if (prty < 0) prty = 0;
502 currFile->
AddUrl(value, uAVal[0], prty);
515 void XrdXmlMetaLink::GetName()
517 static const char *mAtr[] = {
"name", 0};
528 bool XrdXmlMetaLink::PutFile(
const char *buff,
int blen)
530 static const int oFlags = O_EXCL | O_CREAT | O_TRUNC | O_WRONLY;
531 const char *what =
"opening";
545 snprintf(tmpFn,
sizeof(tmpFn),
"%s%u", tmpPath, fSeq);
549 if ((fd = XrdSysFD_Open(tmpFn, oFlags, S_IRUSR|S_IWUSR)) > 0)
551 if (
write(fd, buff, blen) == blen)
553 if (!
close(fd))
return true;
560 snprintf(eText,
sizeof(eText),
"%s %s %s",
XrdSysE2T(eCode), what, tmpFn);
569 bool XrdXmlMetaLink::UrlOK(
char *url)
571 char *colon, pBuff[16];
576 if (!(colon = index(url,
':')))
return false;
578 if (n >= (
int)
sizeof(pBuff))
return false;
579 strncpy(pBuff, url, n);
588 if (prots)
return (strstr(prots, pBuff) != 0);
int unlink(const char *path)
ssize_t write(int fildes, const void *buf, size_t nbyte)
const char * XrdSysE2T(int errcode)
XrdOucFileInfo * nextFile
Link field to simply miltiple file processing.
void AddFileName(const char *filename)
void AddProtocol(const char *protname)
void AddLfn(const char *lfn)
void AddUrl(const char *url, const char *cntry=0, int prty=0, bool fifo=true)
void AddDigest(const char *hname, const char *hval)
void SetSize(long long fsz)
virtual char * GetText(const char *ename, bool reqd=false)=0
static XrdXmlReader * GetReader(const char *fname, const char *enc=0, const char *impl=0)
virtual int GetElement(const char **ename, bool reqd=false)=0
virtual const char * GetError(int &ecode)=0
virtual bool GetAttributes(const char **aname, char **aval)=0