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; }
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 struct zip_file * zip_fopen_index(struct zip *za, int fileno, int flags) { int len, ret; int zfflags; struct zip_file *zf; if ((fileno < 0) || (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; } zfflags = 0; switch (za->cdir->entry[fileno].comp_method) { case ZIP_CM_STORE: zfflags |= ZIP_ZF_CRC; break; case ZIP_CM_DEFLATE: if ((flags & ZIP_FL_COMPRESSED) == 0) zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP; break; default: if ((flags & ZIP_FL_COMPRESSED) == 0) { _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); return NULL; } break; } zf = _zip_file_new(za); zf->flags = zfflags; /* zf->name = za->cdir->entry[fileno].filename; */ zf->method = za->cdir->entry[fileno].comp_method; zf->bytes_left = za->cdir->entry[fileno].uncomp_size; zf->cbytes_left = za->cdir->entry[fileno].comp_size; zf->crc_orig = za->cdir->entry[fileno].crc; if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) { zip_fclose(zf); return NULL; } if ((zf->flags & ZIP_ZF_DECOMP) == 0) zf->bytes_left = zf->cbytes_left; else { if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_fclose(zf); return NULL; } len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf); if (len <= 0) { _zip_error_copy(&za->error, &zf->error); zip_fclose(zf); return NULL; } if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_fclose(zf); return NULL; } zf->zstr->zalloc = Z_NULL; zf->zstr->zfree = Z_NULL; zf->zstr->opaque = NULL; zf->zstr->next_in = (Bytef *)zf->buffer; zf->zstr->avail_in = len; /* negative value to tell zlib that there is no header */ if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) { _zip_error_set(&za->error, ZIP_ER_ZLIB, ret); zip_fclose(zf); return NULL; } } return zf; }