SDL_RWops *SDL_RWFromZIP(const char* archivename, const char* filename) { SDL_RWops* rwops; struct zip* zarchive; struct zip_file* zfile; int errorp = 0; zarchive = zip_open(archivename, ZIP_CHECKCONS, &errorp); if (errorp != 0) { char *errorbuf = NULL; int len = 1; errorbuf = malloc(len); len = zip_error_to_str(errorbuf, len, errorp, errno); errorbuf = realloc(errorbuf, len + 1); len = zip_error_to_str(errorbuf, len, errorp, errno); log_warn("zip_open: %s", errorbuf); free(errorbuf); return NULL; } zfile = zip_fopen(zarchive, filename, 0); if (zfile == NULL) { log_error("zip_open: %s", zip_strerror(zarchive)); zip_close(zarchive); return NULL; } /* libzip does not support seek()ing in file, so we can't use it - TTF_OpenFontRW needs it to read data at the end of files. */ #if 0 rwops = SDL_AllocRW(); if (rwops == NULL) { errno=ENOMEM; zip_close(zarchive); return NULL; } rwops->hidden.unknown.data1 = zfile; rwops->read = rwops_libzip_read; rwops->write = rwops_libzip_write; rwops->seek = rwops_libzip_seek; rwops->close = rwops_libzip_close; return rwops; #endif struct zip_stat zfilestat; if (zip_stat(zarchive, filename, 0, &zfilestat) < 0) { log_warn("zip_open: %s", zip_strerror(zarchive)); zip_close(zarchive); return NULL; } char *content = malloc(zfilestat.size); zip_fread(zfile, content, zfilestat.size); rwops = SDL_RWFromMem(content, zfilestat.size); zip_fclose(zfile); zip_close(zarchive); return rwops; }
AbstractFSProvider::status_t ZIPProvider::ZIPHandle::dir( const std::string & localDirectory, std::list<FileName> & result, const uint8_t flags) { int num = zip_get_num_files(handle); if (num == -1) { WARN(zip_strerror(handle)); return FAILURE; } struct zip_stat sb; zip_stat_init(&sb); // Iterate over indices. for (int i = 0; i < num; ++i) { if (zip_stat_index(handle, i, 0, &sb) == -1) { WARN(zip_strerror(handle)); return FAILURE; } FileName entryFileName(sb.name); // Determine if the entry is a file or a directory. if (entryFileName.getFile().empty()) { if(!(flags & FileUtils::DIR_DIRECTORIES)) { continue; } if (!(flags & FileUtils::DIR_RECURSIVE)) { std::string entryDirectory = entryFileName.getDir(); if(entryDirectory == localDirectory) { continue; } if(entryDirectory.back() == '/') { entryDirectory.resize(entryDirectory.size() - 1); } const auto slashPos = entryDirectory.find_last_of('/'); if(slashPos != std::string::npos) { entryDirectory = entryDirectory.substr(0, slashPos + 1); } else { entryDirectory.clear(); } // Compare the parent directory of the directory with the requested localDirectory. if(entryDirectory != localDirectory) { continue; } } } else { if(!(flags & FileUtils::DIR_FILES)) { continue; } // Compare the directory of the file with the requested localDirectory. if (!(flags & FileUtils::DIR_RECURSIVE) && entryFileName.getDir() != localDirectory) { continue; } } // Check for hidden files beginning with '.' (files only). if (entryFileName.getFile().front() == '.' && !(flags & FileUtils::DIR_HIDDEN_FILES)) { continue; } FileName f; f.setFSName(archiveRoot.getFSName()); f.setDir(archiveRoot.getDir() + entryFileName.getDir()); f.setFile(entryFileName.getFile()); result.push_back(f); } return OK; }
struct input_file *read_file_list (int argc, char **argv, int *nf_r, char *errstr) { struct input_file *list = (struct input_file *) NULL; FILE *fp = (FILE *) NULL; char line[16384], *av, *p, *s; int a, f, nf = 0; #ifndef _WIN32 glob_t gbuf; int rv, op; /* Init */ gbuf.gl_pathv = (char **) NULL; #endif int is_zip; #ifdef ZIPSUPPORT zip_t *z = (zip_t *) NULL; zip_error_t ze; struct zip_stat sb; int zerrno; int ent, nent; const char *name; int namelen; zip_uint8_t opsys; zip_uint32_t extattr; #endif /* Loop over arguments */ for(a = 0; a < argc; a++) { av = argv[a]; if(*av == '@') { /* @list form */ av++; /* skip past the @ */ is_zip = is_zip_file(av, errstr); if(is_zip < 0) goto error; if(is_zip) { #ifdef ZIPSUPPORT z = zip_open(av, 0, &zerrno); if(!z) { zip_error_init_with_code(&ze, zerrno); report_err(errstr, "zip_open: %s: %s", av, zip_error_strerror(&ze)); zip_error_fini(&ze); goto error; } nent = zip_get_num_entries(z, 0); if(nent < 0) { report_err(errstr, "zip_get_num_entries: %s", zip_strerror(z)); goto error; } for(ent = 0; ent < nent; ent++) { if(zip_stat_index(z, ent, 0, &sb)) { report_err(errstr, "zip_stat_index(%d): %s\n", ent, zip_strerror(z)); goto error; } if(zip_file_get_external_attributes(z, ent, 0, &opsys, &extattr)) { report_err(errstr, "zip_get_external_attributes(%d): %s\n", ent, zip_strerror(z)); goto error; } name = sb.name; namelen = strlen(name); if((opsys != ZIP_OPSYS_AMIGA && extattr & 0x10) || (namelen > 0 && name[namelen-1] == '/')) /* Is directory */ continue; /* Otherwise, add to list */ list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(name); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = ent; list[nf].iarg = a; list[nf].arg = av; nf++; } if(zip_close(z)) { report_err(errstr, "zip_close: %s", zip_strerror(z)); goto error; } z = (zip_t *) NULL; #else report_err(errstr, "not compiled with zip support"); goto error; #endif } else { fp = fopen(av, "r"); if(!fp) { report_syserr(errstr, "open: %s", av); goto error; } while(fgets(line, sizeof(line), fp)) { p = sstrip(line); if(*p) { list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(p); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = -1; list[nf].iarg = a; list[nf].arg = av; nf++; } } if(ferror(fp)) { report_syserr(errstr, "read: %s", av); goto error; } fclose(fp); fp = (FILE *) NULL; } } else { /* glob or single filename */ #ifndef _WIN32 rv = glob(av, 0, NULL, &gbuf); if(rv == 0) { /* succeeded */ /* Allocate block */ list = (struct input_file *) realloc(list, (nf+gbuf.gl_pathc) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } /* Zero out the new pointers */ memset(list+nf, 0, gbuf.gl_pathc * sizeof(struct input_file)); /* Record so we know to free them */ op = nf; nf += gbuf.gl_pathc; for(f = 0; f < gbuf.gl_pathc; f++) { s = strdup(gbuf.gl_pathv[f]); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[op].filename = s; list[op].ient = -1; list[op].iarg = a; list[op].arg = av; op++; } globfree(&gbuf); gbuf.gl_pathv = (char **) NULL; } else if(rv == GLOB_NOMATCH) { /* no match */ #endif /* _WIN32 */ /* Assume it's a single entry. */ list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(av); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = -1; list[nf].iarg = a; list[nf].arg = av; nf++; #ifndef _WIN32 } else { report_err(errstr, "glob error: %s", av); goto error; } #endif } } *nf_r = nf; return(list); error: if(fp) fclose(fp); #ifndef _WIN32 if(gbuf.gl_pathv) globfree(&gbuf); #endif #ifdef ZIPSUPPORT if(z) { zip_close(z); z = (zip_t *) NULL; } #endif if(list) { for(f = 0; f < nf; f++) if(list[f].filename) free((void *) list[f].filename); free((void *) list); } return((struct input_file *) NULL); }
/* zipfile.replaceFile(nameInArchive, name, offset, len) */ Handle<Value> ZipFile::Replace_File(const Arguments& args) { ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This()); struct zip_source *source; if (zf->Busy()) return ThrowException(Exception::Error(String::New("Zipfile already in use.."))); if (!args[0]->IsString()) return ThrowException(Exception::TypeError( String::New("Argument must be a file name."))); std::string archive_file = TOSTR(args[0]); std::string name; if (args[1]->IsUndefined()) name = archive_file; else if (!args[1]->IsString()) return ThrowException(Exception::TypeError( String::New("Argument must be a file name."))); name = TOSTR(args[1]); zip_int64_t off; if (args[2]->IsUndefined()) off = 0; else off = args[2]->Int32Value(); zip_int64_t len; if (args[3]->IsUndefined()) len = -1; else len = args[3]->Int32Value(); int idx = -1; std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), archive_file); if (it!=zf->names.end()) { idx = distance(zf->names.begin(), it); } if (idx == -1) { std::stringstream s; s << "No file found by the name of: '" << archive_file << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } source = zip_source_file(zf->archive, name.c_str(), off, len); if (source == NULL) { std::stringstream s; s << "Error while replacing file " << name << " in zip archive: " << zip_strerror(zf->archive) << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } int ret = zip_replace(zf->archive, idx, source); if (ret < 0) { zip_source_free(source); std::stringstream s; s << "Error while replacing file " << name << " in zip archive: " << zip_strerror(zf->archive) << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } return Undefined(); }
ZIPProvider::ZIPHandle::~ZIPHandle() { if (zip_close(handle) == -1) { WARN(zip_strerror(handle)); } }
Handle<Value> ZipFile::readFileSync(const Arguments& args) { HandleScope scope; if (args.Length() != 1 || !args[0]->IsString()) return ThrowException(Exception::TypeError( String::New("first argument must be a file name inside the zip"))); std::string name = TOSTR(args[0]); // TODO - enforce valid index ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This()); if (zf->Busy()) return ThrowException(Exception::Error(String::New("Zipfile already in use.."))); struct zip_file *zf_ptr; int idx = -1; std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), name); if (it!=zf->names.end()) { idx = distance(zf->names.begin(), it); } if (idx == -1) { std::stringstream s; s << "No file found by the name of: '" << name << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } if ((zf_ptr=zip_fopen_index(zf->archive, idx, 0)) == NULL) { zip_fclose(zf_ptr); std::stringstream s; s << "cannot open file #" << idx << " in " << name << ": archive error: " << zip_strerror(zf->archive) << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } struct zip_stat st; zip_stat_index(zf->archive, idx, 0, &st); std::vector<unsigned char> data; data.clear(); data.resize( st.size ); int result = 0; result = (int)zip_fread( zf_ptr, reinterpret_cast<void*> (&data[0]), data.size() ); if (result < 0) { zip_fclose(zf_ptr); std::stringstream s; s << "error reading file #" << idx << " in " << name << ": archive error: " << zip_file_strerror(zf_ptr) << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } #if NODE_VERSION_AT_LEAST(0,3,0) node::Buffer *retbuf = Buffer::New((char *)&data[0],data.size()); #else node::Buffer *retbuf = Buffer::New(data.size()); std::memcpy(retbuf->data(), (char *)&data[0], data.size()); #endif zip_fclose(zf_ptr); return scope.Close(retbuf->handle_); }
Handle<Value> ZipFile::Open(const Arguments& args) { if (args.Length() != 1 || !args[0]->IsString()) return ThrowException(Exception::TypeError( String::New("Argument must be a file name inside the zip"))); std::string name = TOSTR(args[0]); // TODO - enforce valid index ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This()); if (zf->Busy()) return ThrowException(Exception::Error(String::New("Zipfile already in use.."))); zf->file_index = -1; std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), name); if (it!=zf->names.end()) { zf->file_index = distance(zf->names.begin(), it); } if (zf->file_index == -1) { std::stringstream s; s << "No file found by the name of: '" << name << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } if ((zf->file=zip_fopen_index(zf->archive, zf->file_index, 0)) == NULL) { zip_fclose(zf->file); zf->file = NULL; std::stringstream s; s << "cannot open file #" << zf->file_index << " in " << name << ": archive error: " << zip_strerror(zf->archive) << "\n"; return ThrowException(Exception::Error(String::New(s.str().c_str()))); } return Undefined(); }
void print_zip_err(const char *prefix, zip_t *zip) { char buffer[1024]; snprintf(buffer, 1024, "%s: %s\n", prefix, zip_strerror(zip)); engine_print(buffer); }
int session_save(char *filename) { GSList *l, *d; struct device *device; struct datastore *ds; struct zip *zipfile; struct zip_source *src; int bufcnt, devcnt, tmpfile, ret, error; char version[1], rawname[16], metafile[32], *buf; /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(filename); if (!(zipfile = zip_open(filename, ZIP_CREATE, &error))) return SIGROK_ERR; /* Version */ version[0] = '1'; if (!(src = zip_source_buffer(zipfile, version, 1, 0))) return SIGROK_ERR; if (zip_add(zipfile, "version", src) == -1) { g_message("error saving version into zipfile: %s", zip_strerror(zipfile)); return SIGROK_ERR; } /* Metadata */ strcpy(metafile, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SIGROK_ERR; close(tmpfile); make_metadata(metafile); if (!(src = zip_source_file(zipfile, metafile, 0, -1))) return SIGROK_ERR; if (zip_add(zipfile, "metadata", src) == -1) return SIGROK_ERR; unlink(metafile); /* Raw */ devcnt = 1; for (l = session->devices; l; l = l->next) { device = l->data; ds = device->datastore; if (ds) { buf = malloc(ds->num_units * ds->ds_unitsize + DATASTORE_CHUNKSIZE); bufcnt = 0; for (d = ds->chunklist; d; d = d->next) { memcpy(buf + bufcnt, d->data, DATASTORE_CHUNKSIZE); bufcnt += DATASTORE_CHUNKSIZE; } if (!(src = zip_source_buffer(zipfile, buf, ds->num_units * ds->ds_unitsize, TRUE))) return SIGROK_ERR; snprintf(rawname, 15, "raw-%d", devcnt); if (zip_add(zipfile, rawname, src) == -1) return SIGROK_ERR; } devcnt++; } if ((ret = zip_close(zipfile)) == -1) { g_message("error saving zipfile: %s", zip_strerror(zipfile)); return SIGROK_ERR; } return SIGROK_OK; }
int main(int argc, char *argv[]) { int fail, ze; int c; struct zip *z; struct zip_source *zs; char *archive; char errstr[1024]; verbose = 0; fail = 0; prg = argv[0]; while ((c=getopt(argc, argv, "v")) != -1) { switch (c) { case 'v': verbose = 1; break; default: fprintf(stderr, usage, prg); return 1; } } if (argc-optind != 1) { fprintf(stderr, usage, prg); return 1; } archive = argv[optind]; if ((z=zip_open(archive, 0, &ze)) == NULL) { zip_error_to_str(errstr, sizeof(errstr), ze, errno); printf("%s: can't open zip archive '%s': %s\n", prg, archive, errstr); return 1; } fail += do_read(z, "storedok", 0, WHEN_NEVER, 0, 0); fail += do_read(z, "deflateok", 0, WHEN_NEVER, 0, 0); fail += do_read(z, "storedcrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0); fail += do_read(z, "deflatecrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0); fail += do_read(z, "deflatezliberror", 0, WHEN_READ, ZIP_ER_ZLIB, -3); fail += do_read(z, NULL, 0, WHEN_OPEN, ZIP_ER_INVAL, 0); fail += do_read(z, "nosuchfile", 0, WHEN_OPEN, ZIP_ER_NOENT, 0); fail += do_read(z, "deflatezliberror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0,0); fail += do_read(z, "deflatecrcerror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0); fail += do_read(z, "storedcrcerror", ZIP_FL_COMPRESSED, WHEN_READ, ZIP_ER_CRC, 0); fail += do_read(z, "storedok", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0); fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_NOPASSWD, 0); zip_set_default_password(z, "crypt"); fail += do_read(z, "cryptok", 0, WHEN_NEVER, 0, 0); zip_set_default_password(z, "wrong"); fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_WRONGPASSWD, 0); zip_set_default_password(z, NULL); zs = zip_source_buffer(z, "asdf", 4, 0); zip_replace(z, zip_name_locate(z, "storedok", 0), zs); fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0); fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0); zip_delete(z, zip_name_locate(z, "storedok", 0)); fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_NOENT, 0); fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0); zs = zip_source_buffer(z, "asdf", 4, 0); if (zip_file_add(z, "new_file", zs, 0) < 0) fprintf(stderr, "%s: can't add file to zip archive '%s': %s\n", prg, archive, zip_strerror(z)); fail += do_read(z, "new_file", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0); zip_unchange_all(z); if (zip_close(z) == -1) { fprintf(stderr, "%s: can't close zip archive '%s': %s\n", prg, archive, zip_strerror(z)); return 1; } exit(fail ? 1 : 0); }