Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}