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
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <stdlib.h>
00032 #include <sys/types.h>
00033 #include <sys/ipc.h>
00034 #include <unistd.h>
00035 #include <fcntl.h>
00036 #include <time.h>
00037 #include <curl/curl.h>
00038 #include "../../mem/mem.h"
00039 #include "../../db/db.h"
00040 #include "xcap_functions.h"
00041 #include "xcap_client.h"
00042 #include "../presence/hash.h"
00043
00044
00045 #define ETAG_HDR "Etag: "
00046 #define ETAG_HDR_LEN strlen("Etag: ")
00047
00048 size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream);
00049 char* get_xcap_path(xcap_get_req_t req);
00050
00051 int bind_xcap(xcap_api_t* api)
00052 {
00053 if (!api)
00054 {
00055 LM_ERR("Invalid parameter value\n");
00056 return -1;
00057 }
00058 api->get_elem= xcapGetElem;
00059 api->int_node_sel= xcapInitNodeSel;
00060 api->add_step= xcapNodeSelAddStep;
00061 api->add_terminal= xcapNodeSelAddTerminal;
00062 api->free_node_sel= xcapFreeNodeSel;
00063 api->register_xcb= register_xcapcb;
00064 api->getNewDoc= xcapGetNewDoc;
00065
00066 return 0;
00067 }
00068
00069 void xcapFreeNodeSel(xcap_node_sel_t* node)
00070 {
00071 step_t* s, *p;
00072 ns_list_t* n, *m;
00073
00074 s= node->steps;
00075 while(s)
00076 {
00077 p= s;
00078 s= s->next;
00079 pkg_free(p->val.s);
00080 pkg_free(p);
00081 }
00082
00083 n= node->ns_list;
00084 while(n)
00085 {
00086 m= n;
00087 n= n->next;
00088 pkg_free(n->value.s);
00089 pkg_free(n);
00090 }
00091
00092 pkg_free(node);
00093
00094 }
00095
00096 xcap_node_sel_t* xcapInitNodeSel(void)
00097 {
00098 xcap_node_sel_t* nsel= NULL;
00099
00100 nsel= (xcap_node_sel_t*)pkg_malloc(sizeof(xcap_node_sel_t));
00101 if(nsel== NULL)
00102 {
00103 ERR_MEM(PKG_MEM_STR);
00104 }
00105 memset(nsel, 0, sizeof(xcap_node_sel_t));
00106 nsel->steps= (step_t*)pkg_malloc(sizeof(step_t));
00107 if(nsel->steps== NULL)
00108 {
00109 ERR_MEM(PKG_MEM_STR);
00110 }
00111 memset(nsel->steps, 0, sizeof(step_t));
00112 nsel->last_step= nsel->steps;
00113
00114 nsel->ns_list= (ns_list_t*)pkg_malloc(sizeof(ns_list_t));
00115 if(nsel->ns_list== NULL)
00116 {
00117 ERR_MEM(PKG_MEM_STR);
00118 }
00119 memset(nsel->ns_list, 0, sizeof(ns_list_t));
00120 nsel->last_ns= nsel->ns_list;
00121
00122 return nsel;
00123
00124 error:
00125 if(nsel)
00126 {
00127 if(nsel->steps)
00128 pkg_free(nsel->steps);
00129 if(nsel->ns_list)
00130 pkg_free(nsel->ns_list);
00131 pkg_free(nsel);
00132 }
00133
00134 return NULL;
00135 }
00136
00137 xcap_node_sel_t* xcapNodeSelAddStep(xcap_node_sel_t* curr_sel, str* name,
00138 str* namespace, int pos, attr_test_t* attr_test, str* extra_sel)
00139 {
00140 int size= 0;
00141 str new_step= {NULL, 0};
00142 step_t* s= NULL;
00143 char ns_card= 'a';
00144 ns_list_t* ns= NULL;
00145
00146 if(name)
00147 size+= name->len;
00148 else
00149 size+= 1;
00150
00151 if(namespace)
00152 size+= 2;
00153 if(pos> 0)
00154 size+= 7;
00155 if(attr_test)
00156 size+= 2+ attr_test->name.len+ attr_test->value.len;
00157 if(extra_sel)
00158 size+= 2+ extra_sel->len;
00159
00160 new_step.s= (char*)pkg_malloc(size* sizeof(char));
00161 if(new_step.s== NULL)
00162 {
00163 ERR_MEM(PKG_MEM_STR);
00164 }
00165 if(name)
00166 {
00167 if(namespace)
00168 {
00169 ns_card= curr_sel->ns_no+ 'a';
00170 curr_sel->ns_no++;
00171
00172 if(ns_card> 'z')
00173 {
00174 LM_ERR("Insuficient name cards for namespaces\n");
00175 goto error;
00176 }
00177 new_step.len= sprintf(new_step.s, "%c:", ns_card);
00178 }
00179 memcpy(new_step.s+new_step.len, name->s, name->len);
00180 new_step.len+= name->len;
00181 }
00182 else
00183 memcpy(new_step.s+new_step.len, "*", 1);
00184
00185 if(attr_test)
00186 {
00187 new_step.len+= sprintf(new_step.s+ new_step.len, "[%.*s=%.*s]", attr_test->name.len,
00188 attr_test->name.s, attr_test->value.len, attr_test->value.s);
00189 }
00190 if(pos> 0)
00191 new_step.len+= sprintf(new_step.s+ new_step.len, "[%d]", pos);
00192
00193 if(extra_sel)
00194 {
00195 memcpy(new_step.s+ new_step.len, extra_sel->s, extra_sel->len);
00196 new_step.len= extra_sel->len;
00197 }
00198
00199 s= (step_t*)pkg_malloc(sizeof(step_t));
00200 if(s== NULL)
00201 {
00202 ERR_MEM(PKG_MEM_STR);
00203 }
00204 s->val= new_step;
00205 s->next= NULL;
00206
00207 curr_sel->last_step->next= s;
00208 curr_sel->last_step= s;
00209
00210
00211 if(namespace)
00212 {
00213 ns= (ns_list_t*)pkg_malloc(sizeof(ns_list_t));
00214 if(ns== NULL)
00215 {
00216 ERR_MEM(PKG_MEM_STR);
00217 }
00218 ns->name= ns_card;
00219 ns->value.s= (char*)pkg_malloc(namespace->len* sizeof(char));
00220 if(ns->value.s== NULL)
00221 {
00222 ERR_MEM(PKG_MEM_STR);
00223 }
00224 memcpy(ns->value.s, namespace->s, namespace->len);
00225 ns->value.len= namespace->len;
00226
00227 curr_sel->last_ns->next= ns;
00228 curr_sel->last_ns= ns;
00229 }
00230
00231 curr_sel->size+= 1+ new_step.len;
00232 if(namespace->len)
00233 {
00234 curr_sel->size+= namespace->len+ 3;
00235 }
00236
00237 return curr_sel;
00238
00239 error:
00240 if(new_step.s)
00241 pkg_free(new_step.s);
00242 if(s)
00243 pkg_free(s);
00244 if(ns)
00245 {
00246 if(ns->value.s)
00247 pkg_free(ns->value.s);
00248 pkg_free(ns);
00249 }
00250
00251 return NULL;
00252 }
00253
00254 xcap_node_sel_t* xcapNodeSelAddTerminal(xcap_node_sel_t* curr_sel,
00255 char* attr_sel, char* namespace_sel, char* extra_sel )
00256 {
00257
00258 return NULL;
00259 }
00260
00261 char* get_node_selector(xcap_node_sel_t* node_sel)
00262 {
00263 char* buf= NULL;
00264 step_t* s;
00265 int len= 0;
00266 ns_list_t* ns_elem;
00267
00268 buf= (char*)pkg_malloc((node_sel->size+ 10)* sizeof(char));
00269 if(buf== NULL)
00270 {
00271 ERR_MEM(PKG_MEM_STR);
00272 }
00273
00274 s= node_sel->steps->next;
00275
00276 while(1)
00277 {
00278 memcpy(buf+ len, s->val.s, s->val.len);
00279 len+= s->val.len;
00280 s= s->next;
00281 if(s)
00282 buf[len++]= '/';
00283 else
00284 break;
00285 }
00286 ns_elem= node_sel->ns_list;
00287
00288 if(ns_elem)
00289 buf[len++]= '?';
00290
00291 while(ns_elem)
00292 {
00293 len+= sprintf(buf+ len, "xmlns(%c=%.*s)", ns_elem->name,
00294 ns_elem->value.len, ns_elem->value.s);
00295 ns_elem= ns_elem->next;
00296 }
00297
00298 buf[len]= '\0';
00299
00300 return buf;
00301
00302 error:
00303 return NULL;
00304 }
00305
00306 char* xcapGetNewDoc(xcap_get_req_t req, str user, str domain)
00307 {
00308 char* etag= NULL;
00309 char* doc= NULL;
00310 db_key_t query_cols[9];
00311 db_val_t query_vals[9];
00312 int n_query_cols = 0;
00313 char* path= NULL;
00314
00315 path= get_xcap_path(req);
00316 if(path== NULL)
00317 {
00318 LM_ERR("while constructing xcap path\n");
00319 return NULL;
00320 }
00321
00322 doc= send_http_get(path, req.port, NULL, 0, &etag);
00323 if(doc== NULL)
00324 {
00325 LM_DBG("the searched document was not found\n");
00326 goto done;
00327 }
00328
00329 if(etag== NULL)
00330 {
00331 LM_ERR("no etag found\n");
00332 pkg_free(doc);
00333 doc= NULL;
00334 goto done;
00335 }
00336
00337 query_cols[n_query_cols] = &str_username_col;
00338 query_vals[n_query_cols].type = DB_STR;
00339 query_vals[n_query_cols].nul = 0;
00340 query_vals[n_query_cols].val.str_val = user;
00341 n_query_cols++;
00342
00343 query_cols[n_query_cols] = &str_domain_col;
00344 query_vals[n_query_cols].type = DB_STR;
00345 query_vals[n_query_cols].nul = 0;
00346 query_vals[n_query_cols].val.str_val = domain;
00347 n_query_cols++;
00348
00349 query_cols[n_query_cols] = &str_doc_type_col;
00350 query_vals[n_query_cols].type = DB_INT;
00351 query_vals[n_query_cols].nul = 0;
00352 query_vals[n_query_cols].val.int_val= req.doc_sel.doc_type;
00353 n_query_cols++;
00354
00355 query_cols[n_query_cols] = &str_doc_col;
00356 query_vals[n_query_cols].type = DB_STRING;
00357 query_vals[n_query_cols].nul = 0;
00358 query_vals[n_query_cols].val.string_val= doc;
00359 n_query_cols++;
00360
00361 query_cols[n_query_cols] = &str_etag_col;
00362 query_vals[n_query_cols].type = DB_STRING;
00363 query_vals[n_query_cols].nul = 0;
00364 query_vals[n_query_cols].val.string_val= etag;
00365 n_query_cols++;
00366
00367 query_cols[n_query_cols] = &str_source_col;
00368 query_vals[n_query_cols].type = DB_INT;
00369 query_vals[n_query_cols].nul = 0;
00370 query_vals[n_query_cols].val.int_val= XCAP_CL_MOD;
00371 n_query_cols++;
00372
00373 query_cols[n_query_cols] = &str_doc_uri_col;
00374 query_vals[n_query_cols].type = DB_STRING;
00375 query_vals[n_query_cols].nul = 0;
00376 query_vals[n_query_cols].val.string_val= path;
00377 n_query_cols++;
00378
00379 query_cols[n_query_cols] = &str_port_col;
00380 query_vals[n_query_cols].type = DB_INT;
00381 query_vals[n_query_cols].nul = 0;
00382 query_vals[n_query_cols].val.int_val= req.port;
00383 n_query_cols++;
00384
00385 if (xcap_dbf.use_table(xcap_db, &xcap_db_table) < 0)
00386 {
00387 LM_ERR("in use_table-[table]= %.*s\n", xcap_db_table.len, xcap_db_table.s);
00388 goto done;
00389 }
00390
00391 if(xcap_dbf.insert(xcap_db, query_cols, query_vals, n_query_cols)< 0)
00392 {
00393 LM_ERR("in sql insert\n");
00394 goto done;
00395 }
00396
00397 done:
00398 pkg_free(path);
00399 return doc;
00400 }
00401
00402 char* get_xcap_path(xcap_get_req_t req)
00403 {
00404 int len= 0, size;
00405 char* path= NULL;
00406 char* node_selector= NULL;
00407
00408 len= (strlen(req.xcap_root)+ 1+ req.doc_sel.auid.len+ 5+
00409 req.doc_sel.xid.len+ req.doc_sel.filename.len+ 50)* sizeof(char);
00410
00411 if(req.node_sel)
00412 len+= req.node_sel->size;
00413
00414 path= (char*)pkg_malloc(len);
00415 if(path== NULL)
00416 {
00417 ERR_MEM(PKG_MEM_STR);
00418 }
00419
00420 if(req.node_sel)
00421 {
00422 node_selector= get_node_selector(req.node_sel);
00423 if(node_selector== NULL)
00424 {
00425 LM_ERR("while constructing node selector\n");
00426 goto error;
00427 }
00428 }
00429
00430 size= sprintf(path, "%s/%.*s/", req.xcap_root, req.doc_sel.auid.len,
00431 req.doc_sel.auid.s);
00432
00433 if(req.doc_sel.type==USERS_TYPE)
00434 size+= sprintf(path+ size, "%s/%.*s/", "users", req.doc_sel.xid.len,
00435 req.doc_sel.xid.s);
00436 else
00437 size+= sprintf(path+ size, "%s/", "global");
00438 size+= sprintf(path+ size, "%.*s", req.doc_sel.filename.len,
00439 req.doc_sel.filename.s);
00440
00441 if(node_selector)
00442 {
00443 size+= sprintf(path+ size, "/~~%s", node_selector);
00444 }
00445
00446 if(size> len)
00447 {
00448 LM_ERR("buffer size overflow\n");
00449 goto error;
00450 }
00451 pkg_free(node_selector);
00452
00453 return path;
00454
00455 error:
00456 if(path)
00457 pkg_free(path);
00458 if(node_selector)
00459 pkg_free(node_selector);
00460 return NULL;
00461 }
00462
00463
00464
00465 char* xcapGetElem(xcap_get_req_t req, char** etag)
00466 {
00467 char* path= NULL;
00468 char* stream= NULL;
00469
00470 path= get_xcap_path(req);
00471 if(path== NULL)
00472 {
00473 LM_ERR("while constructing xcap path\n");
00474 return NULL;
00475 }
00476
00477 stream= send_http_get(path, req.port, req.etag, req.match_type, etag);
00478 if(stream== NULL)
00479 {
00480 LM_DBG("the serched element was not found\n");
00481 }
00482
00483 if(etag== NULL)
00484 {
00485 LM_ERR("no etag found\n");
00486 pkg_free(stream);
00487 stream= NULL;
00488 }
00489
00490 if(path)
00491 pkg_free(path);
00492
00493 return stream;
00494 }
00495
00496 size_t get_xcap_etag( void *ptr, size_t size, size_t nmemb, void *stream)
00497 {
00498 int len= 0;
00499 char* etag= NULL;
00500
00501 if(strncasecmp(ptr, ETAG_HDR, ETAG_HDR_LEN)== 0)
00502 {
00503 len= size* nmemb- ETAG_HDR_LEN;
00504 etag= (char*)pkg_malloc((len+ 1)* sizeof(char));
00505 if(etag== NULL)
00506 {
00507 ERR_MEM(PKG_MEM_STR);
00508 }
00509 memcpy(etag, ptr+ETAG_HDR_LEN, len);
00510 etag[len]= '\0';
00511 *((char**)stream)= etag;
00512 }
00513 return len;
00514
00515 error:
00516 return -1;
00517 }
00518
00519 char* send_http_get(char* path, unsigned int xcap_port, char* match_etag,
00520 int match_type, char** etag)
00521 {
00522 int len;
00523 char* stream= NULL;
00524 CURLcode ret_code;
00525 CURL* curl_handle= NULL;
00526 static char buf[128];
00527 char* match_header= NULL;
00528 *etag= NULL;
00529
00530 if(match_etag)
00531 {
00532 char* hdr_name= NULL;
00533
00534 memset(buf, 128* sizeof(char), 0);
00535 match_header= buf;
00536
00537 hdr_name= (match_type==IF_MATCH)?"If-Match":"If-None-Match";
00538
00539 len=sprintf(match_header, "%s: %s\n", hdr_name, match_etag);
00540
00541 match_header[len]= '\0';
00542 }
00543
00544 curl_handle = curl_easy_init();
00545
00546 curl_easy_setopt(curl_handle, CURLOPT_URL, path);
00547
00548 curl_easy_setopt(curl_handle, CURLOPT_PORT, xcap_port);
00549
00550 curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1);
00551
00552 curl_easy_setopt(curl_handle, CURLOPT_STDERR, stdout);
00553
00554 curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_function);
00555
00556 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &stream);
00557
00558 curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, get_xcap_etag);
00559
00560 curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, &etag);
00561
00562 if(match_header)
00563 curl_easy_setopt(curl_handle, CURLOPT_HEADER, (long)match_header);
00564
00565
00566 curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
00567
00568 ret_code= curl_easy_perform(curl_handle );
00569
00570 if( ret_code== CURLE_WRITE_ERROR)
00571 {
00572 LM_ERR("while performing curl option\n");
00573 if(stream)
00574 pkg_free(stream);
00575 stream= NULL;
00576 return NULL;
00577 }
00578
00579 curl_global_cleanup();
00580 return stream;
00581 }
00582
00583 size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream)
00584 {
00585
00586 char* data;
00587
00588 data= (char*)pkg_malloc(size* nmemb);
00589 if(data== NULL)
00590 {
00591 ERR_MEM(PKG_MEM_STR);
00592 }
00593
00594 memcpy(data, (char*)ptr, size* nmemb);
00595
00596 *((char**) stream)= data;
00597
00598 return size* nmemb;
00599
00600 error:
00601 return CURLE_WRITE_ERROR;
00602 }