VirtualBox

Ignore:
Timestamp:
Jan 21, 2014 7:51:00 PM (11 years ago)
Author:
vboxsync
Message:

Reduce the TAR API to what's currently used.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/zip/tar.cpp

    r50153 r50154  
    142142    /** The magic (RTTARFILE_MAGIC). */
    143143    uint32_t        u32Magic;
     144    /** The open mode. */
     145    uint32_t        fOpenMode;
    144146    /** Pointer to back to the tar file. */
    145147    PRTTARINTERNAL  pTar;
     
    154156    /** The current offset within this file. */
    155157    uint64_t        offCurrent;
    156     /** The open mode. */
    157     uint32_t        fOpenMode;
     158#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    158159    /** The link flag. */
    159160    char            linkflag;
     161#endif
    160162#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
    161163    /** The VFS I/O stream (only for reading atm). */
    162164    RTVFSIOSTREAM   hVfsIos;
    163     /** The RTFSOBJATTR::fMode value for this VFS object. */
    164     RTFMODE         fVfsMode;
    165     /** The RTFSOBJINFO::ModificationTime value for this VFS object. */
    166     RTTIMESPEC      VfsModTime;
    167165#endif
    168166} RTTARFILEINTERNAL;
     
    465463
    466464    pFileInt->u32Magic = RTTARFILE_MAGIC;
     465#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    467466    pFileInt->pTar = pInt;
     467#endif
    468468    pFileInt->fOpenMode = fOpen;
    469469    pFileInt->pszFilename = RTStrDup(pszFilename);
     
    510510            pNewFile->offCurrent    = 0;
    511511            pNewFile->fOpenMode     = fOpen;
    512             pNewFile->linkflag      = LF_NORMAL;
    513512            pNewFile->hVfsIos       = hVfsIos;
    514             pNewFile->fVfsMode      = ObjInfo.Attr.fMode;
    515             pNewFile->VfsModTime    = ObjInfo.ModificationTime;
    516513
    517514            uint32_t cRefs = RTVfsIoStrmRetain(hVfsIos); Assert(cRefs != UINT32_MAX); NOREF(cRefs);
     
    568565    }
    569566}
    570 
    571 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    572 static int rtTarExtractFileToFile(RTTARFILE hFile, const char *pszTargetName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    573 {
    574     /* Open the target file */
    575     RTFILE hNewFile;
    576     int rc = RTFileOpen(&hNewFile, pszTargetName, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
    577     if (RT_FAILURE(rc))
    578         return rc;
    579 
    580     void *pvTmp = NULL;
    581     do
    582     {
    583         /* Allocate a temporary buffer for reading the tar content in blocks. */
    584         size_t cbTmp = 0;
    585         pvTmp = rtTarMemTmpAlloc(&cbTmp);
    586         if (!pvTmp)
    587         {
    588             rc = VERR_NO_MEMORY;
    589             break;
    590         }
    591 
    592         /* Get the size of the source file */
    593         uint64_t cbToCopy = 0;
    594         rc = RTTarFileGetSize(hFile, &cbToCopy);
    595         if (RT_FAILURE(rc))
    596             break;
    597 
    598         /* Copy the content from hFile over to pszTargetName. */
    599         uint64_t cbAllWritten = 0; /* Already copied */
    600         uint64_t cbRead = 0; /* Actually read in the last step */
    601         for (;;)
    602         {
    603             if (pfnProgressCallback)
    604                 pfnProgressCallback((unsigned)(100.0 / cbOverallSize * cbOverallWritten), pvUser);
    605 
    606             /* Finished already? */
    607             if (cbAllWritten == cbToCopy)
    608                 break;
    609 
    610             /* Read one block. */
    611             cbRead = RT_MIN(cbToCopy - cbAllWritten, cbTmp);
    612             rc = RTTarFileRead(hFile, pvTmp, cbRead, NULL);
    613             if (RT_FAILURE(rc))
    614                 break;
    615 
    616             /* Write the block */
    617             rc = RTFileWrite(hNewFile, pvTmp, cbRead, NULL);
    618             if (RT_FAILURE(rc))
    619                 break;
    620 
    621             /* Count how many bytes are written already */
    622             cbAllWritten += cbRead;
    623             cbOverallWritten += cbRead;
    624         }
    625 
    626     } while (0);
    627 
    628     /* Cleanup */
    629     if (pvTmp)
    630         RTMemTmpFree(pvTmp);
    631 
    632     /* Now set all file attributes */
    633     if (RT_SUCCESS(rc))
    634     {
    635         uint32_t mode;
    636         rc = RTTarFileGetMode(hFile, &mode);
    637         if (RT_SUCCESS(rc))
    638         {
    639             mode |= RTFS_TYPE_FILE; /* For now we support regular files only */
    640             /* Set the mode */
    641             rc = RTFileSetMode(hNewFile, mode);
    642         }
    643     }
    644 
    645     RTFileClose(hNewFile);
    646 
    647     /* Delete the freshly created file in the case of an error */
    648     if (RT_FAILURE(rc))
    649         RTFileDelete(pszTargetName);
    650 
    651     return rc;
    652 }
    653 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    654567
    655568static int rtTarAppendFileFromFile(RTTAR hTar, const char *pszSrcName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     
    13321245}
    13331246
    1334 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* only used internally */
    1335 RTR3DECL(int) RTTarFileGetMode(RTTARFILE hFile, uint32_t *pfMode)
    1336 {
    1337     /* Validate input */
    1338     AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
    1339 
    1340     PRTTARFILEINTERNAL pFileInt = hFile;
    1341     RTTARFILE_VALID_RETURN(pFileInt);
    1342 
    1343 #ifdef RT_USE_TAR_VFS_FOR_ALL_READS
    1344     if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE)
    1345     {
    1346         Assert(pFileInt->hVfsIos != NIL_RTVFSIOSTREAM);
    1347         *pfMode = pFileInt->fVfsMode;
    1348         return VINF_SUCCESS;
    1349     }
    1350 #endif
    1351 
    1352     /* Read the mode out of the header entry */
    1353     char szMode[RT_SIZEOFMEMB(RTTARRECORD, h.mode)+1];
    1354     int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
    1355                           pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mode),
    1356                           szMode,
    1357                           RT_SIZEOFMEMB(RTTARRECORD, h.mode),
    1358                           NULL);
    1359     if (RT_FAILURE(rc))
    1360         return rc;
    1361     szMode[sizeof(szMode) - 1] = '\0';
    1362 
    1363     /* Convert it to an integer */
    1364     return RTStrToUInt32Full(szMode, 8, pfMode);
    1365 }
    1366 #endif
    1367 
    13681247RTR3DECL(int) RTTarFileSetMode(RTTARFILE hFile, uint32_t fMode)
    13691248{
     
    13861265}
    13871266
    1388 #ifdef RT_UNUSED_API
    1389 RTR3DECL(int) RTTarFileGetTime(RTTARFILE hFile, PRTTIMESPEC pTime)
    1390 {
    1391     PRTTARFILEINTERNAL pFileInt = hFile;
    1392     RTTARFILE_VALID_RETURN(pFileInt);
    1393 
    1394 # ifdef RT_USE_TAR_VFS_FOR_ALL_READS
    1395     if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE)
    1396     {
    1397         Assert(pFileInt->hVfsIos != NIL_RTVFSIOSTREAM);
    1398         *pTime = pFileInt->VfsModTime;
    1399         return VINF_SUCCESS;
    1400     }
    1401 # endif
    1402 
    1403     /* Read the time out of the header entry */
    1404     char szModTime[RT_SIZEOFMEMB(RTTARRECORD, h.mtime) + 1];
    1405     int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
    1406                           pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mtime),
    1407                           szModTime,
    1408                           RT_SIZEOFMEMB(RTTARRECORD, h.mtime),
    1409                           NULL);
    1410     if (RT_FAILURE(rc))
    1411         return rc;
    1412     szModTime[sizeof(szModTime) - 1] = '\0';
    1413 
    1414     /* Convert it to an integer */
    1415     int64_t cSeconds;
    1416     rc = RTStrToInt64Full(szModTime, 12, &cSeconds);
    1417 
    1418     /* And back to our time structure */
    1419     if (RT_SUCCESS(rc))
    1420         RTTimeSpecSetSeconds(pTime, cSeconds);
    1421 
    1422     return rc;
    1423 }
    1424 #endif /* RT_UNUSED_API */
    1425 
    14261267RTR3DECL(int) RTTarFileSetTime(RTTARFILE hFile, PRTTIMESPEC pTime)
    14271268{
     
    14431284                         NULL);
    14441285}
    1445 
    1446 #if !defined(RT_USE_TAR_VFS_FOR_ALL_READS) && defined(RT_UNUSED_API)
    1447 RTR3DECL(int) RTTarFileGetOwner(RTTARFILE hFile, uint32_t *pUid, uint32_t *pGid)
    1448 {
    1449     PRTTARFILEINTERNAL pFileInt = hFile;
    1450     RTTARFILE_VALID_RETURN(pFileInt);
    1451 
    1452     /* Read the uid and gid out of the header entry */
    1453     AssertCompileAdjacentMembers(RTTARRECORD, h.uid, h.gid);
    1454     char szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid) + RT_SIZEOFMEMB(RTTARRECORD, h.gid) + 1];
    1455     int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
    1456                           pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.uid),
    1457                           szUidGid,
    1458                           sizeof(szUidGid) - 1,
    1459                           NULL);
    1460     if (RT_FAILURE(rc))
    1461         return rc;
    1462     szUidGid[sizeof(szUidGid) - 1] = '\0';
    1463 
    1464     /* Convert it to integer */
    1465     rc = RTStrToUInt32Full(&szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid)], 8, pGid);
    1466     if (RT_SUCCESS(rc))
    1467     {
    1468         szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid)] = '\0';
    1469         rc = RTStrToUInt32Full(szUidGid, 8, pUid);
    1470     }
    1471     return rc;
    1472 }
    1473 #endif
    14741286
    14751287RTR3DECL(int) RTTarFileSetOwner(RTTARFILE hFile, uint32_t uid, uint32_t gid)
     
    15231335 *   Convenience Functions                                                    *
    15241336 ******************************************************************************/
    1525 
    1526 #ifndef RT_UNUSED_API
    1527 RTR3DECL(int) RTTarFileExists(const char *pszTarFile, const char *pszFile)
    1528 {
    1529     /* Validate input */
    1530     AssertPtrReturn(pszTarFile, VERR_INVALID_POINTER);
    1531     AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
    1532 
    1533     /* Open the tar file */
    1534     RTTAR hTar;
    1535     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    1536     if (RT_FAILURE(rc))
    1537         return rc;
    1538 
    1539     /* Just try to open that file readonly. If this succeed the file exists. */
    1540     RTTARFILE hFile;
    1541     rc = RTTarFileOpen(hTar, &hFile, pszFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
    1542     if (RT_SUCCESS(rc))
    1543         RTTarFileClose(hFile);
    1544 
    1545     RTTarClose(hTar);
    1546 
    1547     return rc;
    1548 }
    1549 #endif /* RT_UNUSED_API */
    15501337
    15511338RTR3DECL(int) RTTarList(const char *pszTarFile, char ***ppapszFiles, size_t *pcFiles)
     
    17011488}
    17021489
    1703 #if 0 /* broken, using wrong offset when reading. fix+test when _really_ need - use the TAR VFS wherever possible! */
    1704 RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile,
    1705                                     PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    1706 {
    1707     /*
    1708      * Validate input
    1709      */
    1710     AssertPtrReturn(pszTarFile, VERR_INVALID_POINTER);
    1711     AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
    1712     AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
    1713     AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
    1714     AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);
    1715     AssertPtrNullReturn(pvUser, VERR_INVALID_POINTER);
    1716 
    1717     /** @todo progress bar - is this TODO still valid? */
    1718 
    1719     int         rc      = VINF_SUCCESS;
    1720     RTTAR       hTar    = NIL_RTTAR;
    1721     RTTARFILE   hFile   = NIL_RTTARFILE;
    1722     char       *pvTmp   = NULL;
    1723     uint64_t    cbToCopy= 0;
    1724     do /* break loop */
    1725     {
    1726         rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    1727         if (RT_FAILURE(rc))
    1728             break;
    1729         rc = RTTarFileOpen(hTar, &hFile, pszFile, RTFILE_O_OPEN | RTFILE_O_READ);
    1730         if (RT_FAILURE(rc))
    1731             break;
    1732         rc = RTTarFileGetSize(hFile, &cbToCopy);
    1733         if (RT_FAILURE(rc))
    1734             break;
    1735 
    1736         /* Allocate the memory for the file content. */
    1737         pvTmp = (char *)RTMemAlloc(cbToCopy);
    1738         if (!pvTmp)
    1739         {
    1740             rc = VERR_NO_MEMORY;
    1741             break;
    1742         }
    1743         size_t cbRead = 0;
    1744         size_t cbAllRead = 0;
    1745         for (;;)
    1746         {
    1747             if (pfnProgressCallback)
    1748                 pfnProgressCallback((unsigned)(100.0 / cbToCopy * cbAllRead), pvUser);
    1749             if (cbAllRead == cbToCopy)
    1750                 break;
    1751             rc = RTTarFileReadAt(hFile, 0, &pvTmp[cbAllRead], cbToCopy - cbAllRead, &cbRead);
    1752             if (RT_FAILURE(rc))
    1753                 break;
    1754             cbAllRead += cbRead;
    1755         }
    1756     } while (0);
    1757 
    1758     /* Set output values on success */
    1759     if (RT_SUCCESS(rc))
    1760     {
    1761         *pcbSize = cbToCopy;
    1762         *ppvBuf = pvTmp;
    1763     }
    1764 
    1765     /* Cleanup */
    1766     if (   RT_FAILURE(rc)
    1767         && pvTmp)
    1768         RTMemFree(pvTmp);
    1769     if (hFile)
    1770         RTTarFileClose(hFile);
    1771     if (hTar)
    1772         RTTarClose(hTar);
    1773 
    1774     return rc;
    1775 }
    1776 #endif
    1777 
    1778 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */
    1779 RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles,
    1780                                 size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    1781 {
    1782     /* Validate input */
    1783     AssertPtrReturn(pszTarFile, VERR_INVALID_POINTER);
    1784     AssertPtrReturn(pszOutputDir, VERR_INVALID_POINTER);
    1785     AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    1786     AssertReturn(cFiles, VERR_INVALID_PARAMETER);
    1787     AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);
    1788     AssertPtrNullReturn(pvUser, VERR_INVALID_POINTER);
    1789 
    1790     /* Open the tar file */
    1791     RTTAR hTar;
    1792     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    1793     if (RT_FAILURE(rc))
    1794         return rc;
    1795 
    1796     do /* break loop */
    1797     {
    1798         /* Get the overall size of all files to extract out of the tar archive
    1799            headers. Only necessary if there is a progress callback. */
    1800         uint64_t cbOverallSize = 0;
    1801         if (pfnProgressCallback)
    1802         {
    1803 //            rc = rtTarGetFilesOverallSize(hFile, papszFiles, cFiles, &cbOverallSize);
    1804 //            if (RT_FAILURE(rc))
    1805 //                break;
    1806         }
    1807 
    1808         uint64_t cbOverallWritten = 0;
    1809         for (size_t i = 0; i < cFiles; ++i)
    1810         {
    1811             RTTARFILE hFile;
    1812             rc = RTTarFileOpen(hTar, &hFile, papszFiles[i], RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
    1813             if (RT_FAILURE(rc))
    1814                 break;
    1815             char *pszTargetFile = RTPathJoinA(pszOutputDir, papszFiles[i]);
    1816             if (pszTargetFile)
    1817                 rc = rtTarExtractFileToFile(hFile, pszTargetFile, cbOverallSize, cbOverallWritten, pfnProgressCallback, pvUser);
    1818             else
    1819                 rc = VERR_NO_STR_MEMORY;
    1820             RTStrFree(pszTargetFile);
    1821             RTTarFileClose(hFile);
    1822             if (RT_FAILURE(rc))
    1823                 break;
    1824         }
    1825     } while (0);
    1826 
    1827     RTTarClose(hTar);
    1828 
    1829     return rc;
    1830 }
    1831 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    1832 
    1833 #ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */
    1834 RTR3DECL(int) RTTarExtractAll(const char *pszTarFile, const char *pszOutputDir, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    1835 {
    1836     /* Validate input */
    1837     AssertPtrReturn(pszTarFile, VERR_INVALID_POINTER);
    1838     AssertPtrReturn(pszOutputDir, VERR_INVALID_POINTER);
    1839     AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);
    1840     AssertPtrNullReturn(pvUser, VERR_INVALID_POINTER);
    1841 
    1842     char **papszFiles;
    1843     size_t cFiles;
    1844 
    1845     /* First fetch the files names contained in the tar file */
    1846     int rc = RTTarList(pszTarFile, &papszFiles, &cFiles);
    1847     if (RT_FAILURE(rc))
    1848         return rc;
    1849 
    1850     /* Extract all files */
    1851     return RTTarExtractFiles(pszTarFile, pszOutputDir, papszFiles, cFiles, pfnProgressCallback, pvUser);
    1852 }
    1853 #endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    1854 
    18551490RTR3DECL(int) RTTarCreate(const char *pszTarFile, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    18561491{
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette