EXT2Err EXT2HashDir()

in lsvmutils/ext2.c [4859:4964]


EXT2Err EXT2HashDir(
    EXT2* ext2,
    const char* root,
    SHA1Hash* sha1,
    SHA256Hash* sha256)
{
    EXT2_DECLARE_ERR(err);
    StrArr paths = STRARR_INITIALIZER;
    SHA1Context sha1Context;
    SHA256Context sha256Context;
    void* data = NULL;
    UINT32 size;

    /* Check for null parameters */
    if (!ext2 || !root || !sha1 || !sha256)
    {
        err = EXT2_ERR_INVALID_PARAMETER;
        GOTO(done);
    }

    /* Clear the hashes */

    if (sha1)
        SHA1Init(&sha1Context);

    if (sha256)
        SHA256Init(&sha256Context);

    /* Form an array of paths */
    if (EXT2_IFERR(err = EXT2Lsr(ext2, root, &paths)))
    {
        GOTO(done);
    }

    /* Sort the path names */
    StrArrSort(&paths);

    /* Hash the contents of all files in this directory */
    {
        UINTN i;

        for (i = 0; i < paths.size; i++)
        {
            EXT2Ino ino;
            EXT2Inode inode;

            if (EXT2_IFERR(err = EXT2PathToInode(
                ext2, 
                paths.data[i], 
                &ino, 
                &inode)))
            {
                GOTO(done);
            }

            /* Skip directories */
            if (inode.i_mode & EXT2_S_IFDIR)
                continue;

            /* Load the file into memory */
            if (EXT2_IFERR(err = EXT2LoadFileFromInode(
                ext2, 
                &inode, 
                &data, 
                &size)))
            {
                GOTO(done);
            }

            /* Update the SHA1 hash */
            if (sha1 && !SHA1Update(&sha1Context, data, size))
            {
                GOTO(done);
            }

            /* Update the SHA256 hash */
            if (sha256 && !SHA256Update(&sha256Context, data, size))
            {
                GOTO(done);
            }

            /* Release the file memory */
            Free(data);
            data = NULL;
        }
    }

    /* Finalize the SHA-1 hash */
    if (sha1)
        SHA1Final(&sha1Context, sha1);

    /* Finalize the SHA-256 hash */
    if (sha256)
        SHA256Final(&sha256Context, sha256);

    err = EXT2_ERR_NONE;

done:

    if (data)
        Free(data);

    StrArrRelease(&paths);

    return err;
}