Changeset 75848 in vbox
- Timestamp:
- Nov 30, 2018 12:23:17 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127051
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r75847 r75848 186 186 } GCTLCMDCTX, *PGCTLCMDCTX; 187 187 188 /**189 * An entry for a source element, including an optional DOS-like wildcard (*,?).190 */191 class SourceFileEntry192 {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 ( !pszFilename206 || !strpbrk(pszFilename, "*?"))207 mSource.assign(pszSource);208 else209 {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() const219 {220 return mSource;221 }222 223 const Utf8Str &GetFilter() const224 {225 return mFilter;226 }227 228 protected:229 Utf8Str mSource;230 Utf8Str mFilter;231 };232 typedef std::vector<SourceFileEntry> SourceVec;233 188 234 189 /** … … 1736 1691 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 1737 1692 1693 bool fDstMustBeDir = false; 1738 1694 const char *pszDst = NULL; 1739 1695 bool fFollow = false; … … 1741 1697 uint32_t uUsage = fHostToGuest ? USAGE_GSTCTRL_COPYTO : USAGE_GSTCTRL_COPYFROM; 1742 1698 1743 SourceVec vecSources;1744 1745 1699 int vrc = VINF_SUCCESS; 1746 while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0) 1700 while ( (ch = RTGetOpt(&GetState, &ValueUnion)) != 0 1701 && ch != VINF_GETOPT_NOT_OPTION) 1747 1702 { 1748 1703 /* For options that require an argument, ValueUnion has received the value. */ … … 1761 1716 case GETOPTDEF_COPY_TARGETDIR: 1762 1717 pszDst = ValueUnion.psz; 1763 break; 1764 1765 case VINF_GETOPT_NOT_OPTION: 1766 /* Last argument and no destination specified with --target-directory yet? 1767 Then use the current (= last) argument as destination. */ 1768 if ( GetState.argc == GetState.iNext 1769 && pszDst == NULL) 1770 pszDst = ValueUnion.psz; 1771 else 1772 { 1773 try 1774 { 1775 vecSources.push_back(SourceFileEntry(ValueUnion.psz)); 1776 } 1777 catch (std::bad_alloc &) 1778 { 1779 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Out of memory"); 1780 } 1781 } 1718 fDstMustBeDir = true; 1782 1719 break; 1783 1720 … … 1787 1724 } 1788 1725 1789 if (!vecSources.size()) 1726 char **papszSources = RTGetOptNonOptionArrayPtr(&GetState); 1727 size_t cSources = &argv[argc] - papszSources; 1728 1729 if (!cSources) 1790 1730 return errorSyntaxEx(USAGE_GUESTCONTROL, uUsage, "No sources specified!"); 1731 1732 /* Unless a --target-directory is given, the last argument is the destination, so 1733 bump it from the source list. */ 1734 if (pszDst == NULL && cSources >= 2) 1735 pszDst = papszSources[--cSources]; 1791 1736 1792 1737 if (pszDst == NULL) … … 1820 1765 HRESULT rc = S_OK; 1821 1766 ComPtr<IProgress> pProgress; 1822 1823 1767 /** @todo r=bird: This codes does nothing to handle the case where there are 1824 1768 * multiple sources. You need to do serveral thing before thats handled … … 1835 1779 * The handling of the wildcard filtering expressions in sources was also just 1836 1780 * skipped. I've corrected this, but you still need to make up your mind wrt 1837 * wildcards or not. 1781 * wildcards or not. 1782 * 1783 * Update: I've kicked out the whole SourceFileEntry/vecSources stuff as we can 1784 * use argv directly without any unnecessary copying. You just have to 1785 * look for the wildcards inside this loop instead. 1838 1786 */ 1839 if (vecSources.size() != 1) 1787 NOREF(fDstMustBeDir); 1788 if (cSources != 1) 1840 1789 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 1846 RT_NOREF(strFilter);1847 if (strFilter.isNotEmpty())1848 rcExit = RTMsgErrorExitFailure("Skipping '%s/%s' because wildcard expansion isn't implemented yet\n",1849 strSrc.c_str(), strFilter.c_str());1790 for (size_t iSrc = 0; iSrc < cSources; iSrc++) 1791 { 1792 const char *pszSource = papszSources[iSrc]; 1793 1794 /* Check if the source contains any wilecards in the last component, if so we 1795 don't know how to deal with it yet and refuse. */ 1796 const char *pszSrcFinalComp = RTPathFilename(pszSource); 1797 if (pszSrcFinalComp && strpbrk(pszSrcFinalComp, "*?")) 1798 rcExit = RTMsgErrorExitFailure("Skipping '%s' because wildcard expansion isn't implemented yet\n", pszSource); 1850 1799 else if (fHostToGuest) 1851 1800 { … … 1854 1803 */ 1855 1804 char szAbsSrc[RTPATH_MAX]; 1856 vrc = RTPathAbs( strSrc.c_str(), szAbsSrc, sizeof(szAbsSrc));1805 vrc = RTPathAbs(pszSource, szAbsSrc, sizeof(szAbsSrc)); 1857 1806 if (RT_SUCCESS(vrc)) 1858 1807 { … … 1887 1836 } 1888 1837 else 1889 rcExit = RTMsgErrorExitFailure("RTPathAbs failed on '%s': %Rrc", strSrc.c_str());1838 rcExit = RTMsgErrorExitFailure("RTPathAbs failed on '%s': %Rrc", pszSource); 1890 1839 } 1891 1840 else … … 1896 1845 /* We need to query the source type on the guest first in order to know which copy flavor we need. */ 1897 1846 ComPtr<IGuestFsObjInfo> pFsObjInfo; 1898 rc = pCtx->pGuestSession->FsObjQueryInfo(Bstr( strSrc).raw(), TRUE /* fFollowSymlinks */, pFsObjInfo.asOutParam());1847 rc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(pszSource).raw(), TRUE /* fFollowSymlinks */, pFsObjInfo.asOutParam()); 1899 1848 if (SUCCEEDED(rc)) 1900 1849 { … … 1907 1856 { 1908 1857 if (pCtx->cVerbose) 1909 RTPrintf("Directory '%s' -> '%s'\n", strSrc.c_str(), pszDst);1858 RTPrintf("Directory '%s' -> '%s'\n", pszSource, pszDst); 1910 1859 1911 1860 SafeArray<DirectoryCopyFlag_T> aCopyFlags; 1912 1861 aCopyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting); 1913 rc = pCtx->pGuestSession->DirectoryCopyFromGuest(Bstr( strSrc).raw(), Bstr(pszDst).raw(),1862 rc = pCtx->pGuestSession->DirectoryCopyFromGuest(Bstr(pszSource).raw(), Bstr(pszDst).raw(), 1914 1863 ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam()); 1915 1864 } … … 1917 1866 { 1918 1867 if (pCtx->cVerbose) 1919 RTPrintf("File '%s' -> '%s'\n", strSrc.c_str(), pszDst);1868 RTPrintf("File '%s' -> '%s'\n", pszSource, pszDst); 1920 1869 1921 1870 SafeArray<FileCopyFlag_T> aCopyFlags; 1922 rc = pCtx->pGuestSession->FileCopyFromGuest(Bstr( strSrc).raw(), Bstr(pszDst).raw(),1871 rc = pCtx->pGuestSession->FileCopyFromGuest(Bstr(pszSource).raw(), Bstr(pszDst).raw(), 1923 1872 ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam()); 1924 1873 } 1925 1874 else 1926 rcExit = RTMsgErrorExitFailure("Not a file or directory: %s\n", strSrc.c_str());1875 rcExit = RTMsgErrorExitFailure("Not a file or directory: %s\n", pszSource); 1927 1876 } 1928 1877 else … … 1930 1879 } 1931 1880 else 1932 rcExit = RTMsgErrorExitFailure("FsObjQueryInfo failed on '%s': %R rc", strSrc.c_str());1881 rcExit = RTMsgErrorExitFailure("FsObjQueryInfo failed on '%s': %Rhrc", pszSource, rc); 1933 1882 } 1934 1883 }
Note:
See TracChangeset
for help on using the changeset viewer.