diff options
Diffstat (limited to 'TAO/examples/Content_Server/SMI_Iterator/client.cpp')
-rw-r--r-- | TAO/examples/Content_Server/SMI_Iterator/client.cpp | 329 |
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; +} |