diff options
author | spaunov <spaunov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2005-10-06 20:33:38 +0000 |
---|---|---|
committer | spaunov <spaunov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2005-10-06 20:33:38 +0000 |
commit | 7d4cb65aaa51595f0dec471bb795b7018db8a4c4 (patch) | |
tree | 09797b91e4353357e077da0395db83df1197849b /TAO/CIAO/DAnCE | |
parent | e6789410be1cc8c102a5b76d47fec292b04f1292 (diff) | |
download | ATCD-7d4cb65aaa51595f0dec471bb795b7018db8a4c4.tar.gz |
Thu Oct 6 15:32:41 CDT 2005 Stoyan Paunov spaunov@isis.vanderbilt.edu
Diffstat (limited to 'TAO/CIAO/DAnCE')
8 files changed, 750 insertions, 88 deletions
diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.cpp b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.cpp new file mode 100644 index 00000000000..8e8c7daa665 --- /dev/null +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.cpp @@ -0,0 +1,269 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ciao/Deployment_DataC.h" +#include "PC_Updater.h" +#include "PC_Updater_T.h" +#include "ace/Containers_T.h" //for ACE_Double_Linked_List + + +#include <iostream> +using namespace std; + +namespace +{ + const size_t TEMP_LEN = 1024; +} + +using namespace PC_Updater_T; + + + //PATH of glory/gory to update the locations of the IADs + // + //PackageConfiguration something; + //ComponentPackageDescriptions basePackage; + //PackagedComponentImplementations implementation; + //ComponentImplementationDescription referencedImplementation; + // + //MONOLITHIC Component: + //MonolithicImplementationDescriptions monolithicImpl; + //NamedImplementationArtifacts primaryArtifact; + //ImplementationArtifactDescription referencedArtifact; + //::CORBA::StringSeq location; + // + //ASSEMBLY-BASED Component + //ComponentAssemblyDescriptions assemblyImpl; + //SubcomponentInstantiationDescriptions instance; + //ComponentPackageDescriptions package; + //... + + + /* + * PC_Updater Constructors + */ + +PC_Updater::PC_Updater (const char* server_path, const char* package) +: server_path_ (server_path), + file_list_ (&allocator_), + package_ (package), + success_ (true) +{ +} + + +PC_Updater::PC_Updater (ACE_CString& server_path, ACE_CString& package) +: server_path_ (server_path), + file_list_ (&allocator_), + package_ (package), + success_ (true) +{ +} + + /* + * PC_Updater - Destructor + */ + +PC_Updater::~PC_Updater () +{ + this->clear_list (); +} + + +void PC_Updater::clear_list () +{ + while (!this->file_list_.is_empty ()) + { + ZIP_File_Info* inf = this->file_list_.delete_head (); + + //deallocate the head of the filename list + delete inf; + } +} + + + /* + * PC_Updater - Object update methods + */ + + + // PackageConfiguration + + bool PC_Updater::update (const ::Deployment::PackageConfiguration &pc) + { + //get the list of files in the package and figure out the names of all necessary files + if (!ZIP_Wrapper::file_list_info (const_cast <char*> (this->package_.c_str ()), this->file_list_)) + return false; + + update_sequence (pc.basePackage, this); + + return this->success_; + } + + + // ComponentInterfaceDescription + + void PC_Updater::update (const ::Deployment::ComponentInterfaceDescription &cid) + { + } + + // Requirement + + void PC_Updater::update (const ::Deployment::Requirement &req) + { + } + + + // ComponentExternalPortEndpoint + + void PC_Updater::update (const ::Deployment::ComponentExternalPortEndpoint &cepe) + { + } + + + + // ImplementationDependency + + void PC_Updater::update(const Deployment::ImplementationDependency &id) + { + } + + // ComponentPackageReference + + void PC_Updater::update (const ::Deployment::ComponentPackageReference &cpr) + { + } + + // SubcomponentInstantiationDescription + + void PC_Updater::update (const ::Deployment::SubcomponentInstantiationDescription &sid) + { + update_sequence (sid.package, this); + } + + // SubcomponentPortEndpoint + + void PC_Updater::update (const ::Deployment::SubcomponentPortEndpoint& spe) + { + } + + // AssemblyConnectionDescription + + void PC_Updater::update (const ::Deployment::AssemblyConnectionDescription &acd) + { + } + + + // AssemblyPropertyMapping + + void + PC_Updater::update (const ::Deployment::AssemblyPropertyMapping &apm) + { + } + + // ComponentAssemblyDescription + + void PC_Updater::update (const ::Deployment::ComponentAssemblyDescription& cad) + { + update_sequence (cad.instance, this); + } + + // ImplementationArtifactDescription + + void PC_Updater::update (const ::Deployment::ImplementationArtifactDescription &iad) + { + bool found = false; + + cout << "label: " << iad.label << endl; + cout << "location: " << CORBA::string_dup (iad.location[0].in ()) << endl; + + ACE_Double_Linked_List_Iterator<ZIP_File_Info> iter (this->file_list_); + char str [TEMP_LEN]; + + while (!iter.done ()) + { + ACE_OS::strncpy ( str, iter.next ()->name_.c_str (), TEMP_LEN); + //weird. Need to call next to get current ?!?! + + const char* name; + const char* ext; + + name = ACE_OS::strstr (str, iad.location[0].in ()); + + if (name) + { + ext = ACE_OS::strstr (name, "."); + + ACE_CString loc (this->server_path_); + loc += iad.location[0].in (); + loc += ext; + + iad.location[0] = CORBA::string_dup (loc.c_str ()); + + cout << "new location: " << iad.location[0].in () << endl << endl; + + found = true; + break; + } + iter++; + } + + if (!found) + this->success_ = false; + } + + // NamedImplementationArtifact + + void PC_Updater::update (const ::Deployment::NamedImplementationArtifact &nia) + { + update (nia.referencedArtifact); + } + + // ImplementationRequirement + + void PC_Updater::update (const ::Deployment::ImplementationRequirement &ir) + { + } + + // MonolithicImplementationDescription + + void PC_Updater::update (const ::Deployment::MonolithicImplementationDescription &mid) + { + update_sequence (mid.primaryArtifact, this); + } + + // Capability + + void PC_Updater::update (const ::Deployment::Capability &capability) + { + } + + + + // ComponentImplementationDescription + + void PC_Updater::update ( + const ::Deployment::ComponentImplementationDescription &cid) + { + update_sequence (cid.assemblyImpl, this); + update_sequence (cid.monolithicImpl, this); + } + + // PackagedComponentImplementation + + void PC_Updater::update (const ::Deployment::PackagedComponentImplementation &pci) + { + PC_Updater::update (pci.referencedImplementation); + } + + // ComponentPackageDescription + + void PC_Updater::update (const ::Deployment::ComponentPackageDescription &comppkgdesc) + { + update_sequence (comppkgdesc.implementation, this); + } + + + // Property + void PC_Updater::update (const Deployment::Property& property) + { + } diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.h b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.h new file mode 100644 index 00000000000..8833f6ec6f3 --- /dev/null +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater.h @@ -0,0 +1,109 @@ +//================================================================== +/** + * file PC_Updater.h + * + * $Id$ + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//===================================================================== + +#ifndef PC_UPDATER_H +#define PC_UPDATER_H +#include /**/ "ace/pre.h" + +#include "ciao/DeploymentC.h" +#include "ace/SString.h" //for the ACE_CString + +#include "ZIP_Wrapper.h" //Wrapper around zzip +#include "ace/Containers_T.h" //for ACE_Double_Linked_List +#include "ace/Malloc_Allocator.h" //for ACE_New_Allocator needed by the doubly link list + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + + /** + * class PC_Updater + * + * This class defines a set of overloaded methods used to update + * the contents of a PackageConfiguration. More specifically the class + * goes through the PackageConfiguration and updates the locations of the + * artifacts, wrt to their location on the HTTP server. + */ + +class PC_Updater +{ +public: + + ///constructors + + PC_Updater (const char* server_path, const char* package); + PC_Updater (ACE_CString& server_path, ACE_CString& package); + + ~PC_Updater (); + + /// A whole slew of overloaded routines for different IDL + /// data types part of the PackageConfiguration. + + bool update (const ::Deployment::PackageConfiguration &pc); + + void update (const ::Deployment::Property &property); + + void update (const ::Deployment::AssemblyConnectionDescription &acd); + + void update (const ::Deployment::AssemblyPropertyMapping &apm); + + void update (const ::Deployment::ComponentPackageDescription &comppkgdesc); + + void update (const ::Deployment::MonolithicImplementationDescription &mid); + + void update (const ::Deployment::PackagedComponentImplementation &pci); + + void update (const ::Deployment::SubcomponentPortEndpoint &spe); + + void update (const ::Deployment::Requirement &requirement); + + void update (const ::Deployment::ComponentExternalPortEndpoint &cepe); + + void update (const ::Deployment::ComponentPackageReference &cpr); + + void update (const ::Deployment::ComponentImplementationDescription &cid); + + void update (const ::Deployment::SubcomponentInstantiationDescription &sid); + + void update (const ::Deployment::NamedImplementationArtifact &named_implementation); + + void update (const ::Deployment::ComponentInterfaceDescription &cid); + + void update (const ::Deployment::Capability &capability); + + void update (const ::Deployment::ImplementationArtifactDescription &iad); + + void update (const ::Deployment::ImplementationRequirement &ir); + + void update(const Deployment::ImplementationDependency &id); + + void update (const ::Deployment::ComponentAssemblyDescription& cad); + +protected: + + void clear_list (); + +private: + + ACE_CString server_path_; + + //create a doubly link list + ACE_New_Allocator allocator_; + ACE_Double_Linked_List<ZIP_File_Info> file_list_; + + ACE_CString package_; + bool success_; +}; + +#include /**/ "ace/post.h" + +#endif /* PC_UPDATER_H */ diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.cpp b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.cpp new file mode 100644 index 00000000000..4bd4de11c67 --- /dev/null +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.cpp @@ -0,0 +1,22 @@ +// $Id$ +#ifndef PC_UPDATER_T_C +#define PC_UPDATER_T_C +#include "PC_Updater.h" +#include "PC_Updater_T.h" + + namespace PC_Updater_T + { + // Dumps a sequence + template <typename SEQUENCE> + void update_sequence (const SEQUENCE &seq, PC_Updater* updater) + { + CORBA::ULong size = seq.length (); + + if (size != 0) + for (CORBA::ULong i = 0; i < size; ++i) + updater->update (seq[i]); + } + + } + +#endif /* PC_Updater_C */ diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.h b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.h new file mode 100644 index 00000000000..d2c7e9cb836 --- /dev/null +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/PC_Updater_T.h @@ -0,0 +1,38 @@ +//================================================================== +/** + * file PC_Updater_T.h + * + * $Id$ + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//===================================================================== + +#ifndef CIAO_CONFIG_HANDLERS_PC_UPDATER_T_H +#define CIAO_CONFIG_HANDLERS_PC_UPDATER_T_H +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + namespace PC_Updater_T + { + template <typename SEQUENCE> + static void update_sequence (const SEQUENCE &seq); + } + + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "PC_Updater_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("PC_Updater_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" +#endif /*CIAO_CONFIG_HANDLERS_PC_Updater_T_H*/ diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.cpp b/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.cpp index 16126713a46..6a11484261f 100644 --- a/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.cpp +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.cpp @@ -25,36 +25,42 @@ #include "Config_Handlers/STD_PC_Intf.h" #include "Config_Handlers/Deployment.hpp" #include "ciao/Deployment_DataC.h" +#include "ciao/Packaging_DataC.h" #include "Config_Handlers/XML_Helper.h" #include "xercesc/dom/DOM.hpp" #include "RM_Helper.h" //to be able to externalize/internalize a PackageConfiguration -#include "tao/CDR.h" //for TAO CDR classes #include "ace/Message_Block.h" //for ACE_Message_Block #include "ace/Thread.h" //for obtaining the ID of the current thread #include "ace/OS_NS_stdlib.h" //for itoa () +#include "URL_Parser.h" //for parsing the URL +#include "HTTP_Client.h" //the HTTP client class to downloading packages -#include "URL_Parser.h" -#include "HTTP_Client.h" - +#include "PC_Updater.h" //A visitor class to walk through the elements of the PC #include <iostream> using namespace std; // Implementation skeleton constructor -CIAO_RepositoryManagerDaemon_i::CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb) -: the_orb_ (CORBA::ORB::_duplicate (the_orb)) +CIAO_RepositoryManagerDaemon_i::CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb, const char* server) +: the_orb_ (CORBA::ORB::_duplicate (the_orb)), + install_root_ (""), + HTTP_server_ (server) { //create directory in which the packages will be stored - ACE_OS::mkdir(RM_STORAGE_PATH); + ACE_OS::mkdir(INSTALL_PATH); //if dir already exists a -1 is returned //we ignore this, just need to make sure the directory exists ACE_OS::getcwd (this->cwd_, TEMP_LEN); + + this->install_root_ = this->cwd_; + this->install_root_ += "/"; + this->install_root_ += INSTALL_PATH; } // Implementation skeleton destructor @@ -100,19 +106,21 @@ void CIAO_RepositoryManagerDaemon_i::installPackage ( //NOTE: I need the absolute path because I will change to a subdirectory //when I am parsing the descriptors - ACE_CString path (this->cwd_); - path += "/"; - path += RM_STORAGE_PATH; + ACE_CString path (this->install_root_); path += "/"; path += installationName; - ACE_CString pc_path (path); ACE_CString package_path (path); - package_path += ".cpk"; //package extension + + ACE_CString pc_path (path); pc_path += PC_EXTENSION; //external PackageConfiguration extension + ACE_CString descriptor_dir (path); + descriptor_dir += "/descriptors/"; //location of the descriptor directory + + //check if URL or local file //download or load into memory @@ -137,7 +145,6 @@ void CIAO_RepositoryManagerDaemon_i::installPackage ( { mb->release (); client.close (); - cout << "open\n"; ACE_THROW (CORBA::INTERNAL ()); } @@ -146,7 +153,6 @@ void CIAO_RepositoryManagerDaemon_i::installPackage ( { mb->release (); client.close (); - cout << "read\n"; ACE_THROW (CORBA::INTERNAL ()); } @@ -182,17 +188,42 @@ void CIAO_RepositoryManagerDaemon_i::installPackage ( } + ZIP_Wrapper::uncompress (const_cast<char*> (package_path.c_str ()), + const_cast<char*> (this->install_root_.c_str ()), + false //not verbose + ); + //Start the parsing + ACE_CString pc_name; + + this->find_PC_name (const_cast<char*> (package_path.c_str ()), pc_name); + + //if the PackageConfiguration name cannot be found, then there is nothing to install + if (pc_name == "") + ACE_THROW (Deployment::PackageError ()); + + + //TODO: move exception throwing out of this func. User boolean error handling!!! + //TODO: check for errors! Deployment::PackageConfiguration_var pc; - try - { - pc = retrieve_PC( const_cast<char*> (package_path.c_str ())); - } - catch (...) //TODO: this does not work. Fix it. + pc = this->retrieve_PC_from_descriptors (const_cast<char*> (pc_name.c_str ()), + descriptor_dir.c_str ()); + + + //forming the server path info + ACE_CString server_path (this->HTTP_server_); + server_path += installationName; + server_path += "/implementations/"; + + PC_Updater updater (server_path, package_path); + + if (!updater.update (pc)) { - cout << "Some exception caugth\n"; - ACE_THROW (CORBA::INTERNAL ()); + cout << "[RM] problem updating the PackageConfiguration!\n"; + remove_extracted_package (package_path.c_str (), path.c_str ()); + remove (package_path.c_str ()); + ACE_THROW (Deployment::PackageError ()); } @@ -207,9 +238,7 @@ void CIAO_RepositoryManagerDaemon_i::installPackage ( //ALSO NEED THE UUID here this->uuids_.bind (ACE_CString (pc->UUID), path); - cout << pc->label << endl; - cout << pc->UUID << endl; - + ACE_TRACE (("Installed PackageConfiguration with: \nlabel %s \nuuid %s\n", pc->label, pc->UUID)); } void CIAO_RepositoryManagerDaemon_i::createPackage ( @@ -366,22 +395,33 @@ void CIAO_RepositoryManagerDaemon_i::deletePackage ( //actually delete the package here! - // I need to figure out how to do that without causing some race condition - bool purge = false; - if (purge) - { - ACE_CString path (RM_STORAGE_PATH); - path += "/"; - path += installationName; - path += ".cpk"; + //TODO: Check if files are ref-counted by the OS, so if I delete it here while + //some other process is still using it from a previous request, would that cause an error, + //or would it decrement the recount and delete the file when the other process is done. + // + //on that note is a file handle is not closed the file does not get deleted! , so see how + //temp files work! + + ACE_CString path (this->install_root_.c_str ()); + path += "/"; + path += installationName; - remove (path.c_str ()); - } + ACE_CString package_path (path); + package_path += ".cpk"; //package extension + + ACE_CString pc_path (path); + pc_path += PC_EXTENSION; //external PackageConfiguration extension + + remove_extracted_package (package_path.c_str (), path.c_str ()); + + remove (package_path.c_str ()); + remove (pc_path.c_str ()); } -//==========================================HELPER METHODS======================================================== +//==========================================HELPER METHODS================================================== -Deployment::PackageConfiguration* CIAO_RepositoryManagerDaemon_i::retrieve_PC (char* package) +Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::retrieve_PC_from_package (char* package) { char temp[128]; unsigned int thread_id = ACE_Thread::self (); @@ -396,9 +436,10 @@ Deployment::PackageConfiguration* CIAO_RepositoryManagerDaemon_i::retrieve_PC (c ACE_CString pcd_name; //extract the necessary descriptors - if (extract_necessary_files (package, + if (extract_descriptor_files (package, pcd_name) < 0) { + ACE_OS::chdir (this->cwd_); ACE_ERROR ((LM_ERROR, "(%P|%t) RepositoryManager: error extracting necessary files\n")); ACE_THROW (CORBA::INTERNAL ()); @@ -416,13 +457,16 @@ Deployment::PackageConfiguration* CIAO_RepositoryManagerDaemon_i::retrieve_PC (c { ACE_ERROR ((LM_ERROR, "(%P|%t) RepositoryManager: Error parsing the PCD\n")); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); ACE_THROW (Deployment::PackageError ()); } ACE_ENDTRY; //able to parse the PC. So lets install the package in the repo //we no longer need the descriptors, so lets erase them! - remove_extracted_files (package); + remove_descriptor_files (package); //change back the the old working dir ACE_OS::chdir (this->cwd_); @@ -436,6 +480,70 @@ Deployment::PackageConfiguration* CIAO_RepositoryManagerDaemon_i::retrieve_PC (c } +//function to parse and return the PackageConfiguration from the already +//extracted descriptor files +Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::retrieve_PC_from_descriptors (const char* pc_name, + const char* descriptor_dir) +{ + //change the working dir + ACE_OS::chdir (descriptor_dir); + + Deployment::PackageConfiguration_var pc; + //parse the PCD to make sure that there are no package errors + ACE_TRY + { + CIAO::Config_Handlers::STD_PC_Intf intf (pc_name); + + pc = intf.get_PC (); + } + ACE_CATCHALL + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) [RM::retrieve_PC_from_descriptors] Error parsing the PCD\n")); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + ACE_THROW (Deployment::PackageError ()); + } + ACE_ENDTRY; + //able to parse the PC. So lets install the package in the repo + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + + return pc._retn (); +} + + +//find out what the name of the PackageConfiguration file is +void CIAO_RepositoryManagerDaemon_i::find_PC_name (char* package, ACE_CString& pcd_name) +{ + pcd_name = ""; //empty the contents of the ACE_CString + + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (package, list))) + return; + + size_t skip_len = ACE_OS::strlen ("descriptors") + 1; + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + + if (ACE_OS::strstr (inf->name_.c_str (), "descriptors")) + if (ACE_OS::strstr (inf->name_.c_str (), ".pcd")) + pcd_name = inf->name_.c_str () + skip_len; + + //deallocate the head of the filename list + delete inf; + } +} + //We are using Xercesc in the Config_Handlers and unfortunately its API only //takes a file in the local file system as an argument, thus need to @@ -443,17 +551,14 @@ Deployment::PackageConfiguration* CIAO_RepositoryManagerDaemon_i::retrieve_PC (c //in the current directory. I use the thread id to guarrantee //lack of race conditions if multithreading is enabled -int CIAO_RepositoryManagerDaemon_i::extract_necessary_files (char* package, ACE_CString& pcd_name) +int CIAO_RepositoryManagerDaemon_i::extract_descriptor_files (char* package, ACE_CString& pcd_name) { - //create a ZIP wrapper - ZIP_Wrapper zip; - //create a doubly link list ACE_New_Allocator allocator; ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); //get the list of files in the package and figure out the names of all necessary files - if (!(zip.file_list_info (package, list))) + if (!(ZIP_Wrapper::file_list_info (package, list))) return 0; size_t skip_len = ACE_OS::strlen ("descriptors") + 1; @@ -469,12 +574,12 @@ int CIAO_RepositoryManagerDaemon_i::extract_necessary_files (char* package, ACE_ //extract the descriptor from the package file = new ACE_Message_Block (0,0); - if (!zip.get_file(const_cast<char*> (package), + if (!ZIP_Wrapper::get_file(const_cast<char*> (package), const_cast<char*> (inf->name_.c_str ()), *file)) { ACE_ERROR ((LM_ERROR, - "[RM::extract_necessary_files] Unable to retrieve file!\n")); + "[RM::extract_descriptor_files] Unable to retrieve file!\n")); //release the message block chain file->release (); return 0; @@ -485,7 +590,7 @@ int CIAO_RepositoryManagerDaemon_i::extract_necessary_files (char* package, ACE_ if(!RM_Helper::write_to_disk (inf->name_.c_str () + skip_len, *file)) { ACE_ERROR ((LM_ERROR, - "[RM::extract_necessary_files] Unable to write out descriptor to disk!\n")); + "[RM::extract_descriptor_files] Unable to write out descriptor to disk!\n")); //release the message block chain file->release (); return 0; @@ -502,10 +607,8 @@ int CIAO_RepositoryManagerDaemon_i::extract_necessary_files (char* package, ACE_ return 1; } -int CIAO_RepositoryManagerDaemon_i::remove_extracted_files (char* package) +int CIAO_RepositoryManagerDaemon_i::remove_descriptor_files (char* package) { - //create a ZIP wrapper - ZIP_Wrapper zip; int return_code = 1; //create a doubly link list @@ -513,7 +616,7 @@ int CIAO_RepositoryManagerDaemon_i::remove_extracted_files (char* package) ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); //get the list of files in the package and figure out the names of all necessary files - if (!(zip.file_list_info (package, list))) + if (!(ZIP_Wrapper::file_list_info (package, list))) return 0; size_t skip_len = ACE_OS::strlen ("descriptors") + 1; @@ -527,7 +630,7 @@ int CIAO_RepositoryManagerDaemon_i::remove_extracted_files (char* package) if(remove (inf->name_.c_str () + skip_len)) { ACE_ERROR ((LM_ERROR, - "[RM::remove_extracted files] Unable to write out descriptor to disk!\n")); + "[RM::remove_descriptor_files] Unable to write out descriptor to disk!\n")); return_code = 0; } } @@ -537,3 +640,66 @@ int CIAO_RepositoryManagerDaemon_i::remove_extracted_files (char* package) return return_code; } + +//function to remove the files extracted from the package upon istallation +//It reads the names of the files from the package. They correspond to the +//names on disk. It deletes each file, then it deletes the directories that +//contain them. +//return 1 on success +// 0 on error + +int CIAO_RepositoryManagerDaemon_i::remove_extracted_package + (const char* package_path, + const char* extraction_location) +{ + //change the working dir + if (ACE_OS::chdir (extraction_location) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "[RM::remove_extracted_package] Unable to chdir to doomed directory!\n"), + 0); + + int return_code = 1; + + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (const_cast <char*> (package_path), list))) + { + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + return 0; + } + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + + //delete file from disk + if(remove (inf->name_.c_str ())) + { + ACE_ERROR ((LM_ERROR, + "[RM::remove_extracted files] Unable to delete %s!\n", inf->name_.c_str ())); + return_code = 0; + } + + //deallocate the head of the filename list + delete inf; + } + + //now remove the descriptors and implementations directories. + ACE_OS::rmdir ("descriptors"); + ACE_OS::rmdir ("implementations"); + + //now go one directory up and delete the extraction directory + ACE_OS::chdir (this->install_root_.c_str ()); + ACE_OS::rmdir (extraction_location); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + + return return_code; +} + + diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.h b/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.h index 4dd8d4bb4ed..e840e47dcee 100644 --- a/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.h +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/RepositoryManager_Impl.h @@ -30,7 +30,7 @@ namespace { ///DIRECTORY WHERE THE PACKAGES WILL BE STORED LOCALLY -const static char* RM_STORAGE_PATH = "RepositoryDir"; +const static char* INSTALL_PATH = "RepositoryDir"; const static size_t TEMP_LEN = 512; @@ -41,7 +41,8 @@ class CIAO_RepositoryManagerDaemon_i : public virtual POA_CIAO::RepositoryManag { public: //Constructor - CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb); + CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb, + const char* server = "http://localhost:5432/"); //Destructor virtual ~CIAO_RepositoryManagerDaemon_i (void); @@ -131,8 +132,16 @@ public: protected: - ///function to parse and return the PackageConfiguration - Deployment::PackageConfiguration* retrieve_PC (char* package); + ///function to parse and return the PackageConfiguration from a specified package + Deployment::PackageConfiguration* retrieve_PC_from_package (char* package); + + ///find out what the name of the PackageConfiguration file is + void find_PC_name (char* package, ACE_CString& pcd_name); + + ///function to parse and return the PackageConfiguration from the already + ///extracted descriptor files + Deployment::PackageConfiguration* retrieve_PC_from_descriptors (const char* pc_name, + const char* descriptor_dir); ///function to extract all necessary files for parsing the PackageConfiguration ///descriptor and populating the idl struct. @@ -141,7 +150,7 @@ public: /// ///NOTE: ACE_CString& pcd_name is an out parameter - int extract_necessary_files (char* package, + int extract_descriptor_files (char* package, ACE_CString& pcd_name); @@ -151,8 +160,18 @@ public: ///return 1 on success /// 0 on error - int remove_extracted_files (char* package); + int remove_descriptor_files (char* package); + + + ///function to remove the files extracted from the package upon istallation + ///It reads the names of the files from the package. They correspond to the + ///names on disk. It deletes each file, then it deletes the directories that + ///contain them. + ///NOTE: extraction location is path/*archive_name*/ + ///return 1 on success + /// 0 on error + int remove_extracted_package (const char* package_path, const char* extraction_location); private: /// Cached information about the installed PackageConfigurations @@ -180,7 +199,9 @@ public: CORBA::ORB_var the_orb_; - char cwd_ [TEMP_LEN]; //will hold the current working directory + char cwd_ [TEMP_LEN]; //will hold the current working directory + ACE_CString install_root_; //full path for the install directory + ACE_CString HTTP_server_; //location of the server }; diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.cpp b/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.cpp index 046b22dc5d2..6c114759b4f 100644 --- a/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.cpp +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.cpp @@ -15,12 +15,14 @@ #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 <string> #include <memory> //for auto_ptr - ///////////////////////////////////////////////////////////////////////////// //NOTE: some #defines problems with zzip & ACE - put these 2 lines on top!!!! ///////////////////////////////////////////////////////////////////////////// @@ -157,10 +159,10 @@ bool ZIP_Wrapper::get_file (char* archive_path, char* filename, ACE_Message_Bloc //uncompress //the uncompress format will be -//mkdir(name of zip archive) -//store all files in that directory. +//mkdir(name of zip archive). //the path is assumed to be an existing directory -bool ZIP_Wrapper::uncompress (char* zip_archive, char* path) +//directory structure of archive is recreated +bool ZIP_Wrapper::uncompress (char* zip_archive, char* path, bool verbose) { ZZIP_DIR * dir; //pointer to a zip archive ZZIP_DIRENT * dir_entry; //pointer to a file within the archive @@ -178,10 +180,21 @@ bool ZIP_Wrapper::uncompress (char* zip_archive, char* path) //?????? //get the name of the archive - std::string arch_dir (path); + ACE_CString arch_dir (path); arch_dir += "/"; - arch_dir += zip_archive; - arch_dir[arch_dir.length () - 4] = '\0'; //NOTE: Assumes .zip or cpk extension + + //get only the name of the archive; remove path info + char* n = ACE_OS::strstr (zip_archive, "/"); + char* zip_name = 0; + while (n != NULL) + { + 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 ACE_OS::mkdir(arch_dir.c_str()); //if dir exists -1 is returned and ignored @@ -193,8 +206,26 @@ bool ZIP_Wrapper::uncompress (char* zip_archive, char* path) char* name = dir_entry->d_name; //remove the subpath part if any NOTE: Lunux style assumed, need to check - while(char* next = strstr(name, "/")) - name = next + 1; + + //let's try to create the directory structure for the package + char dir_name [2048]; + char* next = ACE_OS::strstr (name, "/"); + while (next != NULL) + { + ACE_CString location (arch_dir); + ACE_OS::strncpy (dir_name, name, next - name + 1); + dir_name[next - name + 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, "/"); + } //open a zip handle file = zzip_file_open(dir, dir_entry->d_name, O_RDONLY | O_BINARY); @@ -203,7 +234,8 @@ bool ZIP_Wrapper::uncompress (char* zip_archive, char* path) //allocate buffer - //TODO: change to ACE_NEW_RETURN + //std::auto_ptr releases the memory upon reset. + //ACE_Auto_Ptr does not support this functionality std::auto_ptr<char> buffer; buffer.reset ( new char [dir_entry->st_size + 1]); @@ -219,31 +251,35 @@ bool ZIP_Wrapper::uncompress (char* zip_archive, char* path) file_path += name; //print out the file to be uncompressed - ACE_OS::write(ACE_STDOUT, file_path.c_str (), file_path.length () ); - ACE_OS::write(ACE_STDOUT, "\n", 1); + 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) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("%p\n"), - ACE_TEXT ("[uncompress] file creation error")), - 0); + { + zzip_closedir(dir); + 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), dir_entry->st_size) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("%p\n"), - ACE_TEXT ("[uncompress] file write error")), - 0); + { + zzip_closedir(dir); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[uncompress] file write error")), + 0); + } // Close the file handle ACE_OS::close (handle); - - //free buffer - //TODO: check if auto_ptr has a fxn to release the memory before scope is exited - //delete [] buffer; - } zzip_closedir(dir); diff --git a/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.h b/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.h index d25e23e5331..cb0e7e8752d 100644 --- a/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.h +++ b/TAO/CIAO/DAnCE/spec_RepositoryManager/ZIP_Wrapper.h @@ -14,6 +14,7 @@ #include "ace/Containers_T.h" //for ACE_Double_Linked_List #include "ace/Message_Block.h" //for ACE_Message_Block +#include "ace/SString.h" //for ACE_CString #include "ace/OS_NS_fcntl.h" //for open #include "ace/OS_NS_sys_stat.h" //for filesize and mkdir @@ -29,7 +30,7 @@ class ZIP_File_Info { public: - std::string name_; + ACE_CString name_; size_t size_; ZIP_File_Info* next_; ZIP_File_Info* prev_; @@ -51,24 +52,24 @@ class ZIP_Wrapper public: //get a list of the files in the archive - size_t file_list_info (char* zip_name, ACE_Double_Linked_List<ZIP_File_Info> &list); + static size_t file_list_info (char* zip_name, ACE_Double_Linked_List<ZIP_File_Info> &list); //get file and store it into an ACE_Message_Block //need to provide the correct accessor string. It formed by the ZIP_Options //singleton on argument parsing and stored in ZIP_Options::instance()->read_file_ //ACE_Message_Block is null-terminated, but this is not reflected in the size! - bool get_file (char* accessor, ACE_Message_Block &file); + static bool get_file (char* accessor, ACE_Message_Block &file); //additional get_file function to avert subdirectory traversal problems with //zziplib accessors - bool get_file (char* archive_path, char* filename, ACE_Message_Block &file); + static bool get_file (char* archive_path, char* filename, ACE_Message_Block &file); //uncompress //the uncompress format will be //mkdir(name of zip archive) //store all files in that directory. //the path is assumed to be an existing directory - bool uncompress (char* zip_archive, char* path = ""); + static bool uncompress (char* zip_archive, char* path = "", bool verbose = true); }; #endif |