int __osip_find_next_crlfcrlf(const char *start_of_part, const char **end_of_part) { const char *start_of_line; const char *end_of_line; int i; start_of_line = start_of_part; for (;;) { i = __osip_find_next_crlf(start_of_line, &end_of_line); if (i == -2) { } else if (i != 0) { /* error case??? no end of mesage found */ OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Final CRLF is missing\n")); return i; } if ('\0' == end_of_line[0]) { /* error case??? no end of message found */ OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Final CRLF is missing\n")); return OSIP_SYNTAXERROR; } else if ('\r' == end_of_line[0]) { if ('\n' == end_of_line[1]) end_of_line++; *end_of_part = end_of_line + 1; return OSIP_SUCCESS; } else if ('\n' == end_of_line[0]) { *end_of_part = end_of_line + 1; return OSIP_SUCCESS; } start_of_line = end_of_line; } }
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; } }
/* set all headers */ static int msg_headers_parse(osip_message_t * sip, const char *start_of_header, const char **body) { const char *colon_index; /* index of ':' */ char *hname; char *hvalue; const char *end_of_header; int i; for (;;) { if (start_of_header[0] == '\0') { /* final CRLF is missing */ OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "SIP message does not end with CRLFCRLF\n")); return OSIP_SUCCESS; } i = __osip_find_next_crlf(start_of_header, &end_of_header); if (i == -2) { } else if (i != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return i; /* this is an error case! */ } /* the list of headers MUST always end with */ /* CRLFCRLF (also CRCR and LFLF are allowed) */ if ((start_of_header[0] == '\r') || (start_of_header[0] == '\n')) { *body = start_of_header; return OSIP_SUCCESS; /* end of header found */ } /* find the header name */ colon_index = strchr(start_of_header, ':'); if (colon_index == NULL) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return OSIP_SYNTAXERROR; /* this is also an error case */ } if (colon_index - start_of_header + 1 < 2) return OSIP_SYNTAXERROR; if (end_of_header <= colon_index) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Malformed message\n")); return OSIP_SYNTAXERROR; } hname = (char *) osip_malloc(colon_index - start_of_header + 1); if (hname == NULL) return OSIP_NOMEM; osip_clrncpy(hname, start_of_header, colon_index - start_of_header); { const char *end; /* END of header is (end_of_header-2) if header separation is CRLF */ /* END of header is (end_of_header-1) if header separation is CR or LF */ if ((end_of_header[-2] == '\r') || (end_of_header[-2] == '\n')) end = end_of_header - 2; else end = end_of_header - 1; if ((end) - colon_index < 2) hvalue = NULL; /* some headers (subject) can be empty */ else { hvalue = (char *) osip_malloc((end) - colon_index + 1); if (hvalue == NULL) { osip_free(hname); return OSIP_NOMEM; } osip_clrncpy(hvalue, colon_index + 1, (end) - colon_index - 1); } } /* hvalue MAY contains multiple value. In this case, they */ /* are separated by commas. But, a comma may be part of a */ /* quoted-string ("here, and there" is an example where the */ /* comma is not a separator!) */ i = osip_message_set_multiple_header(sip, hname, hvalue); osip_free(hname); if (hvalue != NULL) osip_free(hvalue); if (i != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return OSIP_SYNTAXERROR; } /* continue on the next header */ start_of_header = end_of_header; } /* Unreachable code OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "This code cannot be reached\n")); */ return OSIP_SYNTAXERROR; }