]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/libtransport/transport_message.c
7af26a014d2a887d221e199547d8c5c2afa3cecd
[working/Evergreen.git] / OpenSRF / src / libtransport / transport_message.c
1 #include "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                 fatal_handler( "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
58         if( sender ) {
59                 new_msg->sender         = strdup((char*)sender);
60                 xmlFree(sender);
61         }
62         if( recipient ) {
63                 new_msg->recipient      = strdup((char*)recipient);
64                 xmlFree(recipient);
65         }
66         if(subject){
67                 new_msg->subject                = strdup((char*)subject);
68                 xmlFree(subject);
69         }
70         if(thread) {
71                 new_msg->thread         = strdup((char*)thread);
72                 xmlFree(thread);
73         }
74         if(router_from) {
75                 new_msg->router_from    = strdup((char*)router_from);
76                 xmlFree(router_from);
77         }
78         if(router_to) {
79                 new_msg->router_to      = strdup((char*)router_to);
80                 xmlFree(router_to);
81         }
82         if(router_class) {
83                 new_msg->router_class = strdup((char*)router_class);
84                 xmlFree(router_class);
85         }
86         if(broadcast) {
87                 if(strcmp(broadcast,"0") )
88                         new_msg->broadcast      = 1;
89                 xmlFree(broadcast);
90         }
91
92         xmlNodePtr search_node = root->children;
93         while( search_node != NULL ) {
94
95                 if( ! strcmp( (char*) search_node->name, "thread" ) ) {
96                         if( search_node->children && search_node->children->content ) 
97                                 new_msg->thread = strdup( (char*) search_node->children->content );
98                 }
99
100                 if( ! strcmp( (char*) search_node->name, "subject" ) ) {
101                         if( search_node->children && search_node->children->content )
102                                 new_msg->subject = strdup( (char*) search_node->children->content );
103                 }
104
105                 if( ! strcmp( (char*) search_node->name, "body" ) ) {
106                         if( search_node->children && search_node->children->content )
107                                 new_msg->body = strdup((char*) search_node->children->content );
108                 }
109
110                 search_node = search_node->next;
111         }
112
113         if( new_msg->thread == NULL ) 
114                 new_msg->thread = strdup("");
115         if( new_msg->subject == NULL )
116                 new_msg->subject = strdup("");
117         if( new_msg->body == NULL )
118                 new_msg->body = strdup("");
119
120         int                     bufsize;
121         xmlChar*                xmlbuf;
122         char*                   encoded_body;
123
124         xmlDocDumpFormatMemory( msg_doc, &xmlbuf, &bufsize, 0 );
125         encoded_body = strdup( (char*) xmlbuf );
126
127         if( encoded_body == NULL ) 
128                 fatal_handler("message_to_xml(): Out of Memory");
129
130         xmlFree(xmlbuf);
131         xmlFreeDoc(msg_doc);
132         xmlCleanupParser();
133
134         /*** remove the XML declaration */
135         int len = strlen(encoded_body);
136         char tmp[len];
137         memset( tmp, 0, len );
138         int i;
139         int found_at = 0;
140
141         /* when we reach the first >, take everything after it */
142         for( i = 0; i!= len; i++ ) {
143                 if( encoded_body[i] == 62) { /* ascii > */
144
145                         /* found_at holds the starting index of the rest of the doc*/
146                         found_at = i + 1; 
147                         break;
148                 }
149         }
150
151         if( found_at ) {
152                 /* move the shortened doc into the tmp buffer */
153                 strncpy( tmp, encoded_body + found_at, len - found_at );
154                 /* move the tmp buffer back into the allocated space */
155                 memset( encoded_body, 0, len );
156                 strcpy( encoded_body, tmp );
157         }
158
159         new_msg->msg_xml = encoded_body;
160         return new_msg;
161
162 }
163
164
165 void message_set_router_info( transport_message* msg, char* router_from,
166                 char* router_to, char* router_class, char* router_command, int broadcast_enabled ) {
167
168         if(router_from)
169                 msg->router_from                = strdup(router_from);
170         else
171                 msg->router_from                = strdup("");
172
173         if(router_to)
174                 msg->router_to                  = strdup(router_to);
175         else
176                 msg->router_to                  = strdup("");
177
178         if(router_class)
179                 msg->router_class               = strdup(router_class);
180         else 
181                 msg->router_class               = strdup("");
182         
183         if(router_command)
184                 msg->router_command     = strdup(router_command);
185         else
186                 msg->router_command     = strdup("");
187
188         msg->broadcast = broadcast_enabled;
189
190         if( msg->router_from == NULL || msg->router_to == NULL ||
191                         msg->router_class == NULL || msg->router_command == NULL ) 
192                 fatal_handler( "message_set_router_info(): Out of Memory" );
193
194         return;
195 }
196
197
198
199 /* encodes the message for traversal */
200 int message_prepare_xml( transport_message* msg ) {
201         if( msg->msg_xml != NULL ) { return 1; }
202         msg->msg_xml = message_to_xml( msg );
203         return 1;
204 }
205
206
207 // ---------------------------------------------------------------------------------
208 //
209 // ---------------------------------------------------------------------------------
210 int message_free( transport_message* msg ){
211         if( msg == NULL ) { return 0; }
212
213         free(msg->body); 
214         free(msg->thread);
215         free(msg->subject);
216         free(msg->recipient);
217         free(msg->sender);
218         free(msg->router_from);
219         free(msg->router_to);
220         free(msg->router_class);
221         free(msg->router_command);
222         if( msg->error_type != NULL ) free(msg->error_type);
223         if( msg->msg_xml != NULL ) free(msg->msg_xml);
224         free(msg);
225         return 1;
226 }
227         
228 // ---------------------------------------------------------------------------------
229 // Allocates a char* holding the XML representation of this jabber message
230 // ---------------------------------------------------------------------------------
231 char* message_to_xml( const transport_message* msg ) {
232
233         int                     bufsize;
234         xmlChar*                xmlbuf;
235         char*                   encoded_body;
236
237         xmlNodePtr      message_node;
238         xmlNodePtr      body_node;
239         xmlNodePtr      thread_node;
240         xmlNodePtr      subject_node;
241         xmlNodePtr      error_node;
242         
243         xmlDocPtr       doc;
244
245         xmlKeepBlanksDefault(0);
246
247         if( ! msg ) { 
248                 warning_handler( "Passing NULL message to message_to_xml()"); 
249                 return 0; 
250         }
251
252         doc = xmlReadDoc( BAD_CAST "<message/>", NULL, NULL, XML_PARSE_NSCLEAN );
253         message_node = xmlDocGetRootElement(doc);
254
255         if( msg->is_error ) {
256                 error_node = xmlNewChild(message_node, NULL, BAD_CAST "error" , NULL );
257                 xmlAddChild( message_node, error_node );
258                 xmlNewProp( error_node, BAD_CAST "type", BAD_CAST msg->error_type );
259                 char code_buf[16];
260                 memset( code_buf, 0, 16);
261                 sprintf(code_buf, "%d", msg->error_code );
262                 xmlNewProp( error_node, BAD_CAST "code", BAD_CAST code_buf  );
263         }
264         
265
266         /* set from and to */
267         xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient );
268         xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender );
269         xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from );
270         xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to );
271         xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class );
272         xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command );
273
274         if( msg->broadcast )
275                 xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" );
276
277         /* Now add nodes where appropriate */
278         char* body                              = msg->body;
279         char* subject                   = msg->subject;
280         char* thread                    = msg->thread; 
281
282         if( thread && strlen(thread) > 0 ) {
283                 thread_node = xmlNewChild(message_node, NULL, (xmlChar*) "thread", NULL );
284 //              xmlNewTextChild(thread_node, NULL, NULL,  );
285                 xmlNodePtr txt = xmlNewText((xmlChar*) thread);
286                 xmlAddChild(thread_node, txt);
287                 xmlAddChild(message_node, thread_node); 
288         }
289
290         if( subject && strlen(subject) > 0 ) {
291                 subject_node = xmlNewChild(message_node, NULL, (xmlChar*) "subject", NULL );
292                 //xmlNewTextChild(subject_node, NULL, NULL, (xmlChar*) subject );
293                 xmlNodePtr txt = xmlNewText((xmlChar*) subject);
294                 xmlAddChild(subject_node, txt);
295                 xmlAddChild( message_node, subject_node ); 
296         }
297
298         if( body && strlen(body) > 0 ) {
299                 body_node = xmlNewChild(message_node, NULL, (xmlChar*) "body", NULL);
300                 //xmlNewTextChild(body_node, NULL, NULL, (xmlChar*) body );
301                 xmlNodePtr txt = xmlNewText((xmlChar*) body);
302                 xmlAddChild(body_node, txt);
303                 xmlAddChild( message_node, body_node ); 
304         }
305
306
307         /*
308         xmlBufferPtr buf = xmlBufferCreate();
309         int status = xmlNodeDump( buf, doc, xmlDocGetRootElement(doc) , 1, 0 ); 
310         */
311
312         //xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
313         xmlDocDumpMemoryEnc( doc, &xmlbuf, &bufsize, "UTF-8" );
314
315         encoded_body = strdup( (char*) xmlbuf );
316
317         if( encoded_body == NULL ) 
318                 fatal_handler("message_to_xml(): Out of Memory");
319
320         xmlFree(xmlbuf);
321         xmlFreeDoc( doc );
322         xmlCleanupParser();
323
324
325         /*** remove the XML declaration */
326         int len = strlen(encoded_body);
327         char tmp[len];
328         memset( tmp, 0, len );
329         int i;
330         int found_at = 0;
331
332         /* when we reach the first >, take everything after it */
333         for( i = 0; i!= len; i++ ) {
334                 if( encoded_body[i] == 62) { /* ascii > */
335
336                         /* found_at holds the starting index of the rest of the doc*/
337                         found_at = i + 1; 
338                         break;
339                 }
340         }
341
342         if( found_at ) {
343                 /* move the shortened doc into the tmp buffer */
344                 strncpy( tmp, encoded_body + found_at, len - found_at );
345                 /* move the tmp buffer back into the allocated space */
346                 memset( encoded_body, 0, len );
347                 strcpy( encoded_body, tmp );
348         }
349
350         return encoded_body;
351 }
352
353
354
355 void jid_get_username( const char* jid, char buf[] ) {
356
357         if( jid == NULL ) { return; }
358
359         /* find the @ and return whatever is in front of it */
360         int len = strlen( jid );
361         int i;
362         for( i = 0; i != len; i++ ) {
363                 if( jid[i] == 64 ) { /*ascii @*/
364                         strncpy( buf, jid, i );
365                         return;
366                 }
367         }
368 }
369
370
371 void jid_get_resource( const char* jid, char buf[])  {
372         if( jid == NULL ) { return; }
373         int len = strlen( jid );
374         int i;
375         for( i = 0; i!= len; i++ ) {
376                 if( jid[i] == 47 ) { /* ascii / */
377                         strncpy( buf, jid + i + 1, len - (i+1) );
378                 }
379         }
380 }
381
382 void jid_get_domain( const char* jid, char buf[] ) {
383
384         if(jid == NULL) return;
385
386         int len = strlen(jid);
387         int i;
388         int index1 = 0; 
389         int index2 = 0;
390
391         for( i = 0; i!= len; i++ ) {
392                 if(jid[i] == 64) /* ascii @ */
393                         index1 = i + 1;
394                 else if(jid[i] == 47 && index1 != 0) /* ascii / */
395                         index2 = i;
396         }
397         if( index1 > 0 && index2 > 0 && index2 > index1 )
398                 memcpy( buf, jid + index1, index2 - index1 );
399 }
400
401 void set_msg_error( transport_message* msg, char* type, int err_code ) {
402
403         if( type != NULL && strlen( type ) > 0 ) {
404                 msg->error_type = safe_malloc( strlen(type)+1); 
405                 strcpy( msg->error_type, type );
406                 msg->error_code = err_code;
407         }
408         msg->is_error = 1;
409 }