Changeset 2283
- Timestamp:
- 13/09/2008 16:31:26 (3 years ago)
- Location:
- box/trunk/bin/bbackupquery
- Files:
-
- 4 edited
-
BackupQueries.cpp (modified) (10 diffs)
-
BackupQueries.h (modified) (4 diffs)
-
bbackupquery.cpp (modified) (1 diff)
-
documentation.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/bin/bbackupquery/BackupQueries.cpp
r2261 r2283 72 72 // 73 73 // -------------------------------------------------------------------------- 74 BackupQueries::BackupQueries(BackupProtocolClient &rConnection, const Configuration &rConfiguration) 75 : mrConnection(rConnection), 74 BackupQueries::BackupQueries(BackupProtocolClient &rConnection, 75 const Configuration &rConfiguration, bool readWrite) 76 : mReadWrite(readWrite), 77 mrConnection(rConnection), 76 78 mrConfiguration(rConfiguration), 77 79 mQuitNow(false), … … 223 225 { "usage", "" }, 224 226 { "undelete", "" }, 227 { "delete", "" }, 225 228 { NULL, NULL } 226 229 }; 227 #define COMMAND_Quit 0 228 #define COMMAND_Exit 1 229 #define COMMAND_List 2 230 #define COMMAND_pwd 3 231 #define COMMAND_cd 4 232 #define COMMAND_lcd 5 233 #define COMMAND_sh 6 234 #define COMMAND_GetObject 7 235 #define COMMAND_Get 8 236 #define COMMAND_Compare 9 237 #define COMMAND_Restore 10 238 #define COMMAND_Help 11 239 #define COMMAND_Usage 12 240 #define COMMAND_Undelete 13 241 static const char *alias[] = {"ls", 0}; 242 static const int aliasIs[] = {COMMAND_List, 0}; 230 231 typedef enum 232 { 233 Command_Quit = 0, 234 Command_Exit, 235 Command_List, 236 Command_pwd, 237 Command_cd, 238 Command_lcd, 239 Command_sh, 240 Command_GetObject, 241 Command_Get, 242 Command_Compare, 243 Command_Restore, 244 Command_Help, 245 Command_Usage, 246 Command_Undelete, 247 Command_Delete, 248 } 249 CommandType; 250 251 static const char *alias[] = {"ls", 0}; 252 static const int aliasIs[] = {Command_List, 0}; 243 253 244 254 // Work out which command it is... … … 294 304 } 295 305 296 if(cmd != C OMMAND_Quit && cmd != COMMAND_Exit)306 if(cmd != Command_Quit && cmd != Command_Exit) 297 307 { 298 308 // If not a quit command, set the return code to zero … … 303 313 switch(cmd) 304 314 { 305 case C OMMAND_Quit:306 case C OMMAND_Exit:315 case Command_Quit: 316 case Command_Exit: 307 317 mQuitNow = true; 308 318 break; 309 319 310 case C OMMAND_List:320 case Command_List: 311 321 CommandList(args, opts); 312 322 break; 313 323 314 case C OMMAND_pwd:324 case Command_pwd: 315 325 { 316 326 // Simple implementation, so do it here … … 320 330 break; 321 331 322 case C OMMAND_cd:332 case Command_cd: 323 333 CommandChangeDir(args, opts); 324 334 break; 325 335 326 case C OMMAND_lcd:336 case Command_lcd: 327 337 CommandChangeLocalDir(args); 328 338 break; 329 339 330 case C OMMAND_sh:340 case Command_sh: 331 341 BOX_ERROR("The command to run must be specified as an argument."); 332 342 break; 333 343 334 case C OMMAND_GetObject:344 case Command_GetObject: 335 345 CommandGetObject(args, opts); 336 346 break; 337 347 338 case C OMMAND_Get:348 case Command_Get: 339 349 CommandGet(args, opts); 340 350 break; 341 351 342 case C OMMAND_Compare:352 case Command_Compare: 343 353 CommandCompare(args, opts); 344 354 break; 345 355 346 case C OMMAND_Restore:356 case Command_Restore: 347 357 CommandRestore(args, opts); 348 358 break; 349 359 350 case C OMMAND_Usage:360 case Command_Usage: 351 361 CommandUsage(); 352 362 break; 353 363 354 case C OMMAND_Help:364 case Command_Help: 355 365 CommandHelp(args); 356 366 break; 357 367 358 case C OMMAND_Undelete:368 case Command_Undelete: 359 369 CommandUndelete(args, opts); 360 370 break; 361 371 372 case Command_Delete: 373 CommandDelete(args, opts); 374 break; 375 362 376 default: 377 BOX_ERROR("Unknown command: " << Command); 363 378 break; 364 379 } … … 602 617 // 603 618 // Function 604 // Name: BackupQueries::FindDirectoryObjectID(const std::string &) 605 // Purpose: Find the object ID of a directory on the store, or return 0 for not found. 606 // If pStack != 0, the object is set to the stack of directories. 607 // Will start from the current directory stack. 619 // Name: BackupQueries::FindDirectoryObjectID(const 620 // std::string &) 621 // Purpose: Find the object ID of a directory on the store, 622 // or return 0 for not found. If pStack != 0, the 623 // object is set to the stack of directories. 624 // Will start from the current directory stack. 608 625 // Created: 2003/10/10 609 626 // 610 627 // -------------------------------------------------------------------------- 611 int64_t BackupQueries::FindDirectoryObjectID(const std::string &rDirName, bool AllowOldVersion, 612 bool AllowDeletedDirs, std::vector<std::pair<std::string, int64_t> > *pStack) 628 int64_t BackupQueries::FindDirectoryObjectID(const std::string &rDirName, 629 bool AllowOldVersion, bool AllowDeletedDirs, 630 std::vector<std::pair<std::string, int64_t> > *pStack) 613 631 { 614 632 // Split up string into elements … … 936 954 937 955 956 // -------------------------------------------------------------------------- 957 // 958 // Function 959 // Name: BackupQueries::FindFileID(const std::string& 960 // rNameOrIdString, const bool *options, 961 // int64_t *pDirIdOut, std::string* pFileNameOut) 962 // Purpose: Locate a file on the store (either by name or by 963 // object ID, depending on opts['i'], where name can 964 // include a path) and return the file ID, placing the 965 // directory ID in *pDirIdOut and the filename part 966 // of the path (if not looking up by ID and not NULL) 967 // in *pFileNameOut. 968 // Created: 2008-09-12 969 // 970 // -------------------------------------------------------------------------- 971 int64_t BackupQueries::FindFileID(const std::string& rNameOrIdString, 972 const bool *opts, int64_t *pDirIdOut, std::string* pFileNameOut, 973 int16_t flagsInclude, int16_t flagsExclude, int16_t* pFlagsOut) 974 { 975 // Find object ID somehow 976 int64_t fileId; 977 int64_t dirId = GetCurrentDirectoryID(); 978 std::string fileName = rNameOrIdString; 979 980 if(!opts['i']) 981 { 982 // does this remote filename include a path? 983 std::string::size_type index = fileName.rfind('/'); 984 if(index != std::string::npos) 985 { 986 std::string dirName(fileName.substr(0, index)); 987 fileName = fileName.substr(index + 1); 988 989 dirId = FindDirectoryObjectID(dirName); 990 if(dirId == 0) 991 { 992 BOX_ERROR("Directory '" << dirName << 993 "' not found."); 994 return 0; 995 } 996 } 997 998 if(pFileNameOut) 999 { 1000 *pFileNameOut = fileName; 1001 } 1002 } 1003 1004 BackupStoreFilenameClear fn(fileName); 1005 1006 // Need to look it up in the current directory 1007 mrConnection.QueryListDirectory( 1008 dirId, flagsInclude, flagsExclude, 1009 true /* do want attributes */); 1010 1011 // Retrieve the directory from the stream following 1012 BackupStoreDirectory dir; 1013 std::auto_ptr<IOStream> dirstream(mrConnection.ReceiveStream()); 1014 dir.ReadFromStream(*dirstream, mrConnection.GetTimeout()); 1015 BackupStoreDirectory::Entry *en; 1016 1017 if(opts['i']) 1018 { 1019 // Specified as ID. 1020 fileId = ::strtoll(rNameOrIdString.c_str(), 0, 16); 1021 if(fileId == std::numeric_limits<long long>::min() || 1022 fileId == std::numeric_limits<long long>::max() || 1023 fileId == 0) 1024 { 1025 BOX_ERROR("Not a valid object ID (specified in hex)."); 1026 return 0; 1027 } 1028 1029 // Check that the item is actually in the directory 1030 en = dir.FindEntryByID(fileId); 1031 if(en == 0) 1032 { 1033 BOX_ERROR("File ID " << 1034 BOX_FORMAT_OBJECTID(fileId) << 1035 " not found in current directory on store.\n" 1036 "(You can only access files by ID from the " 1037 "current directory.)"); 1038 return 0; 1039 } 1040 } 1041 else 1042 { 1043 // Specified by name, find the object in the directory to get the ID 1044 BackupStoreDirectory::Iterator i(dir); 1045 en = i.FindMatchingClearName(fn); 1046 if(en == 0) 1047 { 1048 BOX_ERROR("Filename '" << rNameOrIdString << "' " 1049 "not found in current directory on store.\n" 1050 "(Subdirectories in path not searched.)"); 1051 return 0; 1052 } 1053 1054 fileId = en->GetObjectID(); 1055 } 1056 1057 *pDirIdOut = dirId; 1058 1059 if(pFlagsOut) 1060 { 1061 *pFlagsOut = en->GetFlags(); 1062 } 1063 1064 return fileId; 1065 } 1066 938 1067 939 1068 // -------------------------------------------------------------------------- … … 958 1087 959 1088 // Find object ID somehow 960 int64_t fileId; 961 int64_t dirId = GetCurrentDirectoryID(); 1089 int64_t fileId, dirId; 962 1090 std::string localName; 963 1091 964 // BLOCK965 {966 1092 #ifdef WIN32 967 for (std::vector<std::string>::iterator 968 i = args.begin(); i != args.end(); i++) 969 { 970 std::string out; 971 if(!ConvertConsoleToUtf8(i->c_str(), out)) 972 { 973 BOX_ERROR("Failed to convert encoding."); 974 return; 975 } 976 *i = out; 977 } 978 #endif 979 980 std::string fileName(args[0]); 981 982 if(!opts['i']) 983 { 984 // does this remote filename include a path? 985 std::string::size_type index = fileName.rfind('/'); 986 if(index != std::string::npos) 987 { 988 std::string dirName(fileName.substr(0, index)); 989 fileName = fileName.substr(index + 1); 990 991 dirId = FindDirectoryObjectID(dirName); 992 if(dirId == 0) 993 { 994 BOX_ERROR("Directory '" << dirName << 995 "' not found."); 996 return; 997 } 998 } 999 } 1000 1001 BackupStoreFilenameClear fn(fileName); 1002 1003 // Need to look it up in the current directory 1004 mrConnection.QueryListDirectory( 1005 dirId, 1006 BackupProtocolClientListDirectory::Flags_File, // just files 1007 (opts['i'])?(BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING):(BackupProtocolClientListDirectory::Flags_OldVersion | BackupProtocolClientListDirectory::Flags_Deleted), // only current versions 1008 false /* don't want attributes */); 1009 1010 // Retrieve the directory from the stream following 1011 BackupStoreDirectory dir; 1012 std::auto_ptr<IOStream> dirstream(mrConnection.ReceiveStream()); 1013 dir.ReadFromStream(*dirstream, mrConnection.GetTimeout()); 1014 1015 if(opts['i']) 1016 { 1017 // Specified as ID. 1018 fileId = ::strtoll(args[0].c_str(), 0, 16); 1019 if(fileId == std::numeric_limits<long long>::min() || 1020 fileId == std::numeric_limits<long long>::max() || 1021 fileId == 0) 1022 { 1023 BOX_ERROR("Not a valid object ID (specified in hex)."); 1024 return; 1025 } 1026 1027 // Check that the item is actually in the directory 1028 if(dir.FindEntryByID(fileId) == 0) 1029 { 1030 BOX_ERROR("File ID " << 1031 BOX_FORMAT_OBJECTID(fileId) << 1032 " not found in current " 1033 "directory on store.\n" 1034 "(You can only download files by ID " 1035 "from the current directory.)"); 1036 return; 1037 } 1038 1039 // Must have a local name in the arguments (check at beginning of function ensures this) 1093 for (std::vector<std::string>::iterator 1094 i = args.begin(); i != args.end(); i++) 1095 { 1096 std::string out; 1097 if(!ConvertConsoleToUtf8(i->c_str(), out)) 1098 { 1099 BOX_ERROR("Failed to convert encoding."); 1100 return; 1101 } 1102 *i = out; 1103 } 1104 #endif 1105 1106 int16_t flagsExclude; 1107 1108 if(opts['i']) 1109 { 1110 // can retrieve anything by ID 1111 flagsExclude = BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING; 1112 } 1113 else 1114 { 1115 // only current versions by name 1116 flagsExclude = 1117 BackupProtocolClientListDirectory::Flags_OldVersion | 1118 BackupProtocolClientListDirectory::Flags_Deleted; 1119 } 1120 1121 1122 fileId = FindFileID(args[0], opts, &dirId, &localName, 1123 BackupProtocolClientListDirectory::Flags_File, // just files 1124 flagsExclude, NULL /* don't care about flags found */); 1125 1126 if (fileId == 0) 1127 { 1128 // error already reported 1129 return; 1130 } 1131 1132 if(opts['i']) 1133 { 1134 // Specified as ID. Must have a local name in the arguments 1135 // (check at beginning of function ensures this) 1136 localName = args[1]; 1137 } 1138 else 1139 { 1140 // Specified by name. Local name already set by FindFileID, 1141 // but may be overridden by user supplying a second argument. 1142 if(args.size() == 2) 1143 { 1040 1144 localName = args[1]; 1041 }1042 else1043 {1044 // Specified by name, find the object in the directory to get the ID1045 BackupStoreDirectory::Iterator i(dir);1046 BackupStoreDirectory::Entry *en = i.FindMatchingClearName(fn);1047 1048 if(en == 0)1049 {1050 BOX_ERROR("Filename '" << args[0] << "' "1051 "not found in current "1052 "directory on store.\n"1053 "(Subdirectories in path not "1054 "searched.)");1055 return;1056 }1057 1058 fileId = en->GetObjectID();1059 1060 // Local name is the last argument, which is either1061 // the looked up filename, or a filename specified1062 // by the user.1063 localName = args[args.size() - 1];1064 1145 } 1065 1146 } … … 2211 2292 void BackupQueries::CommandUndelete(const std::vector<std::string> &args, const bool *opts) 2212 2293 { 2294 if (!mReadWrite) 2295 { 2296 BOX_ERROR("This command requires a read-write connection. " 2297 "Please reconnect with the -w option."); 2298 return; 2299 } 2300 2213 2301 // Check arguments 2214 2302 if(args.size() != 1) 2215 2303 { 2216 BOX_ERROR("Incorrect usage. undelete < directory-name>");2304 BOX_ERROR("Incorrect usage. undelete <name> or undelete -i <object-id>"); 2217 2305 return; 2218 2306 } … … 2224 2312 const std::string& storeDirEncoded(args[0]); 2225 2313 #endif 2226 2227 // Get directory ID 2228 int64_t dirID = FindDirectoryObjectID(storeDirEncoded, 2229 false /* no old versions */, true /* find deleted dirs */); 2230 2231 // Allowable? 2232 if(dirID == 0) 2233 { 2234 BOX_ERROR("Directory '" << args[0] << "' not found on server."); 2235 return; 2236 } 2237 if(dirID == BackupProtocolClientListDirectory::RootDirectory) 2238 { 2239 BOX_ERROR("Cannot undelete the root directory."); 2240 return; 2241 } 2242 2243 // Undelete 2244 mrConnection.QueryUndeleteDirectory(dirID); 2245 } 2314 2315 // Find object ID somehow 2316 int64_t fileId, parentId; 2317 std::string fileName; 2318 int16_t flagsOut; 2319 2320 fileId = FindFileID(storeDirEncoded, opts, &parentId, &fileName, 2321 /* include files and directories */ 2322 BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING, 2323 /* include old and deleted files */ 2324 BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING, 2325 &flagsOut); 2326 2327 if (fileId == 0) 2328 { 2329 // error already reported 2330 return; 2331 } 2332 2333 // Undelete it on the store 2334 try 2335 { 2336 // Undelete object 2337 if(flagsOut & BackupProtocolClientListDirectory::Flags_File) 2338 { 2339 mrConnection.QueryUndeleteFile(parentId, fileId); 2340 } 2341 else 2342 { 2343 mrConnection.QueryUndeleteDirectory(fileId); 2344 } 2345 } 2346 catch (BoxException &e) 2347 { 2348 BOX_ERROR("Failed to undelete object: " << 2349 e.what()); 2350 } 2351 catch(std::exception &e) 2352 { 2353 BOX_ERROR("Failed to undelete object: " << 2354 e.what()); 2355 } 2356 catch(...) 2357 { 2358 BOX_ERROR("Failed to undelete object: unknown error"); 2359 } 2360 } 2361 2362 // -------------------------------------------------------------------------- 2363 // 2364 // Function 2365 // Name: BackupQueries::CommandDelete(const 2366 // std::vector<std::string> &, const bool *) 2367 // Purpose: Deletes a file 2368 // Created: 23/11/03 2369 // 2370 // -------------------------------------------------------------------------- 2371 void BackupQueries::CommandDelete(const std::vector<std::string> &args, 2372 const bool *opts) 2373 { 2374 if (!mReadWrite) 2375 { 2376 BOX_ERROR("This command requires a read-write connection. " 2377 "Please reconnect with the -w option."); 2378 return; 2379 } 2380 2381 // Check arguments 2382 if(args.size() != 1) 2383 { 2384 BOX_ERROR("Incorrect usage. delete <name>"); 2385 return; 2386 } 2387 2388 #ifdef WIN32 2389 std::string storeDirEncoded; 2390 if(!ConvertConsoleToUtf8(args[0].c_str(), storeDirEncoded)) return; 2391 #else 2392 const std::string& storeDirEncoded(args[0]); 2393 #endif 2394 2395 // Find object ID somehow 2396 int64_t fileId, parentId; 2397 std::string fileName; 2398 int16_t flagsOut; 2399 2400 fileId = FindFileID(storeDirEncoded, opts, &parentId, &fileName, 2401 /* include files and directories */ 2402 BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING, 2403 /* exclude old and deleted files */ 2404 BackupProtocolClientListDirectory::Flags_OldVersion | 2405 BackupProtocolClientListDirectory::Flags_Deleted, 2406 &flagsOut); 2407 2408 if (fileId == 0) 2409 { 2410 // error already reported 2411 return; 2412 } 2413 2414 BackupStoreFilenameClear fn(fileName); 2415 2416 // Delete it on the store 2417 try 2418 { 2419 // Delete object 2420 if(flagsOut & BackupProtocolClientListDirectory::Flags_File) 2421 { 2422 mrConnection.QueryDeleteFile(parentId, fn); 2423 } 2424 else 2425 { 2426 mrConnection.QueryDeleteDirectory(fileId); 2427 } 2428 } 2429 catch (BoxException &e) 2430 { 2431 BOX_ERROR("Failed to delete object: " << 2432 e.what()); 2433 } 2434 catch(std::exception &e) 2435 { 2436 BOX_ERROR("Failed to delete object: " << 2437 e.what()); 2438 } 2439 catch(...) 2440 { 2441 BOX_ERROR("Failed to delete object: unknown error"); 2442 } 2443 } -
box/trunk/bin/bbackupquery/BackupQueries.h
r2263 r2283 31 31 { 32 32 public: 33 BackupQueries(BackupProtocolClient &rConnection, const Configuration &rConfiguration); 33 BackupQueries(BackupProtocolClient &rConnection, 34 const Configuration &rConfiguration, 35 bool readWrite); 34 36 ~BackupQueries(); 35 37 private: … … 55 57 void CommandRestore(const std::vector<std::string> &args, const bool *opts); 56 58 void CommandUndelete(const std::vector<std::string> &args, const bool *opts); 59 void CommandDelete(const std::vector<std::string> &args, 60 const bool *opts); 57 61 void CommandUsage(); 58 void CommandUsageDisplayEntry(const char *Name, int64_t Size, int64_t HardLimit, int32_t BlockSize); 62 void CommandUsageDisplayEntry(const char *Name, int64_t Size, 63 int64_t HardLimit, int32_t BlockSize); 59 64 void CommandHelp(const std::vector<std::string> &args); 60 65 61 66 // Implementations 62 void List(int64_t DirID, const std::string &rListRoot, const bool *opts, bool FirstLevel); 67 void List(int64_t DirID, const std::string &rListRoot, const bool *opts, 68 bool FirstLevel); 63 69 64 70 public: … … 106 112 107 113 // Utility functions 108 int64_t FindDirectoryObjectID(const std::string &rDirName, bool AllowOldVersion = false, 109 bool AllowDeletedDirs = false, std::vector<std::pair<std::string, int64_t> > *pStack = 0); 114 int64_t FindDirectoryObjectID(const std::string &rDirName, 115 bool AllowOldVersion = false, bool AllowDeletedDirs = false, 116 std::vector<std::pair<std::string, int64_t> > *pStack = 0); 117 int64_t FindFileID(const std::string& rNameOrIdString, 118 const bool *opts, int64_t *pDirIdOut, 119 std::string* pFileNameOut, int16_t flagsInclude, 120 int16_t flagsExclude, int16_t* pFlagsOut); 110 121 int64_t GetCurrentDirectoryID(); 111 122 std::string GetCurrentDirectoryName(); … … 113 124 114 125 private: 126 bool mReadWrite; 115 127 BackupProtocolClient &mrConnection; 116 128 const Configuration &mrConfiguration; -
box/trunk/bin/bbackupquery/bbackupquery.cpp
r2184 r2283 309 309 310 310 // Set up a context for our work 311 BackupQueries context(connection, conf );311 BackupQueries context(connection, conf, readWrite); 312 312 313 313 // Start running commands... first from the command line -
box/trunk/bin/bbackupquery/documentation.txt
r2157 r2283 160 160 < 161 161 162 > undelete <directory-name> 163 undelete -i <object-id> 164 165 Removes the deleted flag from the specified directory name (in the 166 current directory) or hex object ID. Be careful not to use this 167 command where a directory already exists with the same name which is 168 not marked as deleted. 169 < 170 171 > delete <file-name> 172 173 Sets the deleted flag on the specified file name (in the current 174 directory, or with a relative path). 175 < 176 162 177 > quit 163 178
Note: See TracChangeset
for help on using the changeset viewer.
