00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <string.h>
00029 #include "../../str.h"
00030 #include "../../dprint.h"
00031 #include "../../mem/mem.h"
00032 #include "xr_writer.h"
00033 #include "mi_xmlrpc.h"
00034
00035 static char *reply_buffer = 0;
00036 static unsigned int reply_buffer_len = 0;
00037 static xmlrpc_value* reply_item;
00038
00039 int xr_writer_init( unsigned int size )
00040 {
00041 reply_buffer_len = size;
00042
00043 reply_buffer = pkg_malloc(size);
00044 if(!reply_buffer){
00045 LM_ERR("pkg_malloc cannot allocate any more memory!\n");
00046 return -1;
00047 }
00048
00049 return 0;
00050 }
00051
00052 static int xr_write_node(str * buf, struct mi_node * node)
00053 {
00054 char *end;
00055 char *p;
00056 struct mi_attr* attr;
00057
00058 p = buf->s;
00059 end = buf->s + buf->len -1;
00060
00061
00062 if ( node->name.s != NULL ) {
00063 if ( p+node->name.len+3 > end )
00064 return -1;
00065 memcpy(p, node->name.s, node->name.len);
00066 p += node->name.len;
00067 *(p++) = ':';
00068 *(p++) = ':';
00069 *(p++) = ' ';
00070 }
00071 if ( node->value.s != NULL ) {
00072 if ( p+node->value.len > end )
00073 return -1;
00074 memcpy(p, node->value.s, node->value.len);
00075 p += node->value.len;
00076 }
00077
00078
00079 for( attr=node->attributes ; attr!=NULL ; attr=attr->next ) {
00080 if ( attr->name.s != NULL ) {
00081 if ( p+attr->name.len+2 > end )
00082 return -1;
00083 *(p++) = ' ';
00084 memcpy(p,attr->name.s,attr->name.len);
00085 p += attr->name.len;
00086 *(p++) = '=';
00087 }
00088 if (attr->value.s!=NULL) {
00089 if (p+attr->value.len>end)
00090 return -1;
00091 memcpy(p,attr->value.s,attr->value.len);
00092 p += attr->value.len;
00093 }
00094 }
00095
00096
00097 if ( p+1 > end )
00098 return -1;
00099 *(p++) = '\n';
00100
00101 buf->len -= p-buf->s;
00102 buf->s = p;
00103 return 0;
00104 }
00105
00106 static int recur_build_response_array( xmlrpc_env * env, struct mi_node * tree, str * buf )
00107 {
00108 for ( ; tree ; tree = tree->next ) {
00109
00110 if ( xr_write_node( buf, tree ) != 0 ) {
00111 LM_ERR("failed to get MI node data!\n");
00112 return -1;
00113 }
00114
00115 reply_buffer[reply_buffer_len-buf->len] = 0;
00116 reply_item = xmlrpc_build_value(env, "s", reply_buffer);
00117 xmlrpc_array_append_item(env, xr_response, reply_item);
00118
00119 buf->s = reply_buffer;
00120 buf->len = reply_buffer_len;
00121
00122 if ( tree->kids ) {
00123 if ( recur_build_response_array(env, tree->kids, buf) != 0 )
00124 return -1;
00125 }
00126 }
00127 return 0;
00128 }
00129
00130 int xr_build_response_array( xmlrpc_env * env, struct mi_root * tree )
00131 {
00132 str buf;
00133
00134 buf.s = reply_buffer;
00135 buf.len = reply_buffer_len;
00136
00137
00138 if ( tree->code<200 || tree->code>=300 ){
00139 LM_DBG("command processing failure: %s\n", tree->reason.s);
00140 if (tree->reason.s)
00141 xmlrpc_env_set_fault(env, tree->code, tree->reason.s);
00142 else
00143 xmlrpc_env_set_fault(env, tree->code, "Error");
00144 goto error;
00145 }
00146
00147 if ( recur_build_response_array(env, (&tree->node)->kids, &buf) != 0 ) {
00148 LM_ERR("failed to read from the MI tree!\n");
00149 xmlrpc_env_set_fault(env, 500, "Failed to write reply");
00150 goto error;
00151 }
00152
00153 return 0;
00154
00155 error:
00156 if ( reply_buffer ) pkg_free(reply_buffer);
00157 return -1;
00158 }
00159
00160 static int recur_build_response( xmlrpc_env * env, struct mi_node * tree, str * buf )
00161 {
00162 for ( ; tree ; tree = tree->next ) {
00163
00164 if ( xr_write_node( buf, tree ) != 0 ) {
00165
00166 reply_buffer = (char*) pkg_realloc ( reply_buffer, 2*reply_buffer_len);
00167
00168 if ( !reply_buffer ){
00169 LM_ERR("pkg_realloc cannot reallocate any more memory!\n");
00170 return -1;
00171 }
00172
00173 buf->s = reply_buffer +(reply_buffer_len - buf->len);
00174 buf->len += reply_buffer_len;
00175 reply_buffer_len *=2 ;
00176
00177 if ( xr_write_node( buf, tree ) != 0 ) {
00178 LM_ERR("failed to get MI node data!\n");
00179 return -1;
00180 }
00181 }
00182
00183 if ( tree->kids ) {
00184 if ( recur_build_response(env, tree->kids, buf) != 0 )
00185 return -1;
00186 }
00187 }
00188
00189 return 0;
00190 }
00191
00192 char* xr_build_response( xmlrpc_env * env, struct mi_root * tree )
00193 {
00194 str buf;
00195
00196 buf.s = reply_buffer;
00197 buf.len = reply_buffer_len;
00198
00199 if ( tree->code<200 || tree->code>=300 ){
00200 LM_DBG("command processing failure: %s\n", tree->reason.s);
00201 if (tree->reason.s)
00202 xmlrpc_env_set_fault(env, tree->code, tree->reason.s);
00203 else
00204 xmlrpc_env_set_fault(env, tree->code, "Error");
00205 return 0;
00206 }
00207
00208 if ( recur_build_response(env, (&tree->node)->kids, &buf) != 0 ) {
00209 LM_ERR("failed to read from the MI tree!\n");
00210 xmlrpc_env_set_fault(env, 500, "Failed to build reply");
00211 return 0;
00212 }
00213
00214 reply_buffer[reply_buffer_len-buf.len] = 0;
00215
00216 return reply_buffer;
00217 }