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

📄 sip_parse_generic.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END *//* * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. * Use is subject to license terms. */#pragma ident	"@(#)sip_parse_generic.c	1.6	06/08/16 SMI"#include "sip_msg.h"#include "sip_miscdefs.h"/* atoi function from a header */intsip_atoi(_sip_header_t *sip_header, int *num){	boolean_t	num_found = B_FALSE;	*num = 0;	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (isspace(*sip_header->sip_hdr_current)) {			sip_header->sip_hdr_current++;			if (num_found)				break;		} else if (isdigit(*sip_header->sip_hdr_current)) {			*num = (*num * 10) +			    (*sip_header->sip_hdr_current - '0');			num_found = B_TRUE;			sip_header->sip_hdr_current++;		} else {			break;		}	}	if (!num_found)		return (EINVAL);	return (0);}/* Find the 'token' */intsip_find_token(_sip_header_t *sip_header, char token){	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (token != SIP_COMMA &&		    *sip_header->sip_hdr_current == SIP_COMMA) {			sip_header->sip_hdr_current--;			return (1);		}		if (*sip_header->sip_hdr_current++ == token) {			/*			 * sip_hdr_current points to the char			 * after the token			 */			return (0);		}	}	return (1);}/* Find a carriage-return */intsip_find_cr(_sip_header_t *sip_header){	sip_header->sip_hdr_current = sip_header->sip_hdr_end;	while (*sip_header->sip_hdr_current-- != '\n') {		if (sip_header->sip_hdr_current == sip_header->sip_hdr_start)			return (EINVAL);	}	return (0);}/* * Find one of the separator provided, i.e. separator_1st or separator_2nd or * separator_3rd. */intsip_find_separator(_sip_header_t *sip_header, char separator_1st,    char separator_2nd, char separator_3rd){	assert(separator_1st != (char)NULL || separator_2nd != (char)NULL);	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (isspace(*sip_header->sip_hdr_current) ||		    (separator_1st != (char)NULL &&		    (*sip_header->sip_hdr_current == separator_1st)) ||		    (separator_2nd != (char)NULL &&		    (*sip_header->sip_hdr_current == separator_2nd)) ||		    (separator_3rd != (char)NULL &&		    (*sip_header->sip_hdr_current == separator_3rd))) {			return (0);		}		/*		 * If we have escape character, go to the next char		 */		if (*sip_header->sip_hdr_current == '\\')			sip_header->sip_hdr_current++;		sip_header->sip_hdr_current++;	}	return (1);}/* Return when we hit a white space */intsip_find_white_space(_sip_header_t *sip_header){	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (isspace(*sip_header->sip_hdr_current))			return (0);		sip_header->sip_hdr_current++;	}	return (1);}/* Skip to the next non-whitespace */intsip_skip_white_space(_sip_header_t *sip_header){	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (!isspace(*sip_header->sip_hdr_current))			return (0);		sip_header->sip_hdr_current++;	}	return (1);}/* Skip to the non-white space in the reverse direction */intsip_reverse_skip_white_space(_sip_header_t *sip_header){	while (sip_header->sip_hdr_current >= sip_header->sip_hdr_start) {		if (!isspace(*sip_header->sip_hdr_current))			return (0);		sip_header->sip_hdr_current--;	}	return (1);}/* get to the first non space after ':' */intsip_parse_goto_values(_sip_header_t *sip_header){	if (sip_find_token(sip_header, SIP_HCOLON) !=  0)		return (1);	if (sip_skip_white_space(sip_header))		return (1);	return (0);}/* Skip the current value. */intsip_goto_next_value(_sip_header_t *sip_header){	boolean_t	quoted = B_FALSE;	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		if (*sip_header->sip_hdr_current == SIP_QUOTE) {			if (quoted)				quoted = B_FALSE;			else				quoted = B_TRUE;		} else if (!quoted &&		    *sip_header->sip_hdr_current == SIP_COMMA) {			/* value ends before the COMMA */			sip_header->sip_hdr_current--;			return (0);		}		sip_header->sip_hdr_current++;	}	if (quoted)		return (1);	return (0);}/* Parse the header into parameter list. Parameters start with a ';'  */intsip_parse_params(_sip_header_t *sip_header, sip_param_t **parsed_list){	sip_param_t	*param = NULL;	sip_param_t	*new_param;	char		*tmp_ptr;	*parsed_list = NULL;	for (;;) {		boolean_t	quoted_name = B_FALSE;		/* First check if there are any parama */		if (sip_skip_white_space(sip_header) != 0)			return (0);		if (*sip_header->sip_hdr_current != SIP_SEMI)			return (0);		sip_header->sip_hdr_current++;		new_param = calloc(1, sizeof (sip_param_t));		if (new_param == NULL)			return (ENOMEM);		if (param != NULL)			param->param_next = new_param;		else			*parsed_list = new_param;		param = new_param;		/* Let's get to the start of the param name */		if (sip_skip_white_space(sip_header) != 0)			return (EPROTO);		/*		 * start of param name		 */		tmp_ptr = sip_header->sip_hdr_current;		param->param_name.sip_str_ptr = tmp_ptr;		if (sip_find_separator(sip_header, SIP_EQUAL, SIP_SEMI,		    SIP_COMMA) != 0) {			param->param_name.sip_str_len =			    sip_header->sip_hdr_current - tmp_ptr;			param->param_value.sip_str_ptr = NULL;			param->param_value.sip_str_len = 0;			return (0);		}		/*		 * End of param name		 */		param->param_name.sip_str_len =		    sip_header->sip_hdr_current - tmp_ptr;		if (sip_skip_white_space(sip_header) != 0 ||		    *sip_header->sip_hdr_current == SIP_COMMA) {			param->param_value.sip_str_ptr = NULL;			param->param_value.sip_str_len = 0;			return (0);		}		if (*sip_header->sip_hdr_current == SIP_SEMI) {			param->param_value.sip_str_ptr = NULL;			param->param_value.sip_str_len = 0;			continue;		}		assert(*sip_header->sip_hdr_current == SIP_EQUAL);		/* We are at EQUAL, lets go beyond that */		sip_header->sip_hdr_current++;		if (sip_skip_white_space(sip_header) != 0)			return (EPROTO);		if (*sip_header->sip_hdr_current == SIP_QUOTE) {			sip_header->sip_hdr_current++;			quoted_name = B_TRUE;		}		/* start of param value */		param->param_value.sip_str_ptr = sip_header->sip_hdr_current;		tmp_ptr = sip_header->sip_hdr_current;		if (quoted_name && sip_find_token(sip_header, SIP_QUOTE) != 0) {			return (EPROTO);		} else if (sip_find_separator(sip_header, SIP_SEMI, SIP_COMMA,		    (char)NULL) != 0) {			return (EPROTO);		}		param->param_value.sip_str_len = sip_header->sip_hdr_current -		    tmp_ptr;		if (quoted_name)			param->param_value.sip_str_len--;	}}/* * a header only has "header_name : " is an empty header * ":" must exist * sip_hdr_current resets to sip_hdr_start before exit */boolean_tsip_is_empty_hdr(_sip_header_t *sip_header){	if (sip_find_token(sip_header, SIP_HCOLON) != 0) {		sip_header->sip_hdr_current = sip_header->sip_hdr_start;		return (B_TRUE);	}	if (sip_skip_white_space(sip_header) == 0) {		sip_header->sip_hdr_current = sip_header->sip_hdr_start;		return (B_TRUE);	}	sip_header->sip_hdr_current = sip_header->sip_hdr_start;	return (B_FALSE);}/* Parsing an empty header, i.e. only has a ":" */intsip_parse_hdr_empty(_sip_header_t *hdr, sip_parsed_header_t **phdr){	sip_parsed_header_t	*parsed_header;	if (hdr == NULL || phdr == NULL)		return (EINVAL);	/* check if already parsed */	if (hdr->sip_hdr_parsed != NULL) {		*phdr = hdr->sip_hdr_parsed;		return (0);	}	*phdr = NULL;	parsed_header = calloc(1, sizeof (sip_parsed_header_t));	if (parsed_header == NULL)		return (ENOMEM);	parsed_header->sip_header = hdr;	parsed_header->value = NULL;	*phdr = parsed_header;	return (0);}/* validate uri str and parse uri using uri_parse() */voidsip_parse_uri_str(sip_str_t *sip_str, sip_parsed_header_t *hdr,    sip_hdr_value_t *value){	int		error;	/* Parse uri */	if (sip_str->sip_str_len > 0) {		value->sip_value_parsed_uri = sip_parse_uri(sip_str, &error);		if (value->sip_value_parsed_uri == NULL) {			sip_free_phdr(hdr);			return;		}		if (error != 0 ||		    value->sip_value_parsed_uri->sip_uri_errflags != 0) {			value->sip_value_state = SIP_VALUE_BAD;		}	}}/* * parser1 parses hdr format *	header_name: val1[; par1=pval1;par2=pval2 ..][, val2[;parlist..] ] *	val can be str1/str2 or str * headers: Accept, Accept-Encode, Accept-lang, Allow, Content-disp, *	    Content-Encode, Content-Lang, In-reply-to, *	    Priority, Require, Supported, Unsupported *	    Allow-Events, Event, Subscription-State */intsip_parse_hdr_parser1(_sip_header_t *hdr, sip_parsed_header_t **phdr, char sep){	sip_parsed_header_t	*parsed_header;	int			ret;	sip_hdr_value_t		*value = NULL;	sip_hdr_value_t		*last_value = NULL;	if (hdr == NULL || phdr == NULL)		return (EINVAL);	/* check if previously parsed */	if (hdr->sip_hdr_parsed != NULL) {		*phdr = hdr->sip_hdr_parsed;		return (0);	}	*phdr = NULL;	assert(hdr->sip_hdr_start == hdr->sip_hdr_current);	if (sip_parse_goto_values(hdr) != 0)		return (EPROTO);	parsed_header = calloc(1, sizeof (sip_parsed_header_t));	if (parsed_header == NULL)		return (ENOMEM);	parsed_header->sip_header = hdr;	while (hdr->sip_hdr_current < hdr->sip_hdr_end) {		value = calloc(1, sizeof (sip_hdr_value_t));		if (value == NULL) {			sip_free_phdr(parsed_header);			return (ENOMEM);		}		if (last_value != NULL)			last_value->sip_next_value = value;		else			parsed_header->value = (sip_value_t *)value;		value->sip_value_start = hdr->sip_hdr_current;		value->sip_value_header = parsed_header;		if (sip_find_separator(hdr, sep, SIP_COMMA, SIP_SEMI) == 0) {			char	c = *(hdr->sip_hdr_current);			if (isspace(c) && sep == (char)NULL) {				value->str_val_ptr = value->sip_value_start;				value->str_val_len = hdr->sip_hdr_current -				    value->sip_value_start;				/* nothing at the end except SP */				if (sip_skip_white_space(hdr) != 0)					goto end;				/* white space skipped */				c = *(hdr->sip_hdr_current);			}			/* only one string until COMMA, use sip_str_t */			if (c == SIP_COMMA) {				char	*t = hdr->sip_hdr_current;				hdr->sip_hdr_current--;				(void) sip_reverse_skip_white_space(hdr);				value->str_val_ptr = value->sip_value_start;				value->str_val_len = hdr->sip_hdr_current -				    value->sip_value_start + 1;				hdr->sip_hdr_current = t;				goto get_next_val;			}			/* two strings, use sip_2strs_t */			if ((sep != (char)NULL) && (c == sep)) {				value->strs1_val_ptr = value->sip_value_start;				value->strs1_val_len = hdr->sip_hdr_current -				    value->sip_value_start;				value->strs2_val_ptr =				    (++hdr->sip_hdr_current);				if (sip_find_separator(hdr, SIP_SEMI, SIP_COMMA,				    (char)NULL) == 0) {					char t = *(hdr->sip_hdr_current);					value->strs2_val_len =					    hdr->sip_hdr_current -						value->strs2_val_ptr;					/*					 * if COMMA, no param list, get next val					 * if SEMI, need to set params list					 */					if (t == SIP_COMMA)						goto get_next_val;				} else { /* the last part */					value->strs2_val_len =					    hdr->sip_hdr_current -						value->strs2_val_ptr;					goto end;				}			} else if (sep != (char)NULL) {				value->sip_value_state = SIP_VALUE_BAD;				goto get_next_val;			}			/*			 * c == SEMI, value contains single string			 * only one string until SEMI, use sip_str_t			 */			if (c == SIP_SEMI) {				char	*t = hdr->sip_hdr_current;				hdr->sip_hdr_current--;				/* get rid of SP at end of value field */				(void) sip_reverse_skip_white_space(hdr);				value->str_val_ptr = value->sip_value_start;				value->str_val_len = hdr->sip_hdr_current -				    value->str_val_ptr + 1;

⌨️ 快捷键说明

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