Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / Content_Server / SMI_Iterator / client.cpp
blob41e1d89b3ce58d8cff905f8e65e293953da81d2c
1 // -*- C++ -*-
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,
17 char *viewer,
18 size_t length);
20 // Spawn an external viewer
21 int spawn_viewer (const char *content_type,
22 const char *filename);
24 int
25 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
27 try
29 if (argc < 2)
30 ACE_ERROR_RETURN ((LM_ERROR,
31 ACE_TEXT ("Usage: client filename\n")),
32 -1);
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")),
50 -1);
53 // Create a name.
54 CosNaming::Name name;
55 name.length (1);
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")
68 ACE_TEXT ("%s\n")
69 ACE_TEXT ("is not an Iterator_Factory ")
70 ACE_TEXT ("object.\n"),
71 argv[1]),
72 -1);
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]),
79 contents,
80 metadata);
82 ACE_DEBUG ((LM_INFO,
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"),
87 argv[1],
88 metadata->modification_date.in (),
89 metadata->content_type.in ()));
91 int result = ::retrieve_data (metadata->content_type.in (),
92 contents.in ());
94 if (result != 0)
95 return -1;
97 // Done with the Content_Iterator, so destroy it.
98 contents->destroy ();
100 orb->shutdown (0);
102 // orb->destroy ();
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"),
109 exc.status),
110 -1);
112 catch (const CORBA::Exception& ex)
114 ex._tao_print_exception (ACE_TEXT ("Caught unexpected exception:"));
116 return -1;
119 // Wait for all children to exit.
120 ACE_Process_Manager::instance ()->wait ();
122 return 0;
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 &));
134 ACE_FILE_IO file_io;
135 ACE_FILE_Connector connector;
137 if (connector.connect (file_io,
138 file_addr,
140 ACE_Addr::sap_any,
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;
153 int rc;
155 for (;;)
157 rc = contents->next_chunk (offset, chunk);
159 if (!rc)
160 break;
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,
168 ACE_TEXT ("%p\n"),
169 ACE_TEXT ("Unable to write retrieved ")
170 ACE_TEXT ("data to file %s\n"),
171 file_addr.get_path_name ()),
172 -1);
174 else
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)
184 return -1;
186 return 0;
189 int external_viewer (const char *content_type,
190 char *viewer,
191 size_t length)
193 if (content_type == 0)
194 return -1;
196 if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
198 const char lynx[] = "lynx";
199 if (length <= sizeof (lynx))
200 return -1;
201 else
202 ACE_OS::strcpy (viewer, lynx);
204 else if (ACE_OS::strcasecmp (content_type,
205 "text/plain") == 0)
207 const char more[] = "more";
208 if (length <= sizeof (more))
209 return -1;
210 else
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))
218 return -1;
219 else
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))
227 return -1;
228 else
229 ACE_OS::strcpy (viewer, acroread);
231 else if (ACE_OS::strcasecmp (content_type,
232 "image/jpeg") == 0
233 || ACE_OS::strcasecmp (content_type,
234 "image/gif") == 0
235 || ACE_OS::strcasecmp (content_type,
236 "image/tiff") == 0
237 || ACE_OS::strcasecmp (content_type,
238 "image/png") == 0)
240 const char xv[] = "xv";
241 if (length <= sizeof (xv))
242 return -1;
243 else
244 ACE_OS::strcpy (viewer, xv);
246 else
247 ACE_ERROR_RETURN ((LM_ERROR,
248 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
249 content_type),
250 -1);
252 return 0;
256 spawn_viewer (const char *content_type,
257 const char *filename)
259 char viewer[BUFSIZ];
261 if (::external_viewer (content_type,
262 viewer,
263 sizeof (viewer)) != 0)
264 ACE_ERROR_RETURN ((LM_ERROR,
265 ACE_TEXT ("Problem determining which external ")
266 ACE_TEXT ("viewer to use.\n")),
267 -1);
269 // Set up the command line that will be used when spawning the
270 // external viewer.
271 ACE_Process_Options opts;
272 opts.command_line (ACE_TEXT ("%s %s"),
273 viewer,
274 filename);
276 pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
278 switch (result)
280 case 0:
281 // Child
282 return 0;
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 ()),
287 -1);
288 default:
289 // Parent
290 ACE_DEBUG ((LM_INFO,
291 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
292 viewer,
293 result));
294 break;
297 return 0;