int ext2_main()

in lsvmtool/ext2main.c [927:1133]


int ext2_main(
    int argc,
    const char* argv[])
{
    int status = 0;
    EXT2* ext2 = NULL;
    const char* ext2fs = NULL;
    char* dupenv = NULL;
    EXT2Err err;
    int i;      
    Blkdev* rawdev = NULL;
    Blkdev* cachedev = NULL;
    Blkdev* dev = NULL;
    const char* keyfile = NULL;
    const char* masterkeyfile = NULL;
    char* passphrase = NULL;
    size_t passphraseSize = 0;
    UINT8* masterkey = NULL;
    size_t masterkeySize;
    BOOLEAN cached = FALSE;
        
    /* Get the --keyfile option (if any) */
    GetOpt(&argc, argv, "--keyfile", &keyfile);

    /* Get the --masterkeyfile option (if any) */
    GetOpt(&argc, argv, "--masterkeyfile", &masterkeyfile);

    /* Get the --ext2fs option (if any) */
    GetOpt(&argc, argv, "--ext2fs", &ext2fs);
    GetOpt(&argc, argv, "-f", &ext2fs);

    /* Get the --passphrase option (if any) */
    {
        const char* arg = NULL;
        GetOpt(&argc, argv, "--passphrase", &arg);
        GetOpt(&argc, argv, "-p", &arg);
        passphrase = (char*)arg;
    }

    /* Get the --cached option */
    if (GetOpt(&argc, argv, "--cached", NULL) == 1)
        cached = TRUE;

    /* If no --ext2fs option, fallback on EXT2FS environment variable */
    if (!ext2fs)
    {
        if (!(dupenv = Dupenv("EXT2FS")))
        {
            fprintf(stderr, "%s: either specify --ext2fs option or "
                "define EXT2FS environment variable\n", argv[0]);
            exit(1);
        }

        ext2fs = dupenv;
    }

    /* Load the key file (if any) */
    if (!passphrase && keyfile)
    {
        if (LoadFile(keyfile, 1, (UINT8**)&passphrase, &passphraseSize) != 0)
        {
            fprintf(stderr, "%s: failed to read: %s\n", argv[0], keyfile);
            goto done;
        }

        passphrase[passphraseSize] = '\0';
    }

    /* Load the masterkey file (if any) */
    if (masterkeyfile)
    {
        if (LoadFile(masterkeyfile, 0, &masterkey, &masterkeySize) != 0)
        {
            fprintf(stderr, "%s: failed to read: %s\n", argv[0], masterkeyfile);
            goto done;
        }
    }

    /* Print usage */
    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s SUBCOMMAND [ARGS]\n", argv[0]);
        fprintf(stderr, "Where SUBCOMMAND is:\n");

        for (i = 0; i < _ncommands; i++)
        {
            fprintf(stderr, "    %-*s - %s\n", 
                6,
                _commands[i].name,
                _commands[i].help);
        }

        fprintf(stderr, "\n");
        exit(1);
    }

    /* Open the block device file */
    if (!(rawdev = BlkdevOpen(ext2fs, BLKDEV_ACCESS_RDWR, 0)))
    {
        fprintf(stderr, "%s: failed to open: %s\n", argv[0], ext2fs);
        status = 1;
        goto done;
    }

    /* Inject cached device into stack */
    if (!(cachedev = NewCacheBlkdev(rawdev)))
    {
        fprintf(stderr, "%s: failed to create cahced block device", argv[0]);
        status = 1;
        goto done;
    }

    /* Enable caching if --cached option given */
    if (cached)
        cachedev->SetFlags(cachedev, BLKDEV_ENABLE_CACHING);

    /* Create ext2_file_t object from LUKS or raw device */
    if (IsRawLUKSDevice(cachedev))
    {
        Blkdev* luksdev;

        if (masterkey)
        {
            if (!(luksdev = LUKSBlkdevFromMasterkey(
                cachedev, 
                masterkey,
                masterkeySize)))
            {
                fprintf(stderr, "%s: cannot create LUKS block device\n", 
                    argv[0]);
                status = 1;
                goto done;
            }
        }
        else
        {
            if (!passphrase)
            {
#if defined(__linux__)
                if (!(passphrase = getpass("passphrase: ")))
                {
                    fprintf(stderr, "%s: failed to get passphrase\n", argv[0]);
                    status = 1;
                    goto done;
                }
#else /* !defined(__linux__) */
                fprintf(stderr, "%s: use --passphrase to provide passphrase",
                    argv[0]);
                exit(1);
#endif /* !defined(__linux__) */
            }

            if (!(luksdev = LUKSBlkdevFromPassphrase(cachedev, passphrase)))
            {
                fprintf(stderr, "%s: cannot create LUKS block device\n", 
                    argv[0]);
                status = 1;
                goto done;
            }
        }

        /* ext2file -> luksdev -> cachedev -> rawdev */
        dev = luksdev;
    }
    else
    {
        /* ext2file -> cachedev -> rawdev */
        dev = cachedev;
    }

    /* Open the file system (takes ownership of 'file') */
    if (EXT2_IFERR(err = EXT2New(dev, &ext2)))
    {
        fprintf(stderr, "%s: failed to open file system: %s\n", argv[0], 
            EXT2ErrStr(err));
        status = 1;
        goto done;
    }

    /* Find and execute the command given by argv[1] */
    for (i = 0; i < _ncommands; i++)
    {
        if (strcmp(argv[1], _commands[i].name) == 0)
        {
            exit((*_commands[i].callback)(ext2, argc-1, argv+1));
        }
    }

    fprintf(stderr, "%s: unknown command: '%s'\n", argv[0], argv[1]);
    status = 1;

done:

    if (masterkey)
        free(masterkey);

    if (passphrase)
        free(passphrase);

    if (ext2)
        EXT2Delete(ext2);

    if (dupenv)
        free(dupenv);
        
    return status;
}