Beispiel #1
0
/**
 * Attach a decompressor to the given source stream, replacing and releasing the
 * input handle with the decompressor.
 *
 * @returns Exit code.
 * @param   phVfsSrc        The input stream. Replaced on success.
 */
static RTEXITCODE gzipSetupDecompressor(PRTVFSIOSTREAM phVfsSrc)
{
    /*
     * Attach the decompressor to the input stream.
     */
    uint32_t fFlags = 0;
    fFlags |= RTZIPGZIPDECOMP_F_ALLOW_ZLIB_HDR;
    RTVFSIOSTREAM hVfsGunzip;
    int rc = RTZipGzipDecompressIoStream(*phVfsSrc, fFlags, &hVfsGunzip);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc);

    uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc);
    Assert(cRefs > 0); RT_NOREF_PV(cRefs);
    *phVfsSrc = hVfsGunzip;

#if 0
    /* This is a good place for testing stuff. */
    rc = RTVfsCreateReadAheadForIoStream(*phVfsSrc, 0, 16, _4K+1, &hVfsGunzip);
    AssertRC(rc);
    if (RT_SUCCESS(rc))
    {
        uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc);
        Assert(cRefs > 0);
        *phVfsSrc = hVfsGunzip;
    }
#endif

    return RTEXITCODE_SUCCESS;
}
Beispiel #2
0
static RTEXITCODE gzipDecompress(RTVFSIOSTREAM hVfsIn, RTVFSIOSTREAM hVfsOut)
{
    RTEXITCODE      rcExit;
    RTVFSIOSTREAM   hVfsGunzip;
    int rc = RTZipGzipDecompressIoStream(hVfsIn, 0 /*fFlags*/, &hVfsGunzip);
    if (RT_SUCCESS(rc))
    {
        rcExit = gzipPush(hVfsGunzip, hVfsOut);
        RTVfsIoStrmRelease(hVfsGunzip);
    }
    else
        rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc);
    return rcExit;
}
Beispiel #3
0
/**
 * Attach a decompressor to the given source stream, replacing and releasing the
 * input handle with the decompressor.
 *
 * @returns Exit code.
 * @param   phVfsSrc        The input stream. Replaced on success.
 */
static RTEXITCODE gzipSetupDecompressor(PRTVFSIOSTREAM phVfsSrc)
{
    /*
     * Attach the decompressor to the input stream.
     */
    uint32_t fFlags = 0;
    fFlags |= RTZIPGZIPDECOMP_F_ALLOW_ZLIB_HDR;
    RTVFSIOSTREAM hVfsGunzip;
    int rc = RTZipGzipDecompressIoStream(*phVfsSrc, fFlags, &hVfsGunzip);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc);

    uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc);
    Assert(cRefs > 0);
    *phVfsSrc = hVfsGunzip;

    return RTEXITCODE_SUCCESS;
}
/**
 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
 */
static DECLCALLBACK(int) rtVfsChainGunzip_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
                                                      PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
                                                      PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo)
{
    RT_NOREF(pProviderReg, pSpec, pElement, poffError, pErrInfo);
    AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE);

    RTVFSIOSTREAM hVfsIosIn = RTVfsObjToIoStream(hPrevVfsObj);
    if (hVfsIosIn == NIL_RTVFSIOSTREAM)
        return VERR_VFS_CHAIN_CAST_FAILED;

    RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM;
    int rc = RTZipGzipDecompressIoStream(hVfsIosIn, 0 /*fFlags*/, &hVfsIos);
    RTVfsObjFromIoStream(hVfsIosIn);
    if (RT_SUCCESS(rc))
    {
        *phVfsObj = RTVfsObjFromIoStream(hVfsIos);
        RTVfsIoStrmRelease(hVfsIos);
        if (*phVfsObj != NIL_RTVFSOBJ)
            return VINF_SUCCESS;
        rc = VERR_VFS_CHAIN_CAST_FAILED;
    }
    return rc;
}
Beispiel #5
0
/**
 * Opens the input archive specified by the options.
 *
 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + printed message.
 * @param   pOpts           The options.
 * @param   phVfsFss        Where to return the TAR filesystem stream handle.
 */
static RTEXITCODE rtZipTarCmdOpenInputArchive(PRTZIPTARCMDOPS pOpts, PRTVFSFSSTREAM phVfsFss)
{
    int rc;

    /*
     * Open the input file.
     */
    RTVFSIOSTREAM   hVfsIos;
    if (   pOpts->pszFile
        && strcmp(pOpts->pszFile, "-") != 0)
    {
        const char *pszError;
        rc = RTVfsChainOpenIoStream(pOpts->pszFile,
                                    RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
                                    &hVfsIos,
                                    &pszError);
        if (RT_FAILURE(rc))
        {
            if (pszError && *pszError)
                return RTMsgErrorExit(RTEXITCODE_FAILURE,
                                      "RTVfsChainOpenIoStream failed with rc=%Rrc:\n"
                                      "    '%s'\n",
                                      "     %*s^\n",
                                      rc, pOpts->pszFile, pszError - pOpts->pszFile, "");
            return RTMsgErrorExit(RTEXITCODE_FAILURE,
                                  "Failed with %Rrc opening the input archive '%s'", rc, pOpts->pszFile);
        }
    }
    else
    {
        rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT,
                                      RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
                                      true /*fLeaveOpen*/,
                                      &hVfsIos);
        if (RT_FAILURE(rc))
            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to prepare standard in for reading: %Rrc", rc);
    }

    /*
     * Pass it thru a decompressor?
     */
    RTVFSIOSTREAM hVfsIosDecomp = NIL_RTVFSIOSTREAM;
    switch (pOpts->chZipper)
    {
        /* no */
        case '\0':
            rc = VINF_SUCCESS;
            break;

        /* gunzip */
        case 'z':
            rc = RTZipGzipDecompressIoStream(hVfsIos, 0 /*fFlags*/, &hVfsIosDecomp);
            if (RT_FAILURE(rc))
                RTMsgError("Failed to open gzip decompressor: %Rrc", rc);
            break;

        /* bunzip2 */
        case 'j':
            rc = VERR_NOT_SUPPORTED;
            RTMsgError("bzip2 is not supported by this build");
            break;

        /* bug */
        default:
            rc = VERR_INTERNAL_ERROR_2;
            RTMsgError("unknown decompression method '%c'",  pOpts->chZipper);
            break;
    }
    if (RT_FAILURE(rc))
    {
        RTVfsIoStrmRelease(hVfsIos);
        return RTEXITCODE_FAILURE;
    }

    if (hVfsIosDecomp != NIL_RTVFSIOSTREAM)
    {
        RTVfsIoStrmRelease(hVfsIos);
        hVfsIos = hVfsIosDecomp;
        hVfsIosDecomp = NIL_RTVFSIOSTREAM;
    }

    /*
     * Open the filesystem stream.
     */
    if (pOpts->enmFormat == RTZIPTARFORMAT_TAR)
        rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
    else if (pOpts->enmFormat == RTZIPTARFORMAT_XAR)
#ifdef IPRT_WITH_XAR /* Requires C++ and XML, so only in some configruation of IPRT. */
        rc = RTZipXarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
#else
        rc = VERR_NOT_SUPPORTED;
#endif
    else /** @todo make RTZipTarFsStreamFromIoStream fail if not tar file! */
Beispiel #6
0
/**
 * Rewinds the tarball file handle and creates a gunzip | tar chain that
 * results in a filesystem stream.
 *
 * @returns VBox status code, failures with message.
 * @param   hTarballFile        The handle to the tarball file.
 * @param   pszError            Where to store an error message on failure.
 * @param   cbError             The size of the buffer @a pszError points to.
 * @param   phTarFss            Where to return the filesystem stream handle.
 * @param   phFileManifest      Where to return a manifest where the tarball is
 *                              gettting hashed.  The entry will be called
 *                              "extpack" and be ready when the file system
 *                              stream is at an end.  Optional.
 */
int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss,
                          PRTMANIFEST phFileManifest)
{
    Assert(cbError > 0);
    *pszError = '\0';
    *phTarFss = NIL_RTVFSFSSTREAM;

    /*
     * Rewind the file and set up a VFS chain for it.
     */
    int rc = RTFileSeek(hTarballFile, 0, RTFILE_SEEK_BEGIN, NULL);
    if (RT_FAILURE(rc))
        return vboxExtPackReturnError(rc, pszError, cbError, "Failed seeking to the start of the tarball: %Rrc", rc);

    RTVFSIOSTREAM hTarballIos;
    rc = RTVfsIoStrmFromRTFile(hTarballFile, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN, true /*fLeaveOpen*/,
                               &hTarballIos);
    if (RT_FAILURE(rc))
        return vboxExtPackReturnError(rc, pszError, cbError, "RTVfsIoStrmFromRTFile failed: %Rrc", rc);

    RTMANIFEST hFileManifest = NIL_RTMANIFEST;
    rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);
    if (RT_SUCCESS(rc))
    {
        RTVFSIOSTREAM hPtIos;
        rc = RTManifestEntryAddPassthruIoStream(hFileManifest, hTarballIos, "extpack", RTMANIFEST_ATTR_SHA256,
                                                true /*read*/, &hPtIos);
        if (RT_SUCCESS(rc))
        {
            RTVFSIOSTREAM hGunzipIos;
            rc = RTZipGzipDecompressIoStream(hPtIos, 0 /*fFlags*/, &hGunzipIos);
            if (RT_SUCCESS(rc))
            {
                RTVFSFSSTREAM hTarFss;
                rc = RTZipTarFsStreamFromIoStream(hGunzipIos, 0 /*fFlags*/, &hTarFss);
                if (RT_SUCCESS(rc))
                {
                    RTVfsIoStrmRelease(hPtIos);
                    RTVfsIoStrmRelease(hGunzipIos);
                    RTVfsIoStrmRelease(hTarballIos);
                    *phTarFss = hTarFss;
                    if (phFileManifest)
                        *phFileManifest = hFileManifest;
                    else
                        RTManifestRelease(hFileManifest);
                    return VINF_SUCCESS;
                }

                vboxExtPackSetError(pszError, cbError, "RTZipTarFsStreamFromIoStream failed: %Rrc", rc);
                RTVfsIoStrmRelease(hGunzipIos);
            }
            else
                vboxExtPackSetError(pszError, cbError, "RTZipGzipDecompressIoStream failed: %Rrc", rc);
            RTVfsIoStrmRelease(hPtIos);
        }
        else
            vboxExtPackSetError(pszError, cbError, "RTManifestEntryAddPassthruIoStream failed: %Rrc", rc);
        RTManifestRelease(hFileManifest);
    }
    else
        vboxExtPackSetError(pszError, cbError, "RTManifestCreate failed: %Rrc", rc);

    RTVfsIoStrmRelease(hTarballIos);
    return rc;
}