int main(int argc, char *argv[]) { zipFile zf = NULL; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc = {0}; #endif char *zipfilename = NULL; const char* password = NULL; void* buf = NULL; int size_buf = WRITEBUFFERSIZE; int zipfilenamearg = 0; int errclose = 0; int err = 0; int i = 0; int opt_overwrite = APPEND_STATUS_CREATE; int opt_compress_level = Z_DEFAULT_COMPRESSION; int opt_exclude_path = 0; do_banner(); if (argc == 1) { do_help(); return 0; } /* Parse command line options */ 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 = APPEND_STATUS_CREATEAFTER; if ((c == 'a') || (c == 'A')) opt_overwrite = APPEND_STATUS_ADDINZIP; 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; } } if (zipfilenamearg == 0) { do_help(); return 0; } zipfilename = argv[zipfilenamearg]; buf = (void*)malloc(size_buf); if (buf == NULL) { printf("Error allocating memory\n"); return ZIP_INTERNALERROR; } if (opt_overwrite == 2) { /* If the file don't exist, we not append file */ if (check_file_exists(zipfilename) == 0) opt_overwrite = 1; } else if (opt_overwrite == 0) { /* If ask the user what to do because append and overwrite args not set */ //if (check_file_exists(zipfilename) != 0) //{ // char rep = 0; // do // { // char answer[128]; // printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", zipfilename); // if (scanf("%1s", answer) != 1) // exit(EXIT_FAILURE); // rep = answer[0]; // if ((rep >= 'a') && (rep <= 'z')) // rep -= 0x20; // } // while ((rep != 'Y') && (rep != 'N') && (rep != 'A')); // if (rep == 'A') // opt_overwrite = 2; // else if (rep == 'N') // { // do_help(); // free(buf); // return 0; // } //} } #ifdef USEWIN32IOAPI fill_win32_filefunc64A(&ffunc); zf = zipOpen2_64(zipfilename, opt_overwrite, NULL, &ffunc); #else zf = zipOpen64(zipfilename, opt_overwrite); #endif if (zf == NULL) { printf("error opening %s\n", zipfilename); err = ZIP_ERRNO; } else printf("creating %s\n", zipfilename); /* Go through command line args looking for files to add to zip */ for (i = zipfilenamearg + 1; (i < argc) && (err == ZIP_OK); i++) { FILE *fin = NULL; int size_read = 0; const char* filenameinzip = argv[i]; const char *savefilenameinzip; zip_fileinfo zi = {0}; unsigned long crcFile = 0; int zip64 = 0; /* Skip command line options */ if ((((*(argv[i])) == '-') || ((*(argv[i])) == '/')) && (strlen(argv[i]) == 2) && ((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')))) continue; /* Get information about the file on disk so we can store it in zip */ filetime(filenameinzip, &zi.tmz_date, &zi.dosDate); if ((password != NULL) && (err == ZIP_OK)) err = get_file_crc(filenameinzip, buf, size_buf, &crcFile); zip64 = is_large_file(filenameinzip); /* Construct the filename that our file will be stored in the zip as. 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 file be stored with any path info at all? */ if (opt_exclude_path) { const char *tmpptr = NULL; 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. */ } /* Add to zip file */ 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, password, crcFile, zip64); if (err != ZIP_OK) printf("error in opening %s in zipfile (%d)\n", filenameinzip, err); 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) { /* 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)) { 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 (%d)\n", filenameinzip, err); } } 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 (%d)\n", filenameinzip, err); } } errclose = zipClose(zf, NULL); if (errclose != ZIP_OK) printf("error in closing %s (%d)\n", zipfilename, errclose); free(buf); return err; }
int _compress(const char** srcs, int src_num, const char** srcspath, int srcpath_num, const char* dst, int level, const char* password, int exclude_path, PyObject* progress) { zipFile zf = NULL; int size_buf = WRITEBUFFERSIZE; int opt_overwrite = APPEND_STATUS_CREATE; int err = ZIP_OK; int errclose = 0; int i; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc = {0}; #endif void* buf = NULL; buf = (void*)malloc(size_buf); if (buf == NULL) { pyerr_msg = PyErr_Format(PyExc_MemoryError, "could not allocate memory"); return ZIP_ERRNO; } if (srcpath_num > 0) assert(src_num == srcpath_num); #ifdef USEWIN32IOAPI fill_win32_filefunc64A(&ffunc); zf = zipOpen2_64(dst, opt_overwrite, NULL, &ffunc); #else zf = zipOpen64(dst, opt_overwrite); #endif if (zf == NULL) { pyerr_msg = PyErr_Format(PyExc_IOError, "error opening %s", dst); err = ZIP_ERRNO; } for (i = 0; i < src_num && (err == ZIP_OK); i++) { FILE *fin = NULL; int size_read = 0; const char* filenameinzip = srcs[i]; const char* filepathnameinzip; const char *savefilenameinzip; const char *savefilepathnameinzip = NULL; char *fullpathfileinzip = NULL; unsigned long crcFile = 0; int zip64 = 0; zip_fileinfo zi; memset(&zi, 0, sizeof(zip_fileinfo)); if (srcpath_num > 0) filepathnameinzip = srcspath[i]; /* Get information about the file on disk so we can store it in zip */ filetime(filenameinzip, &zi.tmz_date, &zi.dosDate); if ((password != NULL) && (err == ZIP_OK)) err = get_file_crc(filenameinzip, buf, size_buf, &crcFile); zip64 = is_large_file(filenameinzip); /* Construct the filename that our file will be stored in the zip as. 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++; if (srcpath_num > 0) { savefilepathnameinzip = filepathnameinzip; while (savefilepathnameinzip[0] == '\\' || savefilepathnameinzip[0] == '/') savefilepathnameinzip++; } /* Should the file be stored with any path info at all? */ if (exclude_path) { const char *tmpptr = NULL; const char *lastslash = NULL; for (tmpptr = savefilenameinzip; *tmpptr; tmpptr++) { if (*tmpptr == '\\' || *tmpptr == '/') lastslash = tmpptr; } if (lastslash != NULL) savefilenameinzip = lastslash + 1; // base filename follows last slash. if (srcpath_num > 0) { /* prepend savefilepathnameinzip for each savefilenameinzip */ const char * slash; #if (defined(_WIN32)) const char default_slash = '\\'; #else const char default_slash = '/'; #endif size_t extra_len = 0; size_t filename_len = strlen(savefilenameinzip); size_t filepathname_len = strlen(savefilepathnameinzip); /* look for slash used in filepath */ slash = strchr(savefilepathnameinzip, '/'); if (slash == NULL) { slash = strchr(savefilepathnameinzip, '\\'); if (slash == NULL) { // no slash found.. use default slash = &default_slash; } } if (savefilepathnameinzip[filepathname_len-1] != *slash) extra_len = 1; /* allocate buffer */ fullpathfileinzip = (char *)malloc(filename_len + filepathname_len + extra_len + 1); if (fullpathfileinzip == NULL) { free(buf); pyerr_msg = PyErr_Format(PyExc_MemoryError, "error allocating memory on minizip compress"); return ZIP_INTERNALERROR; } strncpy(fullpathfileinzip, savefilepathnameinzip, filepathname_len); if (extra_len) fullpathfileinzip[filepathname_len] = *slash; strncpy(fullpathfileinzip + filepathname_len + extra_len, savefilenameinzip, filename_len); /* terminate string */ fullpathfileinzip[filename_len + filepathname_len + extra_len] = '\0'; /* set pointer */ savefilenameinzip = fullpathfileinzip; } } /* Add to zip file */ err = 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, */ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, crcFile, zip64); if (err != ZIP_OK) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in opening %s in zipfile (%d)", filenameinzip, err); err = ZIP_ERRNO; } else { fin = FOPEN_FUNC(filenameinzip, "rb"); if (fin == NULL) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in opening %s for reading", filenameinzip); err = ZIP_ERRNO; } } if (err == 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)) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in reading %s", filenameinzip); err = ZIP_ERRNO; } if (0 < size_read) { err = zipWriteInFileInZip(zf, buf, size_read); if (err < 0) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in writing %s in the zipfile (%d)", filenameinzip, err); err = ZIP_ERRNO; } } } while ((err == ZIP_OK) && (size_read > 0)); } if (fin) fclose(fin); if (err == ZIP_OK) { err = zipCloseFileInZip(zf); if (err != ZIP_OK) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in closing %s in the zipfile (%d)", filenameinzip, err); err = ZIP_ERRNO; } } if (progress != NULL) { PyObject* args = Py_BuildValue("(I)", i + 1); PyObject* result = PyObject_CallObject(progress, args); if (PyErr_Occurred()) // Ignore errors in the callback, don't want them to crash this c module { PyErr_Clear(); } Py_XDECREF(result); Py_XDECREF(args); } if(srcpath_num > 0 && fullpathfileinzip) free(fullpathfileinzip); } errclose = zipClose(zf, NULL); if (errclose != ZIP_OK) { pyerr_msg = PyErr_Format(PyExc_IOError, "error in closing %s (%d)", dst, errclose); err = ZIP_ERRNO; } free(buf); return err; }