54#include <readline/history.h>
55#include <readline/readline.h>
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);
409std::string
getSizeStr(uint64_t size,
bool human, uint64_t base) {
410 std::ostringstream oss;
419void 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" );
773 if( is_subdirectory(fullPath1, fullPath2) )
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 ) >>
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;
2255 std::getline( std::cin, input );
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();
2306bool 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)
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 &)
int main(int argc, char *argv[])
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.
FSExecutor(const URL &url, Env *env=0)
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.
URL()
Default constructor.
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.
XRootDStatus(uint16_t st=0, uint16_t code=0, uint32_t errN=0, const std::string &message="")
Constructor.
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 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.
XAttrStatus(const std::string &name, const XRootDStatus &status)
Extended attributes with status.
XAttr(const std::string &name, const XRootDStatus &status)