54 #include <readline/history.h>
55 #include <readline/readline.h>
58 using namespace XrdCl;
69 bool SupportsFullURLs(
const std::string &command )
71 static const char *commands[] = {
72 "cache",
"cat",
"chmod",
"locate",
"ls",
"mkdir",
"mv",
73 "prepare",
"rm",
"rmdir",
"spaceinfo",
"stat",
"statvfs",
74 "tail",
"truncate",
"xattr"
77 return std::find( std::begin( commands ), std::end( commands ), command )
78 != std::end( commands );
84 bool HasExplicitURLScheme(
const std::string &argument )
86 std::string::size_type separator = argument.find(
"://" );
87 if( separator == std::string::npos || separator == 0
88 || !std::isalpha(
static_cast<unsigned char>( argument[0] ) ) )
91 for( std::string::size_type i = 1; i < separator; ++i )
93 unsigned char character =
static_cast<unsigned char>( argument[i] );
94 if( !std::isalnum( character ) && character !=
'+'
95 && character !=
'-' && character !=
'.' )
103 URL &endpoint, std::string &error )
105 if( arguments.empty() )
106 return NotURLCommand;
108 if( arguments[0] ==
"query" )
110 for( std::size_t i = 1; i < arguments.size(); ++i )
112 if( HasExplicitURLScheme( arguments[i] ) )
114 error =
"command-first full URLs are not supported for 'query'";
115 return InvalidURLCommand;
118 return NotURLCommand;
121 if( !SupportsFullURLs( arguments[0] ) )
122 return NotURLCommand;
124 bool foundURL =
false;
125 for( std::size_t i = 1; i < arguments.size(); ++i )
127 if( !HasExplicitURLScheme( arguments[i] ) )
130 URL operand( arguments[i] );
131 if( !operand.IsValid() || operand.GetProtocol() ==
"file"
132 || operand.GetProtocol() ==
"stdio" )
134 error =
"invalid remote URL operand";
135 return InvalidURLCommand;
145 else if( endpoint.
GetProtocol() != operand.GetProtocol()
146 || endpoint.
GetHostId() != operand.GetHostId() )
148 error =
"all URL operands must use the same endpoint";
149 return InvalidURLCommand;
152 arguments[i] = operand.GetPathWithParams();
153 if( arguments[i].empty() || arguments[i][0] !=
'/' )
154 arguments[i].insert( arguments[i].begin(),
'/' );
157 return foundURL ? ValidURLCommand : NotURLCommand;
165 const std::string &path,
166 const char *op =
nullptr )
172 const std::string msg =
"A path is required.";
178 env->
GetInt(
"NoCWD", noCwd );
189 msg = std::string( op ) +
" relative path '" + path +
"' is disallowed.";
191 msg =
"Relative path '" + path +
"' is disallowed.";
196 std::string cwd =
"/";
205 std::list<std::string> pathComponents;
206 std::list<std::string>::iterator it;
209 for( it = pathComponents.begin(); it != pathComponents.end(); )
213 it = pathComponents.erase( it );
219 if( it == pathComponents.begin() )
221 const std::string msg =
"Path '" + path +
"' escapes above root.";
225 std::list<std::string>::iterator it1 = it;
227 it = pathComponents.erase( it1 );
228 it = pathComponents.erase( it );
235 for( it = pathComponents.begin(); it != pathComponents.end(); ++it )
240 if( newPath.length() > 1 )
241 newPath.erase( newPath.length()-1, 1 );
251 if( modeStr.length() != 9 )
255 for(
int i = 0; i < 3; ++i )
257 if( modeStr[i] ==
'r' )
259 else if( modeStr[i] ==
'w' )
261 else if( modeStr[i] ==
'x' )
263 else if( modeStr[i] !=
'-' )
266 for(
int i = 3; i < 6; ++i )
268 if( modeStr[i] ==
'r' )
270 else if( modeStr[i] ==
'w' )
272 else if( modeStr[i] ==
'x' )
274 else if( modeStr[i] !=
'-' )
277 for(
int i = 6; i < 9; ++i )
279 if( modeStr[i] ==
'r' )
281 else if( modeStr[i] ==
'w' )
283 else if( modeStr[i] ==
'x' )
285 else if( modeStr[i] !=
'-' )
302 uint32_t argc = args.size();
306 log->
Error(
AppMsg,
"Wrong number of arguments." );
308 "Wrong number of arguments." );
311 if( args[1] !=
"evict" && args[1] !=
"fevict")
317 std::string fullPath;
325 std::string cmd = args[1];
327 cmd.append(fullPath);
338 st.
ToStr().c_str() );
344 std::cout << response->
ToString() <<
'\n';
362 if( args.size() != 2 )
364 log->
Error(
AppMsg,
"Invalid arguments. Expected a path." );
371 env->
PutInt(
"NoCWD", 0 );
391 log->
Error(
AppMsg,
"%s is not a directory.", newPath.c_str() );
405 if( nb == 0 )
return 1;
406 return uint32_t( log10(
double(nb) ) + 1);
409 std::string
getSizeStr(uint64_t size,
bool human, uint64_t base) {
410 std::ostringstream oss;
419 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 )
429 std::cout <<
" " << std::setw( ownerwidth ) << info->
GetOwner();
430 std::cout <<
" " << std::setw( groupwidth ) << info->
GetGroup();
431 std::cout <<
" " << std::setw( sizewidth ) <<
getSizeStr(info->
GetSize(),human, base);
433 std::cout <<
" " << std::setw( sizewidth ) << info->
GetChecksum();
460 uint64_t size = info->
GetSize();
461 std::string displaySize =
getSizeStr(size,human,base);
462 int width = displaySize.size() + 2;
466 std::cout << std::setw( width ) << displaySize <<
" ";
481 uint32_t argc = args.size();
483 bool showUrls =
false;
486 uint64_t base = 1024;
496 for( uint32_t i = 1; i < args.size(); ++i )
498 if( args[i] ==
"-l" )
503 else if( args[i] ==
"-u" )
505 else if( args[i] ==
"-R" )
509 else if( args[i] ==
"-D" )
514 else if( args[i] ==
"-Z" )
519 else if( args[i] ==
"-C" )
526 else if ( args [i] ==
"-h" )
539 std::string newPath =
"/";
552 log->
Debug(
AppMsg,
"Attempting to stat: %s", newPath.c_str() );
556 std::unique_ptr<StatInfo> ptr( info );
575 std::cout << newPath << std::endl;
583 log->
Debug(
AppMsg,
"Attempting to list: %s", newPath.c_str() );
586 st = fs->
DirList( newPath, flags, list );
595 std::cerr <<
"[!] Some of the requests failed. The result may be ";
596 std::cerr <<
"incomplete." << std::endl;
599 uint32_t ownerwidth = 0, groupwidth = 0, sizewidth = 0, ckswidth = 0;
601 for( it = list->
Begin(); it != list->
End() && stats; ++it )
603 StatInfo *info = (*it)->GetStatInfo();
606 uint32_t sizeWidthComp;
608 sizeWidthComp = size.size();
613 if( ownerwidth < info->GetOwner().size() )
614 ownerwidth = info->
GetOwner().size();
615 if( groupwidth < info->GetGroup().size() )
616 groupwidth = info->
GetGroup().size();
617 if( sizewidth < sizeWidthComp )
618 sizewidth = sizeWidthComp;
619 if( ckswidth < info->GetChecksum().size() )
626 for( it = list->
Begin(); it != list->
End(); ++it )
630 StatInfo *info = (*it)->GetStatInfo();
632 std::cout <<
"---- 0000-00-00 00:00:00 ? ";
637 std::cout <<
"root://" << (*it)->GetHostAddress() <<
"/";
638 std::cout << list->
GetParentName() << (*it)->GetName() << std::endl;
655 uint32_t argc = args.size();
657 if( argc < 2 || argc > 4 )
665 std::string modeStr =
"rwxr-x---";
666 std::string path =
"";
668 for( uint32_t i = 1; i < args.size(); ++i )
670 if( args[i] ==
"-p" )
672 else if( !args[i].compare( 0, 2,
"-m" ) )
673 modeStr = args[i].substr( 2, 9 );
693 st = fs->
MkDir( newPath, flags, mode );
696 log->
Error(
AppMsg,
"Unable create directory %s: %s",
698 st.
ToStr().c_str() );
716 uint32_t argc = args.size();
720 log->
Error(
AppMsg,
"Wrong number of arguments." );
724 std::string fullPath;
735 log->
Error(
AppMsg,
"Unable remove directory %s: %s",
737 st.
ToStr().c_str() );
755 uint32_t argc = args.size();
759 log->
Error(
AppMsg,
"Wrong number of arguments." );
763 std::string fullPath1;
768 std::string fullPath2;
769 pathSt =
BuildPath( fullPath2, env, args[2],
"Renaming to" );
775 "cannot move directory to a subdirectory of itself." );
784 fullPath1.c_str(), fullPath2.c_str(),
785 st.
ToStr().c_str() );
803 uint32_t argc = args.size();
807 log->
Error(
AppMsg,
"Wrong number of arguments." );
813 void print(
const std::string &msg )
815 std::unique_lock<std::mutex> lck( mtx );
816 std::cout << msg <<
'\n';
820 std::shared_ptr<print_t> print;
822 print = std::make_shared<print_t>();
824 std::vector<Pipeline> rms;
825 rms.reserve( argc - 1 );
826 for(
size_t i = 1; i < argc; ++i )
828 std::string fullPath;
832 rms.emplace_back(
Rm( fs, fullPath ) >>
837 log->Error( AppMsg,
"Unable remove %s: %s",
839 st.ToStr().c_str() );
843 print->print(
"rm " + fullPath +
" : " + st.ToString() );
853 const size_t rs = rms.size();
872 uint32_t argc = args.size();
876 log->
Error(
AppMsg,
"Wrong number of arguments." );
880 std::string fullPath;
886 uint64_t size = ::strtoll( args[2].c_str(), &result, 0 );
889 log->
Error(
AppMsg,
"Size parameter needs to be an integer" );
901 st.
ToStr().c_str() );
919 uint32_t argc = args.size();
923 log->
Error(
AppMsg,
"Wrong number of arguments." );
927 std::string fullPath;
943 st = fs->
ChMod( fullPath, mode );
946 log->
Error(
AppMsg,
"Unable change mode of %s: %s",
948 st.
ToStr().c_str() );
966 uint32_t argc = args.size();
970 log->
Error(
AppMsg,
"Wrong number of arguments." );
976 bool hasPath =
false;
977 bool doDeepLocate =
false;
978 for( uint32_t i = 1; i < argc; ++i )
980 if( args[i] ==
"-n" )
982 else if( args[i] ==
"-r" )
984 else if( args[i] ==
"-m" || args[i] ==
"-h" )
986 else if( args[i] ==
"-i" )
988 else if( args[i] ==
"-d" )
990 else if( args[i] ==
"-p" )
993 env->
PutInt(
"PreserveLocateTried", 0 );
1002 log->
Error(
AppMsg,
"Invalid argument: %s.", args[i].c_str() );
1007 std::string fullPath;
1008 if( path[0] ==
'*' )
1013 if( !pathSt.
IsOK() )
1023 st = fs->
DeepLocate( fullPath, flags, info );
1025 st = fs->
Locate( fullPath, flags, info );
1031 st.
ToStr().c_str() );
1040 std::cerr <<
"[!] Some of the requests failed. The result may be ";
1041 std::cerr <<
"incomplete." << std::endl;
1045 for( it = info->
Begin(); it != info->
End(); ++it )
1047 std::cout << it->GetAddress() <<
" ";
1048 switch( it->GetType() )
1051 std::cout <<
"Manager ";
1054 std::cout <<
"ManagerPending ";
1057 std::cout <<
"Server ";
1060 std::cout <<
"ServerPending ";
1063 std::cout <<
"Unknown ";
1066 switch( it->GetAccessType() )
1069 std::cout <<
"Read";
1072 std::cout <<
"ReadWrite ";
1075 std::cout <<
"Unknown ";
1077 std::cout << std::endl;
1094 bool isOrQuery =
false;
1096 if( query.find(
'|' ) != std::string::npos )
1101 std::vector<std::string> queryFlags;
1110 std::map<std::string, StatInfo::Flags> flagMap;
1120 std::vector<std::string>::iterator it;
1121 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1122 if( flagMap.find( *it ) == flagMap.end() )
1124 log->
Error(
AppMsg,
"Flag '%s' is not recognized.", it->c_str() );
1133 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1139 for( it = queryFlags.begin(); it != queryFlags.end(); ++it )
1160 uint32_t argc = args.size();
1164 log->
Error(
AppMsg,
"Wrong number of arguments." );
1168 std::vector<std::string> paths;
1171 for( uint32_t i = 1; i < args.size(); ++i )
1173 if( args[i] ==
"-q" )
1175 if( i < args.size()-1 )
1182 log->
Error(
AppMsg,
"Parameter '-q' requires an argument." );
1187 paths.emplace_back( args[i] );
1190 std::vector<XrdCl::Pipeline> stats;
1191 std::vector<std::tuple<std::future<StatInfo>, std::string>> results;
1192 for(
auto &path : paths )
1194 std::string fullPath;
1196 if( !pathSt.
IsOK() )
1198 std::future<XrdCl::StatInfo> ftr;
1199 stats.emplace_back(
XrdCl::Stat( fs, fullPath ) >> ftr );
1200 results.emplace_back( std::move( ftr ), std::move( fullPath ) );
1212 for(
auto &tpl : results )
1214 auto &ftr = std::get<0>( tpl );
1215 auto &fullPath = std::get<1>( tpl );
1216 std::cout << std::endl;
1223 flags +=
"XBitSet|";
1229 flags +=
"Offline|";
1231 flags +=
"POSCPending|";
1233 flags +=
"IsReadable|";
1235 flags +=
"IsWritable|";
1237 flags +=
"BackUpExists|";
1239 if( !flags.empty() )
1240 flags.erase( flags.length()-1, 1 );
1242 std::cout <<
"Path: " << fullPath << std::endl;
1243 std::cout <<
"Id: " << info.
GetId() << std::endl;
1244 std::cout <<
"Size: " << info.
GetSize() << std::endl;
1253 std::cout <<
"Flags: " << info.
GetFlags() <<
" (" << flags <<
")";
1259 std::cout <<
"Owner: " << info.
GetOwner() << std::endl;
1260 std::cout <<
"Group: " << info.
GetGroup();
1263 std::cout << std::endl;
1265 if( query.length() != 0 )
1270 std::cout <<
"Query: " << query <<
" " << std::endl;
1276 log->
Error(
AppMsg,
"Unable stat %s: %s", fullPath.c_str(), st.
ToStr().c_str() );
1294 uint32_t argc = args.size();
1298 log->
Error(
AppMsg,
"Wrong number of arguments." );
1302 std::string fullPath;
1304 if( !pathSt.
IsOK() )
1317 st.
ToStr().c_str() );
1324 std::cout <<
"Path: ";
1325 std::cout << fullPath << std::endl;
1326 std::cout <<
"Nodes with RW space: ";
1327 std::cout << info->
GetNodesRW() << std::endl;
1328 std::cout <<
"Size of largest RW space (MB): ";
1329 std::cout << info->
GetFreeRW() << std::endl;
1330 std::cout <<
"Utilization of RW space (%): ";
1332 std::cout <<
"Nodes with staging space: ";
1334 std::cout <<
"Size of largest staging space (MB): ";
1336 std::cout <<
"Utilization of staging space (%): ";
1354 uint32_t argc = args.size();
1356 if( !( argc >= 3 ) )
1358 log->
Error(
AppMsg,
"Wrong number of arguments." );
1363 if( args[1] ==
"config" )
1365 else if( args[1] ==
"checksumcancel" )
1367 else if( args[1] ==
"checksum" )
1369 else if( args[1] ==
"opaque" )
1371 else if( args[1] ==
"opaquefile" )
1373 else if( args[1] ==
"prepare" )
1375 else if( args[1] ==
"space" )
1377 else if( args[1] ==
"stats" )
1379 else if( args[1] ==
"xattr" )
1389 log->
Error(
AppMsg,
"Wrong number of arguments." );
1393 std::string strArg = args[2];
1398 for(
size_t i = 3; i < args.size(); ++i )
1400 std::string path = args[i];
1402 if( !pathSt.
IsOK() )
1411 std::string strArg = args[2];
1417 if( !pathSt.
IsOK() )
1425 Buffer arg( strArg.size() );
1434 st.
ToStr().c_str() );
1441 std::cout << response->
ToString() << std::endl;
1457 uint32_t argc = args.size();
1461 log->
Error(
AppMsg,
"Wrong number of arguments." );
1466 std::vector<std::string> files;
1467 uint8_t priority = 0;
1470 for( uint32_t i = 1; i < args.size(); ++i )
1472 if( args[i] ==
"-p" )
1474 if( i < args.size()-1 )
1477 int32_t param = ::strtol( args[i+1].c_str(), &result, 0 );
1478 if( *result != 0 || param > 3 || param < 0 )
1480 log->
Error(
AppMsg,
"Size priotiry needs to be an integer between 0 "
1484 priority = (uint8_t)param;
1489 log->
Error(
AppMsg,
"Parameter '-p' requires an argument." );
1493 else if( args[i] ==
"-c" )
1495 else if( args[i] ==
"-f" )
1497 else if( args[i] ==
"-s" )
1499 else if( args[i] ==
"-w" )
1501 else if( args[i] ==
"-e" )
1503 else if( args[i] ==
"-a" )
1506 if( i < args.size()-1 )
1510 files.push_back( args[i+1] );
1515 log->
Error(
AppMsg,
"Parameter '-a' requires an argument." );
1520 files.push_back( args[i] );
1542 std::cout << response->
ToString() <<
'\n';
1566 JobProgress( jobNum, pBytesProcessed, pBytesTotal );
1567 std::cerr << std::endl;
1574 uint64_t bytesProcessed,
1575 uint64_t bytesTotal )
1577 pBytesProcessed = bytesProcessed;
1578 pBytesTotal = bytesTotal;
1580 time_t now = time(0);
1581 if( (now - pPrevious < 1) && (bytesProcessed != bytesTotal) )
1586 std::cerr <<
"Progress: ";
1590 std::cerr <<
"(" << bytesProcessed*100/bytesTotal <<
"%)";
1592 std::cerr << std::flush;
1596 uint64_t pBytesProcessed;
1597 uint64_t pBytesTotal;
1612 uint32_t argc = args.size();
1616 log->
Error(
AppMsg,
"Wrong number of arguments." );
1622 if( server.empty() )
1624 log->
Error(
AppMsg,
"Invalid address: \"%s\".", server.c_str() );
1628 std::vector<std::string> remotes;
1631 for( uint32_t i = 1; i < args.size(); ++i )
1633 if( args[i] ==
"-o" )
1635 if( i < args.size()-1 )
1642 log->
Error(
AppMsg,
"Parameter '-o' requires an argument." );
1647 remotes.emplace_back( args[i] );
1650 if( !local.empty() && remotes.size() > 1 )
1652 log->
Error(
AppMsg,
"If '-o' is used only can be used with only one remote file." );
1656 std::vector<URL> remoteUrls;
1657 remoteUrls.reserve( remotes.size() );
1658 for(
auto &remote : remotes )
1660 std::string remoteFile;
1662 if( !pathSt.
IsOK() )
1665 remoteUrls.emplace_back( server );
1666 remoteUrls.back().SetPath( remoteFile );
1674 std::vector<PropertyList> props( remoteUrls.size() ), results( remoteUrls.size() );
1676 for(
size_t i = 0; i < remoteUrls.size(); ++i )
1678 props[i].Set(
"source", remoteUrls[i].GetURL() );
1679 if( !local.empty() )
1681 props[i].Set(
"target", std::string(
"file://" ) + local );
1685 props[i].Set(
"target",
"stdio://-" );
1687 props[i].Set(
"dynamicSource",
true );
1704 st = process.
Run(handler);
1725 uint32_t argc = args.size();
1727 if( argc < 2 || argc > 5 )
1729 log->
Error(
AppMsg,
"Wrong number of arguments." );
1735 if( server.empty() )
1737 log->
Error(
AppMsg,
"Invalid address: \"%s\".", server.c_str() );
1742 bool followMode =
false;
1743 uint32_t offset = 512;
1745 for( uint32_t i = 1; i < args.size(); ++i )
1747 if( args[i] ==
"-f" )
1749 else if( args[i] ==
"-c" )
1751 if( i < args.size()-1 )
1754 offset = ::strtol( args[i+1].c_str(), &result, 0 );
1757 log->
Error(
AppMsg,
"Offset from the end needs to be a number: %s",
1758 args[i+1].c_str() );
1765 log->
Error(
AppMsg,
"Parameter '-n' requires an argument." );
1773 std::string remoteFile;
1775 if( !pathSt.
IsOK() )
1778 URL remoteUrl( server );
1779 remoteUrl.
SetPath( remoteFile );
1795 st = file.
Stat(
false, info );
1801 offset = size - offset;
1803 uint32_t chunkSize = 1*1024*1024;
1804 char *buffer =
new char[chunkSize];
1805 uint32_t bytesRead = 0;
1808 st = file.
Read( offset, chunkSize, buffer, bytesRead );
1817 offset += bytesRead;
1818 int ret =
write( 1, buffer, bytesRead );
1821 log->
Error(
AppMsg,
"Unable to write to stdout: %s",
1827 if( bytesRead < chunkSize )
1848 using namespace XrdCl;
1854 uint32_t argc = args.size();
1858 log->
Error(
AppMsg,
"Wrong number of arguments." );
1870 std::cerr <<
"[!] Some of the requests failed. The result may be ";
1871 std::cerr <<
"incomplete." << std::endl;
1874 std::cout <<
"Path: " << args[1] << std::endl;
1875 std::cout <<
"Total: " << i->
GetTotal() << std::endl;
1876 std::cout <<
"Free: " << i->
GetFree() << std::endl;
1877 std::cout <<
"Used: " << i->
GetUsed() << std::endl;
1895 uint32_t argc = args.size();
1899 log->
Error(
AppMsg,
"Wrong number of arguments." );
1904 if( args[2] ==
"set")
1906 else if( args[2] ==
"get" )
1908 else if( args[2] ==
"del" )
1910 else if( args[2] ==
"list" )
1920 if( !pathSt.
IsOK() )
1933 log->
Error(
AppMsg,
"Wrong number of arguments." );
1937 std::string key_value = args[3];
1938 size_t pos = key_value.find(
'=' );
1939 std::string key = key_value.substr( 0, pos );
1940 std::string value = key_value.substr( pos + 1 );
1941 std::vector<xattr_t> attrs;
1942 attrs.push_back( std::make_tuple( key, value ) );
1944 std::vector<XAttrStatus> result;
1951 if( !status.
IsOK() )
1952 log->
Error(
AppMsg,
"Unable to xattr set %s %s: %s",
1953 key.c_str(), value.c_str(),
1954 status.
ToStr().c_str() );
1962 log->
Error(
AppMsg,
"Wrong number of arguments." );
1966 std::string key = args[3];
1967 std::vector<std::string> attrs;
1968 attrs.push_back( key );
1970 std::vector<XAttr> result;
1972 XAttr xattr = status.
IsOK() ? result.front() :
XAttr( key, status );
1977 if( !status.
IsOK() )
1978 log->
Error(
AppMsg,
"Unable to xattr get %s : %s",
1980 status.
ToStr().c_str() );
1983 std::cout <<
"# file: " << path <<
'\n';
1984 std::cout << xattr.
name <<
"=\"" << xattr.
value <<
"\"\n";
1994 log->
Error(
AppMsg,
"Wrong number of arguments." );
1998 std::string key = args[3];
1999 std::vector<std::string> attrs;
2000 attrs.push_back( key );
2002 std::vector<XAttrStatus> result ;
2009 if( !status.
IsOK() )
2010 log->
Error(
AppMsg,
"Unable to xattr del %s : %s",
2012 status.
ToStr().c_str() );
2020 log->
Error(
AppMsg,
"Wrong number of arguments." );
2024 std::vector<XAttr> result;
2027 if( !status.
IsOK() )
2029 status.
ToStr().c_str() );
2032 std::cout <<
"# file: " << path <<
'\n';
2033 auto itr = result.begin();
2034 for( ; itr != result.end(); ++itr )
2035 std::cout << itr->name <<
"=\"" << itr->value <<
"\"\n";
2052 printf(
"Usage:\n" );
2053 printf(
" xrdfs [options] host[:port] - interactive mode\n" );
2054 printf(
" xrdfs [options] host[:port] command args - server-first batch\n" );
2055 printf(
" xrdfs [options] command args-with-URLs - command-first batch\n\n" );
2057 printf(
"The two batch forms cannot be mixed.\n\n" );
2059 printf(
"Available options:\n\n" );
2061 printf(
" -4, --ipv4 use only the IPv4 network stack\n" );
2062 printf(
" -6, --ipv6 use only the IPv6 network stack\n" );
2063 printf(
" -d, --debug <level> set debug level: 0 off, 1 low, 2 medium,\n" );
2064 printf(
" 3 high\n" );
2065 printf(
" -h, --help show this help\n" );
2066 printf(
" --no-cwd do not preset a CWD in interactive mode\n\n" );
2068 printf(
"Available commands:\n\n" );
2070 printf(
" exit\n" );
2071 printf(
" Exits from the program.\n\n" );
2073 printf(
" help\n" );
2074 printf(
" This help screen.\n\n" );
2076 printf(
" cache {evict | fevict} <path>\n" );
2077 printf(
" Evict a file from a cache if not in use; while fevict\n" );
2078 printf(
" forcibly evicts the file causing any current uses of the\n" );
2079 printf(
" file to get read failures on a subsequent read\n\n" );
2081 printf(
" cd <path>\n" );
2082 printf(
" Change the current working directory\n\n" );
2084 printf(
" chmod <path> <user><group><other>\n" );
2085 printf(
" Modify permissions. Permission string example:\n" );
2086 printf(
" rwxr-x--x\n\n" );
2088 printf(
" ls [-l] [-u] [-R] [-D] [-Z] [-C] [dirname]\n" );
2089 printf(
" Get directory listing.\n" );
2090 printf(
" -l stat every entry and print long listing\n" );
2091 printf(
" -u print paths as URLs\n" );
2092 printf(
" -R list subdirectories recursively\n" );
2093 printf(
" -D show duplicate entries\n" );
2094 printf(
" -Z if a ZIP archive list its content\n" );
2095 printf(
" -C checksum every entry\n\n" );
2097 printf(
" locate [-n] [-r] [-d] [-m] [-i] [-p] <path>\n" );
2098 printf(
" Get the locations of the path.\n" );
2099 printf(
" -r refresh, don't use cached locations\n" );
2100 printf(
" -n make the server return the response immediately even\n" );
2101 printf(
" though it may be incomplete\n" );
2102 printf(
" -d do a recursive (deep) locate\n" );
2103 printf(
" -m|-h prefer host names to IP addresses\n" );
2104 printf(
" -i ignore network dependencies\n" );
2105 printf(
" -p be passive: ignore tried/triedrc cgi opaque info\n\n" );
2107 printf(
" mkdir [-p] [-m<user><group><other>] <dirname>\n" );
2108 printf(
" Creates a directory/tree of directories.\n\n" );
2110 printf(
" mv <path1> <path2>\n" );
2111 printf(
" Move path1 to path2 locally on the same server.\n\n" );
2113 printf(
" stat [-q query] <path>\n" );
2114 printf(
" Get info about the file or directory.\n" );
2115 printf(
" -q query optional flag query parameter that makes\n" );
2116 printf(
" xrdfs return error code to the shell if the\n" );
2117 printf(
" requested flag combination is not present;\n" );
2118 printf(
" flags may be combined together using '|' or '&'\n" );
2119 printf(
" Available flags:\n" );
2120 printf(
" XBitSet, IsDir, Other, Offline, POSCPending,\n" );
2121 printf(
" IsReadable, IsWritable\n\n" );
2123 printf(
" statvfs <path>\n" );
2124 printf(
" Get info about a virtual file system.\n\n" );
2126 printf(
" query <code> <parameters>\n" );
2127 printf(
" Obtain server information. Query codes:\n\n" );
2129 printf(
" config <what> Server configuration; <what> is\n" );
2130 printf(
" one of the following:\n" );
2131 printf(
" bind_max - the maximum number of parallel streams\n" );
2132 printf(
" chksum - the supported checksum\n" );
2133 printf(
" cms - the status of the cmsd\n" );
2134 printf(
" pio_max - maximum number of parallel I/O requests\n" );
2135 printf(
" readv_ior_max - maximum size of a readv element\n" );
2136 printf(
" readv_iov_max - maximum number of readv entries\n" );
2137 printf(
" role - the role in a cluster\n" );
2138 printf(
" sitename - the site name\n" );
2139 printf(
" tpc - support for third party copies\n" );
2140 printf(
" version - the version of the server\n" );
2141 printf(
" wan_port - the port to use for wan copies\n" );
2142 printf(
" wan_window - the wan_port window size\n" );
2143 printf(
" window - the tcp window size\n" );
2144 printf(
" checksumcancel <path> File checksum cancellation\n" );
2145 printf(
" checksum <path> File checksum\n" );
2146 printf(
" opaque <arg> Implementation dependent\n" );
2147 printf(
" opaquefile <arg> Implementation dependent\n" );
2148 printf(
" space <space> Logical space stats\n" );
2149 printf(
" stats <what> Server stats; <what> is a list\n" );
2150 printf(
" of letters indicating information\n");
2151 printf(
" to be returned:\n" );
2152 printf(
" a - all statistics\n" );
2153 printf(
" p - protocol statistics\n" );
2154 printf(
" b - buffer usage statistics\n" );
2155 printf(
" s - scheduling statistics\n" );
2156 printf(
" d - device polling statistics\n" );
2157 printf(
" u - usage statistics\n" );
2158 printf(
" i - server identification\n" );
2159 printf(
" z - synchronized statistics\n" );
2160 printf(
" l - connection statistics\n" );
2161 printf(
" xattr <path> Extended attributes\n" );
2162 printf(
" prepare <reqid> [filenames] Prepare request status\n\n" );
2164 printf(
" rm <filename>\n" );
2165 printf(
" Remove a file.\n\n" );
2167 printf(
" rmdir <dirname>\n" );
2168 printf(
" Remove a directory.\n\n" );
2170 printf(
" truncate <filename> <length>\n" );
2171 printf(
" Truncate a file.\n\n" );
2173 printf(
" prepare [-c] [-f] [-s] [-w] [-e] [-p priority] [-a requestid] filenames\n" );
2174 printf(
" Prepare one or more files for access.\n" );
2175 printf(
" -c co-locate staged files if possible\n" );
2176 printf(
" -f refresh file access time even if the location is known\n" );
2177 printf(
" -s stage the files to disk if they are not online\n" );
2178 printf(
" -w the files will be accessed for modification\n" );
2179 printf(
" -p priority of the request, 0 (lowest) - 3 (highest)\n" );
2180 printf(
" -a abort stage request\n" );
2181 printf(
" -e evict the file from disk cache\n\n" );
2183 printf(
" cat [-o local file] files\n" );
2184 printf(
" Print contents of one or more files to stdout.\n" );
2185 printf(
" -o print to the specified local file\n\n" );
2187 printf(
" tail [-c bytes] [-f] file\n" );
2188 printf(
" Output last part of files to stdout.\n" );
2189 printf(
" -c num_bytes out last num_bytes\n" );
2190 printf(
" -f output appended data as file grows\n\n" );
2192 printf(
" spaceinfo path\n" );
2193 printf(
" Get space statistics for given path.\n\n" );
2195 printf(
" xattr <path> <code> <params> \n" );
2196 printf(
" Operation on extended attributes. Codes:\n\n" );
2197 printf(
" set <attr> Set extended attribute; <attr> is\n" );
2198 printf(
" string of form name=value\n" );
2199 printf(
" get <name> Get extended attribute\n" );
2200 printf(
" del <name> Delete extended attribute\n" );
2201 printf(
" list List extended attributes\n\n" );
2243 std::cerr << st.
ToStr() << std::endl;
2250 #ifndef HAVE_READLINE
2253 std::cout << prompt << std::flush;
2257 if( !std::cin.good() )
2260 char *linebuf = (
char *)malloc( input.size()+1 );
2261 strncpy( linebuf, input.c_str(), input.size()+1 );
2292 std::ostringstream prompt;
2293 std::string cwd =
"/";
2295 prompt <<
"[" << url.
GetHostId() <<
"] " << cwd <<
" > ";
2296 return prompt.str();
2306 bool getArguments (std::vector<std::string> & result,
const std::string &input)
2309 static const char delimiter =
' ';
2311 const char singleQuote =
'\'', doubleQuote =
'\"';
2315 char currentQuote =
'\0';
2318 for (std::string::const_iterator it = input.begin (); it != input.end (); ++it)
2321 if (*it == singleQuote || *it == doubleQuote)
2330 else if (currentQuote == *it)
2332 currentQuote =
'\0';
2337 if (currentQuote || *it != delimiter)
2347 result.push_back(tmp);
2355 result.push_back(tmp);
2358 return currentQuote ==
'\0';
2369 std::string historyFile = getenv(
"HOME" );
2370 historyFile +=
"/.xrdquery.history";
2381 std::string cmdline;
2389 if( !linebuf || !strncmp( linebuf,
"exit", 4 ) || !strncmp( linebuf,
"quit", 4 ) )
2391 std::cout <<
"Goodbye." << std::endl << std::endl;
2399 std::vector<std::string> args;
2408 std::cerr << st.
ToStr() << std::endl;
2438 enum { NoCwdOption = 256 };
2439 static const option options[] = {
2440 {
"ipv4", no_argument, 0,
'4' },
2441 {
"ipv6", no_argument, 0,
'6' },
2442 {
"debug", required_argument, 0,
'd' },
2443 {
"help", no_argument, 0,
'h' },
2444 {
"no-cwd", no_argument, 0, NoCwdOption },
2450 std::string networkStack;
2453 while( (option = getopt_long( argc, argv,
"+46d:h", options, 0 )) != -1 )
2458 if( networkStack ==
"IPv6" )
2460 std::cerr <<
"xrdfs: -4 and -6 are mutually exclusive" << std::endl;
2463 networkStack =
"IPv4";
2466 if( networkStack ==
"IPv4" )
2468 std::cerr <<
"xrdfs: -4 and -6 are mutually exclusive" << std::endl;
2471 networkStack =
"IPv6";
2476 long level = std::strtol( optarg, &end, 10 );
2477 if( !*optarg || *end || level < 0 || level > 3 )
2479 std::cerr <<
"xrdfs: invalid debug level '" << optarg
2480 <<
"' (expected 0-3)" << std::endl;
2483 debugLevel =
static_cast<int>( level );
2498 if( !networkStack.empty() )
2504 if( debugLevel == 1 )
2506 else if( debugLevel == 2 )
2521 URLCommandResult result = ParseURLCommand( arguments, url, error );
2522 if( result == InvalidURLCommand )
2524 std::cerr <<
"xrdfs: " << error << std::endl;
2528 if( result == ValidURLCommand )
2531 url =
URL( arguments[0] );
2538 if( arguments.size() == 1 )
2541 arguments.erase( arguments.begin() );
2545 if( arguments[0] !=
"query" )
2547 URL inferredEndpoint;
2548 result = ParseURLCommand( arguments, inferredEndpoint, error );
2549 if( result == InvalidURLCommand )
2551 std::cerr <<
"xrdfs: " << error << std::endl;
2555 if( result == ValidURLCommand )
2557 std::cerr <<
"xrdfs: cannot mix a leading endpoint with full URL "
2558 "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)
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)
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)
FSExecutor * CreateExecutor(const URL &url)
int read_history(const char *)
char * readline(const char *prompt)
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)
void getline(uchar *buff, int blen)
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)
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.
DirList::iterator Iterator
Directory listing iterator.
Iterator End()
Get the end iterator.
Iterator Begin()
Get the begin iterator.
const std::string & GetParentName() const
Get parent directory name.
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.
Env * GetEnv()
Get the environment.
XRootDStatus Execute(const CommandParams &args)
bool AddCommand(const std::string &name, Command command)
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
const std::string & GetProtocol() const
Get the protocol.
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.
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)
std::future< XRootDStatus > Async(Pipeline pipeline, time_t timeout=0)
ParallelOperation< false > Parallel(Container &&container)
Factory function for creating parallel operation from a vector.
const uint16_t errInvalidArgs
XRootDStatus WaitFor(Pipeline pipeline, time_t timeout=0)
@ 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.
int GetShellCode() const
Get the status code that may be returned to the shell.
Extended attribute operation status.
Extended attributes with status.