Changeset 67867 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jul 8, 2017 6:22:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp
r67864 r67867 38 38 #include <iprt/ctype.h> 39 39 #include <iprt/file.h> 40 #include <iprt/fsvfs.h> 40 41 #include <iprt/err.h> 41 42 #include <iprt/getopt.h> … … 57 58 #define RTFSISOMAKERCMD_MAX_NAMES 8 58 59 60 /** Maximum directory recursions when adding a directory tree. */ 61 #define RTFSISOMAKERCMD_MAX_DIR_RECURSIONS 32 62 59 63 /** @name Name specifiers 60 64 * @{ */ … … 98 102 RTFSISOMAKERCMD_OPT_NO_JOLIET, 99 103 RTFSISOMAKERCMD_OPT_IMPORT_ISO, 104 RTFSISOMAKERCMD_OPT_PUSH_ISO, 105 RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_JOLIET, 106 RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK, 107 RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK_NO_JOLIET, 108 RTFSISOMAKERCMD_OPT_POP, 100 109 101 110 RTFSISOMAKERCMD_OPT_ELTORITO_NEW_ENTRY, … … 318 327 uint32_t cbRandomOrderVerifciationBlock; 319 328 329 /** The current source VFS, NIL_RTVFS if regular file system is used. */ 330 RTVFS hSrcVfs; 331 /** The specifier for hSrcVfs (error messages). */ 332 const char *pszSrcVfs; 333 /** The option for hSrcVfs. */ 334 const char *pszSrcVfsOption; 335 320 336 /** @name Processing of inputs 321 337 * @{ */ … … 398 414 399 415 400 401 416 /********************************************************************************************************************************* 402 417 * Global Variables * … … 423 438 { "--no-joliet", RTFSISOMAKERCMD_OPT_NO_JOLIET, RTGETOPT_REQ_NOTHING }, 424 439 { "--import-iso", RTFSISOMAKERCMD_OPT_IMPORT_ISO, RTGETOPT_REQ_STRING }, 440 { "--push-iso", RTFSISOMAKERCMD_OPT_PUSH_ISO, RTGETOPT_REQ_STRING }, 441 { "--push-iso-no-joliet", RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_JOLIET, RTGETOPT_REQ_STRING }, 442 { "--push-iso-no-rock", RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK, RTGETOPT_REQ_STRING }, 443 { "--push-iso-no-rock-no-joliet", RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK_NO_JOLIET, RTGETOPT_REQ_STRING }, 444 { "--pop", RTFSISOMAKERCMD_OPT_POP, RTGETOPT_REQ_NOTHING }, 445 425 446 426 447 { "--eltorito-new-entry", RTFSISOMAKERCMD_OPT_ELTORITO_NEW_ENTRY, RTGETOPT_REQ_NOTHING }, … … 726 747 RTFsIsoMakerRelease(pOpts->hIsoMaker); 727 748 pOpts->hIsoMaker = NIL_RTFSISOMAKER; 749 } 750 751 if (pOpts->hSrcVfs != NIL_RTVFS) 752 { 753 RTVfsRelease(pOpts->hSrcVfs); 754 pOpts->hSrcVfs = NIL_RTVFS; 728 755 } 729 756 … … 1499 1526 1500 1527 /** 1528 * Enteres an object into the namespaces given the parent and single name. 1529 * 1530 * This is used by the directory tree recursion code. 1531 * 1532 * @returns IPRT status code. 1533 * @param pOpts The ISO maker command instance. 1534 * @param idxObj The configuration index of the object to be named. 1535 * @param idxParentObj The configuration index of the parent directory. 1536 * @param pszName The name of the object. 1537 * @param pParsed The parsed names - only fNameSpecifies used, no 1538 * names. 1539 * @param pszSrc The full source path for error reporting. 1540 */ 1541 static int rtFsIsoMakerCmdSetNameAndParent(PRTFSISOMAKERCMDOPTS pOpts, uint32_t idxObj, uint32_t idxParentObj, 1542 const char *pszName, PCRTFSISOMKCMDPARSEDNAMES pParsed, const char *pszSrc) 1543 { 1544 int rc = VINF_SUCCESS; 1545 for (uint32_t i = 0; i < pParsed->cNames; i++) 1546 if (pParsed->aNames[i].cchPath > 0) 1547 { 1548 if (pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK) 1549 { 1550 rc = RTFsIsoMakerObjSetNameAndParent(pOpts->hIsoMaker, idxObj, idxParentObj, 1551 pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK, 1552 pszName); 1553 if (RT_FAILURE(rc)) 1554 { 1555 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error setting parent & name '%s' on '%s': %Rrc", 1556 pszName, pszSrc, rc); 1557 break; 1558 } 1559 } 1560 if (pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MINOR_MASK) 1561 { 1562 /** @todo add APIs for this. */ 1563 } 1564 } 1565 return rc; 1566 } 1567 1568 1569 /** 1501 1570 * Adds a file. 1502 1571 * … … 1511 1580 uint32_t *pidxObj) 1512 1581 { 1513 uint32_t idxObj; 1514 int rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(pOpts->hIsoMaker, pszSrc, &idxObj); 1582 int rc; 1583 uint32_t idxObj = UINT32_MAX; 1584 if ( pOpts->hSrcVfs == NIL_RTVFS 1585 || RTVfsChainIsSpec(pszSrc)) 1586 { 1587 rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(pOpts->hIsoMaker, pszSrc, &idxObj); 1588 if (RT_FAILURE(rc)) 1589 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s': %Rrc", pszSrc, rc); 1590 } 1591 else 1592 { 1593 RTVFSFILE hVfsFileSrc; 1594 rc = RTVfsFileOpen(pOpts->hSrcVfs, pszSrc, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSrc); 1595 if (RT_FAILURE(rc)) 1596 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening '%s' (inside '%s'): %Rrc", pszSrc, pOpts->pszSrcVfs, rc); 1597 1598 rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(pOpts->hIsoMaker, hVfsFileSrc, &idxObj); 1599 RTVfsFileRelease(hVfsFileSrc); 1600 if (RT_FAILURE(rc)) 1601 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s' (VFS): %Rrc", pszSrc, rc); 1602 } 1603 1604 pOpts->cItemsAdded++; 1605 if (pidxObj) 1606 *pidxObj = idxObj; 1607 1608 return rtFsIsoMakerCmdSetObjPaths(pOpts, idxObj, pParsed, pszSrc); 1609 } 1610 1611 static bool rtFsIsoMakerCmdIsFilteredOut(PRTFSISOMAKERCMDOPTS pOpts, const char *pszDir, const char *pszName, bool fIsDir) 1612 { 1613 RT_NOREF(pOpts, pszDir, pszName, fIsDir); 1614 return false; 1615 } 1616 1617 /** 1618 * Adds a directory, from a VFS chain or real file system. 1619 * 1620 * @returns IPRT status code. 1621 * @param pOpts The ISO maker command instance. 1622 * @param pszSrc The path to the source directory. 1623 * @param pParsed The parsed names. 1624 */ 1625 static int rtFsIsoMakerCmdAddDir(PRTFSISOMAKERCMDOPTS pOpts, const char *pszSrc, PCRTFSISOMKCMDPARSEDNAMES pParsed) 1626 { 1627 RT_NOREF(pParsed); 1628 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding directory '%s' failed: not implemented", pszSrc); 1629 } 1630 1631 1632 /** 1633 * Worker for rtFsIsoMakerCmdAddVfsDir that does the recursion. 1634 * 1635 * @returns IPRT status code. 1636 * @param pOpts The ISO maker command instance. 1637 * @param hVfsDir The directory to process. 1638 * @param idxDirObj The configuration index of the directory. 1639 * @param pszSrc Pointer to the source path buffer. RTPATH_MAX 1640 * in size. Okay to modify beyond @a cchSrc. 1641 * @param cchSrc Length of the path corresponding to @a hVfsDir. 1642 * @param fNamespaces Which ISO maker namespaces to add the names to. 1643 * @param cDepth Number of recursions. Used to deal with loopy 1644 * directories. 1645 */ 1646 static int rtFsIsoMakerCmdAddVfsDirRecursive(PRTFSISOMAKERCMDOPTS pOpts, RTVFSDIR hVfsDir, uint32_t idxDirObj, 1647 char *pszSrc, size_t cchSrc, uint32_t fNamespaces, uint8_t cDepth) 1648 { 1649 /* 1650 * Check that we're not in too deep. 1651 */ 1652 if (cDepth >= RTFSISOMAKERCMD_MAX_DIR_RECURSIONS) 1653 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_ISOMK_IMPORT_TOO_DEEP_DIR_TREE, 1654 "Recursive (VFS) dir add too deep (depth=%u): %.*s", cDepth, cchSrc, pszSrc); 1655 /* 1656 * Enumerate the directory. 1657 */ 1658 int rc; 1659 size_t cbDirEntryAlloced = sizeof(RTDIRENTRYEX); 1660 PRTDIRENTRYEX pDirEntry = (PRTDIRENTRYEX)RTMemTmpAlloc(cbDirEntryAlloced); 1661 if (pDirEntry) 1662 { 1663 for (;;) 1664 { 1665 /* 1666 * Read the next entry. 1667 */ 1668 size_t cbDirEntry = cbDirEntryAlloced; 1669 rc = RTVfsDirReadEx(hVfsDir, pDirEntry, &cbDirEntry, RTFSOBJATTRADD_UNIX); 1670 if (RT_FAILURE(rc)) 1671 { 1672 if (rc == VERR_NO_MORE_FILES) 1673 rc = VINF_SUCCESS; 1674 else if (rc == VERR_BUFFER_OVERFLOW) 1675 { 1676 RTMemTmpFree(pDirEntry); 1677 cbDirEntryAlloced = RT_ALIGN_Z(RT_MIN(cbDirEntry, cbDirEntryAlloced) + 64, 64); 1678 pDirEntry = (PRTDIRENTRYEX)RTMemTmpAlloc(cbDirEntryAlloced); 1679 if (pDirEntry) 1680 continue; 1681 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "Out of memory (direntry buffer)"); 1682 } 1683 else 1684 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsDirReadEx failed on %.*s: %Rrc", cchSrc, pszSrc, rc); 1685 break; 1686 } 1687 1688 /* Ignore '.' and '..' entries. */ 1689 if (RTDirEntryExIsStdDotLink(pDirEntry)) 1690 continue; 1691 1692 /* 1693 * Process the entry. 1694 */ 1695 1696 /* Update the name. */ 1697 if (cchSrc + 1 + pDirEntry->cbName < RTPATH_MAX) 1698 { 1699 pszSrc[cchSrc] = '/'; /* VFS only groks unix slashes */ 1700 memcpy(&pszSrc[cchSrc + 1], pDirEntry->szName, pDirEntry->cbName); 1701 pszSrc[cchSrc + 1 + pDirEntry->cbName] = '\0'; 1702 } 1703 else 1704 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_FILENAME_TOO_LONG, "Filename is too long (depth %u): '%.*s/%s'", 1705 cDepth, cchSrc, pszSrc, pDirEntry->szName); 1706 1707 /* Okay? Check name filtering. */ 1708 if ( RT_SUCCESS(rc) 1709 && !rtFsIsoMakerCmdIsFilteredOut(pOpts, pszSrc, pDirEntry->szName, RTFS_IS_DIRECTORY(pDirEntry->Info.Attr.fMode))) 1710 { 1711 /* Do type specific adding. */ 1712 uint32_t idxObj = UINT32_MAX; 1713 if (RTFS_IS_FILE(pDirEntry->Info.Attr.fMode)) 1714 { 1715 /* 1716 * Files are added with VFS file sources. 1717 * The ASSUMPTION is that we're working with a virtual file system 1718 * here and won't be wasting native file descriptors. 1719 */ 1720 RTVFSFILE hVfsFileSrc; 1721 rc = RTVfsDirOpenFile(hVfsDir, pDirEntry->szName, 1722 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSrc); 1723 if (RT_SUCCESS(rc)) 1724 { 1725 rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(pOpts->hIsoMaker, hVfsFileSrc, &idxObj); 1726 RTVfsFileRelease(hVfsFileSrc); 1727 if (RT_SUCCESS(rc)) 1728 { 1729 pOpts->cItemsAdded++; 1730 rc = RTFsIsoMakerObjSetNameAndParent(pOpts->hIsoMaker, idxObj, idxDirObj, fNamespaces, 1731 pDirEntry->szName); 1732 if (RT_FAILURE(rc)) 1733 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error setting parent & name on file '%s' to '%s': %Rrc", 1734 pszSrc, pDirEntry->szName, rc); 1735 } 1736 else 1737 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding file '%s' (VFS recursive): %Rrc", pszSrc, rc); 1738 } 1739 else 1740 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening file '%s' (VFS recursive): %Rrc", pszSrc, rc); 1741 } 1742 else if (RTFS_IS_DIRECTORY(pDirEntry->Info.Attr.fMode)) 1743 { 1744 /* 1745 * Open and add the sub-directory. 1746 */ 1747 RTVFSDIR hVfsSubDirSrc; 1748 rc = RTVfsDirOpenDir(hVfsDir, pDirEntry->szName, 0 /*fFlags*/, &hVfsSubDirSrc); 1749 if (RT_SUCCESS(rc)) 1750 { 1751 rc = RTFsIsoMakerAddUnnamedDir(pOpts->hIsoMaker, &pDirEntry->Info, &idxObj); 1752 if (RT_SUCCESS(rc)) 1753 { 1754 pOpts->cItemsAdded++; 1755 rc = RTFsIsoMakerObjSetNameAndParent(pOpts->hIsoMaker, idxObj, idxDirObj, fNamespaces, 1756 pDirEntry->szName); 1757 if (RT_SUCCESS(rc)) 1758 /* Recurse into the sub-directory. */ 1759 rc = rtFsIsoMakerCmdAddVfsDirRecursive(pOpts, hVfsSubDirSrc, idxObj, pszSrc, 1760 cchSrc + 1 + pDirEntry->cbName, fNamespaces, cDepth + 1); 1761 else 1762 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, 1763 "Error setting parent & name on directory '%s' to '%s': %Rrc", 1764 pszSrc, pDirEntry->szName, rc); 1765 } 1766 else 1767 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding directory '%s' (VFS recursive): %Rrc", pszSrc, rc); 1768 RTVfsDirRelease(hVfsSubDirSrc); 1769 } 1770 else 1771 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening directory '%s' (VFS recursive): %Rrc", pszSrc, rc); 1772 } 1773 else if (RTFS_IS_SYMLINK(pDirEntry->Info.Attr.fMode)) 1774 { 1775 /* 1776 * TODO: ISO FS symlink support. 1777 */ 1778 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, 1779 "Adding symlink '%s' failed: not yet implemented", pszSrc); 1780 } 1781 else 1782 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, 1783 "Adding special file '%s' failed: not implemented", pszSrc); 1784 } 1785 if (RT_FAILURE(rc)) 1786 break; 1787 } 1788 1789 RTMemTmpFree(pDirEntry); 1790 } 1791 else 1792 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "Out of memory! (direntry buffer)"); 1793 return rc; 1794 } 1795 1796 1797 /** 1798 * Adds a directory, from the source VFS. 1799 * 1800 * @returns IPRT status code. 1801 * @param pOpts The ISO maker command instance. 1802 * @param pParsed The parsed names. 1803 * @param pidxObj Where to return the configuration index for the 1804 * added file. Optional. 1805 */ 1806 static int rtFsIsoMakerCmdAddVfsDir(PRTFSISOMAKERCMDOPTS pOpts, PCRTFSISOMKCMDPARSEDNAMES pParsed, PCRTFSOBJINFO pObjInfo) 1807 { 1808 Assert(pParsed->cNames < pParsed->cNamesWithSrc); 1809 1810 /* 1811 * Open the directory. 1812 */ 1813 char *pszDir = pParsed->aNames[pParsed->cNamesWithSrc - 1].szPath; 1814 RTPathChangeToUnixSlashes(pszDir, true /*fForce*/); /* VFS currently only understand unix slashes. */ 1815 RTVFSDIR hVfsDirSrc; 1816 int rc = RTVfsDirOpen(pOpts->hSrcVfs, pszDir, 0 /*fFlags*/, &hVfsDirSrc); 1817 if (RT_FAILURE(rc)) 1818 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening directory '%s' (inside '%s'): %Rrc", 1819 pszDir, pOpts->pszSrcVfs, rc); 1820 1821 /* 1822 * Add the directory if it doesn't exist. 1823 */ 1824 uint32_t idxObj = UINT32_MAX; 1825 for (uint32_t i = 0; i < pParsed->cNames; i++) 1826 if (pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK) 1827 { 1828 idxObj = RTFsIsoMakerGetObjIdxForPath(pOpts->hIsoMaker, 1829 pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK, 1830 pParsed->aNames[i].szPath); 1831 if (idxObj != UINT32_MAX) 1832 { 1833 /** @todo make sure the directory is present in the other namespace. */ 1834 break; 1835 } 1836 } 1837 if (idxObj == UINT32_MAX) 1838 { 1839 rc = RTFsIsoMakerAddUnnamedDir(pOpts->hIsoMaker, pObjInfo, &idxObj); 1840 if (RT_SUCCESS(rc)) 1841 rc = rtFsIsoMakerCmdSetObjPaths(pOpts, idxObj, pParsed, pParsed->aNames[pParsed->cNames - 1].szPath); 1842 else 1843 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTFsIsoMakerAddUnnamedDir failed: %Rrc", rc); 1844 } 1515 1845 if (RT_SUCCESS(rc)) 1516 1846 { 1517 pOpts->cItemsAdded++; 1518 if (pidxObj) 1519 *pidxObj = idxObj; 1520 1521 rc = rtFsIsoMakerCmdSetObjPaths(pOpts, idxObj, pParsed, pszSrc); 1522 } 1523 else 1524 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s': %Rrc", pszSrc, rc); 1847 /* 1848 * Add the directory content. 1849 */ 1850 uint32_t fNamespaces = 0; 1851 for (uint32_t i = 0; i < pParsed->cNames; i++) 1852 fNamespaces |= pParsed->aNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK; 1853 rc = rtFsIsoMakerCmdAddVfsDirRecursive(pOpts, hVfsDirSrc, idxObj, pszDir, 1854 pParsed->aNames[pParsed->cNamesWithSrc - 1].cchPath, fNamespaces, 0 /*cDepth*/); 1855 } 1856 RTVfsDirRelease(hVfsDirSrc); 1525 1857 return rc; 1526 1858 } 1859 1860 1527 1861 1528 1862 … … 1540 1874 uint32_t *pidxObj) 1541 1875 { 1542 RTFSOBJINFO ObjInfo; 1543 uint32_t offError; 1544 RTERRINFOSTATIC ErrInfo; 1545 int rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1546 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1547 if (RT_FAILURE(rc)) 1548 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1876 int rc; 1877 RTFSOBJINFO ObjInfo; 1878 if ( pOpts->hSrcVfs == NIL_RTVFS 1879 || RTVfsChainIsSpec(pszSrc)) 1880 { 1881 uint32_t offError; 1882 RTERRINFOSTATIC ErrInfo; 1883 rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1884 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1885 if (RT_FAILURE(rc)) 1886 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1887 } 1888 else 1889 { 1890 rc = RTVfsQueryPathInfo(pOpts->hSrcVfs, pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK); 1891 if (RT_FAILURE(rc)) 1892 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (inside %s): %Rrc", 1893 pszSrc, pOpts->pszSrcVfs, rc); 1894 } 1549 1895 1550 1896 if (RTFS_IS_FILE(ObjInfo.Attr.fMode)) … … 1606 1952 const char *pszSrc = Parsed.aNames[Parsed.cNamesWithSrc - 1].szPath; 1607 1953 RTFSOBJINFO ObjInfo; 1608 uint32_t offError; 1609 RTERRINFOSTATIC ErrInfo; 1610 rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1611 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1612 if (RT_FAILURE(rc)) 1613 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1954 if ( pOpts->hSrcVfs == NIL_RTVFS 1955 || RTVfsChainIsSpec(pszSrc)) 1956 { 1957 uint32_t offError; 1958 RTERRINFOSTATIC ErrInfo; 1959 rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1960 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1961 if (RT_FAILURE(rc)) 1962 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1963 } 1964 else 1965 { 1966 rc = RTVfsQueryPathInfo(pOpts->hSrcVfs, pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK); 1967 if (RT_FAILURE(rc)) 1968 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (in %s): %Rrc", 1969 pszSrc, pOpts->pszSrcVfs, rc); 1970 } 1614 1971 1615 1972 if (RTFS_IS_FILE(ObjInfo.Attr.fMode)) … … 1617 1974 1618 1975 if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 1619 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding directory '%s' failed: not implemented", pszSpec); 1976 { 1977 if ( pOpts->hSrcVfs == NIL_RTVFS 1978 || RTVfsChainIsSpec(pszSrc)) 1979 return rtFsIsoMakerCmdAddDir(pOpts, pszSrc, &Parsed); 1980 return rtFsIsoMakerCmdAddVfsDir(pOpts, &Parsed, &ObjInfo); 1981 } 1620 1982 1621 1983 if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode)) 1622 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding symlink '%s' failed: not implemented", pszSpec);1984 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding symlink '%s' failed: not yet implemented", pszSpec); 1623 1985 1624 1986 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding special file '%s' failed: not implemented", pszSpec); … … 1626 1988 1627 1989 return VINF_SUCCESS; 1990 } 1991 1992 1993 /** 1994 * Opens an ISO and use it for subsequent file system accesses. 1995 * 1996 * This is handy for duplicating a part of an ISO in the new image. 1997 * 1998 * @returns IPRT status code. 1999 * @param pOpts The ISO maker command instance. 2000 * @param pszIsoSpec The ISO path specifier. 2001 * @param pszOption The option we're being called on. 2002 * @param fFlags RTFSISO9660_F_XXX 2003 */ 2004 static int rtFsIsoMakerCmdOptPushIso(PRTFSISOMAKERCMDOPTS pOpts, const char *pszIsoSpec, const char *pszOption, uint32_t fFlags) 2005 { 2006 if (pOpts->hSrcVfs != NIL_RTVFS) 2007 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, 2008 "Nested %s usage is not supported (previous: %s %s)", 2009 pszOption, pOpts->pszSrcVfsOption, pOpts->pszSrcVfs); 2010 2011 /* 2012 * Try open the file. 2013 */ 2014 RTVFSFILE hVfsFileIso; 2015 uint32_t offError; 2016 RTERRINFOSTATIC ErrInfo; 2017 int rc = RTVfsChainOpenFile(pszIsoSpec, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, 2018 &hVfsFileIso, &offError, RTErrInfoInitStatic(&ErrInfo)); 2019 if (RT_SUCCESS(rc)) 2020 { 2021 RTVFS hSrcVfs; 2022 rc = RTFsIso9660VolOpen(hVfsFileIso, fFlags, &hSrcVfs, RTErrInfoInitStatic(&ErrInfo)); 2023 RTVfsFileRelease(hVfsFileIso); 2024 if (RT_SUCCESS(rc)) 2025 { 2026 pOpts->hSrcVfs = hSrcVfs; 2027 pOpts->pszSrcVfs = pszIsoSpec; 2028 pOpts->pszSrcVfsOption = pszOption; 2029 return VINF_SUCCESS; 2030 } 2031 2032 if (RTErrInfoIsSet(&ErrInfo.Core)) 2033 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc - %s", 2034 pszIsoSpec, rc, ErrInfo.Core.pszMsg); 2035 else 2036 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc", pszIsoSpec, rc); 2037 } 2038 else 2039 rc = rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pszIsoSpec, rc, offError, &ErrInfo.Core); 2040 return rc; 2041 } 2042 2043 2044 /** 2045 * Counter part to --push-iso and friends. 2046 * 2047 * @returns IPRT status code. 2048 * @param pOpts The ISO maker command instance. 2049 */ 2050 static int rtFsIsoMakerCmdOptPop(PRTFSISOMAKERCMDOPTS pOpts) 2051 { 2052 if (pOpts->hSrcVfs != NIL_RTVFS) 2053 { 2054 RTVfsRelease(pOpts->hSrcVfs); 2055 pOpts->hSrcVfs = NIL_RTVFS; 2056 pOpts->pszSrcVfs = NULL; 2057 pOpts->pszSrcVfsOption = NULL; 2058 return VINF_SUCCESS; 2059 } 2060 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "--pop without --push-xxx"); 1628 2061 } 1629 2062 … … 2326 2759 break; 2327 2760 2761 case RTFSISOMAKERCMD_OPT_PUSH_ISO: 2762 rc = rtFsIsoMakerCmdOptPushIso(pOpts, ValueUnion.psz, "--push-iso", 0); 2763 break; 2764 2765 case RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_JOLIET: 2766 rc = rtFsIsoMakerCmdOptPushIso(pOpts, ValueUnion.psz, "--push-iso-no-joliet", RTFSISO9660_F_NO_JOLIET); 2767 break; 2768 2769 case RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK: 2770 rc = rtFsIsoMakerCmdOptPushIso(pOpts, ValueUnion.psz, "--push-iso-no-rock", RTFSISO9660_F_NO_ROCK); 2771 break; 2772 2773 case RTFSISOMAKERCMD_OPT_PUSH_ISO_NO_ROCK_NO_JOLIET: 2774 rc = rtFsIsoMakerCmdOptPushIso(pOpts, ValueUnion.psz, "--push-iso-no-rock-no-joliet", 2775 RTFSISO9660_F_NO_ROCK | RTFSISO9660_F_NO_JOLIET); 2776 break; 2777 2778 case RTFSISOMAKERCMD_OPT_POP: 2779 rc = rtFsIsoMakerCmdOptPop(pOpts); 2780 break; 2781 2782 2328 2783 case RTFSISOMAKERCMD_OPT_IMPORT_ISO: 2329 2784 rc = rtFsIsoMakerCmdOptImportIso(pOpts, ValueUnion.psz); … … 2504 2959 Opts.pErrInfo = pErrInfo; 2505 2960 Opts.fVirtualImageMaker = phVfsFile != NULL; 2961 Opts.hSrcVfs = NIL_RTVFS; 2506 2962 Opts.cNameSpecifiers = 1; 2507 2963 Opts.afNameSpecifiers[0] = RTFSISOMAKERCMDNAME_MAJOR_MASK;
Note:
See TracChangeset
for help on using the changeset viewer.