Changeset 2697
- Timestamp:
- 06/06/2010 16:30:20 (2 years ago)
- Location:
- box/trunk/bin/bbackupquery
- Files:
-
- 3 edited
-
BackupQueries.cpp (modified) (10 diffs)
-
BackupQueries.h (modified) (3 diffs)
-
bbackupquery.cpp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/bin/bbackupquery/BackupQueries.cpp
r2641 r2697 67 67 QueryCommandSpecification commands[] = 68 68 { 69 { "quit", "" },70 { "exit", "" },71 { "list", "rodIFtTash", },72 { "pwd", "" },73 { "cd", "od" },74 { "lcd", "" },75 { "sh", "" },76 { "getobject", "" },77 { "get", "i" },78 { "compare", "alcqAEQ" },79 { "restore", "drif" },80 { "help", "" },81 { "usage", "m" },82 { "undelete", "" },83 { "delete", "" },84 { NULL, NULL }69 { "quit", "", Command_Quit }, 70 { "exit", "", Command_Quit }, 71 { "list", "rodIFtTash", Command_List }, 72 { "pwd", "", Command_pwd }, 73 { "cd", "od", Command_cd }, 74 { "lcd", "", Command_lcd }, 75 { "sh", "", Command_sh }, 76 { "getobject", "", Command_GetObject }, 77 { "get", "i", Command_Get }, 78 { "compare", "alcqAEQ", Command_Compare }, 79 { "restore", "drif", Command_Restore }, 80 { "help", "", Command_Help }, 81 { "usage", "m", Command_Usage }, 82 { "undelete", "", Command_Undelete }, 83 { "delete", "", Command_Delete }, 84 { NULL, NULL, Command_Unknown } 85 85 }; 86 86 … … 125 125 } 126 126 127 BackupQueries::ParsedCommand 128 BackupQueries::ParseCommand(const std::string& Command, bool isFromCommandLine) 129 { 130 ParsedCommand parsed; 131 parsed.completeCommand = Command; 132 133 // is the command a shell command? 134 if(Command[0] == 's' && Command[1] == 'h' && Command[2] == ' ' && Command[3] != '\0') 135 { 136 // Yes, run shell command 137 parsed.cmdElements[0] = "sh"; 138 parsed.cmdElements[1] = Command.c_str() + 3; 139 return parsed; 140 } 141 142 // split command into components 143 const char *c = Command.c_str(); 144 bool inQuoted = false; 145 bool inOptions = false; 146 147 std::string s; 148 while(*c != 0) 149 { 150 // Terminating char? 151 if(*c == ((inQuoted)?'"':' ')) 152 { 153 if(!s.empty()) parsed.cmdElements.push_back(s); 154 s.resize(0); 155 inQuoted = false; 156 inOptions = false; 157 } 158 else 159 { 160 // No. Start of quoted parameter? 161 if(s.empty() && *c == '"') 162 { 163 inQuoted = true; 164 } 165 // Start of options? 166 else if(s.empty() && *c == '-') 167 { 168 inOptions = true; 169 } 170 else 171 { 172 if(inOptions) 173 { 174 // Option char 175 parsed.options += *c; 176 } 177 else 178 { 179 // Normal string char 180 s += *c; 181 } 182 } 183 } 184 185 ++c; 186 } 187 188 if(!s.empty()) 189 { 190 parsed.cmdElements.push_back(s); 191 } 192 193 #ifdef WIN32 194 if(isFromCommandLine) 195 { 196 std::string converted; 197 198 if(!ConvertEncoding(parsed.completeCommand, CP_ACP, converted, 199 GetConsoleCP())) 200 { 201 BOX_ERROR("Failed to convert encoding"); 202 return; 203 } 204 205 parsed.completeCommand = converted; 206 207 for(std::vector<std::string>::iterator 208 i = parsed.cmdElements.begin(); 209 i != parsed.cmdElements.end(); i++) 210 { 211 if(!ConvertEncoding(*i, CP_ACP, converted, 212 GetConsoleCP())) 213 { 214 BOX_ERROR("Failed to convert encoding"); 215 return; 216 } 217 218 *i = converted; 219 } 220 } 221 #endif 222 223 return parsed; 224 } 225 127 226 // -------------------------------------------------------------------------- 128 227 // … … 133 232 // 134 233 // -------------------------------------------------------------------------- 135 void BackupQueries::DoCommand(const char *Command, bool isFromCommandLine) 136 { 137 // is the command a shell command? 138 if(Command[0] == 's' && Command[1] == 'h' && Command[2] == ' ' && Command[3] != '\0') 234 void BackupQueries::DoCommand(ParsedCommand& rCommand) 235 { 236 // Check... 237 if(rCommand.cmdElements.size() < 1) 238 { 239 // blank command 240 return; 241 } 242 243 if(rCommand.cmdElements[0] == "sh" && rCommand.cmdElements.size() == 2) 139 244 { 140 245 // Yes, run shell command 141 int result = ::system( Command + 3);246 int result = ::system(rCommand.cmdElements[1].c_str()); 142 247 if(result != 0) 143 248 { … … 148 253 return; 149 254 } 150 151 // split command into components 152 std::vector<std::string> cmdElements; 153 std::string options; 154 { 155 const char *c = Command; 156 bool inQuoted = false; 157 bool inOptions = false; 158 159 std::string s; 160 while(*c != 0) 161 { 162 // Terminating char? 163 if(*c == ((inQuoted)?'"':' ')) 164 { 165 if(!s.empty()) cmdElements.push_back(s); 166 s.resize(0); 167 inQuoted = false; 168 inOptions = false; 169 } 170 else 171 { 172 // No. Start of quoted parameter? 173 if(s.empty() && *c == '"') 174 { 175 inQuoted = true; 176 } 177 // Start of options? 178 else if(s.empty() && *c == '-') 179 { 180 inOptions = true; 181 } 182 else 183 { 184 if(inOptions) 185 { 186 // Option char 187 options += *c; 188 } 189 else 190 { 191 // Normal string char 192 s += *c; 193 } 194 } 195 } 196 197 ++c; 198 } 199 if(!s.empty()) cmdElements.push_back(s); 200 } 201 202 #ifdef WIN32 203 if (isFromCommandLine) 204 { 205 for (std::vector<std::string>::iterator 206 i = cmdElements.begin(); 207 i != cmdElements.end(); i++) 208 { 209 std::string converted; 210 if (!ConvertEncoding(*i, CP_ACP, converted, 211 GetConsoleCP())) 212 { 213 BOX_ERROR("Failed to convert encoding"); 214 return; 215 } 216 *i = converted; 217 } 218 } 219 #endif 220 221 // Check... 222 if(cmdElements.size() < 1) 223 { 224 // blank command 225 return; 226 } 227 255 228 256 // Work out which command it is... 229 257 int cmd = 0; 230 while(commands[cmd].name != 0 && ::strcmp(cmdElements[0].c_str(), commands[cmd].name) != 0) 258 while(commands[cmd].name != 0 && 259 rCommand.cmdElements[0] != commands[cmd].name) 231 260 { 232 261 cmd++; 233 262 } 263 234 264 if(commands[cmd].name == 0) 235 265 { … … 238 268 for(a = 0; alias[a] != 0; ++a) 239 269 { 240 if( ::strcmp(cmdElements[0].c_str(), alias[a]) == 0)270 if(rCommand.cmdElements[0] == alias[a]) 241 271 { 242 272 // Found an alias … … 245 275 } 246 276 } 247 277 } 278 279 if(commands[cmd].name == 0 || commands[cmd].type == Command_Unknown) 280 { 248 281 // No such command 249 if(alias[a] == 0) 250 { 251 BOX_ERROR("Unrecognised command: " << Command); 252 return; 253 } 282 BOX_ERROR("Unrecognised command: " << rCommand.cmdElements[0]); 283 return; 254 284 } 255 285 256 286 // Arguments 257 std::vector<std::string> args(cmdElements.begin() + 1, cmdElements.end()); 287 std::vector<std::string> args(rCommand.cmdElements.begin() + 1, 288 rCommand.cmdElements.end()); 258 289 259 290 // Set up options … … 263 294 { 264 295 // options 265 const char *c = options.c_str();296 const char *c = rCommand.options.c_str(); 266 297 while(*c != 0) 267 298 { … … 278 309 } 279 310 280 if(c md != Command_Quit && cmd != Command_Exit)311 if(commands[cmd].type != Command_Quit) 281 312 { 282 313 // If not a quit command, set the return code to zero … … 285 316 286 317 // Handle command 287 switch(c md)318 switch(commands[cmd].type) 288 319 { 289 320 case Command_Quit: 290 case Command_Exit:291 321 mQuitNow = true; 292 322 break; … … 349 379 350 380 default: 351 BOX_ERROR("Unknown command: " << Command);381 BOX_ERROR("Unknown command: " << rCommand.cmdElements[0]); 352 382 break; 353 383 } -
box/trunk/bin/bbackupquery/BackupQueries.h
r2641 r2697 21 21 class ExcludeList; 22 22 23 typedef struct24 {25 const char* name;26 const char* opts;27 }28 QueryCommandSpecification;29 30 // Data about commands31 extern QueryCommandSpecification commands[];32 33 23 typedef enum 34 24 { 35 Command_ Quit= 0,36 Command_ Exit,25 Command_Unknown = 0, 26 Command_Quit, 37 27 Command_List, 38 28 Command_pwd, … … 50 40 } 51 41 CommandType; 42 43 typedef enum 44 { 45 Complete_End = 0, 46 Complete_RemoteDir, 47 Complete_RemoteFile, 48 Complete_LocalDir, 49 Complete_LocalFile, 50 Complete_LocationName, 51 Complete_RemoteIdInCurrentDir, 52 } 53 CompletionType; 54 55 typedef struct 56 { 57 const char* name; 58 const char* opts; 59 CommandType type; 60 } 61 QueryCommandSpecification; 62 63 // Data about commands 64 extern QueryCommandSpecification commands[]; 52 65 53 66 extern const char *alias[]; … … 72 85 BackupQueries(const BackupQueries &); 73 86 public: 74 75 void DoCommand(const char *Command, bool isFromCommandLine); 87 struct ParsedCommand 88 { 89 std::vector<std::string> cmdElements; 90 std::string options; 91 std::string completeCommand; 92 }; 93 94 ParsedCommand ParseCommand(const std::string& Command, 95 bool isFromCommandLine); 96 void DoCommand(ParsedCommand& rCommand); 97 CompletionType* GetCompletionTypes(ParsedCommand& rCommand); 76 98 77 99 // Ready to stop? -
box/trunk/bin/bbackupquery/bbackupquery.cpp
r2695 r2697 61 61 void PrintUsageAndExit() 62 62 { 63 printf("Usage: bbackupquery [-q*|v*|V|W<level>] [-w] " 63 std::ostringstream out; 64 out << 65 "Usage: bbackupquery [options] [command]...\n" 66 "\n" 67 "Options:\n" 68 " -q Run more quietly, reduce verbosity level by one, can repeat\n" 69 " -Q Run at minimum verbosity, log nothing\n" 70 " -v Run more verbosely, increase verbosity level by one, can repeat\n" 71 " -V Run at maximum verbosity, log everything\n" 72 " -W <level> Set verbosity to error/warning/notice/info/trace/everything\n" 73 " -w Read/write mode, allow changes to store\n" 64 74 #ifdef WIN32 65 "[-u] " 66 #endif 67 "\n" 68 "\t[-c config_file] [-o log_file] [-O log_file_level]\n" 69 "\t[-l protocol_log_file] [commands]\n" 70 "\n" 71 "As many commands as you require.\n" 72 "If commands are multiple words, remember to enclose the command in quotes.\n" 73 "Remember to use the quit command unless you want to end up in interactive mode.\n"); 75 " -u Enable Unicode console, requires font change to Lucida Console\n" 76 #else // !WIN32 77 " -E Disable interactive command editing, may fix entering intl chars\n" 78 #endif 79 " -c <file> Use the specified configuration file. If -c is omitted, the last\n" 80 " argument is the configuration file, or else the default \n" 81 " [" << BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE << 82 "]\n" 83 " -o <file> Write logging output to specified file as well as console\n" 84 " -O <level> Set file verbosity to error/warning/notice/info/trace/everything\n" 85 " -l <file> Write protocol debugging logs to specified file\n" 86 "\n" 87 "Parameters: as many commands as you like. If commands are multiple words,\n" 88 "remember to enclose the command in quotes. Remember to use the quit command\n" 89 "unless you want to end up in interactive mode.\n"; 90 printf("%s", out.str().c_str()); 74 91 exit(1); 75 92 } … … 121 138 } 122 139 140 #ifdef HAVE_RL_COMPLETION_MATCHES 141 #define RL_COMPLETION_MATCHES rl_completion_matches 142 #elif defined HAVE_COMPLETION_MATCHES 143 #define RL_COMPLETION_MATCHES completion_matches 144 #endif 145 123 146 char ** bbackupquery_completion(const char *text, int start, int end) 124 147 { … … 131 154 * directory. 132 155 */ 156 #ifdef RL_COMPLETION_MATCHES 133 157 if (start == 0) 134 158 { 135 #ifdef HAVE_RL_COMPLETION_MATCHES 136 matches = rl_completion_matches(text, 137 command_generator); 138 #elif defined HAVE_COMPLETION_MATCHES 139 matches = completion_matches(text, command_generator); 140 #endif 141 } 159 matches = RL_COMPLETION_MATCHES(text, command_generator); 160 } 161 #endif 142 162 143 163 return matches; … … 191 211 const char* validOpts = "qvVwuc:l:o:O:W:"; 192 212 bool unicodeConsole = false; 193 #else 194 const char* validOpts = "qvVwc:l:o:O:W:"; 213 #elif defined HAVE_LIBREADLINE // && !WIN32 214 const char* validOpts = "qvVwEc:l:o:O:W:"; 215 bool useReadline = true; 195 216 #endif 196 217 … … 286 307 case 'u': 287 308 unicodeConsole = true; 309 break; 310 #elif defined HAVE_LIBREADLINE // && !WIN32 311 case 'E': 312 useReadline = false; 288 313 break; 289 314 #endif … … 383 408 // 3. Make a protocol, and handshake 384 409 if(!quiet) BOX_INFO("Handshake with store..."); 385 BackupProtocolClient connection(socket); 410 std::auto_ptr<BackupProtocolClient> 411 apConnection(new BackupProtocolClient(socket)); 412 BackupProtocolClient& connection(*(apConnection.get())); 386 413 connection.Handshake(); 387 414 … … 403 430 } 404 431 // Login -- if this fails, the Protocol will exception 405 connection.QueryLogin(conf.GetKeyValue Int("AccountNumber"),432 connection.QueryLogin(conf.GetKeyValueUint32("AccountNumber"), 406 433 (readWrite)?0:(BackupProtocolClientLogin::Flags_ReadOnly)); 407 434 … … 417 444 while(c < argc && !context.Stop()) 418 445 { 419 context.DoCommand(argv[c++], true); 446 BackupQueries::ParsedCommand cmd( 447 context.ParseCommand(argv[c++], true)); 448 context.DoCommand(cmd); 420 449 } 421 450 } … … 424 453 425 454 #ifdef HAVE_LIBREADLINE 426 // Must initialise the locale before using editline's readline(), 427 // otherwise cannot enter international characters. 428 if (setlocale(LC_ALL, "") == NULL) 429 { 430 BOX_ERROR("Failed to initialise locale. International " 431 "character support may not work."); 432 } 433 434 #ifdef HAVE_READLINE_HISTORY 435 using_history(); 436 #endif 437 /* Allow conditional parsing of the ~/.inputrc file. */ 438 rl_readline_name = "bbackupquery"; 439 440 /* Tell the completer that we want a crack first. */ 441 rl_attempted_completion_function = bbackupquery_completion; 442 443 char *last_cmd = 0; 444 while(!context.Stop()) 445 { 446 char *command = readline("query > "); 447 if(command == NULL) 448 { 449 // Ctrl-D pressed -- terminate now 450 break; 451 } 452 context.DoCommand(command, false); 453 if(last_cmd != 0 && ::strcmp(last_cmd, command) == 0) 454 { 455 free(command); 456 } 457 else 458 { 459 #ifdef HAVE_READLINE_HISTORY 460 add_history(command); 455 if (useReadline) 456 { 461 457 #else 458 if (false) 459 { 460 #endif 461 // Must initialise the locale before using editline's 462 // readline(), otherwise cannot enter international characters. 463 if (setlocale(LC_ALL, "") == NULL) 464 { 465 BOX_ERROR("Failed to initialise locale. International " 466 "character support may not work."); 467 } 468 469 #ifdef HAVE_READLINE_HISTORY 470 using_history(); 471 #endif 472 473 /* Allow conditional parsing of the ~/.inputrc file. */ 474 rl_readline_name = strdup("bbackupquery"); 475 476 /* Tell the completer that we want a crack first. */ 477 rl_attempted_completion_function = bbackupquery_completion; 478 479 char *last_cmd = 0; 480 while(!context.Stop()) 481 { 482 char *command = readline("query > "); 483 484 if(command == NULL) 485 { 486 // Ctrl-D pressed -- terminate now 487 break; 488 } 489 490 BackupQueries::ParsedCommand cmd( 491 context.ParseCommand(command, false)); 492 context.DoCommand(cmd); 493 494 if(last_cmd != 0 && ::strcmp(last_cmd, command) == 0) 495 { 496 free(command); 497 } 498 else 499 { 500 #ifdef HAVE_READLINE_HISTORY 501 add_history(command); 502 #else 503 free(last_cmd); 504 #endif 505 last_cmd = command; 506 } 507 } 508 #ifndef HAVE_READLINE_HISTORY 462 509 free(last_cmd); 463 #endif 464 last_cmd = command; 465 } 466 } 467 #ifndef HAVE_READLINE_HISTORY 468 free(last_cmd); 469 last_cmd = 0; 470 #endif 471 #else 472 // Version for platforms which don't have readline by default 473 if(fileno(stdin) >= 0) 474 { 475 FdGetLine getLine(fileno(stdin)); 476 while(!context.Stop()) 477 { 478 printf("query > "); 479 fflush(stdout); 480 std::string command(getLine.GetLine()); 481 context.DoCommand(command.c_str(), false); 482 } 483 } 484 #endif 510 last_cmd = 0; 511 #endif 512 } 513 else // !HAVE_LIBREADLINE || !useReadline 514 { 515 // Version for platforms which don't have readline by default 516 if(fileno(stdin) >= 0) 517 { 518 FdGetLine getLine(fileno(stdin)); 519 while(!context.Stop()) 520 { 521 printf("query > "); 522 fflush(stdout); 523 std::string command(getLine.GetLine()); 524 BackupQueries::ParsedCommand cmd( 525 context.ParseCommand(command, false)); 526 context.DoCommand(cmd); 527 } 528 } 529 } 485 530 486 531 // Done... stop nicely
Note: See TracChangeset
for help on using the changeset viewer.
