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 "Iterator_Handler.h"
8 #include "ace/OS_NS_strings.h"
9 #include "ace/OS_NS_string.h"
11 Iterator_Handler::Iterator_Handler ()
12 : file_ (ACE_sap_any_cast (const ACE_FILE_Addr
&)),
23 Iterator_Handler::~Iterator_Handler ()
25 (void) this->file_io_
.close ();
29 Iterator_Handler::next_chunk (CORBA::Boolean pending_data
,
30 const Web_Server::Chunk_Type
&chunk_data
)
34 Web_Server::Chunk_Type_var chunk
= chunk_data
;
36 // Append the received data to the corresponding
37 // buffer/temporary file.
38 if (this->file_io_
.send (chunk
->get_buffer (),
39 chunk
->length ()) == -1)
43 ACE_TEXT ("Unable to write retrieved data to ")
48 this->offset_
+= chunk
->length ();
50 this->contents_
->sendc_next_chunk (this->ami_handler_
.in (),
56 ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
57 this->file_
.get_path_name ()));
59 (*this->request_count_
)--; // No more data.
61 // Done with the iterator, so destroy it.
62 this->contents_
->sendc_destroy (this->ami_handler_
.in ());
64 // File retrieval has completed, so spawn an external viewer to
65 // display its contents.
67 (void) this->spawn_viewer ();
71 Iterator_Handler::destroy ()
73 // Deactivate this reply handler.
79 Iterator_Handler::run (int *request_count
,
81 Web_Server::Iterator_Factory_ptr factory
)
83 if (request_count
!= 0)
84 this->request_count_
= request_count
;
86 // @@ Application code shouldn't throw system exceptions.
87 throw CORBA::BAD_PARAM ();
88 // Initialize the Content Iterator
89 this->initialize_content_iterator (pathname
,
92 // Activate this Reply Handler.
93 this->ami_handler_
= this->_this ();
95 // Begin the asynchronous invocation.
96 this->contents_
->sendc_next_chunk (this->ami_handler_
.in (),
101 Iterator_Handler::initialize_content_iterator
102 (const char *pathname
,
103 Web_Server::Iterator_Factory_ptr factory
)
105 // Obtain a Content Iterator for the desired file.
106 factory
->get_iterator (pathname
,
110 // Create a temporary file to store the retrieved data.
111 ACE_FILE_Connector connector
;
113 if (connector
.connect (this->file_io_
,
118 O_CREAT
| O_TRUNC
| O_WRONLY
,
119 ACE_DEFAULT_FILE_PERMS
) == -1)
120 ACE_ERROR ((LM_ERROR
,
121 ACE_TEXT ("Could not open file %p\n"),
122 this->file_
.get_path_name ()));
124 (*this->request_count_
)++;
128 Iterator_Handler::deactivate ()
130 // Get the POA used when activating the Reply Handler object.
131 PortableServer::POA_var poa
=
132 this->_default_POA ();
134 // Get the object ID associated with this servant.
135 PortableServer::ObjectId_var oid
=
136 poa
->servant_to_id (this);
138 // Now deactivate the iterator object.
139 poa
->deactivate_object (oid
.in ());
144 Iterator_Handler::get_viewer (char *viewer
,
147 const char *content_type
=
148 this->metadata_
->content_type
.in ();
150 if (ACE_OS::strcasecmp (content_type
, "text/html") == 0)
152 const char lynx
[] = "lynx";
153 if (length
<= sizeof (lynx
))
156 ACE_OS::strcpy (viewer
, lynx
);
158 else if (ACE_OS::strcasecmp (content_type
,
161 const char more
[] = "more";
162 if (length
<= sizeof (more
))
165 ACE_OS::strcpy (viewer
, more
);
167 else if (ACE_OS::strcasecmp (content_type
,
168 "application/postscript") == 0)
170 const char ghostview
[] = "ghostview";
171 if (length
<= sizeof (ghostview
))
174 ACE_OS::strcpy (viewer
, ghostview
);
176 else if (ACE_OS::strcasecmp (content_type
,
177 "application/pdf") == 0)
179 const char acroread
[] = "acroread";
180 if (length
<= sizeof (acroread
))
183 ACE_OS::strcpy (viewer
, acroread
);
185 else if (ACE_OS::strcasecmp (content_type
,
187 || ACE_OS::strcasecmp (content_type
,
189 || ACE_OS::strcasecmp (content_type
,
191 || ACE_OS::strcasecmp (content_type
,
194 const char xv
[] = "xv";
195 if (length
<= sizeof (xv
))
198 ACE_OS::strcpy (viewer
, xv
);
201 ACE_ERROR_RETURN ((LM_ERROR
,
202 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
210 Iterator_Handler::spawn_viewer ()
214 if (this->get_viewer (viewer
,
216 ACE_ERROR_RETURN ((LM_ERROR
,
217 ACE_TEXT ("Problem determining which external ")
218 ACE_TEXT ("viewer to use.\n")),
221 // Set up the command line that will be used when spawning the
223 ACE_Process_Options opts
;
224 opts
.command_line (ACE_TEXT ("%s %s"),
226 this->file_
.get_path_name ());
228 pid_t result
= ACE_Process_Manager::instance ()->spawn (opts
);
235 case ACE_INVALID_PID
:
236 ACE_ERROR_RETURN ((LM_ERROR
,
237 ACE_TEXT ("Error during viewer spawn of %p\n"),
238 opts
.command_line_buf ()),
243 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),