/** * @fn void z_delete(z_t zip) * @brief Delete the ZIP context. * @param zip The pointer to release. */ void z_delete(z_t zip) { struct z_s* z = Z_CAST(zip); if(!Z_VALID(z)) return; z_close(z); z->magic = 0; free(z); }
void op_quit(void) { if(automap_unexplore()) return; z_close(); /* puts("@quit\n"); */ glk_exit(); }
/** * @fn int z_open(z_t zip, const z_file_t filename) * @brief Open a new ZIP file. * @param zip The ZIP context. * @param filename ZIP file name. * @return 0 on success else -1. */ int z_open(z_t zip, const z_file_t filename) { struct z_s* z = Z_CAST(zip); if(!Z_VALID(z)) return -1; strcpy(z->filename, filename); /* Open the zip file */ z->ctx = unzOpen64(z->filename); if(!z->ctx) { logger(LOG_ERR, "Unable to open the zip file '%s'\n", z->filename); z_close(z); return -1; } /* Get info about the zip file */ if(unzGetGlobalInfo64(z->ctx, &z->ginfo) != UNZ_OK) { logger(LOG_ERR, "Unable to read the global info related to the '%s' zip file\n", z->filename); z_close(z); return -1; } return 0; }
/** * @fn int z_uncompress(z_t zip, const char* password, z_uncompress_callback_fct callback) * @brief Unzip the ZIP files. * @param zip ZIP context. * @param password The zip password else NULL or empty. * @param callback Callback to received the uncompressed file datas. * @return -1 on failure else 0. */ int z_uncompress(z_t zip, const char* password, z_uncompress_callback_fct callback) { uLong i; struct zentry_s entry; int ret = 0; struct z_s* z = Z_CAST(zip); if(!Z_VALID_OPEN(z)) { logger(LOG_ERR, "Invalid zip pointer!\n"); return -1; } if(!callback) { logger(LOG_ERR, "Invalid file content callback!\n"); return -1; } /* Loop to list all files */ for(i = 0; i < z->ginfo.number_entry; i++) { memset(&entry, 0, sizeof(struct zentry_s)); /* Get info about current file. */ if(unzGetCurrentFileInfo64(z->ctx, &entry.info, entry.name, FILENAME_MAX, NULL, 0, NULL, 0) != UNZ_OK) { logger(LOG_ERR, "Could not read file info from the zip file '%s'\n", z->filename); ret = -1; break; } entry.isdir = z_is_dir(z, entry.name); if(entry.isdir) callback(z, entry); else { // Entry is a file, so extract it. if(!password || !strlen(password)) { if(unzOpenCurrentFile(z->ctx) != UNZ_OK) { logger(LOG_ERR, "Could not open file '%s' into the zip file '%s'\n", entry.name, z->filename); ret = -1; break; } } else { if(unzOpenCurrentFilePassword(z->ctx, password) != UNZ_OK) { logger(LOG_ERR, "Could not open file '%s' into the zip file '%s'\n", entry.name, z->filename); ret = -1; break; } } int error = UNZ_OK; entry.content = (char*)malloc(entry.info.uncompressed_size); if(!entry.content) { logger(LOG_ERR, "Unable to alloc a memory for the content of the zipped file '%s'\n", entry.name); ret = -1; break; } /* read the file */ do { error = unzReadCurrentFile(z->ctx, entry.content, entry.info.uncompressed_size); if ( error < 0 ) { logger(LOG_ERR, "Could not read file '%s' into the zip file '%s': %d\n", entry.name, z->filename, error); unzCloseCurrentFile(z->ctx); break; } } while ( error > 0 ); } callback(z, entry); free(entry.content); /* release content */ unzCloseCurrentFile(z->ctx); /* Go the the next entry listed in the zip file. */ if((i+1) < z->ginfo.number_entry) { if (unzGoToNextFile(z->ctx) != UNZ_OK) { logger(LOG_ERR, "Could not read next file from the zip file '%s'\n", z->filename); break; } } } if(ret) z_close(z); return ret; }