static inline void parse_algo_hdr(struct hdr_field* algo_hdr, int* algo, int* b64_required) { int rc; char* delim=NULL; str tok; str s_tok; s_tok.s = algo_hdr->body.s; s_tok.len = algo_hdr->body.len; do { delim = q_memchr(s_tok.s, ATTR_DELIM[0], s_tok.len); if (delim==NULL) { trim_spaces_lr(s_tok); rc = get_algo(&s_tok); } else { tok.s = s_tok.s; tok.len = delim - s_tok.s; s_tok.s = delim+1; s_tok.len = (delim-tok.s+1); trim_spaces_lr(tok); rc = get_algo(&tok); } if (rc < 2 && rc >=0) *algo = rc; else *b64_required = rc; } while(delim); }
static int strtime(const str *time, int *ihrs, int *imin) { char *colon = q_memchr(time->s, FRD_TIME_SEP, time->len); if (colon == NULL) goto parse_error; str hrs = {time->s, colon - time->s}; str min = {colon + 1, time->len - hrs.len - 1}; if (hrs.len == 0 || min.len == 0) goto parse_error; unsigned int uhrs, umin; if (str2int(&hrs, &uhrs) || str2int(&min, &umin)) goto parse_error; if (uhrs > 23 || umin >= 60) goto parse_error; *imin = umin; *ihrs = uhrs; return 0; parse_error: LM_ERR("cannot parse time-value <%.*s>", time->len, time->s); return -1; }
static int parse_cmd(str* res, str* buffer) { char* cmd_end; if (!res || !buffer) { LOG(L_ERR, "parse_cmd: Invalid parameter value\n"); return -1; } if (buffer->len < 3) { LOG(L_ERR, "parse_cmd: Message too short\n"); return -1; } if (buffer->s[0] != CMD_SEPARATOR) { LOG(L_ERR, "parse_cmd: Command must start with %c\n", CMD_SEPARATOR); return -1; } cmd_end = q_memchr(buffer->s + 1, CMD_SEPARATOR, buffer->len - 1); if (!cmd_end) { LOG(L_ERR, "parse_cmd: Closing '%c' missing\n", CMD_SEPARATOR); return -1; } res->s = buffer->s + 1; res->len = cmd_end - res->s; return 0; }
int select_nameaddr_uri(str* res, select_t* s, struct sip_msg* msg) { char *p; p=find_not_quoted(res, '<'); if (!p) { LM_DBG("no < found, string up to first semicolon is uri\n"); p = q_memchr(res->s, ';', res->len); if (p) res->len = p-res->s; return 0; } res->len=res->len - (p-res->s) -1; res->s=p +1; p=find_not_quoted(res, '>'); if (!p) { LM_ERR("no > found, invalid nameaddr value\n"); return -1; } res->len=p-res->s; return 0; }
static unsigned long long do_acc_parse(str* in, do_acc_parser parser) { char* found=NULL; str token; unsigned long long fret=0, ret; if (!in || !in->s || !in->len) return -1; do { found=q_memchr(in->s, DO_ACC_PARAM_DELIMITER, in->len); if (found) { token.s = in->s; token.len = found - in->s; in->len -= (found - in->s) + 1; in->s = found + 1; } else { token = *in; } if ((ret=parser(&token)) < 0) { LM_ERR("Invalid token <%.*s>!\n", token.len, token.s); return -1; } fret |= ret; } while(found); return fret; }
/* * Parse quoted string in a parameter body * return the string without quotes in r * parameter and update s to point behind the * closing quote */ static inline int parse_quoted(str* s, str* r) { char* end_quote; /* The string must have at least surrounding quotes */ if (s->len < 2) return -1; /* Skip opening quote */ s->s++; s->len--; /* Find closing quote */ end_quote = q_memchr(s->s, '\"', s->len); /* Not found, return error */ if (!end_quote) return -2; /* Let r point to the string without surrounding quotes */ r->s = s->s; r->len = end_quote - s->s; /* Update s parameter to point behind the closing quote */ s->len -= (end_quote - s->s + 1); s->s = end_quote + 1; /* Everything went OK */ return 0; }
/** * extract the node list from the body of a notification request SIP message * the SIP request will look something like: * KDMQ sip:10.0.0.0:5062 * To: ... * From: ... * Max-Forwards: ... * Content-Length: 22 * * sip:host1:port1;param1=value1 * sip:host2:port2;param2=value2 * ... */ int extract_node_list(dmq_node_list_t* update_list, struct sip_msg* msg) { int content_length, total_nodes = 0; str body; str tmp_uri; dmq_node_t *cur = NULL; char *tmp, *end, *match; if(!msg->content_length) { LM_ERR("no content length header found\n"); return -1; } content_length = get_content_length(msg); if(!content_length) { LM_DBG("content length is 0\n"); return total_nodes; } body.s = get_body(msg); body.len = content_length; tmp = body.s; end = body.s + body.len; /* acquire big list lock */ lock_get(&update_list->lock); while(tmp < end) { match = q_memchr(tmp, '\n', end - tmp); if(match) { match++; } else { /* for the last line - take all of it */ match = end; } /* create the orig_uri from the parsed uri line and trim it */ tmp_uri.s = tmp; tmp_uri.len = match - tmp - 1; tmp = match; /* trim the \r, \n and \0's */ trim_r(tmp_uri); if(!find_dmq_node_uri(update_list, &tmp_uri)) { LM_DBG("found new node %.*s\n", STR_FMT(&tmp_uri)); cur = build_dmq_node(&tmp_uri, 1); if(!cur) { LM_ERR("error creating new dmq node\n"); goto error; } cur->next = update_list->nodes; update_list->nodes = cur; update_list->count++; total_nodes++; } } /* release big list lock */ lock_release(&update_list->lock); return total_nodes; error: lock_release(&update_list->lock); return -1; }
/* * Returns the class part of the URI */ str *parseurl(const str* url) { static str cn; cn.s = q_memchr(url->s,':',url->len); if (cn.s && ((cn.s+1)<(url->s+url->len)) ) { cn.s++; cn.len = url->len - (cn.s-url->s); return &cn; } return NULL; }
/** initializes a net structure from a string. * @param dst - net structure that will be filled * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak". * @return -1 on error, 0 on succes */ int mk_net_str(struct net* dst, str* s) { struct ip_addr* t; char* p; struct ip_addr ip; str addr; str mask; unsigned int bitlen; /* test for ip only */ t = str2ip(s); if (unlikely(t == 0)) t = str2ip6(s); if (likely(t)) return mk_net_bitlen(dst, t, t->len*8); /* not a simple ip, maybe an ip/netmask pair */ p = q_memchr(s->s, '/', s->len); if (likely(p)) { addr.s = s->s; addr.len = (int)(long)(p - s->s); mask.s = p + 1; mask.len = s->len - (addr.len + 1); /* allow '/' enclosed by whitespace */ trim_trailing(&addr); trim_leading(&mask); t = str2ip(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } else { t = str2ip6(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip6(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } } } return -1; }
static int check_ftag(struct sip_msg* msg, str* uri) { param_hooks_t hooks; param_t* params; char* semi; struct to_body* from; str t; t = *uri; params = 0; semi = q_memchr(t.s, ';', t.len); if (!semi) { DBG("No ftag parameter found\n"); return -1; } t.len -= semi - uri->s + 1; t.s = semi + 1; trim_leading(&t); if (parse_params(&t, CLASS_URI, &hooks, ¶ms) < 0) { ERR("Error while parsing parameters\n"); return -1; } if (!hooks.uri.ftag) { DBG("No ftag parameter found\n"); goto err; } from = get_from(msg); if (!from || !from->tag_value.len || !from->tag_value.s) { DBG("No from tag parameter found\n"); goto err; } if (from->tag_value.len == hooks.uri.ftag->body.len && !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) { DBG("Route ftag and From tag are same\n"); free_params(params); return 0; } else { DBG("Route ftag and From tag are NOT same\n"); free_params(params); return 1; } err: if (params) free_params(params); return -1; }
/** @brief returns pointer to next line or after the end of buffer */ char* eat_line(char* buffer, unsigned int len) { char* nl; /* jku .. replace for search with a library function; not conforming as I do not care about CR */ nl=(char *)q_memchr( buffer, '\n', len ); if ( nl ) { if ( nl + 1 < buffer+len) nl++; if (( nl+1<buffer+len) && * nl=='\r') nl++; } else nl=buffer+len; return nl; }
/* * Parse username for user and domain parts */ static inline void parse_username(struct username* _u) { char* d; _u->user = _u->whole; if (_u->whole.len <= 2) return; d = q_memchr(_u->whole.s, '@', _u->whole.len); if (d) { _u->domain.s = d + 1; _u->domain.len = _u->whole.len - (d - _u->whole.s) - 1; _u->user.len = d - _u->user.s; } }
int db_delete_urecord(urecord_t* _r) { char b[256]; db_key_t keys[2]; db_val_t vals[2]; char* dom; keys[0] = user_col; keys[1] = domain_col; vals[0].type = DB_STR; vals[0].nul = 0; vals[0].val.str_val.s = _r->aor.s; vals[0].val.str_val.len = _r->aor.len; if (use_domain) { dom = q_memchr(_r->aor.s, '@', _r->aor.len); if (!dom) { LOG(L_ERR, "db_delete_urecord(): You forgot to set modparam(\"registrar\", \"use_domain\", 1) in ser.cfg!\n"); vals[0].val.str_val.len = _r->aor.len; vals[1].type = DB_STR; vals[1].nul = 0; vals[1].val.str_val.s = _r->aor.s; vals[1].val.str_val.len = 0; } else { vals[0].val.str_val.len = dom - _r->aor.s; vals[1].type = DB_STR; vals[1].nul = 0; vals[1].val.str_val.s = dom + 1; vals[1].val.str_val.len = _r->aor.s + _r->aor.len - dom - 1; } } /* FIXME */ memcpy(b, _r->domain->s, _r->domain->len); b[_r->domain->len] = '\0'; db_use_table(db, b); if (db_delete(db, keys, 0, vals, (use_domain) ? (2) : (1)) < 0) { LOG(L_ERR, "db_delete_urecord(): Error while deleting from database\n"); return -1; } return 0; }
/* * Parse username for user and domain parts */ static inline void parse_username(struct username* u) { char* d; u->user = u->whole; if (u->whole.len <= 2) return; d = q_memchr(u->whole.s, '@', u->whole.len); if (d) { u->domain.s = d + 1; u->domain.len = u->whole.len - (d - u->whole.s) - 1; u->user.len = d - u->user.s; } }
/*! \brief * Parse quoted string in a parameter body * return the string without quotes in _r * parameter and update _s to point behind the * closing quote */ static inline int parse_quoted_param(str *_s, str *_r) { char *end_quote; char quote; /* The string must have at least * surrounding quotes */ if(_s->len < 2) { return -1; } /* Store the kind of quoting (single or double) * which we're handling with */ quote = (_s->s)[0]; /* Skip opening quote */ _s->s++; _s->len--; /* Find closing quote */ end_quote = q_memchr(_s->s, quote, _s->len); /* Not found, return error */ if(!end_quote) { return -2; } /* Let _r point to the string without * surrounding quotes */ _r->s = _s->s; _r->len = end_quote - _s->s; /* Update _s parameter to point * behind the closing quote */ _s->len -= (end_quote - _s->s + 1); _s->s = end_quote + 1; /* Everything went OK */ return 0; }
int parse_param_name(str* _s, dig_par_t* _type) { register char* p; register int val; char* end; end = _s->s + _s->len; p = _s->s; val = READ(p); if (_s->len < 4) { goto other; } switch(LOWER_DWORD(val)) { FIRST_QUATERNIONS; default: PARSE_SHORT; goto other; } end: _s->len -= p - _s->s; _s->s = p; trim_leading(_s); if (_s->s[0] == '=') { return 0; } other: p = q_memchr(p, '=', end - p); if (!p) { return -1; /* Parse error */ } else { *_type = PAR_OTHER; _s->len -= p - _s->s; _s->s = p; return 0; } }
/* * Delete contact from the database */ int db_delete_ucontact(ucontact_t* _c) { char b[256]; char* dom; db_key_t keys[3]; db_val_t vals[3]; keys[0] = user_col; keys[1] = contact_col; keys[2] = domain_col; vals[0].type = DB_STR; vals[0].nul = 0; vals[0].val.str_val = *_c->aor; vals[1].type = DB_STR; vals[1].nul = 0; vals[1].val.str_val = _c->c; if (use_domain) { dom = q_memchr(_c->aor->s, '@', _c->aor->len); vals[0].val.str_val.len = dom - _c->aor->s; vals[2].type = DB_STR; vals[2].nul = 0; vals[2].val.str_val.s = dom + 1; vals[2].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1; } /* FIXME */ memcpy(b, _c->domain->s, _c->domain->len); b[_c->domain->len] = '\0'; db_use_table(db, b); if (db_delete(db, keys, 0, vals, (use_domain) ? (3) : (2)) < 0) { LOG(L_ERR, "db_del_ucontact(): Error while deleting from database\n"); return -1; } return 0; }
int check_addr_param1(str *s, struct part_var *pv) { char *end; unsigned int gid; int ret; str spart, sval; ret=0; spart.s = s->s; end = q_memchr(s->s, ':', s->len); ret = -1; if (end == NULL) { ret = str2int(s, &gid); pv->u.parsed_part.partition.s = NULL; if (0 == ret) pv->u.parsed_part.v.ival = gid; else { pv->u.parsed_part.v.sval.s = s->s; pv->u.parsed_part.v.sval.len = s->len; } } else { spart.len = end - spart.s; sval.s = end + 1; sval.len = (s->s + s->len) - sval.s; str_trim_spaces_lr(sval); str_trim_spaces_lr(spart); pv->u.parsed_part.partition = spart; ret = str2int(&sval, &gid); if (0 == ret) pv->u.parsed_part.v.ival = gid; else pv->u.parsed_part.v.sval = sval; } return 0; }
/* * Parse Digest credentials parameter, one by one */ static inline int parse_digest_params(str* _s, dig_cred_t* _c) { char* comma; do { /* Parse the first parameter */ if (parse_digest_param(_s, _c) < 0) { return -1; } /* Try to find the next parameter */ comma = q_memchr(_s->s, ',', _s->len); if (comma) { /* Yes, there is another, * remove any leading white-spaces * and let _s point to the next * parameter name */ _s->len -= comma - _s->s + 1; _s->s = comma + 1; trim_leading(_s); } } while(comma); /* Repeat while there are next parameters */ /* Parse QOP body if the parameter was present */ if (_c->qop.qop_str.s != 0) { parse_qop(&_c->qop); } /* Parse algorithm body if the parameter was present */ if (_c->alg.alg_str.s != 0) { parse_algorithm(&_c->alg); } if (_c->username.whole.s != 0) { parse_username(&_c->username); } return 0; }
/** * parse_hname2_short() - safer version to parse header name stored in short buffers * - parse_hanem2() reads 4 bytes at once, expecting to walk through a buffer * that contains more than the header name (e.g., sip msg buf, full header buf * with name and body) */ char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr) { #define HBUF_MAX_SIZE 256 char hbuf[HBUF_MAX_SIZE]; char *p; if(end-begin>=HBUF_MAX_SIZE-4) { p = q_memchr(begin, ':', end - begin); if(p && p-4> begin) { /* header name termination char found and enough space in buffer after it */ return parse_hname2(begin, end, hdr); } /* not enough space */ return NULL; } /* pad with whitespace - tipycal char after the ':' of the header name */ memset(hbuf, ' ', HBUF_MAX_SIZE); memcpy(hbuf, begin, end-begin); p = parse_hname2(hbuf, hbuf + 4 + (end-begin), hdr); if(!p) return NULL; return begin + (p-hbuf); }
/* * Parse quoted string in a parameter body * return the string without quotes in _r * parameter and update _s to point behind the * closing quote */ static inline int parse_quoted(str* _s, str* _r) { char* end_quote; /* The string must have at least * surrounding quotes */ if (_s->len < 2) { return -1; } /* Skip opening quote */ _s->s++; _s->len--; /* Find closing quote */ end_quote = q_memchr(_s->s, '\"', _s->len); /* Not found, return error */ if (!end_quote) { return -2; } /* Let _r point to the string without * surrounding quotes */ _r->s = _s->s; _r->len = end_quote - _s->s; /* Update _s parameter to point * behind the closing quote */ _s->len -= (end_quote - _s->s + 1); _s->s = end_quote + 1; /* Everything went OK */ return 0; }
int aaa_parse_url(str* aaa_url, aaa_prot_config* aaa_config) { char* p; int len; if (!aaa_url || !aaa_config) { LM_ERR("null arguments\n"); return -1; } p = q_memchr(aaa_url->s, ':', aaa_url->len); if (!p) { LM_ERR("invalid aaa url\n"); return -1; } len = p - aaa_url->s; aaa_config->prot_name = (str*) pkg_malloc (sizeof(str)); if (!aaa_config->prot_name) { LM_ERR("no pkg memory left\n"); return -1; } aaa_config->prot_name->s = (char*) pkg_malloc (len * sizeof(char)); if (!aaa_config->prot_name->s) { LM_ERR("no pkg memory left\n"); return -1; } aaa_config->prot_name->len = len; aaa_config->rest = p + 1; strncpy(aaa_config->prot_name->s, aaa_url->s, len); return 0; }
static int fixup_partition_sets_null(void **param) { str s_param = {(char*)*param, strlen(*param)}; str part_name = {NULL, 0}; char *delim = q_memchr(s_param.s, DS_PARTITION_DELIM, s_param.len); if (delim) { part_name.s = s_param.s; part_name.len = delim - s_param.s; s_param.s = delim + 1; s_param.len -= part_name.len + 1; trim(&part_name); } trim(&s_param); ds_param_t *final_param = shm_malloc(sizeof (ds_param_t)); if (final_param == NULL) { LM_CRIT ("no more shared memory!\n"); return -1; } if (get_gpart(&part_name, &final_param->partition) != 0) { shm_free(final_param); return -1; } if ((set_list_from_string(s_param, &final_param->sets)) != 0){ shm_free(final_param); return -1; } *param = (void*)final_param; return 0; }
char* parse_hname2(char* begin, char* end, struct hdr_field* hdr) { register char* p; register unsigned int val; if ((end - begin) < 4) { hdr->type = HDR_ERROR_T; return begin; } p = begin; val = LOWER_DWORD(READ(p)); hdr->name.s = begin; switch(val) { FIRST_QUATERNIONS; default: switch(LOWER_BYTE(*p)) { case 't': switch(LOWER_BYTE(*(p + 1))) { case 'o': case ' ': hdr->type = HDR_TO_T; p += 2; goto dc_end; case ':': hdr->type = HDR_TO_T; hdr->name.len = 1; return (p + 2); } break; case 'v': PARSE_COMPACT(HDR_VIA_T); break; case 'f': PARSE_COMPACT(HDR_FROM_T); break; case 'i': PARSE_COMPACT(HDR_CALLID_T); break; case 'm': PARSE_COMPACT(HDR_CONTACT_T); break; case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH_T); break; case 'k': PARSE_COMPACT(HDR_SUPPORTED_T); break; case 'c': PARSE_COMPACT(HDR_CONTENTTYPE_T); break; case 'o': PARSE_COMPACT(HDR_EVENT_T); break; case 'x': PARSE_COMPACT(HDR_SESSIONEXPIRES_T);break; case 'a': PARSE_COMPACT(HDR_ACCEPTCONTACT_T); break; case 'u': PARSE_COMPACT(HDR_ALLOWEVENTS_T); break; case 'e': PARSE_COMPACT(HDR_CONTENTENCODING_T); break; case 'b': PARSE_COMPACT(HDR_REFERREDBY_T); break; case 'j': PARSE_COMPACT(HDR_REJECTCONTACT_T); break; case 'd': PARSE_COMPACT(HDR_REQUESTDISPOSITION_T); break; case 's': PARSE_COMPACT(HDR_SUBJECT_T); break; case 'r': PARSE_COMPACT(HDR_REFER_TO_T); break; } goto other; } /* Double colon hasn't been found yet */ dc_end: p = skip_ws(p, end - p); if (*p != ':') { goto other; } else { hdr->name.len = p - hdr->name.s; return (p + 1); } /* Unknown header type */ other: p = q_memchr(p, ':', end - p); if (!p) { /* No double colon found, error.. */ hdr->type = HDR_ERROR_T; hdr->name.s = 0; hdr->name.len = 0; return 0; } else { hdr->type = HDR_OTHER_T; hdr->name.len = p - hdr->name.s; return (p + 1); } }
/* returns pointer to next header line, and fill hdr_f ; * if at end of header returns pointer to the last crlf (always buf)*/ char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hdr) { char *tmp = 0; char *match; struct via_body *vb; struct cseq_body* cseq_b; struct to_body* to_b; int integer, err; unsigned uval; if(!buf) { DBG("null buffer pointer\n"); goto error; } if ((*buf)=='\n' || (*buf)=='\r') { /* double crlf or lflf or crcr */ DBG("found end of header\n"); hdr->type=HDR_EOH_T; return buf; } tmp=parse_hname(buf, end, hdr); if (hdr->type==HDR_ERROR_T) { LOG(L_ERR, "ERROR: get_hdr_field: bad header\n"); goto error; } /* eliminate leading whitespace */ tmp=eat_lws_end(tmp, end); if (tmp>=end) { LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n"); goto error; } /* if header-field well-known, parse it, find its end otherwise ; * after leaving the hdr->type switch, tmp should be set to the * next header field */ switch(hdr->type) { case HDR_VIA_T: /* keep number of vias parsed -- we want to report it in replies for diagnostic purposes */ via_cnt++; vb=pkg_malloc(sizeof(struct via_body)); if (vb==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(vb,0,sizeof(struct via_body)); hdr->body.s=tmp; tmp=parse_via(tmp, end, vb); if (vb->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad via\n"); free_via_list(vb); goto error; } hdr->parsed=vb; vb->hdr.s=hdr->name.s; vb->hdr.len=hdr->name.len; hdr->body.len=tmp-hdr->body.s; break; case HDR_CSEQ_T: cseq_b=pkg_malloc(sizeof(struct cseq_body)); if (cseq_b==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(cseq_b, 0, sizeof(struct cseq_body)); hdr->body.s=tmp; tmp=parse_cseq(tmp, end, cseq_b); if (cseq_b->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n"); free_cseq(cseq_b); goto error; } hdr->parsed=cseq_b; hdr->body.len=tmp-hdr->body.s; DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n", hdr->name.len, ZSW(hdr->name.s), cseq_b->number.len, ZSW(cseq_b->number.s), cseq_b->method.len, cseq_b->method.s); break; case HDR_TO_T: to_b=pkg_malloc(sizeof(struct to_body)); if (to_b==0) { LOG(L_ERR, "get_hdr_field: out of memory\n"); goto error; } memset(to_b, 0, sizeof(struct to_body)); hdr->body.s=tmp; tmp=parse_to(tmp, end,to_b); if (to_b->error==PARSE_ERROR) { LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n"); free_to(to_b); goto error; } hdr->parsed=to_b; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n", hdr->name.len, ZSW(hdr->name.s), hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s)); DBG("DEBUG: to body [%.*s]\n",to_b->body.len, ZSW(to_b->body.s)); break; case HDR_CONTENTLENGTH_T: hdr->body.s=tmp; tmp=parse_content_length(tmp,end, &integer); if (tmp==0) { LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n"); goto error; } hdr->parsed=(void*)(long)integer; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_body : content_length=%d\n", (int)(long)hdr->parsed); break; case HDR_RETRY_AFTER_T: hdr->body.s=tmp; tmp=parse_retry_after(tmp,end, &uval, &err); if (err) { LOG(L_ERR, "ERROR:get_hdr_field: bad retry_after header\n"); goto error; } hdr->parsed=(void*)(unsigned long)uval; hdr->body.len=tmp-hdr->body.s; DBG("DEBUG: get_hdr_body : retry_after=%d\n", (unsigned)(long)hdr->parsed); break; case HDR_IDENTITY_T: case HDR_DATE_T: case HDR_IDENTITY_INFO_T: case HDR_SUPPORTED_T: case HDR_REQUIRE_T: case HDR_CONTENTTYPE_T: case HDR_FROM_T: case HDR_CALLID_T: case HDR_CONTACT_T: case HDR_ROUTE_T: case HDR_RECORDROUTE_T: case HDR_MAXFORWARDS_T: case HDR_AUTHORIZATION_T: case HDR_EXPIRES_T: case HDR_PROXYAUTH_T: case HDR_PROXYREQUIRE_T: case HDR_UNSUPPORTED_T: case HDR_ALLOW_T: case HDR_EVENT_T: case HDR_ACCEPT_T: case HDR_ACCEPTLANGUAGE_T: case HDR_ORGANIZATION_T: case HDR_PRIORITY_T: case HDR_SUBJECT_T: case HDR_USERAGENT_T: case HDR_SERVER_T: case HDR_CONTENTDISPOSITION_T: case HDR_DIVERSION_T: case HDR_RPID_T: case HDR_SIPIFMATCH_T: case HDR_REFER_TO_T: case HDR_SESSIONEXPIRES_T: case HDR_MIN_SE_T: case HDR_SUBSCRIPTION_STATE_T: case HDR_ACCEPTCONTACT_T: case HDR_ALLOWEVENTS_T: case HDR_CONTENTENCODING_T: case HDR_REFERREDBY_T: case HDR_REJECTCONTACT_T: case HDR_REQUESTDISPOSITION_T: case HDR_WWW_AUTHENTICATE_T: case HDR_PROXY_AUTHENTICATE_T: case HDR_PATH_T: case HDR_PRIVACY_T: case HDR_PAI_T: case HDR_PPI_T: case HDR_REASON_T: case HDR_OTHER_T: /* just skip over it */ hdr->body.s=tmp; /* find end of header */ /* find lf */ do { match=q_memchr(tmp, '\n', end-tmp); if (match) { match++; } else { LOG(L_ERR, "ERROR: get_hdr_field: bad body for <%s>(%d)\n", hdr->name.s, hdr->type); /* abort(); */ tmp=end; goto error; } tmp=match; } while( match<end &&( (*match==' ')||(*match=='\t') ) ); tmp=match; hdr->body.len=match-hdr->body.s; break; default: LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n", hdr->type); goto error; } /* jku: if \r covered by current length, shrink it */ trim_r( hdr->body ); hdr->len=tmp-hdr->name.s; return tmp; error: DBG("get_hdr_field: error exit\n"); STATS_BAD_MSG_HDR(); hdr->type=HDR_ERROR_T; hdr->len=tmp-hdr->name.s; return tmp; }
/* * parse acc extra element in form of * <backend>:<tag1>=<value1>;<tag2>=<value2>[;] * last semicolon may miss * all tags shall be added (if not present) to the tag list * and be linked to all extra structures in acc_extra lists by * the index in the vector * * @param string to be parsed(char*) * @return 0(success) / < 0 (error) */ static int parse_acc_list_generic(void* val, str2bkend str2bk, tag_t** tag_arr, int* tags_len) { str sent={(char*)val, strlen((char*)val)}; str tok_list_s, backend_s; str token, tag, value; struct acc_extra** bkend_list; char* end; if ((end=q_memchr(sent.s, ':', sent.len)) == NULL) { LM_ERR("Missing backend separator ':'!\n"); return -1; } backend_s.s = sent.s; backend_s.len = end-sent.s; str_trim_spaces_lr(backend_s); if ((bkend_list = str2bk(&backend_s)) == NULL) { LM_ERR("Invalid backend <%.*s>\n", backend_s.len, backend_s.s); return -1; } tok_list_s.s = end+1; tok_list_s.len = sent.len - (end - sent.s + 1); do { end=q_memchr(tok_list_s.s, ';', tok_list_s.len); /* get key=value parameter */ token.s = tok_list_s.s; if (end != NULL) { token.len = end-tok_list_s.s; tok_list_s.len = tok_list_s.len - (end - tok_list_s.s + 1); tok_list_s.s = end + 1; } else { token.len = tok_list_s.len; } /* we reached the end or there are probably some trailing spaces * after the last ';' */ str_trim_spaces_lr(token); if (!token.len) break; if (parse_extra_token(&token, &tag, &value) < 0) { LM_ERR("failed to parse token!\n"); return -1; } if (add_extra(&tag, &value, bkend_list, tag_arr, tags_len) < 0) { LM_ERR("failed to add extra!\n"); return -1; } } while (end); return 0; }
static int set_partition_arguments(unsigned int type, void *val) { static const char end_pair_delim = ';'; static const char eq_val_delim = '='; static const str blacklist_param = str_init("ds_define_blacklist"); unsigned int i; str raw_line = {(char*)val, strlen(val)}; str arg, value; ds_db_head_t *head = NULL; if (raw_line.s[raw_line.len - 1] != end_pair_delim) raw_line.s[raw_line.len++] = end_pair_delim; if (parse_partition_argument(&raw_line, &head) != 0) return -1; char *first_pos = raw_line.s; /* just for error messages */ char *end_pair_pos = q_memchr(raw_line.s, end_pair_delim, raw_line.len); char *eq_pos = q_memchr(raw_line.s, eq_val_delim, raw_line.len); while (end_pair_pos != NULL && eq_pos != NULL) { arg.s = raw_line.s; arg.len = eq_pos - arg.s; value.s = eq_pos + 1; value.len = end_pair_pos - eq_pos - 1; trim(&arg); trim(&value); if (arg.len <= 0 || value.len <= 0) { LM_ERR("Wrong format in partition arguments specifier at pos %d\n", (int)(arg.s - first_pos + 1)); return -1; } for (i = 0; i < partition_param_count; ++i) if (str_strcmp(&arg, &partition_params[i].name) == 0) { *(partition_params[i].getter_func(head)) = value; break; } if ( i == partition_param_count) { if (str_strcmp(&blacklist_param, &arg) == 0) { value.s[value.len] = 0; if (set_ds_bl_partition(value.s, head->partition_name) != 0) return -1; } else{ /* No paramater found */ LM_ERR("No such parameter known: %.*s\n", arg.len, arg.s); return -1; } } raw_line.s = end_pair_pos + 1; end_pair_pos = q_memchr(raw_line.s, end_pair_delim, raw_line.len); eq_pos = q_memchr(raw_line.s, eq_val_delim, raw_line.len); } return 0; }
/* returns pointer to next header line, and fill hdr_f ; * if at end of header returns pointer to the last crlf (always buf)*/ char* get_sdp_hdr_field(char* buf, char* end, struct hdr_field* hdr) { char* tmp; char *match; if ((*buf)=='\n' || (*buf)=='\r'){ /* double crlf or lflf or crcr */ hdr->type=HDR_EOH_T; return buf; } tmp=parse_hname2(buf, end, hdr); if (hdr->type==HDR_ERROR_T){ LM_ERR("bad header\n"); goto error; } /* eliminate leading whitespace */ tmp=eat_lws_end(tmp, end); if (tmp>=end) { LM_ERR("hf empty\n"); goto error; } /* if header-field well-known, parse it, find its end otherwise ; * after leaving the hdr->type switch, tmp should be set to the * next header field */ switch(hdr->type){ case HDR_CONTENTTYPE_T: case HDR_CONTENTDISPOSITION_T: /* just skip over it */ hdr->body.s=tmp; /* find end of header */ /* find lf */ do{ match=q_memchr(tmp, '\n', end-tmp); if (match){ match++; }else { LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type); tmp=end; goto error; } tmp=match; }while( match<end &&( (*match==' ')||(*match=='\t') ) ); tmp=match; hdr->body.len=match-hdr->body.s; break; default: LM_CRIT("unknown header type %d\n", hdr->type); goto error; } /* jku: if \r covered by current length, shrink it */ trim_r( hdr->body ); hdr->len=tmp-hdr->name.s; return tmp; error: LM_DBG("error exit\n"); hdr->type=HDR_ERROR_T; hdr->len=tmp-hdr->name.s; return tmp; }
/* * parse a partition parameter of type * <part_name> : attr1=val1; attr2=val2; */ int parse_partition(modparam_t t, void *val) { str type, value, token; char *tok_end; struct pm_partition *el, *it; str decl = {(char*)val, strlen((char *)val)}; if (get_partitions() == NULL) { if (alloc_partitions() == NULL) goto out_memfault; el=get_partitions(); } else { el=pkg_malloc(sizeof(struct pm_partition)); if (el == NULL) goto out_memfault; memset(el, 0, sizeof(struct pm_partition)); for (it=get_partitions(); it->next; it=it->next); it->next = el; } tok_end = q_memchr(decl.s, ':', decl.len); if (tok_end == NULL) goto out_invdef; value.s = decl.s; value.len = tok_end - decl.s; str_trim_spaces_lr(value); el->name = value; decl.len = decl.len - (++tok_end - decl.s); decl.s = tok_end; while (decl.len > 0 && decl.s) { tok_end = q_memchr(decl.s, ';', decl.len); if (tok_end == NULL) break; token.s = decl.s; token.len = tok_end - token.s; tok_end = q_memchr(token.s, '=', token.len); if (tok_end == NULL) break; type.s = token.s; type.len = tok_end - type.s; value.s = tok_end + 1; value.len = (token.s + token.len) - value.s; decl.s += token.len + 1; decl.len -= (token.len + 1); str_trim_spaces_lr(type); str_trim_spaces_lr(value); if (!str_strcmp( &type, &part_db_url)) el->url = value; else if (!str_strcmp( &type, &part_table_name)) el->table = value; else goto out_invdef; } if (el->url.s == NULL) { LM_ERR("you should define an URL for this partition %.*s\n", el->name.len, el->name.s); return -1; } return 0; out_invdef: LM_ERR("invalid partition definition!\n"); return -ERR; out_memfault: LM_ERR("no more memory\n"); return -ERR; }
int_list_t *set_list_from_pvs(struct sip_msg *msg, pv_spec_t *pvs, int_list_t *end) { int_list_t *result = end, *new_el; pv_value_t value; if (pv_get_spec_value(msg, pvs, &value) != 0 || value.flags&PV_VAL_NULL || (!(value.flags&PV_VAL_INT) && !(value.flags&PV_VAL_STR))) { LM_ERR("no valid PV value found (error in scripts)\n"); return NULL; } if (value.flags & PV_VAL_INT) { /* Just one element */ new_el = pkg_malloc(sizeof(int_list_t)); if (new_el == NULL) { LM_ERR("no more shared memory\n"); return NULL; } new_el->v.ival = value.ri; new_el->type = GPARAM_TYPE_INT; new_el->next = end; return new_el; } str sval = value.rs; if (sval.s == NULL) goto wrong_value; char * delim; do{ delim = q_memchr(sval.s, LIST_DELIM, sval.len); str s_num = {sval.s, delim ? delim - sval.s : sval.len}; sval.len -= s_num.len + 1; sval.s = delim + 1; trim(&s_num); int u_num; if (s_num.len == 0 || str2sint(&s_num, &u_num) != 0) goto wrong_value; new_el = pkg_malloc(sizeof(int_list_t)); if (new_el == NULL) { goto no_memory; } new_el->v.ival = u_num; new_el->type = GPARAM_TYPE_INT; new_el->next = result; result = new_el; } while (delim); if (sval.len > 0) goto wrong_value; return result; no_memory: while(result != end) { if (result->type == GPARAM_TYPE_PVS) pkg_free(result->v.pvs); int_list_t *aux = result; result = result->next; pkg_free(aux); } LM_ERR("no more private memory\n"); return NULL; wrong_value: while(result != end) { if (result->type == GPARAM_TYPE_PVS) pkg_free(result->v.pvs); int_list_t *aux = result; result = result->next; pkg_free(aux); } LM_ERR("wrong var value <%.*s>\n", value.rs.len, value.rs.s); return NULL; }