int erl_rpc_struct_printf(erl_rpc_ctx_t* ctx, char* name, char* fmt, ...) { int n, buff_size; char *buff; va_list ap; erl_rpc_param_t *param; LM_ERR("parsing name:%s fmt: %s\n",name, fmt); buff = (char*)pkg_malloc(RPC_BUF_SIZE); if (!buff) { ERR("No memory left\n"); return -1; } buff_size = RPC_BUF_SIZE; while(1) { /* Try to print in the allocated space. */ va_start(ap, fmt); n = vsnprintf(buff, buff_size, fmt, ap); va_end(ap); /* If that worked, return the string. */ if (n > -1 && n < buff_size) { if(add_to_recycle_bin(JUNK_PKGCHAR,(void*)buff,ctx)) { goto error; } else if ((param = erl_new_param(ctx))) { param->type = ERL_STRING_EXT; param->value.S.s = buff; param->value.S.len = n; param->member_name = name; erl_rpc_append_param(ctx,param); } else { goto error; } return 0; } /* Else try again with more space. */ if (n > -1) { /* glibc 2.1 */ buff_size = n + 1; /* precisely what is needed */ } else { /* glibc 2.0 */ buff_size *= 2; /* twice the old size */ } if ((buff = pkg_realloc(buff, buff_size)) == 0) { ERR("No memory left\n"); goto error; } } return 0; error: if(buff) pkg_free(buff); return -1; }
int redis_raw_query_handle_reply(redisReply *reply,cdb_raw_entry ***ret, int expected_kv_no,int *reply_no) { int current_size=0,len,i; /* start with a single returned document */ *ret = pkg_malloc(1 * sizeof(cdb_raw_entry *)); if (*ret == NULL) { LM_ERR("No more PKG mem\n"); goto error; } **ret = pkg_malloc(expected_kv_no * sizeof(cdb_raw_entry)); if (**ret == NULL) { LM_ERR("No more pkg mem\n"); goto error; } switch (reply->type) { case REDIS_REPLY_STRING: (*ret)[current_size][0].val.s.s = pkg_malloc(reply->len); if (! (*ret)[current_size][0].val.s.s ) { LM_ERR("No more pkg \n"); goto error; } memcpy((*ret)[current_size][0].val.s.s,reply->str,reply->len); (*ret)[current_size][0].val.s.len = reply->len; (*ret)[current_size][0].type = CDB_STR; current_size++; break; case REDIS_REPLY_INTEGER: (*ret)[current_size][0].val.n = reply->integer; (*ret)[current_size][0].type = CDB_INT; current_size++; break; case REDIS_REPLY_NIL: (*ret)[current_size][0].type = CDB_NULL; (*ret)[current_size][0].val.s.s = NULL; (*ret)[current_size][0].val.s.len = 0; current_size++; break; case REDIS_REPLY_ARRAY: for (i=0;i<reply->elements;i++) { switch (reply->element[i]->type) { case REDIS_REPLY_STRING: case REDIS_REPLY_INTEGER: case REDIS_REPLY_NIL: if (current_size > 0) { *ret = pkg_realloc(*ret,(current_size + 1) * sizeof(cdb_raw_entry *)); if (*ret == NULL) { LM_ERR("No more pkg\n"); goto error; } (*ret)[current_size] = pkg_malloc(expected_kv_no * sizeof(cdb_raw_entry)); if ((*ret)[current_size] == NULL) { LM_ERR("No more pkg\n"); goto error; } } if (reply->element[i]->type == REDIS_REPLY_INTEGER) { (*ret)[current_size][0].val.n = reply->element[i]->integer; (*ret)[current_size][0].type = CDB_INT; } else if (reply->element[i]->type == REDIS_REPLY_NIL) { (*ret)[current_size][0].val.s.s = NULL; (*ret)[current_size][0].val.s.len = 0; (*ret)[current_size][0].type = CDB_NULL; } else { (*ret)[current_size][0].val.s.s = pkg_malloc(reply->element[i]->len); if (! (*ret)[current_size][0].val.s.s ) { LM_ERR("No more pkg \n"); goto error; } memcpy((*ret)[current_size][0].val.s.s,reply->element[i]->str,reply->element[i]->len); (*ret)[current_size][0].val.s.len = reply->element[i]->len; (*ret)[current_size][0].type = CDB_STR; } current_size++; break; default: LM_DBG("Unexpected data type %d found in array - skipping \n",reply->element[i]->type); } } break; } *reply_no = current_size; freeReplyObject(reply); return 1; error: if (*ret) { pkg_free(*ret); for (len = 0;len<current_size;len++) { if ( (*ret)[len][0].type == CDB_STR) pkg_free((*ret)[len][0].val.s.s); pkg_free((*ret)[len]); } } *ret = NULL; *reply_no=0; freeReplyObject(reply); return -1; }
/* * Load ODBC cell data into a single cell */ int db_unixodbc_load_cell(const db1_con_t* _h, int colindex, strn * cell, const db_type_t _t) { SQLRETURN ret = 0; unsigned int truesize = 0; unsigned char hasnull = (_t != DB1_BLOB) ? 1 : 0; do { SQLLEN indicator; int chunklen; char * s; /* Pointer to available area for next chunk */ char * ns; if (cell->buflen > 0) { ns = (char *)pkg_realloc(cell->s, cell->buflen + STRN_LEN); if (ns == NULL) { LM_ERR("no memory left\n"); return 0; } cell->s = ns; /* Overwrite the previous null terminator */ s = cell->s + cell->buflen - hasnull; chunklen = STRN_LEN + hasnull; } else { ns = (char *)pkg_malloc(STRN_LEN); if (ns == NULL) { LM_ERR("no memory left\n"); return 0; } cell->s = ns; s = cell->s; chunklen = STRN_LEN; } cell->buflen += STRN_LEN; ret = SQLGetData(CON_RESULT(_h), colindex, hasnull ? SQL_C_CHAR : SQL_C_BINARY, s, chunklen, &indicator); LM_DBG("SQLGetData returned ret=%d indicator=%d\n", (int)ret, (int)indicator); if (ret == SQL_SUCCESS) { if (indicator == SQL_NULL_DATA) { /* TODO: set buffer pointer to NULL instead of string "NULL" */ strcpy(cell->s, "NULL"); truesize = 4 + (1 - hasnull); } else { /* Get length of data that was available before last SQLGetData call */ if (truesize == 0) truesize = indicator; } } else if (ret == SQL_SUCCESS_WITH_INFO) { SQLINTEGER i = 0; SQLINTEGER native; SQLCHAR state[ 7 ]; SQLCHAR text[256]; SQLSMALLINT len; SQLRETURN ret2; /* Check whether field data was truncated */ do { ret2 = SQLGetDiagRec(SQL_HANDLE_STMT, CON_RESULT(_h), ++i, state, &native, text, sizeof(text), &len ); if (SQL_SUCCEEDED(ret2)) { if (!strcmp("00000", (const char*)state)) break; if (strcmp("01004", (const char*)state) != 0) { /* Not a string truncation */ LM_ERR("SQLGetData failed unixodbc: =%s:%ld:%ld:%s\n", state, (long)i, (long)native, text); return 0; } /* Get length of data that was available before last SQLGetData call */ if (truesize == 0) truesize = indicator; } else if (ret2 == SQL_NO_DATA) { /* Reached end of diagnostic records */ break; } else { /* Failed to get diagnostics */ LM_ERR("SQLGetData failed, failed to get diagnostics (ret2=%d i=%d)\n", ret2, i); return 0; } } while( ret2 == SQL_SUCCESS ); } else { LM_ERR("SQLGetData failed\n"); } } while (ret == SQL_SUCCESS_WITH_INFO); LM_DBG("Total allocated for this cell (before resize): %d bytes\n", cell->buflen); if (cell->buflen > truesize) { cell->s[truesize] = '\0'; /* guarantee strlen() will terminate */ } cell->buflen = truesize + hasnull; LM_DBG("Total allocated for this cell (after resize): %d bytes\n", cell->buflen); LM_DBG("strlen() reports for this cell: %d bytes\n", (int)strlen(cell->s)); return 1; }
static char* serialize_dns_rdata(struct rdata *head,int buf_len,int *len,int do_encoding) { unsigned char *p; struct rdata *it; int needed_len; int entry_len,base64_len=0; struct cname_rdata *cname_rd; struct srv_rdata *srv_rd; struct naptr_rdata *naptr_rd; struct ebl_rdata *ebl_rd; struct txt_rdata *txt_rd; if (do_encoding) { base64_len = calc_base64_encode_len(buf_len); needed_len = buf_len + base64_len; } else { needed_len = buf_len; } if (rdata_buf == NULL || needed_len > rdata_buf_len) { rdata_buf = pkg_realloc(rdata_buf,needed_len); if (rdata_buf == NULL) { LM_ERR("No more pkg\n"); return NULL; } rdata_buf_len = needed_len; } p = rdata_buf; for (it=head;it;it=it->next) { /* copy non-pointer fields of the struct */ memcpy(p,it,rdata_struct_len); p+=rdata_struct_len; switch (it->type) { case T_A: /* copy all 4 bytes */ memcpy(p,it->rdata,sizeof(struct a_rdata)); p+=sizeof(struct a_rdata); break; case T_AAAA: /* copy all 16 bytes */ memcpy(p,it->rdata,sizeof(struct aaaa_rdata)); p+=sizeof(struct aaaa_rdata); break; case T_CNAME: cname_rd=(struct cname_rdata *)it->rdata; entry_len=strlen(cname_rd->name); /* copy len of alias */ memcpy(p,&entry_len,sizeof(int)); p+=sizeof(int); /* copy alias */ memcpy(p,cname_rd->name,entry_len+1); p+=entry_len+1; break; case T_NAPTR: /* copy priority, etc */ memcpy(p,it->rdata,2*sizeof(unsigned short) + sizeof(unsigned int)); p+=2*sizeof(unsigned short) + sizeof(unsigned int); naptr_rd=it->rdata; /* copy flags, flags_len was copied above */ memcpy(p,naptr_rd->flags,naptr_rd->flags_len+1); p+=naptr_rd->flags_len+1; /* copy services & len */ memcpy(p,&naptr_rd->services_len,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(p,naptr_rd->services,naptr_rd->services_len+1); p+=naptr_rd->services_len+1; /* copy regexp & len */ memcpy(p,&naptr_rd->regexp_len,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(p,naptr_rd->regexp,naptr_rd->regexp_len+1); p+=naptr_rd->regexp_len+1; /* copy repl & len */ memcpy(p,&naptr_rd->repl_len,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(p,naptr_rd->repl,naptr_rd->repl_len+1); p+=naptr_rd->repl_len+1; break; case T_SRV: srv_rd=it->rdata; memcpy(p,srv_rd,4*sizeof(unsigned short) + sizeof(unsigned int)); p+=4*sizeof(unsigned short) + sizeof(unsigned int); memcpy(p,srv_rd->name,srv_rd->name_len+1); p+=srv_rd->name_len+1; break; case T_TXT: txt_rd=it->rdata; entry_len=strlen(txt_rd->txt); memcpy(p,&entry_len,sizeof(int)); p+=sizeof(int); memcpy(p,txt_rd->txt,entry_len+1); p+=entry_len+1; break; case T_EBL: ebl_rd=it->rdata; memcpy(p,ebl_rd,sizeof(unsigned char) + sizeof(unsigned int)); p+=sizeof(unsigned char) + sizeof(unsigned int); memcpy(p,ebl_rd->separator,ebl_rd->separator_len+1); p+=ebl_rd->separator_len+1; memcpy(p,&ebl_rd->apex_len,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(p,ebl_rd->apex,ebl_rd->apex_len+1); p+=ebl_rd->apex_len+1; break; default: LM_ERR("Unexpected DNS record type\n"); return NULL; } } if (do_encoding) { if (*len) *len = base64_len; /* encode and return beggining of encoding */ base64encode(p,rdata_buf,buf_len); return (char *)p; } else { if (*len) *len = needed_len; return (char *)rdata_buf; } }
static struct rdata* deserialize_dns_rdata(char *buff,int buf_len,int do_decoding) { unsigned char *p; int max_len=0,actual_len=0,entry_len=0; struct rdata *head,*it,**last; struct naptr_rdata *naptr_rd; struct srv_rdata *srv_rd; struct txt_rdata *txt_rd; struct ebl_rdata *ebl_rd; head=it=NULL; last=&head; if (do_decoding) { max_len = calc_max_base64_decode_len(buf_len); } else { max_len = buf_len; } if (dec_rdata_buf == NULL || max_len > dec_rdata_buf_len) { /* realloc buff if not enough space */ dec_rdata_buf = pkg_realloc(dec_rdata_buf,max_len); if (dec_rdata_buf == NULL) { LM_ERR("No more pkg\n"); return NULL; } dec_rdata_buf_len = max_len; } if (do_decoding) { /* decode base64 buf */ actual_len = base64decode(dec_rdata_buf,(unsigned char *)buff,buf_len); p = dec_rdata_buf; } else { memcpy(dec_rdata_buf,buff,buf_len); actual_len = buf_len; p = dec_rdata_buf; } while ( p < dec_rdata_buf+actual_len) { it = pkg_malloc(sizeof(struct rdata)); if (it == 0) { LM_ERR("no more pkg mem\n"); goto it_alloc_error; } /* copy type, class & ttl */ memcpy(it,p,rdata_struct_len); p+=rdata_struct_len; it->next=0; it->rdata=0; switch (it->type) { case T_A: it->rdata = pkg_malloc(sizeof(struct a_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } memcpy(p,it->rdata,sizeof(struct a_rdata)); p+=sizeof(struct a_rdata); *last=it; last=&(it->next); break; case T_AAAA: it->rdata = pkg_malloc(sizeof(struct aaaa_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } memcpy(p,it->rdata,sizeof(struct aaaa_rdata)); p+=sizeof(struct aaaa_rdata); *last=it; last=&(it->next); break; case T_CNAME: it->rdata = pkg_malloc(sizeof(struct cname_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } memcpy(&entry_len,p,sizeof(int)); p+=sizeof(int); memcpy(((struct cname_rdata*)it->rdata)->name, p,entry_len+1); p+=entry_len+1; *last=it; last=&(it->next); break; case T_NAPTR: it->rdata = pkg_malloc(sizeof(struct naptr_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } naptr_rd = (struct naptr_rdata*)it->rdata; memcpy(naptr_rd,p,2*sizeof(unsigned short) + sizeof(unsigned int)); p+=2*sizeof(unsigned short) + sizeof(unsigned int); memcpy(naptr_rd->flags,p,naptr_rd->flags_len+1); p+=naptr_rd->flags_len+1; memcpy(&naptr_rd->services_len,p,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(naptr_rd->services,p,naptr_rd->services_len+1); p+=naptr_rd->services_len+1; memcpy(&naptr_rd->regexp_len,p,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(naptr_rd->regexp,p,naptr_rd->regexp_len+1); p+=naptr_rd->regexp_len+1; memcpy(&naptr_rd->repl_len,p,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(naptr_rd->repl,p,naptr_rd->repl_len+1); p+=naptr_rd->repl_len+1; *last=it; last=&(it->next); break; case T_SRV: it->rdata = pkg_malloc(sizeof(struct srv_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } srv_rd = (struct srv_rdata*)it->rdata; memcpy(srv_rd,p,4*sizeof(unsigned short) + sizeof(unsigned int)); p+=4*sizeof(unsigned short) + sizeof(unsigned int); memcpy(srv_rd->name,p,srv_rd->name_len+1); p+=srv_rd->name_len+1; *last=it; last=&(it->next); break; case T_TXT: it->rdata = pkg_malloc(sizeof(struct txt_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } txt_rd = (struct txt_rdata*)it->rdata; memcpy(&entry_len,p,sizeof(int)); p+=sizeof(int); memcpy(txt_rd->txt,p,entry_len+1); p+=entry_len+1; *last=it; last=&(it->next); break; case T_EBL: it->rdata = pkg_malloc(sizeof(struct ebl_rdata)); if (it->rdata == 0) { LM_ERR("no more pkg\n"); goto rdata_alloc_error; } ebl_rd = (struct ebl_rdata*)it->rdata; memcpy(ebl_rd,p,sizeof(unsigned char) + sizeof(unsigned int)); p+=sizeof(unsigned char)+sizeof(unsigned int); memcpy(ebl_rd->separator,p,ebl_rd->separator_len+1); p+=ebl_rd->separator_len+1; memcpy(&ebl_rd->apex_len,p,sizeof(unsigned int)); p+=sizeof(unsigned int); memcpy(ebl_rd->apex,p,ebl_rd->apex_len+1); p+=ebl_rd->apex_len+1; *last=it; last=&(it->next); break; } } return head; rdata_alloc_error: if (it) pkg_free(it); it_alloc_error: if (head) free_rdata_list(head); return NULL; }
void python_handle_exception(const char *fmt, ...) { PyObject *pResult; const char *msg; char *buf; size_t buflen, msglen; PyObject *exception, *v, *tb, *args; PyObject *line; int i; char *srcbuf; // We don't want to generate traceback when no errors occured if (!PyErr_Occurred()) return; if (fmt == NULL) srcbuf = NULL; else srcbuf = make_message(fmt); PyErr_Fetch(&exception, &v, &tb); PyErr_Clear(); if (exception == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, PyErr_Fetch() has failed.\n"); return; } PyErr_NormalizeException(&exception, &v, &tb); if (exception == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, PyErr_NormalizeException() has failed.\n"); return; } args = PyTuple_Pack(3, exception, v, tb ? tb : Py_None); Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); if (args == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, PyTuple_Pack() has failed.\n"); return; } pResult = PyObject_CallObject(format_exc_obj, args); Py_DECREF(args); if (pResult == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, traceback.format_exception() has failed.\n"); return; } buflen = 1; buf = (char *)pkg_realloc(NULL, buflen * sizeof(char *)); if (!buf) { LM_ERR("python_handle_exception(): Can't allocate memory (%lu bytes), pkg_realloc() has failed. Not enough memory.\n", (unsigned long)(buflen * sizeof(char *))); return; } memset(buf, 0, sizeof(char *)); for (i = 0; i < PySequence_Size(pResult); i++) { line = PySequence_GetItem(pResult, i); if (line == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, PySequence_GetItem() has failed.\n"); Py_DECREF(pResult); if (buf) pkg_free(buf); return; } msg = PyString_AsString(line); if (msg == NULL) { LM_ERR("python_handle_exception(): Can't get traceback, PyString_AsString() has failed.\n"); Py_DECREF(line); Py_DECREF(pResult); if (buf) pkg_free(buf); return; } msglen = strlen(msg); buflen += ++msglen; buf = (char *)pkg_realloc(buf, buflen * sizeof(char *)); if (!buf) { LM_ERR("python_handle_exception(): Can't allocate memory (%lu bytes), pkg_realloc() has failed. Not enough memory.\n", (unsigned long)(buflen * sizeof(char *))); Py_DECREF(line); Py_DECREF(pResult); return; } strncat(buf, msg, msglen >= buflen ? buflen-1 : msglen); Py_DECREF(line); } if (srcbuf == NULL) LM_ERR("Unhandled exception in the Python code:\n%s", buf); else LM_ERR("%s: Unhandled exception in the Python code:\n%s", srcbuf, buf); if (buf) pkg_free(buf); if (srcbuf) pkg_free(srcbuf); Py_DECREF(pResult); }
static inline int internal_mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { struct mi_node* node= NULL; struct mi_node* node1 = NULL; struct mi_node* node2 = NULL; struct mi_node* node3 = NULL; struct mi_attr* attr= NULL; struct dlg_profile_link *dl; struct dlg_val* dv; int len; char* p; int i, j; time_t _ts; struct tm* t; char date_buf[MI_DATE_BUF_LEN]; int date_buf_len; node = add_mi_node_child(rpl, 0, "dialog",6 , 0, 0 ); if (node==0) goto error; attr = addf_mi_attr( node, 0, "hash", 4, "%u:%u", dlg->h_entry, dlg->h_id ); if (attr==0) goto error; p= int2str((unsigned long)dlg->state, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "state", 5, p, len); if (node1==0) goto error; p= int2str((unsigned long)dlg->user_flags, &len); node1 = add_mi_node_child( node, MI_DUP_VALUE, "user_flags", 10, p, len); if (node1==0) goto error; _ts = (time_t)dlg->start_ts; p= int2str((unsigned long)_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len); if (node1==0) goto error; if (_ts) { t = localtime(&_ts); date_buf_len = strftime(date_buf, MI_DATE_BUF_LEN - 1, "%Y-%m-%d %H:%M:%S", t); if (date_buf_len != 0) { node1 = add_mi_node_child(node,MI_DUP_VALUE, "datestart", 9, date_buf, date_buf_len); if (node1==0) goto error; } } _ts = (time_t)(dlg->tl.timeout?((unsigned int)time(0) + dlg->tl.timeout - get_ticks()):0); p= int2str((unsigned long)_ts, &len); node1 = add_mi_node_child(node,MI_DUP_VALUE, "timeout", 7, p, len); if (node1==0) goto error; if (_ts) { t = localtime(&_ts); date_buf_len = strftime(date_buf, MI_DATE_BUF_LEN - 1, "%Y-%m-%d %H:%M:%S", t); if (date_buf_len != 0) { node1 = add_mi_node_child(node,MI_DUP_VALUE, "dateout", 7, date_buf, date_buf_len); if (node1==0) goto error; } } node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, dlg->from_uri.s, dlg->from_uri.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6, dlg->to_uri.s, dlg->to_uri.len); if(node1 == 0) goto error; if (dlg->legs_no[DLG_LEGS_USED]>0) { node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_tag", 10, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[DLG_CALLER_LEG].tag.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, dlg->legs[DLG_CALLER_LEG].contact.s, dlg->legs[DLG_CALLER_LEG].contact.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, dlg->legs[DLG_CALLER_LEG].r_cseq.s, dlg->legs[DLG_CALLER_LEG].r_cseq.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_route_set",16, dlg->legs[DLG_CALLER_LEG].route_set.s, dlg->legs[DLG_CALLER_LEG].route_set.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, 0,"caller_bind_addr",16, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.s, dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str.len); if(node1 == 0) goto error; node1 = add_mi_node_child(node, MI_DUP_VALUE,"caller_sdp",10, dlg->legs[DLG_CALLER_LEG].sdp.s, dlg->legs[DLG_CALLER_LEG].sdp.len); if(node1 == 0) goto error; } node1 = add_mi_node_child(node, MI_IS_ARRAY, "CALLEES", 7, NULL, 0); if(node1 == 0) goto error; for( i=1 ; i < dlg->legs_no[DLG_LEGS_USED] ; i++ ) { node2 = add_mi_node_child(node1, 0, "callee", 6, NULL, 0); if(node2 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "callee_tag", 10, dlg->legs[i].tag.s, dlg->legs[i].tag.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "callee_contact", 14, dlg->legs[i].contact.s, dlg->legs[i].contact.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE, "caller_cseq", 11, dlg->legs[i].r_cseq.s, dlg->legs[i].r_cseq.len); if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE,"callee_route_set",16, dlg->legs[i].route_set.s, dlg->legs[i].route_set.len); if(node3 == 0) goto error; if (dlg->legs[i].bind_addr) { node3 = add_mi_node_child(node2, 0, "callee_bind_addr",16, dlg->legs[i].bind_addr->sock_str.s, dlg->legs[i].bind_addr->sock_str.len); } else { node3 = add_mi_node_child(node2, 0, "callee_bind_addr",16,0,0); } if(node3 == 0) goto error; node3 = add_mi_node_child(node2, MI_DUP_VALUE,"callee_sdp",10, dlg->legs[i].sdp.s, dlg->legs[i].sdp.len); if(node3 == 0) goto error; } if (with_context) { node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); if(node1 == 0) goto error; if (dlg->vals) { node2 = add_mi_node_child(node1, 0, "values", 6, 0, 0); if(node2 == 0) goto error; /* print dlg values -> iterate the list */ for( dv=dlg->vals ; dv ; dv=dv->next) { /* escape non-printable chars */ p = pkg_realloc(dlg_val_buf, 4 * dv->val.len + 1); if (!p) { LM_ERR("not enough mem to allocate: %d\n", dv->val.len); continue; } for (i = 0, j = 0; i < dv->val.len; i++) { if (dv->val.s[i] < 0x20 || dv->val.s[i] >= 0x7F) { p[j++] = '\\'; switch ((unsigned char)dv->val.s[i]) { case 0x8: p[j++] = 'b'; break; case 0x9: p[j++] = 't'; break; case 0xA: p[j++] = 'n'; break; case 0xC: p[j++] = 'f'; break; case 0xD: p[j++] = 'r'; break; default: p[j++] = 'x'; j += snprintf(&p[j], 3, "%02x", (unsigned char)dv->val.s[i]); break; } } else { p[j++] = dv->val.s[i]; } } add_mi_node_child(node2, MI_DUP_NAME|MI_DUP_VALUE,dv->name.s,dv->name.len, p,j); dlg_val_buf = p; } } /* print dlg profiles */ if (dlg->profile_links) { node3 = add_mi_node_child(node1, MI_IS_ARRAY, "profiles", 8, 0, 0); if(node3 == 0) goto error; for( dl=dlg->profile_links ; dl ; dl=dl->next) { add_mi_node_child(node3, MI_DUP_NAME|MI_DUP_VALUE, dl->profile->name.s,dl->profile->name.len, ZSW(dl->value.s),dl->value.len); } } /* print external context info */ run_dlg_callbacks( DLGCB_MI_CONTEXT, dlg, NULL, DLG_DIR_NONE, (void *)node1); } return 0; error: LM_ERR("failed to add node\n"); return -1; }
void* my_pkg_realloc(void * p, size_t size){ return pkg_realloc(p, size); }
// Check if the requested asymmetrics file has changed and reload it if needed static void checkAsymmetricFile(AsymmetricClients *aptr) { char buf[512], errbuf[256], *which; regex_t *re, **regs; int i, size, code; Bool firstTime = False; struct stat statbuf; FILE *file; str line; if (stat(aptr->file, &statbuf) < 0) return; // ignore missing file if (statbuf.st_mtime <= aptr->timestamp) return; // not changed // now we have work to do which = (aptr == &sipAsymmetrics ? "SIP" : "RTP"); if (!aptr->clients) { // if we are here the first time allocate memory to hold the regexps // initial size of array // (hopefully not reached so we won't need to realloc) size = 32; aptr->clients = (regex_t**)pkg_malloc(size*sizeof(regex_t**)); if (!aptr->clients) { LOG(L_WARN, "warning: mediaproxy/checkAsymmetricFile() cannot " "allocate memory for the %s asymmetric client list. " "%s asymmetric clients will not be handled properly.\n", which, which); return; // ignore as it is not fatal } aptr->size = size; aptr->count = 0; firstTime = True; } else { // else clean old stuff for (i=0; i<aptr->count; i++) { regfree(aptr->clients[i]); pkg_free(aptr->clients[i]); aptr->clients[i] = NULL; } aptr->count = 0; } // read new file = fopen(aptr->file, "r"); i = 0; // this will count on which line are we in the file while (!feof(file)) { if (!fgets(buf, 512, file)) break; i++; line.s = buf; line.len = strlen(buf); trim(&line); if (line.len == 0 || line.s[0] == '#') continue; // comment or empty line. ignore line.s[line.len] = 0; re = (regex_t*)pkg_malloc(sizeof(regex_t)); if (!re) { LOG(L_WARN, "warning: mediaproxy/checkAsymmetricFile(): " "cannot allocate memory for all the %s asymmetric " "clients listed in file. Some of them will not be " "handled properly.\n", which); break; } code = regcomp(re, line.s, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (code == 0) { if (aptr->count+1 > aptr->size) { size = aptr->size * 2; regs = aptr->clients; regs = (regex_t**)pkg_realloc(regs, size*sizeof(regex_t**)); if (!regs) { LOG(L_WARN, "warning: mediaproxy/checkAsymmetricFile(): " "cannot allocate memory for all the %s asymmetric " "clients listed in file. Some of them will not be " "handled properly.\n", which); break; } aptr->clients = regs; aptr->size = size; } aptr->clients[aptr->count] = re; aptr->count++; } else { regerror(code, re, errbuf, 256); LOG(L_WARN, "warning: mediaproxy/checkAsymmetricFile(): cannot " "compile line %d of the %s asymmetric clients file into a " "regular expression (will be ignored): %s", i, which, errbuf); pkg_free(re); } } aptr->timestamp = statbuf.st_mtime; LOG(L_INFO, "info: mediaproxy: %sloaded %s asymmetric clients file " "containing %d entr%s.\n", firstTime ? "" : "re", which, aptr->count, aptr->count==1 ? "y" : "ies"); }
/*! * \brief Wrapper functions around our internal memory management for libmemcached (version < 0.38) callback * \param mem pointer to allocated memory * \param size new size of memory area * \return allocated memory, or NULL on failure * \see pkg_realloc */ static inline void* mcd_realloc_compat(memcached_st *ptr, void *mem, const size_t size) { return pkg_realloc(mem, size); }
static void *osips_realloc(void *ptr, size_t size) { void *p = pkg_realloc(ptr, size); return p; }
/*! * \brief Wrapper functions around our internal memory management for libmemcached (version >= 0.38) callback * \param mem pointer to allocated memory * \param size new size of memory area * \return allocated memory, or NULL on failure * \see pkg_realloc */ static inline void* mcd_realloc(memcached_st *ptr, void *mem, const size_t size, void *context) { return pkg_realloc(mem, size); }
int do_load_balance(struct sip_msg *req, int grp, struct lb_res_str_list *rl, unsigned int alg, struct lb_data *data) { static struct lb_resource **call_res = NULL; static unsigned int call_res_no = 0; static unsigned int *dst_bitmap = NULL; static unsigned int bitmap_size = 0; unsigned int * used_dst_bitmap; struct lb_resource *res; int size; int i,j; unsigned int load, ld; struct lb_dst *dst; struct lb_dst *it; struct lb_dst *last_dst; struct usr_avp *grp_avp; struct usr_avp *mask_avp; struct usr_avp *id_avp; int_str grp_val; int_str mask_val; int_str id_val; /* get references to the resources */ if (rl->n>call_res_no) { call_res = (struct lb_resource**)pkg_realloc (call_res, rl->n*sizeof(struct lb_resorce*)); if (call_res==NULL) { LM_ERR("no more pkg mem - res ptr realloc\n"); return -1; } call_res_no = rl->n; } for( i=0,res=data->resources ; (i<rl->n)&&res ; res=res->next) { if (search_resource_str( rl, &res->name)) { call_res[i++] = res; LM_DBG("found requested (%d) resource %.*s\n", i-1, res->name.len,res->name.s); } } if (i!=rl->n) { LM_ERR("unknown resource in input string\n"); return -1; } /* any previous iteration due failover ? */ grp_avp = search_first_avp( 0, grp_avp_name, &grp_val, 0); mask_avp = search_first_avp( 0, mask_avp_name, &mask_val, 0); id_avp = search_first_avp( 0, id_avp_name, &id_val, 0); if ( grp_avp && mask_avp && id_avp && ((grp_avp->flags&AVP_VAL_STR)==0) && (mask_avp->flags&AVP_VAL_STR) && ((id_avp->flags&AVP_VAL_STR)==0) ) { /* not the first iteration -> use data from AVPs */ grp = grp_val.n ; used_dst_bitmap = (unsigned int*)mask_val.s.s; /* set the previous dst as used (not selected) */ for(last_dst=data->dsts,i=0,j=0 ; last_dst ; last_dst=last_dst->next) { if (last_dst->id==id_val.n) {used_dst_bitmap[i] &= ~(1<<j);break;} j++; if (j==sizeof(unsigned int)) {i++;j=0;} } } else { /* first iteration for this call */ grp_avp = mask_avp = id_avp = NULL; last_dst = NULL; /* search destinations that fulfill the resources */ for( size=(unsigned int)(-1),i=0 ; i<rl->n ; i++) { if (call_res[i]->bitmap_size<size) size = call_res[i]->bitmap_size; } if (size>bitmap_size) { dst_bitmap = (unsigned int*)pkg_realloc ( dst_bitmap, size*sizeof(unsigned int) ); if (dst_bitmap==NULL) { LM_ERR("no more pkg mem - bitmap realloc\n"); return -1; } bitmap_size = size; } memset( dst_bitmap, 0xff , size*sizeof(unsigned int) ); for( i=0 ; i<rl->n ; i++) { for( j=0 ; j<size ; j++) dst_bitmap[j] &= call_res[i]->dst_bitmap[j]; } used_dst_bitmap = dst_bitmap; /* create dialog */ if (lb_dlg_binds.create_dlg( req )!=1 ) { LM_ERR("failed to create dialog\n"); return -1; } } /* end - first LB run */ /* lock the resources */ for( i=0 ; i<rl->n ; i++) get_lock( call_res[i]->lock ); /* do the load-balancing */ load = 0; dst = NULL; for( it=data->dsts,i=0,j=0 ; it ; it=it->next) { if ( (used_dst_bitmap[i] & (1<<j)) && it->group==grp && (it->flags&LB_DST_STAT_DSBL_FLAG)==0 ) { /* valid destination (resources & group & status) */ if ( (ld = get_dst_load(call_res, call_res_no, it, alg)) > load) { /* computing a max */ load = ld; dst = it; } LM_DBG("destination <%.*s> selected for LB set with free=%d " "(max=%d)\n",it->uri.len, it->uri.s,ld, load); } j++; if (j==8*sizeof(unsigned int)) {i++;j=0;} } /* if re-trying, remove the dialog from previous profiles */ if (last_dst) { for( i=0 ; i<rl->n ; i++) { if (lb_dlg_binds.unset_profile( req, &last_dst->profile_id, call_res[i]->profile)!=1) LM_ERR("failed to remove from profile\n"); } } if (dst==NULL) { LM_DBG("no destination found\n"); } else { /* add to the profiles */ for( i=0 ; i<rl->n ; i++) { if (lb_dlg_binds.set_profile( req, &dst->profile_id, call_res[i]->profile)!=0) LM_ERR("failed to add to profile\n"); } } /* unlock the resources*/ for( i=0 ; i<rl->n ; i++) release_lock( call_res[i]->lock ); if (dst) { /* change (add/edit) the AVPs for the next iteration */ if (grp_avp==NULL && mask_avp==NULL) { grp_val.n = grp; if (add_avp( 0, grp_avp_name, grp_val)!=0) { LM_ERR("failed to add GRP AVP"); } mask_val.s.s = (char*)used_dst_bitmap; mask_val.s.len = bitmap_size*sizeof(unsigned int); if (add_avp( AVP_VAL_STR, mask_avp_name, mask_val)!=0) { LM_ERR("failed to add MASK AVP"); } } if (id_avp) { id_avp->data = (void*)(long)dst->id; } else { id_val.n = dst->id; if (add_avp( 0, id_avp_name, id_val)!=0) { LM_ERR("failed to add ID AVP"); } } /* set dst uri */ if (set_dst_uri( req, &dst->uri )!=0) { LM_ERR("failed to set duri\n"); return -2; } } return dst?0:-2; }
void timeout_listener_process(int rank) { struct sockaddr_un saddr_un; struct sockaddr_un *s_un; struct sockaddr_in saddr_in; struct sockaddr_in *s_in; struct sockaddr_in6 *s_in6; int connect_fd; char buffer[BUF_LEN]; char *p, *sp, *end, *start; unsigned int h_entry, h_id; str id; unsigned short port; struct sockaddr* saddr; int len, i,n, left; int optval = 1; struct sockaddr rtpp_info; struct rtpp_notify_node *rtpp_lst; str terminate_reason = str_init("RTPProxy Timeout"); int offset = 0; if (init_child(PROC_MODULE) != 0) { LM_ERR("cannot init child process"); return; } if (!rtpp_notify_socket_un) { p = strrchr(rtpp_notify_socket.s, ':'); if (!p) { LM_ERR("invalid udp address <%.*s>\n", rtpp_notify_socket.len, rtpp_notify_socket.s); return; } n = p- rtpp_notify_socket.s; rtpp_notify_socket.s[n] = 0; id.s = p+1; id.len = rtpp_notify_socket.len - n -1; port= str2s(id.s, id.len, &n); if(n) { LM_ERR("Bad format for socket name. Expected ip:port\n"); return; } memset(&saddr_in, 0, sizeof(saddr_in)); saddr_in.sin_addr.s_addr = inet_addr(rtpp_notify_socket.s); saddr_in.sin_family = AF_INET; saddr_in.sin_port = htons(port); socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd == -1) { LM_ERR("can't create timeout socket\n"); return; } saddr = (struct sockaddr*)&saddr_in; len = sizeof(saddr_in); LM_DBG("binding socket %d to %s:%d\n", socket_fd, rtpp_notify_socket.s, port); } else { /* create socket */ socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (socket_fd == -1) { LM_ERR("Failed to create unix socket\n"); return; } memset(&saddr_un, 0, sizeof(struct sockaddr_un)); saddr_un.sun_family = AF_LOCAL; strncpy(saddr_un.sun_path, rtpp_notify_socket.s, sizeof(saddr_un.sun_path) - 1); saddr = (struct sockaddr*)&saddr_un; len = sizeof(saddr_un); LM_DBG("binding unix socket %s\n", rtpp_notify_socket.s); } if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(optval)) == -1) { LM_ERR("setsockopt failed %s\n", strerror(errno)); return; } if (bind(socket_fd, saddr, len) == -1) { LM_ERR("failed to bind to socket: %s\n", strerror(errno)); return; } /* open socket for listening */ if(listen(socket_fd, 10) == -1) { LM_ERR("socket listen failed: %s(%d)\n", strerror(errno), errno); close(socket_fd); return; } pfds = (struct pollfd *)pkg_malloc(pfds_size*sizeof(struct pollfd)); if (!pfds) { LM_ERR("no more pkg memory\n"); return; } pfds[0].fd = socket_fd; pfds[nfds++].events = POLLIN; for(;;) { nr_events = poll(pfds, nfds, -1); if (nr_events < 0) continue; /* check if the rtpproxy list needs updates */ lock_get(rtpp_notify_h->lock); if (rtpp_notify_h->changed) { /* update list */ update_rtpproxy_list(); rtpp_notify_h->changed = 0; } lock_release(rtpp_notify_h->lock); rtpp_lst = NULL; /* there is a new connection */ if (pfds[0].revents & POLLIN) { i = sizeof(rtpp_info); memset(&rtpp_info, 0, i); connect_fd = accept(socket_fd, &rtpp_info, (socklen_t *)&i); if(connect_fd < 0) { LM_ERR("socket accept failed: %s(%d)\n", strerror(errno), errno); continue; } /* if it is a unix socket, try to authenticate it */ if (rtpp_info.sa_family == AF_UNIX) { s_un = (struct sockaddr_un*)&rtpp_info; /* check if the socket is already opened */ lock_get(rtpp_notify_h->lock); for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next) if ( rtpp_lst->mode == 0 && !strcmp(rtpp_lst->addr, s_un->sun_path)) break; /* if not found add a new one */ if (!rtpp_lst) { /* leave the lock for a moment */ lock_release(rtpp_notify_h->lock); rtpp_lst = (struct rtpp_notify_node*) shm_malloc(sizeof(struct rtpp_notify_node)); if (!rtpp_lst) { LM_ERR("no shm more memory\n"); return; } rtpp_lst->index = 0; rtpp_lst->mode = 0; rtpp_lst->addr = 0; /* copy the socket name */ len = strlen(s_un->sun_path); rtpp_lst->addr = (char *)shm_malloc(len + 1); if (!rtpp_lst->addr) { LM_ERR("no more shm memory\n"); return; } memcpy(rtpp_lst->addr, s_un->sun_path, len + 1); lock_get(rtpp_notify_h->lock); rtpp_lst->next = rtpp_notify_h->rtpp_list; rtpp_notify_h->rtpp_list = rtpp_lst; } } else { /* search if I can find this connection */ if (rtpp_info.sa_family == AF_INET) { s_in = (struct sockaddr_in*)&rtpp_info; lock_get(rtpp_notify_h->lock); for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next) if (rtpp_lst->mode == 1 && memcmp(rtpp_lst->addr, &s_in->sin_addr.s_addr, 4) == 0) break; } else if (rtpp_info.sa_family == AF_INET6) { s_in6 = (struct sockaddr_in6*)&rtpp_info; lock_get(rtpp_notify_h->lock); for (rtpp_lst = rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst = rtpp_lst->next) if (rtpp_lst->mode == 6 && memcmp(rtpp_lst->addr, s_in6->sin6_addr.s6_addr, 16) == 0) break; } else { LM_ERR("cannot accept this type of connection\n"); } } if (!rtpp_lst) { lock_release(rtpp_notify_h->lock); LM_DBG("unknown rtpproxy -- ignoring\n"); shutdown(connect_fd, SHUT_RDWR); close(connect_fd); } else { /* valid connection - checking if already connected */ if (rtpp_lst->index) { LM_DBG("rtpproxy restarted - update connection status\n"); shutdown(rtpp_lst->fd, SHUT_RDWR); close(rtpp_lst->fd); } else { rtpp_lst->index = nfds++; if (nfds > pfds_size) { pfds_size *= 2; pfds = (struct pollfd*)pkg_realloc(pfds, pfds_size*sizeof(struct pollfd)); } } LM_DBG("rtpproxy accepted\n"); pfds[rtpp_lst->index].fd = connect_fd; pfds[rtpp_lst->index].events = POLLIN; rtpp_lst->fd = connect_fd; lock_release(rtpp_notify_h->lock); } nr_events--; } for (i=1; (nr_events && i<nfds); i++) { if (!(pfds[i].revents & POLLIN)) continue; nr_events--; do len = read(pfds[i].fd, buffer + offset, BUF_LEN - offset); while (len == -1 && errno == EINTR); if (len < 0) { LM_ERR("reading from socket failed: %s\n",strerror(errno)); continue; } if (!len) { LM_DBG("closing rtpproxy\n"); lock_get(rtpp_notify_h->lock); for (rtpp_lst=rtpp_notify_h->rtpp_list; rtpp_lst;rtpp_lst=rtpp_lst->next) if (rtpp_lst->index == i) break; if (!rtpp_lst) { LM_ERR("BUG - rtpproxy not found\n"); lock_release(rtpp_notify_h->lock); continue; } rtpp_lst->index = 0; lock_release(rtpp_notify_h->lock); nfds--; shutdown(pfds[i].fd, SHUT_RDWR); close(pfds[i].fd); if (nfds == i) continue; pfds[i].fd = pfds[nfds].fd; lock_get(rtpp_notify_h->lock); for (rtpp_lst=rtpp_notify_h->rtpp_list; rtpp_lst; rtpp_lst=rtpp_lst->next) if (rtpp_lst->index == nfds) break; if (!rtpp_lst) { LM_ERR("BUG - rtpproxy index mismatch\n"); lock_release(rtpp_notify_h->lock); continue; } rtpp_lst->index = i; lock_release(rtpp_notify_h->lock); continue; } LM_INFO("Timeout detected on the following calls [%.*s]\n", len, buffer); p = buffer; left = len + offset; offset = 0; end = buffer + left; do { start = p; /* the message is: h_entry.h_id\n */ sp = memchr(p, '.', left); if (sp == NULL) break; id.s = p; id.len = sp - p; if (sp >= end) break; p = sp + 1; left -= id.len + 1; if(str2int(&id, &h_entry)< 0) { LM_ERR("Wrong formated message received from rtpproxy - invalid" " dialog entry [%.*s]\n", id.len, id.s); break; } sp = memchr(p, '\n', left); if (sp == NULL) break; id.s = p; id.len = sp - p; if (sp >= end) break; p = sp + 1; left -= id.len + 1; if(str2int(&id, &h_id)< 0) { LM_ERR("Wrong formated message received from rtpproxy - invalid" " dialog id [%.*s]\n", id.len, id.s); break; } LM_DBG("hentry = %u, h_id = %u\n", h_entry, h_id); if(dlg_api.terminate_dlg(h_entry, h_id,&terminate_reason)< 0) LM_ERR("Failed to terminate dialog h_entry=[%u], h_id=[%u]\n", h_entry, h_id); LM_DBG("Left to process: %d\n[%.*s]\n", left, left, p); } while (p < end); offset = end - start; memmove(buffer, start, end - start); } } }
/** * Returns the content of the Service-Route header. * data vector is pkg_alloced and should be later freed * inside values are not duplicated * @param msg - the SIP message * @param size - size of the returned vector, filled with the result * @param is_shm - msg from shared memory * @returns - the str vector of uris */ str* cscf_get_service_route(struct sip_msg *msg, int *size, int is_shm) { struct hdr_field *h; rr_t *r, *r2; str *x = 0; int k; if (!size) return 0; *size = 0; if (!msg) return 0; if (parse_headers(msg, HDR_EOH_F, 0) < 0) { LM_ERR("error parsing headers\n"); return 0; } h = msg->headers; while (h) { if (h->name.len == 13 && strncasecmp(h->name.s, "Service-Route", 13) == 0) { if (parse_rr(h) < 0) { LM_ERR("Error parsing as Route header\n"); continue; } r = (rr_t*) h->parsed; h->type = HDR_ROUTE_T; r2 = r; k = 0; while (r2) { k++; r2 = r2->next; } if (!k) { LM_DBG("No items in this Service-Route\n"); continue; } x = pkg_realloc(x,(*size+k)*sizeof(str)); if (!x) { LM_ERR("Error our of pkg memory"); return 0; } r2 = r; while (r2) { x[*size] = r2->nameaddr.uri; (*size) = (*size) + 1; r2 = r2->next; } } h = h->next; } if (is_shm) { h = msg->headers; while (h) { if (h->name.len == 13 && strncasecmp(h->name.s, "Service-Route", 13) == 0) { r = (rr_t*) h->parsed; h->parsed = 0; free_rr(&r); } h = h->next; } } return x; }
static char* serialize_he_rdata(struct hostent *he,int *buf_len,int do_encoding) { unsigned char *p; int i,len=0,needed_len=0,base64_len=0,alias_no=0,addr_no=0; /* addr_type, name_len, alias_no, addr_no */ len+=sizeof(int)*4; /* compute needed buffer length */ if (he->h_name) len+=strlen(he->h_name)+1; if (he->h_aliases) for (i=0;he->h_aliases[i];i++) { /* integer with len + len bytes of alias */ len+=strlen(he->h_aliases[i])+1+sizeof(int); alias_no++; } i=0; if (he->h_addr_list) for (i=0;he->h_addr_list[i];i++) { len+=he->h_length; addr_no++; } if (do_encoding) { /* backend does not support binary values - allocate continous buffer for encoding */ base64_len = calc_base64_encode_len(len); needed_len=len+base64_len; } else needed_len = len; if (he_buf == NULL || needed_len > he_buf_len) { /* realloc if not enough space */ he_buf = pkg_realloc(he_buf,needed_len); if (he_buf == NULL) { LM_ERR("No more pkg\n"); return NULL; } he_buf_len = needed_len; } p = he_buf; /* copy address type */ memcpy(p,&he->h_addrtype,sizeof(int)); p+=sizeof(int); /* copy h_name len */ len=strlen(he->h_name)+1; memcpy(p,&len,sizeof(int)); p+=sizeof(int); /* copy h_name */ memcpy(p,he->h_name,len); p+=len; /* copy number of aliases */ memcpy(p,&alias_no,sizeof(int)); p+=sizeof(int); /* copy aliases, if any */ if (he->h_aliases) for (i=0;he->h_aliases[i];i++) { len=strlen(he->h_aliases[i])+1; /* copy alias length */ memcpy(p,&len,sizeof(int)); p+=sizeof(int); /* copy alias */ memcpy(p,he->h_aliases[i],len); p+=len; } /* copy address no */ memcpy(p,&addr_no,sizeof(int)); p+=sizeof(int); /* copy addresses */ if (he->h_addr_list) for (i=0;he->h_addr_list[i];i++) { /* copy addreses. length will be known from the addrtype field */ len=he->h_length; memcpy(p,he->h_addr_list[i],len); p+=len; } if (do_encoding) { len = needed_len - base64_len; if (buf_len) *buf_len=base64_len; /* do encoding, and return pointer after unencoded data */ base64encode(p,he_buf,len); return (char *)p; } else { if (buf_len) *buf_len = needed_len; return (char *)he_buf; } }
/* creates an url string without password field*/ static void db_get_url(const str* url){ struct db_id* id = new_db_id(url); static str scheme_delimiter={"://",3}; static str port_delimiter={":",1}; static str host_delimiter={"@",1}; static str database_delimiter={"/",1}; str port; /* allocate memory for the database url if necessary*/ database_url.len = 0; /* sanity checks */ if (id == NULL) return; database_url.s = pkg_realloc(database_url.s, url->len * sizeof(char)); if (database_url.s == NULL) { free_db_id(id); return; } /* shortest database_url is s://a/b so we always need the scheme delimiter*/ if (id->scheme != NULL) { memcpy(database_url.s + database_url.len, id->scheme, strlen(id->scheme)); database_url.len += strlen(id->scheme); memcpy(database_url.s + database_url.len, scheme_delimiter.s, scheme_delimiter.len); database_url.len += scheme_delimiter.len; } if (id->username != NULL) { memcpy(database_url.s + database_url.len, id->username, strlen(id->username)); database_url.len += strlen(id->username); } if (id->host != NULL) { memcpy(database_url.s + database_url.len, host_delimiter.s, host_delimiter.len); database_url.len += host_delimiter.len; memcpy(database_url.s + database_url.len, id->host, strlen(id->host)); database_url.len += strlen(id->host); } if (id->port > 0) { port.s = int2str(id->port,&port.len); memcpy(database_url.s + database_url.len, port_delimiter.s, port_delimiter.len); database_url.len += port_delimiter.len; memcpy(database_url.s + database_url.len, port.s, port.len); database_url.len += port.len; } if (id->database != NULL){ memcpy(database_url.s + database_url.len, database_delimiter.s, database_delimiter.len); database_url.len += database_delimiter.len; memcpy(database_url.s + database_url.len, id->database, strlen(id->database)); database_url.len += strlen(id->database); } /* free alocated memory */ free_db_id(id); }
static struct hostent* deserialize_he_rdata(char *buff,int buf_len,int do_decoding) { char **ap,**hap; unsigned char *p; int max_len=0,actual_len=0; int i,alias_no=0,addr_no=0,len=0; /* max estimation of needed buffer */ if (do_decoding) { max_len=calc_max_base64_decode_len(buf_len); } else { max_len = buf_len; } if (dec_he_buf == NULL || max_len > dec_he_buf_len) { /* realloc buff if not enough space */ dec_he_buf = pkg_realloc(dec_he_buf,max_len); if (dec_he_buf == NULL) { LM_ERR("No more pkg\n"); return NULL; } dec_he_buf_len = max_len; } /* set pointer in dec_global_he */ ap = host_aliases; *ap = NULL; dec_global_he.h_aliases = host_aliases; hap = h_addr_ptrs; *hap = NULL; dec_global_he.h_addr_list = h_addr_ptrs; if (do_decoding) { /* decode base64 buf */ actual_len = base64decode(dec_he_buf,(unsigned char *)buff,buf_len); p = dec_he_buf; } else { memcpy(dec_he_buf,buff,buf_len); p = dec_he_buf; } /* set address type & length */ memcpy(&dec_global_he.h_addrtype,p,sizeof(int)); p+=sizeof(int); if (dec_global_he.h_addrtype == AF_INET) dec_global_he.h_length=4; else dec_global_he.h_length=16; /* set name */ memcpy(&len,p,sizeof(int)); p+=sizeof(int); dec_global_he.h_name = (char *)p; p+=len; /* get number of aliases */ memcpy(&alias_no,p,sizeof(int)); p+=sizeof(int); for (i=0;i<alias_no;i++) { /* get alias length, set pointer and skip over length */ memcpy(&len,p,sizeof(int)); p+=sizeof(int); *ap++ = (char *)p; p+=len; } /* get number of addresses */ memcpy(&addr_no,p,sizeof(int)); p+=sizeof(int); for (i=0;i<addr_no;i++) { /* set pointer and skip over length */ *hap++ = (char *)p; p+=dec_global_he.h_length; } return &dec_global_he; }
/* method that processes a stream and keeps the original order * of codecs with the same name */ static int stream_process(struct sip_msg * msg, struct sdp_stream_cell *cell, str * s, str* ss, regex_t* re, int op,int description) { static sdp_payload_attr_t static_payloads[] = { /* as per http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml */ { NULL,0,{ "0",1},{"PCMU",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 0 - PCMU/8000 */ { NULL,0,{ "3",1},{ "GSM",3},{ "8000",4},{NULL,0},{NULL,0} }, /* 3 - GSM/8000 */ { NULL,0,{ "4",1},{"G723",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 4 - G723/8000 */ { NULL,0,{ "5",1},{"DVI4",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 5 - DVI4/8000 */ { NULL,0,{ "6",1},{"DVI4",4},{"16000",5},{NULL,0},{NULL,0} }, /* 6 - DVI4/16000 */ { NULL,0,{ "7",1},{ "LPC",3},{ "8000",4},{NULL,0},{NULL,0} }, /* 7 - LPC/8000 */ { NULL,0,{ "8",1},{"PCMA",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 8 - PCMA/8000 */ { NULL,0,{ "9",1},{"G722",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 9 - G722/8000 */ { NULL,0,{"10",2},{ "L16",3},{"44100",5},{NULL,0},{NULL,0} }, /*10 - L16/44100 */ { NULL,0,{"11",2},{ "L16",3},{"44100",5},{NULL,0},{NULL,0} }, /*11 - L16/44100 */ { NULL,0,{"12",2},{"QCELP",5},{"8000",4},{NULL,0},{NULL,0} }, /*12 -QCELP/8000 */ { NULL,0,{"13",2},{ "CN",2},{ "8000",4},{NULL,0},{NULL,0} }, /*13 - CN/8000 */ { NULL,0,{"14",2},{ "MPA",3},{"90000",5},{NULL,0},{NULL,0} }, /*14 - MPA/90000 */ { NULL,0,{"15",2},{"G728",4},{ "8000",4},{NULL,0},{NULL,0} }, /*15 - G728/8000 */ { NULL,0,{"16",2},{"DVI4",4},{"11025",5},{NULL,0},{NULL,0} }, /*16 - DVI4/11025 */ { NULL,0,{"17",2},{"DVI4",4},{"22050",5},{NULL,0},{NULL,0} }, /*17 - DVI4/22050 */ { NULL,0,{"18",2},{"G729",4},{ "8000",4},{NULL,0},{NULL,0} }, /*18 - G729/8000 */ { NULL,0,{"25",2},{"CelB",4},{ "8000",4},{NULL,0},{NULL,0} }, /*25 - CelB/8000 */ { NULL,0,{"26",2},{"JPEG",4},{"90000",5},{NULL,0},{NULL,0} }, /*26 - JPEG/90000 */ { NULL,0,{"28",2},{ "nv",2},{"90000",5},{NULL,0},{NULL,0} }, /*28 - nv/90000 */ { NULL,0,{"31",2},{"H261",4},{"90000",5},{NULL,0},{NULL,0} }, /*31 - H261/90000 */ { NULL,0,{"32",2},{ "MPV",3},{"90000",5},{NULL,0},{NULL,0} }, /*32 - MPV/90000 */ { NULL,0,{"33",2},{"MP2T",4},{"90000",5},{NULL,0},{NULL,0} }, /*33 - MP2T/90000 */ { NULL,0,{"34",2},{"H263",4},{"90000",5},{NULL,0},{NULL,0} }, /*34 - H263/90000 */ { NULL,0,{"t38",3},{"t38",3},{ "",0},{NULL,0},{NULL,0} }, /*T38- fax */ { NULL,0,{NULL,0},{ NULL,0},{ NULL,0},{NULL,0},{NULL,0} } }; sdp_payload_attr_t *payload; char *cur, *tmp, *buff, temp; struct lump * lmp; str found; int ret, i, depl, single, match, buff_len, is_static; regmatch_t pmatch; lmp = get_associated_lump(msg, cell); if( lmp == NULL) { LM_ERR("There is no lump for this sdp cell\n"); return -1; } /* is stream deleted ?? */ if (lmp->len == 0) return -1; buff_len = 0; ret = 0; buff = pkg_malloc(lmp->len+1); if( buff == NULL) { LM_ERR("Out of memory\n"); return -1; } /* search through each payload */ is_static = 0; payload = cell->payload_attr; while(payload) { if( payload->rtp_enc.s == NULL || (payload->rtp_clock.s == NULL && ss != NULL) || payload->rtp_payload.s == NULL) { goto next_payload; } match = 0; if( description == DESC_REGEXP ||description == DESC_REGEXP_COMPLEMENT ) { /* try to match a regexp */ if (is_static) { match = regexec( re, payload->rtp_enc.s, 1, &pmatch, 0) == 0; } else { temp = payload->rtp_enc.s[payload->rtp_enc.len]; payload->rtp_enc.s[payload->rtp_enc.len] = 0; match = regexec( re, payload->rtp_enc.s, 1, &pmatch, 0) == 0; payload->rtp_enc.s[payload->rtp_enc.len] = temp; } } if( description == DESC_REGEXP_COMPLEMENT) match = !match; if( description == DESC_NAME ) { match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0; } if( description == DESC_NAME_AND_CLOCK) { /* try to match name and clock if there is one */ match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0 && (ss == NULL || ( ss->len == payload->rtp_clock.len && strncasecmp( ss->s, payload->rtp_clock.s , payload->rtp_clock.len) == 0 ) ); } /* if found, search its index in the m= line */ if (match) { match = 0; cur = lmp->u.value; while( !match && cur < lmp->u.value + lmp->len) { /* find the end of the number */ found.s = cur; while( cur < lmp->u.value + lmp->len && *cur != ' ' ) cur++; found.len = cur - found.s; /* does it matches payload number */ if ( found.len == payload->rtp_payload.len && strncmp( found.s,payload->rtp_payload.s,found.len) == 0) { match = 1; } else { /* continue on searching => skip spaces if there still are any */ while( cur < lmp->u.value + lmp->len && * cur == ' ' ) cur++; } } /* have we found both payload and index */ if (match) { if(op == FIND) { ret = 1; goto end; } if( op == DELETE && !is_static ) { /* find the full 'a=...' entry */ if( delete_sdp_line( msg, payload->rtp_enc.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } if( delete_sdp_line( msg, payload->fmtp_string.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } } { /* take the following whitespaces as well */ while( cur < lmp->u.value + lmp->len && *cur == ' ' ) { cur++; found.len++; } /* when trimming the very last payload, avoid trailing ws */ if (cur == lmp->u.value + lmp->len) { tmp = found.s; while (*(--tmp) == ' ') { found.s--; found.len++; } } /* delete the string and update iterators */ for(tmp=found.s ; tmp< lmp->u.value + lmp->len ; tmp++ ) *tmp = *(tmp+found.len); cur -= found.len; lmp->len -= found.len; } /* add the deleted number into a buffer to be addded later */ if( op == ADD_TO_FRONT || op == ADD_TO_BACK) { if( buff_len > 0) { memcpy(&buff[buff_len]," ",1); buff_len++; } memcpy(&buff[buff_len],payload->rtp_payload.s, payload->rtp_payload.len); buff_len += payload->rtp_payload.len; } ret = 1; } } /* next payload */ next_payload: if (!is_static) { payload = payload->next; if (payload==NULL) { payload = static_payloads; is_static = 1; } } else { payload ++; if (payload->rtp_payload.s==NULL) payload=NULL; } } if( op == ADD_TO_FRONT && buff_len >0 ) { depl = buff_len; single = 1; if( lmp->len > 0) { depl++; single = 0; } lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+depl); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } for( i = lmp->len -1 ; i>=0;i--) lmp->u.value[i+depl] = lmp->u.value[i]; memcpy(lmp->u.value,buff,buff_len); if(!single) lmp->u.value[buff_len] = ' '; lmp->len += depl; } if( op == ADD_TO_BACK && buff_len >0 ) { lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+buff_len+1); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } if( lmp->len > 0) { memcpy(&lmp->u.value[lmp->len]," ",1); lmp->len++; } memcpy(&lmp->u.value[lmp->len],buff,buff_len); lmp->len += buff_len; } end: pkg_free(buff); return ret; }
/** * Query a table for specified rows. * \param _h structure representing database connection * \param _k key names * \param _op operators *\param _v values of the keys that must match * \param _c column names to return * \param _n number of key=values pairs to compare * \param _nc number of columns to return * \param _o order by the specified column * \param _r pointer to a structure representing the result * \return zero on success, negative value on failure */ int erlang_srdb1_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op, const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc, const db_key_t _o, db1_res_t** _r) { ei_x_buff argbuf,retbuf; int retcode,i,j,x; int n_cols,n_rows,len; db1_res_t *res; db_row_t *rows = NULL, *row; db_val_t *val; char atom[MAXATOMLEN], *p; ei_term term; int ei_type,size; str *sname; if (!_h || !_r) { LM_ERR("invalid parameter value\n"); return -1; } *_r=NULL; LM_DBG("erlang_srdb1_query table %.*s\n",CON_TABLE(_h)->len, CON_TABLE(_h)->s); ei_x_new(&argbuf); //encode tuple {db_op, table, [cols], [params]} ei_x_encode_tuple_header(&argbuf, 5); ei_x_encode_atom(&argbuf,"select"); ei_x_encode_atom_len(&argbuf,CON_TABLE(_h)->s,CON_TABLE(_h)->len); srdb1_encode_c(_c, _nc, &argbuf); srdb1_encode_k(_k, _op, _v, _n, &argbuf); // ei_x_encode_atom_len(&argbuf,_o->s,_o->len); ei_x_encode_list_header(&argbuf, 0); retcode=erl_bind.do_erlang_call(&(CON_ERLANG(_h)->con),&(CON_ERLANG(_h)->regname), &argbuf, &retbuf); ei_x_free(&argbuf); if (retcode<0) { if(retbuf.buff) shm_free(retbuf.buff); return retcode; } // we have a tuple there: ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &i); x=retbuf.index; ei_skip_term(retbuf.buff, &x); LM_DBG("erlang_srdb1_query: position of end of field list should be %d\n",x); //first is list of 5-element tuples containing name and type of field ei_decode_list_header(retbuf.buff, &(retbuf.index), &n_cols); LM_DBG("erlang_srdb1_query: length -f field_list is %d\n",n_cols); res=db_new_result(); if (db_allocate_columns(res, n_cols) != 0) { LM_ERR("erlang_srdb1_query: db_allocate_columns failed\n"); goto error; } RES_COL_N(res) = n_cols; for(i=0; i < n_cols; i++) { x=retbuf.index; ei_skip_term(retbuf.buff, &x); LM_DBG("erlang_srdb1_query: position of end of this field should be %d\n",x); ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &j); if( j!=5) LM_ERR("erlang_srdb1_query name&type list element tuple is not 5\n"); ei_decode_atom(retbuf.buff, &(retbuf.index), atom); //1 name len=strlen(atom); sname = (str*)pkg_malloc(sizeof(str)+len+1); if (!sname) { LM_ERR("no private memory left\n"); goto error; } sname->len = len; sname->s = (char*)sname + sizeof(str); memcpy(sname->s, atom, len); sname->s[len] = '\0'; RES_NAMES(res)[i] = sname; LM_DBG("decoded header %d, fieled 1: %s\n",i,atom); ei_decode_atom(retbuf.buff, &(retbuf.index), atom); //2 type atom if(strcmp("int",atom)==0) { RES_TYPES(res)[i]=DB1_INT; } if(strcmp("string",atom)==0) { RES_TYPES(res)[i]=DB1_STRING; } if(strcmp("float",atom)==0) { RES_TYPES(res)[i]=DB1_DOUBLE; } if(strcmp("datetime",atom)==0) { RES_TYPES(res)[i]=DB1_DATETIME; } // if(strcmp("string",atom)==0) { RES_TYPES(res)[i]=DB1_BLOB; } ei_skip_term(retbuf.buff, &(retbuf.index)); //3 size (ignored) ei_skip_term(retbuf.buff, &(retbuf.index)); //4 default value (ignored) ei_skip_term(retbuf.buff, &(retbuf.index)); //3 null status (ignored) LM_DBG("end of %d record: %d\n",i,retbuf.index); } ei_decode_ei_term(retbuf.buff, &(retbuf.index), &term); // List tail, LM_DBG("erlang_srdb1_query: position after scanning is %d\n",retbuf.index); //now rows, list of tuples ei_decode_list_header(retbuf.buff, &(retbuf.index), &n_rows); LM_DBG("erlang_srdb1_query values list size is %d\n",n_rows); if (n_rows<=0) { LM_DBG("erlang_srdb1_query no rows returned\n"); RES_ROWS(res) = NULL; RES_NUM_ROWS(res)=0; *_r=res; return 0; } RES_NUM_ROWS(res)=n_rows; rows = pkg_realloc(rows, sizeof(db_row_t) * n_rows); if (rows == NULL) { LM_ERR("erlang_srdb1_query: pkg_realloc rows failed\n"); goto error; } RES_ROWS(res) = rows; for(i=0; i < n_rows; i++) { RES_ROW_N(res)=i+1; row = &RES_ROWS(res)[i]; if (db_allocate_row(res, row) != 0) { LM_ERR("erlang_srdb1_query: db_allocate_row failed for row %d\n",i); goto error; } ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &j); if(j!=n_cols) { LM_ERR("erlang_srdb1_query: mismatch:values list element tuple size is %d n_cols from header was %d\n",j, n_cols); } for (j = 0, val = ROW_VALUES(row); j < RES_COL_N(res); j++, val++) { VAL_TYPE(val) = RES_TYPES(res)[j]; VAL_NULL(val) = 0; VAL_FREE(val) = 0; retcode=ei_get_type_internal(retbuf.buff, &(retbuf.index), &ei_type, &size); if (retcode < 0) { LM_ERR("erlang_srdb1_query: error getting type for element %d %d\n",i,j); goto error; } LM_DBG("erlang_srdb1_query: element %d %d ei_type=%d size=%d\n",i,j,ei_type, size); switch(ei_type) { case ERL_SMALL_INTEGER_EXT: case ERL_INTEGER_EXT: retcode=ei_decode_long(retbuf.buff, &(retbuf.index), &VAL_INT(val)); if(retcode < 0) goto error; LM_DBG("decoded interger %d\n",VAL_INT(val)); break; case ERL_FLOAT_EXT: case NEW_FLOAT_EXT: retcode=ei_decode_double(retbuf.buff, &(retbuf.index), &VAL_DOUBLE(val)); if(retcode < 0) goto error; LM_DBG("decoded float %f\n",VAL_DOUBLE(val)); break; case ERL_ATOM_EXT: case ERL_SMALL_ATOM_EXT: case ERL_ATOM_UTF8_EXT: case ERL_SMALL_ATOM_UTF8_EXT: p=pkg_malloc(size+1); if(!p) { LM_ERR("erlang_srdb1_query: no memory\n"); goto error; } retcode=ei_decode_atom(retbuf.buff, &(retbuf.index), p); if(retcode < 0) { pkg_free(p); goto error; } LM_DBG("decoded small_atom_utf %s\n",p); VAL_STRING(val)=p; VAL_FREE(val)=1; break; case ERL_STRING_EXT: p=pkg_malloc(size+1); if(!p) { LM_ERR("erlang_srdb1_query: no memory\n"); goto error; } retcode=ei_decode_string(retbuf.buff, &(retbuf.index), p); if(retcode < 0) { pkg_free(p); goto error; } LM_DBG("decoded string %s\n",p); VAL_STRING(val)=p; VAL_FREE(val)=1; break; case ERL_SMALL_TUPLE_EXT: case ERL_LARGE_TUPLE_EXT: LM_DBG("got tuple)\n"); if (VAL_TYPE(val)==DB1_DATETIME) { struct tm tm; LM_DBG("and col type is datetime\n"); retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x); if(retcode < 0) goto error; retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x); if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_year);tm.tm_year -=1900; if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_mon); tm.tm_mon -=1; if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_mday); if(retcode < 0) goto error; retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x); if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_hour); if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_min); if(retcode < 0) goto error; retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_sec); if(retcode < 0) goto error; VAL_TIME(val)=mktime(&tm); break; } LM_ERR("erlang_srdb1_query: got tuple but valtype is not datetime element %d in row %d in response\n",j,i); break; case ERL_REFERENCE_EXT: case ERL_NEW_REFERENCE_EXT: case ERL_PORT_EXT: case ERL_PID_EXT: case ERL_NIL_EXT: case ERL_LIST_EXT: case ERL_BINARY_EXT: case ERL_SMALL_BIG_EXT: case ERL_LARGE_BIG_EXT: case ERL_NEW_FUN_EXT: case ERL_FUN_EXT: default: LM_ERR("erlang_srdb1_query: don't know how to handle element %d in row %d in response\n",j,i); } } } ei_decode_ei_term(retbuf.buff, &(retbuf.index), &term); // List tail, *_r=res; return 0; error: if (res) db_free_result(res); LM_ERR("erlang_srdb1_query: Failed\n"); return -1; }