Changeset 75844 in vbox
- Timestamp:
- Nov 30, 2018 12:03:33 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r75832 r75844 189 189 * An entry for a source element, including an optional DOS-like wildcard (*,?). 190 190 */ 191 class SOURCEFILEENTRY 192 { 193 public: 194 195 SOURCEFILEENTRY(const char *pszSource, const char *pszFilter) 196 : mSource(pszSource), 197 mFilter(pszFilter) {} 198 199 SOURCEFILEENTRY(const char *pszSource) 200 : mSource(pszSource) 201 { 202 Parse(pszSource); 203 } 204 205 Utf8Str GetSource() const 206 { 207 return mSource; 208 } 209 210 Utf8Str GetFilter() const 211 { 212 return mFilter; 213 } 214 215 private: 216 217 int Parse(const char *pszPath) 218 { 219 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 220 221 /** @todo r=bird: Do ONE RTPathQueryInfo call here, and only do it when the source is on the HOST. 222 * You're currently doing this for guest files too... 223 * 224 * You realize that a filter is a filter when you define it to be, not when the 225 * file doesn't exist. It something the command defines, nothing else. So, it 226 * makes not sense. */ 227 if ( !RTFileExists(pszPath) 228 && !RTDirExists(pszPath)) 229 { 230 /* No file and no directory -- maybe a filter? */ 231 char *pszFilename = RTPathFilename(pszPath); 232 if ( pszFilename 233 && strpbrk(pszFilename, "*?")) 234 { 235 /* Yep, get the actual filter part. */ 236 mFilter = RTPathFilename(pszPath); 237 /* Remove the filter from actual sourcec directory name. */ 238 RTPathStripFilename(mSource.mutableRaw()); 239 mSource.jolt(); 240 } 241 } 242 243 return VINF_SUCCESS; /** @todo */ 244 } 245 246 private: 247 248 Utf8Str mSource; 249 Utf8Str mFilter; 191 class SourceFileEntry 192 { 193 public: 194 SourceFileEntry(const char *pszSource, const char *pszFilter) 195 : mSource(pszSource) 196 , mFilter(pszFilter) 197 {} 198 199 SourceFileEntry(const char *pszSource) 200 { 201 /** @todo Using host parsing rules for guest filenames might be undesirable... */ 202 203 /* Look for filter and split off the filter part if present. */ 204 const char *pszFilename = RTPathFilename(pszSource); 205 if ( !pszFilename 206 || !strpbrk(pszFilename, "*?")) 207 mSource.assign(pszSource); 208 else 209 { 210 mFilter = pszFilename; 211 size_t cch = pszFilename - pszSource; 212 if (cch > 0 && pszFilename[-1] != ':') 213 cch--; 214 mSource.assign(pszSource, cch); 215 } 216 } 217 218 const Utf8Str &GetSource() const 219 { 220 return mSource; 221 } 222 223 const Utf8Str &GetFilter() const 224 { 225 return mFilter; 226 } 227 228 protected: 229 Utf8Str mSource; 230 Utf8Str mFilter; 250 231 }; 251 typedef std::vector<S OURCEFILEENTRY> SOURCEVEC, *PSOURCEVEC;232 typedef std::vector<SourceFileEntry> SourceVec; 252 233 253 234 /** … … 1760 1741 uint32_t uUsage = fHostToGuest ? USAGE_GSTCTRL_COPYTO : USAGE_GSTCTRL_COPYFROM; 1761 1742 1762 S OURCEVECvecSources;1743 SourceVec vecSources; 1763 1744 1764 1745 int vrc = VINF_SUCCESS; … … 1791 1772 { 1792 1773 try 1793 { /* Save the source directory. */ 1794 /** @todo r=bird: Why the fudge do you do two 'ing stat() calls on the HOST when copy files from the GUEST? 1795 * Guess it is just some stuff that happened while you were working on SOURCEFILEENTRY, but it doesn't make 1796 * it more sensible. 1797 */ 1798 vecSources.push_back(SOURCEFILEENTRY(ValueUnion.psz)); 1774 { 1775 vecSources.push_back(SourceFileEntry(ValueUnion.psz)); 1799 1776 } 1800 1777 catch (std::bad_alloc &) … … 1811 1788 1812 1789 if (!vecSources.size()) 1813 return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage, "No source (s)specified!");1790 return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage, "No sources specified!"); 1814 1791 1815 1792 if (pszDst == NULL) 1816 1793 return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage, "No destination specified!"); 1794 1795 char szAbsDst[RTPATH_MAX]; 1796 if (!fHostToGuest) 1797 { 1798 vrc = RTPathAbs(pszDst, szAbsDst, sizeof(szAbsDst)); 1799 if (RT_SUCCESS(vrc)) 1800 pszDst = szAbsDst; 1801 else 1802 return RTMsgErrorExitFailure("RTPathAbs failed on '%s': %Rrc", pszDst, vrc); 1803 } 1817 1804 1818 1805 RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx); … … 1831 1818 } 1832 1819 1820 HRESULT rc = S_OK; 1833 1821 ComPtr<IProgress> pProgress; 1834 HRESULT rc = S_OK; 1835 1836 for (unsigned long s = 0; s < vecSources.size(); s++) 1837 { 1838 Utf8Str strSrc = vecSources[s].GetSource(); 1839 Utf8Str strFilter = vecSources[s].GetFilter(); 1822 1823 /** @todo r=bird: This codes does nothing to handle the case where there are 1824 * multiple sources. You need to do serveral thing before thats handled 1825 * correctly. For starters the progress object handling needs to be moved 1826 * inside the loop. Next you need to check what the destination is, because you 1827 * can only copy multiple source files/directories to another directory. You 1828 * actually need to check whether the target exists and is a directory 1829 * regardless of you have 1 or 10 source files/dirs. 1830 * 1831 * Btw. the original approach to error handling here was APPALING. If some file 1832 * couldn't be stat'ed or if it was a file/directory, you only spat out messages 1833 * in verbose mode and never set the status code. 1834 * 1835 * The handling of the wildcard filtering expressions in sources was also just 1836 * skipped. I've corrected this, but you still need to make up your mind wrt 1837 * wildcards or not. 1838 */ 1839 if (vecSources.size() != 1) 1840 return RTMsgErrorExitFailure("Only one source file or directory at the moment."); 1841 for (size_t s = 0; s < vecSources.size(); s++) 1842 { 1843 Utf8Str const &strSrc = vecSources[s].GetSource(); 1844 Utf8Str const &strFilter = vecSources[s].GetFilter(); 1845 1840 1846 RT_NOREF(strFilter); 1841 /* strFilter can be NULL if not set. */ 1842 1843 if (fHostToGuest) 1844 { 1845 if (RTFileExists(strSrc.c_str())) 1847 if (strFilter.isNotEmpty()) 1848 rcExit = RTMsgErrorExitFailure("Skipping '%s/%s' because wildcard expansion isn't implemented yet\n"); 1849 else if (fHostToGuest) 1850 { 1851 /* 1852 * Source is host, destiation guest. 1853 */ 1854 char szAbsSrc[RTPATH_MAX]; 1855 vrc = RTPathAbs(strSrc.c_str(), szAbsSrc, sizeof(szAbsSrc)); 1856 if (RT_SUCCESS(vrc)) 1846 1857 { 1847 if (pCtx->cVerbose) 1848 RTPrintf("File '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1849 1850 SafeArray<FileCopyFlag_T> copyFlags; 1851 rc = pCtx->pGuestSession->FileCopyToGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1852 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1858 RTFSOBJINFO ObjInfo; 1859 vrc = RTPathQueryInfo(szAbsSrc, &ObjInfo, RTFSOBJATTRADD_NOTHING); 1860 if (RT_SUCCESS(vrc)) 1861 { 1862 if (RTFS_IS_FILE(ObjInfo.Attr.fMode)) 1863 { 1864 if (pCtx->cVerbose) 1865 RTPrintf("File '%s' -> '%s'\n", szAbsSrc, pszDst); 1866 1867 SafeArray<FileCopyFlag_T> copyFlags; 1868 rc = pCtx->pGuestSession->FileCopyToGuest(Bstr(szAbsSrc).raw(), Bstr(pszDst).raw(), 1869 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1870 } 1871 else if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 1872 { 1873 if (pCtx->cVerbose) 1874 RTPrintf("Directory '%s' -> '%s'\n", szAbsSrc, pszDst); 1875 1876 SafeArray<DirectoryCopyFlag_T> copyFlags; 1877 copyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting); 1878 rc = pCtx->pGuestSession->DirectoryCopyToGuest(Bstr(szAbsSrc).raw(), Bstr(pszDst).raw(), 1879 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1880 } 1881 else 1882 rcExit = RTMsgErrorExitFailure("Not a file or directory: %s\n", szAbsSrc); 1883 } 1884 else 1885 rcExit = RTMsgErrorExitFailure("RTPathQueryInfo failed on '%s': %Rrc", szAbsSrc, vrc); 1853 1886 } 1854 else if (RTDirExists(strSrc.c_str())) 1855 { 1856 if (pCtx->cVerbose) 1857 RTPrintf("Directory '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1858 1859 SafeArray<DirectoryCopyFlag_T> copyFlags; 1860 copyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting); 1861 rc = pCtx->pGuestSession->DirectoryCopyToGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1862 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1863 } 1864 else if (pCtx->cVerbose) 1865 RTPrintf("Warning: \"%s\" does not exist or is not a file/directory, skipping ...\n", strSrc.c_str()); 1887 else 1888 rcExit = RTMsgErrorExitFailure("RTPathAbs failed on '%s': %Rrc", strSrc.c_str()); 1866 1889 } 1867 1890 else 1868 1891 { 1892 /* 1893 * Source guest, destination host. 1894 */ 1869 1895 /* We need to query the source type on the guest first in order to know which copy flavor we need. */ 1870 1896 ComPtr<IGuestFsObjInfo> pFsObjInfo; 1871 FsObjType_T enmObjType = FsObjType_Unknown; /* Shut up MSC */1872 1897 rc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(strSrc).raw(), TRUE /* fFollowSymlinks */, pFsObjInfo.asOutParam()); 1873 1898 if (SUCCEEDED(rc)) 1874 rc = pFsObjInfo->COMGETTER(Type)(&enmObjType);1875 if (FAILED(rc))1876 1899 { 1877 if (pCtx->cVerbose) 1878 RTPrintf("Warning: Cannot stat for element '%s': No such element\n", strSrc.c_str()); 1879 continue; /* Skip. */ 1900 FsObjType_T enmObjType; 1901 CHECK_ERROR(pFsObjInfo,COMGETTER(Type)(&enmObjType)); 1902 if (SUCCEEDED(rc)) 1903 { 1904 /* Take action according to source file. */ 1905 if (enmObjType == FsObjType_Directory) 1906 { 1907 if (pCtx->cVerbose) 1908 RTPrintf("Directory '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1909 1910 SafeArray<DirectoryCopyFlag_T> aCopyFlags; 1911 aCopyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting); 1912 rc = pCtx->pGuestSession->DirectoryCopyFromGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1913 ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam()); 1914 } 1915 else if (enmObjType == FsObjType_File) 1916 { 1917 if (pCtx->cVerbose) 1918 RTPrintf("File '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1919 1920 SafeArray<FileCopyFlag_T> aCopyFlags; 1921 rc = pCtx->pGuestSession->FileCopyFromGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1922 ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam()); 1923 } 1924 else 1925 rcExit = RTMsgErrorExitFailure("Not a file or directory: %s\n", strSrc.c_str()); 1926 } 1927 else 1928 rcExit = RTEXITCODE_FAILURE; 1880 1929 } 1881 1882 if (enmObjType == FsObjType_Directory) 1883 { 1884 if (pCtx->cVerbose) 1885 RTPrintf("Directory '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1886 1887 SafeArray<DirectoryCopyFlag_T> copyFlags; 1888 copyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting); 1889 rc = pCtx->pGuestSession->DirectoryCopyFromGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1890 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1891 } 1892 else if (enmObjType == FsObjType_File) 1893 { 1894 if (pCtx->cVerbose) 1895 RTPrintf("File '%s' -> '%s'\n", strSrc.c_str(), pszDst); 1896 1897 SafeArray<FileCopyFlag_T> copyFlags; 1898 rc = pCtx->pGuestSession->FileCopyFromGuest(Bstr(strSrc).raw(), Bstr(pszDst).raw(), 1899 ComSafeArrayAsInParam(copyFlags), pProgress.asOutParam()); 1900 } 1901 else if (pCtx->cVerbose) 1902 RTPrintf("Warning: Skipping '%s': Not handled\n", strSrc.c_str()); 1930 else 1931 rcExit = RTMsgErrorExitFailure("FsObjQueryInfo failed on '%s': %Rrc", strSrc.c_str()); 1903 1932 } 1904 1933 } … … 1918 1947 vrc = gctlPrintProgressError(pProgress); 1919 1948 } 1920 1921 return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1949 if (RT_FAILURE(vrc)) 1950 rcExit = RTEXITCODE_FAILURE; 1951 1952 return rcExit; 1922 1953 } 1923 1954 … … 1932 1963 } 1933 1964 1934 static DECLCALLBACK(RTEXITCODE) handleCtrtMkDir(PGCTLCMDCTX pCtx, int argc, char **argv)1965 static DECLCALLBACK(RTEXITCODE) gctrlHandleMkDir(PGCTLCMDCTX pCtx, int argc, char **argv) 1935 1966 { 1936 1967 AssertPtrReturn(pCtx, RTEXITCODE_FAILURE); … … 1948 1979 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 1949 1980 1950 SafeArray<DirectoryCreateFlag_T> dirCreateFlags;1981 SafeArray<DirectoryCreateFlag_T> aDirCreateFlags; 1951 1982 uint32_t fDirMode = 0; /* Default mode. */ 1952 1983 uint32_t cDirsCreated = 0; … … 1965 1996 1966 1997 case 'P': /* Create parents */ 1967 dirCreateFlags.push_back(DirectoryCreateFlag_Parents);1998 aDirCreateFlags.push_back(DirectoryCreateFlag_Parents); 1968 1999 break; 1969 2000 … … 1999 2030 HRESULT rc; 2000 2031 CHECK_ERROR(pCtx->pGuestSession, DirectoryCreate(Bstr(ValueUnion.psz).raw(), 2001 fDirMode, ComSafeArrayAsInParam( dirCreateFlags)));2032 fDirMode, ComSafeArrayAsInParam(aDirCreateFlags))); 2002 2033 if (FAILED(rc)) 2003 2034 rcExit = RTEXITCODE_FAILURE; … … 2061 2092 return rcExit; 2062 2093 if (pCtx->cVerbose) 2063 RTPrintf("Removing %RU32 directorie%s s...\n", argc - GetState.iNext + 1, fRecursive ? "trees" : "");2094 RTPrintf("Removing %RU32 directorie%s(s)...\n", argc - GetState.iNext + 1, fRecursive ? "tree" : ""); 2064 2095 } 2065 2096 if (g_fGuestCtrlCanceled) … … 2223 2254 { 2224 2255 GCTLCMD_COMMON_OPTION_DEFS() 2256 /** @todo Missing --force/-f flag. */ 2225 2257 }; 2226 2258 … … 2304 2336 2305 2337 std::vector< Utf8Str >::iterator it = vecSources.begin(); 2306 while ( (it != vecSources.end())2338 while ( it != vecSources.end() 2307 2339 && !g_fGuestCtrlCanceled) 2308 2340 { … … 2317 2349 { 2318 2350 if (pCtx->cVerbose) 2319 RTPrintf("Warning: Cannot stat for element \"%s\": No such element\n", 2320 strCurSource.c_str()); 2351 RTPrintf("Warning: Cannot stat for element \"%s\": No such file or directory\n", strCurSource.c_str()); 2321 2352 ++it; 2322 2353 continue; /* Skip. */ … … 2339 2370 * the same directory. */ 2340 2371 /** @todo r=bird: You are being kind of windowsy (or just DOSish) about the 'sense' part here, 2341 * while being totaly buggy about the behavior. 'VBox Guestguestcontrol ren dir1 dir2 dstdir' will2372 * while being totaly buggy about the behavior. 'VBoxManage guestcontrol ren dir1 dir2 dstdir' will 2342 2373 * stop after 'dir1' and SILENTLY ignore dir2. If you tried this on Windows, you'd see an error 2343 2374 * being displayed. If you 'man mv' on a nearby unixy system, you'd see that they've made perfect … … 2414 2445 2415 2446 case VINF_GETOPT_NOT_OPTION: 2416 {2417 2447 if (strTemplate.isEmpty()) 2418 2448 strTemplate = ValueUnion.psz; … … 2421 2451 "More than one template specified!\n"); 2422 2452 break; 2423 }2424 2453 2425 2454 default: … … 2462 2491 if (fDirectory) 2463 2492 { 2464 Bstr directory;2493 Bstr bstrDirectory; 2465 2494 CHECK_ERROR(pCtx->pGuestSession, DirectoryCreateTemp(Bstr(strTemplate).raw(), 2466 2495 fMode, Bstr(strTempDir).raw(), 2467 2496 fSecure, 2468 directory.asOutParam()));2497 bstrDirectory.asOutParam())); 2469 2498 if (SUCCEEDED(rc)) 2470 RTPrintf("Directory name: %ls\n", directory.raw());2499 RTPrintf("Directory name: %ls\n", bstrDirectory.raw()); 2471 2500 } 2472 2501 else … … 2499 2528 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 2500 2529 2501 DESTDIRMAP mapObjs; 2502 2503 while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0) 2530 while ( (ch = RTGetOpt(&GetState, &ValueUnion)) != 0 2531 && ch != VINF_GETOPT_NOT_OPTION) 2504 2532 { 2505 2533 /* For options that require an argument, ValueUnion has received the value. */ … … 2515 2543 "Command \"%s\" not implemented yet!", ValueUnion.psz); 2516 2544 2517 case VINF_GETOPT_NOT_OPTION:2518 mapObjs[ValueUnion.psz]; /* Add element to check to map. */2519 break;2520 2521 2545 default: 2522 2546 return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT, ch, &ValueUnion); … … 2524 2548 } 2525 2549 2526 size_t cObjs = mapObjs.size(); 2527 if (!cObjs) 2528 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT, 2529 "No element(s) to check specified!"); 2550 if (ch != VINF_GETOPT_NOT_OPTION) 2551 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_STAT, "Nothing to stat!"); 2530 2552 2531 2553 RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx); … … 2533 2555 return rcExit; 2534 2556 2535 HRESULT rc;2536 2557 2537 2558 /* 2538 * Do ing the checks.2559 * Do the file stat'ing. 2539 2560 */ 2540 DESTDIRMAPITER it = mapObjs.begin(); 2541 while (it != mapObjs.end()) 2561 while (ch == VINF_GETOPT_NOT_OPTION) 2542 2562 { 2543 2563 if (pCtx->cVerbose) 2544 RTPrintf("Checking for element \"%s\" ...\n", it->first.c_str());2564 RTPrintf("Checking for element \"%s\" ...\n", ValueUnion.psz); 2545 2565 2546 2566 ComPtr<IGuestFsObjInfo> pFsObjInfo; 2547 rc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(it->first).raw(), FALSE /*followSymlinks*/, pFsObjInfo.asOutParam()); 2548 if (FAILED(rc)) 2567 HRESULT hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(ValueUnion.psz).raw(), FALSE /*followSymlinks*/, 2568 pFsObjInfo.asOutParam()); 2569 if (FAILED(hrc)) 2549 2570 { 2550 2571 /* If there's at least one element which does not exist on the guest, 2551 2572 * drop out with exitcode 1. */ 2552 2573 if (pCtx->cVerbose) 2553 RTPrintf("Cannot stat for element \"%s\": No such element\n", 2554 it->first.c_str()); 2574 RTPrintf("Cannot stat for element \"%s\": No such element\n", ValueUnion.psz); 2555 2575 rcExit = RTEXITCODE_FAILURE; 2556 2576 } … … 2562 2582 { 2563 2583 case FsObjType_File: 2564 RTPrintf("Element \"%s\" found: Is a file\n", it->first.c_str());2584 RTPrintf("Element \"%s\" found: Is a file\n", ValueUnion.psz); 2565 2585 break; 2566 2586 2567 2587 case FsObjType_Directory: 2568 RTPrintf("Element \"%s\" found: Is a directory\n", it->first.c_str());2588 RTPrintf("Element \"%s\" found: Is a directory\n", ValueUnion.psz); 2569 2589 break; 2570 2590 2571 2591 case FsObjType_Symlink: 2572 RTPrintf("Element \"%s\" found: Is a symlink\n", it->first.c_str());2592 RTPrintf("Element \"%s\" found: Is a symlink\n", ValueUnion.psz); 2573 2593 break; 2574 2594 2575 2595 default: 2576 RTPrintf("Element \"%s\" found, type unknown (%ld)\n", it->first.c_str(), objType);2596 RTPrintf("Element \"%s\" found, type unknown (%ld)\n", ValueUnion.psz, objType); 2577 2597 break; 2578 2598 } … … 2581 2601 } 2582 2602 2583 ++it; 2603 /* Next file. */ 2604 ch = RTGetOpt(&GetState, &ValueUnion); 2584 2605 } 2585 2606 … … 2686 2707 ComPtr<IProgress> pProgress; 2687 2708 CHECK_ERROR(pCtx->pGuest, UpdateGuestAdditions(Bstr(strSource).raw(), 2688 ComSafeArrayAsInParam(aArgs),2689 /* Wait for whole update process to complete. */2690 ComSafeArrayAsInParam(aUpdateFlags),2691 pProgress.asOutParam()));2709 ComSafeArrayAsInParam(aArgs), 2710 /* Wait for whole update process to complete. */ 2711 ComSafeArrayAsInParam(aUpdateFlags), 2712 pProgress.asOutParam())); 2692 2713 if (FAILED(rc)) 2693 2714 vrc = gctlPrintError(pCtx->pGuest, COM_IIDOF(IGuest)); … … 2876 2897 } 2877 2898 2878 if (FAILED(rc)) 2899 if (FAILED(rc)) /** @todo yeah, right... Only the last error? */ 2879 2900 rcExit = RTEXITCODE_FAILURE; 2880 2901 … … 2899 2920 2900 2921 std::vector < uint32_t > vecPID; 2901 ULONG ulSessionID= UINT32_MAX;2922 ULONG idSession = UINT32_MAX; 2902 2923 Utf8Str strSessionName; 2903 2924 … … 2914 2935 2915 2936 case 'i': /* Session ID */ 2916 ulSessionID= ValueUnion.u32;2937 idSession = ValueUnion.u32; 2917 2938 break; 2918 2939 … … 2942 2963 } 2943 2964 else 2944 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSEPROCESS, 2945 "Error parsing PID value: %Rrc", rc); 2965 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSEPROCESS, "Error parsing PID value: %Rrc", rc); 2946 2966 break; 2947 2967 } … … 2957 2977 2958 2978 if ( strSessionName.isEmpty() 2959 && ulSessionID== UINT32_MAX)2979 && idSession == UINT32_MAX) 2960 2980 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSEPROCESS, "No session ID specified!"); 2961 2981 2962 2982 if ( strSessionName.isNotEmpty() 2963 && ulSessionID!= UINT32_MAX)2983 && idSession != UINT32_MAX) 2964 2984 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSEPROCESS, 2965 2985 "Either session ID or name (pattern) must be specified"); … … 2976 2996 { 2977 2997 uint32_t uProcsTerminated = 0; 2978 bool fSessionFound = false;2979 2998 2980 2999 SafeIfaceArray <IGuestSession> collSessions; … … 2982 3001 size_t cSessions = collSessions.size(); 2983 3002 2984 uint32_t uSessionsHandled = 0;3003 uint32_t cSessionsHandled = 0; 2985 3004 for (size_t i = 0; i < cSessions; i++) 2986 3005 { … … 2993 3012 CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); 2994 3013 Utf8Str strNameUtf8(strName); /* Session name */ 3014 3015 bool fSessionFound; 2995 3016 if (strSessionName.isEmpty()) /* Search by ID. Slow lookup. */ 2996 { 2997 fSessionFound = uID == ulSessionID; 2998 } 3017 fSessionFound = uID == idSession; 2999 3018 else /* ... or by naming pattern. */ 3000 { 3001 if (RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str())) 3002 fSessionFound = true; 3003 } 3004 3019 fSessionFound = RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str()); 3005 3020 if (fSessionFound) 3006 3021 { 3007 3022 AssertStmt(!pSession.isNull(), break); 3008 uSessionsHandled++;3023 cSessionsHandled++; 3009 3024 3010 3025 SafeIfaceArray <IGuestProcess> collProcs; … … 3038 3053 else 3039 3054 { 3040 if ( ulSessionID!= UINT32_MAX)3055 if (idSession != UINT32_MAX) 3041 3056 RTPrintf("No matching process(es) for session ID %RU32 found\n", 3042 ulSessionID);3057 idSession); 3043 3058 } 3044 3059 … … 3050 3065 } 3051 3066 3052 if (! uSessionsHandled)3067 if (!cSessionsHandled) 3053 3068 RTPrintf("No matching session(s) found\n"); 3054 3069 … … 3087 3102 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 3088 3103 3089 ULONG ulSessionID= UINT32_MAX;3104 ULONG idSession = UINT32_MAX; 3090 3105 Utf8Str strSessionName; 3091 3106 … … 3102 3117 3103 3118 case 'i': /* Session ID */ 3104 ulSessionID= ValueUnion.u32;3119 idSession = ValueUnion.u32; 3105 3120 break; 3106 3121 … … 3118 3133 3119 3134 if ( strSessionName.isEmpty() 3120 && ulSessionID== UINT32_MAX)3135 && idSession == UINT32_MAX) 3121 3136 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSESESSION, 3122 3137 "No session ID specified!"); 3123 3138 3124 3139 if ( !strSessionName.isEmpty() 3125 && ulSessionID!= UINT32_MAX)3140 && idSession != UINT32_MAX) 3126 3141 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_CLOSESESSION, 3127 3142 "Either session ID or name (pattern) must be specified"); … … 3135 3150 do 3136 3151 { 3137 bool fSessionFound = false;3138 3152 size_t cSessionsHandled = 0; 3139 3153 … … 3153 3167 Utf8Str strNameUtf8(strName); /* Session name */ 3154 3168 3169 bool fSessionFound; 3155 3170 if (strSessionName.isEmpty()) /* Search by ID. Slow lookup. */ 3156 { 3157 fSessionFound = uID == ulSessionID; 3158 } 3171 fSessionFound = uID == idSession; 3159 3172 else /* ... or by naming pattern. */ 3160 { 3161 if (RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str())) 3162 fSessionFound = true; 3163 } 3164 3173 fSessionFound = RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str()); 3165 3174 if (fSessionFound) 3166 3175 { … … 3255 3264 RTPrintf("Waiting for events ...\n"); 3256 3265 3266 /** @todo r=bird: This are-we-there-yet approach to things could easily be 3267 * replaced by a global event semaphore that gets signalled from the 3268 * signal handler and the callback event. Please fix! */ 3257 3269 while (!g_fGuestCtrlCanceled) 3258 3270 { … … 3307 3319 { "copyto", gctlHandleCopyTo, USAGE_GSTCTRL_COPYTO, 0, }, 3308 3320 3309 { "mkdir", handleCtrtMkDir,USAGE_GSTCTRL_MKDIR, 0, },3310 { "md", handleCtrtMkDir,USAGE_GSTCTRL_MKDIR, 0, },3311 { "createdirectory", handleCtrtMkDir,USAGE_GSTCTRL_MKDIR, 0, },3312 { "createdir", handleCtrtMkDir,USAGE_GSTCTRL_MKDIR, 0, },3321 { "mkdir", gctrlHandleMkDir, USAGE_GSTCTRL_MKDIR, 0, }, 3322 { "md", gctrlHandleMkDir, USAGE_GSTCTRL_MKDIR, 0, }, 3323 { "createdirectory", gctrlHandleMkDir, USAGE_GSTCTRL_MKDIR, 0, }, 3324 { "createdir", gctrlHandleMkDir, USAGE_GSTCTRL_MKDIR, 0, }, 3313 3325 3314 3326 { "rmdir", gctlHandleRmDir, USAGE_GSTCTRL_RMDIR, 0, },
Note:
See TracChangeset
for help on using the changeset viewer.