Esempio n. 1
0
int MojoSetup_testArchiveCode(int argc, char **argv)
{
    int i;
    printf("Testing archiver code...\n\n");
    for (i = 1; i < argc; i++)
    {
        MojoArchive *archive = MojoArchive_newFromDirectory(argv[i]);
        if (archive != NULL)
            printf("directory '%s'...\n", argv[i]);
        else
        {
            MojoInput *io = MojoInput_newFromFile(argv[i]);
            if (io != NULL)
            {
                archive = MojoArchive_newFromInput(io, argv[i]);
                if (archive != NULL)
                    printf("archive '%s'...\n", argv[i]);
            } // if
        } // else

        if (archive == NULL)
            fprintf(stderr, "Couldn't handle '%s'\n", argv[i]);
        else
        {
            if (!archive->enumerate(archive))
                fprintf(stderr, "enumerate() failed.\n");
            else
            {
                const MojoArchiveEntry *ent;
                while ((ent = archive->enumNext(archive)) != NULL)
                {
                    printf("%s ", ent->filename);
                    if (ent->type == MOJOARCHIVE_ENTRY_FILE)
                    {
                        printf("(file, %d bytes, %o)\n",
                                (int) ent->filesize, ent->perms);

                        MojoInput *input = archive->openCurrentEntry(archive);

                        if(&archive->prevEnum != ent)
                        {
                            fprintf(stderr, "Address of MojoArchiveEntry pointer differs\n");
                            exit(EXIT_FAILURE);
                        } // if

                        if(!input)
                        {
                            fprintf(stderr, "Could not open current entry\n");
                            exit(EXIT_FAILURE);
                        } // if

                        if(!input->ready(input))
                        {
                            input->close(input);
                            continue;
                        } // if

                        uint64 pos = input->tell(input);
                        if(0 != pos)
                        {
                            fprintf(stderr, "position has to be 0 on start, is: %d\n", (int) pos);
                            exit(EXIT_FAILURE);
                        } // if

                        int64 filesize = input->length(input);
                        if(filesize != ent->filesize)
                        {
                            fprintf(stderr, "file size mismatch %d != %d\n",
                            		(int) filesize, (int) ent->filesize);
                            exit(EXIT_FAILURE);
                        } // if

                        boolean ret = input->seek(input, filesize - 1);
                        if(!ret)
                        {
                            fprintf(stderr, "seek() has to return 'true'.\n");
                            exit(EXIT_FAILURE);
                        } // if

                        ret = input->seek(input, filesize);
                        if(ret)
                        {
                            fprintf(stderr, "seek() has to return 'false'.\n");
                            exit(EXIT_FAILURE);
                        } // if

                        pos = input->tell(input);
                        if(filesize -1 != pos)
                        {
                            fprintf(stderr, "position should be %d after seek(), is: %d\n",
                            		(int) filesize - 1, (int) pos);
                            exit(EXIT_FAILURE);
                        } // if

                        input->close(input);
                    } // if
                    else if (ent->type == MOJOARCHIVE_ENTRY_DIR)
                        printf("(dir, %o)\n", ent->perms);
                    else if (ent->type == MOJOARCHIVE_ENTRY_SYMLINK)
                        printf("(symlink -> '%s')\n", ent->linkdest);
                    else
                    {
                        printf("(UNKNOWN?!, %d bytes, -> '%s', %o)\n",
                                (int) ent->filesize, ent->linkdest,
                                ent->perms);
                    } // else
                } // while
            } // else
            archive->close(archive);
            printf("\n\n");
        } // else
    } // for

    return 0;
} // MojoSetup_testArchiveCode
Esempio n. 2
0
MojoArchive *MojoArchive_initBaseArchive(void)
{
    char *basepath = NULL;
    const char *cmd = NULL;
    MojoInput *io = NULL;

    if (GBaseArchive != NULL)
        return GBaseArchive;  // already initialized.

    if ((cmd = cmdlinestr("base", "MOJOSETUP_BASE", NULL)) != NULL)
    {
        char *real = MojoPlatform_realpath(cmd);
        if (real != NULL)
        {
            if (MojoPlatform_isdir(real))
                GBaseArchive = MojoArchive_newFromDirectory(real);
            else
            {
                io = MojoInput_newFromFile(real);
                if (io != NULL)
                    GBaseArchive = MojoArchive_newFromInput(io, real);
            } // else

            if (GBaseArchive != NULL)
                basepath = real;
            else
                free(real);
        } // if
    } // else if

    else
    {
        basepath = MojoPlatform_appBinaryPath();
        if (basepath != NULL)
        {
            io = MojoInput_newFromFile(basepath);

            if (io != NULL)
            {
                // See if there's a MOJOBASE signature at the end of the
                //  file. This means we appended an archive to the executable,
                //  for a self-extracting installer. This method works with
                //  any archive type, even if it wasn't specifically designed
                //  to be appended.
                uint8 buf[8];
                uint64 size = 0;
                const int64 flen = io->length(io) - 16;
                if ( (flen > 0) && (io->seek(io, flen)) &&
                     (io->read(io, buf, 8) == 8) &&
                     (memcmp(buf, "MOJOBASE", 8) == 0) &&
                     (MojoInput_readui64(io, &size)) &&
                     (size < flen) )
                {
                    MojoInput *newio;
                    newio = MojoInput_newFromSubset(io, flen - size, flen);
                    if (newio != NULL)
                        io = newio;
                } // if

                GBaseArchive = MojoArchive_newFromInput(io, basepath);
            } // if

            if (GBaseArchive == NULL)
            {
                // Just use the same directory as the binary instead.
                char *ptr = strrchr(basepath, '/');
                if (ptr != NULL)
                    *ptr = '\0';
                else
                {
                    free(basepath);  // oh well, try cwd.
                    basepath = MojoPlatform_currentWorkingDir();
                } // else
                GBaseArchive = MojoArchive_newFromDirectory(basepath);

                // !!! FIXME: failing this, maybe default.mojosetup?
            } // if
        } // if
    } // else

    if (GBaseArchive == NULL)
    {
        free(basepath);
        basepath = NULL;
    } // if
    GBaseArchivePath = basepath;

    return GBaseArchive;
} // MojoArchive_initBaseArchive