00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdCmsParserCVSID = "$Id: XrdCmsParser.cc 35287 2010-09-14 21:19:35Z ganis $";
00014
00015 #include <stdio.h>
00016 #include <errno.h>
00017 #include <inttypes.h>
00018 #include <stdarg.h>
00019 #include <stddef.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <netinet/in.h>
00023 #include <sys/types.h>
00024
00025 #include "XrdCms/XrdCmsParser.hh"
00026 #include "XrdCms/XrdCmsRRData.hh"
00027 #include "XrdCms/XrdCmsTrace.hh"
00028
00029 #include "XrdOuc/XrdOucErrInfo.hh"
00030
00031 #include "XrdSys/XrdSysError.hh"
00032
00033 using namespace XrdCms;
00034
00035
00036
00037
00038
00039 class XrdCmsParseInit
00040 {
00041 public:
00042
00043 const char **nameVec() {return (const char **)PupNVec;}
00044
00045 XrdCmsParseInit(int mVal, ...)
00046 {va_list ap;
00047 int vp = mVal;
00048 const char *Dummy;
00049 memset(PupNVec, 0, sizeof(PupNVec));
00050 va_start(ap, mVal);
00051 do { if (vp < XrdCmsRRData::Arg_Count)
00052 PupNVec[vp] = va_arg(ap, char *);
00053 else Dummy = va_arg(ap, char *);
00054 } while((vp = va_arg(ap, int)));
00055 va_end(ap);
00056 }
00057 ~XrdCmsParseInit() {}
00058
00059 private:
00060
00061 static char *PupNVec[XrdCmsRRData::Arg_Count];
00062
00063 };
00064
00065
00066
00067
00068
00069 char *XrdCmsParseInit::PupNVec[XrdCmsRRData::Arg_Count];
00070
00071 XrdCmsParseInit XrdCmsParseArgN(XrdCmsRRData::Arg_Null, "",
00072 XrdCmsRRData::Arg_AToken, "authtoken",
00073 XrdCmsRRData::Arg_Avoid, "bad_host",
00074 XrdCmsRRData::Arg_Datlen, "datalen",
00075 XrdCmsRRData::Arg_Ident, "ident",
00076 XrdCmsRRData::Arg_Mode, "mode",
00077 XrdCmsRRData::Arg_Notify, "notify",
00078 XrdCmsRRData::Arg_Opaque, "opaque",
00079 XrdCmsRRData::Arg_Opaque2, "opaque2",
00080 XrdCmsRRData::Arg_Opts, "opts",
00081 XrdCmsRRData::Arg_Path, "path",
00082 XrdCmsRRData::Arg_Path2, "path2",
00083 XrdCmsRRData::Arg_Prty, "prty",
00084 XrdCmsRRData::Arg_Reqid, "reqid",
00085 XrdCmsRRData::Arg_dskFree, "diskfree",
00086 XrdCmsRRData::Arg_dskTot, "disktotal",
00087 XrdCmsRRData::Arg_dskMinf, "diskminf",
00088 XrdCmsRRData::Arg_dskUtil, "diskutil",
00089 XrdCmsRRData::Arg_theLoad, "load",
00090 XrdCmsRRData::Arg_Info, "info",
00091 XrdCmsRRData::Arg_Port, "port",
00092 0, (const char *)0
00093 );
00094
00095
00096
00097 XrdOucPupNames XrdCmsParser::PupName(XrdCmsParseArgN.nameVec(),
00098 XrdCmsRRData::Arg_Count);
00099
00100
00101
00102 XrdOucPup XrdCmsParser::Pup(&Say, &XrdCmsParser::PupName);
00103
00104
00105
00106 XrdOucPupArgs *XrdCmsParser::vecArgs[kYR_MaxReq] = {0};
00107
00108
00109
00110 XrdCmsParser XrdCms::Parser;
00111
00112
00113
00114
00115
00116
00117
00118 XrdOucPupArgs XrdCmsParser::fwdArgA[] =
00119 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00120 setPUP1(XrdCmsRRData::Arg_Mode, char, XrdCmsRRData, Mode),
00121 setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00122 setPUP0(Fence),
00123 setPUP1(XrdCmsRRData::Arg_Opaque, char, XrdCmsRRData, Opaque),
00124 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00125 };
00126
00127
00128
00129 XrdOucPupArgs XrdCmsParser::fwdArgB[] =
00130 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00131 setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00132 setPUP1(XrdCmsRRData::Arg_Path2, char, XrdCmsRRData, Path2),
00133 setPUP0(Fence),
00134 setPUP1(XrdCmsRRData::Arg_Opaque, char, XrdCmsRRData, Opaque),
00135 setPUP1(XrdCmsRRData::Arg_Opaque2, char, XrdCmsRRData, Opaque2),
00136 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00137 };
00138
00139
00140
00141 XrdOucPupArgs XrdCmsParser::fwdArgC[] =
00142 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00143 setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00144 setPUP0(Fence),
00145 setPUP1(XrdCmsRRData::Arg_Opaque, char, XrdCmsRRData, Opaque),
00146 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00147 };
00148
00149
00150
00151 XrdOucPupArgs XrdCmsParser::locArgs[] =
00152 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00153 setPUP1(XrdCmsRRData::Arg_Opts, int, XrdCmsRRData, Opts),
00154 setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00155 setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00156 setPUP0(Fence),
00157 setPUP1(XrdCmsRRData::Arg_Opaque, char, XrdCmsRRData, Opaque),
00158 setPUP1(XrdCmsRRData::Arg_Avoid, char, XrdCmsRRData, Avoid),
00159 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00160 };
00161
00162
00163
00164 XrdOucPupArgs XrdCmsParser::padArgs[] =
00165 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00166 setPUP1(XrdCmsRRData::Arg_Reqid, char, XrdCmsRRData, Reqid),
00167 setPUP1(XrdCmsRRData::Arg_Notify, char, XrdCmsRRData, Notify),
00168 setPUP1(XrdCmsRRData::Arg_Prty, char, XrdCmsRRData, Prty),
00169 setPUP1(XrdCmsRRData::Arg_Mode, char, XrdCmsRRData, Mode),
00170 setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00171 setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00172 setPUP0(Fence),
00173 setPUP1(XrdCmsRRData::Arg_Opaque, char, XrdCmsRRData, Opaque),
00174 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00175 };
00176
00177
00178
00179 XrdOucPupArgs XrdCmsParser::pdlArgs[] =
00180 {setPUP1(XrdCmsRRData::Arg_Ident, char, XrdCmsRRData, Ident),
00181 setPUP1(XrdCmsRRData::Arg_Reqid, char, XrdCmsRRData, Reqid),
00182 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00183 };
00184
00185
00186
00187 XrdOucPupArgs XrdCmsParser::avlArgs[] =
00188 {setPUP1(XrdCmsRRData::Arg_dskFree, int, XrdCmsRRData, dskFree),
00189 setPUP1(XrdCmsRRData::Arg_dskUtil, int, XrdCmsRRData, dskUtil),
00190 setPUP0(End)
00191 };
00192
00193
00194
00195 XrdOucPupArgs XrdCmsParser::pthArgs[] =
00196 {setPUP1(XrdCmsRRData::Arg_Path, char, XrdCmsRRData, Path),
00197 setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00198 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00199 };
00200
00201
00202
00203 XrdOucPupArgs XrdCmsParser::lodArgs[] =
00204 {setPUP1(XrdCmsRRData::Arg_theLoad, char, XrdCmsRRData, Opaque),
00205 setPUP1(XrdCmsRRData::Arg_dskFree, int, XrdCmsRRData, dskFree),
00206 setPUP0(End)
00207 };
00208
00209 XrdOucPupArgs XrdCmsParser::logArgs[] =
00210 {setPUP1(XrdCmsRRData::Arg_Ident, short, CmsLoginData, Version),
00211 setPUP1(XrdCmsRRData::Arg_Mode, int, CmsLoginData, Mode),
00212 setPUP1(XrdCmsRRData::Arg_Info, int, CmsLoginData, HoldTime),
00213 setPUP1(XrdCmsRRData::Arg_dskTot, int, CmsLoginData, tSpace),
00214 setPUP1(XrdCmsRRData::Arg_dskFree, int, CmsLoginData, fSpace),
00215 setPUP1(XrdCmsRRData::Arg_dskMinf, int, CmsLoginData, mSpace),
00216 setPUP1(XrdCmsRRData::Arg_Info, short, CmsLoginData, fsNum),
00217 setPUP1(XrdCmsRRData::Arg_dskUtil, short, CmsLoginData, fsUtil),
00218 setPUP1(XrdCmsRRData::Arg_Port, short, CmsLoginData, dPort),
00219 setPUP1(XrdCmsRRData::Arg_Port, short, CmsLoginData, sPort),
00220 setPUP0(Fence),
00221 setPUP1(XrdCmsRRData::Arg_SID, char, CmsLoginData, SID),
00222 setPUP1(XrdCmsRRData::Arg_Path, char, CmsLoginData, Paths),
00223 setPUP1(XrdCmsRRData::Arg_Datlen,EndFill, CmsLoginData, Size)
00224 };
00225
00226
00227
00228
00229
00230 XrdCmsParser::XrdCmsParser()
00231 {
00232 static int Done = 0;
00233
00234
00235
00236 if (!Done)
00237 {vecArgs[kYR_login] = logArgs;
00238 vecArgs[kYR_chmod] = fwdArgA;
00239 vecArgs[kYR_locate] = locArgs;
00240 vecArgs[kYR_mkdir] = fwdArgA;
00241 vecArgs[kYR_mkpath] = fwdArgA;
00242 vecArgs[kYR_mv] = fwdArgB;
00243 vecArgs[kYR_prepadd] = padArgs;
00244 vecArgs[kYR_prepdel] = pdlArgs;
00245 vecArgs[kYR_rm] = fwdArgC;
00246 vecArgs[kYR_rmdir] = fwdArgC;
00247 vecArgs[kYR_select] = locArgs;
00248 vecArgs[kYR_rm] = fwdArgC;
00249 vecArgs[kYR_statfs] = pthArgs;
00250 vecArgs[kYR_avail] = avlArgs;
00251 vecArgs[kYR_gone] = pthArgs;
00252 vecArgs[kYR_trunc] = fwdArgA;
00253 vecArgs[kYR_try] = pthArgs;
00254 vecArgs[kYR_have] = pthArgs;
00255 vecArgs[kYR_load] = lodArgs;
00256 vecArgs[kYR_state] = pthArgs;
00257 Done = 1;
00258 }
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 int XrdCmsParser::Decode(const char *Man, CmsRRHdr &hdr, char *data, int dlen,
00268 XrdOucErrInfo *eInfo)
00269 {
00270 EPNAME("Decode");
00271 static const int mvsz = static_cast<int>(sizeof(kXR_unt32));
00272 kXR_unt32 uval;
00273 int Result, msgval, msglen;
00274 const char *Path = eInfo->getErrText(), *User = eInfo->getErrUser();
00275 const char *Mgr = (Man ? Man : "?");
00276 char *msg;
00277
00278
00279
00280 if (dlen < mvsz) {msgval = 0; msg = (char *)""; msglen = 0;}
00281 else {memcpy(&uval, data, mvsz);
00282 msgval = static_cast<int>(ntohl(uval));
00283 if (dlen == mvsz) {msg = (char *)""; msglen = 0;}
00284 else {msg = data+mvsz; msglen = dlen - mvsz;}
00285 }
00286
00287
00288
00289 switch(hdr.rrCode)
00290
00291 {case kYR_redirect: Result = -EREMOTE;
00292 TRACE(Redirect, Mgr <<" redirects " <<User <<" to "
00293 <<msg <<':' <<msgval <<' ' <<Path);
00294 break;
00295 case kYR_wait: Result = -EAGAIN;
00296 TRACE(Redirect, Mgr <<" delays " <<User <<' ' <<msgval <<' ' <<Path);
00297 break;
00298 case kYR_waitresp: Result = -EINPROGRESS;
00299 TRACE(Redirect, Mgr <<" idles " <<User <<' ' <<msgval <<' ' <<Path);
00300 break;
00301 case kYR_data: Result = -EALREADY; msgval = msglen;
00302 TRACE(Redirect, Mgr <<" sent " <<User <<" '" <<msg <<"' " <<Path);
00303 break;
00304 case kYR_error: Result = -EINVAL;
00305 if (msgval) msgval = -mapError(msgval);
00306 TRACE(Redirect, Mgr <<" gave " <<User <<" err " <<msgval
00307 <<" '" <<msg <<"' " <<Path);
00308 break;
00309 default: msgval=0; Result = -EINVAL;
00310 msg = (char *)"Redirector protocol error";
00311 TRACE(Redirect, User <<" given error msg '"
00312 <<msg <<"' due to " << Mgr <<' ' <<Path);
00313 }
00314
00315
00316
00317 eInfo->setErrInfo(msgval, msg);
00318 return Result;
00319 }
00320
00321
00322
00323
00324
00325 int XrdCmsParser::mapError(const char *ecode)
00326 {
00327 if (!strcmp("ENOENT", ecode)) return ENOENT;
00328 if (!strcmp("EPERM", ecode)) return EPERM;
00329 if (!strcmp("EACCES", ecode)) return EACCES;
00330 if (!strcmp("EIO", ecode)) return EIO;
00331 if (!strcmp("ENOMEM", ecode)) return ENOMEM;
00332 if (!strcmp("ENOSPC", ecode)) return ENOSPC;
00333 if (!strcmp("ENAMETOOLONG", ecode)) return ENAMETOOLONG;
00334 if (!strcmp("ENETUNREACH", ecode)) return ENETUNREACH;
00335 if (!strcmp("ENOTBLK", ecode)) return ENOTBLK;
00336 if (!strcmp("EISDIR", ecode)) return EISDIR;
00337 return EINVAL;
00338 }
00339
00340 int XrdCmsParser::mapError(int ecode)
00341 {
00342 switch(ecode)
00343 {case kYR_ENOENT: return ENOENT;
00344 case kYR_EPERM: return EPERM;
00345 case kYR_EACCES: return EACCES;
00346 case kYR_EIO: return EIO;
00347 case kYR_ENOMEM: return ENOMEM;
00348 case kYR_ENOSPC: return ENOSPC;
00349 case kYR_ENAMETOOLONG: return ENAMETOOLONG;
00350 case kYR_ENETUNREACH: return ENETUNREACH;
00351 case kYR_ENOTBLK: return ENOTBLK;
00352 case kYR_EISDIR: return EISDIR;
00353 default: return EINVAL;
00354 }
00355 }
00356
00357
00358
00359
00360
00361 int XrdCmsParser::Pack(int rnum, struct iovec *iovP, struct iovec *iovE,
00362 char *Base, char *Work)
00363 {
00364 XrdOucPupArgs *PArgs;
00365 const char *reason;
00366 char buff[16];
00367 int iovcnt;
00368
00369
00370
00371 if ((PArgs = PupArgs(rnum)))
00372 if ((iovcnt = Pup.Pack(iovP, iovE, PArgs, Base, Work))) return iovcnt;
00373 else reason = "too much data for code";
00374 else reason = "invalid request code -";
00375
00376
00377
00378
00379 sprintf(buff, "%d", rnum);
00380 Say.Emsg("Pack", "Unable to pack request;", reason, buff);
00381 return 0;
00382 }