/* returns -1 on error. */ int osip_cseq_parse (osip_cseq_t * cseq, const char *hvalue) { char *method = NULL; const char *end = NULL; cseq->number = NULL; cseq->method = NULL; method = strchr (hvalue, ' '); /* SEARCH FOR SPACE */ end = hvalue + strlen (hvalue); if (method == NULL) return -1; if (method - hvalue + 1 < 2) return -1; cseq->number = (char *) osip_malloc (method - hvalue + 1); if (cseq->number == NULL) return -1; osip_strncpy (cseq->number, hvalue, method - hvalue); osip_clrspace (cseq->number); if (end - method + 1 < 2) return -1; cseq->method = (char *) osip_malloc (end - method + 1); if (cseq->method == NULL) return -1; osip_strncpy (cseq->method, method + 1, end - method); osip_clrspace (cseq->method); return 0; /* ok */ }
/* returns -1 on error. */ int osip_content_type_parse (osip_content_type_t * content_type, const char *hvalue) { char *subtype; char *osip_content_type_params; /* How to parse: we'll place the pointers: subtype => beginning of subtype osip_content_type_params => beginning of params examples: application/multipart ; boundary= ^ ^ */ subtype = strchr (hvalue, '/'); osip_content_type_params = strchr (hvalue, ';'); if (subtype == NULL) return -1; /* do we really mind such an error */ if (osip_content_type_params != NULL) { if (__osip_generic_param_parseall (content_type->gen_params, osip_content_type_params) == -1) return -1; } else osip_content_type_params = subtype + strlen (subtype); if (subtype - hvalue + 1 < 2) return -1; content_type->type = (char *) osip_malloc (subtype - hvalue + 1); if (content_type->type == NULL) return -1; osip_strncpy (content_type->type, hvalue, subtype - hvalue); osip_clrspace (content_type->type); if (osip_content_type_params - subtype < 2) return -1; content_type->subtype = (char *) osip_malloc (osip_content_type_params - subtype); if (content_type->subtype == NULL) return -1; osip_strncpy (content_type->subtype, subtype + 1, osip_content_type_params - subtype - 1); osip_clrspace (content_type->subtype); return 0; }
int osip_uri_param_set (osip_uri_param_t * url_param, char *pname, char *pvalue) { url_param->gname = pname; /* not needed for url, but for all other generic params */ osip_clrspace (url_param->gname); url_param->gvalue = pvalue; if (url_param->gvalue != NULL) osip_clrspace (url_param->gvalue); return 0; }
static int jidentity_init(jidentity_t **fr, char *ch) { char *next; int i; *fr = (jidentity_t *)osip_malloc(sizeof(jidentity_t)); if (*fr==NULL) return -1; i = jidentity_get_and_set_next_token(&((*fr)->i_identity), ch, &next); if (i != 0) goto ji_error1; osip_clrspace ((*fr)->i_identity); ch = next; i = jidentity_get_and_set_next_token(&((*fr)->i_registrar), next, &next); if (i != 0) goto ji_error2; osip_clrspace ((*fr)->i_registrar); ch = next; i = jidentity_get_and_set_next_token(&((*fr)->i_realm), ch, &next); if (i != 0) goto ji_error3; osip_clrspace ((*fr)->i_realm); ch = next; i = jidentity_get_and_set_next_token(&((*fr)->i_userid), ch, &next); if (i != 0) goto ji_error4; osip_clrspace ((*fr)->i_userid); (*fr)->i_pwd = osip_strdup(next); osip_clrspace ((*fr)->i_pwd); if ((*fr)->i_pwd!=NULL && (*fr)->i_pwd[0]!='\0') { eXosip_add_authentication_info((*fr)->i_userid, (*fr)->i_userid, (*fr)->i_pwd, NULL, (*fr)->i_realm); } return 0; ji_error4: osip_free((*fr)->i_realm); ji_error3: osip_free((*fr)->i_registrar); ji_error2: osip_free((*fr)->i_identity); ji_error1: osip_free(*fr); *fr = NULL; return -1; }
char * osip_clrncpy (char *dst, const char *src, size_t len) { osip_strncpy ( dst, src, len); osip_clrspace ( dst ); return dst; }
/* returns -1 on error. */ int osip_message_set_topheader (osip_message_t * sip, const char *hname, const char *hvalue) { osip_header_t *h; int i; if (hname == NULL) return -1; i = osip_header_init (&h); if (i != 0) return -1; h->hname = (char *) osip_malloc (strlen (hname) + 1); if (h->hname == NULL) { osip_header_free (h); return -1; } osip_strncpy (h->hname, hname, strlen (hname)); osip_clrspace (h->hname); if (hvalue != NULL) { /* some headers can be null ("subject:") */ h->hvalue = (char *) osip_malloc (strlen (hvalue) + 1); if (h->hvalue == NULL) { osip_header_free (h); return -1; } osip_strncpy (h->hvalue, hvalue, strlen (hvalue)); osip_clrspace (h->hvalue); } else h->hvalue = NULL; #ifdef USE_TMP_BUFFER sip->message_property = 2; #endif osip_list_add (sip->headers, h, 0); return 0; /* ok */ }
static int osip_body_parse_header (osip_body_t * body, const char *start_of_osip_body_header, const char **next_body) { const char *start_of_line; const char *end_of_line; const char *colon_index; char *hname; char *hvalue; int i; *next_body = NULL; start_of_line = start_of_osip_body_header; for (;;) { i = __osip_find_next_crlf (start_of_line, &end_of_line); if (i == -1) return -1; /* error case: no end of body found */ /* find the headere name */ colon_index = strchr (start_of_line, ':'); if (colon_index == NULL) return -1; /* this is also an error case */ if (colon_index - start_of_line + 1 < 2) return -1; hname = (char *) osip_malloc (colon_index - start_of_line + 1); if (hname == NULL) return -1; osip_strncpy (hname, start_of_line, colon_index - start_of_line); osip_clrspace (hname); if ((end_of_line - 2) - colon_index < 2) return -1; hvalue = (char *) osip_malloc ((end_of_line - 2) - colon_index); if (hvalue == NULL) { osip_free (hname); return -1; } osip_strncpy (hvalue, colon_index + 1, (end_of_line - 2) - colon_index - 1); osip_clrspace (hvalue); /* really store the header in the sip structure */ if (osip_strncasecmp (hname, "content-type", 12) == 0) i = osip_body_set_contenttype (body, hvalue); else i = osip_body_set_header (body, hname, hvalue); osip_free (hname); osip_free (hvalue); if (i == -1) return -1; if (strncmp (end_of_line, CRLF, 2) == 0 || strncmp (end_of_line, "\n", 1) == 0 || strncmp (end_of_line, "\r", 1) == 0) { *next_body = end_of_line; return 0; } start_of_line = end_of_line; } }
int osip_via_parse (osip_via_t * via, const char *hvalue) { const char *version; const char *protocol; const char *host; const char *ipv6host; const char *port; const char *via_params; const char *comment; version = strchr (hvalue, '/'); if (version == NULL) return -1; protocol = strchr (version + 1, '/'); if (protocol == NULL) return -1; /* set the version */ if (protocol - version < 2) return -1; via->version = (char *) osip_malloc (protocol - version); if (via->version == NULL) return -1; osip_strncpy (via->version, version + 1, protocol - version - 1); osip_clrspace (via->version); /* Here: we avoid matching an additionnal space */ host = strchr (protocol + 1, ' '); if (host == NULL) return -1; /* fixed in 0.8.4 */ if (host == protocol + 1) /* there are extra SPACE characters */ { while (0 == strncmp (host, " ", 1)) { host++; if (strlen (host) == 1) return -1; /* via is malformed */ } /* here, we match the real space located after the protocol name */ host = strchr (host + 1, ' '); if (host == NULL) return -1; /* fixed in 0.8.4 */ } /* set the protocol */ if (host - protocol < 2) return -1; via->protocol = (char *) osip_malloc (host - protocol); if (via->protocol == NULL) return -1; osip_strncpy (via->protocol, protocol + 1, host - protocol - 1); osip_clrspace (via->protocol); /* comments in Via are not allowed any more in the latest draft (09) */ comment = strchr (host, '('); if (comment != NULL) { char *end_comment; end_comment = strchr (host, ')'); if (end_comment == NULL) return -1; /* if '(' exist ')' MUST exist */ if (end_comment - comment < 2) return -1; via->comment = (char *) osip_malloc (end_comment - comment); if (via->comment == NULL) return -1; osip_strncpy (via->comment, comment + 1, end_comment - comment - 1); comment--; } else comment = host + strlen (host); via_params = strchr (host, ';'); if ((via_params != NULL) && (via_params < comment)) /* via params exist */ { char *tmp; if (comment - via_params + 1 < 2) return -1; tmp = (char *) osip_malloc (comment - via_params + 1); if (tmp == NULL) return -1; osip_strncpy (tmp, via_params, comment - via_params); __osip_generic_param_parseall (via->via_params, tmp); osip_free (tmp); } if (via_params == NULL) via_params = comment; /* add ipv6 support (0.8.4) */ /* Via: SIP/2.0/UDP [mlke::zeezf:ezfz:zef:zefzf]:port;.... */ ipv6host = strchr (host, '['); if (ipv6host != NULL && ipv6host < via_params) { port = strchr (ipv6host, ']'); if (port == NULL || port > via_params) return -1; if (port - ipv6host < 2) return -1; via->host = (char *) osip_malloc (port - ipv6host); if (via->host == NULL) return -1; osip_strncpy (via->host, ipv6host + 1, port - ipv6host - 1); osip_clrspace (via->host); port = strchr (port, ':'); } else { port = strchr (host, ':'); ipv6host = NULL; } if ((port != NULL) && (port < via_params)) { if (via_params - port < 2) return -1; via->port = (char *) osip_malloc (via_params - port); if (via->port == NULL) return -1; osip_strncpy (via->port, port + 1, via_params - port - 1); osip_clrspace (via->port); } else port = via_params; /* host is already set in the case of ipv6 */ if (ipv6host != NULL) return 0; if (port - host < 2) return -1; via->host = (char *) osip_malloc (port - host); if (via->host == NULL) return -1; osip_strncpy (via->host, host + 1, port - host - 1); osip_clrspace (via->host); return 0; }
int osip_message_set_multiple_header(osip_message_t * sip, char *hname, char *hvalue) { int i; char *ptr; /* current location of the search */ char *comma; /* This is the separator we are elooking for */ char *beg; /* beg of a header */ char *end; /* end of a header */ char *quote1; /* first quote of a pair of quotes */ char *quote2; /* second quuote of a pair of quotes */ size_t hname_len; /* Find header based upon lowercase comparison */ osip_tolower(hname); if (hvalue == NULL) { i = osip_message_set__header(sip, hname, hvalue); if (i != 0) return i; return OSIP_SUCCESS; } ptr = hvalue; comma = strchr(ptr, ','); hname_len = strlen(hname); if (comma == NULL || (hname_len == 4 && strncmp(hname, "date", 4) == 0) || (hname_len == 2 && strncmp(hname, "to", 2) == 0) || (hname_len == 4 && strncmp(hname, "from", 4) == 0) || (hname_len == 7 && strncmp(hname, "call-id", 7) == 0) || (hname_len == 4 && strncmp(hname, "cseq", 4) == 0) || (hname_len == 7 && strncmp(hname, "subject", 7) == 0) || (hname_len == 7 && strncmp(hname, "expires", 7) == 0) || (hname_len == 6 && strncmp(hname, "server", 6) == 0) || (hname_len == 10 && strncmp(hname, "user-agent", 10) == 0) || (hname_len == 16 && strncmp(hname, "www-authenticate", 16) == 0) || (hname_len == 19 && strncmp(hname, "authentication-info", 19) == 0) || (hname_len == 18 && strncmp(hname, "proxy-authenticate", 18) == 0) || (hname_len == 19 && strncmp(hname, "proxy-authorization", 19) == 0) || (hname_len == 25 && strncmp(hname, "proxy-authentication-info", 25) == 0) || (hname_len == 12 && strncmp(hname, "organization", 12) == 0) || (hname_len == 13 && strncmp(hname, "authorization", 13) == 0)) /* there is no multiple header! likely */ /* to happen most of the time... */ /* or hname is a TEXT-UTF8-TRIM and may */ /* contain a comma. this is not a separator */ /* THIS DOES NOT WORK FOR UNKNOWN HEADER!!!! */ { i = osip_message_set__header(sip, hname, hvalue); if (i != 0) return i; return OSIP_SUCCESS; } beg = hvalue; end = NULL; quote2 = NULL; while (comma != NULL) { quote1 = __osip_quote_find(ptr); if (quote1 != NULL) { quote2 = __osip_quote_find(quote1 + 1); if (quote2 == NULL) return OSIP_SYNTAXERROR; /* quotes comes by pair */ ptr = quote2 + 1; } if ((quote1 == NULL) || (quote1 > comma)) { /* We must search for the next comma which is not within quotes! */ end = comma; if (quote1 != NULL && quote1 > comma) { /* comma may be within the quotes */ /* ,<sip:[email protected]>;methods=\"INVITE,BYE,OPTIONS,ACK,CANCEL\",<sip:[email protected]> */ /* we want the next comma after the quotes */ char *tmp_comma; char *tmp_quote1; char *tmp_quote2; tmp_quote1 = quote1; tmp_quote2 = quote2; tmp_comma = strchr(comma + 1, ','); while (1) { if (tmp_comma < tmp_quote1) break; /* ok (before to quotes) */ if (tmp_comma < tmp_quote2) { tmp_comma = strchr(tmp_quote2 + 1, ','); } tmp_quote1 = __osip_quote_find(tmp_quote2 + 1); if (tmp_quote1 == NULL) break; tmp_quote2 = __osip_quote_find(tmp_quote1 + 1); if (tmp_quote2 == NULL) break; /* probably a malformed message? */ } comma = tmp_comma; /* this one is not enclosed within quotes */ } else comma = strchr(comma + 1, ','); if (comma != NULL) ptr = comma + 1; } else if ((quote1 < comma) && (quote2 < comma)) { /* quotes are located before the comma, */ /* continue the search for next quotes */ ptr = quote2 + 1; } else if ((quote1 < comma) && (comma < quote2)) { /* if comma is inside the quotes... */ /* continue with the next comma. */ ptr = quote2 + 1; comma = strchr(ptr, ','); if (comma == NULL) /* this header last at the end of the line! */ { /* this one does not need an allocation... */ #if 0 if (strlen(beg) < 2) return OSIP_SUCCESS; /* empty header */ #else if (beg[0] == '\0' || beg[1] == '\0') return OSIP_SUCCESS; /* empty header */ #endif osip_clrspace(beg); i = osip_message_set__header(sip, hname, beg); if (i != 0) return i; return OSIP_SUCCESS; } } if (end != NULL) { char *avalue; if (end - beg + 1 < 2) return OSIP_SYNTAXERROR; avalue = (char *) osip_malloc(end - beg + 1); if (avalue == NULL) return OSIP_NOMEM; osip_clrncpy(avalue, beg, end - beg); /* really store the header in the sip structure */ i = osip_message_set__header(sip, hname, avalue); osip_free(avalue); if (i != 0) return i; beg = end + 1; end = NULL; if (comma == NULL) /* this header last at the end of the line! */ { /* this one does not need an allocation... */ #if 0 if (strlen(beg) < 2) return OSIP_SUCCESS; /* empty header */ #else if (beg[0] == '\0' || beg[1] == '\0') return OSIP_SUCCESS; /* empty header */ #endif osip_clrspace(beg); i = osip_message_set__header(sip, hname, beg); if (i != 0) return i; return OSIP_SUCCESS; } } } return OSIP_SYNTAXERROR; /* if comma is NULL, we should have already return 0 */ }