00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <unistd.h>
00012 #include <ctype.h>
00013 #include <fcntl.h>
00014 #include <string.h>
00015 #include <stdio.h>
00016 #include <sys/param.h>
00017 #include <sys/stat.h>
00018 #include <sys/types.h>
00019 #include <sys/un.h>
00020
00021 #include "XrdVersion.hh"
00022
00023 #include "XrdSfs/XrdSfsInterface.hh"
00024 #include "XrdNet/XrdNetDNS.hh"
00025 #include "XrdNet/XrdNetOpts.hh"
00026 #include "XrdNet/XrdNetSocket.hh"
00027 #include "XrdOuc/XrdOuca2x.hh"
00028 #include "XrdOuc/XrdOucEnv.hh"
00029 #include "XrdOuc/XrdOucProg.hh"
00030 #include "XrdOuc/XrdOucReqID.hh"
00031 #include "XrdOuc/XrdOucStream.hh"
00032 #include "XrdOuc/XrdOucTrace.hh"
00033 #include "XrdOuc/XrdOucUtils.hh"
00034 #include "XrdSys/XrdSysError.hh"
00035 #include "XrdSys/XrdSysHeaders.hh"
00036 #include "XrdSys/XrdSysLogger.hh"
00037
00038 #include "XrdXrootd/XrdXrootdAdmin.hh"
00039 #include "XrdXrootd/XrdXrootdAio.hh"
00040 #include "XrdXrootd/XrdXrootdCallBack.hh"
00041 #include "XrdXrootd/XrdXrootdFile.hh"
00042 #include "XrdXrootd/XrdXrootdFileLock.hh"
00043 #include "XrdXrootd/XrdXrootdFileLock1.hh"
00044 #include "XrdXrootd/XrdXrootdJob.hh"
00045 #include "XrdXrootd/XrdXrootdMonitor.hh"
00046 #include "XrdXrootd/XrdXrootdPrepare.hh"
00047 #include "XrdXrootd/XrdXrootdProtocol.hh"
00048 #include "XrdXrootd/XrdXrootdStats.hh"
00049 #include "XrdXrootd/XrdXrootdTrace.hh"
00050 #include "XrdXrootd/XrdXrootdXPath.hh"
00051
00052 #include "Xrd/XrdBuffer.hh"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 extern XrdOucTrace *XrdXrootdTrace;
00082
00083 XrdXrootdPrepare *XrdXrootdPrepQ;
00084
00085 XrdOucReqID *XrdXrootdReqID;
00086
00087 const char *XrdXrootdInstance;
00088
00089 XrdInet *XrdXrootdNetwork;
00090
00091 int XrdXrootdPort;
00092
00093
00094
00095
00096
00097 int XrdXrootdProtocol::Configure(char *parms, XrdProtocol_Config *pi)
00098 {
00099
00100
00101
00102
00103
00104
00105
00106 extern XrdSfsFileSystem *XrdSfsGetDefaultFileSystem
00107 (XrdSfsFileSystem *nativeFS,
00108 XrdSysLogger *Logger,
00109 const char *configFn);
00110 extern XrdSecService *XrdXrootdloadSecurity(XrdSysError *, char *, char *);
00111 extern XrdSfsFileSystem *XrdXrootdloadFileSystem(XrdSysError *, char *,
00112 const char *);
00113 extern int optind, opterr;
00114
00115 XrdXrootdXPath *xp;
00116 char *adminp, *fsver, *rdf, *bP, *tmp, c, buff[1024];
00117 int i, n, deper = 0;
00118
00119
00120
00121 eDest.logger(pi->eDest->logger());
00122 XrdXrootdTrace = new XrdOucTrace(&eDest);
00123 SI = new XrdXrootdStats(pi->Stats);
00124 Sched = pi->Sched;
00125 BPool = pi->BPool;
00126 hailWait = pi->hailWait;
00127 readWait = pi->readWait;
00128 Port = pi->Port;
00129 myInst = pi->myInst;
00130 Window = pi->WSize;
00131 WANPort = pi->WANPort;
00132 WANWindow = pi->WANWSize;
00133
00134
00135
00136 XrdXrootdInstance = pi->myInst;
00137 XrdXrootdNetwork = pi->NetTCP;
00138 XrdXrootdPort = pi->Port;
00139
00140
00141
00142 XrdXrootdCallBack::setVals(&eDest, SI, Sched, Port);
00143
00144
00145
00146 if (geteuid() == 0)
00147 {eDest.Emsg("Config", "Security reasons prohibit xrootd running as "
00148 "superuser; xrootd is terminating.");
00149 _exit(8);
00150 }
00151
00152
00153
00154 opterr = 0; optind = 1;
00155 if (pi->argc > 1 && '-' == *(pi->argv[1]))
00156 while ((c=getopt(pi->argc,pi->argv,"mrst")) && ((unsigned char)c != 0xff))
00157 { switch(c)
00158 {
00159 case 'r': deper = 1;
00160 case 'm': XrdOucEnv::Export("XRDREDIRECT", "R");
00161 break;
00162 case 't': deper = 1;
00163 case 's': XrdOucEnv::Export("XRDRETARGET", "1");
00164 break;
00165 case 'y': XrdOucEnv::Export("XRDREDPROXY", "1");
00166 break;
00167 default: eDest.Say("Config warning: ignoring invalid option '",pi->argv[optind-1],"'.");
00168 }
00169 }
00170
00171
00172
00173 if (deper) eDest.Say("Config warning: '-r -t' are deprecated; use '-m -s' instead.");
00174
00175
00176
00177 for ( ; optind < pi->argc; optind++) xexpdo(pi->argv[optind]);
00178
00179
00180
00181
00182 if (!(as_miniosz = as_segsize/2)) as_miniosz = as_segsize;
00183 maxTransz = maxBuffsz = BPool->MaxSize();
00184
00185
00186
00187 rdf = (parms && *parms ? parms : pi->ConfigFN);
00188 if (rdf && Config(rdf)) return 0;
00189 if (pi->DebugON) XrdXrootdTrace->What = TRACE_ALL;
00190
00191
00192
00193 if (!(xp = XPList.Next()))
00194 {XPList.Insert("/tmp"); n = 8;
00195 eDest.Say("Config warning: only '/tmp' will be exported.");
00196 } else {
00197 n = 0;
00198 while(xp) {eDest.Say("Config exporting ", xp->Path(i));
00199 n += i+2; xp = xp->Next();
00200 }
00201 }
00202
00203
00204
00205 bP = tmp = (char *)malloc(n);
00206 xp = XPList.Next();
00207 while(xp) {strcpy(bP, xp->Path(i)); bP += i; *bP++ = ' '; xp = xp->Next();}
00208 *(bP-1) = '\0';
00209 XrdOucEnv::Export("XRDEXPORTS", tmp); free(tmp);
00210
00211
00212
00213 if (!as_noaio) XrdXrootdAioReq::Init(as_segsize, as_maxperreq, as_maxpersrv);
00214 else eDest.Say("Config warning: asynchronous I/O has been disabled!");
00215
00216
00217
00218 if (!SecLib) eDest.Say("Config warning: 'xrootd.seclib' not specified;"
00219 " strong authentication disabled!");
00220 else {TRACE(DEBUG, "Loading security library " <<SecLib);
00221 if (!(CIA = XrdXrootdloadSecurity(&eDest, SecLib, pi->ConfigFN)))
00222 {eDest.Emsg("Config", "Unable to load security system.");
00223 return 0;
00224 }
00225 }
00226
00227
00228
00229 if (FSLib)
00230 {TRACE(DEBUG, "Loading filesystem library " <<FSLib);
00231 osFS = XrdXrootdloadFileSystem(&eDest, FSLib, pi->ConfigFN);
00232 } else osFS = XrdSfsGetDefaultFileSystem(0, eDest.logger(), pi->ConfigFN);
00233 if (!osFS)
00234 {eDest.Emsg("Config", "Unable to load file system.");
00235 return 0;
00236 } else SI->setFS(osFS);
00237
00238
00239
00240 if (chkfsV)
00241 {fsver = (char *)osFS->getVersion();
00242 if (strcmp(XrdVERSION, fsver))
00243 eDest.Emsg("Config", "Warning! xrootd build version " XrdVERSION
00244 "differs from file system version ", fsver);
00245 }
00246
00247
00248
00249 Locker = (XrdXrootdFileLock *)new XrdXrootdFileLock1();
00250 XrdXrootdFile::Init(Locker, as_nosf == 0);
00251 if (as_nosf) eDest.Say("Config warning: sendfile I/O has been disabled!");
00252
00253
00254
00255 ProtStack.Set(pi->Sched, XrdXrootdTrace, TRACE_MEM);
00256 ProtStack.Set((pi->ConnMax/3 ? pi->ConnMax/3 : 30), 60*60);
00257
00258
00259
00260 XrdXrootdReqID = new XrdOucReqID((int)Port, pi->myName,
00261 XrdNetDNS::IPAddr(pi->myAddr));
00262
00263
00264
00265 XrdXrootdPrepQ = new XrdXrootdPrepare(&eDest, pi->Sched);
00266 sprintf(buff, "udp://%s:%d/&L=%%d&U=%%s", pi->myName, pi->Port);
00267 Notify = strdup(buff);
00268
00269
00270
00271 if ((xp = RPList.Next()))
00272 {int k;
00273 char buff[512];
00274 do {k = xp->Opts();
00275 sprintf(buff, " to %s:%d", Route[k].Host, Route[k].Port);
00276 eDest.Say("Config redirecting ", xp->Path(), buff);
00277 xp = xp->Next();
00278 } while(xp);
00279 }
00280
00281
00282
00283 if ((rdf = getenv("XRDREDIRECT"))
00284 && (!strcmp(rdf, "R") || !strcmp(rdf, "M"))) isRedir = *rdf;
00285
00286
00287
00288 if (!isRedir && !XrdXrootdMonitor::Init(Sched,&eDest)) return 0;
00289
00290
00291
00292 if (JobCKS) XrdXrootdAdmin::addJob("chksum", JobCKS);
00293
00294
00295
00296
00297 adminp = XrdOucUtils::genPath(pi->AdmPath, 0, ".xrootd");
00298
00299
00300
00301 if (!(AdminSock = XrdNetSocket::Create(&eDest, adminp, "admin", pi->AdmMode))
00302 || !XrdXrootdAdmin::Init(&eDest, AdminSock)) return 0;
00303
00304
00305
00306 PidFile();
00307
00308
00309
00310 free(adminp);
00311 return 1;
00312 }
00313
00314
00315
00316
00317
00318 #define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
00319
00320 int XrdXrootdProtocol::Config(const char *ConfigFN)
00321 {
00322 XrdOucEnv myEnv;
00323 XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
00324 char *var;
00325 int cfgFD, GoNo, NoGo = 0, ismine;
00326
00327
00328
00329 if ((cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
00330 return eDest.Emsg("Config", errno, "open config file", ConfigFN);
00331 Config.Attach(cfgFD);
00332
00333
00334
00335 while((var = Config.GetMyFirstWord()))
00336 { if ((ismine = !strncmp("xrootd.", var, 7)) && var[7]) var += 7;
00337 else if ((ismine = !strcmp("all.export", var))) var += 4;
00338 else if ((ismine = !strcmp("all.pidpath",var))) var += 4;
00339 else if ((ismine = !strcmp("all.seclib", var))) var += 4;
00340
00341 if (ismine)
00342 { if TS_Xeq("async", xasync);
00343 else if TS_Xeq("chksum", xcksum);
00344 else if TS_Xeq("export", xexp);
00345 else if TS_Xeq("fslib", xfsl);
00346 else if TS_Xeq("log", xlog);
00347 else if TS_Xeq("monitor", xmon);
00348 else if TS_Xeq("pidpath", xpidf);
00349 else if TS_Xeq("prep", xprep);
00350 else if TS_Xeq("redirect", xred);
00351 else if TS_Xeq("seclib", xsecl);
00352 else if TS_Xeq("trace", xtrace);
00353 else {eDest.Say("Config warning: ignoring unknown directive '",var,"'.");
00354 Config.Echo();
00355 continue;
00356 }
00357 if (GoNo) {Config.Echo(); NoGo = 1;}
00358 }
00359 }
00360 return NoGo;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370 void XrdXrootdProtocol::PidFile()
00371 {
00372 int rc, xfd;
00373 char buff[32], pidFN[1200];
00374 char *ppath=XrdOucUtils::genPath(pidPath,XrdOucUtils::InstName(-1));
00375 const char *xop = 0;
00376
00377 if ((rc = XrdOucUtils::makePath(ppath,XrdOucUtils::pathMode)))
00378 {xop = "create"; errno = rc;}
00379 else {snprintf(pidFN, sizeof(pidFN), "%s/xrootd.pid", ppath);
00380
00381 if ((xfd = open(pidFN, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
00382 xop = "open";
00383 else {if (write(xfd,buff,snprintf(buff,sizeof(buff),"%d",
00384 static_cast<int>(getpid()))) < 0) xop = "write";
00385 close(xfd);
00386 }
00387 }
00388
00389 free(ppath);
00390 if (xop) eDest.Emsg("Config", errno, xop, pidFN);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 int XrdXrootdProtocol::xasync(XrdOucStream &Config)
00426 {
00427 char *val;
00428 int i, ppp;
00429 int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
00430 int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
00431 int V_minsf=-1;
00432 long long llp;
00433 static struct asyncopts {const char *opname; int minv; int *oploc;
00434 const char *opmsg;} asopts[] =
00435 {
00436 {"force", -1, &V_force, ""},
00437 {"off", -1, &V_off, ""},
00438 {"nosf", -1, &V_nosf, ""},
00439 {"syncw", -1, &V_syncw, ""},
00440 {"limit", 0, &V_limit, "async limit"},
00441 {"segsize", 4096, &V_segsz, "async segsize"},
00442 {"maxsegs", 0, &V_msegs, "async maxsegs"},
00443 {"maxstalls", 0, &V_mstall,"async maxstalls"},
00444 {"maxtot", 0, &V_mtot, "async maxtot"},
00445 {"minsfsz", 1, &V_minsf, "async minsfsz"},
00446 {"minsize", 4096, &V_minsz, "async minsize"}};
00447 int numopts = sizeof(asopts)/sizeof(struct asyncopts);
00448
00449 if (!(val = Config.GetWord()))
00450 {eDest.Emsg("Config", "async option not specified"); return 1;}
00451
00452 while (val)
00453 {for (i = 0; i < numopts; i++)
00454 if (!strcmp(val, asopts[i].opname))
00455 {if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
00456 {eDest.Emsg("Config","async",(char *)asopts[i].opname,
00457 "value not specified");
00458 return 1;
00459 }
00460 if (asopts[i].minv > 0)
00461 if (XrdOuca2x::a2sz(eDest,asopts[i].opmsg, val, &llp,
00462 (long long)asopts[i].minv)) return 1;
00463 else *asopts[i].oploc = (int)llp;
00464 else if (asopts[i].minv == 0)
00465 if (XrdOuca2x::a2i(eDest,asopts[i].opmsg,val,&ppp,1))
00466 return 1;
00467 else *asopts[i].oploc = ppp;
00468 else *asopts[i].oploc = 1;
00469 break;
00470 }
00471 if (i >= numopts)
00472 eDest.Emsg("Config", "Warning, invalid async option", val);
00473 val = Config.GetWord();
00474 }
00475
00476
00477
00478 if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
00479 {eDest.Emsg("Config", "async limit may not be greater than maxtot");
00480 return 1;
00481 }
00482
00483
00484
00485 if (V_segsz > 0)
00486 {i = BPool->Recalc(V_segsz);
00487 if (!i) {eDest.Emsg("Config", "async segsize is too large"); return 1;}
00488 if (i != V_segsz)
00489 {char buff[64];
00490 sprintf(buff, "%d readjusted to %d", V_segsz, i);
00491 eDest.Emsg("Config", "async segsize", buff);
00492 V_segsz = i;
00493 }
00494 }
00495
00496
00497
00498 if (V_limit > 0) as_maxperlnk = V_limit;
00499 if (V_msegs > 0) as_maxperreq = V_msegs;
00500 if (V_mtot > 0) as_maxpersrv = V_mtot;
00501 if (V_minsz > 0) as_miniosz = V_minsz;
00502 if (V_segsz > 0) as_segsize = V_segsz;
00503 if (V_mstall> 0) as_maxstalls = V_mstall;
00504 if (V_force > 0) as_force = 1;
00505 if (V_off > 0) as_noaio = 1;
00506 if (V_syncw > 0) as_syncw = 1;
00507 if (V_nosf > 0) as_nosf = 1;
00508 if (V_minsf > 0) as_minsfsz = V_minsf;
00509
00510 return 0;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 int XrdXrootdProtocol::xcksum(XrdOucStream &Config)
00529 {
00530 static XrdOucProg *theProg = 0;
00531 char *palg, prog[2048];
00532 int jmax = 4;
00533
00534
00535
00536 while ((palg = Config.GetWord()) && *palg != '/')
00537 {if (strcmp(palg, "max")) break;
00538 if (!(palg = Config.GetWord()))
00539 {eDest.Emsg("Config", "chksum max not specified"); return 1;}
00540 if (XrdOuca2x::a2i(eDest, "chksum max", palg, &jmax, 1)) return 1;
00541 }
00542
00543
00544
00545 if (!palg || *palg == '/')
00546 {eDest.Emsg("Config", "chksum algorithm not specified"); return 1;}
00547 if (JobCKT) free(JobCKT);
00548 JobCKT = strdup(palg);
00549
00550
00551
00552 if (!Config.GetRest(prog, sizeof(prog)))
00553 {eDest.Emsg("Config", "cksum parameters too long"); return 1;}
00554 if (*prog == '\0')
00555 {eDest.Emsg("Config", "chksum program not specified"); return 1;}
00556
00557
00558
00559 if (!theProg) theProg = new XrdOucProg(0);
00560 if (theProg->Setup(prog, &eDest)) return 1;
00561 if (JobCKS) delete JobCKS;
00562 JobCKS = new XrdXrootdJob(Sched, theProg, "chksum", jmax);
00563 return 0;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 int XrdXrootdProtocol::xexp(XrdOucStream &Config)
00580 {
00581 char *val, pbuff[1024];
00582 int popt = 0;
00583
00584
00585
00586 val = Config.GetWord();
00587 if (!val || !val[0])
00588 {eDest.Emsg("Config", "export path not specified"); return 1;}
00589 strlcpy(pbuff, val, sizeof(pbuff));
00590
00591
00592
00593 if ((val = Config.GetWord()))
00594 {if (!strcmp("nolock", val)) popt = XROOTDXP_NOLK;
00595 else if (strcmp("lock", val)) Config.RetToken();
00596 }
00597
00598
00599
00600 return xexpdo(pbuff, popt);
00601 }
00602
00603
00604
00605 int XrdXrootdProtocol::xexpdo(char *path, int popt)
00606 {
00607 const char *opaque;
00608
00609
00610
00611 if (rpCheck(path, &opaque))
00612 {eDest.Emsg("Config", "non-absolute export path -", path); return 1;}
00613
00614
00615
00616 if (!Squash(path)) XPList.Insert(path, popt);
00617 return 0;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 int XrdXrootdProtocol::xfsl(XrdOucStream &Config)
00635 {
00636 char *val, *Slash;
00637
00638
00639
00640 chkfsV = 0;
00641 if ((val = Config.GetWord()) && *val == '?' && !val[1])
00642 {chkfsV = '?'; val = Config.GetWord();}
00643
00644 if (!val || !val[0])
00645 {eDest.Emsg("Config", "fslib not specified"); return 1;}
00646
00647
00648
00649
00650 if (!(Slash = rindex(val, '/'))) Slash = val;
00651 if (!strcmp(Slash, "/libXrdOfs.so"))
00652 eDest.Say("Config warning: ignoring fslib; libXrdOfs.so is built-in.");
00653 else {if (FSLib) free(FSLib);
00654 FSLib = strdup(val);
00655 }
00656 return 0;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 int XrdXrootdProtocol::xlog(XrdOucStream &Config)
00673 {
00674 char *val;
00675 static struct logopts {const char *opname; int opval;} lgopts[] =
00676 {
00677 {"all", -1},
00678 {"disc", SYS_LOG_02},
00679 {"login", SYS_LOG_01}
00680 };
00681 int i, neg, lgval = -1, numopts = sizeof(lgopts)/sizeof(struct logopts);
00682
00683 if (!(val = Config.GetWord()))
00684 {eDest.Emsg("config", "log option not specified"); return 1;}
00685 while (val)
00686 {if ((neg = (val[0] == '-' && val[1]))) val++;
00687 for (i = 0; i < numopts; i++)
00688 {if (!strcmp(val, lgopts[i].opname))
00689 {if (neg) lgval &= ~lgopts[i].opval;
00690 else lgval |= lgopts[i].opval;
00691 break;
00692 }
00693 }
00694 if (i >= numopts) eDest.Emsg("config","invalid log option",val);
00695 val = Config.GetWord();
00696 }
00697 eDest.setMsgMask(lgval);
00698 return 0;
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 int XrdXrootdProtocol::xmon(XrdOucStream &Config)
00729 { char *val, *cp, *monDest[2] = {0, 0};
00730 long long tempval;
00731 int i, monFlush=0, monMBval=0, monWWval=0, xmode=0, monMode[2] = {0, 0};
00732
00733 while((val = Config.GetWord()))
00734
00735 { if (!strcmp("all", val)) xmode = XROOTD_MON_ALL;
00736 else if (!strcmp("flush", val))
00737 {if (!(val = Config.GetWord()))
00738 {eDest.Emsg("Config", "monitor flush value not specified");
00739 return 1;
00740 }
00741 if (XrdOuca2x::a2tm(eDest,"monitor flush",val,
00742 &monFlush,1)) return 1;
00743 }
00744 else if (!strcmp("mbuff",val))
00745 {if (!(val = Config.GetWord()))
00746 {eDest.Emsg("Config", "monitor mbuff value not specified");
00747 return 1;
00748 }
00749 if (XrdOuca2x::a2sz(eDest,"monitor mbuff", val,
00750 &tempval, 1024, 65536)) return 1;
00751 monMBval = static_cast<int>(tempval);
00752 }
00753 else if (!strcmp("window", val))
00754 {if (!(val = Config.GetWord()))
00755 {eDest.Emsg("Config", "monitor window value not specified");
00756 return 1;
00757 }
00758 if (XrdOuca2x::a2tm(eDest,"monitor window",val,
00759 &monWWval,1)) return 1;
00760 }
00761 else break;
00762 }
00763
00764 if (!val) {eDest.Emsg("Config", "monitor dest not specified"); return 1;}
00765
00766 for (i = 0; i < 2; i++)
00767 {if (strcmp("dest", val)) break;
00768 while((val = Config.GetWord()))
00769 if (!strcmp("files",val)) monMode[i] |= XROOTD_MON_FILE;
00770 else if (!strcmp("info", val)) monMode[i] |= XROOTD_MON_INFO;
00771 else if (!strcmp("io", val)) monMode[i] |= XROOTD_MON_IO;
00772 else if (!strcmp("stage",val)) monMode[i] |= XROOTD_MON_STAGE;
00773 else if (!strcmp("user", val)) monMode[i] |= XROOTD_MON_USER;
00774 else break;
00775 if (!val) {eDest.Emsg("Config","monitor dest value not specified");
00776 return 1;
00777 }
00778 if (!(cp = index(val, (int)':')) || !atoi(cp+1))
00779 {eDest.Emsg("Config","monitor dest port missing or invalid in",val);
00780 return 1;
00781 }
00782 monDest[i] = strdup(val);
00783 if (!(val = Config.GetWord())) break;
00784 }
00785
00786 if (val)
00787 {if (!strcmp("dest", val))
00788 eDest.Emsg("Config", "Warning, a maximum of two dest values allowed.");
00789 else eDest.Emsg("Config", "Warning, invalid monitor option", val);
00790 }
00791
00792
00793
00794 if (monDest[0] && monDest[1] && !strcmp(monDest[0], monDest[1]))
00795 {eDest.Emsg("Config", "Warning, monitor dests are identical.");
00796 monMode[0] |= monMode[1]; monMode[1] = 0;
00797 free(monDest[1]); monDest[1] = 0;
00798 }
00799
00800
00801
00802 if (monDest[0] && monMode[0] == XROOTD_MON_STAGE)
00803 {monMode[0] = 0; free(monDest[0]); monDest[0] = 0;}
00804 if (monDest[1] && monMode[1] == XROOTD_MON_STAGE)
00805 {monMode[1] = 0; free(monDest[1]); monDest[1] = 0;}
00806
00807
00808
00809 if (monMode[0] & XROOTD_MON_IO) monMode[0] |= XROOTD_MON_FILE;
00810 if (monMode[1] & XROOTD_MON_IO) monMode[1] |= XROOTD_MON_FILE;
00811
00812
00813
00814 XrdXrootdMonitor::Defaults(monMBval, monWWval, monFlush);
00815 if (monDest[0]) monMode[0] |= (monMode[0] ? xmode : XROOTD_MON_FILE|xmode);
00816 if (monDest[1]) monMode[1] |= (monMode[1] ? xmode : XROOTD_MON_FILE|xmode);
00817 XrdXrootdMonitor::Defaults(monDest[0],monMode[0],monDest[1],monMode[1]);
00818 return 0;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 int XrdXrootdProtocol::xpidf(XrdOucStream &Config)
00835 {
00836 char *val;
00837
00838
00839
00840 val = Config.GetWord();
00841 if (!val || !val[0])
00842 {eDest.Emsg("Config", "pidpath not specified"); return 1;}
00843
00844
00845
00846 if (pidPath) free(pidPath);
00847 pidPath = strdup(val);
00848 return 0;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 int XrdXrootdProtocol::xprep(XrdOucStream &Config)
00866 { int rc, keep = 0, scrub=0;
00867 char *ldir=0,*val,buff[1024];
00868
00869 if (!(val = Config.GetWord()))
00870 {eDest.Emsg("Config", "prep options not specified"); return 1;}
00871
00872 do { if (!strcmp("keep", val))
00873 {if (!(val = Config.GetWord()))
00874 {eDest.Emsg("Config", "prep keep value not specified");
00875 return 1;
00876 }
00877 if (XrdOuca2x::a2tm(eDest,"prep keep int",val,&keep,1)) return 1;
00878 }
00879 else if (!strcmp("scrub", val))
00880 {if (!(val = Config.GetWord()))
00881 {eDest.Emsg("Config", "prep scrub value not specified");
00882 return 1;
00883 }
00884 if (XrdOuca2x::a2tm(eDest,"prep scrub",val,&scrub,0)) return 1;
00885 }
00886 else if (!strcmp("logdir", val))
00887 {if (!(ldir = Config.GetWord()))
00888 {eDest.Emsg("Config", "prep logdir value not specified");
00889 return 1;
00890 }
00891 }
00892 else eDest.Emsg("Config", "Warning, invalid prep option", val);
00893 } while((val = Config.GetWord()));
00894
00895
00896
00897 if (scrub || keep) XrdXrootdPrepare::setParms(scrub, keep);
00898 if (ldir)
00899 if ((rc = XrdOucUtils::genPath(buff, sizeof(buff), ldir, myInst)) < 0
00900 || (rc = XrdOucUtils::makePath(buff, XrdOucUtils::pathMode)) < 0
00901 || (rc = XrdXrootdPrepare::setParms(buff)) < 0)
00902 {eDest.Emsg("Config", rc, "process logdir", ldir);
00903 return 1;
00904 }
00905 return 0;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 int XrdXrootdProtocol::xred(XrdOucStream &Config)
00930 {
00931 static struct rediropts {const char *opname; RD_func opval;} rdopts[] =
00932 {
00933 {"chmod", RD_chmod},
00934 {"dirlist", RD_dirlist},
00935 {"locate", RD_locate},
00936 {"mkdir", RD_mkdir},
00937 {"mv", RD_mv},
00938 {"prepare", RD_prepare},
00939 {"prepstage",RD_prepstg},
00940 {"rm", RD_rm},
00941 {"rmdir", RD_rmdir},
00942 {"stat", RD_stat}
00943 };
00944 char rHost[512], *val, *pp;
00945 int i, k, neg, rPort, numopts = sizeof(rdopts)/sizeof(struct rediropts);
00946
00947
00948
00949 val = Config.GetWord();
00950 if (!val || !val[0] || val[0] == ':')
00951 {eDest.Emsg("Config", "redirect host not specified"); return 1;}
00952 if (!(pp = index(val, ':')))
00953 {eDest.Emsg("Config", "redirect port not specified"); return 1;}
00954 if (!(rPort = atoi(pp+1)))
00955 {eDest.Emsg("Config", "redirect port is invalid"); return 1;}
00956 *pp = '\0';
00957 strlcpy(rHost, val, sizeof(rHost));
00958
00959
00960
00961 if (!(val = Config.GetWord()))
00962 {eDest.Emsg("config", "redirect option not specified"); return 1;}
00963
00964 if (*val == '/')
00965 {for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
00966 if (!Route[k].Host
00967 || (strcmp(Route[k].Host, rHost) && Route[k].Port == rPort)) break;
00968 if (k >= RD_Num)
00969 {eDest.Emsg("Config", "too many diffrent path redirects"); return 1;}
00970 xred_set(RD_func(k), rHost, rPort);
00971 do {RPList.Insert(val, k, 0);
00972 if ((val = Config.GetWord()) && *val != '/')
00973 {eDest.Emsg("Config", "non-absolute redirect path -", val);
00974 return 1;
00975 }
00976 } while(val);
00977 return 0;
00978 }
00979
00980 while (val)
00981 {if (!strcmp(val, "all"))
00982 {for (i = 0; i < numopts; i++)
00983 xred_set(rdopts[i].opval, rHost, rPort);
00984 }
00985 else {if ((neg = (val[0] == '-' && val[1]))) val++;
00986 for (i = 0; i < numopts; i++)
00987 {if (!strcmp(val, rdopts[i].opname))
00988 {if (neg) xred_set(rdopts[i].opval, 0, 0);
00989 else xred_set(rdopts[i].opval, rHost, rPort);
00990 break;
00991 }
00992 }
00993 if (i >= numopts)
00994 eDest.Emsg("config", "invalid redirect option", val);
00995 }
00996 val = Config.GetWord();
00997 }
00998 return 0;
00999 }
01000
01001 void XrdXrootdProtocol::xred_set(RD_func func, const char *rHost, int rPort)
01002 {
01003
01004
01005 if (Route[func].Host) free(Route[func].Host);
01006 Route[func].Host = (rHost ? strdup(rHost) : 0);
01007 Route[func].Port = rPort;
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
01024 {
01025 char *val;
01026
01027
01028
01029 val = Config.GetWord();
01030 if (!val || !val[0])
01031 {eDest.Emsg("Config", "XRootd seclib not specified"); return 1;}
01032
01033
01034
01035 if (SecLib) free(SecLib);
01036 SecLib = strdup(val);
01037 return 0;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
01055 {
01056 char *val;
01057 static struct traceopts {const char *opname; int opval;} tropts[] =
01058 {
01059 {"all", TRACE_ALL},
01060 {"emsg", TRACE_EMSG},
01061 {"debug", TRACE_DEBUG},
01062 {"fs", TRACE_FS},
01063 {"login", TRACE_LOGIN},
01064 {"mem", TRACE_MEM},
01065 {"stall", TRACE_STALL},
01066 {"redirect", TRACE_REDIR},
01067 {"request", TRACE_REQ},
01068 {"response", TRACE_RSP}
01069 };
01070 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
01071
01072 if (!(val = Config.GetWord()))
01073 {eDest.Emsg("config", "trace option not specified"); return 1;}
01074 while (val)
01075 {if (!strcmp(val, "off")) trval = 0;
01076 else {if ((neg = (val[0] == '-' && val[1]))) val++;
01077 for (i = 0; i < numopts; i++)
01078 {if (!strcmp(val, tropts[i].opname))
01079 {if (neg) trval &= ~tropts[i].opval;
01080 else trval |= tropts[i].opval;
01081 break;
01082 }
01083 }
01084 if (i >= numopts)
01085 eDest.Emsg("config", "invalid trace option", val);
01086 }
01087 val = Config.GetWord();
01088 }
01089 XrdXrootdTrace->What = trval;
01090 return 0;
01091 }