XRootD
XrdXrootdConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d X r o o t d C o n f i g . c c */
4 /* */
5 /* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <unistd.h>
31 #include <cctype>
32 #include <fcntl.h>
33 #include <string>
34 #include <cstring>
35 #include <cstdio>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <vector>
40 
41 #ifdef __solaris__
42 #include <sys/isa_defs.h>
43 #endif
44 
45 #include "XrdVersion.hh"
46 
47 #include "XProtocol/XProtocol.hh"
48 
49 #include "XrdSfs/XrdSfsFlags.hh"
51 #include "XrdNet/XrdNetOpts.hh"
52 #include "XrdNet/XrdNetPMarkCfg.hh"
53 #include "XrdNet/XrdNetSocket.hh"
54 #include "XrdOuc/XrdOuca2x.hh"
55 #include "XrdOuc/XrdOucEnv.hh"
56 #include "XrdOuc/XrdOucProg.hh"
57 #include "XrdOuc/XrdOucReqID.hh"
58 #include "XrdOuc/XrdOucString.hh"
59 #include "XrdOuc/XrdOucStream.hh"
60 #include "XrdOuc/XrdOucUtils.hh"
62 #include "XrdSys/XrdSysError.hh"
63 #include "XrdSys/XrdSysHeaders.hh"
64 #include "XrdSys/XrdSysLogger.hh"
65 
66 #include "XrdTls/XrdTlsContext.hh"
67 
80 
81 #include "Xrd/XrdBuffer.hh"
82 #include "Xrd/XrdInet.hh"
83 #include "Xrd/XrdLink.hh"
84 
85 /******************************************************************************/
86 /* P r o t o c o l C o m m a n d L i n e O p t i o n s */
87 /******************************************************************************/
88 
89 /* This is the XRootd server. The syntax is:
90 
91  xrootd [options]
92 
93  options: [<xopt>] [-r] [-t] [-y] [path]
94 
95 Where:
96  xopt are xrd specified options that are screened out.
97 
98  -r This is a redirecting server.
99 
100  -t This server is a redirection target.
101 
102  -y This server is a proxy server.
103 
104  path Export path. Any number of paths may be specified.
105  By default, only '/tmp' is exported.
106 
107 */
108 /******************************************************************************/
109 /* G l o b a l s */
110 /******************************************************************************/
111 
113 
115 
117 
118  const char *XrdXrootdInstance;
119 
121 
124  const char *,
125  const char *, XrdOucEnv *);
127  (XrdSfsFileSystem *nativeFS,
129  const char *configFn,
130  XrdOucEnv *EnvInfo);
131 
132 /******************************************************************************/
133 /* G l o b a l S t a t i c s */
134 /******************************************************************************/
135 
136 namespace XrdXrootd
137 {
138 extern XrdBuffManager *BPool;
139 extern XrdScheduler *Sched;
140 extern XrdXrootdStats *SI;
141 }
142 
143 /******************************************************************************/
144 /* L o c a l S t a t i c s */
145 /******************************************************************************/
146 
147 namespace
148 {
149 char *digParm = 0;
150 char *FSLib[2] = {0,0};
151 std::vector<std::string> FSLPath;
152 char *gpfLib = 0;// Normally zero for default
153 char *gpfParm = 0;
154 char *SecLib;
156 int asyncFlags = 0;
157 
158 static const int asDebug = 0x01;
159 static const int asNoCache = 0x02;
160 }
161 
162 /******************************************************************************/
163 /* C o n f i g u r e */
164 /******************************************************************************/
165 
167 {
168 /*
169  Function: Establish configuration at load time.
170 
171  Input: None.
172 
173  Output: 0 upon success or !0 otherwise.
174 */
175 
177  (XrdSfsFileSystem *nativeFS,
179  const char *configFn,
180  const char *theParms);
181 
182  XrdOucEnv xrootdEnv;
183  XrdXrootdXPath *xp;
184  char *adminp, *rdf, *bP, *tmp, buff[1024];
185  int i, n;
186 
187 // Copy out the special info we want to use at top level
188 //
189  eDest.logger(pi->eDest->logger());
191  SI = new XrdXrootdStats(pi->Stats);
192  XrdXrootd::SI= SI;
193  Sched = pi->Sched; XrdXrootd::Sched = pi->Sched;
194  BPool = pi->BPool; XrdXrootd::BPool = pi->BPool;
195  hailWait = pi->hailWait;
196  readWait = pi->readWait;
197  Port = pi->Port;
198  myInst = pi->myInst;
199  Window = pi->WSize;
200  tlsPort = pi->tlsPort;
201  tlsCtx = pi->tlsCtx;
202  XrdXrootdCF = pi->totalCF;
203 
204 // Record globally accessible values
205 //
207  XrdXrootdPort = pi->Port;
208 
209 // Set the callback object static areas now!
210 //
212 
213 // Pick up exported paths from the command line
214 //
215  for (i = 1; i < pi->argc; i++) xexpdo(pi->argv[i]);
216 
217 // Pre-initialize some i/o values. Note that we now set maximum readv element
218 // transfer size to the buffer size (before it was a reasonable 256K).
219 //
220  n = (pi->theEnv ? pi->theEnv->GetInt("MaxBuffSize") : 0);
221  maxTransz = maxBuffsz = (n ? n : BPool->MaxSize());
222  maxReadv_ior = maxTransz-(int)sizeof(readahead_list);
223 
224 // Export the readv_ior_max and readv_iov_max values
225 //
226  {char buff[256];
227  snprintf(buff, sizeof(buff), "%d,%d", maxReadv_ior, XrdProto::maxRvecsz);
228  XrdOucEnv::Export("XRD_READV_LIMITS", buff);
229  }
230 
231  memset(Route, 0, sizeof(Route));
232 
233 // Now process and configuration parameters
234 //
235  rdf = (parms && *parms ? parms : pi->ConfigFN);
236  if (rdf && Config(rdf)) return 0;
238 
239 // Initialize the packet marking framework if configured. We do that here as
240 // nothing else following this code can fail but we can so be consistent.
241 //
242  bool bad = false;
244  if (PMark)
245  {if (pi->theEnv) pi->theEnv->PutPtr("XrdNetPMark*", PMark);
246  xrootdEnv.PutPtr("XrdNetPMark*", PMark);
247  }
248  else if (bad) return 0;
249 
250 // Check if we are exporting a generic object name
251 //
252  if (XPList.Opts() & XROOTDXP_NOSLASH)
253  {eDest.Say("Config exporting ", XPList.Path(n)); n += 2;}
254  else n = 0;
255 
256 // Check if we are exporting anything
257 //
258  if (!(xp = XPList.Next()) && !n)
259  {XPList.Insert("/tmp"); n = 8;
260  eDest.Say("Config warning: only '/tmp' will be exported.");
261  } else {
262  while(xp) {eDest.Say("Config exporting ", xp->Path(i));
263  n += i+2; xp = xp->Next();
264  }
265  }
266 
267 // Export the exports
268 //
269  bP = tmp = (char *)malloc(n);
270  if (XPList.Opts() & XROOTDXP_NOSLASH)
271  {strcpy(bP, XPList.Path(i)); bP += i, *bP++ = ' ';}
272  xp = XPList.Next();
273  while(xp) {strcpy(bP, xp->Path(i)); bP += i; *bP++ = ' '; xp = xp->Next();}
274  *(bP-1) = '\0';
275  XrdOucEnv::Export("XRDEXPORTS", tmp); free(tmp);
276 
277 // Initialize the security system if this is wanted
278 //
279  if (!ConfigSecurity(xrootdEnv, pi->ConfigFN)) return 0;
280 
281 // Set up the network for self-identification and display it
282 //
283  pi->NetTCP->netIF.Port(Port);
284  pi->NetTCP->netIF.Display("Config ");
285 
286 // Establish our specific environment that will be passed along
287 //
288  xrootdEnv.PutPtr("XrdInet*", (void *)(pi->NetTCP));
289  xrootdEnv.PutPtr("XrdNetIF*", (void *)(&(pi->NetTCP->netIF)));
290  xrootdEnv.PutPtr("XrdScheduler*", Sched);
291 
292 // Copy over the xrd environment which contains plugin argv's
293 //
294  if (pi->theEnv) xrootdEnv.PutPtr("xrdEnv*", pi->theEnv);
295 
296 // Initialize monitoring (it won't do anything if it wasn't enabled). This
297 // needs to be done before we load any plugins as plugins may need monitoring.
298 //
299  if (!ConfigMon(pi, xrootdEnv)) return 0;
300 
301 // Get the filesystem to be used and its features.
302 //
303  if (!ConfigFS(xrootdEnv, pi->ConfigFN)) return 0;
304  fsFeatures = osFS->Features();
306  if (pi->theEnv) pi->theEnv->PutPtr("XrdSfsFileSystem*", osFS);
307 
308 // Check if the file system includes a custom prepare handler as this will
309 // affect how we handle prepare requests.
310 //
311  if (fsFeatures & XrdSfs::hasPRP2 || xrootdEnv.Get("XRD_PrepHandler"))
312  PrepareAlt = true;
313 
314 // Check if the diglib should be loaded. We only support the builtin one. In
315 // the future we will have to change this code to be like the above.
316 //
317  if (digParm)
318  {TRACE(DEBUG, "Loading dig filesystem builtin");
319  digFS = XrdDigGetFS(osFS, eDest.logger(), pi->ConfigFN, digParm);
320  if (!digFS) eDest.Emsg("Config","Unable to load digFS; "
321  "remote debugging disabled!");
322  }
323 
324 // Check if we are going to be processing checksums locally
325 //
326  if (JobCKT) {
327  XrdOucString csList(1024);
328  XrdOucErrInfo myError("Config");
329  XrdOucTList *tP = JobCKTLST;
330  int csNum = 0;
331  do {
332  if(JobLCL) {
333  // Check natively supported checksum
334  if (osFS->chksum(XrdSfsFileSystem::csSize, tP->text, 0, myError)) {
335  eDest.Emsg("Config", tP->text, "checksum is not natively supported.");
336  return 0;
337  }
338  }
339  tP->ival[1] = myError.getErrInfo();
340  if (csNum) csList += ',';
341  csList.append(csNum);
342  csList.append(':');
343  csList.append(tP->text);
344  csNum++;
345  tP = tP->next;
346  } while (tP);
347  if (csNum) XrdOucEnv::Export("XRD_CSLIST", csList.c_str());
348  }
349 
350 // Initialiaze for AIO. If we are not in debug mode and aio is enabled then we
351 // turn off async I/O if tghe filesystem requests it or if this is a caching
352 // proxy and we were asked not to use aio in such a cacse.
353 //
354  if (!(asyncFlags & asDebug) && as_aioOK)
355  {if (fsFeatures & XrdSfs::hasNAIO) as_aioOK = false;
356  else if (asyncFlags & asNoCache && fsFeatures & XrdSfs::hasCACH)
357  as_aioOK = false;
358  if (!as_aioOK) eDest.Say("Config asynchronous I/O has been disabled!");
359  }
360 
361 // Compute the maximum stutter allowed during async I/O (one per 64k)
362 //
363  if (as_segsize > 65536) as_okstutter = as_segsize/65536;
364 
365 // Establish final sendfile processing mode. This may be turned off by the
366 // link or by the SFS plugin usually because it's a proxy.
367 //
368  const char *why = 0;
369  if (!as_nosf)
370  {if (fsFeatures & XrdSfs::hasNOSF) why = "file system plugin.";
371  else if (!XrdLink::sfOK) why = "OS kernel.";
372  if (why)
373  {as_nosf = true;
374  eDest.Say("Config sendfile has been disabled by ", why);
375  }
376  }
377 
378 // Create the file lock manager and initialize file handling
379 //
382 
383 // Schedule protocol object cleanup (also advise the transit protocol)
384 //
385  ProtStack.Set(pi->Sched, &XrdXrootdTrace, TRACE_MEM);
386  n = (pi->ConnMax/3 ? pi->ConnMax/3 : 30);
387  ProtStack.Set(n, 60*60);
388  XrdXrootdTransit::Init(pi->Sched, n, 60*60);
389 
390 // Initialize the request ID generation object
391 //
392  PrepID = new XrdOucReqID(pi->urAddr, (int)Port);
393 
394 // Initialize for prepare processing
395 //
397  sprintf(buff, "%%s://%s:%d/&L=%%d&U=%%s", pi->myName, pi->Port);
398  Notify = strdup(buff);
399 
400 // Set the redirect flag if we are a pure redirector
401 //
402  int tlsFlags = myRole & kXR_tlsAny;
404  if ((rdf = getenv("XRDREDIRECT"))
405  && (!strcmp(rdf, "R") || !strcmp(rdf, "M")))
406  {isRedir = *rdf;
408  if (!strcmp(rdf, "M")) myRole |=kXR_attrMeta;
409  }
412  myRole |= tlsFlags;
413 
414 // Turn off client redirects if we are neither a redirector nor a proxy server
415 //
416  if (CL_Redir && !isRedir && !isProxy)
417  {CL_Redir = false;
418  eDest.Say("Config warning: 'redirect client' ignored; "
419  "not a redirector nor a proxy server");
420  }
421 
422 // Check if we are redirecting anything
423 //
424  if ((xp = RPList.Next()))
425  {int k;
426  char buff[2048], puff[1024];
427  do {k = xp->Opts();
428  if (Route[k].Host[0] == Route[k].Host[1]
429  && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
430  else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
431  sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
432  eDest.Say("Config redirect static ", xp->Path(), buff);
433  xp = xp->Next();
434  } while(xp);
435  }
436 
437  if ((xp = RQList.Next()))
438  {int k;
439  const char *cgi1, *cgi2;
440  char buff[2048], puff[1024], xCgi[RD_Num] = {0};
441  if (isRedir) {cgi1 = "+"; cgi2 = getenv("XRDCMSCLUSTERID");}
442  else {cgi1 = ""; cgi2 = pi->myName;}
443  myCNlen = snprintf(buff, sizeof(buff), "%s%s", cgi1, cgi2);
444  myCName = strdup(buff);
445  do {k = xp->Opts();
446  if (Route[k].Host[0] == Route[k].Host[1]
447  && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
448  else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
449  sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
450  eDest.Say("Config redirect enoent ", xp->Path(), buff);
451  if (!xCgi[k] && cgi2)
452  {bool isdup = Route[k].Host[0] == Route[k].Host[1]
453  && Route[k].Port[0] == Route[k].Port[1];
454  for (i = 0; i < 2; i++)
455  {n = snprintf(buff,sizeof(buff), "%s?tried=%s%s",
456  Route[k].Host[i], cgi1, cgi2);
457  free(Route[k].Host[i]); Route[k].Host[i] = strdup(buff);
458  Route[k].RDSz[i] = n;
459  if (isdup) {Route[k].Host[1] = Route[k].Host[0];
460  Route[k].RDSz[1] = n; break;
461  }
462  }
463  }
464  xCgi[k] = 1;
465  xp = xp->Next();
466  } while(xp);
467  }
468 
469 // Add all jobs that we can run to the admin object
470 //
471  if (JobCKS) XrdXrootdAdmin::addJob("chksum", JobCKS);
472 
473 // Establish the path to be used for admin functions. We will loose this
474 // storage upon an error but we don't care because we'll just exit.
475 //
476  adminp = XrdOucUtils::genPath(pi->AdmPath, 0, ".xrootd");
477 
478 // Setup the admin path (used in all roles).
479 //
480  if (!(AdminSock = XrdNetSocket::Create(&eDest, adminp, "admin", pi->AdmMode))
481  || !XrdXrootdAdmin::Init(&eDest, AdminSock)) return 0;
482 
483 // Indicate whether or not we support extended attributes
484 //
485  {XrdOucEnv myEnv;
486  XrdOucErrInfo eInfo("", &myEnv);
487  char buff[128];
488  if (osFS->FAttr(0, eInfo, 0) == SFS_OK)
489  {usxMaxNsz = myEnv.GetInt("usxMaxNsz");
490  if (usxMaxNsz < 0) usxMaxNsz = 0;
491  usxMaxVsz = myEnv.GetInt("usxMaxVsz");
492  if (usxMaxVsz < 0) usxMaxVsz = 0;
493  snprintf(buff, sizeof(buff), "%d %d", usxMaxNsz, usxMaxVsz);
494  usxParms = strdup(buff);
495  } else {
496  usxMaxNsz = 0;
497  usxMaxVsz = 0;
498  usxParms = strdup("0 0");
499  }
500  }
501 
502 // Finally, check if we really need to be in bypass mode if it is set
503 //
504  if (OD_Bypass)
505  {const char *penv = getenv("XRDXROOTD_PROXY");
506  if (!penv || *penv != '=')
507  {OD_Bypass = false;
508  eDest.Say("Config warning: 'fsoverload bypass' ignored; "
509  "not a forwarding proxy.");
510  }
511  }
512 
513 // Add any additional features
514 //
519  myRole |= kXR_anongpf;
520 
521 // Finally note whether or not we have TLS enabled
522 //
523  if (tlsCtx) myRole |= kXR_haveTLS;
524 
525 // Return success
526 //
527  free(adminp);
528  return 1;
529 }
530 
531 /******************************************************************************/
532 /* C o n f i g */
533 /******************************************************************************/
534 
535 #define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
536 #define TS_Zeq(x,m) (!strcmp(x,var)) GoNo = m(&eDest, Config)
537 
538 int XrdXrootdProtocol::Config(const char *ConfigFN)
539 {
540  XrdOucEnv myEnv;
541  XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
542  char *var;
543  int cfgFD, GoNo, NoGo = 0, ismine;
544 
545  // Open and attach the config file
546  //
547  if ((cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
548  return eDest.Emsg("Config", errno, "open config file", ConfigFN);
549  Config.Attach(cfgFD);
550 
551  // Indicate what we are about to do in the capture stream
552  //
553  static const char *cvec[] = { "*** xroot protocol config:", 0 };
554  Config.Capture(cvec);
555 
556  // Process items
557  //
558  while((var = Config.GetMyFirstWord()))
559  { if ((ismine = !strncmp("xrootd.", var, 7)) && var[7]) var += 7;
560  else if ((ismine = !strcmp("all.export", var))) var += 4;
561  else if ((ismine = !strcmp("all.seclib", var))) var += 4;
562 
563  if (ismine)
564  { if TS_Xeq("async", xasync);
565  else if TS_Xeq("bindif", xbif);
566  else if TS_Xeq("chksum", xcksum);
567  else if TS_Xeq("diglib", xdig);
568  else if TS_Xeq("export", xexp);
569  else if TS_Xeq("fslib", xfsl);
570  else if TS_Xeq("fsoverload", xfso);
571  else if TS_Xeq("gpflib", xgpf);
572  else if TS_Xeq("log", xlog);
573  else if TS_Xeq("mongstream", xmongs);
574  else if TS_Xeq("monitor", xmon);
575  else if TS_Zeq("pmark", XrdNetPMarkCfg::Parse);
576  else if TS_Xeq("prep", xprep);
577  else if TS_Xeq("redirect", xred);
578  else if TS_Xeq("seclib", xsecl);
579  else if TS_Xeq("tls", xtls);
580  else if TS_Xeq("tlsreuse", xtlsr);
581  else if TS_Xeq("trace", xtrace);
582  else if TS_Xeq("limit", xlimit);
583  else {if (!strcmp(var, "pidpath"))
584  {eDest.Say("Config warning: 'xrootd.pidpath' no longer "
585  "supported; use 'all.pidpath'.");
586  } else {
587  eDest.Say("Config warning: ignoring unknown "
588  "directive '", var, "'.");
589  }
590  Config.Echo(false);
591  continue;
592  }
593  if (GoNo) {Config.Echo(); NoGo = 1;}
594  }
595  }
596 
597 // We now have to generate the correct TLS context if one was specified. Our
598 // context must be of the non-verified kind as we don't accept certs.
599 //
600  if (!NoGo && tlsCtx)
601  {tlsCtx = tlsCtx->Clone(false,true);
602  if (!tlsCtx)
603  {eDest.Say("Config failure: unable to setup TLS for protocol!");
604  NoGo = 1;
605  } else {
606  static const char *sessID = "xroots";
607  tlsCtx->SessionCache(tlsCache, sessID, 6);
608  }
609  }
610 
611 // Add our config to our environment and return
612 //
613  return NoGo;
614 }
615 
616 /******************************************************************************/
617 /* P r i v a t e F u n c t i o n s */
618 /******************************************************************************/
619 /******************************************************************************/
620 /* C h e c k T L S */
621 /******************************************************************************/
622 
623 int XrdXrootdProtocol::CheckTLS(const char *tlsProt)
624 {
625 
626 // If login specified, turn off session as it doesn't make sense together.
627 //
631 
632 // Turn off TPC TLS requirement if login or session is required to have TLS
633 // However, that flag must remain to be set in the protocol response.
634 //
637 
638 // If some authnetication protocols need TLS then we must requie that login
639 // uses TLS. For incapable clients, we leave this alone as we will skip
640 // TLS authnetication based protocols should the login phase not have TLS.
641 //
642  if (tlsProt && !(tlsCap & Req_TLSLogin))
643  {eDest.Say("Config Authentication protocol(s)", tlsProt,
644  " require TLS; login now requires TLS.");
645  myRole |= kXR_tlsLogin;
646  tlsCap |= Req_TLSLogin;
647  }
648 
649 // If there are any TLS requirements then TLS must have been configured.
650 //
651  if (myRole & kXR_tlsAny && !tlsCtx)
652  {eDest.Say("Config failure: unable to honor TLS requirement; "
653  "TLS not configured!");
654  return 0;
655  }
656 
657 // All done
658 //
659  return 1;
660 }
661 
662 /******************************************************************************/
663 /* C o n f i g F S */
664 /******************************************************************************/
665 
666 bool XrdXrootdProtocol::ConfigFS(XrdOucEnv &xEnv, const char *cfn)
667 {
668  const char *fsLoc;
669  int n;
670 
671 // Get the filesystem to be used
672 //
673  if (FSLib[0])
674  {TRACE(DEBUG, "Loading base filesystem library " <<FSLib[0]);
675  osFS = XrdXrootdloadFileSystem(&eDest, 0, FSLib[0], cfn, &xEnv);
676  fsLoc = FSLib[0];
677  } else {
678  osFS = XrdSfsGetDefaultFileSystem(0, eDest.logger(), cfn, &xEnv);
679  fsLoc = "default";
680  }
681 
682 // Make sure we have loaded something
683 //
684  if (!osFS)
685  {eDest.Emsg("Config", "Unable to load base file system using", fsLoc);
686  return false;
687  }
688  if (FSLib[0]) osFS->EnvInfo(&xEnv);
689 
690 // If there is an old style wrapper, load it now.
691 //
692  if (FSLib[1] && !ConfigFS(FSLib[1], xEnv, cfn)) return false;
693 
694 // Run through any other pushdowns
695 //
696  if ((n = FSLPath.size()))
697  for (int i = 0; i < n; i++)
698  {if (!ConfigFS(FSLPath[i].c_str(), xEnv, cfn)) return false;}
699 
700 // Inform the statistics object which filesystem to use
701 //
702  SI->setFS(osFS);
703 
704 // All done here
705 //
706  return true;
707 }
708 
709 /******************************************************************************/
710 
711 bool XrdXrootdProtocol::ConfigFS(const char *path, XrdOucEnv &xEnv,
712  const char *cfn)
713 {
714 
715 // Try to load this wrapper library
716 //
717  TRACE(DEBUG, "Loading wrapper filesystem library " <<path);
718  osFS = XrdXrootdloadFileSystem(&eDest, osFS, path, cfn, &xEnv);
719  if (!osFS)
720  {eDest.Emsg("Config", "Unable to load file system wrapper from", path);
721  return false;
722  }
723  osFS->EnvInfo(&xEnv);
724  return true;
725 }
726 
727 /******************************************************************************/
728 /* C o n f i g S e c u r i t y */
729 /******************************************************************************/
730 
731 int XrdXrootdProtocol::ConfigSecurity(XrdOucEnv &xEnv, const char *cfn)
732 {
733  XrdSecGetProt_t secGetProt = 0;
734  char idBuff[256];
735  int n;
736 
737 // Obtain our uid and username
738 //
739  myUID = geteuid();
740  if ((n = XrdOucUtils::UidName(myUID, idBuff, sizeof(idBuff))))
741  {myUName = strdup(idBuff);
742  myUNLen = n;
743  }
744 
745 // Obtain our gid and groupname
746 //
747  myGID = getegid();
748  if ((n = XrdOucUtils::GidName(myGID, idBuff, sizeof(idBuff))))
749  {myGName = strdup(idBuff);
750  myGNLen = n;
751  }
752 
753 // TLS support is independent of security per se. Record context, if any.
754 //
755  if (tlsCtx) xEnv.PutPtr("XrdTLSContext*", (void *)tlsCtx);
756 
757 // Check if we need to load anything
758 //
759  if (!SecLib)
760  {eDest.Say("Config warning: 'xrootd.seclib' not specified;"
761  " strong authentication disabled!");
762  xEnv.PutPtr("XrdSecGetProtocol*", (void *)0);
763  xEnv.PutPtr("XrdSecProtector*" , (void *)0);
764  return 1;
765  }
766 
767 // Blad some debugging info
768 //
769  TRACE(DEBUG, "Loading security library " <<SecLib);
770 
771 // Load the security server
772 //
773  if (!(CIA = XrdSecLoadSecService(&eDest, cfn,
774  (strcmp(SecLib,"default") ? SecLib : 0),
775  &secGetProt, &DHS)))
776  {eDest.Emsg("Config", "Unable to load security system.");
777  return 0;
778  }
779 
780 // Set environmental pointers
781 //
782  xEnv.PutPtr("XrdSecGetProtocol*", (void *)secGetProt);
783  xEnv.PutPtr("XrdSecProtector*" , (void *)DHS);
784 
785 // If any protocol needs TLS then all logins must use TLS, ufortunately.
786 //
787  const char *tlsProt = CIA->protTLS();
788  if (tlsProt) return CheckTLS(tlsProt);
789  return 1;
790 }
791 
792 /******************************************************************************/
793 /* x a s y n c */
794 /******************************************************************************/
795 
796 /* Function: xasync
797 
798  Purpose: To parse directive: async [limit <aiopl>] [maxsegs <msegs>]
799  [maxtot <mtot>] [segsize <segsize>]
800  [minsize <iosz>] [maxstalls <cnt>]
801  [timeout <tos>]
802  [Debug] [force] [syncw] [off]
803  [nocache] [nosf]
804 
805  <aiopl> maximum number of async req per link. Default 8.
806  <msegs> maximum number of async ops per request. Default 8.
807  <mtot> maximum number of async ops per server. Default is 4096.
808  of maximum connection times aiopl divided by two.
809  <segsz> The aio segment size. This is the maximum size that data
810  will be read or written. The defaults to 64K but is
811  adjusted for each request to minimize latency.
812  <iosz> the minimum number of bytes that must be read or written
813  to allow async processing to occur (default is maxbsz/2
814  typically 1M).
815  <tos> second timeout for async I/O.
816  <cnt> Maximum number of client stalls before synchronous i/o is
817  used. Async mode is tried after <cnt> requests.
818  Debug Turns on async I/O for everything. This an internal
819  undocumented option used for testing purposes.
820  force Uses async i/o for all requests, even when not explicitly
821  requested (this is compatible with synchronous clients).
822  syncw Use synchronous i/o for write requests.
823  off Disables async i/o
824  nocache Disables async I/O is this is a caching proxy.
825  nosf Disables use of sendfile to send data to the client.
826 
827  Output: 0 upon success or 1 upon failure.
828 */
829 
830 int XrdXrootdProtocol::xasync(XrdOucStream &Config)
831 {
832  char *val;
833  int i, ppp;
834  int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
835  int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
836  int V_minsf=-1, V_debug=-1, V_noca=-1, V_tmo=-1;
837  long long llp;
838  struct asyncopts {const char *opname; int minv; int *oploc;
839  const char *opmsg;} asopts[] =
840  {
841  {"Debug", -1, &V_debug, ""},
842  {"force", -1, &V_force, ""},
843  {"off", -1, &V_off, ""},
844  {"nocache", -1, &V_noca, ""},
845  {"nosf", -1, &V_nosf, ""},
846  {"syncw", -1, &V_syncw, ""},
847  {"limit", 0, &V_limit, "async limit"},
848  {"segsize", 4096, &V_segsz, "async segsize"},
849  {"timeout", 0, &V_tmo, "async timeout"},
850  {"maxsegs", 0, &V_msegs, "async maxsegs"},
851  {"maxstalls", 0, &V_mstall,"async maxstalls"},
852  {"maxtot", 0, &V_mtot, "async maxtot"},
853  {"minsfsz", 1, &V_minsf, "async minsfsz"},
854  {"minsize", 4096, &V_minsz, "async minsize"}};
855  int numopts = sizeof(asopts)/sizeof(struct asyncopts);
856 
857  if (!(val = Config.GetWord()))
858  {eDest.Emsg("Config", "async option not specified"); return 1;}
859 
860  while (val)
861  {for (i = 0; i < numopts; i++)
862  if (!strcmp(val, asopts[i].opname))
863  {if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
864  {eDest.Emsg("Config","async",(char *)asopts[i].opname,
865  "value not specified");
866  return 1;
867  }
868  if (asopts[i].minv > 0)
869  if (XrdOuca2x::a2sz(eDest,asopts[i].opmsg, val, &llp,
870  (long long)asopts[i].minv)) return 1;
871  else *asopts[i].oploc = (int)llp;
872  else if (asopts[i].minv == 0)
873  if (XrdOuca2x::a2i(eDest,asopts[i].opmsg,val,&ppp,1))
874  return 1;
875  else *asopts[i].oploc = ppp;
876  else *asopts[i].oploc = 1;
877  break;
878  }
879  if (i >= numopts)
880  eDest.Emsg("Config", "Warning, invalid async option", val);
881  val = Config.GetWord();
882  }
883 
884 // Make sure max values are consistent
885 //
886  if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
887  {eDest.Emsg("Config", "async limit may not be greater than maxtot");
888  return 1;
889  }
890 
891 // Calculate the actual segment size
892 //
893  if (V_segsz > 0)
894  {i = BPool->Recalc(V_segsz);
895  if (!i) {eDest.Emsg("Config", "async segsize is too large"); return 1;}
896  if (i != V_segsz)
897  {char buff[64];
898  sprintf(buff, "%d readjusted to %d", V_segsz, i);
899  eDest.Emsg("Config", "async segsize", buff);
900  V_segsz = i;
901  }
902  }
903 
904 // Calculate actual timeout
905 //
906  if (V_tmo >= 0)
907  {i = V_tmo;
908  if (V_tmo < 1) i = 1;
909  else if (V_tmo > 360) i = 360;
910  if (i != V_tmo)
911  {char buff[64];
912  sprintf(buff, "%d readjusted to %d", V_tmo, i);
913  eDest.Emsg("Config", "async timeout", buff);
914  V_tmo = i;
915  }
916  }
917 
918 // Establish async options
919 //
920  if (V_limit > 0) as_maxperlnk = V_limit;
921  if (V_msegs > 0) as_maxperreq = V_msegs;
922  if (V_mtot > 0) as_maxpersrv = V_mtot;
923  if (V_minsz > 0) as_miniosz = V_minsz;
924  if (V_segsz > 0){as_segsize = V_segsz; as_seghalf = V_segsz/2;}
925  if (V_tmo >= 0) as_timeout = V_tmo;
926  if (V_mstall> 0) as_maxstalls = V_mstall;
927  if (V_debug > 0) asyncFlags |= asDebug;
928  if (V_force > 0) as_force = true;
929  if (V_off > 0) as_aioOK = false;
930  if (V_syncw > 0) as_syncw = true;
931  if (V_noca > 0) asyncFlags |= asNoCache;
932  if (V_nosf > 0) as_nosf = true;
933  if (V_minsf > 0) as_minsfsz = V_minsf;
934 
935  return 0;
936 }
937 
938 /******************************************************************************/
939 /* x b i f */
940 /******************************************************************************/
941 
942 /* Function: xbif
943 
944  Purpose: To parse the directive: bindif <trg>
945 
946  <trg>: <host>:<port>[%<prvhost>:<port>]] [<trg>]
947 */
948 
949 namespace XrdXrootd
950 {
951 char *bifResp[2] = {0,0};
952 int bifRLen[2] = {0,0};
953 }
954 
955 int XrdXrootdProtocol::xbif(XrdOucStream &Config)
956 {
957  static const int brSize = sizeof(XrdProto::bifReqs);
958  using XrdXrootd::bifResp;
959  using XrdXrootd::bifRLen;
960 
961  XrdOucString bSpec[2];
962  char *bHost[2], *val, buff[512];
963  int bPort[2], thePort;
964 
965 // Cleanup any previous bif specification
966 //
967  if (bifResp[1])
968  {if (bifResp[1] != bifResp[0]) free(bifResp[1]);
969  bifResp[1] = 0; bifRLen[1] = 0;
970  }
971  if (bifResp[0])
972  {free(bifResp[0]);
973  bifResp[0] = 0; bifRLen[0] = 0;
974  }
975 
976 // Process all of the options
977 //
978  while((val = Config.GetWord()) && *val)
979  {if (!xred_php(val, bHost, bPort, "bindif", true)) return 1;
980  for (int i = 0; i < 2 && bHost[i] != 0; i++)
981  {thePort = (bPort[i] ? bPort[i] : XrdXrootdPort);
982  snprintf(buff, sizeof(buff), "%s%s:%d",
983  (bSpec[i].length() ? "," : ""), bHost[i], thePort);
984  bSpec[i] += buff;
985  }
986  }
987 
988 // Generate the "b" record for each type of interface
989 //
990  for (int i = 0; i < 2 && bSpec[i].length(); i++)
991  {int n = brSize + bSpec[i].length() + 1;
992  n = (n + 7) & ~7;
993  XrdProto::bifReqs *bifRec = (XrdProto::bifReqs *)malloc(n);
994  memset(bifRec, 0, n);
995  bifRec->theTag = 'B';
996  bifRec->bifILen = htons(static_cast<kXR_unt16>(n-brSize));
997  strcpy(((char *)bifRec)+brSize, bSpec[i].c_str());
998  bifResp[i] = (char *)bifRec;
999  bifRLen[i] = n;
1000  }
1001 
1002 // Now complete the definition
1003 //
1004  if (bifResp[0] && bifResp[1] == 0)
1005  {bifResp[1] = bifResp[0];
1006  bifRLen[1] = bifRLen[0];
1007  }
1008 
1009 // All done
1010 //
1011  return 0;
1012 }
1013 
1014 /******************************************************************************/
1015 /* x c k s u m */
1016 /******************************************************************************/
1017 
1018 /* Function: xcksum
1019 
1020  Purpose: To parse the directive: chksum [chkcgi] [max <n>] <type> [<path>]
1021 
1022  max maximum number of simultaneous jobs
1023  chkcgi Always check for checksum type in cgo info.
1024  <type> algorithm of checksum (e.g., md5). If more than one
1025  checksum is supported then they should be listed with
1026  each separated by a space.
1027  <path> the path of the program performing the checksum
1028  If no path is given, the checksum is local.
1029 
1030  Output: 0 upon success or !0 upon failure.
1031 */
1032 
1033 int XrdXrootdProtocol::xcksum(XrdOucStream &Config)
1034 {
1035  static XrdOucProg *theProg = 0;
1036  int (*Proc)(XrdOucStream *, char **, int) = 0;
1037  XrdOucTList *tP, *algFirst = 0, *algLast = 0;
1038  char *palg, prog[2048];
1039  int jmax = 4, anum[2] = {0,0};
1040 
1041 // Get the algorithm name and the program implementing it
1042 //
1043  JobCKCGI = 0;
1044  while ((palg = Config.GetWord()) && *palg != '/')
1045  {if (!strcmp(palg,"chkcgi")) {JobCKCGI = 1; continue;}
1046  if (strcmp(palg, "max"))
1047  {XrdOucUtils::toLower(palg);
1048  XrdOucTList *xalg = new XrdOucTList(palg, anum); anum[0]++;
1049  if (algLast) algLast->next = xalg;
1050  else algFirst = xalg;
1051  algLast = xalg;
1052  continue;
1053  }
1054  if (!(palg = Config.GetWord()))
1055  {eDest.Emsg("Config", "chksum max not specified"); return 1;}
1056  if (XrdOuca2x::a2i(eDest, "chksum max", palg, &jmax, 0)) return 1;
1057  }
1058 
1059 // Verify we have an algoritm
1060 //
1061  if (!algFirst)
1062  {eDest.Emsg("Config", "chksum algorithm not specified"); return 1;}
1063  if (JobCKT) free(JobCKT);
1064  JobCKT = strdup(algFirst->text);
1065 
1066 // Handle alternate checksums
1067 //
1068  while((tP = JobCKTLST)) {JobCKTLST = tP->next; delete tP;}
1069  JobCKTLST = algFirst;
1070  if (algFirst->next) JobCKCGI = 2;
1071 
1072 // Handle program if we have one
1073 //
1074  if (palg)
1075  {int n = strlen(palg);
1076  if (n+2 >= (int)sizeof(prog))
1077  {eDest.Emsg("Config", "cksum program too long"); return 1;}
1078  strcpy(prog, palg); palg = prog+n; *palg++ = ' '; n = sizeof(prog)-n-1;
1079  if (!Config.GetRest(palg, n))
1080  {eDest.Emsg("Config", "cksum parameters too long"); return 1;}
1081  } else *prog = 0;
1082 
1083 // Check if we have a program. If not, then this will be a local checksum and
1084 // the algorithm will be verified after we load the filesystem.
1085 //
1086  if (*prog) JobLCL = 0;
1087  else { JobLCL = 1; Proc = &CheckSum; strcpy(prog, "chksum");}
1088 
1089 // Set up the program and job
1090 //
1091  if (!theProg) theProg = new XrdOucProg(0);
1092  if (theProg->Setup(prog, &eDest, Proc)) return 1;
1093  if (JobCKS) delete JobCKS;
1094  if (jmax) JobCKS = new XrdXrootdJob(Sched, theProg, "chksum", jmax);
1095  else JobCKS = 0;
1096  return 0;
1097 }
1098 
1099 /******************************************************************************/
1100 /* x d i g */
1101 /******************************************************************************/
1102 
1103 /* Function: xdig
1104 
1105  Purpose: To parse the directive: diglib * <parms>
1106 
1107  * use builtin digfs library (only one supported now).
1108  parms parameters for digfs.
1109 
1110  Output: 0 upon success or !0 upon failure.
1111 */
1112 
1113 int XrdXrootdProtocol::xdig(XrdOucStream &Config)
1114 {
1115  char parms[4096], *val;
1116 
1117 // Get the path
1118 //
1119  if (!(val = Config.GetWord()))
1120  {eDest.Emsg("Config", "diglib not specified"); return 1;}
1121 
1122 // Make sure it refers to an internal one
1123 //
1124  if (strcmp(val, "*"))
1125  {eDest.Emsg("Config", "builtin diglib not specified"); return 1;}
1126 
1127 // Grab the parameters
1128 //
1129  if (!Config.GetRest(parms, sizeof(parms)))
1130  {eDest.Emsg("Config", "diglib parameters too long"); return 1;}
1131  if (digParm) free(digParm);
1132  digParm = strdup(parms);
1133 
1134 // All done
1135 //
1136  return 0;
1137 }
1138 
1139 /******************************************************************************/
1140 /* x e x p */
1141 /******************************************************************************/
1142 
1143 /* Function: xexp
1144 
1145  Purpose: To parse the directive: export <path> [lock|nolock] [mwfiles]
1146 
1147  <path> the path to be exported.
1148 
1149  Output: 0 upon success or !0 upon failure.
1150 */
1151 
1152 int XrdXrootdProtocol::xexp(XrdOucStream &Config)
1153 {
1154  char *val, pbuff[1024];
1155  int popt = 0;
1156 
1157 // Get the path
1158 //
1159  val = Config.GetWord();
1160  if (!val || !val[0])
1161  {eDest.Emsg("Config", "export path not specified"); return 1;}
1162  strlcpy(pbuff, val, sizeof(pbuff));
1163 
1164 // Get export lock option
1165 //
1166  while((val = Config.GetWord()))
1167  { if (!strcmp( "nolock", val)) popt |= XROOTDXP_NOLK;
1168  else if (!strcmp( "lock", val)) popt &= ~XROOTDXP_NOLK;
1169  else if (!strcmp("mwfiles", val)) popt |= XROOTDXP_NOMWCHK;
1170  else {Config.RetToken(); break;}
1171  }
1172 
1173 // Add path to configuration
1174 //
1175  return xexpdo(pbuff, popt);
1176 }
1177 
1178 /******************************************************************************/
1179 
1180 int XrdXrootdProtocol::xexpdo(char *path, int popt)
1181 {
1182  char *opaque;
1183  int xopt;
1184 
1185 // Check if we are exporting a generic name
1186 //
1187  if (*path == '*')
1188  {popt |= XROOTDXP_NOSLASH | XROOTDXP_NOCGI;
1189  if (*(path+1))
1190  {if (*(path+1) == '?') popt &= ~XROOTDXP_NOCGI;
1191  else {eDest.Emsg("Config","invalid export path -",path);return 1;}
1192  }
1193  XPList.Set(popt, path);
1194  return 0;
1195  }
1196 
1197 // Make sure path start with a slash
1198 //
1199  if (rpCheck(path, &opaque))
1200  {eDest.Emsg("Config", "non-absolute export path -", path); return 1;}
1201 
1202 // Record the path
1203 //
1204  if (!(xopt = Squash(path)) || xopt != (popt|XROOTDXP_OK))
1205  XPList.Insert(path, popt);
1206  return 0;
1207 }
1208 
1209 /******************************************************************************/
1210 /* x f s l */
1211 /******************************************************************************/
1212 
1213 /* Function: xfsl
1214 
1215  Purpose: To parse the directive: fslib [throttle | [-2] <fspath2>]
1216  {default | [-2] <fspath1>}
1217  | ++ <fspath2>
1218 
1219  -2 Uses version2 of the plugin initializer.
1220  This is ignored now because it's always done.
1221  ++ Pushes a wrapper onto the library stack.
1222  throttle load libXrdThrottle.so as the head interface.
1223  <fspath2> load the named library as the head interface.
1224  default load libXrdOfs.so ro libXrdPss.so as the tail
1225  interface. This is the default.
1226  <fspath1> load the named library as the tail interface.
1227 
1228  Output: 0 upon success or !0 upon failure.
1229 */
1230 
1231 int XrdXrootdProtocol::xfsl(XrdOucStream &Config)
1232 {
1233  char *val;
1234 
1235 // Get the path
1236 //
1237  if (!(val = Config.GetWord()))
1238  {eDest.Emsg("Config", "fslib not specified"); return 1;}
1239 
1240 // First check for a psuhdown
1241 //
1242  if (!strcmp("++", val))
1243  {if (!(val = Config.GetWord()))
1244  {eDest.Emsg("Config", "fslib wrapper not specified"); return 1;}
1245  if (strcmp("throttle", val)) FSLPath.push_back((std::string)val);
1246  else FSLPath.push_back("libXrdThrottle.so");
1247  return 0;
1248  }
1249 
1250 // Clear storage pointers
1251 //
1252  if (FSLib[0]) {free(FSLib[0]); FSLib[0] = 0;}
1253  if (FSLib[1]) {free(FSLib[1]); FSLib[1] = 0;}
1254 
1255 // Check if this is "thottle"
1256 //
1257  if (!strcmp("throttle", val))
1258  {FSLib[1] = strdup("libXrdThrottle.so");
1259  if (!(val = Config.GetWord()))
1260  {eDest.Emsg("Config","fslib throttle target library not specified");
1261  return 1;
1262  }
1263  return xfsL(Config, val, 0);
1264  }
1265 
1266 // Check for default or default library, the common case
1267 //
1268  if (xfsL(Config, val, 1)) return 1;
1269  if (!FSLib[1]) return 0;
1270 
1271 // If we dont have another token, then demote the previous library
1272 //
1273  if (!(val = Config.GetWord()))
1274  {FSLib[0] = FSLib[1]; FSLib[1] = 0;
1275  return 0;
1276  }
1277 
1278 // Check for default or default library, the common case
1279 //
1280  return xfsL(Config, val, 0);
1281 }
1282 
1283 /******************************************************************************/
1284 
1285 int XrdXrootdProtocol::xfsL(XrdOucStream &Config, char *val, int lix)
1286 {
1287  char *Slash;
1288 
1289 // Check if this is a version token
1290 //
1291  if (!strcmp(val, "-2"))
1292  {if (!(val = Config.GetWord()))
1293  {eDest.Emsg("Config", "fslib not specified"); return 1;}
1294  }
1295 
1296 // We will play fast and furious with the syntax as "default" should not be
1297 // prefixed with a version number but will let that pass.
1298 //
1299  if (!strcmp("default", val)) return 0;
1300 
1301 // If this is the "standard" name tell the user that we are ignoring this lib.
1302 // Otherwise, record the path and return.
1303 //
1304  if (!(Slash = rindex(val, '/'))) Slash = val;
1305  else Slash++;
1306  if (!strcmp(Slash, "libXrdOfs.so"))
1307  eDest.Say("Config warning: 'fslib libXrdOfs.so' is actually built-in.");
1308  else FSLib[lix] = strdup(val);
1309  return 0;
1310 }
1311 
1312 /******************************************************************************/
1313 /* x f s o */
1314 /******************************************************************************/
1315 
1316 /* Function: xfso
1317 
1318  Purpose: To parse the directive: fsoverload [options]
1319 
1320  options: [[no]bypass] [redirect <host>:<port>[%<prvhost>:<port>]]
1321  [stall <sec>]
1322 
1323  bypass If path is a forwarding path, redirect client to the
1324  location specified in the path to bypass this server.
1325  The default is nobypass.
1326  redirect Redirect the request to the specified destination.
1327  stall Stall the client <sec> seconds. The default is 33.
1328 */
1329 
1330 int XrdXrootdProtocol::xfso(XrdOucStream &Config)
1331 {
1332  static const int rHLen = 264;
1333  char rHost[2][rHLen], *hP[2] = {0,0}, *val;
1334  int rPort[2], bypass = -1, stall = -1;
1335 
1336 // Process all of the options
1337 //
1338  while((val = Config.GetWord()) && *val)
1339  { if (!strcmp(val, "bypass")) bypass = 1;
1340  else if (!strcmp(val, "nobypass")) bypass = 0;
1341  else if (!strcmp(val, "redirect"))
1342  {val = Config.GetWord();
1343  if (!xred_php(val, hP, rPort, "redirect")) return 1;
1344  for (int i = 0; i < 2; i++)
1345  {if (!hP[i]) rHost[i][0] = 0;
1346  else {strlcpy(rHost[i], hP[i], rHLen);
1347  hP[i] = rHost[i];
1348  }
1349  }
1350  }
1351  else if (!strcmp(val, "stall"))
1352  {if (!(val = Config.GetWord()) || !(*val))
1353  {eDest.Emsg("Config", "stall value not specified");
1354  return 1;
1355  }
1356  if (XrdOuca2x::a2tm(eDest,"stall",val,&stall,0,32767))
1357  return 1;
1358  }
1359  else {eDest.Emsg("config","invalid fsoverload option",val); return 1;}
1360  }
1361 
1362 // Set all specified values
1363 //
1364  if (bypass >= 0) OD_Bypass = (bypass ? true : false);
1365  if (stall >= 0) OD_Stall = stall;
1366  if (hP[0])
1367  {if (Route[RD_ovld].Host[0]) free(Route[RD_ovld].Host[0]);
1368  if (Route[RD_ovld].Host[1]) free(Route[RD_ovld].Host[1]);
1369  Route[RD_ovld].Host[0] = strdup(hP[0]);
1370  Route[RD_ovld].Port[0] = rPort[0];
1371  Route[RD_ovld].RDSz[0] = strlen(hP[0]);
1372  if (hP[1])
1373  {Route[RD_ovld].Host[1] = strdup(hP[1]);
1374  Route[RD_ovld].Port[1] = rPort[1];
1375  Route[RD_ovld].RDSz[1] = strlen(hP[1]);
1376  } else {
1377  Route[RD_ovld].Host[1] = Route[RD_ovld].Host[0];
1378  Route[RD_ovld].Port[1] = Route[RD_ovld].Port[0];
1379  Route[RD_ovld].RDSz[1] = Route[RD_ovld].RDSz[0];
1380  }
1381  OD_Redir = true;
1382  } else OD_Redir = false;
1383 
1384  return 0;
1385 }
1386 
1387 /******************************************************************************/
1388 /* x g p f */
1389 /******************************************************************************/
1390 
1391 /* Function: xgpf
1392 
1393  Purpose: To parse the directive: gpflib <path> <parms>
1394 
1395  <path> library path to use or default to use the builtin one.
1396  parms optional parameters.
1397 
1398  Output: 0 upon success or !0 upon failure.
1399 */
1400 
1401 int XrdXrootdProtocol::xgpf(XrdOucStream &Config)
1402 {
1403  char parms[4096], *val;
1404 
1405 // Remove any previous parameters
1406 //
1407  if (gpfLib) {free(gpfLib); gpfLib = 0;}
1408  if (gpfParm) {free(gpfParm); gpfParm = 0;}
1409 
1410 // Get the path
1411 //
1412  if (!(val = Config.GetWord()))
1413  {eDest.Emsg("Config", "gpflib not specified"); return 1;}
1414 
1415 // If this refers to out default, then keep the library pointer nil
1416 //
1417  if (strcmp(val, "default")) gpfLib = strdup(val);
1418 
1419 // Grab the parameters
1420 //
1421  if (!Config.GetRest(parms, sizeof(parms)))
1422  {eDest.Emsg("Config", "gpflib parameters too long"); return 1;}
1423  gpfParm = strdup(parms);
1424 
1425 // All done
1426 //
1427  return 0;
1428 }
1429 
1430 /******************************************************************************/
1431 /* x l o g */
1432 /******************************************************************************/
1433 
1434 /* Function: xlog
1435 
1436  Purpose: To parse the directive: log <events>
1437 
1438  <events> the blank separated list of events to log.
1439 
1440  Output: 0 upon success or 1 upon failure.
1441 */
1442 
1443 int XrdXrootdProtocol::xlog(XrdOucStream &Config)
1444 {
1445  char *val;
1446  static struct logopts {const char *opname; int opval;} lgopts[] =
1447  {
1448  {"all", -1},
1449  {"disc", SYS_LOG_02},
1450  {"login", SYS_LOG_01}
1451  };
1452  int i, neg, lgval = -1, numopts = sizeof(lgopts)/sizeof(struct logopts);
1453 
1454  if (!(val = Config.GetWord()))
1455  {eDest.Emsg("config", "log option not specified"); return 1;}
1456  while (val)
1457  {if ((neg = (val[0] == '-' && val[1]))) val++;
1458  for (i = 0; i < numopts; i++)
1459  {if (!strcmp(val, lgopts[i].opname))
1460  {if (neg) lgval &= ~lgopts[i].opval;
1461  else lgval |= lgopts[i].opval;
1462  break;
1463  }
1464  }
1465  if (i >= numopts) eDest.Emsg("config","invalid log option",val);
1466  val = Config.GetWord();
1467  }
1468  eDest.setMsgMask(lgval);
1469  return 0;
1470 }
1471 
1472 /******************************************************************************/
1473 /* x p r e p */
1474 /******************************************************************************/
1475 
1476 /* Function: xprep
1477 
1478  Purpose: To parse the directive: prep [keep <sec>] [scrub <sec>]
1479  [logdir <path>]
1480  keep <sec> time (seconds, M, H) to keep logdir entries.
1481  scrub <sec> time (seconds, M, H) between logdir scrubs.
1482  logdir <path> the absolute path to the prepare log directory.
1483 
1484  Output: 0 upon success or !0 upon failure. Ignored by master.
1485 */
1486 int XrdXrootdProtocol::xprep(XrdOucStream &Config)
1487 { int rc, keep = 0, scrub=0;
1488  char *ldir=0,*val,buff[1024];
1489 
1490  if (!(val = Config.GetWord()))
1491  {eDest.Emsg("Config", "prep options not specified"); return 1;}
1492 
1493  do { if (!strcmp("keep", val))
1494  {if (!(val = Config.GetWord()))
1495  {eDest.Emsg("Config", "prep keep value not specified");
1496  return 1;
1497  }
1498  if (XrdOuca2x::a2tm(eDest,"prep keep int",val,&keep,1)) return 1;
1499  }
1500  else if (!strcmp("scrub", val))
1501  {if (!(val = Config.GetWord()))
1502  {eDest.Emsg("Config", "prep scrub value not specified");
1503  return 1;
1504  }
1505  if (XrdOuca2x::a2tm(eDest,"prep scrub",val,&scrub,0)) return 1;
1506  }
1507  else if (!strcmp("logdir", val))
1508  {if (!(ldir = Config.GetWord()))
1509  {eDest.Emsg("Config", "prep logdir value not specified");
1510  return 1;
1511  }
1512  }
1513  else eDest.Emsg("Config", "Warning, invalid prep option", val);
1514  } while((val = Config.GetWord()));
1515 
1516 // Set the values
1517 //
1518  if (scrub || keep) XrdXrootdPrepare::setParms(scrub, keep);
1519  if (ldir)
1520  if ((rc = XrdOucUtils::genPath(buff, sizeof(buff), ldir, myInst)) < 0
1521  || (rc = XrdOucUtils::makePath(buff, XrdOucUtils::pathMode)) < 0
1522  || (rc = XrdXrootdPrepare::setParms(buff)) < 0)
1523  {eDest.Emsg("Config", rc, "process logdir", ldir);
1524  return 1;
1525  }
1526  return 0;
1527 }
1528 
1529 /******************************************************************************/
1530 /* x r e d */
1531 /******************************************************************************/
1532 
1533 /* Function: xred
1534 
1535  Purpose: To parse the directive: redirect <host>:<port>[%<prvhost>:<port>]
1536  {<funcs>|[?]<path>} |
1537  client <domlist>
1538 
1539  <funcs> are one or more of the following functions that will
1540  be immediately redirected to <host>:<port>. Each function
1541  may be prefixed by a minus sign to disable redirection.
1542 
1543  chmod dirlist locate mkdir mv prepare rm rmdir stat
1544 
1545  <paths> redirects the client when an attempt is made to open
1546  one of absolute <paths>. Up to 4 different redirect
1547  combinations may be specified. When prefixed by "?"
1548  then the redirect applies to any operation on the path
1549  that results in an ENOENT error.
1550 
1551  <domlist> {private | local | .<domain>} [<domlist>]
1552 
1553  Output: 0 upon success or !0 upon failure.
1554 */
1555 
1556 int XrdXrootdProtocol::xred(XrdOucStream &Config)
1557 {
1558  static struct rediropts {const char *opname; RD_func opval;} rdopts[] =
1559  {
1560  {"chmod", RD_chmod},
1561  {"chksum", RD_chksum},
1562  {"dirlist", RD_dirlist},
1563  {"locate", RD_locate},
1564  {"mkdir", RD_mkdir},
1565  {"mv", RD_mv},
1566  {"prepare", RD_prepare},
1567  {"prepstage",RD_prepstg},
1568  {"rm", RD_rm},
1569  {"rmdir", RD_rmdir},
1570  {"stat", RD_stat},
1571  {"trunc", RD_trunc}
1572  };
1573  static const int rHLen = 264;
1574  char rHost[2][rHLen], *hP[2], *val;
1575  int i, k, neg, numopts = sizeof(rdopts)/sizeof(struct rediropts);
1576  int rPort[2], isQ = 0;
1577 
1578 // Get the host and port
1579 //
1580  val = Config.GetWord();
1581  if (!xred_php(val, hP, rPort, "redirect")) return 1;
1582 
1583 // Copy out he values as the target variable will be lost
1584 //
1585  for (i = 0; i < 2; i++)
1586  {if (!hP[i]) rHost[i][0] = 0;
1587  else {strlcpy(rHost[i], hP[i], rHLen);
1588  hP[i] = rHost[i];
1589  }
1590  }
1591 
1592 // Set all redirect target functions
1593 //
1594  if (!(val = Config.GetWord()))
1595  {eDest.Emsg("config", "redirect option not specified"); return 1;}
1596 
1597 // Handle the client option
1598 //
1599  if (!strcmp("client", val)) return xred_clnt(Config, hP, rPort);
1600 
1601  if (*val == '/' || (isQ = ((*val == '?') || !strcmp(val,"enoent"))))
1602  {if (isQ)
1603  {RQLxist = 1;
1604  if (!(val = Config.GetWord()))
1605  {eDest.Emsg("Config", "redirect path not specified.");
1606  return 1;
1607  }
1608  if (*val != '/')
1609  {eDest.Emsg("Config", "non-absolute redirect path -", val);
1610  return 1;
1611  }
1612  }
1613  for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
1614  if (xred_xok(k, hP, rPort)) break;
1615  if (k >= RD_Num)
1616  {eDest.Emsg("Config", "too many different path redirects"); return 1;}
1617  xred_set(RD_func(k), hP, rPort);
1618  do {if (isQ) RQList.Insert(val, k, 0);
1619  else RPList.Insert(val, k, 0);
1620  if ((val = Config.GetWord()) && *val != '/')
1621  {eDest.Emsg("Config", "non-absolute redirect path -", val);
1622  return 1;
1623  }
1624  } while(val);
1625  return 0;
1626  }
1627 
1628  while (val)
1629  {if (!strcmp(val, "all"))
1630  {for (i = 0; i < numopts; i++)
1631  xred_set(rdopts[i].opval, hP, rPort);
1632  }
1633  else {if ((neg = (val[0] == '-' && val[1]))) val++;
1634  for (i = 0; i < numopts; i++)
1635  {if (!strcmp(val, rdopts[i].opname))
1636  {if (neg) xred_set(rdopts[i].opval, 0, 0);
1637  else xred_set(rdopts[i].opval, hP, rPort);
1638  break;
1639  }
1640  }
1641  if (i >= numopts)
1642  eDest.Emsg("config", "invalid redirect option", val);
1643  }
1644  val = Config.GetWord();
1645  }
1646  return 0;
1647 }
1648 
1649 /******************************************************************************/
1650 
1651 int XrdXrootdProtocol::xred_clnt(XrdOucStream &Config,char *hP[2],int rPort[2])
1652 {
1653  static const int maxDom = sizeof(RouteClient.Domain)/sizeof(char*);
1654  char *val;
1655 
1656 // Reset values
1657 //
1658  if (CL_Redir)
1659  {for (int i = 0; i < RouteClient.DomCnt; i++)
1660  {if (RouteClient.Domain[i]) free(RouteClient.Domain[i]);}
1661  }
1662  for (int i = 0; i < maxDom; i++) RouteClient.Domain[i] = 0;
1663  RouteClient.DomCnt = 0;
1664  RouteClient.pvtIP = false;
1665  RouteClient.lclDom = false;
1666  CL_Redir = true;
1667 
1668 // Process arguments
1669 //
1670  if (!(val = Config.GetWord()))
1671  {eDest.Emsg("Config", "redirect client argument not specified.");
1672  return 1;
1673  }
1674 
1675  while(val)
1676  { if (!strcmp("private", val)) RouteClient.pvtIP = true;
1677  else if (!strcmp("local", val)) RouteClient.lclDom = true;
1678  else if (*val == '.')
1679  {if (RouteClient.DomCnt >= maxDom)
1680  {eDest.Emsg("Config",
1681  "Too many redirect client domains specified.");
1682  return 1;
1683  }
1684  RouteClient.Domain[RouteClient.DomCnt++] = strdup(val);
1685  }
1686  else {eDest.Emsg("Config", "Invalid redirect client domain -", val);
1687  return 1;
1688  }
1689  val = Config.GetWord();
1690  }
1691 
1692 // Set the host parameters
1693 //
1694  xred_set(RD_client, hP, rPort);
1695  return 0;
1696 }
1697 
1698 /******************************************************************************/
1699 
1700 bool XrdXrootdProtocol::xred_php(char *val, char *hP[2], int rPort[2],
1701  const char *what, bool optport)
1702 {
1703  XrdNetAddr testAddr;
1704  char *pp;
1705 
1706 // Make sure we have a value
1707 //
1708  if (!val || !(*val))
1709  {eDest.Emsg("config", what, "argument not specified"); return false;}
1710 
1711 // Check if we have two hosts here
1712 //
1713  hP[0] = val;
1714  if (!(pp = index(val, '%'))) hP[1] = 0;
1715  else {hP[1] = pp+1; *pp = 0;}
1716 
1717 // Verify corectness here
1718 //
1719  if (!(*val) || (hP[1] && !*hP[1]))
1720  {eDest.Emsg("Config", "malformed", what, "host specification");
1721  return false;
1722  }
1723 
1724 // Process the hosts
1725 //
1726  for (int i = 0; i < 2; i++)
1727  {if (!(val = hP[i])) break;
1728  if (!val || !val[0] || val[0] == ':')
1729  {eDest.Emsg("Config", what, "host not specified"); return false;}
1730  if ((pp = rindex(val, ':')))
1731  {if ((rPort[i] = XrdOuca2x::a2p(eDest, "tcp", pp+1, false)) <= 0)
1732  return false;
1733  *pp = '\0';
1734  } else {
1735  if (optport) rPort[i] = 0;
1736  else {eDest.Emsg("Config", what, "port not specified");
1737  return false;
1738  }
1739  }
1740  const char *eText = testAddr.Set(val, 0);
1741  if (eText)
1742  {if (XrdNetAddrInfo::isHostName(val) && !strncmp(eText,"Dynamic",7))
1743  eDest.Say("Config warning: ", eText, " as ", val);
1744  else {eDest.Say("Config failure: ", what, " target ", val,
1745  " is invalid; ", eText);
1746  return false;
1747  }
1748  }
1749  }
1750 
1751 // All done
1752 //
1753  return true;
1754 }
1755 
1756 void XrdXrootdProtocol::xred_set(RD_func func, char *rHost[2], int rPort[2])
1757 {
1758 
1759 // Reset static redirection
1760 //
1761  if (Route[func].Host[0]) free(Route[func].Host[0]);
1762  if (Route[func].Host[0] != Route[func].Host[1]) free(Route[func].Host[1]);
1763 
1764  if (rHost)
1765  {Route[func].Host[0] = strdup(rHost[0]);
1766  Route[func].Port[0] = rPort[0];
1767  } else {
1768  Route[func].Host[0] = Route[func].Host[1] = 0;
1769  Route[func].Port[0] = Route[func].Port[1] = 0;
1770  return;
1771  }
1772 
1773  if (!rHost[1])
1774  {Route[func].Host[1] = Route[func].Host[0];
1775  Route[func].Port[1] = Route[func].Port[0];
1776  } else {
1777  Route[func].Host[1] = strdup(rHost[1]);
1778  Route[func].Port[1] = rPort[1];
1779  }
1780 }
1781 
1782 bool XrdXrootdProtocol::xred_xok(int func, char *rHost[2], int rPort[2])
1783 {
1784  if (!Route[func].Host[0]) return true;
1785 
1786  if (strcmp(Route[func].Host[0], rHost[0])
1787  || Route[func].Port[0] != rPort[0]) return false;
1788 
1789  if (!rHost[1]) return Route[func].Host[0] == Route[func].Host[1];
1790 
1791  if (strcmp(Route[func].Host[1], rHost[1])
1792  || Route[func].Port[1] != rPort[1]) return false;
1793 
1794  return true;
1795 }
1796 
1797 /******************************************************************************/
1798 /* x s e c l */
1799 /******************************************************************************/
1800 
1801 /* Function: xsecl
1802 
1803  Purpose: To parse the directive: seclib {default | <path>}
1804 
1805  <path> the path of the security library to be used.
1806  "default" uses the default security library.
1807 
1808  Output: 0 upon success or !0 upon failure.
1809 */
1810 
1811 int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
1812 {
1813  char *val;
1814 
1815 // Get the path
1816 //
1817  val = Config.GetWord();
1818  if (!val || !val[0])
1819  {eDest.Emsg("Config", "seclib argument not specified"); return 1;}
1820 
1821 // Record the path
1822 //
1823  if (SecLib) free(SecLib);
1824  SecLib = strdup(val);
1825  return 0;
1826 }
1827 
1828 /******************************************************************************/
1829 /* x t l s */
1830 /******************************************************************************/
1831 
1832 /* Function: xtls
1833 
1834 topPurpose: To parse the directive: tls [capable] <reqs>
1835 
1836  capable Enforce TLS requirements only for TLS capable clients.
1837  Otherwise, TLS is enforced for all clients.
1838  <reqs> are one or more of the following tls requirements. Each
1839  may be prefixed by a minus sign to disable it. Note
1840  this directive is cummalitive.
1841 
1842  all Requires all of the below.
1843  data All bound sockets must use TLS. When specified,
1844  session is implied unless login is specified.
1845  gpfile getile and putfile requests must use TLS
1846  login Logins and all subsequent requests must use TLS
1847  none Turns all requirements off (default).
1848  off Synonym for none.
1849  session All requests after login must use TLS
1850  tpc Third party copy requests must use TLS
1851 
1852  Output: 0 upon success or !0 upon failure.
1853 */
1854 
1855 int XrdXrootdProtocol::xtls(XrdOucStream &Config)
1856 {
1857  static const int Req_TLSAll = Req_TLSData|Req_TLSLogin|Req_TLSTPC;
1858  static struct enforceopts {const char *opname; int opval; int enval;}
1859  enfopts[] =
1860  {
1861  {"all", kXR_tlsAny, Req_TLSAll},
1862  {"data", kXR_tlsData, Req_TLSData},
1863  {"gpfile", kXR_tlsGPF, Req_TLSGPFile},
1864  {"login", kXR_tlsLogin, Req_TLSLogin},
1865  {"session", kXR_tlsSess, Req_TLSSess},
1866  {"tpc", kXR_tlsTPC, Req_TLSTPC}
1867  };
1868  char *val;
1869  int i, numopts = sizeof(enfopts)/sizeof(struct enforceopts);
1870  bool neg, forall = true;
1871 
1872  if (!(val = Config.GetWord()))
1873  {eDest.Emsg("config", "tls parameter not specified"); return 1;}
1874 
1875  if (!strcmp("capable", val))
1876  {forall = false;
1877  if (!(val = Config.GetWord()))
1878  {eDest.Emsg("config", "tls requirement not specified"); return 1;}
1879  }
1880 
1881  while (val)
1882  {if (!strcmp(val, "off") || !strcmp(val, "none"))
1883  {myRole &= ~kXR_tlsAny;
1884  if (forall) tlsCap = tlsNot = 0;
1885  else tlsCap = 0;
1886  } else {
1887  if ((neg = (val[0] == '-' && val[1]))) val++;
1888  for (i = 0; i < numopts; i++)
1889  {if (!strcmp(val, enfopts[i].opname))
1890  {if (neg) myRole &= ~enfopts[i].opval;
1891  else myRole |= enfopts[i].opval;
1892  if (neg) tlsCap &= ~enfopts[i].enval;
1893  else tlsCap |= enfopts[i].enval;
1894  if (forall)
1895  {if (neg) tlsNot &= ~enfopts[i].enval;
1896  else tlsNot |= enfopts[i].enval;
1897  }
1898  break;
1899  }
1900  }
1901  if (i >= numopts)
1902  {eDest.Emsg("config", "Invalid tls requirement -", val);
1903  return 1;
1904  }
1905  }
1906  val = Config.GetWord();
1907  }
1908 
1909 // If data needs TLS but the session does not, then force session TLS
1910 //
1911  if ((myRole & kXR_tlsData) && !(myRole & (kXR_tlsLogin | kXR_tlsSess)))
1912  myRole |= kXR_tlsSess;
1913  if ((tlsCap & kXR_tlsData) && !(tlsCap & (Req_TLSLogin | Req_TLSSess)))
1914  tlsCap |= Req_TLSSess;
1915  if ((tlsNot & kXR_tlsData) && !(tlsNot & (Req_TLSLogin | Req_TLSSess)))
1916  tlsNot |= Req_TLSSess;
1917 
1918 // Do final resolution on the settins
1919 //
1920  return (CheckTLS(0) ? 0 : 1);
1921 }
1922 
1923 /******************************************************************************/
1924 /* x t l s r */
1925 /******************************************************************************/
1926 
1927 /* Function: xtlsr
1928 
1929  Purpose: To parse the directive: tlsreuse off | on [flush <ft>[h|m|s]]
1930 
1931  off turns off the TLS session reuse cache.
1932  on turns on the TLS session reuse cache.
1933  <ft> sets the cache flush frequency. the default is set
1934  by the TLS libraries and is typically connection count.
1935 
1936  Output: 0 upon success or !0 upon failure.
1937 */
1938 
1939 int XrdXrootdProtocol::xtlsr(XrdOucStream &Config)
1940 {
1941  char *val;
1942  int num;
1943 
1944 // Get the argument
1945 //
1946  val = Config.GetWord();
1947  if (!val || !val[0])
1948  {eDest.Emsg("Config", "tlsreuse argument not specified"); return 1;}
1949 
1950 // If it's off, we set it off
1951 //
1952  if (!strcmp(val, "off"))
1954  return 0;
1955  }
1956 
1957 // If it's on we may need more to do
1958 //
1959  if (!strcmp(val, "on"))
1960  {if (!tlsCtx) {eDest.Emsg("Config warning:", "Ignoring "
1961  "'tlsreuse on'; TLS not configured!");
1962  return 0;
1963  }
1965  if (!(val = Config.GetWord())) return 0;
1966  if (!strcmp(val, "flush" ))
1967  {if (!(val = Config.GetWord()))
1968  {eDest.Emsg("Config", "tlsreuse flush value not specified");
1969  return 1;
1970  }
1971  if (XrdOuca2x::a2tm(eDest,"tlsreuse flush",val,&num,1)) return 1;
1972  if (num < 60) num = 60;
1973  else if (num > XrdTlsContext::scFMax)
1974  num = XrdTlsContext::scFMax;
1975  tlsCache |= num;
1976  }
1977  }
1978 
1979 // We have a bad keyword
1980 //
1981  eDest.Emsg("config", "Invalid tlsreuse option -", val);
1982  return 1;
1983 }
1984 
1985 /******************************************************************************/
1986 /* x t r a c e */
1987 /******************************************************************************/
1988 
1989 /* Function: xtrace
1990 
1991  Purpose: To parse the directive: trace <events>
1992 
1993  <events> the blank separated list of events to trace. Trace
1994  directives are cummalative.
1995 
1996  Output: 0 upon success or 1 upon failure.
1997 */
1998 
1999 int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
2000 {
2001  char *val;
2002  static struct traceopts {const char *opname; int opval;} tropts[] =
2003  {
2004  {"all", TRACE_ALL},
2005  {"auth", TRACE_AUTH},
2006  {"debug", TRACE_DEBUG},
2007  {"emsg", TRACE_EMSG},
2008  {"fs", TRACE_FS},
2009  {"fsaio", TRACE_FSAIO},
2010  {"fsio", TRACE_FSIO},
2011  {"login", TRACE_LOGIN},
2012  {"mem", TRACE_MEM},
2013  {"pgcserr", TRACE_PGCS},
2014  {"redirect", TRACE_REDIR},
2015  {"request", TRACE_REQ},
2016  {"response", TRACE_RSP},
2017  {"stall", TRACE_STALL}
2018  };
2019  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2020 
2021  if (!(val = Config.GetWord()))
2022  {eDest.Emsg("config", "trace option not specified"); return 1;}
2023  while (val)
2024  {if (!strcmp(val, "off")) trval = 0;
2025  else {if ((neg = (val[0] == '-' && val[1]))) val++;
2026  for (i = 0; i < numopts; i++)
2027  {if (!strcmp(val, tropts[i].opname))
2028  {if (neg) trval &= ~tropts[i].opval;
2029  else trval |= tropts[i].opval;
2030  break;
2031  }
2032  }
2033  if (i >= numopts)
2034  eDest.Emsg("config", "invalid trace option", val);
2035  }
2036  val = Config.GetWord();
2037  }
2038  XrdXrootdTrace.What = trval;
2039  return 0;
2040 }
2041 
2042 /******************************************************************************/
2043 /* x l i m i t */
2044 /******************************************************************************/
2045 
2046 /* Function: xlimit
2047 
2048  Purpose: To parse the directive: limit [prepare <count>] [noerror]
2049 
2050  prepare <count> The maximum number of prepares that are allowed
2051  during the course of a single connection
2052 
2053  noerror When possible, do not issue an error when a limit
2054  is hit.
2055 
2056  Output: 0 upon success or 1 upon failure.
2057 */
2058 int XrdXrootdProtocol::xlimit(XrdOucStream &Config)
2059 {
2060  int plimit = -1;
2061  const char *word;
2062 
2063 // Look for various limits set
2064 //
2065  while ( (word = Config.GetWord()) ) {
2066  if (!strcmp(word, "prepare")) {
2067  if (!(word = Config.GetWord()))
2068  {
2069  eDest.Emsg("Config", "'limit prepare' value not specified");
2070  return 1;
2071  }
2072  if (XrdOuca2x::a2i(eDest, "limit prepare", word, &plimit, 0)) { return 1; }
2073  } else if (!strcmp(word, "noerror")) {
2074  LimitError = false;
2075  }
2076  }
2077  if (plimit >= 0) {PrepareLimit = plimit;}
2078  return 0;
2079 }
#define kXR_isManager
Definition: XProtocol.hh:1156
#define kXR_tlsLogin
Definition: XProtocol.hh:1184
#define kXR_suppgrw
Definition: XProtocol.hh:1174
#define kXR_attrMeta
Definition: XProtocol.hh:1159
#define kXR_haveTLS
Definition: XProtocol.hh:1179
#define kXR_anongpf
Definition: XProtocol.hh:1172
#define kXR_tlsAny
Definition: XProtocol.hh:1181
#define kXR_tlsTPC
Definition: XProtocol.hh:1186
#define kXR_isServer
Definition: XProtocol.hh:1157
#define kXR_attrCache
Definition: XProtocol.hh:1158
#define kXR_attrProxy
Definition: XProtocol.hh:1160
#define kXR_LBalServer
Definition: XProtocol.hh:1151
#define kXR_tlsGPF
Definition: XProtocol.hh:1183
#define kXR_supposc
Definition: XProtocol.hh:1175
#define kXR_tlsSess
Definition: XProtocol.hh:1185
#define kXR_DataServer
Definition: XProtocol.hh:1150
#define kXR_supgpf
Definition: XProtocol.hh:1173
#define kXR_tlsData
Definition: XProtocol.hh:1182
unsigned short kXR_unt16
Definition: XPtypes.hh:67
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
XrdSfsFileSystem * XrdDigGetFS(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *cFN, const char *parms)
Definition: XrdDigFS.cc:105
#define TRACE_AUTH
Definition: XrdHttpTrace.hh:48
#define TRACE_REQ
Definition: XrdHttpTrace.hh:51
#define TRACE_RSP
Definition: XrdHttpTrace.hh:53
#define TRACE_REDIR
Definition: XrdHttpTrace.hh:52
int open(const char *path, int oflag,...)
XrdSecProtocol *(* XrdSecGetProt_t)(const char *hostname, XrdNetAddrInfo &endPoint, XrdSecParameters &sectoken, XrdOucErrInfo *einfo)
Typedef to simplify the encoding of methods returning XrdSecProtocol.
XrdSecService * XrdSecLoadSecService(XrdSysError *eDest, const char *cfn, const char *seclib, XrdSecGetProt_t *getP, XrdSecProtector **proP)
#define SFS_OK
const int SYS_LOG_02
Definition: XrdSysError.hh:73
const int SYS_LOG_01
Definition: XrdSysError.hh:72
if(Avsz)
size_t strlcpy(char *dst, const char *src, size_t sz)
#define TRACE_DEBUG
Definition: XrdTrace.hh:36
#define TRACE_MEM
Definition: XrdTrace.hh:38
#define TRACE(act, x)
Definition: XrdTrace.hh:63
#define TRACE_ALL
Definition: XrdTrace.hh:35
const char * XrdXrootdInstance
XrdSysTrace XrdXrootdTrace
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *EnvInfo)
Definition: XrdOfsFS.cc:49
XrdXrootdPrepare * XrdXrootdPrepQ
#define TS_Zeq(x, m)
XrdOucString * XrdXrootdCF
#define TS_Xeq(x, m)
XrdSfsFileSystem * XrdXrootdloadFileSystem(XrdSysError *, XrdSfsFileSystem *, const char *, const char *, XrdOucEnv *)
int XrdXrootdPort
#define TRACE_FS
#define TRACE_FSAIO
#define TRACE_FSIO
#define TRACE_PGCS
#define TRACE_LOGIN
#define TRACE_EMSG
#define TRACE_STALL
#define XROOTDXP_OK
#define XROOTDXP_NOLK
#define XROOTDXP_NOSLASH
#define XROOTDXP_NOMWCHK
#define XROOTDXP_NOCGI
int Recalc(int bsz)
Definition: XrdBuffer.cc:195
static XrdNetIF netIF
Definition: XrdInet.hh:68
static bool isHostName(const char *name)
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:216
void Display(const char *pfx="=====> ")
Definition: XrdNetIF.cc:142
int Port()
Definition: XrdNetIF.hh:322
static int Parse(XrdSysError *eLog, XrdOucStream &Config)
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
void Set(int inQMax, time_t agemax=1800)
Definition: XrdObject.icc:90
long GetInt(const char *varname)
Definition: XrdOucEnv.cc:253
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:188
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:316
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
Definition: XrdOucProg.cc:296
const char * c_str() const
int length() const
void append(const int i)
XrdOucTList * next
Definition: XrdOucTList.hh:45
char * text
Definition: XrdOucTList.hh:46
static const mode_t pathMode
Definition: XrdOucUtils.hh:47
static char * genPath(const char *path, const char *inst, const char *psfx=0)
Definition: XrdOucUtils.cc:417
static int GidName(gid_t gID, char *gName, int gNsz, time_t keepT=0)
Definition: XrdOucUtils.cc:547
static int UidName(uid_t uID, char *uName, int uNsz, time_t keepT=0)
static int makePath(char *path, mode_t mode, bool reset=false)
Definition: XrdOucUtils.cc:917
static void toLower(char *str)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:45
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
Definition: XrdOuca2x.cc:257
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition: XrdOuca2x.cc:288
static int a2p(XrdSysError &, const char *ptype, const char *val, bool anyOK=true)
Definition: XrdOuca2x.cc:140
const char * myName
Definition: XrdProtocol.hh:82
XrdBuffManager * BPool
Definition: XrdProtocol.hh:63
XrdScheduler * Sched
Definition: XrdProtocol.hh:64
XrdTlsContext * tlsCtx
Definition: XrdProtocol.hh:99
const char * AdmPath
Definition: XrdProtocol.hh:76
XrdSysError * eDest
Definition: XrdProtocol.hh:61
XrdOucString * totalCF
Definition: XrdProtocol.hh:100
XrdOucEnv * theEnv
Definition: XrdProtocol.hh:66
const char * myInst
Definition: XrdProtocol.hh:81
XrdStats * Stats
Definition: XrdProtocol.hh:65
virtual const char * protTLS()=0
virtual void EnvInfo(XrdOucEnv *envP)
virtual int chksum(csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
virtual int FAttr(XrdSfsFACtl *faReq, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141
void setMsgMask(int mask)
Definition: XrdSysError.hh:154
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141
void SetLogger(XrdSysLogger *logp)
Definition: XrdSysTrace.cc:65
XrdTlsContext * Clone(bool full=true, bool startCRLRefresh=false)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int scNone
Do not change any option settings.
static const int scOff
Turn off cache.
static const int scFMax
static const int scSrvr
Turn on cache server mode (default)
static int Init(XrdSysError *erp, XrdNetSocket *asock)
static void addJob(const char *jname, XrdXrootdJob *jp)
static void setVals(XrdSysError *erp, XrdXrootdStats *SIp, XrdScheduler *schp, int port)
static void Init(XrdXrootdFileLock *lp, XrdSysError *erP, bool sfok)
static int setParms(int stime, int skeep)
static XrdXrootdStats * SI
static const char * myInst
static XrdSfsFileSystem * digFS
static XrdNetPMark * PMark
static short as_okstutter
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
static const char Req_TLSGPFile
static const char Req_TLSSess
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static char * usxParms
static const char * myCName
static const char Req_TLSData
static XrdXrootdFileLock * Locker
static const char Req_TLSTPC
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static struct XrdXrootdProtocol::RC_Table RouteClient
static const char * myUName
static const char Req_TLSLogin
static int Configure(char *parms, XrdProtocol_Config *pi)
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static XrdSecProtector * DHS
static XrdBuffManager * BPool
static XrdSecService * CIA
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSfsFileSystem * osFS
void setFS(XrdSfsFileSystem *fsp)
static void Init(XrdScheduler *schedP, int qMax, int qTTL)
Perform one-time initialization.
void Insert(const char *pd, int popt=0, int flags=XROOTDXP_OK)
XrdXrootdXPath * Next()
void Set(int opts, const char *pathdata=0)
XrdCmsConfig Config
XrdSysLogger Logger
Definition: XrdGlobals.cc:47
struct ServerResponseBifs_Protocol bifReqs
Definition: XProtocol.hh:1120
static const int maxRvecsz
Definition: XProtocol.hh:686
static const uint64_t hasPGRW
Feature: pgRead and pgWrite.
Definition: XrdSfsFlags.hh:56
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions)
Definition: XrdSfsFlags.hh:62
static const uint64_t hasGPFA
Feature: gpFile anonymous.
Definition: XrdSfsFlags.hh:53
static const uint64_t hasCACH
Feature: Implements a data cache.
Definition: XrdSfsFlags.hh:74
static const uint64_t hasNOSF
Feature: Supports no sendfile.
Definition: XrdSfsFlags.hh:71
static const uint64_t hasPOSC
Feature: Persist On Successful Close.
Definition: XrdSfsFlags.hh:59
static const uint64_t hasGPF
Feature: gpFile.
Definition: XrdSfsFlags.hh:50
static const uint64_t hasNAIO
Feature: Supports no async I/O.
Definition: XrdSfsFlags.hh:77
static const uint64_t hasPRXY
Feature: Proxy Server.
Definition: XrdSfsFlags.hh:65
XrdXrootdStats * SI
XrdScheduler * Sched
char * bifResp[2]
XrdBuffManager * BPool