00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036
00037 #include "../../lib/srdb1/db.h"
00038 #include "../../hashes.h"
00039 #include "../../dprint.h"
00040 #include "../../mem/shm_mem.h"
00041 #include "../../str.h"
00042 #include "../alias_db/alias_db.h"
00043 #include "../../data_lump_rpl.h"
00044 #include "presentity.h"
00045 #include "presence.h"
00046 #include "notify.h"
00047 #include "publish.h"
00048 #include "hash.h"
00049 #include "utils_func.h"
00050
00051
00052 xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
00053 const char *ns);
00054 static str pu_200_rpl = str_init("OK");
00055 static str pu_412_rpl = str_init("Conditional request failed");
00056
00057 static str str_offline_etag_val = str_init("*#-OFFLINE-#*");
00058
00059 #define ETAG_LEN 128
00060
00061 char* generate_ETag(int publ_count)
00062 {
00063 char* etag= NULL;
00064 int size = 0;
00065
00066 etag = (char*)pkg_malloc(ETAG_LEN*sizeof(char));
00067 if(etag ==NULL)
00068 {
00069 ERR_MEM(PKG_MEM_STR);
00070 }
00071 memset(etag, 0, ETAG_LEN*sizeof(char));
00072 size = snprintf (etag, ETAG_LEN, "%c.%d.%d.%d.%d",prefix, startup_time, pid, counter, publ_count);
00073 if( size <0 )
00074 {
00075 LM_ERR("unsuccessfull snprintf\n ");
00076 pkg_free(etag);
00077 return NULL;
00078 }
00079 if(size >= ETAG_LEN)
00080 {
00081 LM_ERR("buffer size overflown\n");
00082 pkg_free(etag);
00083 return NULL;
00084 }
00085
00086 etag[size] = '\0';
00087 LM_DBG("etag= %s / %d\n ",etag, size);
00088 return etag;
00089
00090 error:
00091 return NULL;
00092
00093 }
00094
00095 int publ_send200ok(struct sip_msg *msg, int lexpire, str etag)
00096 {
00097 char buf[128];
00098 int buf_len= 128, size;
00099 str hdr_append= {0, 0}, hdr_append2= {0, 0} ;
00100
00101 if (msg == NULL)
00102 return 0;
00103
00104 LM_DBG("send 200OK reply\n");
00105 LM_DBG("etag= %s - len= %d\n", etag.s, etag.len);
00106
00107 hdr_append.s = buf;
00108 hdr_append.s[0]='\0';
00109 hdr_append.len = snprintf(hdr_append.s, buf_len, "Expires: %d\r\n",
00110 ((lexpire==0)?0:(lexpire-expires_offset)));
00111 if(hdr_append.len < 0)
00112 {
00113 LM_ERR("unsuccessful snprintf\n");
00114 goto error;
00115 }
00116 if(hdr_append.len >= buf_len)
00117 {
00118 LM_ERR("buffer size overflown\n");
00119 goto error;
00120 }
00121 hdr_append.s[hdr_append.len]= '\0';
00122
00123 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00124 {
00125 LM_ERR("unable to add lump_rl\n");
00126 goto error;
00127 }
00128
00129 size= sizeof(char)*(20+etag.len) ;
00130 hdr_append2.s = (char *)pkg_malloc(size);
00131 if(hdr_append2.s == NULL)
00132 {
00133 ERR_MEM(PKG_MEM_STR);
00134 }
00135 hdr_append2.s[0]='\0';
00136 hdr_append2.len = snprintf(hdr_append2.s, size, "SIP-ETag: %s\r\n", etag.s);
00137 if(hdr_append2.len < 0)
00138 {
00139 LM_ERR("unsuccessful snprintf\n ");
00140 goto error;
00141 }
00142 if(hdr_append2.len >= size)
00143 {
00144 LM_ERR("buffer size overflown\n");
00145 goto error;
00146 }
00147
00148 hdr_append2.s[hdr_append2.len]= '\0';
00149 if (add_lump_rpl(msg, hdr_append2.s, hdr_append2.len, LUMP_RPL_HDR)==0 )
00150 {
00151 LM_ERR("unable to add lump_rl\n");
00152 goto error;
00153 }
00154
00155 if(slb.freply(msg, 200, &pu_200_rpl) < 0)
00156 {
00157 LM_ERR("sending reply\n");
00158 goto error;
00159 }
00160
00161 pkg_free(hdr_append2.s);
00162 return 0;
00163
00164 error:
00165
00166 if(hdr_append2.s)
00167 pkg_free(hdr_append2.s);
00168
00169 return -1;
00170 }
00171 presentity_t* new_presentity( str* domain,str* user,int expires,
00172 pres_ev_t* event, str* etag, str* sender)
00173 {
00174 presentity_t *presentity= NULL;
00175 int size, init_len;
00176
00177
00178 size = sizeof(presentity_t)+ domain->len+ user->len+ etag->len +1;
00179 if(sender)
00180 size+= sizeof(str)+ sender->len* sizeof(char);
00181
00182 init_len= size;
00183
00184 presentity = (presentity_t*)pkg_malloc(size);
00185 if(presentity == NULL)
00186 {
00187 ERR_MEM(PKG_MEM_STR);
00188 }
00189 memset(presentity, 0, size);
00190 size= sizeof(presentity_t);
00191
00192 presentity->domain.s = (char*)presentity+ size;
00193 strncpy(presentity->domain.s, domain->s, domain->len);
00194 presentity->domain.len = domain->len;
00195 size+= domain->len;
00196
00197 presentity->user.s = (char*)presentity+size;
00198 strncpy(presentity->user.s, user->s, user->len);
00199 presentity->user.len = user->len;
00200 size+= user->len;
00201
00202 presentity->etag.s = (char*)presentity+ size;
00203 memcpy(presentity->etag.s, etag->s, etag->len);
00204 presentity->etag.s[etag->len]= '\0';
00205 presentity->etag.len = etag->len;
00206
00207 size+= etag->len+1;
00208
00209 if(sender)
00210 {
00211 presentity->sender= (str*)((char*)presentity+ size);
00212 size+= sizeof(str);
00213 presentity->sender->s= (char*)presentity + size;
00214 memcpy(presentity->sender->s, sender->s, sender->len);
00215 presentity->sender->len= sender->len;
00216 size+= sender->len;
00217 }
00218
00219 if(size> init_len)
00220 {
00221 LM_ERR("buffer size overflow init_len= %d, size= %d\n", init_len, size);
00222 goto error;
00223 }
00224 presentity->event= event;
00225 presentity->expires = expires;
00226 presentity->received_time= (int)time(NULL);
00227 return presentity;
00228
00229 error:
00230 if(presentity)
00231 pkg_free(presentity);
00232 return NULL;
00233 }
00234
00235 xmlNodePtr xmlNodeGetChildByName(xmlNodePtr node, const char *name)
00236 {
00237 xmlNodePtr cur = node->children;
00238 while (cur) {
00239 if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0)
00240 return cur;
00241 cur = cur->next;
00242 }
00243 return NULL;
00244 }
00245
00246 int check_if_dialog(str body, int *is_dialog)
00247 {
00248 xmlDocPtr doc;
00249 xmlNodePtr node;
00250
00251 doc = xmlParseMemory(body.s, body.len);
00252 if(doc== NULL)
00253 {
00254 LM_ERR("failed to parse xml document\n");
00255 return -1;
00256 }
00257
00258 node = doc->children;
00259 node = xmlNodeGetChildByName(node, "dialog");
00260
00261 if(node == NULL)
00262 *is_dialog = 0;
00263 else
00264 *is_dialog = 1;
00265
00266 xmlFreeDoc(doc);
00267 return 0;
00268 }
00269
00270
00271 int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
00272 int new_t, int* sent_reply, char* sphere)
00273 {
00274 db_key_t query_cols[12], update_keys[8], result_cols[5];
00275 db_op_t query_ops[12];
00276 db_val_t query_vals[12], update_vals[8];
00277 db1_res_t *result= NULL;
00278 int n_query_cols = 0;
00279 int n_update_cols = 0;
00280 char* dot= NULL;
00281 str etag= {0, 0};
00282 str cur_etag= {0, 0};
00283 str* rules_doc= NULL;
00284 str pres_uri= {0, 0};
00285 int rez_body_col, rez_sender_col, n_result_cols= 0;
00286 db_row_t *row = NULL ;
00287 db_val_t *row_vals = NULL;
00288 str old_body, sender;
00289 int is_dialog= 0, bla_update_publish= 1;
00290 int affected_rows = 0;
00291 int ret = -1;
00292 int db_record_exists = 0;
00293 int num_watchers = 0;
00294
00295 if (sent_reply) *sent_reply= 0;
00296 if(pres_notifier_processes == 0 && presentity->event->req_auth)
00297 {
00298
00299 if(presentity->event->get_rules_doc(&presentity->user,
00300 &presentity->domain, &rules_doc))
00301 {
00302 LM_ERR("getting rules doc\n");
00303 goto error;
00304 }
00305 }
00306
00307 if(uandd_to_uri(presentity->user, presentity->domain, &pres_uri)< 0)
00308 {
00309 LM_ERR("constructing uri from user and domain\n");
00310 goto error;
00311 }
00312
00313
00314 query_cols[n_query_cols] = &str_domain_col;
00315 query_ops[n_query_cols] = OP_EQ;
00316 query_vals[n_query_cols].type = DB1_STR;
00317 query_vals[n_query_cols].nul = 0;
00318 query_vals[n_query_cols].val.str_val = presentity->domain;
00319 n_query_cols++;
00320
00321 query_cols[n_query_cols] = &str_username_col;
00322 query_ops[n_query_cols] = OP_EQ;
00323 query_vals[n_query_cols].type = DB1_STR;
00324 query_vals[n_query_cols].nul = 0;
00325 query_vals[n_query_cols].val.str_val = presentity->user;
00326 n_query_cols++;
00327
00328 query_cols[n_query_cols] = &str_event_col;
00329 query_ops[n_query_cols] = OP_EQ;
00330 query_vals[n_query_cols].type = DB1_STR;
00331 query_vals[n_query_cols].nul = 0;
00332 query_vals[n_query_cols].val.str_val = presentity->event->name;
00333 n_query_cols++;
00334
00335 query_cols[n_query_cols] = &str_etag_col;
00336 query_ops[n_query_cols] = OP_EQ;
00337 query_vals[n_query_cols].type = DB1_STR;
00338 query_vals[n_query_cols].nul = 0;
00339 query_vals[n_query_cols].val.str_val = presentity->etag;
00340 n_query_cols++;
00341
00342 result_cols[rez_body_col= n_result_cols++] = &str_body_col;
00343 result_cols[rez_sender_col= n_result_cols++] = &str_sender_col;
00344
00345 if(new_t)
00346 {
00347
00348
00349 if ( publ_cache_enabled &&
00350 insert_phtable(&pres_uri, presentity->event->evp->type, sphere)< 0)
00351 {
00352 LM_ERR("inserting record in hash table\n");
00353 goto error;
00354 }
00355
00356
00357 query_cols[n_query_cols] = &str_sender_col;
00358 query_vals[n_query_cols].type = DB1_STR;
00359 query_vals[n_query_cols].nul = 0;
00360 if(presentity->sender)
00361 {
00362 query_vals[n_query_cols].val.str_val.s = presentity->sender->s;
00363 query_vals[n_query_cols].val.str_val.len = presentity->sender->len;
00364 } else {
00365 query_vals[n_query_cols].val.str_val.s = "";
00366 query_vals[n_query_cols].val.str_val.len = 0;
00367 }
00368 n_query_cols++;
00369
00370 query_cols[n_query_cols] = &str_body_col;
00371 query_vals[n_query_cols].type = DB1_BLOB;
00372 query_vals[n_query_cols].nul = 0;
00373 query_vals[n_query_cols].val.str_val = *body;
00374 n_query_cols++;
00375
00376 query_cols[n_query_cols] = &str_received_time_col;
00377 query_vals[n_query_cols].type = DB1_INT;
00378 query_vals[n_query_cols].nul = 0;
00379 query_vals[n_query_cols].val.int_val = presentity->received_time;
00380 n_query_cols++;
00381
00382 if (presentity->expires != -1)
00383 {
00384
00385 query_cols[n_query_cols] = &str_expires_col;
00386 query_vals[n_query_cols].type = DB1_INT;
00387 query_vals[n_query_cols].nul = 0;
00388 query_vals[n_query_cols].val.int_val = presentity->expires+
00389 (int)time(NULL);
00390 n_query_cols++;
00391
00392 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00393 {
00394 LM_ERR("unsuccessful use_table\n");
00395 goto error;
00396 }
00397
00398 LM_DBG("inserting %d cols into table\n",n_query_cols);
00399
00400 if (pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols) < 0)
00401 {
00402 LM_ERR("inserting new record in database\n");
00403 goto error;
00404 }
00405 }
00406 else
00407 {
00408
00409 query_cols[n_query_cols] = &str_expires_col;
00410 query_vals[n_query_cols].type = DB1_INT;
00411 query_vals[n_query_cols].nul = 0;
00412 query_vals[n_query_cols].val.int_val = -1;
00413 n_query_cols++;
00414
00415 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00416 {
00417 LM_ERR("unsuccessful use_table\n");
00418 goto error;
00419 }
00420
00421 if (pa_dbf.replace == NULL)
00422 {
00423 LM_ERR("replace is required for pidf-manipulation support\n");
00424 goto error;
00425 }
00426 if (pa_dbf.replace(pa_db, query_cols, query_vals, n_query_cols, 4, 0) < 0)
00427 {
00428 LM_ERR("replacing record in database\n");
00429 goto error;
00430 }
00431 }
00432
00433 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00434 {
00435 LM_ERR("sending 200OK\n");
00436 goto error;
00437 }
00438 if (sent_reply) *sent_reply= 1;
00439 goto send_notify;
00440 }
00441 else
00442 {
00443
00444 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00445 {
00446 LM_ERR("unsuccessful sql use table\n");
00447 goto error;
00448 }
00449
00450 if(EVENT_DIALOG_SLA(presentity->event->evp))
00451 {
00452
00453 if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals,
00454 result_cols, n_query_cols, n_result_cols, 0, &result) < 0)
00455 {
00456 LM_ERR("unsuccessful sql query\n");
00457 goto error;
00458 }
00459 if(result== NULL)
00460 goto error;
00461
00462 if (!(result->n > 0))
00463 goto send_412;
00464
00465 db_record_exists= 1;
00466
00467 row = &result->rows[0];
00468 row_vals = ROW_VALUES(row);
00469
00470 old_body.s = (char*)row_vals[rez_body_col].val.string_val;
00471 old_body.len = strlen(old_body.s);
00472 if(check_if_dialog(*body, &is_dialog)< 0)
00473 {
00474 LM_ERR("failed to check if dialog stored\n");
00475 goto error;
00476 }
00477
00478 if(is_dialog== 1)
00479 goto after_dialog_check;
00480
00481 if(check_if_dialog(old_body, &is_dialog)< 0)
00482 {
00483 LM_ERR("failed to check if dialog stored\n");
00484 goto error;
00485 }
00486
00487 if(is_dialog==0 )
00488 goto after_dialog_check;
00489
00490 sender.s = (char*)row_vals[rez_sender_col].val.string_val;
00491 sender.len= strlen(sender.s);
00492
00493 LM_DBG("old_sender = %.*s\n", sender.len, sender.s );
00494 if(presentity->sender)
00495 {
00496 if(!(presentity->sender->len == sender.len &&
00497 strncmp(presentity->sender->s, sender.s, sender.len)== 0))
00498 bla_update_publish= 0;
00499 }
00500 after_dialog_check:
00501 pa_dbf.free_result(pa_db, result);
00502 result = NULL;
00503
00504 }
00505
00506 if(presentity->expires <= 0)
00507 {
00508
00509 if (!db_record_exists)
00510 {
00511 if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals,
00512 result_cols, n_query_cols, n_result_cols, 0, &result) < 0)
00513 {
00514 LM_ERR("unsuccessful sql query\n");
00515 goto error;
00516 }
00517 if(result== NULL)
00518 goto error;
00519
00520 if (!(result->n > 0))
00521 goto send_412;
00522
00523 db_record_exists = 1;
00524
00525 pa_dbf.free_result(pa_db, result);
00526 result = NULL;
00527 }
00528
00529 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00530 {
00531 LM_ERR("sending 200OK reply\n");
00532 goto error;
00533 }
00534 if (sent_reply) *sent_reply= 1;
00535
00536 if (pres_notifier_processes > 0)
00537 {
00538 if ((num_watchers = publ_notify_notifier(pres_uri, presentity->event)) < 0)
00539 {
00540 LM_ERR("updating watcher records\n");
00541 goto error;
00542 }
00543
00544 if (num_watchers > 0)
00545 {
00546 if (mark_presentity_for_delete(presentity) < 0)
00547 {
00548 LM_ERR("Marking presentities\n");
00549 goto error;
00550 }
00551 }
00552 }
00553 else
00554 {
00555 if( publ_notify( presentity, pres_uri, body, &presentity->etag, rules_doc)< 0 )
00556 {
00557 LM_ERR("while sending notify\n");
00558 goto error;
00559 }
00560 }
00561
00562 if (pres_notifier_processes == 0 || num_watchers == 0)
00563 {
00564 if (delete_presentity(presentity) < 0)
00565 {
00566 LM_ERR("Deleting presentity\n");
00567 goto error;
00568 }
00569
00570 LM_DBG("deleted from db %.*s\n", presentity->user.len, presentity->user.s);
00571 }
00572
00573
00574 if( publ_cache_enabled &&
00575 delete_phtable(&pres_uri, presentity->event->evp->type)< 0)
00576 {
00577 LM_ERR("deleting record from hash table\n");
00578 goto error;
00579 }
00580 goto done;
00581 }
00582
00583 n_update_cols= 0;
00584
00585
00586 if( EVENT_DIALOG_SLA(presentity->event->evp) && bla_update_publish==0)
00587 {
00588 LM_DBG("drop Publish for BLA from a different sender that"
00589 " wants to overwrite an existing dialog\n");
00590 LM_DBG("sender = %.*s\n", presentity->sender->len, presentity->sender->s );
00591 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00592 {
00593 LM_ERR("sending 200OK reply\n");
00594 goto error;
00595 }
00596 if (sent_reply) *sent_reply= 1;
00597 goto done;
00598 }
00599
00600 if(presentity->event->etag_not_new== 0)
00601 {
00602
00603 unsigned int publ_nr;
00604 str str_publ_nr= {0, 0};
00605
00606 dot= presentity->etag.s+ presentity->etag.len;
00607 while(*dot!= '.' && str_publ_nr.len< presentity->etag.len)
00608 {
00609 str_publ_nr.len++;
00610 dot--;
00611 }
00612 if(str_publ_nr.len== presentity->etag.len)
00613 {
00614 LM_ERR("wrong etag\n");
00615 goto error;
00616 }
00617 str_publ_nr.s= dot+1;
00618 str_publ_nr.len--;
00619
00620 if( str2int(&str_publ_nr, &publ_nr)< 0)
00621 {
00622 LM_ERR("converting string to int\n");
00623 goto error;
00624 }
00625 etag.s = generate_ETag(publ_nr+1);
00626 if(etag.s == NULL)
00627 {
00628 LM_ERR("while generating etag\n");
00629 goto error;
00630 }
00631 etag.len=(strlen(etag.s));
00632
00633 cur_etag= etag;
00634
00635 update_keys[n_update_cols] = &str_etag_col;
00636 update_vals[n_update_cols].type = DB1_STR;
00637 update_vals[n_update_cols].nul = 0;
00638 update_vals[n_update_cols].val.str_val = etag;
00639 n_update_cols++;
00640
00641 }
00642 else
00643 cur_etag= presentity->etag;
00644
00645 update_keys[n_update_cols] = &str_expires_col;
00646 update_vals[n_update_cols].type = DB1_INT;
00647 update_vals[n_update_cols].nul = 0;
00648 update_vals[n_update_cols].val.int_val= presentity->expires +
00649 (int)time(NULL);
00650 n_update_cols++;
00651
00652 update_keys[n_update_cols] = &str_received_time_col;
00653 update_vals[n_update_cols].type = DB1_INT;
00654 update_vals[n_update_cols].nul = 0;
00655 update_vals[n_update_cols].val.int_val= presentity->received_time;
00656 n_update_cols++;
00657
00658 if(body && body->s)
00659 {
00660 update_keys[n_update_cols] = &str_body_col;
00661 update_vals[n_update_cols].type = DB1_BLOB;
00662 update_vals[n_update_cols].nul = 0;
00663 update_vals[n_update_cols].val.str_val = *body;
00664 n_update_cols++;
00665
00666
00667 if(sphere_enable &&
00668 presentity->event->evp->type== EVENT_PRESENCE)
00669 {
00670 if( publ_cache_enabled &&
00671 update_phtable(presentity, pres_uri, *body)< 0)
00672 {
00673 LM_ERR("failed to update sphere for presentity\n");
00674 goto error;
00675 }
00676 }
00677 }
00678
00679
00680 if( presentity->sender)
00681 {
00682 update_keys[n_update_cols] = &str_sender_col;
00683 update_vals[n_update_cols].type = DB1_STR;
00684 update_vals[n_update_cols].nul = 0;
00685 update_vals[n_update_cols].val.str_val = *presentity->sender;
00686 n_update_cols++;
00687 }
00688
00689
00690 if (!pa_dbf.affected_rows && !db_record_exists)
00691 {
00692 if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals,
00693 result_cols, n_query_cols, n_result_cols, 0, &result) < 0)
00694 {
00695 LM_ERR("unsuccessful sql query\n");
00696 goto error;
00697 }
00698 if(result== NULL)
00699 goto error;
00700
00701 if (!(result->n > 0))
00702 goto send_412;
00703
00704 db_record_exists = 1;
00705 pa_dbf.free_result(pa_db, result);
00706 result = NULL;
00707 }
00708
00709 if( pa_dbf.update( pa_db,query_cols, query_ops, query_vals,
00710 update_keys, update_vals, n_query_cols, n_update_cols )<0)
00711 {
00712 LM_ERR("updating published info in database\n");
00713 goto error;
00714 }
00715
00716 if (pa_dbf.affected_rows && !db_record_exists)
00717 {
00718 if ((affected_rows = pa_dbf.affected_rows ( pa_db ))<0)
00719 {
00720 LM_ERR("unsuccessful sql affected rows operation");
00721 goto error;
00722 }
00723
00724 LM_DBG ("affected rows after update: %d\n", affected_rows );
00725 }
00726
00727
00728
00729 if ((pa_dbf.affected_rows && !affected_rows) || (!pa_dbf.affected_rows && !db_record_exists))
00730 goto send_412;
00731
00732
00733 if (publ_send200ok(msg, presentity->expires, cur_etag)< 0)
00734 {
00735 LM_ERR("sending 200OK reply\n");
00736 goto error;
00737 }
00738 if (sent_reply) *sent_reply= 1;
00739
00740 if(etag.s)
00741 pkg_free(etag.s);
00742 etag.s= NULL;
00743
00744 if(!body)
00745 goto done;
00746 }
00747
00748 send_notify:
00749
00750
00751 if (pres_notifier_processes > 0)
00752 {
00753 if (publ_notify_notifier(pres_uri, presentity->event) < 0)
00754 {
00755 LM_ERR("updating watcher records\n");
00756 goto error;
00757 }
00758 }
00759 else
00760 {
00761 if( publ_notify( presentity, pres_uri, body, NULL, rules_doc)< 0 )
00762 {
00763 LM_ERR("while sending notify\n");
00764 goto error;
00765 }
00766 }
00767
00768 done:
00769 if(rules_doc)
00770 {
00771 if(rules_doc->s)
00772 pkg_free(rules_doc->s);
00773 pkg_free(rules_doc);
00774 }
00775 if(pres_uri.s)
00776 pkg_free(pres_uri.s);
00777
00778 return 0;
00779
00780 send_412:
00781
00782 LM_ERR("No E_Tag match %*s\n", presentity->etag.len, presentity->etag.s);
00783 if (msg != NULL)
00784 {
00785 if (slb.freply(msg, 412, &pu_412_rpl) < 0)
00786 {
00787 LM_ERR("sending '412 Conditional request failed' reply\n");
00788 goto error;
00789 }
00790 }
00791 if (sent_reply) *sent_reply= 1;
00792 ret = 0;
00793
00794 error:
00795 if(result)
00796 pa_dbf.free_result(pa_db, result);
00797 if(etag.s)
00798 pkg_free(etag.s);
00799 if(rules_doc)
00800 {
00801 if(rules_doc->s)
00802 pkg_free(rules_doc->s);
00803 pkg_free(rules_doc);
00804 }
00805 if(pres_uri.s)
00806 pkg_free(pres_uri.s);
00807
00808 return ret;
00809 }
00810
00811 int pres_htable_restore(void)
00812 {
00813
00814
00815 db_key_t result_cols[6];
00816 db1_res_t *result= NULL;
00817 db_row_t *row= NULL ;
00818 db_val_t *row_vals;
00819 int i;
00820 str user, domain, ev_str, uri, body;
00821 int n_result_cols= 0;
00822 int user_col, domain_col, event_col, expires_col, body_col = 0;
00823 int event;
00824 event_t ev;
00825 char* sphere= NULL;
00826
00827 result_cols[user_col= n_result_cols++]= &str_username_col;
00828 result_cols[domain_col= n_result_cols++]= &str_domain_col;
00829 result_cols[event_col= n_result_cols++]= &str_event_col;
00830 result_cols[expires_col= n_result_cols++]= &str_expires_col;
00831 if(sphere_enable)
00832 result_cols[body_col= n_result_cols++]= &str_body_col;
00833
00834 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00835 {
00836 LM_ERR("unsuccessful use table sql operation\n");
00837 goto error;
00838 }
00839
00840 static str query_str = str_init("username");
00841 if (db_fetch_query(&pa_dbf, pres_fetch_rows, pa_db, 0, 0, 0, result_cols,
00842 0, n_result_cols, &query_str, &result) < 0)
00843 {
00844 LM_ERR("querying presentity\n");
00845 goto error;
00846 }
00847 if(result== NULL)
00848 goto error;
00849
00850 if(result->n<= 0)
00851 {
00852 pa_dbf.free_result(pa_db, result);
00853 return 0;
00854 }
00855
00856 do {
00857 for(i= 0; i< result->n; i++)
00858 {
00859 row = &result->rows[i];
00860 row_vals = ROW_VALUES(row);
00861
00862 if(row_vals[expires_col].val.int_val< (int)time(NULL))
00863 continue;
00864
00865 sphere= NULL;
00866 user.s= (char*)row_vals[user_col].val.string_val;
00867 user.len= strlen(user.s);
00868 domain.s= (char*)row_vals[domain_col].val.string_val;
00869 domain.len= strlen(domain.s);
00870 ev_str.s= (char*)row_vals[event_col].val.string_val;
00871 ev_str.len= strlen(ev_str.s);
00872
00873 if(event_parser(ev_str.s, ev_str.len, &ev)< 0)
00874 {
00875 LM_ERR("parsing event\n");
00876 free_event_params(ev.params.list, PKG_MEM_TYPE);
00877 goto error;
00878 }
00879 event= ev.type;
00880 free_event_params(ev.params.list, PKG_MEM_TYPE);
00881
00882 if(uandd_to_uri(user, domain, &uri)< 0)
00883 {
00884 LM_ERR("constructing uri\n");
00885 goto error;
00886 }
00887
00888
00889 if(sphere_enable && event== EVENT_PRESENCE )
00890 {
00891 body.s= (char*)row_vals[body_col].val.string_val;
00892 body.len= strlen(body.s);
00893 sphere= extract_sphere(body);
00894 }
00895
00896 if(insert_phtable(&uri, event, sphere)< 0)
00897 {
00898 LM_ERR("inserting record in presentity hash table");
00899 pkg_free(uri.s);
00900 if(sphere)
00901 pkg_free(sphere);
00902 goto error;
00903 }
00904 if(sphere)
00905 pkg_free(sphere);
00906 pkg_free(uri.s);
00907 }
00908 } while((db_fetch_next(&pa_dbf, pres_fetch_rows, pa_db, &result)==1)
00909 && (RES_ROW_N(result)>0));
00910
00911 pa_dbf.free_result(pa_db, result);
00912
00913 return 0;
00914
00915 error:
00916 if(result)
00917 pa_dbf.free_result(pa_db, result);
00918 return -1;
00919 }
00920
00921 char* extract_sphere(str body)
00922 {
00923
00924
00925 xmlDocPtr doc= NULL;
00926 xmlNodePtr node;
00927 char* cont, *sphere= NULL;
00928
00929
00930 doc= xmlParseMemory(body.s, body.len);
00931 if(doc== NULL)
00932 {
00933 LM_ERR("failed to parse xml body\n");
00934 return NULL;
00935 }
00936
00937 node= xmlNodeGetNodeByName(doc->children, "sphere", "rpid");
00938
00939 if(node== NULL)
00940 node= xmlNodeGetNodeByName(doc->children, "sphere", "r");
00941
00942 if(node)
00943 {
00944 LM_DBG("found sphere definition\n");
00945 cont= (char*)xmlNodeGetContent(node);
00946 if(cont== NULL)
00947 {
00948 LM_ERR("failed to extract sphere node content\n");
00949 goto error;
00950 }
00951 sphere= (char*)pkg_malloc((strlen(cont)+ 1)*sizeof(char));
00952 if(sphere== NULL)
00953 {
00954 xmlFree(cont);
00955 ERR_MEM(PKG_MEM_STR);
00956 }
00957 strcpy(sphere, cont);
00958 xmlFree(cont);
00959 }
00960 else
00961 LM_DBG("didn't find sphere definition\n");
00962
00963 error:
00964 xmlFreeDoc(doc);
00965
00966 return sphere;
00967 }
00968
00969 xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
00970 const char *ns)
00971 {
00972 xmlNodePtr cur = node;
00973 while (cur) {
00974 xmlNodePtr match = NULL;
00975 if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) {
00976 if (!ns || (cur->ns && xmlStrcasecmp(cur->ns->prefix,
00977 (unsigned char*)ns) == 0))
00978 return cur;
00979 }
00980 match = xmlNodeGetNodeByName(cur->children, name, ns);
00981 if (match)
00982 return match;
00983 cur = cur->next;
00984 }
00985 return NULL;
00986 }
00987
00988 char* get_sphere(str* pres_uri)
00989 {
00990 unsigned int hash_code;
00991 char* sphere= NULL;
00992 pres_entry_t* p;
00993 db_key_t query_cols[6];
00994 db_val_t query_vals[6];
00995 db_key_t result_cols[6];
00996 db1_res_t *result = NULL;
00997 db_row_t *row= NULL;
00998 db_val_t *row_vals;
00999 int n_result_cols = 0;
01000 int n_query_cols = 0;
01001 struct sip_uri uri;
01002 str body;
01003
01004
01005 if(!sphere_enable)
01006 return NULL;
01007
01008 if ( publ_cache_enabled )
01009 {
01010
01011 hash_code= core_hash(pres_uri, NULL, phtable_size);
01012
01013 lock_get(&pres_htable[hash_code].lock);
01014
01015 p= search_phtable(pres_uri, EVENT_PRESENCE, hash_code);
01016
01017 if(p)
01018 {
01019 if(p->sphere)
01020 {
01021 sphere= (char*)pkg_malloc(strlen(p->sphere)* sizeof(char));
01022 if(sphere== NULL)
01023 {
01024 lock_release(&pres_htable[hash_code].lock);
01025 ERR_MEM(PKG_MEM_STR);
01026 }
01027 strcpy(sphere, p->sphere);
01028 }
01029 lock_release(&pres_htable[hash_code].lock);
01030 return sphere;
01031 }
01032 lock_release(&pres_htable[hash_code].lock);
01033 }
01034
01035 if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
01036 {
01037 LM_ERR("failed to parse presentity uri\n");
01038 goto error;
01039 }
01040
01041 query_cols[n_query_cols] = &str_domain_col;
01042 query_vals[n_query_cols].type = DB1_STR;
01043 query_vals[n_query_cols].nul = 0;
01044 query_vals[n_query_cols].val.str_val = uri.host;
01045 n_query_cols++;
01046
01047 query_cols[n_query_cols] = &str_username_col;
01048 query_vals[n_query_cols].type = DB1_STR;
01049 query_vals[n_query_cols].nul = 0;
01050 query_vals[n_query_cols].val.str_val = uri.user;
01051 n_query_cols++;
01052
01053 query_cols[n_query_cols] = &str_event_col;
01054 query_vals[n_query_cols].type = DB1_STR;
01055 query_vals[n_query_cols].nul = 0;
01056 query_vals[n_query_cols].val.str_val.s= "presence";
01057 query_vals[n_query_cols].val.str_val.len= 8;
01058 n_query_cols++;
01059
01060 result_cols[n_result_cols++] = &str_body_col;
01061
01062 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
01063 {
01064 LM_ERR("in use_table\n");
01065 return NULL;
01066 }
01067
01068 static str query_str = str_init("received_time");
01069 if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
01070 result_cols, n_query_cols, n_result_cols, &query_str , &result) < 0)
01071 {
01072 LM_ERR("failed to query %.*s table\n", presentity_table.len, presentity_table.s);
01073 if(result)
01074 pa_dbf.free_result(pa_db, result);
01075 return NULL;
01076 }
01077
01078 if(result== NULL)
01079 return NULL;
01080
01081 if (result->n<=0 )
01082 {
01083 LM_DBG("no published record found in database\n");
01084 pa_dbf.free_result(pa_db, result);
01085 return NULL;
01086 }
01087
01088 row = &result->rows[result->n-1];
01089 row_vals = ROW_VALUES(row);
01090 if(row_vals[0].val.string_val== NULL)
01091 {
01092 LM_ERR("NULL notify body record\n");
01093 goto error;
01094 }
01095
01096 body.s= (char*)row_vals[0].val.string_val;
01097 body.len= strlen(body.s);
01098 if(body.len== 0)
01099 {
01100 LM_ERR("Empty notify body record\n");
01101 goto error;
01102 }
01103
01104 sphere= extract_sphere(body);
01105
01106 pa_dbf.free_result(pa_db, result);
01107
01108 return sphere;
01109
01110 error:
01111 if(result)
01112 pa_dbf.free_result(pa_db, result);
01113 return NULL;
01114
01115 }
01116
01117 int mark_presentity_for_delete(presentity_t *pres)
01118 {
01119 db_key_t query_cols[4], result_cols[1], update_cols[3];
01120 db_val_t query_vals[4], update_vals[3], *value;
01121 db_row_t *row;
01122 db1_res_t *result = NULL;
01123 int n_query_cols = 0, n_update_cols = 0;
01124 int ret = -1;
01125 str *cur_body = NULL, *new_body = NULL;
01126
01127 if (pres->event->agg_nbody == NULL)
01128 {
01129
01130 if (delete_presentity(pres) < 0)
01131 {
01132 LM_ERR("deleting presentity\n");
01133 goto error;
01134 }
01135 goto done;
01136 }
01137
01138 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
01139 {
01140 LM_ERR("unsuccessful use table sql operation\n");
01141 goto error;
01142 }
01143
01144 query_cols[n_query_cols] = &str_username_col;
01145 query_vals[n_query_cols].type = DB1_STR;
01146 query_vals[n_query_cols].nul = 0;
01147 query_vals[n_query_cols].val.str_val = pres->user;
01148 n_query_cols++;
01149
01150 query_cols[n_query_cols] = &str_domain_col;
01151 query_vals[n_query_cols].type = DB1_STR;
01152 query_vals[n_query_cols].nul = 0;
01153 query_vals[n_query_cols].val.str_val = pres->domain;
01154 n_query_cols++;
01155
01156 query_cols[n_query_cols] = &str_event_col;
01157 query_vals[n_query_cols].type = DB1_STR;
01158 query_vals[n_query_cols].nul = 0;
01159 query_vals[n_query_cols].val.str_val = pres->event->name;
01160 n_query_cols++;
01161
01162 query_cols[n_query_cols] = &str_etag_col;
01163 query_vals[n_query_cols].type = DB1_STR;
01164 query_vals[n_query_cols].nul = 0;
01165 query_vals[n_query_cols].val.str_val = pres->etag;
01166 n_query_cols++;
01167
01168 result_cols[0] = &str_body_col;
01169
01170 if (pa_dbf.query(pa_db, query_cols, 0, query_vals, result_cols,
01171 n_query_cols, 1, 0, &result) < 0)
01172 {
01173 LM_ERR("query failed\n");
01174 goto error;
01175 }
01176
01177 if (result == NULL)
01178 {
01179 LM_ERR("bad result\n");
01180 goto error;
01181 }
01182
01183 if (RES_ROW_N(result) <= 0)
01184 {
01185
01186 LM_INFO("Found 0 presentities - expected 1\n");
01187 goto done;
01188 }
01189
01190 if (RES_ROW_N(result) > 1)
01191 {
01192
01193
01194 LM_ERR("Found %d presentities - expected 1\n", RES_ROW_N(result));
01195
01196 if (delete_presentity(pres) < 0)
01197 {
01198 LM_ERR("deleting presentity\n");
01199 goto error;
01200 }
01201
01202
01203
01204 goto done;
01205 }
01206
01207 row = RES_ROWS(result);
01208 value = ROW_VALUES(row);
01209
01210 if ((cur_body = (str *) pkg_malloc(sizeof(str))) == NULL)
01211 {
01212 LM_ERR("allocating pkg memory\n");
01213 goto error;
01214 }
01215 cur_body->s = (char *) value->val.string_val;
01216 cur_body->len = strlen (cur_body->s);
01217 if ((new_body = pres->event->agg_nbody(&pres->user, &pres->domain,
01218 &cur_body, 1, 0)) == NULL)
01219 {
01220 LM_ERR("preparing body\n");
01221 goto error;
01222 }
01223
01224 update_cols[n_update_cols] = &str_etag_col;
01225 update_vals[n_update_cols].type = DB1_STR;
01226 update_vals[n_update_cols].nul = 0;
01227 update_vals[n_update_cols].val.str_val = str_offline_etag_val;
01228 n_update_cols++;
01229
01230 update_cols[n_update_cols] = &str_expires_col;
01231 update_vals[n_update_cols].type = DB1_INT;
01232 update_vals[n_update_cols].nul = 0;
01233 update_vals[n_update_cols].val.int_val = (int)time(NULL);
01234 n_update_cols++;
01235
01236 update_cols[n_update_cols] = &str_body_col;
01237 update_vals[n_update_cols].type = DB1_STR;
01238 update_vals[n_update_cols].nul = 0;
01239 update_vals[n_update_cols].val.str_val.s = new_body->s;
01240 update_vals[n_update_cols].val.str_val.len = new_body->len;
01241 n_update_cols++;
01242
01243 if (pa_dbf.update(pa_db, query_cols, 0, query_vals, update_cols,
01244 update_vals, n_query_cols, n_update_cols) < 0)
01245 {
01246 LM_ERR("unsuccessful sql update operation");
01247 goto error;
01248 }
01249
01250 if (pa_dbf.affected_rows)
01251 ret = pa_dbf.affected_rows(pa_db);
01252 else
01253 done:
01254 ret = 0;
01255
01256 error:
01257 free_notify_body(new_body, pres->event);
01258 if (cur_body) pkg_free(cur_body);
01259 if (result) pa_dbf.free_result(pa_db, result);
01260 return ret;
01261 }
01262
01263 int delete_presentity(presentity_t *pres)
01264 {
01265 db_key_t query_cols[4];
01266 db_val_t query_vals[4];
01267 int n_query_cols = 0;
01268
01269 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
01270 {
01271 LM_ERR("unsuccessful use table sql operation\n");
01272 goto error;
01273 }
01274
01275 query_cols[n_query_cols] = &str_username_col;
01276 query_vals[n_query_cols].type = DB1_STR;
01277 query_vals[n_query_cols].nul = 0;
01278 query_vals[n_query_cols].val.str_val = pres->user;
01279 n_query_cols++;
01280
01281 query_cols[n_query_cols] = &str_domain_col;
01282 query_vals[n_query_cols].type = DB1_STR;
01283 query_vals[n_query_cols].nul = 0;
01284 query_vals[n_query_cols].val.str_val = pres->domain;
01285 n_query_cols++;
01286
01287 query_cols[n_query_cols] = &str_event_col;
01288 query_vals[n_query_cols].type = DB1_STR;
01289 query_vals[n_query_cols].nul = 0;
01290 query_vals[n_query_cols].val.str_val = pres->event->name;
01291 n_query_cols++;
01292
01293 query_cols[n_query_cols] = &str_etag_col;
01294 query_vals[n_query_cols].type = DB1_STR;
01295 query_vals[n_query_cols].nul = 0;
01296 query_vals[n_query_cols].val.str_val = pres->etag;
01297 n_query_cols++;
01298
01299 if(pa_dbf.delete(pa_db, query_cols, 0, query_vals, n_query_cols) < 0)
01300 {
01301 LM_ERR("unsuccessful sql delete operation");
01302 goto error;
01303 }
01304
01305 if (pa_dbf.affected_rows)
01306 return pa_dbf.affected_rows(pa_db);
01307 else
01308 return 0;
01309
01310 error:
01311 return -1;
01312 }
01313
01314 int delete_offline_presentities(str *pres_uri, pres_ev_t *event)
01315 {
01316 db_key_t query_cols[4];
01317 db_val_t query_vals[4];
01318 int n_query_cols = 0;
01319 struct sip_uri uri;
01320
01321 if (parse_uri(pres_uri->s, pres_uri->len, &uri) < 0)
01322 {
01323 LM_ERR("failed to parse presentity uri\n");
01324 goto error;
01325 }
01326
01327 query_cols[n_query_cols] = &str_username_col;
01328 query_vals[n_query_cols].type = DB1_STR;
01329 query_vals[n_query_cols].nul = 0;
01330 query_vals[n_query_cols].val.str_val = uri.user;
01331 n_query_cols++;
01332
01333 query_cols[n_query_cols] = &str_domain_col;
01334 query_vals[n_query_cols].type = DB1_STR;
01335 query_vals[n_query_cols].nul = 0;
01336 query_vals[n_query_cols].val.str_val = uri.host;
01337 n_query_cols++;
01338
01339 query_cols[n_query_cols] = &str_event_col;
01340 query_vals[n_query_cols].type = DB1_STR;
01341 query_vals[n_query_cols].nul = 0;
01342 query_vals[n_query_cols].val.str_val = event->name;
01343 n_query_cols++;
01344
01345 query_cols[n_query_cols] = &str_etag_col;
01346 query_vals[n_query_cols].type = DB1_STR;
01347 query_vals[n_query_cols].nul = 0;
01348 query_vals[n_query_cols].val.str_val = str_offline_etag_val;
01349 n_query_cols++;
01350
01351 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
01352 {
01353 LM_ERR("unsuccessful use table sql operation\n");
01354 goto error;
01355 }
01356
01357 if (pa_dbf.delete(pa_db, query_cols, 0, query_vals, n_query_cols) < 0)
01358 {
01359 LM_ERR("unsuccessful sql delete operation");
01360 goto error;
01361 }
01362
01363 if (pa_dbf.affected_rows)
01364 return pa_dbf.affected_rows(pa_db);
01365 else
01366 return 0;
01367
01368 error:
01369 return -1;
01370 }