1 #include <opensrf/transport_message.h>
4 // ---------------------------------------------------------------------------------
5 // Allocates and initializes a new transport_message
6 // ---------------------------------------------------------------------------------
7 transport_message* message_init( const char* body, const char* subject,
8 const char* thread, const char* recipient, const char* sender ) {
10 transport_message* msg = safe_malloc( sizeof(transport_message) );
12 if( body == NULL ) { body = ""; }
13 if( thread == NULL ) { thread = ""; }
14 if( subject == NULL ) { subject = ""; }
15 if( sender == NULL ) { sender = ""; }
16 if( recipient == NULL ) { recipient = ""; }
18 msg->body = strdup(body);
19 msg->thread = strdup(thread);
20 msg->subject = strdup(subject);
21 msg->recipient = strdup(recipient);
22 msg->sender = strdup(sender);
24 if( msg->body == NULL || msg->thread == NULL ||
25 msg->subject == NULL || msg->recipient == NULL ||
26 msg->sender == NULL ) {
28 osrfLogError(OSRF_LOG_MARK, "message_init(): Out of Memory" );
32 free( msg->recipient );
38 msg->router_from = NULL;
39 msg->router_to = NULL;
40 msg->router_class = NULL;
41 msg->router_command = NULL;
44 msg->error_type = NULL;
53 transport_message* new_message_from_xml( const char* msg_xml ) {
55 if( msg_xml == NULL || *msg_xml == '\0' )
58 transport_message* new_msg = safe_malloc( sizeof(transport_message) );
61 new_msg->subject = NULL;
62 new_msg->thread = NULL;
63 new_msg->recipient = NULL;
64 new_msg->sender = NULL;
65 new_msg->router_from = NULL;
66 new_msg->router_to = NULL;
67 new_msg->router_class = NULL;
68 new_msg->router_command = NULL;
69 new_msg->osrf_xid = NULL;
70 new_msg->is_error = 0;
71 new_msg->error_type = NULL;
72 new_msg->error_code = 0;
73 new_msg->broadcast = 0;
74 new_msg->msg_xml = NULL;
76 xmlKeepBlanksDefault(0);
77 xmlDocPtr msg_doc = xmlReadDoc( BAD_CAST msg_xml, NULL, NULL, 0 );
78 xmlNodePtr root = xmlDocGetRootElement(msg_doc);
80 xmlChar* sender = xmlGetProp(root, BAD_CAST "from");
81 xmlChar* recipient = xmlGetProp(root, BAD_CAST "to");
82 xmlChar* subject = xmlGetProp(root, BAD_CAST "subject");
83 xmlChar* thread = xmlGetProp( root, BAD_CAST "thread" );
84 xmlChar* router_from = xmlGetProp( root, BAD_CAST "router_from" );
85 xmlChar* router_to = xmlGetProp( root, BAD_CAST "router_to" );
86 xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" );
87 xmlChar* broadcast = xmlGetProp( root, BAD_CAST "broadcast" );
88 xmlChar* osrf_xid = xmlGetProp( root, BAD_CAST "osrf_xid" );
91 message_set_osrf_xid( new_msg, (char*) osrf_xid);
96 new_msg->sender = strdup((const char*)router_from);
99 new_msg->sender = strdup((const char*)sender);
105 new_msg->recipient = strdup((const char*)recipient);
109 new_msg->subject = strdup((const char*)subject);
113 new_msg->thread = strdup((const char*)thread);
117 new_msg->router_from = strdup((const char*)router_from);
118 xmlFree(router_from);
121 new_msg->router_to = strdup((const char*)router_to);
125 new_msg->router_class = strdup((const char*)router_class);
126 xmlFree(router_class);
129 if(strcmp((const char*) broadcast,"0") )
130 new_msg->broadcast = 1;
134 xmlNodePtr search_node = root->children;
135 while( search_node != NULL ) {
137 if( ! strcmp( (const char*) search_node->name, "thread" ) ) {
138 if( search_node->children && search_node->children->content )
139 new_msg->thread = strdup( (const char*) search_node->children->content );
142 if( ! strcmp( (const char*) search_node->name, "subject" ) ) {
143 if( search_node->children && search_node->children->content )
144 new_msg->subject = strdup( (const char*) search_node->children->content );
147 if( ! strcmp( (const char*) search_node->name, "body" ) ) {
148 if( search_node->children && search_node->children->content )
149 new_msg->body = strdup((const char*) search_node->children->content );
152 search_node = search_node->next;
155 if( new_msg->thread == NULL )
156 new_msg->thread = strdup("");
157 if( new_msg->subject == NULL )
158 new_msg->subject = strdup("");
159 if( new_msg->body == NULL )
160 new_msg->body = strdup("");
162 new_msg->msg_xml = xmlDocToString(msg_doc, 0);
169 void message_set_osrf_xid( transport_message* msg, const char* osrf_xid ) {
172 msg->osrf_xid = strdup(osrf_xid);
173 else msg->osrf_xid = strdup("");
176 void message_set_router_info( transport_message* msg, const char* router_from,
177 const char* router_to, const char* router_class, const char* router_command,
178 int broadcast_enabled ) {
183 msg->router_from = strdup(router_from);
185 msg->router_from = strdup("");
188 msg->router_to = strdup(router_to);
190 msg->router_to = strdup("");
193 msg->router_class = strdup(router_class);
195 msg->router_class = strdup("");
198 msg->router_command = strdup(router_command);
200 msg->router_command = strdup("");
202 msg->broadcast = broadcast_enabled;
204 if( msg->router_from == NULL || msg->router_to == NULL ||
205 msg->router_class == NULL || msg->router_command == NULL )
206 osrfLogError(OSRF_LOG_MARK, "message_set_router_info(): Out of Memory" );
213 /* encodes the message for traversal */
214 int message_prepare_xml( transport_message* msg ) {
216 if( msg->msg_xml == NULL )
217 msg->msg_xml = message_to_xml( msg );
222 // ---------------------------------------------------------------------------------
224 // ---------------------------------------------------------------------------------
225 int message_free( transport_message* msg ){
226 if( msg == NULL ) { return 0; }
231 free(msg->recipient);
233 free(msg->router_from);
234 free(msg->router_to);
235 free(msg->router_class);
236 free(msg->router_command);
238 if( msg->error_type != NULL ) free(msg->error_type);
239 if( msg->msg_xml != NULL ) free(msg->msg_xml);
244 // ---------------------------------------------------------------------------------
245 // Allocates a char* holding the XML representation of this jabber message
246 // ---------------------------------------------------------------------------------
247 char* message_to_xml( const transport_message* msg ) {
251 //char* encoded_body;
253 xmlNodePtr message_node;
254 xmlNodePtr body_node;
255 xmlNodePtr thread_node;
256 xmlNodePtr subject_node;
257 xmlNodePtr error_node;
261 xmlKeepBlanksDefault(0);
264 osrfLogWarning(OSRF_LOG_MARK, "Passing NULL message to message_to_xml()");
268 doc = xmlReadDoc( BAD_CAST "<message/>", NULL, NULL, XML_PARSE_NSCLEAN );
269 message_node = xmlDocGetRootElement(doc);
271 if( msg->is_error ) {
272 error_node = xmlNewChild(message_node, NULL, BAD_CAST "error" , NULL );
273 xmlAddChild( message_node, error_node );
274 xmlNewProp( error_node, BAD_CAST "type", BAD_CAST msg->error_type );
276 osrf_clearbuf( code_buf, sizeof(code_buf));
277 sprintf(code_buf, "%d", msg->error_code );
278 xmlNewProp( error_node, BAD_CAST "code", BAD_CAST code_buf );
281 /* set from and to */
282 xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient );
283 xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender );
284 xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from );
285 xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to );
286 xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class );
287 xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command );
288 xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid );
291 xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" );
293 /* Now add nodes where appropriate */
294 char* body = msg->body;
295 char* subject = msg->subject;
296 char* thread = msg->thread;
298 if( thread && *thread ) {
299 thread_node = xmlNewChild(message_node, NULL, (xmlChar*) "thread", NULL );
300 xmlNodePtr txt = xmlNewText((xmlChar*) thread);
301 xmlAddChild(thread_node, txt);
302 xmlAddChild(message_node, thread_node);
305 if( subject && *subject ) {
306 subject_node = xmlNewChild(message_node, NULL, (xmlChar*) "subject", NULL );
307 xmlNodePtr txt = xmlNewText((xmlChar*) subject);
308 xmlAddChild(subject_node, txt);
309 xmlAddChild( message_node, subject_node );
312 if( body && *body ) {
313 body_node = xmlNewChild(message_node, NULL, (xmlChar*) "body", NULL);
314 xmlNodePtr txt = xmlNewText((xmlChar*) body);
315 xmlAddChild(body_node, txt);
316 xmlAddChild( message_node, body_node );
319 xmlBufferPtr xmlbuf = xmlBufferCreate();
320 xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
321 char* xml = strdup((const char*) (xmlBufferContent(xmlbuf)));
322 xmlBufferFree(xmlbuf);
330 void jid_get_username( const char* jid, char buf[], int size ) {
332 if( jid == NULL || buf == NULL || size <= 0 ) { return; }
336 /* find the @ and return whatever is in front of it */
337 int len = strlen( jid );
339 for( i = 0; i != len; i++ ) {
340 if( jid[i] == '@' ) {
341 if(i > size) i = size;
342 memcpy( buf, jid, i );
350 void jid_get_resource( const char* jid, char buf[], int size) {
351 if( jid == NULL || buf == NULL || size <= 0 ) { return; }
353 // Find the last slash, if any
355 const char* start = strrchr( jid, '/' );
358 // Copy the text beyond the slash, up to a maximum size
360 size_t len = strlen( ++start );
361 if( len > size ) len = size;
362 memcpy( buf, start, len );
369 void jid_get_domain( const char* jid, char buf[], int size ) {
371 if(jid == NULL) return;
373 int len = strlen(jid);
378 for( i = 0; i!= len; i++ ) {
381 else if(jid[i] == '/' && index1 != 0)
385 if( index1 > 0 && index2 > 0 && index2 > index1 ) {
386 int dlen = index2 - index1;
387 if(dlen > size) dlen = size;
388 memcpy( buf, jid + index1, dlen );
389 buf[dlen] = '\0'; // memcpy doesn't provide the nul
395 void set_msg_error( transport_message* msg, const char* type, int err_code ) {
399 if( type != NULL && *type ) {
400 msg->error_type = safe_malloc( strlen(type)+1);
401 strcpy( msg->error_type, type );
402 msg->error_code = err_code;