XrdCmsParser.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d C m s P a r s e r . c c                        */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdCmsParser.cc 35287 2010-09-14 21:19:35Z ganis $
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 /*                         L o c a l   C l a s s e s                          */
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 /*                        S t a t i c   O b j e c t s                         */
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 // The structure that defines the item names to the packer/unpacker
00096 //
00097 XrdOucPupNames XrdCmsParser::PupName(XrdCmsParseArgN.nameVec(),
00098                                      XrdCmsRRData::Arg_Count);
00099 
00100 // Common protocol data unpacker
00101 //
00102 XrdOucPup      XrdCmsParser::Pup(&Say, &XrdCmsParser::PupName);
00103 
00104 // Reference array
00105 //
00106 XrdOucPupArgs *XrdCmsParser::vecArgs[kYR_MaxReq] = {0};
00107 
00108 // The actual parser object
00109 //
00110 XrdCmsParser   XrdCms::Parser;
00111 
00112 /******************************************************************************/
00113 /*          S t a t i c   P a r s i n g   D e s i f i n i t i o n s           */
00114 /******************************************************************************/
00115   
00116 // {chmod, mkdir, mkpath, trunc} <id> <mode> <path> [<opq>]
00117 //
00118 XrdOucPupArgs XrdCmsParser::fwdArgA[] =
00119 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00120 /*1*/         setPUP1(XrdCmsRRData::Arg_Mode,    char, XrdCmsRRData, Mode),
00121 /*2*/         setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00122 /*3*/         setPUP0(Fence),
00123 /*4*/         setPUP1(XrdCmsRRData::Arg_Opaque,  char, XrdCmsRRData, Opaque),
00124 /*5*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00125              };
00126 
00127 // mv <id> <path1> <path2> [<opq1> [<opq2>]]
00128 //
00129 XrdOucPupArgs XrdCmsParser::fwdArgB[] =
00130 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00131 /*1*/         setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00132 /*2*/         setPUP1(XrdCmsRRData::Arg_Path2,   char, XrdCmsRRData, Path2),
00133 /*3*/         setPUP0(Fence),
00134 /*4*/         setPUP1(XrdCmsRRData::Arg_Opaque,  char, XrdCmsRRData, Opaque),
00135 /*5*/         setPUP1(XrdCmsRRData::Arg_Opaque2, char, XrdCmsRRData, Opaque2),
00136 /*6*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00137              };
00138 
00139 // {rm, rmdir, statfs} <id> <path> <opq>
00140 //
00141 XrdOucPupArgs XrdCmsParser::fwdArgC[] =
00142 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00143 /*1*/         setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00144 /*2*/         setPUP0(Fence),
00145 /*3*/         setPUP1(XrdCmsRRData::Arg_Opaque,  char, XrdCmsRRData, Opaque),
00146 /*4*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00147             };
00148 
00149 // {locate, select} <id> <opts> <path> [<opq> [<avoid>]]
00150 //
00151 XrdOucPupArgs XrdCmsParser::locArgs[] =
00152 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00153 /*1*/         setPUP1(XrdCmsRRData::Arg_Opts,    int,  XrdCmsRRData, Opts),
00154 /*2*/         setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00155 /*3*/         setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00156 /*4*/         setPUP0(Fence),
00157 /*5*/         setPUP1(XrdCmsRRData::Arg_Opaque,  char, XrdCmsRRData, Opaque),
00158 /*6*/         setPUP1(XrdCmsRRData::Arg_Avoid,   char, XrdCmsRRData, Avoid),
00159 /*7*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00160              };
00161 
00162 // prepadd <id> <reqid> <notify> <prty> <mode> <path> [<opaque>]
00163 //
00164 XrdOucPupArgs XrdCmsParser::padArgs[] =
00165 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00166 /*1*/         setPUP1(XrdCmsRRData::Arg_Reqid,   char, XrdCmsRRData, Reqid),
00167 /*2*/         setPUP1(XrdCmsRRData::Arg_Notify,  char, XrdCmsRRData, Notify),
00168 /*3*/         setPUP1(XrdCmsRRData::Arg_Prty,    char, XrdCmsRRData, Prty),
00169 /*4*/         setPUP1(XrdCmsRRData::Arg_Mode,    char, XrdCmsRRData, Mode),
00170 /*5*/         setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00171 /*6*/         setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00172 /*7*/         setPUP0(Fence),
00173 /*8*/         setPUP1(XrdCmsRRData::Arg_Opaque,  char, XrdCmsRRData, Opaque),
00174 /*9*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00175              };
00176 
00177 // prepdel <id> <reqid>
00178 //
00179 XrdOucPupArgs XrdCmsParser::pdlArgs[] =
00180 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   char, XrdCmsRRData, Ident),
00181 /*1*/         setPUP1(XrdCmsRRData::Arg_Reqid,   char, XrdCmsRRData, Reqid),
00182 /*2*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00183              };
00184 
00185 // avail   <dskFree> <dskUtil>
00186 //
00187 XrdOucPupArgs XrdCmsParser::avlArgs[] =
00188 /*0*/        {setPUP1(XrdCmsRRData::Arg_dskFree, int, XrdCmsRRData, dskFree),
00189 /*1*/         setPUP1(XrdCmsRRData::Arg_dskUtil, int, XrdCmsRRData, dskUtil),
00190 /*2*/         setPUP0(End)
00191              };
00192 
00193 // try <path>
00194 //
00195 XrdOucPupArgs XrdCmsParser::pthArgs[] =
00196 /*0*/        {setPUP1(XrdCmsRRData::Arg_Path,    char, XrdCmsRRData, Path),
00197 /*1*/         setPUP1(XrdCmsRRData::Arg_Datlen,Datlen, XrdCmsRRData, PathLen),
00198 /*2*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,XrdCmsRRData, Request.datalen)
00199              };
00200 
00201 // load <cpu> <io> <load> <mem> <pag> <dut> <dsk>
00202 //      0     1    2      3     5     5
00203 XrdOucPupArgs XrdCmsParser::lodArgs[] =
00204 /*0*/        {setPUP1(XrdCmsRRData::Arg_theLoad, char, XrdCmsRRData, Opaque),
00205 /*1*/         setPUP1(XrdCmsRRData::Arg_dskFree, int,  XrdCmsRRData, dskFree),
00206 /*2*/         setPUP0(End)
00207              };
00208 
00209 XrdOucPupArgs XrdCmsParser::logArgs[] =
00210 /*0*/        {setPUP1(XrdCmsRRData::Arg_Ident,   short,   CmsLoginData, Version),
00211 /*1*/         setPUP1(XrdCmsRRData::Arg_Mode,    int,     CmsLoginData, Mode),
00212 /*2*/         setPUP1(XrdCmsRRData::Arg_Info,    int,     CmsLoginData, HoldTime),
00213 /*3*/         setPUP1(XrdCmsRRData::Arg_dskTot,  int,     CmsLoginData, tSpace),
00214 /*4*/         setPUP1(XrdCmsRRData::Arg_dskFree, int,     CmsLoginData, fSpace),
00215 /*5*/         setPUP1(XrdCmsRRData::Arg_dskMinf, int,     CmsLoginData, mSpace),
00216 /*6*/         setPUP1(XrdCmsRRData::Arg_Info,    short,   CmsLoginData, fsNum),
00217 /*7*/         setPUP1(XrdCmsRRData::Arg_dskUtil, short,   CmsLoginData, fsUtil),
00218 /*8*/         setPUP1(XrdCmsRRData::Arg_Port,    short,   CmsLoginData, dPort),
00219 /*9*/         setPUP1(XrdCmsRRData::Arg_Port,    short,   CmsLoginData, sPort),
00220 /*0*/         setPUP0(Fence),
00221 /*1*/         setPUP1(XrdCmsRRData::Arg_SID,     char,    CmsLoginData, SID),
00222 /*2*/         setPUP1(XrdCmsRRData::Arg_Path,    char,    CmsLoginData, Paths),
00223 /*3*/         setPUP1(XrdCmsRRData::Arg_Datlen,EndFill,   CmsLoginData, Size)
00224              };
00225 
00226 /******************************************************************************/
00227 /*                           C o n s t r u c t o r                            */
00228 /******************************************************************************/
00229 
00230 XrdCmsParser::XrdCmsParser()
00231 {
00232    static int Done = 0;
00233 
00234 // Setup the Parse vector
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 /*                                D e c o d e                                 */
00263 /******************************************************************************/
00264 
00265 // Decode responses to the redirector. Very simple lean protocol.
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 // Responses are always in the form of <int><string>
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 // Now decode the response code
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 // Insert the information into the error object
00316 //
00317    eInfo->setErrInfo(msgval, msg);
00318    return Result;
00319 }
00320 
00321 /******************************************************************************/
00322 /*                              m a p E r r o r                               */
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 /*                                  P a c k                                   */
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 // Pack the request
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 // Indicate failure (we don't translate the request code as it drags in too
00377 // many dependent object files, sigh.
00378 //
00379    sprintf(buff, "%d", rnum);
00380    Say.Emsg("Pack", "Unable to pack request;", reason, buff);
00381    return 0;
00382 }

Generated on Tue Jul 5 14:46:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1