- Timestamp:
- Nov 24, 2010 7:39:22 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r34250 r34337 80 80 { 81 81 RTStrmPrintf(pStrm, 82 "VBoxManage guestcontrol exec ute<vmname>|<uuid>\n"82 "VBoxManage guestcontrol exec[ute] <vmname>|<uuid>\n" 83 83 " <path to program>\n" 84 84 " --username <name> --password <password>\n" … … 90 90 * stuff, e.g. "VBoxManage guestcontrol execute <VMName> --username <> ... -- /bin/rm -Rf /foo". */ 91 91 "\n" 92 " copyto <vmname>|<uuid>\n"92 " copyto|cp <vmname>|<uuid>\n" 93 93 " <source on host> <destination on guest>\n" 94 94 " --username <name> --password <password>\n" 95 95 " [--dryrun] [--recursive] [--verbose] [--flags <flags>]\n" 96 96 "\n" 97 " createdir ectory<vmname>|<uuid>\n"97 " createdir[ectory]|mkdir|md <vmname>|<uuid>\n" 98 98 " <directory to create on guest>\n" 99 99 " --username <name> --password <password>\n" … … 264 264 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 265 265 266 Utf8Str Utf8Cmd(a->argv[1]); 266 static const RTGETOPTDEF s_aOptions[] = 267 { 268 { "--arguments", 'a', RTGETOPT_REQ_STRING }, 269 { "--environment", 'e', RTGETOPT_REQ_STRING }, 270 { "--flags", 'f', RTGETOPT_REQ_STRING }, 271 { "--password", 'p', RTGETOPT_REQ_STRING }, 272 { "--timeout", 't', RTGETOPT_REQ_UINT32 }, 273 { "--username", 'u', RTGETOPT_REQ_STRING }, 274 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 275 { "--wait-for", 'w', RTGETOPT_REQ_STRING } 276 }; 277 278 int ch; 279 RTGETOPTUNION ValueUnion; 280 RTGETOPTSTATE GetState; 281 RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); 282 283 Utf8Str Utf8Cmd; 267 284 uint32_t uFlags = 0; 268 285 /* Note: this uses IN_BSTR as it must be BSTR on COM and CBSTR on XPCOM */ … … 278 295 bool fTimeout = false; 279 296 280 /* Always use the actual command line as argv[0]. */ 281 args.push_back(Bstr(Utf8Cmd).raw()); 282 283 /** @todo r=bird: Use RTGetOpt here, no new code using strcmp-if-switching! */ 284 /* Iterate through all possible commands (if available). */ 285 bool usageOK = true; 286 for (int i = 2; usageOK && i < a->argc; i++) 287 { 288 if ( !strcmp(a->argv[i], "--arguments") 289 || !strcmp(a->argv[i], "--args") 290 || !strcmp(a->argv[i], "--arg")) 291 { 292 if (i + 1 >= a->argc) 293 usageOK = false; 294 else 297 int vrc = VINF_SUCCESS; 298 bool fUsageOK = true; 299 while ( (ch = RTGetOpt(&GetState, &ValueUnion)) 300 && RT_SUCCESS(vrc)) 301 { 302 /* For options that require an argument, ValueUnion has received the value. */ 303 switch (ch) 304 { 305 case 'a': /* Arguments */ 295 306 { 296 307 char **papszArg; 297 308 int cArgs; 298 309 299 int vrc = RTGetOptArgvFromString(&papszArg, &cArgs, a->argv[i + 1], NULL);310 vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL); 300 311 if (RT_SUCCESS(vrc)) 301 312 { … … 305 316 RTGetOptArgvFree(papszArg); 306 317 } 307 ++i; 308 } 309 } 310 else if ( !strcmp(a->argv[i], "--environment") 311 || !strcmp(a->argv[i], "--env")) 312 { 313 if (i + 1 >= a->argc) 314 usageOK = false; 315 else 318 break; 319 } 320 321 case 'e': /* Environment */ 316 322 { 317 323 char **papszArg; 318 324 int cArgs; 319 325 320 int vrc = RTGetOptArgvFromString(&papszArg, &cArgs, a->argv[i + 1], NULL);326 vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL); 321 327 if (RT_SUCCESS(vrc)) 322 328 { … … 326 332 RTGetOptArgvFree(papszArg); 327 333 } 328 ++i; 329 } 330 } 331 else if (!strcmp(a->argv[i], "--flags")) 332 { 333 if (i + 1 >= a->argc) 334 usageOK = false; 335 else 336 { 334 break; 335 } 336 337 case 'f': /* Flags */ 337 338 /** @todo Needs a bit better processing as soon as we have more flags. */ 338 if (! strcmp(a->argv[i + 1], "ignoreorphanedprocesses"))339 if (!RTStrICmp(ValueUnion.psz, "ignoreorphanedprocesses")) 339 340 uFlags |= ExecuteProcessFlag_IgnoreOrphanedProcesses; 340 341 else 341 usageOK = false; 342 ++i; 343 } 344 } 345 else if ( !strcmp(a->argv[i], "--username") 346 || !strcmp(a->argv[i], "--user")) 347 { 348 if (i + 1 >= a->argc) 349 usageOK = false; 350 else 351 { 352 Utf8UserName = a->argv[i + 1]; 353 ++i; 354 } 355 } 356 else if ( !strcmp(a->argv[i], "--password") 357 || !strcmp(a->argv[i], "--pwd")) 358 { 359 if (i + 1 >= a->argc) 360 usageOK = false; 361 else 362 { 363 Utf8Password = a->argv[i + 1]; 364 ++i; 365 } 366 } 367 else if (!strcmp(a->argv[i], "--timeout")) 368 { 369 if ( i + 1 >= a->argc 370 || RTStrToUInt32Full(a->argv[i + 1], 10, &u32TimeoutMS) != VINF_SUCCESS 371 || u32TimeoutMS == 0) 372 { 373 usageOK = false; 374 } 375 else 376 { 342 fUsageOK = false; 343 break; 344 345 case 'p': /* Password */ 346 Utf8Password = ValueUnion.psz; 347 break; 348 349 case 't': /* Timeout */ 350 u32TimeoutMS = ValueUnion.u32; 377 351 fTimeout = true; 378 ++i; 379 } 380 } 381 else if (!strcmp(a->argv[i], "--wait-for")) 382 { 383 if (i + 1 >= a->argc) 384 usageOK = false; 385 else 386 { 387 if (!strcmp(a->argv[i + 1], "exit")) 352 break; 353 354 case 'u': /* User name */ 355 Utf8UserName = ValueUnion.psz; 356 break; 357 358 case 'v': /* Verbose */ 359 fVerbose = true; 360 break; 361 362 case 'w': /* Wait for ... */ 363 { 364 if (!RTStrICmp(ValueUnion.psz, "exit")) 388 365 fWaitForExit = true; 389 else if (! strcmp(a->argv[i + 1], "stdout"))366 else if (!RTStrICmp(ValueUnion.psz, "stdout")) 390 367 { 391 368 fWaitForExit = true; 392 369 fWaitForStdOut = true; 393 370 } 394 else if (! strcmp(a->argv[i + 1], "stderr"))371 else if (!RTStrICmp(ValueUnion.psz, "stderr")) 395 372 { 396 373 fWaitForExit = true; … … 398 375 } 399 376 else 400 usageOK = false; 401 ++i; 402 } 403 } 404 else if (!strcmp(a->argv[i], "--verbose")) 405 fVerbose = true; 406 /** @todo Add fancy piping stuff here. */ 407 else 408 return errorSyntax(USAGE_GUESTCONTROL, 409 "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str()); 410 } 411 412 if (!usageOK) 377 fUsageOK = false; 378 break; 379 } 380 381 case VINF_GETOPT_NOT_OPTION: 382 { 383 /* The actual command we want to execute on the guest. */ 384 Utf8Cmd = ValueUnion.psz; 385 break; 386 } 387 388 default: 389 return RTGetOptPrintError(ch, &ValueUnion); 390 } 391 } 392 393 if (!fUsageOK) 413 394 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 395 396 if (Utf8Cmd.isEmpty()) 397 return errorSyntax(USAGE_GUESTCONTROL, 398 "No command to execute specified!"); 414 399 415 400 if (Utf8UserName.isEmpty()) … … 419 404 HRESULT rc = S_OK; 420 405 ComPtr<IGuest> guest; 421 intvrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);406 vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 422 407 if (RT_SUCCESS(vrc)) 423 408 { … … 612 597 * @param pList Copy list used for insertion. 613 598 */ 614 /** @todo r=bird: static? */ 615 int ctrlCopyDirectoryEntryAppend(const char *pszFileSource, const char *pszFileDest, 616 PRTLISTNODE pList) 599 static int ctrlCopyDirectoryEntryAppend(const char *pszFileSource, const char *pszFileDest, 600 PRTLISTNODE pList) 617 601 { 618 602 AssertPtrReturn(pszFileSource, VERR_INVALID_POINTER); … … 654 638 * @param pList Pointer to the object list to use. 655 639 */ 656 /** @todo r=bird: static? */ 657 int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir, 658 const char *pszFilter, const char *pszDest, 659 uint32_t uFlags, uint32_t *pcObjects, PRTLISTNODE pList) 640 static int ctrlCopyDirectoryRead(const char *pszRootDir, const char *pszSubDir, 641 const char *pszFilter, const char *pszDest, 642 uint32_t uFlags, uint32_t *pcObjects, PRTLISTNODE pList) 660 643 { 661 644 AssertPtrReturn(pszRootDir, VERR_INVALID_POINTER); … … 797 780 * @param pList Where to store the object list. 798 781 */ 799 /** @todo r=bird: static? */ 800 int ctrlCopyInit(const char *pszSource, const char *pszDest, uint32_t uFlags, 801 uint32_t *pcObjects, PRTLISTNODE pList) 782 static int ctrlCopyInit(const char *pszSource, const char *pszDest, uint32_t uFlags, 783 uint32_t *pcObjects, PRTLISTNODE pList) 802 784 { 803 785 AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER); … … 923 905 * Destroys a copy list. 924 906 */ 925 /** @todo r=bird: static? */ 926 void ctrlCopyDestroy(PRTLISTNODE pList) 907 static void ctrlCopyDestroy(PRTLISTNODE pList) 927 908 { 928 909 AssertPtr(pList); … … 960 941 * @param uFlags Copy flags. 961 942 */ 962 /** @todo r=bird: static? */ 963 int ctrlCopyFileToGuest(IGuest *pGuest, const char *pszSource, const char *pszDest, 964 const char *pszUserName, const char *pszPassword, 965 uint32_t uFlags) 943 static int ctrlCopyFileToGuest(IGuest *pGuest, const char *pszSource, const char *pszDest, 944 const char *pszUserName, const char *pszPassword, 945 uint32_t uFlags) 966 946 { 967 947 AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER); … … 1042 1022 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 1043 1023 1044 Utf8Str Utf8Source(a->argv[1]); 1045 Utf8Str Utf8Dest(a->argv[2]); 1024 static const RTGETOPTDEF s_aOptions[] = 1025 { 1026 { "--dryrun", 'd', RTGETOPT_REQ_NOTHING }, 1027 //{ "--flags", 'f', RTGETOPT_REQ_STRING }, 1028 { "--follow", 'F', RTGETOPT_REQ_NOTHING }, 1029 { "--password", 'p', RTGETOPT_REQ_STRING }, 1030 { "--recursive", 'R', RTGETOPT_REQ_NOTHING }, 1031 { "--update", 'U', RTGETOPT_REQ_NOTHING }, 1032 { "--username", 'u', RTGETOPT_REQ_STRING }, 1033 { "--verbose", 'v', RTGETOPT_REQ_NOTHING } 1034 }; 1035 1036 int ch; 1037 RTGETOPTUNION ValueUnion; 1038 RTGETOPTSTATE GetState; 1039 RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); 1040 1041 Utf8Str Utf8Source; 1042 Utf8Str Utf8Dest; 1046 1043 Utf8Str Utf8UserName; 1047 1044 Utf8Str Utf8Password; … … 1050 1047 bool fCopyRecursive = false; 1051 1048 bool fDryRun = false; 1052 /** @todo r=bird: Use RTGetOpt here, no new code using strcmp-if-switching! */ 1053 1054 /* Iterate through all possible commands (if available). */ 1055 bool usageOK = true; 1056 for (int i = 3; usageOK && i < a->argc; i++) 1057 { 1058 if ( !strcmp(a->argv[i], "--username") 1059 || !strcmp(a->argv[i], "--user")) 1060 { 1061 if (i + 1 >= a->argc) 1062 usageOK = false; 1063 else 1064 { 1065 Utf8UserName = a->argv[i + 1]; 1066 ++i; 1067 } 1068 } 1069 else if ( !strcmp(a->argv[i], "--password") 1070 || !strcmp(a->argv[i], "--pwd")) 1071 { 1072 if (i + 1 >= a->argc) 1073 usageOK = false; 1074 else 1075 { 1076 Utf8Password = a->argv[i + 1]; 1077 ++i; 1078 } 1079 } 1080 else if (!strcmp(a->argv[i], "--dryrun")) 1081 { 1082 fDryRun = true; 1083 } 1084 else if (!strcmp(a->argv[i], "--flags")) 1085 { 1086 if (i + 1 >= a->argc) 1087 usageOK = false; 1088 else 1089 { 1049 1050 int vrc = VINF_SUCCESS; 1051 uint32_t uNoOptionIdx = 0; 1052 bool fUsageOK = true; 1053 while ( (ch = RTGetOpt(&GetState, &ValueUnion)) 1054 && RT_SUCCESS(vrc)) 1055 { 1056 /* For options that require an argument, ValueUnion has received the value. */ 1057 switch (ch) 1058 { 1059 case 'd': /* Dry run */ 1060 fDryRun = true; 1061 break; 1062 1063 case 'f': /* Flags */ 1090 1064 /* Nothing to do here yet. */ 1091 ++i; 1092 } 1093 } 1094 else if ( !strcmp(a->argv[i], "--recursive") 1095 || !strcmp(a->argv[i], "--r")) 1096 { 1097 uFlags |= CopyFileFlag_Recursive; 1098 } 1099 else if ( !strcmp(a->argv[i], "--update") 1100 || !strcmp(a->argv[i], "--u")) 1101 { 1102 uFlags |= CopyFileFlag_Update; 1103 } 1104 else if ( !strcmp(a->argv[i], "--follow") 1105 || !strcmp(a->argv[i], "--f")) 1106 { 1107 uFlags |= CopyFileFlag_FollowLinks; 1108 } 1109 /** @todo Add force flag for overwriting existing stuff. */ 1110 else if (!strcmp(a->argv[i], "--verbose")) 1111 fVerbose = true; 1112 else 1113 return errorSyntax(USAGE_GUESTCONTROL, 1114 "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str()); 1115 } 1116 1117 if (!usageOK) 1065 break; 1066 1067 case 'F': /* Follow symlinks */ 1068 uFlags |= CopyFileFlag_FollowLinks; 1069 break; 1070 1071 case 'p': /* Password */ 1072 Utf8Password = ValueUnion.psz; 1073 break; 1074 1075 case 'R': /* Recursive processing */ 1076 uFlags |= CopyFileFlag_Recursive; 1077 break; 1078 1079 case 'U': /* Only update newer files */ 1080 uFlags |= CopyFileFlag_Update; 1081 break; 1082 1083 case 'u': /* User name */ 1084 Utf8UserName = ValueUnion.psz; 1085 break; 1086 1087 case 'v': /* Verbose */ 1088 fVerbose = true; 1089 break; 1090 1091 case VINF_GETOPT_NOT_OPTION: 1092 { 1093 /* Get the actual source + destination. */ 1094 switch (uNoOptionIdx) 1095 { 1096 case 0: 1097 Utf8Source = ValueUnion.psz; 1098 break; 1099 1100 case 1: 1101 Utf8Dest = ValueUnion.psz; 1102 break; 1103 1104 default: 1105 break; 1106 } 1107 uNoOptionIdx++; 1108 break; 1109 } 1110 1111 default: 1112 return RTGetOptPrintError(ch, &ValueUnion); 1113 } 1114 } 1115 1116 if (!fUsageOK) 1118 1117 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 1119 1118 … … 1129 1128 return errorSyntax(USAGE_GUESTCONTROL, 1130 1129 "No user name specified!"); 1131 1132 1130 HRESULT rc = S_OK; 1133 1131 ComPtr<IGuest> guest; 1134 intvrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);1132 vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 1135 1133 if (RT_SUCCESS(vrc)) 1136 1134 { … … 1261 1259 || !strcmp(a->argv[i], "-m")) 1262 1260 { 1263 /** @todo r=bird: the mode is octal, isn't it? */1264 1261 if (i + 1 >= a->argc 1265 || RTStrToUInt32Full(a->argv[i + 1], 10, &uMode) != VINF_SUCCESS)1262 || RTStrToUInt32Full(a->argv[i + 1], 8 /* Base, octal */, &uMode) != VINF_SUCCESS) 1266 1263 usageOK = false; 1267 1264 else … … 1504 1501 else if ( !strcmp(a->argv[0], "createdirectory") 1505 1502 || !strcmp(a->argv[0], "createdir") 1506 || !strcmp(a->argv[0], "mkdir")) 1503 || !strcmp(a->argv[0], "mkdir") 1504 || !strcmp(a->argv[0], "md")) 1507 1505 { 1508 1506 return handleCtrlCreateDirectory(&arg);
Note:
See TracChangeset
for help on using the changeset viewer.