//=============================================================================== /** * @file ZIP_Wrapper.cpp * * $Id$ * * Purpose: implementing the ZIP_Wrapper class * * @author Stoyan Paunov, Vipul Singh * */ //=============================================================================== #include "ace/Containers_T.h" //for ACE_Double_Linked_List #include "ace/Message_Block.h" //for ACE_Message_Block #include "ace/OS_NS_fcntl.h" //for open #include "ace/OS_NS_unistd.h" //for close #include "ace/OS_NS_string.h" //for strncpy #include "ace/SString.h" //for ACE_CString #include "ace/OS_NS_sys_stat.h" //for stat #include "ace/OS_NS_sys_stat.h" //for filesize and mkdir #include "ace/OS_Memory.h" //for ACE_NEW* macros #include #include "unzip.h" #define MAXFILENAME (256) #define CASESENSITIVITY (0) #define WRITEBUFFERSIZE (8192) #include "ZIP_Wrapper.h" //ZIP_File_Info constructor ZIP_File_Info::ZIP_File_Info (char* name, size_t size) : name_ (name), size_ (size), next_ (0), prev_ (0) { } //ZIP_File_Info default constructor ZIP_File_Info::ZIP_File_Info () : name_ (""), size_ (0), next_ (0), prev_ (0) { } /// Gets a list of the files in the archive. int ZIP_Wrapper::file_list_info (char* zip_name, ACE_Double_Linked_List &list) { unzFile uf=0; char filename_try[MAXFILENAME+16] = ""; if (zip_name!=0) { strncpy(filename_try, zip_name, MAXFILENAME-1); /* strncpy doesnt append the trailing NULL, if the string is too long. */ filename_try[ MAXFILENAME ] = '\0'; /* open the zip file */ uf = unzOpen(zip_name); /* if zipfile could not be opened, try appending .zip to name */ if (uf==0) { ACE_OS::strcat(filename_try, ".zip"); uf = unzOpen(filename_try); } } /* If zipfile could not be opened still, return */ if (uf==0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("There is some problem in opening" " %s or %s.zip using unzOpen \n"), zip_name, zip_name)); return 1; } unz_global_info gi; /* get information about all the files in zip file*/ int err = unzGetGlobalInfo(uf, &gi); if (err!=UNZ_OK) ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetGlobalInfo failed while trying" " to get global information about zipfile \n"), err)); /* gi.number_entry corresponds to the number of directory entries in the zip file */ for (uLong i=0;ispace () == 0) { ACE_Message_Block* next = 0; ACE_NEW_RETURN (next, ACE_Message_Block (BUFSIZ), false); head->cont (); head = head->cont (); } num_read = unzReadCurrentFile(archive_path, head->wr_ptr(), head->space()); if (num_read > 0) head->wr_ptr (num_read); } while (num_read > 0); if (num_read < 0) return_code = false; unzCloseCurrentFile(uf); unzClose(uf); return return_code; } } return return_code; } /// uncompress the zip file /// The zip file will be uncompressed into a directory /// with the name of zip archive. /// the path is assumed to be an existing directory bool ZIP_Wrapper::uncompress (char* zip_archive, char* path, bool verbose) { //open the zip archive unzFile uf=0; uf = unzOpen(zip_archive); if (uf==0) { ACE_DEBUG((LM_DEBUG,ACE_TEXT("unzOpen failed to open the" " zipfile\n"))); return false; } //get the name of the archive ACE_CString arch_dir (path); arch_dir += "/"; //get only the name of the archive; remove path info char* n = ACE_OS::strstr (zip_archive, "/"); char* zip_name = 0; while (n != 0) { zip_name = ++n; n = ACE_OS::strstr (n, "/"); } arch_dir += zip_name; //NOTE: Assumes .zip or cpk extension arch_dir = arch_dir.substring (0, arch_dir.length () - 4); //create directory with the name of zip archive ACE_OS::mkdir(arch_dir.c_str()); //if dir exists -1 is returned and ignored unz_global_info gi; int err = unzGetGlobalInfo(uf, &gi); if (err!=UNZ_OK) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetGlobalInfo failed to get global" " information about zipfile \n"), err)); return false; } err =unzGoToFirstFile(uf); if (err!=UNZ_OK) { ACE_DEBUG((LM_DEBUG,ACE_TEXT("error %d with zipfile in" " unzGoToFirstFile \n"), err)); return false; } /* read each entry of zip file, create directory structure if it is a non existing directory whereas if it is a file, write the file at the proper path in the directory structure */ for (uLong i=0;i buffer (temp); //read in the data unzReadCurrentFile(uf, &(*buffer), file_size); //close the zip handle unzCloseCurrentFile(uf); //create file name + path to open std::string file_path (arch_dir.c_str ()); //NOTE: need the c-style char to stop at '\0' file_path += "/"; file_path += filename_inzip; //print out the file to be uncompressed if (verbose) { ACE_OS::write(ACE_STDOUT, file_path.c_str (), file_path.length () ); ACE_OS::write(ACE_STDOUT, "\n", 1); } // Open a file handle to the local filesystem ACE_HANDLE handle = ACE_OS::open (file_path.c_str (), O_CREAT | O_TRUNC | O_WRONLY); if (handle == ACE_INVALID_HANDLE) { unzClose(uf); ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("[uncompress] file creation error")), 0); } //write the uncompressed data to the file if (ACE_OS::write (handle, &(*buffer), file_size) == -1) { unzClose(uf); ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("[uncompress] file write error")), 0); } // Close the file handle ACE_OS::close (handle); } return 0; }