int main(int argc, char *argv[]) { #if 0 int i; #endif struct zip *za, *destza; #if 0 #define BUFSIZE 65536 struct zip_file *zf1, *zf2; char buf1[BUFSIZE], buf2[BUFSIZE]; #endif #if 0 if (argc != 2) { fprintf(stderr, "%s: call with one option: the zip-file to destroy" "^H^H^H^H^H^H^Htest\n", argv[0]); return 1; } #endif if (argc != 3) { fprintf(stderr, "%s: call with two options: src dest\n", argv[0]); return 1; } if ((za=zip_open(argv[1], ZIP_CHECKCONS))==NULL) { fprintf(stderr, "%s: %s: can't open file: %s\n", argv[0], argv[1], zip_err_str[zip_err]); return 1; } if ((destza=zip_open(argv[2], ZIP_CREATE))==NULL) { fprintf(stderr, "%s: %s: can't open file: %s\n", argv[0], argv[2], zip_err_str[zip_err]); return 1; } #if 0 for (i=0; i<za->nentry; i++) { printf("%8d %s\n", za->entry[i].uncomp_size, za->entry[i].fn); zip_add_zip(destza, za->entry[i].fn, za, i, 0, 0); } #endif if (zip_add_zip(destza, NULL, NULL, za, 0, 0, 0) == -1) fprintf(stderr, "%s: %s: can't add file to zip '%s': %s\n", argv[0], za->entry[0].fn, argv[1], zip_err_str[zip_err]); #if 0 zf1= zf_open_index(za, 1); if (!zf1) { fprintf(stderr, "boese, boese\n"); exit(100); } i = zf_read(zf1, buf1, 100); if (i < 0) fprintf(stderr, "read error: %s\n", zip_err_str[zf1->flags]); else { buf1[i] = 0; printf("read %d bytes: '%s'\n", i, buf1); } zf2 = zf_open_index(za, 1); i = zf_read(zf2, buf2, 200); if (i < 0) fprintf(stderr, "read error: %s\n", zip_err_str[zf2->flags]); else { buf2[i] = 0; printf("read %d bytes: '%s'\n", i, buf2); } i = zf_read(zf1, buf1, 100); if (i < 0) fprintf(stderr, "read error: %s\n", zip_err_str[zf1->flags]); else { buf1[i] = 0; printf("read %d bytes: '%s'\n", i, buf1); } zf_close(zf1); zf_close(zf2); #endif if (zip_close(destza)!=0) { fprintf(stderr, "%s: %s: can't close file: %s\n", argv[0], argv[2], zip_err_str[zip_err]); return 1; } if (zip_close(za)!=0) { fprintf(stderr, "%s: %s: can't close file: %s\n", argv[0], argv[1], zip_err_str[zip_err]); return 1; } return 0; }
bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile, const bool selected) { static const char errPrefix[] = "divelog.de-upload:"; if (!amount_selected) { report_error(tr("no dives were selected").toUtf8()); return false; } xsltStylesheetPtr xslt = NULL; struct zip *zip; xslt = get_stylesheet("divelogs-export.xslt"); if (!xslt) { qDebug() << errPrefix << "missing stylesheet"; return false; } int error_code; zip = zip_open(QFile::encodeName(tempfile), ZIP_CREATE, &error_code); if (!zip) { char buffer[1024]; zip_error_to_str(buffer, sizeof buffer, error_code, errno); report_error(tr("failed to create zip file for upload: %s").toUtf8(), buffer); return false; } /* walk the dive list in chronological order */ for (int i = 0; i < dive_table.nr; i++) { FILE *f; char filename[PATH_MAX]; int streamsize; char *membuf; xmlDoc *transformed; struct zip_source *s; /* * Get the i'th dive in XML format so we can process it. * We need to save to a file before we can reload it back into memory... */ struct dive *dive = get_dive(i); if (!dive) continue; if (selected && !dive->selected) continue; f = tmpfile(); if (!f) { report_error(tr("cannot create temporary file: %s").toUtf8(), qt_error_string().toUtf8().data()); goto error_close_zip; } save_dive(f, dive); fseek(f, 0, SEEK_END); streamsize = ftell(f); rewind(f); membuf = (char *)malloc(streamsize + 1); if (!membuf || (streamsize = fread(membuf, streamsize, 1, f)) == 0) { report_error(tr("internal error: %s").toUtf8(), qt_error_string().toUtf8().data()); fclose(f); free((void *)membuf); goto error_close_zip; } membuf[streamsize] = 0; fclose(f); /* * Parse the memory buffer into XML document and * transform it to divelogs.de format, finally dumping * the XML into a character buffer. */ xmlDoc *doc = xmlReadMemory(membuf, streamsize, "divelog", NULL, 0); if (!doc) { qWarning() << errPrefix << "could not parse back into memory the XML file we've just created!"; report_error(tr("internal error").toUtf8()); free((void *)membuf); goto error_close_zip; } free((void *)membuf); transformed = xsltApplyStylesheet(xslt, doc, NULL); xmlDocDumpMemory(transformed, (xmlChar **)&membuf, &streamsize); xmlFreeDoc(doc); xmlFreeDoc(transformed); /* * Save the XML document into a zip file. */ snprintf(filename, PATH_MAX, "%d.xml", i + 1); s = zip_source_buffer(zip, membuf, streamsize, 1); if (s) { int64_t ret = zip_add(zip, filename, s); if (ret == -1) qDebug() << errPrefix << "failed to include dive:" << i; } } zip_close(zip); xsltFreeStylesheet(xslt); return true; error_close_zip: zip_close(zip); QFile::remove(tempfile); xsltFreeStylesheet(xslt); return false; }
static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { struct zip_stat sb; const char *path = stream->orig_path; size_t path_len = strlen(stream->orig_path); char file_dirname[MAXPATHLEN]; struct zip *za; char *fragment; size_t fragment_len; int err; zend_string *file_basename; fragment = strchr(path, '#'); if (!fragment) { return -1; } if (strncasecmp("zip://", path, 6) == 0) { path += 6; } fragment_len = strlen(fragment); if (fragment_len < 1) { return -1; } path_len = strlen(path); if (path_len >= MAXPATHLEN) { return -1; } memcpy(file_dirname, path, path_len - fragment_len); file_dirname[path_len - fragment_len] = '\0'; file_basename = php_basename((char *)path, path_len - fragment_len, NULL, 0); fragment++; if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) { zend_string_release(file_basename); return -1; } za = zip_open(file_dirname, ZIP_CREATE, &err); if (za) { memset(ssb, 0, sizeof(php_stream_statbuf)); if (zip_stat(za, fragment, ZIP_FL_NOCASE, &sb) != 0) { zip_close(za); zend_string_release(file_basename); return -1; } zip_close(za); if (path[path_len-1] != '/') { ssb->sb.st_size = sb.size; ssb->sb.st_mode |= S_IFREG; /* regular file */ } else { ssb->sb.st_size = 0; ssb->sb.st_mode |= S_IFDIR; /* regular directory */ } ssb->sb.st_mtime = sb.mtime; ssb->sb.st_atime = sb.mtime; ssb->sb.st_ctime = sb.mtime; ssb->sb.st_nlink = 1; ssb->sb.st_rdev = -1; #ifndef PHP_WIN32 ssb->sb.st_blksize = -1; ssb->sb.st_blocks = -1; #endif ssb->sb.st_ino = -1; } zend_string_release(file_basename); return 0; }
void process_zip(char *pPath) { #ifdef HAVE_LIBZZIP ZZIP_DIR *dir; ZZIP_FILE *fp; ZZIP_DIRENT dirent; char buf[BUF_SIZE]; int nRead; long depth = 0; int ret = 0; dir = zzip_dir_open(pPath, 0); if (!dir) { return; } while (zzip_dir_read(dir, &dirent)) { fp = zzip_file_open(dir, dirent.d_name, 0); if (fp) { // pull the data and scan while ((nRead = zzip_file_read(fp, buf, BUF_SIZE)) > 0) { depth += nRead; if (is_match(buf,nRead)) { ret = 1; if (!LogTotalMatches) { send_match(hit,pPath); break; } } bzero(buf, sizeof(buf)); if ((ScanDepth != 0) && (depth >= (ScanDepth * 1024))) { break; } } zzip_file_close(fp); } } if ((LogTotalMatches && TotalMatches) || ret) { send_match(hit, pPath); } zzip_dir_close(dir); #else #ifdef HAVE_LIBZIP struct zip *za; int err, ret = 0, nRead; char errstr[1024], buf[BUF_SIZE]; long depth; if ((za = zip_open(pPath, 0, &err)) == NULL) { return; } while ((nRead = zip_fread(za, &buf, BUF_SIZE)) > 0) { depth += nRead; if (is_match(buf,nRead)) { ret = 1; if (!LogTotalMatches) { send_match(hit,pPath); zip_close(za); return; } } bzero(buf, sizeof(buf)); if ((ScanDepth != 0) && (depth >= (ScanDepth * 1024))) { break; } } if ((LogTotalMatches && TotalMatches) || ret) { send_match(hit, pPath); } zip_close(za); #endif /* HAVE_LIBZIP */ return; #endif /* HAVE_ZZIP */ }
bool UncompressAllFiles(std::string ZipName, std::vector<std::string>* pFileNames, std::vector<std::vector<char> >* data, std::string* pError) { #ifdef WIN32 HZIP hz = OpenZip(ZipName.c_str(),0); if (!hz){if(pError) *pError += ("Unable to open ZIP archive. Aborting.\n"); return false;} ZIPENTRY ze; if (GetZipItem(hz, -1, &ze) != ZR_OK) {if(pError) *pError += ("Unable to return information about ZIP archive. Aborting.\n"); return false;} int NumFiles = ze.index; //set up returns for the number of files... pFileNames->resize(NumFiles); data->resize(NumFiles); for (int i=0; i<NumFiles; i++){ if (GetZipItem(hz,i,&ze) != ZR_OK) {if(pError) *pError += "Error loading ZIP file information. Aborting.\n"; return false;} int size = ze.unc_size; (*data)[i].resize(size+1); if (UnzipItem(hz, i, &((*data)[i].front()), size) != ZR_OK) {if(pError) *pError += "Could not unzip sub-file. Aborting.\n"; return false;} (*data)[i][size] = '\0'; (*pFileNames)[i] = ze.name; } if (CloseZip(hz) != ZR_OK) {if(pError) *pError += "Error closing ZIP file.\n"; return false;} return true; #else //Mac/Linux Zip read code int err; struct zip * hz = zip_open(ZipName.c_str(), ZIP_CHECKCONS, &err); if (!hz){if(pError) *pError += ("Unable to open ZIP archive. Aborting.\n"); return false;} int NumFiles = zip_get_num_entries(hz,0); if (NumFiles < 0) { if(pError) *pError += ("Unable to return information about ZIP archive. Aborting.\n"); return false;} //set up returns for the number of files... pFileNames->resize(NumFiles); data->resize(NumFiles); for (int i=0; i<NumFiles; i++){ struct zip_stat stat; err = zip_stat_index(hz, i, 0, &stat); int size = stat.size; (*data)[i].resize(size+1); struct zip_file * zfile = zip_fopen_index(hz, i, 0); if (zip_fread(zfile, &((*data)[i].front()), size) != size) {if(pError) *pError += "Could not unzip sub-file. Aborting.\n"; return false;} (*data)[i][size] = '\0'; (*pFileNames)[i] = zip_get_name(hz, i, 0); } if (zip_close(hz) != 0) {if(pError) *pError += "Error closing ZIP file.\n"; return false;} return true; #endif }
/** * Save the current session to the specified file. * * @param filename The name of the filename to save the current session as. * Must not be NULL. * @param sdi The device instance from which the data was captured. * @param buf The data to be saved. * @param unitsize The number of bytes per sample. * @param units The number of samples. * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or SR_ERR * upon other errors. */ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, unsigned char *buf, int unitsize, int units) { GSList *l; GVariant *gvar; FILE *meta; struct sr_channel *probe; struct zip *zipfile; struct zip_source *versrc, *metasrc, *logicsrc; int tmpfile, ret, probecnt; uint64_t samplerate, timeBase, tmp_u64; char rawname[16], metafile[32], *s; struct sr_status status; if (!filename) { sr_err("%s: filename was NULL", __func__); return SR_ERR_ARG; } /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(filename); if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret))) return SR_ERR; /* init "metadata" */ strcpy(metafile, "DSView-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[version]\n"); fprintf(meta, "DSView version = %s\n", PACKAGE_VERSION); /* metadata */ fprintf(meta, "[header]\n"); if (sdi->driver) { fprintf(meta, "driver = %s\n", sdi->driver->name); fprintf(meta, "device mode = %d\n", sdi->mode); } /* metadata */ fprintf(meta, "capturefile = data\n"); fprintf(meta, "unitsize = %d\n", unitsize); fprintf(meta, "total samples = %d\n", units); fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels)); if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); s = sr_samplerate_string(samplerate); fprintf(meta, "samplerate = %s\n", s); g_free(s); g_variant_unref(gvar); } if (sdi->mode == DSO && sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_TIMEBASE, &gvar) == SR_OK) { timeBase = g_variant_get_uint64(gvar); fprintf(meta, "hDiv = %d\n", timeBase); g_variant_unref(gvar); } probecnt = 1; for (l = sdi->channels; l; l = l->next) { probe = l->data; if (probe->enabled || sdi->mode == DSO) { if (probe->name) fprintf(meta, "probe%d = %s\n", probe->index, probe->name); if (probe->trigger) fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger); if (sdi->mode == DSO) { fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled); fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling); fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv); fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor); fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos); if (sr_status_get(sdi, &status, 0, 0) == SR_OK) { if (probe->index == 0) { fprintf(meta, " period%d = %d\n", probe->index, status.ch0_period); fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch0_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min); } else { fprintf(meta, " period%d = %d\n", probe->index, status.ch1_period); fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch1_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min); } } } probecnt++; } } if (!(logicsrc = zip_source_buffer(zipfile, buf, units * unitsize, FALSE))) return SR_ERR; snprintf(rawname, 15, "data"); if (zip_add(zipfile, rawname, logicsrc) == -1) return SR_ERR; fclose(meta); if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) return SR_ERR; if (zip_add(zipfile, "header", metasrc) == -1) return SR_ERR; if ((ret = zip_close(zipfile)) == -1) { sr_info("error saving zipfile: %s", zip_strerror(zipfile)); return SR_ERR; } unlink(metafile); return SR_OK; }
/** * Append data to an existing session file. * * The session file must have been created with sr_session_save_init() * or sr_session_save() beforehand. * * @param filename The name of the filename to append to. Must not be NULL. * @param buf The data to be appended. * @param unitsize The number of bytes per sample. * @param units The number of samples. * * @retval SR_OK Success * @retval SR_ERR_ARG Invalid arguments * @retval SR_ERR Other errors * * @since 0.3.0 */ SR_API int sr_session_append(const char *filename, unsigned char *buf, int unitsize, int units) { struct zip *archive; struct zip_source *logicsrc; zip_int64_t num_files; struct zip_file *zf; struct zip_stat zs; struct zip_source *metasrc; GKeyFile *kf; GError *error; gsize len; int chunk_num, next_chunk_num, tmpfile, ret, i; const char *entry_name; char *metafile, tmpname[32], chunkname[16]; if ((ret = sr_sessionfile_check(filename)) != SR_OK) return ret; if (!(archive = zip_open(filename, 0, &ret))) return SR_ERR; if (zip_stat(archive, "metadata", 0, &zs) == -1) return SR_ERR; metafile = g_malloc(zs.size); zf = zip_fopen_index(archive, zs.index, 0); zip_fread(zf, metafile, zs.size); zip_fclose(zf); /* * If the file was only initialized but doesn't yet have any * data it in, it won't have a unitsize field in metadata yet. */ error = NULL; kf = g_key_file_new(); if (!g_key_file_load_from_data(kf, metafile, zs.size, 0, &error)) { sr_err("Failed to parse metadata: %s.", error->message); return SR_ERR; } g_free(metafile); tmpname[0] = '\0'; if (!g_key_file_has_key(kf, "device 1", "unitsize", &error)) { if (error && error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { sr_err("Failed to check unitsize key: %s", error ? error->message : "?"); return SR_ERR; } /* Add unitsize field. */ g_key_file_set_integer(kf, "device 1", "unitsize", unitsize); metafile = g_key_file_to_data(kf, &len, &error); strcpy(tmpname, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(tmpname)) == -1) return SR_ERR; if (write(tmpfile, metafile, len) < 0) { sr_dbg("Failed to create new metadata: %s", strerror(errno)); g_free(metafile); unlink(tmpname); return SR_ERR; } close(tmpfile); if (!(metasrc = zip_source_file(archive, tmpname, 0, -1))) { sr_err("Failed to create zip source for metadata."); g_free(metafile); unlink(tmpname); return SR_ERR; } if (zip_replace(archive, zs.index, metasrc) == -1) { sr_err("Failed to replace metadata file."); g_free(metafile); unlink(tmpname); return SR_ERR; } g_free(metafile); } g_key_file_free(kf); next_chunk_num = 1; num_files = zip_get_num_entries(archive, 0); for (i = 0; i < num_files; i++) { entry_name = zip_get_name(archive, i, 0); if (strncmp(entry_name, "logic-1", 7)) continue; if (strlen(entry_name) == 7) { /* This file has no extra chunks, just a single "logic-1". * Rename it to "logic-1-1" * and continue with chunk 2. */ if (zip_rename(archive, i, "logic-1-1") == -1) { sr_err("Failed to rename 'logic-1' to 'logic-1-1'."); unlink(tmpname); return SR_ERR; } next_chunk_num = 2; break; } else if (strlen(entry_name) > 8 && entry_name[7] == '-') { chunk_num = strtoull(entry_name + 8, NULL, 10); if (chunk_num >= next_chunk_num) next_chunk_num = chunk_num + 1; } } snprintf(chunkname, 15, "logic-1-%d", next_chunk_num); if (!(logicsrc = zip_source_buffer(archive, buf, units * unitsize, FALSE))) { unlink(tmpname); return SR_ERR; } if (zip_add(archive, chunkname, logicsrc) == -1) { unlink(tmpname); return SR_ERR; } if ((ret = zip_close(archive)) == -1) { sr_info("error saving session file: %s", zip_strerror(archive)); unlink(tmpname); return SR_ERR; } unlink(tmpname); return SR_OK; }
Zipper::~Zipper() { zip_close(archive_); }
static int zip_create(const struct sr_output *o) { struct out_context *outc; struct sr_channel *ch; FILE *meta; struct zip *zipfile; struct zip_source *versrc, *metasrc; GVariant *gvar; GSList *l; int tmpfile, ret; char version[1], metafile[32], *s; outc = o->priv; if (outc->samplerate == 0) { if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { outc->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } } /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(outc->filename); if (!(zipfile = zip_open(outc->filename, ZIP_CREATE, &ret))) return SR_ERR; /* "version" */ version[0] = '2'; if (!(versrc = zip_source_buffer(zipfile, version, 1, 0))) return SR_ERR; if (zip_add(zipfile, "version", versrc) == -1) { sr_info("Error saving version into zipfile: %s.", zip_strerror(zipfile)); return SR_ERR; } /* init "metadata" */ strcpy(metafile, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[global]\n"); fprintf(meta, "sigrok version = %s\n", SR_PACKAGE_VERSION_STRING); fprintf(meta, "[device 1]\ncapturefile = logic-1\n"); fprintf(meta, "total probes = %d\n", g_slist_length(o->sdi->channels)); s = sr_samplerate_string(outc->samplerate); fprintf(meta, "samplerate = %s\n", s); g_free(s); for (l = o->sdi->channels; l; l = l->next) { ch = l->data; if (ch->type != SR_CHANNEL_LOGIC) continue; if (!ch->enabled) continue; fprintf(meta, "probe%d = %s\n", ch->index + 1, ch->name); } fclose(meta); if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) { unlink(metafile); return SR_ERR; } if (zip_add(zipfile, "metadata", metasrc) == -1) { unlink(metafile); return SR_ERR; } if ((ret = zip_close(zipfile)) == -1) { sr_info("Error saving zipfile: %s.", zip_strerror(zipfile)); unlink(metafile); return SR_ERR; } unlink(metafile); return SR_OK; }
static int load_mzm_common(struct world *mzx_world, const void *buffer, int file_length, int start_x, int start_y, int mode, int savegame, char *name) { const unsigned char *bufferPtr = buffer; char magic_string[5]; int storage_mode; int width, height; int savegame_mode; int num_robots; int robots_location; int data_start; int expected_data_size; // MegaZeux 2.83 is the last version that won't save the ver, // so if we don't have a ver, just act like it's 2.83 int mzm_world_version = 0x0253; if (file_length < 4) goto err_invalid; memcpy(magic_string, bufferPtr, 4); bufferPtr += 4; magic_string[4] = 0; if(!strncmp(magic_string, "MZMX", 4)) { // An MZM1 file is always storage mode 0 storage_mode = 0; savegame_mode = 0; num_robots = 0; robots_location = 0; if (file_length < 16) goto err_invalid; width = mem_getc(&bufferPtr); height = mem_getc(&bufferPtr); bufferPtr += 10; } else if(!strncmp(magic_string, "MZM2", 4)) { if (file_length < 16) goto err_invalid; width = mem_getw(&bufferPtr); height = mem_getw(&bufferPtr); robots_location = mem_getd(&bufferPtr); num_robots = mem_getc(&bufferPtr); storage_mode = mem_getc(&bufferPtr); savegame_mode = mem_getc(&bufferPtr); bufferPtr += 1; } else if(!strncmp(magic_string, "MZM3", 4)) { if (file_length < 20) goto err_invalid; // MZM3 is like MZM2, except the robots are stored as source code if // savegame_mode is 0 and version >= VERSION_PROGRAM_SOURCE. width = mem_getw(&bufferPtr); height = mem_getw(&bufferPtr); robots_location = mem_getd(&bufferPtr); num_robots = mem_getc(&bufferPtr); storage_mode = mem_getc(&bufferPtr); savegame_mode = mem_getc(&bufferPtr); mzm_world_version = mem_getw(&bufferPtr); bufferPtr += 3; } else goto err_invalid; data_start = bufferPtr - (const unsigned char *)buffer; expected_data_size = (width * height) * (storage_mode ? 2 : 6); // Validate if( (savegame_mode > 1) || (savegame_mode < 0) // Invalid save mode || (storage_mode > 1) || (storage_mode < 0) // Invalid storage mode || (file_length - data_start < expected_data_size) // not enough space to store data || (file_length < robots_location) // The end of file is before the robot offset || (robots_location && (expected_data_size + data_start > robots_location)) // robots offset before data end ) goto err_invalid; // If the mzm version is newer than the MZX version, show a message and continue. if(mzm_world_version > WORLD_VERSION) { error_message(E_MZM_FILE_VERSION_TOO_RECENT, mzm_world_version, name); } // If the MZM is a save MZM but we're not loading at runtime, show a message and continue. if(savegame_mode > savegame) { error_message(E_MZM_FILE_FROM_SAVEGAME, 0, name); } switch(mode) { // Write to board case 0: { struct board *src_board = mzx_world->current_board; int board_width = src_board->board_width; int board_height = src_board->board_height; int effective_width = width; int effective_height = height; int file_line_skip; int line_skip; int x, y; int offset = start_x + (start_y * board_width); char *level_id = src_board->level_id; char *level_param = src_board->level_param; char *level_color = src_board->level_color; char *level_under_id = src_board->level_under_id; char *level_under_param = src_board->level_under_param; char *level_under_color = src_board->level_under_color; enum thing src_id; // Clip if((effective_width + start_x) >= board_width) effective_width = board_width - start_x; if((effective_height + start_y) >= board_height) effective_height = board_height - start_y; line_skip = board_width - effective_width; switch(storage_mode) { case 0: { // Board style, write as is enum thing current_id; int current_robot_loaded = 0; int robot_x_locations[256]; int robot_y_locations[256]; int width_difference; int i; width_difference = width - effective_width; for(y = 0; y < effective_height; y++) { for(x = 0; x < effective_width; x++, offset++) { current_id = (enum thing)mem_getc(&bufferPtr); if(current_id >= SENSOR) { if(is_robot(current_id)) { robot_x_locations[current_robot_loaded] = x + start_x; robot_y_locations[current_robot_loaded] = y + start_y; current_robot_loaded++; } // Wipe a bunch of crap we don't want in MZMs with spaces else current_id = 0; } src_id = (enum thing)level_id[offset]; if(src_id >= SENSOR) { if(src_id == SENSOR) clear_sensor_id(src_board, level_param[offset]); else if(is_signscroll(src_id)) clear_scroll_id(src_board, level_param[offset]); else if(is_robot(src_id)) clear_robot_id(src_board, level_param[offset]); } // Don't allow the player to be overwritten if(src_id != PLAYER) { level_id[offset] = current_id; level_param[offset] = mem_getc(&bufferPtr); level_color[offset] = mem_getc(&bufferPtr); level_under_id[offset] = mem_getc(&bufferPtr); level_under_param[offset] = mem_getc(&bufferPtr); level_under_color[offset] = mem_getc(&bufferPtr); // We don't want this on the under layer, thanks if(level_under_id[offset] >= SENSOR) { level_under_id[offset] = 0; level_under_param[offset] = 0; level_under_color[offset] = 7; } } else { bufferPtr += 5; } } offset += line_skip; // Gotta run through and mark the next robots to be skipped for(i = 0; i < width_difference; i++) { current_id = (enum thing)mem_getc(&bufferPtr); bufferPtr += 5; if(is_robot(current_id)) { robot_x_locations[current_robot_loaded] = -1; current_robot_loaded++; } } } for(i = current_robot_loaded; i < num_robots; i++) { robot_x_locations[i] = -1; } if(num_robots) { struct zip_archive *zp; unsigned int file_id; unsigned int robot_id; int result; struct robot *cur_robot; int current_x, current_y; int offset; int new_param; int robot_calculated_size = 0; int robot_partial_size = 0; int current_position; int dummy = 0; // We suppress the errors that will generally occur here and barely // error check the zip functions. Why? This needs to run all the way // through, regardless of whether it finds errors. Otherwise, we'll // get invalid robots with ID=0 littered around the board. set_error_suppression(E_WORLD_ROBOT_MISSING, 1); set_error_suppression(E_BOARD_ROBOT_CORRUPT, 1); // Reset the error count. get_and_reset_error_count(); if(mzm_world_version <= WORLD_LEGACY_FORMAT_VERSION) { robot_partial_size = legacy_calculate_partial_robot_size(savegame_mode, mzm_world_version); bufferPtr = buffer; bufferPtr += robots_location; zp = NULL; } else { zp = zip_open_mem_read(buffer, file_length); zip_read_directory(zp); assign_fprops(zp, 1); } // If we're loading a "runtime MZM" then it means that we're loading // bytecode. And to do this we must both be in-game and must be // running the same version this was made in. But since loading // dynamically created MZMs in the editor is still useful, we'll just // dummy out the robots. if((savegame_mode > savegame) || (WORLD_VERSION < mzm_world_version)) { dummy = 1; } for(i = 0; i < num_robots; i++) { cur_robot = cmalloc(sizeof(struct robot)); current_x = robot_x_locations[i]; current_y = robot_y_locations[i]; // TODO: Skipped legacy robots aren't checked for, so the loaded // chars for dummy robots on clipped MZMs might be off. This // shouldn't matter too often though. if(mzm_world_version <= WORLD_LEGACY_FORMAT_VERSION) { create_blank_robot(cur_robot); current_position = bufferPtr - (const unsigned char *)buffer; // If we fail, we have to continue, or robots won't be dummied // correctly. In this case, seek to the end. if(current_position + robot_partial_size <= file_length) { robot_calculated_size = legacy_load_robot_calculate_size(bufferPtr, savegame_mode, mzm_world_version); if(current_position + robot_calculated_size <= file_length) { legacy_load_robot_from_memory(mzx_world, cur_robot, bufferPtr, savegame_mode, mzm_world_version, (int)current_position); } else { bufferPtr = (const unsigned char*)buffer + file_length; dummy = 1; } } else { bufferPtr = (const unsigned char*)buffer + file_length; dummy = 1; } bufferPtr += robot_calculated_size; } // Search the zip until a robot is found. else do { result = zip_get_next_prop(zp, &file_id, NULL, &robot_id); if(result != ZIP_SUCCESS) { // We have to continue, or we'll get screwed up robots. create_blank_robot(cur_robot); create_blank_robot_program(cur_robot); dummy = 1; break; } else if(file_id != FPROP_ROBOT || (int)robot_id < i) { // Not a robot or is a skipped robot zip_skip_file(zp); } else if((int)robot_id > i) { // There's a robot missing. create_blank_robot(cur_robot); create_blank_robot_program(cur_robot); break; } else { load_robot(mzx_world, cur_robot, zp, savegame_mode, mzm_world_version); break; } } while(1); if(dummy) { // Unfortunately, getting the actual character for the robot is // kind of a lot of work right now. We have to load it then // throw it away. // If this is from a futer version and the format changed, we'll // just end up with an 'R' char, but this shouldn't happen again if(current_x != -1) { offset = current_x + (current_y * board_width); level_id[offset] = CUSTOM_BLOCK; level_param[offset] = cur_robot->robot_char; } clear_robot(cur_robot); } else { cur_robot->world_version = mzx_world->version; cur_robot->xpos = current_x; cur_robot->ypos = current_y; #ifdef CONFIG_DEBYTECODE // If we're loading source code at runtime, we need to compile it if(savegame_mode < savegame) prepare_robot_bytecode(mzx_world, cur_robot); #endif if(current_x != -1) { new_param = find_free_robot(src_board); offset = current_x + (current_y * board_width); if(new_param != -1) { if((enum thing)level_id[offset] != PLAYER) { add_robot_name_entry(src_board, cur_robot, cur_robot->robot_name); src_board->robot_list[new_param] = cur_robot; cur_robot->xpos = current_x; cur_robot->ypos = current_y; level_param[offset] = new_param; } else { clear_robot(cur_robot); } } else { clear_robot(cur_robot); level_id[offset] = 0; level_param[offset] = 0; level_color[offset] = 7; } } else { clear_robot(cur_robot); } } } if(mzm_world_version > WORLD_LEGACY_FORMAT_VERSION) { zip_close(zp, NULL); } // If any errors were encountered, report if(get_and_reset_error_count()) goto err_robots; } break; } case 1: { // Compact style; expand to customblocks // Board style, write as is file_line_skip = (width - effective_width) * 2; for(y = 0; y < effective_height; y++) { for(x = 0; x < effective_width; x++, offset++) { src_id = (enum thing)level_id[offset]; if(src_id == SENSOR) clear_sensor_id(src_board, level_param[offset]); else if(is_signscroll(src_id)) clear_scroll_id(src_board, level_param[offset]); else if(is_robot(src_id)) clear_robot_id(src_board, level_param[offset]); // Don't allow the player to be overwritten if(src_id != PLAYER) { level_id[offset] = CUSTOM_BLOCK; level_param[offset] = mem_getc(&bufferPtr); level_color[offset] = mem_getc(&bufferPtr); level_under_id[offset] = 0; level_under_param[offset] = 0; level_under_color[offset] = 0; } else { bufferPtr += 2; } } offset += line_skip; bufferPtr += file_line_skip; } break; } } break; } // Overlay/vlayer case 1: case 2: { struct board *src_board = mzx_world->current_board; int dest_width = src_board->board_width; int dest_height = src_board->board_height; char *dest_chars; char *dest_colors; int effective_width = width; int effective_height = height; int file_line_skip; int line_skip; int x, y; int offset; if(mode == 1) { // Overlay if(!src_board->overlay_mode) setup_overlay(src_board, 3); dest_chars = src_board->overlay; dest_colors = src_board->overlay_color; dest_width = src_board->board_width; dest_height = src_board->board_height; } else { // Vlayer dest_chars = mzx_world->vlayer_chars; dest_colors = mzx_world->vlayer_colors; dest_width = mzx_world->vlayer_width; dest_height = mzx_world->vlayer_height; } offset = start_x + (start_y * dest_width); // Clip if((effective_width + start_x) >= dest_width) effective_width = dest_width - start_x; if((effective_height + start_y) >= dest_height) effective_height = dest_height - start_y; line_skip = dest_width - effective_width; switch(storage_mode) { case 0: { // Coming from board storage; for now use param as char file_line_skip = (width - effective_width) * 6; for(y = 0; y < effective_height; y++) { for(x = 0; x < effective_width; x++, offset++) { // Skip ID bufferPtr += 1; dest_chars[offset] = mem_getc(&bufferPtr); dest_colors[offset] = mem_getc(&bufferPtr); // Skip under parts bufferPtr += 3; } offset += line_skip; bufferPtr += file_line_skip; } break; } case 1: { // Coming from layer storage; transfer directly file_line_skip = (width - effective_width) * 2; for(y = 0; y < effective_height; y++) { for(x = 0; x < effective_width; x++, offset++) { dest_chars[offset] = mem_getc(&bufferPtr); dest_colors[offset] = mem_getc(&bufferPtr); } offset += line_skip; bufferPtr += file_line_skip; } break; } } break; } } // Clear none of the validation error suppressions: // 1) in combination with poor practice, they could lock MZX, // 2) they'll get reset after reloading the world. return 0; err_robots: // The main file loaded fine, but there was a problem handling robots error_message(E_MZM_ROBOT_CORRUPT, 0, name); return 0; err_invalid: error_message(E_MZM_FILE_INVALID, 0, name); return -1; }
static void save_mzm_common(struct world *mzx_world, int start_x, int start_y, int width, int height, int mode, int savegame, void *(*alloc)(size_t, void **), void **storage) { int storage_mode = 0; void *buffer; unsigned char *bufferPtr; size_t mzm_size; int num_robots_alloc = 0; if(mode) storage_mode = 1; if(savegame) savegame = 1; // Before saving the MZM, we first calculate its file size // Then we allocate the memory needed to store the MZM mzm_size = 20; // Add on the storage space required to store all tiles if (storage_mode == 0) { mzm_size += width * height * 6; } else { mzm_size += width * height * 2; } if (mode == 0) { // Allocate memory for robots struct board *src_board = mzx_world->current_board; struct robot **robot_list = src_board->robot_list_name_sorted; int num_robots_active = src_board->num_robots_active; int i; for (i = 0; i < num_robots_active; i++) { struct robot *cur_robot = robot_list[i]; if (cur_robot) { if (cur_robot->xpos >= start_x && cur_robot->ypos >= start_y && cur_robot->xpos < start_x + width && cur_robot->ypos < start_y + height) { mzm_size += save_robot_calculate_size(mzx_world, cur_robot, savegame, WORLD_VERSION); num_robots_alloc++; } } } } // Now, we need to add the total overhead of the zip file. // File names are all "r##", so the max name length is 3. mzm_size += zip_bound_total_header_usage(num_robots_alloc, 3); buffer = alloc(mzm_size, storage); bufferPtr = buffer; memcpy(bufferPtr, "MZM3", 4); bufferPtr += 4; mem_putw(width, &bufferPtr); mem_putw(height, &bufferPtr); // Come back here later if there's robot information mem_putd(0, &bufferPtr); mem_putc(0, &bufferPtr); mem_putc(storage_mode, &bufferPtr); mem_putc(0, &bufferPtr); mem_putw(WORLD_VERSION, &bufferPtr); bufferPtr += 3; switch(mode) { // Board, raw case 0: { struct zip_archive *zp; struct board *src_board = mzx_world->current_board; int board_width = src_board->board_width; char *level_id = src_board->level_id; char *level_param = src_board->level_param; char *level_color = src_board->level_color; char *level_under_id = src_board->level_under_id; char *level_under_param = src_board->level_under_param; char *level_under_color = src_board->level_under_color; int x, y; int offset = start_x + (start_y * board_width); int line_skip = board_width - width; int num_robots = 0; int robot_numbers[256]; int robot_table_position; enum thing current_id; int i; for(y = 0; y < height; y++) { for(x = 0; x < width; x++, offset++) { current_id = (enum thing)level_id[offset]; if(is_robot(current_id)) { // Robot robot_numbers[num_robots] = level_param[offset]; num_robots++; mem_putc(current_id, &bufferPtr); mem_putc(0, &bufferPtr); mem_putc(level_color[offset], &bufferPtr); mem_putc(level_under_id[offset], &bufferPtr); mem_putc(level_under_param[offset], &bufferPtr); mem_putc(level_under_color[offset], &bufferPtr); } else if((current_id == SENSOR) || is_signscroll(current_id) || (current_id == PLAYER)) { // Sensor, scroll, sign, or player // Put customblock fake mem_putc((int)CUSTOM_BLOCK, &bufferPtr); mem_putc(get_id_char(src_board, offset), &bufferPtr); mem_putc(get_id_color(src_board, offset), &bufferPtr); mem_putc(level_under_id[offset], &bufferPtr); mem_putc(level_under_param[offset], &bufferPtr); mem_putc(level_under_color[offset], &bufferPtr); } else { mem_putc(current_id, &bufferPtr); mem_putc(level_param[offset], &bufferPtr); mem_putc(level_color[offset], &bufferPtr); mem_putc(level_under_id[offset], &bufferPtr); mem_putc(level_under_param[offset], &bufferPtr); mem_putc(level_under_color[offset], &bufferPtr); } } offset += line_skip; } // Get the zip redy 2 go zp = zip_open_mem_write(buffer, mzm_size); robot_table_position = bufferPtr - (unsigned char *)buffer; // Get the zip in position. Won't alter the bufferPtr zseek(zp, robot_table_position, SEEK_SET); // Go back to header to put robot table information if(num_robots) { struct robot **robot_list = src_board->robot_list; char name[4]; bufferPtr = buffer; bufferPtr += 8; // Where the robots will be stored // (not actually necessary anymore) mem_putd(robot_table_position, &bufferPtr); // Number of robots mem_putc(num_robots, &bufferPtr); // Skip board storage mode bufferPtr += 1; // Savegame mode for robots mem_putc(savegame, &bufferPtr); // Write robots into the zip for(i = 0; i < num_robots; i++) { sprintf(name, "r%2.2X", i); // Save each robot save_robot(mzx_world, robot_list[robot_numbers[i]], zp, savegame, WORLD_VERSION, name, FPROP_ROBOT, 0, i); } } zip_close(zp, NULL); break; } // Overlay/Vlayer case 1: case 2: { struct board *src_board = mzx_world->current_board; int board_width; int x, y; int offset; int line_skip; char *chars; char *colors; if(mode == 1) { // Overlay if(!src_board->overlay_mode) setup_overlay(src_board, 3); chars = src_board->overlay; colors = src_board->overlay_color; board_width = src_board->board_width; } else { // Vlayer chars = mzx_world->vlayer_chars; colors = mzx_world->vlayer_colors; board_width = mzx_world->vlayer_width; } offset = start_x + (start_y * board_width); line_skip = board_width - width; for(y = 0; y < height; y++) { for(x = 0; x < width; x++, offset++) { mem_putc(chars[offset], &bufferPtr); mem_putc(colors[offset], &bufferPtr); } offset += line_skip; } break; } // Board, char based case 3: { struct board *src_board = mzx_world->current_board; int board_width = src_board->board_width; int x, y; int offset = start_x + (start_y * board_width); int line_skip = board_width - width; for(y = 0; y < height; y++) { for(x = 0; x < width; x++, offset++) { mem_putc(get_id_char(src_board, offset), &bufferPtr); mem_putc(get_id_color(src_board, offset), &bufferPtr); } offset += line_skip; } break; } } }
BinaryInput::BinaryInput( const std::string& filename, G3DEndian fileEndian, bool compressed) : m_filename(filename), m_bitPos(0), m_bitString(0), m_beginEndBits(0), m_alreadyRead(0), m_length(0), m_bufferLength(0), m_buffer(NULL), m_pos(0), m_freeBuffer(true) { setEndian(fileEndian); // Update global file tracker _internal::currentFilesUsed.insert(m_filename); #if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ std::string zipfile; if (FileSystem::inZipfile(m_filename, zipfile)) { // Load from zipfile // zipRead(filename, v, s); std::string internalFile = m_filename.substr(zipfile.length() + 1); struct zip* z = zip_open(zipfile.c_str(), ZIP_CHECKCONS, NULL); { struct zip_stat info; zip_stat_init( &info ); // TODO: Docs unclear if zip_stat_init is required. zip_stat(z, internalFile.c_str(), ZIP_FL_NOCASE, &info); m_bufferLength = m_length = info.size; // sets machines up to use MMX, if they want m_buffer = reinterpret_cast<uint8*>(System::alignedMalloc(m_length, 16)); struct zip_file* zf = zip_fopen( z, internalFile.c_str(), ZIP_FL_NOCASE ); { int64 test = zip_fread( zf, m_buffer, m_length ); debugAssertM(test == m_length, internalFile + " was corrupt because it unzipped to the wrong size."); (void)test; } zip_fclose( zf ); } zip_close( z ); if (compressed) { decompress(); } m_freeBuffer = true; return; } #endif // Figure out how big the file is and verify that it exists. m_length = FileSystem::size(m_filename); // Read the file into memory FILE* file = fopen(m_filename.c_str(), "rb"); if (! file || (m_length == -1)) { throw format("File not found: \"%s\"", m_filename.c_str()); return; } if (! compressed && (m_length > INITIAL_BUFFER_LENGTH)) { // Read only a subset of the file so we don't consume // all available memory. m_bufferLength = INITIAL_BUFFER_LENGTH; } else { // Either the length is fine or the file is compressed // and requires us to read the whole thing for zlib. m_bufferLength = m_length; } debugAssert(m_freeBuffer); m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16); if (m_buffer == NULL) { if (compressed) { throw "Not enough memory to load compressed file. (1)"; } // Try to allocate a small array; not much memory is available. // Give up if we can't allocate even 1k. while ((m_buffer == NULL) && (m_bufferLength > 1024)) { m_bufferLength /= 2; m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16); } } debugAssert(m_buffer); fread(m_buffer, m_bufferLength, sizeof(int8), file); fclose(file); file = NULL; if (compressed) { if (m_bufferLength != m_length) { throw "Not enough memory to load compressed file. (2)"; } decompress(); } }
static int closefile(struct zip* fp) { return zip_close(fp); }
KaraokePlayable_ZIP::~KaraokePlayable_ZIP() { if ( m_zip ) zip_close( m_zip ); }
/** * Content handler. * * @param r * Request structure pointer * @return * Response status */ static ngx_int_t ngx_http_unzip_handler(ngx_http_request_t *r) { ngx_buf_t *b; ngx_chain_t out; ngx_str_t unzip_filename; ngx_str_t unzip_extract; struct zip *zip_source; struct zip_stat zip_st; struct zip_file *file_in_zip; int err = 0; char *unzipfile_path; char *unzipextract_path; unsigned char *zip_content; unsigned int zip_read_bytes; ngx_http_unzip_loc_conf_t *unzip_config; unzip_config = ngx_http_get_module_loc_conf(r, ngx_http_unzip_module); /* let's try to get file_in_unzip_archivefile and file_in_unzip_extract from nginx configuration */ if (ngx_http_complex_value(r, unzip_config->file_in_unzip_archivefile, &unzip_filename) != NGX_OK || ngx_http_complex_value(r, unzip_config->file_in_unzip_extract, &unzip_extract) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to read unzip module configuration settings."); return NGX_ERROR; } /* we're supporting just GET and HEAD requests */ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Only GET and HEAD requests are supported by the unzip module."); return NGX_HTTP_NOT_ALLOWED; } /* fill path variables with 0 as ngx_string_t doesn't terminate string with 0 */ unzipfile_path = malloc(unzip_filename.len+1); if (unzipfile_path == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate buffer."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } unzipextract_path = malloc(unzip_extract.len+1); if (unzipextract_path == NULL) { free(unzipfile_path); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate buffer."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } memset(unzipfile_path, 0, unzip_filename.len+1); memset(unzipextract_path, 0, unzip_extract.len+1); /* get path variables terminated with 0 */ strncpy(unzipfile_path, (char *)unzip_filename.data, unzip_filename.len); strncpy(unzipextract_path, (char *)unzip_extract.data, unzip_extract.len); /* try to open archive (zip) file */ if (!(zip_source = zip_open(unzipfile_path, 0, &err))) { free(unzipfile_path); free(unzipextract_path); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s : no such archive file.", unzipfile_path); return NGX_HTTP_NOT_FOUND; } /* initialize structure */ zip_stat_init(&zip_st); /* let's check what's the size of a file. return 404 if we can't stat file inside archive */ if (0 != zip_stat(zip_source, unzipextract_path, 0, &zip_st)) { free(unzipfile_path); free(unzipextract_path); zip_close(zip_source); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no file %s inside %s archive.", unzipextract_path, unzipfile_path); return NGX_HTTP_NOT_FOUND; } /* allocate buffer for the file content */ if (!(zip_content = ngx_palloc(r->pool, zip_st.size))) { free(unzipfile_path); free(unzipextract_path); zip_close(zip_source); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer memory."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* * try to open a file that we want - if not return 500 as we know that the file is there (making zip_stat before) * so let's return 500. */ if (!(file_in_zip = zip_fopen(zip_source, unzipextract_path, 0))) { free(unzipfile_path); free(unzipextract_path); zip_close(zip_source); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to open %s from %s archive (corrupted?).", unzipextract_path, unzipfile_path); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* * let's get file content and check if we got all * we're expecting to get zip_st.size bytes so return 500 if we get something else. */ if (!(zip_read_bytes = zip_fread(file_in_zip, zip_content, zip_st.size)) || zip_read_bytes != zip_st.size) { free(unzipfile_path); free(unzipextract_path); zip_fclose(file_in_zip); zip_close(zip_source); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "couldn't get %d bytes of %s from %s archive (corrupted?).", zip_st.size, unzipextract_path, unzipfile_path); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* close both files */ zip_fclose(file_in_zip); zip_close(zip_source); /* let's clean */ free(unzipfile_path); free(unzipextract_path); /* set the content-type header. */ if (ngx_http_set_content_type(r) != NGX_OK) { r->headers_out.content_type.len = sizeof("text/plain") - 1; r->headers_out.content_type.data = (u_char *) "text/plain"; } /* allocate a new buffer for sending out the reply. */ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer."); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* insertion in the buffer chain. */ out.buf = b; out.next = NULL; /* just one buffer */ b->pos = zip_content; b->last = zip_content + zip_read_bytes; b->memory = 1; b->last_buf = 1; /* sending the headers for the reply. */ r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = zip_read_bytes; ngx_http_send_header(r); return ngx_http_output_filter(r, &out); } /* ngx_http_unzip_handler */
ZipFileInput::~ZipFileInput() { if(m_archiveHandle) zip_close(m_archiveHandle); }
int subsurface_zip_close(struct zip *zip) { return zip_close(zip); }
ZipFile::~ZipFile() { zip_close(archive_); }
/** * Initialize a saved session file. * * @param filename The name of the filename to save the current session as. * Must not be NULL. * @param samplerate The samplerate to store for this session. * @param channels A NULL-terminated array of strings containing the names * of all the channels active in this session. * * @retval SR_OK Success * @retval SR_ERR_ARG Invalid arguments * @retval SR_ERR Other errors * * @since 0.3.0 */ SR_API int sr_session_save_init(const char *filename, uint64_t samplerate, char **channels) { FILE *meta; struct zip *zipfile; struct zip_source *versrc, *metasrc; int tmpfile, cnt, ret, i; char version[1], metafile[32], *s; if (!filename) { sr_err("%s: filename was NULL", __func__); return SR_ERR_ARG; } /* Quietly delete it first, libzip wants replace ops otherwise. */ unlink(filename); if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret))) return SR_ERR; /* "version" */ version[0] = '2'; if (!(versrc = zip_source_buffer(zipfile, version, 1, 0))) return SR_ERR; if (zip_add(zipfile, "version", versrc) == -1) { sr_info("error saving version into zipfile: %s", zip_strerror(zipfile)); return SR_ERR; } /* init "metadata" */ strcpy(metafile, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[global]\n"); fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION); /* metadata */ fprintf(meta, "[device 1]\n"); /* metadata */ fprintf(meta, "capturefile = logic-1\n"); cnt = 0; for (i = 0; channels[i]; i++) cnt++; fprintf(meta, "total probes = %d\n", cnt); s = sr_samplerate_string(samplerate); fprintf(meta, "samplerate = %s\n", s); g_free(s); for (i = 0; channels[i]; i++) fprintf(meta, "probe%d = %s\n", i + 1, channels[i]); fclose(meta); if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) { unlink(metafile); return SR_ERR; } if (zip_add(zipfile, "metadata", metasrc) == -1) { unlink(metafile); return SR_ERR; } if ((ret = zip_close(zipfile)) == -1) { sr_info("error saving zipfile: %s", zip_strerror(zipfile)); unlink(metafile); return SR_ERR; } unlink(metafile); return SR_OK; }
static void zip_Close(struct PCK_Catalog *cat) { zip_close((struct zip*)cat->context); SDL_free(cat); }
void dlgPackageExporter::slot_export_package(){ //#ifndef Q_OS_WIN // filePath = ui->filePath->text(); //#endif QFile file_xml( filePath ); if( file_xml.open( QIODevice::WriteOnly ) ) { XMLexport writer( mpHost ); //write trigs QList<QTreeWidgetItem *> items = treeWidget->findItems(QString("Triggers"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); QList<QTreeWidgetItem *> trigList; recurseTree(top,trigList); for (int i=0;i<trigList.size();i++){ QTreeWidgetItem * item = trigList.at(i); if (item->checkState(0) == Qt::Unchecked && triggerMap.contains(item)){ triggerMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && triggerMap.contains(item) && triggerMap[item]->mModuleMasterFolder){ triggerMap[item]->mModuleMasterFolder=false; modTriggerMap.insert(item, triggerMap[item]); } } items = treeWidget->findItems(QString("Timers"), Qt::MatchExactly, 0); top = items.first(); QList<QTreeWidgetItem *> timerList; recurseTree(top,timerList); for (int i=0;i<timerList.size();i++){ QTreeWidgetItem * item = timerList.at(i); if (item->checkState(0) == Qt::Unchecked && timerMap.contains(item)){ timerMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && timerMap.contains(item) && timerMap[item]->mModuleMasterFolder){ timerMap[item]->mModuleMasterFolder=false; modTimerMap.insert(item, timerMap[item]); } } items = treeWidget->findItems(QString("Aliases"), Qt::MatchExactly, 0); top = items.first(); QList<QTreeWidgetItem *> aliasList; recurseTree(top,aliasList); for (int i=0;i<aliasList.size();i++){ QTreeWidgetItem * item = aliasList.at(i); if (item->checkState(0) == Qt::Unchecked && aliasMap.contains(item)){ aliasMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && aliasMap.contains(item) && aliasMap[item]->mModuleMasterFolder){ aliasMap[item]->mModuleMasterFolder=false; modAliasMap.insert(item, aliasMap[item]); } } items = treeWidget->findItems(QString("Buttons"), Qt::MatchExactly, 0); top = items.first(); QList<QTreeWidgetItem *> actionList; recurseTree(top,actionList); for (int i=0;i<actionList.size();i++){ QTreeWidgetItem * item = actionList.at(i); if (item->checkState(0) == Qt::Unchecked && actionMap.contains(item)){ actionMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && actionMap.contains(item) && actionMap[item]->mModuleMasterFolder){ actionMap[item]->mModuleMasterFolder=false; modActionMap.insert(item, actionMap[item]); } } items = treeWidget->findItems(QString("Scripts"), Qt::MatchExactly, 0); top = items.first(); QList<QTreeWidgetItem *> scriptList; recurseTree(top,scriptList); for (int i=0;i<scriptList.size();i++){ QTreeWidgetItem * item = scriptList.at(i); if (item->checkState(0) == Qt::Unchecked && scriptMap.contains(item)){ scriptMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && scriptMap.contains(item) && scriptMap[item]->mModuleMasterFolder){ scriptMap[item]->mModuleMasterFolder=false; modScriptMap.insert(item, scriptMap[item]); } } items = treeWidget->findItems(QString("Keys"), Qt::MatchExactly, 0); top = items.first(); QList<QTreeWidgetItem *> keyList; recurseTree(top,keyList); for (int i=0;i<keyList.size();i++){ QTreeWidgetItem * item = keyList.at(i); if (item->checkState(0) == Qt::Unchecked && keyMap.contains(item)){ keyMap[item]->exportItem = false; } else if (item->checkState(0) == Qt::Checked && keyMap.contains(item) && keyMap[item]->mModuleMasterFolder){ keyMap[item]->mModuleMasterFolder=false; modKeyMap.insert(item, keyMap[item]); } } writer.exportGenericPackage(&file_xml); file_xml.close(); //now fix all the stuff we weren't exporting //trigger, timer, alias,action,script, keys for (int i=0;i<trigList.size();i++){ QTreeWidgetItem * item = trigList.at(i); if (triggerMap.contains(item)){ triggerMap[item]->exportItem = true; } if (modTriggerMap.contains(item)){ modTriggerMap[item]->mModuleMasterFolder = true; } } for (int i=0;i<timerList.size();i++){ QTreeWidgetItem * item = timerList.at(i); if (timerMap.contains(item)){ timerMap[item]->exportItem = true; } if (modTimerMap.contains(item)){ modTimerMap[item]->mModuleMasterFolder = true; } } for (int i=0;i<actionList.size();i++){ QTreeWidgetItem * item = actionList.at(i); if (actionMap.contains(item)){ actionMap[item]->exportItem = true; } if (modActionMap.contains(item)){ modActionMap[item]->mModuleMasterFolder = true; } } for (int i=0;i<scriptList.size();i++){ QTreeWidgetItem * item = scriptList.at(i); if (scriptMap.contains(item)){ scriptMap[item]->exportItem = true; } if (modScriptMap.contains(item)){ modScriptMap[item]->mModuleMasterFolder = true; } } for (int i=0;i<keyList.size();i++){ QTreeWidgetItem * item = keyList.at(i); if (keyMap.contains(item)){ keyMap[item]->exportItem = true; } if (modKeyMap.contains(item)){ modKeyMap[item]->mModuleMasterFolder = true; } } for (int i=0;i<aliasList.size();i++){ QTreeWidgetItem * item = aliasList.at(i); if (aliasMap.contains(item)){ aliasMap[item]->exportItem = true; } if (modAliasMap.contains(item)){ modAliasMap[item]->mModuleMasterFolder = true; } } //#ifdef Q_OS_WIN int err = 0; char buf[100]; zip* archive = zip_open( zipFile.toStdString().c_str(), ZIP_CREATE|ZIP_TRUNCATE, &err); qDebug()<<"dp saving to"<<zipFile; if ( err != 0 ) { zip_error_to_str(buf, sizeof(buf), err, errno); qDebug()<<"dp zip open error"<<zipFile<<buf; close(); return; } err = zip_dir_add( archive, tempDir.toStdString().c_str(), ZIP_FL_ENC_GUESS ); if ( err != 0 ) { zip_error_to_str(buf, sizeof(buf), err, errno); qDebug()<<"dp zip add dir error"<<buf; close(); return; } QDir dir(tempDir); QStringList contents = dir.entryList(); for(int i=0;i<contents.size();i++) { QString fname = contents[i]; if ( fname == "." || fname == ".." ) continue; QString fullName = tempDir+"/"+contents[i]; struct zip_source *s = zip_source_file( archive, fullName.toStdString().c_str(), 0, 0); if ( s == NULL ) { int sep = 0; zip_error_get( archive, &err, &sep); zip_error_to_str(buf, sizeof(buf), err, errno); qDebug()<<"zip source error"<<fullName<<fname<<buf; } err = zip_file_add( archive, fname.toStdString().c_str(), s, ZIP_FL_OVERWRITE ); if ( err == -1 ) { int sep = 0; zip_error_get( archive, &err, &sep); zip_error_to_str(buf, sizeof(buf), err, errno); qDebug()<<"added file error"<<fullName<<fname<<buf; } } err = zip_close( archive ); if ( err != 0 ){ zip_error_to_str(buf, sizeof(buf), err, errno); qDebug()<<"dp close file error"<<buf; close(); return; } //JlCompress::compressDir(zip, tempDir ); // #else // ui->infoLabel->setText("Exported package to "+filePath); // #endif } else { ui->infoLabel->setText("Failed to export - couldn't open "+filePath+" for writing in. Do you have the necessary permissions to write to that folder?"); } close(); }
bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { if (installInProgress_) { ERROR_LOG(HLE, "Cannot have two installs in progress at the same time"); return false; } installInProgress_ = true; std::string pspGame = GetSysDirectory(DIRECTORY_GAME); INFO_LOG(HLE, "Installing %s into %s", zipfile.c_str(), pspGame.c_str()); if (!File::Exists(zipfile)) { ERROR_LOG(HLE, "ZIP file %s doesn't exist", zipfile.c_str()); return false; } int error; #if defined(_WIN32) && !defined(__MINGW32__) struct zip *z = zip_open(ConvertUTF8ToWString(zipfile).c_str(), 0, &error); #elif defined(__SYMBIAN32__) // If zipfile is non-ascii, this may not function correctly. Other options? struct zip *z = zip_open(std::wstring(zipfile.begin(), zipfile.end()).c_str(), 0, &error); #else struct zip *z = zip_open(zipfile.c_str(), 0, &error); #endif if (!z) { ERROR_LOG(HLE, "Failed to open ZIP file %s, error code=%i", zipfile.c_str(), error); return false; } int numFiles = zip_get_num_files(z); // First, find all the directories, and precreate them before we fill in with files. // Also, verify that this is a PSP zip file with the correct layout. bool isPSP = false; int stripChars = 0; for (int i = 0; i < numFiles; i++) { const char *fn = zip_get_name(z, i, 0); std::string zippedName = fn; if (zippedName.find("EBOOT.PBP") != std::string::npos) { int slashCount = 0; int lastSlashLocation = -1; int slashLocation = -1; for (size_t i = 0; i < zippedName.size(); i++) { if (zippedName[i] == '/') { slashCount++; slashLocation = lastSlashLocation; lastSlashLocation = (int)i; } } if (slashCount >= 1 && (!isPSP || slashLocation < stripChars + 1)) { stripChars = slashLocation + 1; isPSP = true; } else { INFO_LOG(HLE, "Wrong number of slashes (%i) in %s", slashCount, zippedName.c_str()); } } } if (!isPSP) { ERROR_LOG(HLE, "File not a PSP game, no EBOOT.PBP found."); installProgress_ = 0.0f; installInProgress_ = false; installError_ = "Not a PSP game"; InstallDone(); return false; } size_t allBytes = 0, bytesCopied = 0; // Create all the directories in one pass std::set<std::string> createdDirs; for (int i = 0; i < numFiles; i++) { const char *fn = zip_get_name(z, i, 0); std::string zippedName = fn; std::string outFilename = pspGame + zippedName.substr(stripChars); bool isDir = *outFilename.rbegin() == '/'; if (!isDir && outFilename.find("/") != std::string::npos) { outFilename = outFilename.substr(0, outFilename.rfind('/')); } if (createdDirs.find(outFilename) == createdDirs.end()) { File::CreateFullPath(outFilename.c_str()); createdDirs.insert(outFilename); } if (!isDir && strchr(fn, '/') != 0) { struct zip_stat zstat; if (zip_stat_index(z, i, 0, &zstat) >= 0) { allBytes += zstat.size; } } } // Now, loop through again in a second pass, writing files. std::vector<std::string> createdFiles; for (int i = 0; i < numFiles; i++) { const char *fn = zip_get_name(z, i, 0); // Note that we do NOT write files that are not in a directory, to avoid random // README files etc. if (strchr(fn, '/') != 0) { struct zip_stat zstat; zip_stat_index(z, i, 0, &zstat); size_t size = zstat.size; fn += stripChars; std::string outFilename = pspGame + fn; bool isDir = *outFilename.rbegin() == '/'; if (isDir) continue; if (i < 10) { INFO_LOG(HLE, "Writing %i bytes to %s", (int)size, outFilename.c_str()); } zip_file *zf = zip_fopen_index(z, i, 0); FILE *f = fopen(outFilename.c_str(), "wb"); if (f) { size_t pos = 0; const size_t blockSize = 1024 * 128; u8 *buffer = new u8[blockSize]; while (pos < size) { size_t bs = std::min(blockSize, pos - size); zip_fread(zf, buffer, bs); size_t written = fwrite(buffer, 1, bs, f); if (written != bs) { ERROR_LOG(HLE, "Wrote %i bytes out of %i - Disk full?", (int)written, (int)bs); delete [] buffer; buffer = 0; fclose(f); zip_fclose(zf); deleteFile(outFilename.c_str()); // Yes it's a goto. Sue me. I think it's appropriate here. goto bail; } pos += bs; bytesCopied += bs; installProgress_ = (float)bytesCopied / (float)allBytes; // printf("Progress: %f\n", installProgress_); } zip_fclose(zf); fclose(f); createdFiles.push_back(outFilename); delete [] buffer; } else { ERROR_LOG(HLE, "Failed to open file for writing"); } } } INFO_LOG(HLE, "Extracted %i files (%i bytes / %i).", numFiles, (int)bytesCopied, (int)allBytes); zip_close(z); z = 0; installProgress_ = 1.0f; installInProgress_ = false; installError_ = ""; if (deleteAfter) { deleteFile(zipfile.c_str()); } InstallDone(); return true; bail: zip_close(z); // We end up here if disk is full or couldn't write to storage for some other reason. installProgress_ = 0.0f; installInProgress_ = false; installError_ = "Storage full"; if (deleteAfter) { deleteFile(zipfile.c_str()); } for (size_t i = 0; i < createdFiles.size(); i++) { deleteFile(createdFiles[i].c_str()); } for (auto iter = createdDirs.begin(); iter != createdDirs.end(); ++iter) { deleteDir(iter->c_str()); } InstallDone(); return false; }
bool GetCompressedFiles(std::string ZipName, std::vector<std::string>* pFileNames, std::vector<std::vector<char> >* data, std::string* pError) { #ifdef WIN32 HZIP hz = OpenZip(ZipName.c_str(),0); if (!hz){if(pError) *pError += ("Unable to open ZIP archive. Aborting.\n"); return false;} ZIPENTRY ze; if (GetZipItem(hz, -1, &ze) != ZR_OK) {if(pError) *pError += ("Unable to return information about ZIP archive. Aborting.\n"); return false;} int NumFiles = ze.index; //set up returns for data... data->resize(NumFiles); for (int i=0; i<NumFiles; i++){ if (GetZipItem(hz,i,&ze) != ZR_OK) {if(pError) *pError += "Error loading ZIP file information. Aborting.\n"; return false;} int NumDesiredFiles = pFileNames->size(); for (int j=0; j<NumDesiredFiles; j++){ if ((*pFileNames)[j].compare(ze.name)==0){ //if this is one of the file's we're looking for int size = ze.unc_size; (*data)[j].resize(size+1); //or clear... if (UnzipItem(hz, i, &((*data)[j].front()), size) != ZR_OK) {if(pError) *pError += "Could not unzip sub-file. Aborting.\n"; return false;} (*data)[j][size] = '\0'; } } } if (CloseZip(hz) != ZR_OK) {if(pError) *pError += "Error closing ZIP file.\n"; return false;} return true; #else //Mac/Linux Zip read code int err; struct zip * hz = zip_open(ZipName.c_str(), ZIP_CHECKCONS, &err); if (!hz){if(pError) *pError += ("Unable to open ZIP archive. Aborting.\n"); return false;} int NumFiles = zip_get_num_entries(hz,0); if (NumFiles < 0) { if(pError) *pError += ("Unable to return information about ZIP archive. Aborting.\n"); return false;} //set up returns for data... data->resize(NumFiles); for (uint i=0; i<NumFiles; i++){ struct zip_file * zfile = zip_fopen_index(hz, i, 0); int NumDesiredFiles = pFileNames->size(); const char * entryname = zip_get_name(hz, i, 0); struct zip_stat stat; err = zip_stat_index(hz, i, 0, &stat); for (int j=0; j<NumDesiredFiles; j++){ if ((*pFileNames)[j].compare(entryname)==0){ //if this is one of the file's we're looking for int size = stat.size; (*data)[j].resize(size+1); //or clear... if (zip_fread(zfile, &((*data)[j].front()), size) != size) {if(pError) *pError += "Could not unzip sub-file. Aborting.\n"; return false;} (*data)[j][size] = '\0'; } } zip_fclose(zfile); } if (zip_close(hz) != 0) {if(pError) *pError += "Error closing ZIP file.\n"; return false;} return true; #endif }
static int zip_gc (lua_State *L) { ZZIP_DIR**f = topfile(L, 1); if (*f != NULL) /* ignore closed files */ zip_close(L); return 0; }
~ZipArchive() override { zip_close(_zip); }
bool extractMap(const std::string& file) { int err = 0; zip* zipFile = zip_open(file.c_str(), 0, &err); if(!zipFile) { std::cout << "[ERROR]: Failed to open archive file: " << file << ".\n"; return false; } auto fileNumber = zip_get_num_entries(zipFile, 0); std::string folderName = file.substr(0, file.find_last_of('.')) + "/"; // cut off file extension, add dir char stripWebChars(folderName); if(!makeFolder(folderName)) return false; for(auto i = 0u; i < fileNumber; i++) { zip_file* zipped = zip_fopen_index(zipFile, i, 0); struct zip_stat fileInfo; zip_stat_init(&fileInfo); zip_stat_index(zipFile, i, 0, &fileInfo); if(fileInfo.valid & ZIP_STAT_NAME && fileInfo.valid & ZIP_STAT_SIZE && fileInfo.valid & ZIP_STAT_COMP_SIZE) { std::string fileStr = fileInfo.name; if(fileStr.find('.') == std::string::npos) // if we don't have a dot, this is a folder { continue; // skip this folder } if(fileStr.find('/') != std::string::npos) // if we have any dir chars in the string, strip out dirs { fileStr = fileStr.substr(fileStr.find_last_of('/') + 1); } #ifndef __linux__ #pragma warning(push) #pragma warning(disable: 4244) #endif std::vector<bbyte> bytes(fileInfo.size); // just gotta deal with this conversion #ifndef __linux__ #pragma warning(pop) #endif zip_fread(zipped, bytes.data(), fileInfo.size); std::ofstream fout; fout.open(folderName + fileStr, std::ofstream::binary); if(fout.bad()) { std::cout << "[ERROR]: Unable to extract file: " << fileInfo.name << '\n'; return false; } fout.write(bytes.data(), bytes.size()); fout.close(); } else { std::cout << "[ERROR]: Bad file data for file in archive: " << file << '\n'; return false; } zip_fclose(zipped); } zip_close(zipFile); // delete the zip file, it's no longer needed #ifdef __linux__ // TBD #else DeleteFile(file.c_str()); #endif return true; }
void main_window::on_save_mission() { if (m_filename.empty()) { on_save_as_mission(); return; } zip_t *zip = zip_open(m_filename.c_str(), ZIP_DEFAULT_COMPRESSION_LEVEL, 0); if (!zip) { alert("Unable to save mission " + m_filename); return; } std::string str = "<!--Open Horizon mission-->\n"; str += "<mission location=\"" + m_location + "\">\n"; auto &p = m_scene_view->get_player(); str += "\t<player "; str += "x=\"" + std::to_string(p.pos.x) + "\" "; str += "y=\"" + std::to_string(p.pos.y + p.y) + "\" "; str += "z=\"" + std::to_string(p.pos.z) + "\" "; str += "yaw=\"" + std::to_string(p.yaw.get_deg()) + "\" "; str += "editor_y=\"" + std::to_string(p.y) + "\" "; str += ">\n"; str += "\t\t<attribute "; for (auto &a: p.attributes) { if (!a.second.empty()) str += a.first + "=\"" + a.second + "\" "; } str += "/>\n"; str += "\t</player>\n"; for (auto &o: m_scene_view->get_objects()) { str += "\n\t<object "; str += "name=\"" + o.name + "\" "; str += "id=\"" + o.id + "\" "; str += "active=\"" + to_string(o.active) + "\" "; str += "x=\"" + std::to_string(o.pos.x) + "\" "; str += "y=\"" + std::to_string(o.pos.y + o.y) + "\" "; str += "z=\"" + std::to_string(o.pos.z) + "\" "; str += "yaw=\"" + std::to_string(o.yaw.get_deg()) + "\" "; str += "editor_y=\"" + std::to_string(o.y) + "\" "; str += ">\n"; str += "\t\t<attribute "; for (auto &a: o.attributes) { if (!a.second.empty()) str += a.first + "=\"" + a.second + "\" "; } str += "/>\n"; str += "\t</object>\n"; } for (auto &z: m_scene_view->get_zones()) { str += "\n\t<zone "; str += "name=\"" + z.name + "\" "; str += "active=\"" + to_string(z.active) + "\" "; str += "x=\"" + std::to_string(z.pos.x) + "\" "; str += "y=\"" + std::to_string(z.pos.y) + "\" "; str += "z=\"" + std::to_string(z.pos.z) + "\" "; str += "radius=\"" + std::to_string(z.radius) + "\" "; str += ">\n"; str += "\t\t<attribute "; for (auto &a: z.attributes) { if (!a.second.empty()) str += a.first + "=\"" + a.second + "\" "; } str += "/>\n"; str += "\t</zone>\n"; } for (auto &pth: m_scene_view->get_paths()) { str += "\n\t<path "; str += "name=\"" + pth.name + "\" "; str += ">\n"; for (auto &p: pth.points) { str += "\t\t<point "; str += "x=\"" + std::to_string(p.x) + "\" "; str += "y=\"" + std::to_string(p.y + p.w) + "\" "; str += "z=\"" + std::to_string(p.z) + "\" "; str += "editor_y=\"" + std::to_string(p.w) + "\" "; str += "/>\n"; } str += "\t</path>\n"; } str += "</mission>\n"; zip_entry_open(zip, "objects.xml"); zip_entry_write(zip, str.c_str(), str.length()); zip_entry_close(zip); std::string script = to_str(m_script_edit->toPlainText()); zip_entry_open(zip, "script.lua"); zip_entry_write(zip, script.c_str(), script.size()); zip_entry_close(zip); std::string info = "<!--Open Horizon mission info-->\n"; info += "<info "; info += "name=\"" + std::string(to_str(m_mission_title->text())) + "\">\n"; info += "\t<author name=\"" + std::string(to_str(m_mission_author->text())) + "\" "; info += "email=\"" + std::string(to_str(m_mission_email->text())) + "\"/>\n"; info += "\t<description>"; info += to_str(m_mission_description->toPlainText()); info += "</description>\n"; info += "</info>\n"; zip_entry_open(zip, "info.xml"); zip_entry_write(zip, info.c_str(), info.size()); zip_entry_close(zip); zip_close(zip); }
int main(int argc, char *argv[]) { const char *archive; struct zip *za, *z_in; struct zip_source *zs; char buf[100]; int c, arg, err, flags, idx; flags = 0; prg = argv[0]; if (argc < 2) { fprintf(stderr, usage, prg); return 1; } while ((c=getopt(argc, argv, "cent")) != -1) { switch (c) { case 'c': flags |= ZIP_CHECKCONS; break; case 'e': flags |= ZIP_EXCL; break; case 'n': flags |= ZIP_CREATE; break; case 't': flags |= ZIP_TRUNCATE; break; default: fprintf(stderr, usage, argv[0]); return 1; } } arg = optind; archive = argv[arg++]; if (flags == 0) flags = ZIP_CREATE; if ((za=zip_open(archive, flags, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "can't open zip archive `%s': %s\n", archive, buf); return 1; } err = 0; while (arg < argc) { if (strcmp(argv[arg], "add") == 0 && arg+2 < argc) { /* add */ if ((zs=zip_source_buffer(za, argv[arg+2], strlen(argv[arg+2]), 0)) == NULL) { fprintf(stderr, "can't create zip_source from buffer: %s\n", zip_strerror(za)); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { zip_source_free(zs); fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "add_dir") == 0 && arg+1 < argc) { /* add directory */ if (zip_add_dir(za, argv[arg+1]) < 0) { fprintf(stderr, "can't add directory `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 2; } else if (strcmp(argv[arg], "add_file") == 0 && arg+4 < argc) { /* add */ if ((zs=zip_source_file(za, argv[arg+2], atoi(argv[arg+3]), atoi(argv[arg+4]))) == NULL) { fprintf(stderr, "can't create zip_source from file: %s\n", zip_strerror(za)); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { zip_source_free(zs); fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 5; } else if (strcmp(argv[arg], "add_from_zip") == 0 && arg+5 < argc) { /* add from another zip file */ idx = atoi(argv[arg+3]); if ((z_in=zip_open(argv[arg+2], ZIP_CHECKCONS, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "can't open source zip archive `%s': %s\n", argv[arg+2], buf); err = 1; break; } if ((zs=zip_source_zip(za, z_in, idx, 0, atoi(argv[arg+4]), atoi(argv[arg+5]))) == NULL) { fprintf(stderr, "error creating file source from `%s' index '%d': %s\n", argv[arg+2], idx, zip_strerror(za)); zip_close(z_in); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); zip_source_free(zs); zip_close(z_in); err = 1; break; } arg += 6; } else if (strcmp(argv[arg], "count_extra") == 0 && arg+2 < argc) { zip_int16_t count; zip_flags_t ceflags = 0; idx = atoi(argv[arg+1]); ceflags = get_flags(argv[arg+2]); if ((count=zip_file_extra_fields_count(za, idx, ceflags)) < 0) { fprintf(stderr, "can't get extra field count for file at index `%d': %s\n", idx, zip_strerror(za)); err = 1; break; } else { printf("Extra field count: %d\n", count); } arg += 3; } else if (strcmp(argv[arg], "count_extra_by_id") == 0 && arg+3 < argc) { zip_int16_t count, eid; zip_flags_t ceflags = 0; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); ceflags = get_flags(argv[arg+3]); if ((count=zip_file_extra_fields_count_by_id(za, idx, eid, ceflags)) < 0) { fprintf(stderr, "can't get extra field count for file at index `%d' and for id `%d': %s\n", idx, eid, zip_strerror(za)); err = 1; break; } else { printf("Extra field count: %d\n", count); } arg += 4; } else if (strcmp(argv[arg], "delete") == 0 && arg+1 < argc) { /* delete */ idx = atoi(argv[arg+1]); if (zip_delete(za, idx) < 0) { fprintf(stderr, "can't delete file at index `%d': %s\n", idx, zip_strerror(za)); err = 1; break; } arg += 2; } else if (strcmp(argv[arg], "delete_extra") == 0 && arg+1 < argc) { zip_flags_t geflags; zip_uint16_t eid; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); geflags = get_flags(argv[arg+3]); if ((zip_file_extra_field_delete(za, idx, eid, geflags)) < 0) { fprintf(stderr, "can't delete extra field data for file at index `%d', extra field id `%d': %s\n", idx, eid, zip_strerror(za)); err = 1; break; } arg += 4; } else if (strcmp(argv[arg], "delete_extra_by_id") == 0 && arg+1 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); if ((zip_file_extra_field_delete_by_id(za, idx, eid, eidx, geflags)) < 0) { fprintf(stderr, "can't delete extra field data for file at index `%d', extra field id `%d', extra field idx `%d': %s\n", idx, eid, eidx, zip_strerror(za)); err = 1; break; } arg += 5; } else if (strcmp(argv[arg], "get_archive_comment") == 0) { const char *comment; int len; /* get archive comment */ if ((comment=zip_get_archive_comment(za, &len, 0)) == NULL) printf("No archive comment\n"); else printf("Archive comment: %.*s\n", len, comment); arg += 1; } else if (strcmp(argv[arg], "get_extra") == 0 && arg+3 < argc) { zip_flags_t geflags; zip_uint16_t id, eidx, eflen; const zip_uint8_t *efdata; /* get extra field data */ idx = atoi(argv[arg+1]); eidx = atoi(argv[arg+2]); geflags = get_flags(argv[arg+3]); if ((efdata=zip_file_extra_field_get(za, idx, eidx, &id, &eflen, geflags)) == NULL) { fprintf(stderr, "can't get extra field data for file at index %d, extra field %d, flags %u: %s\n", idx, eidx, geflags, zip_strerror(za)); err = 1; } else { printf("Extra field 0x%04x: len %d", id, eflen); if (eflen > 0) { printf(", data "); hexdump(efdata, eflen); } printf("\n"); } arg += 4; } else if (strcmp(argv[arg], "get_extra_by_id") == 0 && arg+4 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx, eflen; const zip_uint8_t *efdata; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); if ((efdata=zip_file_extra_field_get_by_id(za, idx, eid, eidx, &eflen, geflags)) == NULL) { fprintf(stderr, "can't get extra field data for file at index %d, extra field id %d, ef index %d, flags %u: %s\n", idx, eid, eidx, geflags, zip_strerror(za)); err = 1; } else { printf("Extra field 0x%04x: len %d", eid, eflen); if (eflen > 0) { printf(", data "); hexdump(efdata, eflen); } printf("\n"); } arg += 5; } else if (strcmp(argv[arg], "get_file_comment") == 0 && arg+1 < argc) { const char *comment; int len; /* get file comment */ idx = atoi(argv[arg+1]); if ((comment=zip_get_file_comment(za, idx, &len, 0)) == NULL) { fprintf(stderr, "can't get comment for `%s': %s\n", zip_get_name(za, idx, 0), zip_strerror(za)); err = 1; break; } else if (len == 0) printf("No comment for `%s'\n", zip_get_name(za, idx, 0)); else printf("File comment for `%s': %.*s\n", zip_get_name(za, idx, 0), len, comment); arg += 2; } else if (strcmp(argv[arg], "rename") == 0 && arg+2 < argc) { /* rename */ idx = atoi(argv[arg+1]); if (zip_rename(za, idx, argv[arg+2]) < 0) { fprintf(stderr, "can't rename file at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "set_extra") == 0 && arg+5 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx; const zip_uint8_t *efdata; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); efdata = (zip_uint8_t *)argv[arg+5]; if ((zip_file_extra_field_set(za, idx, eid, eidx, efdata, (zip_uint16_t)strlen((const char *)efdata), geflags)) < 0) { fprintf(stderr, "can't set extra field data for file at index `%d', extra field id `%d', index `%d': %s\n", idx, eid, eidx, zip_strerror(za)); err = 1; break; } arg += 6; } else if (strcmp(argv[arg], "set_file_comment") == 0 && arg+2 < argc) { /* set file comment */ idx = atoi(argv[arg+1]); if (zip_file_set_comment(za, idx, argv[arg+2], (zip_uint16_t)strlen(argv[arg+2]), 0) < 0) { fprintf(stderr, "can't set file comment at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "set_file_compression") == 0 && arg+3 < argc) { /* set file compression */ zip_int32_t method; zip_uint32_t flags; idx = atoi(argv[arg+1]); method = get_compression_method(argv[arg+2]); flags = atoi(argv[arg+3]); if (zip_set_file_compression(za, idx, method, flags) < 0) { fprintf(stderr, "can't set file compression method at index `%d' to `%s', flags `%d': %s\n", idx, argv[arg+2], flags, zip_strerror(za)); err = 1; break; } arg += 4; } else { fprintf(stderr, "unrecognized command `%s', or not enough arguments\n", argv[arg]); err = 1; break; } } if (zip_close(za) == -1) { fprintf(stderr, "can't close zip archive `%s': %s\n", archive, zip_strerror(za)); return 1; } return err; }
CEXPORT void resource_loader_deinitialize() { image_cache_destroy(); zip_close(APKArchive); }
// fname must have form of zip://full_filepath.zip:full_filepath_in_zip DB_FILE* vfs_zip_open (const char *fname) { trace ("vfs_zip: open %s\n", fname); if (strncasecmp (fname, "zip://", 6)) { return NULL; } fname += 6; struct zip *z = NULL; struct zip_stat st; const char *colon = fname; for (;;) { colon = strchr (colon, ':'); if (!colon) { break; } char zipname[colon-fname+1]; memcpy (zipname, fname, colon-fname); zipname[colon-fname] = 0; colon = colon+1; z = zip_open (zipname, 0, NULL); if (!z) { continue; } memset (&st, 0, sizeof (st)); int res = zip_stat(z, colon, 0, &st); if (res != 0) { zip_close (z); return NULL; } break; } if (!z) { return NULL; } fname = colon; struct zip_file *zf = zip_fopen_index (z, st.index, 0); if (!zf) { zip_close (z); return NULL; } ddb_zip_file_t *f = malloc (sizeof (ddb_zip_file_t)); memset (f, 0, sizeof (ddb_zip_file_t)); f->file.vfs = &plugin; f->z = z; f->zf = zf; f->index = st.index; f->size = st.size; trace ("vfs_zip: end open %s\n", fname); return (DB_FILE*)f; }