XRootD
XrdClCopy.cc File Reference
#include "XrdApps/XrdCpConfig.hh"
#include "XrdApps/XrdCpFile.hh"
#include "XrdCl/XrdClConstants.hh"
#include "XrdCl/XrdClCopyProcess.hh"
#include "XrdCl/XrdClDefaultEnv.hh"
#include "XrdCl/XrdClLog.hh"
#include "XrdCl/XrdClFileSystem.hh"
#include "XrdCl/XrdClUtils.hh"
#include "XrdCl/XrdClDlgEnv.hh"
#include "XrdSys/XrdSysE2T.hh"
#include "XrdSys/XrdSysPthread.hh"
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <limits>
+ Include dependency graph for XrdClCopy.cc:

Go to the source code of this file.

Classes

class  ProgressDisplay
 

Functions

void AdjustFileInfo (XrdCpFile *file)
 
bool AllOptionsSupported (XrdCpConfig *config)
 
void AppendCGI (std::string &url, const char *newCGI)
 
void CleanUpResults (std::vector< XrdCl::PropertyList * > &results)
 
uint32_t CountSources (XrdCpFile *file)
 
const char * FileType2String (XrdCpFile::PType type)
 
XrdCpFileIndexRemote (XrdCl::FileSystem *fs, std::string basePath, long dirOffset)
 
int main (int argc, char **argv)
 
void ProcessCommandLineEnv (XrdCpConfig *config)
 

Function Documentation

◆ AdjustFileInfo()

void AdjustFileInfo ( XrdCpFile file)

Definition at line 391 of file XrdClCopy.cc.

392 {
393  //----------------------------------------------------------------------------
394  // If the file is url and the directory offset is not set we set it
395  // to the last slash
396  //----------------------------------------------------------------------------
397  if( file->Doff == 0 )
398  {
399  char *slash = file->Path;
400  for( ; *slash; ++slash ) {};
401  for( ; *slash != '/' && slash > file->Path; --slash ) {};
402  file->Doff = slash - file->Path;
403  }
404 };
short Doff
Definition: XrdCpFile.hh:46
char * Path
Definition: XrdCpFile.hh:45

References XrdCpFile::Doff, and XrdCpFile::Path.

Referenced by main().

+ Here is the caller graph for this function:

◆ AllOptionsSupported()

bool AllOptionsSupported ( XrdCpConfig config)

Definition at line 308 of file XrdClCopy.cc.

309 {
310  if( config->pHost )
311  {
312  std::cerr << "SOCKS Proxies are not yet supported" << std::endl;
313  return false;
314  }
315 
316  return true;
317 }
char * pHost
Definition: XrdCpConfig.hh:71

References XrdCpConfig::pHost.

Referenced by main().

+ Here is the caller graph for this function:

◆ AppendCGI()

void AppendCGI ( std::string &  url,
const char *  newCGI 
)

Definition at line 322 of file XrdClCopy.cc.

323 {
324  if( !newCGI || !(*newCGI) )
325  return;
326 
327  if( *newCGI == '&' )
328  ++newCGI;
329 
330  if( url.find( '?' ) == std::string::npos )
331  url += "?";
332 
333  if( url.find( '&' ) == std::string::npos )
334  url += "&";
335 
336  url += newCGI;
337 }

Referenced by main().

+ Here is the caller graph for this function:

◆ CleanUpResults()

void CleanUpResults ( std::vector< XrdCl::PropertyList * > &  results)

Definition at line 459 of file XrdClCopy.cc.

460 {
461  std::vector<XrdCl::PropertyList *>::iterator it;
462  for( it = results.begin(); it != results.end(); ++it )
463  delete *it;
464 }

Referenced by main().

+ Here is the caller graph for this function:

◆ CountSources()

uint32_t CountSources ( XrdCpFile file)

Definition at line 381 of file XrdClCopy.cc.

382 {
383  uint32_t count;
384  for( count = 0; file; file = file->Next, ++count ) {};
385  return count;
386 }
XrdCpFile * Next
Definition: XrdCpFile.hh:44

References XrdCpFile::Next.

Referenced by main().

+ Here is the caller graph for this function:

◆ FileType2String()

const char* FileType2String ( XrdCpFile::PType  type)

Definition at line 364 of file XrdClCopy.cc.

365 {
366  switch( type )
367  {
368  case XrdCpFile::isDir: return "directory";
369  case XrdCpFile::isFile: return "local file";
370  case XrdCpFile::isXroot: return "xroot";
371  case XrdCpFile::isHttp: return "http";
372  case XrdCpFile::isHttps: return "https";
373  case XrdCpFile::isStdIO: return "stdio";
374  default: return "other";
375  };
376 }

References XrdCpFile::isDir, XrdCpFile::isFile, XrdCpFile::isHttp, XrdCpFile::isHttps, XrdCpFile::isStdIO, and XrdCpFile::isXroot.

Referenced by main().

+ Here is the caller graph for this function:

◆ IndexRemote()

XrdCpFile* IndexRemote ( XrdCl::FileSystem fs,
std::string  basePath,
long  dirOffset 
)

Definition at line 409 of file XrdClCopy.cc.

412 {
413  using namespace XrdCl;
414 
415  Log *log = DefaultEnv::GetLog();
416  log->Debug( AppMsg, "Indexing %s", basePath.c_str() );
417 
418  DirectoryList *dirList = 0;
419  XRootDStatus st = fs->DirList( URL( basePath ).GetPath(), DirListFlags::Recursive
421  if( !st.IsOK() )
422  {
423  log->Info( AppMsg, "Failed to get directory listing for %s: %s",
424  basePath.c_str(),
425  st.GetErrorMessage().c_str() );
426  return 0;
427  }
428 
429  XrdCpFile start, *current = 0;
430  XrdCpFile *end = &start;
431  int badUrl = 0;
432  for( auto itr = dirList->Begin(); itr != dirList->End(); ++itr )
433  {
434  DirectoryList::ListEntry *e = *itr;
435  if( e->GetStatInfo()->TestFlags( StatInfo::IsDir ) )
436  continue;
437  std::string path = basePath + '/' + e->GetName();
438  current = new XrdCpFile( path.c_str(), badUrl );
439  if( badUrl )
440  {
441  log->Error( AppMsg, "Bad URL: %s", current->Path );
442  delete current;
443  return 0;
444  }
445 
446  current->Doff = dirOffset;
447  end->Next = current;
448  end = current;
449  }
450 
451  delete dirList;
452 
453  return start.Next;
454 }
static Log * GetLog()
Get default log.
const std::string & GetName() const
Get file name.
StatInfo * GetStatInfo()
Get the stat info object.
Iterator End()
Get the end iterator.
Iterator Begin()
Get the begin iterator.
XRootDStatus DirList(const std::string &path, DirListFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Handle diagnostics.
Definition: XrdClLog.hh:101
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition: XrdClLog.cc:231
void Info(uint64_t topic, const char *format,...)
Print an info.
Definition: XrdClLog.cc:265
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
bool TestFlags(uint32_t flags) const
Test flags.
@ IsDir
This is a directory.
URL representation.
Definition: XrdClURL.hh:31
const std::string & GetErrorMessage() const
Get error message.
const uint64_t AppMsg
@ Merge
Merge duplicates.
@ Recursive
Do a recursive listing.
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:124

References XrdCl::AppMsg, XrdCl::DirectoryList::Begin(), XrdCl::Log::Debug(), XrdCl::FileSystem::DirList(), XrdCpFile::Doff, XrdCl::DirectoryList::End(), XrdCl::Log::Error(), XrdCl::XRootDStatus::GetErrorMessage(), XrdCl::DefaultEnv::GetLog(), XrdCl::DirectoryList::ListEntry::GetName(), XrdCl::DirectoryList::ListEntry::GetStatInfo(), XrdCl::Log::Info(), XrdCl::StatInfo::IsDir, XrdCl::Status::IsOK(), XrdCl::DirListFlags::Locate, XrdCl::DirListFlags::Merge, XrdCpFile::Next, XrdCpFile::Path, XrdCl::DirListFlags::Recursive, and XrdCl::StatInfo::TestFlags().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 469 of file XrdClCopy.cc.

470 {
471  using namespace XrdCl;
472 
473  //----------------------------------------------------------------------------
474  // Configure the copy command, if it returns then everything went well, ugly
475  //----------------------------------------------------------------------------
476  XrdCpConfig config( argv[0] );
477  config.Config( argc, argv, XrdCpConfig::optRmtRec );
478  if( !AllOptionsSupported( &config ) )
479  return 50; // generic error
480  ProcessCommandLineEnv( &config );
481 
482  //----------------------------------------------------------------------------
483  // Set options
484  //----------------------------------------------------------------------------
485  CopyProcess process;
486  Log *log = DefaultEnv::GetLog();
487  if( config.Dlvl )
488  {
489  if( config.Dlvl == 1 ) log->SetLevel( Log::InfoMsg );
490  else if( config.Dlvl == 2 ) log->SetLevel( Log::DebugMsg );
491  else if( config.Dlvl == 3 ) log->SetLevel( Log::DumpMsg );
492  }
493 
494  ProgressDisplay progress;
495  if( config.Want(XrdCpConfig::DoNoPbar) || !isatty( fileno( stdout ) ) )
496  progress.PrintProgressBar( false );
497 
498  bool posc = false;
499  bool force = false;
500  bool coerce = false;
501  bool makedir = false;
502  bool dynSrc = false;
503  bool delegate = false;
504  bool preserveXAttr = false;
505  bool rmOnBadCksum = false;
506  bool continue_ = false;
507  bool recurse = false;
508  bool zipappend = false;
509  bool doserver = false;
510  std::string thirdParty = "none";
511 
512  if( config.Want( XrdCpConfig::DoPosc ) ) posc = true;
513  if( config.Want( XrdCpConfig::DoForce ) ) force = true;
514  if( config.Want( XrdCpConfig::DoCoerce ) ) coerce = true;
515  if( config.Want( XrdCpConfig::DoTpc ) ) thirdParty = "first";
516  if( config.Want( XrdCpConfig::DoTpcOnly ) ) thirdParty = "only";
517  if( config.Want( XrdCpConfig::DoZipAppend ) ) zipappend = true;
518  if( config.Want( XrdCpConfig::DoServer ) ) doserver = true;
519  if( config.Want( XrdCpConfig::DoTpcDlgt ) )
520  {
521  // the env var is being set already here (we are issuing a stat
522  // inhere and we need the env var when we are establishing the
523  // connection and authenticating), but we are also setting a delegate
524  // parameter for CopyJob so it can be used on its own.
526  delegate = true;
527  }
528  else
530 
531  if( config.Want( XrdCpConfig::DoRecurse ) )
532  {
533  makedir = true;
534  recurse = true;
535  }
536  if( config.Want( XrdCpConfig::DoPath ) ) makedir = true;
537  if( config.Want( XrdCpConfig::DoDynaSrc ) ) dynSrc = true;
538  if( config.Want( XrdCpConfig::DoXAttr ) ) preserveXAttr = true;
539  if( config.Want( XrdCpConfig::DoRmOnBadCksum ) ) rmOnBadCksum = true;
540  if( config.Want( XrdCpConfig::DoContinue ) ) continue_ = true;
541 
542  if( force && continue_ )
543  {
544  std::cerr << "Invalid argument combination: continue + force." << std::endl;
545  return 50;
546  }
547 
548  //----------------------------------------------------------------------------
549  // Checksums
550  //----------------------------------------------------------------------------
551  std::string checkSumType;
552  std::string checkSumPreset;
553  std::string checkSumMode = "none";
554  if( config.Want( XrdCpConfig::DoCksum ) )
555  {
556  checkSumMode = "end2end";
557  std::vector<std::string> ckSumParams;
558  Utils::splitString( ckSumParams, config.CksVal, ":" );
559  if( ckSumParams.size() > 1 )
560  {
561  if( ckSumParams[1] == "print" )
562  {
563  checkSumMode = "target";
564  progress.PrintTargetCheckSum( true );
565  }
566  else
567  checkSumPreset = ckSumParams[1];
568  }
569  checkSumType = ckSumParams[0];
570  }
571 
572  if( config.Want( XrdCpConfig::DoCksrc ) )
573  {
574  checkSumMode = "source";
575  std::vector<std::string> ckSumParams;
576  Utils::splitString( ckSumParams, config.CksVal, ":" );
577  if( ckSumParams.size() == 2 )
578  {
579  checkSumMode = "source";
580  checkSumType = ckSumParams[0];
581  progress.PrintSourceCheckSum( true );
582  }
583  else
584  {
585  std::cerr << "Invalid parameter: " << config.CksVal << std::endl;
586  return 50; // generic error
587  }
588  }
589 
590  if( !config.AddCksVal.empty() )
591  progress.PrintAdditionalCheckSum( true );
592 
593  //----------------------------------------------------------------------------
594  // ZIP archive
595  //----------------------------------------------------------------------------
596  std::string zipFile;
597  bool zip = false;
598  if( config.Want( XrdCpConfig::DoZip ) )
599  {
600  zipFile = config.zipFile;
601  zip = true;
602  }
603 
604  //----------------------------------------------------------------------------
605  // Extreme Copy
606  //----------------------------------------------------------------------------
607  int nbSources = 0;
608  bool xcp = false;
609  if( config.Want( XrdCpConfig::DoSources ) )
610  {
611  nbSources = config.nSrcs;
612  xcp = true;
613  }
614 
615  //----------------------------------------------------------------------------
616  // Environment settings
617  //----------------------------------------------------------------------------
619 
620  /* Stop PostMaster when exiting main() to ensure proper shutdown */
621  struct scope_exit {
622  ~scope_exit() { XrdCl::DefaultEnv::GetPostMaster()->Stop(); }
623  } stopPostMaster;
624 
625  if( config.nStrm != 0 )
626  env->PutInt( "SubStreamsPerChannel", config.nStrm + 1 /*stands for the control stream*/ );
627 
628  if( config.Retry != -1 )
629  {
630  env->PutInt( "CpRetry", config.Retry );
631  env->PutString( "CpRetryPolicy", config.RetryPolicy );
632  }
633 
634  if( config.Want( XrdCpConfig::DoNoTlsOK ) )
635  env->PutInt( "NoTlsOK", 1 );
636 
637  if( config.Want( XrdCpConfig::DoTlsNoData ) )
638  env->PutInt( "TlsNoData", 1 );
639 
640  if( config.Want( XrdCpConfig::DoTlsMLF ) )
641  env->PutInt( "TlsMetalink", 1 );
642 
643  if( config.Want( XrdCpConfig::DoZipMtlnCksum ) )
644  env->PutInt( "ZipMtlnCksum", 1 );
645 
646  int chunkSize = DefaultCPChunkSize;
647  env->GetInt( "CPChunkSize", chunkSize );
648 
649  int blockSize = DefaultXCpBlockSize;
650  env->GetInt( "XCpBlockSize", blockSize );
651 
652  int parallelChunks = DefaultCPParallelChunks;
653  env->GetInt( "CPParallelChunks", parallelChunks );
654  if( parallelChunks < 1 ||
655  parallelChunks > std::numeric_limits<uint8_t>::max() )
656  {
657  std::cerr << "Can only handle between 1 and ";
658  std::cerr << (int)std::numeric_limits<uint8_t>::max();
659  std::cerr << " chunks in parallel. You asked for " << parallelChunks;
660  std::cerr << "." << std::endl;
661  return 50; // generic error
662  }
663 
664  if( !preserveXAttr )
665  {
666  int val = DefaultPreserveXAttrs;
667  env->GetInt( "PreserveXAttrs", val );
668  if( val ) preserveXAttr = true;
669  }
670 
671  log->Dump( AppMsg, "Chunk size: %d, parallel chunks %d, streams: %d",
672  chunkSize, parallelChunks, config.nStrm + 1 );
673 
674  //----------------------------------------------------------------------------
675  // Build the URLs
676  //----------------------------------------------------------------------------
677  std::vector<XrdCl::PropertyList*> resultVect;
678 
679  std::string dest;
680  if( config.dstFile->Protocol == XrdCpFile::isDir ||
681  config.dstFile->Protocol == XrdCpFile::isFile )
682  {
683  dest = "file://";
684 
685  // if it is not an absolute path append cwd
686  if( config.dstFile->Path[0] != '/' )
687  {
688  char buf[FILENAME_MAX];
689  char *cwd = getcwd( buf, FILENAME_MAX );
690  if( !cwd )
691  {
692  XRootDStatus st( stError, XProtocol::mapError( errno ), errno );
693  std::cerr << st.GetErrorMessage() << std::endl;
694  return st.GetShellCode();
695  }
696  dest += cwd;
697  dest += '/';
698  }
699  }
700  dest += config.dstFile->Path;
701 
702  //----------------------------------------------------------------------------
703  // We need to check whether our target is a file or a directory:
704  // 1) it's a file, so we can accept only one source
705  // 2) it's a directory, so:
706  // * we can accept multiple sources
707  // * we need to append the source name
708  //----------------------------------------------------------------------------
709  bool targetIsDir = false;
710  bool targetExists = false;
711  if( config.dstFile->Protocol == XrdCpFile::isDir )
712  targetIsDir = true;
713  else if( config.dstFile->Protocol == XrdCpFile::isXroot ||
714  config.dstFile->Protocol == XrdCpFile::isXroots )
715  {
716  URL target( dest );
717  FileSystem fs( target );
718  StatInfo *statInfo = 0;
719  XRootDStatus st = fs.Stat( target.GetPathWithParams(), statInfo );
720  if( st.IsOK() )
721  {
722  if( statInfo->TestFlags( StatInfo::IsDir ) )
723  targetIsDir = true;
724  targetExists = true;
725  }
726  else if( st.errNo == kXR_NotFound && config.Want( XrdCpConfig::DoPath ) )
727  {
728  int n = strlen(config.dstFile->Path);
729  if( config.dstFile->Path[n-1] == '/' )
730  targetIsDir = true;
731  }
732  else if( st.errNo == kXR_NotAuthorized )
733  {
734  log->Error( AppMsg, "%s (destination)", st.ToString().c_str() );
735  std::cerr << st.ToStr() << std::endl;
736  return st.GetShellCode();
737  }
738 
739  delete statInfo;
740  }
741 
742  if( !targetIsDir && targetExists && !force && !recurse && !zipappend )
743  {
744  XRootDStatus st( stError, errInvalidOp, EEXIST );
745  // Unable to create /tmp/test.txt; file exists
746  log->Error( AppMsg, "%s (destination)", st.ToString().c_str() );
747  std::cerr << "Run: " << st.ToStr() << std::endl;
748  return st.GetShellCode();
749  }
750 
751  //----------------------------------------------------------------------------
752  // If we have multiple sources and target is neither a directory nor stdout
753  // then we cannot proceed
754  //----------------------------------------------------------------------------
755  if( CountSources(config.srcFile) > 1 && !targetIsDir &&
756  config.dstFile->Protocol != XrdCpFile::isStdIO )
757  {
758  std::cerr << "Multiple sources were given but target is not a directory.";
759  std::cerr << std::endl;
760  return 50; // generic error
761  }
762 
763  //----------------------------------------------------------------------------
764  // If we're doing remote recursive copy, chain all the files (if it's a
765  // directory)
766  //----------------------------------------------------------------------------
767  bool remoteSrcIsDir = false;
768  if( config.Want( XrdCpConfig::DoRecurse ) &&
769  config.srcFile->Protocol == XrdCpFile::isXroot )
770  {
771  URL source( config.srcFile->Path );
772  FileSystem *fs = new FileSystem( source );
773  StatInfo *statInfo = 0;
774 
775  XRootDStatus st = fs->Stat( source.GetPath(), statInfo );
776  if( st.IsOK() && statInfo->TestFlags( StatInfo::IsDir ) )
777  {
778  remoteSrcIsDir = true;
779  //------------------------------------------------------------------------
780  // Recursively index the remote directory
781  //------------------------------------------------------------------------
782  delete config.srcFile;
783  std::string url = source.GetURL();
784  config.srcFile = IndexRemote( fs, url, url.size() );
785  if ( !config.srcFile )
786  {
787  std::cerr << "Error indexing remote directory.";
788  return 50; // generic error
789  }
790  }
791 
792  delete fs;
793  delete statInfo;
794  }
795 
796  XrdCpFile *sourceFile = config.srcFile;
797  //----------------------------------------------------------------------------
798  // Process the sources
799  //----------------------------------------------------------------------------
800  while( sourceFile )
801  {
802  AdjustFileInfo( sourceFile );
803 
804  //--------------------------------------------------------------------------
805  // Create a job for every source
806  //--------------------------------------------------------------------------
807  PropertyList properties;
808  PropertyList *results = new PropertyList;
809  std::string source = sourceFile->Path;
810  if( sourceFile->Protocol == XrdCpFile::isFile )
811  {
812  // make sure it is an absolute path
813  if( source[0] == '/' )
814  source = "file://" + source;
815  else
816  {
817  char buf[FILENAME_MAX];
818  char *cwd = getcwd( buf, FILENAME_MAX );
819  if( !cwd )
820  {
821  XRootDStatus st( stError, XProtocol::mapError( errno ), errno );
822  std::cerr << st.GetErrorMessage() << std::endl;
823  return st.GetShellCode();
824  }
825  source = "file://" + std::string( cwd ) + '/' + source;
826  }
827  }
828 
829  AppendCGI( source, config.srcOpq );
830 
831  log->Dump( AppMsg, "Processing source entry: %s, type %s, target file: %s",
832  sourceFile->Path, FileType2String( sourceFile->Protocol ),
833  dest.c_str() );
834 
835  //--------------------------------------------------------------------------
836  // Set up the job
837  //--------------------------------------------------------------------------
838  std::string target = dest;
839 
840 
841  bool srcIsDir = false;
842  // if this is local file, for a directory Dlen + Doff will overlap with path size
843  if( strncmp( sourceFile->ProtName, "file", 4 ) == 0 )
844  srcIsDir = std::string( sourceFile->Path ).size() == size_t( sourceFile->Doff + sourceFile->Dlen );
845  // otherwise we are handling a remote file
846  else
847  srcIsDir = remoteSrcIsDir;
848  // if this is a recursive copy make sure we preserve the directory structure
849  if( config.Want( XrdCpConfig::DoRecurse ) && srcIsDir )
850  {
851  // get the source directory
852  std::string srcDir( sourceFile->Path, sourceFile->Doff );
853  // remove the trailing slash
854  if( srcDir[srcDir.size() - 1] == '/' )
855  srcDir = srcDir.substr( 0, srcDir.size() - 1 );
856  size_t diroff = srcDir.rfind( '/' );
857  // if there is no '/' it means a directory name has been given as relative path
858  if( diroff == std::string::npos ) diroff = 0;
859  target += '/';
860  target += sourceFile->Path + diroff;
861  // remove the filename from destination path as it will be appended later anyway
862  target = target.substr( 0 , target.rfind('/') );
863  }
864  AppendCGI( target, config.dstOpq );
865 
866  properties.Set( "source", source );
867  properties.Set( "target", target );
868  properties.Set( "force", force );
869  properties.Set( "posc", posc );
870  properties.Set( "coerce", coerce );
871  properties.Set( "makeDir", makedir );
872  properties.Set( "dynamicSource", dynSrc );
873  properties.Set( "thirdParty", thirdParty );
874  properties.Set( "checkSumMode", checkSumMode );
875  properties.Set( "checkSumType", checkSumType );
876  properties.Set( "checkSumPreset", checkSumPreset );
877  properties.Set( "chunkSize", chunkSize );
878  properties.Set( "parallelChunks", parallelChunks );
879  properties.Set( "zipArchive", zip );
880  properties.Set( "xcp", xcp );
881  properties.Set( "xcpBlockSize", blockSize );
882  properties.Set( "delegate", delegate );
883  properties.Set( "targetIsDir", targetIsDir );
884  properties.Set( "preserveXAttr", preserveXAttr );
885  properties.Set( "xrate", config.xRate );
886  properties.Set( "xrateThreshold", config.xRateThreshold );
887  properties.Set( "rmOnBadCksum", rmOnBadCksum );
888  properties.Set( "continue", continue_ );
889  properties.Set( "zipAppend", zipappend );
890  properties.Set( "addcksums", config.AddCksVal );
891  properties.Set( "doServer", doserver );
892 
893  if( zip )
894  properties.Set( "zipSource", zipFile );
895 
896  if( xcp )
897  properties.Set( "nbXcpSources", nbSources );
898 
899 
900  XRootDStatus st = process.AddJob( properties, results );
901  if( !st.IsOK() )
902  {
903  std::cerr << "AddJob " << source << " -> " << target << ": ";
904  std::cerr << st.ToStr() << std::endl;
905  }
906  resultVect.push_back( results );
907  sourceFile = sourceFile->Next;
908  }
909 
910  //----------------------------------------------------------------------------
911  // Configure the copy process
912  //----------------------------------------------------------------------------
913  PropertyList processConfig;
914  processConfig.Set( "jobType", "configuration" );
915  processConfig.Set( "parallel", config.Parallel );
916  process.AddJob( processConfig, 0 );
917 
918  //----------------------------------------------------------------------------
919  // Prepare and run the copy process
920  //----------------------------------------------------------------------------
921  XRootDStatus st = process.Prepare();
922  if( !st.IsOK() )
923  {
924  CleanUpResults( resultVect );
925  std::cerr << "Prepare: " << st.ToStr() << std::endl;
926  return st.GetShellCode();
927  }
928 
929  st = process.Run( &progress );
930  if( !st.IsOK() )
931  {
932  if( resultVect.size() == 1 )
933  std::cerr << "Run: " << st.ToStr() << std::endl;
934  else
935  {
936  std::vector<XrdCl::PropertyList*>::iterator it;
937  uint16_t i = 1;
938  uint16_t jobsRun = 0;
939  uint16_t errors = 0;
940  for( it = resultVect.begin(); it != resultVect.end(); ++it, ++i )
941  {
942  if( !(*it)->HasProperty( "status" ) )
943  continue;
944 
945  XRootDStatus st = (*it)->Get<XRootDStatus>("status");
946  if( !st.IsOK() )
947  {
948  std::cerr << "Job #" << i << ": " << st.ToStr();
949  ++errors;
950  }
951  ++jobsRun;
952  }
953  std::cerr << "Jobs total: " << resultVect.size();
954  std::cerr << ", run: " << jobsRun;
955  std::cerr << ", errors: " << errors << std::endl;
956  }
957  CleanUpResults( resultVect );
958  return st.GetShellCode();
959  }
960  CleanUpResults( resultVect );
961  return 0;
962 }
@ kXR_NotAuthorized
Definition: XProtocol.hh:998
@ kXR_NotFound
Definition: XProtocol.hh:999
bool AllOptionsSupported(XrdCpConfig *config)
Definition: XrdClCopy.cc:308
const char * FileType2String(XrdCpFile::PType type)
Definition: XrdClCopy.cc:364
XrdCpFile * IndexRemote(XrdCl::FileSystem *fs, std::string basePath, long dirOffset)
Definition: XrdClCopy.cc:409
void ProcessCommandLineEnv(XrdCpConfig *config)
Definition: XrdClCopy.cc:342
void CleanUpResults(std::vector< XrdCl::PropertyList * > &results)
Definition: XrdClCopy.cc:459
void AdjustFileInfo(XrdCpFile *file)
Definition: XrdClCopy.cc:391
uint32_t CountSources(XrdCpFile *file)
Definition: XrdClCopy.cc:381
void AppendCGI(std::string &url, const char *newCGI)
Definition: XrdClCopy.cc:322
void PrintAdditionalCheckSum(bool print)
Definition: XrdClCopy.cc:282
void PrintSourceCheckSum(bool print)
Definition: XrdClCopy.cc:280
void PrintProgressBar(bool print)
Definition: XrdClCopy.cc:279
void PrintTargetCheckSum(bool print)
Definition: XrdClCopy.cc:281
static int mapError(int rc)
Definition: XProtocol.hh:1358
Copy the data from one point to another.
XRootDStatus Run(CopyProgressHandler *handler)
Run the copy jobs.
XRootDStatus Prepare()
XRootDStatus AddJob(const PropertyList &properties, PropertyList *results)
static PostMaster * GetPostMaster()
Get default post master.
static Env * GetEnv()
Get default client environment.
void Enable()
Enable delegation in the environment.
Definition: XrdClDlgEnv.hh:47
static DlgEnv & Instance()
Definition: XrdClDlgEnv.hh:28
void Disable()
Disable delegation in the environment.
Definition: XrdClDlgEnv.hh:55
bool PutInt(const std::string &key, int value)
Definition: XrdClEnv.cc:110
bool PutString(const std::string &key, const std::string &value)
Definition: XrdClEnv.cc:52
bool GetInt(const std::string &key, int &value)
Definition: XrdClEnv.cc:89
Send file/filesystem queries to an XRootD cluster.
XRootDStatus Stat(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
@ InfoMsg
print info
Definition: XrdClLog.hh:111
@ DebugMsg
print debug info
Definition: XrdClLog.hh:112
@ DumpMsg
print details of the request and responses
Definition: XrdClLog.hh:113
void SetLevel(LogLevel level)
Set the level of the messages that should be sent to the destination.
Definition: XrdClLog.hh:173
void Dump(uint64_t topic, const char *format,...)
Print a dump message.
Definition: XrdClLog.cc:299
bool Stop()
Stop the postmaster.
A key-value pair map storing both keys and values as strings.
void Set(const std::string &name, const Item &value)
Object stat info.
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
Definition: XrdClUtils.hh:56
std::string ToStr() const
Convert to string.
PType Protocol
Definition: XrdCpFile.hh:49
char ProtName[8]
Definition: XrdCpFile.hh:50
short Dlen
Definition: XrdCpFile.hh:47
const int DefaultCPChunkSize
const uint16_t stError
An error occurred that could potentially be retried.
Definition: XrdClStatus.hh:32
const uint16_t errInvalidOp
Definition: XrdClStatus.hh:51
const int DefaultCPParallelChunks
const int DefaultXCpBlockSize
const int DefaultPreserveXAttrs
std::string ToString() const
Create a string representation.
Definition: XrdClStatus.cc:97
uint32_t errNo
Errno, if any.
Definition: XrdClStatus.hh:148
int GetShellCode() const
Get the status code that may be returned to the shell.
Definition: XrdClStatus.hh:129
static const uint64_t DoZipMtlnCksum
Definition: XrdCpConfig.hh:189
static const uint64_t DoNoPbar
Definition: XrdCpConfig.hh:122
static const uint64_t DoCoerce
Definition: XrdCpConfig.hh:105
static const uint64_t DoForce
Definition: XrdCpConfig.hh:111
static const uint64_t DoRmOnBadCksum
Definition: XrdCpConfig.hh:192
static const uint64_t DoNoTlsOK
Definition: XrdCpConfig.hh:177
static const uint64_t DoTpc
Definition: XrdCpConfig.hh:150
static const uint64_t DoCksum
Definition: XrdCpConfig.hh:101
static const uint64_t DoCksrc
Definition: XrdCpConfig.hh:100
static const uint64_t DoTpcDlgt
Definition: XrdCpConfig.hh:152
static const uint64_t DoZip
Definition: XrdCpConfig.hh:171
static const uint64_t DoContinue
Definition: XrdCpConfig.hh:195
static const uint64_t DoRecurse
Definition: XrdCpConfig.hh:132
static const uint64_t DoZipAppend
Definition: XrdCpConfig.hh:204
static const uint64_t DoDynaSrc
Definition: XrdCpConfig.hh:166
static const uint64_t DoSources
Definition: XrdCpConfig.hh:144
static const uint64_t DoXAttr
Definition: XrdCpConfig.hh:186
static const uint64_t DoTlsMLF
Definition: XrdCpConfig.hh:180
static const int optRmtRec
Definition: XrdCpConfig.hh:218
static const uint64_t DoPath
Definition: XrdCpConfig.hh:183
static const uint64_t DoPosc
Definition: XrdCpConfig.hh:125
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

References XrdCpConfig::AddCksVal, XrdCl::CopyProcess::AddJob(), AdjustFileInfo(), AllOptionsSupported(), AppendCGI(), XrdCl::AppMsg, XrdCpConfig::CksVal, CleanUpResults(), XrdCpConfig::Config(), CountSources(), XrdCl::Log::DebugMsg, XrdCl::DefaultCPChunkSize, XrdCl::DefaultCPParallelChunks, XrdCl::DefaultPreserveXAttrs, XrdCl::DefaultXCpBlockSize, XrdCl::DlgEnv::Disable(), XrdCpFile::Dlen, XrdCpConfig::Dlvl, XrdCpConfig::DoCksrc, XrdCpConfig::DoCksum, XrdCpConfig::DoCoerce, XrdCpConfig::DoContinue, XrdCpConfig::DoDynaSrc, XrdCpFile::Doff, XrdCpConfig::DoForce, XrdCpConfig::DoNoPbar, XrdCpConfig::DoNoTlsOK, XrdCpConfig::DoPath, XrdCpConfig::DoPosc, XrdCpConfig::DoRecurse, XrdCpConfig::DoRmOnBadCksum, XrdCpConfig::DoServer, XrdCpConfig::DoSources, XrdCpConfig::DoTlsMLF, XrdCpConfig::DoTlsNoData, XrdCpConfig::DoTpc, XrdCpConfig::DoTpcDlgt, XrdCpConfig::DoTpcOnly, XrdCpConfig::DoXAttr, XrdCpConfig::DoZip, XrdCpConfig::DoZipAppend, XrdCpConfig::DoZipMtlnCksum, XrdCpConfig::dstFile, XrdCpConfig::dstOpq, XrdCl::Log::Dump(), XrdCl::Log::DumpMsg, XrdCl::DlgEnv::Enable(), XrdCl::errInvalidOp, XrdCl::Status::errNo, XrdCl::Log::Error(), FileType2String(), XrdCl::DefaultEnv::GetEnv(), XrdCl::XRootDStatus::GetErrorMessage(), XrdCl::Env::GetInt(), XrdCl::DefaultEnv::GetLog(), XrdCl::URL::GetPath(), XrdCl::URL::GetPathWithParams(), XrdCl::DefaultEnv::GetPostMaster(), XrdCl::Status::GetShellCode(), XrdCl::URL::GetURL(), IndexRemote(), XrdCl::Log::InfoMsg, XrdCl::DlgEnv::Instance(), XrdCpFile::isDir, XrdCl::StatInfo::IsDir, XrdCpFile::isFile, XrdCl::Status::IsOK(), XrdCpFile::isStdIO, XrdCpFile::isXroot, XrdCpFile::isXroots, kXR_NotAuthorized, kXR_NotFound, XProtocol::mapError(), XrdCpFile::Next, XrdCpConfig::nSrcs, XrdCpConfig::nStrm, XrdCpConfig::optRmtRec, XrdCpConfig::Parallel, XrdCpFile::Path, XrdCl::CopyProcess::Prepare(), ProgressDisplay::PrintAdditionalCheckSum(), ProgressDisplay::PrintProgressBar(), ProgressDisplay::PrintSourceCheckSum(), ProgressDisplay::PrintTargetCheckSum(), ProcessCommandLineEnv(), XrdCpFile::ProtName, XrdCpFile::Protocol, XrdCl::Env::PutInt(), XrdCl::Env::PutString(), XrdCpConfig::Retry, XrdCpConfig::RetryPolicy, XrdCl::CopyProcess::Run(), XrdCl::PropertyList::Set(), XrdCl::Log::SetLevel(), XrdCl::Utils::splitString(), XrdCpConfig::srcFile, XrdCpConfig::srcOpq, XrdCl::FileSystem::Stat(), XrdCl::stError, XrdCl::PostMaster::Stop(), XrdCl::StatInfo::TestFlags(), XrdCl::XRootDStatus::ToStr(), XrdCl::Status::ToString(), XrdCpConfig::Want(), XrdCpConfig::xRate, XrdCpConfig::xRateThreshold, and XrdCpConfig::zipFile.

+ Here is the call graph for this function:

◆ ProcessCommandLineEnv()

void ProcessCommandLineEnv ( XrdCpConfig config)

Definition at line 342 of file XrdClCopy.cc.

343 {
345 
346  XrdCpConfig::defVar *cursor = config->intDefs;
347  while( cursor )
348  {
349  env->PutInt( cursor->vName, cursor->intVal );
350  cursor = cursor->Next;
351  }
352 
353  cursor = config->strDefs;
354  while( cursor )
355  {
356  env->PutString( cursor->vName, cursor->strVal );
357  cursor = cursor->Next;
358  }
359 }
const char * vName
Definition: XrdCpConfig.hh:53
defVar * intDefs
Definition: XrdCpConfig.hh:63
defVar * strDefs
Definition: XrdCpConfig.hh:64

References XrdCl::DefaultEnv::GetEnv(), XrdCpConfig::intDefs, XrdCpConfig::defVar::Next, XrdCl::Env::PutInt(), XrdCl::Env::PutString(), XrdCpConfig::strDefs, and XrdCpConfig::defVar::vName.

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: