summaryrefslogtreecommitdiff
path: root/TAO/examples/Content_Server/SMI_Iterator/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/examples/Content_Server/SMI_Iterator/client.cpp')
-rw-r--r--TAO/examples/Content_Server/SMI_Iterator/client.cpp329
1 files changed, 329 insertions, 0 deletions
diff --git a/TAO/examples/Content_Server/SMI_Iterator/client.cpp b/TAO/examples/Content_Server/SMI_Iterator/client.cpp
new file mode 100644
index 00000000000..dcec6b9a578
--- /dev/null
+++ b/TAO/examples/Content_Server/SMI_Iterator/client.cpp
@@ -0,0 +1,329 @@
+// -*- C++ -*-
+// $Id$
+
+// Ossama Othman <ossama@uci.edu>
+
+#include "ace/FILE_Connector.h"
+#include "ace/Process_Manager.h"
+#include "orbsvcs/CosNamingC.h"
+#include "Web_ServerC.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_string.h"
+
+
+ACE_RCSID (SMI_Iterator,
+ client,
+ "$Id$")
+
+
+// Retrieve the data from the server
+int retrieve_data (const char *content_type,
+ Web_Server::Content_Iterator_ptr contents
+ ACE_ENV_ARG_DECL);
+
+
+// Map content type to viewer.
+int external_viewer (const char *content_type,
+ char *viewer,
+ size_t length);
+
+// Spawn an external viewer
+int spawn_viewer (const char *content_type,
+ const char *filename);
+
+int
+main (int argc, char *argv[])
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ if (argc < 2)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Usage: client filename\n")),
+ -1);
+
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init (argc,
+ argv,
+ "Mighty ORB"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Get a reference to the Name Service.
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("NameService"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Narrow to a Naming Context
+ CosNaming::NamingContext_var nc =
+ CosNaming::NamingContext::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (obj.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Nil reference to ")
+ ACE_TEXT ("Name Service\n")),
+ -1);
+ }
+
+ // Create a name.
+ CosNaming::Name name;
+ name.length (1);
+ name[0].id = CORBA::string_dup ("Iterator_Factory");
+ name[0].kind = CORBA::string_dup ("");
+
+ obj = nc->resolve (name ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Now narrow to an Iterator_Factory reference.
+ Web_Server::Iterator_Factory_var factory =
+ Web_Server::Iterator_Factory::_narrow (obj.in ());
+ if (CORBA::is_nil (factory.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Object pointed to by:\n ")
+ ACE_TEXT ("%s\n")
+ ACE_TEXT ("is not an Iterator_Factory ")
+ ACE_TEXT ("object.\n"),
+ argv[1]),
+ -1);
+ }
+
+ // Get a Content_Iterator
+ const char *pathname = argv[1];
+ Web_Server::Content_Iterator_var contents;
+ Web_Server::Metadata_Type_var metadata;
+ factory->get_iterator (pathname,
+ contents,
+ metadata
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("File <%s> has the following ")
+ ACE_TEXT ("characteristics:\n")
+ ACE_TEXT (" Modification Date: %s\n")
+ ACE_TEXT (" Content Type: %s\n"),
+ argv[1],
+ metadata->modification_date.in (),
+ metadata->content_type.in ()));
+
+ int result = ::retrieve_data (metadata->content_type.in (),
+ contents.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (result != 0)
+ return -1;
+
+ // Done with the Content_Iterator, so destroy it.
+ contents->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->shutdown (0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ // ACE_TRY_CHECK;
+ }
+ ACE_CATCH (Web_Server::Error_Result, exc)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Caught Web Server exception ")
+ ACE_TEXT ("with status %d\n"),
+ exc.status),
+ -1);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("Caught unexpected exception:"));
+
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ // Wait for all children to exit.
+ ACE_Process_Manager::instance ()->wait ();
+
+ return 0;
+}
+
+
+int retrieve_data (const char *content_type,
+ Web_Server::Content_Iterator_ptr iterator
+ ACE_ENV_ARG_DECL)
+{
+ Web_Server::Content_Iterator_var contents =
+ Web_Server::Content_Iterator::_duplicate (iterator);
+
+ // Create a temporary file where the retrieved data will be stored.
+ ACE_FILE_Addr file_addr (ACE_sap_any_cast (const ACE_FILE_Addr &));
+ ACE_FILE_IO file_io;
+ ACE_FILE_Connector connector;
+
+ if (connector.connect (file_io,
+ file_addr,
+ 0,
+ ACE_Addr::sap_any,
+ 0,
+ O_CREAT | O_TRUNC | O_WRONLY,
+ ACE_DEFAULT_FILE_PERMS) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Could not open file \"%s\"%p\n"),
+ file_addr.get_path_name ()));
+ }
+
+ // Retrieve and store chunks of data.
+ Web_Server::Chunk_Type_var chunk;
+ CORBA::ULong offset = 0;
+ int rc;
+
+ for (;;)
+ {
+ rc = contents->next_chunk (offset, chunk ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (!rc)
+ break;
+
+ // Write the received data to a file.
+ if (file_io.send (chunk->get_buffer (),
+ chunk->length ()) == -1)
+ {
+ (void) file_io.close ();
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Unable to write retrieved ")
+ ACE_TEXT ("data to file %s\n"),
+ file_addr.get_path_name ()),
+ -1);
+ }
+ else
+ offset += chunk->length ();
+ }
+
+ // Done writing to the file.
+ (void) file_io.close ();
+
+ // Now spawn a view to display the retrieved data.
+ if (::spawn_viewer (content_type,
+ file_addr.get_path_name ()) != 0)
+ return -1;
+
+ return 0;
+}
+
+int external_viewer (const char *content_type,
+ char *viewer,
+ size_t length)
+{
+ if (content_type == 0)
+ return -1;
+
+ if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
+ {
+ const char lynx[] = "lynx";
+ if (length <= sizeof (lynx))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, lynx);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "text/plain") == 0)
+ {
+ const char more[] = "more";
+ if (length <= sizeof (more))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, more);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "application/postscript") == 0)
+ {
+ const char ghostview[] = "ghostview";
+ if (length <= sizeof (ghostview))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, ghostview);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "application/pdf") == 0)
+ {
+ const char acroread[] = "acroread";
+ if (length <= sizeof (acroread))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, acroread);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "image/jpeg") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/gif") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/tiff") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/png") == 0)
+ {
+ const char xv[] = "xv";
+ if (length <= sizeof (xv))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, xv);
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unsupported MIME type: <%s>\n"),
+ content_type),
+ -1);
+
+ return 0;
+}
+
+int
+spawn_viewer (const char *content_type,
+ const char *filename)
+{
+ char viewer[BUFSIZ];
+
+ if (::external_viewer (content_type,
+ viewer,
+ sizeof (viewer)) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problem determining which external ")
+ ACE_TEXT ("viewer to use.\n")),
+ -1);
+
+ // Set up the command line that will be used when spawning the
+ // external viewer.
+ ACE_Process_Options opts;
+ opts.command_line (ACE_TEXT ("%s %s"),
+ viewer,
+ filename);
+
+ pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
+
+ switch (result)
+ {
+ case 0:
+ // Child
+ return 0;
+ case ACE_INVALID_PID:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Error during viewer spawn of %p\n"),
+ opts.command_line_buf ()),
+ -1);
+ default:
+ // Parent
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
+ viewer,
+ result));
+ break;
+ }
+
+ return 0;
+}