From 0f75ab0e3cea30ee86d2bd34cff125b221d5d02b Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Sun, 24 Oct 2021 15:35:39 -0400 Subject: Initial code commit --- funzip.f90 | 37 ++++++++++++++++ libzip-wrapper.prj | 71 +++++++++++++++++++++++++++++ unzip_wrap.f90 | 48 ++++++++++++++++++++ zwrapper.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 284 insertions(+) create mode 100644 funzip.f90 create mode 100644 libzip-wrapper.prj create mode 100644 unzip_wrap.f90 create mode 100644 zwrapper.c diff --git a/funzip.f90 b/funzip.f90 new file mode 100644 index 0000000..dc71e84 --- /dev/null +++ b/funzip.f90 @@ -0,0 +1,37 @@ +program funzip +use m_unzip +implicit none + + character(len=512)::archive, dir + logical::success, file_exists + + success = .false. + + if(command_argument_count() < 1 .or. command_argument_count() > 2) then + + call get_command_argument(0, archive) + Print *, "Usage: "//trim(archive)//" []" + + else + + call get_command_argument(1, archive) + if(command_argument_count() == 2) then + call get_command_argument(2, dir) + else + dir = "." + end if + + inquire(file=trim(archive), exist=file_exists) + if(.not. file_exists) then + Print *, "Could not locate '"//trim(archive)//"'" + end if + + if(unzip(trim(archive), trim(dir), indexed='/tmp/zip.lst')) then + + Print *, "Successfully extracted '"//trim(archive)//"'" + + end if + + end if + +end program funzip diff --git a/libzip-wrapper.prj b/libzip-wrapper.prj new file mode 100644 index 0000000..68d31be --- /dev/null +++ b/libzip-wrapper.prj @@ -0,0 +1,71 @@ +{ + "Root":{ + "Folders":[], + "Name":"+libzip-wrapper (funzip)", + "Files":[{ + "filename":"funzip.f90", + "enabled":"1" + },{ + "filename":"unzip_wrap.f90", + "enabled":"1" + },{ + "filename":"zwrapper.c", + "enabled":"1" + }] + }, + "Name":"libzip-wrapper (funzip)", + "Options":{ + "Compiler Options":{ + "Fortran Flags":"", + "Link Flags":"-lzip", + "C Flags":"" + }, + "Architecture":0, + "Type":0, + "Revision":2, + "Windows GUI":0, + "File Options":{ + "Library Directories":["Default Library Directory"], + "Build Directory":"build", + "Module Directory":"modules", + "Include Directories":["Default Include Directory"] + }, + "Target":"funzip", + "Fortran Options":{ + "Use C Preprocessor":"false", + "Runtime Diagnostics":"false", + "Floating Point Exception Trap":0, + "Cray Pointers":"false", + "Enable Coarrays":"false", + "Enable OpenMP":"false", + "Initialize Variables to Zero":"false", + "Default Double for Real":"false" + }, + "Code Generation Options":{ + "CPU Specific":"false", + "Processor":"generic", + "Aggressive Loops":"false", + "Debugging":"true", + "Optimization Mode":0, + "Profiling":"false" + }, + "Build Dependencies":1, + "Launch Options":{ + "Working Directory":"", + "Launch Using MPI":"false", + "Keep Console":"true", + "External Console":"false", + "Command Line Arguments":"", + "Build Before Launch":"true" + }, + "Build Options":{ + "Makefile":"Makefile", + "Auto Makefile":"true" + }, + "Linker Options":{ + "Static Linking Mode":0, + "Link MPI Library":"false", + "Link LAPACK":0 + } + } +} \ No newline at end of file diff --git a/unzip_wrap.f90 b/unzip_wrap.f90 new file mode 100644 index 0000000..c29dfd7 --- /dev/null +++ b/unzip_wrap.f90 @@ -0,0 +1,48 @@ +module m_unzip +implicit none + + interface + function unzip_file_c(archive, directory, indexed) bind(c, name="unzip_file") + use iso_c_binding + integer(kind=c_int)::unzip_file_c + type(c_ptr), value::archive, directory, indexed + end function unzip_file_c + end interface + +contains + + function unzip(archive, directory, indexed) + use iso_c_binding + implicit none + + logical::unzip + character(*), intent(in)::archive, directory + character(*), intent(in), optional::indexed + + character(kind=c_char, len=:), pointer::c_arc, c_dir, c_index + + allocate(character(len=(len_trim(archive)+1)) :: c_arc) + c_arc = trim(archive)//c_null_char + allocate(character(len=(len_trim(directory)+1)) :: c_dir) + c_dir = trim(directory)//c_null_char + + if(present(indexed)) then + allocate(character(len=(len_trim(indexed)+1)) :: c_index) + c_index = trim(indexed)//c_null_char + else + c_index => NULL() + end if + + !if(associated(c_index)) then + + unzip = (unzip_file_c(c_loc(c_arc), c_loc(c_dir), c_loc(c_index)) == 1) + + deallocate(c_arc) + deallocate(c_dir) + if(associated(c_index)) then + deallocate(c_index) + end if + + end function unzip + +end module m_unzip \ No newline at end of file diff --git a/zwrapper.c b/zwrapper.c new file mode 100644 index 0000000..6d07f2b --- /dev/null +++ b/zwrapper.c @@ -0,0 +1,128 @@ +#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 + +} + +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 { + zf = zip_fopen_index(za, i, 0); + fp = fopen(fullfile, "w"); + 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; +} -- cgit v1.2.3