Esempio n. 1
0
gp_container *gp_open_zip(const char *path)
{
	struct zip_priv *priv;
	gp_container *ret;
	gp_io *io;
	int err;

	io = open_zip(path);

	if (!io)
		return NULL;

	ret = malloc(sizeof(gp_container) + sizeof(struct zip_priv));

	if (!ret) {
		err = ENOMEM;
		goto err0;
	}

	GP_DEBUG(1, "ZIP Container initialized");

	ret->img_count = -1;
	ret->cur_img = 0;
	ret->ops = &zip_ops;

	priv = GP_CONTAINER_PRIV(ret);

	priv->io = io;

	priv->table.next = NULL;
	priv->table.prev = NULL;

	/* Cache for current table for seeks */
	priv->cur_table = &priv->table;
	priv->cur_table_pos = 0;

	/* Current position */
	priv->cur_pos = 0;

	/* Last table, used for insertion */
	priv->tables_used = 0;
	priv->table_used = 0;
	priv->last_table = &priv->table;

	return ret;
err0:
	gp_io_close(io);
	errno = err;
	return NULL;
}
Esempio n. 2
0
static YogVal
compress(YogEnv* env, YogVal self, YogVal pkg, YogVal args, YogVal kw, YogVal block)
{
    SAVE_ARGS5(env, self, pkg, args, kw, block);
    YogVal path = YUNDEF;
    YogVal files = YUNDEF;
    PUSH_LOCALS2(env, path, files);
    YogCArg params[] = { { "path", &path }, { "*", &files }, { NULL, NULL } };
    YogGetArgs_parse_args(env, "compress", params, args, kw);
    if (!IS_PTR(path) || (BASIC_OBJ_TYPE(path) != TYPE_STRING)) {
        YogError_raise_TypeError(env, "path must be String");
    }

    struct zip* archive = open_zip(env, pkg, path, ZIP_CREATE);
    int n = zip_get_num_files(archive);
    int i;
    for (i = 0; i < n; i++) {
        if (zip_delete(archive, i) != 0) {
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
    }
    uint_t size = YogArray_size(env, files);
    uint_t j;
    for (j = 0; j < size; j++) {
        YogHandle* name = VAL2HDL(env, YogArray_at(env, files, j));
        YogMisc_check_String(env, name, "Filename");
        YogVal bin = YogString_to_bin_in_default_encoding(env, name);
        const char* fname = BINARY_CSTR(bin);
        struct zip_source* source = zip_source_file(archive, fname, 0, 0);
        if (source == NULL) {
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
        if (zip_add(archive, fname, source) < 0) {
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
    }
    close_zip(env, pkg, archive);

    RETURN(env, YNIL);
}
Esempio n. 3
0
static YogVal
decompress(YogEnv* env, YogVal self, YogVal pkg, YogVal args, YogVal kw, YogVal block)
{
    SAVE_ARGS5(env, self, pkg, args, kw, block);
    YogVal zip = YUNDEF;
    YogVal dest = YNIL;
    YogVal s = YUNDEF;
    PUSH_LOCALS3(env, zip, dest, s);
    YogCArg params[] = {
        { "zip", &zip },
        { "|", NULL },
        { "dest", &dest },
        { NULL, NULL } };
    YogGetArgs_parse_args(env, "decompress", params, args, kw);
    if (!IS_PTR(zip) || (BASIC_OBJ_TYPE(zip) != TYPE_STRING)) {
        YogError_raise_TypeError(env, "zip must be String");
    }
    if (!IS_NIL(dest) && (!IS_PTR(dest) || (BASIC_OBJ_TYPE(dest) != TYPE_STRING))) {
        YogError_raise_TypeError(env, "dest must be nil or String");
    }

    struct zip* archive = open_zip(env, pkg, zip, 0);
    int n = zip_get_num_files(archive);
    YogHandle* h = VAL2HDL(env, dest);
    int i;
    for (i = 0; i < n; i++) {
        const char* name = zip_get_name(archive, i, 0);
        if (name == NULL) {
            close_zip(env, pkg, archive);
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
        YogVal bin = YogString_to_bin_in_default_encoding(env, h);
        char* path = (char*)YogSysdeps_alloca(strlen(BINARY_CSTR(bin)) + strlen(name) + 2);
        strcpy(path, BINARY_CSTR(bin));
        strcat(path, "/");
        strcat(path, name);
        char* dir = (char*)YogSysdeps_alloca(strlen(path) + 1);
        strcpy(dir, path);
        dirname(dir);
        make_dirs(env, dir);

        struct zip_file* file = zip_fopen_index(archive, i, 0);
        if (file == NULL) {
            close_zip(env, pkg, archive);
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
        FILE* fp = fopen(path, "wb");
        if (fp == NULL) {
            zip_fclose(file);
            close_zip(env, pkg, archive);
            s = YogString_from_string(env, path);
            YogError_raise_sys_err(env, errno, s);
        }
        while (1) {
            char buf[1024];
            int len = zip_fread(file, buf, array_sizeof(buf));
            if (len < 0) {
                zip_fclose(file);
                close_zip(env, pkg, archive);
                raise_ZipError(env, pkg, zip_strerror(archive));
            }
            else if (len == 0) {
                break;
            }
            fwrite(buf, sizeof(char), len, fp);
            if (ferror(fp)) {
                zip_fclose(file);
                close_zip(env, pkg, archive);
                YogError_raise_IOError(env, name);
            }
        }

        fclose(fp);
        if (zip_fclose(file) != 0) {
            close_zip(env, pkg, archive);
            raise_ZipError(env, pkg, zip_strerror(archive));
        }
    }
    close_zip(env, pkg, archive);

    RETURN(env, YNIL);
}