34 #include "XrdVersion.hh"
40 #define DEBUG(usr,x) if (Debug) SYSTRACE(SysTrace.,usr,EPName,0,x)
42 #define EPNAME(x) const char *EPName=x
114 const char *
Info(
char *bP,
int bL)
139 void DoIt()
override;
156 void makeArgs(
PrepRequest &req,
const char *argVec[]);
174 static const int bReserve = 40;
175 char *lp, *bPNow = bP, *bPEnd = bP+bL-bReserve;
177 bool isTrunc =
false;
183 eLog->
Emsg(
"PrepGRun",
"Prep exec for",req.
Info(ib,
sizeof(ib)),
184 "failed; invalid buffer size.");
191 {len = strlen(lp) + 1;
192 if (bPNow + len >= bPEnd) {isTrunc =
true;
break;}
210 if (bPNow == bP) len = snprintf(bP, bL,
"No information available.") + 1;
211 else {
if (isTrunc) bPNow += snprintf(bPNow, bReserve,
212 "***response has been truncated***");
214 len = bPNow - bP + 1;
256 void PrepGRun::makeArgs(
PrepRequest &req,
const char *argVec[])
266 for (
int i = 0; i < (int)req.
argMem.size(); i++)
267 argVec[j++] = req.
argMem[i].c_str();
287 const char **argVec = (
const char **)alloca((n+2) *
sizeof(
char*));
291 makeArgs(req, argVec);
299 rc = prepProg.
Run(&cmd, argVec, n, req.
envVec);
307 else bytes = Capture(req, cmd, bP, bL);
315 eLog->
Emsg(
"PrepGRun",
"Prep exec for",req.
Info(ib,
sizeof(ib)),
"failed.");
320 if (bP)
return bytes;
321 return (rc ? -1 : 0);
352 const char *ApplyN2N(
const char *tid,
const char *path,
char *buff,
int blen);
353 PrepRequest *Assemble(
int &rc,
const char *tid,
const char *reqName,
356 bool del=
false,
bool locked=
false);
371 const char *PrepGPI::ApplyN2N(
const char *tid,
const char *path,
char *buff,
378 const char *pfn =
ossP->
Lfn2Pfn(path, buff, blen, rc);
384 snprintf(buff,
sizeof(buff),
"handle %s path", tid);
385 eLog->
Emsg(
"PrepGPI", rc, buff, path);
401 PrepRequest *PrepGPI::Assemble(
int &rc,
const char *tid,
const char *reqName,
412 while(pP) {n++; pP = pP->
next;}
416 if (n >
maxFiles) {rc = E2BIG;
return 0;}
425 snprintf(buff,
sizeof(buff),
"XRDPREP_TID=%s", tid);
426 rP->
envMem.emplace_back(buff);
441 snprintf(buff,
sizeof(buff),
"XRDPREP_COLOC=%s",
443 rP->
envMem.emplace_back(buff);
447 snprintf(buff,
sizeof(buff),
"XRDPREP_NOTIFY=%s",
449 rP->
envMem.emplace_back(buff);
471 for (n = 0; n < (int)rP->
envMem.size(); n++)
492 if ((pP = pargs.
paths))
497 do {path = (
usePFN ? ApplyN2N(tid,pP->
text,buff,
sizeof(buff)):pP->text);
500 {snprintf(pBuff,
sizeof(pBuff),
"%s?%s", path, cP->
text);
503 rP->
argMem.emplace_back(path);
508 do {path = (
usePFN ? ApplyN2N(tid,pP->
text,buff,
sizeof(buff)):pP->text);
510 rP->
argMem.emplace_back(path);
532 const char *reqName, *reqOpts, *tid = (client ? client->
tident :
"anon");
548 else {reqName =
"prep";
555 if (ignore)
return RetErr(eInfo, ENOTSUP,
"process", reqName);
559 PrepRequest *rP = Assemble(rc, tid, reqName, pargs, reqOpts);
563 if (!rP || rP->
argMem.size() == 0)
564 return RetErr(eInfo, (rc ? rc : EINVAL), reqName,
"files");
582 const char *tid = (client ? client->
tident :
"anon");
592 if (reqFind(pargs.
reqid, rPP, rP,
true))
593 {bL = snprintf(bP, bL,
"Request %s cancelled.", pargs.
reqid);
595 bL = snprintf(bP, bL,
"Request %s not cancellable.", pargs.
reqid);
603 PrepRequest *rP = Assemble(rc, tid,
"cancel", pargs,
"n");
607 if (!rP)
return RetErr(eInfo, (rc ? rc : EINVAL),
"cancel",
"files");
627 OucBuffer() : pBuff(0) {}
628 ~OucBuffer() {
if (pBuff) pBuff->
Recycle();}
630 const char *tid = (client ? client->
tident :
"anon");
639 if (reqFind(pargs.
reqid, rPP, rP))
640 {bL = snprintf(bP, bL,
"Request %s queued.", pargs.
reqid)+1;
642 bL = snprintf(bP, bL,
"Request %s not queued.", pargs.
reqid)+1;
653 {bP = OucBuff.pBuff->
Buffer();
660 PrepRequest *rP = Assemble(rc, tid,
"query", pargs,
"");
664 if (!rP)
return RetErr(eInfo, (rc ? rc : EINVAL),
"query",
"request");
672 DEBUG(tid,
"Waiting to launch query "<<rP->
reqID);
677 return RetErr(eInfo, ETIMEDOUT,
"query",
"request");
685 rc = qryRunner.
Run(*rP, bP, bL);
696 if (rc <= 0)
return RetErr(eInfo, ECANCELED,
"query",
"request");
701 else {OucBuff.pBuff->SetLen(rc);
716 bool del,
bool locked)
720 if (!strcmp(
"*", reqid))
return false;
730 while(rP && strcmp(reqid, rP->
reqID)) {rPP = rP; rP = rP->
next;}
754 int PrepGPI::RetErr(
XrdOucErrInfo &eInfo,
int rc,
const char *txt1,
762 snprintf(bP, bL,
"Unable to %s %s; %s", txt1, txt2,
XrdSysE2T(rc));
778 const char *tid = rP->
tID, *reqName = rP->
reqName;
783 if (
Debug) snprintf(reqID,
sizeof(reqID),
"%s", rP->
reqID);
801 DEBUG(tid, reqName<<
" request "<<reqID<<(grP ?
" scheduled" :
" queued"));
842 if (!(tokP = gpiConf.
GetLine()) || !*tokP)
843 {
eLog->
Emsg(
"PrepGPI",
"Parameters not specified.");
851 if (Token ==
"-admit")
852 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
853 {
eLog->
Emsg(
"PrepGPI",
"-admit argument not specified.");
859 while((argPos = Args.
tokenize(Token, argPos,
',')) != -1)
866 else {
eLog->
Emsg(
"PrepGPI",
"Invalid -admit request -",
873 {
eLog->
Emsg(
"PrepGPI",
"invalid -admit request list");
877 else if (Token ==
"-cgi")
addCGI=
true;
878 else if (Token ==
"-debug")
Debug =
true;
879 else if (Token ==
"-maxfiles")
880 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
881 {
eLog->
Emsg(
"PrepGPI",
"-maxfiles argument not specified.");
887 else if (Token ==
"-maxquery")
888 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
889 {
eLog->
Emsg(
"PrepGPI",
"-maxquery argument not specified.");
895 else if (Token ==
"-maxreq")
896 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
897 {
eLog->
Emsg(
"PrepGPI",
"-maxreq argument not specified.");
901 &maxReq, 1, 64))
return 0;
903 else if (Token ==
"-maxresp")
904 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
905 {
eLog->
Emsg(
"PrepGPI",
"-maxresp argument not specified.");
910 &rspsz, 2048, 16777216))
return 0;
911 maxResp =
static_cast<int>(rspsz);
913 else if (Token ==
"-pfn")
usePFN =
true;
914 else if (Token ==
"-run")
915 {
if (!(tokP = gpiConf.
GetToken()) || *tokP ==
'-')
916 {
eLog->
Emsg(
"PrepGPI",
"-run argument not specified.");
921 else {
eLog->
Emsg(
"PrepGPI",
"Invalid option -", Token.
c_str());
929 {
eLog->
Emsg(
"PrepGPI",
"'-admit' was not specified.");
936 {
eLog->
Emsg(
"PrepGPI",
"prepare program not specified.");
957 eLog->
Emsg(
"PrepGPI",
"Unable to use prepare program", RunPgm.
c_str());
966 gRun->
next = PrepGRun::Q;
static XrdSysError eDest(0,"crypto_")
XrdOfsPrepare * XrdOfsgetPrepare(XrdOfsgetPrepareArguments)
XrdVERSIONINFO(XrdOfsgetPrepare, PrepGPI)
#define XrdOfsgetPrepareArguments
char * notify
Notification path or 0.
XrdOucTList * paths
List of paths.
XrdOucTList * oinfo
1-to-1 correspondence of opaque info
const char * XrdSysE2T(int errcode)
int query(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0) override
int begin(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0) override
int cancel(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0) override
PrepGRun(XrdOucProg &pgm)
int Run(PrepRequest &req, char *bP=0, int bL=0)
void Sched(PrepRequest *rP)
virtual int Lfn2Pfn(const char *Path, char *buff, int blen)
XrdOucBuffer * Alloc(int sz)
void Recycle()
Recycle the buffer. The buffer may be reused in the future.
void * GetPtr(const char *varname)
int setErrInfo(int code, const char *emsg)
char * getMsgBuff(int &mblen)
char * GetToken(char **rest=0, int lowcase=0)
int Gather(const char *cfname, Level lvl, const char *parms=0)
bool useData(const char *data)
@ only_body
Only directive bodies as a string blob.
int RunDone(XrdOucStream &cmd) const
int Run(XrdOucStream *Sp, const char *argV[], int argc=0, const char *envV[]=0) const
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
const char * c_str() const
int tokenize(XrdOucString &tok, int from, char del=':')
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
void Schedule(XrdJob *jp)
const char * tident
Trace identifier always preset.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
void SetLogger(XrdSysLogger *logp)
static const int qryMaxWT
XrdSysTrace SysTrace("PrepGPI")
static const int okCancel
XrdSysCondVar qryCond(0, "prepG query")
std::vector< std::string > argMem
static PrepRequest * First
const char * Info(char *bP, int bL)
const char * envVec[envSZ]
static PrepRequest * Last
std::vector< std::string > envMem
const char * argVec[argSZ]
static const size_t Max_Error_Len