XRootD
XrdCpConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C p C o n f i g . c c */
4 /* */
5 /* (c) 2011 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 Department 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 <fcntl.h>
32 #include <getopt.h>
33 #include <cstdio>
34 #include <cstdlib>
35 #include <cstring>
36 #include <sys/stat.h>
37 #include <sys/types.h>
38 
39 #include "XrdVersion.hh"
40 #include "XrdApps/XrdCpConfig.hh"
41 #include "XrdApps/XrdCpFile.hh"
42 #include "XrdCks/XrdCksCalc.hh"
43 #include "XrdCks/XrdCksManager.hh"
44 #include "XrdOuc/XrdOucStream.hh"
45 #include "XrdSys/XrdSysE2T.hh"
46 #include "XrdSys/XrdSysError.hh"
47 #include "XrdSys/XrdSysHeaders.hh"
48 #include "XrdSys/XrdSysLogger.hh"
49 
50 
51 /******************************************************************************/
52 /* D e f i n e M a c r o s */
53 /******************************************************************************/
54 
55 #define EMSG(x) std::cerr <<PName <<": " <<x <<std::endl
56 
57 #define FMSG(x,y) {EMSG(x);exit(y);}
58 
59 #define UMSG(x) {EMSG(x);Usage(22);}
60 
61 #define ZMSG(x) {EMSG(x);return 0;}
62 
63 // Bypass stupid issue with stupid solaris for missdefining 'struct opt'.
64 //
65 #ifdef __solaris__
66 #define OPT_TYPE (char *)
67 #else
68 #define OPT_TYPE
69 #endif
70 
71 /******************************************************************************/
72 /* S t a t i c M e m b e r s */
73 /******************************************************************************/
74 
76 {
78 static XrdSysError eDest(&Logger, "");
79 };
80 
82 
83 const char *XrdCpConfig::opLetters = ":C:d:D:EfFhHI:NpPrRsS:t:T:vVX:y:z:ZA";
84 
85 struct option XrdCpConfig::opVec[] = // For getopt_long()
86  {
87  {OPT_TYPE "allow-http", 0, 0, XrdCpConfig::OpAllowHttp},
88  {OPT_TYPE "cksum", 1, 0, XrdCpConfig::OpCksum},
89  {OPT_TYPE "coerce", 0, 0, XrdCpConfig::OpCoerce},
90  {OPT_TYPE "continue", 0, 0, XrdCpConfig::OpContinue},
91  {OPT_TYPE "debug", 1, 0, XrdCpConfig::OpDebug},
92  {OPT_TYPE "dynamic-src", 0, 0, XrdCpConfig::OpDynaSrc},
93  {OPT_TYPE "force", 0, 0, XrdCpConfig::OpForce},
94  {OPT_TYPE "help", 0, 0, XrdCpConfig::OpHelp},
95  {OPT_TYPE "infiles", 1, 0, XrdCpConfig::OpIfile},
96  {OPT_TYPE "license", 0, 0, XrdCpConfig::OpLicense},
97  {OPT_TYPE "nopbar", 0, 0, XrdCpConfig::OpNoPbar},
98  {OPT_TYPE "notlsok", 0, 0, XrdCpConfig::OpNoTlsOK},
99  {OPT_TYPE "parallel", 1, 0, XrdCpConfig::OpParallel},
100  {OPT_TYPE "path", 0, 0, XrdCpConfig::OpPath},
101  {OPT_TYPE "posc", 0, 0, XrdCpConfig::OpPosc},
102  {OPT_TYPE "proxy", 1, 0, XrdCpConfig::OpProxy},
103  {OPT_TYPE "recursive", 0, 0, XrdCpConfig::OpRecurse},
104  {OPT_TYPE "retry", 1, 0, XrdCpConfig::OpRetry},
105  {OPT_TYPE "retry-policy", 1, 0, XrdCpConfig::OpRetryPolicy},
106  {OPT_TYPE "rm-bad-cksum", 0, 0, XrdCpConfig::OpRmOnBadCksum},
107  {OPT_TYPE "server", 0, 0, XrdCpConfig::OpServer},
108  {OPT_TYPE "silent", 0, 0, XrdCpConfig::OpSilent},
109  {OPT_TYPE "sources", 1, 0, XrdCpConfig::OpSources},
110  {OPT_TYPE "streams", 1, 0, XrdCpConfig::OpStreams},
111  {OPT_TYPE "tlsmetalink", 0, 0, XrdCpConfig::OpTlsMLF},
112  {OPT_TYPE "tlsnodata", 0, 0, XrdCpConfig::OpTlsNoData},
113  {OPT_TYPE "tpc", 1, 0, XrdCpConfig::OpTpc},
114  {OPT_TYPE "verbose", 0, 0, XrdCpConfig::OpVerbose},
115  {OPT_TYPE "version", 0, 0, XrdCpConfig::OpVersion},
116  {OPT_TYPE "xattr", 0, 0, XrdCpConfig::OpXAttr},
117  {OPT_TYPE "xrate", 1, 0, XrdCpConfig::OpXrate},
118  {OPT_TYPE "xrate-threshold",1, 0, XrdCpConfig::OpXrateThreshold},
119  {OPT_TYPE "zip", 1, 0, XrdCpConfig::OpZip},
120  {OPT_TYPE "zip-append", 0, 0, XrdCpConfig::OpZipAppend},
121  {OPT_TYPE "zip-mtln-cksum", 0, 0, XrdCpConfig::OpZipMtlnCksum},
122  {0, 0, 0, 0}
123  };
124 
125 /******************************************************************************/
126 /* C o n s t r u c t o r */
127 /******************************************************************************/
128 
129 XrdCpConfig::XrdCpConfig(const char *pgm)
130 {
131  if ((PName = rindex(pgm, '/'))) PName++;
132  else PName = pgm;
133  XrdCpFile::SetMsgPfx(PName);
134  intDefs = 0;
135  intDend = 0;
136  strDefs = 0;
137  strDend = 0;
138  dstOpq = 0;
139  srcOpq = 0;
140  pHost = 0;
141  pPort = 0;
142  xRate = 0;
143  xRateThreshold = 0;
144  Parallel = 1;
145  OpSpec = 0;
146  Dlvl = 0;
147  nSrcs = 1;
148  nStrm = 0;
149  Retry =-1;
150  RetryPolicy = "force";
151  Verbose = 0;
152  numFiles = 0;
153  totBytes = 0;
154  CksLen = 0;
155  CksMan = 0;
156  CksObj = 0;
157  CksVal = 0;
158  srcFile = 0;
159  dstFile = 0;
160  inFile = 0;
161  parmVal = 0;
162  parmCnt = 0;
163  zipFile = 0;
164 }
165 
166 /******************************************************************************/
167 /* D e s t r u c t o r */
168 /******************************************************************************/
169 
171 {
172  XrdCpFile *pNow;
173  defVar *dP;
174 
175  if (inFile) free(inFile);
176  if (pHost) free(pHost);
177  if (parmVal) free(parmVal);
178  if (CksObj) delete CksObj;
179  if (CksMan) delete CksMan;
180  if (zipFile) free(zipFile);
181  if (dstFile) delete dstFile;
182 
183  while((pNow = pFile)) {pFile = pFile->Next; delete pNow;}
184 
185  while((dP = intDefs)) {intDefs = dP->Next; delete dP;}
186  while((dP = strDefs)) {strDefs = dP->Next; delete dP;}
187 
188 }
189 
190 /******************************************************************************/
191 /* C o n f i g */
192 /******************************************************************************/
193 
194 void XrdCpConfig::Config(int aCnt, char **aVec, int opts)
195 {
196  extern char *optarg;
197  extern int optind, opterr;
198  static int pgmSet = 0;
199  char Buff[128], *Path, opC;
200  XrdCpFile pBase;
201  int i, rc;
202 
203 // Allocate a parameter vector
204 //
205  if (parmVal) free(parmVal);
206  parmVal = (char **)malloc(aCnt*sizeof(char *));
207 
208 // Preset handling options
209 //
210  Argv = aVec;
211  Argc = aCnt;
212  Opts = opts;
213  opterr = 0;
214  optind = 1;
215  opC = 0;
216 
217 // Set name of executable for error messages
218 //
219  if (!pgmSet)
220  {char *Slash = rindex(aVec[0], '/');
221  pgmSet = 1;
222  Pgm = (Slash ? Slash+1 : aVec[0]);
223  Log->SetPrefix(Pgm);
224  }
225 
226 // Process legacy options first before atempting normal options
227 //
228 do{while(optind < Argc && Legacy(optind)) {}
229  if ((opC = getopt_long(Argc, Argv, opLetters, opVec, &i)) != (char)-1)
230  switch(opC)
231  {case OpCksum: defCks(optarg);
232  break;
233  case OpCoerce: OpSpec |= DoCoerce;
234  break;
235  case OpDebug: OpSpec |= DoDebug;
236  if (!a2i(optarg, &Dlvl, 0, 3)) Usage(22);
237  break;
238  case OpDynaSrc: OpSpec |= DoDynaSrc;
239  break;
240  case OpForce: OpSpec |= DoForce;
241  break;
242  case OpZip: OpSpec |= DoZip;
243  if (zipFile) free(zipFile);
244  zipFile = strdup(optarg);
245  break;
246  case OpHelp: Usage(0);
247  break;
248  case OpIfile: if (inFile) free(inFile);
249  inFile = strdup(optarg);
250  OpSpec |= DoIfile;
251  break;
252  case OpLicense: License();
253  break;
254  case OpNoPbar: OpSpec |= DoNoPbar;
255  break;
256  case OpNoTlsOK: OpSpec |= DoNoTlsOK;
257  break;
258  case OpPath: OpSpec |= DoPath;
259  break;
260  case OpPosc: OpSpec |= DoPosc;
261  break;
262  case OpProxy: OpSpec |= DoProxy;
263  defPxy(optarg);
264  break;
265  case OpRecurse: OpSpec |= DoRecurse;
266  break;
267  case OpRecursv: OpSpec |= DoRecurse;
268  break;
269  case OpRetry: OpSpec |= DoRetry;
270  if (!a2i(optarg, &Retry, 0, -1)) Usage(22);
271  break;
273  RetryPolicy = optarg;
274  if( RetryPolicy != "force" && RetryPolicy != "continue" ) Usage(22);
275  break;
276  case OpZipAppend: OpSpec |= DoZipAppend;
277  break;
279  break;
280  case OpSilent: OpSpec |= DoSilent|DoNoPbar;
281  break;
282  case OpSources: OpSpec |= DoSources;
283  if (!a2i(optarg, &nSrcs, 1, 32)) Usage(22);
284  break;
285  case OpStreams: OpSpec |= DoStreams;
286  if (!a2i(optarg, &nStrm, 1, 15)) Usage(22);
287  break;
288  case OpTlsNoData: OpSpec |= DoTlsNoData;
289  break;
290  case OpTlsMLF: OpSpec |= DoTlsMLF;
291  break;
292  case OpTpc: OpSpec |= DoTpc;
293  if (!strcmp("delegate", optarg))
294  {OpSpec|= DoTpcDlgt;
295  if (optind >= Argc)
296  {UMSG("Missing tpc qualifier after "
297  "'delegate'");
298  }
299  optarg = Argv[optind++];
300  }
301  if (!strcmp("only", optarg)) OpSpec|= DoTpcOnly;
302  else if (strcmp("first", optarg))
303  {optind--;
304  UMSG("Invalid option, '" <<OpName()
305  <<' ' <<optarg <<"' ");
306  }
307  break;
308  case OpVerbose: OpSpec |= DoVerbose;
309  Verbose = 1;
310  break;
311  case OpVersion: std::cerr <<XrdVERSION <<std::endl; exit(0);
312  break;
313  case OpXrate: OpSpec |= DoXrate;
314  if (!a2z(optarg, &xRate, 10*1024LL, -1)) Usage(22);
315  break;
317  if (!a2z(optarg, &xRateThreshold, 10*1024LL, -1)) Usage(22);
318  break;
319  case OpParallel: OpSpec |= DoParallel;
320  if (!a2i(optarg, &Parallel, 1, 128)) Usage(22);
321  break;
322  case OpAllowHttp: OpSpec |= DoAllowHttp;
323  break;
324  case OpXAttr : OpSpec |= DoXAttr;
325  break;
327  break;
329  break;
330  case OpContinue : OpSpec |= DoContinue;
331  break;
332  case ':': UMSG("'" <<OpName() <<"' argument missing.");
333  break;
334  case '?': if (!Legacy(optind-1))
335  UMSG("Invalid option, '" <<OpName() <<"'.");
336  break;
337  default: UMSG("Internal error processing '" <<OpName() <<"'.");
338  break;
339  }
340  } while(opC != (char)-1 && optind < Argc);
341 
342 // Make sure we have the right number of files
343 //
344  if (inFile) {if (!parmCnt ) UMSG("Destination not specified.");}
345  else { if (!parmCnt ) UMSG("No files specified.");
346  if ( parmCnt == 1 ) UMSG("Destination not specified.");
347  }
348 
349 // Check for conflicts wit third party copy
350 //
351  if (OpSpec & DoTpc && nSrcs > 1)
352  UMSG("Third party copy requires a single source.");
353 
354 // Check for conflicts with ZIP archive
355 //
356  if( OpSpec & DoZip & DoCksrc )
357  UMSG("Cannot calculate source checksum for a file in ZIP archive.");
358 
359  if( ( OpSpec & DoZip & DoCksum ) && !CksData.HasValue() )
360  UMSG("Cannot calculate source checksum for a file in ZIP archive.");
361 
362 // Turn off verbose if we are in server mode
363 //
364  if (OpSpec & DoServer)
365  {OpSpec &= ~DoVerbose;
366  Verbose = 0;
367  }
368 
369 // Turn on auto-path creation if requested via envar
370 //
371  if (getenv("XRD_MAKEPATH")) OpSpec |= DoPath;
372 
373 // Process the destination first as it is special
374 //
375  dstFile = new XrdCpFile(parmVal[--parmCnt], rc);
376  if (rc) FMSG("Invalid url, '" <<dstFile->Path <<"'.", 22);
377 
378 // Allow HTTP if XRDCP_ALLOW_HTTP is set
379  if (getenv("XRDCP_ALLOW_HTTP")) {
380  OpSpec |= DoAllowHttp;
381  }
382 
383 // Do a protocol check
384 //
392  {FMSG(dstFile->ProtName <<"file protocol is not supported.", 22)}
393 
394 // Resolve this file if it is a local file
395 //
396  isLcl = (dstFile->Protocol == XrdCpFile::isFile)
398  if (isLcl && (rc = dstFile->Resolve()))
399  {if (rc != ENOENT || (Argc - optind - 1) > 1 || OpSpec & DoRecurse)
400  FMSG(XrdSysE2T(rc) <<" processing " <<dstFile->Path, 2);
401  }
402 
403 // Now pick up all the source files from the command line
404 //
405  pLast = &pBase;
406  for (i = 0; i < parmCnt; i++) ProcFile(parmVal[i]);
407 
408 // If an input file list was specified, process it as well
409 //
410  if (inFile)
412  char *fname;
413  int inFD = open(inFile, O_RDONLY);
414  if (inFD < 0) FMSG(XrdSysE2T(errno) <<" opening infiles " <<inFile, 2);
415  inList.Attach(inFD);
416  while((fname = inList.GetLine())) if (*fname) ProcFile(fname);
417  }
418 
419 // Check if we have any sources or too many sources
420 //
421  if (!numFiles) UMSG("Source not specified.");
422  if (Opts & opt1Src && numFiles > 1)
423  FMSG("Only a single source is allowed.", 2);
424  srcFile = pBase.Next;
425 
426 // Check if we have an appropriate destination
427 //
430  FMSG("Destination is neither remote nor a directory.", 2);
431 
432 // Do the dumb check
433 //
434  if (isLcl && Opts & optNoLclCp)
435  FMSG("All files are local; use 'cp' instead!", 1);
436 
437 // Check for checksum spec conflicts
438 //
439  if (OpSpec & DoCksum)
440  {if (CksData.Length && numFiles > 1)
441  FMSG("Checksum with fixed value requires a single input file.", 2);
442  if (CksData.Length && OpSpec & DoRecurse)
443  FMSG("Checksum with fixed value conflicts with '--recursive'.", 2);
444  }
445 
446 // Now extend all local sources if recursive is in effect
447 //
448  if (OpSpec & DoRecurse && !(Opts & optNoXtnd))
449  {pPrev = &pBase; pBase.Next = srcFile;
450  while((pFile = pPrev->Next))
451  {if (pFile->Protocol != XrdCpFile::isDir) pPrev = pFile;
452  else {Path = pFile->Path;
453  pPrev->Next = pFile->Next;
454  if (Verbose) EMSG("Indexing files in " <<Path);
455  numFiles--;
456  if ((rc = pFile->Extend(&pLast, numFiles, totBytes)))
457  FMSG(XrdSysE2T(rc) <<" indexing " <<Path, 2);
458  if (pFile->Next)
459  {pLast->Next = pPrev->Next;
460  pPrev->Next = pFile->Next;
461  }
462  delete pFile;
463  }
464  }
465  if (!(srcFile = pBase.Next))
466  FMSG("No regular files found to copy!", 2);
467  if (Verbose) EMSG("Copying " <<Human(totBytes, Buff, sizeof(Buff))
468  <<" from " <<numFiles
469  <<(numFiles != 1 ? " files." : " file."));
470  }
471 }
472 
473 /******************************************************************************/
474 /* P r i v a t e M e t h o d s */
475 /******************************************************************************/
476 /******************************************************************************/
477 /* Private: a 2 i */
478 /******************************************************************************/
479 
480 int XrdCpConfig::a2i(const char *item, int *val, int minv, int maxv)
481 {
482  char *eP;
483 
484 // Convert the numeric argument
485 //
486  errno = 0;
487  *val = strtol(item, &eP, 10);
488  if (errno || *eP) ZMSG("'" <<OpName() <<"' argument is not a number.");
489 
490 // Impose min/max limits
491 //
492  if (*val < minv)
493  ZMSG("'" <<OpName() <<"' argument must be >= " <<minv <<'.');
494  if (maxv >= 0 && *val > maxv)
495  ZMSG("'" <<OpName() <<"' argument must be <= " <<maxv <<'.');
496  return 1;
497 }
498 /******************************************************************************/
499 /* Private: a 2 l */
500 /******************************************************************************/
501 
502 int XrdCpConfig::a2l(const char *item, long long *val,
503  long long minv, long long maxv)
504 {
505  char *eP;
506 
507 // Convert the numeric argument
508 //
509  errno = 0;
510  *val = strtoll(item, &eP, 10);
511  if (errno || *eP) ZMSG("'" <<OpName() <<"' argument is not a number.");
512 
513 // Impose min/max limits
514 //
515  if (*val < minv)
516  ZMSG("'" <<OpName() <<"' argument must be >= " <<minv <<'.');
517  if (maxv >= 0 && *val > maxv)
518  ZMSG("'" <<OpName() <<"' argument must be <= " <<maxv <<'.');
519  return 1;
520 }
521 
522 /******************************************************************************/
523 /* Private: a 2 t */
524 /******************************************************************************/
525 
526 int XrdCpConfig::a2t(const char *item, int *val, int minv, int maxv)
527 { int qmult;
528  char *eP, *fP = (char *)item + strlen(item) - 1;
529 
530 // Get scaling
531 //
532  if (*fP == 's' || *fP == 'S') qmult = 1;
533  else if (*fP == 'm' || *fP == 'M') qmult = 60;
534  else if (*fP == 'h' || *fP == 'H') qmult = 60*60;
535  else if (*fP == 'd' || *fP == 'D') qmult = 60*60*24;
536  else {qmult = 1; fP++;}
537 
538 // Convert the value
539 //
540  errno = 0;
541  *val = strtoll(item, &eP, 10) * qmult;
542  if (errno || eP != fP)
543  ZMSG("'" <<OpName() <<"' argument is not a valid time.");
544 
545 // Impose min/max limits
546 //
547  if (*val < minv)
548  ZMSG("'" <<OpName() <<"' argument must be >= " <<minv <<'.');
549  if (maxv >= 0 && *val > maxv)
550  ZMSG("'" <<OpName() <<"' argument must be <= " <<maxv <<'.');
551  return 1;
552 }
553 
554 /******************************************************************************/
555 /* Private: a 2 x */
556 /******************************************************************************/
557 
558 int XrdCpConfig::a2x(const char *Val, char *Buff, int Vlen)
559 {
560  int n, i = 0, Odd = 0;
561  if (Vlen & 0x01) return 0;
562  while(Vlen--)
563  { if (*Val >= '0' && *Val <= '9') n = *Val-48;
564  else if (*Val >= 'a' && *Val <= 'f') n = *Val-87;
565  else if (*Val >= 'A' && *Val <= 'F') n = *Val-55;
566  else return 0;
567  if (Odd) Buff[i++] |= n;
568  else Buff[i ] = n << 4;
569  Val++; Odd = ~Odd;
570  }
571  return 1;
572 }
573 
574 /******************************************************************************/
575 /* Private: a 2 z */
576 /******************************************************************************/
577 
578 int XrdCpConfig::a2z(const char *item, long long *val,
579  long long minv, long long maxv)
580 { long long qmult;
581  char *eP, *fP = (char *)item + strlen(item) - 1;
582 
583 // Get scaling
584 //
585  if (*fP == 'k' || *fP == 'K') qmult = 1024LL;
586  else if (*fP == 'm' || *fP == 'M') qmult = 1024LL*1024LL;
587  else if (*fP == 'g' || *fP == 'G') qmult = 1024LL*1024LL*1024LL;
588  else if (*fP == 't' || *fP == 'T') qmult = 1024LL*1024LL*1024LL*1024LL;
589  else {qmult = 1; fP++;}
590 
591 // Convert the value
592 //
593  errno = 0;
594  *val = strtoll(item, &eP, 10) * qmult;
595  if (errno || eP != fP)
596  ZMSG("'" <<OpName() <<"' argument is not a valid time.");
597 
598 // Impose min/max limits
599 //
600  if (*val < minv)
601  ZMSG("'" <<OpName() <<"' argument must be >= " <<minv <<'.');
602  if (maxv >= 0 && *val > maxv)
603  ZMSG("'" <<OpName() <<"' argument must be <= " <<maxv <<'.');
604  return 1;
605 }
606 
607 /******************************************************************************/
608 /* Private: d e f C k s */
609 /******************************************************************************/
610 
611 int XrdCpConfig::defCks(const char *opval)
612 {
613  if( CksVal )
614  {
615  std::string cksum( opval );
616  size_t pos = cksum.find( ':' );
617  std::string mode = cksum.substr( pos + 1 );
618  if( mode != "source" )
619  FMSG("Additional checksum must be of mode 'source'.", 13);
620  AddCksVal.push_back( cksum.substr( 0, pos ) );
621  return 1;
622  }
623 
624  static XrdVERSIONINFODEF(myVer, xrdcp, XrdVNUMBER, XrdVERSION);
625  const char *Colon = index(opval, ':');
626  char csName[XrdCksData::NameSize];
627  int n;
628 
629 // Initialize the checksum manager if we have not done so already
630 //
631  if (!CksMan)
632  {CksMan = new XrdCksManager(Log, 0, myVer, true);
633  if (!(CksMan->Init("")))
634  {delete CksMan; CksMan = 0;
635  FMSG("Unable to initialize checksum processing.", 13);
636  }
637  }
638 
639 // Copy out the checksum name
640 //
641  n = (Colon ? Colon - opval : strlen(opval));
642  if (n >= XrdCksData::NameSize)
643  UMSG("Invalid checksum type, '" <<opval <<"'.");
644  strncpy(csName, opval, n); csName[n] = 0;
645  toLower( csName );
646 
647 // Get a checksum object for this checksum
648 //
649  if( strcmp( csName, "auto" ) )
650  {
651  if (CksObj) {delete CksObj; CksObj = 0;}
652  if (!CksData.Set(csName) || !(CksObj = CksMan->Object(CksData.Name)))
653  UMSG("Invalid checksum type, '" <<csName <<"'.");
654  CksObj->Type(CksLen);
655  }
656 
657 // Reset checksum information
658 //
659  CksData.Length = 0;
660  OpSpec &= ~(DoCkprt | DoCksrc | DoCksum);
661 
662 // Check for any additional arguments
663 //
664  if (Colon)
665  {Colon++;
666  if (!(*Colon)) UMSG(CksData.Name <<" argument missing after ':'.");
667  if (!strcmp(Colon, "print")) OpSpec |= (DoCkprt | DoCksum);
668  else if (!strcmp(Colon, "source")) OpSpec |= (DoCkprt | DoCksrc);
669  else {n = strlen(Colon);
670  if (n != CksLen*2 || !CksData.Set(Colon, n))
671  UMSG("Invalid " <<CksData.Name <<" value '" <<Colon <<"'.");
672  OpSpec |= DoCksum;
673  }
674  } else OpSpec |= DoCksum;
675 
676 // All done
677 //
678  CksVal = opval;
679  return 1;
680 }
681 
682 /******************************************************************************/
683 /* Private: d e f O p q */
684 /******************************************************************************/
685 
686 int XrdCpConfig::defOpq(const char *theOp)
687 {
688  const char *oVal = theOp+3;
689 
690 // Make sure opaque information was specified
691 //
692  if (!(*oVal)) UMSG("'" <<theOp <<"' opaque data not specified.");
693 
694 // Set proper opaque data
695 //
696  if (*(theOp+2) == 'S') srcOpq = oVal;
697  else dstOpq = oVal;
698 
699 // All done
700 //
701  return 1;
702 }
703 
704 /******************************************************************************/
705 /* Private: d e f O p t */
706 /******************************************************************************/
707 
708 int XrdCpConfig::defOpt(const char *theOp, const char *theArg)
709 {
710  defVar *dP;
711  int opval, isInt = (*(theOp+2) == 'I');
712  const char *vName = theOp+3;
713  char *eP;
714 
715 // Make sure define variable name specified
716 //
717  if (!(*vName)) UMSG("'" <<theOp <<"' variable not specified.");
718 
719 // Make sure we have a value
720 //
721  if (!theArg) UMSG("'" <<theOp <<"' argument not specified.");
722 
723 // For integer arguments convert the value
724 //
725  if (isInt)
726  {errno = 0;
727  opval = strtol(theArg, &eP, 10);
728  if (errno || *eP) UMSG("'" <<theOp <<"' argument is not a number.");
729  dP = new defVar(vName, opval);
730  if (!intDend) intDefs = intDend = dP;
731  else {intDend->Next = dP; intDend = dP;}
732  } else {
733  dP = new defVar(vName, theArg);
734  if (!strDend) strDefs = strDend = dP;
735  else {strDend->Next = dP; strDend = dP;}
736  }
737 
738 // Convert the argument
739 //
740  return 2;
741 }
742 
743 /******************************************************************************/
744 /* Private: d e f P x y */
745 /******************************************************************************/
746 
747 void XrdCpConfig::defPxy(const char *opval)
748 {
749  const char *Colon = index(opval, ':');
750  char *eP;
751  int n;
752 
753 // Make sure the host was specified
754 //
755  if (Colon == opval) UMSG("Proxy host not specified.");
756 
757 // Make sure the port was specified
758 //
759  if (!Colon || !(*(Colon+1))) UMSG("Proxy port not specified.");
760 
761 // Make sure the port is a valid number that is not too big
762 //
763  errno = 0;
764  pPort = strtol(Colon+1, &eP, 10);
765  if (errno || *eP || pPort < 1 || pPort > 65535)
766  UMSG("Invalid proxy port, '" <<opval <<"'.");
767 
768 // Copy out the proxy host
769 //
770  if (pHost) free(pHost);
771  n = Colon - opval + 1;
772  pHost = (char *)malloc(n);
773  strncpy(pHost, opval, n-1);
774  pHost[n-1] = 0;
775 }
776 
777 
778 /******************************************************************************/
779 /* H u m a n */
780 /******************************************************************************/
781 
782 const char *XrdCpConfig::Human(long long inval, char *Buff, int Blen)
783 {
784  static const char *sfx[] = {" bytes", "KB", "MB", "GB", "TB", "PB"};
785  unsigned int i;
786 
787  for (i = 0; i < sizeof(sfx)/sizeof(sfx[0]) - 1 && inval >= 1024; i++)
788  inval = inval/1024;
789 
790  snprintf(Buff, Blen, "%lld%s", inval, sfx[i]);
791  return Buff;
792 }
793 
794 /******************************************************************************/
795 /* Private: L e g a c y */
796 /******************************************************************************/
797 
798 int XrdCpConfig::Legacy(int oIndex)
799 {
800  extern int optind;
801  char *oArg;
802  int rc;
803 
804 // if (!Argv[oIndex]) return 0;
805 
806  while(oIndex < Argc && (*Argv[oIndex] != '-' || *(Argv[oIndex]+1) == '\0'))
807  parmVal[parmCnt++] = Argv[oIndex++];
808  if (oIndex >= Argc) return 0;
809 
810  if (oIndex+1 >= Argc || *Argv[oIndex+1] == '-') oArg = 0;
811  else oArg = Argv[oIndex+1];
812  if (!(rc = Legacy(Argv[oIndex], oArg))) return 0;
813  optind = oIndex + rc;
814 
815  return 1;
816 }
817 
818 /******************************************************************************/
819 
820 int XrdCpConfig::Legacy(const char *theOp, const char *theArg)
821 {
822  if (!strcmp(theOp, "-adler")) return defCks("adler32:source");
823 
824  if (!strncmp(theOp, "-DI", 3) || !strncmp(theOp, "-DS", 3))
825  return defOpt(theOp, theArg);
826 
827  if (!strcmp(theOp, "-extreme") || !strcmp(theOp, "-x"))
828  {if (nSrcs <= 1) {nSrcs = dfltSrcs; OpSpec |= DoSources;}
829  return 1;
830  }
831 
832  if (!strcmp(theOp, "-np")) {OpSpec |= DoNoPbar; return 1;}
833 
834  if (!strcmp(theOp, "-md5")) return defCks("md5:source");
835 
836  if (!strncmp(theOp,"-OD",3) || !strncmp(theOp,"-OS",3)) return defOpq(theOp);
837 
838  if (!strcmp(theOp, "-version")) {std::cerr <<XrdVERSION <<std::endl; exit(0);}
839 
840  if (!strcmp(theOp, "-force"))
841  FMSG("-force is no longer supported; use --retry instead!",22);
842 
843  return 0;
844 }
845 
846 /******************************************************************************/
847 /* Private: L i c e n s e */
848 /******************************************************************************/
849 
850 void XrdCpConfig::License()
851 {
852  const char *theLicense =
853 #include "../../LICENSE"
854 ;
855 
856  std::cerr <<theLicense;
857  exit(0);
858 }
859 
860 /******************************************************************************/
861 /* Private: O p N a m e */
862 /******************************************************************************/
863 
864 const char *XrdCpConfig::OpName()
865 {
866  extern int optind, optopt;
867  static char oName[4] = {'-', 0, 0, 0};
868 
869  if (!optopt || optopt == '-' || *(Argv[optind-1]+1) == '-')
870  return Argv[optind-1];
871  oName[1] = optopt;
872  return oName;
873 }
874 
875 /******************************************************************************/
876 /* p r o c F i l e */
877 /******************************************************************************/
878 
879 void XrdCpConfig::ProcFile(const char *fname)
880 {
881  int rc;
882 
883 // Chain in this file in the input list
884 //
885  pLast->Next = pFile = new XrdCpFile(fname, rc);
886  if (rc) FMSG("Invalid url, '" <<fname <<"'.", 22);
887 
888 // For local files, make sure it exists and get its size
889 //
890  if (pFile->Protocol == XrdCpFile::isFile && (rc = pFile->Resolve()))
891  FMSG(XrdSysE2T(rc) <<" processing " <<pFile->Path, 2);
892 
893 // Process file based on type (local or remote)
894 //
895  if (pFile->Protocol == XrdCpFile::isFile) totBytes += pFile->fSize;
896  else if (pFile->Protocol == XrdCpFile::isDir)
897  {if (!(OpSpec & DoRecurse))
898  FMSG(pFile->Path <<" is a directory.", 2);
899  }
900  else if (pFile->Protocol == XrdCpFile::isStdIO)
901  {if (Opts & optNoStdIn)
902  FMSG("Using stdin as a source is disallowed.", 22);
903  if (numFiles)
904  FMSG("Multiple sources disallowed with stdin.", 22);
905  }
906  else if (!((pFile->Protocol == XrdCpFile::isXroot) ||
907  (pFile->Protocol == XrdCpFile::isXroots) ||
908  (pFile->Protocol == XrdCpFile::isPelican) ||
909  (pFile->Protocol == XrdCpFile::isS3) ||
910  (Want(DoAllowHttp) && ((pFile->Protocol == XrdCpFile::isHttp) ||
911  (pFile->Protocol == XrdCpFile::isHttps)))))
912  {FMSG(pFile->ProtName <<" file protocol is not supported.", 22)}
913  else if (OpSpec & DoRecurse && !(Opts & optRmtRec))
914  {FMSG("Recursive copy from a remote host is not supported.",22)}
915  else isLcl = 0;
916 
917 // Update last pointer and we are done if this is stdin
918 //
919  numFiles++;
920  pLast = pFile;
921 }
922 
923 /******************************************************************************/
924 /* U s a g e */
925 /******************************************************************************/
926 
927 void XrdCpConfig::Usage(int rc)
928 {
929  static const char *Syntax = "\n"
930  "Usage: xrdcp [<options>] <src> [<src> [. . .]] <dest>\n";
931 
932  static const char *Syntax1= "\n"
933  "Usage: xrdcp [<options>] <src> <dest>\n";
934 
935  static const char *Options= "\n"
936  "Options: [--allow-http] [--cksum <args>] [--coerce] [--continue]\n"
937  " [--debug <lvl>] [--dynamic-src] [--force] [--help]\n"
938  " [--infiles <fn>] [--license] [--nopbar] [--notlsok]\n"
939  " [--parallel <n>] [--posc] [--proxy <host>:<port>]\n"
940  " [--recursive] [--retry <n>] [--retry-policy <force|continue>]\n"
941  " [--rm-bad-cksum] [--server] [--silent] [--sources <n>]\n"
942  " [--streams <n>] [--tlsmetalink] [--tlsnodata]\n"
943  " [--tpc [delegate] {first|only}] [--verbose] [--version]\n"
944  " [--xattr] [--xrate <rate>] [--xrate-threshold <rate>]\n"
945  " [--zip <file>] [--zip-append] [--zip-mtln-cksum]\n";
946 
947  static const char *Syntax2= "\n"
948  "<src>: [[x]root[s]://<host>[:<port>]/]<path> | -";
949 
950  static const char *Syntay2= "\n"
951  "<src>: [[x]root[s]://<host>[:<port>]/]<path>";
952 
953  static const char *Syntax3= "\n"
954  "<dest>: [[x]root[s]://<host>[:<port>]/]<path> | -";
955 
956  static const char *Detail = "\n"
957  "Note: using a dash (-) for <src> uses stdin and for <dest> stdout\n\n"
958  "-A | --allow-http allow HTTP as source or destination protocol. Requires\n"
959  " the XrdClHttp client plugin\n"
960  "-C | --cksum <args> verifies the checksum at the destination as provided\n"
961  " by the source server or locally computed. The args are\n"
962  " <ckstype>[:{<value>|print|source}]\n"
963  " where <ckstype> is one of adler32, crc32, crc32c, md5,\n"
964  " zcrc32 or auto. If 'auto' is chosen, xrdcp will try to\n"
965  " automatically infer the right checksum type based on the\n"
966  " source/destination configuration, source file type\n"
967  " (e.g. metalink, ZIP), and available checksum plug-ins.\n"
968  " If the hex value of the checksum is given, it is used.\n"
969  " Otherwise, the server's checksum is used for remote files\n"
970  " and computed for local files. Specifying print merely\n"
971  " prints the checksum but does not verify it.\n"
972  "-F | --coerce coerces the copy by ignoring file locking semantics\n"
973  " --continue continue copying a file from the point where the previous\n"
974  " copy was interrupted\n"
975  "-d | --debug <lvl> sets the debug level: 0 off, 1 low, 2 medium, 3 high\n"
976  "-Z | --dynamic-src file size may change during the copy\n"
977  "-f | --force replaces any existing output file\n"
978  "-h | --help prints this information\n"
979  "-I | --infiles <fname> specifies the file that contains a list of input files\n"
980  "-H | --license prints license terms and conditions\n"
981  "-N | --nopbar does not print the progress bar\n"
982  " --notlsok if server is too old to support TLS encryption fallback\n"
983  " to unencrypted communication\n"
984  " --parallel <n> number of files to copy at the same time\n"
985  "-P | --posc enables persist on successful close semantics\n"
986  "-D | --proxy <host>:<port> uses the specified SOCKS4 proxy connection\n"
987  "-r | --recursive recursively copies all source files\n"
988  "-t | --retry <n> maximum number of times to retry failed copy-jobs\n"
989  " --retry-policy <policy> retry policy: force or continue\n"
990  " --rm-bad-cksum remove the target file if checksum verification failed\n"
991  " (enables also POSC semantics)\n"
992  " --server runs in a server environment with added operations\n"
993  "-s | --silent produces no output other than error messages\n"
994  "-y | --sources <n> uses up to the number of sources specified in parallel\n"
995  "-S | --streams <n> copies using the specified number of TCP connections\n"
996  " --tlsmetalink convert [x]root to [x]roots protocol in metalinks\n"
997  "-E | --tlsnodata in case of [x]roots protocol, encrypt only the control\n"
998  " stream and leave the data streams unencrypted\n"
999  "-T | --tpc <args> uses third party copy mode between the src and dest.\n"
1000  " Both the src and dest must allow tpc mode. Argument\n"
1001  " 'first' tries tpc and if it fails, does a normal copy;\n"
1002  " while 'only' fails the copy unless tpc succeeds.\n"
1003  "-v | --verbose produces more information about the copy\n"
1004  "-V | --version prints the version number\n"
1005  " --xattr preserve extended attributes\n"
1006  "-X | --xrate <rate> limits the transfer to the specified rate. You can\n"
1007  " suffix the value with 'k', 'm', or 'g'\n"
1008  " --xrate-threshold <rate> If the transfer rate drops below given threshold force\n"
1009  " the client to use different source or if no more sources\n"
1010  " are available fail the transfer. You can suffix the value\n"
1011  " with 'k', 'm', or 'g'\n"
1012  "-z | --zip <file> treat the source as a ZIP archive containing given file\n"
1013  " --zip-append append file to existing zip archive\n"
1014  " --zip-mtln-cksum use the checksum available in a metalink file even if\n"
1015  " a file is being extracted from a ZIP archive\n"
1016  "\n"
1017  "Legacy options: [-adler] [-DI<var> <val>] [-DS<var> <val>] [-np]\n"
1018  " [-md5] [-OD<cgi>] [-OS<cgi>] [-version] [-x]";
1019 
1020  std::cerr <<(Opts & opt1Src ? Syntax1 : Syntax) <<Options;
1021  std::cerr <<(Opts & optNoStdIn ? Syntay2 : Syntax2) <<Syntax3 <<std::endl;
1022  if (!rc) std::cerr <<Detail <<std::endl;
1023  exit(rc);
1024 }
int inList(const char *var, const char **Vec)
#define OPT_TYPE
Definition: XrdCpConfig.cc:68
#define ZMSG(x)
Definition: XrdCpConfig.cc:61
#define FMSG(x, y)
Definition: XrdCpConfig.cc:57
#define EMSG(x)
Definition: XrdCpConfig.cc:55
#define UMSG(x)
Definition: XrdCpConfig.cc:59
static XrdSysError eDest(0,"crypto_")
int optopt
int optind
#define open
Definition: XrdPosix.hh:76
XrdOucString Path
struct myOpts opts
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
virtual const char * Type(int &csSize)=0
int Set(const char *csName)
Definition: XrdCksData.hh:81
char Length
Definition: XrdCksData.hh:52
bool HasValue()
Definition: XrdCksData.hh:125
static const int NameSize
Definition: XrdCksData.hh:41
char Name[NameSize]
Definition: XrdCksData.hh:44
virtual int Init(const char *ConfigFN, const char *DfltCalc=0)=0
virtual XrdCksCalc * Object(const char *name)
Definition: XrdCks.hh:214
static void SetMsgPfx(const char *pfx)
Definition: XrdCpFile.hh:57
PType Protocol
Definition: XrdCpFile.hh:49
int Resolve()
Definition: XrdCpFile.cc:156
int Extend(XrdCpFile **pLast, int &nFile, long long &nBytes)
Definition: XrdCpFile.cc:129
long long fSize
Definition: XrdCpFile.hh:51
char * Path
Definition: XrdCpFile.hh:45
char ProtName[8]
Definition: XrdCpFile.hh:50
XrdCpFile * Next
Definition: XrdCpFile.hh:44
const char * SetPrefix(const char *prefix)
Definition: XrdSysError.hh:160
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)
static XrdSysLogger Logger
Definition: XrdCpConfig.cc:77
static const uint64_t OpVerbose
Definition: XrdCpConfig.hh:154
static const uint64_t OpXAttr
Definition: XrdCpConfig.hh:185
static const uint64_t DoProxy
Definition: XrdCpConfig.hh:128
defVar * intDefs
Definition: XrdCpConfig.hh:63
void Config(int argc, char **argv, int Opts=0)
Definition: XrdCpConfig.cc:194
static const uint64_t OpRecurse
Definition: XrdCpConfig.hh:130
XrdCksCalc * CksObj
Definition: XrdCpConfig.hh:87
static const uint64_t OpContinue
Definition: XrdCpConfig.hh:194
static const uint64_t DoRetry
Definition: XrdCpConfig.hh:135
static const uint64_t DoStreams
Definition: XrdCpConfig.hh:147
std::vector< std::string > AddCksVal
Definition: XrdCpConfig.hh:97
static const uint64_t OpParallel
Definition: XrdCpConfig.hh:162
static const uint64_t OpZipAppend
Definition: XrdCpConfig.hh:203
const char * dstOpq
Definition: XrdCpConfig.hh:65
static const uint64_t DoZipMtlnCksum
Definition: XrdCpConfig.hh:189
XrdCksData CksData
Definition: XrdCpConfig.hh:85
static const uint64_t OpSilent
Definition: XrdCpConfig.hh:140
static const uint64_t OpTlsMLF
Definition: XrdCpConfig.hh:179
static const uint64_t OpNoTlsOK
Definition: XrdCpConfig.hh:176
XrdCks * CksMan
Definition: XrdCpConfig.hh:86
XrdCpFile * srcFile
Definition: XrdCpConfig.hh:90
const char * Pgm
Definition: XrdCpConfig.hh:67
XrdCpFile * dstFile
Definition: XrdCpConfig.hh:91
static const uint64_t OpRetryPolicy
Definition: XrdCpConfig.hh:200
static const uint64_t OpDebug
Definition: XrdCpConfig.hh:107
char * zipFile
Definition: XrdCpConfig.hh:93
XrdCpConfig(const char *pgname)
Definition: XrdCpConfig.cc:129
static const uint64_t OpRetry
Definition: XrdCpConfig.hh:134
static const uint64_t DoNoPbar
Definition: XrdCpConfig.hh:122
static const uint64_t OpXrateThreshold
Definition: XrdCpConfig.hh:197
static const uint64_t DoCoerce
Definition: XrdCpConfig.hh:105
static const uint64_t OpServer
Definition: XrdCpConfig.hh:137
static const uint64_t DoForce
Definition: XrdCpConfig.hh:111
static const uint64_t OpVersion
Definition: XrdCpConfig.hh:157
static const uint64_t OpTpc
Definition: XrdCpConfig.hh:149
static const uint64_t DoParallel
Definition: XrdCpConfig.hh:163
static const uint64_t DoRmOnBadCksum
Definition: XrdCpConfig.hh:192
static const uint64_t DoNoTlsOK
Definition: XrdCpConfig.hh:177
static const uint64_t OpPath
Definition: XrdCpConfig.hh:182
long long OpSpec
Definition: XrdCpConfig.hh:73
static const uint64_t OpRecursv
Definition: XrdCpConfig.hh:131
static const uint64_t OpProxy
Definition: XrdCpConfig.hh:127
static const uint64_t DoTpc
Definition: XrdCpConfig.hh:150
static const uint64_t DoDebug
Definition: XrdCpConfig.hh:108
char * pHost
Definition: XrdCpConfig.hh:71
static const uint64_t OpSources
Definition: XrdCpConfig.hh:143
static const uint64_t DoCksum
Definition: XrdCpConfig.hh:101
defVar * strDefs
Definition: XrdCpConfig.hh:64
static const uint64_t OpPosc
Definition: XrdCpConfig.hh:124
static const uint64_t DoXrate
Definition: XrdCpConfig.hh:160
static const uint64_t DoCksrc
Definition: XrdCpConfig.hh:100
static const uint64_t OpZipMtlnCksum
Definition: XrdCpConfig.hh:188
static const int opt1Src
Definition: XrdCpConfig.hh:216
static const uint64_t OpXrate
Definition: XrdCpConfig.hh:159
static const uint64_t DoTpcDlgt
Definition: XrdCpConfig.hh:152
static const uint64_t DoZip
Definition: XrdCpConfig.hh:171
static const uint64_t DoVerbose
Definition: XrdCpConfig.hh:155
static const uint64_t DoContinue
Definition: XrdCpConfig.hh:195
static const uint64_t OpCksum
Definition: XrdCpConfig.hh:99
const char * CksVal
Definition: XrdCpConfig.hh:88
static const int OpAllowHttp
Definition: XrdCpConfig.hh:209
static const uint64_t DoRecurse
Definition: XrdCpConfig.hh:132
static const uint64_t OpTlsNoData
Definition: XrdCpConfig.hh:173
static const int optNoLclCp
Definition: XrdCpConfig.hh:220
static const uint64_t DoXrateThreshold
Definition: XrdCpConfig.hh:198
const char * srcOpq
Definition: XrdCpConfig.hh:66
static const uint64_t DoZipAppend
Definition: XrdCpConfig.hh:204
static const uint64_t OpIfile
Definition: XrdCpConfig.hh:116
static const uint64_t DoDynaSrc
Definition: XrdCpConfig.hh:166
int Want(uint64_t What)
Definition: XrdCpConfig.hh:226
static const int DoAllowHttp
Definition: XrdCpConfig.hh:210
long long xRate
Definition: XrdCpConfig.hh:68
static const int optNoStdIn
Definition: XrdCpConfig.hh:219
static const uint64_t OpNoPbar
Definition: XrdCpConfig.hh:121
static const uint64_t DoSources
Definition: XrdCpConfig.hh:144
static const uint64_t DoSilent
Definition: XrdCpConfig.hh:141
static const uint64_t OpForce
Definition: XrdCpConfig.hh:110
static const uint64_t OpRmOnBadCksum
Definition: XrdCpConfig.hh:191
static const uint64_t OpDynaSrc
Definition: XrdCpConfig.hh:165
static const uint64_t DoXAttr
Definition: XrdCpConfig.hh:186
static const int optNoXtnd
Definition: XrdCpConfig.hh:217
static const uint64_t DoTlsMLF
Definition: XrdCpConfig.hh:180
static const uint64_t OpZip
Definition: XrdCpConfig.hh:170
static const uint64_t OpLicense
Definition: XrdCpConfig.hh:119
static const uint64_t DoIfile
Definition: XrdCpConfig.hh:117
static const uint64_t OpHelp
Definition: XrdCpConfig.hh:113
static XrdSysError * Log
Definition: XrdCpConfig.hh:95
static const int optRmtRec
Definition: XrdCpConfig.hh:218
static const uint64_t DoRetryPolicy
Definition: XrdCpConfig.hh:201
std::string RetryPolicy
Definition: XrdCpConfig.hh:78
static const uint64_t DoPath
Definition: XrdCpConfig.hh:183
static const uint64_t DoPosc
Definition: XrdCpConfig.hh:125
static const uint64_t OpStreams
Definition: XrdCpConfig.hh:146
long long xRateThreshold
Definition: XrdCpConfig.hh:69
static const uint64_t OpCoerce
Definition: XrdCpConfig.hh:104
long long totBytes
Definition: XrdCpConfig.hh:83
static const uint64_t DoTpcOnly
Definition: XrdCpConfig.hh:151
static const uint64_t DoTlsNoData
Definition: XrdCpConfig.hh:174
static const uint64_t DoServer
Definition: XrdCpConfig.hh:138
static const uint64_t DoCkprt
Definition: XrdCpConfig.hh:102