summaryrefslogtreecommitdiff
path: root/CIAO/DAnCE/RepositoryManager
diff options
context:
space:
mode:
Diffstat (limited to 'CIAO/DAnCE/RepositoryManager')
-rw-r--r--CIAO/DAnCE/RepositoryManager/Options.cpp147
-rw-r--r--CIAO/DAnCE/RepositoryManager/Options.h93
-rw-r--r--CIAO/DAnCE/RepositoryManager/PC_Updater.cpp256
-rw-r--r--CIAO/DAnCE/RepositoryManager/PC_Updater.h113
-rw-r--r--CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp20
-rw-r--r--CIAO/DAnCE/RepositoryManager/PC_Updater_T.h40
-rw-r--r--CIAO/DAnCE/RepositoryManager/README46
-rw-r--r--CIAO/DAnCE/RepositoryManager/RM_Helper.cpp265
-rw-r--r--CIAO/DAnCE/RepositoryManager/RM_Helper.h81
-rw-r--r--CIAO/DAnCE/RepositoryManager/RMadmin.cpp249
-rw-r--r--CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp279
-rw-r--r--CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc53
-rw-r--r--CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl13
-rw-r--r--CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp1226
-rw-r--r--CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h249
-rw-r--r--CIAO/DAnCE/RepositoryManager/URL_Parser.cpp101
-rw-r--r--CIAO/DAnCE/RepositoryManager/URL_Parser.h66
-rw-r--r--CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp375
-rw-r--r--CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h117
19 files changed, 3789 insertions, 0 deletions
diff --git a/CIAO/DAnCE/RepositoryManager/Options.cpp b/CIAO/DAnCE/RepositoryManager/Options.cpp
new file mode 100644
index 00000000000..a9fd5a67d3d
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/Options.cpp
@@ -0,0 +1,147 @@
+// $Id$
+
+// Options.cpp,v Stoyan
+
+#include "ace/Get_Opt.h"
+#include "ace/ARGV.h"
+#include "Options.h"
+
+
+bool
+Options::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("ov:n:l:u:t:icfdsTNa"));
+
+ int c;
+
+ while ((c = get_opt ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ this->write_to_ior_ = true;
+ this->register_with_ns_ = false;
+ break;
+ case 'v':
+ this->write_to_ior_ = false;
+ this->register_with_ns_ = true;
+ this->repoman_name_ = get_opt.opt_arg ();
+ break;
+ case 'i':
+ this->install_ = true;
+ break;
+ case 'c':
+ this->create_ = true;
+ break;
+ case 'd':
+ this->delete_ = true;
+ break;
+ case 'f':
+ this->find_ = true;
+ break;
+ case 's':
+ this->shutdown_ = true;
+ break;
+ case 'n':
+ this->name_ = get_opt.opt_arg ();
+ break;
+ case 'l':
+ this->path_ = get_opt.opt_arg ();
+ break;
+ case 'u':
+ this->uuid_ = get_opt.opt_arg ();
+ break;
+ case 'N':
+ this->all_names_ = true;
+ break;
+ case 'T':
+ this->all_types_ = true;
+ break;
+ case 't':
+ this->names_by_type_ = true;
+ this->type_ = get_opt.opt_arg ();
+ break;
+ // Usage fallthrough.
+ default:
+ this->usage ();
+ return false;
+ }
+
+ if ((this->name_ == "")
+ && (this->shutdown_ == false)
+ && (this->uuid_ == "")
+ && (this->all_names_ == false)
+ && (this->all_types_ == false)
+ && (this->names_by_type_ == false))
+ {
+ this->usage ();
+ return false;
+ }
+ else if (this->name_ != "")
+ {
+ if (!(this->install_ || this->create_ || this->find_ || this->delete_))
+ {
+ this->usage ();
+ return false;
+ }
+ else if (this->install_ && this->path_ == "")
+ {
+ this->usage ();
+ return false;
+ }
+ else if (this->create_ && this->path_ == "")
+ {
+ this->usage ();
+ return false;
+ }
+ }
+ else if (this->uuid_ != "")
+ {
+ if (!this->find_)
+ {
+ this->usage ();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/// @todo Exit is not nice, return -1 so that the caller can do something and
+/// we don't exit abruptly
+void Options::usage (void)
+{
+ ACE_DEBUG ((LM_INFO, "OPTIONS: \n\
+ -o <using ior file> \n\
+ -v <: name of naming service> \n\
+ -s <shutdown> \n\
+ -n <:name> \n\
+ [-i <install> -l <:path>] \n\
+ [-c <create> -l <:path>] \n\
+ [-d <delete>] \n\
+ [-f <find>] \n\
+ -u <:uuid> \n\
+ [-f <find>] \n\
+ -a <names by type> \n\
+ [-t <:type>] \n\
+ -N <all names> \n\
+ -T <all types> \n"));
+}
+
+Options::Options (void)
+ : name_ (""),
+ uuid_ (""),
+ type_ (""),
+ path_ (""),
+ delete_ (false),
+ install_ (false),
+ create_ (false),
+ find_ (false),
+ all_names_ (false),
+ all_types_ (false),
+ names_by_type_ (false),
+ shutdown_ (false),
+ register_with_ns_ (false),
+ write_to_ior_ (true),
+ repoman_name_ ("")
+{
+}
diff --git a/CIAO/DAnCE/RepositoryManager/Options.h b/CIAO/DAnCE/RepositoryManager/Options.h
new file mode 100644
index 00000000000..845e339cedd
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/Options.h
@@ -0,0 +1,93 @@
+// $Id$
+
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Options.h
+ *
+ * $Id$
+ *
+ * TheOptions is an Options class wrapped into an ACE_Singleton
+ * with Null_Mutex because the client is single-threaded.
+ *
+ *
+ * @author Stoyan Paunov
+ */
+//=============================================================================
+
+
+#ifndef RM_OPTIONS_H
+#define RM_OPTIONS_H
+
+#include "ace/Get_Opt.h"
+#include "ace/SString.h" //for ACE_CString
+#include "ace/Singleton.h" //for ACE_Singleton
+#include "ace/Null_Mutex.h" //for ACE_Null_Mutex
+
+//forward declaration
+class Options;
+
+typedef ACE_Singleton <Options, ACE_Null_Mutex> TheOptions;
+
+class Options
+{
+public:
+
+ ///constructor
+ Options (void);
+
+ /// parses commandline arguments
+ bool parse_args (int argc, ACE_TCHAR *argv[]);
+
+ /// Name of package
+ ACE_CString name_;
+
+ /// Name of package
+ ACE_CString uuid_;
+
+ /// Type of package
+ ACE_CString type_;
+
+ /// specifies the local path for install
+ ACE_CString path_;
+
+ /// delete the name_
+ bool delete_;
+
+ /// installs the name_
+ bool install_;
+
+ /// creates the name_
+ bool create_;
+
+ /// finds the name_
+ bool find_;
+
+ /// get all Names
+ bool all_names_;
+
+ /// get all types
+ bool all_types_;
+
+ /// find all names by type
+ bool names_by_type_;
+
+ /// shutdown the RepositoryManagerDemon
+ bool shutdown_;
+
+ // use naming service
+ bool register_with_ns_;
+
+ // use ior file
+ bool write_to_ior_;
+
+ // Name of RepoMan
+ ACE_CString repoman_name_;
+
+protected:
+ //usage function
+ void usage (void);
+};
+
+#endif /* RM_OPTIONS_H */
diff --git a/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp b/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp
new file mode 100644
index 00000000000..1acd3d8c4b9
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp
@@ -0,0 +1,256 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "DAnCE/Deployment/Deployment_DataC.h"
+#include "PC_Updater.h"
+#include "PC_Updater_T.h"
+#include "ace/Containers_T.h" //for ACE_Double_Linked_List
+
+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_ (),
+ package_ (package),
+ success_ (true)
+{
+}
+
+
+PC_Updater::PC_Updater (ACE_CString& server_path, ACE_CString& package)
+: server_path_ (server_path),
+ file_list_ (),
+ 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 (::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 (::Deployment::ComponentInterfaceDescription &)
+ {
+ }
+
+ // Requirement
+
+ void PC_Updater::update (::Deployment::Requirement &)
+ {
+ }
+
+
+ // ComponentExternalPortEndpoint
+
+ void PC_Updater::update (::Deployment::ComponentExternalPortEndpoint &)
+ {
+ }
+
+
+
+ // ImplementationDependency
+
+ void PC_Updater::update (Deployment::ImplementationDependency &)
+ {
+ }
+
+ // ComponentPackageReference
+
+ void PC_Updater::update (::Deployment::ComponentPackageReference &)
+ {
+ }
+
+ // SubcomponentInstantiationDescription
+
+ void PC_Updater::update (::Deployment::SubcomponentInstantiationDescription &sid)
+ {
+ update_sequence (sid.basePackage, this);
+ }
+
+ // SubcomponentPortEndpoint
+
+ void PC_Updater::update (::Deployment::SubcomponentPortEndpoint& )
+ {
+ }
+
+ // AssemblyConnectionDescription
+
+ void PC_Updater::update (::Deployment::AssemblyConnectionDescription &)
+ {
+ }
+
+
+ // AssemblyPropertyMapping
+
+ void
+ PC_Updater::update (::Deployment::AssemblyPropertyMapping &)
+ {
+ }
+
+ // ComponentAssemblyDescription
+
+ void PC_Updater::update (::Deployment::ComponentAssemblyDescription& cad)
+ {
+ update_sequence (cad.instance, this);
+ }
+
+ // ImplementationArtifactDescription
+
+ void PC_Updater::update (::Deployment::ImplementationArtifactDescription &iad)
+ {
+ const char* location = CORBA::string_dup (iad.location[0]);
+
+ //create an iterator
+ ACE_Double_Linked_List_Iterator<ZIP_File_Info> iter (this->file_list_);
+
+ //find the correct path and return
+ while (!iter.done ())
+ {
+ const char* full_path = iter.next ()->name_.c_str ();
+ //weird. Need to call next to get current ?!?!
+
+ //is it an implementation artifact?
+ const char* name = ACE_OS::strstr (full_path, "implementations/");
+ if (name)
+ {
+ //now check if the name matches
+ name = ACE_OS::strstr (full_path, iad.location[0]);
+
+ if (name)
+ {
+ ACE_CString loc (this->server_path_);
+ loc += "/implementations/";
+ loc += location;
+
+ iad.location[0] = CORBA::string_dup (loc.c_str ());
+
+ //cout << "Location after update: " << iad.location[0] << endl << endl;
+ return;
+ }
+ }
+ iter++;
+ }
+
+ ACE_ERROR ((LM_ERROR,
+ "[PC_Updater::update] Unable to update: %s!\n",
+ location));
+
+ this->success_ = false;
+ }
+
+ // NamedImplementationArtifact
+
+ void PC_Updater::update (::Deployment::NamedImplementationArtifact &nia)
+ {
+ update (nia.referencedArtifact);
+ }
+
+ // ImplementationRequirement
+ void PC_Updater::update (::Deployment::ImplementationRequirement &)
+ {
+ }
+
+ // MonolithicImplementationDescription
+ void PC_Updater::update (::Deployment::MonolithicImplementationDescription &mid)
+ {
+ update_sequence (mid.primaryArtifact, this);
+ }
+
+ // Capability
+ void PC_Updater::update (::Deployment::Capability &)
+ {
+ }
+
+ // ComponentImplementationDescription
+ void PC_Updater::update (::Deployment::ComponentImplementationDescription &cid)
+ {
+ update_sequence (cid.assemblyImpl, this);
+ update_sequence (cid.monolithicImpl, this);
+ }
+
+ // PackagedComponentImplementation
+ void PC_Updater::update (::Deployment::PackagedComponentImplementation &pci)
+ {
+ PC_Updater::update (pci.referencedImplementation);
+ }
+
+ // ComponentPackageDescription
+ void PC_Updater::update (::Deployment::ComponentPackageDescription &comppkgdesc)
+ {
+ update_sequence (comppkgdesc.implementation, this);
+ }
+
+
+ // Property
+ void PC_Updater::update (Deployment::Property& )
+ {
+ }
diff --git a/CIAO/DAnCE/RepositoryManager/PC_Updater.h b/CIAO/DAnCE/RepositoryManager/PC_Updater.h
new file mode 100644
index 00000000000..5b22e249331
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/PC_Updater.h
@@ -0,0 +1,113 @@
+
+/* -*- C++ -*- */
+
+//========================================================================
+/**
+ * file PC_Updater.h
+ *
+ * $Id$
+ *
+ * This class is used to update the location field of the implementation
+ * artifacts in the PackageConfiguration, so that they point to the
+ * physical libraries on the collocated HTTP server
+ *
+ * author Stoyan Paunov <spaunov@isis.vanderbilt.edu>
+ */
+//========================================================================
+
+#ifndef PC_UPDATER_H
+#define PC_UPDATER_H
+#include /**/ "ace/pre.h"
+
+#include "DAnCE/Deployment/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 (::Deployment::PackageConfiguration &pc);
+
+ void update (::Deployment::Property &property);
+
+ void update (::Deployment::AssemblyConnectionDescription &acd);
+
+ void update (::Deployment::AssemblyPropertyMapping &apm);
+
+ void update (::Deployment::ComponentPackageDescription &comppkgdesc);
+
+ void update (::Deployment::MonolithicImplementationDescription &mid);
+
+ void update (::Deployment::PackagedComponentImplementation &pci);
+
+ void update (::Deployment::SubcomponentPortEndpoint &spe);
+
+ void update (::Deployment::Requirement &requirement);
+
+ void update (::Deployment::ComponentExternalPortEndpoint &cepe);
+
+ void update (::Deployment::ComponentPackageReference &cpr);
+
+ void update (::Deployment::ComponentImplementationDescription &cid);
+
+ void update (::Deployment::SubcomponentInstantiationDescription &sid);
+
+ void update (::Deployment::NamedImplementationArtifact &named_implementation);
+
+ void update (::Deployment::ComponentInterfaceDescription &cid);
+
+ void update (::Deployment::Capability &capability);
+
+ void update (::Deployment::ImplementationArtifactDescription &iad);
+
+ void update (::Deployment::ImplementationRequirement &ir);
+
+ void update (::Deployment::ImplementationDependency &id);
+
+ void update (::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/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp b/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp
new file mode 100644
index 00000000000..a5f5ec5fb2e
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp
@@ -0,0 +1,20 @@
+// $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 (SEQUENCE &seq, PC_Updater* updater)
+ {
+ CORBA::ULong const size = seq.length ();
+
+ for (CORBA::ULong i = 0; i < size; ++i)
+ updater->update (seq[i]);
+ }
+}
+
+#endif /* PC_Updater_C */
diff --git a/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h b/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h
new file mode 100644
index 00000000000..0696c685e2b
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h
@@ -0,0 +1,40 @@
+
+/* -*- C++ -*- */
+
+//==================================================================
+/**
+ * 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 (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/CIAO/DAnCE/RepositoryManager/README b/CIAO/DAnCE/RepositoryManager/README
new file mode 100644
index 00000000000..322b00098ac
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/README
@@ -0,0 +1,46 @@
+This is the README file for the Repository Manager (RM).
+
+Building RM:
+In order to be able to compile the RM you need to have ZLIB lib because the RM
+uses it to read the contents of CCM packages. In order to compile the RM
+successfully you will need to do the following:
+1.Download the binary version of ZLIB or build it yourself
+3.Create an "include" and a "lib" subdirectory. Then copy the libraries files into
+ the "lib" subdirectory and copy zlib.h into the "include" subdirectory.
+4.Set $ZLIB_ROOT to point to the directories where you placed the libraries and
+ the include files.
+5.Turn on zzip and zlib in default.features for MPC.
+6.MPC will handle the rest.
+
+If you want to get the component package through http server:
+1.Be sure to set JAWS_DOCUMENT_ROOT to the installation path of the RepoMan, i.e., $CIAO_ROOT/DAnCE/RepositoryManager.
+2.Start JAWS: $ACE_ROOT/apps/JAWS/server/main
+
+Start RM:
+1.Using ior file:
+ RepositoryManagerDaemon -o
+2.Using Naming Service:
+ RepositoryManagerDaemon -v [NameofRM]
+
+Using RMadmin:
+1.Install component package: (use BasicSP for example)
+ Be sure you have BasicSP.cpk in the $CIAO_ROOT/DAnCE/RepositoryManager/packages
+ > RMadmin -o -n BasicSP -i -l packages/BasicSP.cpk
+ or
+ > RMadmin -o -n BasicSP -i -l http://127.0.0.1:5432/packages/BasicSP.cpk (If the JAWS is started)
+ This will create the BasicSP directory, BasicSP.cpk file and BasicSP.epc file in the
+ $CIAO_ROOT/DAnCE/RepositoryManager/RepositoryManager/
+2.Delete component package: (use BasicSP for example)
+ > RMadmin -o -n BasicSP -d
+3.Find component package by its name: (use BasicSP for example)
+ > RMadmin -o -n BasicSP -f
+4.Stop RM:
+ > RMadmin -o -s
+ This will create the RM_record file in the $CIAO_ROOT/DAnCE/RepositoryManager/RepositoryManager/ which record the
+ names and UUIDs of the installed component packages.
+
+
+
+
+
+
diff --git a/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp b/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp
new file mode 100644
index 00000000000..cd4b92669d0
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp
@@ -0,0 +1,265 @@
+// $Id$
+
+#include "RM_Helper.h"
+#include "ace/Auto_Ptr.h" //for Auto_Ptr
+#include "ace/OS_NS_fcntl.h" //for open
+#include "ace/OS_NS_unistd.h" //for close
+#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir
+#include "ace/OS_NS_string.h"
+
+
+void
+RM_Helper::pc_to_cdr (const Deployment::PackageConfiguration& pc, TAO_OutputCDR& cdr)
+{
+ cdr << pc;
+}
+
+
+void
+RM_Helper::cdr_to_pc (Deployment::PackageConfiguration& pc, TAO_InputCDR& cdr)
+{
+ cdr >> pc;
+}
+
+
+bool
+RM_Helper::externalize (const Deployment::PackageConfiguration& pc, const char* path)
+{
+ size_t bufsiz = 0;
+ TAO_OutputCDR out (bufsiz);
+
+ RM_Helper::pc_to_cdr (pc, out);
+
+ const ACE_Message_Block* mb = out.begin ();
+
+ return write_pc_to_disk (path, *(const_cast<ACE_Message_Block*> (mb)));
+}
+
+
+bool
+RM_Helper::reincarnate (Deployment::PackageConfiguration& pc, const char* path)
+{
+ size_t length = 0;
+ ACE_Auto_Ptr<ACE_Message_Block> mb (read_pc_from_disk (path, length));
+
+ if (!mb.get ())
+ return false;
+
+ TAO_InputCDR in (mb.get ());
+
+ RM_Helper::cdr_to_pc (pc, in);
+
+ return true;
+}
+
+
+/// This function attempts to copy the file from a specified location
+/// to another specified location on the hard disk.
+bool
+RM_Helper::copy_from_disk_to_disk (const char* from_path, const char* to_path)
+{
+ if (ACE_OS::strcmp (from_path, to_path) == 0)
+ return true;
+
+ // Open the files
+ ACE_HANDLE from_handle = ACE_OS::open (from_path, O_RDONLY);
+ if (from_handle == ACE_INVALID_HANDLE)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::copy_from_disk_to_disk] file open error")),
+ 0);
+
+ ACE_stat file_info;
+ ACE_OS::fstat (from_handle, &file_info);
+ ACE_UINT64 file_length = file_info.st_size;
+
+ ACE_HANDLE to_handle = ACE_OS::open (to_path, O_CREAT | O_TRUNC | O_WRONLY);
+ if (to_handle == ACE_INVALID_HANDLE)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::copy_from_disk_to_disk] file creation error")),
+ 0);
+
+
+ // Read the contents of the file into the buffer and write the data to another file
+ ACE_Message_Block *mb = 0;
+ size_t length;
+ size_t number = 0;
+ bool last = false;
+
+ while (true)
+ {
+ if ((file_length - BUFSIZ*number) > BUFSIZ)
+ length = BUFSIZ;
+ else
+ {
+ length = static_cast<size_t> (file_length - BUFSIZ*number);
+ last = true;
+ }
+
+ mb = new ACE_Message_Block (length);
+
+ if (ACE_OS::read_n (from_handle, mb->wr_ptr (), length) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::copy_from_disk_to_disk] file read error")),
+ 0);
+
+ ++number;
+
+ mb->length (length);
+
+ for (ACE_Message_Block *curr = mb; curr != 0; curr = curr->cont ())
+ if (ACE_OS::write_n (to_handle, curr->rd_ptr (), curr->length ()) == -1)
+ {
+ mb->release ();
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::copy_from_disk_to_disk] file write error")),
+ 0);
+ }
+
+ mb->release ();
+
+ if (last)
+ break;
+ }
+
+ // Close the files
+ ACE_OS::close (from_handle);
+ ACE_OS::close (to_handle);
+
+ return true;
+}
+
+
+/// This function attempts to write a sequence of bytes from an
+/// ACE_Message_Block to a specified location. A 0 is returned
+/// in the case of an error and a 1 upon success
+bool RM_Helper::write_to_disk (
+ const char* full_path,
+ ACE_Message_Block& mb,
+ bool replace
+ )
+{
+ ACE_stat stat;
+
+ if (ACE_OS::stat(full_path, &stat) != -1 && !replace)
+ return false;
+
+ // Open a file handle to the local filesystem
+ ACE_HANDLE handle = ACE_OS::open (full_path, O_CREAT | O_TRUNC | O_WRONLY);
+ if (handle == ACE_INVALID_HANDLE)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::write_to_disk] file creation error")),
+ false);
+
+ // Write the data to the file
+ for (ACE_Message_Block * curr = &mb; curr != 0; curr = curr->cont ())
+ if (ACE_OS::write_n (handle, curr->rd_ptr(), curr->length()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("write error")),
+ false);
+
+ // Close the file handle
+ ACE_OS::close (handle);
+
+ return true;
+}
+
+
+/// This function attempts to write a sequence of bytes from an
+/// ACE_Message_Block to a specified location. A 0 is returned
+/// in the case of an error and a 1 upon success
+///
+/// @note This function write the contents in a way that preserves the
+/// structure of the ACE_Message_Block. It is relevant for
+/// PackageConfigurations ONLY
+bool RM_Helper::write_pc_to_disk (
+ const char* full_path,
+ ACE_Message_Block& mb,
+ bool replace
+ )
+{
+ ACE_stat stat;
+
+ if (ACE_OS::stat(full_path, &stat) != -1 && !replace)
+ return false;
+
+ // Open a file handle to the local filesystem
+ ACE_HANDLE const handle = ACE_OS::open (full_path, O_CREAT | O_TRUNC | O_WRONLY);
+ if (handle == ACE_INVALID_HANDLE)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::write_to_disk] file creation error")),
+ false);
+
+ // write the data to the file
+ for (ACE_Message_Block * curr = &mb; curr != 0; curr = curr->cont ())
+ if (ACE_OS::write_n (handle, curr->rd_ptr(), curr->length()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("write error")),
+ 0);
+
+ // Close the file handle
+ ACE_OS::close (handle);
+
+ return true;
+}
+
+
+/// Function to read the contents of a file from disk into an ACE_Message_Block
+/// returns a pointer to an ACE_Message_Block and updates the lenght on success
+/// 0 on failure
+ACE_Message_Block*
+RM_Helper::read_pc_from_disk (
+ const char* full_path,
+ size_t &length
+ )
+{
+ length = 0;
+
+ // Open the file
+ ACE_HANDLE const handle = ACE_OS::open (full_path, O_RDONLY);
+ if (handle == ACE_INVALID_HANDLE)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::read_mb_from_disk] file open error")),
+ 0);
+
+ ACE_stat file_info;
+ ACE_OS::fstat (handle, &file_info);
+
+ // Get and check the length of the file
+ length = static_cast<size_t> (file_info.st_size);
+
+ ACE_INT64 check = length;
+ if (check != file_info.st_size)
+ {
+ length = 0;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::read_mb_from_disk] file length error")),
+ 0);
+ }
+
+ // Read the contents of the file into the buffer
+ ACE_Message_Block* mb = 0;
+ ACE_NEW_RETURN (mb, ACE_Message_Block (length + 1), 0);
+
+ if (ACE_OS::read_n (handle, mb->wr_ptr (), length) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("[RM::read_mb_from_disk] file read error")),
+ 0);
+
+ mb->length (length);
+
+ // Close the file handle
+ ACE_OS::close (handle);
+
+ return mb;
+}
diff --git a/CIAO/DAnCE/RepositoryManager/RM_Helper.h b/CIAO/DAnCE/RepositoryManager/RM_Helper.h
new file mode 100644
index 00000000000..47e46d35a6f
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RM_Helper.h
@@ -0,0 +1,81 @@
+
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file RM_Helper.h
+ *
+ * $Id$
+ *
+ * This class aggregates a number of helper functions used by the
+ * CIAO RepositoryManager
+ *
+ *
+ * @author Stoyan Paunov
+ */
+//=============================================================================
+
+#ifndef RM_HELPER_H_
+#define RM_HELPER_H_
+
+
+#include "DAnCE/Deployment/Deployment_Packaging_DataC.h"
+#include "tao/CDR.h"
+#include "ace/Message_Block.h"
+
+
+class RM_Helper
+{
+public:
+
+ static void pc_to_cdr (const Deployment::PackageConfiguration& pc, TAO_OutputCDR& cdr);
+
+ static void cdr_to_pc (Deployment::PackageConfiguration& pc, TAO_InputCDR& cdr);
+
+ static bool externalize (const Deployment::PackageConfiguration& pc, const char* path);
+
+ static bool reincarnate (Deployment::PackageConfiguration& pc, const char* path);
+
+ /**
+ * Function that copies the file from a specified location to another
+ * specified location on the hard disk.
+ * @retval true on success
+ * @retval false on error
+ */
+ static bool copy_from_disk_to_disk (const char* from_path, const char* to_path);
+
+ /**
+ * Function that writes out a file to a specified location on the hard disk
+ * @retval true on success
+ * @retval false on already exists and replace == false
+ * @retval false on error
+ */
+ static bool write_to_disk (const char* full_path,
+ ACE_Message_Block& mb,
+ bool replace = true
+ );
+
+ /**
+ * Function that writes out a file to a specified location on the hard disk
+ * @retval true on success
+ * @retval false on already exists and replace == false
+ * @retval 0 on error
+ * @note This function is relevant for PackageConfigurations ONLY
+ */
+ static bool write_pc_to_disk (const char* full_path,
+ ACE_Message_Block& mb,
+ bool replace = true);
+
+ /**
+ * Function to read the contents of a file from disk into an
+ * ACE_Message_Block returns a pointer to an ACE_Message_Block and updates
+ * the lenght on success
+ * @retval 0 on failure
+ */
+
+ static ACE_Message_Block* read_pc_from_disk (const char* full_path,
+ size_t &length);
+
+};
+
+#endif
diff --git a/CIAO/DAnCE/RepositoryManager/RMadmin.cpp b/CIAO/DAnCE/RepositoryManager/RMadmin.cpp
new file mode 100644
index 00000000000..f61a9f2a71e
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RMadmin.cpp
@@ -0,0 +1,249 @@
+/* -*- C++ -*- */
+
+/***
+ * file RMClient.cpp
+ *
+ * $Id$
+ *
+ * A sample client to the RepositoryManager showcasing how to use it
+ *
+ * author Stoyan Paunov <spaunov@isis.vanderbilt.edu>
+ * Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
+ **/
+
+#include "RepositoryManagerDaemonC.h"
+#include "Options.h"
+
+#include "ace/OS_NS_fcntl.h" //for open
+#include "ace/OS_NS_unistd.h" //for close
+#include "ace/OS_NS_sys_stat.h" //for filesize and fstat and mkdir
+#include "ace/streams.h"
+
+#include "Config_Handlers/DnC_Dump.h"
+
+#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 "Package_Handlers/PCD_Handler.h"
+
+#include "orbsvcs/CosNamingC.h"
+
+
+//IOR file of the RM
+static const char *ior = "file://RepositoryManagerDaemon.ior";
+
+// Name service of the RM
+static const char *RMname_service;
+
+/// main function that provides a sample interface for RM clients
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ // Initialize orb
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv,
+ "");
+
+
+ Options* options = TheOptions::instance ();
+ if (!options->parse_args (argc, argv))
+ return -1;
+
+ CORBA::Object_var obj;
+
+ if (options->write_to_ior_)
+ {
+ obj = orb->string_to_object (ior);
+ }
+
+ else if (options->register_with_ns_)
+ {
+ if (options->repoman_name_ != "")
+ RMname_service = const_cast<char*> (options->repoman_name_.c_str ());
+
+ // Naming Service related operations
+ CORBA::Object_var naming_context_object =
+ orb->resolve_initial_references ("NameService");
+
+ CosNaming::NamingContext_var naming_context =
+ CosNaming::NamingContext::_narrow (naming_context_object.in ());
+
+ // Initialize the Naming Sequence
+ CosNaming::Name name (1);
+ name.length (1);
+
+ // String dup required for MSVC6
+ name[0].id = CORBA::string_dup (RMname_service);
+
+ // Resolve object from name
+ obj = naming_context->resolve (name);
+ }
+
+
+ CIAO::RepositoryManagerDaemon_var rm =
+ CIAO::RepositoryManagerDaemon::_narrow (obj.in ());
+
+ if (CORBA::is_nil (rm.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to acquire RepositoryManagerDaemon's objref\n"),
+ -1);
+ }
+
+ if (options->shutdown_)
+ {
+ rm->shutdown ();
+ }
+ else if (options->all_names_)
+ {
+ try
+ {
+ CORBA::StringSeq_var seq = rm->getAllNames ();
+ cout << "Known Names:\n";
+ for (size_t i = 0;
+ i < seq->length ();
+ ++i)
+ cout << seq[i] << endl;
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException caught!" << ex << "\n";
+ return 0;
+ }
+ }
+ else if (options->all_types_)
+ {
+ try
+ {
+ CORBA::StringSeq_var seq = rm->getAllTypes ();
+ cout << "Known Component Interface Types:\n";
+ for (size_t i = 0;
+ i < seq->length ();
+ ++i)
+ cout << seq[i] << endl;
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException caught!" << ex << "\n";
+ return 0;
+ }
+ }
+ else if (options->type_ != "" && options->names_by_type_)
+ {
+ try
+ {
+ CORBA::StringSeq_var seq = rm->findNamesByType (options->type_.c_str ());
+ cout << "Known Component Interface Types:\n";
+ for (size_t i = 0;
+ i < seq->length ();
+ ++i)
+ cout << seq[i] << endl;
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException caught!" << ex << "\n";
+ return 0;
+ }
+ }
+ else if (options->install_)
+ {
+ try
+ {
+ rm->installPackage (options->name_.c_str (), options->path_.c_str (), false);
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException caught!" << ex << "\n";
+ return 0;
+ }
+
+ cout << "\nReassuring that the package in the repository ..." << endl;
+ try
+ {
+ Deployment::PackageConfiguration_var pc = rm->findPackageByName (options->name_.c_str ());
+ cout << "The package was found!" << endl;
+ cout << "Label: " << pc->label << endl;
+ cout << "UUID: " << pc->UUID << endl;
+ }
+ catch (CORBA::Exception &)
+ {
+ cout << "\nError! Package not found!" << endl;
+ }
+ }
+ else if (options->create_)
+ {
+ try
+ {
+ // Change the working dir.
+ char cwd [1024];
+ ACE_OS::getcwd (cwd, 1024);
+ ACE_CString descriptor_dir (cwd);
+ descriptor_dir += "/packageDescriptors/RACE/descriptors/";
+ ACE_OS::chdir (descriptor_dir.c_str ());
+
+ Deployment::PackageConfiguration *pc = new Deployment::PackageConfiguration ();
+
+ // Parse the PCD to make sure that there are no package errors.
+ try
+ {
+ CIAO::Config_Handlers::Packaging::PCD_Handler::package_config ("default.pcd", *pc);
+ }
+ catch (...)
+ {
+ ACE_ERROR ((
+ LM_ERROR,
+ "(%P|%t) [RM::retrieve_PC_from_descriptors] Error parsing the PCD\n"));
+
+ throw Deployment::PackageError ();
+ }
+
+ ACE_OS::chdir (cwd);
+
+ rm->createPackage (options->name_.c_str (), *pc, options->path_.c_str (), false);
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException caught!" << ex << "\n";
+ return 0;
+ }
+ }
+ else if (options->delete_)
+ {
+ try
+ {
+ rm->deletePackage (options->name_.c_str ());
+ cout << options->name_.c_str () << " deleted" << endl;
+ }
+ catch (CORBA::Exception & ex)
+ {
+ cout << "\nException: " << ex << endl;
+ }
+
+ }
+ else if (options->find_)
+ {
+ if (options->name_ != "")
+ {
+ Deployment::PackageConfiguration_var pc = rm->findPackageByName (options->name_.c_str ());
+ cout << "The package was found!" << endl;
+ //Deployment::DnC_Dump::dump (pc);
+ }
+ else
+ {
+ Deployment::PackageConfiguration_var pc = rm->findPackageByUUID (options->uuid_.c_str ());
+ cout << "The package was found!" << endl;
+ //Deployment::DnC_Dump::dump (pc);
+ }
+ }
+
+ orb->shutdown (1);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Unknown exception \n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp b/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp
new file mode 100644
index 00000000000..5cefc3467c9
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp
@@ -0,0 +1,279 @@
+
+/* -*- C++ -*- */
+
+//======================================================================
+/**
+ * @file RepositoryManager.cpp
+ *
+ * $Id$
+ *
+ * Description:
+ * Main driver program for the CIAO RepositoryManager
+ * Please run as follows:
+ * RepositoryManagerDaemon [int:nthreads]
+ *
+ * @author Stoyan Paunov
+ */
+//======================================================================
+
+#include "RepositoryManager_Impl.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/streams.h"
+#include "ace/Auto_Ptr.h"
+#include "ace/Task.h"
+#include "ace/Get_Opt.h"
+#include "ace/SString.h"
+
+#include "orbsvcs/CosNamingC.h"
+
+namespace CIAO
+{
+ namespace RepositoryManager
+ {
+ /// Name of the file holding the IOR of the RM
+ const char * RMior = "RepositoryManagerDaemon.ior";
+
+ // Name of RepoMan
+ const char * repoman_name_ = "RepositoryManager";
+
+ //Name service of the RM
+ const char * RMname_service = "RepositoryManager";
+
+ /// Default number of worker threads to run in the multi-threaded RM
+ static unsigned int nthreads = 3;
+ static ACE_CString HTTPserver = "127.0.0.1:5432";
+
+ static bool register_with_ns_ = false;
+ static bool write_to_ior_ = true;
+ }
+}
+
+// Forward declaration
+bool parse_args (int argc, char *argv[]);
+
+/**
+ * @class Worker
+ *
+ * Class that implements the service routine of the worker threads
+ * of the repository manager
+ */
+class Worker : public ACE_Task_Base
+{
+public:
+ /// ctor
+ Worker (CORBA::ORB_ptr orb);
+
+ /// The thread entry point.
+ virtual int svc (void);
+
+private:
+ /// The orb
+ CORBA::ORB_var orb_;
+};
+
+bool
+write_ior_file (CORBA::ORB_ptr orb,
+ CIAO::RepositoryManagerDaemon_ptr obj)
+{
+ CORBA::String_var ior =
+ orb->object_to_string (obj);
+
+ FILE* RMior_file =
+ ACE_OS::fopen (CIAO::RepositoryManager::RMior, "w");
+
+ if (RMior_file)
+ {
+ ACE_OS::fprintf (RMior_file,
+ "%s",
+ ior.in ());
+ ACE_OS::fclose (RMior_file);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+register_with_ns (CORBA::ORB_ptr orb,
+ CIAO::RepositoryManagerDaemon_ptr obj)
+{
+ if (CIAO::RepositoryManager::repoman_name_ != "")
+ CIAO::RepositoryManager::RMname_service =
+ CIAO::RepositoryManager::repoman_name_;
+
+ // Naming Service related operations
+ CORBA::Object_var naming_context_object =
+ orb->resolve_initial_references ("NameService");
+
+ CosNaming::NamingContext_var naming_context =
+ CosNaming::NamingContext::_narrow (naming_context_object.in ());
+
+ // Initialize the Naming Sequence
+ CosNaming::Name name (1);
+ name.length (1);
+
+ // String dup required for MSVC6
+ name[0].id = CORBA::string_dup (CIAO::RepositoryManager::RMname_service);
+
+ // Register the servant with the Naming Service
+ naming_context->rebind (name, obj);
+
+ return true;
+}
+
+///Main function
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ //init the ORB
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ if (!parse_args (argc, argv))
+ return -1;
+
+ // Get the root POA object
+ CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
+
+ // Downcast to POA type
+ PortableServer::POA_var root_poa = PortableServer::POA::_narrow (obj.in ());
+
+ //activate the POA manager
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
+ mgr->activate ();
+
+ // Create a servant
+ CIAO_RepositoryManagerDaemon_i* repo = 0;
+ ACE_NEW_RETURN (repo,
+ CIAO_RepositoryManagerDaemon_i (
+ orb.in (),
+ CIAO::RepositoryManager::HTTPserver.c_str (),
+ CIAO::RepositoryManager::repoman_name_),
+ 1);
+
+ //transfer ownership to the POA
+ PortableServer::ServantBase_var owner_transfer(repo);
+
+ //register and implicitly activate servant
+ CIAO::RepositoryManagerDaemon_var RepositoryManagerDaemon = repo->_this ();
+
+ bool retval = false;
+
+ if (CIAO::RepositoryManager::write_to_ior_)
+ {
+ retval =
+ write_ior_file (orb.in (),
+ RepositoryManagerDaemon.in ());
+ }
+ else if (CIAO::RepositoryManager::register_with_ns_)
+ {
+ retval =
+ register_with_ns (orb.in (),
+ RepositoryManagerDaemon.in ());
+ }
+
+ if (!retval)
+ return -1;
+
+
+ Worker worker (orb.in ());
+ if (worker.activate (THR_NEW_LWP | THR_JOINABLE,
+ CIAO::RepositoryManager::nthreads) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot activate worker threads\n"),
+ 1);
+
+ worker.thr_mgr ()->wait ();
+
+ ACE_DEBUG ((LM_DEBUG, "event loop finished\n"));
+
+ // done
+ return 0;
+
+ // todo shutdown orb
+ }
+ catch (CORBA::Exception &ex) {
+ cerr << "CORBA Exception: " << ex << endl;
+
+ return 1;
+ }
+
+
+ return 0;
+}
+
+
+// ****************************************************************
+
+///Code to parse the arguments
+
+ bool
+ parse_args (int argc, char *argv[])
+ {
+ ACE_Get_Opt get_opts (argc, argv, "ov:s:n:");
+ int c;
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ CIAO::RepositoryManager::write_to_ior_ = true;
+ CIAO::RepositoryManager::register_with_ns_ = false;
+ break;
+ case 'v':
+ CIAO::RepositoryManager::write_to_ior_ = false;
+ CIAO::RepositoryManager::register_with_ns_ = true;
+ CIAO::RepositoryManager::repoman_name_ = get_opts.opt_arg ();
+ break;
+ case 's':
+ CIAO::RepositoryManager::HTTPserver = get_opts.opt_arg ();
+ break;
+ case 'n':
+ CIAO::RepositoryManager::nthreads = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case '?': // display help for use of the server.
+ ACE_DEBUG ((LM_INFO,
+ "usage: %s\n"
+ "-o <using ior file>\n"
+ "-v <name of naming service>\n"
+ "-s <IP:PORT for HTTP server>\n"
+ "-n <number of threads>\n",
+ argv [0]));
+ return false;
+ break;
+ default:
+ ;
+ }
+
+ return true;
+ }
+
+
+
+// ****************************************************************
+
+///Constuctor for the worker class
+Worker::Worker (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+///implementation of the service routine inherited from ACE::Task_Base
+
+int Worker::svc (void)
+{
+ try
+ {
+ this->orb_->run ();
+ }
+ catch (const CORBA::Exception&)
+ {
+ }
+ return 0;
+}
+
+
diff --git a/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc b/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc
new file mode 100644
index 00000000000..d14d97843cd
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc
@@ -0,0 +1,53 @@
+// -*- MPC -*-
+// $Id$
+
+//RepositoryManager project: implementation of a repository manager
+//compleint with the D&C spec
+
+project (RepositoryManager) : ciao_server_dnc, ciao_config_handlers, zlib, ciaoexe {
+
+ includes += $(CIAO_ROOT)/tools/Config_Handlers $(ACE_ROOT)/contrib/minizip
+ //to circumvent an improper include resolution
+ //in the Package_Handlers/PC_Intf.h
+ exename = RepositoryManagerDaemon
+ requires += zlib
+ after += minizip
+ libs += Package_Config_Handlers minizip
+
+ IDL_Files {
+ RepositoryManagerDaemon.idl
+ }
+
+ Source_Files {
+ RepositoryManagerDaemonC.cpp
+ RepositoryManagerDaemonS.cpp
+ ZIP_Wrapper.cpp
+ RepositoryManager.cpp
+ RepositoryManager_Impl.cpp
+ RM_Helper.cpp
+ URL_Parser.cpp
+ PC_Updater_T.cpp
+ PC_Updater.cpp
+ }
+
+}
+
+
+
+// RMadmin project: a sample client for the RM.
+
+project (RMAdmin) : ciao_servant_dnc, ciao_config_handlers, ciaoexe {
+ exename = RMadmin
+ after += RepositoryManager
+
+ IDL_Files {
+ RepositoryManagerDaemon.idl
+ }
+
+ Source_Files {
+ RMadmin.cpp
+ RepositoryManagerDaemonC.cpp
+ Options.cpp
+ RM_Helper.cpp
+ }
+}
diff --git a/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl b/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl
new file mode 100644
index 00000000000..9deac4abd0e
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl
@@ -0,0 +1,13 @@
+// $Id$
+
+#include "DAnCE/Deployment/Deployment_RepositoryManager.idl"
+
+module CIAO
+{
+ interface RepositoryManagerDaemon : Deployment::RepositoryManager
+ {
+ // Shutdown the daemon process.
+ oneway void shutdown ();
+ };
+};
+
diff --git a/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp b/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp
new file mode 100644
index 00000000000..b3c86d5c221
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp
@@ -0,0 +1,1226 @@
+// $Id$
+
+//====================================================================
+/**
+ * @file RepositoryManager_Impl.cpp
+ *
+ * $Id$
+ *
+ * Description: Actial implementation of the RepoMan
+ *
+ * @author Stoyan Paunov
+ * Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
+ */
+//====================================================================
+
+#include "RepositoryManager_Impl.h"
+
+#include "ace/OS_NS_fcntl.h" //for open
+#include "ace/OS_NS_unistd.h" //for close
+#include "ace/OS_NS_sys_stat.h" //for filesize and fstat and mkdir
+#include "ace/OS_NS_string.h" //for ACE_CString
+#include "ace/OS_Memory.h" //for ACE_NEW* macros
+
+
+//to remove a file or dir from the local filesystem need remove () from stdio.h
+// ---> need to include ace/OS_NS_stdio.h which would include the correct file for any OS!
+#include "ace/OS_NS_stdio.h"
+
+#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
+
+//for the PackageConfiguration parsing
+#include "DAnCE/Deployment/Deployment_DataC.h"
+#include "DAnCE/Deployment/Deployment_Packaging_DataC.h"
+#include "Package_Handlers/PCD_Handler.h"
+
+#include "RM_Helper.h" //to be able to externalize/internalize a PackageConfiguration
+#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 "ace/Dirent.h"
+
+#include "URL_Parser.h" //for parsing the URL
+#include "tao/HTTP_Client.h" //the HTTP client class to downloading packages
+
+#include "PC_Updater.h" //A visitor class to walk through the elements of the PC
+
+#include "ace/Configuration_Import_Export.h"
+
+namespace
+{
+ static const char* PC_EXTENSION = ".epc";
+
+ static const char *RM_RECORD_FILE = "RM_record";
+ static const char *RM_RECORD_NAME_SECTION = "Names";
+ static const char *RM_RECORD_UUID_SECTION = "UUIDs";
+}
+
+//-----------------------------------------------------------------
+//Constructor
+//
+//-----------------------------------------------------------------
+
+CIAO_RepositoryManagerDaemon_i::CIAO_RepositoryManagerDaemon_i
+ (CORBA::ORB_ptr the_orb, const char* server, const char* install_dir)
+ : the_orb_ (CORBA::ORB::_duplicate (the_orb)),
+ install_root_ (""),
+ HTTP_server_ ("http://"),
+ install_path (install_dir)
+{
+ //form the path
+ this->HTTP_server_ += server;
+ this->HTTP_server_ += "/";
+ this->HTTP_server_ += install_path;
+ this->HTTP_server_ += "/";
+
+ //create directory in which the packages will be stored
+ ACE_OS::mkdir(install_path.c_str ());
+ //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;
+
+ // Install the configuration files to get the names, UUIDs, & types info.
+ ACE_Configuration_Heap cfg;
+ cfg.open ();
+ ACE_Configuration_Section_Key root = cfg.root_section ();
+
+ ACE_Registry_ImpExp config_importer (cfg);
+ ACE_OS::chdir (install_path.c_str ());
+ config_importer.import_config (RM_RECORD_FILE);
+ ACE_OS::chdir (this->cwd_);
+
+ ACE_CString name;
+ ACE_Configuration::VALUETYPE type;
+ ACE_CString path;
+
+ ACE_Configuration_Section_Key NameSection;
+ cfg.open_section (root, RM_RECORD_NAME_SECTION, 1, NameSection);
+ u_int index = 0;
+ while (!cfg.enumerate_values (NameSection, index, name, type))
+ {
+ cfg.get_string_value (NameSection, name.c_str (), path);
+ this->names_.bind (name, path);
+
+ ++index;
+ }
+
+ ACE_Configuration_Section_Key UUIDSection;
+ cfg.open_section (root, RM_RECORD_UUID_SECTION, 1, UUIDSection);
+ index = 0;
+ while (!cfg.enumerate_values (UUIDSection, index, name, type))
+ {
+ cfg.get_string_value (UUIDSection, name.c_str (), path);
+ this->uuids_.bind (name, path);
+
+ ++index;
+ }
+
+ // Add types
+ index = 0;
+ for (PCMap_Iterator iter = this->names_.begin ();
+ iter != this->names_.end ();
+ ++iter, ++index)
+ {
+ PCEntry& element = *iter;
+
+ ::Deployment::PackageConfiguration_var pc = this->findPackageByName (element.ext_id_.c_str ());
+
+ if(!this->add_type (pc, element.ext_id_.c_str ()))
+ ACE_ERROR ((LM_ERROR, "Failed to add the type\n"));
+ }
+}
+
+//-----------------------------------------------------------------
+//Destructor
+//
+//-----------------------------------------------------------------
+
+CIAO_RepositoryManagerDaemon_i::~CIAO_RepositoryManagerDaemon_i (void)
+{
+ this->names_.unbind_all ();
+ this->uuids_.unbind_all ();
+ this->types_.unbind_all ();
+}
+
+//-----------------------------------------------------------------
+//shutdown
+//
+//-----------------------------------------------------------------
+
+void CIAO_RepositoryManagerDaemon_i::shutdown ()
+
+{
+ // Release resource.
+ this->names_.unbind_all ();
+ this->uuids_.unbind_all ();
+ this->types_.unbind_all ();
+
+ this->the_orb_->shutdown (0);
+}
+
+
+//-----------------------------------------------------------------
+//installPackage
+//
+//-----------------------------------------------------------------
+
+void CIAO_RepositoryManagerDaemon_i::installPackage (
+ const char * installationName,
+ const char * location,
+ ::CORBA::Boolean replace
+ )
+{
+
+ PCEntry *entry = 0;
+ if (this->names_.find (ACE_CString (installationName), entry) == 0)
+ {
+ if (!replace)
+ throw Deployment::NameExists ();
+ else
+ deletePackage (installationName);
+ }
+
+ //Now lets form the path for the local file
+ //NOTE: I need the absolute path because I will change to a subdirectory
+ //when I am parsing the descriptors
+
+ ACE_CString path (this->install_root_);
+ path += "/";
+ path += installationName;
+
+ 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
+
+ if (ACE_OS::strstr (location, "http://"))
+ {
+
+ //TODO: how can I incorporate a Auto_Ptr is explicit release is needed
+ ACE_Message_Block* mb = 0;
+ ACE_NEW_THROW_EX (mb, ACE_Message_Block (), CORBA::NO_MEMORY ());
+
+ //get the remote file
+ if (!HTTP_Get (location, *mb))
+ {
+ mb->release ();
+ throw CORBA::INTERNAL ();
+ }
+
+ // Write file to designated location on disk
+ if (!RM_Helper::write_to_disk (package_path.c_str (), *mb))
+ {
+ mb->release ();
+ throw CORBA::INTERNAL ();
+ }
+
+ mb->release ();
+ }
+ else
+ {
+ if (!RM_Helper::copy_from_disk_to_disk (location, package_path.c_str ()))
+ throw CORBA::INTERNAL ();
+ }
+
+
+ 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 == "")
+ {
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+
+ throw Deployment::PackageError ();
+ }
+
+ //TODO: move exception throwing out of this func. User boolean error handling!!!
+ //TODO: check for errors!
+ Deployment::PackageConfiguration_var pc;
+ pc = this->retrieve_PC_from_descriptors (const_cast<char*> (pc_name.c_str ()),
+ descriptor_dir.c_str ());
+
+
+ if (this->uuids_.find (ACE_CString (pc->UUID), entry) == 0)
+ {
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+
+ throw Deployment::NameExists ();
+ }
+
+ //forming the server path info
+ ACE_CString server_path (this->HTTP_server_);
+ server_path += installationName;
+
+ //NOTE: ComponentPackageReferences are currently NOT supported
+ if (!(pc->basePackage.length () > 0))
+ {
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+
+ throw CORBA::NO_IMPLEMENT ();
+ }
+
+ PC_Updater updater (server_path, package_path);
+
+ if (!updater.update (pc))
+ {
+ ACE_DEBUG ((LM_ERROR, "[RM] problem updating the PackageConfiguration!\n"));
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ throw Deployment::PackageError ();
+ }
+
+
+ //now lets externalize the PackageConfiguration, so that we can access it later on
+ //without having to do the whole parsing again.
+ //NOTE: Order here is important. Do not populate maps before the externalization!
+ RM_Helper::externalize (pc, pc_path.c_str ());
+
+ //insert the package into the database
+ if (this->names_.bind (ACE_CString (installationName), path) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM] could not bind %s.\n",
+ installationName));
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ //remove the PackageConfiguration externalization
+ remove (pc_path.c_str ());
+
+ //throw exception
+ throw CORBA::INTERNAL ();
+ }
+
+ //ALSO NEED THE UUID here
+ if (this->uuids_.bind (ACE_CString (pc->UUID), path) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM] could not bind %s.\n",
+ ACE_CString (pc->UUID).c_str ()));
+
+ //unbind the name
+ this->names_.unbind (installationName);
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ //remove the PackageConfiguration externalization
+ remove (pc_path.c_str ());
+
+ //throw exception
+ throw CORBA::INTERNAL ();
+ }
+
+ //now add the type interface
+ if(!this->add_type (pc, installationName))
+ ACE_ERROR ((LM_ERROR, "Failed to add the type\n"));
+
+ this->dump ();
+
+ this->save ();
+
+ ACE_DEBUG ((LM_INFO,
+ "Installed PackageConfiguration \n\tname: %s \n\tuuid: %s\n",
+ installationName, ACE_CString (pc->UUID).c_str ()));
+}
+
+
+//-----------------------------------------------------------------
+//createPackage
+//
+//-----------------------------------------------------------------
+
+void CIAO_RepositoryManagerDaemon_i::createPackage (
+ const char * installationName,
+ const ::Deployment::PackageConfiguration & package,
+ const char * baseLocation,
+ ::CORBA::Boolean replace
+ )
+{
+ ::Deployment::PackageConfiguration pc = package;
+
+ // Find if there is a PackageConfiguration with the same name.
+ PCEntry *entry = 0;
+ if (this->names_.find (ACE_CString (installationName), entry) == 0)
+ {
+ if (!replace)
+ throw Deployment::NameExists ();
+ else
+ deletePackage (installationName);
+ }
+
+ // Find if there is a PackageConfiguration with the same uuid.
+ if (this->uuids_.find (ACE_CString (pc.UUID), entry) == 0)
+ throw Deployment::NameExists ();
+
+ // Find if the PackageConfiguration has a basePackage.
+ // NOTE: ComponentPackageReferences are currently NOT supported.
+ if (!(pc.basePackage.length () > 0))
+ throw CORBA::NO_IMPLEMENT ();
+
+ // Form the path for the local file
+ ACE_CString path (this->install_root_);
+ path += "/";
+ path += installationName;
+
+ ACE_CString package_path (path);
+ package_path += ".cpk"; //package extension
+
+ ACE_CString pc_path (path);
+ pc_path += PC_EXTENSION; //external PackageConfiguration extension
+
+ // Check if URL or local file, download or load into memory
+ if (ACE_OS::strstr (baseLocation, "http://"))
+ {
+ //TODO: how can I incorporate a Auto_Ptr is explicit release is needed
+ ACE_Message_Block* mb;
+ ACE_NEW_THROW_EX (mb, ACE_Message_Block (), CORBA::NO_MEMORY ());
+
+ //get the remote file
+ if (!HTTP_Get (baseLocation, *mb))
+ {
+ mb->release ();
+ throw CORBA::INTERNAL ();
+ }
+
+ // Write file to designated location on disk
+ if (!RM_Helper::write_to_disk (package_path.c_str (), *mb))
+ {
+ mb->release ();
+ throw CORBA::INTERNAL ();
+ }
+
+ mb->release ();
+ }
+ else
+ {
+ if (!RM_Helper::copy_from_disk_to_disk (baseLocation, package_path.c_str ()))
+ throw CORBA::INTERNAL ();
+ }
+
+
+ ZIP_Wrapper::uncompress (const_cast<char*> (package_path.c_str ()),
+ const_cast<char*> (this->install_root_.c_str ()),
+ false //not verbose
+ );
+
+ // Form the server path info
+ ACE_CString server_path (this->HTTP_server_);
+ server_path += installationName;
+
+ // Update the newly installed package configration informantion.
+ PC_Updater updater (server_path, package_path);
+
+ if (!updater.update (pc))
+ {
+ ACE_ERROR ((LM_ERROR, "[RM] problem updating the PackageConfiguration!\n"));
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ throw Deployment::PackageError ();
+ }
+
+ // Externalize the PackageConfiguration, so that we can access it later on
+ // without having to do the whole parsing again.
+ // NOTE: Order here is important. Do not populate maps before the externalization!
+ RM_Helper::externalize (pc, pc_path.c_str ());
+
+ // Insert the name of the package.
+ if (this->names_.bind (ACE_CString (installationName), path) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM] could not bind %s.\n",
+ installationName));
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ //remove the PackageConfiguration externalization
+ remove (pc_path.c_str ());
+
+ //throw exception
+ throw CORBA::INTERNAL ();
+ }
+
+ // Insert the UUID of the package.
+ if (this->uuids_.bind (ACE_CString (pc.UUID), path) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM] could not bind %s.\n",
+ ACE_CString (pc.UUID).c_str ()));
+
+ //unbind the name
+ this->names_.unbind (installationName);
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ //remove the PackageConfiguration externalization
+ remove (pc_path.c_str ());
+
+ //throw exception
+ throw CORBA::INTERNAL ();
+ }
+
+ //now add the type interface
+ //TODO: CHECK if successful
+ if(!this->add_type (pc, installationName))
+ ACE_ERROR ((LM_ERROR, "Failed to add the type\n"));
+
+ this->dump ();
+
+ this->save ();
+
+ ACE_DEBUG ((LM_INFO,
+ "Created PackageConfiguration \n directory: %s \n name: %s \n uuid: %s\n",
+ path.c_str (), installationName, ACE_CString (pc.UUID).c_str ()));
+}
+
+
+//-----------------------------------------------------------------
+//findPackageByName
+//
+//-----------------------------------------------------------------
+
+::Deployment::PackageConfiguration*
+CIAO_RepositoryManagerDaemon_i::findPackageByName (const char * name)
+
+{
+ // Find out if the PackageConfiguration was installed in the repository,
+ // return it if found or throw and exception otherwise
+
+ PCEntry *entry = 0;
+
+ if (this->names_.find (ACE_CString (name), entry) != 0)
+ throw Deployment::NoSuchName ();
+ //PackageConfiguration was not found
+
+ ACE_CString pc_path (entry->int_id_.c_str ());
+ pc_path += PC_EXTENSION;
+
+ Deployment::PackageConfiguration_var pc;
+ ACE_NEW_THROW_EX (pc,
+ Deployment::PackageConfiguration (),
+ CORBA::NO_MEMORY ());
+
+
+ if(!RM_Helper::reincarnate (pc, pc_path.c_str ()))
+ throw CORBA::INTERNAL ();
+
+ ACE_DEBUG ((LM_INFO, "Successfully looked up \'%s\'.\n", name));
+
+ return pc._retn ();
+}
+
+
+//-----------------------------------------------------------------
+//findPackageByUUID
+//
+//-----------------------------------------------------------------
+
+::Deployment::PackageConfiguration*
+CIAO_RepositoryManagerDaemon_i::findPackageByUUID (const char * UUID)
+
+{
+ // Find out if the PackageConfiguration was installed in the repository,
+ // return it if found or throw and exception otherwise
+
+ PCEntry *entry = 0;
+
+ if (this->uuids_.find (ACE_CString (UUID), entry) != 0)
+ throw Deployment::NoSuchName ();
+ //PackageConfiguration was not found
+
+ ACE_CString pc_path (entry->int_id_.c_str ());
+ pc_path += PC_EXTENSION;
+
+ Deployment::PackageConfiguration_var pc;
+ ACE_NEW_THROW_EX (pc,
+ Deployment::PackageConfiguration (),
+ CORBA::NO_MEMORY ());
+
+
+ if(!RM_Helper::reincarnate (pc, pc_path.c_str ()))
+ throw CORBA::INTERNAL ();
+
+ ACE_DEBUG ((LM_INFO, "Successfully looked up %s.\n", UUID));
+
+ return pc._retn ();
+}
+
+//-----------------------------------------------------------------
+//findPackageByType
+//
+//-----------------------------------------------------------------
+
+::CORBA::StringSeq * CIAO_RepositoryManagerDaemon_i::findNamesByType (
+ const char * type
+ )
+{
+ CIEntry *entry = 0;
+
+ //find the type in the interface map
+ if (this->types_.find (ACE_CString (type), entry) != 0)
+ {
+ //return an empty sequence
+ CORBA::StringSeq_var seq;
+ ACE_NEW_THROW_EX (seq, CORBA::StringSeq (0), CORBA::NO_MEMORY ());
+
+ return seq._retn ();
+ }
+ else
+ {
+ CISet ci_set = (*entry).int_id_set_;
+
+ CORBA::ULong len = ci_set.size ();
+
+ //allocate a sequence of the right length
+ CORBA::StringSeq_var seq;
+ ACE_NEW_THROW_EX (seq,
+ CORBA::StringSeq (len),
+ CORBA::NO_MEMORY ());
+ seq->length (len);
+
+ //store the elements in the string sequence
+ CISet_Iterator ci_set_iter (ci_set);
+ CORBA::ULong index = 0;
+ for (ci_set_iter = ci_set.begin ();
+ ci_set_iter != ci_set.end () && index < len;
+ ++ci_set_iter, ++index)
+ {
+ seq[index] = CORBA::string_dup ((*ci_set_iter).c_str ());
+ }
+
+ return seq._retn ();
+ }
+}
+
+
+//-----------------------------------------------------------------
+//getAllNames
+//
+//-----------------------------------------------------------------
+
+::CORBA::StringSeq*
+CIAO_RepositoryManagerDaemon_i::getAllNames ()
+
+{
+ //Map.current_size () gives you the current number with the duplicates
+ //Map.total_size () gives you the allocated space + the empty slots
+ //Apparently the only way to figure out the number of keys is to
+ //count them with an iterator.
+
+ CORBA::ULong num_entries = 0;
+
+ for (PCMap_Iterator i = this->names_.begin ();
+ i != this->names_.end ();
+ ++i)
+ ++num_entries;
+
+ CORBA::StringSeq_var seq;
+ ACE_NEW_THROW_EX (seq, CORBA::StringSeq (num_entries), CORBA::NO_MEMORY ());
+
+
+ seq->length (num_entries);
+
+ CORBA::ULong index = 0;
+ for (PCMap_Iterator iter = this->names_.begin ();
+ iter != this->names_.end () && index < num_entries;
+ ++iter, ++index)
+ {
+ PCEntry& element = *iter;
+ seq[index] = CORBA::string_dup (element.ext_id_.c_str ());
+ }
+
+ ACE_DEBUG ((LM_INFO, "The number of packages %d\n", seq->length ()));
+
+ return seq._retn (); //release the underlying CORBA::StringSeq
+}
+
+
+//-----------------------------------------------------------------
+//getAllTypes
+//
+//-----------------------------------------------------------------
+
+::CORBA::StringSeq * CIAO_RepositoryManagerDaemon_i::getAllTypes (
+
+ )
+{
+ //Map.current_size () gives you the current number with the duplicates
+ //Map.total_size () gives you the allocated space + the empty slots
+ //Apparently the only way to figure out the number of keys is to
+ //count them with an iterator.
+
+ CORBA::ULong num_entries = 0;
+
+ for (CIMap_Iterator i = this->types_.begin ();
+ i != this->types_.end ();
+ ++i)
+ ++num_entries;
+
+ CORBA::StringSeq_var seq;
+ ACE_NEW_THROW_EX (seq,
+ CORBA::StringSeq (num_entries),
+ CORBA::NO_MEMORY ());
+
+
+ seq->length (num_entries);
+
+ CORBA::ULong index = 0;
+ for (CIMap_Iterator iter = this->types_.begin ();
+ iter != this->types_.end () && index < num_entries;
+ ++iter, ++index)
+
+ {
+ CIEntry& element = *iter;
+ seq[index] = CORBA::string_dup (element.ext_id_.c_str ());
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "The number of types: %d\n", num_entries));
+
+ return seq._retn (); //release the underlying CORBA::StringSeq
+}
+
+
+//-----------------------------------------------------------------
+//DeletePackage
+//
+//-----------------------------------------------------------------
+
+void CIAO_RepositoryManagerDaemon_i::deletePackage (
+ const char * installationName
+ )
+{
+ bool internal_err = false;
+
+ PCEntry *entry = 0;
+
+ if (this->names_.find (ACE_CString (installationName), entry) != 0)
+ throw Deployment::NoSuchName ();
+
+ //cache the package path
+ ACE_CString path (entry->int_id_.c_str ());
+
+ //remove the name association
+ if (this->names_.unbind (installationName) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Unable to unbind %s.\n",
+ installationName));
+ internal_err = true;
+ }
+
+ //the package location
+ ACE_CString package_path (path);
+ package_path += ".cpk"; //package extension
+
+ //the PackageConfiguration externalization location
+ ACE_CString pc_path (path);
+ pc_path += PC_EXTENSION; //external PackageConfiguration extension
+
+ Deployment::PackageConfiguration_var pc;
+ ACE_NEW_THROW_EX (pc,
+ Deployment::PackageConfiguration (),
+ CORBA::NO_MEMORY ());
+
+
+ if(!RM_Helper::reincarnate (pc, pc_path.c_str ()))
+ {
+ ACE_ERROR ((LM_ERROR, "Could not reincarnate PC\n"));
+ internal_err = true;
+ }
+
+ if (this->uuids_.unbind (ACE_CString (pc->UUID)) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "Could not remove UUID\n"));
+ internal_err = true;
+ }
+
+ //remove the type from the interface map
+ if (!this->remove_type (pc, installationName))
+ {
+ ACE_ERROR ((LM_ERROR, "Could not remove type\n"));
+ internal_err = true;
+ }
+
+ //actually delete the package here!
+
+ //clean the extracted files
+ remove_extracted_package (path.c_str ());
+ //remove the package
+ remove (package_path.c_str ());
+ //remove the PackageConfiguration externalization
+ remove (pc_path.c_str ());
+
+ this->dump ();
+
+ this->save ();
+
+ if (internal_err)
+ throw CORBA::INTERNAL ();
+ else
+ ACE_DEBUG ((LM_INFO, "Successfully deleted \'%s\'\n", installationName));
+
+}
+
+
+//==========================================HELPER METHODS==================================================
+
+Deployment::PackageConfiguration*
+CIAO_RepositoryManagerDaemon_i::retrieve_PC_from_package (char* package)
+{
+ char temp[128];
+ // ACE_thread_t thread_id = ACE_Thread::self ();
+ char* PID = ACE_OS::itoa (ACE_OS::getpid (), temp, 10);
+
+ ACE_OS::mkdir(PID);
+ //if dir already exists a -1 is returned
+ //we ignore this, just need to make sure the directory exists
+
+ //change the working dir
+ ACE_OS::chdir (PID);
+
+ ACE_CString pcd_name;
+ //extract the necessary descriptors
+ 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"));
+ throw CORBA::INTERNAL ();
+ }
+
+ Deployment::PackageConfiguration_var pc;
+ //parse the PCD to make sure that there are no package errors
+ try
+ {
+ //CIAO::Config_Handlers::STD_PC_Intf intf (pcd_name.c_str ());
+ //pc = intf.get_PC ();
+ }
+ catch (...)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) RepositoryManager: Error parsing the PCD\n"));
+
+ //change back the the old working dir
+ ACE_OS::chdir (this->cwd_);
+ throw Deployment::PackageError ();
+ }
+ //able to parse the PC. So lets install the package in the repo
+
+ //we no longer need the descriptors, so lets erase them!
+ remove_descriptor_files (package);
+
+ //change back the the old working dir
+ ACE_OS::chdir (this->cwd_);
+
+ //now lets erase the directory!
+ ACE_OS::rmdir (PID);
+ //the ACE_OS::rmdir does not work. Possibly because we need to delete
+ //the contents first. I will look into it more closely when I am back.
+
+ return pc._retn ();
+}
+
+
+//function to retvieve a file via HTTP
+//stores the file in the passed preallocated ACE_Message_Block
+//returns 1 on success
+// 0 on error
+
+int CIAO_RepositoryManagerDaemon_i::HTTP_Get (const char* URL, ACE_Message_Block &mb)
+{
+ URL_Parser *parser = TheURL_Parser::instance ();
+ if (!parser->parseURL (const_cast<char*> (URL)))
+ return 0;
+
+ // Create a client
+ TAO_HTTP_Client client;
+
+ // Open the client
+ if (client.open (parser->filename_,
+ parser->hostname_,
+ parser->port_) == -1)
+ {
+ client.close ();
+ return 0;
+ }
+
+ // Read from it
+ if (client.read (&mb) <= 0)
+ {
+ client.close ();
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+//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 = new Deployment::PackageConfiguration ();
+ //parse the PCD to make sure that there are no package errors
+ try
+ {
+ CIAO::Config_Handlers::Packaging::PCD_Handler::package_config (pc_name, *pc);
+ }
+ catch (...)
+ {
+ 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_);
+ throw Deployment::PackageError ();
+ }
+ //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
+//write out the contents of the deployent plan to a file
+//in the current directory. I use the thread id to guarrantee
+//lack of race conditions if multithreading is enabled
+
+int CIAO_RepositoryManagerDaemon_i::extract_descriptor_files (char* package, ACE_CString& pcd_name)
+{
+ //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 0;
+
+ size_t skip_len = ACE_OS::strlen ("descriptors") + 1;
+
+ while (!list.is_empty ())
+ {
+ ZIP_File_Info* inf = list.delete_head ();
+ ACE_Message_Block* file = 0;
+ 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;
+
+ //extract the descriptor from the package
+ ACE_NEW_RETURN (file, ACE_Message_Block (0,0), 0);
+ if (!ZIP_Wrapper::get_file(const_cast<char*> (package),
+ const_cast<char*> (inf->name_.c_str ()),
+ *file))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM::extract_descriptor_files] Unable to retrieve file!\n"));
+ //release the message block chain
+ file->release ();
+ return 0;
+ }
+
+
+ //write the file to disk
+ if(!RM_Helper::write_to_disk (inf->name_.c_str () + skip_len, *file))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM::extract_descriptor_files] Unable to write out descriptor to disk!\n"));
+ //release the message block chain
+ file->release ();
+ return 0;
+ }
+
+ //release the message block chain
+ file->release ();
+ }
+
+ //deallocate the head of the filename list
+ delete inf;
+ }
+
+ return 1;
+}
+
+int CIAO_RepositoryManagerDaemon_i::remove_descriptor_files (char* package)
+{
+ 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 (package, list)))
+ return 0;
+
+ 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"))
+ {
+ //delete disk
+ if(remove (inf->name_.c_str () + skip_len))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "[RM::remove_descriptor_files] Unable to remove file from disk!\n"));
+ return_code = 0;
+ }
+ }
+ //deallocate the head of the filename list
+ delete inf;
+ }
+
+ return return_code;
+}
+
+int CIAO_RepositoryManagerDaemon_i::remove_extracted_package (const char* path)
+ {
+ ACE_TCHAR full_path[MAXPATHLEN];
+ ACE_OS::getcwd (full_path, sizeof(full_path));
+
+ ACE_OS::chdir (path);
+
+ ACE_Dirent dir (path);
+
+ for (ACE_DIRENT *directory; (directory = dir.read ()) != 0;)
+ {
+ if (ACE_OS::strcmp (directory->d_name, ".") == 0
+ || ACE_OS::strcmp (directory->d_name, "..") == 0)
+ continue;
+
+ ACE_stat stat_buf;
+ ACE_OS::lstat (directory->d_name, &stat_buf);
+
+ ACE_CString temp = path;
+ temp += "/";
+ temp += directory->d_name;
+ switch (stat_buf.st_mode & S_IFMT)
+ {
+ case S_IFREG: // Either a regular file or an executable.
+ remove (temp.c_str ());
+ break;
+
+ case S_IFDIR:
+ remove_extracted_package (temp.c_str ());
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ACE_OS::chdir (full_path);
+
+ ACE_OS::rmdir (path);
+
+ return 0;
+ }
+
+//function to extract the type of the component from
+//the PackageConfiguration and update the interface map
+//returns 1 on success
+// 0 on error
+
+int CIAO_RepositoryManagerDaemon_i::add_type (Deployment::PackageConfiguration& pc,
+ const char* name)
+{
+ if (pc.basePackage.length () > 0)
+ {
+ ::CORBA::StringSeq supportedTypes = pc.basePackage[0]
+ .implementation[0]
+ .referencedImplementation
+ .implements
+ .supportedType;
+
+ if (supportedTypes.length () != 0)
+ {
+ CORBA::ULong len = supportedTypes.length ();
+ for (CORBA::ULong i = 0; i < len; ++i)
+ {
+ this->types_.bind (ACE_CString (supportedTypes[i]), name);
+ }
+ }
+ }
+ else //ComponentPackageReference
+ {
+ //not implemented yet
+ return 0;
+ }
+
+ return 1;
+}
+
+//function to remove the interface type of the component
+//being removed from the interface map
+//returns 1 on success
+// 0 on error
+
+int CIAO_RepositoryManagerDaemon_i::remove_type (Deployment::PackageConfiguration& pc,
+ const char* name)
+{
+ if (pc.basePackage.length () > 0)
+ {
+ ::CORBA::StringSeq supportedTypes = pc.basePackage[0]
+ .implementation[0]
+ .referencedImplementation
+ .implements
+ .supportedType;
+
+ if (supportedTypes.length () != 0)
+ {
+ CORBA::ULong len = supportedTypes.length ();
+ for (CORBA::ULong i = 0; i < len; ++i)
+ {
+ if (this->types_.unbind (ACE_CString (supportedTypes[i]), ACE_CString (name)) != 0)
+ ACE_DEBUG ((LM_DEBUG, "Could not find type %s with package name %s!\n",
+ ACE_CString (supportedTypes[i]).c_str (),
+ name));
+ }
+ }
+ }
+ else //ComponentPackageReference
+ {
+ //not implemented yet
+ return 0;
+ }
+
+ return 1;
+}
+
+//function to dump the state of the RepositoryManager
+void CIAO_RepositoryManagerDaemon_i::dump (void)
+{
+#if defined (ACE_HAS_DUMP)
+
+ ACE_DEBUG(LM_DEBUG, "NAMES:\n");
+ this->names_.dump ();
+ ACE_DEBUG(LM_DEBUG, "UUIDs:\n");
+ this->uuids_.dump ();
+ ACE_DEBUG (LM_DEBUG, "Component Interface Types:\n");
+ this->types_.dump ();
+
+#endif /* ACE_HAS_DUMP */
+}
+
+//function to save the package info of the RepositoryManager
+void CIAO_RepositoryManagerDaemon_i::save (void)
+{
+ // Save the names, UUIDs, & types info to the configuration files.
+ ACE_Configuration_Heap cfg;
+ cfg.open ();
+ ACE_Configuration_Section_Key root = cfg.root_section ();
+
+ ACE_Configuration_Section_Key NameSection;
+ cfg.open_section (root, RM_RECORD_NAME_SECTION, 1, NameSection);
+ for (PCMap_Iterator iter = this->names_.begin ();
+ iter != this->names_.end ();
+ ++iter)
+ {
+ PCEntry& element = *iter;
+ cfg.set_string_value (NameSection, element.ext_id_.c_str (), element.int_id_.c_str ());
+ }
+
+ ACE_Configuration_Section_Key UUIDSection;
+ cfg.open_section (root, RM_RECORD_UUID_SECTION, 1, UUIDSection);
+ for (PCMap_Iterator iter = this->uuids_.begin ();
+ iter != this->uuids_.end ();
+ ++iter)
+ {
+ PCEntry& element = *iter;
+ cfg.set_string_value (UUIDSection, element.ext_id_.c_str (), element.int_id_.c_str ());
+ }
+
+ ACE_Registry_ImpExp exporter (cfg);
+ ACE_OS::chdir (install_path.c_str ());
+ exporter.export_config (RM_RECORD_FILE);
+ ACE_OS::chdir (this->cwd_);
+}
diff --git a/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h b/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h
new file mode 100644
index 00000000000..734ce8fc004
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h
@@ -0,0 +1,249 @@
+
+/* -*- C++ -*- */
+
+//======================================================================
+/**
+ * @file RepositoryManager_Impl.h
+ *
+ * $Id$
+ *
+ * Description:
+ * This file is the main implementation file for the RepositoryManager
+ * in CIAO. We have used a number of techniques in order to increase
+ * scalability of the RepoMan while still maintaining complience with
+ * the D&C spec
+ *
+ * @author Stoyan Paunov
+ * Shanshan Jiang <shanshan.jiang@vanderbilt.edu>
+ */
+//======================================================================
+
+#ifndef REPOSITORYMANAGERI_H_
+#define REPOSITORYMANAGERI_H_
+
+
+//-----------------------------NOTE---------------------------------
+//I need to disable all the code which has to do with interface
+//type information because we currently do not support assembly
+//interfaces which causes undesired behavior with respect to the
+//hash tables because the specificType field in assembly interfaces
+//is empty, so two unrelated intefaces appear to be related.
+
+
+#include "RepositoryManagerDaemonS.h"
+
+#include "ace/Hash_Map_Manager_T.h" //for the ACE_Hash_Map_Manager
+#include "ace/Hash_Multi_Map_Manager_T.h" //for the ACE_Hash_MultiMap_Manager
+#include "ace/Null_Mutex.h" //for ACE_Null_Mutex
+#include "ace/RW_Mutex.h" //for ACE_RW_Mutex
+#include "ace/OS_NS_string.h" //for ACE_CString
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+namespace
+{
+ static const size_t TEMP_LEN = 1024;
+}
+
+class CIAO_RepositoryManagerDaemon_i :
+ public virtual POA_CIAO::RepositoryManagerDaemon
+{
+public:
+ /// Constructor
+ CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb,
+ const char* server = "localhost:5432",
+ const char* install_dir = "RepositoryManager");
+
+ /// Destructor
+ virtual ~CIAO_RepositoryManagerDaemon_i (void);
+
+ virtual
+ void shutdown (
+
+ );
+
+ virtual
+ void installPackage (
+ const char * installationName,
+ const char * location,
+ ::CORBA::Boolean replace
+ );
+
+ virtual
+ void createPackage (
+ const char * installationName,
+ const ::Deployment::PackageConfiguration & package,
+ const char * baseLocation,
+ ::CORBA::Boolean replace
+ );
+
+ virtual
+ ::Deployment::PackageConfiguration * findPackageByName (
+ const char * name
+ );
+
+ virtual
+ ::Deployment::PackageConfiguration * findPackageByUUID (
+ const char * UUID
+ );
+
+ virtual
+ ::CORBA::StringSeq * findNamesByType (
+ const char * type
+ );
+
+ virtual
+ ::CORBA::StringSeq * getAllNames (
+
+ );
+
+ virtual
+ ::CORBA::StringSeq * getAllTypes (
+
+ );
+
+ virtual
+ void deletePackage (
+ const char * installationName
+ );
+
+protected:
+
+ /// 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 retrieve a file via HTTP
+ /// stores the file in the passed preallocated ACE_Message_Block
+ /// @retval 1 success
+ /// @retval 0 error
+ int HTTP_Get (const char* URL, ACE_Message_Block &mb);
+
+ /// Function to extract all necessary files for parsing the
+ /// PackageConfiguration descriptor and populating the idl struct.
+ /// @retval 1 success
+ /// @retval 0 error
+ ///
+ /// @note ACE_CString& pcd_name is an out parameter
+ int extract_descriptor_files (char* package,
+ ACE_CString& pcd_name);
+
+
+ /// Function to remove the files extracted for parsing the PackageConfiguration
+ /// descriptor and populating the idl struct. It reads the names of the files
+ /// from the package. They correspond to the names on disk.
+ /// @retval 1 on success
+ /// @retval 0 on error
+ 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*/
+ /// @retval 1 on success
+ /// @retval 0 on error
+ int remove_extracted_package (const char* package_path);
+
+ /// Function to extract the type of the component from
+ /// the PackageConfiguration and update the interface map
+ /// @retval 1 on success
+ /// @retval 0 on error
+ int add_type (::Deployment::PackageConfiguration& pc,
+ const char* name);
+
+ /// Function to remove the interface type of the component
+ /// being removed from the interface map
+ /// @retval 1 on success
+ /// @retval 0 on error
+ int remove_type (::Deployment::PackageConfiguration& pc,
+ const char* name);
+
+ /// Function to dump the state of the RepositoryManager
+ void dump (void);
+
+ /// Function to save the package info of the RepositoryManager
+ void save (void);
+
+private:
+ /// Cached information about the installed PackageConfigurations
+ /// A separate map for the installation names and their UUID's
+ /// Key: PackageConfiguration name or its UUID (CString type)
+ /// Value: The location of the local copy of the package
+
+ ///Based on the synchronization needed we can parametrize this with either
+ ///ACE_Null_Mutex or ACE_RW_Mutex
+
+ typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ ACE_CString,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_RW_Mutex> PCMap;
+
+ typedef PCMap::ITERATOR PCMap_Iterator;
+ typedef PCMap::ENTRY PCEntry;
+
+
+ /// Cached information about the installed Component Interfaces
+ /// A map which associates Component supportedType with the
+ /// names of packages which implement this component type
+ /// Key: Component supportedType
+ /// Value: Unbounded set of the names of installed packages which
+ /// implement this component type
+
+ ///Based on the synchronization needed we can parametrize this with either
+ ///ACE_Null_Mutex or ACE_RW_Mutex
+
+ typedef ACE_Hash_Multi_Map_Manager<ACE_CString,
+ ACE_CString,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_RW_Mutex> CIMap;
+
+ typedef CIMap::ITERATOR CIMap_Iterator;
+ typedef CIMap::ENTRY CIEntry;
+ typedef CIEntry::VALUE_SET CISet;
+ typedef CIEntry::VALUE_SET_ITERATOR CISet_Iterator;
+
+ /// A hash map that associates the names of
+ /// PackageConfigurations with their location
+ PCMap names_;
+
+ /// a hash map that associates the UUIDs of
+ /// PackageConfigurations with their location
+ PCMap uuids_;
+
+ /// a hash map which associates Component Interface
+ /// UUIDs with their implementations
+ CIMap types_;
+
+ /// The ORB
+ CORBA::ORB_var the_orb_;
+
+ /// Will hold the current working directory
+ char cwd_ [TEMP_LEN];
+
+ /// Full path for the install directory
+ ACE_CString install_root_;
+
+ /// Location of the server
+ ACE_CString HTTP_server_;
+
+ /// Directory where the packages will be stored locally
+ ACE_CString install_path;
+};
+
+#endif /* REPOSITORYMANAGER_H_ */
diff --git a/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp b/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp
new file mode 100644
index 00000000000..37187ebff61
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp
@@ -0,0 +1,101 @@
+// $Id$
+
+#include "ace/Get_Opt.h"
+#include "ace/ARGV.h"
+#include "URL_Parser.h"
+
+#include "ace/ACE.h"
+#include "ace/OS_NS_string.h"
+
+bool
+URL_Parser::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("rwu:h:p:f:d"));
+
+ bool success = true;
+ int c;
+
+ while ((c = get_opt ()) != -1)
+ switch (c)
+ {
+ case 'd':
+ this->debug_ = true;
+ break;
+ case 'u':
+ success = parseURL (get_opt.opt_arg ());
+ break;
+ // Usage fallthrough.
+ default:
+ success = false;
+ }
+
+ if (this->hostname_ == 0 || this->filename_ == 0)
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+URL_Parser::URL_Parser (void)
+ : hostname_ (ACE::strnew ("127.0.0.1")),
+ port_ (ACE_DEFAULT_HTTP_SERVER_PORT),
+ filename_ (0),
+ debug_ (false)
+{
+}
+
+bool URL_Parser::parseURL (char* url)
+{
+ char* ptr = 0;
+ bool success = true;
+ ptr = ACE_OS::strstr (url, "http://");
+ if (ptr)
+ url += ACE_OS::strlen ("http://");
+
+ if (url[0] == '/')
+ {
+ this->filename_ = ACE_OS::strdup (url);
+ }
+ else
+ {
+ ptr = ACE_OS::strstr (url, ":");
+ if (ptr)
+ this->port_ = ACE_OS::atoi (ptr + 1);
+ else
+ ptr = ACE_OS::strstr (url, "/");
+
+ if(!ptr)
+ success = false;
+ else
+ {
+ size_t host_len = ptr - url;
+ ACE::strdelete (this->hostname_);
+ ACE_NEW_RETURN (this->hostname_, char [host_len + 1], false);
+ ACE_OS::strncpy (this->hostname_, url, host_len);
+ this->hostname_ [host_len] = '\0';
+ ptr = ACE_OS::strstr (ptr, "/");
+ if (ptr)
+ {
+ this->filename_ = ACE_OS::strdup(ptr);
+ }
+ else
+ {
+ success = false;
+ }
+ }
+ }
+ return success;
+}
+
+
+void URL_Parser::Error (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "./http_client -u http://hostname:port/filename [-d]\n"));
+}
+
+URL_Parser::~URL_Parser()
+{
+ delete [] this->hostname_;
+ ACE_OS::free (this->filename_);
+}
diff --git a/CIAO/DAnCE/RepositoryManager/URL_Parser.h b/CIAO/DAnCE/RepositoryManager/URL_Parser.h
new file mode 100644
index 00000000000..0dfef0262ad
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/URL_Parser.h
@@ -0,0 +1,66 @@
+
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file URL_Parser.h
+ *
+ * $Id$
+ *
+ * Parses a URL into its logical chunks
+ *
+ * @author Stoyan Paunov
+ */
+//=============================================================================
+
+
+#ifndef URL_PARSER_H
+#define URL_PARSER_H
+
+#include "ace/Get_Opt.h"
+#include "ace/ARGV.h"
+#include "ace/Singleton.h" //for ACE_Singleton
+#include "ace/Null_Mutex.h" //for ACE_Null_Mutex
+
+// Forward declaration
+class URL_Parser;
+
+typedef ACE_Singleton <URL_Parser, ACE_Null_Mutex> TheURL_Parser;
+
+class URL_Parser
+{
+public:
+
+ friend class ACE_Singleton <URL_Parser, ACE_Null_Mutex>;
+
+ /// Parses commandline arguments
+ bool parse_args (int argc, ACE_TCHAR *argv[]);
+
+ /// Return false on failure
+ bool parseURL (char* url);
+
+ void Error (void);
+
+ /// Hostname to connect to
+ ACE_TCHAR *hostname_;
+
+ /// Port number to use
+ u_short port_;
+
+ /// Filename to upload/download
+ ACE_TCHAR *filename_;
+
+ /// Turns on verbosity
+ bool debug_;
+
+ /// destructor
+ ~URL_Parser (void);
+
+protected:
+ /// protected constructor, singleton
+ URL_Parser (void);
+};
+
+
+
+#endif /* URL_PARSER_H */
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;
+}
diff --git a/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h b/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h
new file mode 100644
index 00000000000..918a60f6352
--- /dev/null
+++ b/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h
@@ -0,0 +1,117 @@
+
+/* -*- C++ -*- */
+
+//=======================================================================
+/**
+ * @file ZIP_Wrapper.h
+ *
+ * $Id$
+ *
+ * Purpose: to provide a wrapper around minizip for easy handling of
+ * ZIP archives. This wrapper can be used as an auxiliary
+ * class that allows a program to become ZIP-aware
+ *
+ * @author Stoyan Paunov, Vipul Singh
+ *
+ *
+ */
+//=======================================================================
+
+#ifndef _ZIP_WRAPPER_H_
+#define _ZIP_WRAPPER_H_
+
+#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/Log_Msg.h"
+#include "ace/Synch.h"
+#include "ace/OS_NS_fcntl.h" //for open
+#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir
+
+#include "unzip.h"
+
+
+/**
+ * @class ZIP_File_Info
+ *
+ * This class is used as a carrier of information
+ * about entities residing inside a ZIP archive
+ */
+class ZIP_File_Info
+{
+public:
+ ACE_CString name_;
+ size_t size_;
+ ZIP_File_Info* next_;
+ ZIP_File_Info* prev_;
+
+ ZIP_File_Info (char* name, size_t size);
+ ZIP_File_Info ();
+};
+
+/**
+ * @class ZIP_Wrappers
+ *
+ * This class is the actual workhorse that provides all of
+ * the necessary functionality
+ */
+class ZIP_Wrapper
+{
+public:
+
+ /// Get file and store it into an ACE_Message_Block. The function
+ /// averts subdirectory traversal problems.
+ /// NOTE: Be sure to release the message block even if the function returns
+ /// false becuase the return value might be due to unsuccessful allocation
+
+ ///archive_path is the zip archive with the path
+ ///filename is the name of the file to be looked for in the zip archive.
+ ///the file is stored in ACE message block.
+ static bool get_file (char* archive_path, char* filename,
+ ACE_Message_Block &file);
+
+ /// 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
+
+ ///zip_archive is the arcive to be uncompressed with full path.
+ ///path is used for creating a directory with the name of zip archive.
+ static bool uncompress (char* zip_archive, char* path = "",
+ bool verbose = true);
+
+ /// Get a list of the files in the archive
+
+ ///zip_name is the name of zipfile with fullpath.
+ ///list stores information about each entry in zip file.
+ static int file_list_info (char* zip_name,
+ ACE_Double_Linked_List<ZIP_File_Info> &list);
+
+ ///Check if an entry of a zip file is a file or directory
+ ///We assume a directoryname terminates with a forward slash
+ ///Returns 1 for directory while 0 for file.
+
+ ///filename_inzip is an entry in a zipfile
+ static int checkdir (char* filename_inzip);
+
+ ///Create directory structure if entry in zipfile is a directory
+
+ ///filename_inzip is an entry in a zipfile
+ ///arch_dir stores the name of the directory to be created
+ static int makethedir (char* filename_inzip, ACE_CString arch_dir);
+
+ ///If entry in zipfile is a file, then read the file and write
+ /// the uncompressed data at the proper filepath.
+
+ ///filename_inzip is an entry in a zipfile
+ ///uf refers to the zip archive
+ ///file_info is used to get information about current file
+ ///verbose decides if the details are to be printed or not
+ ///arch_dir is the name of file with full path where it is to be
+ ///uncompressed
+ static int handlethefile (char* filename_inzip, unzFile uf,
+ unz_file_info file_info,
+ bool verbose, ACE_CString arch_dir);
+};
+
+#endif