示例#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
示例#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
示例#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
示例#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
示例#5
0
static boolean unpack(UZ2input *inp)
{
    MojoInput *io = inp->io;
    uLongf ul = (uLongf) inp->uncompsize;

    // we checked these formally elsewhere.
    assert(inp->compsize > 0);
    assert(inp->uncompsize > 0);
    assert(inp->compsize <= MAXCOMPSIZE);
    assert(inp->uncompsize <= MAXUNCOMPSIZE);

    if (io->read(io, inp->compbuf, inp->compsize) != inp->compsize)
        return false;
    if (uncompress(inp->uncompbuf, &ul, inp->compbuf, inp->compsize) != Z_OK)
        return false;
    if (ul != ((uLongf) inp->uncompsize))  // corrupt data.
        return false;

    inp->uncompindex = 0;
    return true;
} // unpack
示例#6
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
示例#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
static boolean MojoArchive_pck_enumerate(MojoArchive *ar)
{
    MojoArchiveEntry *archiveEntries = NULL;
    PCKinfo *info = (PCKinfo *) ar->opaque;
    const int dataStart = info->dataStart;
    const int fileCount = dataStart / sizeof (PCKentry);
    const size_t len = fileCount * sizeof (MojoArchiveEntry);
    PCKentry fileEntry;
    uint64 i, realFileCount = 0;
    char directory[256] = {'\0'};
    MojoInput *io = ar->io;

    MojoArchive_resetEntry(&ar->prevEnum);

    archiveEntries = (MojoArchiveEntry *) xmalloc(len);

    for (i = 0; i < fileCount; i++)
    {
        int dotdot;
        int64 br;

        br = io->read(io, fileEntry.filename, sizeof (fileEntry.filename));
        if (br != sizeof (fileEntry.filename))
            return false;
        else if (!MojoInput_readui32(io, &fileEntry.filesize))
            return false;

        dotdot = (strcmp(fileEntry.filename, "..") == 0);

        if ((!dotdot) && (fileEntry.filesize == 0x80000000))
        {
            MojoArchiveEntry *entry = &archiveEntries[realFileCount];

            strcat(directory, fileEntry.filename);
            strcat(directory, "/");

            entry->filename = xstrdup(directory);
            entry->type = MOJOARCHIVE_ENTRY_DIR;
            entry->perms = MojoPlatform_defaultDirPerms();
            entry->filesize = 0;
            realFileCount++;
        } // if

        else if ((dotdot) && (fileEntry.filesize == 0x80000000))
        {
            // remove trailing path separator
            char *pathSep;
            const size_t strLength = strlen(directory);
            directory[strLength - 1] = '\0';

            pathSep = strrchr(directory, '/');
            if(pathSep != NULL)
            {
                pathSep++;
                *pathSep = '\0';
            } // if
        } // else if

        else
        {
            MojoArchiveEntry *entry = &archiveEntries[realFileCount];
            if (directory[0] == '\0')
                entry->filename = xstrdup(fileEntry.filename);
            else
            {
                const size_t len = sizeof (char) * strlen(directory) +
                                   strlen(fileEntry.filename) + 1;
                entry->filename = (char *) xmalloc(len);
                strcat(entry->filename, directory);
                strcat(entry->filename, fileEntry.filename);
            } // else

            entry->perms = MojoPlatform_defaultFilePerms();
            entry->type = MOJOARCHIVE_ENTRY_FILE;
            entry->filesize = fileEntry.filesize;

            realFileCount++;
        } // else
    } // for

    info->fileCount = realFileCount;
    info->archiveEntries = archiveEntries;
    info->nextEnumPos = 0;
    info->nextFileStart = dataStart;

    return true;
} // MojoArchive_pck_enumerate