00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00056
00057
00058 extern XrdOfsStats OfsStats;
00059
00060 extern XrdOucTrace OfsTrace;
00061
00062 class XrdOss;
00063 extern XrdOss *XrdOfsOss;
00064
00065
00066
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
00084
00085
00086 int XrdOfs::Configure(XrdSysError &Eroute) {
00087
00088
00089
00090
00091
00092
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
00102
00103 Eroute.Say("++++++ File system initialization started.");
00104
00105
00106
00107 Options = 0;
00108 if (getenv("XRDDEBUG")) OfsTrace.What = TRACE_MOST | TRACE_debug;
00109
00110
00111
00112 myPort = (var = getenv("XRDPORT")) ? strtol(var, (char **)NULL, 10) : 0;
00113
00114
00115
00116 if( !ConfigFN || !*ConfigFN)
00117 Eroute.Emsg("Config", "Configuration file not specified.");
00118 else {
00119
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
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
00135
00136 if ((retc = Config.LastError()))
00137 NoGo = Eroute.Emsg("Config", -retc, "read config file",
00138 ConfigFN);
00139 Config.Close();
00140 }
00141
00142
00143
00144 if (Options & Authorize) NoGo |= setupAuth(Eroute);
00145
00146
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
00163
00164 if (Options & isManager)
00165 XrdOucEnv::Export("XRDREDIRECT", (Options & isMeta ? "M" : "R"));
00166 else XrdOucEnv::Export("XRDREDIRECT", "0");
00167
00168
00169
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
00185
00186 if (!(Options & isManager)
00187 && !evrObject.Init(&Eroute, Balancer)) NoGo = 1;
00188
00189
00190
00191 if (Options & haveRole)
00192 {Eroute.Say("++++++ Configuring ", myRole, " role. . .");
00193 NoGo |= ConfigRedir(Eroute);
00194 }
00195
00196
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
00209
00210 if (!(XrdOfsOss = XrdOssGetSS(Eroute.logger(), ConfigFN, OssLib))) NoGo = 1;
00211
00212
00213
00214 if (!NoGo && evsObject) NoGo = evsObject->Start(&Eroute);
00215
00216
00217
00218
00219 if (poscAuto != -1 && !NoGo) NoGo |= ConfigPosc(Eroute);
00220
00221
00222
00223 OfsStats.setRole(myRole);
00224
00225
00226
00227 if (!NoGo) Config_Display(Eroute);
00228
00229
00230
00231 tmp = (NoGo ? " initialization failed." : " initialization completed.");
00232 Eroute.Say("------ File system ", myRole, tmp);
00233 return NoGo;
00234 }
00235
00236
00237
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);
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
00319
00320
00321
00322
00323
00324 int XrdOfs::ConfigDispFwd(char *buff, struct fwdOpt &Fwd)
00325 {
00326 const char *cP;
00327 char pbuff[16], *bp;
00328
00329
00330
00331 if (!(cP = Fwd.Cmd)) return 0;
00332 bp = buff;
00333 setBuff(" ofs.forward ", 19);
00334
00335
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
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;
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
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
00384
00385 if ((rc = XrdOucUtils::makePath(poscLog, AMode)))
00386 {Eroute.Emsg("Config", rc, "create path for", poscLog);
00387 return 1;
00388 }
00389
00390
00391
00392 poscQ = new XrdOfsPoscq(&Eroute, XrdOfsOss, poscLog);
00393 rP = poscQ->Init(rc);
00394 if (!rc) return 1;
00395
00396
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
00421
00422 return NoGo;
00423 }
00424
00425
00426
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
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
00445
00446
00447
00448
00449
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;
00461 }
00462
00463
00464
00465 return 0;
00466 }
00467
00468
00469
00470
00471
00472 int XrdOfs::ConfigXeq(char *var, XrdOucStream &Config,
00473 XrdSysError &Eroute)
00474 {
00475 char *val, vBuff[64];
00476
00477
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);
00488 TS_Xeq("role", xrole);
00489 TS_Xeq("trace", xtrace);
00490
00491
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
00498
00499 Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
00500 Config.Echo();
00501 return 0;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 int XrdOfs::xalib(XrdOucStream &Config, XrdSysError &Eroute)
00519 {
00520 char *val, parms[1024];
00521
00522
00523
00524 if (!(val = Config.GetWord()) || !val[0])
00525 {Eroute.Emsg("Config", "authlib not specified"); return 1;}
00526
00527
00528
00529 if (AuthLib) free(AuthLib);
00530 AuthLib = strdup(val);
00531
00532
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
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
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
00657
00658 Options |= Forwarding;
00659 return 0;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
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
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
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
00729
00730 if (!(val = Config.GetWord()))
00731 {Eroute.Emsg("Config", "notifymsg event not specified");
00732 return 1;
00733 }
00734
00735
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
00745
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
00755
00756 Config.SetEnv(myEnv);
00757 return XrdOfsEvs::Parse(Eroute, noval, buff);
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
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
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
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
00850
00851 if (evsObject) delete evsObject;
00852 evsObject = new XrdOfsEvs(noval, val, msgL, msgB);
00853
00854
00855
00856 return 0;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 int XrdOfs::xolib(XrdOucStream &Config, XrdSysError &Eroute)
00874 {
00875 char *val, parms[2048];
00876 int pl;
00877
00878
00879
00880 if (!(val = Config.GetWord()) || !val[0])
00881 {Eroute.Emsg("Config", "osslib not specified"); return 1;}
00882
00883
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
00892
00893 if (OssLib) free(OssLib);
00894 OssLib = strdup(parms);
00895 return 0;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
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
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
00931
00932 if (popt > -2) val = Config.GetWord();
00933
00934
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
00958
00959 if (htime >= 0) poscHold = htime;
00960 if (popt > -2) poscAuto = popt;
00961 return 0;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
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
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
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
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
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
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
01113
01114 if (!(ropt = mopt | qopt | ropt | sopt))
01115 {Eroute.Emsg("Config", "role not specified"); return 1;}
01116
01117
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
01126
01127 free(myRole);
01128 myRole = strdup(role);
01129 Options &= resetit;
01130 Options |= ropt;
01131 return 0;
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
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
01201
01202 return 0;
01203 }
01204
01205
01206
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
01218
01219 if (!AuthLib) return 0 == (Authorization = XrdAccDefaultAuthorizeObject
01220 (Eroute.logger(),ConfigFN,AuthParm));
01221
01222
01223
01224
01225 if (!(myLib = new XrdSysPlugin(&Eroute, AuthLib))) return 1;
01226
01227
01228
01229 ep = (XrdAccAuthorize *(*)(XrdSysLogger *, const char *, const char *))
01230 (myLib->getPlugin("XrdAccAuthorizeObject"));
01231 if (!ep) return 1;
01232
01233
01234
01235 return 0 == (Authorization = ep(Eroute.logger(), ConfigFN, AuthParm));
01236 }
01237
01238
01239
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 }