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;
}