int main(int argc, char **argv)
{
    /*
     * Initialize IPRT and create the test.
     */
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstRTFilesystem", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    /*
     * If no args, display usage.
     */
    if (argc < 2)
    {
        RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Syntax: %s <image>\n", argv[0]);
        return RTTestSkipAndDestroy(hTest, "Missing required arguments\n");
    }

    /* Open image. */
    RTFILE hFile;
    RTVFSFILE hVfsFile;
    rc = RTFileOpen(&hFile, argv[1], RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ);
    if (RT_FAILURE(rc))
    {
        RTTestIFailed("RTFileOpen -> %Rrc", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    rc = RTVfsFileFromRTFile(hFile, 0, false, &hVfsFile);
    if (RT_FAILURE(rc))
    {
        RTTestIFailed("RTVfsFileFromRTFile -> %Rrc", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    rc = tstRTFilesystem(hTest, hVfsFile);

    RTTESTI_CHECK(rc == VINF_SUCCESS);

    RTVfsFileRelease(hVfsFile);

    /*
     * Summary
     */
    return RTTestSummaryAndDestroy(hTest);
}
Example #2
0
File: tar.cpp Project: mcenirm/vbox
RTR3DECL(int) RTTarFileOpen(RTTAR hTar, PRTTARFILE phFile, const char *pszFilename, uint32_t fOpen)
{
    /* Write only interface now. */
    AssertReturn(fOpen & RTFILE_O_WRITE, VERR_INVALID_PARAMETER);

    PRTTARINTERNAL pInt = hTar;
    RTTAR_VALID_RETURN(pInt);

    if (!pInt->hTarFile)
        return VERR_INVALID_HANDLE;

    if (fOpen & RTFILE_O_WRITE)
    {
        if (!(pInt->fOpenMode & RTFILE_O_WRITE))
            return VERR_WRITE_PROTECT;
        if (pInt->fFileOpenForWrite)
            return VERR_TOO_MANY_OPEN_FILES;
    }

    int rc = VINF_SUCCESS;
    if (!(fOpen & RTFILE_O_WRITE))
    {
        /*
         * Rewind the stream if necessary.
         */
        if (!pInt->fFssAtStart)
        {
            if (pInt->hVfsFss != NIL_RTVFSFSSTREAM)
            {
                uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX);
                pInt->hVfsFss  = NIL_RTVFSFSSTREAM;
            }

            if (pInt->hVfsFile == NIL_RTVFSFILE)
            {
                rc = RTVfsFileFromRTFile(pInt->hTarFile, RTFILE_O_READ, true /*fLeaveOpen*/, &pInt->hVfsFile);
                if (RT_FAILURE(rc))
                    return rc;
            }

            RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pInt->hVfsFile);
            rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pInt->hVfsFss);
            RTVfsIoStrmRelease(hVfsIos);
            if (RT_FAILURE(rc))
                return rc;
        }

        /*
         * Search the file system stream.
         */
        pInt->fFssAtStart = false;
        for (;;)
        {
            char           *pszName;
            RTVFSOBJTYPE    enmType;
            RTVFSOBJ        hVfsObj;
            rc = RTVfsFsStrmNext(pInt->hVfsFss, &pszName, &enmType, &hVfsObj);
            if (rc == VERR_EOF)
                return VERR_FILE_NOT_FOUND;
            if (RT_FAILURE(rc))
                return rc;

            if (!RTStrCmp(pszName, pszFilename))
            {
                if (enmType == RTVFSOBJTYPE_FILE || enmType == RTVFSOBJTYPE_IO_STREAM)
                    rc = rtTarFileCreateHandleForReadOnly(pszName, RTVfsObjToIoStream(hVfsObj), fOpen, phFile);
                else
                {
                    rc = VERR_UNEXPECTED_FS_OBJ_TYPE;
                    RTStrFree(pszName);
                }
                RTVfsObjRelease(hVfsObj);
                break;
            }
            RTStrFree(pszName);
            RTVfsObjRelease(hVfsObj);
        } /* Search loop. */
    }
    else
    {
        PRTTARFILEINTERNAL pFileInt = rtTarFileCreateForWrite(pInt, pszFilename, fOpen);
        if (!pFileInt)
            return VERR_NO_MEMORY;

        pInt->fFileOpenForWrite = true;

        /* If we are in write mode, we also in append mode. Add an dummy
         * header at the end of the current file. It will be filled by the
         * close operation. */
        rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart);
        if (RT_SUCCESS(rc))
        {
            RTTARRECORD record;
            RT_ZERO(record);
            rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL);
        }

        if (RT_SUCCESS(rc))
            *phFile = (RTTARFILE)pFileInt;
        else
        {
            /* Cleanup on failure */
            if (pFileInt->pszFilename)
                RTStrFree(pFileInt->pszFilename);
            RTMemFree(pFileInt);
        }
    }

    return rc;
}
Example #3
0
int main(int argc, char **argv)
{
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    /*
     * Parse the command line.
     */
    static const RTGETOPTDEF s_aOptions[] =
    {
        { "--ascii",        'a', RTGETOPT_REQ_NOTHING },
        { "--stdout",       'c', RTGETOPT_REQ_NOTHING },
        { "--to-stdout",    'c', RTGETOPT_REQ_NOTHING },
        { "--decompress",   'd', RTGETOPT_REQ_NOTHING },
        { "--uncompress",   'd', RTGETOPT_REQ_NOTHING },
        { "--force",        'f', RTGETOPT_REQ_NOTHING },
        { "--list",         'l', RTGETOPT_REQ_NOTHING },
        { "--no-name",      'n', RTGETOPT_REQ_NOTHING },
        { "--name",         'N', RTGETOPT_REQ_NOTHING },
        { "--quiet",        'q', RTGETOPT_REQ_NOTHING },
        { "--recursive",    'r', RTGETOPT_REQ_NOTHING },
        { "--suffix",       'S', RTGETOPT_REQ_STRING  },
        { "--test",         't', RTGETOPT_REQ_NOTHING },
        { "--verbose",      'v', RTGETOPT_REQ_NOTHING },
        { "--fast",         '1', RTGETOPT_REQ_NOTHING },
        { "-1",             '1', RTGETOPT_REQ_NOTHING },
        { "-2",             '2', RTGETOPT_REQ_NOTHING },
        { "-3",             '3', RTGETOPT_REQ_NOTHING },
        { "-4",             '4', RTGETOPT_REQ_NOTHING },
        { "-5",             '5', RTGETOPT_REQ_NOTHING },
        { "-6",             '6', RTGETOPT_REQ_NOTHING },
        { "-7",             '7', RTGETOPT_REQ_NOTHING },
        { "-8",             '8', RTGETOPT_REQ_NOTHING },
        { "-9",             '9', RTGETOPT_REQ_NOTHING },
        { "--best",         '9', RTGETOPT_REQ_NOTHING }
    };

    bool        fAscii      = false;
    bool        fStdOut     = false;
    bool        fDecompress = false;
    bool        fForce      = false;
    bool        fList       = false;
    bool        fName       = true;
    bool        fQuiet      = false;
    bool        fRecursive  = false;
    const char *pszSuff     = ".gz";
    bool        fTest       = false;
    unsigned    uLevel      = 6;

    RTEXITCODE  rcExit      = RTEXITCODE_SUCCESS;
    unsigned    cProcessed  = 0;
    RTVFSIOSTREAM hVfsStdOut= NIL_RTVFSIOSTREAM;

    RTGETOPTSTATE GetState;
    rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
                      RTGETOPTINIT_FLAGS_OPTS_FIRST);
    for (;;)
    {
        RTGETOPTUNION ValueUnion;
        rc = RTGetOpt(&GetState, &ValueUnion);
        switch (rc)
        {
        case 0:
        {
            /*
             * If we've processed any files we're done.  Otherwise take
             * input from stdin and write the output to stdout.
             */
            if (cProcessed > 0)
                return rcExit;
#if 0
            rc = RTVfsFileFromRTFile(1,
                                     RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
                                     true /*fLeaveOpen*/,
                                     &hVfsOut);


            if (!fForce && isStdHandleATty(fDecompress ? 0 : 1))
                return RTMsgErrorExit(RTEXITCODE_SYNTAX,
                                      "Yeah, right. I'm not %s any compressed data %s the terminal without --force.\n",
                                      fDecompress ? "reading" : "writing",
                                      fDecompress ? "from"    : "to");
#else
            rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "reading from standard input has not yet been implemented");
#endif
            return rcExit;
        }

        case VINF_GETOPT_NOT_OPTION:
        {
            if (!*pszSuff && !fStdOut)
                return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --suffix option specified an empty string");
            if (!fStdOut && RTVfsChainIsSpec(ValueUnion.psz))
                return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must use standard out with VFS chain specifications");

            RTEXITCODE rcExit2;
            if (fList)
                rcExit2 = gzipListFile(ValueUnion.psz, fForce);
            else if (fTest)
                rcExit2 = gzipTestFile(ValueUnion.psz, fForce);
            else if (fDecompress)
                rcExit2 = gzipDecompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut);
            else
                rcExit2 = gzipCompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut);
            if (rcExit2 != RTEXITCODE_SUCCESS)
                rcExit = rcExit2;

            cProcessed++;
            break;
        }

        case 'a':
            fAscii      = true;
            break;
        case 'c':
            fStdOut     = true;
            break;
        case 'd':
            fDecompress = true;
            break;
        case 'f':
            fForce      = true;
            break;
        case 'l':
            fList       = true;
            break;
        case 'n':
            fName       = false;
            break;
        case 'N':
            fName       = true;
            break;
        case 'q':
            fQuiet      = true;
            break;
        case 'r':
            fRecursive  = true;
            break;
        case 'S':
            pszSuff     = ValueUnion.psz;
            break;
        case 't':
            fTest       = true;
            break;
        case 'v':
            fQuiet      = false;
            break;
        case '1':
            uLevel      = 1;
            break;
        case '2':
            uLevel      = 2;
            break;
        case '3':
            uLevel      = 3;
            break;
        case '4':
            uLevel      = 4;
            break;
        case '5':
            uLevel      = 5;
            break;
        case '6':
            uLevel      = 6;
            break;
        case '7':
            uLevel      = 7;
            break;
        case '8':
            uLevel      = 8;
            break;
        case '9':
            uLevel      = 9;
            break;

        case 'h':
            RTPrintf("Usage: to be written\nOption dump:\n");
            for (unsigned i = 0; i < RT_ELEMENTS(s_aOptions); i++)
                RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong);
            return RTEXITCODE_SUCCESS;

        case 'V':
            RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision());
            return RTEXITCODE_SUCCESS;

        default:
            return RTGetOptPrintError(rc, &ValueUnion);
        }
    }
}