XRootD
Loading...
Searching...
No Matches
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 "XrdCl/XrdClOptimizers.hh"
#include "XrdSys/XrdSysE2T.hh"
#include "XrdSys/XrdSysPthread.hh"
#include "XrdOuc/XrdOucPrivateUtils.hh"
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>
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)
XrdCpFile * IndexRemote (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 397 of file XrdClCopy.cc.

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

References AdjustFileInfo(), XrdCpFile::Doff, and XrdCpFile::Path.

Referenced by AdjustFileInfo(), and main().

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

◆ AllOptionsSupported()

bool AllOptionsSupported ( XrdCpConfig * config)

Definition at line 313 of file XrdClCopy.cc.

314{
315 if( config->pHost )
316 {
317 std::cerr << "SOCKS Proxies are not yet supported" << std::endl;
318 return false;
319 }
320
321 return true;
322}

References AllOptionsSupported(), and XrdCpConfig::pHost.

Referenced by AllOptionsSupported(), and main().

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

◆ AppendCGI()

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

Definition at line 327 of file XrdClCopy.cc.

328{
329 if( !newCGI || !(*newCGI) )
330 return;
331
332 if( *newCGI == '&' )
333 ++newCGI;
334
335 if( url.find( '?' ) == std::string::npos )
336 url += "?";
337
338 if( url.find( '&' ) == std::string::npos )
339 url += "&";
340
341 url += newCGI;
342}

References AppendCGI().

Referenced by AppendCGI(), and main().

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

◆ CleanUpResults()

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

Definition at line 465 of file XrdClCopy.cc.

466{
467 std::vector<XrdCl::PropertyList *>::iterator it;
468 for( it = results.begin(); it != results.end(); ++it )
469 delete *it;
470}

References CleanUpResults().

Referenced by CleanUpResults(), and main().

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

◆ CountSources()

uint32_t CountSources ( XrdCpFile * file)

Definition at line 387 of file XrdClCopy.cc.

388{
389 uint32_t count;
390 for( count = 0; file; file = file->Next, ++count ) {};
391 return count;
392}
XrdCpFile * Next
Definition XrdCpFile.hh:44

References CountSources(), and XrdCpFile::Next.

Referenced by CountSources(), and main().

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

◆ FileType2String()

const char * FileType2String ( XrdCpFile::PType type)

Definition at line 369 of file XrdClCopy.cc.

370{
371 switch( type )
372 {
373 case XrdCpFile::isDir: return "directory";
374 case XrdCpFile::isFile: return "local file";
375 case XrdCpFile::isXroot: return "xroot";
376 case XrdCpFile::isXroots: return "xroots";
377 case XrdCpFile::isHttp: return "http";
378 case XrdCpFile::isHttps: return "https";
379 case XrdCpFile::isStdIO: return "stdio";
380 default: return "other";
381 };
382}

References FileType2String(), XrdCpFile::isDir, XrdCpFile::isFile, XrdCpFile::isHttp, XrdCpFile::isHttps, XrdCpFile::isStdIO, XrdCpFile::isXroot, and XrdCpFile::isXroots.

Referenced by FileType2String(), and main().

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

◆ IndexRemote()

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

Definition at line 415 of file XrdClCopy.cc.

418{
419 using namespace XrdCl;
420
421 Log *log = DefaultEnv::GetLog();
422 log->Debug( AppMsg, "Indexing %s", basePath.c_str() );
423
424 DirectoryList *dirList = 0;
425 XRootDStatus st = fs->DirList( URL( basePath ).GetPath(), DirListFlags::Recursive
427 if( !st.IsOK() )
428 {
429 log->Info( AppMsg, "Failed to get directory listing for %s: %s",
430 basePath.c_str(),
431 st.GetErrorMessage().c_str() );
432 return 0;
433 }
434
435 XrdCpFile start, *current = 0;
436 XrdCpFile *end = &start;
437 int badUrl = 0;
438 for( auto itr = dirList->Begin(); itr != dirList->End(); ++itr )
439 {
440 DirectoryList::ListEntry *e = *itr;
442 continue;
443 std::string path = basePath + '/' + e->GetName();
444 current = new XrdCpFile( path.c_str(), badUrl );
445 if( badUrl )
446 {
447 log->Error( AppMsg, "Bad URL: %s", current->Path );
448 delete current;
449 return 0;
450 }
451
452 current->Doff = dirOffset;
453 end->Next = current;
454 end = current;
455 }
456
457 delete dirList;
458
459 return start.Next;
460}
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, time_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.

References XrdCpFile::XrdCpFile(), 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(), IndexRemote(), 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 IndexRemote(), and 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 475 of file XrdClCopy.cc.

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

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, 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::DoTpcModePush, XrdCpConfig::DoTpcOnly, XrdCpConfig::DoXAttr, XrdCpConfig::DoZip, XrdCpConfig::DoZipAppend, XrdCpConfig::DoZipMtlnCksum, XrdCpConfig::dstFile, XrdCpConfig::dstOpq, XrdCl::Log::Dump(), XrdCl::Log::DumpMsg, XrdCl::errInvalidOp, XrdCl::Status::errNo, XrdCl::Log::Error(), FileType2String(), XrdCl::DefaultEnv::GetEnv(), XrdCl::XRootDStatus::GetErrorMessage(), XrdCl::Env::GetInt(), XrdCl::Log::GetLevel(), XrdCl::DefaultEnv::GetLog(), XrdCl::URL::GetPath(), XrdCl::URL::GetPathWithParams(), XrdCl::DefaultEnv::GetPostMaster(), XrdCl::Status::GetShellCode(), XrdCl::URL::GetURL(), XrdCpConfig::HttpHeaders, IndexRemote(), XrdCl::Log::InfoMsg, XrdCl::DlgEnv::Instance(), XrdCl::StatInfo::IsDir, XrdCpFile::isDir, XrdCpFile::isFile, XrdCl::Status::IsOK(), XrdCpFile::isStdIO, XrdCpFile::isXroot, XrdCpFile::isXroots, kXR_NotAuthorized, kXR_NotFound, main(), XProtocol::mapError(), XrdCpFile::Next, XrdCpConfig::nSrcs, XrdCpConfig::nStrm, obfuscateAuth(), 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::stError, XrdCl::PostMaster::Stop(), XrdCpConfig::tcpTokenFile, XrdCl::StatInfo::TestFlags(), XrdCl::XRootDStatus::ToStr(), XrdCl::Status::ToString(), unlikely, 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 347 of file XrdClCopy.cc.

348{
350
351 XrdCpConfig::defVar *cursor = config->intDefs;
352 while( cursor )
353 {
354 env->PutInt( cursor->vName, cursor->intVal );
355 cursor = cursor->Next;
356 }
357
358 cursor = config->strDefs;
359 while( cursor )
360 {
361 env->PutString( cursor->vName, cursor->strVal );
362 cursor = cursor->Next;
363 }
364}
defVar * intDefs
defVar * strDefs
const char * vName

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

Referenced by main(), and ProcessCommandLineEnv().

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