XRootD
XrdOfsConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O f s C o n f i g . c c */
4 /* */
5 /* (C) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <unistd.h>
32 #include <cctype>
33 #include <cerrno>
34 #include <fcntl.h>
35 #include <netdb.h>
36 #include <cstdlib>
37 #include <string>
38 #include <strings.h>
39 #include <cstdio>
40 #include <netinet/in.h>
41 #include <vector>
42 #include <sys/param.h>
43 #include <sys/stat.h>
44 
45 #include "XrdVersion.hh"
46 #include "XProtocol/XProtocol.hh"
47 
48 #include "XrdCks/XrdCks.hh"
49 
50 #include "XrdNet/XrdNetUtils.hh"
51 
52 #include "XrdSfs/XrdSfsFlags.hh"
53 
54 #include "XrdOfs/XrdOfs.hh"
55 #include "XrdOfs/XrdOfsCksFile.hh"
56 #include "XrdOfs/XrdOfsConfigCP.hh"
57 #include "XrdOfs/XrdOfsConfigPI.hh"
58 #include "XrdOfs/XrdOfsEvs.hh"
59 #include "XrdOfs/XrdOfsFSctl_PI.hh"
60 #include "XrdOfs/XrdOfsPoscq.hh"
61 #include "XrdOfs/XrdOfsStats.hh"
62 #include "XrdOfs/XrdOfsTPC.hh"
64 #include "XrdOfs/XrdOfsTrace.hh"
65 
66 #include "XrdOss/XrdOss.hh"
67 
68 #include "XrdOuc/XrdOuca2x.hh"
69 #include "XrdOuc/XrdOucEnv.hh"
70 #include "XrdOuc/XrdOucNSWalk.hh"
71 #include "XrdOuc/XrdOucStream.hh"
72 #include "XrdOuc/XrdOucTUtils.hh"
73 #include "XrdOuc/XrdOucUtils.hh"
74 
75 #include "XrdSys/XrdSysError.hh"
76 #include "XrdSys/XrdSysHeaders.hh"
77 
78 #include "XrdNet/XrdNetAddr.hh"
79 
80 #include "XrdCms/XrdCmsClient.hh"
81 #include "XrdCms/XrdCmsFinder.hh"
82 #include "XrdCms/XrdCmsRole.hh"
83 
85 
86 /******************************************************************************/
87 /* G l o b a l O b j e c t s */
88 /******************************************************************************/
89 
90 extern XrdOfsStats OfsStats;
91 
92 extern XrdSysTrace OfsTrace;
93 
94 extern XrdOfs* XrdOfsFS;
95 
96 class XrdOss;
97 extern XrdOss *XrdOfsOss;
98 
99 class XrdScheduler;
101 
103 
104 namespace XrdOfsTPCParms
105 {
106 extern XrdOfsTPCConfig Cfg;
107 }
108 
109 namespace
110 {
111 int SetMode(const char *path, mode_t mode) {return chmod(path, mode);}
112 
113 std::vector<std::string> csList; // Configured checksums
114 }
115 
116 /******************************************************************************/
117 /* d e f i n e s */
118 /******************************************************************************/
119 
120 #define TS_Xeq(x,m) if (!strcmp(x,var)) return m(Config,Eroute);
121 
122 #define TS_XPI(x,m) if (!strcmp(x,var))\
123  return !ofsConfig->Parse(XrdOfsConfigPI:: m);
124 
125 #define TS_Str(x,m) if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
126 
127 #define TS_PList(x,m) if (!strcmp(x,var)) \
128  {m.Insert(new XrdOucPList(val,1)); return 0;}
129 
130 #define TS_Chr(x,m) if (!strcmp(x,var)) {m = val[0]; return 0;}
131 
132 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; Config.Echo(); return 0;}
133 
134 #define Max(x,y) (x > y ? x : y)
135 
136 /******************************************************************************/
137 /* g e t V e r s i o n */
138 /******************************************************************************/
139 
140 const char *XrdOfs::getVersion() {return XrdVERSION;}
141 
142 /******************************************************************************/
143 /* C o n f i g u r e */
144 /******************************************************************************/
145 
146 int XrdOfs::Configure(XrdSysError &Eroute) {return Configure(Eroute, 0);}
147 
148 int XrdOfs::Configure(XrdSysError &Eroute, XrdOucEnv *EnvInfo) {
149 /*
150  Function: Establish default values using a configuration file.
151 
152  Input: None.
153 
154  Output: 0 upon success or !0 otherwise.
155 */
156  char *var;
157  const char *tmp;
158  int cfgFD, retc, NoGo = 0;
159  XrdOucEnv myEnv;
160  XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
161 
162 // Print warm-up message
163 //
164  Eroute.Say("++++++ File system initialization started.");
165 
166 // Start off with no POSC log. Note that XrdSfsGetDefaultFileSystem nakes sure
167 // that we are configured only once.
168 //
169  poscLog = NULL;
170 
171 // Establish the network interface that the caller must provide
172 //
173  if (!EnvInfo || !(myIF = (XrdNetIF *)EnvInfo->GetPtr("XrdNetIF*")))
174  {Eroute.Emsg("Finder", "Network i/f undefined; unable to self-locate.");
175  NoGo = 1;
176  }
177  ofsSchedP = (XrdScheduler *)EnvInfo->GetPtr("XrdScheduler*");
178 
179 // Preset all variables with common defaults
180 //
181  Options = 0;
182  if (getenv("XRDDEBUG")) OfsTrace.What = TRACE_MOST | TRACE_debug;
183 
184 // Allocate a our plugin configurator
185 //
186  ofsConfig = XrdOfsConfigPI::New(ConfigFN, &Config, &Eroute, 0, this);
187 
188 // If there is no config file, return with the defaults sets.
189 //
190  if( !ConfigFN || !*ConfigFN)
191  Eroute.Emsg("Config", "Configuration file not specified.");
192  else {
193  // Try to open the configuration file.
194  //
195  if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
196  return Eroute.Emsg("Config", errno, "open config file",
197  ConfigFN);
198  Config.Attach(cfgFD);
199  static const char *cvec[] = {"*** ofs plugin config:",0};
200  Config.Capture(cvec);
201 
202  // Now start reading records until eof.
203  //
204  while((var = Config.GetMyFirstWord()))
205  {if (!strncmp(var, "ofs.", 4)
206  || !strcmp(var, "all.role")
207  || !strcmp(var, "all.subcluster"))
208  {if (ConfigXeq(var+4,Config,Eroute)) {Config.Echo();NoGo=1;}}
209  else if (!strcmp(var, "oss.defaults")
210  || !strcmp(var, "all.export"))
211  {xexp(Config, Eroute, *var == 'a');
212  Config.noEcho();
213  }
214  }
215 
216  // Now check if any errors occurred during file i/o
217  //
218  if ((retc = Config.LastError()))
219  NoGo = Eroute.Emsg("Config", -retc, "read config file",
220  ConfigFN);
221  Config.Close();
222  }
223 
224 // If no exports were specified, the default is that we are writable
225 //
226  if (ossRW == ' ') ossRW = 'w';
227 
228 // Adjust the umask to correspond to the maximum mode allowed
229 //
230  mode_t uMask = 0777 & (~(dMask[1] | fMask[1]));
231  umask(uMask);
232 
233 // Export our role if we actually have one
234 //
235  if (myRole) XrdOucEnv::Export("XRDROLE", myRole);
236 
237 // Set the redirect option for other layers
238 //
239  if (Options & isManager)
240  XrdOucEnv::Export("XRDREDIRECT", (Options & isMeta ? "M" : "R"));
241  else XrdOucEnv::Export("XRDREDIRECT", "0");
242 
243 // If we are a proxy, then figure out where the prosy storge system resides
244 //
245  if ((Options & isProxy) && !(Options & isManager))
246  {char buff[2048], *bp, *libofs = getenv("XRDOFSLIB");
247  if (!libofs) bp = buff;
248  else {strcpy(buff, libofs); bp = buff+strlen(buff)-1;
249  while(bp != buff && *(bp-1) != '/') bp--;
250  }
251  strcpy(bp, "libXrdPss.so");
252  ofsConfig->Default(XrdOfsConfigPI::theOssLib, buff, 0);
253  ofsConfig->Default(XrdOfsConfigPI::theCksLib, buff, 0);
254  }
255 
256 // Configure third party copy but only if we are not a manager. Phase 1 needs
257 // to be done before we load the plugins as they may need this info.
258 //
259  if ((Options & ThirdPC) && !(Options & isManager))
260  NoGo |= ConfigTPC(Eroute, EnvInfo);
261 
262 // We need to do pre-initialization for event recording as the oss needs some
263 // environmental information from that initialization to initialize the frm,
264 // should it need to be used. We will do full evr initialization after the oss
265 // and the finder are initialized. A bit messy in the current plug-in world.
266 //
267  if (!(Options & isManager) && !evrObject.Init(&Eroute)) NoGo = 1;
268 
269 // Determine whether we should load authorization
270 //
271  int piOpts = XrdOfsConfigPI::allXXXLib;
272  if (!(Options & Authorize)) piOpts &= ~XrdOfsConfigPI::theAutLib;
273 
274 // We need to export plugins to other protocols which means we need to
275 // record them in the outmost environment. So get it.
276 //
277  XrdOucEnv *xrdEnv = 0;
278  if (EnvInfo) xrdEnv = (XrdOucEnv*)EnvInfo->GetPtr("xrdEnv*");
279 
280 // Now load all of the required plugins
281 //
282  if (!ofsConfig->Load(piOpts, EnvInfo)) NoGo = 1;
283  else {ofsConfig->Plugin(XrdOfsOss);
284  ossFeatures = XrdOfsOss->Features();
285  if (ossFeatures & XRDOSS_HASNOSF) FeatureSet |= XrdSfs::hasNOSF;
286  if (ossFeatures & XRDOSS_HASCACH)
288  if (xrdEnv) xrdEnv->Put("XrdCache", "T"); // Existence check
289  }
290  if (ossFeatures & XRDOSS_HASNAIO) FeatureSet |= XrdSfs::hasNAIO;
291  if (ossFeatures & XRDOSS_HASFICL) FeatureSet |= XrdSfs::hasFICL;
292  if (ossFeatures & XRDOSS_HASXERT) tryXERT = true;
293  if (xrdEnv) xrdEnv->PutPtr("XrdOss*", XrdOfsOss);
294  ofsConfig->Plugin(Cks);
295  CksPfn = !ofsConfig->OssCks();
296  CksRdr = !ofsConfig->LclCks();
297  if (ofsConfig->Plugin(prepHandler))
298  {prepAuth = ofsConfig->PrepAuth();
300  }
301  if (Options & Authorize)
302  {ofsConfig->Plugin(Authorization);
303  XrdOfsTPC::Init(Authorization);
304  if (xrdEnv) xrdEnv->PutPtr("XrdAccAuthorize*",Authorization);
306  }
307  }
308 
309 // If a cache has been configured then that cache may want to interact with
310 // the cache-specific FSctl() operation. We check if a plugin was provided.
311 //
312  if (ossFeatures & XRDOSS_HASCACH)
313  FSctl_PC = (XrdOfsFSctl_PI*)EnvInfo->GetPtr("XrdFSCtl_PC*");
314 
315 // Configure third party copy phase 2, but only if we are not a manager.
316 //
317  if ((Options & ThirdPC) && !(Options & isManager)) NoGo |= ConfigTPC(Eroute);
318 
319 // Extract out the export list should it have been supplied by the oss plugin
320 //
321  ossRPList = (XrdOucPListAnchor *)EnvInfo->GetPtr("XrdOssRPList*");
322 
323 // Initialize redirection. We type te herald here to minimize confusion
324 //
325  if (Options & haveRole)
326  {Eroute.Say("++++++ Configuring ", myRole, " role. . .");
327  if (ConfigRedir(Eroute, EnvInfo))
328  {Eroute.Emsg("Config", "Unable to create cluster management client.");
329  NoGo = 1;
330  }
331  }
332 
333 // Initialize the FSctl plugin if we have one. Note that we needed to defer
334 // until now because we needed to configure the cms plugin first (see above).
335 //
336  if (ofsConfig->Plugin(FSctl_PI) && !ofsConfig->ConfigCtl(Finder, EnvInfo))
337  {Eroute.Emsg("Config", "Unable to configure FSctl plugin.");
338  NoGo = 1;
339  }
340 
341 // Initialize the cache FSctl handler if we have one. The same deferal applies.
342 //
343  if (FSctl_PC)
344  {struct XrdOfsFSctl_PI::Plugins thePI = {Authorization, Finder,
346  XrdOucEnv pcEnv;
347  pcEnv.PutPtr("XrdOfsHandle*", dummyHandle);
348  if (!FSctl_PC->Configure(ConfigFN, 0, &pcEnv, thePI))
349  {Eroute.Emsg("Config", "Unable to configure cache FSctl handler.");
350  NoGo = 1;
351  }
352  }
353 
354 // Initialize th Evr object if we are an actual server
355 //
356  if (!(Options & isManager) && !evrObject.Init(Balancer)) NoGo = 1;
357 
358 // Turn off forwarding if we are not a pure remote redirector or a peer
359 //
360  if (Options & Forwarding)
361  {const char *why = 0;
362  if (!(Options & Authorize)) why = "authorization not enabled";
363  else if (!(Options & isPeer) && (Options & (isServer | isProxy)))
364  why = "not a pure manager";
365  if (why)
366  {Eroute.Say("Config warning: forwarding turned off; ", why);
367  Options &= ~(Forwarding);
370  fwdTRUNC.Reset();
371  }
372  }
373 
374 // If we need to send notifications, initialize the interface
375 //
376  if (!NoGo && evsObject) NoGo = evsObject->Start(&Eroute);
377 
378 // If the OSS plugin is really a proxy. If it is, it will export its origin.
379 // We also suppress translating lfn to pfn (usually done via osslib +cksio).
380 // Note: consulting the ENVAR below is historic and remains for compatibility
381 // Otherwise we can configure checkpointing if we are a data server.
382 //
383  if (ossFeatures & XRDOSS_HASPRXY || getenv("XRDXROOTD_PROXY"))
384  {OssIsProxy = 1;
385  CksPfn = false;
387  } else if (!(Options & isManager) && !XrdOfsConfigCP::Init()) NoGo = 1;
388 
389 // Indicate wheter oss implements pgrw or it has to be simulated
390 //
391  OssHasPGrw = (ossFeatures & XRDOSS_HASPGRW) != 0;
392 
393 // If POSC processing is enabled (as by default) do it. Warning! This must be
394 // the last item in the configuration list as we need a working filesystem.
395 // Note that in proxy mode we always disable posc!
396 //
397  if (OssIsProxy || getenv("XRDXROOTD_NOPOSC"))
398  {if (poscAuto != -1 && !NoGo)
399  Eroute.Say("Config POSC has been disabled by the osslib plugin.");
400  } else if (poscAuto != -1 && !NoGo) NoGo |= ConfigPosc(Eroute);
401 
402 // Configure realtime checksums if need be
403 //
404  if (CksRTCgi || CksRTName) NoGo |= ConfigCksRT(Eroute, EnvInfo);
405 
406 // Setup statistical monitoring
407 //
408  OfsStats.setRole(myRole);
409 
410 // Display final configuration
411 //
412  if (!NoGo) Config_Display(Eroute);
413  delete ofsConfig; ofsConfig = 0;
414 
415 // All done
416 //
417  tmp = (NoGo ? " initialization failed." : " initialization completed.");
418  Eroute.Say("------ File system ", myRole, tmp);
419  return NoGo;
420 }
421 
422 /******************************************************************************/
423 /* C o n f i g _ D i s p l a y */
424 /******************************************************************************/
425 
426 #define setBuff(x,y) {strcpy(bp, x); bp += y;}
427 
429 {
430  const char *cloc, *pval;
431  char buff[8192], fwbuff[512], *bp;
432  int i;
433 
434  if (!ConfigFN || !ConfigFN[0]) cloc = "default";
435  else cloc = ConfigFN;
436  if (!poscQ) pval = "off";
437  else pval = (poscAuto ? "auto" : "manual");
438 
439  snprintf(buff, sizeof(buff), "Config effective %s ofs configuration:\n"
440  " all.role %s\n"
441  "%s"
442  " ofs.maxdelay %d\n"
443  " ofs.persist %s hold %d%s%s\n"
444  " ofs.trace %x",
445  cloc, myRole,
446  (Options & Authorize ? " ofs.authorize\n" : ""),
447  MaxDelay,
448  pval, poscHold, (poscLog ? " logdir " : ""),
449  (poscLog ? poscLog : ""), OfsTrace.What);
450 
451  Eroute.Say(buff);
452 
453  if (CksRTCgi || CksRTName)
454  {snprintf(buff, sizeof(buff), " ofs.cksrt auto %s%s",
455  (CksRTName ? CksRTName:"none"),(CksRTCgi ? " chkcgi":""));
456  Eroute.Say(buff);
457  }
458 
459  ofsConfig->Display();
460 
461  if (Options & Forwarding)
462  {*fwbuff = 0;
463  if (ConfigDispFwd(buff, fwdCHMOD))
464  {Eroute.Say(buff); strcat(fwbuff, " ch");}
465  if (ConfigDispFwd(buff, fwdMKDIR))
466  {Eroute.Say(buff); strcat(fwbuff, " mk");}
467  if (ConfigDispFwd(buff, fwdMV))
468  {Eroute.Say(buff); strcat(fwbuff, " mv");}
469  if (ConfigDispFwd(buff, fwdRM))
470  {Eroute.Say(buff); strcat(fwbuff, " rm");}
471  if (ConfigDispFwd(buff, fwdRMDIR))
472  {Eroute.Say(buff); strcat(fwbuff, " rd");}
473  if (ConfigDispFwd(buff, fwdTRUNC))
474  {Eroute.Say(buff); strcat(fwbuff, " tr");}
475  if (*fwbuff) XrdOucEnv::Export("XRDOFS_FWD", fwbuff);
476  }
477 
478  if (evsObject)
479  {bp = buff;
480  setBuff(" ofs.notify ", 18); // 1234567890
481  if (evsObject->Enabled(XrdOfsEvs::Chmod)) setBuff("chmod ", 6);
482  if (evsObject->Enabled(XrdOfsEvs::Closer)) setBuff("closer ", 7);
483  if (evsObject->Enabled(XrdOfsEvs::Closew)) setBuff("closew ", 7);
484  if (evsObject->Enabled(XrdOfsEvs::Create)) setBuff("create ", 7);
485  if (evsObject->Enabled(XrdOfsEvs::Mkdir)) setBuff("mkdir ", 6);
486  if (evsObject->Enabled(XrdOfsEvs::Mv)) setBuff("mv ", 3);
487  if (evsObject->Enabled(XrdOfsEvs::Openr)) setBuff("openr ", 6);
488  if (evsObject->Enabled(XrdOfsEvs::Openw)) setBuff("openw ", 6);
489  if (evsObject->Enabled(XrdOfsEvs::Rm)) setBuff("rm ", 3);
490  if (evsObject->Enabled(XrdOfsEvs::Rmdir)) setBuff("rmdir ", 6);
491  if (evsObject->Enabled(XrdOfsEvs::Trunc)) setBuff("trunc ", 6);
492  if (evsObject->Enabled(XrdOfsEvs::Fwrite)) setBuff("fwrite ", 7);
493  setBuff("msgs ", 5);
494  i=sprintf(fwbuff,"%d %d ",evsObject->maxSmsg(),evsObject->maxLmsg());
495  setBuff(fwbuff, i);
496  cloc = evsObject->Prog();
497  if (*cloc != '>') setBuff("|",1);
498  setBuff(cloc, strlen(cloc));
499  setBuff("\0", 1);
500  Eroute.Say(buff);
501  }
502 }
503 
504 /******************************************************************************/
505 /* p r i v a t e f u n c t i o n s */
506 /******************************************************************************/
507 /******************************************************************************/
508 /* C o n f i g C k s R T */
509 /******************************************************************************/
510 
511 int XrdOfs::ConfigCksRT(XrdSysError &Eroute, XrdOucEnv* envP)
512 {
513  const char *why = 0;
514  const char *csSpec = 0;
515 
516 // Check if the directive is applicable to us
517 //
518  if (OssIsProxy) why = "not applicable to proxies";
519  else if (Options & isManager) why = "not applicable to managers";
520  else if (!Cks || !(csSpec = envP->Get("csList")))
521  why = "checksums not configured";
522  if (why)
523  {Eroute.Say("Config warning: Ignoring cksrt directive ", why);
524  if (CksRTName) {free(CksRTName); CksRTName = 0;}
525  CksRTCgi = false;
526  return 0;
527  }
528 
529 // Construct the list of supported checksums
530 //
531  XrdOucTUtils::splitString(csList, csSpec, " ");
532  if (csList.size() == 0)
533  {Eroute.Say("Config failure: Unable to determine configured cheksums!");
534  return 1;
535  }
536 
537 // Configure the automatic checksum if applicable
538 //
539  if (CksRTName)
540  {if (!strcmp(CksRTName, "default"))
541  {free(CksRTName);
542  CksRTName = strdup(csList[0].c_str());
543  }
544 
545  if (!(CksRTCalc = Cks->Object(CksRTName)))
546  {Eroute.Say("Config failure: cksrt auto ", CksRTName,
547  " checksum either non-native or not configured!");
548  return 1;
549  }
550  }
551 
552 // Success
553 //
555  return 0;
556 }
557 
558 /******************************************************************************/
559 /* C o n f i g D i s p F w d */
560 /******************************************************************************/
561 
562 int XrdOfs::ConfigDispFwd(char *buff, struct fwdOpt &Fwd)
563 {
564  const char *cP;
565  char pbuff[16], *bp;
566 
567 // Return if this is not being forwarded
568 //
569  if (!(cP = Fwd.Cmd)) return 0;
570  bp = buff;
571  setBuff(" ofs.forward ", 19);
572 
573 // Chck which way this is being forwarded
574 //
575  if (*Fwd.Cmd == '+'){setBuff("2way ",5); cP++;}
576  else if (!Fwd.Port) {setBuff("1way ",5);}
577  else { setBuff("3way ",5);
578  if (Fwd.Port < 0) {setBuff("local ",6);}
579  else {int n = sprintf(pbuff, ":%d ", Fwd.Port);
580  setBuff(Fwd.Host, strlen(Fwd.Host));
581  setBuff(pbuff, n);
582  }
583  }
584  setBuff(cP, strlen(cP));
585  return 1;
586 }
587 
588 /******************************************************************************/
589 /* C o n f i g P o s c */
590 /******************************************************************************/
591 
592 int XrdOfs::ConfigPosc(XrdSysError &Eroute)
593 {
594  extern XrdOfs* XrdOfsFS;
595  const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
596  class CloseFH : public XrdOfsHanCB
597  {public: void Retired(XrdOfsHandle *hP) {XrdOfsFS->Unpersist(hP);}};
598  static XrdOfsHanCB *hCB = static_cast<XrdOfsHanCB *>(new CloseFH);
599 
600  XrdOfsPoscq::recEnt *rP, *rPP;
602  XrdOfsHandle *hP;
603  const char *iName;
604  char pBuff[MAXPATHLEN], *aPath;
605  int NoGo, rc;
606 
607 // Construct the proper path to the recovery file
608 //
609  iName = XrdOucUtils::InstName(-1);
610  if (poscLog) aPath = XrdOucUtils::genPath(poscLog, iName, ".ofs/posc.log");
611  else {if (!(aPath = getenv("XRDADMINPATH")))
612  {XrdOucUtils::genPath(pBuff, MAXPATHLEN, "/tmp", iName);
613  aPath = pBuff;
614  }
615  aPath = XrdOucUtils::genPath(aPath, (char *)0, ".ofs/posc.log");
616  }
617  rc = strlen(aPath)-1;
618  if (aPath[rc] == '/') aPath[rc] = '\0';
619  free(poscLog); poscLog = aPath;
620 
621 // Make sure directory path exists
622 //
623  if ((rc = XrdOucUtils::makePath(poscLog, AMode)))
624  {Eroute.Emsg("Config", rc, "create path for", poscLog);
625  return 1;
626  }
627 
628 // Create object then initialize it
629 //
630  poscQ = new XrdOfsPoscq(&Eroute, XrdOfsOss, poscLog, int(poscSync));
631  rP = poscQ->Init(rc);
632  if (!rc) return 1;
633 
634 // Get file handles and put then in pending delete for all recovered records
635 //
636  NoGo = 0;
637  while(rP)
638  {qP = &(rP->reqData);
639  if (qP->addT && poscHold)
641  {Eroute.Emsg("Config", "Unable to persist", qP->User, qP->LFN);
642  qP->addT = 0;
643  } else {
644  hP->PoscSet(qP->User, rP->Offset, rP->Mode);
645  hP->Retire(hCB, poscHold);
646  }
647  }
648  if (!(qP->addT) || !poscHold)
649  {if ((rc = XrdOfsOss->Unlink(qP->LFN)) && rc != -ENOENT)
650  {Eroute.Emsg("Config", rc, "unpersist", qP->LFN); NoGo = 1;}
651  else {Eroute.Emsg("Config", "Unpersisted", qP->User, qP->LFN);
652  poscQ->Del(qP->LFN, rP->Offset);
653  }
654  }
655  rPP = rP; rP = rP->Next; delete rPP;
656  }
657 
658 // All done
659 //
660  if (!NoGo) FeatureSet |= XrdSfs::hasPOSC;
661  return NoGo;
662 }
663 
664 /******************************************************************************/
665 /* C o n f i g R e d i r */
666 /******************************************************************************/
667 
668 int XrdOfs::ConfigRedir(XrdSysError &Eroute, XrdOucEnv *EnvInfo)
669 {
670  XrdCmsClient_t CmsPI;
671  XrdSysLogger *myLogger = Eroute.logger();
672  int isRedir = Options & isManager;
673  int RMTopts = (Options & isServer ? XrdCms::IsTarget : 0)
674  | (Options & isProxy ? XrdCms::IsProxy : 0)
675  | (Options & isMeta ? XrdCms::IsMeta : 0);
676  int TRGopts = (Options & isProxy ? XrdCms::IsProxy : 0)
677  | (isRedir ? XrdCms::IsRedir : 0) | XrdCms::IsTarget;
678 
679 // Get the cms object creator plugin
680 //
681  ofsConfig->Plugin(CmsPI);
682 
683 // For manager roles, we simply do a standard config
684 //
685  if (isRedir)
686  { if (CmsPI) Finder = CmsPI(myLogger, RMTopts, myPort, XrdOfsOss);
687  else if (XrdCmsFinderRMT::VCheck(XrdVERSIONINFOVAR(XrdOfs)))
689  RMTopts,myPort);
690  else return 1;
691  if (!Finder) return 1;
692  if (!ofsConfig->Configure(Finder, EnvInfo))
693  {delete Finder; Finder = 0; return 1;}
694  if (EnvInfo) EnvInfo->PutPtr("XRDCMSMANLIST", Finder->Managers());
695  }
696 
697 // If we are a subcluster for another cluster then we can only be so if we
698 // are a pure manager. If a subcluster directive was encountered and this is
699 // not true we need to turn that off here. Subclusters need a target finder
700 // just like supervisors eventhough we are not a supervisor.
701 //
702  if ((Options & haveRole) != isManager) Options &= ~SubCluster;
703 
704 // For server roles find the port number and create the object. We used to pass
705 // the storage system object to the finder to allow it to process cms storage
706 // requests. The cms no longer sends such requests so there is no need to do
707 // so. And, in fact, we need to defer creating a storage system until after the
708 // finder is created. So, it's just as well we pass a numm pointer. At some
709 // point the finder should remove all storage system related code.
710 //
711  if (Options & (isServer | SubCluster | (isPeer & ~isManager)))
712  {if (!myPort)
713  {Eroute.Emsg("Config", "Unable to determine server's port number.");
714  return 1;
715  }
716  if (CmsPI) Balancer = CmsPI(myLogger, TRGopts, myPort, XrdOfsOss);
717  else if (XrdCmsFinderTRG::VCheck(XrdVERSIONINFOVAR(XrdOfs)))
718  Balancer = (XrdCmsClient *)new XrdCmsFinderTRG(myLogger,
719  TRGopts,myPort);
720  else return 1;
721  if (!Balancer) return 1;
722  if (!ofsConfig->Configure(Balancer, EnvInfo))
723  {delete Balancer; Balancer = 0; return 1;}
724  if (Options & (isProxy | SubCluster))
725  Balancer = 0; // No chatting for proxies or subclusters
726  }
727 
728 // All done
729 //
730  return 0;
731 }
732 
733 /******************************************************************************/
734 /* C o n f i g T P C */
735 /******************************************************************************/
736 
737 
738 int XrdOfs::ConfigTPC(XrdSysError &Eroute, XrdOucEnv *envP)
739 {
741 
742 // Check if we need to configure rge credentials directory
743 //
744  if (Cfg.fCreds)
745  {char *cpath = Cfg.cPath;
746  if (!(Cfg.cPath = ConfigTPCDir(Eroute, ".ofs/.tpccreds/", cpath)))
747  return 1;
748  free(cpath);
749  }
750 
751 // Construct the reproxy path. We always do this as need to solve the cart-horse
752 // problem of plugin loading. If we don't need it it will be ignored later.
753 //
754  if (!(Cfg.rPath = ConfigTPCDir(Eroute, ".ofs/.tpcproxy"))) return 1;
755  if (envP) envP->Put("tpc.rpdir", Cfg.rPath);
756 
757 // Check if TPC monitoring is wanted and set it up
758 //
759  Cfg.tpcMon = (XrdXrootdTpcMon*)envP->GetPtr("TpcMonitor*");
760 
761 // All done
762 //
763  return 0;
764 }
765 
766 /******************************************************************************/
767 
768 int XrdOfs::ConfigTPC(XrdSysError &Eroute)
769 {
771 
772 // If the oss plugin does not use a reproxy then remove it from the TPC config.
773 // Otherwise, complete it.
774 //
775  if (ossFeatures & XRDOSS_HASRPXY && Cfg.rPath)
776  {char rPBuff[1024];
777  reProxy = true;
778  snprintf(rPBuff,sizeof(rPBuff),"%s/%x-%%d.rpx",Cfg.rPath,int(time(0)));
779  free(Cfg.rPath);
780  Cfg.rPath = strdup(rPBuff);
781  } else {
782  if (Cfg.rPath) free(Cfg.rPath);
783  Cfg.rPath = 0;
784  }
785 
786 // Initialize the TPC object
787 //
788  XrdOfsTPC::Init();
789 
790 // Start TPC operations
791 //
792  return (XrdOfsTPC::Start() ? 0 : 1);
793 }
794 /******************************************************************************/
795 /* C o n f i g T P C D i r */
796 /******************************************************************************/
797 
798 char *XrdOfs::ConfigTPCDir(XrdSysError &Eroute, const char *sfx,
799  const char *xPath)
800 {
801 
802  const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
803  const int BMode = S_IRWXU| S_IRGRP|S_IXGRP; // 750
804  const int nswOpt= XrdOucNSWalk::retFile | XrdOucNSWalk::retLink;
805  const char *iName;
806  char pBuff[MAXPATHLEN], *aPath;
807  int rc;
808 
809 // Construct the proper path to stored credentials
810 //
811  iName = XrdOucUtils::InstName(-1);
812  if (xPath) aPath = XrdOucUtils::genPath(xPath, iName, sfx);
813  else {if (!(aPath = getenv("XRDADMINPATH")))
814  {XrdOucUtils::genPath(pBuff, MAXPATHLEN, "/tmp", iName);
815  aPath = pBuff;
816  }
817  aPath = XrdOucUtils::genPath(aPath, (char *)0, sfx);
818  }
819 
820 // Make sure directory path exists
821 //
822  if ((rc = XrdOucUtils::makePath(aPath, AMode)))
823  {Eroute.Emsg("Config", rc, "create TPC path", aPath);
824  free(aPath);
825  return 0;
826  }
827 
828 // Protect the last component
829 //
830  if (SetMode(aPath, BMode))
831  {Eroute.Emsg("Config", errno, "protect TPC path", aPath);
832  free(aPath);
833  return 0;
834  }
835 
836 // list the contents of the directory
837 //
838  XrdOucNSWalk nsWalk(&Eroute, aPath, 0, nswOpt);
839  XrdOucNSWalk::NSEnt *nsX, *nsP = nsWalk.Index(rc);
840  if (rc)
841  {Eroute.Emsg("Config", rc, "list TPC path", aPath);
842  free(aPath);
843  return 0;
844  }
845 
846 // Remove directory contents of all files
847 //
848  bool isBad = false;
849  while((nsX = nsP))
850  {nsP = nsP->Next;
851  if (unlink(nsX->Path))
852  {Eroute.Emsg("Config", errno, "remove TPC creds", nsX->Path);
853  isBad = true;
854  }
855  delete nsX;
856  }
857 
858 // Check if all went well
859 //
860  if (isBad) {free(aPath); return 0;}
861 
862 // All done
863 //
864  return aPath;
865 }
866 
867 /******************************************************************************/
868 /* C o n f i g X e q */
869 /******************************************************************************/
870 
872  XrdSysError &Eroute)
873 {
874  char *val, vBuff[64];
875 
876  // Now assign the appropriate global variable
877  //
878  TS_Bit("authorize", Options, Authorize);
879  TS_XPI("authlib", theAutLib);
880  TS_XPI("ckslib", theCksLib);
881  TS_Xeq("cksrt", xcksrt);
882  TS_Xeq("cksrdsz", xcrds);
883  TS_XPI("cmslib", theCmsLib);
884  TS_Xeq("crmode", xcrm);
885  TS_XPI("ctllib", theCtlLib);
886  TS_Xeq("dirlist", xdirl);
887  TS_Xeq("forward", xforward);
888  TS_Xeq("maxdelay", xmaxd);
889  TS_Xeq("notify", xnot);
890  TS_Xeq("notifymsg", xnmsg);
891  TS_XPI("osslib", theOssLib);
892  TS_Xeq("persist", xpers);
893  TS_XPI("preplib", thePrpLib);
894  TS_Xeq("role", xrole);
895  TS_Xeq("tpc", xtpc);
896  TS_Xeq("trace", xtrace);
897  TS_Xeq("xattr", xatr);
898  TS_XPI("xattrlib", theAtrLib);
899 
900  // Process miscellaneous directives handled elsemwhere
901  //
902  if (!strcmp("chkpnt", var)) return (XrdOfsConfigCP::Parse(Config) ? 0 : 1);
903 
904  // Screen out the subcluster directive (we need to track that)
905  //
906  TS_Bit("subcluster",Options,SubCluster);
907 
908  // Get the actual value for simple directives
909  //
910  strlcpy(vBuff, var, sizeof(vBuff)); var = vBuff;
911  if (!(val = Config.GetWord()))
912  {Eroute.Emsg("Config", "value not specified for", var); return 1;}
913 
914  // No match found, complain.
915  //
916  Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
917  Config.Echo();
918  return 0;
919 }
920 
921 /******************************************************************************/
922 /* V a l i d C S T */
923 /******************************************************************************/
924 
925 bool XrdOfs::ValidCST(const char* cst)
926 {
927  std::string csWant(cst);
928 
929 // Check if checksum type is in the list of valid ones. The list is short.
930 //
931  if (csList.size())
932  {for (const auto& name : csList)
933  {if (name == csWant) return true;}
934  }
935  return false;
936 }
937 
938 /******************************************************************************/
939 /* x c k s r t */
940 /******************************************************************************/
941 
942 /* Function: xcksrt
943 
944  Purpose: To parse the directive: cksrt [auto <cipher>] [chkcgi]
945 
946  auto Specifies that realtime checksums be automatically
947  computed using the specified cipher. If cgi is allowed
948  and specified, the cipher in the cgi is used. Specifying
949  'auto none' or 'auto off', disables automatic real-time
950  checksums, this is the default. Specifying 'auto default'
951  uses the default checksum speciied by the xrootd.chksum
952  directive.
953 
954  chkcgi A realtime checksum can be request using the cgi element
955  "cks.type=<cipher>" on the open request URL, where <cipher>
956  is the desired checksum cipher to use. If the cipher is
957  not supported for use the open() call fails. Note that
958  it must have been allowed by the xrootd.chksum directive.
959 
960  Output: 0 upon success or !0 upon failure.
961 
962  Notes: Checksums must have been configured for this directive to take
963  effect.
964 */
965 
966 int XrdOfs::xcksrt(XrdOucStream &Config, XrdSysError &Eroute)
967 {
968  char *val;
969  bool cgi = false, spec = false;
970 
971 // Initialize the defaults
972 //
973  CksRTCgi = false;
974  if (CksRTName) {free(CksRTName); CksRTName = 0;}
975 
976 // Process the options
977 //
978  while ((val = Config.GetWord()) && *val)
979  {spec = true;
980  if (!strcmp(val, "auto"))
981  {if (!(val = Config.GetWord()) || *val == '\0')
982  {Eroute.Emsg("Config", "cksrt auto cipher not specified.");
983  return 1;
984  }
985  if (CksRTName) {free(CksRTName); CksRTName = 0;}
986  if (strcmp(val, "none") && strcmp(val, "off"))
987  CksRTName = strdup(val);
988  continue;
989  }
990  if (!strcmp(val, "chkcgi")) {cgi = true; continue;}
991 
992  Eroute.Emsg("Config", "Inavlid cksrt parameter -", val);
993  return 1;
994  }
995 
996 // Verify that we encountered some kind of parameter
997 //
998  if (!spec)
999  {Eroute.Emsg("Config", "No cksrt parameters specified!"); return 1;}
1000 
1001 // Finish up
1002 //
1003  if (cgi) CksRTCgi = cgi;
1004  return 0;
1005 }
1006 
1007 /******************************************************************************/
1008 /* x c r d s */
1009 /******************************************************************************/
1010 
1011 /* Function: xcrds
1012 
1013  Purpose: To parse the directive: cksrdsz <size>
1014 
1015  <size> number of bytes to segment reads when calclulating a
1016  checksum. Can be suffixed by k,m,g. Maximum is 1g and
1017  is automatically set to be atleast 64k and to be a
1018  multiple of 64k.
1019 
1020  Output: 0 upon success or !0 upon failure.
1021 */
1022 
1023 int XrdOfs::xcrds(XrdOucStream &Config, XrdSysError &Eroute)
1024 {
1025  static const long long maxRds = 1024*1024*1024;
1026  char *val;
1027  long long rdsz;
1028 
1029 // Get the size
1030 //
1031  if (!(val = Config.GetWord()) || !val[0])
1032  {Eroute.Emsg("Config", "cksrdsz size not specified"); return 1;}
1033 
1034 // Now convert it
1035 //
1036  if (XrdOuca2x::a2sz(Eroute, "cksrdsz size", val, &rdsz, 1, maxRds)) return 1;
1037  ofsConfig->SetCksRdSz(static_cast<int>(rdsz));
1038 
1039 // This value is also used for real-time checksum rereads. However, while
1040 // minimum is 64K the maximum is set to 2MB. Also in 64K units.
1041 //
1042  XrdOfsCksFile::setRDSZ(rdsz);
1043  return 0;
1044 }
1045 
1046 /******************************************************************************/
1047 /* x c r m */
1048 /******************************************************************************/
1049 
1050 /* Function: xcrm
1051 
1052  Purpose: To parse the directive: crmode [dirs <mspec>] [files <mspec>]
1053 
1054  <mspec>: common | legacy | [raw] <modes>
1055 
1056  common uses dirs 0700:0755 and files 0600:0644
1057 
1058  legacy uses dirs 0000:0775 and files 0000:0775
1059 
1060  raw Allows actual specification of mode bits without enforcing
1061  default requirements. The resulting modes may not be 0.
1062  Otherwise, the specified values are made consistent with
1063  the default mode settings.
1064 
1065  <modes>: <minv> | :<maxv> | <minv>:<maxv>
1066 
1067  <minv>: The minimum mode value required (always set), see <mval>.
1068  <maxv>: The maximum mode value to be enforced, see <mval>.
1069 
1070  <mval> is either an octal mode specifiation or a standard ls type
1071  mode specification (i.e. 'rwx'). The specification is in
1072  groups of 3 letters. The first group designates user mode,
1073  the scond group mode, and the last other mode. To disallow
1074  a mode specify a dash. Note that for files, the 'x'
1075  character must be a dash unless raw mode is enabled. It is
1076  impossible to disllow any mode for user except for raw mode.
1077 
1078  Output: 0 upon success or !0 upon failure.
1079 */
1080 
1081 int XrdOfs::xcrm(XrdOucStream &Config, XrdSysError &Eroute)
1082 {
1083  static const mode_t dMin = 0700, dMax = 0775, fMin = 0600, fMax = 0664;
1084  static const mode_t xBit = 0111, wBit = 0002;
1085  const char *mtype;
1086  char *colon, *val, *minM, *maxM;
1087  mode_t mMask[2];
1088  bool isDirs, isRaw;
1089 
1090 // Get the size
1091 //
1092  if (!(val = Config.GetWord()) || !val[0])
1093  {Eroute.Emsg("Config", "crmode argument not specified"); return 1;}
1094 
1095 // Process all of the specs
1096 //
1097 do{if (!strcmp("dirs", val)) {isDirs = true; mtype = "dirs mode";}
1098  else if (!strcmp("files", val)) {isDirs = false; mtype = "files mode";}
1099  else {Eroute.Emsg("Config", "invalid mode type - ", val);
1100  return 1;
1101  }
1102 
1103  if (!(val = Config.GetWord()) || !val[0])
1104  {Eroute.Emsg("Config", mtype, "value not specified"); return 1;}
1105 
1106  if (!strcmp(val, "common"))
1107  {if (isDirs) {dMask[0] = dMin; dMask[1] = dMax;}
1108  else {fMask[0] = fMin; fMask[1] = fMax;}
1109  continue;
1110  }
1111 
1112  if (!strcmp(val, "legacy"))
1113  {if (isDirs) {dMask[0] = 0; dMask[1] = 0775;}
1114  else {fMask[0] = 0; fMask[1] = 0775;}
1115  continue;
1116  }
1117 
1118  if ((isRaw = !strcmp(val, "raw")))
1119  {if (!(val = Config.GetWord()) || !val[0])
1120  {Eroute.Emsg("Config", mtype, "value not specified"); return 1;}
1121  }
1122 
1123  colon = index(val, ':');
1124  if (!colon || colon == val || *(colon+1) == 0)
1125  {Eroute.Emsg("Config",mtype,"mode spec requires min and max values");
1126  return 1;
1127  }
1128  minM = val; *colon = 0; maxM = colon + 1;
1129 
1130  if (!XrdOucUtils::mode2mask(minM, mMask[0]))
1131  {Eroute.Emsg("Config", mtype, "value is invalid -", minM);
1132  return 1;
1133  }
1134 
1135  if (!XrdOucUtils::mode2mask(maxM, mMask[1]))
1136  {Eroute.Emsg("Config", mtype, "value is invalid -", maxM);
1137  return 1;
1138  }
1139 
1140  if (isDirs)
1141  {if (isRaw) {dMask[0] = mMask[0]; dMask[1] = mMask[1];}
1142  else {if ((mMask[0] | mMask[1]) & wBit)
1143  {Eroute.Say("Config warning: 'other' w-mode removed from dirs mode!");
1144  mMask[0] &= ~wBit; mMask[1] &= ~wBit;
1145  }
1146  dMask[0] = (mMask[0] | dMin) & dMax;
1147  dMask[1] = (mMask[1] | dMin) & dMax;
1148  }
1149  if ((dMask[0] & dMask[1]) != dMask[0])
1150  {Eroute.Emsg("Config","dirs mode min and max values are inconsistent!");
1151  return 1;
1152  }
1153  } else { // Files
1154  if (isRaw) {fMask[0] = mMask[0]; fMask[1] = mMask[1];}
1155  else {if ((mMask[0] | mMask[1]) & wBit)
1156  {Eroute.Say("Config warning: 'other' w-mode removed from files mode!");
1157  mMask[0] &= ~wBit; mMask[1] &= ~wBit;
1158  }
1159  if ((mMask[0] | mMask[1]) & xBit)
1160  {Eroute.Say("Config warning: x-mode removed from files mode!");
1161  mMask[0] &= ~xBit; mMask[1] &= ~xBit;
1162  }
1163  fMask[0] = (mMask[0] | fMin) & fMax;
1164  fMask[1] = (mMask[1] | fMin) & fMax;
1165  }
1166  if ((fMask[0] & fMask[1]) != fMask[0])
1167  {Eroute.Emsg("Config","files mode min and max values are inconsistent!");
1168  return 1;
1169  }
1170  }
1171  } while((val = Config.GetWord()) && val[0]);
1172 
1173 // All done, return success
1174 //
1175  return 0;
1176 }
1177 
1178 /******************************************************************************/
1179 /* x d i r l */
1180 /******************************************************************************/
1181 
1182 /* Function: xdirl
1183 
1184  Purpose: To parse the directive: dirlist {local | remote}
1185 
1186  local processes directory listings locally. The oss plugin
1187  must be capable of doing this. This is the default.
1188  remote if clustering is enabled, directory listings are
1189  processed as directed by the cmsd.
1190 
1191  Output: 0 upon success or !0 upon failure.
1192 */
1193 
1194 int XrdOfs::xdirl(XrdOucStream &Config, XrdSysError &Eroute)
1195 {
1196  char *val;
1197 
1198 // Get the parameter
1199 //
1200  if (!(val = Config.GetWord()) || !val[0])
1201  {Eroute.Emsg("Config", "dirlist parameter not specified"); return 1;}
1202 
1203 // Set appropriate option
1204 //
1205  if (!strcmp(val, "local")) DirRdr = false;
1206  else if (!strcmp(val, "remote")) DirRdr = true;
1207  else {Eroute.Emsg("Config", "Invalid dirlist parameter -", val); return 1;}
1208 
1209  return 0;
1210 }
1211 
1212 /******************************************************************************/
1213 /* x e x p */
1214 /******************************************************************************/
1215 
1216 /* Function: xexp
1217 
1218  Purpose: To prescan the all.export and oss.defaults directives to determine
1219  if we have any writable paths.
1220 
1221  Output: 0 upon success or !0 upon failure.
1222 */
1223 
1224 int XrdOfs::xexp(XrdOucStream &Config, XrdSysError &Eroute, bool isExport)
1225 {
1226  static struct rwOpts {const char *opname; int isRW;} rwtab[] =
1227  {{"r/o", 0}, {"readonly", 0},
1228  {"forcero", 0}, {"notwritable", 0},
1229  {"writable", 1}, {"r/w", 1}
1230  };
1231  static bool defRW = true;
1232  int isrw = -1, numopts = sizeof(rwtab)/sizeof(struct rwOpts);
1233  char *val;
1234 
1235 // If this is an export and we already know that we have a writable path, return
1236 // Otherwise, scan over the path argument.
1237 //
1238  if (isExport && (ossRW == 'w' || !(val = Config.GetWord()))) return 0;
1239 
1240 // Throw away path and scan all the options looking for something of interest
1241 //
1242  while((val = Config.GetWord()))
1243  {for (int i = 0; i < numopts; i++)
1244  if (!strcmp(val, rwtab[i].opname)) isrw = rwtab[i].isRW;
1245  else if (!strcmp(val, "cache")) {isrw = 0; break;}
1246  }
1247 
1248 // Handle result depending if this is an export or a defaults
1249 //
1250  if (isrw < 0) isrw = defRW;
1251  if (isExport) ossRW = (isrw ? 'w' : 'r');
1252  else {defRW = (isrw ? true : false);
1253  if (ossRW == ' ' && !isrw) ossRW = 'r';
1254  }
1255  return 0;
1256 }
1257 
1258 /******************************************************************************/
1259 /* x f o r w a r d */
1260 /******************************************************************************/
1261 
1262 /* Function: xforward
1263 
1264  Purpose: To parse the directive: forward [<handling>] <metaops>
1265 
1266  handling: 1way | 2way | 3way {local | <host>:<port>}
1267 
1268  1way forward does not respond (the default)
1269  2way forward responds; relay response back.
1270  3way forward 1way and execute locally or redirect to <host>
1271  <metaops> list of meta-file operations to forward to manager
1272 
1273  Output: 0 upon success or !0 upon failure.
1274 */
1275 
1276 int XrdOfs::xforward(XrdOucStream &Config, XrdSysError &Eroute)
1277 {
1278  enum fwdType {OfsFWDALL = 0x3f, OfsFWDCHMOD = 0x01, OfsFWDMKDIR = 0x02,
1279  OfsFWDMV = 0x04, OfsFWDRM = 0x08, OfsFWDRMDIR = 0x10,
1280  OfsFWDREM = 0x18, OfsFWDTRUNC = 0x20, OfsFWDNONE = 0};
1281 
1282  static struct fwdopts {const char *opname; fwdType opval;} fwopts[] =
1283  {
1284  {"all", OfsFWDALL},
1285  {"chmod", OfsFWDCHMOD},
1286  {"mkdir", OfsFWDMKDIR},
1287  {"mv", OfsFWDMV},
1288  {"rm", OfsFWDRM},
1289  {"rmdir", OfsFWDRMDIR},
1290  {"remove", OfsFWDREM},
1291  {"trunc", OfsFWDTRUNC}
1292  };
1293  int fwval = OfsFWDNONE, fwspec = OfsFWDNONE;
1294  int numopts = sizeof(fwopts)/sizeof(struct fwdopts);
1295  int i, neg, rPort = 0, is2way = 0, is3way = 0;
1296  char *val, *pp, rHost[512];
1297 
1298  *rHost = '\0';
1299  if (!(val = Config.GetWord()))
1300  {Eroute.Emsg("Config", "forward option not specified"); return 1;}
1301  if ((is2way = !strcmp("2way", val)) || !strcmp("1way", val)
1302  || (is3way = !strcmp("3way", val)))
1303  if (!(val = Config.GetWord()))
1304  {Eroute.Emsg("Config", "forward operation not specified"); return 1;}
1305 
1306  if (is3way)
1307  {if (!strcmp("local", val)) rPort = -1;
1308  else
1309  {if (*val == ':')
1310  {Eroute.Emsg("Config", "redirect host not specified"); return 1;}
1311  if (!(pp = index(val, ':')))
1312  {Eroute.Emsg("Config", "redirect port not specified"); return 1;}
1313  if ((rPort = atoi(pp+1)) <= 0)
1314  {Eroute.Emsg("Config", "redirect port is invalid"); return 1;}
1315  *pp = '\0';
1316  strlcpy(rHost, val, sizeof(rHost));
1317  }
1318  if (!(val = Config.GetWord()))
1319  {Eroute.Emsg("Config", "forward operation not specified"); return 1;}
1320  }
1321 
1322  while (val)
1323  {if (!strcmp(val, "off")) {fwval = OfsFWDNONE; fwspec = OfsFWDALL;}
1324  else {if ((neg = (val[0] == '-' && val[1]))) val++;
1325  for (i = 0; i < numopts; i++)
1326  {if (!strcmp(val, fwopts[i].opname))
1327  {if (neg) fwval &= ~fwopts[i].opval;
1328  else fwval |= fwopts[i].opval;
1329  fwspec |= fwopts[i].opval;
1330  break;
1331  }
1332  }
1333  if (i >= numopts)
1334  Eroute.Say("Config warning: ignoring invalid forward option '",val,"'.");
1335  }
1336  val = Config.GetWord();
1337  }
1338 
1339  if (fwspec & OfsFWDCHMOD)
1340  {fwdCHMOD.Cmd = (fwval&OfsFWDCHMOD ? (is2way ? "+chmod" :"chmod") : 0);
1341  if (fwdCHMOD.Host) free(fwdCHMOD.Host);
1342  fwdCHMOD.Host = strdup(rHost); fwdCHMOD.Port = rPort;
1343  }
1344  if (fwspec&OfsFWDMKDIR)
1345  {fwdMKDIR.Cmd = (fwval&OfsFWDMKDIR ? (is2way ? "+mkdir" :"mkdir") : 0);
1346  if (fwdMKDIR.Host) free(fwdMKDIR.Host);
1347  fwdMKDIR.Host = strdup(rHost); fwdMKDIR.Port = rPort;
1348  fwdMKPATH.Cmd= (fwval&OfsFWDMKDIR ? (is2way ? "+mkpath":"mkpath") : 0);
1349  if (fwdMKPATH.Host) free(fwdMKPATH.Host);
1350  fwdMKPATH.Host = strdup(rHost); fwdMKPATH.Port = rPort;
1351  }
1352  if (fwspec&OfsFWDMV)
1353  {fwdMV .Cmd = (fwval&OfsFWDMV ? (is2way ? "+mv" :"mv") : 0);
1354  if (fwdMV.Host) free(fwdMV.Host);
1355  fwdMV.Host = strdup(rHost); fwdMV.Port = rPort;
1356  }
1357  if (fwspec&OfsFWDRM)
1358  {fwdRM .Cmd = (fwval&OfsFWDRM ? (is2way ? "+rm" :"rm") : 0);
1359  if (fwdRM.Host) free(fwdRM.Host);
1360  fwdRM.Host = strdup(rHost); fwdRM.Port = rPort;
1361  }
1362  if (fwspec&OfsFWDRMDIR)
1363  {fwdRMDIR.Cmd = (fwval&OfsFWDRMDIR ? (is2way ? "+rmdir" :"rmdir") : 0);
1364  if (fwdRMDIR.Host) free(fwdRMDIR.Host);
1365  fwdRMDIR.Host = strdup(rHost); fwdRMDIR.Port = rPort;
1366  }
1367  if (fwspec&OfsFWDTRUNC)
1368  {fwdTRUNC.Cmd = (fwval&OfsFWDTRUNC ? (is2way ? "+trunc" :"trunc") : 0);
1369  if (fwdTRUNC.Host) free(fwdTRUNC.Host);
1370  fwdTRUNC.Host = strdup(rHost); fwdTRUNC.Port = rPort;
1371  }
1372 
1373 // All done
1374 //
1375  Options |= Forwarding;
1376  return 0;
1377 }
1378 
1379 /******************************************************************************/
1380 /* x m a x d */
1381 /******************************************************************************/
1382 
1383 /* Function: xmaxd
1384 
1385  Purpose: To parse the directive: maxdelay <secs>
1386 
1387  <secs> maximum delay imposed for staging
1388 
1389  Output: 0 upon success or !0 upon failure.
1390 */
1391 
1392 int XrdOfs::xmaxd(XrdOucStream &Config, XrdSysError &Eroute)
1393 {
1394  char *val;
1395  int maxd;
1396 
1397  if (!(val = Config.GetWord()))
1398  {Eroute.Emsg("Config","maxdelay value not specified");return 1;}
1399  if (XrdOuca2x::a2i(Eroute, "maxdelay", val, &maxd, 30)) return 1;
1400 
1401  MaxDelay = maxd;
1402  return 0;
1403 }
1404 
1405 /******************************************************************************/
1406 /* x n m s g */
1407 /******************************************************************************/
1408 
1409 /* Function: xnmsg
1410 
1411  Purpose: To parse the directive: notifymsg <event> <msg>
1412 
1413  Args: <events> - one or more of: all chmod closer closew close mkdir mv
1414  openr openw open rm rmdir fwrite
1415  <msg> the notification message to be sent (see notify).
1416 
1417  Type: Manager only, non-dynamic.
1418 
1419  Output: 0 upon success or !0 upon failure.
1420 */
1421 
1422 int XrdOfs::xnmsg(XrdOucStream &Config, XrdSysError &Eroute)
1423 {
1424  static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
1425  noopts[] = {
1426  {"chmod", XrdOfsEvs::Chmod},
1427  {"closer", XrdOfsEvs::Closer},
1428  {"closew", XrdOfsEvs::Closew},
1429  {"create", XrdOfsEvs::Create},
1430  {"mkdir", XrdOfsEvs::Mkdir},
1431  {"mv", XrdOfsEvs::Mv},
1432  {"openr", XrdOfsEvs::Openr},
1433  {"openw", XrdOfsEvs::Openw},
1434  {"rm", XrdOfsEvs::Rm},
1435  {"rmdir", XrdOfsEvs::Rmdir},
1436  {"trunc", XrdOfsEvs::Trunc},
1437  {"fwrite", XrdOfsEvs::Fwrite}
1438  };
1439  XrdOfsEvs::Event noval;
1440  int numopts = sizeof(noopts)/sizeof(struct notopts);
1441  char *val, buff[1024];
1442  XrdOucEnv *myEnv;
1443  int i;
1444 
1445  // At this point, make sure we have a value
1446  //
1447  if (!(val = Config.GetWord()))
1448  {Eroute.Emsg("Config", "notifymsg event not specified");
1449  return 1;
1450  }
1451 
1452  // Get the evant number
1453  //
1454  for (i = 0; i < numopts; i++) if (!strcmp(val, noopts[i].opname)) break;
1455  if (i >= numopts)
1456  {Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
1457  return 1;
1458  }
1459  noval = noopts[i].opval;
1460 
1461  // We need to suck all the tokens to the end of the line for remaining
1462  // options. Do so, until we run out of space in the buffer.
1463  //
1464  myEnv = Config.SetEnv(0);
1465  if (!Config.GetRest(buff, sizeof(buff)))
1466  {Eroute.Emsg("Config", "notifymsg arguments too long");
1467  Config.SetEnv(myEnv);
1468  return 1;
1469  }
1470 
1471  // Restore substitutions and parse the message
1472  //
1473  Config.SetEnv(myEnv);
1474  return XrdOfsEvs::Parse(Eroute, noval, buff);
1475 }
1476 
1477 /******************************************************************************/
1478 /* x n o t */
1479 /* Based on code developed by Derek Feichtinger, CERN. */
1480 /******************************************************************************/
1481 
1482 /* Function: xnot
1483 
1484  Purpose: Parse directive: notify <events> [msgs <min> [<max>]]
1485  {|<prog> | ><path>}
1486 
1487  Args: <events> - one or more of: all chmod closer closew close mkdir mv
1488  openr openw open rm rmdir fwrite
1489  opaque and other possible information to be sent.
1490  msgs - Maximum number of messages to keep and queue. The
1491  <min> if for small messages (default 90) and <max> is
1492  for big messages (default 10).
1493  <prog> - is the program to execute and dynamically feed messages
1494  about the indicated events. Messages are piped to prog.
1495  <path> - is the udp named socket to receive the message. The
1496  server creates the path if it's not present.
1497 
1498  Output: 0 upon success or !0 upon failure.
1499 */
1500 int XrdOfs::xnot(XrdOucStream &Config, XrdSysError &Eroute)
1501 {
1502  static struct notopts {const char *opname; XrdOfsEvs::Event opval;}
1503  noopts[] = {
1504  {"all", XrdOfsEvs::All},
1505  {"chmod", XrdOfsEvs::Chmod},
1506  {"close", XrdOfsEvs::Close},
1507  {"closer", XrdOfsEvs::Closer},
1508  {"closew", XrdOfsEvs::Closew},
1509  {"create", XrdOfsEvs::Create},
1510  {"mkdir", XrdOfsEvs::Mkdir},
1511  {"mv", XrdOfsEvs::Mv},
1512  {"open", XrdOfsEvs::Open},
1513  {"openr", XrdOfsEvs::Openr},
1514  {"openw", XrdOfsEvs::Openw},
1515  {"rm", XrdOfsEvs::Rm},
1516  {"rmdir", XrdOfsEvs::Rmdir},
1517  {"trunc", XrdOfsEvs::Trunc},
1518  {"fwrite", XrdOfsEvs::Fwrite}
1519  };
1521  int numopts = sizeof(noopts)/sizeof(struct notopts);
1522  int i, neg, msgL = 90, msgB = 10;
1523  char *val, parms[1024];
1524 
1525  if (!(val = Config.GetWord()))
1526  {Eroute.Emsg("Config", "notify parameters not specified"); return 1;}
1527  while (val && *val != '|' && *val != '>')
1528  {if (!strcmp(val, "msgs"))
1529  {if (!(val = Config.GetWord()))
1530  {Eroute.Emsg("Config", "notify msgs value not specified");
1531  return 1;
1532  }
1533  if (XrdOuca2x::a2i(Eroute, "msg count", val, &msgL, 0)) return 1;
1534  if (!(val = Config.GetWord())) break;
1535  if (isdigit(*val)
1536  && XrdOuca2x::a2i(Eroute, "msg count", val, &msgB, 0)) return 1;
1537  if (!(val = Config.GetWord())) break;
1538  continue;
1539  }
1540  if ((neg = (val[0] == '-' && val[1]))) val++;
1541  i = strlen(val);
1542  for (i = 0; i < numopts; i++)
1543  {if (!strcmp(val, noopts[i].opname))
1544  {if (neg) noval = static_cast<XrdOfsEvs::Event>(~noopts[i].opval&noval);
1545  else noval = static_cast<XrdOfsEvs::Event>( noopts[i].opval|noval);
1546  break;
1547  }
1548  }
1549  if (i >= numopts)
1550  Eroute.Say("Config warning: ignoring invalid notify event '",val,"'.");
1551  val = Config.GetWord();
1552  }
1553 
1554 // Check if we have a program here and some events
1555 //
1556  if (!val) {Eroute.Emsg("Config","notify program not specified");return 1;}
1557  if (!noval) {Eroute.Emsg("Config","notify events not specified"); return 1;}
1558 
1559 // Get the remaining parameters
1560 //
1561  Config.RetToken();
1562  if (!Config.GetRest(parms, sizeof(parms)))
1563  {Eroute.Emsg("Config", "notify parameters too long"); return 1;}
1564  val = (*parms == '|' ? parms+1 : parms);
1565 
1566 // Create an notification object
1567 //
1568  if (evsObject) delete evsObject;
1569  evsObject = new XrdOfsEvs(noval, val, msgL, msgB);
1570 
1571 // All done
1572 //
1573  return 0;
1574 }
1575 
1576 /******************************************************************************/
1577 /* x p e r s */
1578 /******************************************************************************/
1579 
1580 /* Function: xpers
1581 
1582  Purpose: To parse the directive: persist [auto | manual | off]
1583  [hold <sec>] [logdir <dirp>]
1584  [sync <snum>]
1585 
1586  auto POSC processing always on for creation requests
1587  manual POSC processing must be requested (default)
1588  off POSC processing is disabled
1589  <sec> Seconds inclomplete files held (default 10m)
1590  <dirp> Directory to hold POSC recovery log (default adminpath)
1591  <snum> Number of outstanding equests before syncing to disk.
1592 
1593  Output: 0 upon success or !0 upon failure.
1594 */
1595 
1596 int XrdOfs::xpers(XrdOucStream &Config, XrdSysError &Eroute)
1597 {
1598  char *val;
1599  int snum = -1, htime = -1, popt = -2;
1600 
1601  if (!(val = Config.GetWord()))
1602  {Eroute.Emsg("Config","persist option not specified");return 1;}
1603 
1604 // Check for valid option
1605 //
1606  if (!strcmp(val, "auto" )) popt = 1;
1607  else if (!strcmp(val, "off" )) popt = -1;
1608  else if (!strcmp(val, "manual" )) popt = 0;
1609 
1610 // Check if we should get the next token
1611 //
1612  if (popt > -2) val = Config.GetWord();
1613 
1614 // Check for hold or log
1615 //
1616  while(val)
1617  { if (!strcmp(val, "hold"))
1618  {if (!(val = Config.GetWord()))
1619  {Eroute.Emsg("Config","persist hold value not specified");
1620  return 1;
1621  }
1622  if (XrdOuca2x::a2tm(Eroute,"persist hold",val,&htime,0))
1623  return 1;
1624  }
1625  else if (!strcmp(val, "logdir"))
1626  {if (!(val = Config.GetWord()))
1627  {Eroute.Emsg("Config","persist logdir path not specified");
1628  return 1;
1629  }
1630  if (poscLog) free(poscLog);
1631  poscLog = strdup(val);
1632  }
1633  else if (!strcmp(val, "sync"))
1634  {if (!(val = Config.GetWord()))
1635  {Eroute.Emsg("Config","sync value not specified");
1636  return 1;
1637  }
1638  if (XrdOuca2x::a2i(Eroute,"sync value",val,&snum,0,32767))
1639  return 1;
1640  }
1641  else Eroute.Say("Config warning: ignoring invalid persist option '",val,"'.");
1642  val = Config.GetWord();
1643  }
1644 
1645 // Set values as needed
1646 //
1647  if (htime >= 0) poscHold = htime;
1648  if (popt > -2) poscAuto = popt;
1649  if (snum > -1) poscSync = snum;
1650  return 0;
1651 }
1652 
1653 /******************************************************************************/
1654 /* x r o l e */
1655 /******************************************************************************/
1656 
1657 /* Function: xrole
1658 
1659  Purpose: Parse: role { {[meta] | [proxy]} manager
1660  | [proxy] server
1661  | [proxy] supervisor
1662  } [if ...]
1663 
1664  manager xrootd: act as a manager (redirecting server). Prefixes:
1665  meta - connect only to manager meta's
1666  proxy - ignored
1667  cmsd: accept server subscribes and redirectors. Prefix
1668  modifiers do the following:
1669  meta - No other managers apply
1670  proxy - manage a cluster of proxy servers
1671 
1672  server xrootd: act as a server (supply local data). Prefix
1673  modifications do the following:
1674  proxy - server is part of a cluster. A local
1675  cmsd is required.
1676  cmsd: subscribe to a manager, possibly as a proxy.
1677 
1678  supervisor xrootd: equivalent to manager. The prefix modification
1679  is ignored.
1680  cmsd: equivalent to manager but also subscribe to a
1681  manager. When proxy is specified, then subscribe
1682  as a proxy and only accept proxies.
1683 
1684  if Apply the manager directive if "if" is true. See
1685  XrdOucUtils:doIf() for "if" syntax.
1686 
1687  Notes 1. The peer designation only affects how the olbd communicates.
1688 
1689  Type: Server only, non-dynamic.
1690 
1691  Output: 0 upon success or !0 upon failure.
1692 */
1693 
1694 int XrdOfs::xrole(XrdOucStream &Config, XrdSysError &Eroute)
1695 {
1696  const int resetit = ~haveRole;
1697  XrdCmsRole::RoleID roleID;
1698  char *val, *Tok1, *Tok2;
1699  int rc, ropt = 0;
1700 
1701 // Get the first token
1702 //
1703  if (!(val = Config.GetWord()) || !strcmp(val, "if"))
1704  {Eroute.Emsg("Config", "role not specified"); return 1;}
1705  Tok1 = strdup(val);
1706 
1707 // Get second token which might be an "if"
1708 //
1709  if ((val = Config.GetWord()) && strcmp(val, "if"))
1710  {Tok2 = strdup(val);
1711  val = Config.GetWord();
1712  } else Tok2 = 0;
1713 
1714 // Process the if at this point
1715 //
1716  if (val && !strcmp("if", val))
1717  {if ((rc = XrdOucUtils::doIf(&Eroute,Config,"role directive",
1718  getenv("XRDHOST"), XrdOucUtils::InstName(1),
1719  getenv("XRDPROG"))) <= 0)
1720  {free(Tok1); if (Tok2) free(Tok2);
1721  if (!rc) Config.noEcho();
1722  return (rc < 0);
1723  }
1724  }
1725 
1726 // Convert the role names to a role ID, if possible
1727 //
1728  roleID = XrdCmsRole::Convert(Tok1, Tok2);
1729 
1730 // Set markers based on the role we have
1731 //
1732  rc = 0;
1733  switch(roleID)
1734  {case XrdCmsRole::MetaManager: ropt = isManager | isMeta ; break;
1735  case XrdCmsRole::Manager: ropt = isManager ; break;
1736  case XrdCmsRole::Supervisor: ropt = isSuper ; break;
1737  case XrdCmsRole::Server: ropt = isServer ; break;
1738  case XrdCmsRole::ProxyManager: ropt = isManager | isProxy; break;
1739  case XrdCmsRole::ProxySuper: ropt = isSuper | isProxy; break;
1740  case XrdCmsRole::ProxyServer: ropt = isServer | isProxy; break;
1741  default: Eroute.Emsg("Config", "invalid role -", Tok1, Tok2); rc = 1;
1742  }
1743 
1744 // Release storage and return if an error occurred
1745 //
1746  free(Tok1);
1747  if (Tok2) free(Tok2);
1748  if (rc) return rc;
1749 
1750 // Set values
1751 //
1752  free(myRole);
1753  myRole = strdup(XrdCmsRole::Name(roleID));
1754  strcpy(myRType, XrdCmsRole::Type(roleID));
1755  Options &= resetit;
1756  Options |= ropt;
1757  return 0;
1758 }
1759 
1760 /******************************************************************************/
1761 /* x t p c */
1762 /******************************************************************************/
1763 
1764 /* Function: xtpc
1765 
1766  Purpose: To parse the directive: tpc [cksum <type>] [ttl <dflt> [<max>]]
1767  [logok] [xfr <n>] [allow <parms>]
1768  [require {all|client|dest} <auth>[+]]
1769  [restrict <path>]
1770  [streams <num>[,<max>]]
1771  [echo] [scan {stderr | stdout}]
1772  [autorm] [pgm <path> [parms]]
1773  [fcreds [?]<auth> =<evar>]
1774  [fcpath <path>] [oids]
1775 
1776  tpc redirect [xdlg] <host>:<port> [<cgi>]
1777 
1778  xdlg: delegated | undelegated
1779 
1780  parms: [dn <name>] [group <grp>] [host <hn>] [vo <vo>]
1781 
1782  <dflt> the default seconds a tpc authorization may be valid.
1783  <max> the maximum seconds a tpc authorization may be valid.
1784  cksum checksum incoming files using <type> checksum.
1785  logok log successful authorizations.
1786  allow only allow destinations that match the specified
1787  authentication specification.
1788  <n> maximum number of simultaneous transfers.
1789  <num> the default number of TCP streams to use for the copy.
1790  <max> The maximum number of TCP streams to use for the copy/
1791  <auth> require that the client, destination, or both (i.e. all)
1792  use the specified authentication protocol. Additional
1793  require statements may be specified to add additional
1794  valid authentication mechanisms. If the <auth> is suffixed
1795  by a plus, then the request must also be encrypted using
1796  the authentication's session key.
1797  echo echo the pgm's output to the log.
1798  autorm Remove file when copy fails.
1799  scan scan fr error messages either in stderr or stdout. The
1800  default is to scan both.
1801  pgm specifies the transfer command with optional paramaters.
1802  It must be the last parameter on the line.
1803  fcreds Forward destination credentials for protocol <auth>. The
1804  request fails if thee are no credentials for <auth>. If a
1805  question mark preceeds <auth> then if the client has not
1806  forwarded its credentials, the server's credentials are
1807  used. Otherwise, the copy fails.
1808  =<evar> the name of the envar to be set with the path to the
1809  credentials to be forwarded.
1810  fcpath where creds are stored (default <adminpath>/.ofs/.tpccreds).
1811  oids Object ID's are acceptable for the source lfn.
1812  <host> The redirection target host which may be localhost.
1813  <port> The redirection target port.
1814  <cgi> Optional cgi information.
1815 
1816  Output: 0 upon success or !0 upon failure.
1817 */
1818 
1819 int XrdOfs::xtpc(XrdOucStream &Config, XrdSysError &Eroute)
1820 {
1821  char *val, pgm[1024];
1823  *pgm = 0;
1824  int reqType;
1825  bool rdrok = true;
1826 
1827  while((val = Config.GetWord()))
1828  {if (!strcmp(val, "redirect"))
1829  {if (rdrok) return xtpcr(Config, Eroute);
1830  Eroute.Emsg("Config", "tpc redirect must be seprately specified.");
1831  return 1;
1832  }
1833  rdrok = false;
1834  if (!strcmp(val, "allow"))
1835  {if (!xtpcal(Config, Eroute)) return 1;
1836  continue;
1837  }
1838  if (!strcmp(val, "cksum"))
1839  {if (!(val = Config.GetWord()))
1840  {Eroute.Emsg("Config","cksum type not specified"); return 1;}
1841  if (Parms.cksType) free(Parms.cksType);
1842  Parms.cksType = strdup(val);
1843  continue;
1844  }
1845  if (!strcmp(val, "scan"))
1846  {if (!(val = Config.GetWord()))
1847  {Eroute.Emsg("Config","scan type not specified"); return 1;}
1848  if (strcmp(val, "stderr")) Parms.errMon = -2;
1849  else if (strcmp(val, "stdout")) Parms.errMon = -1;
1850  else if (strcmp(val, "all" )) Parms.errMon = 0;
1851  else {Eroute.Emsg("Config","invalid scan type -",val); return 1;}
1852  continue;
1853  }
1854  if (!strcmp(val, "echo")) {Parms.doEcho = true; continue;}
1855  if (!strcmp(val, "logok")) {Parms.LogOK = true; continue;}
1856  if (!strcmp(val, "autorm")){Parms.autoRM = true; continue;}
1857  if (!strcmp(val, "oids")) {Parms.noids = false;continue;}
1858  if (!strcmp(val, "pgm"))
1859  {if (!Config.GetRest(pgm, sizeof(pgm)))
1860  {Eroute.Emsg("Config", "tpc command line too long"); return 1;}
1861  if (!*pgm)
1862  {Eroute.Emsg("Config", "tpc program not specified"); return 1;}
1863  if (Parms.XfrProg) free(Parms.XfrProg);
1864  Parms.XfrProg = strdup( pgm );
1865  break;
1866  }
1867  if (!strcmp(val, "require"))
1868  {if (!(val = Config.GetWord()))
1869  {Eroute.Emsg("Config","tpc require parameter not specified"); return 1;}
1870  if (!strcmp(val, "all")) reqType = XrdOfsTPC::reqALL;
1871  else if (!strcmp(val, "client")) reqType = XrdOfsTPC::reqORG;
1872  else if (!strcmp(val, "dest")) reqType = XrdOfsTPC::reqDST;
1873  else {Eroute.Emsg("Config", "invalid tpc require type -", val); return 1;}
1874  break;
1875  if (!(val = Config.GetWord()))
1876  {Eroute.Emsg("Config","tpc require auth not specified"); return 1;}
1877  XrdOfsTPC::Require(val, reqType);
1878  continue;
1879  }
1880  if (!strcmp(val, "restrict"))
1881  {if (!(val = Config.GetWord()))
1882  {Eroute.Emsg("Config","tpc restrict path not specified"); return 1;}
1883  if (*val != '/')
1884  {Eroute.Emsg("Config","tpc restrict path not absolute"); return 1;}
1885  if (!XrdOfsTPC::Restrict(val)) return 1;
1886  continue;
1887  }
1888  if (!strcmp(val, "ttl"))
1889  {if (!(val = Config.GetWord()))
1890  {Eroute.Emsg("Config","tpc ttl value not specified"); return 1;}
1891  if (XrdOuca2x::a2tm(Eroute,"tpc ttl default",val,&Parms.dflTTL,1))
1892  return 1;
1893  if (!(val = Config.GetWord())) break;
1894  if (!(isdigit(*val))) {Config.RetToken(); continue;}
1895  if (XrdOuca2x::a2tm(Eroute,"tpc ttl maximum",val,&Parms.maxTTL,1))
1896  return 1;
1897  continue;
1898  }
1899  if (!strcmp(val, "xfr"))
1900  {if (!(val = Config.GetWord()))
1901  {Eroute.Emsg("Config","tpc xfr value not specified"); return 1;}
1902  if (XrdOuca2x::a2i(Eroute,"tpc xfr",val,&Parms.xfrMax,1)) return 1;
1903  continue;
1904  }
1905  if (!strcmp(val, "streams"))
1906  {if (!(val = Config.GetWord()))
1907  {Eroute.Emsg("Config","tpc streams value not specified"); return 1;}
1908  char *comma = index(val,',');
1909  if (comma)
1910  {*comma++ = 0;
1911  if (!(*comma))
1912  {Eroute.Emsg("Config","tpc streams max value missing"); return 1;}
1913  if (XrdOuca2x::a2i(Eroute,"tpc max streams",comma,&Parms.tcpSMax,0,15))
1914  return 1;
1915  }
1916  if (XrdOuca2x::a2i(Eroute,"tpc streams",val,&Parms.tcpSTRM,0,15)) return 1;
1917  continue;
1918  }
1919  if (!strcmp(val, "fcreds"))
1920  {char aBuff[64];
1921  Parms.fCreds = true;
1922  if (!(val = Config.GetWord()) || (*val == '?' && *(val+1) == '\0'))
1923  {Eroute.Emsg("Config","tpc fcreds auth not specified"); return 1;}
1924  if (strlen(val) >= sizeof(aBuff))
1925  {Eroute.Emsg("Config","invalid fcreds auth -", val); return 1;}
1926  strcpy(aBuff, val);
1927  if (!(val = Config.GetWord()) || *val != '=' || *(val+1) == 0)
1928  {Eroute.Emsg("Config","tpc fcreds envar not specified"); return 1;}
1929  const char *emsg = XrdOfsTPC::AddAuth(aBuff,val+1);
1930  if (emsg) {Eroute.Emsg("Config",emsg,"-", val); return 1;}
1931  continue;
1932  }
1933  if (!strcmp(val, "fcpath"))
1934  {if (!(val = Config.GetWord()))
1935  {Eroute.Emsg("Config","tpc fcpath arg not specified"); return 1;}
1936  if (Parms.cPath) free(Parms.cPath);
1937  Parms.cPath = strdup(val);
1938  continue;
1939  }
1940  Eroute.Say("Config warning: ignoring invalid tpc option '",val,"'.");
1941  }
1942 
1943  Options |= ThirdPC;
1944  return 0;
1945 }
1946 
1947 /******************************************************************************/
1948 /* x t p c a l */
1949 /******************************************************************************/
1950 
1951 int XrdOfs::xtpcal(XrdOucStream &Config, XrdSysError &Eroute)
1952 {
1953  struct tpcalopts {const char *opname; char *opval;} tpopts[] =
1954  {{"dn", 0}, {"group", 0}, {"host", 0}, {"vo", 0}};
1955  int i, spec = 0, numopts = sizeof(tpopts)/sizeof(struct tpcalopts);
1956  char *val;
1957 
1958  while((val = Config.GetWord()))
1959  {for (i = 0; i < numopts && strcmp(tpopts[i].opname, val); i++) {}
1960  if (i > numopts) {Config.RetToken(); break;}
1961  {Eroute.Emsg("Config", "invalid tpc allow parameter -", val);
1962  return 0;
1963  }
1964  if (!(val = Config.GetWord()))
1965  {Eroute.Emsg("Config","tpc allow",tpopts[i].opname,"value not specified");
1966  return 0;
1967  }
1968  if (tpopts[i].opval) free(tpopts[i].opval);
1969  tpopts[i].opval = strdup(val);
1970  spec = 1;
1971  }
1972 
1973  if (!spec) {Eroute.Emsg("Config","tpc allow parms not specified"); return 1;}
1974 
1975  XrdOfsTPC::Allow(tpopts[0].opval, tpopts[1].opval,
1976  tpopts[2].opval, tpopts[3].opval);
1977  return 1;
1978 }
1979 
1980 /******************************************************************************/
1981 /* x t p c r */
1982 /******************************************************************************/
1983 
1984 int XrdOfs::xtpcr(XrdOucStream &Config, XrdSysError &Eroute)
1985 {
1986  char hname[256];
1987  const char *cgi, *cgisep, *hBeg, *hEnd, *pBeg, *pEnd, *eText;
1988  char *val;
1989  int n, port, dlgI;
1990 
1991 // Get the next token
1992 //
1993  if (!(val = Config.GetWord()))
1994  {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
1995 
1996 // See if this is for delegated or undelegated (all is the default)
1997 //
1998  if (!strcmp(val, "delegated")) dlgI = 0;
1999  else if (!strcmp(val, "undelegated")) dlgI = 1;
2000  else dlgI = -1;
2001 
2002 // Get host and port
2003 //
2004  if (dlgI >= 0 && !(val = Config.GetWord()))
2005  {Eroute.Emsg("Config", "tpc redirect host not specified"); return 1;}
2006 
2007 // Parse this as it may be complicated.
2008 //
2009  if (!XrdNetUtils::Parse(val, &hBeg, &hEnd, &pBeg, &pEnd))
2010  {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
2011 
2012 // Copy out the host target (make sure it's not too long)
2013 //
2014  n = hEnd - hBeg;
2015  if (*val == '[') n += 2;
2016  if (n >= (int)sizeof(hname))
2017  {Eroute.Emsg("Config", "Invalid tpc redirect target -", val); return 1;}
2018  strncpy(hname, val, n);
2019  hname[n] = 0;
2020 
2021 // Substitute our hostname for localhost if present
2022 //
2023  if (!strcmp(hname, "localhost"))
2024  {char *myHost = XrdNetUtils::MyHostName(0, &eText);
2025  if (!myHost)
2026  {Eroute.Emsg("Config", "Unable to determine tpc localhost;",eText);
2027  return 1;
2028  }
2029  n = snprintf(hname, sizeof(hname), "%s", myHost);
2030  free(myHost);
2031  if (n >= (int)sizeof(hname))
2032  {Eroute.Emsg("Config", "Invalid tpc localhost resolution -", hname);
2033  return 1;
2034  }
2035  }
2036 
2037 // Make sure a port was specified
2038 //
2039  if (pBeg == hEnd)
2040  {Eroute.Emsg("Config", "tpc redirect port not specified"); return 1;}
2041 
2042 // Get the numeric version of the port number
2043 //
2044  if (!(port = XrdNetUtils::ServPort(pBeg, false, &eText)))
2045  {Eroute.Emsg("Config", "Invalid tpc redirect port;",eText); return 1;}
2046 
2047 // Check if there is cgi that must be included
2048 //
2049  if (!(cgi = Config.GetWord())) cgisep = cgi = (char *)"";
2050  else cgisep = (*cgi != '?' ? "?" : "");
2051 
2052 // Copy out the hostname to be used
2053 //
2054  int k = (dlgI < 0 ? 0 : dlgI);
2055 do{if (tpcRdrHost[k]) {free(tpcRdrHost[k]); tpcRdrHost[k] = 0;}
2056 
2057  n = strlen(hname) + strlen(cgisep) + strlen(cgi) + 1;
2058  tpcRdrHost[k] = (char *)malloc(n);
2059  snprintf(tpcRdrHost[k], n, "%s%s%s", hname, cgisep, cgi);
2060  tpcRdrPort[k] = port;
2061  k++;
2062  } while(dlgI < 0 && k < 2);
2063 
2064 // All done
2065 //
2066  Options |= RdrTPC;
2067  return 0;
2068 }
2069 
2070 /******************************************************************************/
2071 /* x t r a c e */
2072 /******************************************************************************/
2073 
2074 /* Function: xtrace
2075 
2076  Purpose: To parse the directive: trace <events>
2077 
2078  <events> the blank separated list of events to trace. Trace
2079  directives are cummalative.
2080 
2081  Output: 0 upon success or !0 upon failure.
2082 */
2083 
2084 int XrdOfs::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
2085 {
2086  static struct traceopts {const char *opname; int opval;} tropts[] =
2087  {{"aio", TRACE_aio},
2088  {"all", TRACE_ALL},
2089  {"chkpnt", TRACE_chkpnt},
2090  {"chmod", TRACE_chmod},
2091  {"close", TRACE_close},
2092  {"closedir", TRACE_closedir},
2093  {"debug", TRACE_debug},
2094  {"delay", TRACE_delay},
2095  {"dir", TRACE_dir},
2096  {"exists", TRACE_exists},
2097  {"getstats", TRACE_getstats},
2098  {"fsctl", TRACE_fsctl},
2099  {"io", TRACE_IO},
2100  {"mkdir", TRACE_mkdir},
2101  {"most", TRACE_MOST},
2102  {"open", TRACE_open},
2103  {"opendir", TRACE_opendir},
2104  {"qscan", TRACE_qscan},
2105  {"read", TRACE_read},
2106  {"readdir", TRACE_readdir},
2107  {"redirect", TRACE_redirect},
2108  {"remove", TRACE_remove},
2109  {"rename", TRACE_rename},
2110  {"sync", TRACE_sync},
2111  {"truncate", TRACE_truncate},
2112  {"write", TRACE_write}
2113  };
2114  int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2115  char *val;
2116 
2117  if (!(val = Config.GetWord()))
2118  {Eroute.Emsg("Config", "trace option not specified"); return 1;}
2119  while (val)
2120  {if (!strcmp(val, "off")) trval = 0;
2121  else {if ((neg = (val[0] == '-' && val[1]))) val++;
2122  for (i = 0; i < numopts; i++)
2123  {if (!strcmp(val, tropts[i].opname))
2124  {if (neg) trval &= ~tropts[i].opval;
2125  else trval |= tropts[i].opval;
2126  break;
2127  }
2128  }
2129  if (i >= numopts)
2130  Eroute.Say("Config warning: ignoring invalid trace option '",val,"'.");
2131  }
2132  val = Config.GetWord();
2133  }
2134  OfsTrace.What = trval;
2135 
2136 // All done
2137 //
2138  return 0;
2139 }
2140 
2141 /******************************************************************************/
2142 /* x a t r */
2143 /******************************************************************************/
2144 
2145 /* Function: xatr
2146 
2147  Purpose: To parse the directive: xattr [maxnsz <nsz>] [maxvsz <vsz>]
2148 
2149  [uset {on|off}]
2150 
2151  on enables user settable extended attributes.
2152 
2153  off disaables user settable extended attributes.
2154 
2155  <nsz> maximum length of an attribute name. The user
2156  specifiable limit will be 8 less.
2157 
2158  <vsz> maximum length of an attribute value.
2159 
2160  Notes: 1. This directive is not cummalative.
2161 
2162  Output: 0 upon success or !0 upon failure.
2163 */
2164 
2165 int XrdOfs::xatr(XrdOucStream &Config, XrdSysError &Eroute)
2166 {
2167  char *val;
2168  static const int xanRsv = 7;
2169  long long vtmp;
2170  int maxN = kXR_faMaxNlen, maxV = kXR_faMaxVlen;
2171  bool isOn = true;
2172 
2173  while((val = Config.GetWord()))
2174  { if (!strcmp("maxnsz", val))
2175  {if (!(val = Config.GetWord()))
2176  {Eroute.Emsg("Config","xattr maxnsz value not specified");
2177  return 1;
2178  }
2179  if (XrdOuca2x::a2sz(Eroute,"maxnsz",val,&vtmp,
2180  xanRsv+1,kXR_faMaxNlen+xanRsv)) return 1;
2181  maxN = static_cast<int>(vtmp);
2182  }
2183  else if (!strcmp("maxvsz", val))
2184  {if (!(val = Config.GetWord()))
2185  {Eroute.Emsg("Config","xattr maxvsz value not specified");
2186  return 1;
2187  }
2188  if (XrdOuca2x::a2sz(Eroute,"maxvsz",val,&vtmp,0,kXR_faMaxVlen))
2189  return 1;
2190  maxV = static_cast<int>(vtmp);
2191  }
2192  else if (!strcmp("uset", val))
2193  {if (!(val = Config.GetWord()))
2194  {Eroute.Emsg("Config","xattr uset value not specified");
2195  return 1;
2196  }
2197  if (!strcmp("on", val)) isOn = true;
2198  else if (!strcmp("off", val)) isOn = false;
2199  else {Eroute.Emsg("Config", "invalid xattr uset value -", val);
2200  return 1;
2201  }
2202  }
2203  else {Eroute.Emsg("Config", "invalid xattr option -", val);
2204  return 1;
2205  }
2206  }
2207 
2208  usxMaxNsz = (isOn ? maxN-xanRsv : 0);
2209  usxMaxVsz = maxV;
2210  return 0;
2211 }
2212 
2213 /******************************************************************************/
2214 /* t h e R o l e */
2215 /******************************************************************************/
2216 
2217 const char *XrdOfs::theRole(int opts)
2218 {
2219  if (opts & isPeer) return "peer";
2220  else if (opts & isManager
2221  && opts & isServer) return "supervisor";
2222  else if (opts & isManager) return "manager";
2223  else if (opts & isProxy) {return "proxy";}
2224  return "server";
2225 }
@ kXR_faMaxVlen
Definition: XProtocol.hh:312
@ kXR_faMaxNlen
Definition: XProtocol.hh:311
XrdSysLogger myLogger
Definition: XrdAccTest.cc:65
#define TRACE_delay
Definition: XrdBwmTrace.hh:75
#define TRACE_debug
Definition: XrdBwmTrace.hh:78
XrdCmsClient *(* XrdCmsClient_t)(XrdSysLogger *, int, int, XrdOss *)
#define setBuff(x, y)
#define TS_Bit(x, m, v)
XrdScheduler * ofsSchedP
Definition: XrdOfsConfig.cc:99
XrdOss * XrdOfsOss
Definition: XrdOfs.cc:165
XrdVERSIONINFO(XrdOfs, XrdOfs)
#define TS_XPI(x, m)
XrdSysTrace OfsTrace
#define TS_Xeq(x, m)
XrdOfsStats OfsStats
Definition: XrdOfs.cc:115
XrdOfs * XrdOfsFS
Definition: XrdOfsFS.cc:47
#define TRACE_dir
Definition: XrdOfsTrace.hh:77
#define TRACE_rename
Definition: XrdOfsTrace.hh:90
#define TRACE_read
Definition: XrdOfsTrace.hh:81
#define TRACE_qscan
Definition: XrdOfsTrace.hh:79
#define TRACE_getstats
Definition: XrdOfsTrace.hh:94
#define TRACE_chkpnt
Definition: XrdOfsTrace.hh:99
#define TRACE_exists
Definition: XrdOfsTrace.hh:85
#define TRACE_close
Definition: XrdOfsTrace.hh:80
#define TRACE_open
Definition: XrdOfsTrace.hh:78
#define TRACE_sync
Definition: XrdOfsTrace.hh:91
#define TRACE_truncate
Definition: XrdOfsTrace.hh:92
#define TRACE_remove
Definition: XrdOfsTrace.hh:89
#define TRACE_redirect
Definition: XrdOfsTrace.hh:82
#define TRACE_opendir
Definition: XrdOfsTrace.hh:73
#define TRACE_chmod
Definition: XrdOfsTrace.hh:86
#define TRACE_closedir
Definition: XrdOfsTrace.hh:75
#define TRACE_IO
Definition: XrdOfsTrace.hh:84
#define TRACE_readdir
Definition: XrdOfsTrace.hh:74
#define TRACE_mkdir
Definition: XrdOfsTrace.hh:95
#define TRACE_MOST
Definition: XrdOfsTrace.hh:71
#define TRACE_fsctl
Definition: XrdOfsTrace.hh:93
#define TRACE_aio
Definition: XrdOfsTrace.hh:97
#define TRACE_write
Definition: XrdOfsTrace.hh:83
#define XRDOSS_HASFICL
Definition: XrdOss.hh:544
#define XRDOSS_HASRPXY
Definition: XrdOss.hh:542
#define XRDOSS_HASCACH
Definition: XrdOss.hh:540
#define XRDOSS_HASPRXY
Definition: XrdOss.hh:538
#define XRDOSS_HASXERT
Definition: XrdOss.hh:543
#define XRDOSS_HASNOSF
Definition: XrdOss.hh:539
#define XRDOSS_HASPGRW
Definition: XrdOss.hh:536
#define XRDOSS_HASNAIO
Definition: XrdOss.hh:541
#define open
Definition: XrdPosix.hh:78
#define unlink(a)
Definition: XrdPosix.hh:119
struct myOpts opts
int emsg(int rc, char *msg)
size_t strlcpy(char *dst, const char *src, size_t sz)
#define TRACE_ALL
Definition: XrdTrace.hh:35
virtual XrdCksCalc * Object(const char *name)
Definition: XrdCks.hh:214
virtual XrdOucTList * Managers()
static bool VCheck(XrdVersionInfo &urVersion)
static bool VCheck(XrdVersionInfo &urVersion)
static const char * Name(RoleID rid)
Definition: XrdCmsRole.hh:63
static RoleID Convert(const char *Tok1, const char *Tok2)
Definition: XrdCmsRole.hh:47
static const char * Type(RoleID rid)
Definition: XrdCmsRole.hh:78
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
Definition: XrdNetUtils.cc:702
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
Definition: XrdNetUtils.cc:874
static bool Parse(const char *hSpec, const char **hName, const char **hNend, const char **hPort, const char **hPend)
Definition: XrdNetUtils.cc:780
static void Init(XrdCks *cp, XrdOucEnv *ep)
static void setRDSZ(int sz)
static bool Init()
static bool Parse(XrdOucStream &Config)
bool ConfigCtl(XrdCmsClient *cmscP, XrdOucEnv *envP=0)
void Default(TheLib what, const char *lpath, const char *lparm=0)
void SetCksRdSz(int rdsz)
bool Plugin(XrdAccAuthorize *&piP)
Get Authorization plugin.
static XrdOfsConfigPI * New(const char *cfn, XrdOucStream *cfgP, XrdSysError *errP, XrdVersionInfo *verP=0, XrdSfsFileSystem *sfsP=0)
bool Load(int what, XrdOucEnv *envP=0)
bool Configure(XrdCmsClient *cmscP, XrdOucEnv *envP)
@ theOssLib
Oss plugin.
@ allXXXLib
All plugins (Load() only)
@ theCksLib
Checksum manager plugin.
void Display()
Display configuration settings.
int Init(XrdSysError *eObj)
Definition: XrdOfsEvr.cc:132
static int Parse(XrdSysError &Eroute, Event eNum, char *mText)
Definition: XrdOfsEvs.cc:287
int maxSmsg()
Definition: XrdOfsEvs.hh:141
int maxLmsg()
Definition: XrdOfsEvs.hh:142
int Start(XrdSysError *eobj)
Definition: XrdOfsEvs.cc:394
const char * Prog()
Definition: XrdOfsEvs.hh:148
int Enabled(Event theEvents)
Definition: XrdOfsEvs.hh:139
virtual bool Configure(const char *CfgFN, const char *Parms, XrdOucEnv *envP, const Plugins &plugs)
The Plugins struct is used to pass plugin pointers to configure.
int Retire(int &retc, long long *retsz=0, char *buff=0, int blen=0)
int PoscSet(const char *User, int Unum, short Mode)
static const int opPC
static int Alloc(const char *thePath, int Opts, XrdOfsHandle **Handle)
int Del(const char *Lfn, int Offset, int Unlink=0)
Definition: XrdOfsPoscq.cc:159
recEnt * Init(int &Ok)
Definition: XrdOfsPoscq.cc:207
void setRole(const char *theRole)
Definition: XrdOfsStats.hh:68
static int Restrict(const char *Path)
Definition: XrdOfsTPC.cc:465
static const int reqDST
Definition: XrdOfsTPC.hh:86
static const char * AddAuth(const char *auth, const char *avar)
Definition: XrdOfsTPC.cc:164
static void Init()
Definition: XrdOfsTPC.cc:414
static int Start()
Definition: XrdOfsTPC.cc:520
static const int reqORG
Definition: XrdOfsTPC.hh:87
static void Require(const char *Auth, int RType)
Definition: XrdOfsTPC.cc:445
static void Allow(char *vDN, char *vGN, char *vHN, char *vVO)
Definition: XrdOfsTPC.cc:209
static const int reqALL
Definition: XrdOfsTPC.hh:85
struct fwdOpt fwdTRUNC
Definition: XrdOfs.hh:425
mode_t dMask[2]
Definition: XrdOfs.hh:394
int myPort
Definition: XrdOfs.hh:390
XrdCmsClient * Finder
Definition: XrdOfs.hh:439
mode_t fMask[2]
Definition: XrdOfs.hh:395
struct fwdOpt fwdRMDIR
Definition: XrdOfs.hh:424
XrdOfsEvr evrObject
Definition: XrdOfs.hh:438
char * ConfigFN
Definition: XrdOfs.hh:430
int tpcRdrPort[2]
Definition: XrdOfs.hh:400
@ isProxy
Definition: XrdOfs.hh:377
@ haveRole
Definition: XrdOfs.hh:382
@ RdrTPC
Definition: XrdOfs.hh:386
@ ThirdPC
Definition: XrdOfs.hh:384
@ isMeta
Definition: XrdOfs.hh:381
@ SubCluster
Definition: XrdOfs.hh:385
@ isManager
Definition: XrdOfs.hh:378
@ isPeer
Definition: XrdOfs.hh:376
@ isSuper
Definition: XrdOfs.hh:380
@ isServer
Definition: XrdOfs.hh:379
@ Authorize
Definition: XrdOfs.hh:374
@ Forwarding
Definition: XrdOfs.hh:383
virtual int Configure(XrdSysError &)
struct fwdOpt fwdMKPATH
Definition: XrdOfs.hh:421
void Config_Display(XrdSysError &)
char * tpcRdrHost[2]
Definition: XrdOfs.hh:399
int Options
Definition: XrdOfs.hh:389
struct fwdOpt fwdMKDIR
Definition: XrdOfs.hh:420
static int MaxDelay
Definition: XrdOfs.hh:427
struct fwdOpt fwdMV
Definition: XrdOfs.hh:422
XrdNetIF * myIF
Definition: XrdOfs.hh:404
const char * getVersion()
struct fwdOpt fwdRM
Definition: XrdOfs.hh:423
virtual int ConfigXeq(char *var, XrdOucStream &, XrdSysError &)
bool ValidCST(const char *cst)
struct fwdOpt fwdCHMOD
Definition: XrdOfs.hh:419
void Unpersist(XrdOfsHandle *hP, int xcev=1)
Definition: XrdOfs.cc:2933
virtual uint64_t Features()
Definition: XrdOss.cc:60
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
static int Export(const char *Var, const char *Val)
Definition: XrdOucEnv.cc:188
void * GetPtr(const char *varname)
Definition: XrdOucEnv.cc:281
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:316
void Put(const char *varname, const char *value)
Definition: XrdOucEnv.hh:85
static const int retFile
static const int retLink
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
Definition: XrdOucTUtils.hh:51
static char * genPath(const char *path, const char *inst, const char *psfx=0)
Definition: XrdOucUtils.cc:506
static const char * InstName(int TranOpt=0)
Definition: XrdOucUtils.cc:852
static bool mode2mask(const char *mode, mode_t &mask)
static int doIf(XrdSysError *eDest, XrdOucStream &Config, const char *what, const char *hname, const char *nname, const char *pname)
Definition: XrdOucUtils.cc:280
static int makePath(char *path, mode_t mode, bool reset=false)
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
virtual void EnvInfo(XrdOucEnv *envP)
uint64_t FeatureSet
Adjust features at initialization.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
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:162
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:175
@ IsTarget
The role is server and will be a redirection target.
@ IsProxy
The role is proxy {plus one or more of the below}.
@ IsRedir
The role is manager and will redirect users.
@ IsMeta
The role is meta {plus one or more of the above}.
XrdCmsConfig Config
XrdOfsTPCConfig Cfg
Definition: XrdOfsTPC.cc:85
XrdOucEnv * envP
Definition: XrdPss.cc:110
static const uint64_t hasAUTZ
Feature: Authorization.
Definition: XrdSfsFlags.hh:44
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions)
Definition: XrdSfsFlags.hh:62
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 hasFICL
Feature: Supports file cloning and samefs.
Definition: XrdSfsFlags.hh:80
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
struct Request reqData
Definition: XrdOfsPoscq.hh:61
XrdXrootdTpcMon * tpcMon
const char * Cmd
Definition: XrdOfs.hh:409
char * Host
Definition: XrdOfs.hh:410
void Reset()
Definition: XrdOfs.hh:412
struct NSEnt * Next
Definition: XrdOucNSWalk.hh:48