#include #include #ifdef WIN32 #include #else #include #include #endif #include #define BUF_SIZE 128 #ifndef MAX_PATH #define MAX_PATH 2048 #endif const char pathsep = #ifdef WIN32 '\\'; #else '/'; #endif int makedir(const char *dir) { #ifdef WIN32 return mkdir(dir); #else return mkdir(dir, 0755); #endif } void gen_full_filename(const char *basedir, const char *file, char *dest, size_t destsize) { int i; #ifdef WIN32 char *fix; #endif if(basedir == NULL) strncpy(dest, file, destsize); else if(file == NULL) strncpy(dest, basedir, destsize); else { if(basedir[strlen(basedir)-1] == '/' || basedir[strlen(basedir)-1] == '\\') snprintf(dest, destsize, "%s%s", basedir, file); else snprintf(dest, destsize, "%s%c%s", basedir, pathsep, file); } #ifdef WIN32 fix = strchr(dest, '/'); while(fix != NULL) { *fix = '\\'; fix = strchr(dest, '/'); } #endif } void ensure_directory(const char *base, const char *filename) { char *onedir; char *fulldir; char *tmp; if(filename == NULL || base == NULL) return; if(strlen(filename) == 0) return; onedir = (char *)malloc((strlen(filename)+1)*sizeof(char)); fulldir = (char *)malloc((strlen(filename)+strlen(base)+2)*sizeof(char)); strcpy(onedir, filename); tmp = onedir; tmp = strchr(onedir, pathsep); #ifdef WIN32 if(tmp == NULL) tmp = strchr(onedir, '/'); #endif while(tmp != NULL) { *tmp = '\0'; gen_full_filename(base, onedir, fulldir, (strlen(filename)+strlen(base)+2)); makedir(fulldir); *tmp = pathsep; tmp++; #ifdef WIN32 if(strchr(tmp, pathsep) == NULL) tmp = strchr(tmp, '/'); else tmp = strchr(tmp, pathsep); #else tmp = strchr(tmp, pathsep); #endif } free(onedir); free(fulldir); } int unzip_file(const char *filename, const char *directory, const char *index_of_files_file) { struct zip *za; struct zip_file *zf; struct zip_stat sb; char buf[BUF_SIZE]; int err, i; size_t this_read, total_read; char fullfile[MAX_PATH]; FILE *fp; FILE *fp_index; za = zip_open(filename, 0, &err); if (za == NULL) { return -1; } if(index_of_files_file != NULL) fp_index = fopen(index_of_files_file, "w"); else fp_index = NULL; for(i=0; i < zip_get_num_entries(za,0); i++) { if (zip_stat_index(za, i, 0, &sb) == 0) { gen_full_filename(directory, sb.name, fullfile, MAX_PATH); if(fullfile[strlen(fullfile)-1] == pathsep) { makedir(fullfile); } else { ensure_directory(directory, sb.name); zf = zip_fopen_index(za, i, 0); fp = fopen(fullfile, "wb"); if(zf != NULL && fp != NULL) { total_read = 0; while(total_read < sb.size) { this_read = zip_fread(zf, buf, BUF_SIZE); fwrite(buf, sizeof(char), this_read, fp); total_read += this_read; } if(fp_index != NULL) fprintf(fp_index, "%s\n", fullfile); } if(zf != NULL) zip_fclose(zf); if(fp != NULL) fclose(fp); } } } zip_close(za); if(fp_index != NULL) fclose(fp_index); return 1; }