2 // Ossama Othman <ossama@uci.edu>
4 #include "ace/FILE_Connector.h"
5 #include "ace/Process_Manager.h"
6 #include "orbsvcs/CosNamingC.h"
7 #include "Web_ServerC.h"
8 #include "ace/OS_NS_strings.h"
9 #include "ace/OS_NS_string.h"
11 // Retrieve the data from the server
12 int retrieve_data (const char *content_type
,
13 Web_Server::Content_Iterator_ptr contents
);
15 // Map content type to viewer.
16 int external_viewer (const char *content_type
,
20 // Spawn an external viewer
21 int spawn_viewer (const char *content_type
,
22 const char *filename
);
25 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
30 ACE_ERROR_RETURN ((LM_ERROR
,
31 ACE_TEXT ("Usage: client filename\n")),
34 // Initialize the ORB.
35 CORBA::ORB_var orb
= CORBA::ORB_init (argc
, argv
, "Mighty ORB");
37 // Get a reference to the Name Service.
38 CORBA::Object_var obj
=
39 orb
->resolve_initial_references ("NameService");
41 // Narrow to a Naming Context
42 CosNaming::NamingContext_var nc
=
43 CosNaming::NamingContext::_narrow (obj
.in ());
45 if (CORBA::is_nil (obj
.in ()))
47 ACE_ERROR_RETURN ((LM_ERROR
,
48 ACE_TEXT ("Nil reference to ")
49 ACE_TEXT ("Name Service\n")),
56 name
[0].id
= CORBA::string_dup ("Iterator_Factory");
57 name
[0].kind
= CORBA::string_dup ("");
59 obj
= nc
->resolve (name
);
61 // Now narrow to an Iterator_Factory reference.
62 Web_Server::Iterator_Factory_var factory
=
63 Web_Server::Iterator_Factory::_narrow (obj
.in ());
64 if (CORBA::is_nil (factory
.in ()))
66 ACE_ERROR_RETURN ((LM_ERROR
,
67 ACE_TEXT ("Object pointed to by:\n")
69 ACE_TEXT ("is not an Iterator_Factory ")
70 ACE_TEXT ("object.\n"),
75 // Get a Content_Iterator
76 Web_Server::Content_Iterator_var contents
;
77 Web_Server::Metadata_Type_var metadata
;
78 factory
->get_iterator (ACE_TEXT_ALWAYS_CHAR(argv
[1]),
83 ACE_TEXT ("File <%s> has the following ")
84 ACE_TEXT ("characteristics:\n")
85 ACE_TEXT (" Modification Date: %s\n")
86 ACE_TEXT (" Content Type: %s\n"),
88 metadata
->modification_date
.in (),
89 metadata
->content_type
.in ()));
91 int result
= ::retrieve_data (metadata
->content_type
.in (),
97 // Done with the Content_Iterator, so destroy it.
104 catch (const Web_Server::Error_Result
& exc
)
106 ACE_ERROR_RETURN ((LM_ERROR
,
107 ACE_TEXT ("Caught Web Server exception ")
108 ACE_TEXT ("with status %d\n"),
112 catch (const CORBA::Exception
& ex
)
114 ex
._tao_print_exception (ACE_TEXT ("Caught unexpected exception:"));
119 // Wait for all children to exit.
120 ACE_Process_Manager::instance ()->wait ();
126 int retrieve_data (const char *content_type
,
127 Web_Server::Content_Iterator_ptr iterator
)
129 Web_Server::Content_Iterator_var contents
=
130 Web_Server::Content_Iterator::_duplicate (iterator
);
132 // Create a temporary file where the retrieved data will be stored.
133 ACE_FILE_Addr
file_addr (ACE_sap_any_cast (const ACE_FILE_Addr
&));
135 ACE_FILE_Connector connector
;
137 if (connector
.connect (file_io
,
142 O_CREAT
| O_TRUNC
| O_WRONLY
,
143 ACE_DEFAULT_FILE_PERMS
) == -1)
145 ACE_ERROR ((LM_ERROR
,
146 ACE_TEXT ("Could not open file \"%s\"%p\n"),
147 file_addr
.get_path_name ()));
150 // Retrieve and store chunks of data.
151 Web_Server::Chunk_Type_var chunk
;
152 CORBA::ULong offset
= 0;
157 rc
= contents
->next_chunk (offset
, chunk
);
162 // Write the received data to a file.
163 if (file_io
.send (chunk
->get_buffer (),
164 chunk
->length ()) == -1)
166 (void) file_io
.close ();
167 ACE_ERROR_RETURN ((LM_ERROR
,
169 ACE_TEXT ("Unable to write retrieved ")
170 ACE_TEXT ("data to file %s\n"),
171 file_addr
.get_path_name ()),
175 offset
+= chunk
->length ();
178 // Done writing to the file.
179 (void) file_io
.close ();
181 // Now spawn a view to display the retrieved data.
182 if (::spawn_viewer (content_type
,
183 ACE_TEXT_ALWAYS_CHAR(file_addr
.get_path_name ())) != 0)
189 int external_viewer (const char *content_type
,
193 if (content_type
== 0)
196 if (ACE_OS::strcasecmp (content_type
, "text/html") == 0)
198 const char lynx
[] = "lynx";
199 if (length
<= sizeof (lynx
))
202 ACE_OS::strcpy (viewer
, lynx
);
204 else if (ACE_OS::strcasecmp (content_type
,
207 const char more
[] = "more";
208 if (length
<= sizeof (more
))
211 ACE_OS::strcpy (viewer
, more
);
213 else if (ACE_OS::strcasecmp (content_type
,
214 "application/postscript") == 0)
216 const char ghostview
[] = "ghostview";
217 if (length
<= sizeof (ghostview
))
220 ACE_OS::strcpy (viewer
, ghostview
);
222 else if (ACE_OS::strcasecmp (content_type
,
223 "application/pdf") == 0)
225 const char acroread
[] = "acroread";
226 if (length
<= sizeof (acroread
))
229 ACE_OS::strcpy (viewer
, acroread
);
231 else if (ACE_OS::strcasecmp (content_type
,
233 || ACE_OS::strcasecmp (content_type
,
235 || ACE_OS::strcasecmp (content_type
,
237 || ACE_OS::strcasecmp (content_type
,
240 const char xv
[] = "xv";
241 if (length
<= sizeof (xv
))
244 ACE_OS::strcpy (viewer
, xv
);
247 ACE_ERROR_RETURN ((LM_ERROR
,
248 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
256 spawn_viewer (const char *content_type
,
257 const char *filename
)
261 if (::external_viewer (content_type
,
263 sizeof (viewer
)) != 0)
264 ACE_ERROR_RETURN ((LM_ERROR
,
265 ACE_TEXT ("Problem determining which external ")
266 ACE_TEXT ("viewer to use.\n")),
269 // Set up the command line that will be used when spawning the
271 ACE_Process_Options opts
;
272 opts
.command_line (ACE_TEXT ("%s %s"),
276 pid_t result
= ACE_Process_Manager::instance ()->spawn (opts
);
283 case ACE_INVALID_PID
:
284 ACE_ERROR_RETURN ((LM_ERROR
,
285 ACE_TEXT ("Error during viewer spawn of %p\n"),
286 opts
.command_line_buf ()),
291 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),