virtual req::ptr<File> open(const String& filename, const String& mode, int options, const req::ptr<StreamContext>& context) { std::string url(filename.c_str()); auto pound = url.find('#'); if (pound == std::string::npos) { return nullptr; } // 6 is the position after zip:// auto path = url.substr(6, pound - 6); auto file = url.substr(pound + 1); if (path.empty() || file.empty()) { return nullptr; } int err; auto z = _zip_open(path, 0, &err); if (z == nullptr) { return nullptr; } return req::make<ZipStream>(z, file); }
zip_open(const char *fn, int flags, int *zep) { FILE *fp; if (flags & ZIP_OVERWRITE) { return _zip_allocate_new(fn, zep); } switch (_zip_file_exists(fn, flags, zep)) { case -1: if (!(flags & ZIP_OVERWRITE)) { return NULL; } case 0: return _zip_allocate_new(fn, zep); default: break; } if ((fp=fopen(fn, "rb")) == NULL) { set_error(zep, NULL, ZIP_ER_OPEN); return NULL; } return _zip_open(fn, fp, flags, 0, zep); }
ZIP_EXTERN struct zip * zip_fdopen(int fd_orig, int flags, int *zep) { int fd; FILE *fp; if (flags & ZIP_TRUNCATE) { *zep = ZIP_ER_INVAL; return NULL; } /* We dup() here to avoid messing with the passed in fd. We could not restore it to the original state in case of error. */ if ((fd=dup(fd_orig)) < 0) { *zep = ZIP_ER_OPEN; return NULL; } if ((fp=fdopen(fd, "rb")) == NULL) { close(fd); *zep = ZIP_ER_OPEN; return NULL; } close(fd_orig); return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep); }
ZIP_EXTERN struct zip * zip_open(const char *fn, int flags, int *zep) { FILE *fp; switch (_zip_file_exists(fn, flags, zep)) { case -1: return NULL; case 0: return _zip_allocate_new(fn, zep); default: break; } if ((fp=fopen(fn, "rb")) == NULL) { set_error(zep, NULL, ZIP_ER_OPEN); return NULL; } return _zip_open(fn, fp, flags, 0, zep); }
ZIP_EXTERN struct zip * zip_open(const char *fn, int _flags, int *zep) { FILE *fp; unsigned int flags; if (_flags < 0) { if (zep) *zep = ZIP_ER_INVAL; return NULL; } flags = (unsigned int)_flags; switch (_zip_file_exists(fn, flags, zep)) { case -1: return NULL; case 0: return _zip_allocate_new(fn, flags, zep); default: if (flags & ZIP_TRUNCATE) { FILE *f; if ((f = fopen(fn, "rb")) == NULL) { set_error(zep, NULL, ZIP_ER_OPEN); return NULL; } fclose(f); return _zip_allocate_new(fn, flags, zep); } break; } if ((fp=fopen(fn, "rb")) == NULL) { set_error(zep, NULL, ZIP_ER_OPEN); return NULL; } return _zip_open(fn, fp, flags, zep); }
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; } } }