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  }
411  myRole |= tlsFlags;
412 
413 // Turn off client redirects if we are neither a redirector nor a proxy server
414 //
415  if (CL_Redir && !isRedir && !isProxy)
416  {CL_Redir = false;
417  eDest.Say("Config warning: 'redirect client' ignored; "
418  "not a redirector nor a proxy server");
419  }
420 
421 // Check if we are redirecting anything
422 //
423  if ((xp = RPList.Next()))
424  {int k;
425  char buff[2048], puff[1024];
426  do {k = xp->Opts();
427  if (Route[k].Host[0] == Route[k].Host[1]
428  && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
429  else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
430  sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
431  eDest.Say("Config redirect static ", xp->Path(), buff);
432  xp = xp->Next();
433  } while(xp);
434  }
435 
436  if ((xp = RQList.Next()))
437  {int k;
438  const char *cgi1, *cgi2;
439  char buff[2048], puff[1024], xCgi[RD_Num] = {0};
440  if (isRedir) {cgi1 = "+"; cgi2 = getenv("XRDCMSCLUSTERID");}
441  else {cgi1 = ""; cgi2 = pi->myName;}
442  myCNlen = snprintf(buff, sizeof(buff), "%s%s", cgi1, cgi2);
443  myCName = strdup(buff);
444  do {k = xp->Opts();
445  if (Route[k].Host[0] == Route[k].Host[1]
446  && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
447  else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
448  sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
449  eDest.Say("Config redirect enoent ", xp->Path(), buff);
450  if (!xCgi[k] && cgi2)
451  {bool isdup = Route[k].Host[0] == Route[k].Host[1]
452  && Route[k].Port[0] == Route[k].Port[1];
453  for (i = 0; i < 2; i++)
454  {n = snprintf(buff,sizeof(buff), "%s?tried=%s%s",
455  Route[k].Host[i], cgi1, cgi2);
456  free(Route[k].Host[i]); Route[k].Host[i] = strdup(buff);
457  Route[k].RDSz[i] = n;
458  if (isdup) {Route[k].Host[1] = Route[k].Host[0];
459  Route[k].RDSz[1] = n; break;
460  }
461  }
462  }
463  xCgi[k] = 1;
464  xp = xp->Next();
465  } while(xp);
466  }
467 
468 // Add all jobs that we can run to the admin object
469 //
470  if (JobCKS) XrdXrootdAdmin::addJob("chksum", JobCKS);
471 
472 // Establish the path to be used for admin functions. We will loose this
473 // storage upon an error but we don't care because we'll just exit.
474 //
475  adminp = XrdOucUtils::genPath(pi->AdmPath, 0, ".xrootd");
476 
477 // Setup the admin path (used in all roles).
478 //
479  if (!(AdminSock = XrdNetSocket::Create(&eDest, adminp, "admin", pi->AdmMode))
480  || !XrdXrootdAdmin::Init(&eDest, AdminSock)) return 0;
481 
482 // Indicate whether or not we support extended attributes
483 //
484  {XrdOucEnv myEnv;
485  XrdOucErrInfo eInfo("", &myEnv);
486  char buff[128];
487  if (osFS->FAttr(0, eInfo, 0) == SFS_OK)
488  {usxMaxNsz = myEnv.GetInt("usxMaxNsz");
489  if (usxMaxNsz < 0) usxMaxNsz = 0;
490  usxMaxVsz = myEnv.GetInt("usxMaxVsz");
491  if (usxMaxVsz < 0) usxMaxVsz = 0;
492  snprintf(buff, sizeof(buff), "%d %d", usxMaxNsz, usxMaxVsz);
493  usxParms = strdup(buff);
494  } else {
495  usxMaxNsz = 0;
496  usxMaxVsz = 0;
497  usxParms = strdup("0 0");
498  }
499  }
500 
501 // Finally, check if we really need to be in bypass mode if it is set
502 //
503  if (OD_Bypass)
504  {const char *penv = getenv("XRDXROOTD_PROXY");
505  if (!penv || *penv != '=')
506  {OD_Bypass = false;
507  eDest.Say("Config warning: 'fsoverload bypass' ignored; "
508  "not a forwarding proxy.");
509  }
510  }
511 
512 // Add any additional features
513 //
518  myRole |= kXR_anongpf;
519 
520 // Finally note whether or not we have TLS enabled
521 //
522  if (tlsCtx) myRole |= kXR_haveTLS;
523 
524 // Return success
525 //
526  free(adminp);
527  return 1;
528 }
529 
530 /******************************************************************************/
531 /* C o n f i g */
532 /******************************************************************************/
533 
534 #define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
535 #define TS_Zeq(x,m) (!strcmp(x,var)) GoNo = m(&eDest, Config)
536 
537 int XrdXrootdProtocol::Config(const char *ConfigFN)
538 {
539  XrdOucEnv myEnv;
540  XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
541  char *var;
542  int cfgFD, GoNo, NoGo = 0, ismine;
543 
544  // Open and attach the config file
545  //
546  if ((cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
547  return eDest.Emsg("Config", errno, "open config file", ConfigFN);
548  Config.Attach(cfgFD);
549 
550  // Indicate what we are about to do in the capture stream
551  //
552  static const char *cvec[] = { "*** xroot protocol config:", 0 };
553  Config.Capture(cvec);
554 
555  // Process items
556  //
557  while((var = Config.GetMyFirstWord()))
558  { if ((ismine = !strncmp("xrootd.", var, 7)) && var[7]) var += 7;
559  else if ((ismine = !strcmp("all.export", var))) var += 4;
560  else if ((ismine = !strcmp("all.seclib", var))) var += 4;
561 
562  if (ismine)
563  { if TS_Xeq("async", xasync);
564  else if TS_Xeq("bindif", xbif);
565  else if TS_Xeq("chksum", xcksum);
566  else if TS_Xeq("diglib", xdig);
567  else if TS_Xeq("export", xexp);
568  else if TS_Xeq("fslib", xfsl);
569  else if TS_Xeq("fsoverload", xfso);
570  else if TS_Xeq("gpflib", xgpf);
571  else if TS_Xeq("log", xlog);
572  else if TS_Xeq("mongstream", xmongs);
573  else if TS_Xeq("monitor", xmon);
574  else if TS_Zeq("pmark", XrdNetPMarkCfg::Parse);
575  else if TS_Xeq("prep", xprep);
576  else if TS_Xeq("redirect", xred);
577  else if TS_Xeq("seclib", xsecl);
578  else if TS_Xeq("tls", xtls);
579  else if TS_Xeq("tlsreuse", xtlsr);
580  else if TS_Xeq("trace", xtrace);
581  else if TS_Xeq("limit", xlimit);
582  else {if (!strcmp(var, "pidpath"))
583  {eDest.Say("Config warning: 'xrootd.pidpath' no longer "
584  "supported; use 'all.pidpath'.");
585  } else {
586  eDest.Say("Config warning: ignoring unknown "
587  "directive '", var, "'.");
588  }
589  Config.Echo(false);
590  continue;
591  }
592  if (GoNo) {Config.Echo(); NoGo = 1;}
593  }
594  }
595 
596 // We now have to generate the correct TLS context if one was specified. Our
597 // context must be of the non-verified kind as we don't accept certs.
598 //
599  if (!NoGo && tlsCtx)
600  {tlsCtx = tlsCtx->Clone(false,true);
601  if (!tlsCtx)
602  {eDest.Say("Config failure: unable to setup TLS for protocol!");
603  NoGo = 1;
604  } else {
605  static const char *sessID = "xroots";
606  tlsCtx->SessionCache(tlsCache, sessID, 6);
607  }
608  }
609 
610 // Add our config to our environment and return
611 //
612  return NoGo;
613 }
614 
615 /******************************************************************************/
616 /* P r i v a t e F u n c t i o n s */
617 /******************************************************************************/
618 /******************************************************************************/
619 /* C h e c k T L S */
620 /******************************************************************************/
621 
622 int XrdXrootdProtocol::CheckTLS(const char *tlsProt)
623 {
624 
625 // If login specified, turn off session as it doesn't make sense together.
626 //
630 
631 // Turn off TPC TLS requirement if login or session is required to have TLS
632 // However, that flag must remain to be set in the protocol response.
633 //
636 
637 // If some authnetication protocols need TLS then we must requie that login
638 // uses TLS. For incapable clients, we leave this alone as we will skip
639 // TLS authnetication based protocols should the login phase not have TLS.
640 //
641  if (tlsProt && !(tlsCap & Req_TLSLogin))
642  {eDest.Say("Config Authentication protocol(s)", tlsProt,
643  " require TLS; login now requires TLS.");
644  myRole |= kXR_tlsLogin;
645  tlsCap |= Req_TLSLogin;
646  }
647 
648 // If there are any TLS requirements then TLS must have been configured.
649 //
650  if (myRole & kXR_tlsAny && !tlsCtx)
651  {eDest.Say("Config failure: unable to honor TLS requirement; "
652  "TLS not configured!");
653  return 0;
654  }
655 
656 // All done
657 //
658  return 1;
659 }
660 
661 /******************************************************************************/
662 /* C o n f i g F S */
663 /******************************************************************************/
664 
665 bool XrdXrootdProtocol::ConfigFS(XrdOucEnv &xEnv, const char *cfn)
666 {
667  const char *fsLoc;
668  int n;
669 
670 // Get the filesystem to be used
671 //
672  if (FSLib[0])
673  {TRACE(DEBUG, "Loading base filesystem library " <<FSLib[0]);
674  osFS = XrdXrootdloadFileSystem(&eDest, 0, FSLib[0], cfn, &xEnv);
675  fsLoc = FSLib[0];
676  } else {
677  osFS = XrdSfsGetDefaultFileSystem(0, eDest.logger(), cfn, &xEnv);
678  fsLoc = "default";
679  }
680 
681 // Make sure we have loaded something
682 //
683  if (!osFS)
684  {eDest.Emsg("Config", "Unable to load base file system using", fsLoc);
685  return false;
686  }
687  if (FSLib[0]) osFS->EnvInfo(&xEnv);
688 
689 // If there is an old style wrapper, load it now.
690 //
691  if (FSLib[1] && !ConfigFS(FSLib[1], xEnv, cfn)) return false;
692 
693 // Run through any other pushdowns
694 //
695  if ((n = FSLPath.size()))
696  for (int i = 0; i < n; i++)
697  {if (!ConfigFS(FSLPath[i].c_str(), xEnv, cfn)) return false;}
698 
699 // Inform the statistics object which filesystem to use
700 //
701  SI->setFS(osFS);
702 
703 // All done here
704 //
705  return true;
706 }
707 
708 /******************************************************************************/
709 
710 bool XrdXrootdProtocol::ConfigFS(const char *path, XrdOucEnv &xEnv,
711  const char *cfn)
712 {
713 
714 // Try to load this wrapper library
715 //
716  TRACE(DEBUG, "Loading wrapper filesystem library " <<path);
717  osFS = XrdXrootdloadFileSystem(&eDest, osFS, path, cfn, &xEnv);
718  if (!osFS)
719  {eDest.Emsg("Config", "Unable to load file system wrapper from", path);
720  return false;
721  }
722  osFS->EnvInfo(&xEnv);
723  return true;
724 }
725 
726 /******************************************************************************/
727 /* C o n f i g S e c u r i t y */
728 /******************************************************************************/
729 
730 int XrdXrootdProtocol::ConfigSecurity(XrdOucEnv &xEnv, const char *cfn)
731 {
732  XrdSecGetProt_t secGetProt = 0;
733  char idBuff[256];
734  int n;
735 
736 // Obtain our uid and username
737 //
738  myUID = geteuid();
739  if ((n = XrdOucUtils::UidName(myUID, idBuff, sizeof(idBuff))))
740  {myUName = strdup(idBuff);
741  myUNLen = n;
742  }
743 
744 // Obtain our gid and groupname
745 //
746  myGID = getegid();
747  if ((n = XrdOucUtils::GidName(myGID, idBuff, sizeof(idBuff))))
748  {myGName = strdup(idBuff);
749  myGNLen = n;
750  }
751 
752 // TLS support is independent of security per se. Record context, if any.
753 //
754  if (tlsCtx) xEnv.PutPtr("XrdTLSContext*", (void *)tlsCtx);
755 
756 // Check if we need to load anything
757 //
758  if (!SecLib)
759  {eDest.Say("Config warning: 'xrootd.seclib' not specified;"
760  " strong authentication disabled!");
761  xEnv.PutPtr("XrdSecGetProtocol*", (void *)0);
762  xEnv.PutPtr("XrdSecProtector*" , (void *)0);
763  return 1;
764  }
765 
766 // Blad some debugging info
767 //
768  TRACE(DEBUG, "Loading security library " <<SecLib);
769 
770 // Load the security server
771 //
772  if (!(CIA = XrdSecLoadSecService(&eDest, cfn,
773  (strcmp(SecLib,"default") ? SecLib : 0),
774  &secGetProt, &DHS)))
775  {eDest.Emsg("Config", "Unable to load security system.");
776  return 0;
777  }
778 
779 // Set environmental pointers
780 //
781  xEnv.PutPtr("XrdSecGetProtocol*", (void *)secGetProt);
782  xEnv.PutPtr("XrdSecProtector*" , (void *)DHS);
783 
784 // If any protocol needs TLS then all logins must use TLS, ufortunately.
785 //
786  const char *tlsProt = CIA->protTLS();
787  if (tlsProt) return CheckTLS(tlsProt);
788  return 1;
789 }
790 
791 /******************************************************************************/
792 /* x a s y n c */
793 /******************************************************************************/
794 
795 /* Function: xasync
796 
797  Purpose: To parse directive: async [limit <aiopl>] [maxsegs <msegs>]
798  [maxtot <mtot>] [segsize <segsize>]
799  [minsize <iosz>] [maxstalls <cnt>]
800  [timeout <tos>]
801  [Debug] [force] [syncw] [off]
802  [nocache] [nosf]
803 
804  <aiopl> maximum number of async req per link. Default 8.
805  <msegs> maximum number of async ops per request. Default 8.
806  <mtot> maximum number of async ops per server. Default is 4096.
807  of maximum connection times aiopl divided by two.
808  <segsz> The aio segment size. This is the maximum size that data
809  will be read or written. The defaults to 64K but is
810  adjusted for each request to minimize latency.
811  <iosz> the minimum number of bytes that must be read or written
812  to allow async processing to occur (default is maxbsz/2
813  typically 1M).
814  <tos> second timeout for async I/O.
815  <cnt> Maximum number of client stalls before synchronous i/o is
816  used. Async mode is tried after <cnt> requests.
817  Debug Turns on async I/O for everything. This an internal
818  undocumented option used for testing purposes.
819  force Uses async i/o for all requests, even when not explicitly
820  requested (this is compatible with synchronous clients).
821  syncw Use synchronous i/o for write requests.
822  off Disables async i/o
823  nocache Disables async I/O is this is a caching proxy.
824  nosf Disables use of sendfile to send data to the client.
825 
826  Output: 0 upon success or 1 upon failure.
827 */
828 
829 int XrdXrootdProtocol::xasync(XrdOucStream &Config)
830 {
831  char *val;
832  int i, ppp;
833  int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
834  int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
835  int V_minsf=-1, V_debug=-1, V_noca=-1, V_tmo=-1;
836  long long llp;
837  struct asyncopts {const char *opname; int minv; int *oploc;
838  const char *opmsg;} asopts[] =
839  {
840  {"Debug", -1, &V_debug, ""},
841  {"force", -1, &V_force, ""},
842  {"off", -1, &V_off, ""},
843  {"nocache", -1, &V_noca, ""},
844  {"nosf", -1, &V_nosf, ""},
845  {"syncw", -1, &V_syncw, ""},
846  {"limit", 0, &V_limit, "async limit"},
847  {"segsize", 4096, &V_segsz, "async segsize"},
848  {"timeout", 0, &V_tmo, "async timeout"},
849  {"maxsegs", 0, &V_msegs, "async maxsegs"},
850  {"maxstalls", 0, &V_mstall,"async maxstalls"},
851  {"maxtot", 0, &V_mtot, "async maxtot"},
852  {"minsfsz", 1, &V_minsf, "async minsfsz"},
853  {"minsize", 4096, &V_minsz, "async minsize"}};
854  int numopts = sizeof(asopts)/sizeof(struct asyncopts);
855 
856  if (!(val = Config.GetWord()))
857  {eDest.Emsg("Config", "async option not specified"); return 1;}
858 
859  while (val)
860  {for (i = 0; i < numopts; i++)
861  if (!strcmp(val, asopts[i].opname))
862  {if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
863  {eDest.Emsg("Config","async",(char *)asopts[i].opname,
864  "value not specified");
865  return 1;
866  }
867  if (asopts[i].minv > 0)
868  if (XrdOuca2x::a2sz(eDest,asopts[i].opmsg, val, &llp,
869  (long long)asopts[i].minv)) return 1;
870  else *asopts[i].oploc = (int)llp;
871  else if (asopts[i].minv == 0)
872  if (XrdOuca2x::a2i(eDest,asopts[i].opmsg,val,&ppp,1))
873  return 1;
874  else *asopts[i].oploc = ppp;
875  else *asopts[i].oploc = 1;
876  break;
877  }
878  if (i >= numopts)
879  eDest.Emsg("Config", "Warning, invalid async option", val);
880  val = Config.GetWord();
881  }
882 
883 // Make sure max values are consistent
884 //
885  if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
886  {eDest.Emsg("Config", "async limit may not be greater than maxtot");
887  return 1;
888  }
889 
890 // Calculate the actual segment size
891 //
892  if (V_segsz > 0)
893  {i = BPool->Recalc(V_segsz);
894  if (!i) {eDest.Emsg("Config", "async segsize is too large"); return 1;}
895  if (i != V_segsz)
896  {char buff[64];
897  sprintf(buff, "%d readjusted to %d", V_segsz, i);
898  eDest.Emsg("Config", "async segsize", buff);
899  V_segsz = i;
900  }
901  }
902 
903 // Calculate actual timeout
904 //
905  if (V_tmo >= 0)
906  {i = V_tmo;
907  if (V_tmo < 1) i = 1;
908  else if (V_tmo > 360) i = 360;
909  if (i != V_tmo)
910  {char buff[64];
911  sprintf(buff, "%d readjusted to %d", V_tmo, i);
912  eDest.Emsg("Config", "async timeout", buff);
913  V_tmo = i;
914  }
915  }
916 
917 // Establish async options
918 //
919  if (V_limit > 0) as_maxperlnk = V_limit;
920  if (V_msegs > 0) as_maxperreq = V_msegs;
921  if (V_mtot > 0) as_maxpersrv = V_mtot;
922  if (V_minsz > 0) as_miniosz = V_minsz;
923  if (V_segsz > 0){as_segsize = V_segsz; as_seghalf = V_segsz/2;}
924  if (V_tmo >= 0) as_timeout = V_tmo;
925  if (V_mstall> 0) as_maxstalls = V_mstall;
926  if (V_debug > 0) asyncFlags |= asDebug;
927  if (V_force > 0) as_force = true;
928  if (V_off > 0) as_aioOK = false;
929  if (V_syncw > 0) as_syncw = true;
930  if (V_noca > 0) asyncFlags |= asNoCache;
931  if (V_nosf > 0) as_nosf = true;
932  if (V_minsf > 0) as_minsfsz = V_minsf;
933 
934  return 0;
935 }
936 
937 /******************************************************************************/
938 /* x b i f */
939 /******************************************************************************/
940 
941 /* Function: xbif
942 
943  Purpose: To parse the directive: bindif <trg>
944 
945  <trg>: <host>:<port>[%<prvhost>:<port>]] [<trg>]
946 */
947 
948 namespace XrdXrootd
949 {
950 char *bifResp[2] = {0,0};
951 int bifRLen[2] = {0,0};
952 }
953 
954 int XrdXrootdProtocol::xbif(XrdOucStream &Config)
955 {
956  static const int brSize = sizeof(XrdProto::bifReqs);
957  using XrdXrootd::bifResp;
958  using XrdXrootd::bifRLen;
959 
960  XrdOucString bSpec[2];
961  char *bHost[2], *val, buff[512];
962  int bPort[2], thePort;
963 
964 // Cleanup any previous bif specification
965 //
966  if (bifResp[1])
967  {if (bifResp[1] != bifResp[0]) free(bifResp[1]);
968  bifResp[1] = 0; bifRLen[1] = 0;
969  }
970  if (bifResp[0])
971  {free(bifResp[0]);
972  bifResp[0] = 0; bifRLen[0] = 0;
973  }
974 
975 // Process all of the options
976 //
977  while((val = Config.GetWord()) && *val)
978  {if (!xred_php(val, bHost, bPort, "bindif", true)) return 1;
979  for (int i = 0; i < 2 && bHost[i] != 0; i++)
980  {thePort = (bPort[i] ? bPort[i] : XrdXrootdPort);
981  snprintf(buff, sizeof(buff), "%s%s:%d",
982  (bSpec[i].length() ? "," : ""), bHost[i], thePort);
983  bSpec[i] += buff;
984  }
985  }
986 
987 // Generate the "b" record for each type of interface
988 //
989  for (int i = 0; i < 2 && bSpec[i].length(); i++)
990  {int n = brSize + bSpec[i].length() + 1;
991  n = (n + 7) & ~7;
992  XrdProto::bifReqs *bifRec = (XrdProto::bifReqs *)malloc(n);
993  memset(bifRec, 0, n);
994  bifRec->theTag = 'B';
995  bifRec->bifILen = htons(static_cast<kXR_unt16>(n-brSize));
996  strcpy(((char *)bifRec)+brSize, bSpec[i].c_str());
997  bifResp[i] = (char *)bifRec;
998  bifRLen[i] = n;
999  }
1000 
1001 // Now complete the definition
1002 //
1003  if (bifResp[0] && bifResp[1] == 0)
1004  {bifResp[1] = bifResp[0];
1005  bifRLen[1] = bifRLen[0];
1006  }
1007 
1008 // All done
1009 //
1010  return 0;
1011 }
1012 
1013 /******************************************************************************/
1014 /* x c k s u m */
1015 /******************************************************************************/
1016 
1017 /* Function: xcksum
1018 
1019  Purpose: To parse the directive: chksum [chkcgi] [max <n>] <type> [<path>]
1020 
1021  max maximum number of simultaneous jobs
1022  chkcgi Always check for checksum type in cgo info.
1023  <type> algorithm of checksum (e.g., md5). If more than one
1024  checksum is supported then they should be listed with
1025  each separated by a space.
1026  <path> the path of the program performing the checksum
1027  If no path is given, the checksum is local.
1028 
1029  Output: 0 upon success or !0 upon failure.
1030 */
1031 
1032 int XrdXrootdProtocol::xcksum(XrdOucStream &Config)
1033 {
1034  static XrdOucProg *theProg = 0;
1035  int (*Proc)(XrdOucStream *, char **, int) = 0;
1036  XrdOucTList *tP, *algFirst = 0, *algLast = 0;
1037  char *palg, prog[2048];
1038  int jmax = 4, anum[2] = {0,0};
1039 
1040 // Get the algorithm name and the program implementing it
1041 //
1042  JobCKCGI = 0;
1043  while ((palg = Config.GetWord()) && *palg != '/')
1044  {if (!strcmp(palg,"chkcgi")) {JobCKCGI = 1; continue;}
1045  if (strcmp(palg, "max"))
1046  {XrdOucUtils::toLower(palg);
1047  XrdOucTList *xalg = new XrdOucTList(palg, anum); anum[0]++;
1048  if (algLast) algLast->next = xalg;
1049  else algFirst = xalg;
1050  algLast = xalg;
1051  continue;
1052  }
1053  if (!(palg = Config.GetWord()))
1054  {eDest.Emsg("Config", "chksum max not specified"); return 1;}
1055  if (XrdOuca2x::a2i(eDest, "chksum max", palg, &jmax, 0)) return 1;
1056  }
1057 
1058 // Verify we have an algoritm
1059 //
1060  if (!algFirst)
1061  {eDest.Emsg("Config", "chksum algorithm not specified"); return 1;}
1062  if (JobCKT) free(JobCKT);
1063  JobCKT = strdup(algFirst->text);
1064 
1065 // Handle alternate checksums
1066 //
1067  while((tP = JobCKTLST)) {JobCKTLST = tP->next; delete tP;}
1068  JobCKTLST = algFirst;
1069  if (algFirst->next) JobCKCGI = 2;
1070 
1071 // Handle program if we have one
1072 //
1073  if (palg)
1074  {int n = strlen(palg);
1075  if (n+2 >= (int)sizeof(prog))
1076  {eDest.Emsg("Config", "cksum program too long"); return 1;}
1077  strcpy(prog, palg); palg = prog+n; *palg++ = ' '; n = sizeof(prog)-n-1;
1078  if (!Config.GetRest(palg, n))
1079  {eDest.Emsg("Config", "cksum parameters too long"); return 1;}
1080  } else *prog = 0;
1081 
1082 // Check if we have a program. If not, then this will be a local checksum and
1083 // the algorithm will be verified after we load the filesystem.
1084 //
1085  if (*prog) JobLCL = 0;
1086  else { JobLCL = 1; Proc = &CheckSum; strcpy(prog, "chksum");}
1087 
1088 // Set up the program and job
1089 //
1090  if (!theProg) theProg = new XrdOucProg(0);
1091  if (theProg->Setup(prog, &eDest, Proc)) return 1;
1092  if (JobCKS) delete JobCKS;
1093  if (jmax) JobCKS = new XrdXrootdJob(Sched, theProg, "chksum", jmax);
1094  else JobCKS = 0;
1095  return 0;
1096 }
1097 
1098 /******************************************************************************/
1099 /* x d i g */
1100 /******************************************************************************/
1101 
1102 /* Function: xdig
1103 
1104  Purpose: To parse the directive: diglib * <parms>
1105 
1106  * use builtin digfs library (only one supported now).
1107  parms parameters for digfs.
1108 
1109  Output: 0 upon success or !0 upon failure.
1110 */
1111 
1112 int XrdXrootdProtocol::xdig(XrdOucStream &Config)
1113 {
1114  char parms[4096], *val;
1115 
1116 // Get the path
1117 //
1118  if (!(val = Config.GetWord()))
1119  {eDest.Emsg("Config", "diglib not specified"); return 1;}
1120 
1121 // Make sure it refers to an internal one
1122 //
1123  if (strcmp(val, "*"))
1124  {eDest.Emsg("Config", "builtin diglib not specified"); return 1;}
1125 
1126 // Grab the parameters
1127 //
1128  if (!Config.GetRest(parms, sizeof(parms)))
1129  {eDest.Emsg("Config", "diglib parameters too long"); return 1;}
1130  if (digParm) free(digParm);
1131  digParm = strdup(parms);
1132 
1133 // All done
1134 //
1135  return 0;
1136 }
1137 
1138 /******************************************************************************/
1139 /* x e x p */
1140 /******************************************************************************/
1141 
1142 /* Function: xexp
1143 
1144  Purpose: To parse the directive: export <path> [lock|nolock] [mwfiles]
1145 
1146  <path> the path to be exported.
1147 
1148  Output: 0 upon success or !0 upon failure.
1149 */
1150 
1151 int XrdXrootdProtocol::xexp(XrdOucStream &Config)
1152 {
1153  char *val, pbuff[1024];
1154  int popt = 0;
1155 
1156 // Get the path
1157 //
1158  val = Config.GetWord();
1159  if (!val || !val[0])
1160  {eDest.Emsg("Config", "export path not specified"); return 1;}
1161  strlcpy(pbuff, val, sizeof(pbuff));
1162 
1163 // Get export lock option
1164 //
1165  while((val = Config.GetWord()))
1166  { if (!strcmp( "nolock", val)) popt |= XROOTDXP_NOLK;
1167  else if (!strcmp( "lock", val)) popt &= ~XROOTDXP_NOLK;
1168  else if (!strcmp("mwfiles", val)) popt |= XROOTDXP_NOMWCHK;
1169  else {Config.RetToken(); break;}
1170  }
1171 
1172 // Add path to configuration
1173 //
1174  return xexpdo(pbuff, popt);
1175 }
1176 
1177 /******************************************************************************/
1178 
1179 int XrdXrootdProtocol::xexpdo(char *path, int popt)
1180 {
1181  char *opaque;
1182  int xopt;
1183 
1184 // Check if we are exporting a generic name
1185 //
1186  if (*path == '*')
1187  {popt |= XROOTDXP_NOSLASH | XROOTDXP_NOCGI;
1188  if (*(path+1))
1189  {if (*(path+1) == '?') popt &= ~XROOTDXP_NOCGI;
1190  else {eDest.Emsg("Config","invalid export path -",path);return 1;}
1191  }
1192  XPList.Set(popt, path);
1193  return 0;
1194  }
1195 
1196 // Make sure path start with a slash
1197 //
1198  if (rpCheck(path, &opaque))
1199  {eDest.Emsg("Config", "non-absolute export path -", path); return 1;}
1200 
1201 // Record the path
1202 //
1203  if (!(xopt = Squash(path)) || xopt != (popt|XROOTDXP_OK))
1204  XPList.Insert(path, popt);
1205  return 0;
1206 }
1207 
1208 /******************************************************************************/
1209 /* x f s l */
1210 /******************************************************************************/
1211 
1212 /* Function: xfsl
1213 
1214  Purpose: To parse the directive: fslib [throttle | [-2] <fspath2>]
1215  {default | [-2] <fspath1>}
1216  | ++ <fspath2>
1217 
1218  -2 Uses version2 of the plugin initializer.
1219  This is ignored now because it's always done.
1220  ++ Pushes a wrapper onto the library stack.
1221  throttle load libXrdThrottle.so as the head interface.
1222  <fspath2> load the named library as the head interface.
1223  default load libXrdOfs.so ro libXrdPss.so as the tail
1224  interface. This is the default.
1225  <fspath1> load the named library as the tail interface.
1226 
1227  Output: 0 upon success or !0 upon failure.
1228 */
1229 
1230 int XrdXrootdProtocol::xfsl(XrdOucStream &Config)
1231 {
1232  char *val;
1233 
1234 // Get the path
1235 //
1236  if (!(val = Config.GetWord()))
1237  {eDest.Emsg("Config", "fslib not specified"); return 1;}
1238 
1239 // First check for a psuhdown
1240 //
1241  if (!strcmp("++", val))
1242  {if (!(val = Config.GetWord()))
1243  {eDest.Emsg("Config", "fslib wrapper not specified"); return 1;}
1244  if (strcmp("throttle", val)) FSLPath.push_back((std::string)val);
1245  else FSLPath.push_back("libXrdThrottle.so");
1246  return 0;
1247  }
1248 
1249 // Clear storage pointers
1250 //
1251  if (FSLib[0]) {free(FSLib[0]); FSLib[0] = 0;}
1252  if (FSLib[1]) {free(FSLib[1]); FSLib[1] = 0;}
1253 
1254 // Check if this is "thottle"
1255 //
1256  if (!strcmp("throttle", val))
1257  {FSLib[1] = strdup("libXrdThrottle.so");
1258  if (!(val = Config.GetWord()))
1259  {eDest.Emsg("Config","fslib throttle target library not specified");
1260  return 1;
1261  }
1262  return xfsL(Config, val, 0);
1263  }
1264 
1265 // Check for default or default library, the common case
1266 //
1267  if (xfsL(Config, val, 1)) return 1;
1268  if (!FSLib[1]) return 0;
1269 
1270 // If we dont have another token, then demote the previous library
1271 //
1272  if (!(val = Config.GetWord()))
1273  {FSLib[0] = FSLib[1]; FSLib[1] = 0;
1274  return 0;
1275  }
1276 
1277 // Check for default or default library, the common case
1278 //
1279  return xfsL(Config, val, 0);
1280 }
1281 
1282 /******************************************************************************/
1283 
1284 int XrdXrootdProtocol::xfsL(XrdOucStream &Config, char *val, int lix)
1285 {
1286  char *Slash;
1287 
1288 // Check if this is a version token
1289 //
1290  if (!strcmp(val, "-2"))
1291  {if (!(val = Config.GetWord()))
1292  {eDest.Emsg("Config", "fslib not specified"); return 1;}
1293  }
1294 
1295 // We will play fast and furious with the syntax as "default" should not be
1296 // prefixed with a version number but will let that pass.
1297 //
1298  if (!strcmp("default", val)) return 0;
1299 
1300 // If this is the "standard" name tell the user that we are ignoring this lib.
1301 // Otherwise, record the path and return.
1302 //
1303  if (!(Slash = rindex(val, '/'))) Slash = val;
1304  else Slash++;
1305  if (!strcmp(Slash, "libXrdOfs.so"))
1306  eDest.Say("Config warning: 'fslib libXrdOfs.so' is actually built-in.");
1307  else FSLib[lix] = strdup(val);
1308  return 0;
1309 }
1310 
1311 /******************************************************************************/
1312 /* x f s o */
1313 /******************************************************************************/
1314 
1315 /* Function: xfso
1316 
1317  Purpose: To parse the directive: fsoverload [options]
1318 
1319  options: [[no]bypass] [redirect <host>:<port>[%<prvhost>:<port>]]
1320  [stall <sec>]
1321 
1322  bypass If path is a forwarding path, redirect client to the
1323  location specified in the path to bypass this server.
1324  The default is nobypass.
1325  redirect Redirect the request to the specified destination.
1326  stall Stall the client <sec> seconds. The default is 33.
1327 */
1328 
1329 int XrdXrootdProtocol::xfso(XrdOucStream &Config)
1330 {
1331  static const int rHLen = 264;
1332  char rHost[2][rHLen], *hP[2] = {0,0}, *val;
1333  int rPort[2], bypass = -1, stall = -1;
1334 
1335 // Process all of the options
1336 //
1337  while((val = Config.GetWord()) && *val)
1338  { if (!strcmp(val, "bypass")) bypass = 1;
1339  else if (!strcmp(val, "nobypass")) bypass = 0;
1340  else if (!strcmp(val, "redirect"))
1341  {val = Config.GetWord();
1342  if (!xred_php(val, hP, rPort, "redirect")) return 1;
1343  for (int i = 0; i < 2; i++)
1344  {if (!hP[i]) rHost[i][0] = 0;
1345  else {strlcpy(rHost[i], hP[i], rHLen);
1346  hP[i] = rHost[i];
1347  }
1348  }
1349  }
1350  else if (!strcmp(val, "stall"))
1351  {if (!(val = Config.GetWord()) || !(*val))
1352  {eDest.Emsg("Config", "stall value not specified");
1353  return 1;
1354  }
1355  if (XrdOuca2x::a2tm(eDest,"stall",val,&stall,0,32767))
1356  return 1;
1357  }
1358  else {eDest.Emsg("config","invalid fsoverload option",val); return 1;}
1359  }
1360 
1361 // Set all specified values
1362 //
1363  if (bypass >= 0) OD_Bypass = (bypass ? true : false);
1364  if (stall >= 0) OD_Stall = stall;
1365  if (hP[0])
1366  {if (Route[RD_ovld].Host[0]) free(Route[RD_ovld].Host[0]);
1367  if (Route[RD_ovld].Host[1]) free(Route[RD_ovld].Host[1]);
1368  Route[RD_ovld].Host[0] = strdup(hP[0]);
1369  Route[RD_ovld].Port[0] = rPort[0];
1370  Route[RD_ovld].RDSz[0] = strlen(hP[0]);
1371  if (hP[1])
1372  {Route[RD_ovld].Host[1] = strdup(hP[1]);
1373  Route[RD_ovld].Port[1] = rPort[1];
1374  Route[RD_ovld].RDSz[1] = strlen(hP[1]);
1375  } else {
1376  Route[RD_ovld].Host[1] = Route[RD_ovld].Host[0];
1377  Route[RD_ovld].Port[1] = Route[RD_ovld].Port[0];
1378  Route[RD_ovld].RDSz[1] = Route[RD_ovld].RDSz[0];
1379  }
1380  OD_Redir = true;
1381  } else OD_Redir = false;
1382 
1383  return 0;
1384 }
1385 
1386 /******************************************************************************/
1387 /* x g p f */
1388 /******************************************************************************/
1389 
1390 /* Function: xgpf
1391 
1392  Purpose: To parse the directive: gpflib <path> <parms>
1393 
1394  <path> library path to use or default to use the builtin one.
1395  parms optional parameters.
1396 
1397  Output: 0 upon success or !0 upon failure.
1398 */
1399 
1400 int XrdXrootdProtocol::xgpf(XrdOucStream &Config)
1401 {
1402  char parms[4096], *val;
1403 
1404 // Remove any previous parameters
1405 //
1406  if (gpfLib) {free(gpfLib); gpfLib = 0;}
1407  if (gpfParm) {free(gpfParm); gpfParm = 0;}
1408 
1409 // Get the path
1410 //
1411  if (!(val = Config.GetWord()))
1412  {eDest.Emsg("Config", "gpflib not specified"); return 1;}
1413 
1414 // If this refers to out default, then keep the library pointer nil
1415 //
1416  if (strcmp(val, "default")) gpfLib = strdup(val);
1417 
1418 // Grab the parameters
1419 //
1420  if (!Config.GetRest(parms, sizeof(parms)))
1421  {eDest.Emsg("Config", "gpflib parameters too long"); return 1;}
1422  gpfParm = strdup(parms);
1423 
1424 // All done
1425 //
1426  return 0;
1427 }
1428 
1429 /******************************************************************************/
1430 /* x l o g */
1431 /******************************************************************************/
1432 
1433 /* Function: xlog
1434 
1435  Purpose: To parse the directive: log <events>
1436 
1437  <events> the blank separated list of events to log.
1438 
1439  Output: 0 upon success or 1 upon failure.
1440 */
1441 
1442 int XrdXrootdProtocol::xlog(XrdOucStream &Config)
1443 {
1444  char *val;
1445  static struct logopts {const char *opname; int opval;} lgopts[] =
1446  {
1447  {"all", -1},
1448  {"disc", SYS_LOG_02},
1449  {"login", SYS_LOG_01}
1450  };
1451  int i, neg, lgval = -1, numopts = sizeof(lgopts)/sizeof(struct logopts);
1452 
1453  if (!(val = Config.GetWord()))
1454  {eDest.Emsg("config", "log option not specified"); return 1;}
1455  while (val)
1456  {if ((neg = (val[0] == '-' && val[1]))) val++;
1457  for (i = 0; i < numopts; i++)
1458  {if (!strcmp(val, lgopts[i].opname))
1459  {if (neg) lgval &= ~lgopts[i].opval;
1460  else lgval |= lgopts[i].opval;
1461  break;
1462  }
1463  }
1464  if (i >= numopts) eDest.Emsg("config","invalid log option",val);
1465  val = Config.GetWord();
1466  }
1467  eDest.setMsgMask(lgval);
1468  return 0;
1469 }
1470 
1471 /******************************************************************************/
1472 /* x p r e p */
1473 /******************************************************************************/
1474 
1475 /* Function: xprep
1476 
1477  Purpose: To parse the directive: prep [keep <sec>] [scrub <sec>]
1478  [logdir <path>]
1479  keep <sec> time (seconds, M, H) to keep logdir entries.
1480  scrub <sec> time (seconds, M, H) between logdir scrubs.
1481  logdir <path> the absolute path to the prepare log directory.
1482 
1483  Output: 0 upon success or !0 upon failure. Ignored by master.
1484 */
1485 int XrdXrootdProtocol::xprep(XrdOucStream &Config)
1486 { int rc, keep = 0, scrub=0;
1487  char *ldir=0,*val,buff[1024];
1488 
1489  if (!(val = Config.GetWord()))
1490  {eDest.Emsg("Config", "prep options not specified"); return 1;}
1491 
1492  do { if (!strcmp("keep", val))
1493  {if (!(val = Config.GetWord()))
1494  {eDest.Emsg("Config", "prep keep value not specified");
1495  return 1;
1496  }
1497  if (XrdOuca2x::a2tm(eDest,"prep keep int",val,&keep,1)) return 1;
1498  }
1499  else if (!strcmp("scrub", val))
1500  {if (!(val = Config.GetWord()))
1501  {eDest.Emsg("Config", "prep scrub value not specified");
1502  return 1;
1503  }
1504  if (XrdOuca2x::a2tm(eDest,"prep scrub",val,&scrub,0)) return 1;
1505  }
1506  else if (!strcmp("logdir", val))
1507  {if (!(ldir = Config.GetWord()))
1508  {eDest.Emsg("Config", "prep logdir value not specified");
1509  return 1;
1510  }
1511  }
1512  else eDest.Emsg("Config", "Warning, invalid prep option", val);
1513  } while((val = Config.GetWord()));
1514 
1515 // Set the values
1516 //
1517  if (scrub || keep) XrdXrootdPrepare::setParms(scrub, keep);
1518  if (ldir)
1519  if ((rc = XrdOucUtils::genPath(buff, sizeof(buff), ldir, myInst)) < 0
1520  || (rc = XrdOucUtils::makePath(buff, XrdOucUtils::pathMode)) < 0
1521  || (rc = XrdXrootdPrepare::setParms(buff)) < 0)
1522  {eDest.Emsg("Config", rc, "process logdir", ldir);
1523  return 1;
1524  }
1525  return 0;
1526 }
1527 
1528 /******************************************************************************/
1529 /* x r e d */
1530 /******************************************************************************/
1531 
1532 /* Function: xred
1533 
1534  Purpose: To parse the directive: redirect <host>:<port>[%<prvhost>:<port>]
1535  {<funcs>|[?]<path>} |
1536  client <domlist>
1537 
1538  <funcs> are one or more of the following functions that will
1539  be immediately redirected to <host>:<port>. Each function
1540  may be prefixed by a minus sign to disable redirection.
1541 
1542  chmod dirlist locate mkdir mv prepare rm rmdir stat
1543 
1544  <paths> redirects the client when an attempt is made to open
1545  one of absolute <paths>. Up to 4 different redirect
1546  combinations may be specified. When prefixed by "?"
1547  then the redirect applies to any operation on the path
1548  that results in an ENOENT error.
1549 
1550  <domlist> {private | local | .<domain>} [<domlist>]
1551 
1552  Output: 0 upon success or !0 upon failure.
1553 */
1554 
1555 int XrdXrootdProtocol::xred(XrdOucStream &Config)
1556 {
1557  static struct rediropts {const char *opname; RD_func opval;} rdopts[] =
1558  {
1559  {"chmod", RD_chmod},
1560  {"chksum", RD_chksum},
1561  {"dirlist", RD_dirlist},
1562  {"locate", RD_locate},
1563  {"mkdir", RD_mkdir},
1564  {"mv", RD_mv},
1565  {"prepare", RD_prepare},
1566  {"prepstage",RD_prepstg},
1567  {"rm", RD_rm},
1568  {"rmdir", RD_rmdir},
1569  {"stat", RD_stat},
1570  {"trunc", RD_trunc}
1571  };
1572  static const int rHLen = 264;
1573  char rHost[2][rHLen], *hP[2], *val;
1574  int i, k, neg, numopts = sizeof(rdopts)/sizeof(struct rediropts);
1575  int rPort[2], isQ = 0;
1576 
1577 // Get the host and port
1578 //
1579  val = Config.GetWord();
1580  if (!xred_php(val, hP, rPort, "redirect")) return 1;
1581 
1582 // Copy out he values as the target variable will be lost
1583 //
1584  for (i = 0; i < 2; i++)
1585  {if (!hP[i]) rHost[i][0] = 0;
1586  else {strlcpy(rHost[i], hP[i], rHLen);
1587  hP[i] = rHost[i];
1588  }
1589  }
1590 
1591 // Set all redirect target functions
1592 //
1593  if (!(val = Config.GetWord()))
1594  {eDest.Emsg("config", "redirect option not specified"); return 1;}
1595 
1596 // Handle the client option
1597 //
1598  if (!strcmp("client", val)) return xred_clnt(Config, hP, rPort);
1599 
1600  if (*val == '/' || (isQ = ((*val == '?') || !strcmp(val,"enoent"))))
1601  {if (isQ)
1602  {RQLxist = 1;
1603  if (!(val = Config.GetWord()))
1604  {eDest.Emsg("Config", "redirect path not specified.");
1605  return 1;
1606  }
1607  if (*val != '/')
1608  {eDest.Emsg("Config", "non-absolute redirect path -", val);
1609  return 1;
1610  }
1611  }
1612  for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
1613  if (xred_xok(k, hP, rPort)) break;
1614  if (k >= RD_Num)
1615  {eDest.Emsg("Config", "too many different path redirects"); return 1;}
1616  xred_set(RD_func(k), hP, rPort);
1617  do {if (isQ) RQList.Insert(val, k, 0);
1618  else RPList.Insert(val, k, 0);
1619  if ((val = Config.GetWord()) && *val != '/')
1620  {eDest.Emsg("Config", "non-absolute redirect path -", val);
1621  return 1;
1622  }
1623  } while(val);
1624  return 0;
1625  }
1626 
1627  while (val)
1628  {if (!strcmp(val, "all"))
1629  {for (i = 0; i < numopts; i++)
1630  xred_set(rdopts[i].opval, hP, rPort);
1631  }
1632  else {if ((neg = (val[0] == '-' && val[1]))) val++;
1633  for (i = 0; i < numopts; i++)
1634  {if (!strcmp(val, rdopts[i].opname))
1635  {if (neg) xred_set(rdopts[i].opval, 0, 0);
1636  else xred_set(rdopts[i].opval, hP, rPort);
1637  break;
1638  }
1639  }
1640  if (i >= numopts)
1641  eDest.Emsg("config", "invalid redirect option", val);
1642  }
1643  val = Config.GetWord();
1644  }
1645  return 0;
1646 }
1647 
1648 /******************************************************************************/
1649 
1650 int XrdXrootdProtocol::xred_clnt(XrdOucStream &Config,char *hP[2],int rPort[2])
1651 {
1652  static const int maxDom = sizeof(RouteClient.Domain)/sizeof(char*);
1653  char *val;
1654 
1655 // Reset values
1656 //
1657  if (CL_Redir)
1658  {for (int i = 0; i < RouteClient.DomCnt; i++)
1659  {if (RouteClient.Domain[i]) free(RouteClient.Domain[i]);}
1660  }
1661  for (int i = 0; i < maxDom; i++) RouteClient.Domain[i] = 0;
1662  RouteClient.DomCnt = 0;
1663  RouteClient.pvtIP = false;
1664  RouteClient.lclDom = false;
1665  CL_Redir = true;
1666 
1667 // Process arguments
1668 //
1669  if (!(val = Config.GetWord()))
1670  {eDest.Emsg("Config", "redirect client argument not specified.");
1671  return 1;
1672  }
1673 
1674  while(val)
1675  { if (!strcmp("private", val)) RouteClient.pvtIP = true;
1676  else if (!strcmp("local", val)) RouteClient.lclDom = true;
1677  else if (*val == '.')
1678  {if (RouteClient.DomCnt >= maxDom)
1679  {eDest.Emsg("Config",
1680  "Too many redirect client domains specified.");
1681  return 1;
1682  }
1683  RouteClient.Domain[RouteClient.DomCnt++] = strdup(val);
1684  }
1685  else {eDest.Emsg("Config", "Invalid redirect client domain -", val);
1686  return 1;
1687  }
1688  val = Config.GetWord();
1689  }
1690 
1691 // Set the host parameters
1692 //
1693  xred_set(RD_client, hP, rPort);
1694  return 0;
1695 }
1696 
1697 /******************************************************************************/
1698 
1699 bool XrdXrootdProtocol::xred_php(char *val, char *hP[2], int rPort[2],
1700  const char *what, bool optport)
1701 {
1702  XrdNetAddr testAddr;
1703  char *pp;
1704 
1705 // Make sure we have a value
1706 //
1707  if (!val || !(*val))
1708  {eDest.Emsg("config", what, "argument not specified"); return false;}
1709 
1710 // Check if we have two hosts here
1711 //
1712  hP[0] = val;
1713  if (!(pp = index(val, '%'))) hP[1] = 0;
1714  else {hP[1] = pp+1; *pp = 0;}
1715 
1716 // Verify corectness here
1717 //
1718  if (!(*val) || (hP[1] && !*hP[1]))
1719  {eDest.Emsg("Config", "malformed", what, "host specification");
1720  return false;
1721  }
1722 
1723 // Process the hosts
1724 //
1725  for (int i = 0; i < 2; i++)
1726  {if (!(val = hP[i])) break;
1727  if (!val || !val[0] || val[0] == ':')
1728  {eDest.Emsg("Config", what, "host not specified"); return false;}
1729  if ((pp = rindex(val, ':')))
1730  {if ((rPort[i] = XrdOuca2x::a2p(eDest, "tcp", pp+1, false)) <= 0)
1731  return false;
1732  *pp = '\0';
1733  } else {
1734  if (optport) rPort[i] = 0;
1735  else {eDest.Emsg("Config", what, "port not specified");
1736  return false;
1737  }
1738  }
1739  const char *eText = testAddr.Set(val, 0);
1740  if (eText)
1741  {if (XrdNetAddrInfo::isHostName(val) && !strncmp(eText,"Dynamic",7))
1742  eDest.Say("Config warning: ", eText, " as ", val);
1743  else {eDest.Say("Config failure: ", what, " target ", val,
1744  " is invalid; ", eText);
1745  return false;
1746  }
1747  }
1748  }
1749 
1750 // All done
1751 //
1752  return true;
1753 }
1754 
1755 void XrdXrootdProtocol::xred_set(RD_func func, char *rHost[2], int rPort[2])
1756 {
1757 
1758 // Reset static redirection
1759 //
1760  if (Route[func].Host[0]) free(Route[func].Host[0]);
1761  if (Route[func].Host[0] != Route[func].Host[1]) free(Route[func].Host[1]);
1762 
1763  if (rHost)
1764  {Route[func].Host[0] = strdup(rHost[0]);
1765  Route[func].Port[0] = rPort[0];
1766  } else {
1767  Route[func].Host[0] = Route[func].Host[1] = 0;
1768  Route[func].Port[0] = Route[func].Port[1] = 0;
1769  return;
1770  }
1771 
1772  if (!rHost[1])
1773  {Route[func].Host[1] = Route[func].Host[0];
1774  Route[func].Port[1] = Route[func].Port[0];
1775  } else {
1776  Route[func].Host[1] = strdup(rHost[1]);
1777  Route[func].Port[1] = rPort[1];
1778  }
1779 }
1780 
1781 bool XrdXrootdProtocol::xred_xok(int func, char *rHost[2], int rPort[2])
1782 {
1783  if (!Route[func].Host[0]) return true;
1784 
1785  if (strcmp(Route[func].Host[0], rHost[0])
1786  || Route[func].Port[0] != rPort[0]) return false;
1787 
1788  if (!rHost[1]) return Route[func].Host[0] == Route[func].Host[1];
1789 
1790  if (strcmp(Route[func].Host[1], rHost[1])
1791  || Route[func].Port[1] != rPort[1]) return false;
1792 
1793  return true;
1794 }
1795 
1796 /******************************************************************************/
1797 /* x s e c l */
1798 /******************************************************************************/
1799 
1800 /* Function: xsecl
1801 
1802  Purpose: To parse the directive: seclib {default | <path>}
1803 
1804  <path> the path of the security library to be used.
1805  "default" uses the default security library.
1806 
1807  Output: 0 upon success or !0 upon failure.
1808 */
1809 
1810 int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
1811 {
1812  char *val;
1813 
1814 // Get the path
1815 //
1816  val = Config.GetWord();
1817  if (!val || !val[0])
1818  {eDest.Emsg("Config", "seclib argument not specified"); return 1;}
1819 
1820 // Record the path
1821 //
1822  if (SecLib) free(SecLib);
1823  SecLib = strdup(val);
1824  return 0;
1825 }
1826 
1827 /******************************************************************************/
1828 /* x t l s */
1829 /******************************************************************************/
1830 
1831 /* Function: xtls
1832 
1833 topPurpose: To parse the directive: tls [capable] <reqs>
1834 
1835  capable Enforce TLS requirements only for TLS capable clients.
1836  Otherwise, TLS is enforced for all clients.
1837  <reqs> are one or more of the following tls requirements. Each
1838  may be prefixed by a minus sign to disable it. Note
1839  this directive is cummalitive.
1840 
1841  all Requires all of the below.
1842  data All bound sockets must use TLS. When specified,
1843  session is implied unless login is specified.
1844  gpfile getile and putfile requests must use TLS
1845  login Logins and all subsequent requests must use TLS
1846  none Turns all requirements off (default).
1847  off Synonym for none.
1848  session All requests after login must use TLS
1849  tpc Third party copy requests must use TLS
1850 
1851  Output: 0 upon success or !0 upon failure.
1852 */
1853 
1854 int XrdXrootdProtocol::xtls(XrdOucStream &Config)
1855 {
1856  static const int Req_TLSAll = Req_TLSData|Req_TLSLogin|Req_TLSTPC;
1857  static struct enforceopts {const char *opname; int opval; int enval;}
1858  enfopts[] =
1859  {
1860  {"all", kXR_tlsAny, Req_TLSAll},
1861  {"data", kXR_tlsData, Req_TLSData},
1862  {"gpfile", kXR_tlsGPF, Req_TLSGPFile},
1863  {"login", kXR_tlsLogin, Req_TLSLogin},
1864  {"session", kXR_tlsSess, Req_TLSSess},
1865  {"tpc", kXR_tlsTPC, Req_TLSTPC}
1866  };
1867  char *val;
1868  int i, numopts = sizeof(enfopts)/sizeof(struct enforceopts);
1869  bool neg, forall = true;
1870 
1871  if (!(val = Config.GetWord()))
1872  {eDest.Emsg("config", "tls parameter not specified"); return 1;}
1873 
1874  if (!strcmp("capable", val))
1875  {forall = false;
1876  if (!(val = Config.GetWord()))
1877  {eDest.Emsg("config", "tls requirement not specified"); return 1;}
1878  }
1879 
1880  while (val)
1881  {if (!strcmp(val, "off") || !strcmp(val, "none"))
1882  {myRole &= ~kXR_tlsAny;
1883  if (forall) tlsCap = tlsNot = 0;
1884  else tlsCap = 0;
1885  } else {
1886  if ((neg = (val[0] == '-' && val[1]))) val++;
1887  for (i = 0; i < numopts; i++)
1888  {if (!strcmp(val, enfopts[i].opname))
1889  {if (neg) myRole &= ~enfopts[i].opval;
1890  else myRole |= enfopts[i].opval;
1891  if (neg) tlsCap &= ~enfopts[i].enval;
1892  else tlsCap |= enfopts[i].enval;
1893  if (forall)
1894  {if (neg) tlsNot &= ~enfopts[i].enval;
1895  else tlsNot |= enfopts[i].enval;
1896  }
1897  break;
1898  }
1899  }
1900  if (i >= numopts)
1901  {eDest.Emsg("config", "Invalid tls requirement -", val);
1902  return 1;
1903  }
1904  }
1905  val = Config.GetWord();
1906  }
1907 
1908 // If data needs TLS but the session does not, then force session TLS
1909 //
1910  if ((myRole & kXR_tlsData) && !(myRole & (kXR_tlsLogin | kXR_tlsSess)))
1911  myRole |= kXR_tlsSess;
1912  if ((tlsCap & kXR_tlsData) && !(tlsCap & (Req_TLSLogin | Req_TLSSess)))
1913  tlsCap |= Req_TLSSess;
1914  if ((tlsNot & kXR_tlsData) && !(tlsNot & (Req_TLSLogin | Req_TLSSess)))
1915  tlsNot |= Req_TLSSess;
1916 
1917 // Do final resolution on the settins
1918 //
1919  return (CheckTLS(0) ? 0 : 1);
1920 }
1921 
1922 /******************************************************************************/
1923 /* x t l s r */
1924 /******************************************************************************/
1925 
1926 /* Function: xtlsr
1927 
1928  Purpose: To parse the directive: tlsreuse off | on [flush <ft>[h|m|s]]
1929 
1930  off turns off the TLS session reuse cache.
1931  on turns on the TLS session reuse cache.
1932  <ft> sets the cache flush frequency. the default is set
1933  by the TLS libraries and is typically connection count.
1934 
1935  Output: 0 upon success or !0 upon failure.
1936 */
1937 
1938 int XrdXrootdProtocol::xtlsr(XrdOucStream &Config)
1939 {
1940  char *val;
1941  int num;
1942 
1943 // Get the argument
1944 //
1945  val = Config.GetWord();
1946  if (!val || !val[0])
1947  {eDest.Emsg("Config", "tlsreuse argument not specified"); return 1;}
1948 
1949 // If it's off, we set it off
1950 //
1951  if (!strcmp(val, "off"))
1953  return 0;
1954  }
1955 
1956 // If it's on we may need more to do
1957 //
1958  if (!strcmp(val, "on"))
1959  {if (!tlsCtx) {eDest.Emsg("Config warning:", "Ignoring "
1960  "'tlsreuse on'; TLS not configured!");
1961  return 0;
1962  }
1964  if (!(val = Config.GetWord())) return 0;
1965  if (!strcmp(val, "flush" ))
1966  {if (!(val = Config.GetWord()))
1967  {eDest.Emsg("Config", "tlsreuse flush value not specified");
1968  return 1;
1969  }
1970  if (XrdOuca2x::a2tm(eDest,"tlsreuse flush",val,&num,1)) return 1;
1971  if (num < 60) num = 60;
1972  else if (num > XrdTlsContext::scFMax)
1973  num = XrdTlsContext::scFMax;
1974  tlsCache |= num;
1975  }
1976  }
1977 
1978 // We have a bad keyword
1979 //
1980  eDest.Emsg("config", "Invalid tlsreuse option -", val);
1981  return 1;
1982 }
1983 
1984 /******************************************************************************/
1985 /* x t r a c e */
1986 /******************************************************************************/
1987 
1988 /* Function: xtrace
1989 
1990  Purpose: To parse the directive: trace <events>
1991 
1992  <events> the blank separated list of events to trace. Trace
1993  directives are cummalative.
1994 
1995  Output: 0 upon success or 1 upon failure.
1996 */
1997 
1998 int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
1999 {
2000  char *val;
2001  static struct traceopts {const char *opname; int opval;} tropts[] =
2002  {
2003  {"all", TRACE_ALL},
2004  {"auth", TRACE_AUTH},
2005  {"debug", TRACE_DEBUG},
2006  {"emsg", TRACE_EMSG},
2007  {"fs", TRACE_FS},
2008  {"fsaio", TRACE_FSAIO},
2009  {"fsio", TRACE_FSIO},
2010  {"login", TRACE_LOGIN},
2011  {"mem", TRACE_MEM},
2012  {"pgcserr", TRACE_PGCS},
2013  {"redirect", TRACE_REDIR},
2014  {"request", TRACE_REQ},
2015  {"response", TRACE_RSP},
2016  {"stall", TRACE_STALL}
2017  };
2018  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2019 
2020  if (!(val = Config.GetWord()))
2021  {eDest.Emsg("config", "trace option not specified"); return 1;}
2022  while (val)
2023  {if (!strcmp(val, "off")) trval = 0;
2024  else {if ((neg = (val[0] == '-' && val[1]))) val++;
2025  for (i = 0; i < numopts; i++)
2026  {if (!strcmp(val, tropts[i].opname))
2027  {if (neg) trval &= ~tropts[i].opval;
2028  else trval |= tropts[i].opval;
2029  break;
2030  }
2031  }
2032  if (i >= numopts)
2033  eDest.Emsg("config", "invalid trace option", val);
2034  }
2035  val = Config.GetWord();
2036  }
2037  XrdXrootdTrace.What = trval;
2038  return 0;
2039 }
2040 
2041 /******************************************************************************/
2042 /* x l i m i t */
2043 /******************************************************************************/
2044 
2045 /* Function: xlimit
2046 
2047  Purpose: To parse the directive: limit [prepare <count>] [noerror]
2048 
2049  prepare <count> The maximum number of prepares that are allowed
2050  during the course of a single connection
2051 
2052  noerror When possible, do not issue an error when a limit
2053  is hit.
2054 
2055  Output: 0 upon success or 1 upon failure.
2056 */
2057 int XrdXrootdProtocol::xlimit(XrdOucStream &Config)
2058 {
2059  int plimit = -1;
2060  const char *word;
2061 
2062 // Look for various limits set
2063 //
2064  while ( (word = Config.GetWord()) ) {
2065  if (!strcmp(word, "prepare")) {
2066  if (!(word = Config.GetWord()))
2067  {
2068  eDest.Emsg("Config", "'limit prepare' value not specified");
2069  return 1;
2070  }
2071  if (XrdOuca2x::a2i(eDest, "limit prepare", word, &plimit, 0)) { return 1; }
2072  } else if (!strcmp(word, "noerror")) {
2073  LimitError = false;
2074  }
2075  }
2076  if (plimit >= 0) {PrepareLimit = plimit;}
2077  return 0;
2078 }
#define kXR_isManager
Definition: XProtocol.hh:1154
#define kXR_tlsLogin
Definition: XProtocol.hh:1181
#define kXR_suppgrw
Definition: XProtocol.hh:1171
#define kXR_attrMeta
Definition: XProtocol.hh:1156
#define kXR_haveTLS
Definition: XProtocol.hh:1176
#define kXR_anongpf
Definition: XProtocol.hh:1169
#define kXR_tlsAny
Definition: XProtocol.hh:1178
#define kXR_tlsTPC
Definition: XProtocol.hh:1183
#define kXR_isServer
Definition: XProtocol.hh:1155
#define kXR_attrProxy
Definition: XProtocol.hh:1157
#define kXR_LBalServer
Definition: XProtocol.hh:1149
#define kXR_tlsGPF
Definition: XProtocol.hh:1180
#define kXR_supposc
Definition: XProtocol.hh:1172
#define kXR_tlsSess
Definition: XProtocol.hh:1182
#define kXR_DataServer
Definition: XProtocol.hh:1148
#define kXR_supgpf
Definition: XProtocol.hh:1170
#define kXR_tlsData
Definition: XProtocol.hh:1179
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:208
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:235
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:170
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:298
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:48
static char * genPath(const char *path, const char *inst, const char *psfx=0)
Definition: XrdOucUtils.cc:414
static int GidName(gid_t gID, char *gName, int gNsz, time_t keepT=0)
Definition: XrdOucUtils.cc:544
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:914
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:1118
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