VirtualBox

Ignore:
Timestamp:
Nov 5, 2010 5:16:12 PM (14 years ago)
Author:
vboxsync
Message:

iprt/tar.h: some review, clean and adding documentation.

File:
1 edited

Legend:

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

    r33540 r33804  
    4141#include <iprt/string.h>
    4242
     43
    4344/******************************************************************************
    4445 *   Structures and Typedefs                                                  *
     
    5859/** @} */
    5960
     61/**
     62 * A tar file header.
     63 */
    6064typedef union RTTARRECORD
    6165{
     
    7983    } h;
    8084} RTTARRECORD;
    81 typedef RTTARRECORD *PRTTARRECORD;
    8285AssertCompileSize(RTTARRECORD, 512);
    8386AssertCompileMemberOffset(RTTARRECORD, h.size, 100+8*3);
     87/** Pointer to a tar file header. */
     88typedef RTTARRECORD *PRTTARRECORD;
     89
    8490
    8591#if 0 /* not currently used */
     
    9298#endif
    9399
    94 typedef struct RTTARFILEINTERNAL* PRTTARFILEINTERNAL;
     100/** Pointer to a tar file handle. */
     101typedef struct RTTARFILEINTERNAL *PRTTARFILEINTERNAL;
     102
     103/**
     104 * The internal data of a tar handle.
     105 */
    95106typedef struct RTTARINTERNAL
    96107{
     108    /** The magic (RTTAR_MAGIC). */
     109    uint32_t            u32Magic;
     110    /** The handle to the tar file. */
     111    RTFILE              hTarFile;
     112    /** The open mode for hTarFile. */
     113    uint32_t            fOpenMode;
     114    /** Whether a file within the archive is currently open for writing.
     115     * Only one can be open.  */
     116    bool                fFileOpenForWrite;
     117    /** Whether operating in stream mode. */
     118    bool                fStreamMode;
     119    /** The file cache of one file.  */
     120    PRTTARFILEINTERNAL  pFileCache;
     121} RTTARINTERNAL;
     122/** Pointer to a the internal data of a tar handle.  */
     123typedef RTTARINTERNAL* PRTTARINTERNAL;
     124
     125/**
     126 * The internal data of a file within a tar file.
     127 */
     128typedef struct RTTARFILEINTERNAL
     129{
     130    /** The magic (RTTARFILE_MAGIC). */
    97131    uint32_t        u32Magic;
    98     RTFILE          hTarFile;
    99     bool            fFileOpenForWrite;
    100     uint32_t        fOpenMode;
    101     bool            fStreamMode;
    102     PRTTARFILEINTERNAL pFileCache;
    103 } RTTARINTERNAL;
    104 typedef RTTARINTERNAL* PRTTARINTERNAL;
    105 
    106 typedef struct RTTARFILEINTERNAL
    107 {
    108     uint32_t        u32Magic;
     132    /** Pointer to back to the tar file. */
    109133    PRTTARINTERNAL  pTar;
     134    /** The name of the file. */
    110135    char           *pszFilename;
    111     uint64_t        uStart;
     136    /** The offset into the archive where the file header starts. */
     137    uint64_t        offStart;
     138    /** The size of the file. */
    112139    uint64_t        cbSize;
     140    /** The size set by RTTarFileSetSize(). */
    113141    uint64_t        cbSetSize;
    114     uint64_t        uCurrentPos;
     142    /** The current offset within this file. */
     143    uint64_t        offCurrent;
     144    /** The open mode. */
    115145    uint32_t        fOpenMode;
    116146} RTTARFILEINTERNAL;
    117 typedef RTTARFILEINTERNAL* PRTTARFILEINTERNAL;
     147/** Pointer to the internal data of a tar file.  */
     148typedef RTTARFILEINTERNAL *PRTTARFILEINTERNAL;
     149
    118150
    119151/******************************************************************************
     
    155187    } while (0)
    156188
     189
    157190/******************************************************************************
    158191 *   Internal Functions                                                       *
     
    220253}
    221254
    222 DECLINLINE(int) rtTarCreateHeaderRecord(PRTTARRECORD pRecord, const char *pszSrcName, uint64_t cbSize, RTUID uid, RTGID gid, RTFMODE fmode, int64_t mtime)
    223 {
     255DECLINLINE(int) rtTarCreateHeaderRecord(PRTTARRECORD pRecord, const char *pszSrcName, uint64_t cbSize,
     256                                        RTUID uid, RTGID gid, RTFMODE fmode, int64_t mtime)
     257{
     258    /** @todo check for field overflows. */
    224259    /* Fill the header record */
    225260//    RT_ZERO(pRecord);
     
    236271
    237272    /* Create the checksum out of the new header */
    238     uint32_t chksum = 0;
    239     int rc = rtTarCalcChkSum(pRecord, &chksum);
     273    uint32_t uChkSum = 0;
     274    int rc = rtTarCalcChkSum(pRecord, &uChkSum);
    240275    if (RT_FAILURE(rc))
    241276        return rc;
    242277    /* Format the checksum */
    243     RTStrPrintf(pRecord->h.chksum, sizeof(pRecord->h.chksum), "%0.7o", chksum);
     278    RTStrPrintf(pRecord->h.chksum, sizeof(pRecord->h.chksum), "%0.7o", uChkSum);
    244279
    245280    return VINF_SUCCESS;
    246281}
    247282
    248 DECLINLINE(void*) rtTarMemTmpAlloc(size_t *pcbSize)
     283DECLINLINE(void *) rtTarMemTmpAlloc(size_t *pcbSize)
    249284{
    250285    *pcbSize = 0;
    251     /* Allocate a reasonably large buffer, fall back on a tiny one. Note:
    252      * has to be 512 byte aligned and >= 512 byte. */
     286    /* Allocate a reasonably large buffer, fall back on a tiny one.
     287     * Note: has to be 512 byte aligned and >= 512 byte. */
    253288    size_t cbTmp = _1M;
    254289    void *pvTmp = RTMemTmpAlloc(cbTmp);
     
    298333    pFileInt->u32Magic = RTTARFILE_MAGIC;
    299334    pFileInt->pTar = pInt;
     335    pFileInt->fOpenMode = fOpen;
    300336    pFileInt->pszFilename = RTStrDup(pszFilename);
    301     pFileInt->fOpenMode = fOpen;
     337    if (!pFileInt->pszFilename)
     338    {
     339        RTMemFree(pFileInt);
     340        return NULL;
     341    }
    302342
    303343    return pFileInt;
     
    312352    memcpy(pNewInt, pInt, sizeof(RTTARFILEINTERNAL));
    313353    pNewInt->pszFilename = RTStrDup(pInt->pszFilename);
     354    if (!pNewInt->pszFilename)
     355    {
     356        RTMemFree(pNewInt);
     357        return NULL;
     358    }
    314359
    315360    return pNewInt;
     
    329374static int rtTarExtractFileToFile(RTTARFILE hFile, const char *pszTargetName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    330375{
     376    /* Open the target file */
    331377    RTFILE hNewFile;
    332     /* Open the target file */
    333378    int rc = RTFileOpen(&hNewFile, pszTargetName, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
    334379    if (RT_FAILURE(rc))
    335380        return rc;
    336381
    337     void *pvTmp = 0;
     382    void *pvTmp = NULL;
    338383    do
    339384    {
     
    346391            break;
    347392        }
     393
    348394        /* Get the size of the source file */
    349395        uint64_t cbToCopy = 0;
     
    351397        if (RT_FAILURE(rc))
    352398            break;
     399
    353400        /* Copy the content from hFile over to pszTargetName. */
    354401        uint64_t cbAllWritten = 0; /* Already copied */
     
    358405            if (pfnProgressCallback)
    359406                pfnProgressCallback((unsigned)(100.0 / cbOverallSize * cbOverallWritten), pvUser);
     407
    360408            /* Finished already? */
    361409            if (cbAllWritten == cbToCopy)
    362410                break;
     411
    363412            /* Read one block. */
    364413            cbRead = RT_MIN(cbToCopy - cbAllWritten, cbTmp);
     
    366415            if (RT_FAILURE(rc))
    367416                break;
     417
    368418            /* Write the block */
    369419            rc = RTFileWrite(hNewFile, pvTmp, cbRead, NULL);
    370420            if (RT_FAILURE(rc))
    371421                break;
     422
    372423            /* Count how many bytes are written already */
    373424            cbAllWritten += cbRead;
     
    375426        }
    376427
    377     }
    378     while(0);
     428    } while(0);
    379429
    380430    /* Cleanup */
     
    406456static int rtTarAppendFileFromFile(RTTAR hTar, const char *pszSrcName, const uint64_t cbOverallSize, uint64_t &cbOverallWritten, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    407457{
     458    /* Open the source file */
    408459    RTFILE hOldFile;
    409     /* Open the source file */
    410460    int rc = RTFileOpen(&hOldFile, pszSrcName, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    411461    if (RT_FAILURE(rc))
     
    413463
    414464    RTTARFILE hFile = NIL_RTTARFILE;
    415     void *pvTmp = 0;
     465    void *pvTmp = NULL;
    416466    do
    417467    {
     
    432482        RTFMODE fmode = 0600; /* Make some save default */
    433483        int64_t mtime = 0;
     484
    434485        /* This isn't critical. Use the defaults if it fails. */
    435486        rc = RTFileQueryInfo(hOldFile, &info, RTFSOBJATTRADD_UNIX);
     
    441492            mtime = RTTimeSpecGetSeconds(&info.ModificationTime);
    442493        }
     494
    443495        /* Set the mode from the other file */
    444496        rc = RTTarFileSetMode(hFile, fmode);
    445497        if (RT_FAILURE(rc))
    446498            break;
     499
    447500        /* Set the modification time from the other file */
    448501        RTTIMESPEC time;
     
    451504        if (RT_FAILURE(rc))
    452505            break;
     506
    453507        /* Set the owner from the other file */
    454508        rc = RTTarFileSetOwner(hFile, uid, gid);
     
    465519        }
    466520
    467         uint64_t cbAllWritten = 0; /* Already copied */
    468         uint64_t cbRead = 0; /* Actually read in the last step */
    469         uint64_t cbWrite = 0; /* Actually write in the last step */
    470521        /* Copy the content from pszSrcName over to hFile. This is done block
    471522         * wise in 512 byte steps. After this copying is finished hFile will be
    472523         * on a 512 byte boundary, regardless if the file copied is 512 byte
    473524         * size aligned. */
     525        uint64_t cbAllWritten = 0; /* Already copied */
     526        uint64_t cbRead       = 0; /* Actually read in the last step */
     527        uint64_t cbWrite      = 0; /* Actually write in the last step */
    474528        for (;;)
    475529        {
     
    478532            if (cbAllWritten >= cbToCopy)
    479533                break;
     534
    480535            /* Read one block. Either its the buffer size or the rest of the
    481536             * file. */
    482537            cbRead = RT_MIN(cbToCopy - cbAllWritten, cbTmp);
    483             /* Read one block */
    484538            rc = RTFileRead(hOldFile, pvTmp, cbRead, NULL);
    485539            if (RT_FAILURE(rc))
    486540                break;
     541
    487542            /* Write one block. */
    488543            rc = RTTarFileWriteAt(hFile, cbAllWritten, pvTmp, cbRead, NULL);
    489544            if (RT_FAILURE(rc))
    490545                break;
     546
    491547            /* Count how many bytes (of the original file) are written already */
    492548            cbAllWritten += cbRead;
    493549            cbOverallWritten += cbRead;
    494550        }
    495     }
    496     while(0);
     551    } while (0);
    497552
    498553    /* Cleanup */
     
    518573}
    519574
    520 static int rtTarFindFile(RTFILE hFile, const char *pszFile, uint64_t *puOffset, uint64_t *pcbSize)
     575static int rtTarFindFile(RTFILE hFile, const char *pszFile, uint64_t *poff, uint64_t *pcbSize)
    521576{
    522577    /* Assume we are on the file head. */
    523     int rc = VINF_SUCCESS;
    524     bool fFound = false;
     578    int         rc      = VINF_SUCCESS;
     579    bool        fFound = false;
    525580    RTTARRECORD record;
    526581    for (;;)
     
    531586        if (RT_FAILURE(rc))
    532587            break;
     588
    533589        /* We support normal files only */
    534590        if (   record.h.linkflag == LF_OLDNORMAL
     
    541597                if (RT_FAILURE(rc))
    542598                    break;
     599
    543600                /* Seek back, to position the file pointer at the start of the header. */
    544                 rc = RTFileSeek(hFile, -(int64_t)sizeof(RTTARRECORD), RTFILE_SEEK_CURRENT, puOffset);
     601                rc = RTFileSeek(hFile, -(int64_t)sizeof(RTTARRECORD), RTFILE_SEEK_CURRENT, poff);
    545602                fFound = true;
    546603                break;
     
    575632        if (RT_FAILURE(rc))
    576633            break;
     634
    577635        /* We support normal files only */
    578636        if (   record.h.linkflag == LF_OLDNORMAL
     
    583641                if (!RTStrCmp(record.h.name, papszFiles[i]))
    584642                {
    585                     uint64_t cbSize;
    586643                    /* Get the file size */
     644                    uint64_t cbSize = 0;
    587645                    rc = RTStrToUInt64Full(record.h.size, 8, &cbSize);
     646
    588647                    /* Sum up the overall size */
    589648                    *pcbOverallSize += cbSize;
     
    613672 ******************************************************************************/
    614673
    615 RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char* pszTarname, uint32_t fMode, bool fStream)
    616 {
    617     PRTTARINTERNAL pInt = (PRTTARINTERNAL)RTMemAllocZ(sizeof(RTTARINTERNAL));
    618     if (!pInt)
     674RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode, bool fStream)
     675{
     676    /*
     677     * Create a tar instance.
     678     */
     679    PRTTARINTERNAL pThis = (PRTTARINTERNAL)RTMemAllocZ(sizeof(RTTARINTERNAL));
     680    if (!pThis)
    619681        return VERR_NO_MEMORY;
    620682
    621     pInt->u32Magic = RTTAR_MAGIC;
    622     pInt->fOpenMode = fMode;
    623     pInt->fStreamMode = fStream && (fMode & RTFILE_O_READ);
    624 
    625     int rc = VINF_SUCCESS;
    626     do
    627     {
    628         /* Open the tar file. */
    629         rc = RTFileOpen(&pInt->hTarFile, pszTarname, fMode);
    630         if (RT_FAILURE(rc))
    631             break;
    632     }
    633     while(0);
    634 
    635     if (RT_FAILURE(rc))
    636     {
    637         /* Todo: remove if created by us */
    638         if (pInt->hTarFile)
    639             RTFileClose(pInt->hTarFile);
    640         RTMemFree(pInt);
    641     }else
    642         *phTar = (RTTAR)pInt;
    643 
     683    pThis->u32Magic    = RTTAR_MAGIC;
     684    pThis->fOpenMode   = fMode;
     685    pThis->fStreamMode = fStream && (fMode & RTFILE_O_READ);
     686
     687    /*
     688     * Open the tar file.
     689     */
     690    int rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode);
     691    if (RT_SUCCESS(rc))
     692    {
     693        *phTar = pThis;
     694        return VINF_SUCCESS;
     695    }
     696
     697    RTMemFree(pThis);
    644698    return rc;
    645699}
     
    666720#endif
    667721
    668     if (pInt->hTarFile)
     722    if (pInt->hTarFile != NIL_RTFILE)
    669723        rc = RTFileClose(pInt->hTarFile);
    670724
     
    673727    {
    674728        rtDeleteTarFileInternal(pInt->pFileCache);
    675         pInt->pFileCache = 0;
     729        pInt->pFileCache = NULL;
    676730    }
    677731
     
    709763
    710764    int rc = VINF_SUCCESS;
    711     do
     765    do /* break loop */
    712766    {
    713767        if (pFileInt->fOpenMode & RTFILE_O_WRITE)
    714768        {
    715769            pInt->fFileOpenForWrite = true;
     770
    716771            /* If we are in write mode, we also in append mode. Add an dummy
    717772             * header at the end of the current file. It will be filled by the
    718773             * close operation. */
    719             rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->uStart);
     774            rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart);
    720775            if (RT_FAILURE(rc))
    721776                break;
     
    732787            if (RT_FAILURE(rc))
    733788                break;
     789
    734790            /* Search for the file. */
    735             rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->uStart, &pFileInt->cbSize);
     791            rc = rtTarFindFile(pFileInt->pTar->hTarFile, pszFilename, &pFileInt->offStart, &pFileInt->cbSize);
    736792            if (RT_FAILURE(rc))
    737793                break;
     
    739795        else
    740796        {
    741         }
    742 
    743     }
    744     while(0);
     797            /** @todo is something missing here? */
     798        }
     799
     800    } while (0);
    745801
    746802    /* Cleanup on failure */
     
    773829        /* In read mode, we want to make sure to stay at the aligned end of this
    774830         * file, so the next file could be read immediately. */
    775         uint64_t uCurPos = RTFileTell(pFileInt->pTar->hTarFile);
     831        uint64_t offCur = RTFileTell(pFileInt->pTar->hTarFile);
     832
    776833        /* Check that the file pointer is somewhere within the last open file.
    777834         * If we are at the beginning (nothing read yet) nothing will be done.
    778835         * A user could open/close a file more than once, without reading
    779836         * something. */
    780         if (pFileInt->uStart + sizeof(RTTARRECORD) < uCurPos && uCurPos < RT_ALIGN(pFileInt->uStart + sizeof(RTTARRECORD) + pFileInt->cbSize, sizeof(RTTARRECORD)))
     837        if (   pFileInt->offStart + sizeof(RTTARRECORD) < offCur
     838            && offCur < RT_ALIGN(pFileInt->offStart + sizeof(RTTARRECORD) + pFileInt->cbSize, sizeof(RTTARRECORD)))
    781839        {
    782840            /* Seek to the next file header. */
    783             uint64_t uNextPos = RT_ALIGN(pFileInt->uStart + sizeof(RTTARRECORD) + pFileInt->cbSize, sizeof(RTTARRECORD));
    784             rc = RTFileSeek(pFileInt->pTar->hTarFile, uNextPos - uCurPos, RTFILE_SEEK_CURRENT, NULL);
     841            uint64_t offNext = RT_ALIGN(pFileInt->offStart + sizeof(RTTARRECORD) + pFileInt->cbSize, sizeof(RTTARRECORD));
     842            rc = RTFileSeek(pFileInt->pTar->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL);
    785843        }
    786844    }
     
    798856                    break;
    799857            }
     858
    800859            /* If the written size isn't 512 byte aligned, we need to fix this. */
    801860            RTTARRECORD record;
     
    805864            {
    806865                /* Note the RTFile method. We didn't increase the cbSize or cbCurrentPos here. */
    807                 rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + sizeof(RTTARRECORD) + pFileInt->cbSize, &record, cbSizeAligned - pFileInt->cbSize, NULL);
     866                rc = RTFileWriteAt(pFileInt->pTar->hTarFile,
     867                                   pFileInt->offStart + sizeof(RTTARRECORD) + pFileInt->cbSize,
     868                                   &record,
     869                                   cbSizeAligned - pFileInt->cbSize,
     870                                   NULL);
    808871                if (RT_FAILURE(rc))
    809872                    break;
    810873            }
     874
    811875            /* Create a header record for the file */
    812876            /* Todo: mode, gid, uid, mtime should be setable (or detected myself) */
    813877            RTTIMESPEC time;
    814878            RTTimeNow(&time);
    815             rc = rtTarCreateHeaderRecord(&record, pFileInt->pszFilename, pFileInt->cbSize, 0, 0, 0600, RTTimeSpecGetSeconds(&time));
     879            rc = rtTarCreateHeaderRecord(&record, pFileInt->pszFilename, pFileInt->cbSize,
     880                                         0, 0, 0600, RTTimeSpecGetSeconds(&time));
    816881            if (RT_FAILURE(rc))
    817882                break;
     883
    818884            /* Write this at the start of the file data */
    819             rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart, &record, sizeof(RTTARRECORD), NULL);
     885            rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart, &record, sizeof(RTTARRECORD), NULL);
    820886            if (RT_FAILURE(rc))
    821887                break;
     
    830896}
    831897
    832 RTR3DECL(int) RTTarFileSeek(RTTARFILE hFile, uint64_t uOffset, unsigned uMethod, uint64_t *poffActual)
     898RTR3DECL(int) RTTarFileSeek(RTTARFILE hFile, uint64_t offSeek, unsigned uMethod, uint64_t *poffActual)
    833899{
    834900    PRTTARFILEINTERNAL pFileInt = hFile;
     
    842908        case RTFILE_SEEK_BEGIN:
    843909        {
    844             if (uOffset > pFileInt->cbSize)
     910            if (offSeek > pFileInt->cbSize)
    845911                return VERR_SEEK_ON_DEVICE;
    846             pFileInt->uCurrentPos = uOffset;
     912            pFileInt->offCurrent = offSeek;
    847913            break;
    848914        }
    849915        case RTFILE_SEEK_CURRENT:
    850916        {
    851             if (pFileInt->uCurrentPos + uOffset > pFileInt->cbSize)
     917            if (pFileInt->offCurrent + offSeek > pFileInt->cbSize)
    852918                return VERR_SEEK_ON_DEVICE;
    853             pFileInt->uCurrentPos += uOffset;
     919            pFileInt->offCurrent += offSeek;
    854920            break;
    855921        }
    856922        case RTFILE_SEEK_END:
    857923        {
    858             if ((int64_t)pFileInt->cbSize - (int64_t)uOffset < 0)
     924            if ((int64_t)pFileInt->cbSize - (int64_t)offSeek < 0)
    859925                return VERR_NEGATIVE_SEEK;
    860             pFileInt->uCurrentPos = pFileInt->cbSize - uOffset;
     926            pFileInt->offCurrent = pFileInt->cbSize - offSeek;
    861927            break;
    862928        }
     
    870936{
    871937    PRTTARFILEINTERNAL pFileInt = hFile;
    872     RTTARFILE_VALID_RETURN_RC(pFileInt, ~0ULL);
    873 
    874     return pFileInt->uCurrentPos;
     938    RTTARFILE_VALID_RETURN_RC(pFileInt, UINT64_MAX);
     939
     940    return pFileInt->offCurrent;
    875941}
    876942
     
    881947
    882948    /* Todo: optimize this, by checking the current pos */
    883     return RTTarFileReadAt(hFile, pFileInt->uCurrentPos, pvBuf, cbToRead, pcbRead);
    884 }
    885 
    886 RTR3DECL(int) RTTarFileReadAt(RTTARFILE hFile, uint64_t uOffset, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     949    return RTTarFileReadAt(hFile, pFileInt->offCurrent, pvBuf, cbToRead, pcbRead);
     950}
     951
     952RTR3DECL(int) RTTarFileReadAt(RTTARFILE hFile, uint64_t off, void *pvBuf, size_t cbToRead, size_t *pcbRead)
    887953{
    888954    PRTTARFILEINTERNAL pFileInt = hFile;
     
    890956
    891957    /* Check that we not read behind the end of file. If so return immediately. */
    892     if (uOffset > pFileInt->cbSize)
     958    if (off > pFileInt->cbSize)
    893959    {
    894960        if (pcbRead)
     
    897963    }
    898964
    899     size_t cbToCopy = RT_MIN(pFileInt->cbSize - uOffset, cbToRead);
     965    size_t cbToCopy = RT_MIN(pFileInt->cbSize - off, cbToRead);
    900966    size_t cbTmpRead = 0;
    901     int rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->uStart + 512 + uOffset, pvBuf, cbToCopy, &cbTmpRead);
    902     pFileInt->uCurrentPos = uOffset + cbTmpRead;
     967    int rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->offStart + 512 + off, pvBuf, cbToCopy, &cbTmpRead);
     968    pFileInt->offCurrent = off + cbTmpRead;
    903969    if (pcbRead)
    904970        *pcbRead = cbTmpRead;
     
    912978    RTTARFILE_VALID_RETURN(pFileInt);
    913979
    914     /* Todo: optimize this, by checking the current pos */
    915     return RTTarFileWriteAt(hFile, pFileInt->uCurrentPos, pvBuf, cbToWrite, pcbWritten);
    916 }
    917 
    918 RTR3DECL(int) RTTarFileWriteAt(RTTARFILE hFile, uint64_t uOffset, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
     980    /** @todo Optimize this, by checking the current pos */
     981    return RTTarFileWriteAt(hFile, pFileInt->offCurrent, pvBuf, cbToWrite, pcbWritten);
     982}
     983
     984RTR3DECL(int) RTTarFileWriteAt(RTTARFILE hFile, uint64_t off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
    919985{
    920986    PRTTARFILEINTERNAL pFileInt = hFile;
     
    925991
    926992    size_t cbTmpWritten = 0;
    927     int rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + 512 + uOffset, pvBuf, cbToWrite, &cbTmpWritten);
     993    int rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart + 512 + off, pvBuf, cbToWrite, &cbTmpWritten);
    928994    pFileInt->cbSize += cbTmpWritten;
    929     pFileInt->uCurrentPos = uOffset + cbTmpWritten;
     995    pFileInt->offCurrent = off + cbTmpWritten;
    930996    if (pcbWritten)
    931997        *pcbWritten = cbTmpWritten;
     
    9551021        return VERR_WRITE_ERROR;
    9561022
    957     /* Todo: if cbSize is smaller than pFileInt->cbSize we have to truncate the
    958        current file. */
     1023    /** @todo If cbSize is smaller than pFileInt->cbSize we have to
     1024     * truncate the current file. */
    9591025    pFileInt->cbSetSize = cbSize;
    9601026
     
    9711037
    9721038    /* Read the mode out of the header entry */
    973     char mode[8];
    974     int rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.mode), mode, 8, NULL);
     1039    char szMode[RT_SIZEOFMEMB(RTTARRECORD, h.mode)+1];
     1040    int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
     1041                          pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mode),
     1042                          szMode,
     1043                          RT_SIZEOFMEMB(RTTARRECORD, h.mode),
     1044                          NULL);
    9751045    if (RT_FAILURE(rc))
    9761046        return rc;
     1047    szMode[sizeof(szMode) - 1] = '\0';
     1048
    9771049    /* Convert it to an integer */
    978     return RTStrToUInt32Full(mode, 8, pfMode);
     1050    return RTStrToUInt32Full(szMode, 8, pfMode);
    9791051}
    9801052
     
    9881060
    9891061    /* Convert the mode to an string. */
    990     char mode[8];
    991     RTStrPrintf(mode, sizeof(mode), "%0.7o", fMode);
     1062    char szMode[RT_SIZEOFMEMB(RTTARRECORD, h.mode)];
     1063    RTStrPrintf(szMode, sizeof(szMode), "%0.7o", fMode);
     1064
    9921065    /* Write it directly into the header */
    993     return RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.mode), mode, 8, NULL);
     1066    return RTFileWriteAt(pFileInt->pTar->hTarFile,
     1067                         pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mode),
     1068                         szMode,
     1069                         RT_SIZEOFMEMB(RTTARRECORD, h.mode),
     1070                         NULL);
    9941071}
    9951072
     
    10001077
    10011078    /* Read the time out of the header entry */
    1002     char mtime[12];
    1003     int rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.mtime), mtime, 12, NULL);
     1079    char szModTime[RT_SIZEOFMEMB(RTTARRECORD, h.mtime) + 1];
     1080    int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
     1081                          pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mtime),
     1082                          szModTime,
     1083                          RT_SIZEOFMEMB(RTTARRECORD, h.mtime),
     1084                          NULL);
    10041085    if (RT_FAILURE(rc))
    10051086        return rc;
     1087    szModTime[sizeof(szModTime) - 1] = '\0';
     1088
    10061089    /* Convert it to an integer */
    1007     int64_t tmpSeconds;
    1008     rc = RTStrToInt64Full(mtime, 12, &tmpSeconds);
     1090    int64_t cSeconds;
     1091    rc = RTStrToInt64Full(szModTime, 12, &cSeconds);
     1092
    10091093    /* And back to our time structure */
    10101094    if (RT_SUCCESS(rc))
    1011         RTTimeSpecSetSeconds(pTime, tmpSeconds);
     1095        RTTimeSpecSetSeconds(pTime, cSeconds);
    10121096
    10131097    return rc;
     
    10231107
    10241108    /* Convert the time to an string. */
    1025     char mtime[12];
    1026     RTStrPrintf(mtime, sizeof(mtime), "%0.11o", RTTimeSpecGetSeconds(pTime));
     1109    char szModTime[RT_SIZEOFMEMB(RTTARRECORD, h.mtime)];
     1110    RTStrPrintf(szModTime, sizeof(szModTime), "%0.11o", RTTimeSpecGetSeconds(pTime));
     1111
    10271112    /* Write it directly into the header */
    1028     return RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.mtime), mtime, 12, NULL);
     1113    return RTFileWriteAt(pFileInt->pTar->hTarFile,
     1114                         pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.mtime),
     1115                         szModTime,
     1116                         RT_SIZEOFMEMB(RTTARRECORD, h.mtime),
     1117                         NULL);
    10291118}
    10301119
     
    10351124
    10361125    /* Read the uid and gid out of the header entry */
    1037     char uid[8];
    1038     int rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.uid), uid, 8, NULL);
     1126    AssertCompileAdjacentMembers(RTTARRECORD, h.uid, h.gid);
     1127    char szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid) + RT_SIZEOFMEMB(RTTARRECORD, h.gid) + 1];
     1128    int rc = RTFileReadAt(pFileInt->pTar->hTarFile,
     1129                          pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.uid),
     1130                          szUidGid,
     1131                          sizeof(szUidGid) - 1,
     1132                          NULL);
    10391133    if (RT_FAILURE(rc))
    10401134        return rc;
    1041     char gid[8];
    1042     rc = RTFileReadAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.gid), gid, 8, NULL);
    1043     if (RT_FAILURE(rc))
    1044         return rc;
     1135    szUidGid[sizeof(szUidGid) - 1] = '\0';
     1136
    10451137    /* Convert it to integer */
    1046     rc = RTStrToUInt32Full(uid, 8, pUid);
    1047     if (RT_FAILURE(rc))
    1048         return rc;
    1049 
    1050     return RTStrToUInt32Full(gid, 8, pGid);
     1138    rc = RTStrToUInt32Full(&szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid)], 8, pGid);
     1139    if (RT_SUCCESS(rc))
     1140    {
     1141        szUidGid[RT_SIZEOFMEMB(RTTARRECORD, h.uid)] = '\0';
     1142        rc = RTStrToUInt32Full(szUidGid, 8, pUid);
     1143    }
     1144    return rc;
    10511145}
    10521146
     
    10581152    if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE)
    10591153        return VERR_WRITE_ERROR;
     1154    AssertReturn(uid == (uint32_t)-1 || uid <= 07777777, VERR_OUT_OF_RANGE);
     1155    AssertReturn(gid == (uint32_t)-1 || gid <= 07777777, VERR_OUT_OF_RANGE);
    10601156
    10611157    int rc = VINF_SUCCESS;
     
    10641160    {
    10651161        /* Convert the uid to an string. */
    1066         char tmpUid[8];
    1067         RTStrPrintf(tmpUid, sizeof(tmpUid), "%0.7o", uid);
     1162        char szUid[RT_SIZEOFMEMB(RTTARRECORD, h.uid)];
     1163        RTStrPrintf(szUid, sizeof(szUid), "%0.7o", uid);
     1164
    10681165        /* Write it directly into the header */
    1069         rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.uid), tmpUid, 8, NULL);
     1166        rc = RTFileWriteAt(pFileInt->pTar->hTarFile,
     1167                           pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.uid),
     1168                           szUid,
     1169                           RT_SIZEOFMEMB(RTTARRECORD, h.uid),
     1170                           NULL);
    10701171        if (RT_FAILURE(rc))
    10711172            return rc;
    10721173    }
     1174
    10731175    if (gid != (uint32_t)-1)
    10741176    {
    10751177        /* Convert the gid to an string. */
    1076         char tmpGid[8];
    1077         RTStrPrintf(tmpGid, sizeof(tmpGid), "%0.7o", gid);
     1178        char szGid[RT_SIZEOFMEMB(RTTARRECORD, h.gid)];
     1179        RTStrPrintf(szGid, sizeof(szGid), "%0.7o", gid);
     1180
    10781181        /* Write it directly into the header */
    1079         rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + RT_OFFSETOF(RTTARRECORD, h.gid), tmpGid, 8, NULL);
     1182        rc = RTFileWriteAt(pFileInt->pTar->hTarFile,
     1183                           pFileInt->offStart + RT_OFFSETOF(RTTARRECORD, h.gid),
     1184                           szGid,
     1185                           RT_SIZEOFMEMB(RTTARRECORD, h.gid),
     1186                           NULL);
    10801187        if (RT_FAILURE(rc))
    10811188            return rc;
     
    10971204    /* Open the tar file */
    10981205    RTTAR hTar;
    1099     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false);
     1206    int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    11001207    if (RT_FAILURE(rc))
    11011208        return rc;
     
    11211228    /* Open the tar file */
    11221229    RTTAR hTar;
    1123     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false);
     1230    int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    11241231    if (RT_FAILURE(rc))
    11251232        return rc;
     
    11291236
    11301237    PRTTARINTERNAL pInt = hTar;
    1131     char **papszFiles = 0;
     1238    char **papszFiles = NULL;
    11321239    size_t cFiles = 0;
    1133     do
     1240    do /* break loop */
    11341241    {
    11351242        /* Initialize the file name array with one slot */
    11361243        size_t cFilesAlloc = 1;
    1137         papszFiles = (char**)RTMemAlloc(sizeof(char *));
     1244        papszFiles = (char **)RTMemAlloc(sizeof(char *));
    11381245        if (!papszFiles)
    11391246        {
    1140             return VERR_NO_MEMORY;
     1247            rc = VERR_NO_MEMORY;
    11411248            break;
    11421249        }
     
    11851292                break;
    11861293        }
    1187     }
    1188     while(0);
     1294    } while(0);
    11891295
    11901296    if (rc == VERR_TAR_END_OF_FILE)
     
    12091315}
    12101316
    1211 RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    1212 {
    1213     /* Validate input */
     1317RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile,
     1318                                    PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     1319{
     1320    /*
     1321     * Validate input
     1322     */
    12141323    AssertPtrReturn(pszTarFile, VERR_INVALID_POINTER);
    12151324    AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
     
    12191328    AssertPtrNullReturn(pvUser, VERR_INVALID_POINTER);
    12201329
    1221     /* Todo: progress bar */
    1222 
    1223     int rc = VINF_SUCCESS;
    1224     RTTAR hTar = NIL_RTTAR;
    1225     RTTARFILE hFile = NIL_RTTARFILE;
    1226     char *pvTmp = 0;
    1227     uint64_t cbToCopy = 0;
    1228     do
    1229     {
    1230         rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false);
     1330    /** @todo progress bar - is this TODO still valid? */
     1331
     1332    int         rc      = VINF_SUCCESS;
     1333    RTTAR       hTar    = NIL_RTTAR;
     1334    RTTARFILE   hFile  = NIL_RTTARFILE;
     1335    char       *pvTmp   = NULL;
     1336    uint64_t    cbToCopy= 0;
     1337    do /* break loop */
     1338    {
     1339        rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    12311340        if (RT_FAILURE(rc))
    12321341            break;
     
    12371346        if (RT_FAILURE(rc))
    12381347            break;
     1348
    12391349        /* Allocate the memory for the file content. */
    1240         pvTmp = (char*)RTMemAlloc(cbToCopy);
     1350        pvTmp = (char *)RTMemAlloc(cbToCopy);
    12411351        if (!pvTmp)
    12421352        {
     
    12571367            cbAllRead += cbRead;
    12581368        }
    1259     }
    1260     while(0);
     1369    } while (0);
    12611370
    12621371    /* Set output values on success */
     
    12791388}
    12801389
    1281 RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
     1390RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles,
     1391                                size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
    12821392{
    12831393    /* Validate input */
     
    12911401    /* Open the tar file */
    12921402    RTTAR hTar;
    1293     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false);
     1403    int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, false /*fStream*/);
    12941404    if (RT_FAILURE(rc))
    12951405        return rc;
    12961406
    1297     do
     1407    do /* break loop */
    12981408    {
    12991409        /* Get the overall size of all files to extract out of the tar archive
     
    13151425                break;
    13161426            char *pszTargetFile = RTPathJoinA(pszOutputDir, papszFiles[i]);
    1317             if (!pszTargetFile)
    1318             {
     1427            if (pszTargetFile)
     1428                rc = rtTarExtractFileToFile(hFile, pszTargetFile, cbOverallSize, cbOverallWritten, pfnProgressCallback, pvUser);
     1429            else
    13191430                rc = VERR_NO_STR_MEMORY;
    1320                 break;
    1321             }
    1322             rc = rtTarExtractFileToFile(hFile, pszTargetFile, cbOverallSize, cbOverallWritten, pfnProgressCallback, pvUser);
    13231431            RTStrFree(pszTargetFile);
    13241432            RTTarFileClose(hFile);
     
    13261434                break;
    13271435        }
    1328     }
    1329     while(0);
     1436    } while (0);
    13301437
    13311438    RTTarClose(hTar);
     
    13641471
    13651472    RTTAR hTar;
    1366     int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_CREATE | RTFILE_O_READWRITE | RTFILE_O_DENY_NONE, false);
     1473    int rc = RTTarOpen(&hTar, pszTarFile, RTFILE_O_CREATE | RTFILE_O_READWRITE | RTFILE_O_DENY_NONE, false /*fStream*/);
    13671474    if (RT_FAILURE(rc))
    13681475        return rc;
     
    14311538    if (!pInt->pFileCache)
    14321539    {
    1433         rc = RTTarCurrentFile(hTar, 0);
     1540        rc = RTTarCurrentFile(hTar, NULL);
    14341541        if (RT_FAILURE(rc))
    14351542            return rc;
     
    14381545    /* Check that the file pointer is somewhere within the last open file.
    14391546     * If not we are somehow busted. */
    1440     uint64_t uCurPos = RTFileTell(pInt->hTarFile);
    1441     if (!(pInt->pFileCache->uStart <= uCurPos && uCurPos < pInt->pFileCache->uStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize))
     1547    uint64_t offCur = RTFileTell(pInt->hTarFile);
     1548    if (!(   pInt->pFileCache->offStart <= offCur
     1549          && offCur < pInt->pFileCache->offStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize))
    14421550        return VERR_INVALID_STATE;
    14431551
    14441552    /* Seek to the next file header. */
    1445     uint64_t uNextPos = RT_ALIGN(pInt->pFileCache->uStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize, sizeof(RTTARRECORD));
    1446     rc = RTFileSeek(pInt->hTarFile, uNextPos - uCurPos, RTFILE_SEEK_CURRENT, NULL);
     1553    uint64_t offNext = RT_ALIGN(pInt->pFileCache->offStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize, sizeof(RTTARRECORD));
     1554    rc = RTFileSeek(pInt->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL);
    14471555    if (RT_FAILURE(rc))
    14481556        return rc;
    14491557
    14501558    /* Again check the current filename to fill the cache with the new value. */
    1451     return RTTarCurrentFile(hTar, 0);
     1559    return RTTarCurrentFile(hTar, NULL);
    14521560}
    14531561
     
    14711579    {
    14721580        /* Are we still direct behind that header? */
    1473         if (pInt->pFileCache->uStart + sizeof(RTTARRECORD) == RTFileTell(pInt->hTarFile))
     1581        if (pInt->pFileCache->offStart + sizeof(RTTARRECORD) == RTFileTell(pInt->hTarFile))
    14741582        {
    14751583            /* Yes, so the streaming can start. Just return the cached file
     
    14791587                *ppszFilename = RTStrDup(pInt->pFileCache->pszFilename);
    14801588            return VINF_SUCCESS;
    1481         }else
    1482         {
    1483             /* Else delete the last open file cache. Might be recreated below. */
    1484             rtDeleteTarFileInternal(pInt->pFileCache);
    1485             pInt->pFileCache = 0;
    1486         }
    1487     }
    1488 
    1489     PRTTARFILEINTERNAL pFileInt = 0;
    1490     do
     1589        }
     1590
     1591        /* Else delete the last open file cache. Might be recreated below. */
     1592        rtDeleteTarFileInternal(pInt->pFileCache);
     1593        pInt->pFileCache = NULL;
     1594    }
     1595
     1596    PRTTARFILEINTERNAL pFileInt = NULL;
     1597    do /* break loop */
    14911598    {
    14921599        /* Try to read a header entry from the current position. If we aren't
     
    14991606        if (RT_FAILURE(rc))
    15001607            break;
     1608
    15011609        /* We support normal files only */
    15021610        if (   record.h.linkflag == LF_OLDNORMAL
     
    15091617                break;
    15101618            }
     1619
    15111620            /* Get the file size */
    15121621            rc = RTStrToUInt64Full(record.h.size, 8, &pFileInt->cbSize);
    15131622            if (RT_FAILURE(rc))
    15141623                break;
     1624
    15151625            /* The start is -512 from here. */
    1516             pFileInt->uStart = RTFileTell(pInt->hTarFile) - sizeof(RTTARRECORD);
     1626            pFileInt->offStart = RTFileTell(pInt->hTarFile) - sizeof(RTTARRECORD);
     1627
    15171628            /* Copy the new file structure to our cache. */
    15181629            pInt->pFileCache = rtCopyTarFileInternal(pFileInt);
     
    15201631                *ppszFilename = RTStrDup(pFileInt->pszFilename);
    15211632        }
    1522     }while (0);
     1633    } while (0);
    15231634
    15241635    if (RT_FAILURE(rc))
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