Changeset 91188 in vbox
- Timestamp:
- Sep 9, 2021 10:59:50 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 146842
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloudMachine.cpp
r91175 r91188 41 41 static HRESULT getMachineList(com::SafeIfaceArray<ICloudMachine> &aMachines, 42 42 const ComPtr<ICloudClient> &pClient); 43 43 44 static HRESULT getMachineById(ComPtr<ICloudMachine> &pMachineOut, 44 45 const ComPtr<ICloudClient> &pClient, … … 47 48 const ComPtr<ICloudClient> &pClient, 48 49 const char *pcszName); 49 static HRESULT getMachine(ComPtr<ICloudMachine> &pMachineOut, 50 const ComPtr<ICloudClient> &pClient, 51 const char *pcszWhatever); 50 static HRESULT getMachineByGuess(ComPtr<ICloudMachine> &pMachineOut, 51 const ComPtr<ICloudClient> &pClient, 52 const char *pcszWhatever); 53 54 struct MachineSpec { 55 const char *pcszSpec; 56 enum { GUESS, ID, NAME } enmKind; 57 58 MachineSpec() 59 : pcszSpec(NULL), enmKind(GUESS) {} 60 }; 61 62 static int checkMachineSpecArgument(MachineSpec &aMachineSpec, 63 int ch, const RTGETOPTUNION &Val); 64 static HRESULT getMachineBySpec(ComPtr<ICloudMachine> &pMachineOut, 65 const ComPtr<ICloudClient> &pClient, 66 const MachineSpec &aMachineSpec); 52 67 53 68 … … 371 386 */ 372 387 static HRESULT 373 getMachine (ComPtr<ICloudMachine> &pMachineOut,374 const ComPtr<ICloudClient> &pClient,375 const char *pcszWhatever)388 getMachineByGuess(ComPtr<ICloudMachine> &pMachineOut, 389 const ComPtr<ICloudClient> &pClient, 390 const char *pcszWhatever) 376 391 { 377 392 ComPtr<ICloudMachine> pMachine; … … 406 421 { "-?", 'h', RTGETOPT_REQ_NOTHING } 407 422 423 static RTEXITCODE 424 errThereCanBeOnlyOne() 425 { 426 return RTMsgErrorExit(RTEXITCODE_SYNTAX, 427 "only one machine can be specified"); 428 } 429 430 431 #define CLOUD_MACHINE_RTGETOPTDEF_MACHINE \ 432 { "--id", 'i', RTGETOPT_REQ_STRING }, \ 433 { "--name", 'n', RTGETOPT_REQ_STRING } 434 435 436 /* 437 * Almost all the cloud machine commands take a machine argument, so 438 * factor out the code to fish it out from the command line. 439 * 440 * ch - option should be processed by the caller. 441 * VINF_SUCCESS - option was processed. 442 * VERR_PARSE_ERROR - RTEXITCODE_SYNTAX 443 * Other IPRT errors - RTEXITCODE_FAILURE 444 */ 445 static int 446 checkMachineSpecArgument(MachineSpec &aMachineSpec, 447 int ch, const RTGETOPTUNION &Val) 448 { 449 int rc; 450 451 switch (ch) 452 { 453 /* 454 * Note that we don't used RTGETOPT_REQ_UUID here as it would 455 * be too limiting. First, we need the original string for 456 * the API call, not the UUID, and second, if the UUID has bad 457 * forward RTGetOptPrintError doesn't have access to the 458 * option argument for the error message. So do the format 459 * check ourselves. 460 */ 461 case 'i': /* --id */ 462 { 463 const char *pcszId = Val.psz; 464 465 if (aMachineSpec.pcszSpec != NULL) 466 { 467 errThereCanBeOnlyOne(); 468 return VERR_PARSE_ERROR; 469 } 470 471 RTUUID Uuid; 472 rc = RTUuidFromStr(&Uuid, pcszId); 473 if (RT_FAILURE(rc)) 474 { 475 RTMsgError("not a valid uuid: %s", pcszId); 476 return VERR_PARSE_ERROR; 477 } 478 479 aMachineSpec.pcszSpec = pcszId; 480 aMachineSpec.enmKind = MachineSpec::ID; 481 return VINF_SUCCESS; 482 } 483 484 case 'n': /* --name */ 485 { 486 const char *pcszName = Val.psz; 487 488 if (aMachineSpec.pcszSpec != NULL) 489 { 490 errThereCanBeOnlyOne(); 491 return VERR_PARSE_ERROR; 492 } 493 494 aMachineSpec.pcszSpec = pcszName; 495 aMachineSpec.enmKind = MachineSpec::NAME; 496 return VINF_SUCCESS; 497 } 498 499 /* 500 * Plain word (no dash/es). This must name a machine, though 501 * we have to guess whether it's an id or a name. 502 */ 503 case VINF_GETOPT_NOT_OPTION: 504 { 505 const char *pcszNameOrId = Val.psz; 506 507 if (aMachineSpec.pcszSpec != NULL) 508 { 509 errThereCanBeOnlyOne(); 510 return VERR_PARSE_ERROR; 511 } 512 513 aMachineSpec.pcszSpec = pcszNameOrId; 514 aMachineSpec.enmKind = MachineSpec::GUESS; 515 return VINF_SUCCESS; 516 } 517 518 /* might as well do it here */ 519 case 'h': /* --help */ 520 { 521 printHelp(g_pStdOut); 522 return VINF_CALLBACK_RETURN; 523 } 524 } 525 526 /* let the caller deal with it */ 527 return VINF_NOT_SUPPORTED; 528 } 529 530 531 static HRESULT 532 getMachineBySpec(ComPtr<ICloudMachine> &pMachineOut, 533 const ComPtr<ICloudClient> &pClient, 534 const MachineSpec &aMachineSpec) 535 { 536 HRESULT hrc = E_FAIL; 537 538 if (aMachineSpec.pcszSpec == NULL) 539 { 540 RTMsgErrorExit(RTEXITCODE_SYNTAX, "machine not specified"); 541 return E_FAIL; 542 } 543 544 if (aMachineSpec.pcszSpec[0] == '\0') 545 { 546 RTMsgError("machine name is empty"); 547 return E_FAIL; 548 } 549 550 switch (aMachineSpec.enmKind) 551 { 552 case MachineSpec::ID: 553 hrc = getMachineById(pMachineOut, pClient, aMachineSpec.pcszSpec); 554 if (FAILED(hrc)) 555 { 556 if (hrc == VBOX_E_OBJECT_NOT_FOUND) 557 RTMsgError("unable to find machine with id %s", aMachineSpec.pcszSpec); 558 return hrc; 559 } 560 break; 561 562 case MachineSpec::NAME: 563 hrc = getMachineByName(pMachineOut, pClient, aMachineSpec.pcszSpec); 564 if (FAILED(hrc)) 565 { 566 if (hrc == VBOX_E_OBJECT_NOT_FOUND) 567 RTMsgError("unable to find machine with name %s", aMachineSpec.pcszSpec); 568 return hrc; 569 } 570 break; 571 572 case MachineSpec::GUESS: 573 hrc = getMachineByGuess(pMachineOut, pClient, aMachineSpec.pcszSpec); 574 if (FAILED(hrc)) 575 { 576 if (hrc == VBOX_E_OBJECT_NOT_FOUND) 577 RTMsgError("unable to find machine %s", aMachineSpec.pcszSpec); 578 return hrc; 579 } 580 break; 581 } 582 583 /* switch was exhaustive (and successful) */ 584 AssertReturn(SUCCEEDED(hrc), E_FAIL); 585 return S_OK; 586 } 587 588 589 408 590 409 591 /* … … 417 599 const ComPtr<ICloudClient> &pClient) 418 600 { 419 /* 420 * cloud machine ... 421 */ 601 int rc; 602 422 603 enum 423 604 { … … 428 609 }; 429 610 611 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE); 430 612 static const RTGETOPTDEF s_aOptions[] = 431 {613 { 432 614 { "console-history", kMachine_ConsoleHistory, RTGETOPT_REQ_NOTHING }, 433 615 { "consolehistory", kMachine_ConsoleHistory, RTGETOPT_REQ_NOTHING }, 434 616 { "info", kMachine_Info, RTGETOPT_REQ_NOTHING }, 435 617 { "list", kMachine_List, RTGETOPT_REQ_NOTHING }, 436 618 CLOUD_MACHINE_RTGETOPTDEF_HELP 437 619 }; 438 439 int rc;440 441 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE);442 620 443 621 RTGETOPTSTATE OptState; … … 445 623 s_aOptions, RT_ELEMENTS(s_aOptions), 446 624 iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 447 AssertRCStmt(rc, 448 return RTMsgErrorExit(RTEXITCODE_INIT, /* internal error */ 449 "cloud machine: RTGetOptInit: %Rra", rc)); 625 AssertRCReturn(rc, RTMsgErrorExit(RTEXITCODE_INIT, 626 "cloud machine: RTGetOptInit: %Rra", rc)); 450 627 451 628 int ch; … … 516 693 const ComPtr<ICloudClient> &pClient) 517 694 { 518 /* 519 * cloud machine list 520 */ 695 HRESULT hrc; 696 int rc; 697 698 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_LIST); 521 699 static const RTGETOPTDEF s_aOptions[] = 522 700 { 523 701 { "--long", 'l', RTGETOPT_REQ_NOTHING }, 524 702 { "--sort", 's', RTGETOPT_REQ_NOTHING }, 525 703 CLOUD_MACHINE_RTGETOPTDEF_HELP 526 704 }; 527 705 … … 531 709 enum kSortOrderEnum { kSortOrder_None, kSortOrder_Name, kSortOrder_Id }; 532 710 kSortOrderEnum enmSortOrder = kSortOrder_None; 533 534 HRESULT hrc;535 int rc;536 537 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_LIST);538 711 539 712 RTGETOPTSTATE OptState; … … 541 714 s_aOptions, RT_ELEMENTS(s_aOptions), 542 715 iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 543 AssertRCStmt(rc, 544 return RTMsgErrorExit(RTEXITCODE_INIT, /* internal error */ 545 "cloud machine list: RTGetOptInit: %Rra", rc)); 716 AssertRCReturn(rc, RTMsgErrorExit(RTEXITCODE_INIT, 717 "cloud machine list: RTGetOptInit: %Rra", rc)); 546 718 547 719 int ch; … … 684 856 const ComPtr<ICloudClient> &pClient) 685 857 { 858 MachineSpec machineSpec; 859 ComPtr<ICloudMachine> pMachine; 686 860 HRESULT hrc; 861 int rc; 862 863 enum 864 { 865 kMachineInfoIota = 1000, 866 kMachineInfo_Details, 867 }; 687 868 688 869 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_INFO); 689 690 if (iFirst == a->argc) 691 { 692 return RTMsgErrorExit(RTEXITCODE_SYNTAX, 693 "cloud machine info: machine id required\n" 694 "Try '--help' for more information."); 695 } 696 697 for (int i = iFirst; i < a->argc; ++i) 698 { 699 ComPtr<ICloudMachine> pMachine; 700 hrc = getMachine(pMachine, pClient, a->argv[i]); 701 if (hrc == VBOX_E_OBJECT_NOT_FOUND) 702 return RTMsgErrorExit(RTEXITCODE_FAILURE, 703 "%s: not found", a->argv[i]); 704 else if (FAILED(hrc)) 705 return RTEXITCODE_FAILURE; 706 707 hrc = printMachineInfo(pMachine); 708 if (FAILED(hrc)) 709 return RTEXITCODE_FAILURE; 710 } 870 static const RTGETOPTDEF s_aOptions[] = 871 { 872 { "--details", kMachineInfo_Details, RTGETOPT_REQ_NOTHING }, 873 CLOUD_MACHINE_RTGETOPTDEF_MACHINE, 874 CLOUD_MACHINE_RTGETOPTDEF_HELP 875 }; 876 877 RTGETOPTSTATE OptState; 878 rc = RTGetOptInit(&OptState, a->argc, a->argv, 879 s_aOptions, RT_ELEMENTS(s_aOptions), 880 iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 881 AssertRCReturn(rc, RTMsgErrorExit(RTEXITCODE_INIT, 882 "RTGetOptInit: %Rra", rc)); 883 884 int ch; 885 RTGETOPTUNION Val; 886 while ((ch = RTGetOpt(&OptState, &Val)) != 0) 887 { 888 rc = checkMachineSpecArgument(machineSpec, ch, Val); 889 if (rc == VINF_SUCCESS) 890 continue; 891 else if (rc == VINF_CALLBACK_RETURN) 892 return RTEXITCODE_SUCCESS; 893 else if (rc == VERR_PARSE_ERROR) 894 return RTEXITCODE_SYNTAX; 895 896 switch (ch) 897 { 898 case kMachineInfo_Details: 899 /* currently no-op */ 900 break; 901 902 default: 903 return RTGetOptPrintError(ch, &Val); 904 } 905 } 906 907 hrc = getMachineBySpec(pMachine, pClient, machineSpec); 908 if (FAILED(hrc)) 909 return RTEXITCODE_FAILURE; 910 911 912 hrc = printMachineInfo(pMachine); 913 if (FAILED(hrc)) 914 return RTEXITCODE_FAILURE; 711 915 712 916 return RTEXITCODE_SUCCESS; … … 950 1154 const ComPtr<ICloudClient> &pClient) 951 1155 { 1156 MachineSpec machineSpec; 1157 ComPtr<ICloudMachine> pMachine; 952 1158 HRESULT hrc; 1159 int rc; 953 1160 954 1161 // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_CONSOLEHISTORY); 955 956 if (iFirst == a->argc) 957 { 958 return RTMsgErrorExit(RTEXITCODE_SYNTAX, 959 "cloud machine info: machine id required\n" 960 "Try '--help' for more information."); 961 } 962 963 if (a->argc - iFirst > 1) 964 { 965 return RTMsgErrorExit(RTEXITCODE_SYNTAX, 966 "cloud machine info: too many arguments\n" 967 "Try '--help' for more information."); 968 } 969 970 ComPtr<ICloudMachine> pMachine; 971 hrc = getMachine(pMachine, pClient, a->argv[iFirst]); 1162 static const RTGETOPTDEF s_aOptions[] = 1163 { 1164 CLOUD_MACHINE_RTGETOPTDEF_MACHINE, 1165 CLOUD_MACHINE_RTGETOPTDEF_HELP 1166 }; 1167 1168 RTGETOPTSTATE OptState; 1169 rc = RTGetOptInit(&OptState, a->argc, a->argv, 1170 s_aOptions, RT_ELEMENTS(s_aOptions), 1171 iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 1172 AssertRCStmt(rc, 1173 return RTMsgErrorExit(RTEXITCODE_INIT, /* internal error */ 1174 "RTGetOptInit: %Rra", rc)); 1175 1176 int ch; 1177 RTGETOPTUNION Val; 1178 while ((ch = RTGetOpt(&OptState, &Val)) != 0) 1179 { 1180 rc = checkMachineSpecArgument(machineSpec, ch, Val); 1181 if (rc == VINF_SUCCESS) 1182 continue; 1183 else if (rc == VINF_CALLBACK_RETURN) 1184 return RTEXITCODE_SUCCESS; 1185 else if (rc == VERR_PARSE_ERROR) 1186 return RTEXITCODE_SYNTAX; 1187 1188 switch (ch) 1189 { 1190 /* no other options currently */ 1191 default: 1192 return RTGetOptPrintError(ch, &Val); 1193 } 1194 } 1195 1196 hrc = getMachineBySpec(pMachine, pClient, machineSpec); 972 1197 if (FAILED(hrc)) 973 1198 return RTEXITCODE_FAILURE; 1199 974 1200 975 1201 ComPtr<IDataStream> pHistoryStream;
Note:
See TracChangeset
for help on using the changeset viewer.