Patch that:
[OpenSRF.git] / src / libopensrf / transport_message.c
1 #include <opensrf/transport_message.h>
2
3
4 // ---------------------------------------------------------------------------------
5 // Allocates and initializes a new transport_message
6 // ---------------------------------------------------------------------------------
7 transport_message* message_init( char* body, 
8                 char* subject, char* thread, char* recipient, char* sender ) {
9
10         transport_message* msg = 
11                 (transport_message*) safe_malloc( sizeof(transport_message) );
12
13         if( body                                        == NULL ) { body                        = ""; }
14         if( thread                              == NULL ) { thread              = ""; }
15         if( subject                             == NULL ) { subject             = ""; }
16         if( sender                              == NULL ) { sender              = ""; }
17         if( recipient                   ==      NULL ) { recipient      = ""; }
18
19         msg->body                               = strdup(body);
20         msg->thread                             = strdup(thread);
21         msg->subject                    = strdup(subject);
22         msg->recipient                  = strdup(recipient);
23         msg->sender                             = strdup(sender);
24
25         if(     msg->body               == NULL || msg->thread                          == NULL ||
26                         msg->subject    == NULL || msg->recipient                       == NULL ||
27                         msg->sender             == NULL ) {
28
29                 osrfLogError(OSRF_LOG_MARK,  "message_init(): Out of Memory" );
30                 return NULL;
31         }
32
33         return msg;
34 }
35
36
37 transport_message* new_message_from_xml( const char* msg_xml ) {
38
39         if( msg_xml == NULL || strlen(msg_xml) < 1 )
40                 return NULL;
41
42         transport_message* new_msg = 
43                 (transport_message*) safe_malloc( sizeof(transport_message) );
44
45         xmlKeepBlanksDefault(0);
46         xmlDocPtr msg_doc = xmlReadDoc( BAD_CAST msg_xml, NULL, NULL, 0 );
47         xmlNodePtr root = xmlDocGetRootElement(msg_doc);
48
49         xmlChar* sender = xmlGetProp(root, BAD_CAST "from");
50         xmlChar* recipient      = xmlGetProp(root, BAD_CAST "to");
51         xmlChar* subject                = xmlGetProp(root, BAD_CAST "subject");
52         xmlChar* thread         = xmlGetProp( root, BAD_CAST "thread" );
53         xmlChar* router_from    = xmlGetProp( root, BAD_CAST "router_from" );
54         xmlChar* router_to      = xmlGetProp( root, BAD_CAST "router_to" );
55         xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" );
56         xmlChar* broadcast      = xmlGetProp( root, BAD_CAST "broadcast" );
57    xmlChar* osrf_xid    = xmlGetProp( root, BAD_CAST "osrf_xid" );
58
59    if( osrf_xid ) {
60       message_set_osrf_xid( new_msg, (char*) osrf_xid);
61       xmlFree(osrf_xid);
62    }
63
64         if( router_from ) {
65                 new_msg->sender         = strdup((char*)router_from);
66         } else {
67                 if( sender ) {
68                         new_msg->sender         = strdup((char*)sender);
69                         xmlFree(sender);
70                 }
71         }
72
73         if( recipient ) {
74                 new_msg->recipient      = strdup((char*)recipient);
75                 xmlFree(recipient);
76         }
77         if(subject){
78                 new_msg->subject                = strdup((char*)subject);
79                 xmlFree(subject);
80         }
81         if(thread) {
82                 new_msg->thread         = strdup((char*)thread);
83                 xmlFree(thread);
84         }
85         if(router_from) {
86                 new_msg->router_from    = strdup((char*)router_from);
87                 xmlFree(router_from);
88         }
89         if(router_to) {
90                 new_msg->router_to      = strdup((char*)router_to);
91                 xmlFree(router_to);
92         }
93         if(router_class) {
94                 new_msg->router_class = strdup((char*)router_class);
95                 xmlFree(router_class);
96         }
97         if(broadcast) {
98                 if(strcmp((char*) broadcast,"0") )
99                         new_msg->broadcast      = 1;
100                 xmlFree(broadcast);
101         }
102
103         xmlNodePtr search_node = root->children;
104         while( search_node != NULL ) {
105
106                 if( ! strcmp( (char*) search_node->name, "thread" ) ) {
107                         if( search_node->children && search_node->children->content ) 
108                                 new_msg->thread = strdup( (char*) search_node->children->content );
109                 }
110
111                 if( ! strcmp( (char*) search_node->name, "subject" ) ) {
112                         if( search_node->children && search_node->children->content )
113                                 new_msg->subject = strdup( (char*) search_node->children->content );
114                 }
115
116                 if( ! strcmp( (char*) search_node->name, "body" ) ) {
117                         if( search_node->children && search_node->children->content )
118                                 new_msg->body = strdup((char*) search_node->children->content );
119                 }
120
121                 search_node = search_node->next;
122         }
123
124         if( new_msg->thread == NULL ) 
125                 new_msg->thread = strdup("");
126         if( new_msg->subject == NULL )
127                 new_msg->subject = strdup("");
128         if( new_msg->body == NULL )
129                 new_msg->body = strdup("");
130
131         new_msg->msg_xml = xmlDocToString(msg_doc, 0);
132    xmlFreeDoc(msg_doc);
133    xmlCleanupParser();
134
135         return new_msg;
136 }
137
138 void message_set_osrf_xid( transport_message* msg, char* osrf_xid ) {
139    if(!msg) return;
140    if( osrf_xid )
141       msg->osrf_xid = strdup(osrf_xid);
142    else msg->osrf_xid = strdup("");
143 }
144
145 void message_set_router_info( transport_message* msg, char* router_from,
146                 char* router_to, char* router_class, char* router_command, int broadcast_enabled ) {
147
148         if(router_from)
149                 msg->router_from                = strdup(router_from);
150         else
151                 msg->router_from                = strdup("");
152
153         if(router_to)
154                 msg->router_to                  = strdup(router_to);
155         else
156                 msg->router_to                  = strdup("");
157
158         if(router_class)
159                 msg->router_class               = strdup(router_class);
160         else 
161                 msg->router_class               = strdup("");
162         
163         if(router_command)
164                 msg->router_command     = strdup(router_command);
165         else
166                 msg->router_command     = strdup("");
167
168         msg->broadcast = broadcast_enabled;
169
170         if( msg->router_from == NULL || msg->router_to == NULL ||
171                         msg->router_class == NULL || msg->router_command == NULL ) 
172                 osrfLogError(OSRF_LOG_MARK,  "message_set_router_info(): Out of Memory" );
173
174         return;
175 }
176
177
178
179 /* encodes the message for traversal */
180 int message_prepare_xml( transport_message* msg ) {
181         if( msg->msg_xml != NULL ) { return 1; }
182         msg->msg_xml = message_to_xml( msg );
183         return 1;
184 }
185
186
187 // ---------------------------------------------------------------------------------
188 //
189 // ---------------------------------------------------------------------------------
190 int message_free( transport_message* msg ){
191         if( msg == NULL ) { return 0; }
192
193         free(msg->body); 
194         free(msg->thread);
195         free(msg->subject);
196         free(msg->recipient);
197         free(msg->sender);
198         free(msg->router_from);
199         free(msg->router_to);
200         free(msg->router_class);
201         free(msg->router_command);
202    free(msg->osrf_xid);
203         if( msg->error_type != NULL ) free(msg->error_type);
204         if( msg->msg_xml != NULL ) free(msg->msg_xml);
205         free(msg);
206         return 1;
207 }
208         
209 // ---------------------------------------------------------------------------------
210 // Allocates a char* holding the XML representation of this jabber message
211 // ---------------------------------------------------------------------------------
212 char* message_to_xml( const transport_message* msg ) {
213
214         //int                   bufsize;
215         //xmlChar*              xmlbuf;
216         //char*                 encoded_body;
217
218         xmlNodePtr      message_node;
219         xmlNodePtr      body_node;
220         xmlNodePtr      thread_node;
221         xmlNodePtr      subject_node;
222         xmlNodePtr      error_node;
223         
224         xmlDocPtr       doc;
225
226         xmlKeepBlanksDefault(0);
227
228         if( ! msg ) { 
229                 osrfLogWarning(OSRF_LOG_MARK,  "Passing NULL message to message_to_xml()"); 
230                 return 0; 
231         }
232
233         doc = xmlReadDoc( BAD_CAST "<message/>", NULL, NULL, XML_PARSE_NSCLEAN );
234         message_node = xmlDocGetRootElement(doc);
235
236         if( msg->is_error ) {
237                 error_node = xmlNewChild(message_node, NULL, BAD_CAST "error" , NULL );
238                 xmlAddChild( message_node, error_node );
239                 xmlNewProp( error_node, BAD_CAST "type", BAD_CAST msg->error_type );
240                 char code_buf[16];
241                 osrf_clearbuf( code_buf, sizeof(code_buf));
242                 sprintf(code_buf, "%d", msg->error_code );
243                 xmlNewProp( error_node, BAD_CAST "code", BAD_CAST code_buf  );
244         }
245
246         /* set from and to */
247         xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient );
248         xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender );
249         xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from );
250         xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to );
251         xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class );
252         xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command );
253         xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid );
254
255         if( msg->broadcast )
256                 xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" );
257
258         /* Now add nodes where appropriate */
259         char* body                              = msg->body;
260         char* subject                   = msg->subject;
261         char* thread                    = msg->thread; 
262
263         if( thread && strlen(thread) > 0 ) {
264                 thread_node = xmlNewChild(message_node, NULL, (xmlChar*) "thread", NULL );
265                 xmlNodePtr txt = xmlNewText((xmlChar*) thread);
266                 xmlAddChild(thread_node, txt);
267                 xmlAddChild(message_node, thread_node); 
268         }
269
270         if( subject && strlen(subject) > 0 ) {
271                 subject_node = xmlNewChild(message_node, NULL, (xmlChar*) "subject", NULL );
272                 xmlNodePtr txt = xmlNewText((xmlChar*) subject);
273                 xmlAddChild(subject_node, txt);
274                 xmlAddChild( message_node, subject_node ); 
275         }
276
277         if( body && strlen(body) > 0 ) {
278                 body_node = xmlNewChild(message_node, NULL, (xmlChar*) "body", NULL);
279                 xmlNodePtr txt = xmlNewText((xmlChar*) body);
280                 xmlAddChild(body_node, txt);
281                 xmlAddChild( message_node, body_node ); 
282         }
283
284         xmlBufferPtr xmlbuf = xmlBufferCreate();
285         xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
286         char* xml = strdup((char*) (xmlBufferContent(xmlbuf)));
287         xmlBufferFree(xmlbuf);
288         xmlFreeDoc( doc );               
289         xmlCleanupParser();
290         return xml;
291 }
292
293
294
295 void jid_get_username( const char* jid, char buf[], int size ) {
296
297         if( jid == NULL ) { return; }
298
299         /* find the @ and return whatever is in front of it */
300         int len = strlen( jid );
301         int i;
302         for( i = 0; i != len; i++ ) {
303                 if( jid[i] == 64 ) { /*ascii @*/
304                         if(i > size)  i = size;
305                         strncpy( buf, jid, i );
306                         buf[i] = '\0'; // strncpy doesn't provide the nul
307                         return;
308                 }
309         }
310 }
311
312
313 void jid_get_resource( const char* jid, char buf[], int size)  {
314         if( jid == NULL ) { return; }
315         int len = strlen( jid );
316         int i;
317         for( i = 0; i!= len; i++ ) {
318                 if( jid[i] == 47 ) { /* ascii / */
319                         const char* start = jid + i + 1; /* right after the '/' */
320                         int rlen = len - (i+1);
321                         if(rlen > size) rlen = size;
322                         strncpy( buf, start, rlen );
323                         buf[rlen] = '\0'; // strncpy doesn't provide the nul
324                 }
325         }
326 }
327
328 void jid_get_domain( const char* jid, char buf[], int size ) {
329
330         if(jid == NULL) return;
331
332         int len = strlen(jid);
333         int i;
334         int index1 = 0; 
335         int index2 = 0;
336
337         for( i = 0; i!= len; i++ ) {
338                 if(jid[i] == 64) /* ascii @ */
339                         index1 = i + 1;
340                 else if(jid[i] == 47 && index1 != 0) /* ascii / */
341                         index2 = i;
342         }
343
344         if( index1 > 0 && index2 > 0 && index2 > index1 ) {
345                 int dlen = index2 - index1;
346                 if(dlen > size) dlen = size;
347                 memcpy( buf, jid + index1, dlen );
348                 buf[dlen] = '\0'; // memcpy doesn't provide the nul
349         }
350 }
351
352 void set_msg_error( transport_message* msg, char* type, int err_code ) {
353
354         if( type != NULL && strlen( type ) > 0 ) {
355                 msg->error_type = safe_malloc( strlen(type)+1); 
356                 strcpy( msg->error_type, type );
357                 msg->error_code = err_code;
358         }
359         msg->is_error = 1;
360 }