ZIP_EXTERN zip_source_t *
zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error)
{
    struct read_data *ctx;
    zip_source_t *zs;

    if (data == NULL && len > 0) {
	zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	free(ctx);
	return NULL;
    }

    ctx->out = NULL;
    ctx->mtime = time(NULL);
    zip_error_init(&ctx->error);
    
    if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) {
	buffer_free(ctx->in);
	free(ctx);
	return NULL;
    }

    return zs;
}
Exemple #2
0
VFSZipFileTLS* vfs_zipfile_get_tls(VFSNode *node, bool create) {
	VFSZipFileData *zdata = node->data1;
	VFSZipFileTLS *tls = SDL_TLSGet(zdata->tls_id);

	if(tls || !create) {
		return tls;
	}

	tls = calloc(1, sizeof(VFSZipFileTLS));
	SDL_TLSSet(zdata->tls_id, tls, (void(*)(void*))vfs_zipfile_free_tls);

	zip_source_t *src = zip_source_function_create(vfs_zipfile_srcfunc, node, &tls->error);
	zip_t *zip = tls->zip = zip_open_from_source(src, ZIP_RDONLY, &tls->error);

	// FIXME: Taisei currently doesn't handle zip files without explicit directory entries correctly (file listing will not work)

	if(!zip) {
		char *r = vfs_node_repr(zdata->source, true);
		vfs_set_error("Failed to open zip archive '%s': %s", r, zip_error_strerror(&tls->error));
		free(r);
		vfs_zipfile_free_tls(tls);
		SDL_TLSSet(zdata->tls_id, 0, NULL);
		zip_source_free(src);
		return NULL;
	}

	return tls;
}
Exemple #3
0
zip_source_t *source_hole_create(const char *fname, int flags, zip_error_t *error)
{
    hole_t *ud = hole_new(fname, flags, error);

    if (ud == NULL) {
        return NULL;
    }
    return zip_source_function_create(source_hole_cb, ud, error);
}
ZIP_EXTERN zip_source_t *
zip_source_function(zip_t *za, zip_source_callback zcb, void *ud)
{
    if (za == NULL) {
        return NULL;
    }

    return zip_source_function_create(zcb, ud, &za->error);
}
zip_source_t *
_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error)
{
    _zip_source_win32_read_file_t *ctx;
    zip_source_t *zs;

    if (h == INVALID_HANDLE_VALUE && fname == NULL) {
	zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->fname = NULL;
    if (fname) {
	if ((ctx->fname = ops->op_strdup(fname)) == NULL) {
	    zip_error_set(error, ZIP_ER_MEMORY, 0);
	    free(ctx);
	    return NULL;
	}
    }

    ctx->ops = ops;
    ctx->h = h;
    ctx->start = start;
    ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len);
    ctx->closep = ctx->fname ? 1 : closep;
    if (st) {
	memcpy(&ctx->st, st, sizeof(ctx->st));
	ctx->st.name = NULL;
	ctx->st.valid &= ~ZIP_STAT_NAME;
    }
    else {
	zip_stat_init(&ctx->st);
    }

    ctx->tmpname = NULL;
    ctx->hout = INVALID_HANDLE_VALUE;

    zip_error_init(&ctx->error);

    ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
    if (ctx->fname) {
	HANDLE th;

	th = ops->op_open(ctx);
	if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) {
	    ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
	}
	if (th != INVALID_HANDLE_VALUE) {
	    CloseHandle(th);
	}
    }
    else if (GetFileType(ctx->h) == FILE_TYPE_DISK) {
	ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
    }

    if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
	free(ctx->fname);
	free(ctx);
	return NULL;
    }

    return zs;
}
zip_source_t *
_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error)
{
    struct read_file *ctx;
    zip_source_t *zs;
    
    if (file == NULL && fname == NULL) {
	zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }
    
    if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->fname = NULL;
    if (fname) {
	if ((ctx->fname=strdup(fname)) == NULL) {
	    zip_error_set(error, ZIP_ER_MEMORY, 0);
	    free(ctx);
	    return NULL;
	}
    }
    ctx->f = file;
    ctx->start = start;
    ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len);
    if (st) {
	memcpy(&ctx->st, st, sizeof(ctx->st));
        ctx->st.name = NULL;
        ctx->st.valid &= ~ZIP_STAT_NAME;
    }
    else {
	zip_stat_init(&ctx->st);
    }
    
    ctx->tmpname = NULL;
    ctx->fout = NULL;
   
    zip_error_init(&ctx->error);

    ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
    if (ctx->fname) {
	struct stat sb;

	if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) {
            ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
	}
    }
    else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) {
        ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
    }

    if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) {
	free(ctx->fname);
	free(ctx);
	return NULL;
    }

    return zs;
}