VirtualBox

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

tar.cpp: Prepared for dropping all the TAR reading code and use the VFS code instead. (changes are all disabled)

File:
1 edited

Legend:

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

    r50139 r50147  
    55
    66/*
    7  * Copyright (C) 2009-2013 Oracle Corporation
     7 * Copyright (C) 2009-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2525 */
    2626
     27//#define RT_USE_TAR_VFS_FOR_ALL_READS - make default on trunk!
    2728
    2829/******************************************************************************
     
    3940#include <iprt/path.h>
    4041#include <iprt/string.h>
     42#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     43# include <iprt/vfs.h>
     44# include <iprt/zip.h>
     45#endif /* RT_USE_TAR_VFS_FOR_ALL_READS */
     46
    4147
    4248#include "internal/magics.h"
     
    110116    /** Whether operating in stream mode. */
    111117    bool                fStreamMode;
     118#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    112119    /** The file cache of one file.  */
    113120    PRTTARFILEINTERNAL  pFileCache;
     121#else /* RT_USE_TAR_VFS_FOR_ALL_READS */
     122    /** The tar file VFS handle. */
     123    RTVFSFILE           hVfsFile;
     124    /** The tar file system VFS handle. */
     125    RTVFSFSSTREAM       hVfsFss;
     126    /** Set if hVfsFss is at the start of the stream and doesn't need rewinding. */
     127    bool                fFssAtStart;
     128    /** The current stream object (fStreamMode = true). */
     129    RTVFSIOSTREAM       hVfsCur;
     130    /** The name of the current object (fStreamMode = true). */
     131    char               *pszVfsCurName;
     132#endif /* RT_USE_TAR_VFS_FOR_ALL_READS */
    114133} RTTARINTERNAL;
    115134/** Pointer to a the internal data of a tar handle.  */
     
    139158    /** The link flag. */
    140159    char            linkflag;
     160#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     161    /** The VFS I/O stream (only for reading atm). */
     162    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;
     167#endif
    141168} RTTARFILEINTERNAL;
    142169/** Pointer to the internal data of a tar file.  */
    143170typedef RTTARFILEINTERNAL *PRTTARFILEINTERNAL;
    144 
    145 #if 0 /* not currently used */
    146 typedef struct RTTARFILELIST
    147 {
    148     char *pszFilename;
    149     RTTARFILELIST *pNext;
    150 } RTTARFILELIST;
    151 typedef RTTARFILELIST *PRTTARFILELIST;
    152 #endif
    153171
    154172
     
    230248}
    231249
     250#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    232251DECLINLINE(uint64_t) rtTarRecToSize(PRTTARRECORD pRecord)
    233252{
     
    269288    return (uint64_t)cbSize;
    270289}
     290#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    271291
    272292/**
     
    325345}
    326346
     347#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    327348DECLINLINE(int) rtTarReadHeaderRecord(RTFILE hFile, PRTTARRECORD pRecord)
    328349{
     
    360381    return rc;
    361382}
     383#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    362384
    363385DECLINLINE(int) rtTarCreateHeaderRecord(PRTTARRECORD pRecord, const char *pszSrcName, uint64_t cbSize,
     
    448470    if (!pFileInt->pszFilename)
    449471    {
     472#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     473        pFileInt->hVfsIos = NIL_RTVFSIOSTREAM;
     474#endif
    450475        RTMemFree(pFileInt);
    451476        return NULL;
     
    454479    return pFileInt;
    455480}
     481
     482#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     483
     484/**
     485 * Creates a tar file handle for a read-only VFS stream object.
     486 *
     487 * @returns IPRT status code.
     488 * @param   pszName             The file name. Automatically freed on failure.
     489 * @param   hVfsIos             The VFS I/O stream we create the handle around.
     490 *                              The reference is NOT consumed.
     491 * @param   fOpen               The open flags.
     492 * @param   ppFile              Where to return the handle.
     493 */
     494static int rtTarFileCreateHandleForReadOnly(char *pszName, RTVFSIOSTREAM hVfsIos, uint32_t fOpen, PRTTARFILEINTERNAL *ppFile)
     495{
     496    int rc;
     497    PRTTARFILEINTERNAL pNewFile = (PRTTARFILEINTERNAL)RTMemAllocZ(sizeof(*pNewFile));
     498    if (pNewFile)
     499    {
     500        RTFSOBJINFO ObjInfo;
     501        rc = RTVfsIoStrmQueryInfo(hVfsIos, &ObjInfo, RTFSOBJATTRADD_UNIX);
     502        if (RT_SUCCESS(rc))
     503        {
     504            pNewFile->u32Magic      = RTTARFILE_MAGIC;
     505            pNewFile->pTar          = NULL;
     506            pNewFile->pszFilename   = pszName;
     507            pNewFile->offStart      = UINT64_MAX;
     508            pNewFile->cbSize        = ObjInfo.cbObject;
     509            pNewFile->cbSetSize     = 0;
     510            pNewFile->offCurrent    = 0;
     511            pNewFile->fOpenMode     = fOpen;
     512            pNewFile->linkflag      = LF_NORMAL;
     513            pNewFile->hVfsIos       = hVfsIos;
     514            pNewFile->fVfsMode      = ObjInfo.Attr.fMode;
     515            pNewFile->VfsModTime    = ObjInfo.ModificationTime;
     516
     517            uint32_t cRefs = RTVfsIoStrmRetain(hVfsIos); Assert(cRefs != UINT32_MAX); NOREF(cRefs);
     518
     519            *ppFile = pNewFile;
     520            return VINF_SUCCESS;
     521        }
     522
     523        RTMemFree(pNewFile);
     524    }
     525    else
     526        rc = VERR_NO_MEMORY;
     527    RTStrFree(pszName);
     528    return rc;
     529}
     530
     531#else  /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    456532
    457533DECLINLINE(PRTTARFILEINTERNAL) rtCopyTarFileInternal(PRTTARFILEINTERNAL pInt)
     
    472548}
    473549
     550#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     551
    474552DECLINLINE(void) rtDeleteTarFileInternal(PRTTARFILEINTERNAL pInt)
    475553{
     
    478556        if (pInt->pszFilename)
    479557            RTStrFree(pInt->pszFilename);
     558#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     559        if (pInt->hVfsIos != NIL_RTVFSIOSTREAM)
     560        {
     561            RTVfsIoStrmRelease(pInt->hVfsIos);
     562            pInt->hVfsIos = NIL_RTVFSIOSTREAM;
     563        }
     564#endif
     565
    480566        pInt->u32Magic = RTTARFILE_MAGIC_DEAD;
    481567        RTMemFree(pInt);
     
    483569}
    484570
     571#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    485572static int rtTarExtractFileToFile(RTTARFILE hFile, const char *pszTargetName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    486573{
     
    564651    return rc;
    565652}
     653#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    566654
    567655static int rtTarAppendFileFromFile(RTTAR hTar, const char *pszSrcName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     
    672760    return rc;
    673761}
     762
     763#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    674764
    675765static int rtTarSkipData(RTFILE hFile, PRTTARRECORD pRecord)
     
    727817}
    728818
    729 #ifdef SOME_UNUSED_FUNCTION
    730 static int rtTarGetFilesOverallSize(RTFILE hFile, const char * const *papszFiles, size_t cFiles, uint64_t *pcbOverallSize)
    731 {
    732     int rc = VINF_SUCCESS;
    733     size_t cFound = 0;
    734     RTTARRECORD record;
    735     for (;;)
    736     {
    737         /* Read & verify a header record */
    738         rc = rtTarReadHeaderRecord(hFile, &record);
    739         /* Check for error or EOF. */
    740         if (RT_FAILURE(rc))
    741             break;
    742 
    743         /* We support normal files only */
    744         if (   record.h.linkflag == LF_OLDNORMAL
    745             || record.h.linkflag == LF_NORMAL)
    746         {
    747             for (size_t i = 0; i < cFiles; ++i)
    748             {
    749                 if (!RTStrCmp(record.h.name, papszFiles[i]))
    750                 {
    751                     /* Sum up the overall size */
    752                     *pcbOverallSize += rtTarRecToSize(&record);
    753                     ++cFound;
    754                     break;
    755                 }
    756             }
    757             if (   cFound == cFiles
    758                 || RT_FAILURE(rc))
    759                 break;
    760         }
    761         rc = rtTarSkipData(hFile, &record);
    762         if (RT_FAILURE(rc))
    763             break;
    764     }
    765     if (rc == VERR_TAR_END_OF_FILE)
    766         rc = VINF_SUCCESS;
    767 
    768     /* Make sure the file pointer is at the begin of the file again. */
    769     if (RT_SUCCESS(rc))
    770         rc = RTFileSeek(hFile, 0, RTFILE_SEEK_BEGIN, 0);
    771     return rc;
    772 }
    773 #endif /* SOME_UNUSED_FUNCTION */
     819#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     820
    774821
    775822/******************************************************************************
     
    779826RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode, bool fStream)
    780827{
     828    AssertReturn(!fStream || !(fMode & RTFILE_O_WRITE), VERR_INVALID_PARAMETER);
     829
    781830    /*
    782831     * Create a tar instance.
     
    793842     * Open the tar file.
    794843     */
    795     int rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode);
     844    int rc;
     845#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     846    pThis->hVfsFile         = NIL_RTVFSFILE;
     847    pThis->hVfsFss          = NIL_RTVFSFSSTREAM;
     848    pThis->fFssAtStart      = false;
     849    pThis->hVfsCur          = NIL_RTVFSIOSTREAM;
     850    pThis->pszVfsCurName    = NULL;
     851
     852    if (!(fMode & RTFILE_O_WRITE))
     853    {
     854        rc = RTVfsFileOpenNormal(pszTarname, fMode, &pThis->hVfsFile);
     855        if (RT_SUCCESS(rc))
     856        {
     857            RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pThis->hVfsFile);
     858            rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pThis->hVfsFss);
     859            if (RT_SUCCESS(rc))
     860                pThis->fFssAtStart = true;
     861            else
     862            {
     863                RTVfsFileRelease(pThis->hVfsFile);
     864                pThis->hVfsFile = NIL_RTVFSFILE;
     865            }
     866            RTVfsIoStrmRelease(hVfsIos);
     867        }
     868    }
     869    else
     870#endif
     871        rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode);
    796872    if (RT_SUCCESS(rc))
    797873    {
     
    825901#endif
    826902
     903#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     904    if (pInt->hVfsFss != NIL_RTVFSFSSTREAM)
     905    {
     906        uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX);
     907        pInt->hVfsFss  = NIL_RTVFSFSSTREAM;
     908    }
     909
     910    if (pInt->hVfsFile != NIL_RTVFSFILE)
     911    {
     912        uint32_t cRefs = RTVfsFileRelease(pInt->hVfsFile); Assert(cRefs != UINT32_MAX);
     913        pInt->hVfsFile = NIL_RTVFSFILE;
     914    }
     915
     916    if (pInt->hVfsCur != NIL_RTVFSIOSTREAM)
     917    {
     918        RTVfsIoStrmRelease(pInt->hVfsCur);
     919        pInt->hVfsCur = NIL_RTVFSIOSTREAM;
     920    }
     921
     922    if (pInt->pszVfsCurName)
     923    {
     924        RTStrFree(pInt->pszVfsCurName);
     925        pInt->pszVfsCurName = NULL;
     926    }
     927#endif /* RT_USE_TAR_VFS_FOR_ALL_READS */
     928
    827929    if (pInt->hTarFile != NIL_RTFILE)
     930    {
    828931        rc = RTFileClose(pInt->hTarFile);
    829 
     932        pInt->hTarFile = NIL_RTFILE;
     933    }
     934
     935#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    830936    /* Delete any remaining cached file headers. */
    831937    if (pInt->pFileCache)
     
    834940        pInt->pFileCache = NULL;
    835941    }
     942#endif
    836943
    837944    pInt->u32Magic = RTTAR_MAGIC_DEAD;
     
    863970    }
    864971
    865     PRTTARFILEINTERNAL pFileInt = rtCreateTarFileInternal(pInt, pszFilename, fOpen);
    866     if (!pFileInt)
    867         return VERR_NO_MEMORY;
    868 
    869972    int rc = VINF_SUCCESS;
    870     do /* break loop */
    871     {
    872         if (pFileInt->fOpenMode & RTFILE_O_WRITE)
    873         {
    874             pInt->fFileOpenForWrite = true;
    875 
    876             /* If we are in write mode, we also in append mode. Add an dummy
    877              * header at the end of the current file. It will be filled by the
    878              * close operation. */
    879             rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart);
     973#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     974    if (!(fOpen & RTFILE_O_WRITE))
     975    {
     976        /*
     977         * Rewind the stream if necessary.
     978         */
     979        if (!pInt->fFssAtStart)
     980        {
     981            if (pInt->hVfsFss != NIL_RTVFSFSSTREAM)
     982            {
     983                uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX);
     984                pInt->hVfsFss  = NIL_RTVFSFSSTREAM;
     985            }
     986
     987            if (pInt->hVfsFile == NIL_RTVFSFILE)
     988            {
     989                rc = RTVfsFileFromRTFile(pInt->hTarFile, RTFILE_O_READ, true /*fLeaveOpen*/, &pInt->hVfsFile);
     990                if (RT_FAILURE(rc))
     991                    return rc;
     992            }
     993            Assert(pInt->hVfsCur == NIL_RTVFSIOSTREAM && pInt->pszVfsCurName == NULL);
     994
     995            RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pInt->hVfsFile);
     996            rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pInt->hVfsFss);
     997            RTVfsIoStrmRelease(hVfsIos);
    880998            if (RT_FAILURE(rc))
     999                return rc;
     1000        }
     1001
     1002        /*
     1003         * Search the file system stream.
     1004         */
     1005        pInt->fFssAtStart = false;
     1006        for (;;)
     1007        {
     1008            char           *pszName;
     1009            RTVFSOBJTYPE    enmType;
     1010            RTVFSOBJ        hVfsObj;
     1011            rc = RTVfsFsStrmNext(pInt->hVfsFss, &pszName, &enmType, &hVfsObj);
     1012            if (rc == VERR_EOF)
     1013                return VERR_FILE_NOT_FOUND;
     1014            if (RT_FAILURE(rc))
     1015                return rc;
     1016
     1017            if (!RTStrCmp(pszName, pszFilename))
     1018            {
     1019                if (enmType == RTVFSOBJTYPE_FILE || enmType == RTVFSOBJTYPE_IO_STREAM)
     1020                    rc = rtTarFileCreateHandleForReadOnly(pszName, RTVfsObjToIoStream(hVfsObj), fOpen, phFile);
     1021                else
     1022                {
     1023                    rc = VERR_UNEXPECTED_FS_OBJ_TYPE;
     1024                    RTStrFree(pszName);
     1025                }
     1026                RTVfsObjRelease(hVfsObj);
    8811027                break;
    882             RTTARRECORD record;
    883             RT_ZERO(record);
    884             rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL);
    885             if (RT_FAILURE(rc))
    886                 break;
    887         }
    888         else if (pFileInt->fOpenMode & RTFILE_O_READ)
    889         {
    890             /* We need to be on the start of the file */
    891             rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_BEGIN, NULL);
    892             if (RT_FAILURE(rc))
    893                 break;
    894 
    895             /* Search for the file. */
    896             rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->offStart, &pFileInt->cbSize);
    897             if (RT_FAILURE(rc))
    898                 break;
     1028            }
     1029            RTStrFree(pszName);
     1030            RTVfsObjRelease(hVfsObj);
     1031        } /* Search loop. */
     1032    }
     1033    else
     1034#endif /* RT_USE_TAR_VFS_FOR_ALL_READS */
     1035    {
     1036        PRTTARFILEINTERNAL pFileInt = rtCreateTarFileInternal(pInt, pszFilename, fOpen);
     1037        if (!pFileInt)
     1038            return VERR_NO_MEMORY;
     1039
     1040        do /* break loop */
     1041        {
     1042#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
     1043            if (pFileInt->fOpenMode & RTFILE_O_WRITE)
     1044#endif
     1045            {
     1046                pInt->fFileOpenForWrite = true;
     1047
     1048                /* If we are in write mode, we also in append mode. Add an dummy
     1049                 * header at the end of the current file. It will be filled by the
     1050                 * close operation. */
     1051                rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart);
     1052                if (RT_FAILURE(rc))
     1053                    break;
     1054                RTTARRECORD record;
     1055                RT_ZERO(record);
     1056                rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL);
     1057                if (RT_FAILURE(rc))
     1058                    break;
     1059            }
     1060#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
     1061            else
     1062            {
     1063                Assert(pFileInt->fOpenMode & RTFILE_O_READ); /* see first assertion */
     1064
     1065                /* We need to be on the start of the file */
     1066                rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_BEGIN, NULL);
     1067                if (RT_FAILURE(rc))
     1068                    break;
     1069
     1070                /* Search for the file. */
     1071                rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->offStart, &pFileInt->cbSize);
     1072                if (RT_FAILURE(rc))
     1073                    break;
     1074            }
     1075#endif
     1076        } while (0);
     1077
     1078        /* Cleanup on failure */
     1079        if (RT_FAILURE(rc))
     1080        {
     1081            if (pFileInt->pszFilename)
     1082                RTStrFree(pFileInt->pszFilename);
     1083            RTMemFree(pFileInt);
    8991084        }
    9001085        else
    901         {
    902             /** @todo is something missing here? */
    903         }
    904 
    905     } while (0);
    906 
    907     /* Cleanup on failure */
    908     if (RT_FAILURE(rc))
    909     {
    910         if (pFileInt->pszFilename)
    911             RTStrFree(pFileInt->pszFilename);
    912         RTMemFree(pFileInt);
    913     }
    914     else
    915         *phFile = (RTTARFILE)pFileInt;
     1086            *phFile = (RTTARFILE)pFileInt;
     1087    }
    9161088
    9171089    return rc;
     
    9291101    int rc = VINF_SUCCESS;
    9301102
    931     /* In write mode: */
     1103    /* In read mode: */
    9321104    if (pFileInt->fOpenMode & RTFILE_O_READ)
    9331105    {
     1106#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    9341107        /* In read mode, we want to make sure to stay at the aligned end of this
    9351108         * file, so the next file could be read immediately. */
     
    9471120            rc = RTFileSeek(pFileInt->pTar->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL);
    9481121        }
     1122#endif
    9491123    }
    9501124    else if (pFileInt->fOpenMode & RTFILE_O_WRITE)
     
    10011175}
    10021176
     1177#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    10031178RTR3DECL(int) RTTarFileSeek(RTTARFILE hFile, uint64_t offSeek, unsigned uMethod, uint64_t *poffActual)
    10041179{
     
    10401215    return VINF_SUCCESS;
    10411216}
    1042 
     1217#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     1218
     1219
     1220#ifndef RT_USE_TAR_VFS_FOR_ALL_READS
    10431221RTR3DECL(uint64_t) RTTarFileTell(RTTARFILE hFile)
    10441222{
     
    10481226    return pFileInt->offCurrent;
    10491227}
     1228#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    10501229
    10511230RTR3DECL(int) RTTarFileRead(RTTARFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     
    10541233    RTTARFILE_VALID_RETURN(pFileInt);
    10551234
    1056     /* Todo: optimize this, by checking the current pos */
    10571235    return RTTarFileReadAt(hFile, pFileInt->offCurrent, pvBuf, cbToRead, pcbRead);
    10581236}
     
    10621240    PRTTARFILEINTERNAL pFileInt = hFile;
    10631241    RTTARFILE_VALID_RETURN(pFileInt);
     1242
     1243#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     1244
     1245    size_t cbTmpRead = 0;
     1246    int rc = RTVfsIoStrmReadAt(pFileInt->hVfsIos, off, pvBuf, cbToRead, true /*fBlocking*/, &cbTmpRead);
     1247    if (RT_SUCCESS(rc))
     1248    {
     1249        pFileInt->offCurrent = off + cbTmpRead;
     1250        if (pcbRead)
     1251            *pcbRead = cbTmpRead;
     1252        if (rc == VINF_EOF)
     1253            rc = pcbRead ? VINF_SUCCESS : VERR_EOF;
     1254    }
     1255    else if (pcbRead)
     1256        *pcbRead = 0;
     1257#else
    10641258
    10651259    /* Check that we not read behind the end of file. If so return immediately. */
     
    10781272        *pcbRead = cbTmpRead;
    10791273
     1274#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     1275
    10801276    return rc;
    10811277}
     
    11361332}
    11371333
     1334#ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* only used internally */
    11381335RTR3DECL(int) RTTarFileGetMode(RTTARFILE hFile, uint32_t *pfMode)
    11391336{
     
    11431340    PRTTARFILEINTERNAL pFileInt = hFile;
    11441341    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
    11451351
    11461352    /* Read the mode out of the header entry */
     
    11581364    return RTStrToUInt32Full(szMode, 8, pfMode);
    11591365}
     1366#endif
    11601367
    11611368RTR3DECL(int) RTTarFileSetMode(RTTARFILE hFile, uint32_t fMode)
     
    11791386}
    11801387
     1388#ifdef RT_UNUSED_API
    11811389RTR3DECL(int) RTTarFileGetTime(RTTARFILE hFile, PRTTIMESPEC pTime)
    11821390{
    11831391    PRTTARFILEINTERNAL pFileInt = hFile;
    11841392    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
    11851402
    11861403    /* Read the time out of the header entry */
     
    12051422    return rc;
    12061423}
     1424#endif /* RT_UNUSED_API */
    12071425
    12081426RTR3DECL(int) RTTarFileSetTime(RTTARFILE hFile, PRTTIMESPEC pTime)
     
    12261444}
    12271445
     1446#if !defined(RT_USE_TAR_VFS_FOR_ALL_READS) && defined(RT_UNUSED_API)
    12281447RTR3DECL(int) RTTarFileGetOwner(RTTARFILE hFile, uint32_t *pUid, uint32_t *pGid)
    12291448{
     
    12521471    return rc;
    12531472}
     1473#endif
    12541474
    12551475RTR3DECL(int) RTTarFileSetOwner(RTTARFILE hFile, uint32_t uid, uint32_t gid)
     
    13041524 ******************************************************************************/
    13051525
     1526#ifndef RT_UNUSED_API
    13061527RTR3DECL(int) RTTarFileExists(const char *pszTarFile, const char *pszFile)
    13071528{
     
    13261547    return rc;
    13271548}
     1549#endif /* RT_UNUSED_API */
    13281550
    13291551RTR3DECL(int) RTTarList(const char *pszTarFile, char ***ppapszFiles, size_t *pcFiles)
     
    13391561    if (RT_FAILURE(rc))
    13401562        return rc;
     1563
     1564#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     1565    /*
     1566     * Enumerate the VFS file system stream.
     1567     */
     1568    size_t cFiles          = 0;
     1569    size_t cFilesAllocated = 0;
     1570    char **papszFiles      = NULL;
     1571    for (;;)
     1572    {
     1573        char           *pszName;
     1574        RTVFSOBJTYPE    enmType;
     1575        RTVFSOBJ        hVfsObj;
     1576        rc = RTVfsFsStrmNext(hTar->hVfsFss, &pszName, &enmType, &hVfsObj);
     1577        if (rc == VERR_EOF)
     1578        {
     1579            RTTarClose(hTar);
     1580            *pcFiles = cFiles;
     1581            *ppapszFiles = papszFiles;
     1582            return VINF_SUCCESS;
     1583        }
     1584        if (RT_FAILURE(rc))
     1585            break;
     1586
     1587        if (cFiles >= cFilesAllocated)
     1588        {
     1589            size_t cNew = !cFilesAllocated ? 64 : cFilesAllocated < _1M ? cFilesAllocated * 2 : cFilesAllocated + _1M;
     1590            void *pvNew = RTMemRealloc(papszFiles, cNew * sizeof(char *));
     1591            if (!pvNew)
     1592            {
     1593                rc = VERR_NO_MEMORY;
     1594                RTStrFree(pszName);
     1595                RTVfsObjRelease(hVfsObj);
     1596                break;
     1597            }
     1598            cFilesAllocated = cNew;
     1599            papszFiles = (char **)pvNew;
     1600        }
     1601
     1602        papszFiles[cFiles++] = pszName;
     1603
     1604        RTVfsObjRelease(hVfsObj);
     1605    } /* Search loop. */
     1606
     1607    /*
     1608     * Failed, clean up and return.
     1609     */
     1610    if (papszFiles)
     1611    {
     1612        while (cFiles-- > 0)
     1613            RTStrFree(papszFiles[cFiles]);
     1614        RTMemFree(papszFiles);
     1615    }
     1616
     1617#else /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    13411618
    13421619    /* This is done by internal methods, cause we didn't have a RTTARDIR
     
    14171694        RTMemFree(papszFiles);
    14181695    }
     1696#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    14191697
    14201698    RTTarClose(hTar);
     
    14231701}
    14241702
     1703#if 0 /* broken, using wrong offset when reading. fix+test when _really_ need - use the TAR VFS wherever possible! */
    14251704RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile,
    14261705                                    PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     
    14951774    return rc;
    14961775}
    1497 
     1776#endif
     1777
     1778#ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */
    14981779RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles,
    14991780                                size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     
    15481829    return rc;
    15491830}
    1550 
     1831#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     1832
     1833#ifndef RT_USE_TAR_VFS_FOR_ALL_READS /* Unused */
    15511834RTR3DECL(int) RTTarExtractAll(const char *pszTarFile, const char *pszOutputDir, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    15521835{
     
    15681851    return RTTarExtractFiles(pszTarFile, pszOutputDir, papszFiles, cFiles, pfnProgressCallback, pvUser);
    15691852}
     1853#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    15701854
    15711855RTR3DECL(int) RTTarCreate(const char *pszTarFile, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     
    16211905    RTTAR_VALID_RETURN(pInt);
    16221906
     1907#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     1908    if (!pInt->fStreamMode)
     1909        return VERR_INVALID_STATE;
     1910
     1911    if (!pInt->pszVfsCurName)
     1912    {
     1913        int rc = RTTarSeekNextFile(pInt);
     1914        if (RT_FAILURE(rc))
     1915            return rc;
     1916    }
     1917    Assert(pInt->pszVfsCurName);
     1918
     1919    if (ppszFilename)
     1920    {
     1921        *ppszFilename = RTStrDup(pInt->pszVfsCurName);
     1922        if (!*ppszFilename)
     1923            return VERR_NO_STR_MEMORY;
     1924    }
     1925
     1926    return pInt->hVfsCur != NIL_RTVFSIOSTREAM ? VINF_SUCCESS : VINF_TAR_DIR_PATH;
     1927
     1928#else  /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    16231929    /* Open and close the file on the current position. This makes sure the
    16241930     * cache is filled in case we never read something before. On success it
     
    16301936
    16311937    return rc;
     1938#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    16321939}
    16331940
     
    16371944    RTTAR_VALID_RETURN(pInt);
    16381945
    1639     int rc = VINF_SUCCESS;
    1640 
    16411946    if (!pInt->fStreamMode)
    16421947        return VERR_INVALID_STATE;
     1948
     1949#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     1950    /*
     1951     * Release the current object.
     1952     */
     1953    if (pInt->hVfsCur != NIL_RTVFSIOSTREAM)
     1954    {
     1955        RTVfsIoStrmRelease(pInt->hVfsCur);
     1956        pInt->hVfsCur = NIL_RTVFSIOSTREAM;
     1957    }
     1958
     1959    if (pInt->pszVfsCurName)
     1960    {
     1961        RTStrFree(pInt->pszVfsCurName);
     1962        pInt->pszVfsCurName = NULL;
     1963    }
     1964
     1965    /*
     1966     * Find the next file.
     1967     */
     1968    for (;;)
     1969    {
     1970        char           *pszName;
     1971        RTVFSOBJTYPE    enmType;
     1972        RTVFSOBJ        hVfsObj;
     1973        int rc = RTVfsFsStrmNext(hTar->hVfsFss, &pszName, &enmType, &hVfsObj);
     1974        if (rc == VERR_EOF)
     1975            return VERR_TAR_END_OF_FILE;
     1976
     1977        if (   enmType == RTVFSOBJTYPE_FILE
     1978            || enmType == RTVFSOBJTYPE_IO_STREAM
     1979            || enmType == RTVFSOBJTYPE_DIR)
     1980        {
     1981            pInt->pszVfsCurName = pszName;
     1982            if (enmType == RTVFSOBJTYPE_DIR)
     1983                rc = VINF_TAR_DIR_PATH;
     1984            else
     1985            {
     1986                pInt->hVfsCur = RTVfsObjToIoStream(hVfsObj);
     1987                Assert(pInt->hVfsCur != NIL_RTVFSIOSTREAM);
     1988                rc = VINF_SUCCESS;
     1989            }
     1990            RTVfsObjRelease(hVfsObj);
     1991            return rc;
     1992        }
     1993        RTStrFree(pszName);
     1994        RTVfsObjRelease(hVfsObj);
     1995    }
     1996
     1997#else  /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     1998    int rc = VINF_SUCCESS;
    16431999
    16442000    /* If there is nothing in the cache, it means we never read something. Just
     
    16752031    /* Again check the current filename to fill the cache with the new value. */
    16762032    return RTTarCurrentFile(hTar, NULL);
     2033#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    16772034}
    16782035
     
    16892046    if (!pInt->fStreamMode)
    16902047        return VERR_INVALID_STATE;
     2048
     2049#ifdef RT_USE_TAR_VFS_FOR_ALL_READS
     2050    /*
     2051     * Make sure there is a current file (first call w/o RTTarSeekNextFile call).
     2052     */
     2053    if (pInt->hVfsCur == NIL_RTVFSIOSTREAM)
     2054    {
     2055        if (pInt->pszVfsCurName)
     2056            return -VINF_TAR_DIR_PATH;
     2057
     2058        int rc = RTTarSeekNextFile(pInt);
     2059        if (RT_FAILURE(rc))
     2060            return rc;
     2061
     2062        if (pInt->hVfsCur == NIL_RTVFSIOSTREAM)
     2063            return -VINF_TAR_DIR_PATH;
     2064    }
     2065    Assert(pInt->pszVfsCurName);
     2066
     2067    /*
     2068     * Return a copy of the filename if requested.
     2069     */
     2070    if (ppszFilename)
     2071    {
     2072        *ppszFilename = RTStrDup(pInt->pszVfsCurName);
     2073        if (!*ppszFilename)
     2074            return VERR_NO_STR_MEMORY;
     2075    }
     2076
     2077    /*
     2078     * Create a handle for it.
     2079     */
     2080    int rc = rtTarFileCreateHandleForReadOnly(RTStrDup(pInt->pszVfsCurName), pInt->hVfsCur, RTFILE_O_READ, phFile);
     2081    if (RT_FAILURE(rc) && ppszFilename)
     2082    {
     2083        RTStrFree(*ppszFilename);
     2084        *ppszFilename = NULL;
     2085    }
     2086
     2087#else  /* !RT_USE_TAR_VFS_FOR_ALL_READS */
    16912088
    16922089    int rc = VINF_SUCCESS;
     
    17652162        *phFile = pFileInt;
    17662163
    1767     return rc;
    1768 }
    1769 
     2164#endif /* !RT_USE_TAR_VFS_FOR_ALL_READS */
     2165    return rc;
     2166}
     2167
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