56#include <readline/history.h>
57#include <readline/readline.h>
71 bool SupportsFullURLs(
const std::string &command )
73 static const char *commands[] = {
74 "cache",
"cat",
"chmod",
"locate",
"ls",
"mkdir",
"mv",
75 "prepare",
"rm",
"rmdir",
"spaceinfo",
"stat",
"statvfs",
76 "tail",
"truncate",
"xattr"
79 return std::find( std::begin( commands ), std::end( commands ), command )
80 != std::end( commands );
86 bool HasExplicitURLScheme(
const std::string &argument )
88 std::string::size_type separator = argument.find(
"://" );
89 if( separator == std::string::npos || separator == 0
90 || !std::isalpha(
static_cast<unsigned char>( argument[0] ) ) )
93 for( std::string::size_type i = 1; i < separator; ++i )
95 unsigned char character =
static_cast<unsigned char>( argument[i] );
96 if( !std::isalnum( character ) && character !=
'+'
97 && character !=
'-' && character !=
'.' )
105 URL &endpoint, std::string &error )
107 if( arguments.empty() )
108 return NotURLCommand;
110 if( arguments[0] ==
"query" )
112 for( std::size_t i = 1; i < arguments.size(); ++i )
114 if( HasExplicitURLScheme( arguments[i] ) )
116 error =
"command-first full URLs are not supported for 'query'";
117 return InvalidURLCommand;
120 return NotURLCommand;
123 if( !SupportsFullURLs( arguments[0] ) )
124 return NotURLCommand;
126 bool foundURL =
false;
127 for( std::size_t i = 1; i < arguments.size(); ++i )
129 if( !HasExplicitURLScheme( arguments[i] ) )
132 URL operand( arguments[i] );
133 if( !operand.IsValid() || operand.GetProtocol() ==
"file"
134 || operand.GetProtocol() ==
"stdio" )
136 error =
"invalid remote URL operand";
137 return InvalidURLCommand;
147 else if( endpoint.
GetProtocol() != operand.GetProtocol()
148 || endpoint.
GetHostId() != operand.GetHostId() )
150 error =
"all URL operands must use the same endpoint";
151 return InvalidURLCommand;
154 arguments[i] = operand.GetPathWithParams();
155 if( arguments[i].empty() || arguments[i][0] !=
'/' )
156 arguments[i].insert( arguments[i].begin(),
'/' );
159 return foundURL ? ValidURLCommand : NotURLCommand;
167 const std::string &path,
168 const char *op =
nullptr )
174 const std::string msg =
"A path is required.";
180 env->
GetInt(
"NoCWD", noCwd );
191 msg = std::string( op ) +
" relative path '" + path +
"' is disallowed.";
193 msg =
"Relative path '" + path +
"' is disallowed.";
198 std::string cwd =
"/";
207 std::list<std::string> pathComponents;
208 std::list<std::string>::iterator it;
211 for( it = pathComponents.begin(); it != pathComponents.end(); )
215 it = pathComponents.erase( it );
221 if( it == pathComponents.begin() )
223 const std::string msg =
"Path '" + path +
"' escapes above root.";
227 std::list<std::string>::iterator it1 = it;
229 it = pathComponents.erase( it1 );
230 it = pathComponents.erase( it );
237 for( it = pathComponents.begin(); it != pathComponents.end(); ++it )
242 if( newPath.length() > 1 )
243 newPath.erase( newPath.length()-1, 1 );
253 if( modeStr.length() != 9 )
257 for(
int i = 0; i < 3; ++i )
259 if( modeStr[i] ==
'r' )
261 else if( modeStr[i] ==
'w' )
263 else if( modeStr[i] ==
'x' )
265 else if( modeStr[i] !=
'-' )
268 for(
int i = 3; i < 6; ++i )
270 if( modeStr[i] ==
'r' )
272 else if( modeStr[i] ==
'w' )
274 else if( modeStr[i] ==
'x' )
276 else if( modeStr[i] !=
'-' )
279 for(
int i = 6; i < 9; ++i )
281 if( modeStr[i] ==
'r' )
283 else if( modeStr[i] ==
'w' )
285 else if( modeStr[i] ==
'x' )
287 else if( modeStr[i] !=
'-' )
304 uint32_t argc = args.size();
308 log->
Error(
AppMsg,
"Wrong number of arguments." );
310 "Wrong number of arguments." );
313 if( args[1] !=
"evict" && args[1] !=
"fevict")
319 std::string fullPath;
327 std::string cmd = args[1];
329 cmd.append(fullPath);
340 st.
ToStr().c_str() );
346 std::cout << response->
ToString() <<
'\n';
364 if( args.size() != 2 )
366 log->
Error(
AppMsg,
"Invalid arguments. Expected a path." );
373 env->
PutInt(
"NoCWD", 0 );
393 log->
Error(
AppMsg,
"%s is not a directory.", newPath.c_str() );
407 if( nb == 0 )
return 1;
408 return uint32_t( log10(
double(nb) ) + 1);
411std::string
getSizeStr(uint64_t size,
bool human, uint64_t base) {
412 std::ostringstream oss;
421void PrintDirListStatInfo(
StatInfo *info,
bool hascks =
false, uint32_t ownerwidth = 0, uint32_t groupwidth = 0, uint32_t sizewidth = 0,
bool human =
false, uint64_t base = 1000 )
431 std::cout <<
" " << std::setw( ownerwidth ) << info->
GetOwner();
432 std::cout <<
" " << std::setw( groupwidth ) << info->
GetGroup();
433 std::cout <<
" " << std::setw( sizewidth ) <<
getSizeStr(info->
GetSize(),human, base);
435 std::cout <<
" " << std::setw( sizewidth ) << info->
GetChecksum();
462 uint64_t size = info->
GetSize();
463 std::string displaySize =
getSizeStr(size,human,base);
464 int width = displaySize.size() + 2;
468 std::cout << std::setw( width ) << displaySize <<
" ";
483 uint32_t argc = args.size();
485 bool showUrls =
false;
488 uint64_t base = 1024;
498 for( uint32_t i = 1; i < args.size(); ++i )
500 if( args[i] ==
"-l" )
505 else if( args[i] ==
"-u" )
507 else if( args[i] ==
"-R" )
511 else if( args[i] ==
"-D" )
516 else if( args[i] ==
"-Z" )
521 else if( args[i] ==
"-C" )
528 else if ( args [i] ==
"-h" )
541 std::string newPath =
"/";
554 log->
Debug(
AppMsg,
"Attempting to stat: %s", newPath.c_str() );
558 std::unique_ptr<StatInfo> ptr( info );
577 std::cout << newPath << std::endl;
585 log->
Debug(
AppMsg,
"Attempting to list: %s", newPath.c_str() );
588 st = fs->
DirList( newPath, flags, list );
597 std::cerr <<
"[!] Some of the requests failed. The result may be ";
598 std::cerr <<
"incomplete." << std::endl;
601 uint32_t ownerwidth = 0, groupwidth = 0, sizewidth = 0, ckswidth = 0;
603 for( it = list->
Begin(); it != list->
End() && stats; ++it )
605 StatInfo *info = (*it)->GetStatInfo();
608 uint32_t sizeWidthComp;
610 sizeWidthComp = size.size();
615 if( ownerwidth < info->GetOwner().size() )
616 ownerwidth = info->
GetOwner().size();
617 if( groupwidth < info->GetGroup().size() )
618 groupwidth = info->
GetGroup().size();
619 if( sizewidth < sizeWidthComp )
620 sizewidth = sizeWidthComp;
621 if( ckswidth < info->GetChecksum().size() )
628 for( it = list->
Begin(); it != list->
End(); ++it )
632 StatInfo *info = (*it)->GetStatInfo();
634 std::cout <<
"---- 0000-00-00 00:00:00 ? ";
639 std::cout <<
"root://" << (*it)->GetHostAddress() <<
"/";
640 std::cout << list->
GetParentName() << (*it)->GetName() << std::endl;
657 uint32_t argc = args.size();
659 if( argc < 2 || argc > 4 )
667 std::string modeStr =
"rwxr-x---";
668 std::string path =
"";
670 for( uint32_t i = 1; i < args.size(); ++i )
672 if( args[i] ==
"-p" )
674 else if( !args[i].compare( 0, 2,
"-m" ) )
675 modeStr = args[i].substr( 2, 9 );
695 st = fs->
MkDir( newPath, flags, mode );
698 log->
Error(
AppMsg,
"Unable create directory %s: %s",
700 st.
ToStr().c_str() );
718 uint32_t argc = args.size();
722 log->
Error(
AppMsg,
"Wrong number of arguments." );
726 std::string fullPath;
737 log->
Error(
AppMsg,
"Unable remove directory %s: %s",
739 st.
ToStr().c_str() );
757 uint32_t argc = args.size();
761 log->
Error(
AppMsg,
"Wrong number of arguments." );
765 std::string fullPath1;
770 std::string fullPath2;
771 pathSt =
BuildPath( fullPath2, env, args[2],
"Renaming to" );
777 "cannot move directory to a subdirectory of itself." );
786 fullPath1.c_str(), fullPath2.c_str(),
787 st.
ToStr().c_str() );
805 uint32_t argc = args.size();
809 log->
Error(
AppMsg,
"Wrong number of arguments." );
815 void print(
const std::string &msg )
817 std::unique_lock<std::mutex> lck( mtx );
818 std::cout << msg <<
'\n';
822 std::shared_ptr<print_t> print;
824 print = std::make_shared<print_t>();
826 std::vector<Pipeline> rms;
827 rms.reserve( argc - 1 );
828 for(
size_t i = 1; i < argc; ++i )
830 std::string fullPath;
834 rms.emplace_back(
Rm( fs, fullPath ) >>
841 st.
ToStr().c_str() );
845 print->print(
"rm " + fullPath +
" : " + st.
ToString() );
855 const size_t rs = rms.size();
874 uint32_t argc = args.size();
878 log->
Error(
AppMsg,
"Wrong number of arguments." );
882 std::string fullPath;
888 uint64_t size = ::strtoll( args[2].c_str(), &result, 0 );
891 log->
Error(
AppMsg,
"Size parameter needs to be an integer" );
903 st.
ToStr().c_str() );
921 uint32_t argc = args.size();
925 log->
Error(
AppMsg,
"Wrong number of arguments." );
929 std::string fullPath;
945 st = fs->
ChMod( fullPath, mode );
948 log->
Error(
AppMsg,
"Unable change mode of %s: %s",
950 st.
ToStr().c_str() );
968 uint32_t argc = args.size();
972 log->
Error(
AppMsg,
"Wrong number of arguments." );
978 bool hasPath =
false;
979 bool doDeepLocate =
false;
980 for( uint32_t i = 1; i < argc; ++i )
982 if( args[i] ==
"-n" )
984 else if( args[i] ==
"-r" )
986 else if( args[i] ==
"-m" || args[i] ==
"-h" )
988 else if( args[i] ==
"-i" )
990 else if( args[i] ==
"-d" )
992 else if( args[i] ==
"-p" )
995 env->
PutInt(
"PreserveLocateTried", 0 );
1004 log->
Error(
AppMsg,
"Invalid argument: %s.", args[i].c_str() );
1009 std::string fullPath;
1010 if( path[0] ==
'*' )
1015 if( !pathSt.
IsOK() )
1025 st = fs->
DeepLocate( fullPath, flags, info );
1027 st = fs->
Locate( fullPath, flags, info );
1033 st.
ToStr().c_str() );
1042 std::cerr <<
"[!] Some of the requests failed. The result may be ";
1043 std::cerr <<
"incomplete." << std::endl;
1047 for( it = info->
Begin(); it != info->
End(); ++it )
1049 std::cout << it->GetAddress() <<
" ";
1050 switch( it->GetType() )
1053 std::cout <<
"Manager ";
1056 std::cout <<
"ManagerPending ";
1059 std::cout <<
"Server ";
1062 std::cout <<
"ServerPending ";
1065 std::cout <<
"Unknown ";
1068 switch( it->GetAccessType() )
1071 std::cout <<
"Read";
1074 std::cout <<
"ReadWrite ";
1077 std::cout <<
"Unknown ";
1079 std::cout << std::endl;
1096 bool isOrQuery =
false;
1098 if( query.find(
'|' ) != std::string::npos )
1103 std::vector<std::string> queryFlags;
1112 std::map<std::string, StatInfo::Flags> flagMap;
1122 std::vector<std::string>::iterator it;
1123 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1124 if( flagMap.find( *it ) == flagMap.end() )
1126 log->
Error(
AppMsg,
"Flag '%s' is not recognized.", it->c_str() );
1135 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1141 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1162 uint32_t argc = args.size();
1166 log->
Error(
AppMsg,
"Wrong number of arguments." );
1170 std::vector<std::string> paths;
1173 for( uint32_t i = 1; i < args.size(); ++i )
1175 if( args[i] ==
"-q" )
1177 if( i < args.size()-1 )
1184 log->
Error(
AppMsg,
"Parameter '-q' requires an argument." );
1189 paths.emplace_back( args[i] );
1192 std::vector<XrdCl::Pipeline> stats;
1193 std::vector<std::tuple<std::future<StatInfo>, std::string>> results;
1194 for(
auto &path : paths )
1196 std::string fullPath;
1198 if( !pathSt.
IsOK() )
1200 std::future<XrdCl::StatInfo> ftr;
1201 stats.emplace_back(
XrdCl::Stat( fs, fullPath ) >> ftr );
1202 results.emplace_back( std::move( ftr ), std::move( fullPath ) );
1214 for(
auto &tpl : results )
1216 auto &ftr = std::get<0>( tpl );
1217 auto &fullPath = std::get<1>( tpl );
1218 std::cout << std::endl;
1225 flags +=
"XBitSet|";
1231 flags +=
"Offline|";
1233 flags +=
"POSCPending|";
1235 flags +=
"IsReadable|";
1237 flags +=
"IsWritable|";
1239 flags +=
"BackUpExists|";
1241 if( !flags.empty() )
1242 flags.erase( flags.length()-1, 1 );
1244 std::cout <<
"Path: " << fullPath << std::endl;
1245 std::cout <<
"Id: " << info.
GetId() << std::endl;
1246 std::cout <<
"Size: " << info.
GetSize() << std::endl;
1255 std::cout <<
"Flags: " << info.
GetFlags() <<
" (" << flags <<
")";
1261 std::cout <<
"Owner: " << info.
GetOwner() << std::endl;
1262 std::cout <<
"Group: " << info.
GetGroup();
1265 std::cout << std::endl;
1267 if( query.length() != 0 )
1272 std::cout <<
"Query: " << query <<
" " << std::endl;
1278 log->
Error(
AppMsg,
"Unable stat %s: %s", fullPath.c_str(), st.
ToStr().c_str() );
1296 uint32_t argc = args.size();
1300 log->
Error(
AppMsg,
"Wrong number of arguments." );
1304 std::string fullPath;
1306 if( !pathSt.
IsOK() )
1319 st.
ToStr().c_str() );
1326 std::cout <<
"Path: ";
1327 std::cout << fullPath << std::endl;
1328 std::cout <<
"Nodes with RW space: ";
1329 std::cout << info->
GetNodesRW() << std::endl;
1330 std::cout <<
"Size of largest RW space (MB): ";
1331 std::cout << info->
GetFreeRW() << std::endl;
1332 std::cout <<
"Utilization of RW space (%): ";
1334 std::cout <<
"Nodes with staging space: ";
1336 std::cout <<
"Size of largest staging space (MB): ";
1338 std::cout <<
"Utilization of staging space (%): ";
1356 uint32_t argc = args.size();
1358 if( !( argc >= 3 ) )
1360 log->
Error(
AppMsg,
"Wrong number of arguments." );
1365 if( args[1] ==
"config" )
1367 else if( args[1] ==
"checksumcancel" )
1369 else if( args[1] ==
"checksum" )
1371 else if( args[1] ==
"opaque" )
1373 else if( args[1] ==
"opaquefile" )
1375 else if( args[1] ==
"prepare" )
1377 else if( args[1] ==
"space" )
1379 else if( args[1] ==
"stats" )
1381 else if( args[1] ==
"xattr" )
1391 log->
Error(
AppMsg,
"Wrong number of arguments." );
1395 std::string strArg = args[2];
1400 for(
size_t i = 3; i < args.size(); ++i )
1402 std::string path = args[i];
1404 if( !pathSt.
IsOK() )
1413 std::string strArg = args[2];
1419 if( !pathSt.
IsOK() )
1427 Buffer arg( strArg.size() );
1436 st.
ToStr().c_str() );
1443 std::cout << response->
ToString() << std::endl;
1459 uint32_t argc = args.size();
1463 log->
Error(
AppMsg,
"Wrong number of arguments." );
1468 std::vector<std::string> files;
1469 uint8_t priority = 0;
1472 for( uint32_t i = 1; i < args.size(); ++i )
1474 if( args[i] ==
"-p" )
1476 if( i < args.size()-1 )
1479 int32_t param = ::strtol( args[i+1].c_str(), &result, 0 );
1480 if( *result != 0 || param > 3 || param < 0 )
1482 log->
Error(
AppMsg,
"Size priotiry needs to be an integer between 0 "
1486 priority = (uint8_t)param;
1491 log->
Error(
AppMsg,
"Parameter '-p' requires an argument." );
1495 else if( args[i] ==
"-c" )
1497 else if( args[i] ==
"-f" )
1499 else if( args[i] ==
"-s" )
1501 else if( args[i] ==
"-w" )
1503 else if( args[i] ==
"-e" )
1505 else if( args[i] ==
"-a" )
1508 if( i < args.size()-1 )
1512 files.push_back( args[i+1] );
1517 log->
Error(
AppMsg,
"Parameter '-a' requires an argument." );
1522 files.push_back( args[i] );
1544 std::cout << response->
ToString() <<
'\n';
1568 JobProgress( jobNum, pBytesProcessed, pBytesTotal );
1569 std::cerr << std::endl;
1576 uint64_t bytesProcessed,
1577 uint64_t bytesTotal )
1579 pBytesProcessed = bytesProcessed;
1580 pBytesTotal = bytesTotal;
1582 time_t now = time(0);
1583 if( (now - pPrevious < 1) && (bytesProcessed != bytesTotal) )
1588 std::cerr <<
"Progress: ";
1592 std::cerr <<
"(" << bytesProcessed*100/bytesTotal <<
"%)";
1594 std::cerr << std::flush;
1598 uint64_t pBytesProcessed;
1599 uint64_t pBytesTotal;
1614 uint32_t argc = args.size();
1618 log->
Error(
AppMsg,
"Wrong number of arguments." );
1624 if( server.empty() )
1626 log->
Error(
AppMsg,
"Invalid address: \"%s\".", server.c_str() );
1630 std::vector<std::string> remotes;
1633 for( uint32_t i = 1; i < args.size(); ++i )
1635 if( args[i] ==
"-o" )
1637 if( i < args.size()-1 )
1644 log->
Error(
AppMsg,
"Parameter '-o' requires an argument." );
1649 remotes.emplace_back( args[i] );
1652 if( !local.empty() && remotes.size() > 1 )
1654 log->
Error(
AppMsg,
"If '-o' is used only can be used with only one remote file." );
1659 if( !local.empty() && local[0] !=
'/' )
1661 std::unique_ptr<char,
decltype( &free )> cwd( getcwd(
nullptr, 0 ), free );
1665 log->
Error(
AppMsg,
"Unable to get the current directory: %s",
1669 local = std::string( cwd.get() ) +
"/" + local;
1672 std::vector<URL> remoteUrls;
1673 remoteUrls.reserve( remotes.size() );
1674 for(
auto &remote : remotes )
1676 std::string remoteFile;
1678 if( !pathSt.
IsOK() )
1681 remoteUrls.emplace_back( server );
1682 remoteUrls.back().SetPath( remoteFile );
1690 std::vector<PropertyList> props( remoteUrls.size() ), results( remoteUrls.size() );
1692 for(
size_t i = 0; i < remoteUrls.size(); ++i )
1694 props[i].Set(
"source", remoteUrls[i].GetURL() );
1695 if( !local.empty() )
1697 props[i].Set(
"target", std::string(
"file://" ) + local );
1701 props[i].Set(
"target",
"stdio://-" );
1703 props[i].Set(
"dynamicSource",
true );
1720 st = process.
Run(handler);
1741 uint32_t argc = args.size();
1743 if( argc < 2 || argc > 5 )
1745 log->
Error(
AppMsg,
"Wrong number of arguments." );
1751 if( server.empty() )
1753 log->
Error(
AppMsg,
"Invalid address: \"%s\".", server.c_str() );
1758 bool followMode =
false;
1759 uint32_t offset = 512;
1761 for( uint32_t i = 1; i < args.size(); ++i )
1763 if( args[i] ==
"-f" )
1765 else if( args[i] ==
"-c" )
1767 if( i < args.size()-1 )
1770 offset = ::strtol( args[i+1].c_str(), &result, 0 );
1773 log->
Error(
AppMsg,
"Offset from the end needs to be a number: %s",
1774 args[i+1].c_str() );
1781 log->
Error(
AppMsg,
"Parameter '-n' requires an argument." );
1789 std::string remoteFile;
1791 if( !pathSt.
IsOK() )
1794 URL remoteUrl( server );
1795 remoteUrl.
SetPath( remoteFile );
1811 st = file.
Stat(
false, info );
1817 offset = size - offset;
1819 uint32_t chunkSize = 1*1024*1024;
1820 char *buffer =
new char[chunkSize];
1821 uint32_t bytesRead = 0;
1824 st = file.
Read( offset, chunkSize, buffer, bytesRead );
1833 offset += bytesRead;
1834 int ret =
write( 1, buffer, bytesRead );
1837 log->
Error(
AppMsg,
"Unable to write to stdout: %s",
1843 if( bytesRead < chunkSize )
1864 using namespace XrdCl;
1870 uint32_t argc = args.size();
1874 log->
Error(
AppMsg,
"Wrong number of arguments." );
1886 std::cerr <<
"[!] Some of the requests failed. The result may be ";
1887 std::cerr <<
"incomplete." << std::endl;
1890 std::cout <<
"Path: " << args[1] << std::endl;
1891 std::cout <<
"Total: " << i->
GetTotal() << std::endl;
1892 std::cout <<
"Free: " << i->
GetFree() << std::endl;
1893 std::cout <<
"Used: " << i->
GetUsed() << std::endl;
1911 uint32_t argc = args.size();
1915 log->
Error(
AppMsg,
"Wrong number of arguments." );
1920 if( args[2] ==
"set")
1922 else if( args[2] ==
"get" )
1924 else if( args[2] ==
"del" )
1926 else if( args[2] ==
"list" )
1936 if( !pathSt.
IsOK() )
1949 log->
Error(
AppMsg,
"Wrong number of arguments." );
1953 std::string key_value = args[3];
1954 size_t pos = key_value.find(
'=' );
1955 std::string key = key_value.substr( 0, pos );
1956 std::string value = key_value.substr( pos + 1 );
1957 std::vector<xattr_t> attrs;
1958 attrs.push_back( std::make_tuple( key, value ) );
1960 std::vector<XAttrStatus> result;
1967 if( !status.
IsOK() )
1968 log->
Error(
AppMsg,
"Unable to xattr set %s %s: %s",
1969 key.c_str(), value.c_str(),
1970 status.
ToStr().c_str() );
1978 log->
Error(
AppMsg,
"Wrong number of arguments." );
1982 std::string key = args[3];
1983 std::vector<std::string> attrs;
1984 attrs.push_back( key );
1986 std::vector<XAttr> result;
1988 XAttr xattr = status.
IsOK() ? result.front() :
XAttr( key, status );
1993 if( !status.
IsOK() )
1994 log->
Error(
AppMsg,
"Unable to xattr get %s : %s",
1996 status.
ToStr().c_str() );
1999 std::cout <<
"# file: " << path <<
'\n';
2000 std::cout << xattr.
name <<
"=\"" << xattr.
value <<
"\"\n";
2010 log->
Error(
AppMsg,
"Wrong number of arguments." );
2014 std::string key = args[3];
2015 std::vector<std::string> attrs;
2016 attrs.push_back( key );
2018 std::vector<XAttrStatus> result ;
2025 if( !status.
IsOK() )
2026 log->
Error(
AppMsg,
"Unable to xattr del %s : %s",
2028 status.
ToStr().c_str() );
2036 log->
Error(
AppMsg,
"Wrong number of arguments." );
2040 std::vector<XAttr> result;
2043 if( !status.
IsOK() )
2045 status.
ToStr().c_str() );
2048 std::cout <<
"# file: " << path <<
'\n';
2049 auto itr = result.begin();
2050 for( ; itr != result.end(); ++itr )
2051 std::cout << itr->name <<
"=\"" << itr->value <<
"\"\n";
2068 printf(
"Usage:\n" );
2069 printf(
" xrdfs [options] host[:port] - interactive mode\n" );
2070 printf(
" xrdfs [options] host[:port] command args - server-first batch\n" );
2071 printf(
" xrdfs [options] command args-with-URLs - command-first batch\n\n" );
2073 printf(
"The two batch forms cannot be mixed.\n\n" );
2075 printf(
"Available options:\n\n" );
2077 printf(
" -4, --ipv4 use only the IPv4 network stack\n" );
2078 printf(
" -6, --ipv6 use only the IPv6 network stack\n" );
2079 printf(
" -d, --debug <level> set debug level: 0 off, 1 low, 2 medium,\n" );
2080 printf(
" 3 high\n" );
2081 printf(
" -h, --help show this help\n" );
2082 printf(
" --no-cwd do not preset a CWD in interactive mode\n\n" );
2084 printf(
"Available commands:\n\n" );
2086 printf(
" exit\n" );
2087 printf(
" Exits from the program.\n\n" );
2089 printf(
" help\n" );
2090 printf(
" This help screen.\n\n" );
2092 printf(
" cache {evict | fevict} <path>\n" );
2093 printf(
" Evict a file from a cache if not in use; while fevict\n" );
2094 printf(
" forcibly evicts the file causing any current uses of the\n" );
2095 printf(
" file to get read failures on a subsequent read\n\n" );
2097 printf(
" cd <path>\n" );
2098 printf(
" Change the current working directory\n\n" );
2100 printf(
" chmod <path> <user><group><other>\n" );
2101 printf(
" Modify permissions. Permission string example:\n" );
2102 printf(
" rwxr-x--x\n\n" );
2104 printf(
" ls [-l] [-u] [-R] [-D] [-Z] [-C] [dirname]\n" );
2105 printf(
" Get directory listing.\n" );
2106 printf(
" -l stat every entry and print long listing\n" );
2107 printf(
" -u print paths as URLs\n" );
2108 printf(
" -R list subdirectories recursively\n" );
2109 printf(
" -D show duplicate entries\n" );
2110 printf(
" -Z if a ZIP archive list its content\n" );
2111 printf(
" -C checksum every entry\n\n" );
2113 printf(
" locate [-n] [-r] [-d] [-m] [-i] [-p] <path>\n" );
2114 printf(
" Get the locations of the path.\n" );
2115 printf(
" -r refresh, don't use cached locations\n" );
2116 printf(
" -n make the server return the response immediately even\n" );
2117 printf(
" though it may be incomplete\n" );
2118 printf(
" -d do a recursive (deep) locate\n" );
2119 printf(
" -m|-h prefer host names to IP addresses\n" );
2120 printf(
" -i ignore network dependencies\n" );
2121 printf(
" -p be passive: ignore tried/triedrc cgi opaque info\n\n" );
2123 printf(
" mkdir [-p] [-m<user><group><other>] <dirname>\n" );
2124 printf(
" Creates a directory/tree of directories.\n\n" );
2126 printf(
" mv <path1> <path2>\n" );
2127 printf(
" Move path1 to path2 locally on the same server.\n\n" );
2129 printf(
" stat [-q query] <path>\n" );
2130 printf(
" Get info about the file or directory.\n" );
2131 printf(
" -q query optional flag query parameter that makes\n" );
2132 printf(
" xrdfs return error code to the shell if the\n" );
2133 printf(
" requested flag combination is not present;\n" );
2134 printf(
" flags may be combined together using '|' or '&'\n" );
2135 printf(
" Available flags:\n" );
2136 printf(
" XBitSet, IsDir, Other, Offline, POSCPending,\n" );
2137 printf(
" IsReadable, IsWritable\n\n" );
2139 printf(
" statvfs <path>\n" );
2140 printf(
" Get info about a virtual file system.\n\n" );
2142 printf(
" query <code> <parameters>\n" );
2143 printf(
" Obtain server information. Query codes:\n\n" );
2145 printf(
" config <what> Server configuration; <what> is\n" );
2146 printf(
" one of the following:\n" );
2147 printf(
" bind_max - the maximum number of parallel streams\n" );
2148 printf(
" chksum - the supported checksum\n" );
2149 printf(
" cms - the status of the cmsd\n" );
2150 printf(
" pio_max - maximum number of parallel I/O requests\n" );
2151 printf(
" readv_ior_max - maximum size of a readv element\n" );
2152 printf(
" readv_iov_max - maximum number of readv entries\n" );
2153 printf(
" role - the role in a cluster\n" );
2154 printf(
" sitename - the site name\n" );
2155 printf(
" tpc - support for third party copies\n" );
2156 printf(
" version - the version of the server\n" );
2157 printf(
" wan_port - the port to use for wan copies\n" );
2158 printf(
" wan_window - the wan_port window size\n" );
2159 printf(
" window - the tcp window size\n" );
2160 printf(
" checksumcancel <path> File checksum cancellation\n" );
2161 printf(
" checksum <path> File checksum\n" );
2162 printf(
" opaque <arg> Implementation dependent\n" );
2163 printf(
" opaquefile <arg> Implementation dependent\n" );
2164 printf(
" space <space> Logical space stats\n" );
2165 printf(
" stats <what> Server stats; <what> is a list\n" );
2166 printf(
" of letters indicating information\n");
2167 printf(
" to be returned:\n" );
2168 printf(
" a - all statistics\n" );
2169 printf(
" p - protocol statistics\n" );
2170 printf(
" b - buffer usage statistics\n" );
2171 printf(
" s - scheduling statistics\n" );
2172 printf(
" d - device polling statistics\n" );
2173 printf(
" u - usage statistics\n" );
2174 printf(
" i - server identification\n" );
2175 printf(
" z - synchronized statistics\n" );
2176 printf(
" l - connection statistics\n" );
2177 printf(
" xattr <path> Extended attributes\n" );
2178 printf(
" prepare <reqid> [filenames] Prepare request status\n\n" );
2180 printf(
" rm <filename>\n" );
2181 printf(
" Remove a file.\n\n" );
2183 printf(
" rmdir <dirname>\n" );
2184 printf(
" Remove a directory.\n\n" );
2186 printf(
" truncate <filename> <length>\n" );
2187 printf(
" Truncate a file.\n\n" );
2189 printf(
" prepare [-c] [-f] [-s] [-w] [-e] [-p priority] [-a requestid] filenames\n" );
2190 printf(
" Prepare one or more files for access.\n" );
2191 printf(
" -c co-locate staged files if possible\n" );
2192 printf(
" -f refresh file access time even if the location is known\n" );
2193 printf(
" -s stage the files to disk if they are not online\n" );
2194 printf(
" -w the files will be accessed for modification\n" );
2195 printf(
" -p priority of the request, 0 (lowest) - 3 (highest)\n" );
2196 printf(
" -a abort stage request\n" );
2197 printf(
" -e evict the file from disk cache\n\n" );
2199 printf(
" cat [-o local file] files\n" );
2200 printf(
" Print contents of one or more files to stdout.\n" );
2201 printf(
" -o print to the specified local file\n\n" );
2203 printf(
" tail [-c bytes] [-f] file\n" );
2204 printf(
" Output last part of files to stdout.\n" );
2205 printf(
" -c num_bytes out last num_bytes\n" );
2206 printf(
" -f output appended data as file grows\n\n" );
2208 printf(
" spaceinfo path\n" );
2209 printf(
" Get space statistics for given path.\n\n" );
2211 printf(
" xattr <path> <code> <params> \n" );
2212 printf(
" Operation on extended attributes. Codes:\n\n" );
2213 printf(
" set <attr> Set extended attribute; <attr> is\n" );
2214 printf(
" string of form name=value\n" );
2215 printf(
" get <name> Get extended attribute\n" );
2216 printf(
" del <name> Delete extended attribute\n" );
2217 printf(
" list List extended attributes\n\n" );
2259 std::cerr << st.
ToStr() << std::endl;
2266#ifndef HAVE_READLINE
2269 std::cout << prompt << std::flush;
2271 std::getline( std::cin, input );
2273 if( !std::cin.good() )
2276 char *linebuf = (
char *)malloc( input.size()+1 );
2277 strncpy( linebuf, input.c_str(), input.size()+1 );
2308 std::ostringstream prompt;
2309 std::string cwd =
"/";
2311 prompt <<
"[" << url.
GetHostId() <<
"] " << cwd <<
" > ";
2312 return prompt.str();
2322bool getArguments (std::vector<std::string> & result,
const std::string &input)
2325 static const char delimiter =
' ';
2327 const char singleQuote =
'\'', doubleQuote =
'\"';
2331 char currentQuote =
'\0';
2334 for (std::string::const_iterator it = input.begin (); it != input.end (); ++it)
2337 if (*it == singleQuote || *it == doubleQuote)
2346 else if (currentQuote == *it)
2348 currentQuote =
'\0';
2353 if (currentQuote || *it != delimiter)
2363 result.push_back(tmp);
2371 result.push_back(tmp);
2374 return currentQuote ==
'\0';
2385 std::string historyFile = getenv(
"HOME" );
2386 historyFile +=
"/.xrdquery.history";
2397 std::string cmdline;
2405 if( !linebuf || !strncmp( linebuf,
"exit", 4 ) || !strncmp( linebuf,
"quit", 4 ) )
2407 std::cout <<
"Goodbye." << std::endl << std::endl;
2415 std::vector<std::string> args;
2424 std::cerr << st.
ToStr() << std::endl;
2454 enum { NoCwdOption = 256 };
2455 static const option options[] = {
2456 {
"ipv4", no_argument, 0,
'4' },
2457 {
"ipv6", no_argument, 0,
'6' },
2458 {
"debug", required_argument, 0,
'd' },
2459 {
"help", no_argument, 0,
'h' },
2460 {
"no-cwd", no_argument, 0, NoCwdOption },
2466 std::string networkStack;
2469 while( (option = getopt_long( argc, argv,
"+46d:h", options, 0 )) != -1 )
2474 if( networkStack ==
"IPv6" )
2476 std::cerr <<
"xrdfs: -4 and -6 are mutually exclusive" << std::endl;
2479 networkStack =
"IPv4";
2482 if( networkStack ==
"IPv4" )
2484 std::cerr <<
"xrdfs: -4 and -6 are mutually exclusive" << std::endl;
2487 networkStack =
"IPv6";
2492 long level = std::strtol( optarg, &end, 10 );
2493 if( !*optarg || *end || level < 0 || level > 3 )
2495 std::cerr <<
"xrdfs: invalid debug level '" << optarg
2496 <<
"' (expected 0-3)" << std::endl;
2499 debugLevel =
static_cast<int>( level );
2514 if( !networkStack.empty() )
2520 if( debugLevel == 1 )
2522 else if( debugLevel == 2 )
2537 URLCommandResult result = ParseURLCommand( arguments, url, error );
2538 if( result == InvalidURLCommand )
2540 std::cerr <<
"xrdfs: " << error << std::endl;
2544 if( result == ValidURLCommand )
2547 url =
URL( arguments[0] );
2554 if( arguments.size() == 1 )
2557 arguments.erase( arguments.begin() );
2561 if( arguments[0] !=
"query" )
2563 URL inferredEndpoint;
2564 result = ParseURLCommand( arguments, inferredEndpoint, error );
2565 if( result == InvalidURLCommand )
2567 std::cerr <<
"xrdfs: " << error << std::endl;
2571 if( result == ValidURLCommand )
2573 std::cerr <<
"xrdfs: cannot mix a leading endpoint with full URL "
2574 "operands; use either server-first or command-first syntax"
void PrintDirListStatInfo(StatInfo *info, bool hascks=false, uint32_t ownerwidth=0, uint32_t groupwidth=0, uint32_t sizewidth=0, bool human=false, uint64_t base=1000)
uint32_t nbDigits(uint64_t nb)
XRootDStatus DoQuery(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoLocate(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
int write_history(const char *)
XRootDStatus DoMkDir(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
void add_history(const char *)
XRootDStatus DoRmDir(FileSystem *query, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoRm(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoTail(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
int ExecuteInteractive(const URL &url, bool noCwd=false)
int main(int argc, char **argv)
void rl_bind_key(char, uint16_t)
XRootDStatus DoStat(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus ProcessStatQuery(StatInfo &info, const std::string &query)
XRootDStatus DoCat(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus BuildPath(std::string &newPath, Env *env, const std::string &path, const char *op=nullptr)
std::string BuildPrompt(Env *env, const URL &url)
XRootDStatus DoMv(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoPrepare(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoChMod(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
FSExecutor * CreateExecutor(const URL &url)
XRootDStatus DoLS(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
bool getArguments(std::vector< std::string > &result, const std::string &input)
XRootDStatus DoCD(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoXAttr(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
char * readline(const char *prompt)
XRootDStatus DoStatVFS(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoCache(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus DoSpaceInfo(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
int read_history(const char *)
XRootDStatus ConvertMode(Access::Mode &mode, const std::string &modeStr)
int ExecuteCommand(FSExecutor *ex, const FSExecutor::CommandParams &args)
std::string getSizeStr(uint64_t size, bool human, uint64_t base)
XRootDStatus DoTruncate(FileSystem *fs, Env *env, const FSExecutor::CommandParams &args)
XRootDStatus PrintHelp(FileSystem *, Env *, const FSExecutor::CommandParams &)
static bool is_subdirectory(const std::string_view dir, const std::string_view subdir)
const char * XrdSysE2T(int errcode)
virtual void EndJob(uint32_t jobNum, const XrdCl::PropertyList *results)
virtual void JobProgress(uint32_t jobNum, uint64_t bytesProcessed, uint64_t bytesTotal)
Job progress.
Binary blob representation.
void FromString(const std::string str)
Fill the buffer from a string.
std::string ToString() const
Convert the buffer to a string.
Copy the data from one point to another.
XRootDStatus Run(CopyProgressHandler *handler)
Run the copy jobs.
XRootDStatus AddJob(const PropertyList &properties, PropertyList *results)
Interface for copy progress notification.
static Log * GetLog()
Get default log.
static Env * GetEnv()
Get default client environment.
const std::string & GetParentName() const
Get parent directory name.
DirList::iterator Iterator
Directory listing iterator.
Iterator End()
Get the end iterator.
Iterator Begin()
Get the begin iterator.
bool PutInt(const std::string &key, int value)
bool PutString(const std::string &key, const std::string &value)
bool GetString(const std::string &key, std::string &value)
bool GetInt(const std::string &key, int &value)
Execute queries given as a commandline.
std::vector< std::string > CommandParams
Definition of command argument list.
XRootDStatus Execute(const CommandParams &args)
bool AddCommand(const std::string &name, Command command)
Env * GetEnv()
Get the environment.
Container for space information.
uint64_t GetUsed() const
Amount of used space in MB.
uint64_t GetLargestFreeChunk() const
Largest single chunk of free space.
uint64_t GetTotal() const
Amount of total space in MB.
uint64_t GetFree() const
Amount of free space in MB.
static XRootDStatus GetSpaceInfo(SpaceInfo *&result, FileSystem *fs, const std::string &path)
Recursively get space information for given path.
Send file/filesystem queries to an XRootD cluster.
XRootDStatus Mv(const std::string &source, const std::string &dest, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus DirList(const std::string &path, DirListFlags::Flags flags, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Locate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus SendCache(const std::string &info, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Truncate(const std::string &path, uint64_t size, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus RmDir(const std::string &path, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus ListXAttr(const std::string &path, ResponseHandler *handler, time_t timeout=0)
XRootDStatus Stat(const std::string &path, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus StatVFS(const std::string &path, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus GetXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, time_t timeout=0)
XRootDStatus ChMod(const std::string &path, Access::Mode mode, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus DelXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, time_t timeout=0)
XRootDStatus Prepare(const std::vector< std::string > &fileList, PrepareFlags::Flags flags, uint8_t priority, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus MkDir(const std::string &path, MkDirFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Query(QueryCode::Code queryCode, const Buffer &arg, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus SetXAttr(const std::string &path, const std::vector< xattr_t > &attrs, ResponseHandler *handler, time_t timeout=0)
bool GetProperty(const std::string &name, std::string &value) const
XRootDStatus DeepLocate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Close(ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Stat(bool force, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Iterator Begin()
Get the location begin iterator.
@ Read
read access is allowed
@ ReadWrite
write access is allowed
@ ServerPending
server node where the file is pending to be online
@ ManagerOnline
manager node where the file is online
@ ServerOnline
server node where the file is online
@ ManagerPending
manager node where the file is pending to be online
LocationList::iterator Iterator
Iterator over locations.
Iterator End()
Get the location end iterator.
@ DebugMsg
print debug info
@ DumpMsg
print details of the request and responses
void SetLevel(LogLevel level)
Set the level of the messages that should be sent to the destination.
void Error(uint64_t topic, const char *format,...)
Report an error.
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Pipeline exception, wrapps an XRootDStatus.
const XRootDStatus & GetError() const
A key-value pair map storing both keys and values as strings.
uint64_t GetFreeRW() const
Get size of the largest contiguous area of free r/w space (in MB)
uint64_t GetNodesStaging() const
Get number of nodes that can provide staging space.
uint8_t GetUtilizationStaging() const
Get percentage of the partition utilization represented by FreeStaging.
uint64_t GetFreeStaging() const
Get size of the largest contiguous area of free staging space (in MB)
uint8_t GetUtilizationRW() const
Get percentage of the partition utilization represented by FreeRW.
uint64_t GetNodesRW() const
Get number of nodes that can provide read/write space.
std::string GetChangeTimeAsString() const
Get change time.
std::string GetModTimeAsString() const
Get modification time.
bool HasChecksum() const
Has checksum.
bool TestFlags(uint32_t flags) const
Test flags.
uint64_t GetSize() const
Get size (in bytes)
const std::string GetModeAsOctString() const
Get mode.
const std::string & GetOwner() const
Get owner.
@ IsReadable
Read access is allowed.
@ IsDir
This is a directory.
@ Other
Neither a file nor a directory.
@ BackUpExists
Back up copy exists.
@ XBitSet
Executable/searchable bit set.
@ Offline
File is not online (ie. on disk)
@ IsWritable
Write access is allowed.
uint32_t GetFlags() const
Get flags.
bool ExtendedFormat() const
Has extended stat information.
const std::string & GetModeAsString() const
Get mode.
const std::string & GetId() const
Get id.
const std::string & GetGroup() const
Get group.
std::string GetAccessTimeAsString() const
Get change time.
const std::string & GetChecksum() const
Get checksum.
std::string GetHostId() const
Get the host part of the URL (user:password@host:port)
std::map< std::string, std::string > ParamsMap
void SetParams(const std::string ¶ms)
Set params.
std::string GetURL() const
Get the URL.
std::string GetObfuscatedURL() const
Get the URL with authz information obfuscated.
void SetPath(const std::string &path)
Set the path.
const std::string & GetProtocol() const
Get the protocol.
bool IsValid() const
Is the url valid.
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
static std::string BytesToString(uint64_t bytes)
Convert bytes to a human readable string.
std::string ToStr() const
Convert to string.
static std::string genHumanSize(size_t size, uint64_t base)
const uint16_t errInvalidAddr
const uint16_t stError
An error occurred that could potentially be retried.
const uint16_t errResponseNegative
Query response was negative.
StatImpl< false > Stat(Ctx< File > file, Arg< bool > force, time_t timeout=0)
const uint16_t errOSError
const uint16_t errInvalidArgs
XRootDStatus WaitFor(Pipeline pipeline, time_t timeout=0)
std::future< XRootDStatus > Async(Pipeline pipeline, time_t timeout=0)
ParallelOperation< false > Parallel(Container &&container)
Factory function for creating parallel operation from a vector.
@ OX
world executable/browsable
@ GX
group executable/browsable
@ UX
owner executable/browsable
@ Zip
List content of ZIP files.
@ Recursive
Do a recursive listing.
@ Cksm
Get checksum for every entry.
@ MakePath
create the entire directory tree if it doesn't exist
Flags
Open flags, may be or'd when appropriate.
@ Read
Open only for reading.
@ Cancel
cancel staging request
@ Colocate
co-locate staged files, if possible
Code
XRootD query request codes.
@ OpaqueFile
Implementation dependent.
@ XAttr
Query file extended attributes.
@ Opaque
Implementation dependent.
@ Config
Query server configuration.
@ Stats
Query server stats.
@ ChecksumCancel
Query file checksum cancellation.
@ Checksum
Query file checksum.
@ Space
Query logical space stats.
@ Prepare
Query prepare status.
uint16_t code
Error type, or additional hints on what to do.
bool IsOK() const
We're fine.
std::string ToString() const
Create a string representation.
int GetShellCode() const
Get the status code that may be returned to the shell.
Extended attribute operation status.
Extended attributes with status.