static int
strcat_simple_header (char **_string, size_t * malloc_size, char **_message, void *ptr_header, char *header_name, size_t size_of_header, int (*xxx_to_str) (void *, char **), char **next)
{
  char *string;
  char *message;
  char *tmp;
  int i;

  string = *_string;
  message = *_message;

  if (ptr_header != NULL) {
    if (*malloc_size < message - string + 100 + size_of_header)
      /* take some memory avoid to osip_realloc too much often */
    {                           /* should not happen often */
      size_t size = message - string;

      *malloc_size = message - string + size_of_header + 100;
      string = osip_realloc (string, *malloc_size);
      if (string == NULL) {
        *_string = NULL;
        *_message = NULL;
        return OSIP_NOMEM;
      }
      message = string + size;
    }
    message = osip_strn_append (message, header_name, size_of_header);

    i = xxx_to_str (ptr_header, &tmp);
    if (i != 0) {
      *_string = string;
      *_message = message;
      *next = NULL;
      return i;
    }
    if (*malloc_size < message - string + strlen (tmp) + 100) {
      size_t size = message - string;

      *malloc_size = message - string + strlen (tmp) + 100;
      string = osip_realloc (string, *malloc_size);
      if (string == NULL) {
        *_string = NULL;
        *_message = NULL;
        return OSIP_NOMEM;
      }
      message = string + size;
    }

    message = osip_str_append (message, tmp);
    osip_free (tmp);
    message = osip_strn_append (message, CRLF, 2);
  }
  *_string = string;
  *_message = message;
  *next = message;
  return OSIP_SUCCESS;
}
/* returns null on error. */
int
osip_content_type_to_str (const osip_content_type_t * content_type,
			  char **dest)
{
  char *buf;
  char *tmp;
  size_t len;

  *dest = NULL;
  if ((content_type == NULL) || (content_type->type == NULL)
      || (content_type->subtype == NULL))
    return -1;

  /* try to guess a long enough length */
  len = strlen (content_type->type) + strlen (content_type->subtype) + 4	/* for '/', ' ', ';' and '\0' */
    + 10 * osip_list_size (content_type->gen_params);

  buf = (char *) osip_malloc (len);
  tmp = buf;

  sprintf (tmp, "%s/%s", content_type->type, content_type->subtype);

  tmp = tmp + strlen (tmp);
  {
    int pos = 0;
    osip_generic_param_t *u_param;

    if (!osip_list_eol (content_type->gen_params, pos))
      {				/* needed for cannonical form! (authentication issue of rfc2543) */
	sprintf (tmp, " ");
	tmp++;
      }
    while (!osip_list_eol (content_type->gen_params, pos))
      {
	size_t tmp_len;

	u_param =
	  (osip_generic_param_t *) osip_list_get (content_type->gen_params,
						  pos);
	if (u_param->gvalue == NULL)
	  {
	    osip_free (buf);
	    return -1;
	  }
	tmp_len = strlen (buf) + 4 + strlen (u_param->gname)
	  + strlen (u_param->gvalue);
	if (len < tmp_len)
	  {
	    buf = osip_realloc (buf, tmp_len);
	    len = tmp_len;
	    tmp = buf + strlen (buf);
	  }
	sprintf (tmp, ";%s=%s", u_param->gname, u_param->gvalue);
	tmp = tmp + strlen (tmp);
	pos++;
      }
  }
  *dest = buf;
  return 0;
}
Esempio n. 3
0
char *strdup_printf(const char *fmt, ...)
{
	/* Guess we need no more than 100 bytes. */
	int n, size = 100;

	char *p;

	va_list ap;

	if ((p = osip_malloc(size)) == NULL)
		return NULL;
	while (1) {
		/* Try to print in the allocated space. */
		va_start(ap, fmt);
#ifdef WIN32
		n = _vsnprintf(p, size, fmt, ap);
#else
		n = vsnprintf(p, size, fmt, ap);
#endif
		va_end(ap);
		/* If that worked, return the string. */
		if (n > -1 && n < size)
			return p;
		/* Else try again with more space. */
		if (n > -1)				/* glibc 2.1 */
			size = n + 1;		/* precisely what is needed */
		else					/* glibc 2.0 */
			size *= 2;			/* twice the old size */
		if ((p = osip_realloc(p, size)) == NULL)
			return NULL;
	}
}
Esempio n. 4
0
char *
__osip_uri_escape_nonascii_and_nondef (const char *string, const char *def)
{
  size_t alloc = strlen (string) + 1;
  size_t length;
  char *ns = osip_malloc (alloc);
  unsigned char in;
  size_t newlen = alloc;
  int index = 0;
  const char *tmp;
  int i;

  length = alloc - 1;
  while (length--)
    {
      in = *string;

      i = 0;
      tmp = NULL;
      if (osip_is_alphanum (in))
        tmp = string;
      else
        {
          for (; def[i] != '\0' && def[i] != in; i++)
            {
            }
          if (def[i] != '\0')
            tmp = string;
        }
      if (tmp == NULL)
        {
          /* encode it */
          newlen += 2;          /* the size grows with two, since this'll become a %XX */
          if (newlen > alloc)
            {
              alloc *= 2;
              ns = osip_realloc (ns, alloc);
              if (!ns)
                return NULL;
            }
          sprintf (&ns[index], "%%%02X", in);
          index += 3;
      } else
        {
          /* just copy this */
          ns[index++] = in;
        }
      string++;
    }
  ns[index] = 0;                /* terminate it */
  return ns;
}
Esempio n. 5
0
/* append string_osip_to_append to string at position cur
   size is the current allocated size of the element
*/
char *__osip_sdp_append_string(char *string, size_t size, char *cur,
							   char *string_osip_to_append)
{
	size_t length = strlen(string_osip_to_append);

	if (cur - string + length > size) {
		size_t length2;

		length2 = cur - string;
		string = osip_realloc(string, size + length + 10);
		cur = string + length2;	/* the initial allocation may have changed! */
	}
	osip_strncpy(cur, string_osip_to_append, length);
	return cur + strlen(cur);
}
static int
_osip_message_realloc (char **message, char **dest, size_t needed, size_t * malloc_size)
{
  size_t size = *message - *dest;

  if (*malloc_size < (size_t) (size + needed + 100)) {
    *malloc_size = size + needed + 100;
    *dest = osip_realloc (*dest, *malloc_size);
    if (*dest == NULL)
      return OSIP_NOMEM;
    *message = *dest + size;
  }

  return OSIP_SUCCESS;
}
/* returns null on error. */
int
osip_content_type_to_str (const osip_content_type_t * content_type, char **dest)
{
  char *buf;
  char *tmp;
  size_t len;

  *dest = NULL;
  if ((content_type == NULL) || (content_type->type == NULL)
      || (content_type->subtype == NULL))
    return OSIP_BADPARAMETER;

  /* try to guess a long enough length */
  len = strlen (content_type->type) + strlen (content_type->subtype) + 4        /* for '/', ' ', ';' and '\0' */
    + 10 * osip_list_size (&content_type->gen_params);

  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return OSIP_NOMEM;
  tmp = buf;

  sprintf (tmp, "%s/%s", content_type->type, content_type->subtype);

  tmp = tmp + strlen (tmp);
  {
    osip_list_iterator_t it;
    osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&content_type->gen_params, &it);
    while (u_param != OSIP_SUCCESS) {
      size_t tmp_len;
      if (u_param->gvalue == NULL) {
        osip_free (buf);
        return OSIP_SYNTAXERROR;
      }
      tmp_len = strlen (buf) + 4 + strlen (u_param->gname)
        + strlen (u_param->gvalue) + 1;
      if (len < tmp_len) {
        buf = osip_realloc (buf, tmp_len);
        len = tmp_len;
        tmp = buf + strlen (buf);
      }
      snprintf (tmp, len - (tmp - buf), "; %s=%s", u_param->gname, u_param->gvalue);
      tmp = tmp + strlen (tmp);
      u_param = (osip_generic_param_t *) osip_list_get_next(&it);
    }
  }
  *dest = buf;
  return OSIP_SUCCESS;
}
/* returns null on error. */
int
osip_call_info_to_str (const osip_call_info_t * call_info, char **dest)
{
  char *buf;
  char *tmp;
  size_t len;
  size_t plen;

  *dest = NULL;
  if ((call_info == NULL) || (call_info->element == NULL))
    return OSIP_BADPARAMETER;

  len = strlen (call_info->element) + 2;
  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return OSIP_NOMEM;
  *dest = buf;

  sprintf (buf, "%s", call_info->element);

  {
    int pos = 0;
    osip_generic_param_t *u_param;

    while (!osip_list_eol (&call_info->gen_params, pos))
      {
        u_param =
          (osip_generic_param_t *) osip_list_get (&call_info->gen_params, pos);
        if (u_param->gvalue == NULL)
          plen = strlen (u_param->gname) + 2;
        else
          plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3;
        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (u_param->gvalue == NULL)
          sprintf (tmp, ";%s", u_param->gname);
        else
          sprintf (tmp, ";%s=%s", u_param->gname, u_param->gvalue);
        pos++;
      }
  }
  *dest = buf;
  return OSIP_SUCCESS;
}
/* returns null on error. */
int
osip_accept_encoding_to_str (const osip_accept_encoding_t * accept_encoding,
                             char **dest)
{
  char *buf;
  char *tmp;
  size_t len;

  *dest = NULL;
  if ((accept_encoding == NULL) || (accept_encoding->element == NULL))
    return -1;

  len = strlen (accept_encoding->element) + 2;
  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return -1;

  sprintf (buf, "%s", accept_encoding->element);
  {
    int pos = 0;
    size_t plen;
    osip_generic_param_t *u_param;

    while (!osip_list_eol (&accept_encoding->gen_params, pos))
      {
        u_param =
          (osip_generic_param_t *) osip_list_get (&accept_encoding->gen_params,
                                                  pos);
        if (u_param->gvalue == NULL)
          plen = strlen (u_param->gname) + 2;
        else
          plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3;
        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (u_param->gvalue == NULL)
          sprintf (tmp, ";%s", u_param->gname);
        else
          sprintf (tmp, ";%s=%s", u_param->gname, u_param->gvalue);
        pos++;
      }
  }
  *dest = buf;
  return 0;
}
/* returns null on error. */
int
osip_accept_encoding_to_str (const osip_accept_encoding_t * accept_encoding, char **dest)
{
  char *buf;
  char *tmp;
  size_t len;

  *dest = NULL;
  if ((accept_encoding == NULL) || (accept_encoding->element == NULL))
    return OSIP_BADPARAMETER;

  len = strlen (accept_encoding->element) + 2;
  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return OSIP_NOMEM;

  sprintf (buf, "%s", accept_encoding->element);
  {
    size_t plen;
    osip_list_iterator_t it;
    osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&accept_encoding->gen_params, &it);
    while (u_param != OSIP_SUCCESS) {
      if (u_param->gvalue == NULL)
        plen = strlen (u_param->gname) + 2;
      else
        plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3;
      len = len + plen;
      buf = (char *) osip_realloc (buf, len);
      tmp = buf;
      tmp = tmp + strlen (tmp);
      if (u_param->gvalue == NULL)
        snprintf (tmp, len - (tmp - buf), ";%s", u_param->gname);
      else
        snprintf (tmp, len - (tmp - buf), ";%s=%s", u_param->gname, u_param->gvalue);
      u_param = (osip_generic_param_t *) osip_list_get_next(&it);
    }
  }
  *dest = buf;
  return OSIP_SUCCESS;
}
static int
strcat_headers_all_on_one_line (char **_string, size_t * malloc_size, char **_message, osip_list_t * headers, char *header, size_t size_of_header, int (*xxx_to_str) (void *, char **), char **next)
{
  char *string;
  char *message;
  char *tmp;
  int pos = 0;
  int i;

  string = *_string;
  message = *_message;

  pos = 0;
  while (!osip_list_eol (headers, pos)) {
    if (*malloc_size < message - string + 100 + size_of_header)
      /* take some memory avoid to osip_realloc too much often */
    {                           /* should not happen often */
      size_t size = message - string;

      *malloc_size = message - string + size_of_header + 100;
      string = osip_realloc (string, *malloc_size);
      if (string == NULL) {
        *_string = NULL;
        *_message = NULL;
        return OSIP_NOMEM;
      }
      message = string + size;
    }
    message = osip_strn_append (message, header, size_of_header);

    while (!osip_list_eol (headers, pos)) {
      void *elt;

      elt = (void *) osip_list_get (headers, pos);
      i = xxx_to_str (elt, &tmp);
      if (i != 0) {
        *_string = string;
        *_message = message;
        *next = NULL;
        return i;
      }
      if (*malloc_size < message - string + strlen (tmp) + 100) {
        size_t size = message - string;

        *malloc_size = message - string + (int) strlen (tmp) + 100;
        string = osip_realloc (string, *malloc_size);
        if (string == NULL) {
          *_string = NULL;
          *_message = NULL;
          return OSIP_NOMEM;
        }
        message = string + size;
      }

      message = osip_str_append (message, tmp);
      osip_free (tmp);

      pos++;
      if (!osip_list_eol (headers, pos)) {
        message = osip_strn_append (message, ", ", 2);
      }
    }
    message = osip_strn_append (message, CRLF, 2);
  }
  *_string = string;
  *_message = message;
  *next = message;
  return OSIP_SUCCESS;
}
Esempio n. 12
0
/* returns null on error. */
int
osip_via_to_str (const osip_via_t * via, char **dest)
{
  char *buf;
  size_t len;
  size_t plen;
  char *tmp;

  *dest = NULL;
  if ((via == NULL) || (via->host == NULL)
      || (via->version == NULL) || (via->protocol == NULL))
    return -1;

  len = strlen (via->version) + 1 + strlen (via->protocol) + 1 + 3 + 2; /* sip/xxx/xxx */
  len = len + strlen (via->host) + 3 + 1;
  if (via->port != NULL)
    len = len + strlen (via->port) + 2;

  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return -1;

  if (strchr (via->host, ':') != NULL)
    {
      if (via->port == NULL)
        sprintf (buf, "SIP/%s/%s [%s]", via->version, via->protocol, via->host);
      else
        sprintf (buf, "SIP/%s/%s [%s]:%s", via->version, via->protocol,
                 via->host, via->port);
  } else
    {
      if (via->port == NULL)
        sprintf (buf, "SIP/%s/%s %s", via->version, via->protocol, via->host);
      else
        sprintf (buf, "SIP/%s/%s %s:%s", via->version, via->protocol,
                 via->host, via->port);
    }



  {
    int pos = 0;
    osip_generic_param_t *u_param;

    while (!osip_list_eol (&via->via_params, pos))
      {
        u_param = (osip_generic_param_t *) osip_list_get (&via->via_params, pos);

        if (u_param->gvalue == NULL)
          plen = strlen (u_param->gname) + 2;
        else
          plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3;
        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (u_param->gvalue == NULL)
          sprintf (tmp, ";%s", u_param->gname);
        else
          sprintf (tmp, ";%s=%s", u_param->gname, u_param->gvalue);
        pos++;
      }
  }

  if (via->comment != NULL)
    {
      len = len + strlen (via->comment) + 4;
      buf = (char *) osip_realloc (buf, len);
      tmp = buf;
      tmp = tmp + strlen (tmp);
      sprintf (tmp, " (%s)", via->comment);
    }
  *dest = buf;
  return 0;
}
Esempio n. 13
0
/* returns null on error. */
int
osip_body_to_str (const osip_body_t * body, char **dest, size_t *str_length)
{
  char *tmp_body;
  char *tmp;
  char *ptr;
  int pos;
  int i;
  size_t length;

  *dest = NULL;
  *str_length = 0;
  if (body == NULL)
    return -1;
  if (body->body == NULL)
    return -1;
  if (body->headers == NULL)
    return -1;
  if (body->length <= 0)
    return -1;

  length = body->length + (osip_list_size (body->headers) * 40);
  tmp_body = (char *) osip_malloc (length);
  if (tmp_body == NULL)
    return -1;
  ptr = tmp_body;		/* save the initial address of the string */

  if (body->content_type != NULL)
    {
      osip_strncpy (tmp_body, "content-type: ", 14);
      tmp_body = tmp_body + strlen (tmp_body);
      i = osip_content_type_to_str (body->content_type, &tmp);
      if (i == -1)
	{
	  osip_free (ptr);
	  return -1;
	}
      if (length < tmp_body - ptr + strlen (tmp) + 4)
	{
	  size_t len;

	  len = tmp_body - ptr;
	  length = length + strlen (tmp) + 4;
	  ptr = osip_realloc (ptr, length);
	  tmp_body = ptr + len;
	}

      osip_strncpy (tmp_body, tmp, strlen (tmp));
      osip_free (tmp);
      tmp_body = tmp_body + strlen (tmp_body);
      osip_strncpy (tmp_body, CRLF, 2);
      tmp_body = tmp_body + 2;
    }

  pos = 0;
  while (!osip_list_eol (body->headers, pos))
    {
      osip_header_t *header;

      header = (osip_header_t *) osip_list_get (body->headers, pos);
      i = osip_header_to_str (header, &tmp);
      if (i == -1)
	{
	  osip_free (ptr);
	  return -1;
	}
      if (length < tmp_body - ptr + strlen (tmp) + 4)
	{
	  size_t len;

	  len = tmp_body - ptr;
	  length = length + strlen (tmp) + 4;
	  ptr = osip_realloc (ptr, length);
	  tmp_body = ptr + len;
	}
      osip_strncpy (tmp_body, tmp, strlen (tmp));
      osip_free (tmp);
      tmp_body = tmp_body + strlen (tmp_body);
      osip_strncpy (tmp_body, CRLF, 2);
      tmp_body = tmp_body + 2;
      pos++;
    }

  if ((osip_list_size (body->headers) > 0) || (body->content_type != NULL))
    {
      osip_strncpy (tmp_body, CRLF, 2);
      tmp_body = tmp_body + 2;
    }
  if (length < tmp_body - ptr + body->length + 4)
    {
      size_t len;

      len = tmp_body - ptr;
      length = length + body->length + 4;
      ptr = osip_realloc (ptr, length);
      tmp_body = ptr + len;
    }
  memcpy(tmp_body,body->body,body->length);
  tmp_body = tmp_body + body->length;

  /* end of this body */
  if (str_length!=NULL)
     *str_length = tmp_body - ptr;
  *dest = ptr;
  return 0;

}
Esempio n. 14
0
/* returns -1 on error. */
int osip_record_route_to_str(const osip_record_route_t * record_route, char **dest)
{
	char *url;
	char *buf;
	int i;
	size_t len;

	*dest = NULL;
	if ((record_route == NULL) || (record_route->url == NULL))
		return OSIP_BADPARAMETER;

	i = osip_uri_to_str(record_route->url, &url);
	if (i != 0)
		return i;

	if (record_route->displayname == NULL)
		len = strlen(url) + 5;
	else
		len = strlen(url) + strlen(record_route->displayname) + 5;

	buf = (char *) osip_malloc(len);
	if (buf == NULL) {
		osip_free(url);
		return OSIP_NOMEM;
	}

	/* route and record-route always use brackets */
	if (record_route->displayname != NULL)
		sprintf(buf, "%s <%s>", record_route->displayname, url);
	else
		sprintf(buf, "<%s>", url);
	osip_free(url);

	{
		int pos = 0;
		osip_generic_param_t *u_param;
		size_t plen;
		char *tmp;

		while (!osip_list_eol(&record_route->gen_params, pos)) {
			u_param =
				(osip_generic_param_t *) osip_list_get(&record_route->gen_params,
													   pos);

			if (u_param->gvalue == NULL)
				plen = strlen(u_param->gname) + 2;
			else
				plen = strlen(u_param->gname) + strlen(u_param->gvalue) + 3;
			len = len + plen;
			buf = (char *) osip_realloc(buf, len);
			tmp = buf;
			tmp = tmp + strlen(tmp);
			if (u_param->gvalue == NULL)
				sprintf(tmp, ";%s", u_param->gname);
			else
				sprintf(tmp, ";%s=%s", u_param->gname, u_param->gvalue);
			pos++;
		}
	}
	*dest = buf;
	return OSIP_SUCCESS;
}
Esempio n. 15
0
int
osip_uri_to_str (const osip_uri_t * url, char **dest)
{
  char *buf;
  size_t len;
  size_t plen;
  char *tmp;
  const char *scheme;

  *dest = NULL;
  if (url == NULL)
    return -1;
  if (url->host == NULL && url->string == NULL)
    return -1;
  if (url->scheme == NULL && url->string != NULL)
    return -1;
  if (url->string == NULL && url->scheme == NULL)
    scheme = "sip";             /* default is sipurl */
  else
    scheme = url->scheme;

  if (url->string != NULL)
    {
      buf = (char *) osip_malloc (strlen (scheme) + strlen (url->string) + 3);
      if (buf == NULL)
        return -1;
      *dest = buf;
      sprintf (buf, "%s:", scheme);
      buf = buf + strlen (scheme) + 1;
      sprintf (buf, "%s", url->string);
      buf = buf + strlen (url->string);
      return 0;
    }

  len = strlen (scheme) + 1 + strlen (url->host) + 5;
  if (url->username != NULL)
    len = len + (strlen (url->username) * 3) + 1;       /* count escaped char */
  if (url->password != NULL)
    len = len + (strlen (url->password) * 3) + 1;
  if (url->port != NULL)
    len = len + strlen (url->port) + 3;

  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    return -1;
  tmp = buf;

  sprintf (tmp, "%s:", scheme);
  tmp = tmp + strlen (tmp);

  if (url->username != NULL)
    {
      char *tmp2 = __osip_uri_escape_userinfo (url->username);

      sprintf (tmp, "%s", tmp2);
      osip_free (tmp2);
      tmp = tmp + strlen (tmp);
    }
  if ((url->password != NULL) && (url->username != NULL))
    {                           /* be sure that when a password is given, a username is also given */
      char *tmp2 = __osip_uri_escape_password (url->password);

      sprintf (tmp, ":%s", tmp2);
      osip_free (tmp2);
      tmp = tmp + strlen (tmp);
    }
  if (url->username != NULL)
    {                           /* we add a '@' only when username is present... */
      sprintf (tmp, "@");
      tmp++;
    }
  if (strchr (url->host, ':') != NULL)
    {
      sprintf (tmp, "[%s]", url->host);
      tmp = tmp + strlen (tmp);
  } else
    {
      sprintf (tmp, "%s", url->host);
      tmp = tmp + strlen (tmp);
    }
  if (url->port != NULL)
    {
      sprintf (tmp, ":%s", url->port);
      tmp = tmp + strlen (tmp);
    }

  {
    int pos = 0;
    osip_uri_param_t *u_param;

    while (!osip_list_eol (&url->url_params, pos))
      {
        char *tmp1;
        char *tmp2 = NULL;

        u_param = (osip_uri_param_t *) osip_list_get (&url->url_params, pos);

        tmp1 = __osip_uri_escape_uri_param (u_param->gname);
        if (u_param->gvalue == NULL)
          plen = strlen (tmp1) + 2;
        else
          {
            tmp2 = __osip_uri_escape_uri_param (u_param->gvalue);
            plen = strlen (tmp1) + strlen (tmp2) + 3;
          }
        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (u_param->gvalue == NULL)
          sprintf (tmp, ";%s", tmp1);
        else
          {
            sprintf (tmp, ";%s=%s", tmp1, tmp2);
            osip_free (tmp2);
          }
        osip_free (tmp1);
        pos++;
      }
  }

  {
    int pos = 0;
    osip_uri_header_t *u_header;

    while (!osip_list_eol (&url->url_headers, pos))
      {
        char *tmp1;
        char *tmp2;

        u_header = (osip_uri_header_t *) osip_list_get (&url->url_headers, pos);
        tmp1 = __osip_uri_escape_header_param (u_header->gname);

        if (tmp1 == NULL)
          {
            osip_free (buf);
            return -1;
          }

        tmp2 = __osip_uri_escape_header_param (u_header->gvalue);

        if (tmp2 == NULL)
          {
            osip_free (tmp1);
            osip_free (buf);
            return -1;
          }
        plen = strlen (tmp1) + strlen (tmp2) + 4;

        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (pos == 0)
          sprintf (tmp, "?%s=%s", tmp1, tmp2);
        else
          sprintf (tmp, "&%s=%s", tmp1, tmp2);
        osip_free (tmp1);
        osip_free (tmp2);
        pos++;
      }
  }

  *dest = buf;
  return 0;
}
Esempio n. 16
0
/* returns -1 on error. */
int
osip_from_to_str (const osip_from_t * from, char **dest)
{
  char *url;
  char *buf;
  int i;
  size_t len;

  *dest = NULL;
  if ((from == NULL) || (from->url == NULL))
    return -1;

  i = osip_uri_to_str (from->url, &url);
  if (i != 0)
    return -1;

  if (from->displayname == NULL)
    len = strlen (url) + 5;
  else
    len = strlen (url) + strlen (from->displayname) + 5;

  buf = (char *) osip_malloc (len);
  if (buf == NULL)
    {
      osip_free (url);
      return -1;
    }

  if (from->displayname != NULL)
    sprintf (buf, "%s <%s>", from->displayname, url);
  else
    /* from rfc2543bis-04: for authentication related issue!
       "The To and From header fields always include the < and >
       delimiters even if the display-name is empty." */
    sprintf (buf, "<%s>", url);
  osip_free (url);

  {
    int pos = 0;
    osip_generic_param_t *u_param;
    size_t plen;
    char *tmp;

    while (!osip_list_eol (&from->gen_params, pos))
      {
        u_param = (osip_generic_param_t *) osip_list_get (&from->gen_params, pos);

        if (u_param->gvalue == NULL)
          plen = strlen (u_param->gname) + 2;
        else
          plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3;
        len = len + plen;
        buf = (char *) osip_realloc (buf, len);
        tmp = buf;
        tmp = tmp + strlen (tmp);
        if (u_param->gvalue == NULL)
          sprintf (tmp, ";%s", u_param->gname);
        else
          sprintf (tmp, ";%s=%s", u_param->gname, u_param->gvalue);
        pos++;
      }
  }
  *dest = buf;
  return 0;
}
Esempio n. 17
0
static int
_osip_message_to_str (osip_message_t * sip, char **dest,
                      size_t * message_length, int sipfrag)
{
  size_t malloc_size;
  size_t total_length = 0;

  /* Added at SIPit day1 */
  char *start_of_bodies;
  char *content_length_to_modify = NULL;

  char *message;
  char *next;
  char *tmp;
  int pos;
  int i;
  char *boundary = NULL;

  malloc_size = SIP_MESSAGE_MAX_LENGTH;

  *dest = NULL;
  if ((sip == NULL))
    return -1;

  {
    if (1 == osip_message_get__property (sip))
      {                         /* message is already available in "message" */

        *dest = osip_malloc (sip->message_length + 1);
        if (*dest == NULL)
          return -1;
        memcpy (*dest, sip->message, sip->message_length);
        (*dest)[sip->message_length] = '\0';
        if (message_length != NULL)
          *message_length = sip->message_length;
        return 0;
    } else
      {
        /* message should be rebuilt: delete the old one if exists. */
        osip_free (sip->message);
        sip->message = NULL;
      }
  }

  message = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH);      /* ???? message could be > 4000  */
  if (message == NULL)
    return -1;
  *dest = message;

  /* add the first line of message */
  i = __osip_message_startline_to_str (sip, &tmp);
  if (i == -1)
    {
      if (!sipfrag)
        {
          osip_free (*dest);
          *dest = NULL;
          return -1;
        }

      /* A start-line isn't required for message/sipfrag parts. */
  } else
    {
      message = osip_str_append (message, tmp);
      osip_free (tmp);
      message = osip_strn_append (message, CRLF, 2);
    }

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message, &sip->vias,
                                 "Via: ", 5,
                                 ((int (*)(void *, char **))
                                  &osip_via_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->record_routes, "Record-Route: ", 14,
                                 ((int (*)(void *, char **))
                                  &osip_record_route_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message, &sip->routes,
                                 "Route: ", 7,
                                 ((int (*)(void *, char **))
                                  &osip_route_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->from, "From: ", 6,
                            ((int (*)(void *, char **)) &osip_from_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->to, "To: ", 4,
                            ((int (*)(void *, char **)) &osip_to_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->call_id, "Call-ID: ", 9,
                            ((int (*)(void *, char **)) &osip_call_id_to_str),
                            &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->cseq, "CSeq: ", 6,
                            ((int (*)(void *, char **)) &osip_cseq_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message, &sip->contacts,
                                 "Contact: ", 9,
                                 ((int (*)(void *, char **))
                                  &osip_contact_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_headers_one_per_line (dest, &malloc_size, &message,
                                   &sip->authorizations, "Authorization: ", 15,
                                   ((int (*)(void *, char **))
                                    &osip_authorization_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->www_authenticates, "WWW-Authenticate: ",
                                 18,
                                 ((int (*)(void *, char **))
                                  &osip_www_authenticate_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->proxy_authenticates,
                                 "Proxy-Authenticate: ", 20,
                                 ((int (*)(void *, char **))
                                  &osip_www_authenticate_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->proxy_authorizations,
                                 "Proxy-Authorization: ", 21,
                                 ((int (*)(void *, char **))
                                  &osip_authorization_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  pos = 0;
  while (!osip_list_eol (&sip->headers, pos))
    {
      osip_header_t *header;
      size_t header_len = 0;

      header = (osip_header_t *) osip_list_get (&sip->headers, pos);
      i = osip_header_to_str (header, &tmp);
      if (i == -1)
        {
          osip_free (*dest);
          *dest = NULL;
          return -1;
        }

      header_len = strlen (tmp);

      if (_osip_message_realloc (&message, dest, header_len + 3, &malloc_size) < 0)
	{
	  osip_free (tmp);
          *dest = NULL;
	  return -1;
	}

      message = osip_str_append (message, tmp);
      osip_free (tmp);
      message = osip_strn_append (message, CRLF, 2);

      pos++;
    }

  i =
    strcat_headers_all_on_one_line (dest, &malloc_size, &message, &sip->allows,
                                    "Allow: ", 7,
                                    ((int (*)(void *, char **))
                                     &osip_content_length_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->content_type, "Content-Type: ", 14,
                            ((int (*)(void *, char **))
                             &osip_content_type_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_all_on_one_line (dest, &malloc_size, &message,
                                    &sip->content_encodings,
                                    "Content-Encoding: ", 18,
                                    ((int (*)(void *, char **))
                                     &osip_content_length_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i = strcat_simple_header (dest, &malloc_size, &message,
                            sip->mime_version, "Mime-Version: ", 14,
                            ((int (*)(void *, char **))
                             &osip_content_length_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->call_infos, "Call-Info: ", 11,
                                 ((int (*)(void *, char **))
                                  &osip_call_info_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->alert_infos, "Alert-Info: ", 12,
                                 ((int (*)(void *, char **))
                                  &osip_call_info_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->error_infos, "Error-Info: ", 12,
                                 ((int (*)(void *, char **))
                                  &osip_call_info_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_all_on_one_line (dest, &malloc_size, &message,
                                    &sip->accepts, "Accept: ", 8,
                                    ((int (*)(void *, char **))
                                     &osip_accept_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_all_on_one_line (dest, &malloc_size, &message,
                                    &sip->accept_encodings,
                                    "Accept-Encoding: ", 17,
                                    ((int (*)(void *, char **))
                                     &osip_accept_encoding_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_all_on_one_line (dest, &malloc_size, &message,
                                    &sip->accept_languages,
                                    "Accept-Language: ", 17,
                                    ((int (*)(void *, char **))
                                     &osip_accept_encoding_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->authentication_infos,
                                 "Authentication-Info: ", 21,
                                 ((int (*)(void *, char **))
                                  &osip_authentication_info_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;

  i =
    strcat_headers_one_per_line (dest, &malloc_size, &message,
                                 &sip->proxy_authentication_infos,
                                 "Proxy-Authentication-Info: ", 27,
                                 ((int (*)(void *, char **))
                                  &osip_authentication_info_to_str), &next);
  if (i != 0)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }
  message = next;


  /* we have to create the body before adding the contentlength */
  /* add enough lenght for "Content-Length: " */

  if (_osip_message_realloc (&message, dest, 16, &malloc_size) < 0)
    return -1;

  if (sipfrag && osip_list_eol (&sip->bodies, 0))
    {
      /* end of headers */
      osip_strncpy (message, CRLF, 2);
      message = message + 2;

      /* same remark as at the beginning of the method */
      sip->message_property = 1;
      sip->message = osip_strdup (*dest);
      sip->message_length = message - *dest;
      if (message_length != NULL)
        *message_length = message - *dest;

      return 0;                 /* it's all done */
    }

  osip_strncpy (message, "Content-Length: ", 16);
  message = message + 16;

  /* SIPit Day1
     ALWAYS RECALCULATE?
     if (sip->contentlength!=NULL)
     {
     i = osip_content_length_to_str(sip->contentlength, &tmp);
     if (i==-1) {
     osip_free(*dest);
     *dest = NULL;
     return -1;
     }
     osip_strncpy(message,tmp,strlen(tmp));
     osip_free(tmp);
     }
     else
     { */
  if (osip_list_eol (&sip->bodies, 0))   /* no body */
    message = osip_strn_append (message, "0", 1);
  else
    {
      /* BUG: p130 (rfc2543bis-04)
         "No SP after last token or quoted string"

         In fact, if extra spaces exist: the stack can't be used
         to make user-agent that wants to make authentication...
         This should be changed...
       */

      content_length_to_modify = message;
      message = osip_str_append (message, "     ");
    }
  /*  } */

  message = osip_strn_append (message, CRLF, 2);


  /* end of headers */
  message = osip_strn_append (message, CRLF, 2);

  start_of_bodies = message;
  total_length = start_of_bodies - *dest;

  if (osip_list_eol (&sip->bodies, 0))
    {
      /* same remark as at the beginning of the method */
      sip->message_property = 1;
      sip->message = osip_strdup (*dest);
      sip->message_length = total_length;
      if (message_length != NULL)
        *message_length = total_length;

      return 0;                 /* it's all done */
    }

  if (sip->mime_version != NULL && sip->content_type
      && sip->content_type->type
      && !osip_strcasecmp (sip->content_type->type, "multipart"))
    {
      osip_generic_param_t *ct_param = NULL;

      /* find the boundary */
      i = osip_generic_param_get_byname (&sip->content_type->gen_params,
                                         "boundary", &ct_param);
      if ((i >= 0) && ct_param && ct_param->gvalue)
        {
          size_t len = strlen (ct_param->gvalue);

          if (len > MIME_MAX_BOUNDARY_LEN)
            {
              osip_free (*dest);
              *dest = NULL;
              return -1;
            }

          boundary = osip_malloc (len + 5);

          osip_strncpy (boundary, CRLF, 2);
          osip_strncpy (boundary + 2, "--", 2);

          if (ct_param->gvalue[0] == '"' && ct_param->gvalue[len - 1] == '"')
            osip_strncpy (boundary + 4, ct_param->gvalue + 1, len - 2);
          else
            osip_strncpy (boundary + 4, ct_param->gvalue, len);
        }
    }

  pos = 0;
  while (!osip_list_eol (&sip->bodies, pos))
    {
      osip_body_t *body;
      size_t body_length;

      body = (osip_body_t *) osip_list_get (&sip->bodies, pos);

      if (boundary)
        {
          /* Needs at most 77 bytes,
             last realloc allocate at least 100 bytes extra */
          message = osip_str_append (message, boundary);
          message = osip_strn_append (message, CRLF, 2);
        }

      i = osip_body_to_str (body, &tmp, &body_length);
      if (i != 0)
        {
          osip_free (*dest);
          *dest = NULL;
          if (boundary)
            osip_free (boundary);
          return -1;
        }

      if (malloc_size < message - *dest + 100 + body_length)
        {
          size_t size = message - *dest;
          int offset_of_body;
          int offset_content_length_to_modify = 0;

          offset_of_body = (int) (start_of_bodies - *dest);
          if (content_length_to_modify != NULL)
            offset_content_length_to_modify =
              (int) (content_length_to_modify - *dest);
          malloc_size = message - *dest + body_length + 100;
          *dest = osip_realloc (*dest, malloc_size);
          if (*dest == NULL)
            {
              osip_free (tmp);  /* fixed 09/Jun/2005 */
              if (boundary)
                osip_free (boundary);
              return -1;
            }
          start_of_bodies = *dest + offset_of_body;
          if (content_length_to_modify != NULL)
            content_length_to_modify = *dest + offset_content_length_to_modify;
          message = *dest + size;
        }

      memcpy (message, tmp, body_length);
      message[body_length] = '\0';
      osip_free (tmp);
      message = message + body_length;

      pos++;
    }

  if (boundary)
    {
      /* Needs at most 79 bytes,
         last realloc allocate at least 100 bytes extra */
      message = osip_str_append (message, boundary);
      message = osip_strn_append (message, "--", 2);
      message = osip_strn_append (message, CRLF, 2);

      osip_free (boundary);
      boundary = NULL;
    }

  if (content_length_to_modify == NULL)
    {
      osip_free (*dest);
      *dest = NULL;
      return -1;
    }

  /* we NOW have the length of bodies: */
  {
    size_t size = message - start_of_bodies;
    char tmp2[15];

    total_length += size;
    sprintf (tmp2, "%i", size);
    /* do not use osip_strncpy here! */
    strncpy (content_length_to_modify + 5 - strlen (tmp2), tmp2, strlen (tmp2));
  }

  /* same remark as at the beginning of the method */
  sip->message_property = 1;
  sip->message = osip_malloc (total_length + 1);
  if (sip->message != NULL)
    {
      memcpy (sip->message, *dest, total_length);
      sip->message[total_length] = '\0';
      sip->message_length = total_length;
      if (message_length != NULL)
        *message_length = total_length;
    }
  return 0;
}
static int
_osip_message_to_str (osip_message_t * sip, char **dest, size_t * message_length, int sipfrag)
{
  size_t malloc_size;
  size_t total_length = 0;

  /* Added at SIPit day1 */
  char *start_of_bodies;
  char *content_length_to_modify = NULL;

  char *message;
  char *next;
  char *tmp;
  int pos;
  int i;
  char *boundary = NULL;

  malloc_size = SIP_MESSAGE_MAX_LENGTH;

  *dest = NULL;
  if (sip == NULL)
    return OSIP_BADPARAMETER;

  {
    if (1 == osip_message_get__property (sip)) {        /* message is already available in "message" */

      *dest = osip_malloc (sip->message_length + 1);
      if (*dest == NULL)
        return OSIP_NOMEM;
      memcpy (*dest, sip->message, sip->message_length);
      (*dest)[sip->message_length] = '\0';
      if (message_length != NULL)
        *message_length = sip->message_length;
      return OSIP_SUCCESS;
    }
    else {
      /* message should be rebuilt: delete the old one if exists. */
      osip_free (sip->message);
      sip->message = NULL;
    }
  }

  message = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH);      /* ???? message could be > 4000  */
  if (message == NULL)
    return OSIP_NOMEM;
  *dest = message;

  /* add the first line of message */
  i = __osip_message_startline_to_str (sip, &tmp);
  if (i != 0) {
    if (!sipfrag) {
      osip_free (*dest);
      *dest = NULL;
      return i;
    }

    /* A start-line isn't required for message/sipfrag parts. */
  }
  else {
    message = osip_str_append (message, tmp);
    osip_free (tmp);
    message = osip_strn_append (message, CRLF, 2);
  }

  {
    struct to_str_table {
      char header_name[30];
      int header_length;
      osip_list_t *header_list;
      void *header_data;
      int (*to_str) (void *, char **);
    }
#ifndef MINISIZE
    table[25] =
#else
    table[15] =
#endif
    {
      {
      "Via: ", 5, NULL, NULL, (int (*)(void *, char **)) &osip_via_to_str}, {
      "Record-Route: ", 14, NULL, NULL, (int (*)(void *, char **)) &osip_record_route_to_str}, {
      "Route: ", 7, NULL, NULL, (int (*)(void *, char **)) &osip_route_to_str}, {
      "From: ", 6, NULL, NULL, (int (*)(void *, char **)) &osip_from_to_str}, {
      "To: ", 4, NULL, NULL, (int (*)(void *, char **)) &osip_to_to_str}, {
      "Call-ID: ", 9, NULL, NULL, (int (*)(void *, char **)) &osip_call_id_to_str}, {
      "CSeq: ", 6, NULL, NULL, (int (*)(void *, char **)) &osip_cseq_to_str}, {
      "Contact: ", 9, NULL, NULL, (int (*)(void *, char **)) &osip_contact_to_str}, {
      "Authorization: ", 15, NULL, NULL, (int (*)(void *, char **)) &osip_authorization_to_str}, {
      "WWW-Authenticate: ", 18, NULL, NULL, (int (*)(void *, char **)) &osip_www_authenticate_to_str}, {
      "Proxy-Authenticate: ", 20, NULL, NULL, (int (*)(void *, char **)) &osip_www_authenticate_to_str}, {
      "Proxy-Authorization: ", 21, NULL, NULL, (int (*)(void *, char **)) &osip_authorization_to_str}, {
      "Content-Type: ", 14, NULL, NULL, (int (*)(void *, char **)) &osip_content_type_to_str}, {
      "Mime-Version: ", 14, NULL, NULL, (int (*)(void *, char **)) &osip_content_length_to_str},
#ifndef MINISIZE
      {
      "Allow: ", 7, NULL, NULL, (int (*)(void *, char **)) &osip_allow_to_str}, {
      "Content-Encoding: ", 18, NULL, NULL, (int (*)(void *, char **)) &osip_content_encoding_to_str}, {
      "Call-Info: ", 11, NULL, NULL, (int (*)(void *, char **)) &osip_call_info_to_str}, {
      "Alert-Info: ", 12, NULL, NULL, (int (*)(void *, char **)) &osip_call_info_to_str}, {
      "Error-Info: ", 12, NULL, NULL, (int (*)(void *, char **)) &osip_call_info_to_str}, {
      "Accept: ", 8, NULL, NULL, (int (*)(void *, char **)) &osip_accept_to_str}, {
      "Accept-Encoding: ", 17, NULL, NULL, (int (*)(void *, char **)) &osip_accept_encoding_to_str}, {
      "Accept-Language: ", 17, NULL, NULL, (int (*)(void *, char **)) &osip_accept_language_to_str}, {
      "Authentication-Info: ", 21, NULL, NULL, (int (*)(void *, char **)) &osip_authentication_info_to_str}, {
      "Proxy-Authentication-Info: ", 27, NULL, NULL, (int (*)(void *, char **)) &osip_authentication_info_to_str},
#endif
      { {
      '\0'}, 0, NULL, NULL, NULL}
    };

    /* BEGIN: Added by l00183184, 2013/8/5   PN:DTS2013071906746 alg升级 */
    /* 判断list是否需要强制分为多行写 */
#ifndef MINISIZE
    char MultiLine[25] = {1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 
    0, 0, 1, 1, 1, 0, 0, 0, 0, 0};
#else
    char MultiLine[15] = {1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0};
#endif
    /* END:   Added by l00183184, 2013/8/5   PN:DTS2013071906746 alg升级 */

    table[0].header_list = &sip->vias;
    table[1].header_list = &sip->record_routes;
    table[2].header_list = &sip->routes;
    table[3].header_data = sip->from;
    table[4].header_data = sip->to;
    table[5].header_data = sip->call_id;
    table[6].header_data = sip->cseq;
    table[7].header_list = &sip->contacts;
    table[8].header_list = &sip->authorizations;
    table[9].header_list = &sip->www_authenticates;
    table[10].header_list = &sip->proxy_authenticates;
    table[11].header_list = &sip->proxy_authorizations;
    table[12].header_data = sip->content_type;
    table[13].header_data = sip->mime_version;
#ifndef MINISIZE
    table[14].header_list = &sip->allows;
    table[15].header_list = &sip->content_encodings;
    table[16].header_list = &sip->call_infos;
    table[17].header_list = &sip->alert_infos;
    table[18].header_list = &sip->error_infos;
    table[19].header_list = &sip->accepts;
    table[20].header_list = &sip->accept_encodings;
    table[21].header_list = &sip->accept_languages;
    table[22].header_list = &sip->authentication_infos;
    table[23].header_list = &sip->proxy_authentication_infos;
#endif

    pos = 0;
    while (table[pos].header_name[0] != '\0') {
      if (table[13].header_list == NULL)
        i = strcat_simple_header (dest, &malloc_size, &message, table[pos].header_data, table[pos].header_name, table[pos].header_length, ((int (*)(void *, char **))
                                                                                                                                           table[pos].to_str), &next);
      /* BEGIN: Modified by l00183184, 2013/8/5   PN:DTS2013071906746 alg升级 */
      /* 只有对应的routes等这几个头域的list分行写,其他的list合在一行 */
      /* 根据Rfc3261:
      Multiple header field rows with the same field-name MAY be present in
      a message if and only if the entire field-value for that header field
      is defined as a comma-separated list (that is, if follows the grammar
      defined in Section 7.3).*/
      if (1 == MultiLine[pos])
      {
          i = strcat_headers_one_per_line (dest, &malloc_size, &message, table[pos].header_list, table[pos].header_name, table[pos].header_length, ((int (*)(void *, char **))
                                                                                                                                                    table[pos].to_str), &next);
      }
      else
      {
          i = strcat_headers_all_on_one_line (dest, &malloc_size, &message, table[pos].header_list, table[pos].header_name, table[pos].header_length, ((int (*)(void *, char **))
                                                                                                                                                 table[pos].to_str), &next);
      }
      /* END:   Modified by l00183184, 2013/8/5   PN:DTS2013071906746 alg升级 */
      if (i != 0) {
        osip_free (*dest);
        *dest = NULL;
        return i;
      }
      message = next;

      pos++;
    }
  }

  pos = 0;
  while (!osip_list_eol (&sip->headers, pos)) {
    osip_header_t *header;
    size_t header_len = 0;

    header = (osip_header_t *) osip_list_get (&sip->headers, pos);
    i = osip_header_to_str (header, &tmp);
    if (i != 0) {
      osip_free (*dest);
      *dest = NULL;
      return i;
    }

    header_len = strlen (tmp);

    if (_osip_message_realloc (&message, dest, header_len + 3, &malloc_size) < 0) {
      osip_free (tmp);
      *dest = NULL;
      return OSIP_NOMEM;
    }

    message = osip_str_append (message, tmp);
    osip_free (tmp);
    message = osip_strn_append (message, CRLF, 2);

    pos++;
  }

  /* we have to create the body before adding the contentlength */
  /* add enough lenght for "Content-Length: " */

  if (_osip_message_realloc (&message, dest, 16, &malloc_size) < 0)
    return OSIP_NOMEM;

  if (sipfrag && osip_list_eol (&sip->bodies, 0)) {
    /* end of headers */
    osip_strncpy (message, CRLF, 2);
    message = message + 2;

    /* same remark as at the beginning of the method */
    sip->message_property = 1;
    sip->message = osip_strdup (*dest);
    sip->message_length = message - *dest;
    if (message_length != NULL)
      *message_length = message - *dest;

    return OSIP_SUCCESS;        /* it's all done */
  }

  osip_strncpy (message, "Content-Length: ", 16);
  message = message + 16;

  /* SIPit Day1
     ALWAYS RECALCULATE?
     if (sip->contentlength!=NULL)
     {
     i = osip_content_length_to_str(sip->contentlength, &tmp);
     if (i!=0) {
     osip_free(*dest);
     *dest = NULL;
     return i;
     }
     osip_strncpy(message,tmp,strlen(tmp));
     osip_free(tmp);
     }
     else
     { */
  if (osip_list_eol (&sip->bodies, 0))  /* no body */
    message = osip_strn_append (message, "0", 1);
  else {
    /* BUG: p130 (rfc2543bis-04)
       "No SP after last token or quoted string"

       In fact, if extra spaces exist: the stack can't be used
       to make user-agent that wants to make authentication...
       This should be changed...
     */

    content_length_to_modify = message;
    message = osip_str_append (message, "     ");
  }
  /*  } */

  message = osip_strn_append (message, CRLF, 2);


  /* end of headers */
  message = osip_strn_append (message, CRLF, 2);

  start_of_bodies = message;
  total_length = start_of_bodies - *dest;

  if (osip_list_eol (&sip->bodies, 0)) {
    /* same remark as at the beginning of the method */
    sip->message_property = 1;
    sip->message = osip_strdup (*dest);
    sip->message_length = total_length;
    if (message_length != NULL)
      *message_length = total_length;

    return OSIP_SUCCESS;        /* it's all done */
  }

  if (sip->mime_version != NULL && sip->content_type && sip->content_type->type && !osip_strcasecmp (sip->content_type->type, "multipart")) {
    osip_generic_param_t *ct_param = NULL;

    /* find the boundary */
    i = osip_generic_param_get_byname (&sip->content_type->gen_params, "boundary", &ct_param);
    if ((i >= 0) && ct_param && ct_param->gvalue) {
      size_t len = strlen (ct_param->gvalue);

      if (len > MIME_MAX_BOUNDARY_LEN) {
        osip_free (*dest);
        *dest = NULL;
        return OSIP_SYNTAXERROR;
      }

      boundary = osip_malloc (len + 5);
      if (boundary == NULL) {
        osip_free (*dest);
        *dest = NULL;
        return OSIP_NOMEM;
      }

      osip_strncpy (boundary, CRLF, 2);
      osip_strncpy (boundary + 2, "--", 2);

      if (ct_param->gvalue[0] == '"' && ct_param->gvalue[len - 1] == '"')
        osip_strncpy (boundary + 4, ct_param->gvalue + 1, len - 2);
      else
        osip_strncpy (boundary + 4, ct_param->gvalue, len);
    }
  }

  pos = 0;
  while (!osip_list_eol (&sip->bodies, pos)) {
    osip_body_t *body;
    size_t body_length;

    body = (osip_body_t *) osip_list_get (&sip->bodies, pos);

    if (boundary) {
      /* Needs at most 77 bytes,
         last realloc allocate at least 100 bytes extra */
      message = osip_str_append (message, boundary);
      message = osip_strn_append (message, CRLF, 2);
    }

    i = osip_body_to_str (body, &tmp, &body_length);
    if (i != 0) {
      osip_free (*dest);
      *dest = NULL;
      if (boundary)
        osip_free (boundary);
      return i;
    }

    if (malloc_size < message - *dest + 100 + body_length) {
      size_t size = message - *dest;
      int offset_of_body;
      int offset_content_length_to_modify = 0;

      offset_of_body = (int) (start_of_bodies - *dest);
      if (content_length_to_modify != NULL)
        offset_content_length_to_modify = (int) (content_length_to_modify - *dest);
      malloc_size = message - *dest + body_length + 100;
      *dest = osip_realloc (*dest, malloc_size);
      if (*dest == NULL) {
        osip_free (tmp);        /* fixed 09/Jun/2005 */
        if (boundary)
          osip_free (boundary);
        return OSIP_NOMEM;
      }
      start_of_bodies = *dest + offset_of_body;
      if (content_length_to_modify != NULL)
        content_length_to_modify = *dest + offset_content_length_to_modify;
      message = *dest + size;
    }

    memcpy (message, tmp, body_length);
    message[body_length] = '\0';
    osip_free (tmp);
    message = message + body_length;

    pos++;
  }

  if (boundary) {
    /* Needs at most 79 bytes,
       last realloc allocate at least 100 bytes extra */
    message = osip_str_append (message, boundary);
    message = osip_strn_append (message, "--", 2);
    message = osip_strn_append (message, CRLF, 2);

    osip_free (boundary);
    boundary = NULL;
  }

  if (content_length_to_modify == NULL) {
    osip_free (*dest);
    *dest = NULL;
    return OSIP_SYNTAXERROR;
  }

  /* we NOW have the length of bodies: */
  {
    size_t size = message - start_of_bodies;
    char tmp2[15];

    total_length += size;
    snprintf (tmp2, 15, "%i", (int) size);
    /* do not use osip_strncpy here! */
    strncpy (content_length_to_modify + 5 - strlen (tmp2), tmp2, strlen (tmp2));
  }

  /* same remark as at the beginning of the method */
  sip->message_property = 1;
  sip->message = osip_malloc (total_length + 1);
  if (sip->message != NULL) {
    memcpy (sip->message, *dest, total_length);
    sip->message[total_length] = '\0';
    sip->message_length = total_length;
    if (message_length != NULL)
      *message_length = total_length;
  }
  return OSIP_SUCCESS;
}
Esempio n. 19
0
/* returns null on error. */
int
osip_accept_to_str (const osip_accept_t * accept, char **dest)
{
  char *buf;
  char *tmp;
  size_t len;

  *dest = NULL;
  if (accept == NULL)
    return -1;

  if ((accept->type == NULL) && (accept->subtype == NULL))
    {
      /* Empty header ! */
      buf = (char *) osip_malloc (2);
      buf[0] = ' ';
      buf[1] = '\0';
      *dest = buf;
      return 0;
    }

  /* try to guess a long enough length */
  len = strlen (accept->type) + strlen (accept->subtype) + 4    /* for '/', ' ', ';' and '\0' */
    + 10 * osip_list_size (accept->gen_params);

  buf = (char *) osip_malloc (len);
  tmp = buf;

  sprintf (tmp, "%s/%s", accept->type, accept->subtype);

  tmp = tmp + strlen (tmp);
  {
    int pos = 0;
    osip_generic_param_t *u_param;

#if 0
    if (!osip_list_eol (accept->gen_params, pos))
      {                         /* needed for cannonical form! (authentication issue of rfc2543) */
        sprintf (tmp, " ");
        tmp++;
      }
#endif
    while (!osip_list_eol (accept->gen_params, pos))
      {
        size_t tmp_len;

        u_param = (osip_generic_param_t *) osip_list_get (accept->gen_params, pos);
        if (u_param->gvalue == NULL)
          {
            osip_free (buf);
            return -1;
          }
        tmp_len = strlen (buf) + 4 + strlen (u_param->gname)
          + strlen (u_param->gvalue) + 1;
        if (len < tmp_len)
          {
            buf = osip_realloc (buf, tmp_len);
            len = tmp_len;
            tmp = buf + strlen (buf);
          }
        sprintf (tmp, "; %s=%s", u_param->gname, u_param->gvalue);
        tmp = tmp + strlen (tmp);
        pos++;
      }
  }
  *dest = buf;
  return 0;
}