2 // Ossama Othman <ossama@uci.edu>
4 #include "ace/FILE_Connector.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Process_Manager.h"
7 #include "Callback_i.h"
8 #include "ace/OS_NS_strings.h"
9 #include "ace/OS_NS_string.h"
11 Callback_i::Callback_i (int *request_count
)
12 : file_ (ACE_sap_any_cast (ACE_FILE_Addr
&)),
18 request_count_ (request_count
)
20 // Create a temporary file to store the retrieved data.
21 ACE_FILE_Connector connector
;
23 if (connector
.connect (this->file_io_
,
28 O_CREAT
| O_TRUNC
| O_WRONLY
,
29 ACE_DEFAULT_FILE_PERMS
) == -1)
32 ACE_TEXT ("Could not open file \"%s\"%p\n"),
33 this->file_
.get_path_name ()));
36 (*this->request_count_
)++;
39 Callback_i::~Callback_i (void)
41 (void) this->file_io_
.close ();
45 Callback_i::next_chunk (const Web_Server::Chunk_Type
& chunk_data
,
46 CORBA::Boolean last_chunk
)
50 Web_Server::Chunk_Type_var chunk
= chunk_data
;
52 // Append the received data to the corresponding
53 // buffer/temporary file.
54 if (this->file_io_
.send (chunk
->get_buffer (),
55 chunk
->length ()) == -1)
57 (*this->request_count_
)--; // Don't wait for more data.
61 ACE_TEXT ("Unable to write retrieved data to ")
62 ACE_TEXT ("file <%s>"),
63 this->file_
.get_path_name ()));
70 ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX
,
74 this->last_chunk_
= 1; // Received entire content.
78 ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
79 this->file_
.get_path_name ()));
81 (*this->request_count_
)--; // No more data.
83 // File retrieval has completed, so spawn an external viewer to
84 // display its contents.
86 // If the entire metadata has been received, then spawn an
87 // external viewer to display the received file.
88 if (this->metadata_received ())
90 (void) this->file_io_
.close ();
93 (void) this->spawn_viewer ();
99 Callback_i::metadata (const Web_Server::Metadata_Type
&metadata
)
104 ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX
,
107 this->metadata_
= metadata
;
111 ACE_TEXT ("Retrieved file has the following ")
112 ACE_TEXT ("characteristics:\n")
113 ACE_TEXT (" Modification Date: %s\n")
114 ACE_TEXT (" Content Type: %s\n"),
115 this->metadata_
.modification_date
.in (),
116 this->metadata_
.content_type
.in ()));
118 // If the entire content of the data has been received, then spawn
119 // an external viewer to display it.
120 if (this->content_received ())
124 (void) this->spawn_viewer ();
127 catch (const CORBA::Exception
& ex
)
129 ex
._tao_print_exception (
130 ACE_TEXT ("Caught unexpected exception ")
131 ACE_TEXT ("in Callback_i::metdata(...):"));
136 Callback_i::metadata_received (void)
138 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
,
143 return (this->metadata_
.content_type
.in () != 0);
147 Callback_i::content_received (void)
149 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
,
154 return this->last_chunk_
;
158 Callback_i::get_viewer (char *viewer
,
161 const char *content_type
=
162 this->metadata_
.content_type
.in ();
164 if (ACE_OS::strcasecmp (content_type
, "text/html") == 0)
166 const char lynx
[] = "lynx";
167 if (length
<= sizeof (lynx
))
170 ACE_OS::strcpy (viewer
, lynx
);
172 else if (ACE_OS::strcasecmp (content_type
,
175 const char more
[] = "more";
176 if (length
<= sizeof (more
))
179 ACE_OS::strcpy (viewer
, more
);
181 else if (ACE_OS::strcasecmp (content_type
,
182 "application/postscript") == 0)
184 const char ghostview
[] = "ghostview";
185 if (length
<= sizeof (ghostview
))
188 ACE_OS::strcpy (viewer
, ghostview
);
190 else if (ACE_OS::strcasecmp (content_type
,
191 "application/pdf") == 0)
193 const char acroread
[] = "acroread";
194 if (length
<= sizeof (acroread
))
197 ACE_OS::strcpy (viewer
, acroread
);
199 else if (ACE_OS::strcasecmp (content_type
,
201 || ACE_OS::strcasecmp (content_type
,
203 || ACE_OS::strcasecmp (content_type
,
205 || ACE_OS::strcasecmp (content_type
,
208 const char xv
[] = "xv";
209 if (length
<= sizeof (xv
))
212 ACE_OS::strcpy (viewer
, xv
);
215 ACE_ERROR_RETURN ((LM_ERROR
,
216 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
224 Callback_i::spawn_viewer (void)
228 if (this->get_viewer (viewer
,
229 sizeof (viewer
)) != 0)
230 ACE_ERROR_RETURN ((LM_ERROR
,
231 ACE_TEXT ("Problem determining which external ")
232 ACE_TEXT ("viewer to use.\n")),
235 // Set up the command line that will be used when spawning the
237 ACE_Process_Options opts
;
238 opts
.command_line (ACE_TEXT ("%s %s"),
240 this->file_
.get_path_name ());
242 pid_t result
= ACE_Process_Manager::instance ()->spawn (opts
);
249 case ACE_INVALID_PID
:
250 ACE_ERROR_RETURN ((LM_ERROR
,
251 ACE_TEXT ("Error during viewer spawn of %p\n"),
252 opts
.command_line_buf ()),
257 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
267 Callback_i::deactivate (void)
269 // Get the POA used when activating the Reply Handler object.
270 PortableServer::POA_var poa
= this->_default_POA ();
272 // Get the object ID associated with this servant.
273 PortableServer::ObjectId_var oid
=
274 poa
->servant_to_id (this);
276 // Now deactivate the iterator object.
277 poa
->deactivate_object (oid
.in ());