int main( int argc, char *argv[]) { int i; int opt_overwrite=0; int opt_compress_level=Z_DEFAULT_COMPRESSION; int opt_exclude_path=0; int zipfilenamearg = 0; char filename_try[MAXFILENAME+16]; int zipok; int err=0; int size_buf=0; void* buf=NULL; const char* password=NULL; do_banner(); if (argc==1) { do_help(); return 0; } else { for (i=1;i<argc;i++) { if ((*argv[i])=='-') { const char *p=argv[i]+1; while ((*p)!='\0') { char c=*(p++);; if ((c=='o') || (c=='O')) opt_overwrite = 1; if ((c=='a') || (c=='A')) opt_overwrite = 2; if ((c>='0') && (c<='9')) opt_compress_level = c-'0'; if ((c=='j') || (c=='J')) opt_exclude_path = 1; if (((c=='p') || (c=='P')) && (i+1<argc)) { password=argv[i+1]; i++; } } } else { if (zipfilenamearg == 0) { zipfilenamearg = i ; } } } } size_buf = WRITEBUFFERSIZE; buf = (void*)malloc(size_buf); if (buf==NULL) { printf("Error allocating memory\n"); return ZIP_INTERNALERROR; } if (zipfilenamearg==0) { zipok=0; } else { int i,len; int dot_found=0; zipok = 1 ; strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1); /* strncpy doesnt append the trailing NULL, of the string is too long. */ filename_try[ MAXFILENAME ] = '\0'; len=(int)strlen(filename_try); for (i=0;i<len;i++) if (filename_try[i]=='.') dot_found=1; if (dot_found==0) strcat(filename_try,".zip"); if (opt_overwrite==2) { /* if the file don't exist, we not append file */ if (check_exist_file(filename_try)==0) opt_overwrite=1; } else if (opt_overwrite==0) if (check_exist_file(filename_try)!=0) { char rep=0; do { char answer[128]; int ret; printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); ret = scanf("%1s",answer); if (ret != 1) { exit(EXIT_FAILURE); } rep = answer[0] ; if ((rep>='a') && (rep<='z')) rep -= 0x20; } while ((rep!='Y') && (rep!='N') && (rep!='A')); if (rep=='N') zipok = 0; if (rep=='A') opt_overwrite = 2; } } if (zipok==1) { zipFile zf; int errclose; # ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc; fill_win32_filefunc64A(&ffunc); zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); # else zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0); # endif if (zf == NULL) { printf("error opening %s\n",filename_try); err= ZIP_ERRNO; } else printf("creating %s\n",filename_try); for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++) { if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) && ((argv[i][1]=='o') || (argv[i][1]=='O') || (argv[i][1]=='a') || (argv[i][1]=='A') || (argv[i][1]=='p') || (argv[i][1]=='P') || ((argv[i][1]>='0') || (argv[i][1]<='9'))) && (strlen(argv[i]) == 2))) { FILE * fin; int size_read; const char* filenameinzip = argv[i]; const char *savefilenameinzip; zip_fileinfo zi; unsigned long crcFile=0; int zip64 = 0; zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; zi.dosDate = 0; zi.internal_fa = 0; zi.external_fa = 0; filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); /* err = zipOpenNewFileInZip(zf,filenameinzip,&zi, NULL,0,NULL,0,NULL / * comment * /, (opt_compress_level != 0) ? Z_DEFLATED : 0, opt_compress_level); */ if ((password != NULL) && (err==ZIP_OK)) err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); zip64 = isLargeFile(filenameinzip); /* The path name saved, should not include a leading slash. */ /*if it did, windows/xp and dynazip couldn't read the zip file. */ savefilenameinzip = filenameinzip; while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) { savefilenameinzip++; } /*should the zip file contain any path at all?*/ if( opt_exclude_path ) { const char *tmpptr; const char *lastslash = 0; for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) { if( *tmpptr == '\\' || *tmpptr == '/') { lastslash = tmpptr; } } if( lastslash != NULL ) { savefilenameinzip = lastslash+1; // base filename follows last slash. } } /**/ err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, NULL,0,NULL,0,NULL /* comment*/, (opt_compress_level != 0) ? Z_DEFLATED : 0, opt_compress_level,0, /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password,crcFile, zip64); if (err != ZIP_OK) printf("error in opening %s in zipfile\n",filenameinzip); else { fin = FOPEN_FUNC(filenameinzip,"rb"); if (fin==NULL) { err=ZIP_ERRNO; printf("error in opening %s for reading\n",filenameinzip); } } if (err == ZIP_OK) do { err = ZIP_OK; size_read = (int)fread(buf,1,size_buf,fin); if (size_read < size_buf) if (feof(fin)==0) { printf("error in reading %s\n",filenameinzip); err = ZIP_ERRNO; } if (size_read>0) { err = zipWriteInFileInZip (zf,buf,size_read); if (err<0) { printf("error in writing %s in the zipfile\n", filenameinzip); } } } while ((err == ZIP_OK) && (size_read>0)); if (fin) fclose(fin); if (err<0) err=ZIP_ERRNO; else { err = zipCloseFileInZip(zf); if (err!=ZIP_OK) printf("error in closing %s in the zipfile\n", filenameinzip); } } } errclose = zipClose(zf,NULL); if (errclose != ZIP_OK) printf("error in closing %s\n",filename_try); } else { do_help(); } free(buf); return 0; }
int minizip_zip(const char * lpszzipfilename, const char * lpszfilename, const char * lpszpassword, int nmode, int nLevel) { int nret = -1; int nstatus = 0; // int opt_compress_level = Z_DEFAULT_COMPRESSION; if (nLevel != Z_DEFAULT_COMPRESSION && nLevel != Z_BEST_COMPRESSION && nLevel != Z_BEST_SPEED && nLevel != Z_NO_COMPRESSION) { return -10086; } int nzipmode = APPEND_STATUS_CREATE; if (nmode ==0) { nzipmode = APPEND_STATUS_CREATE; } else { nzipmode = APPEND_STATUS_ADDINZIP; } // Create archive zipfilename zipFile zf = zipOpen64(lpszzipfilename, nzipmode); if (zf == NULL) { nstatus = ERROR_CREATE_ZIP; } int size_buf = WRITE_BUFFER_SIZE; Bytef* buf = (Bytef*) malloc(size_buf); // Get information about the file on disk so we can store it in zip zip_fileinfo zi; memset(&zi,0x00,sizeof(zip_fileinfo)); getFileTime(lpszfilename, &zi.tmz_date, &zi.dosDate); unsigned long crcFile = 0; if (nstatus == ZIP_OK) { nstatus = getCRC32(lpszfilename, buf, size_buf, &crcFile); } int zip64 = isLargeFile(lpszfilename); // Construct the filename that our file will be stored in the zip as. const char *savefilenameinzip = lpszfilename; { const char *tmpptr = NULL; const char *lastslash = 0; for (tmpptr = savefilenameinzip; *tmpptr; tmpptr++) { if (*tmpptr == '\\' || *tmpptr == '/') { lastslash = tmpptr; } } if (lastslash != NULL) { savefilenameinzip = lastslash + 1; } } if ((lpszpassword) && (lpszpassword[0] ==0)) { lpszpassword = NULL; } // Create zip file nstatus = zipOpenNewFileInZip3_64(zf, savefilenameinzip, &zi, NULL, 0, NULL, 0, NULL /* comment*/, Z_DEFLATED, nLevel, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, lpszpassword, crcFile, zip64); // Add file to zip FILE *fin = NULL; if (nstatus == ZIP_OK) { fin = fopen64(lpszfilename, "rb"); if (fin == NULL) { nstatus = ERROR_FILE_NOT_FOUND; } } int size_read = 0; if (nstatus == ZIP_OK) { // Read contents of file and write it to zip do { size_read = (int) fread(buf, 1, size_buf, fin); if ((size_read < size_buf) && (feof(fin) == 0)) { nstatus = ERROR_WHILE_READ; } if (size_read > 0) { nstatus = zipWriteInFileInZip(zf, buf, size_read); } } while ((nstatus == ZIP_OK) && (size_read > 0)); } if (fin) { fclose(fin); } if (nstatus >= 0) { nstatus = zipCloseFileInZip(zf); } zipClose(zf, NULL); // Release memory free(buf); if (nstatus == UNZ_OK) { nret = 0; } return nret; }
void ExportEPUB::SaveFolderAsEpubToLocation(const QString &fullfolderpath, const QString &fullfilepath) { QString tempFile = fullfolderpath + "-tmp.epub"; QDateTime timeNow = QDateTime::currentDateTime(); zip_fileinfo fileInfo; #ifdef Q_OS_WIN32 zlib_filefunc64_def ffunc; fill_win32_filefunc64W(&ffunc); zipFile zfile = zipOpen2_64(Utility::QStringToStdWString(QDir::toNativeSeparators(tempFile)).c_str(), APPEND_STATUS_CREATE, NULL, &ffunc); #else zipFile zfile = zipOpen64(QDir::toNativeSeparators(tempFile).toUtf8().constData(), APPEND_STATUS_CREATE); #endif if (zfile == NULL) { boost_throw(CannotOpenFile() << errinfo_file_fullpath(tempFile.toStdString())); } memset(&fileInfo, 0, sizeof(fileInfo)); fileInfo.tmz_date.tm_sec = timeNow.time().second(); fileInfo.tmz_date.tm_min = timeNow.time().minute(); fileInfo.tmz_date.tm_hour = timeNow.time().hour(); fileInfo.tmz_date.tm_mday = timeNow.date().day(); fileInfo.tmz_date.tm_mon = timeNow.date().month() - 1; fileInfo.tmz_date.tm_year = timeNow.date().year(); // Write the mimetype. This must be uncompressed and the first entry in the archive. if (zipOpenNewFileInZip64(zfile, "mimetype", &fileInfo, NULL, 0, NULL, 0, NULL, Z_NO_COMPRESSION, 0, 0) != Z_OK) { zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath("mimetype")); } if (zipWriteInFileInZip(zfile, EPUB_MIME_DATA, (unsigned int)strlen(EPUB_MIME_DATA)) != Z_OK) { zipCloseFileInZip(zfile); zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath("mimetype")); } zipCloseFileInZip(zfile); // Write all the files in our directory path to the archive. QDirIterator it(fullfolderpath, QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::Hidden, QDirIterator::Subdirectories); while (it.hasNext()) { it.next(); QString relpath = it.filePath().remove(fullfolderpath); while (relpath.startsWith("/")) { relpath = relpath.remove(0, 1); } // Add the file entry to the archive. // We should check the uncompressed file size. If it's over >= 0xffffffff the last parameter (zip64) should be 1. if (zipOpenNewFileInZip4_64(zfile, relpath.toUtf8().constData(), &fileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 8, 0, 15, 8, Z_DEFAULT_STRATEGY, NULL, 0, 0x0b00, 1<<11, 0) != Z_OK) { zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString())); } // Open the file on disk. We will read this and write what we read into // the archive. QFile dfile(it.filePath()); if (!dfile.open(QIODevice::ReadOnly)) { zipCloseFileInZip(zfile); zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotOpenFile() << errinfo_file_fullpath(it.fileName().toStdString())); } // Write the data from the file on disk into the archive. char buff[BUFF_SIZE] = {0}; qint64 read = 0; while ((read = dfile.read(buff, BUFF_SIZE)) > 0) { if (zipWriteInFileInZip(zfile, buff, read) != Z_OK) { dfile.close(); zipCloseFileInZip(zfile); zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString())); } } dfile.close(); // There was an error reading the file on disk. if (read < 0) { zipCloseFileInZip(zfile); zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString())); } if (zipCloseFileInZip(zfile) != Z_OK) { zipClose(zfile, NULL); QFile::remove(tempFile); boost_throw(CannotStoreFile() << errinfo_file_fullpath(relpath.toStdString())); } } zipClose(zfile, NULL); // Overwrite the contents of the real file with the contents from the temp // file we saved the data do. We do this instead of simply copying the file // because a file copy will lose extended attributes such as labels on OS X. QFile temp_epub(tempFile); if (!temp_epub.open(QFile::ReadOnly)) { boost_throw(CannotOpenFile() << errinfo_file_fullpath(tempFile.toStdString())); } QFile real_epub(fullfilepath); if (!real_epub.open(QFile::WriteOnly | QFile::Truncate)) { temp_epub.close(); boost_throw(CannotWriteFile() << errinfo_file_fullpath(fullfilepath.toStdString())); } // Copy the contents from the temp file to the real file. char buff[BUFF_SIZE] = {0}; qint64 read = 0; qint64 written = 0; while ((read = temp_epub.read(buff, BUFF_SIZE)) > 0) { written = real_epub.write(buff, read); if (written != read) { temp_epub.close(); real_epub.close(); QFile::remove(tempFile); boost_throw(CannotCopyFile() << errinfo_file_fullpath(fullfilepath.toStdString())); } } if (read == -1) { temp_epub.close(); real_epub.close(); QFile::remove(tempFile); boost_throw(CannotCopyFile() << errinfo_file_fullpath(fullfilepath.toStdString())); } temp_epub.close(); real_epub.close(); QFile::remove(tempFile); }
/** * @fn int z_compress(z_t zip, const z_file_t zname, const char* password, z_clevel_et level, _Bool append, _Bool exclude_path, fifo_t files) * @brief Creation of a new ZIP file. * @param zip The ZIP context. * @param zname The zip file name. * @param password the zip password else NULL or empty. * @param level The compression level. * @param append Append mode. * @param exclude_path Exclude the file path. * @param files The file list. * @retunr 0 on success else -1. */ int z_compress(z_t zip, const z_file_t zname, const char* password, z_clevel_et level, _Bool append, _Bool exclude_path, fifo_t files) { struct z_s* z = Z_CAST(zip); z_file_t filename_try; int size_buf = 0; void* buf = NULL; zipFile zf; size_buf = Z_WRITE_BUFFER_SIZE; buf = (void*)malloc(size_buf); if (!buf) { logger(LOG_ERR, "Error allocating memory\n"); return -1; } bzero(filename_try, sizeof(z_file_t)); strcpy(filename_try, zname); if(!string_indexof(filename_try, ".") == -1) strcat(filename_try, ".zip"); zf = zipOpen64(filename_try, (append) ? 2 : 0); if (!zf) { free(buf); logger(LOG_ERR, "Error opening %s\n", filename_try); return -1; } else logger(LOG_DEBUG, "Creating %s\n", filename_try); while(!fifo_empty(files)) { const char* filenameinzip = fifo_pop(files); FILE * fin; int size_read; const char *savefilenameinzip; zip_fileinfo zi; unsigned long crc_file = 0; int zip64 = 0; memset(&zi, 0, sizeof(zip_fileinfo)); if(file_is_dir(filenameinzip)) { ((char*)filenameinzip)[strlen(filenameinzip)] = z->dir_delimiter; strncat((char*)filenameinzip, ".empty", sizeof(file_name_t)); file_touch(filenameinzip); } logger(LOG_DEBUG, "Trying to add file '%s'\n", filenameinzip); file_time(filenameinzip, (struct tm*)&zi.tmz_date); if(password != NULL && strlen(password)) if(z_get_file_crc(filenameinzip, buf, size_buf, &crc_file) != ZIP_OK) { zipClose(zf, NULL); free(buf); logger(LOG_ERR, "Error getting the crc for the file %s\n", filenameinzip); return -1; } zip64 = file_is_large_file(filenameinzip); /* The path name saved, should not include a leading slash. */ /*if it did, windows/xp and dynazip couldn't read the zip file. */ savefilenameinzip = filenameinzip; while(savefilenameinzip[0] == z->dir_delimiter) savefilenameinzip++; /*should the zip file contain any path at all?*/ if(exclude_path) { const char *tmpptr; const char *lastslash = 0; for(tmpptr = savefilenameinzip; *tmpptr; tmpptr++) { if(*tmpptr == z->dir_delimiter) lastslash = tmpptr; } if(lastslash) savefilenameinzip = lastslash+1; // base filename follows last slash. } if(zipOpenNewFileInZip3_64(zf, savefilenameinzip, &zi, NULL, 0, NULL, 0, NULL /* comment*/, (level != 0) ? Z_DEFLATED : 0, level,0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, (password != NULL && strlen(password)) ? password : NULL, crc_file, zip64) != ZIP_OK) { zipClose(zf, NULL); free(buf); logger(LOG_ERR, "Error in opening %s in zipfile\n", filenameinzip); return -1; } fin = fopen64(filenameinzip, "rb"); if(!fin) { zipCloseFileInZip(zf); zipClose(zf, NULL); free(buf); logger(LOG_ERR, "Error in opening %s for reading\n", filenameinzip); return -1; } do { size_read = (int)fread(buf,1,size_buf,fin); if(size_read < size_buf) if(!feof(fin)) { logger(LOG_ERR, "Error in reading %s\n",filenameinzip); break; } if (size_read > 0) { if(zipWriteInFileInZip(zf, buf, size_read) < 0) { logger(LOG_ERR, "Error in writing %s in the zipfile\n", filenameinzip); break; } } } while(size_read > 0); if(fin) fclose(fin); if(zipCloseFileInZip(zf) != ZIP_OK) { logger(LOG_ERR, "Error in closing %s in the zipfile\n", filenameinzip); break; } } if(zipClose(zf, NULL) != ZIP_OK) logger(LOG_ERR, "Error in closing %s\n",filename_try); free(buf); return 0; }