⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msg_parser.c

📁 libosip-0.9.7源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)  Copyright (C) 2001,2002,2003  Aymeric MOIZARD jack@atosc.org    This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public  License along with this library; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <stdio.h>#include <stdlib.h>#include <osip/smsg.h>#include <osip/port.h>#include "msg.h"static intstartline_parsereq (startline_t * dest, char *buf, char **headers){  char *p1;  char *p2;  char *requesturi;  int i;  dest->sipmethod = NULL;  dest->statuscode = NULL;  dest->reasonphrase = NULL;  /* The first token is the method name: */  p2 = strchr (buf, ' ');  if (p2 == NULL)    return -1;  if (p2-buf==0)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "No space allowed here\n"));      return -1;    }  dest->sipmethod = (char *) smalloc (p2 - buf + 1);  sstrncpy (dest->sipmethod, buf, p2 - buf);  /* The second token is a sip-url or a uri: */  p1 = strchr (p2 + 2, ' ');	/* no space allowed inside sip-url */  if (p1 - p2 < 2)    return -1;  requesturi = (char *) smalloc (p1 - p2);  sstrncpy (requesturi, p2 + 1, (p1 - p2 - 1));  sclrspace (requesturi);  url_init (&(dest->rquri));  i = url_parse (dest->rquri, requesturi);  sfree (requesturi);  if (i == -1)    return -1;  /* find the the version and the beginning of headers */  {    char *hp = p1;    while ((*hp != '\r') && (*hp != '\n'))      {	if (*hp)	  hp++;	else	  {	    OSIP_TRACE (osip_trace			(__FILE__, __LINE__, OSIP_ERROR, NULL,			 "No crlf found\n"));	    return -1;	  }      }    if (hp - p1 < 2)      return -1;    dest->sipversion = (char *) smalloc (hp - p1);    sstrncpy (dest->sipversion, p1 + 1, (hp - p1 - 1));    hp++;    if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0]))      hp++;    (*headers) = hp;  }  return 0;}static intstartline_parseresp (startline_t * dest, char *buf, char **headers){  char *statuscode;  char *reasonphrase;  dest->rquri = NULL;  dest->sipmethod = NULL;  *headers = buf;  statuscode = strchr (buf, ' ');	/* search for first SPACE */  if (statuscode == NULL)    return -1;  dest->sipversion = (char *) smalloc (statuscode - (*headers) + 1);  sstrncpy (dest->sipversion, *headers, statuscode - (*headers));  reasonphrase = strchr (statuscode + 1, ' ');  dest->statuscode = (char *) smalloc (reasonphrase - statuscode);  sstrncpy (dest->statuscode, statuscode + 1, reasonphrase - statuscode - 1);  {    char *hp = reasonphrase;    while ((*hp != '\r') && (*hp != '\n'))      {	if (*hp)	  hp++;	else	  {	    OSIP_TRACE (osip_trace			(__FILE__, __LINE__, OSIP_ERROR, NULL,			 "No crlf found\n"));	    return -1;	  }      }    dest->reasonphrase = (char *) smalloc (hp - reasonphrase);    sstrncpy (dest->reasonphrase, reasonphrase + 1, hp - reasonphrase - 1);    hp++;    if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0]))      hp++;    (*headers) = hp;  }  return 0;}/* return size of request URI */static intmsg_startline_parse (startline_t * dest, char *buf, char **headers){  if (0 == strncmp ((const char *) buf, (const char *) "SIP/", 4))    return startline_parseresp (dest, buf, headers);  else    return startline_parsereq (dest, buf, headers);}intfind_next_occurence (char *str, char *buf, char **index_of_str){  *index_of_str = NULL;		/* AMD fix */  if ((NULL == str) || (NULL == buf))    return -1;  /* TODO? we may prefer strcasestr instead of strstr? */  *index_of_str = strstr ((const char *) buf, (const char *) str);  if (NULL == (*index_of_str))    return -1;  return 0;}intfind_next_crlf (char *start_of_header, char **end_of_header){  char *tmp;  *end_of_header = NULL;	/* AMD fix */  for (;;)    {      int leol = 1;		/* number of line-end symbols: */      /* if CR or LF =1, if CRLF =2  */      char *soh = start_of_header;      while (('\r' != *soh) && ('\n' != *soh))	{	  if (*soh)	    soh++;	  else	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_ERROR, NULL,			   "Final CRLF is missing\n"));	      return -1;	    }	}      if (('\r' == soh[0]) && ('\n' == soh[1]))	{			/* case 1: CRLF is the separator */	  tmp = soh + 1;	  leol = 2;	}      else	tmp = soh;		/* case 2 or 3: CR or LF is the separator */      /* VERIFY if TMP is the end of header or LWS.            */      /* LWS are extra SP, HT, CR and LF contained in headers. */      if ((' ' == tmp[1]) || ('\t' == tmp[1]))	{	  /* AMD fix: SPECIAL case! for people who add extra spaces  */	  /* with no meaning at the end of the body of SIP messages? */	  /* if this occur before the body, this is an error case    */	  /* because the last header of a message MUST end with a    */	  /* CRLFCRLF (not only CRLF). I prefer to assume that buggy */	  /* implementation exists... :( */	  char *extraspaces = tmp + 2;	  /* replace line end and TAB symbols by SP */	  tmp[1] = ' ';	  tmp[0] = ' ';	  if (2 == leol)	    tmp[-1] = ' ';	  for (;;)	    {			/* this is for line ending with '\cr\lf\t    ' (i.e more than one space after tab) */	      if (' ' == *extraspaces)		extraspaces++;	      else if ('\t' == *extraspaces)		{		  *extraspaces = ' ';		  extraspaces++;		}	      else if ('\0' == *extraspaces)		{		  tmp[1] = '\0';	/* this is the real limit of SIP message */		  *end_of_header = tmp + 1;		  return 0;		}	      else		break;	    }	  /* YES, this is LWS extra characters    */	  /* restart search of the end of headers */	  start_of_header = extraspaces;	}      else	{	  *end_of_header = tmp + 1;	/* beggining of next header */	  return 0;	}    }}intfind_next_crlfcrlf (char *start_of_part, char **end_of_part){  char *start_of_line;  char *end_of_line;  int i;  start_of_line = start_of_part;  for (;;)    {      i = find_next_crlf (start_of_line, &end_of_line);      if (i == -1)	{			/* error case??? no end of mesage found */	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "Final CRLF is missing\n"));	  return -1;	}      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 -1;	}      else if ('\r' == end_of_line[0])	{	  if ('\n' == end_of_line[1])	    end_of_line++;	  *end_of_part = end_of_line + 1;	  return 0;	}      else if ('\n' == end_of_line[0])	{	  *end_of_part = end_of_line + 1;	  return 0;	}      start_of_line = end_of_line;    }}intmsg_set_header (sip_t * sip, char *hname, char *hvalue){  int my_index;  if (hname == NULL)    return -1;  stolowercase (hname);  /* some headers are analysed completely      */  /* this method is used for selective parsing */  my_index = parser_isknownheader (hname);  if (my_index >= 0)		/* ok */    {      int ret;      ret = parser_callmethod (my_index, sip, hvalue);      if (ret == -1)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "Could not set header: \"%s\" %s\n", hname, hvalue));	  return -1;	}      return 0;    }  /* unknownheader */  if (msg_setheader (sip, hname, hvalue) == -1)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "Could not set unknown header\n"));      return -1;    }  return 0;}intmsg_handle_multiple_values (sip_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 */  beg = hvalue;  end = NULL;  ptr = hvalue;  if (hvalue == NULL)    {      i = msg_set_header (sip, hname, hvalue);      if (i == -1)	return -1;      return 0;    }  comma = strchr (ptr, ',');  stolowercase (hname);  if (comma == NULL || (strncmp (hname, "date", 4) == 0 && strlen (hname) == 4 )      || strncmp (hname, "organization", 12) == 0 || (strncmp (hname, "to", 2) == 0 && strlen (hname) == 2) || (strncmp (hname, "from", 4) == 0 && strlen (hname) == 4)	/* AMD: BUG fix */      || strncmp (hname, "call-id", 7) == 0 || (strncmp (hname, "cseq", 4) == 0 && strlen (hname) == 4)	/* AMD: BUG fix */      || strncmp (hname, "subject", 7) == 0 || strncmp (hname, "user-agent", 10) == 0 || strncmp (hname, "server", 6) == 0 || strncmp (hname, "www-authenticate", 16) == 0	/* AMD: BUG fix */      || strncmp (hname, "authentication-info", 19) == 0 || strncmp (hname, "proxy-authenticate", 20) == 0 || strncmp (hname, "proxy-authorization", 19) == 0 || strncmp (hname, "proxy-authentication-info", 25) == 0	/* AMD: BUG fix */      || 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 = msg_set_header (sip, hname, hvalue);      if (i == -1)	return -1;      return 0;    }  quote2 = NULL;  while (comma != NULL)    {      quote1 = quote_find (ptr);      if (quote1 != NULL)	{	  quote2 = quote_find (quote1 + 1);	  if (quote2 == NULL)	    return -1;		/* quotes comes by pair */	  ptr = quote2 + 1;	}      if ((quote1 == NULL) || (quote1 > comma))	{	  end = comma;	  comma = strchr (comma + 1, ',');	  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 (strlen (beg) < 2)		return 0;	/* empty header */	      sclrspace (beg);	      i = msg_set_header (sip, hname, beg);	      if (i == -1)		return -1;	      return 0;	    }	}      if (end != NULL)	{	  char *avalue;	  if (end - beg + 1 < 2)	    return -1;	  avalue = (char *) smalloc (end - beg + 1);	  sstrncpy (avalue, beg, end - beg);	  sclrspace (avalue);	  /* really store the header in the sip structure */	  i = msg_set_header (sip, hname, avalue);	  sfree (avalue);	  if (i == -1)	    return -1;	  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 (strlen (beg) < 2)		return 0;	/* empty header */	      sclrspace (beg);	      i = msg_set_header (sip, hname, beg);	      if (i == -1)		return -1;	      return 0;	    }	}    }  return -1;			/* if comma is NULL, we should have already return 0 */}/* set all headers */intmsg_headers_parse (sip_t * sip, char *start_of_header, char **body){  char *colon_index;		/* index of ':' */  char *hname;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -