77 #include "XrdVersion.hh"
80 #define ENODATA ENOATTR
84 #define ETIME ETIMEDOUT
114 const char *getTime()
116 static char buff[16];
121 if (gettimeofday(&tv, 0))
122 {perror(
"gettimeofday");
125 tmp = localtime(&tv.tv_sec);
127 {perror(
"localtime");
131 if (strftime(buff,
sizeof(buff),
"%y%m%d:%H%M%S. ", tmp) <= 0)
137 snprintf(tuff,
sizeof(tuff),
"%d",
static_cast<int>(tv.tv_usec/100000));
158 static const char *startUP = getTime();
165 int XrdXrootdProtocol::do_Auth()
194 {eText =
eMsg.getErrText(rc);
195 eDest.
Emsg(
"Xeq",
"User authentication failed;", eText);
212 if (!logLogin(
true))
return -1;
219 {
TRACEP(LOGIN,
"more auth requested; sz=" <<(parm ? parm->
size : 0));
224 eDest.
Emsg(
"Xeq",
"Security requested additional auth w/o parms!");
239 eText =
eMsg.getErrText(rc);
240 eDest.
Emsg(
"Xeq",
"User authentication failed;", eText);
248 int XrdXrootdProtocol::do_Bind()
254 char buff[64], *cp, *dp;
301 if (strcmp(
Link->
Host(), lp->Host()))
313 for (i = 1; i <
maxStreams && pp->Stream[i]; i++) {}
321 pp->Stream[i] =
this;
328 if ( (dp = rindex(cp,
'@'))) *dp =
'\0';
329 if (!(dp = rindex(cp,
'.'))) pPid = 0;
330 else {*dp++ =
'\0'; pPid = strtol(dp, (
char **)NULL, 10);}
344 *(pp->pmHandle),
Link->
ID);
350 sprintf(buff,
"FD %d#%d bound",
Link->
FDnum(), i);
359 buff[0] =
static_cast<char>(i);
378 int XrdXrootdProtocol::do_Chmod()
409 int XrdXrootdProtocol::do_CKsum(
int canit)
412 char *algT =
JobCKT, *args[6];
426 if (rpCheck(
argp->
buff, &opaque))
return rpEmsg(
"Check summing",
argp->
buff);
440 algT = getCksType(opaque, cksT,
sizeof(cksT));
443 snprintf(ebuf,
sizeof(ebuf),
"%s checksum not supported.", cksT);
450 if (
JobLCL && (rc = do_CKsum(algT,
argp->
buff, opaque)) <= 0)
return rc;
467 if (
Client->
eaAPI->
Get(std::string(
"request.name"), keyval) && !keyval.empty())
468 args[4] =
const_cast<char *
>(keyval.c_str());
486 int XrdXrootdProtocol::do_CKsum(
char *algT,
const char *
Path,
char *Opaque)
488 static char Space =
' ';
490 int CKTLen = strlen(algT);
492 myError,
CRED, Opaque);
493 const char *csData = myError.getErrText(
ec);
497 if (rc)
return fsError(rc, 0, myError,
Path, Opaque);
503 struct iovec
iov[4] = {{0,0}, {algT, (size_t)CKTLen}, {&Space, 1},
504 {(
char *)csData, strlen(csData)+1}};
511 {
const char *eTxt[2] = {
JobCKT,
" checksum not available."};
512 myError.setErrInfo(0, eTxt, 2);
525 int XrdXrootdProtocol::do_Clone()
543 "clone does not refer to an open dest file");
550 if ( (clVecNum <= 0) ||
563 std::vector<XrdOucCloneSeg> clVec(clVecNum);
571 for (
int i = 0; i < clVecNum; i++)
572 {fh.Set(clList[i].srcFH);
573 if (!srcFile || currFH != fh.handle)
577 "clone does not refer to an open src file");
584 const char *
eMsg = myError.getErrText(ecode);
588 else fdNum = myError.getErrInfo();
592 "clone does not refer to an open src file");
594 clVec[i].srcFD = fdNum;
595 n2hll(clList[i].srcOffs, clVec[i].srcOffs);
596 n2hll(clList[i].srcLen, clVec[i].srcLen);
597 n2hll(clList[i].dstOffs, clVec[i].dstOffs);
602 int rc = dstFile->
Clone(clVec);
603 if (
SFS_OK != rc)
return fsError(rc, 0, dstFile->
error, 0, 0);
612 int XrdXrootdProtocol::do_Close()
628 "close does not refer to an open file");
638 if (fp->
pgwFob && !do_PgClose(fp, rc))
663 rc = fp->XrdSfsp->close();
664 TRACEP(FS,
" fh=" <<fh.handle <<
" close rc=" <<rc);
668 return fsError(rc, 0, fp->XrdSfsp->error, 0, 0);
677 if (
SFS_OK != rc) retval = fsError(rc, 0, fp->XrdSfsp->error, 0, 0);
684 if (!doDel) fp->Ref(-1);
696 int XrdXrootdProtocol::do_Dirlist()
698 int bleft, rc = 0, dlen, cnt = 0;
699 char *opaque, *buff, ebuff[4096];
725 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s",
argp->
buff);
742 return do_DirStat(dp, ebuff, opaque);
752 do {buff = ebuff; bleft =
sizeof(ebuff);
753 while(dname || (dname = dp->
nextEntry()))
754 {dlen = strlen(dname);
755 if (dlen > 2 || dname[0] !=
'.' || (dlen == 2 && dname[1] !=
'.'))
756 {
if ((bleft -= (dlen+1)) < 0)
break;
757 strcpy(buff, dname); buff += dlen; *buff =
'\n'; buff++; cnt++;
762 }
while(!rc && dname);
768 else {*(buff-1) =
'\0';
777 if (!rc) {
TRACEP(FS,
"dirlist entries=" <<cnt <<
" path=" <<
argp->
buff);}
790 char *buff, *dLoc, *algT = 0;
791 const char *csData, *dname;
792 int bleft, rc = 0, dlen, cnt = 0, statSz = 160;
794 struct {
char ebuff[8192];
char epad[512];} XB;
801 algT = getCksType(opaque, cksT,
sizeof(cksT));
804 snprintf(ebuf,
sizeof(ebuf),
"%s checksum not supported.", cksT);
819 dlen = strlen(pbuff);
820 if (pbuff[dlen-1] !=
'/') {pbuff[dlen] =
'/'; dlen++;}
829 strcpy(XB.ebuff,
".\n0 0 0 0\n");
830 buff = XB.ebuff+10; bleft =
sizeof(XB.ebuff)-10;
840 do {
while(dname || (dname = dp->
nextEntry()))
841 {dlen = strlen(dname);
842 if (dlen > 2 || dname[0] !=
'.' || (dlen == 2 && dname[1] !=
'.'))
843 {
if ((bleft -= (dlen+1)) < 0 || bleft < statSz)
break;
844 if (dLoc) strcpy(dLoc, dname);
847 if (rc ==
SFS_ERROR && myError.getErrInfo() == ENOENT)
848 {dname = 0;
continue;}
853 strcpy(buff, dname); buff += dlen; *buff =
'\n'; buff++; cnt++;
854 dlen = StatGen(
Stat, buff,
sizeof(XB.epad));
855 bleft -= dlen; buff += (dlen-1);
858 pbuff, myError,
CRED, opaque);
859 csData = myError.getErrText();
860 if (
ec !=
SFS_OK || !(*csData) || *csData ==
'!')
862 int n = snprintf(buff,
sizeof(XB.epad),
" [ %s:%s ]",
864 buff += n; bleft -= n;
866 *buff =
'\n'; buff++;
872 buff = XB.ebuff; bleft =
sizeof(XB.ebuff);
875 }
while(!rc && dname);
881 else {*(buff-1) =
'\0';
890 if (!rc) {
TRACEP(FS,
"dirstat entries=" <<cnt <<
" path=" <<
argp->
buff);}
898 int XrdXrootdProtocol::do_Endsess()
910 memcpy((
void *)&sessID.
Pid, &sp->
Pid,
sizeof(sessID.
Pid));
911 memcpy((
void *)&sessID.
FD, &sp->
FD,
sizeof(sessID.
FD));
912 memcpy((
void *)&sessID.
Inst, &sp->
Inst,
sizeof(sessID.
Inst));
916 TRACEP(LOGIN,
"endsess " <<sessID.
Pid <<
':' <<sessID.
FD <<
'.' <<sessID.
Inst);
924 if ((sessID.
FD == 0 && sessID.
Inst == 0)
929 TRACEP(LOGIN,
"endsess " <<sessID.
Pid <<
':' <<sessID.
FD <<
'.' <<sessID.
Inst
930 <<
" rc=" <<rc <<
" (" <<
XrdSysE2T(rc < 0 ? -rc : EAGAIN) <<
")");
953 int XrdXrootdProtocol::do_gpFile()
974 int XrdXrootdProtocol::do_Locate()
978 char *opaque = 0, *
Path, *fn =
argp->
buff, opt[8], *op=opt;
995 TRACEP(FS,
"locate " <<opt <<
' ' <<fn);
999 if (*fn !=
'*'){
Path = fn;
1002 else if (*(fn+1)) {
Path = fn+1;
1017 {
if (rpCheck(
Path, &opaque))
return rpEmsg(
"Locating",
Path);
1018 if (!doDig && !Squash(
Path))
return vpEmsg(
"Locating",
Path);
1027 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
1031 TRACEP(FS,
"rc=" <<rc <<
" locate " <<fn);
1039 int XrdXrootdProtocol::do_Login()
1043 int i, pid, rc, sendSID = 0;
1053 {
const char *
emsg =
"login requires TLS be enabled";
1055 {
emsg =
"login requires TLS support";
1065 uname[
sizeof(uname)-1] = 0;
1071 "duplicate login; already logged in");
1138 if (pp && i ) {
if (!sendSID) rc =
Response.
Send((
void *)pp, i);
1139 else {
struct iovec
iov[3];
1140 iov[1].iov_base = (
char *)&sessID;
1141 iov[1].iov_len =
sizeof(sessID);
1142 iov[2].iov_base = (
char *)pp;
1148 else {rc = (sendSID ?
Response.
Send((
void *)&sessID,
sizeof(sessID))
1153 else {rc = (sendSID ?
Response.
Send((
void *)&sessID,
sizeof(sessID))
1171 char *rnumb = loginEnv.Get(
"xrd.rn");
1172 char *cCode = loginEnv.Get(
"xrd.cc");
1173 char *tzVal = loginEnv.Get(
"xrd.tz");
1174 char *appXQ = loginEnv.Get(
"xrd.appname");
1175 char *aInfo = loginEnv.Get(
"xrd.info");
1176 int tzNum = (tzVal ? atoi(tzVal) : 0);
1177 if (cCode && *cCode && tzNum >= -12 && tzNum <= 14)
1185 snprintf(apBuff,
sizeof(apBuff),
"&R=%s&x=%s&y=%s&I=%c",
1186 (rnumb ? rnumb :
""),
1187 (appXQ ? appXQ :
""), (aInfo ? aInfo :
""),
1193 {
int majr, minr, pchr;
1194 if (sscanf(rnumb,
"v%d.%d.%d", &majr, &minr, &pchr) == 3)
1195 clientRN = (majr<<16) | ((minr<<8) | pchr);
1196 else if (sscanf(rnumb,
"v%d-%*x", &majr) == 1)
clientRN = -1;
1198 if (appXQ)
AppName = strdup(appXQ);
1226 int XrdXrootdProtocol::do_Mkdir()
1259 int XrdXrootdProtocol::do_Mv()
1262 char *oldp, *newp, *Opaque, *Npaque;
1279 while(*newp && *newp !=
' ') newp++;
1280 if (*newp) {*newp =
'\0'; newp++;
1281 while(*newp && *newp ==
' ') newp++;
1287 if (rpCheck(oldp, &Opaque))
return rpEmsg(
"Renaming", oldp);
1288 if (rpCheck(newp, &Npaque))
return rpEmsg(
"Renaming to", newp);
1289 if (!Squash(oldp))
return vpEmsg(
"Renaming", oldp);
1290 if (!Squash(newp))
return vpEmsg(
"Renaming to", newp);
1300 TRACEP(FS,
"rc=" <<rc <<
" mv " <<oldp <<
' ' <<newp);
1312 int XrdXrootdProtocol::do_Offload(
int (
XrdXrootdProtocol::*Invoke)(),
int pathID)
1335 pp->
Resume = &XrdXrootdProtocol::do_OffloadIO;
1339 pp->
reTry = &isAvail;
1349 if ((pioP = pp->
pioFree))
break;
1350 pp->
reTry = &isAvail;
1352 TRACEP(FSZIO,
"busy path " <<pathID <<
" offs=" <<
IO.Offset);
1354 TRACEP(FSZIO,
"retry path " <<pathID <<
" offs=" <<
IO.Offset);
1365 pioP->
Set(Invoke,
IO, streamID);
1378 int XrdXrootdProtocol::do_OffloadIO()
1391 TRACEP(FSZIO,
"dispatch new I/O path " <<
PathID <<
" offs=" <<
IO.Offset);
1401 if (rc > 0 && !
isNOP)
1403 Resume = &XrdXrootdProtocol::do_OffloadIO;
1423 if (rc)
isNOP =
true;
1429 TRACEP(FSZIO,
"offload complete path "<<
PathID<<
" virt rc=" <<rc);
1430 return (rc ? rc : -EINPROGRESS);
1448 : fp(0), xp(0), Locker(lkP), path(fn), mode(0),
1454 else {
if (fp)
delete fp;
1455 if (mode) Locker->
Unlock(path,mode);
1462 int XrdXrootdProtocol::do_Open()
1466 int rc, mode,
opts, optt, openopts, compchk = 0;
1468 char *opaque,
usage, ebuff[2048], opC;
1469 bool doDig, doforce =
false, isAsync =
false, doClone =
false;
1470 char *fn =
argp->
buff, opt[24], *op=opt;
1473 struct stat statbuf;
1475 int resplen =
sizeof(myResp.fhandle);
1476 struct iovec IOResp[3];
1495 mode = mapMode(mode) | S_IRUSR | S_IWUSR;
usage =
'r';
1531 {openopts |=
SFS_O_RAWIO; *op++ =
'c'; compchk = 1;}
1534 {*op++ =
'a'; isAsync =
true;}
1545 "file cloning is not supported" :
1546 "colocating with a specified file is not supported");
1549 "cloned file is not being opened R/W");
1550 {*op++ =
'K'; doClone =
true;}
1553 "file must be opened as a new file in order to colocate");
1558 "file template does not refer to an open file");
1566 {
char* cgiP = index(fn,
'?');
1567 if (cgiP) *cgiP = 0;
1568 TRACEP(FS,
"open " <<opt <<
' ' <<fn);
1569 if (cgiP) *cgiP =
'?';
1574 if (rpCheck(fn, &opaque))
return rpEmsg(
"Opening", fn);
1583 else {
int ropt = -1;
1584 if (!(popt = Squash(fn)))
return vpEmsg(
"Opening", fn);
1603 OpenHelper oHelp(
Locker, fn);
1610 if (rc > 0) who = (rc > 1 ?
"readers" :
"reader");
1612 who = (rc > 1 ?
"writers" :
"writer");
1614 snprintf(ebuff,
sizeof(ebuff)-1,
1615 "%s file %s is already opened by %d %s; open denied.",
1616 (
'r' ==
usage ?
"Input" :
"Output"), fn, rc, who);
1619 }
else oHelp.mode =
usage;
1630 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s",fn);
1652 std::string oinfo(opaque ? opaque :
"");
1656 oinfo += (!oinfo.empty() ?
"&" :
"") + coloc;
1662 (mode_t)mode,
CRED, oinfo.c_str())))
1663 return fsError(rc, opC, fp->
error, fn, opaque);
1668 return fsError(rc, opC, fp->
error, fn, opaque);
1674 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s", fn);
1692 {snprintf(ebuff,
sizeof(ebuff)-1,
"Insufficient memory to open %s", fn);
1706 if ((
'r' ==
usage && wrtrs) || (
'w' ==
usage && rdrs) || wrtrs > 1)
1707 {snprintf(ebuff,
sizeof(ebuff)-1,
1708 "%s file %s forced opened with %d reader(s) and %d writer(s).",
1709 (
'r' ==
usage ?
"Input" :
"Output"), fn, rdrs, wrtrs);
1716 memset(&myResp, 0,
sizeof(myResp));
1717 if (!compchk) resplen =
sizeof(myResp.fhandle);
1719 fp->
getCXinfo((
char *)myResp.cptype, cpsize);
1720 myResp.cpsize =
static_cast<kXR_int32>(htonl(cpsize));
1721 resplen =
sizeof(myResp);
1727 {retStat = StatGen(statbuf, ebuff,
sizeof(ebuff));
1728 IOResp[1].iov_base = (
char *)&myResp; IOResp[1].iov_len =
sizeof(myResp);
1729 IOResp[2].iov_base = ebuff; IOResp[2].iov_len = retStat;
1730 resplen =
sizeof(myResp) + retStat;
1749 memcpy((
void *)myResp.fhandle,(
const void *)&fhandle,
sizeof(myResp.fhandle));
1789 int XrdXrootdProtocol::do_Ping()
1805 int XrdXrootdProtocol::do_Prepare(
bool isQuery)
1818 int rc, pathnum = 0;
1819 char reqid[128], nidbuff[512], *path, *opaque, *prpid = 0;
1822 bool isCancel, isEvict, isPrepare;
1842 isPrepare = !(isCancel || isQuery);
1849 "Surpassed this connection's prepare limit.");
1867 if (isCancel || isQuery)
1868 {
if (!(prpid = pathlist.GetLine()))
1870 fsprep.
reqid = prpid;
1875 prpid =
PrepID->
isMine(prpid, hport, hname,
sizeof(hname));
1878 "Prepare requestid owned by an unknown server");
1880 << hname <<
':' <<hport);
1886 {prpid =
PrepID->
ID(reqid,
sizeof(reqid));
1887 fsprep.
reqid = reqid;
1890 reqid[0]=
'*'; reqid[1]=
'\0';
1891 fsprep.
reqid = prpid = reqid;
1904 while((path = pathlist.GetLine()))
1905 {
if (rpCheck(path, &opaque))
return rpEmsg(
"Preparing", path);
1906 if (!Squash(path))
return vpEmsg(
"Preparing", path);
1908 (pLast ? (pLast->next = pP) : (pFirst = pP)); pLast = pP;
1910 (oLast ? (oLast->next = oP) : (oFirst = oP)); oLast = oP;
1913 fsprep.
paths = pFirst;
1914 fsprep.
oinfo = oFirst;
1938 char *mBuff = myError.getMsgBuff(rc);
1939 pargs.reqid = prpid;
1941 pargs.paths = pFirst;
1943 if (rc < 0) rc =
Response.
Send(
"No information found.");
1971 else snprintf(nidbuff,
sizeof(nidbuff),
"%s://%s:%d/",
2005 {pargs.reqid = prpid;
2007 pargs.paths = pFirst;
2024 int XrdXrootdProtocol::do_Protocol()
2035 bool wantTLS =
false;
2060 ioVec[iovN ].iov_base = (
void *)&theResp.
secreq;
2061 ioVec[iovN++].iov_len = n;
2087 theResp.
flags = (wantTLS ? theRlt : theRle);
2089 theResp.
flags = theRlf;
2095 theResp.
pval = verNum;
2103 if (rc == 0 && wantTLS)
2119 int XrdXrootdProtocol::do_Qconf()
2123 char *val, buff[4096], *bp=buff;
2124 int n, bleft =
sizeof(buff);
2128 if (!qcargs.GetLine() || !(val = qcargs.GetToken()))
2133 if (!strcmp(val,
"cmsd") || !strcmp(val,
"xrootd"))
2134 return do_QconfCX(qcargs, val);
2142 if (!strcmp(
"bind_max", val))
2143 {n = snprintf(bp, bleft,
"%d\n",
maxStreams-1);
2144 bp += n; bleft -= n;
2146 else if (!strcmp(
"chksum", val))
2147 {
const char *csList = getenv(
"XRD_CSLIST");
2149 {n = snprintf(bp, bleft,
"chksum\n");
2150 bp += n; bleft -= n;
2153 n = snprintf(bp, bleft,
"%s\n", csList);
2154 bp += n; bleft -= n;
2156 else if (!strcmp(
"cid", val))
2157 {
const char *cidval = getenv(
"XRDCMSCLUSTERID");
2158 if (!cidval || !(*cidval)) cidval =
"cid";
2159 n = snprintf(bp, bleft,
"%s\n", cidval);
2160 bp += n; bleft -= n;
2162 else if (!strcmp(
"cms", val))
2165 n = snprintf(bp, bleft,
"%s\n", myError.getErrText());
2166 else n = snprintf(bp, bleft,
"%s\n",
"cms");
2167 bp += n; bleft -= n;
2169 else if (!strcmp(
"pio_max", val))
2170 {n = snprintf(bp, bleft,
"%d\n",
maxPio+1);
2171 bp += n; bleft -= n;
2173 else if (!strcmp(
"proxy", val))
2174 {
const char* pxyOrigin =
"proxy";
2176 {pxyOrigin = getenv(
"XRDXROOTD_PROXY");
2177 if (!pxyOrigin) pxyOrigin =
"proxy";
2179 n = snprintf(bp,bleft,
"%s\n",pxyOrigin);
2180 bp += n; bleft -= n;
2182 else if (!strcmp(
"readv_ior_max", val))
2184 bp += n; bleft -= n;
2186 else if (!strcmp(
"readv_iov_max", val))
2188 bp += n; bleft -= n;
2190 else if (!strcmp(
"role", val))
2191 {
const char *theRole = getenv(
"XRDROLE");
2192 n = snprintf(bp, bleft,
"%s\n", (theRole ? theRole :
"none"));
2193 bp += n; bleft -= n;
2195 else if (!strcmp(
"sitename", val))
2196 {
const char *siteName = getenv(
"XRDSITE");
2197 n = snprintf(bp, bleft,
"%s\n", (siteName ? siteName :
"sitename"));
2198 bp += n; bleft -= n;
2200 else if (!strcmp(
"start", val))
2201 {n = snprintf(bp, bleft,
"%s\n", startUP);
2202 bp += n; bleft -= n;
2204 else if (!strcmp(
"sysid", val))
2205 {
const char *cidval = getenv(
"XRDCMSCLUSTERID");
2206 const char *nidval = getenv(
"XRDCMSVNID");
2207 if (!cidval || !(*cidval) || !nidval || !(*nidval))
2208 {cidval =
"sysid"; nidval =
"";}
2209 n = snprintf(bp, bleft,
"%s %s\n", nidval, cidval);
2210 bp += n; bleft -= n;
2212 else if (!strcmp(
"tpc", val))
2213 {
char *tpcval = getenv(
"XRDTPC");
2214 n = snprintf(bp, bleft,
"%s\n", (tpcval ? tpcval :
"tpc"));
2215 bp += n; bleft -= n;
2217 else if (!strcmp(
"tpcdlg", val))
2218 {
char *tpcval = getenv(
"XRDTPCDLG");
2219 n = snprintf(bp, bleft,
"%s\n", (tpcval ? tpcval :
"tpcdlg"));
2220 bp += n; bleft -= n;
2222 else if (!strcmp(
"tls_port", val) &&
tlsPort)
2223 {n = snprintf(bp, bleft,
"%d\n",
tlsPort);
2224 bp += n; bleft -= n;
2226 else if (!strcmp(
"window", val) &&
Window)
2227 {n = snprintf(bp, bleft,
"%d\n",
Window);
2228 bp += n; bleft -= n;
2230 else if (!strcmp(
"version", val))
2231 {n = snprintf(bp, bleft,
"%s\n", XrdVSTRING);
2232 bp += n; bleft -= n;
2234 else if (!strcmp(
"vnid", val))
2235 {
const char *nidval = getenv(
"XRDCMSVNID");
2236 if (!nidval || !(*nidval)) nidval =
"vnid";
2237 n = snprintf(bp, bleft,
"%s\n", nidval);
2239 else if (!strcmp(
"fattr", val))
2240 {n = snprintf(bp, bleft,
"%s\n",
usxParms);
2241 bp += n; bleft -= n;
2243 else {n = strlen(val);
2244 if (bleft <= n)
break;
2245 strcpy(bp, val); bp +=n; *bp =
'\n'; bp++;
2248 }
while(bleft > 0 && (val = qcargs.GetToken()));
2267 bool isCMSD = (*val ==
'c');
2292 int XrdXrootdProtocol::do_Qfh()
2297 const char *fArg = 0, *qType =
"";
2309 "query does not refer to an open file");
2335 "Required query argument not present");
2340 TRACEP(FS,
"fh=" <<fh.handle <<
" query " <<qType <<
" rc=" <<rc);
2353 int XrdXrootdProtocol::do_Qopaque(
short qopt)
2358 const char *Act, *AData;
2366 myData.Arg2 = 0; myData.
Arg2Len = 0;
2368 Act =
" qopaque '"; AData =
"...";
2383 myData.Arg2 = opaque;
2402 TRACEP(FS,
"rc=" <<rc <<Act <<AData <<
"'");
2404 return fsError(rc, 0, myError, 0, 0);
2411 int XrdXrootdProtocol::do_Qspace()
2432 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
2447 int XrdXrootdProtocol::do_Query()
2467 case kXR_QPrep:
return do_Prepare(
true);
2474 "Invalid information query type code");
2481 int XrdXrootdProtocol::do_Qxattr()
2503 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
2517 int XrdXrootdProtocol::do_Read()
2528 else if (do_ReadNone(retc, pathID))
return retc;
2539 "read does not refer to an open file");
2543 TRACEP(FSIO, pathID <<
" fh=" <<fh.handle <<
" read " <<
IO.
IOLen
2546 "Read length is negative");
2571 if (!pathID) pP =
this;
2572 else {
if (!(pP =
VerifyStream(retc, pathID,
false)))
return retc;
2598 if (pathID)
return do_Offload(&XrdXrootdProtocol::do_ReadAll, pathID);
2602 return do_ReadAll();
2613 int XrdXrootdProtocol::do_ReadAll()
2648 {
if ((rc = getBuff(1, Quantum)) <= 0)
return rc;}
2659 IO.Offset += xframt;
IO.
IOLen -= xframt;
2673 int XrdXrootdProtocol::do_ReadNone(
int &retc,
int &pathID)
2682 pathID =
static_cast<int>(rargs->
pathid);
2683 if ((ralsz -=
sizeof(
read_args)) <= 0)
return 0;
2702 "preread does not refer to an open file");
2720 int XrdXrootdProtocol::do_ReadV()
2734 int rdVBeg, rdVBreak, rdVNow, rdVNum, rdVecNum;
2735 int currFH, i, k, Quantum, Qleft, rdVecLen =
Request.header.dlen;
2737 int ioMon = (rvMon > 1);
2738 char *buffp, vType = (ioMon ? XROOTD_MON_READU : XROOTD_MON_READV);
2743 rdVecNum = rdVecLen / sizeof(readahead_list);
2744 if ( (rdVecNum <= 0) || (rdVecNum*hdrSZ != rdVecLen) )
2745 return Response.Send(kXR_ArgInvalid, "Read vector is invalid");
2751 if (rdVecNum > XrdProto::maxRvecsz)
2752 return
Response.
Send(kXR_ArgTooLong, "Read vector is too long");
2762 raVec = (readahead_list *)
argp->buff;
2764 for (i = 0; i < rdVecNum; i++)
2765 {totSZ += (rdVec[i].size = ntohl(raVec[i].rlen));
2766 if (rdVec[i].size < 0) return Response.Send(kXR_ArgInvalid,
2767 "Readv length is negative");
2768 if (rdVec[i].size > Quantum) return Response.Send(kXR_NoMemory,
2769 "Single readv transfer is too large");
2770 rdVec[i].offset = ntohll(raVec[i].offset);
2771 memcpy(&rdVec[i].info, raVec[i].fhandle, sizeof(int));
2776 rdVec[i].offset = -1;
2779 rdVBreak = rdVecNum;
2784 if (totSZ > 0x80000000LL)
2785 return
Response.
Send(kXR_NoMemory, "Total readv transfer is too large");
2790 Quantum = totSZ < maxTransz ? totSZ : maxTransz;
2794 if ((Quantum < halfBSize && Quantum > 1024) || Quantum > argp->bsize)
2795 {
if ((k = getBuff(1, Quantum)) <= 0)
return k;}
2802 "readv does not refer to an open file");
2807 currFH = rdVec[0].info;
2808 memcpy(respHdr.fhandle, &currFH,
sizeof(respHdr.fhandle));
2810 "readv does not refer to an open file");
2815 rdVBeg = rdVNow = 0; rdVXfr = rdVAmt = 0;
2819 for (i = 0; i < rdVecNum; i++)
2820 {
if (rdVec[i].info != currFH)
2822 if (xfrSZ != rdVAmt)
break;
2823 rdVNum = i - rdVBeg; rdVXfr += rdVAmt;
2827 htons(rdVNum),
rvSeq, vType);
2828 if (ioMon)
for (k = rdVBeg; k < i; k++)
2830 htonl(rdVec[k].size), htonll(rdVec[k].offset));
2832 rdVXfr = rdVAmt = 0;
2833 if (i == rdVBreak)
break;
2834 rdVBeg = rdVNow = i; currFH = rdVec[i].info;
2835 memcpy(respHdr.fhandle, &currFH,
sizeof(respHdr.fhandle));
2838 "readv does not refer to an open file");
2841 if (Qleft < (rdVec[i].size + hdrSZ))
2844 if (xfrSZ != rdVAmt)
break;
2850 rdVNow = i; rdVXfr += rdVAmt; rdVAmt = 0;
2853 xfrSZ = rdVec[i].size; rdVAmt += xfrSZ;
2854 respHdr.rlen = htonl(xfrSZ);
2855 respHdr.offset = htonll(rdVec[i].offset);
2856 memcpy(buffp, &respHdr, hdrSZ);
2857 rdVec[i].data = buffp + hdrSZ;
2858 buffp += (xfrSZ+hdrSZ); Qleft -= (xfrSZ+hdrSZ);
2859 TRACEP(FSIO,
"fh=" <<currFH<<
" readV "<< xfrSZ <<
'@'<<rdVec[i].offset);
2881 int XrdXrootdProtocol::do_Rm()
2911 int XrdXrootdProtocol::do_Rmdir()
2941 int XrdXrootdProtocol::do_Set()
2948 if (!setargs.GetLine() || !(val = setargs.GetToken(&rest)))
2957 if (!strcmp(
"appid", val))
2958 {
while(*rest && *rest ==
' ') rest++;
2962 else if (!strcmp(
"monitor", val))
return do_Set_Mon(setargs);
2963 else if (!strcmp(
"cache", val))
return do_Set_Cache(setargs);
2980 char *cmd, *cargs, *opaque =
nullptr;
2981 const char *myArgs[2];
2990 if (!(cmd = setargs.
GetToken(&cargs)))
2995 if (cargs && *cargs ==
'/')
2996 {
if (rpCheck(cargs, &opaque))
return rpEmsg(
"Setting", cargs);
2997 if (!Squash(cargs))
return vpEmsg(
"Setting", cargs);
2998 myData.ArgP = myArgs; myData.
Arg2Len = -2;
3002 myData.Arg2 = opaque; myData.
Arg2Len = (opaque ? strlen(opaque) : 0);
3009 TRACEP(FS,
"rc=" <<rc <<
"set cache " <<myData.
Arg1 <<
' ' <<cargs);
3011 return fsError(rc, 0, myError, 0, 0);
3027 if (!(val = setargs.
GetToken(&appid)))
3034 if (!strcmp(val,
"info"))
3036 {
while(*appid && *appid ==
' ') appid++;
3037 if (strlen(appid) > 1024) appid[1024] =
'\0';
3045 if (!strcmp(val,
"on"))
3048 {
while(*appid && *appid ==
' ') appid++;
3057 if (!strcmp(val,
"off"))
3059 {
while(*appid && *appid ==
' ') appid++;
3075 int XrdXrootdProtocol::do_Stat()
3081 char *opaque, xxBuff[1024];
3100 "stat does not refer to an open file");
3104 StatGen(buf,xxBuff,
sizeof(xxBuff)));
3127 memmove(&
argp->
buff[n+1], opaque, strlen(opaque)+1);
3137 StatGen(buf,xxBuff,
sizeof(xxBuff)));
3146 int XrdXrootdProtocol::do_Statx()
3150 char *path, *opaque, *respinfo =
argp->
buff;
3161 while((path = pathlist.GetLine()))
3162 {
if (rpCheck(path, &opaque))
return rpEmsg(
"Stating", path);
3163 if (!Squash(path))
return vpEmsg(
"Stating", path);
3165 TRACEP(FS,
"rc=" <<rc <<
" stat " <<path);
3168 else {
if (mode == (mode_t)-1) *respinfo = (char)
kXR_offline;
3169 else if (S_ISDIR(mode)) *respinfo = (
char)
kXR_isDir;
3184 int XrdXrootdProtocol::do_Sync()
3219 int XrdXrootdProtocol::do_Truncate()
3224 long long theOffset;
3243 "trunc does not refer to an open file");
3249 TRACEP(FS,
"fh=" <<fh.
handle <<
" trunc rc=" <<rc <<
" sz=" <<theOffset);
3270 TRACEP(FS,
"rc=" <<rc <<
" trunc " <<theOffset <<
' ' <<
argp->
buff);
3284 int XrdXrootdProtocol::do_Write()
3300 return do_WriteNone(pathID);
3307 "Write length is negative");
3326 {
if (pathID)
return do_Offload(&XrdXrootdProtocol::do_WriteAio,pathID);
3327 return do_WriteAio();
3335 if (pathID)
return do_Offload(&XrdXrootdProtocol::do_WriteAll, pathID);
3339 return do_WriteAll();
3350 int XrdXrootdProtocol::do_WriteAio()
3360 return do_WriteAll();
3376 int XrdXrootdProtocol::do_WriteAll()
3383 {
if ((rc = getBuff(0, Quantum)) <= 0)
return rc;}
3391 {
Resume = &XrdXrootdProtocol::do_WriteCont;
3398 return do_WriteNone();
3400 IO.Offset += Quantum;
IO.
IOLen -= Quantum;
3418 int XrdXrootdProtocol::do_WriteCont()
3426 return do_WriteNone();
3432 if (
IO.
IOLen > 0)
return do_WriteAll();
3440 int XrdXrootdProtocol::do_WriteNone()
3442 char *buff, dbuff[4096];
3452 blen =
sizeof(dbuff);
3461 if (rlen < 0)
return Link->
setEtext(
"link read error");
3465 Resume = &XrdXrootdProtocol::do_WriteNone;
3473 return do_WriteNoneMsg();
3478 int XrdXrootdProtocol::do_WriteNone(
int pathID,
XErrorCode ec,
3486 else do_WriteNoneMsg();
3502 return do_WriteNone();
3509 int XrdXrootdProtocol::do_WriteNoneMsg()
3563 return do_WriteNone();
3569 if (
IO.
IOLen > 0)
return do_WriteAll();
3577 int XrdXrootdProtocol::do_WriteV()
3595 long long totSZ, maxSZ;
3601 wrVecNum = wrVecLen / wveSZ;
3602 if ( (wrVecLen <= 0) || (wrVecNum*wveSZ != wrVecLen) )
3628 totSZ = 0; maxSZ = 0; k = 0; Quantum =
maxTransz; curFH = 0;
3629 for (
int i = 0; i < wrVecNum; i++)
3630 {
if (wrLst[i].
wlen == 0)
continue;
3631 memcpy(&wrVec[k].info, wrLst[i].
fhandle,
sizeof(
int));
3632 wrVec[k].
size = ntohl(wrLst[i].
wlen);
3633 if (wrVec[k].size < 0)
3637 if (wrVec[k].size > Quantum)
3642 if (wrVec[k].info == curFH) totSZ += wrVec[k].
size;
3643 else {
if (maxSZ < totSZ) maxSZ = totSZ;
3644 totSZ = wrVec[k].
size;
3651 if (maxSZ < totSZ) maxSZ = totSZ;
3662 else Quantum =
static_cast<int>(maxSZ);
3666 if ((Quantum < halfBSize && Quantum > 1024) || Quantum >
argp->
bsize)
3667 {
if (getBuff(0, Quantum) <= 0)
return -1;}
3696 freeInfo.doit =
false;
3705 int XrdXrootdProtocol::do_WriteVec()
3718 {
if (rc < 0)
return rc;
3720 Resume = &XrdXrootdProtocol::do_WriteVec;
3728 done = newfile =
false;
3748 if (done || newfile)
3765 if (xfrSZ< 0)
break;
3831 for (i = 1; i < sfvnum; i++) xframt += sfvec[i].sendsz;
3832 if (xframt >
IO.
IOLen)
return 1;
3848 else IO.
File->fdNum = fildes;
3858 int XrdXrootdProtocol::fsError(
int rc,
char opC,
XrdOucErrInfo &myError,
3859 const char *
Path,
char *Cgi)
3861 int ecode, popt, rs;
3873 return fsOvrld(opC,
Path, Cgi);
3883 if (Cgi) rs = fsRedirNoEnt(
eMsg, Cgi, popt);
3906 <<
eMsg <<
':' <<ecode);
3923 if (ecode <= 0) ecode = 1800;
3928 return (rc ? rc : 1);
3964 sprintf(buff,
"%d", rc);
3976 int XrdXrootdProtocol::fsOvrld(
char opC,
const char *
Path,
char *Cgi)
3978 static const char *prot =
"root://";
3979 static int negOne = -1;
3980 static char quest =
'?', slash =
'/';
3982 struct iovec rdrResp[8];
3983 char *destP=0, dest[512];
3984 int iovNum=0, pOff, port;
3992 { rdrResp[1].iov_base = (
char *)&negOne;
3993 rdrResp[1].iov_len =
sizeof(negOne);
3994 rdrResp[2].iov_base = (
char *)prot;
3995 rdrResp[2].iov_len = 7;
3996 rdrResp[3].iov_base = (
char *)dest;
3997 rdrResp[3].iov_len = strlen(dest);
3998 rdrResp[4].iov_base = (
char *)&slash;
3999 rdrResp[4].iov_len = (*
Path ==
'/' ? 1 : 0);
4000 rdrResp[5].iov_base = (
char *)(
Path+pOff);
4001 rdrResp[5].iov_len = strlen(
Path+pOff);
4003 {rdrResp[6].iov_base = (
char *)?
4004 rdrResp[6].iov_len =
sizeof(quest);
4005 rdrResp[7].iov_base = (
char *)Cgi;
4006 rdrResp[7].iov_len = strlen(Cgi);
4046 int XrdXrootdProtocol::fsRedirNoEnt(
const char *
eMsg,
char *Cgi,
int popt)
4048 struct iovec ioV[4];
4049 char *tried, *trend, *ptried = 0;
4056 {
do {
if (!(tried = strstr(Cgi,
"tried=")))
break;
4057 if (tried == trend || *(tried-1) ==
'&')
4058 {
if (!ptried || (*(tried+6) && *(tried+6) !=
'&')) ptried=tried;}
4059 Cgi = index(tried+6,
'&');
4066 if ((tried = ptried))
4068 while(*(tried+1) && *(tried+1) ==
',') tried++;
4069 trend = index(tried,
'&');
4070 if (trend) {tlen = trend - tried; *trend = 0;}
4071 else tlen = strlen(tried);
4078 if ((trend = tried) &&
eMsg)
4079 do {
if ((trend = strstr(trend,
myCName)))
4082 trend = index(trend+
myCNlen,
',');
4090 if (!tried || !tlen || tlen > 16384)
4098 ioV[1].iov_base = (
char *)&pnum;
4099 ioV[1].iov_len =
sizeof(pnum);
4102 ioV[3].iov_base = tried;
4103 ioV[3].iov_len = tlen;
4134 auto cmpchr = [](
const char* a,
const char* b) {
return strcmp(a,b)<0;};
4144 auto it = niMap.find(netID);
4145 if (it == niMap.end())
4147 niMap[niP->
netID] = niP;
4148 }
else niP = it->second;
4156 time_t nowT = time(0);
4159 {
const char* eTxt = niP->
netAddr.
Set(netID, port);
4162 {
eDest.
Emsg(
"RedirIP",
"Unable to init NetInfo for", netID, eTxt);
4167 eDest.
Emsg(
"RedirIP",
"Unable to refresh NetInfo for", netID, eTxt);
4182 int XrdXrootdProtocol::fsRedirPI(
const char *trg,
int port,
int trglen)
4186 THandle() :
Info(0) {}
4187 ~THandle() {
if (
Info)
Info->refs--;}
4196 const char* TCgi = index(trg,
'?');
4197 if (!TCgi) {TCgi =
""; TDst = trg;}
4198 else TDst.assign(trg, TCgi-trg);
4199 T.Info = fsRedirIP(TDst.c_str(), port);
4201 uint16_t TPort =
static_cast<uint16_t
>(newPort);
4202 Target =
RedirPI->
Redirect(TDst.c_str(), TPort, TCgi, T.Info->netAddr,
4204 newPort =
static_cast<int>(TPort);
4212 std::string urlHead, TDst, urlPort;
4213 const char* urlTail;
4214 const char* hBeg = strstr(trg,
"://");
4216 {
eDest.
Emsg(
"RedirPI",
"Invalid redirect URL -", trg);
4220 urlHead.assign(trg, hBeg-trg);
4221 urlTail = strstr(hBeg,
"/");
4222 if (!urlTail) {urlTail =
""; TDst = hBeg;}
4223 else {
if (urlTail-hBeg < 3)
4224 {
eDest.
Emsg(
"RedirPI",
"Mlalformed URL -", trg);
4227 TDst.assign(hBeg, urlTail-hBeg);
4229 T.Info = fsRedirIP(TDst.c_str(), port);
4231 size_t colon = TDst.find(
":");
4232 if (colon != std::string::npos)
4233 {urlPort.assign(TDst, colon+1, std::string::npos);
4237 urlPort.c_str(), urlTail, newPort,
4239 if (port == -1 || newPort >= 0) newPort = port;
4246 if (Target.front() !=
'!')
4248 <<Target.c_str() <<
" portarg="<<newPort);
4256 snprintf(mbuff,
sizeof(mbuff),
"Redirect failed; %s",Target.c_str());
4265 int XrdXrootdProtocol::getBuff(
const int isRead,
int Quantum)
4284 "insufficient memory to read file" :
4285 "insufficient memory to write file"));
4296 char *XrdXrootdProtocol::getCksType(
char *opaque,
char *cspec,
int cslen)
4302 if (opaque && *opaque)
4304 if ((cksT = jobEnv.Get(
"cks.type")))
4306 while(tP && strcasecmp(tP->
text, cksT)) tP = tP->
next;
4307 if (!tP && cspec) snprintf(cspec, cslen,
"%s", cksT);
4308 return (tP ? tP->
text : 0);
4321 bool XrdXrootdProtocol::logLogin(
bool xauth)
4323 const char *uName, *ipName, *tMsg, *zMsg =
"";
4324 char lBuff[512], pBuff[512];
4340 if (*tMsg) zMsg =
" ";
4344 snprintf(lBuff,
sizeof(lBuff),
"%s %s %s%slogin%s%s",
4347 (xauth ?
" as " :
""),
4348 (uName ? uName :
""));
4353 {snprintf(pBuff,
sizeof(pBuff),
"via %s auth for %s",
4371 eDest.
Emsg(
"Xeq",
"session requires TLS but",
Link->
ID,
"is incapable.");
4395 #define Map_Mode(x,y) if (Mode & kXR_ ## x) newmode |= S_I ## y
4397 int XrdXrootdProtocol::mapMode(
int Mode)
4419 const char *bP = Buff;
4422 else {snprintf(Buff,
sizeof(Buff),
4423 "&p=%s&n=%s&h=%s&o=%s&r=%s&g=%s&m=%s%s&I=%c",
4445 int XrdXrootdProtocol::rpCheck(
char *fn,
char **opaque)
4454 if (!(cp = index(fn,
'?'))) *opaque = 0;
4455 else {*cp =
'\0'; *opaque = cp+1;
4456 if (!**opaque) *opaque = 0;
4459 if (*fn !=
'/')
return 0;
4461 while ((cp = index(fn,
'/')))
4463 if (fn[0] ==
'.' && fn[1] ==
'.' && (fn[2] ==
'/' || fn[2] ==
'\0'))
4473 int XrdXrootdProtocol::rpEmsg(
const char *op,
char *fn)
4476 snprintf(buff,
sizeof(buff)-1,
"%s relative path '%s' is disallowed.",op,fn);
4477 buff[
sizeof(buff)-1] =
'\0';
4495 else if (theFile->fdNum >= 0) theFile->
sfEnabled = 1;
4506 int XrdXrootdProtocol::Squash(
char *fn)
4508 char *ofn, *ifn = fn;
4515 || (*(ifn+1) ==
'.' && *(ifn+1) && *(ifn+2) ==
'/'))
break;
4522 while(*ifn) {*ofn = *ifn++;
4524 {
while(*ifn ==
'/') ifn++;
4525 if (ifn[0] ==
'.' && ifn[1] ==
'/') ifn += 2;
4539 int XrdXrootdProtocol::vpEmsg(
const char *op,
char *fn)
4542 snprintf(buff,
sizeof(buff)-1,
"%s path '%s' is disallowed.",op,fn);
4543 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
struct ClientCloneRequest clone
int emsg(int rc, char *msg)
const char * Arg1
PLUGFS, PLUGIN, PLUGIO, 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/PLUGFS 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)
static std::string UrlEncode(const std::string &input)
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 Clone(XrdSfsFile &srcFile)
virtual int truncate(XrdSfsFileOffset fsize)=0
virtual const char * FName()=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 maxClonesz
static const int maxWvecsz
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasSXIO
Feature: Supports SfsXio.
static const uint64_t hasFICL
Feature: Supports file cloning and samefs.
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