74 #include "XrdVersion.hh"
77 #define ENODATA ENOATTR
81 #define ETIME ETIMEDOUT
111 const char *getTime()
113 static char buff[16];
118 if (gettimeofday(&tv, 0))
119 {perror(
"gettimeofday");
122 tmp = localtime(&tv.tv_sec);
124 {perror(
"localtime");
128 if (strftime(buff,
sizeof(buff),
"%y%m%d:%H%M%S. ", tmp) <= 0)
134 snprintf(tuff,
sizeof(tuff),
"%d",
static_cast<int>(tv.tv_usec/100000));
155 static const char *startUP = getTime();
162 int XrdXrootdProtocol::do_Auth()
191 {eText =
eMsg.getErrText(rc);
192 eDest.
Emsg(
"Xeq",
"User authentication failed;", eText);
209 if (!logLogin(
true))
return -1;
216 {
TRACEP(LOGIN,
"more auth requested; sz=" <<(parm ? parm->
size : 0));
221 eDest.
Emsg(
"Xeq",
"Security requested additional auth w/o parms!");
236 eText =
eMsg.getErrText(rc);
237 eDest.
Emsg(
"Xeq",
"User authentication failed;", eText);
245 int XrdXrootdProtocol::do_Bind()
251 char buff[64], *cp, *dp;
298 if (strcmp(
Link->
Host(), lp->Host()))
310 for (i = 1; i <
maxStreams && pp->Stream[i]; i++) {}
318 pp->Stream[i] =
this;
325 if ( (dp = rindex(cp,
'@'))) *dp =
'\0';
326 if (!(dp = rindex(cp,
'.'))) pPid = 0;
327 else {*dp++ =
'\0'; pPid = strtol(dp, (
char **)NULL, 10);}
341 *(pp->pmHandle),
Link->
ID);
347 sprintf(buff,
"FD %d#%d bound",
Link->
FDnum(), i);
356 buff[0] =
static_cast<char>(i);
375 int XrdXrootdProtocol::do_Chmod()
406 int XrdXrootdProtocol::do_CKsum(
int canit)
409 char *algT =
JobCKT, *args[6];
423 if (rpCheck(
argp->
buff, &opaque))
return rpEmsg(
"Check summing",
argp->
buff);
437 algT = getCksType(opaque, cksT,
sizeof(cksT));
440 snprintf(ebuf,
sizeof(ebuf),
"%s checksum not supported.", cksT);
447 if (
JobLCL && (rc = do_CKsum(algT,
argp->
buff, opaque)) <= 0)
return rc;
464 if (
Client->
eaAPI->
Get(std::string(
"request.name"), keyval) && !keyval.empty())
465 args[4] =
const_cast<char *
>(keyval.c_str());
483 int XrdXrootdProtocol::do_CKsum(
char *algT,
const char *
Path,
char *Opaque)
485 static char Space =
' ';
487 int CKTLen = strlen(algT);
489 myError,
CRED, Opaque);
490 const char *csData = myError.getErrText(
ec);
494 if (rc)
return fsError(rc, 0, myError,
Path, Opaque);
500 struct iovec
iov[4] = {{0,0}, {algT, (size_t)CKTLen}, {&Space, 1},
501 {(
char *)csData, strlen(csData)+1}};
508 {
const char *eTxt[2] = {
JobCKT,
" checksum not available."};
509 myError.setErrInfo(0, eTxt, 2);
522 int XrdXrootdProtocol::do_Close()
538 "close does not refer to an open file");
548 if (fp->
pgwFob && !do_PgClose(fp, rc))
573 rc = fp->XrdSfsp->close();
574 TRACEP(FS,
" fh=" <<fh.handle <<
" close rc=" <<rc);
578 return fsError(rc, 0, fp->XrdSfsp->error, 0, 0);
587 if (
SFS_OK != rc) retval = fsError(rc, 0, fp->XrdSfsp->error, 0, 0);
594 if (!doDel) fp->Ref(-1);
606 int XrdXrootdProtocol::do_Dirlist()
608 int bleft, rc = 0, dlen, cnt = 0;
609 char *opaque, *buff, ebuff[4096];
635 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s",
argp->
buff);
652 return do_DirStat(dp, ebuff, opaque);
662 do {buff = ebuff; bleft =
sizeof(ebuff);
663 while(dname || (dname = dp->
nextEntry()))
664 {dlen = strlen(dname);
665 if (dlen > 2 || dname[0] !=
'.' || (dlen == 2 && dname[1] !=
'.'))
666 {
if ((bleft -= (dlen+1)) < 0)
break;
667 strcpy(buff, dname); buff += dlen; *buff =
'\n'; buff++; cnt++;
672 }
while(!rc && dname);
678 else {*(buff-1) =
'\0';
687 if (!rc) {
TRACEP(FS,
"dirlist entries=" <<cnt <<
" path=" <<
argp->
buff);}
700 char *buff, *dLoc, *algT = 0;
701 const char *csData, *dname;
702 int bleft, rc = 0, dlen, cnt = 0, statSz = 160;
704 struct {
char ebuff[8192];
char epad[512];} XB;
711 algT = getCksType(opaque, cksT,
sizeof(cksT));
714 snprintf(ebuf,
sizeof(ebuf),
"%s checksum not supported.", cksT);
729 dlen = strlen(pbuff);
730 if (pbuff[dlen-1] !=
'/') {pbuff[dlen] =
'/'; dlen++;}
739 strcpy(XB.ebuff,
".\n0 0 0 0\n");
740 buff = XB.ebuff+10; bleft =
sizeof(XB.ebuff)-10;
750 do {
while(dname || (dname = dp->
nextEntry()))
751 {dlen = strlen(dname);
752 if (dlen > 2 || dname[0] !=
'.' || (dlen == 2 && dname[1] !=
'.'))
753 {
if ((bleft -= (dlen+1)) < 0 || bleft < statSz)
break;
754 if (dLoc) strcpy(dLoc, dname);
757 if (rc ==
SFS_ERROR && myError.getErrInfo() == ENOENT)
758 {dname = 0;
continue;}
763 strcpy(buff, dname); buff += dlen; *buff =
'\n'; buff++; cnt++;
764 dlen = StatGen(
Stat, buff,
sizeof(XB.epad));
765 bleft -= dlen; buff += (dlen-1);
768 pbuff, myError,
CRED, opaque);
769 csData = myError.getErrText();
770 if (
ec !=
SFS_OK || !(*csData) || *csData ==
'!')
772 int n = snprintf(buff,
sizeof(XB.epad),
" [ %s:%s ]",
774 buff += n; bleft -= n;
776 *buff =
'\n'; buff++;
782 buff = XB.ebuff; bleft =
sizeof(XB.ebuff);
785 }
while(!rc && dname);
791 else {*(buff-1) =
'\0';
800 if (!rc) {
TRACEP(FS,
"dirstat entries=" <<cnt <<
" path=" <<
argp->
buff);}
808 int XrdXrootdProtocol::do_Endsess()
820 memcpy((
void *)&sessID.
Pid, &sp->
Pid,
sizeof(sessID.
Pid));
821 memcpy((
void *)&sessID.
FD, &sp->
FD,
sizeof(sessID.
FD));
822 memcpy((
void *)&sessID.
Inst, &sp->
Inst,
sizeof(sessID.
Inst));
826 TRACEP(LOGIN,
"endsess " <<sessID.
Pid <<
':' <<sessID.
FD <<
'.' <<sessID.
Inst);
834 if ((sessID.
FD == 0 && sessID.
Inst == 0)
839 TRACEP(LOGIN,
"endsess " <<sessID.
Pid <<
':' <<sessID.
FD <<
'.' <<sessID.
Inst
840 <<
" rc=" <<rc <<
" (" <<
XrdSysE2T(rc < 0 ? -rc : EAGAIN) <<
")");
863 int XrdXrootdProtocol::do_gpFile()
884 int XrdXrootdProtocol::do_Locate()
888 char *opaque = 0, *
Path, *fn =
argp->
buff, opt[8], *op=opt;
905 TRACEP(FS,
"locate " <<opt <<
' ' <<fn);
909 if (*fn !=
'*'){
Path = fn;
912 else if (*(fn+1)) {
Path = fn+1;
927 {
if (rpCheck(
Path, &opaque))
return rpEmsg(
"Locating",
Path);
928 if (!doDig && !Squash(
Path))
return vpEmsg(
"Locating",
Path);
937 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
941 TRACEP(FS,
"rc=" <<rc <<
" locate " <<fn);
949 int XrdXrootdProtocol::do_Login()
953 int i, pid, rc, sendSID = 0;
963 {
const char *
emsg =
"login requires TLS be enabled";
965 {
emsg =
"login requires TLS support";
975 uname[
sizeof(uname)-1] = 0;
981 "duplicate login; already logged in");
1048 if (pp && i ) {
if (!sendSID) rc =
Response.
Send((
void *)pp, i);
1049 else {
struct iovec
iov[3];
1050 iov[1].iov_base = (
char *)&sessID;
1051 iov[1].iov_len =
sizeof(sessID);
1052 iov[2].iov_base = (
char *)pp;
1058 else {rc = (sendSID ?
Response.
Send((
void *)&sessID,
sizeof(sessID))
1063 else {rc = (sendSID ?
Response.
Send((
void *)&sessID,
sizeof(sessID))
1081 char *rnumb = loginEnv.Get(
"xrd.rn");
1082 char *cCode = loginEnv.Get(
"xrd.cc");
1083 char *tzVal = loginEnv.Get(
"xrd.tz");
1084 char *appXQ = loginEnv.Get(
"xrd.appname");
1085 char *aInfo = loginEnv.Get(
"xrd.info");
1086 int tzNum = (tzVal ? atoi(tzVal) : 0);
1087 if (cCode && *cCode && tzNum >= -12 && tzNum <= 14)
1095 snprintf(apBuff,
sizeof(apBuff),
"&R=%s&x=%s&y=%s&I=%c",
1096 (rnumb ? rnumb :
""),
1097 (appXQ ? appXQ :
""), (aInfo ? aInfo :
""),
1103 {
int majr, minr, pchr;
1104 if (sscanf(rnumb,
"v%d.%d.%d", &majr, &minr, &pchr) == 3)
1105 clientRN = (majr<<16) | ((minr<<8) | pchr);
1106 else if (sscanf(rnumb,
"v%d-%*x", &majr) == 1)
clientRN = -1;
1108 if (appXQ)
AppName = strdup(appXQ);
1136 int XrdXrootdProtocol::do_Mkdir()
1169 int XrdXrootdProtocol::do_Mv()
1172 char *oldp, *newp, *Opaque, *Npaque;
1189 while(*newp && *newp !=
' ') newp++;
1190 if (*newp) {*newp =
'\0'; newp++;
1191 while(*newp && *newp ==
' ') newp++;
1197 if (rpCheck(oldp, &Opaque))
return rpEmsg(
"Renaming", oldp);
1198 if (rpCheck(newp, &Npaque))
return rpEmsg(
"Renaming to", newp);
1199 if (!Squash(oldp))
return vpEmsg(
"Renaming", oldp);
1200 if (!Squash(newp))
return vpEmsg(
"Renaming to", newp);
1210 TRACEP(FS,
"rc=" <<rc <<
" mv " <<oldp <<
' ' <<newp);
1222 int XrdXrootdProtocol::do_Offload(
int (
XrdXrootdProtocol::*Invoke)(),
int pathID)
1245 pp->
Resume = &XrdXrootdProtocol::do_OffloadIO;
1249 pp->
reTry = &isAvail;
1259 if ((pioP = pp->
pioFree))
break;
1260 pp->
reTry = &isAvail;
1262 TRACEP(FSZIO,
"busy path " <<pathID <<
" offs=" <<
IO.Offset);
1264 TRACEP(FSZIO,
"retry path " <<pathID <<
" offs=" <<
IO.Offset);
1275 pioP->
Set(Invoke,
IO, streamID);
1288 int XrdXrootdProtocol::do_OffloadIO()
1301 TRACEP(FSZIO,
"dispatch new I/O path " <<
PathID <<
" offs=" <<
IO.Offset);
1311 if (rc > 0 && !
isNOP)
1313 Resume = &XrdXrootdProtocol::do_OffloadIO;
1333 if (rc)
isNOP =
true;
1339 TRACEP(FSZIO,
"offload complete path "<<
PathID<<
" virt rc=" <<rc);
1340 return (rc ? rc : -EINPROGRESS);
1358 : fp(0), xp(0), Locker(lkP), path(fn), mode(0),
1364 else {
if (fp)
delete fp;
1365 if (mode) Locker->
Unlock(path,mode);
1372 int XrdXrootdProtocol::do_Open()
1376 int rc, mode,
opts, openopts, compchk = 0;
1377 int popt, retStat = 0;
1378 char *opaque,
usage, ebuff[2048], opC;
1379 bool doDig, doforce =
false, isAsync =
false;
1380 char *fn =
argp->
buff, opt[16], *op=opt;
1383 struct stat statbuf;
1385 int resplen =
sizeof(myResp.fhandle);
1386 struct iovec IOResp[3];
1399 mode = mapMode(mode) | S_IRUSR | S_IWUSR;
usage =
'r';
1435 {openopts |=
SFS_O_RAWIO; *op++ =
'c'; compchk = 1;}
1438 {*op++ =
'a'; isAsync =
true;}
1450 {
char* cgiP = index(fn,
'?');
1451 if (cgiP) *cgiP = 0;
1452 TRACEP(FS,
"open " <<opt <<
' ' <<fn);
1453 if (cgiP) *cgiP =
'?';
1458 if (rpCheck(fn, &opaque))
return rpEmsg(
"Opening", fn);
1468 if (!(popt = Squash(fn)))
return vpEmsg(
"Opening", fn);
1480 OpenHelper oHelp(
Locker, fn);
1487 if (rc > 0) who = (rc > 1 ?
"readers" :
"reader");
1489 who = (rc > 1 ?
"writers" :
"writer");
1491 snprintf(ebuff,
sizeof(ebuff)-1,
1492 "%s file %s is already opened by %d %s; open denied.",
1493 (
'r' ==
usage ?
"Input" :
"Output"), fn, rc, who);
1496 }
else oHelp.mode =
usage;
1507 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s",fn);
1526 (mode_t)mode,
CRED, opaque)))
1527 {rc = fsError(rc, opC, fp->
error, fn, opaque);
return rc;}
1533 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s", fn);
1551 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s", fn);
1565 if ((
'r' ==
usage && wrtrs) || (
'w' ==
usage && rdrs) || wrtrs > 1)
1566 {snprintf(ebuff,
sizeof(ebuff)-1,
1567 "%s file %s forced opened with %d reader(s) and %d writer(s).",
1568 (
'r' ==
usage ?
"Input" :
"Output"), fn, rdrs, wrtrs);
1575 memset(&myResp, 0,
sizeof(myResp));
1576 if (!compchk) resplen =
sizeof(myResp.fhandle);
1578 fp->
getCXinfo((
char *)myResp.cptype, cpsize);
1579 myResp.cpsize =
static_cast<kXR_int32>(htonl(cpsize));
1580 resplen =
sizeof(myResp);
1586 {retStat = StatGen(statbuf, ebuff,
sizeof(ebuff));
1587 IOResp[1].iov_base = (
char *)&myResp; IOResp[1].iov_len =
sizeof(myResp);
1588 IOResp[2].iov_base = ebuff; IOResp[2].iov_len = retStat;
1589 resplen =
sizeof(myResp) + retStat;
1608 memcpy((
void *)myResp.fhandle,(
const void *)&fhandle,
sizeof(myResp.fhandle));
1648 int XrdXrootdProtocol::do_Ping()
1664 int XrdXrootdProtocol::do_Prepare(
bool isQuery)
1677 int rc, pathnum = 0;
1678 char reqid[128], nidbuff[512], *path, *opaque, *prpid = 0;
1681 bool isCancel, isEvict, isPrepare;
1701 isPrepare = !(isCancel || isQuery);
1708 "Surpassed this connection's prepare limit.");
1726 if (isCancel || isQuery)
1727 {
if (!(prpid = pathlist.GetLine()))
1729 fsprep.
reqid = prpid;
1734 prpid =
PrepID->
isMine(prpid, hport, hname,
sizeof(hname));
1737 "Prepare requestid owned by an unknown server");
1739 << hname <<
':' <<hport);
1745 {prpid =
PrepID->
ID(reqid,
sizeof(reqid));
1746 fsprep.
reqid = reqid;
1749 reqid[0]=
'*'; reqid[1]=
'\0';
1750 fsprep.
reqid = prpid = reqid;
1763 while((path = pathlist.GetLine()))
1764 {
if (rpCheck(path, &opaque))
return rpEmsg(
"Preparing", path);
1765 if (!Squash(path))
return vpEmsg(
"Preparing", path);
1767 (pLast ? (pLast->next = pP) : (pFirst = pP)); pLast = pP;
1769 (oLast ? (oLast->next = oP) : (oFirst = oP)); oLast = oP;
1772 fsprep.
paths = pFirst;
1773 fsprep.
oinfo = oFirst;
1797 char *mBuff = myError.getMsgBuff(rc);
1798 pargs.reqid = prpid;
1800 pargs.paths = pFirst;
1802 if (rc < 0) rc =
Response.
Send(
"No information found.");
1830 else snprintf(nidbuff,
sizeof(nidbuff),
"%s://%s:%d/",
1864 {pargs.reqid = prpid;
1866 pargs.paths = pFirst;
1883 int XrdXrootdProtocol::do_Protocol()
1894 bool wantTLS =
false;
1919 ioVec[iovN ].iov_base = (
void *)&theResp.
secreq;
1920 ioVec[iovN++].iov_len = n;
1946 theResp.
flags = (wantTLS ? theRlt : theRle);
1948 theResp.
flags = theRlf;
1954 theResp.
pval = verNum;
1962 if (rc == 0 && wantTLS)
1978 int XrdXrootdProtocol::do_Qconf()
1982 char *val, buff[4096], *bp=buff;
1983 int n, bleft =
sizeof(buff);
1987 if (!qcargs.GetLine() || !(val = qcargs.GetToken()))
1992 if (!strcmp(val,
"cmsd") || !strcmp(val,
"xrootd"))
1993 return do_QconfCX(qcargs, val);
2001 if (!strcmp(
"bind_max", val))
2002 {n = snprintf(bp, bleft,
"%d\n",
maxStreams-1);
2003 bp += n; bleft -= n;
2005 else if (!strcmp(
"chksum", val))
2006 {
const char *csList = getenv(
"XRD_CSLIST");
2008 {n = snprintf(bp, bleft,
"chksum\n");
2009 bp += n; bleft -= n;
2012 n = snprintf(bp, bleft,
"%s\n", csList);
2013 bp += n; bleft -= n;
2015 else if (!strcmp(
"cid", val))
2016 {
const char *cidval = getenv(
"XRDCMSCLUSTERID");
2017 if (!cidval || !(*cidval)) cidval =
"cid";
2018 n = snprintf(bp, bleft,
"%s\n", cidval);
2019 bp += n; bleft -= n;
2021 else if (!strcmp(
"cms", val))
2024 n = snprintf(bp, bleft,
"%s\n", myError.getErrText());
2025 else n = snprintf(bp, bleft,
"%s\n",
"cms");
2026 bp += n; bleft -= n;
2028 else if (!strcmp(
"pio_max", val))
2029 {n = snprintf(bp, bleft,
"%d\n",
maxPio+1);
2030 bp += n; bleft -= n;
2032 else if (!strcmp(
"proxy", val))
2033 {
const char* pxyOrigin =
"proxy";
2035 {pxyOrigin = getenv(
"XRDXROOTD_PROXY");
2036 if (!pxyOrigin) pxyOrigin =
"proxy";
2038 n = snprintf(bp,bleft,
"%s\n",pxyOrigin);
2039 bp += n; bleft -= n;
2041 else if (!strcmp(
"readv_ior_max", val))
2043 bp += n; bleft -= n;
2045 else if (!strcmp(
"readv_iov_max", val))
2047 bp += n; bleft -= n;
2049 else if (!strcmp(
"role", val))
2050 {
const char *theRole = getenv(
"XRDROLE");
2051 n = snprintf(bp, bleft,
"%s\n", (theRole ? theRole :
"none"));
2052 bp += n; bleft -= n;
2054 else if (!strcmp(
"sitename", val))
2055 {
const char *siteName = getenv(
"XRDSITE");
2056 n = snprintf(bp, bleft,
"%s\n", (siteName ? siteName :
"sitename"));
2057 bp += n; bleft -= n;
2059 else if (!strcmp(
"start", val))
2060 {n = snprintf(bp, bleft,
"%s\n", startUP);
2061 bp += n; bleft -= n;
2063 else if (!strcmp(
"sysid", val))
2064 {
const char *cidval = getenv(
"XRDCMSCLUSTERID");
2065 const char *nidval = getenv(
"XRDCMSVNID");
2066 if (!cidval || !(*cidval) || !nidval || !(*nidval))
2067 {cidval =
"sysid"; nidval =
"";}
2068 n = snprintf(bp, bleft,
"%s %s\n", nidval, cidval);
2069 bp += n; bleft -= n;
2071 else if (!strcmp(
"tpc", val))
2072 {
char *tpcval = getenv(
"XRDTPC");
2073 n = snprintf(bp, bleft,
"%s\n", (tpcval ? tpcval :
"tpc"));
2074 bp += n; bleft -= n;
2076 else if (!strcmp(
"tpcdlg", val))
2077 {
char *tpcval = getenv(
"XRDTPCDLG");
2078 n = snprintf(bp, bleft,
"%s\n", (tpcval ? tpcval :
"tpcdlg"));
2079 bp += n; bleft -= n;
2081 else if (!strcmp(
"tls_port", val) &&
tlsPort)
2082 {n = snprintf(bp, bleft,
"%d\n",
tlsPort);
2083 bp += n; bleft -= n;
2085 else if (!strcmp(
"window", val) &&
Window)
2086 {n = snprintf(bp, bleft,
"%d\n",
Window);
2087 bp += n; bleft -= n;
2089 else if (!strcmp(
"version", val))
2090 {n = snprintf(bp, bleft,
"%s\n", XrdVSTRING);
2091 bp += n; bleft -= n;
2093 else if (!strcmp(
"vnid", val))
2094 {
const char *nidval = getenv(
"XRDCMSVNID");
2095 if (!nidval || !(*nidval)) nidval =
"vnid";
2096 n = snprintf(bp, bleft,
"%s\n", nidval);
2098 else if (!strcmp(
"fattr", val))
2099 {n = snprintf(bp, bleft,
"%s\n",
usxParms);
2100 bp += n; bleft -= n;
2102 else {n = strlen(val);
2103 if (bleft <= n)
break;
2104 strcpy(bp, val); bp +=n; *bp =
'\n'; bp++;
2107 }
while(bleft > 0 && (val = qcargs.GetToken()));
2126 bool isCMSD = (*val ==
'c');
2151 int XrdXrootdProtocol::do_Qfh()
2156 const char *fArg = 0, *qType =
"";
2168 "query does not refer to an open file");
2188 "Required query argument not present");
2193 TRACEP(FS,
"fh=" <<fh.handle <<
" query " <<qType <<
" rc=" <<rc);
2206 int XrdXrootdProtocol::do_Qopaque(
short qopt)
2211 const char *Act, *AData;
2219 myData.Arg2 = 0; myData.
Arg2Len = 0;
2221 Act =
" qopaque '"; AData =
"...";
2236 myData.Arg2 = opaque;
2239 Act =
" qopaquf '"; AData =
argp->
buff;
2248 TRACEP(FS,
"rc=" <<rc <<Act <<AData <<
"'");
2250 return fsError(rc, 0, myError, 0, 0);
2257 int XrdXrootdProtocol::do_Qspace()
2278 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
2293 int XrdXrootdProtocol::do_Query()
2310 case kXR_QPrep:
return do_Prepare(
true);
2317 "Invalid information query type code");
2324 int XrdXrootdProtocol::do_Qxattr()
2346 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
2360 int XrdXrootdProtocol::do_Read()
2371 else if (do_ReadNone(retc, pathID))
return retc;
2382 "read does not refer to an open file");
2386 TRACEP(FSIO, pathID <<
" fh=" <<fh.handle <<
" read " <<
IO.
IOLen
2389 "Read length is negative");
2414 if (!pathID) pP =
this;
2415 else {
if (!(pP =
VerifyStream(retc, pathID,
false)))
return retc;
2441 if (pathID)
return do_Offload(&XrdXrootdProtocol::do_ReadAll, pathID);
2445 return do_ReadAll();
2456 int XrdXrootdProtocol::do_ReadAll()
2491 {
if ((rc = getBuff(1, Quantum)) <= 0)
return rc;}
2502 IO.Offset += xframt;
IO.
IOLen -= xframt;
2516 int XrdXrootdProtocol::do_ReadNone(
int &retc,
int &pathID)
2525 pathID =
static_cast<int>(rargs->
pathid);
2526 if ((ralsz -=
sizeof(
read_args)) <= 0)
return 0;
2545 "preread does not refer to an open file");
2563 int XrdXrootdProtocol::do_ReadV()
2577 int rdVBeg, rdVBreak, rdVNow, rdVNum, rdVecNum;
2578 int currFH, i, k, Quantum, Qleft, rdVecLen =
Request.header.dlen;
2580 int ioMon = (rvMon > 1);
2581 char *buffp, vType = (ioMon ? XROOTD_MON_READU : XROOTD_MON_READV);
2586 rdVecNum = rdVecLen / sizeof(readahead_list);
2587 if ( (rdVecNum <= 0) || (rdVecNum*hdrSZ != rdVecLen) )
2588 return Response.Send(kXR_ArgInvalid, "Read vector is invalid");
2594 if (rdVecNum > XrdProto::maxRvecsz)
2595 return
Response.
Send(kXR_ArgTooLong, "Read vector is too long");
2605 raVec = (readahead_list *)
argp->buff;
2607 for (i = 0; i < rdVecNum; i++)
2608 {totSZ += (rdVec[i].size = ntohl(raVec[i].rlen));
2609 if (rdVec[i].size < 0) return Response.Send(kXR_ArgInvalid,
2610 "Readv length is negative");
2611 if (rdVec[i].size > Quantum) return Response.Send(kXR_NoMemory,
2612 "Single readv transfer is too large");
2613 rdVec[i].offset = ntohll(raVec[i].offset);
2614 memcpy(&rdVec[i].info, raVec[i].fhandle, sizeof(int));
2619 rdVec[i].offset = -1;
2622 rdVBreak = rdVecNum;
2627 if (totSZ > 0x80000000LL)
2628 return
Response.
Send(kXR_NoMemory, "Total readv transfer is too large");
2633 Quantum = totSZ < maxTransz ? totSZ : maxTransz;
2637 if ((Quantum < halfBSize && Quantum > 1024) || Quantum > argp->bsize)
2638 {
if ((k = getBuff(1, Quantum)) <= 0)
return k;}
2645 "readv does not refer to an open file");
2650 currFH = rdVec[0].info;
2651 memcpy(respHdr.fhandle, &currFH,
sizeof(respHdr.fhandle));
2653 "readv does not refer to an open file");
2658 rdVBeg = rdVNow = 0; rdVXfr = rdVAmt = 0;
2662 for (i = 0; i < rdVecNum; i++)
2663 {
if (rdVec[i].info != currFH)
2665 if (xfrSZ != rdVAmt)
break;
2666 rdVNum = i - rdVBeg; rdVXfr += rdVAmt;
2670 htons(rdVNum),
rvSeq, vType);
2671 if (ioMon)
for (k = rdVBeg; k < i; k++)
2673 htonl(rdVec[k].size), htonll(rdVec[k].offset));
2675 rdVXfr = rdVAmt = 0;
2676 if (i == rdVBreak)
break;
2677 rdVBeg = rdVNow = i; currFH = rdVec[i].info;
2678 memcpy(respHdr.fhandle, &currFH,
sizeof(respHdr.fhandle));
2681 "readv does not refer to an open file");
2684 if (Qleft < (rdVec[i].size + hdrSZ))
2687 if (xfrSZ != rdVAmt)
break;
2693 rdVNow = i; rdVXfr += rdVAmt; rdVAmt = 0;
2696 xfrSZ = rdVec[i].size; rdVAmt += xfrSZ;
2697 respHdr.rlen = htonl(xfrSZ);
2698 respHdr.offset = htonll(rdVec[i].offset);
2699 memcpy(buffp, &respHdr, hdrSZ);
2700 rdVec[i].data = buffp + hdrSZ;
2701 buffp += (xfrSZ+hdrSZ); Qleft -= (xfrSZ+hdrSZ);
2702 TRACEP(FSIO,
"fh=" <<currFH<<
" readV "<< xfrSZ <<
'@'<<rdVec[i].offset);
2724 int XrdXrootdProtocol::do_Rm()
2754 int XrdXrootdProtocol::do_Rmdir()
2784 int XrdXrootdProtocol::do_Set()
2791 if (!setargs.GetLine() || !(val = setargs.GetToken(&rest)))
2800 if (!strcmp(
"appid", val))
2801 {
while(*rest && *rest ==
' ') rest++;
2805 else if (!strcmp(
"monitor", val))
return do_Set_Mon(setargs);
2806 else if (!strcmp(
"cache", val))
return do_Set_Cache(setargs);
2823 char *cmd, *cargs, *opaque =
nullptr;
2824 const char *myArgs[2];
2833 if (!(cmd = setargs.
GetToken(&cargs)))
2838 if (cargs && *cargs ==
'/')
2839 {
if (rpCheck(cargs, &opaque))
return rpEmsg(
"Setting", cargs);
2840 if (!Squash(cargs))
return vpEmsg(
"Setting", cargs);
2841 myData.ArgP = myArgs; myData.
Arg2Len = -2;
2845 myData.Arg2 = opaque; myData.
Arg2Len = (opaque ? strlen(opaque) : 0);
2852 TRACEP(FS,
"rc=" <<rc <<
"set cache " <<myData.
Arg1 <<
' ' <<cargs);
2854 return fsError(rc, 0, myError, 0, 0);
2870 if (!(val = setargs.
GetToken(&appid)))
2877 if (!strcmp(val,
"info"))
2879 {
while(*appid && *appid ==
' ') appid++;
2880 if (strlen(appid) > 1024) appid[1024] =
'\0';
2888 if (!strcmp(val,
"on"))
2891 {
while(*appid && *appid ==
' ') appid++;
2900 if (!strcmp(val,
"off"))
2902 {
while(*appid && *appid ==
' ') appid++;
2918 int XrdXrootdProtocol::do_Stat()
2924 char *opaque, xxBuff[1024];
2943 "stat does not refer to an open file");
2947 StatGen(buf,xxBuff,
sizeof(xxBuff)));
2970 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
2980 StatGen(buf,xxBuff,
sizeof(xxBuff)));
2989 int XrdXrootdProtocol::do_Statx()
2993 char *path, *opaque, *respinfo =
argp->
buff;
3004 while((path = pathlist.GetLine()))
3005 {
if (rpCheck(path, &opaque))
return rpEmsg(
"Stating", path);
3006 if (!Squash(path))
return vpEmsg(
"Stating", path);
3008 TRACEP(FS,
"rc=" <<rc <<
" stat " <<path);
3011 else {
if (mode == (mode_t)-1) *respinfo = (char)
kXR_offline;
3012 else if (S_ISDIR(mode)) *respinfo = (
char)
kXR_isDir;
3027 int XrdXrootdProtocol::do_Sync()
3062 int XrdXrootdProtocol::do_Truncate()
3067 long long theOffset;
3086 "trunc does not refer to an open file");
3092 TRACEP(FS,
"fh=" <<fh.
handle <<
" trunc rc=" <<rc <<
" sz=" <<theOffset);
3113 TRACEP(FS,
"rc=" <<rc <<
" trunc " <<theOffset <<
' ' <<
argp->
buff);
3127 int XrdXrootdProtocol::do_Write()
3143 return do_WriteNone(pathID);
3150 "Write length is negative");
3169 {
if (pathID)
return do_Offload(&XrdXrootdProtocol::do_WriteAio,pathID);
3170 return do_WriteAio();
3178 if (pathID)
return do_Offload(&XrdXrootdProtocol::do_WriteAll, pathID);
3182 return do_WriteAll();
3193 int XrdXrootdProtocol::do_WriteAio()
3203 return do_WriteAll();
3219 int XrdXrootdProtocol::do_WriteAll()
3226 {
if ((rc = getBuff(0, Quantum)) <= 0)
return rc;}
3234 {
Resume = &XrdXrootdProtocol::do_WriteCont;
3241 return do_WriteNone();
3243 IO.Offset += Quantum;
IO.
IOLen -= Quantum;
3261 int XrdXrootdProtocol::do_WriteCont()
3269 return do_WriteNone();
3275 if (
IO.
IOLen > 0)
return do_WriteAll();
3283 int XrdXrootdProtocol::do_WriteNone()
3285 char *buff, dbuff[4096];
3295 blen =
sizeof(dbuff);
3304 if (rlen < 0)
return Link->
setEtext(
"link read error");
3308 Resume = &XrdXrootdProtocol::do_WriteNone;
3316 return do_WriteNoneMsg();
3321 int XrdXrootdProtocol::do_WriteNone(
int pathID,
XErrorCode ec,
3329 else do_WriteNoneMsg();
3345 return do_WriteNone();
3352 int XrdXrootdProtocol::do_WriteNoneMsg()
3406 return do_WriteNone();
3412 if (
IO.
IOLen > 0)
return do_WriteAll();
3420 int XrdXrootdProtocol::do_WriteV()
3438 long long totSZ, maxSZ;
3444 wrVecNum = wrVecLen / wveSZ;
3445 if ( (wrVecLen <= 0) || (wrVecNum*wveSZ != wrVecLen) )
3471 totSZ = 0; maxSZ = 0; k = 0; Quantum =
maxTransz; curFH = 0;
3472 for (
int i = 0; i < wrVecNum; i++)
3473 {
if (wrLst[i].
wlen == 0)
continue;
3474 memcpy(&wrVec[k].info, wrLst[i].
fhandle,
sizeof(
int));
3475 wrVec[k].
size = ntohl(wrLst[i].
wlen);
3476 if (wrVec[k].size < 0)
3480 if (wrVec[k].size > Quantum)
3485 if (wrVec[k].info == curFH) totSZ += wrVec[k].
size;
3486 else {
if (maxSZ < totSZ) maxSZ = totSZ;
3487 totSZ = wrVec[k].
size;
3494 if (maxSZ < totSZ) maxSZ = totSZ;
3505 else Quantum =
static_cast<int>(maxSZ);
3509 if ((Quantum < halfBSize && Quantum > 1024) || Quantum >
argp->
bsize)
3510 {
if (getBuff(0, Quantum) <= 0)
return -1;}
3539 freeInfo.doit =
false;
3548 int XrdXrootdProtocol::do_WriteVec()
3561 {
if (rc < 0)
return rc;
3563 Resume = &XrdXrootdProtocol::do_WriteVec;
3571 done = newfile =
false;
3591 if (done || newfile)
3608 if (xfrSZ< 0)
break;
3674 for (i = 1; i < sfvnum; i++) xframt += sfvec[i].sendsz;
3675 if (xframt >
IO.
IOLen)
return 1;
3691 else IO.
File->fdNum = fildes;
3701 int XrdXrootdProtocol::fsError(
int rc,
char opC,
XrdOucErrInfo &myError,
3702 const char *
Path,
char *Cgi)
3704 int ecode, popt, rs;
3716 return fsOvrld(opC,
Path, Cgi);
3726 if (Cgi) rs = fsRedirNoEnt(
eMsg, Cgi, popt);
3749 <<
eMsg <<
':' <<ecode);
3766 if (ecode <= 0) ecode = 1800;
3771 return (rc ? rc : 1);
3807 sprintf(buff,
"%d", rc);
3819 int XrdXrootdProtocol::fsOvrld(
char opC,
const char *
Path,
char *Cgi)
3821 static const char *prot =
"root://";
3822 static int negOne = -1;
3823 static char quest =
'?', slash =
'/';
3825 struct iovec rdrResp[8];
3826 char *destP=0, dest[512];
3827 int iovNum=0, pOff, port;
3835 { rdrResp[1].iov_base = (
char *)&negOne;
3836 rdrResp[1].iov_len =
sizeof(negOne);
3837 rdrResp[2].iov_base = (
char *)prot;
3838 rdrResp[2].iov_len = 7;
3839 rdrResp[3].iov_base = (
char *)dest;
3840 rdrResp[3].iov_len = strlen(dest);
3841 rdrResp[4].iov_base = (
char *)&slash;
3842 rdrResp[4].iov_len = (*
Path ==
'/' ? 1 : 0);
3843 rdrResp[5].iov_base = (
char *)(
Path+pOff);
3844 rdrResp[5].iov_len = strlen(
Path+pOff);
3846 {rdrResp[6].iov_base = (
char *)?
3847 rdrResp[6].iov_len =
sizeof(quest);
3848 rdrResp[7].iov_base = (
char *)Cgi;
3849 rdrResp[7].iov_len = strlen(Cgi);
3889 int XrdXrootdProtocol::fsRedirNoEnt(
const char *
eMsg,
char *Cgi,
int popt)
3891 struct iovec ioV[4];
3892 char *tried, *trend, *ptried = 0;
3899 {
do {
if (!(tried = strstr(Cgi,
"tried=")))
break;
3900 if (tried == trend || *(tried-1) ==
'&')
3901 {
if (!ptried || (*(tried+6) && *(tried+6) !=
'&')) ptried=tried;}
3902 Cgi = index(tried+6,
'&');
3909 if ((tried = ptried))
3911 while(*(tried+1) && *(tried+1) ==
',') tried++;
3912 trend = index(tried,
'&');
3913 if (trend) {tlen = trend - tried; *trend = 0;}
3914 else tlen = strlen(tried);
3921 if ((trend = tried) &&
eMsg)
3922 do {
if ((trend = strstr(trend,
myCName)))
3925 trend = index(trend+
myCNlen,
',');
3933 if (!tried || !tlen || tlen > 16384)
3941 ioV[1].iov_base = (
char *)&pnum;
3942 ioV[1].iov_len =
sizeof(pnum);
3945 ioV[3].iov_base = tried;
3946 ioV[3].iov_len = tlen;
3977 auto cmpchr = [](
const char* a,
const char* b) {
return strcmp(a,b)<0;};
3987 auto it = niMap.find(netID);
3988 if (it == niMap.end())
3990 niMap[niP->
netID] = niP;
3991 }
else niP = it->second;
3999 time_t nowT = time(0);
4002 {
const char* eTxt = niP->
netAddr.
Set(netID, port);
4005 {
eDest.
Emsg(
"RedirIP",
"Unable to init NetInfo for", netID, eTxt);
4010 eDest.
Emsg(
"RedirIP",
"Unable to refresh NetInfo for", netID, eTxt);
4025 int XrdXrootdProtocol::fsRedirPI(
const char *trg,
int port,
int trglen)
4029 THandle() :
Info(0) {}
4030 ~THandle() {
if (
Info)
Info->refs--;}
4039 const char* TCgi = index(trg,
'?');
4040 if (!TCgi) {TCgi =
""; TDst = trg;}
4041 else TDst.assign(trg, TCgi-trg);
4042 T.Info = fsRedirIP(TDst.c_str(), port);
4044 uint16_t TPort =
static_cast<uint16_t
>(newPort);
4045 Target =
RedirPI->
Redirect(TDst.c_str(), TPort, TCgi, T.Info->netAddr,
4047 newPort =
static_cast<int>(TPort);
4055 std::string urlHead, TDst, urlPort;
4056 const char* urlTail;
4057 const char* hBeg = strstr(trg,
"://");
4059 {
eDest.
Emsg(
"RedirPI",
"Invalid redirect URL -", trg);
4063 urlHead.assign(trg, hBeg-trg);
4064 urlTail = strstr(hBeg,
"/");
4065 if (!urlTail) {urlTail =
""; TDst = hBeg;}
4066 else {
if (urlTail-hBeg < 3)
4067 {
eDest.
Emsg(
"RedirPI",
"Mlalformed URL -", trg);
4070 TDst.assign(hBeg, urlTail-hBeg);
4072 T.Info = fsRedirIP(TDst.c_str(), port);
4074 size_t colon = TDst.find(
":");
4075 if (colon != std::string::npos)
4076 {urlPort.assign(TDst, colon+1, std::string::npos);
4080 urlPort.c_str(), urlTail, newPort,
4082 if (port == -1 || newPort >= 0) newPort = port;
4089 if (Target.front() !=
'!')
4091 <<Target.c_str() <<
" portarg="<<newPort);
4099 snprintf(mbuff,
sizeof(mbuff),
"Redirect failed; %s",Target.c_str());
4108 int XrdXrootdProtocol::getBuff(
const int isRead,
int Quantum)
4127 "insufficient memory to read file" :
4128 "insufficient memory to write file"));
4139 char *XrdXrootdProtocol::getCksType(
char *opaque,
char *cspec,
int cslen)
4145 if (opaque && *opaque)
4147 if ((cksT = jobEnv.Get(
"cks.type")))
4149 while(tP && strcasecmp(tP->
text, cksT)) tP = tP->
next;
4150 if (!tP && cspec) snprintf(cspec, cslen,
"%s", cksT);
4151 return (tP ? tP->
text : 0);
4164 bool XrdXrootdProtocol::logLogin(
bool xauth)
4166 const char *uName, *ipName, *tMsg, *zMsg =
"";
4167 char lBuff[512], pBuff[512];
4183 if (*tMsg) zMsg =
" ";
4187 snprintf(lBuff,
sizeof(lBuff),
"%s %s %s%slogin%s%s",
4190 (xauth ?
" as " :
""),
4191 (uName ? uName :
""));
4196 {snprintf(pBuff,
sizeof(pBuff),
"via %s auth for %s",
4214 eDest.
Emsg(
"Xeq",
"session requires TLS but",
Link->
ID,
"is incapable.");
4238 #define Map_Mode(x,y) if (Mode & kXR_ ## x) newmode |= S_I ## y
4240 int XrdXrootdProtocol::mapMode(
int Mode)
4262 const char *bP = Buff;
4265 else {snprintf(Buff,
sizeof(Buff),
4266 "&p=%s&n=%s&h=%s&o=%s&r=%s&g=%s&m=%s%s&I=%c",
4288 int XrdXrootdProtocol::rpCheck(
char *fn,
char **opaque)
4297 if (!(cp = index(fn,
'?'))) *opaque = 0;
4298 else {*cp =
'\0'; *opaque = cp+1;
4299 if (!**opaque) *opaque = 0;
4302 if (*fn !=
'/')
return 0;
4304 while ((cp = index(fn,
'/')))
4306 if (fn[0] ==
'.' && fn[1] ==
'.' && (fn[2] ==
'/' || fn[2] ==
'\0'))
4316 int XrdXrootdProtocol::rpEmsg(
const char *op,
char *fn)
4319 snprintf(buff,
sizeof(buff)-1,
"%s relative path '%s' is disallowed.",op,fn);
4320 buff[
sizeof(buff)-1] =
'\0';
4338 else if (theFile->fdNum >= 0) theFile->
sfEnabled = 1;
4349 int XrdXrootdProtocol::Squash(
char *fn)
4351 char *ofn, *ifn = fn;
4358 || (*(ifn+1) ==
'.' && *(ifn+1) && *(ifn+2) ==
'/'))
break;
4365 while(*ifn) {*ofn = *ifn++;
4367 {
while(*ifn ==
'/') ifn++;
4368 if (ifn[0] ==
'.' && ifn[1] ==
'/') ifn += 2;
4382 int XrdXrootdProtocol::vpEmsg(
const char *op,
char *fn)
4385 snprintf(buff,
sizeof(buff)-1,
"%s path '%s' is disallowed.",op,fn);
4386 buff[
sizeof(buff)-1] =
'\0';
struct ClientTruncateRequest truncate
#define kXR_ShortProtRespLen
struct ClientCloseRequest close
struct ClientMkdirRequest mkdir
struct ClientAuthRequest auth
#define kXR_PROTSIGNVERSION
struct ClientDirlistRequest dirlist
struct ClientOpenRequest open
struct ClientRequestHdr header
struct ClientWriteVRequest writev
struct ClientLoginRequest login
struct ClientChmodRequest chmod
struct ClientQueryRequest query
struct ClientReadRequest read
struct ClientMvRequest mv
struct ClientBindRequest bind
#define kXR_PROTOCOLVERSION
struct ClientEndsessRequest endsess
struct ClientSyncRequest sync
struct ClientPrepareRequest prepare
struct ClientStatRequest stat
struct ClientWriteRequest write
ServerResponseReqs_Protocol secreq
struct ClientProtocolRequest protocol
struct ClientLocateRequest locate
int emsg(int rc, char *msg)
const char * Arg1
PLUGINO, PLUGION, PLUGXC.
int Arg2Len
Length or -count of args in extension.
char * notify
Notification path or 0.
XrdOucTList * paths
List of paths.
XrdOucTList * oinfo
1-to-1 correspondence of opaque info
long long XrdSfsFileOffset
< SFS_FSCTL_PLUGIN/PLUGIO/PLUGXC parms
const char * XrdSysE2T(int errcode)
XrdOucString * XrdXrootdCF
const kXR_char XROOTD_MON_OPENW
const kXR_char XROOTD_MON_STAT
const kXR_char XROOTD_MON_REDLOCAL
const kXR_char XROOTD_MON_PREP
const kXR_char XROOTD_MON_OPENC
const kXR_char XROOTD_MON_TRUNC
const kXR_char XROOTD_MON_CLOSE
const kXR_char XROOTD_MON_CHMOD
const kXR_char XROOTD_MON_LOCATE
const kXR_char XROOTD_MON_OPENR
const kXR_char XROOTD_MON_MV
const kXR_char XROOTD_MON_RMDIR
const kXR_char XROOTD_MON_RM
const kXR_char XROOTD_MON_OPENDIR
const kXR_char XROOTD_MON_QUERY
const kXR_char XROOTD_MON_MKDIR
XrdSysTrace XrdXrootdTrace
#define STATIC_REDIRECT(xfnc)
static const char * errName(kXR_int32 errCode)
static int mapError(int rc)
void Release(XrdBuffer *bp)
XrdBuffer * Obtain(int bsz)
static const int ValuSize
static const int NameSize
static bool GetAssumeV4()
static XrdLink * fd2link(int fd)
static bool RegisterCloseRequestCb(XrdLink *lp, XrdProtocol *pp, bool(*cb)(void *), void *cbarg)
void Serialize()
Wait for all outstanding requests to be completed on the link.
int setEtext(const char *text)
bool setTLS(bool enable, XrdTlsContext *ctx=0)
Enable or disable TLS on the link.
int Recv(char *buff, int blen)
const char * Host() const
int Terminate(const char *owner, int fdnum, unsigned int inst)
void setID(const char *userid, int procid)
XrdNetAddrInfo * AddrInfo()
char * ID
Pointer to the client's link identity.
void setProtName(const char *name)
void setLocation(XrdNetAddrInfo::LocInfo &loc)
unsigned int Inst() const
bool isIPType(IPType ipType) const
const char * Set(const char *hSpec, int pNum=PortInSpec)
bool getEA(int &ec, int &ac)
static bool getEA(const char *cgi, int &ecode, int &acode)
virtual Handle * Begin(XrdSecEntity &Client, const char *path=0, const char *cgi=0, const char *app=0)=0
virtual void Done(int &Result, XrdOucErrInfo *eInfo, const char *Path=0)=0
void setErrCB(XrdOucEICB *cb, unsigned long long cbarg=0)
const char * getErrText()
int setErrInfo(int code, const char *emsg)
void setUCap(int ucval)
Set user capabilties.
void Reset()
Reset object to no message state. Call this method to release appendages.
char * ID(char *buff, int blen)
char * isMine(char *reqid, int &hport, char *hname, int hlen)
const char * c_str() const
char * GetToken(char **rest=0, int lowcase=0)
static void Sanitize(char *instr, char subc='_')
static int isFWD(const char *path, int *port=0, char *hBuff=0, int hBLen=0, bool pTrim=false)
void Schedule(XrdJob *jp)
bool Add(XrdSecAttr &attr)
XrdSecAttr * Get(const void *sigkey)
char * vorg
Entity's virtual organization(s)
const char * pident
Trace identifier (originator)
XrdNetAddrInfo * addrInfo
Entity's connection details.
XrdSecEntityAttr * eaAPI
non-const API to attributes
const char * tident
Trace identifier always preset.
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
XrdSecMonitor * secMon
If !0 security monitoring enabled.
char * grps
Entity's group name(s)
char * name
Entity's name.
unsigned int ueid
Unique ID of entity instance.
char * role
Entity's role(s)
void Display(XrdSysError &mDest)
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.
virtual XrdSecProtect * New4Server(XrdSecProtocol &aprot, int plvl)
virtual int ProtResp(ServerResponseReqs_Protocol &resp, XrdNetAddrInfo &nai, int pver)
virtual void Delete()=0
Delete the protocol object. DO NOT use C++ delete() on this object.
virtual int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)=0
virtual const char * getParms(int &size, XrdNetAddrInfo *endPoint=0)=0
virtual bool PostProcess(XrdSecEntity &entity, XrdOucErrInfo &einfo)
virtual XrdSecProtocol * getProtocol(const char *host, XrdNetAddrInfo &endPoint, const XrdSecCredentials *cred, XrdOucErrInfo &einfo)=0
virtual int autoStat(struct stat *buf)
virtual const char * nextEntry()=0
virtual int open(const char *path, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual XrdSfsDirectory * newDir(char *user=0, int MonID=0)=0
virtual void Connect(const XrdSecEntity *client=0)
virtual int chmod(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int fsctl(const int cmd, const char *args, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
virtual int rename(const char *oPath, const char *nPath, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaqueO=0, const char *opaqueN=0)=0
virtual int mkdir(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)
virtual int truncate(const char *path, XrdSfsFileOffset fsize, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int chksum(csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
virtual int remdir(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual int prepare(XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
virtual int stat(const char *Name, struct stat *buf, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual XrdSfsFile * newFile(char *user=0, int MonID=0)=0
virtual int rem(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual XrdSfsXferSize writev(XrdOucIOVec *writeV, int wdvCnt)
virtual int SendData(XrdSfsDio *sfDio, XrdSfsFileOffset offset, XrdSfsXferSize size)
virtual int open(const char *fileName, XrdSfsFileOpenMode openMode, mode_t createMode, const XrdSecEntity *client=0, const char *opaque=0)=0
virtual XrdSfsXferSize read(XrdSfsFileOffset offset, XrdSfsXferSize size)=0
virtual XrdSfsXferSize readv(XrdOucIOVec *readV, int rdvCnt)
virtual int truncate(XrdSfsFileOffset fsize)=0
virtual int getCXinfo(char cxtype[4], int &cxrsz)=0
virtual int stat(struct stat *buf)=0
virtual void setXio(XrdSfsXio *xioP)
virtual int fctl(const int cmd, const char *args, XrdOucErrInfo &eInfo)=0
virtual XrdSfsXferSize write(XrdSfsFileOffset offset, const char *buffer, XrdSfsXferSize size)=0
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)
static void Snooze(int seconds)
virtual void numLocks(const char *path, int &rcnt, int &wcnt)=0
virtual int Unlock(const char *path, char mode)=0
virtual int Lock(const char *path, char mode, bool force)=0
void rvOps(int rsz, int ssz)
void wvOps(int wsz, int ssz)
int Add(XrdXrootdFile *fp)
XrdXrootdFile * Get(int fnum)
XrdXrootdFile * Del(XrdXrootdMonitor *monP, int fnum, bool dodel=true)
int Schedule(const char *jkey, const char **args, XrdXrootdResponse *resp, int Opts=0)
int Cancel(const char *jkey=0, XrdXrootdResponse *resp=0)
static void Open(XrdXrootdFileStats *fsP, const char *Path, unsigned int uDID, bool isRW)
kXR_unt32 MapInfo(const char *Info)
kXR_unt32 MapPath(const char *Path)
void Register(const char *Uname, const char *Hname, const char *Pname, unsigned int xSID=0)
void Report(const char *Info)
void Add_rv(kXR_unt32 dictid, kXR_int32 rlen, kXR_int16 vcnt, kXR_char vseq, kXR_char vtype)
void Add_rd(kXR_unt32 dictid, kXR_int32 rlen, kXR_int64 offset)
void Add_wr(kXR_unt32 dictid, kXR_int32 wlen, kXR_int64 offset)
void Open(kXR_unt32 dictid, off_t fsize)
int Write(long long offs, int dlen) override
void Read(long long offs, int dlen) override
static XrdXrootdNormAio * Alloc(XrdXrootdProtocol *protP, XrdXrootdResponse &resp, XrdXrootdFile *fP)
int(XrdXrootdProtocol::* ResumePio)()
static XrdXrootdPio * Alloc(int n=1)
void Set(int(XrdXrootdProtocol::*Invoke)(), XrdXrootd::IOParms &io, const kXR_char *theSID)
static int List(XrdXrootdPrepArgs &pargs, char *resp, int resplen)
static void Log(XrdXrootdPrepArgs &pargs)
static void Logdel(char *reqid)
static XrdXrootdStats * SI
int SendFile(int fildes) override
XrdXrootdProtocol * VerifyStream(int &rc, int pID, bool lok=true)
static XrdSfsFileSystem * digFS
int SetSF(kXR_char *fhandle, bool seton=false)
XrdNetPMark::Handle * pmHandle
static XrdNetPMark * PMark
XrdXrootdProtocol * Stream[maxStreams]
static XrdXrootdXPath RPList
static const char Req_TLSGPFile
static bool CloseRequestCb(void *cbarg)
void SetFD(int fildes) override
static const char Req_TLSSess
XrdXrootdFileTable * FTab
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static unsigned int getSID()
XrdSecProtocol * AuthProt
int getData(gdCallBack *gdcbP, const char *dtype, char *buff, int blen)
XrdXrootdMonitor::User Monitor
static XrdXrootdRedirPI * RedirPI
static const char * myCName
static const char Req_TLSData
static XrdXrootdFileLock * Locker
int(XrdXrootdProtocol::* Resume)()
static const char Req_TLSTPC
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static const char Req_TLSLogin
XrdXrootdResponse Response
int(XrdXrootdProtocol::* ResumePio)()
static const int maxStreams
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static XrdSecProtector * DHS
static XrdBuffManager * BPool
XrdSysSemaphore * boundRecycle
static XrdSecService * CIA
static RAtomic_int srvrAioOps
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSfsFileSystem * osFS
virtual std::string RedirectURL(const char *urlHead, const char *Target, const char *port, const char *urlTail, int &rdrOpts, XrdNetAddrInfo &TNetInfo, XrdNetAddrInfo &CNetInfo)
virtual std::string Redirect(const char *Target, uint16_t &port, const char *TCgi, XrdNetAddrInfo &TNetInfo, XrdNetAddrInfo &CNetInfo)=0
void setID(unsigned long long id)
unsigned long long getID()
void StreamID(kXR_char *sid)
int Stats(char *buff, int blen, int do_sync=0)
int Validate(const char *pd, const int pl=0)
static const int maxRvecsz
static const int maxWvecsz
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasSXIO
Feature: Supports SfsXio.
ssize_t Send(int fd, KernelBuffer &buffer)
static const kXR_int32 doSync
char TimeZone
+/- hours from GMT (-128 if not set)
unsigned char Country[2]
Two letter TLD country code.
static const int uRedirFlgs
ucap: Client supports "file://"
static const int uUrlOK
ucap: Supports async responses
static const int uIPv64
ucap: Supports only IPv4 info
static const int uReadR
ucap: Supports multiple protocols
static const int uEcRedir
ucap: Client supports redirect flags
static const int uMProt
ucap: Supports url redirects
static const int uLclF
ucap: Client is on a private net
static const int uAsync
ucap: Extract protocol version
static const int uIPv4
ucap: Supports read redirects
Generic structure to pass security information back and forth.
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.
static const int useBasic