static size_t span_attribute_value(char *s) { size_t n; n = span_token_lws(s); if (n > 0 && s[n] == '=') { n += 1 + span_lws(s + n + 1); if (s[n] == '"') n += span_quoted(s + n); else n += span_token(s + n); n += span_lws(s + n); } return n; }
issize_t sip_p_asserted_identity_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)h; while (*s == ',') /* Ignore empty entries (comma-whitespace) */ *s = '\0', s += span_lws(s + 1) + 1; if (sip_name_addr_d(home, &s, &paid->paid_display, paid->paid_url, NULL, NULL) == -1) return -1; return msg_parse_next_field(home, h, s, slen); }
issize_t sip_remote_party_id_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h; while (*s == ',') /* Ignore empty entries (comma-whitespace) */ *s = '\0', s += span_lws(s + 1) + 1; if (sip_name_addr_d(home, &s, &rpid->rpid_display, rpid->rpid_url, &rpid->rpid_params, NULL) == -1) return -1; return msg_parse_next_field(home, h, s, slen); }
/** Parsing @CallInfo, @ErrorInfo. */ static issize_t sip_info_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_call_info_t *ci = h->sh_call_info; char *end = s + slen; assert(h); while (*s == ',') s += span_lws(s + 1) + 1; if (sip_name_addr_d(home, &s, NULL, ci->ci_url, &ci->ci_params, NULL) < 0) return -1; /* Recurse */ return msg_parse_next_field(home, h, s, end - s); }
/** Decode a string containg header field. * * The header object is initialized with the contents of the string. The * string is modified when parsing. The home is used to allocate extra * memory required when parsing, e.g., for parameter list or when there * string contains multiple header fields. * * @deprecated * Use msg_header_make() or header-specific make functions, e.g., * sip_via_make(). * * @retval 0 when successful * @retval -1 upon an error. */ issize_t sip_header_field_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { if (h && s && s[slen] == '\0') { size_t n = span_lws(s); s += n; slen -= n; for (n = slen; n >= 1 && IS_LWS(s[n - 1]); n--) ; s[n] = '\0'; assert(SIP_HDR_TEST(h)); return h->sh_class->hc_parse(home, h, s, slen); } else return -1; }
/** Parsing @CallInfo, @ErrorInfo. */ static issize_t sip_info_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_call_info_t *ci = h->sh_call_info; char *end = s + slen; for(;;) { ci = h->sh_call_info; end = s + slen; while (*s == ',') s += span_lws(s + 1) + 1; if (sip_name_addr_d(home, &s, NULL, ci->ci_url, &ci->ci_params, NULL) < 0) return -1; slen = end - s; msg_parse_next_field_without_recursion(); } }
issize_t sip_accept_disposition_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_accept_disposition_t *ad = (sip_accept_disposition_t *)h; assert(h); /* Ignore empty entries (comma-whitespace) */ while (*s == ',') s += span_lws(s + 1) + 1; /* "Accept:" #(type/subtyp ; *(parameters))) */ if (/* Parse protocol */ sip_version_d(&s, &ad->ad_type) == -1 || (ad->ad_subtype = strchr(ad->ad_type, '/')) == NULL || (*s == ';' && msg_params_d(home, &s, &ad->ad_params) == -1)) return -1; if (ad->ad_subtype) ad->ad_subtype++; return msg_parse_next_field(home, h, s, slen); }
static issize_t sip_caller_prefs_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { for(;;) { sip_caller_prefs_t *cp = (sip_caller_prefs_t *)h; url_t url[1]; char const *ignore = NULL; int kludge = 0; assert(h); while (*s == ',') /* Ignore empty entries (comma-whitespace) */ *s = '\0', s += span_lws(s + 1) + 1; /* Kludge: support PoC IS spec with a typo... */ if (su_casenmatch(s, "*,", 2)) s[1] = ';', kludge = 0; else if (s[0] != '*' && s[0] != '<') { /* Kludge: missing URL - */ size_t n = span_attribute_value(s); kludge = n > 0 && (s[n] == '\0' || s[n] == ',' || s[n] == ';'); } if (kludge) { if (msg_any_list_d(home, &s, (msg_param_t **)&cp->cp_params, msg_attribute_value_scanner, ';') == -1) return -1; } /* Parse params (and ignore display name and url) */ else if (sip_name_addr_d(home, &s, &ignore, url, &cp->cp_params, NULL) == -1) return -1; /* Be liberal... */ /* if (url->url_type != url_any) return -1; */ msg_parse_next_field_without_recursion(); } }
issize_t sip_timestamp_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen) { sip_timestamp_t *ts = (sip_timestamp_t*)h; ts->ts_stamp = s; s += span_digit(s); if (s == ts->ts_stamp) return -1; if (*s == '.') { s += span_digit(s + 1) + 1; } if (IS_LWS(*s)) { *s = '\0'; s += span_lws(s + 1) + 1; ts->ts_delay = s; s += span_digit(s); if (*s == '.') { s += span_digit(s + 1) + 1; } } if (!*s || IS_LWS(*s)) *s++ = '\0'; else return -1; return 0; }