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 <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <time.h>
00032
00033 #include "../../ut.h"
00034 #include "../../dprint.h"
00035 #include "../../data_lump_rpl.h"
00036 #include "../../cmpapi.h"
00037 #include "../../parser/msg_parser.h"
00038 #include "../../parser/parse_event.h"
00039 #include "../../parser/parse_expires.h"
00040 #include "../../parser/parse_cseq.h"
00041 #include "../../parser/parse_from.h"
00042 #include "../../parser/contact/parse_contact.h"
00043 #include "../../parser/parse_rr.h"
00044 #include "../presence/subscribe.h"
00045 #include "../presence/utils_func.h"
00046 #include "../presence/hash.h"
00047 #include "subscribe.h"
00048 #include "notify.h"
00049 #include "rls.h"
00050
00051 int counter= 0;
00052
00053 static str su_200_rpl = str_init("OK");
00054 static str pu_421_rpl = str_init("Extension Required");
00055 static str pu_400_rpl = str_init("Bad request");
00056 static str stale_cseq_rpl = str_init("Stale Cseq Value");
00057 static str pu_489_rpl = str_init("Bad Event");
00058
00059 #define Stale_cseq_code 401
00060
00061 subs_t* constr_new_subs(struct sip_msg* msg, struct to_body *pto,
00062 pres_ev_t* event);
00063 int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node);
00064
00065 int update_rlsubs( subs_t* subs,unsigned int hash_code);
00066
00067 int get_resource_list(str* pres_uri, char** list)
00068 {
00069 db_key_t query_cols[5];
00070 db_val_t query_vals[5];
00071 db_key_t result_cols[3];
00072 int n_query_cols = 0;
00073 db_res_t *result = 0;
00074 db_row_t *row ;
00075 db_val_t *row_vals ;
00076 str body ;
00077 struct sip_uri uri;
00078 int n_result_cols= 0;
00079 int etag_col, xcap_col;
00080 char* etag= NULL;
00081 xcap_get_req_t req;
00082
00083 xcap_doc_sel_t doc_sel;
00084 char* rls_list;
00085
00086 if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
00087 {
00088 LM_ERR("while parsing uri\n");
00089 return -1;
00090 }
00091
00092 query_cols[n_query_cols] = &str_username_col;
00093 query_vals[n_query_cols].type = DB_STR;
00094 query_vals[n_query_cols].nul = 0;
00095 query_vals[n_query_cols].val.str_val = uri.user;
00096 n_query_cols++;
00097
00098 query_cols[n_query_cols] = &str_domain_col;
00099 query_vals[n_query_cols].type = DB_STR;
00100 query_vals[n_query_cols].nul = 0;
00101 query_vals[n_query_cols].val.str_val = uri.host;
00102 n_query_cols++;
00103
00104 query_cols[n_query_cols] = &str_doc_type_col;
00105 query_vals[n_query_cols].type = DB_INT;
00106 query_vals[n_query_cols].nul = 0;
00107 query_vals[n_query_cols].val.int_val= RESOURCE_LIST;
00108 n_query_cols++;
00109
00110 if (rls_dbf.use_table(rls_db, &rls_xcap_table) < 0)
00111 {
00112 LM_ERR("in use_table-[table]= %.*s\n", rls_xcap_table.len, rls_xcap_table.s);
00113 return -1;
00114 }
00115
00116 result_cols[xcap_col= n_result_cols++] = &str_doc_col;
00117 result_cols[etag_col= n_result_cols++]= &str_etag_col;
00118
00119 if(rls_dbf.query(rls_db, query_cols, 0 , query_vals, result_cols,
00120 n_query_cols, n_result_cols, 0, &result)<0)
00121 {
00122 LM_ERR("while querying table xcap for [uri]=%.*s\n",
00123 pres_uri->len, pres_uri->s);
00124 if(result)
00125 rls_dbf.free_result(rls_db, result);
00126 return -1;
00127 }
00128
00129 if(result->n<= 0)
00130 {
00131 LM_DBG("No xcap document for [uri]=%.*s\n",pres_uri->len,pres_uri->s);
00132
00133 if(rls_integrated_xcap_server)
00134 {
00135 rls_dbf.free_result(rls_db, result);
00136 *list= 0;
00137 return 0;
00138 }
00139
00140
00141 doc_sel.auid.s= "resource-lists";
00142 doc_sel.auid.len= strlen("resource-lists");
00143 doc_sel.doc_type= RESOURCE_LIST;
00144 doc_sel.type= USERS_TYPE;
00145 doc_sel.xid= *pres_uri;
00146 doc_sel.filename.s= "index";
00147 doc_sel.filename.len= 5;
00148
00149 memset(&req, 0, sizeof(xcap_get_req_t));
00150 req.xcap_root= xcap_root;
00151 req.port= xcap_port;
00152 req.doc_sel= doc_sel;
00153 req.etag= etag;
00154 req.match_type= IF_NONE_MATCH;
00155
00156 rls_list= xcap_GetNewDoc(req, uri.user, uri.host);
00157 if(rls_list== NULL)
00158 {
00159 LM_ERR("while fetching data from xcap server\n");
00160 goto error;
00161 }
00162
00163 *list= rls_list;
00164 return 0;
00165 }
00166
00167 row = &result->rows[0];
00168 row_vals = ROW_VALUES(row);
00169
00170 body.s = (char*)row_vals[xcap_col].val.string_val;
00171 if(body.s== NULL)
00172 {
00173 LM_ERR("Xcap doc NULL\n");
00174 goto error;
00175 }
00176 body.len = strlen(body.s);
00177 if(body.len== 0)
00178 {
00179 LM_ERR("Xcap doc empty\n");
00180 goto error;
00181 }
00182 LM_DBG("xcap body:\n%.*s", body.len,body.s);
00183 rls_list= (char*)pkg_malloc((body.len+ 1)* sizeof(char));
00184 if(rls_list== NULL)
00185 {
00186 rls_dbf.free_result(rls_db, result);
00187 ERR_MEM(PKG_MEM_STR);
00188 }
00189 memcpy(rls_list, body.s, body.len);
00190 rls_list[body.len]= '\0';
00191 rls_dbf.free_result(rls_db, result);
00192 *list= rls_list;
00193
00194 return 0;
00195
00196 error:
00197 if(result)
00198 rls_dbf.free_result(rls_db, result);
00199 return -1;
00200
00201 }
00202
00203
00204 int reply_421(struct sip_msg* msg)
00205 {
00206 str hdr_append;
00207 char buffer[256];
00208
00209 hdr_append.s = buffer;
00210 hdr_append.s[0]='\0';
00211 hdr_append.len = sprintf(hdr_append.s, "Require: eventlist\r\n");
00212 if(hdr_append.len < 0)
00213 {
00214 LM_ERR("unsuccessful sprintf\n");
00215 return -1;
00216 }
00217 hdr_append.s[hdr_append.len]= '\0';
00218
00219 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00220 {
00221 LM_ERR("unable to add lump_rl\n");
00222 return -1;
00223 }
00224
00225 if (slb.send_reply(msg, 421, &pu_421_rpl) == -1)
00226 {
00227 LM_ERR("while sending reply\n");
00228 return -1;
00229 }
00230 return 0;
00231
00232 }
00233
00234 int reply_200(struct sip_msg* msg, str* contact, int expires)
00235 {
00236 str hdr_append;
00237 int len;
00238
00239 hdr_append.s = (char *)pkg_malloc( sizeof(char)*(contact->len+ 70));
00240 if(hdr_append.s == NULL)
00241 {
00242 LM_ERR("no more pkg memory\n");
00243 return -1;
00244 }
00245 hdr_append.len = sprintf(hdr_append.s, "Expires: %d\r\n", expires);
00246 if(hdr_append.len< 0)
00247 {
00248 LM_ERR("unsuccessful sprintf\n");
00249 goto error;
00250 }
00251 strncpy(hdr_append.s+hdr_append.len ,"Contact: <", 10);
00252 hdr_append.len += 10;
00253 strncpy(hdr_append.s+hdr_append.len, contact->s, contact->len);
00254 hdr_append.len+= contact->len;
00255 strncpy(hdr_append.s+hdr_append.len, ">", 1);
00256 hdr_append.len += 1;
00257 strncpy(hdr_append.s+hdr_append.len, CRLF, CRLF_LEN);
00258 hdr_append.len += CRLF_LEN;
00259
00260 len = sprintf(hdr_append.s+ hdr_append.len, "Require: eventlist\r\n");
00261 if(len < 0)
00262 {
00263 LM_ERR("unsuccessful sprintf\n");
00264 goto error;
00265 }
00266 hdr_append.len+= len;
00267 hdr_append.s[hdr_append.len]= '\0';
00268
00269 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00270 {
00271 LM_ERR("unable to add lump_rl\n");
00272 goto error;
00273 }
00274
00275 if(slb.send_reply(msg, 200, &su_200_rpl)== -1)
00276 {
00277 LM_ERR("while sending reply\n");
00278 goto error;
00279 }
00280 pkg_free(hdr_append.s);
00281 return 0;
00282
00283 error:
00284 pkg_free(hdr_append.s);
00285 return -1;
00286 }
00287
00288 int reply_489(struct sip_msg * msg)
00289 {
00290 str hdr_append;
00291 char buffer[256];
00292 str* ev_list;
00293
00294 hdr_append.s = buffer;
00295 hdr_append.s[0]='\0';
00296 hdr_append.len = sprintf(hdr_append.s, "Allow-Events: ");
00297 if(hdr_append.len < 0)
00298 {
00299 LM_ERR("unsuccessful sprintf\n");
00300 return -1;
00301 }
00302
00303 if(pres_get_ev_list(&ev_list)< 0)
00304 {
00305 LM_ERR("while getting ev_list\n");
00306 return -1;
00307 }
00308 memcpy(hdr_append.s+ hdr_append.len, ev_list->s, ev_list->len);
00309 hdr_append.len+= ev_list->len;
00310 pkg_free(ev_list->s);
00311 pkg_free(ev_list);
00312 memcpy(hdr_append.s+ hdr_append.len, CRLF, CRLF_LEN);
00313 hdr_append.len+= CRLF_LEN;
00314 hdr_append.s[hdr_append.len]= '\0';
00315
00316 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00317 {
00318 LM_ERR("unable to add lump_rl\n");
00319 return -1;
00320 }
00321 if (slb.send_reply(msg, 489, &pu_489_rpl) == -1)
00322 {
00323 LM_ERR("while sending reply\n");
00324 return -1;
00325 }
00326 return 0;
00327 }
00328
00329
00330 int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
00331 {
00332 struct to_body *pto, *pfrom = NULL, TO;
00333 int found= 0;
00334 struct hdr_field* hdr;
00335 subs_t subs;
00336 str resource_list= {0, 0};
00337 int i, len= 0;
00338 pres_ev_t* event= NULL;
00339 int err_ret= -1;
00340 str* contact= NULL;
00341 xmlDocPtr doc= NULL;
00342 xmlNodePtr rl_node= NULL;
00343 unsigned int hash_code;
00344 int to_tag_gen= 0;
00345 event_t* parsed_event;
00346 param_t* ev_param= NULL;
00347
00348
00349
00350 memset(&subs, 0, sizeof(subs_t));
00351
00352 if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00353 {
00354 LM_ERR("parsing headers\n");
00355 if (slb.send_reply(msg, 400, &pu_400_rpl) == -1)
00356 {
00357 LM_ERR("while sending 400 reply\n");
00358 return -1;
00359 }
00360 return 0;
00361 }
00362
00363
00364 if(msg->event && msg->event->body.len > 0)
00365 {
00366 if (!msg->event->parsed && (parse_event(msg->event) < 0))
00367 {
00368 LM_ERR("cannot parse Event header\n");
00369 goto error;
00370 }
00371 if(! ( ((event_t*)msg->event->parsed)->parsed & rls_events) )
00372 {
00373 return to_presence_code;
00374 }
00375 }
00376 else
00377 goto bad_event;
00378
00379
00380 parsed_event= (event_t*)msg->event->parsed;
00381 event= pres_search_event(parsed_event);
00382 if(event== NULL)
00383 {
00384 goto bad_event;
00385 }
00386 subs.event= event;
00387
00388
00389 ev_param= parsed_event->params;
00390 while(ev_param)
00391 {
00392 if(ev_param->name.len== 2 && strncmp(ev_param->name.s, "id", 2)== 0)
00393 {
00394 subs.event_id= ev_param->body;
00395 break;
00396 }
00397 ev_param= ev_param->next;
00398 }
00399
00400
00401 if(msg->to->parsed != NULL)
00402 {
00403 pto = (struct to_body*)msg->to->parsed;
00404 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
00405 }
00406 else
00407 {
00408 memset( &TO , 0, sizeof(TO) );
00409 if( !parse_to(msg->to->body.s,msg->to->body.s+msg->to->body.len+1,&TO));
00410 {
00411 LM_DBG("'To' header NOT parsed\n");
00412 goto error;
00413 }
00414 pto = &TO;
00415 }
00416
00417 if(pto->tag_value.s== NULL || pto->tag_value.len==0)
00418
00419 {
00420
00421 if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
00422 &subs.pres_uri)< 0)
00423 {
00424 LM_ERR("while constructing uri from user and domain\n");
00425 goto error;
00426 }
00427 if( get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
00428 {
00429 LM_ERR("while attepmting to get a resource list\n");
00430 goto error;
00431 }
00432 if( resource_list.s== NULL )
00433 {
00434
00435
00436 return to_presence_code;
00437 }
00438 resource_list.len= strlen(resource_list.s);
00439
00440 }
00441 else
00442 {
00443 if( msg->callid==NULL || msg->callid->body.s==NULL)
00444 {
00445 LM_ERR("cannot parse callid header\n");
00446 goto error;
00447 }
00448 if (msg->from->parsed == NULL)
00449 {
00450 LM_DBG("'From' header not parsed\n");
00451
00452 if ( parse_from_header( msg )<0 )
00453 {
00454 LM_DBG("ERROR cannot parse From header\n");
00455 goto error;
00456 }
00457 }
00458 pfrom = (struct to_body*)msg->from->parsed;
00459 if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00460 {
00461 LM_ERR("no from tag value present\n");
00462 goto error;
00463 }
00464
00465
00466 hash_code= core_hash(&msg->callid->body, &pto->tag_value, hash_size);
00467 lock_get(&rls_table[hash_code].lock);
00468
00469 if(pres_search_shtable(rls_table,msg->callid->body,
00470 pto->tag_value, pfrom->tag_value, hash_code)== NULL)
00471 {
00472 lock_release(&rls_table[hash_code].lock);
00473 return to_presence_code;
00474 }
00475 lock_release(&rls_table[hash_code].lock);
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 hdr= msg->headers;
00490 while(hdr)
00491 {
00492 if(cmp_hdrname_strzn(&hdr->name, "Support", 7)== 0)
00493 break;
00494 hdr= hdr->next;
00495 }
00496 while(hdr!= NULL )
00497 {
00498 len= hdr->body.len- 8;
00499 for(i= 0; i< len; i++)
00500 {
00501 if(strncmp(hdr->body.s+ i, "eventlist", 9)== 0)
00502 {
00503 found= 1;
00504 goto found_support;
00505 }
00506 }
00507 hdr= hdr->sibling;
00508 }
00509
00510 found_support:
00511 if(found== 0)
00512 {
00513 LM_ERR("No 'Support: eventlist' header found\n");
00514 if(reply_421(msg)< 0)
00515 return -1;
00516 return 0;
00517 }
00518
00519
00520
00521 if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
00522 &to_tag_gen, server_address)< 0)
00523 {
00524 LM_ERR("bad Subscribe request\n");
00525 goto error;
00526 }
00527
00528 hash_code= core_hash(&subs.callid, &subs.to_tag, hash_size);
00529
00530 if(pto->tag_value.s== NULL || pto->tag_value.len==0)
00531
00532 {
00533 subs.local_cseq= 0;
00534
00535 if(subs.expires!= 0)
00536 {
00537 subs.version= 1;
00538 if(pres_insert_shtable(rls_table, hash_code, &subs)< 0)
00539 {
00540 LM_ERR("while adding new subscription\n");
00541 goto error;
00542 }
00543 }
00544 }
00545 else
00546 {
00547 str reason;
00548 int rt;
00549
00550 rt= update_rlsubs(&subs, hash_code);
00551 if(rt< 0)
00552 {
00553 LM_ERR("while updating resource list subscription\n");
00554 goto error;
00555 }
00556
00557 if(rt>= 400)
00558 {
00559 reason= (rt==400)?pu_400_rpl:stale_cseq_rpl;
00560
00561 if (slb.send_reply(msg, 400, &reason) == -1)
00562 {
00563 LM_ERR("while sending reply\n");
00564 goto error;
00565 }
00566 return 0;
00567 }
00568
00569 if(get_resource_list(&subs.pres_uri, &resource_list.s)< 0)
00570 {
00571 LM_ERR("when getting resource list\n");
00572 goto error;
00573 }
00574 resource_list.len= strlen(resource_list.s);
00575 }
00576
00577 doc= xmlParseMemory(resource_list.s, resource_list.len);
00578 if(doc== NULL)
00579 {
00580 LM_ERR("while parsing XML memory\n");
00581 goto error;
00582 }
00583 rl_node= XMLDocGetNodeByName(doc, "resource-lists", NULL);
00584 if(rl_node== NULL)
00585 {
00586 LM_ERR("while extracting resource-lists node\n");
00587 goto error;
00588 }
00589
00590
00591
00592 if(resource_subscriptions(&subs, rl_node)< 0)
00593 {
00594 LM_ERR("while sending Subscribe requests to resources in a list\n");
00595 goto error;
00596 }
00597
00598
00599 if(reply_200(msg, &subs.contact, subs.expires)< 0)
00600 goto error;
00601
00602
00603 if(send_full_notify(&subs,rl_node,subs.version,&subs.pres_uri,hash_code)< 0)
00604 {
00605 LM_ERR("while sending full state Notify\n");
00606 goto error;
00607 }
00608 if(contact)
00609 {
00610 if(contact->s)
00611 pkg_free(contact->s);
00612 pkg_free(contact);
00613 }
00614
00615 pkg_free(resource_list.s);
00616 pkg_free(subs.pres_uri.s);
00617
00618 if(subs.record_route.s)
00619 pkg_free(subs.record_route.s);
00620 xmlFreeDoc(doc);
00621 return 1;
00622
00623 bad_event:
00624 if(reply_489(msg)< 0)
00625 {
00626 LM_ERR("while sending 489 reply\n");
00627 err_ret= -1;
00628 }
00629 err_ret= 0;
00630
00631 error:
00632 LM_ERR("occured in rls_handle_subscribe\n");
00633
00634 if(contact)
00635 {
00636 if(contact->s)
00637 pkg_free(contact->s);
00638 pkg_free(contact);
00639 }
00640 if(subs.pres_uri.s)
00641 pkg_free(subs.pres_uri.s);
00642
00643 if(subs.record_route.s)
00644 pkg_free(subs.record_route.s);
00645
00646 if(doc)
00647 xmlFreeDoc(doc);
00648 if(resource_list.s)
00649 pkg_free(resource_list.s);
00650 return err_ret;
00651 }
00652
00653 int update_rlsubs( subs_t* subs, unsigned int hash_code)
00654 {
00655 subs_t* s, *ps;
00656
00657
00658 lock_get(&rls_table[hash_code].lock);
00659
00660 s= pres_search_shtable(rls_table, subs->callid,
00661 subs->to_tag, subs->from_tag, hash_code);
00662 if(s== NULL)
00663 {
00664 LM_DBG("record not found in hash table\n");
00665 lock_release(&rls_table[hash_code].lock);
00666 return -1;
00667 }
00668
00669 s->expires= subs->expires+ (int)time(NULL);
00670 s->remote_cseq= subs->remote_cseq;
00671
00672 if(s->db_flag & NO_UPDATEDB_FLAG)
00673 s->db_flag= UPDATEDB_FLAG;
00674
00675 if( s->remote_cseq>= subs->remote_cseq)
00676 {
00677 lock_release(&rls_table[hash_code].lock);
00678 LM_DBG("stored cseq= %d\n", s->remote_cseq);
00679 return Stale_cseq_code;
00680 }
00681
00682 subs->pres_uri.s= (char*)pkg_malloc(s->pres_uri.len* sizeof(char));
00683 if(subs->pres_uri.s== NULL)
00684 {
00685 ERR_MEM(PKG_MEM_STR);
00686 }
00687 memcpy(subs->pres_uri.s, s->pres_uri.s, s->pres_uri.len);
00688 subs->pres_uri.len= s->pres_uri.len;
00689
00690 if(subs->expires== 0)
00691 {
00692
00693 ps= rls_table[hash_code].entries;
00694 int found= 0;
00695 while(ps->next)
00696 {
00697 if(ps->next== s)
00698 {
00699 found= 1;
00700 break;
00701 }
00702 ps= ps->next;
00703 }
00704 if(found== 0)
00705 {
00706 LM_ERR("record not found\n");
00707 goto error;
00708 }
00709 ps->next= s->next;
00710 shm_free(s);
00711 }
00712 else
00713 {
00714 s->remote_cseq= subs->remote_cseq;
00715 s->expires= subs->expires+ (int)time(NULL);
00716 }
00717
00718 subs->local_cseq= s->local_cseq;
00719 subs->version= s->version;
00720
00721 lock_release(&rls_table[hash_code].lock);
00722
00723 return 0;
00724
00725 error:
00726 lock_release(&rls_table[hash_code].lock);
00727 return -1;
00728 }
00729
00730 int send_resource_subs(char* uri, void* param)
00731 {
00732 str pres_uri;
00733
00734 pres_uri.s= uri;
00735 pres_uri.len= strlen(uri);
00736
00737 ((subs_info_t*)param)->pres_uri= &pres_uri;
00738
00739 return pua_send_subscribe((subs_info_t*)param);
00740 }
00741
00742 int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node)
00743 {
00744 char* uri= NULL;
00745 subs_info_t s;
00746 str wuri= {0, 0};
00747 static char buf[64];
00748 str extra_headers;
00749 str did_str= {0, 0};
00750
00751
00752
00753
00754 CONSTR_RLSUBS_DID(subs, &did_str);
00755
00756 memset(&s, 0, sizeof(subs_info_t));
00757
00758 if( uandd_to_uri(subs->from_user, subs->from_domain, &wuri)< 0)
00759 {
00760 LM_ERR("while constructing uri from user and domain\n");
00761 goto error;
00762 }
00763 s.id= did_str;
00764 s.watcher_uri= &wuri;
00765 s.contact= &subs->local_contact;
00766 s.event= get_event_flag(&subs->event->name);
00767 if(s.event< 0)
00768 {
00769 LM_ERR("not recognized event\n");
00770 goto error;
00771 }
00772 s.expires= subs->expires;
00773 s.source_flag= RLS_SUBSCRIBE;
00774 extra_headers.s= buf;
00775 extra_headers.len= sprintf(extra_headers.s,
00776 "Max-Forwards: 70\r\nSupport: eventlist\r\n");
00777 s.extra_headers= &extra_headers;
00778
00779 if(process_list_and_exec(rl_node, send_resource_subs,(void*)(&s))< 0)
00780 {
00781 LM_ERR("while processing list\n");
00782 goto error;
00783 }
00784
00785 pkg_free(wuri.s);
00786 pkg_free(did_str.s);
00787
00788 return 0;
00789
00790 error:
00791 if(wuri.s)
00792 pkg_free(wuri.s);
00793 if(uri)
00794 xmlFree(uri);
00795 if(did_str.s)
00796 pkg_free(did_str.s);
00797 return -1;
00798
00799 }
00800