Ejemplo n.º 1
0
static int64 MojoInput_xz_read(MojoInput *io, void *buf, uint32 bufsize)
{
    XZinfo *info = (XZinfo *) io->opaque;
    MojoInput *origio = info->origio;
    int64 retval = 0;

    if (bufsize == 0)
        return 0;    // quick rejection.

    info->stream.next_out = buf;
    info->stream.avail_out = bufsize;

    while (retval < ((int64) bufsize))
    {
        const uint32 before = info->stream.total_out;
        lzma_ret rc;

        lzma_action action = LZMA_FINISH;
        if (info->stream.avail_in == 0)
        {
            int64 br = origio->length(origio) - origio->tell(origio);
            if (br > 0)
            {
                action = LZMA_RUN;
                if (br > XZ_READBUFSIZE)
                    br = XZ_READBUFSIZE;

                br = origio->read(origio, info->buffer, (uint32) br);
                if (br <= 0)
                    return -1;

                info->stream.next_in = info->buffer;
                info->stream.avail_in = (uint32) br;
            } // if
        } // if

        rc = lzma_code(&info->stream, LZMA_RUN);
        retval += (info->stream.total_out - before);

        if (rc != LZMA_OK)
            return -1;
    } // while

    assert(retval >= 0);
    info->uncompressed_position += (uint32) retval;

    return retval;
} // MojoInput_xz_read
Ejemplo n.º 2
0
static int64 MojoInput_gzip_read(MojoInput *io, void *buf, uint32 bufsize)
{
    GZIPinfo *info = (GZIPinfo *) io->opaque;
    MojoInput *origio = info->origio;
    int64 retval = 0;

    if (bufsize == 0)
        return 0;    // quick rejection.

    info->stream.next_out = buf;
    info->stream.avail_out = bufsize;

    while (retval < ((int64) bufsize))
    {
        const uint32 before = info->stream.total_out;
        int rc;

        if (info->stream.avail_in == 0)
        {
            int64 br = origio->length(origio) - origio->tell(origio);
            if (br > 0)
            {
                if (br > GZIP_READBUFSIZE)
                    br = GZIP_READBUFSIZE;

                br = origio->read(origio, info->buffer, (uint32) br);
                if (br <= 0)
                    return -1;

                info->stream.next_in = info->buffer;
                info->stream.avail_in = (uint32) br;
            } // if
        } // if

        rc = inflate(&info->stream, Z_SYNC_FLUSH);
        retval += (info->stream.total_out - before);

        if ((rc == Z_STREAM_END) && (retval == 0))
            return 0;
        else if ((rc != Z_OK) && (rc != Z_STREAM_END))
            return -1;
    } // while

    assert(retval >= 0);
    info->uncompressed_position += (uint32) retval;

    return retval;
} // MojoInput_gzip_read
Ejemplo n.º 3
0
static int64 MojoInput_bzip2_read(MojoInput *io, void *buf, uint32 bufsize)
{
    BZIP2info *info = (BZIP2info *) io->opaque;
    MojoInput *origio = info->origio;
    int64 retval = 0;

    if (bufsize == 0)
        return 0;    // quick rejection.

    info->stream.next_out = buf;
    info->stream.avail_out = bufsize;

    while (retval < ((int64) bufsize))
    {
        const uint32 before = info->stream.total_out_lo32;
        int rc;

        if (info->stream.avail_in == 0)
        {
            int64 br = origio->length(origio) - origio->tell(origio);
            if (br > 0)
            {
                if (br > BZIP2_READBUFSIZE)
                    br = BZIP2_READBUFSIZE;

                br = origio->read(origio, info->buffer, (uint32) br);
                if (br <= 0)
                    return -1;

                info->stream.next_in = (char *) info->buffer;
                info->stream.avail_in = (uint32) br;
            } // if
        } // if

        rc = BZ2_bzDecompress(&info->stream);
        retval += (info->stream.total_out_lo32 - before);
        if (rc != BZ_OK)
            return -1;
    } // while

    assert(retval >= 0);
    info->uncompressed_position += (uint32) retval;

    return retval;
} // MojoInput_bzip2_read
Ejemplo n.º 4
0
static void trySwitchBinary(MojoArchive *ar)
{
    MojoInput *io = ar->openCurrentEntry(ar);
    if (io != NULL)
    {
        const uint32 imglen = (uint32) io->length(io);
        uint8 *img = (uint8 *) xmalloc(imglen);
        const uint32 br = io->read(io, img, imglen);
        io->close(io);
        if (br == imglen)
        {
            logInfo("Switching binary with '%0'...", ar->prevEnum.filename);
            MojoPlatform_switchBin(img, imglen);  // no return on success.
            logError("...Switch binary failed.");
        } // if
        free(img);
    } // if
} // trySwitchBinary
Ejemplo n.º 5
0
int MojoSetup_testNetworkCode(int argc, char **argv)
{
    int i;
    fprintf(stderr, "Testing networking code...\n\n");
    for (i = 1; i < argc; i++)
    {
        static char buf[64 * 1024];
        uint32 start = 0;
        const char *url = argv[i];
        int64 length = -1;
        int64 total_br = 0;
        int64 br = 0;
        printf("\n\nFetching '%s' ...\n", url);
        MojoInput *io = MojoInput_newFromURL(url);
        if (io == NULL)
        {
            fprintf(stderr, "failed!\n");
            continue;
        } // if

        start = MojoPlatform_ticks();
        while (!io->ready(io))
            MojoPlatform_sleep(10);
        fprintf(stderr, "took about %d ticks to get started\n",
                (int) (MojoPlatform_ticks() - start));

        length = io->length(io);
        fprintf(stderr, "Ready to read (%lld) bytes.\n",
                (long long) length);

        do
        {
            start = MojoPlatform_ticks();
            if (!io->ready(io))
            {
                fprintf(stderr, "Not ready!\n");
                while (!io->ready(io))
                    MojoPlatform_sleep(10);
                fprintf(stderr, "took about %d ticks to get ready\n",
                        (int) (MojoPlatform_ticks() - start));
            } // if

            start = MojoPlatform_ticks();
            br = io->read(io, buf, sizeof (buf));
            fprintf(stderr, "read blocked for about %d ticks\n",
                    (int) (MojoPlatform_ticks() - start));
            if (br > 0)
            {
                total_br += br;
                fprintf(stderr, "read %lld bytes\n", (long long) br);
                fwrite(buf, br, 1, stdout);
            } // if
        } while (br > 0);

        if (br < 0)
            fprintf(stderr, "ERROR IN TRANSMISSION.\n\n");
        else
        {
            fprintf(stderr, "TRANSMISSION COMPLETE!\n\n");
            fprintf(stderr, "(Read %lld bytes, expected %lld.)\n",
                    (long long) total_br, length);
        } // else
        io->close(io);
    } // for

    return 0;
} // MojoSetup_testNetworkCode
Ejemplo n.º 6
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
Ejemplo n.º 7
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