Exemple #1
0
/**
 * Basic API checks.
 */
static void tst1(void)
{
    RTTestISub("Manifest creation");

    size_t cbSize = 0;
    size_t iFailed = 0;

    /*
     * test1.txt = "This is a test text."
     * test2.txt = "Another test text."
     */
    static RTMANIFESTTEST /*const*/ s_aFiles[] = /** @todo API misdesign, this should be const. */
    {
        { "test1.txt", "794a8cc644b318ae6461aeea62915e399e441e8"  },
        { "test2.txt", "f17393902ee94c1e8bbd4bf417cdc70051feca00" }
    };
    static const char s_szTestPattern[] =
        "SHA1 (test1.txt)= 794a8cc644b318ae6461aeea62915e399e441e8\n"
        "SHA1 (test2.txt)= f17393902ee94c1e8bbd4bf417cdc70051feca00\n"
    ;

    void *pvBuf = NULL;
    RTTESTI_CHECK_RC_RETV(RTManifestWriteFilesBuf(&pvBuf, &cbSize, RTDIGESTTYPE_SHA1, s_aFiles, 2), VINF_SUCCESS);

    /* Check returned memory size */
    RTTESTI_CHECK_RETV(cbSize == strlen(s_szTestPattern));

    /* Check for correct manifest file content */
    RTTESTI_CHECK(memcmp(pvBuf, s_szTestPattern, cbSize) == 0);

    RTTestISub("Manifest verify");
    RTTESTI_CHECK_RC(RTManifestVerifyFilesBuf(pvBuf, cbSize, s_aFiles, 2, 0), VINF_SUCCESS);

    /* To little files to check */
    RTTESTI_CHECK_RC(RTManifestVerifyFilesBuf(pvBuf, cbSize, s_aFiles, 1, 0), VERR_MANIFEST_FILE_MISMATCH);

    /* Make the digest type invalid */
    ((char*)pvBuf)[0] = 'L';
    RTTESTI_CHECK_RC(RTManifestVerifyFilesBuf(pvBuf, cbSize, s_aFiles, 2, 0), VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE);
    ((char*)pvBuf)[0] = 'S'; /* Restore */

    /* Make the file name invalid */
    ((char*)pvBuf)[8] = 'z';
    RTTESTI_CHECK_RC(RTManifestVerifyFilesBuf(pvBuf, cbSize, s_aFiles, 2, 0), VERR_MANIFEST_FILE_MISMATCH);
    ((char*)pvBuf)[8] = 's'; /* Restore */

    /* Make the second digest invalid */
    ((char*)pvBuf)[99] = '0';
    RTTESTI_CHECK_RC(RTManifestVerifyFilesBuf(pvBuf, cbSize, s_aFiles, 2, &iFailed), VERR_MANIFEST_DIGEST_MISMATCH);
    RTTESTI_CHECK(iFailed == 1);

    /* Cleanup */
    RTMemFree(pvBuf);
}
Exemple #2
0
RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enmDigestType,
                                   const char * const *papszFiles, size_t cFiles,
                                   PFNRTPROGRESS pfnProgressCallback, void *pvUser)
{
    /* Validate input */
    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);

    RTFILE file;
    int rc = RTFileOpen(&file, pszManifestFile, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL);
    if (RT_FAILURE(rc))
        return rc;

    PRTMANIFESTTEST paFiles = 0;
    void *pvBuf = 0;
    do
    {
        paFiles = (PRTMANIFESTTEST)RTMemAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
        if (!paFiles)
        {
            rc = VERR_NO_MEMORY;
            break;
        }

        RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
        for (size_t i = 0; i < cFiles; ++i)
        {
            paFiles[i].pszTestFile = papszFiles[i];
            /* Calculate the SHA1 digest of every file */
            if (pfnProgressCallback)
            {
                callback.cCurrentFile = i;
                rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, rtSHAProgressCallback, &callback);
            }
            else
                rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, NULL, NULL);
            if (RT_FAILURE(rc))
                break;
        }

        if (RT_SUCCESS(rc))
        {
            size_t cbSize = 0;
            rc = RTManifestWriteFilesBuf(&pvBuf, &cbSize, enmDigestType, paFiles, cFiles);
            if (RT_FAILURE(rc))
                break;

            rc = RTFileWrite(file, pvBuf, cbSize, 0);
        }
    }while (0);

    RTFileClose(file);

    /* Cleanup */
    if (pvBuf)
        RTMemFree(pvBuf);
    if (paFiles)
    {
        for (size_t i = 0; i < cFiles; ++i)
            if (paFiles[i].pszTestDigest)
                RTStrFree((char*)paFiles[i].pszTestDigest);
        RTMemFree(paFiles);
    }

    /* Delete the manifest file on failure */
    if (RT_FAILURE(rc))
        RTFileDelete(pszManifestFile);

    return rc;
}