static int copy_source(zip_t *za, zip_source_t *src) { zip_uint8_t buf[BUFSIZE]; zip_int64_t n; int ret; if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } ret = 0; while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) { if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { ret = -1; break; } } if (n < 0) { _zip_error_set_from_source(&za->error, src); ret = -1; } zip_source_close(src); return ret; }
static int copy_source(struct zip *za, struct zip_source *src, FILE *ft) { char buf[BUFSIZE]; zip_int64_t n; int ret; if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } ret = 0; while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) { if (fwrite(buf, 1, (size_t)n, ft) != (size_t)n) { _zip_error_set(&za->error, ZIP_ER_WRITE, errno); ret = -1; break; } } if (n < 0) { if (ret == 0) _zip_error_set_from_source(&za->error, src); ret = -1; } zip_source_close(src); return ret; }
ZIP_EXTERN struct zip_file * zip_fopen_index_encrypted(struct zip *za, zip_uint64_t index, zip_flags_t flags, const char *password) { struct zip_file *zf; struct zip_source *src; if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) return NULL; if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); zip_source_free(src); return NULL; } if ((zf=_zip_file_new(za)) == NULL) { zip_source_free(src); return NULL; } zf->src = src; return zf; }
int main() { zip_source_t *zsrc = loadFromFile(); if (!zsrc) return 1; fprintf(stderr, "zip_open_from_source...\n"); zip_error_t error; zip_error_init(&error); zip_t *archive = zip_open_from_source(zsrc, 0, &error); if (!archive) return 2; zip_error_fini(&error); show(archive, "after zip_open_from_source"); const char *name = "y.txt"; zip_flags_t flags = 0; zip_source_t *otherZsrc = zip_source_buffer_create("hello", 5, 0, &error); fprintf(stderr, "zip_file_add...\n"); zip_int64_t i = zip_file_add(archive, name, otherZsrc, flags); fprintf(stderr, "zip_file_add(): i=%lld\n", i); // show(archive, "after zip_file_add"); zip_source_keep(zsrc); int ret; ret = zip_close(archive); // print to stdout zip_stat_t zst; ret = zip_source_stat(zsrc, &zst); fprintf(stderr, "zip_source_stat: ret=%d, zst.size=%d\n", ret, zst.size); ret = zip_source_open(zsrc); fprintf(stderr, "zip_source_open: ret=%d\n", ret); unsigned char data[10000]; zip_uint64_t n = zip_source_read(zsrc, data, sizeof(data)); fprintf(stderr, "zip_source_read: n=%d\n", n); write(1, data, n); // print to stdout }
ZIP_EXTERN int zip_source_open(zip_source_t *src) { if (src->source_closed) { return -1; } if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { zip_error_set(&src->error, ZIP_ER_DELETED, 0); return -1; } if (ZIP_SOURCE_IS_OPEN_READING(src)) { if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) { zip_error_set(&src->error, ZIP_ER_INUSE, 0); return -1; } } else { if (ZIP_SOURCE_IS_LAYERED(src)) { if (zip_source_open(src->src) < 0) { _zip_error_set_from_source(&src->error, src->src); return -1; } } if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) { if (ZIP_SOURCE_IS_LAYERED(src)) { zip_source_close(src->src); } return -1; } } src->eof = false; src->had_read_error = false; _zip_error_clear(&src->error); src->open_count++; return 0; }
zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags, const char *password) { struct zip_file *zf; zip_compression_implementation comp_impl; zip_encryption_implementation enc_impl; struct zip_source *src, *s2; zip_uint64_t start; struct zip_stat st; if (fileno >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) { _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); return NULL; } if (fileno >= za->cdir->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } if (flags & ZIP_FL_ENCRYPTED) flags |= ZIP_FL_COMPRESSED; zip_stat_index(za, fileno, flags, &st); enc_impl = NULL; if ((flags & ZIP_FL_ENCRYPTED) == 0) { if (st.encryption_method != ZIP_EM_NONE) { if (password == NULL) { _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); return NULL; } if ((enc_impl=zip_get_encryption_implementation( st.encryption_method)) == NULL) { _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); return NULL; } } } comp_impl = NULL; if ((flags & ZIP_FL_COMPRESSED) == 0) { if (st.comp_method != ZIP_CM_STORE) { if ((comp_impl=zip_get_compression_implementation( st.comp_method)) == NULL) { _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); return NULL; } } } if ((start=_zip_file_get_offset(za, fileno)) == 0) return NULL; if (st.comp_size == 0) { if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) return NULL; } else { if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size, 0, &st)) == NULL) return NULL; if (enc_impl) { if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0, password)) == NULL) { zip_source_free(src); /* XXX: set error (how?) */ return NULL; } src = s2; } if (comp_impl) { if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method, 0)) == NULL) { zip_source_free(src); /* XXX: set error (how?) */ return NULL; } src = s2; } if ((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE ) { if ((s2=zip_source_crc(za, src, 1)) == NULL) { zip_source_free(src); /* XXX: set error (how?) */ return NULL; } src = s2; } } if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); zip_source_free(src); return NULL; } zf = _zip_file_new(za); zf->src = src; return zf; }
ZIP_EXTERN zip_t * zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { static zip_int64_t needed_support_read = -1; static zip_int64_t needed_support_write = -1; unsigned int flags; zip_int64_t supported; exists_t exists; if (_flags < 0 || src == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } flags = (unsigned int)_flags; supported = zip_source_supports(src); if (needed_support_read == -1) { needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1); needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); } if ((supported & needed_support_read) != needed_support_read) { zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); return NULL; } if ((supported & needed_support_write) != needed_support_write) { flags |= ZIP_RDONLY; } if ((flags & (ZIP_RDONLY|ZIP_TRUNCATE)) == (ZIP_RDONLY|ZIP_TRUNCATE)) { zip_error_set(error, ZIP_ER_RDONLY, 0); return NULL; } exists = _zip_file_exists(src, error); switch (exists) { case EXISTS_ERROR: return NULL; case EXISTS_NOT: if ((flags & ZIP_CREATE) == 0) { zip_error_set(error, ZIP_ER_NOENT, 0); return NULL; } return _zip_allocate_new(src, flags, error); default: { zip_t *za; if (flags & ZIP_EXCL) { zip_error_set(error, ZIP_ER_EXISTS, 0); return NULL; } if (zip_source_open(src) < 0) { _zip_error_set_from_source(error, src); return NULL; } if (flags & ZIP_TRUNCATE) { za = _zip_allocate_new(src, flags, error); } else { /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */ za = _zip_open(src, flags, error); } if (za == NULL) { zip_source_close(src); return NULL; } return za; } } }