int vfat_main()

in lsvmtool/vfatmain.c [404:530]


int vfat_main(
    int argc,
    const char* argv[])
{
    int status = 1;
    const char* vfatfs = NULL;
    Blkdev* dev = NULL;
    VFAT* vfat = NULL;
    UINTN i;
    UINTN offset = 0;

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

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

    /* If no --vfatfs option, fallback on EXT2FS environment variable */
    if (!vfatfs)
    {
        const char* dupenv;

        if (!(dupenv = Dupenv("VFATFS")))
        {
            fprintf(stderr, "%s: either specify --vfatfs option or "
                "define EXT2FS environment variable\n", argv[0]);
            return 1;
        }

        vfatfs = dupenv;
    }

    /* 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");
        return 1;
    }

    /* If raw disk device (e.g., /dev/sda), find the start offset. */
    if (strlen(vfatfs) >= 1 && !isdigit(vfatfs[strlen(vfatfs)-1]))
    {
        GPT gpt;

        /* Read the GPT */
        if (LoadGPT(vfatfs, &gpt) != 0)
        {
            fprintf(stderr, "%s: failed to load GPT: %s\n", argv[0], argv[1]);
            goto done;
        }

        /* Find the first VFAT */
        for (i = 0; i < GPT_MAX_ENTRIES; i++)
        {
            const GPTEntry* ent = &gpt.entries[i];

           /* EFI GUID is always: C12A7328-F81F-11D2-BA4B-00A0C93EC93B. */
            UINT64 g1 = 0x11d2f81fc12a7328;
            UINT64 g2 = 0x3bc93ec9a0004bba;   

            if (IS_BIG_ENDIAN)
            {
                g1 = 0xc12a7328f81f11d2;
                g2 = ByteSwapU64(g2);
            }    


            if (ent->typeGUID1 == 0)
                break;

            if (g1 == ent->typeGUID1 && g2 == ent->typeGUID2)
            {
                offset = ent->startingLBA * BLKDEV_BLKSIZE;
                break;
            }
        }

        if (offset == 0)
        {
            fprintf(stderr, "%s: failed to resolve parition\n", argv[0]);
            return 1;
        }
    }

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

    /* Create the VFAT object */
    if (VFATInit(dev, &vfat) != 0)
    {
        fprintf(stderr, "%s: VFAInit() failed\n", argv[0]);
        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)
            return((*_commands[i].callback)(vfat, argc-1, argv+1));
    }

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

done:

    if (vfat)
        VFATRelease(vfat);

    return status;
}