XrdOfsConfig.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d O f s C o n f i g . c c                        */
00004 /*                                                                            */
00005 /* (C) 2010 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 Deprtment of Energy              */
00009 /******************************************************************************/
00010 
00011 /*
00012    The routines in this file handle ofs() initialization. They get the
00013    configuration values either from configuration file or XrdOfsconfig.h (in that
00014    order of precedence).
00015 
00016    These routines are thread-safe if compiled with:
00017    AIX: -D_THREAD_SAFE
00018    SUN: -D_REENTRANT
00019 */
00020   
00021 #include <unistd.h>
00022 #include <ctype.h>
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <netdb.h>
00026 #include <stdlib.h>
00027 #include <strings.h>
00028 #include <stdio.h>
00029 #include <netinet/in.h>
00030 #include <sys/param.h>
00031 
00032 #include "XrdOfs/XrdOfs.hh"
00033 #include "XrdOfs/XrdOfsEvs.hh"
00034 #include "XrdOfs/XrdOfsPoscq.hh"
00035 #include "XrdOfs/XrdOfsStats.hh"
00036 #include "XrdOfs/XrdOfsTrace.hh"
00037 
00038 #include "XrdNet/XrdNetDNS.hh"
00039 
00040 #include "XrdOuc/XrdOuca2x.hh"
00041 #include "XrdOuc/XrdOucEnv.hh"
00042 #include "XrdSys/XrdSysError.hh"
00043 #include "XrdSys/XrdSysHeaders.hh"
00044 #include "XrdSys/XrdSysPlugin.hh"
00045 #include "XrdOuc/XrdOucStream.hh"
00046 #include "XrdOuc/XrdOucTrace.hh"
00047 #include "XrdOuc/XrdOucUtils.hh"
00048 
00049 #include "XrdCms/XrdCmsClient.hh"
00050 #include "XrdCms/XrdCmsFinder.hh"
00051 
00052 #include "XrdAcc/XrdAccAuthorize.hh"
00053 
00054 /******************************************************************************/
00055 /*                        G l o b a l   O b j e c t s                         */
00056 /******************************************************************************/
00057 
00058 extern XrdOfsStats OfsStats;
00059 
00060 extern XrdOucTrace OfsTrace;
00061   
00062 class  XrdOss;
00063 extern XrdOss     *XrdOfsOss;
00064 
00065 /******************************************************************************/
00066 /*                               d e f i n e s                                */
00067 /******************************************************************************/
00068 
00069 #define TS_Xeq(x,m)   if (!strcmp(x,var)) return m(Config,Eroute);
00070 
00071 #define TS_Str(x,m)   if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
00072 
00073 #define TS_PList(x,m)  if (!strcmp(x,var)) \
00074                           {m.Insert(new XrdOucPList(val,1)); return 0;}
00075 
00076 #define TS_Chr(x,m)   if (!strcmp(x,var)) {m = val[0]; return 0;}
00077 
00078 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; Config.Echo(); return 0;}
00079 
00080 #define Max(x,y) (x > y ? x : y)
00081 
00082 /******************************************************************************/
00083 /*                             C o n f i g u r e                              */
00084 /******************************************************************************/
00085   
00086 int XrdOfs::Configure(XrdSysError &Eroute) {
00087 /*
00088   Function: Establish default values using a configuration file.
00089 
00090   Input:    None.
00091 
00092   Output:   0 upon success or !0 otherwise.
00093 */
00094    extern XrdOss *XrdOssGetSS(XrdSysLogger *, const char *, const char *);
00095    char *var;
00096    const char *tmp;
00097    int  i, j, cfgFD, retc, NoGo = 0;
00098    XrdOucEnv myEnv;
00099    XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
00100 
00101 // Print warm-up message
00102 //
00103    Eroute.Say("++++++ File system initialization started.");
00104 
00105 // Preset all variables with common defaults
00106 //
00107    Options            = 0;
00108    if (getenv("XRDDEBUG")) OfsTrace.What = TRACE_MOST | TRACE_debug;
00109 
00110 // Obtain port number we will be using
00111 //
00112    myPort = (var = getenv("XRDPORT")) ? strtol(var, (char **)NULL, 10) : 0;
00113 
00114 // If there is no config file, return with the defaults sets.
00115 //
00116    if( !ConfigFN || !*ConfigFN)
00117      Eroute.Emsg("Config", "Configuration file not specified.");
00118      else {
00119            // Try to open the configuration file.
00120            //
00121            if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
00122               return Eroute.Emsg("Config", errno, "open config file",
00123                                  ConfigFN);
00124            Config.Attach(cfgFD);
00125 
00126            // Now start reading records until eof.
00127            //
00128            while((var = Config.GetMyFirstWord()))
00129                 {if (!strncmp(var, "ofs.", 4)
00130                  ||  !strcmp(var, "all.role"))
00131                     if (ConfigXeq(var+4,Config,Eroute)) {Config.Echo();NoGo=1;}
00132                 }
00133 
00134            // Now check if any errors occured during file i/o
00135            //
00136            if ((retc = Config.LastError()))
00137            NoGo = Eroute.Emsg("Config", -retc, "read config file",
00138                               ConfigFN);
00139            Config.Close();
00140           }
00141 
00142 // Determine whether we should initialize authorization
00143 //
00144    if (Options & Authorize) NoGo |= setupAuth(Eroute);
00145 
00146 // Check if redirection wanted
00147 //
00148    if (getenv("XRDREDIRECT")) i  = isManager;
00149       else i = 0;
00150    if (getenv("XRDRETARGET")) i |= isServer;
00151    if (getenv("XRDREDPROXY")) i |= isProxy;
00152    if (i)
00153       {if ((j = Options & haveRole) && (i ^ j))
00154           {free(myRole); myRole = strdup(theRole(i));
00155            Eroute.Say("Config warning: command line role options override "
00156                        "config file; 'ofs.role", myRole, "' in effect.");
00157           }
00158        Options &= ~(haveRole);
00159        Options |= i;
00160       }
00161 
00162 // Set the redirect option for other layers
00163 //
00164    if (Options & isManager)
00165            XrdOucEnv::Export("XRDREDIRECT", (Options & isMeta ? "M" : "R"));
00166       else XrdOucEnv::Export("XRDREDIRECT", "0");
00167 
00168 // Configure the storage system at this point. This must be done prior to
00169 // configuring cluster processing. First check if we will be proxying.
00170 //
00171    if (Options & isProxy)
00172       {char buff[2048], *bp, *libofs = getenv("XRDOFSLIB");
00173        if (OssLib) Eroute.Say("Config warning: ",
00174                    "specified osslib overrides default proxy lib.");
00175           else {if (!libofs) bp = buff;
00176                    else {strcpy(buff, libofs); bp = buff+strlen(buff)-1;
00177                          while(bp != buff && *(bp-1) != '/') bp--;
00178                         }
00179                 strcpy(bp, "libXrdProxy.so");
00180                 OssLib = strdup(buff);
00181                }
00182       }
00183 
00184 // Initialize th Evr object if we are an actual server
00185 //
00186    if (!(Options & isManager) 
00187    && !evrObject.Init(&Eroute, Balancer)) NoGo = 1;
00188 
00189 // Initialize redirection.  We type te herald here to minimize confusion
00190 //
00191    if (Options & haveRole)
00192       {Eroute.Say("++++++ Configuring ", myRole, " role. . .");
00193        NoGo |= ConfigRedir(Eroute);
00194       }
00195 
00196 // Turn off forwarding if we are not a pure remote redirector or a peer
00197 //
00198    if (Options & Forwarding)
00199       if (!(Options & isPeer)
00200       && (Options & (isServer | isProxy)))
00201          {Eroute.Say("Config warning: forwarding turned off; not a pure manager");
00202           Options &= ~(Forwarding);
00203           fwdCHMOD.Reset(); fwdMKDIR.Reset(); fwdMKPATH.Reset();
00204           fwdMV.Reset();    fwdRM.Reset();    fwdRMDIR.Reset();
00205           fwdTRUNC.Reset();
00206          }
00207 
00208 // Now configure the storage system
00209 //
00210    if (!(XrdOfsOss = XrdOssGetSS(Eroute.logger(), ConfigFN, OssLib))) NoGo = 1;
00211 
00212 // If we need to send notifications, initialize the interface
00213 //
00214    if (!NoGo && evsObject) NoGo = evsObject->Start(&Eroute);
00215 
00216 // If POSC processing is enabled (as by default) do it. Warning! This must be
00217 // the last item in the configuration list as we need a working filesystem.
00218 //
00219    if (poscAuto != -1 && !NoGo) NoGo |= ConfigPosc(Eroute);
00220 
00221 // Setup statistical monitoring
00222 //
00223    OfsStats.setRole(myRole);
00224 
00225 // Display final configuration
00226 //
00227    if (!NoGo) Config_Display(Eroute);
00228 
00229 // All done
00230 //
00231    tmp = (NoGo ? " initialization failed." : " initialization completed.");
00232    Eroute.Say("------ File system ", myRole, tmp);
00233    return NoGo;
00234 }
00235 
00236 /******************************************************************************/
00237 /*                        C o n f i g _ D i s p l a y                         */
00238 /******************************************************************************/
00239 
00240 #define setBuff(x,y) {strcpy(bp, x); bp += y;}
00241   
00242 void XrdOfs::Config_Display(XrdSysError &Eroute)
00243 {
00244      const char *cloc, *pval;
00245      char buff[8192], fwbuff[512], *bp;
00246      int i;
00247 
00248      if (!ConfigFN || !ConfigFN[0]) cloc = "default";
00249         else cloc = ConfigFN;
00250      if (!poscQ) pval = "off";
00251         else     pval = (poscAuto ? "auto" : "manual");
00252 
00253      snprintf(buff, sizeof(buff), "Config effective %s ofs configuration:\n"
00254                                   "       ofs.role %s\n"
00255                                   "%s"
00256                                   "%s%s%s"
00257                                   "       ofs.maxdelay   %d\n"
00258                                   "%s%s%s"
00259                                   "       ofs.persist    %s hold %d%s%s%s"
00260                                   "       ofs.trace      %x",
00261               cloc, myRole,
00262               (Options & Authorize ? "       ofs.authorize\n" : ""),
00263               (AuthLib                   ? "       ofs.authlib " : ""),
00264               (AuthLib ? AuthLib : ""), (AuthLib ? "\n" : ""),
00265                MaxDelay,
00266               (OssLib                    ? "       ofs.osslib " : ""),
00267               (OssLib ? OssLib : ""), (OssLib ? "\n" : ""),
00268                pval, poscHold, (poscLog ? " logdir " : ""),
00269                (poscLog ? poscLog    : ""), (poscLog ? "\n" : ""),
00270               OfsTrace.What);
00271 
00272      Eroute.Say(buff);
00273 
00274      if (Options & Forwarding)
00275         {*fwbuff = 0;
00276          if (ConfigDispFwd(buff, fwdCHMOD))
00277             {Eroute.Say(buff); strcat(fwbuff, " ch");}
00278          if (ConfigDispFwd(buff, fwdMKDIR))
00279             {Eroute.Say(buff); strcat(fwbuff, " mk");}
00280          if (ConfigDispFwd(buff, fwdMV))
00281             {Eroute.Say(buff); strcat(fwbuff, " mv");}
00282          if (ConfigDispFwd(buff, fwdRM))
00283             {Eroute.Say(buff); strcat(fwbuff, " rm");}
00284          if (ConfigDispFwd(buff, fwdRMDIR))
00285             {Eroute.Say(buff); strcat(fwbuff, " rd");}
00286          if (ConfigDispFwd(buff, fwdTRUNC))
00287             {Eroute.Say(buff); strcat(fwbuff, " tr");}
00288          if (*fwbuff) XrdOucEnv::Export("XRDOFS_FWD", fwbuff);
00289         }
00290 
00291      if (evsObject)
00292         {bp = buff;
00293          setBuff("       ofs.notify ", 11);              //  1234567890
00294          if (evsObject->Enabled(XrdOfsEvs::Chmod))  setBuff("chmod ",  6);
00295          if (evsObject->Enabled(XrdOfsEvs::Closer)) setBuff("closer ", 7);
00296          if (evsObject->Enabled(XrdOfsEvs::Closew)) setBuff("closew ", 7);
00297          if (evsObject->Enabled(XrdOfsEvs::Create)) setBuff("create ", 7);
00298          if (evsObject->Enabled(XrdOfsEvs::Mkdir))  setBuff("mkdir ",  6);
00299          if (evsObject->Enabled(XrdOfsEvs::Mv))     setBuff("mv ",     3);
00300          if (evsObject->Enabled(XrdOfsEvs::Openr))  setBuff("openr ",  6);
00301          if (evsObject->Enabled(XrdOfsEvs::Openw))  setBuff("openw ",  6);
00302          if (evsObject->Enabled(XrdOfsEvs::Rm))     setBuff("rm ",     3);
00303          if (evsObject->Enabled(XrdOfsEvs::Rmdir))  setBuff("rmdir ",  6);
00304          if (evsObject->Enabled(XrdOfsEvs::Trunc))  setBuff("trunc ",  6);
00305          if (evsObject->Enabled(XrdOfsEvs::Fwrite)) setBuff("fwrite ", 7);
00306          setBuff("msgs ", 5);
00307          i=sprintf(fwbuff,"%d %d ",evsObject->maxSmsg(),evsObject->maxLmsg());
00308          setBuff(fwbuff, i);
00309          cloc = evsObject->Prog();
00310          if (*cloc != '>') setBuff("|",1);
00311          setBuff(cloc, strlen(cloc));
00312          setBuff("\0", 1);
00313          Eroute.Say(buff);
00314         }
00315 }
00316 
00317 /******************************************************************************/
00318 /*                     p r i v a t e   f u n c t i o n s                      */
00319 /******************************************************************************/
00320 /******************************************************************************/
00321 /*                         C o n f i g D i s p F w d                          */
00322 /******************************************************************************/
00323   
00324 int XrdOfs::ConfigDispFwd(char *buff, struct fwdOpt &Fwd)
00325 {
00326    const char *cP;
00327    char pbuff[16], *bp;
00328 
00329 // Return if this is not being forwarded
00330 //
00331    if (!(cP = Fwd.Cmd)) return 0;
00332    bp = buff;
00333    setBuff("       ofs.forward ", 19);
00334 
00335 // Chck which way this is being forwarded
00336 //
00337          if (*Fwd.Cmd == '+'){setBuff("2way ",5); cP++;}
00338    else  if (!Fwd.Port)      {setBuff("1way ",5);}
00339    else {                     setBuff("3way ",5);
00340          if (Fwd.Port < 0)   {setBuff("local ",6);}
00341             else {int n = sprintf(pbuff, ":%d ", Fwd.Port);
00342                   setBuff(Fwd.Host, strlen(Fwd.Host));
00343                   setBuff(pbuff, n);
00344                  }
00345         }
00346    setBuff(cP, strlen(cP));
00347    return 1;
00348 }
00349 
00350 /******************************************************************************/
00351 /*                            C o n f i g P o s c                             */
00352 /******************************************************************************/
00353   
00354 int XrdOfs::ConfigPosc(XrdSysError &Eroute)
00355 {
00356    extern XrdOfs XrdOfsFS;
00357    const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
00358    class  CloseFH : public XrdOfsHanCB
00359          {public: void Retired(XrdOfsHandle *hP) {XrdOfsFS.Unpersist(hP);}};
00360    static XrdOfsHanCB *hCB = static_cast<XrdOfsHanCB *>(new CloseFH);
00361 
00362    XrdOfsPoscq::recEnt  *rP, *rPP;
00363    XrdOfsPoscq::Request *qP;
00364    XrdOfsHandle *hP;
00365    const char *iName;
00366    char pBuff[MAXPATHLEN], *aPath;
00367    int NoGo, rc;
00368 
00369 // Construct the proper path to the recovery file
00370 //
00371    iName = XrdOucUtils::InstName(-1);
00372    if (poscLog) aPath = XrdOucUtils::genPath(poscLog, iName, ".ofs/posc.log");
00373       else {if (!(aPath = getenv("XRDADMINPATH")))
00374                {XrdOucUtils::genPath(pBuff, MAXPATHLEN, "/tmp", iName);
00375                 aPath = pBuff;
00376                }
00377             aPath = XrdOucUtils::genPath(aPath, (char *)0, ".ofs/posc.log");
00378            }
00379    rc = strlen(aPath)-1;
00380    if (aPath[rc] == '/') aPath[rc] = '\0';
00381    free(poscLog); poscLog = aPath;
00382 
00383 // Make sure directory path exists
00384 //
00385    if ((rc = XrdOucUtils::makePath(poscLog, AMode)))
00386       {Eroute.Emsg("Config", rc, "create path for", poscLog);
00387        return 1;
00388       }
00389 
00390 // Create object then initialize it
00391 //
00392    poscQ = new XrdOfsPoscq(&Eroute, XrdOfsOss, poscLog);
00393    rP = poscQ->Init(rc);
00394    if (!rc) return 1;
00395 
00396 // Get file handles and put then in pending delete for all recovered records
00397 //
00398    NoGo = 0;
00399    while(rP)
00400         {qP = &(rP->reqData);
00401          if (qP->addT && poscHold)
00402             {if (XrdOfsHandle::Alloc(qP->LFN, XrdOfsHandle::opPC, &hP))
00403                 {Eroute.Emsg("Config", "Unable to persist", qP->User, qP->LFN);
00404                  qP->addT = 0;
00405                 } else {
00406                  hP->PoscSet(qP->User, rP->Offset, rP->Mode);
00407                  hP->Retire(hCB, poscHold);
00408                 }
00409             }
00410          if (!(qP->addT) || !poscHold)
00411             {if ((rc = XrdOfsOss->Unlink(qP->LFN)) && rc != -ENOENT)
00412                 {Eroute.Emsg("Config", rc, "unpersist", qP->LFN); NoGo = 1;}
00413                 else {Eroute.Emsg("Config", "Unpersisted", qP->User, qP->LFN);
00414                       poscQ->Del(qP->LFN, rP->Offset);
00415                      }
00416             }
00417          rPP = rP; rP = rP->Next; delete rPP;
00418         }
00419 
00420 // All done
00421 //
00422    return NoGo;
00423 }
00424 
00425 /******************************************************************************/
00426 /*                           C o n f i g R e d i r                            */
00427 /******************************************************************************/
00428   
00429 int XrdOfs::ConfigRedir(XrdSysError &Eroute) 
00430 {
00431    int isRedir = Options & isManager;
00432    int RMTopts = (Options & isServer ? XrdCms::IsTarget : 0)
00433                | (Options & isMeta   ? XrdCms::IsMeta   : 0);
00434 
00435 // For manager roles, we simply do a standard config
00436 //
00437    if (isRedir) 
00438       {Finder = (XrdCmsClient *)new XrdCmsFinderRMT(Eroute.logger(),
00439                                                     RMTopts,myPort);
00440        if (!Finder->Configure(ConfigFN))
00441           {delete Finder; Finder = 0; return 1;}
00442       }
00443 
00444 // For server roles find the port number and create the object. We used to pass
00445 // the storage system object to the finder to allow it to process cms storage
00446 // requests. The cms no longer sends such requests so there is no need to do
00447 // so. And, in fact, we need to defer creating a storage system until after the
00448 // finder is created. So, it's just as well we pass a numm pointer. At some
00449 // point the finder should remove all storage system related code.
00450 //
00451    if (Options & (isServer | (isPeer & ~isManager)))
00452       {if (!myPort)
00453           {Eroute.Emsg("Config", "Unable to determine server's port number.");
00454            return 1;
00455           }
00456        Balancer = new XrdCmsFinderTRG(Eroute.logger(),
00457                          (isRedir ? XrdCms::IsRedir : 0), myPort, 0);
00458        if (!Balancer->Configure(ConfigFN))
00459           {delete Balancer; Balancer = 0; return 1;}
00460        if (Options & isProxy) Balancer = 0; // No chatting for proxies
00461       }
00462 
00463 // All done
00464 //
00465    return 0;
00466 }
00467   
00468 /******************************************************************************/
00469 /*                             C o n f i g X e q                              */
00470 /******************************************************************************/
00471   
00472 int XrdOfs::ConfigXeq(char *var, XrdOucStream &Config,
00473                                  XrdSysError &Eroute)
00474 {
00475     char *val, vBuff[64];
00476 
00477     // Now assign the appropriate global variable
00478     //
00479     TS_Bit("authorize",     Options, Authorize);
00480     TS_Xeq("authlib",       xalib);
00481     TS_Xeq("forward",       xforward);
00482     TS_Xeq("maxdelay",      xmaxd);
00483     TS_Xeq("notify",        xnot);
00484     TS_Xeq("notifymsg",     xnmsg);
00485     TS_Xeq("osslib",        xolib);
00486     TS_Xeq("persist",       xpers);
00487     TS_Xeq("redirect",      xred);     // Deprecated
00488     TS_Xeq("role",          xrole);
00489     TS_Xeq("trace",         xtrace);
00490 
00491     // Get the actual value for simple directives
00492     //
00493     strlcpy(vBuff, var, sizeof(vBuff)); var = vBuff;
00494     if (!(val = Config.GetWord()))
00495        {Eroute.Emsg("Config", "value not specified for", var); return 1;}
00496 
00497     // No match found, complain.
00498     //
00499     Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
00500     Config.Echo();
00501     return 0;
00502 }
00503 
00504 /******************************************************************************/
00505 /*                                 x a l i b                                  */
00506 /******************************************************************************/
00507   
00508 /* Function: xalib
00509 
00510    Purpose:  To parse the directive: authlib <path> [<parms>]
00511 
00512              <path>    the path of the authorization library to be used.
00513              <parms>   optional parms to be passed
00514 
00515   Output: 0 upon success or !0 upon failure.
00516 */
00517 
00518 int XrdOfs::xalib(XrdOucStream &Config, XrdSysError &Eroute)
00519 {
00520     char *val, parms[1024];
00521 
00522 // Get the path
00523 //
00524    if (!(val = Config.GetWord()) || !val[0])
00525       {Eroute.Emsg("Config", "authlib not specified"); return 1;}
00526 
00527 // Record the path
00528 //
00529    if (AuthLib) free(AuthLib);
00530    AuthLib = strdup(val);
00531 
00532 // Record any parms
00533 //
00534    if (!Config.GetRest(parms, sizeof(parms)))
00535       {Eroute.Emsg("Config", "authlib parameters too long"); return 1;}
00536    if (AuthParm) free(AuthParm);
00537    AuthParm = (*parms ? strdup(parms) : 0);
00538    return 0;
00539 }
00540 
00541 /******************************************************************************/
00542 /*                              x f o r w a r d                               */
00543 /******************************************************************************/
00544   
00545 /* Function: xforward
00546 
00547    Purpose:  To parse the directive: forward [<handling>] <metaops>
00548 
00549              handling: 1way | 2way | 3way {local | <host>:<port>}
00550 
00551              1way      forward does not respond (the default)
00552              2way      forward responds; relay response back.
00553              3way      forward 1way and execute locally or redirect to <host>
00554              <metaops> list of meta-file operations to forward to manager
00555 
00556    Output: 0 upon success or !0 upon failure.
00557 */
00558 
00559 int XrdOfs::xforward(XrdOucStream &Config, XrdSysError &Eroute)
00560 {
00561     enum fwdType {OfsFWDALL = 0x3f, OfsFWDCHMOD = 0x01, OfsFWDMKDIR = 0x02,
00562                   OfsFWDMV  = 0x04, OfsFWDRM    = 0x08, OfsFWDRMDIR = 0x10,
00563                   OfsFWDREM = 0x18, OfsFWDTRUNC = 0x20, OfsFWDNONE  = 0};
00564 
00565     static struct fwdopts {const char *opname; fwdType opval;} fwopts[] =
00566        {
00567         {"all",      OfsFWDALL},
00568         {"chmod",    OfsFWDCHMOD},
00569         {"mkdir",    OfsFWDMKDIR},
00570         {"mv",       OfsFWDMV},
00571         {"rm",       OfsFWDRM},
00572         {"rmdir",    OfsFWDRMDIR},
00573         {"remove",   OfsFWDREM},
00574         {"trunc",    OfsFWDTRUNC}
00575        };
00576     int fwval = OfsFWDNONE, fwspec = OfsFWDNONE;
00577     int numopts = sizeof(fwopts)/sizeof(struct fwdopts);
00578     int i, neg, rPort = 0, is2way = 0, is3way = 0;
00579     char *val, *pp, rHost[512];
00580 
00581     *rHost = '\0';
00582     if (!(val = Config.GetWord()))
00583        {Eroute.Emsg("Config", "foward option not specified"); return 1;}
00584     if ((is2way = !strcmp("2way", val)) || !strcmp("1way", val)
00585     ||  (is3way = !strcmp("3way", val)))
00586        if (!(val = Config.GetWord()))
00587           {Eroute.Emsg("Config", "foward operation not specified"); return 1;}
00588 
00589     if (is3way)
00590        {if (!strcmp("local", val)) rPort = -1;
00591         else
00592        {if (*val == ':')
00593            {Eroute.Emsg("Config", "redirect host not specified"); return 1;}
00594         if (!(pp = index(val, ':')))
00595            {Eroute.Emsg("Config", "redirect port not specified"); return 1;}
00596         if ((rPort = atoi(pp+1)) <= 0)
00597            {Eroute.Emsg("Config", "redirect port is invalid");    return 1;}
00598         *pp = '\0';
00599         strlcpy(rHost, val, sizeof(rHost));
00600        }
00601         if (!(val = Config.GetWord()))
00602            {Eroute.Emsg("Config", "foward operation not specified"); return 1;}
00603        }
00604 
00605     while (val)
00606          {if (!strcmp(val, "off")) {fwval = OfsFWDNONE; fwspec = OfsFWDALL;}
00607              else {if ((neg = (val[0] == '-' && val[1]))) val++;
00608                    for (i = 0; i < numopts; i++)
00609                        {if (!strcmp(val, fwopts[i].opname))
00610                            {if (neg) fwval &= ~fwopts[i].opval;
00611                                else  fwval |=  fwopts[i].opval;
00612                             fwspec |= fwopts[i].opval;
00613                             break;
00614                            }
00615                        }
00616                    if (i >= numopts)
00617                       Eroute.Say("Config warning: ignoring invalid foward option '",val,"'.");
00618                   }
00619           val = Config.GetWord();
00620          }
00621 
00622     if (fwspec & OfsFWDCHMOD) 
00623        {fwdCHMOD.Cmd = (fwval&OfsFWDCHMOD ? (is2way ? "+chmod" :"chmod")  : 0);
00624         if (fwdCHMOD.Host) free(fwdCHMOD.Host);
00625         fwdCHMOD.Host = strdup(rHost); fwdCHMOD.Port = rPort;
00626        }
00627     if (fwspec&OfsFWDMKDIR) 
00628        {fwdMKDIR.Cmd = (fwval&OfsFWDMKDIR ? (is2way ? "+mkdir" :"mkdir")  : 0);
00629         if (fwdMKDIR.Host) free(fwdMKDIR.Host);
00630         fwdMKDIR.Host = strdup(rHost); fwdMKDIR.Port = rPort;
00631         fwdMKPATH.Cmd= (fwval&OfsFWDMKDIR ? (is2way ? "+mkpath":"mkpath") : 0);
00632         if (fwdMKPATH.Host) free(fwdMKPATH.Host);
00633         fwdMKPATH.Host = strdup(rHost); fwdMKPATH.Port = rPort;
00634        }
00635     if (fwspec&OfsFWDMV)    
00636        {fwdMV   .Cmd = (fwval&OfsFWDMV    ? (is2way ? "+mv"    :"mv")     : 0);
00637         if (fwdMV.Host) free(fwdMV.Host);
00638         fwdMV.Host = strdup(rHost); fwdMV.Port = rPort;
00639        }
00640     if (fwspec&OfsFWDRM)    
00641        {fwdRM   .Cmd = (fwval&OfsFWDRM    ? (is2way ? "+rm"    :"rm")     : 0);
00642         if (fwdRM.Host) free(fwdRM.Host);
00643         fwdRM.Host = strdup(rHost); fwdRM.Port = rPort;
00644        }
00645     if (fwspec&OfsFWDRMDIR) 
00646        {fwdRMDIR.Cmd = (fwval&OfsFWDRMDIR ? (is2way ? "+rmdir" :"rmdir")  : 0);
00647         if (fwdRMDIR.Host) free(fwdRMDIR.Host);
00648         fwdRMDIR.Host = strdup(rHost); fwdRMDIR.Port = rPort;
00649        }
00650     if (fwspec&OfsFWDTRUNC) 
00651        {fwdTRUNC.Cmd = (fwval&OfsFWDTRUNC ? (is2way ? "+trunc" :"trunc")  : 0);
00652         if (fwdTRUNC.Host) free(fwdTRUNC.Host);
00653         fwdTRUNC.Host = strdup(rHost); fwdTRUNC.Port = rPort;
00654        }
00655 
00656 // All done
00657 //
00658    Options |= Forwarding;
00659    return 0;
00660 }
00661   
00662 /******************************************************************************/
00663 /*                                 x m a x d                                  */
00664 /******************************************************************************/
00665 
00666 /* Function: xmaxd
00667 
00668    Purpose:  To parse the directive: maxdelay <secs>
00669 
00670              <secs>    maximum delay imposed for staging
00671 
00672    Output: 0 upon success or !0 upon failure.
00673 */
00674 
00675 int XrdOfs::xmaxd(XrdOucStream &Config, XrdSysError &Eroute)
00676 {
00677     char *val;
00678     int maxd;
00679 
00680       if (!(val = Config.GetWord()))
00681          {Eroute.Emsg("Config","maxdelay value not specified");return 1;}
00682       if (XrdOuca2x::a2i(Eroute, "maxdelay", val, &maxd, 30)) return 1;
00683 
00684       MaxDelay = maxd;
00685       return 0;
00686 }
00687 
00688 /******************************************************************************/
00689 /*                                 x n m s g                                  */
00690 /******************************************************************************/
00691 
00692 /* Function: xnmsg
00693 
00694    Purpose:  To parse the directive: notifymsg <event> <msg>
00695 
00696    Args:     <events> - one or more of: all chmod closer closew close mkdir mv
00697                                         openr openw open rm rmdir fwrite
00698              <msg>      the notification message to be sent (see notify).
00699 
00700    Type: Manager only, non-dynamic.
00701 
00702    Output: 0 upon success or !0 upon failure.
00703 */
00704 
00705 int XrdOfs::xnmsg(XrdOucStream &Config, XrdSysError &Eroute)
00706 {
00707     static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
00708         noopts[] = {
00709         {"chmod",    XrdOfsEvs::Chmod},
00710         {"closer",   XrdOfsEvs::Closer},
00711         {"closew",   XrdOfsEvs::Closew},
00712         {"create",   XrdOfsEvs::Create},
00713         {"mkdir",    XrdOfsEvs::Mkdir},
00714         {"mv",       XrdOfsEvs::Mv},
00715         {"openr",    XrdOfsEvs::Openr},
00716         {"openw",    XrdOfsEvs::Openw},
00717         {"rm",       XrdOfsEvs::Rm},
00718         {"rmdir",    XrdOfsEvs::Rmdir},
00719         {"trunc",    XrdOfsEvs::Trunc},
00720         {"fwrite",   XrdOfsEvs::Fwrite}
00721        };
00722     XrdOfsEvs::Event noval;
00723     int numopts = sizeof(noopts)/sizeof(struct notopts);
00724     char *val, buff[1024];
00725     XrdOucEnv *myEnv;
00726     int i;
00727 
00728    // At this point, make sure we have a value
00729    //
00730    if (!(val = Config.GetWord()))
00731       {Eroute.Emsg("Config", "notifymsg event not specified");
00732        return 1;
00733       }
00734 
00735    // Get the evant number
00736    //
00737    for (i = 0; i < numopts; i++) if (!strcmp(val, noopts[i].opname)) break;
00738    if (i >= numopts)
00739       {Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
00740        return 1;
00741       }
00742    noval = noopts[i].opval;
00743 
00744    // We need to suck all the tokens to the end of the line for remaining
00745    // options. Do so, until we run out of space in the buffer.
00746    //
00747    myEnv = Config.SetEnv(0);
00748    if (!Config.GetRest(buff, sizeof(buff)))
00749       {Eroute.Emsg("Config", "notifymsg arguments too long");
00750        Config.SetEnv(myEnv);
00751        return 1;
00752       }
00753 
00754    // Restore substitutions and parse the message
00755    //
00756    Config.SetEnv(myEnv);
00757    return XrdOfsEvs::Parse(Eroute, noval, buff);
00758 }
00759   
00760 /******************************************************************************/
00761 /*                                  x n o t                                   */
00762 /* Based on code developed by Derek Feichtinger, CERN.                        */
00763 /******************************************************************************/
00764 
00765 /* Function: xnot
00766 
00767    Purpose:  Parse directive: notify <events> [msgs <min> [<max>]] 
00768                                      {|<prog> | ><path>}
00769 
00770    Args:     <events> - one or more of: all chmod closer closew close mkdir mv
00771                                         openr openw open rm rmdir fwrite
00772                         opaque and other possible information to be sent.
00773              msgs     - Maximum number of messages to keep and queue. The
00774                         <min> if for small messages (default 90) and <max> is
00775                         for big messages (default 10).
00776              <prog>   - is the program to execute and dynamically feed messages
00777                         about the indicated events. Messages are piped to prog.
00778              <path>   - is the udp named socket to receive the message. The
00779                         server creates the path if it's not present.
00780 
00781    Output: 0 upon success or !0 upon failure.
00782 */
00783 int XrdOfs::xnot(XrdOucStream &Config, XrdSysError &Eroute)
00784 {
00785     static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
00786         noopts[] = {
00787         {"all",      XrdOfsEvs::All},
00788         {"chmod",    XrdOfsEvs::Chmod},
00789         {"close",    XrdOfsEvs::Close},
00790         {"closer",   XrdOfsEvs::Closer},
00791         {"closew",   XrdOfsEvs::Closew},
00792         {"create",   XrdOfsEvs::Create},
00793         {"mkdir",    XrdOfsEvs::Mkdir},
00794         {"mv",       XrdOfsEvs::Mv},
00795         {"open",     XrdOfsEvs::Open},
00796         {"openr",    XrdOfsEvs::Openr},
00797         {"openw",    XrdOfsEvs::Openw},
00798         {"rm",       XrdOfsEvs::Rm},
00799         {"rmdir",    XrdOfsEvs::Rmdir},
00800         {"trunc",    XrdOfsEvs::Trunc},
00801         {"fwrite",   XrdOfsEvs::Fwrite}
00802        };
00803     XrdOfsEvs::Event noval = XrdOfsEvs::None;
00804     int numopts = sizeof(noopts)/sizeof(struct notopts);
00805     int i, neg, msgL = 90, msgB = 10;
00806     char *val, parms[1024];
00807 
00808     if (!(val = Config.GetWord()))
00809        {Eroute.Emsg("Config", "notify parameters not specified"); return 1;}
00810     while (val && *val != '|' && *val != '>')
00811          {if (!strcmp(val, "msgs"))
00812              {if (!(val = Config.GetWord()))
00813                  {Eroute.Emsg("Config", "notify msgs value not specified");
00814                   return 1;
00815                  }
00816               if (XrdOuca2x::a2i(Eroute, "msg count", val, &msgL, 0)) return 1;
00817               if (!(val = Config.GetWord())) break;
00818               if (isdigit(*val)
00819               && XrdOuca2x::a2i(Eroute, "msg count", val, &msgB, 0)) return 1;
00820               if (!(val = Config.GetWord())) break;
00821               continue;
00822              }
00823           if ((neg = (val[0] == '-' && val[1]))) val++;
00824           i = strlen(val);
00825           for (i = 0; i < numopts; i++)
00826               {if (!strcmp(val, noopts[i].opname))
00827                   {if (neg) noval = static_cast<XrdOfsEvs::Event>(~noopts[i].opval&noval);
00828                       else  noval = static_cast<XrdOfsEvs::Event>( noopts[i].opval|noval);
00829                    break;
00830                   }
00831               }
00832           if (i >= numopts)
00833              Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
00834           val = Config.GetWord();
00835          }
00836 
00837 // Check if we have a program here and some events
00838 //
00839    if (!val)   {Eroute.Emsg("Config","notify program not specified");return 1;}
00840    if (!noval) {Eroute.Emsg("Config","notify events not specified"); return 1;}
00841 
00842 // Get the remaining parameters
00843 //
00844    Config.RetToken();
00845    if (!Config.GetRest(parms, sizeof(parms)))
00846       {Eroute.Emsg("Config", "notify parameters too long"); return 1;}
00847    val = (*parms == '|' ? parms+1 : parms);
00848 
00849 // Create an notification object
00850 //
00851    if (evsObject) delete evsObject;
00852    evsObject = new XrdOfsEvs(noval, val, msgL, msgB);
00853 
00854 // All done
00855 //
00856    return 0;
00857 }
00858   
00859 /******************************************************************************/
00860 /*                                 x o l i b                                  */
00861 /******************************************************************************/
00862   
00863 /* Function: xolib
00864 
00865    Purpose:  To parse the directive: osslib <path> [<parms>]
00866 
00867              <path>    the path of the oss library to be used.
00868              <parms>   optional parms to be passed
00869 
00870   Output: 0 upon success or !0 upon failure.
00871 */
00872 
00873 int XrdOfs::xolib(XrdOucStream &Config, XrdSysError &Eroute)
00874 {
00875     char *val, parms[2048];
00876     int pl;
00877 
00878 // Get the path and parms
00879 //
00880    if (!(val = Config.GetWord()) || !val[0])
00881       {Eroute.Emsg("Config", "osslib not specified"); return 1;}
00882 
00883 // Combine the path and parameters
00884 //
00885    strcpy(parms, val);
00886    pl = strlen(val);
00887    *(parms+pl) = ' ';
00888    if (!Config.GetRest(parms+pl+1, sizeof(parms)-pl-1))
00889       {Eroute.Emsg("Config", "osslib parameters too long"); return 1;}
00890 
00891 // Record the path
00892 //
00893    if (OssLib) free(OssLib);
00894    OssLib = strdup(parms);
00895    return 0;
00896 }
00897 
00898 /******************************************************************************/
00899 /*                                 x p e r s                                  */
00900 /******************************************************************************/
00901   
00902 /* Function: xpers
00903 
00904    Purpose:  To parse the directive: persist [auto | manual | off]
00905                                              [hold <sec>] [logdir <dirp>]
00906 
00907              auto      POSC processing always on for creation requests
00908              manual    POSC processing must be requested (default)
00909              off       POSC processing is disabled
00910              <sec>     Seconds inclomplete files held (default 10m)
00911              <dirp>    Directory to hold POSC recovery log (default adminpath)
00912 
00913    Output: 0 upon success or !0 upon failure.
00914 */
00915 
00916 int XrdOfs::xpers(XrdOucStream &Config, XrdSysError &Eroute)
00917 {
00918    char *val;
00919    int htime = -1, popt = -2;
00920 
00921    if (!(val = Config.GetWord()))
00922       {Eroute.Emsg("Config","persist option not specified");return 1;}
00923 
00924 // Check for valid option
00925 //
00926         if (!strcmp(val, "auto"   )) popt =  1;
00927    else if (!strcmp(val, "off"    )) popt = -1;
00928    else if (!strcmp(val, "manual" )) popt =  0;
00929 
00930 // Check if we should get the next token
00931 //
00932    if (popt > -2) val = Config.GetWord();
00933 
00934 // Check for hold or log
00935 //
00936    while(val)
00937         {     if (!strcmp(val, "hold"))
00938                  {if (!(val = Config.GetWord()))
00939                      {Eroute.Emsg("Config","persist hold value not specified");
00940                       return 1;
00941                      }
00942                   if (XrdOuca2x::a2tm(Eroute,"persist hold",val,&htime,0))
00943                       return 1;
00944                  }
00945          else if (!strcmp(val, "logdir"))
00946                  {if (!(val = Config.GetWord()))
00947                      {Eroute.Emsg("Config","persist logdir path not specified");
00948                       return 1;
00949                      }
00950                   if (poscLog) free(poscLog);
00951                   poscLog = strdup(val);
00952                  }
00953          else Eroute.Say("Config warning: ignoring invalid persist option '",val,"'.");
00954          val = Config.GetWord();
00955         }
00956 
00957 // Set values as needed
00958 //
00959    if (htime >= 0) poscHold = htime;
00960    if (popt  > -2) poscAuto = popt;
00961    return 0;
00962 }
00963 
00964 /******************************************************************************/
00965 /*                                  x r e d                                   */
00966 /******************************************************************************/
00967 
00968 /* Function: xred
00969 
00970    Purpose:  Parse directive: redirect [proxy|remote|target] [if ...]
00971 
00972    Args:     proxy    - enables this server for proxy   load balancing
00973              remote   - enables this server for dynamic load balancing
00974              target   - enables this server as a redirection target
00975              if       - applies directive if "if" is true. 
00976                         See XrdOucUtils::doIf() for syntax.
00977 
00978    Output: 0 upon success or !0 upon failure.
00979 */
00980 
00981 int XrdOfs::xred(XrdOucStream &Config, XrdSysError &Eroute)
00982 {
00983     const char *mode = "remote";
00984     char *val;
00985     int rc, ropt = 0;
00986 
00987     Eroute.Say("Config warning: redirect directive is deprecated; use 'all.role'.");
00988 
00989     if ((val = Config.GetWord()))
00990        {     if (!strcmp("proxy",  val)) {ropt = isProxy;
00991                                           mode = "proxy";
00992                                          }
00993         else if (!strcmp("remote", val))  ropt = isManager;
00994         else if (!strcmp("target", val)) {ropt = isServer;
00995                                           mode = "target";
00996                                          }
00997        }
00998 
00999     if (!ropt) ropt = isManager;
01000        else if (val) val = Config.GetWord();
01001 
01002     if (val)
01003        {if (strcmp("if", val)) Config.RetToken();
01004         if ((rc = XrdOucUtils::doIf(&Eroute, Config, "redirect directive",
01005                                    getenv("XRDHOST"), XrdOucUtils::InstName(1),
01006                                    getenv("XRDPROG"))) <= 0)
01007            return (rc < 0);
01008        }
01009     Options |= ropt;
01010     return 0;
01011 }
01012 
01013 /******************************************************************************/
01014 /*                                 x r o l e                                  */
01015 /******************************************************************************/
01016 
01017 /* Function: xrole
01018 
01019    Purpose:  Parse: role { {[meta] | [peer] [proxy]} manager
01020                            | peer | proxy | [proxy]  server
01021                            |                [proxy]  supervisor
01022                          } [if ...]
01023 
01024              manager    xrootd: act as a manager (redirecting server). Prefixes:
01025                                 meta  - connect only to manager meta's
01026                                 peer  - ignored
01027                                 proxy - ignored
01028                         cmsd:   accept server subscribes and redirectors. Prefix
01029                                 modifiers do the following:
01030                                 meta  - No other managers apply
01031                                 peer  - subscribe to other managers as a peer
01032                                 proxy - manage a cluster of proxy servers
01033 
01034              peer       xrootd: same as "peer manager"
01035                         olbd:   same as "peer manager" but no server subscribers
01036                                 are required to function (i.e., run stand-alone).
01037 
01038              proxy      xrootd: act as a server but supply data from another 
01039                                 server. No local olbd is present or required.
01040                         olbd:   Generates an error as this makes no sense.
01041 
01042              server     xrootd: act as a server (supply local data). Prefix
01043                                 modifications do the following:
01044                                 proxy - server is part of a cluster. A local
01045                                         olbd is required.
01046                         olbd:   subscribe to a manager, possibly as a proxy.
01047 
01048              supervisor xrootd: equivalent to manager. The prefix modification
01049                                 is ignored.
01050                         olbd:   equivalent to manager but also subscribe to a
01051                                 manager. When proxy is specified, then subscribe
01052                                 as a proxy and only accept proxies.
01053 
01054              if         Apply the manager directive if "if" is true. See
01055                         XrdOucUtils:doIf() for "if" syntax.
01056 
01057    Notes  1. The peer designation only affects how the olbd communicates.
01058 
01059    Type: Server only, non-dynamic.
01060 
01061    Output: 0 upon success or !0 upon failure.
01062 */
01063 
01064 int XrdOfs::xrole(XrdOucStream &Config, XrdSysError &Eroute)
01065 {
01066    const int resetit = ~haveRole;
01067    char role[64];
01068    char *val;
01069    int rc, mopt = 0, qopt = 0, ropt = 0, sopt = 0;
01070 
01071    *role = '\0';
01072    if (!(val = Config.GetWord()))
01073       {Eroute.Emsg("Config", "role not specified"); return 1;}
01074 
01075 
01076 // Scan for "meta" o/w "peer" or "proxy"
01077 //
01078    if (!strcmp("meta", val))
01079       {mopt = isMeta; strcpy(role, val); val = Config.GetWord();}
01080       else {if (!strcmp("peer", val))
01081                {qopt = isPeer; strcpy(role, val);
01082                 val = Config.GetWord();
01083                }
01084             if (val && !strcmp("proxy", val))
01085                {ropt = isProxy;
01086                 if (qopt) strcat(role, " ");
01087                 strcat(role, val);
01088                 val = Config.GetWord();
01089                }
01090            }
01091 
01092 // Scan for other possible alternatives
01093 //
01094    if (val && strcmp("if", val))
01095       {     if (!strcmp("manager",    val)) sopt = isManager;
01096        else if (!strcmp("server",     val)) sopt = isServer;
01097        else if (!strcmp("supervisor", val)) sopt = isSuper;
01098        else    {Eroute.Emsg("Config", "invalid role -", val); return 1;}
01099 
01100        if (mopt || qopt || ropt) strcat(role, " ");
01101        strcat(role, val);
01102        val = Config.GetWord();
01103       }
01104 
01105 // Scan for invalid roles: peer proxy | peer server | {peer} supervisor
01106 //
01107    if (((mopt || (qopt && ropt)) && !sopt)
01108    ||  ((mopt || qopt) && sopt == isServer)
01109    ||  ((mopt || qopt) && sopt == isSuper))
01110       {Eroute.Emsg("Config", "invalid role -", role); return 1;}
01111 
01112 // Make sure a role was specified
01113 //
01114     if (!(ropt = mopt | qopt | ropt | sopt))
01115        {Eroute.Emsg("Config", "role not specified"); return 1;}
01116 
01117 // Pick up optional "if"
01118 //
01119     if (val && !strcmp("if", val))
01120        if ((rc = XrdOucUtils::doIf(&Eroute,Config,"role directive",
01121                                    getenv("XRDHOST"), XrdOucUtils::InstName(1),
01122                                    getenv("XRDPROG"))) <= 0)
01123            return (rc < 0);
01124 
01125 // Set values
01126 //
01127     free(myRole);
01128     myRole = strdup(role);
01129     Options &= resetit;
01130     Options |= ropt;
01131     return 0;
01132 }
01133 
01134 /******************************************************************************/
01135 /*                                x t r a c e                                 */
01136 /******************************************************************************/
01137 
01138 /* Function: xtrace
01139 
01140    Purpose:  To parse the directive: trace <events>
01141 
01142              <events> the blank separated list of events to trace. Trace
01143                       directives are cummalative.
01144 
01145    Output: 0 upon success or !0 upon failure.
01146 */
01147 
01148 int XrdOfs::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
01149 {
01150     static struct traceopts {const char *opname; int opval;} tropts[] =
01151        {
01152         {"aio",      TRACE_aio},
01153         {"all",      TRACE_ALL},
01154         {"chmod",    TRACE_chmod},
01155         {"close",    TRACE_close},
01156         {"closedir", TRACE_closedir},
01157         {"debug",    TRACE_debug},
01158         {"delay",    TRACE_delay},
01159         {"dir",      TRACE_dir},
01160         {"exists",   TRACE_exists},
01161         {"getstats", TRACE_getstats},
01162         {"fsctl",    TRACE_fsctl},
01163         {"io",       TRACE_IO},
01164         {"mkdir",    TRACE_mkdir},
01165         {"most",     TRACE_MOST},
01166         {"open",     TRACE_open},
01167         {"opendir",  TRACE_opendir},
01168         {"qscan",    TRACE_qscan},
01169         {"read",     TRACE_read},
01170         {"readdir",  TRACE_readdir},
01171         {"redirect", TRACE_redirect},
01172         {"remove",   TRACE_remove},
01173         {"rename",   TRACE_rename},
01174         {"sync",     TRACE_sync},
01175         {"truncate", TRACE_truncate},
01176         {"write",    TRACE_write}
01177        };
01178     int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
01179     char *val;
01180 
01181     if (!(val = Config.GetWord()))
01182        {Eroute.Emsg("Config", "trace option not specified"); return 1;}
01183     while (val)
01184          {if (!strcmp(val, "off")) trval = 0;
01185              else {if ((neg = (val[0] == '-' && val[1]))) val++;
01186                    for (i = 0; i < numopts; i++)
01187                        {if (!strcmp(val, tropts[i].opname))
01188                            {if (neg) trval &= ~tropts[i].opval;
01189                                else  trval |=  tropts[i].opval;
01190                             break;
01191                            }
01192                        }
01193                    if (i >= numopts)
01194                       Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
01195                   }
01196           val = Config.GetWord();
01197          }
01198     OfsTrace.What = trval;
01199 
01200 // All done
01201 //
01202    return 0;
01203 }
01204 
01205 /******************************************************************************/
01206 /*                             s e t u p A u t h                              */
01207 /******************************************************************************/
01208 
01209 int XrdOfs::setupAuth(XrdSysError &Eroute)
01210 {
01211    extern XrdAccAuthorize *XrdAccDefaultAuthorizeObject(XrdSysLogger *lp,
01212                                                         const char   *cfn,
01213                                                         const char   *parm);
01214    XrdSysPlugin    *myLib;
01215    XrdAccAuthorize *(*ep)(XrdSysLogger *, const char *, const char *);
01216 
01217 // Authorization comes from the library or we use the default
01218 //
01219    if (!AuthLib) return 0 == (Authorization = XrdAccDefaultAuthorizeObject
01220                               (Eroute.logger(),ConfigFN,AuthParm));
01221 
01222 // Create a pluin object (we will throw this away without deletion because
01223 // the library must stay open but we never want to reference it again).
01224 //
01225    if (!(myLib = new XrdSysPlugin(&Eroute, AuthLib))) return 1;
01226 
01227 // Now get the entry point of the object creator
01228 //
01229    ep = (XrdAccAuthorize *(*)(XrdSysLogger *, const char *, const char *))
01230                              (myLib->getPlugin("XrdAccAuthorizeObject"));
01231    if (!ep) return 1;
01232 
01233 // Get the Object now
01234 //
01235    return 0 == (Authorization = ep(Eroute.logger(), ConfigFN, AuthParm));
01236 }
01237   
01238 /******************************************************************************/
01239 /*                               t h e R o l e                                */
01240 /******************************************************************************/
01241   
01242 const char *XrdOfs::theRole(int opts)
01243 {
01244           if (opts & isPeer)    return "peer";
01245      else if (opts & isManager
01246           &&  opts & isServer)  return "supervisor";
01247      else if (opts & isManager) return "manager";
01248      else if (opts & isProxy)   return "proxy";
01249                                 return "server";
01250 }

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