summaryrefslogtreecommitdiff
path: root/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp')
-rw-r--r--CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp b/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp
new file mode 100644
index 00000000000..b318af0ad13
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp
@@ -0,0 +1,375 @@
+
+//===============================================================================
+/**
+ * @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 <string>
+#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<ZIP_File_Info> &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;i<gi.number_entry;i++)
+ {
+ char filename_inzip[256];
+ unz_file_info file_info;
+ /* get information about the current file in zip file */
+ err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip,
+ sizeof(filename_inzip), 0, 0, 0, 0);
+ if (err!=UNZ_OK)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetCurrentFileInfo failed"
+ " while trying to get information"
+ " about current file\n"), err));
+ break;
+ }
+ ZIP_File_Info* next = 0;
+ ACE_NEW_RETURN (next, ZIP_File_Info (filename_inzip,
+ sizeof(filename_inzip)), -1);
+ /* add information about current file to the list */
+ list.insert_tail (next);
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ ACE_DEBUG((LM_DEBUG,ACE_TEXT(" unzGoToNextFile failed"
+ " while trying to go to next file\n"), err));
+ break;
+ }
+ }
+ }
+ unzCloseCurrentFile(uf);
+ return gi.number_entry;
+}
+
+
+//get file and store it into ACE message block.
+bool ZIP_Wrapper::get_file (char* archive_path, char* filename,
+ ACE_Message_Block &file)
+{
+ bool return_code = true;
+ unzFile uf=0;
+ uf = unzOpen(archive_path);
+ /* locate the desired file in the zip file and set it as current file*/
+ int j=unzLocateFile(uf, filename, 0);
+ if (j==UNZ_END_OF_LIST_OF_FILE)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("File not found in zip archive")));
+ return false;
+ }
+ else if (j==UNZ_OK)
+ {
+ int k=unzOpenCurrentFile(uf);
+ if (k!=UNZ_OK)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("Error in opening the current"
+ " file using unzOpenCurrentFile")));
+ return false;
+ }
+ else
+ {
+ int num_read = 0;
+ ACE_Message_Block* head = &file;
+
+ //read the file into the ACE_Message_Block
+ do
+ {
+ if (head->space () == 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<gi.number_entry;i++)
+ {
+ char filename_inzip[256];
+ unz_file_info file_info;
+ err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip,
+ sizeof(filename_inzip), 0, 0, 0, 0);
+ if (err!=UNZ_OK)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetCurrentFileInfo failed"
+ " while trying to get information"
+ " about currentfile\n"), err));
+ break;
+ }
+ int direc = checkdir(filename_inzip);
+ /* If it is a directory, we create directory structure */
+ if (direc==1)
+ {
+ makethedir(filename_inzip, arch_dir);
+ }
+ /* If it is a file, we read its data and write the uncompressed
+ data to the file with proper path.*/
+ else if (direc==0)
+ {
+ handlethefile(filename_inzip, uf, file_info, verbose, arch_dir);
+ }
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ ACE_ERROR((LM_ERROR,ACE_TEXT("unzGoToNextFile failed"
+ " while trying to go to"
+ " nextfile\n"), err));
+ break;
+ }
+ }
+ }
+ unzClose(uf);
+ return true;
+}
+
+
+
+///try to find if it is a directory OR file
+int ZIP_Wrapper::checkdir (char* filename_inzip)
+{
+ int direc = 0;
+ char* dircheck = ACE_OS::strstr (filename_inzip, "/");
+ /* We assume that a directory will have its entry terminating in a /
+ We also assume that the directory entries in the zip file use
+ forward slash for both unix and windows */
+ while (dircheck != 0)
+ {
+ int i = ACE_OS::strcmp(dircheck, "/");
+ if (i == 0)
+ {
+ direc = 1;
+ break;
+ }
+ ++dircheck;
+ dircheck = ACE_OS::strstr (dircheck, "/");
+ }
+ return direc;
+}
+
+///Create directory structure if entry in zipfile is a directory
+int ZIP_Wrapper::makethedir (char* filename_inzip, ACE_CString arch_dir)
+{
+//let's try to create the directory structure for the package
+ char dir_name [2048];
+ char* next = ACE_OS::strstr (filename_inzip, "/");
+ while (next != 0)
+ {
+ ACE_CString location (arch_dir);
+ ACE_OS::strncpy (dir_name, filename_inzip, next - filename_inzip
+ + 1);
+
+ dir_name[next - filename_inzip + 1] = '\0';
+ location += "/";
+ location += dir_name;
+ ACE_stat stat;
+ if (ACE_OS::stat (location.c_str (), &stat) == -1)
+ ACE_OS::mkdir (location.c_str ());
+ next++;
+ next = ACE_OS::strstr (next, "/");
+ }
+ return 0;
+}
+
+///If entry in zipfile is a file, then read the file and write the
+///uncompressed data at the proper filepath.
+int ZIP_Wrapper::handlethefile (char* filename_inzip, unzFile uf,
+ unz_file_info file_info, bool verbose,
+ ACE_CString arch_dir)
+{
+ int k = unzOpenCurrentFile(uf);
+ if (k!=UNZ_OK)
+ {
+ ACE_ERROR((LM_ERROR,ACE_TEXT("unzOpenCurrentFile failed in"
+ " opening the current file")));
+ return false;
+ }
+ else
+ {
+ size_t const file_size = file_info.uncompressed_size;
+ char* temp = 0;
+ ACE_NEW_RETURN (temp, char [file_size], false);
+ ACE_Auto_Basic_Array_Ptr<char> 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;
+}