Example #1
0
static int
add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft,
              struct zip_error *error)
{
    char buf[BUFSIZE];
    ssize_t n;

    st->comp_size = 0;
    while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) {
        if (fwrite(buf, 1, n, ft) != (size_t)n) {
            _zip_error_set(error, ZIP_ER_WRITE, errno);
            return -1;
        }

        st->comp_size += n;
    }
    if (n < 0) {
        ch_set_error(error, cb, ud);
        return -1;
    }

    return 0;
}
Example #2
0
static int
add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud,
                struct zip_stat *st, FILE *ft)
{
    char b1[BUFSIZE], b2[BUFSIZE];
    int end, flush, ret;
    ssize_t n;
    size_t n2;
    z_stream zstr;
    int mem_level;

    st->comp_method = ZIP_CM_DEFLATE;
    st->comp_size = st->size = 0;
    st->crc = (unsigned int)crc32(0, NULL, 0);

    zstr.zalloc = Z_NULL;
    zstr.zfree = Z_NULL;
    zstr.opaque = NULL;
    zstr.avail_in = 0;
    zstr.avail_out = 0;

    if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
        mem_level = TORRENT_MEM_LEVEL;
    else
        mem_level = MAX_MEM_LEVEL;

    /* -MAX_WBITS: undocumented feature of zlib to _not_ write a zlib header */
    deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, mem_level,
                 Z_DEFAULT_STRATEGY);

    zstr.next_out = (Bytef *)b2;
    zstr.avail_out = sizeof(b2);
    zstr.next_in = NULL;
    zstr.avail_in = 0;

    flush = 0;
    end = 0;
    while (!end) {
        if (zstr.avail_in == 0 && !flush) {
            if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
                ch_set_error(&za->error, cb, ud);
                deflateEnd(&zstr);
                return -1;
            }
            if (n > 0) {
                zstr.avail_in = (unsigned int)n;
                zstr.next_in = (Bytef *)b1;
                st->size += n;
                st->crc = (unsigned int)crc32(st->crc, (Bytef *)b1, (unsigned int)n);
            }
            else
                flush = Z_FINISH;
        }

        ret = deflate(&zstr, flush);
        if (ret != Z_OK && ret != Z_STREAM_END) {
            _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
            return -1;
        }

        if (zstr.avail_out != sizeof(b2)) {
            n2 = sizeof(b2) - zstr.avail_out;

            if (fwrite(b2, 1, n2, ft) != n2) {
                _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
                return -1;
            }

            zstr.next_out = (Bytef *)b2;
            zstr.avail_out = sizeof(b2);
            st->comp_size += n2;
        }

        if (ret == Z_STREAM_END) {
            deflateEnd(&zstr);
            end = 1;
        }
    }

    return 0;
}
Example #3
0
static int
add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
		FILE *ft, struct zip_error *error)
{
    char b1[BUFSIZE], b2[BUFSIZE];
    int end, flush, ret;
    ssize_t n;
    z_stream zstr;

    st->comp_method = ZIP_CM_DEFLATE;
    st->comp_size = st->size = 0;
    st->crc = crc32(0, NULL, 0);

    zstr.zalloc = Z_NULL;
    zstr.zfree = Z_NULL;
    zstr.opaque = NULL;
    zstr.avail_in = 0;
    zstr.avail_out = 0;

    /* -15: undocumented feature of zlib to _not_ write a zlib header */
    deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9,
		 Z_DEFAULT_STRATEGY);

    zstr.next_out = (Bytef *)b2;
    zstr.avail_out = sizeof(b2);
    zstr.avail_in = 0;

    flush = 0;
    end = 0;
    while (!end) {
	if (zstr.avail_in == 0 && !flush) {
	    if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
		ch_set_error(error, cb, ud);
		deflateEnd(&zstr);
		return -1;
	    }
	    if (n > 0) {
		zstr.avail_in = n;
		zstr.next_in = (Bytef *)b1;
		st->size += n;
		st->crc = crc32(st->crc, (Bytef *)b1, n);
	    }
	    else
		flush = Z_FINISH;
	}

	ret = deflate(&zstr, flush);
	if (ret != Z_OK && ret != Z_STREAM_END) {
	    _zip_error_set(error, ZIP_ER_ZLIB, ret);
	    return -1;
	}
	
	if (zstr.avail_out != sizeof(b2)) {
	    n = sizeof(b2) - zstr.avail_out;
	    
	    if (fwrite(b2, 1, n, ft) != n) {
		_zip_error_set(error, ZIP_ER_WRITE, errno);
		return -1;
	    }
	
	    zstr.next_out = (Bytef *)b2;
	    zstr.avail_out = sizeof(b2);
	    st->comp_size += n;
	}

	if (ret == Z_STREAM_END) {
	    deflateEnd(&zstr);
	    end = 1;
	}
    }

    return 0;
}
Example #4
0
static int
add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
{
    off_t offstart, offend;
    zip_source_callback cb;
    void *ud;
    struct zip_stat st;

    cb = zs->f;
    ud = zs->ud;

    if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) {
        ch_set_error(&za->error, cb, ud);
        return -1;
    }

    if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
        ch_set_error(&za->error, cb, ud);
        return -1;
    }

    offstart = ftello(ft);

    if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
        return -1;

    if (st.comp_method != ZIP_CM_STORE) {
        if (add_data_comp(cb, ud, &st, ft, &za->error) < 0)
            return -1;
    }
    else {
        if (add_data_uncomp(za, cb, ud, &st, ft) < 0)
            return -1;
    }

    if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
        ch_set_error(&za->error, cb, ud);
        return -1;
    }

    offend = ftello(ft);

    if (fseeko(ft, offstart, SEEK_SET) < 0) {
        _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
        return -1;
    }


    de->last_mod = st.mtime;
    de->comp_method = st.comp_method;
    de->crc = st.crc;
    de->uncomp_size = (unsigned int)st.size;
    de->comp_size = (unsigned int)st.comp_size;

    if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
        _zip_dirent_torrent_normalize(de);

    if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
        return -1;

    if (fseeko(ft, offend, SEEK_SET) < 0) {
        _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
        return -1;
    }

    return 0;
}
Example #5
0
static int
add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft)
{
    off_t offstart, offend;
    zip_source_callback cb;
    void *ud;
    struct zip_stat st;
    
    cb = za->entry[idx].source->f;
    ud = za->entry[idx].source->ud;

    if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < sizeof(st)) {
	ch_set_error(&za->error, cb, ud);
	return -1;
    }

    if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
	ch_set_error(&za->error, cb, ud);
	return -1;
    }

    offstart = ftell(ft);

    if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
	return -1;

    if (st.comp_method != ZIP_CM_STORE) {
	if (add_data_comp(cb, ud, &st, ft, &za->error) < 0)
	    return -1;
    }
    else {
	if (add_data_uncomp(cb, ud, &st, ft, &za->error) < 0)
	    return -1;
    }

    if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
	ch_set_error(&za->error, cb, ud);
	return -1;
    }

    offend = ftell(ft);

    if (fseek(ft, offstart, SEEK_SET) < 0) {
	_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	return -1;
    }
    
    de->comp_method = st.comp_method;
    de->last_mod = st.mtime;
    de->crc = st.crc;
    de->uncomp_size = st.size;
    de->comp_size = st.comp_size;

    if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
	return -1;
    
    if (fseek(ft, offend, SEEK_SET) < 0) {
	_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	return -1;
    }

    return 0;
}