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

📄 sip_parse_uri.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 3 页
字号:
 *                   ":" / "@" / "&" / "=" / "+" / "$" / "," */static voidsip_uri_parse_abs_path(_sip_uri_t *outurl, char *scan, char *uend){	if (scan == uend || *scan != '/')		return;	outurl->sip_uri_path.sip_str_ptr = scan;	outurl->sip_uri_path.sip_str_len = uend - scan;	++scan;	while (scan < uend && (SIP_URI_ISPCHAR(*scan) ||	    SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISURLESCAPE(scan, uend) ||	    *scan == '/' || *scan == ';')) {		++scan;	}	if (scan < uend)		outurl->sip_uri_errflags |= SIP_URIERR_PATH;}/* * reg-name =  1*( unreserved / escaped / "$" / "," / ";" *             / ":" / "@" / "&" / "=" / "+" ) */static voidsip_uri_parse_abs_regname(_sip_uri_t *outurl, char *scan, char *uend){	if (scan == uend)		return;	outurl->sip_uri_regname.sip_str_ptr = scan;	outurl->sip_uri_regname.sip_str_len = uend - scan;	while (scan < uend && (SIP_URI_ISUNRESERVED(*scan) ||	    SIP_URI_ISURLESCAPE(scan, uend) || SIP_URI_ISREGNAME(*scan))) {		++scan;	}	if (scan < uend)		outurl->sip_uri_errflags |= SIP_URIERR_REGNAME;}/* * The format of the password is supposed to be :XXX * password =  *( unreserved / escaped / "&" / "=" / "+" / "$" / "," ) */static voidsip_uri_parse_password(_sip_uri_t *outurl, char *scan, char *uend){	if (scan == uend || *scan != ':' || scan + 1 == uend)		return;	++scan;	outurl->sip_uri_password.sip_str_ptr = scan;	outurl->sip_uri_password.sip_str_len = uend - scan;	while (scan < uend && (SIP_URI_ISUNRESERVED(*scan) ||	    SIP_URI_ISURLESCAPE(scan, uend) || SIP_URI_ISOTHER(*scan) ||	    *scan == '&')) {		++scan;	}	if (scan < uend)		outurl->sip_uri_errflags |= SIP_URIERR_PASS;}/* * user =  1*( unreserved / escaped / user-unreserved ) * user-unreserved  =  "&" / "=" / "+" / "$" / "," / ";" / "?" / "/" */static voidsip_uri_parse_user(_sip_uri_t *outurl, char *scan, char *uend){	if (scan == uend) {		outurl->sip_uri_errflags |= SIP_URIERR_USER;		return;	}	outurl->sip_uri_user.sip_str_ptr = scan;	outurl->sip_uri_user.sip_str_len = uend - scan;	if (sip_uri_parse_tel(scan, uend)) {		outurl->sip_uri_isteluser = B_TRUE;	} else {		while (scan < uend && (SIP_URI_ISUNRESERVED(*scan) ||		    SIP_URI_ISURLESCAPE(scan, uend) || SIP_URI_ISUSER(*scan))) {			++scan;		}		if (scan < uend)			outurl->sip_uri_errflags |= SIP_URIERR_USER;	}}/* * the format of port is supposed to be :XXX * port =  1*DIGIT */static voidsip_uri_parse_port(_sip_uri_t *outurl, char *scan, char *uend){	if (scan == uend || *scan != ':' || scan + 1 == uend) {		outurl->sip_uri_errflags |= SIP_URIERR_PORT;		return;	}	++scan;	/* parse numeric port number */	if (SIP_URI_ISDIGIT(*scan)) {		outurl->sip_uri_port = *scan - '0';		while (++scan < uend && SIP_URI_ISDIGIT(*scan)) {		    outurl->sip_uri_port =			outurl->sip_uri_port * 10 + (*scan - '0');			if (outurl->sip_uri_port > 0xffff) {				outurl->sip_uri_errflags |= SIP_URIERR_PORT;				outurl->sip_uri_port = 0;				break;			}		}	}	if (scan < uend) {		outurl->sip_uri_errflags |= SIP_URIERR_PORT;		outurl->sip_uri_port = 0;	}}/* * parse an IPv4 address *    1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT *  advances pscan to end of IPv4 address, or after last "." that was *  a valid IPv4 or domain name. * returns 1 if ipv4 found, 0 otherwise */static intsip_uri_parse_ipv4(char *scan, char *uend){	int	j = 0;	int	val = 0;	for (j = 0; j < 4; ++j) {		if (!SIP_URI_ISDIGIT(*scan))			break;		val = *scan - '0';		while (++scan < uend && SIP_URI_ISDIGIT(*scan)) {			val = val * 10 + (*scan - '0');			if (val > 255)				return (0);		}		if (j < 3) {			if (*scan != '.')				break;			++scan;		}	}	if (j == 4 && scan == uend)		return (1);	return (0);}/* * parse an IPv6 address *  IPv6address = hexpart [ ":" IPv4address ] *  IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT *  hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] *  hexseq  = hex4 *( ":" hex4) *  hex4    = 1*4HEXDIG *  if not found, leaves pscan unchanged, otherwise advances to end *  returns 1 if valid, *  0 if invalid */static intsip_uri_parse_ipv6(char *scan, char *uend){	char		*mark;	unsigned	j = 0;			/* index for addr */	unsigned	val = 0;		/* hex value */	int		zpad = 0;		/* index of :: delimiter */	if (*scan != '[')		return (0);	++scan;	j = 0;	/* check for leading "::", set zpad to the position of the "::" */	if (scan + 1 < uend && scan[0] == ':' && scan[1] == ':') {		zpad = 0;		scan += 2;	} else {		zpad = -1;	}	/* loop through up to 16 bytes of IPv6 address */	while (scan < uend && j < 15) {		if (!SIP_URI_ISHEX(*scan))			break;		mark = scan;		val = SIP_URI_HEXVAL(*scan);		while (++scan < uend && SIP_URI_ISHEX(*scan)) {			val = val * 16 + SIP_URI_HEXVAL(*scan);			if (val > 0xffff)				return (0);		}		/* always require a delimiter or ] */		if (scan == uend)			return (0);		if (*scan == '.' && (j == 12 || (zpad != -1 && j < 12)) &&		    mark < uend && sip_uri_parse_ipv4(mark, uend - 1) &&		    *(uend - 1) == ']') {			mark = uend - 1;			j += 4;			scan = mark + 1;			break;		}		/* set address */		j += 2;		/* check for delimiter or ] */		if (*scan == ':') {			/* found ":" delimiter, check for "::" */			if (++scan < uend && *scan == ':') {				if (zpad != -1)					return (0);				zpad = j;				if (++scan < uend && *scan == ']') {					++scan;					break;				}			}		} else if (*scan == ']' && (j == 16 || zpad != -1)) {			++scan;			break;		} else {			/* not a valid delimiter */			return (0);		}	}	if (zpad == -1 && j < 16)		return (0);	if (zpad != -1) {		if (j > 15)			return (0);	}	if (scan == uend)		return (1);	return (0);}/* * hostname         =  *( domainlabel "." ) toplabel [ "." ] * domainlabel      =  alphanum / alphanum *( alphanum / "-" ) alphanum * toplabel         =  ALPHA / ALPHA *( alphanum / "-" ) alphanum */static intsip_uri_parse_hostname(char *scan, char *uend){	int	sawalpha = 0;	if (scan < uend && SIP_URI_ISALNUM(*scan)) {		do {			sawalpha = SIP_URI_ISALPHA(*scan);			while (SIP_URI_ISHOST(*scan))				++scan;			if (*scan != '.')				break;			++scan;		} while (scan < uend && SIP_URI_ISALNUM(*scan));	}	if (sawalpha && scan == uend)		return (1);	return (0);}/* * parse the network path portion of a full URL */static voidsip_uri_parse_netpath(_sip_uri_t *outurl, char **pscan, char *uend,    boolean_t issip){	char	*mark = (char *)0;	char	*mark2 = (char *)0;	char	*scan = *pscan;	int	gothost = 0;	/* look for the first high-level delimiter */	mark = scan;	while (scan < uend && *scan != '@')		++scan;	/* handle userinfo section of URL */	if (scan < uend && *scan == '@') {		/* parse user */		mark2 = mark;		while (mark < scan && *mark != ':')			++mark;		sip_uri_parse_user(outurl, mark2, mark);		/* parse password */		if (*mark == ':')			sip_uri_parse_password(outurl, mark, scan);		mark = ++scan;	}	scan = mark;	if (scan < uend && *scan == '[') {	/* look for an IPv6 address */		while (scan < uend && *scan != ']')			++scan;		if (scan < uend) {			++scan;			if (sip_uri_parse_ipv6(mark, scan))				gothost = 1;		}	} else {		while (scan < uend && ((issip && !SIP_URI_ISSIPHDELIM(*scan)) ||		    (!issip && !SIP_URI_ISABSHDELIM(*scan)))) {			++scan;		}		/* look for an IPv4 address */		if (mark < scan && SIP_URI_ISDIGIT(*mark) &&		    sip_uri_parse_ipv4(mark, scan)) {			gothost = 1;		}		/* look for a valid host name */		if (!gothost && mark < scan &&		    sip_uri_parse_hostname(mark, scan)) {			gothost = 1;		}	}	/* handle invalid host name */	if (!gothost)		outurl->sip_uri_errflags |= SIP_URIERR_HOST;	/* save host name */	outurl->sip_uri_host.sip_str_ptr = mark;	outurl->sip_uri_host.sip_str_len = scan - mark;	mark = scan;	/* parse the port number */	if (scan < uend && *scan == ':') {		while (scan < uend && ((issip && !SIP_URI_ISSIPDELIM(*scan)) ||		    (!issip && !SIP_URI_ISABSDELIM(*scan)))) {			++scan;		}		sip_uri_parse_port(outurl, mark, scan);	}	/* set return pointer */	*pscan = scan;}/* * parse a URL * URL = SIP-URI / SIPS-URI / absoluteURI */voidsip_uri_parse_it(_sip_uri_t *outurl, sip_str_t *uri_str){	char 		*mark;	char		*scan;	char		*uend;	char		*str = uri_str->sip_str_ptr;	unsigned	urlen = uri_str->sip_str_len;	/* reset output parameters */	(void) memset(outurl, 0, sizeof (sip_uri_t));	/* strip enclosing angle brackets */	if (urlen > 1 && str[0] == '<' && str[urlen-1] == '>') {		urlen -= 2;		++str;	}	uend = str + urlen;	/* strip off space prefix and trailing spaces */	while (str < uend && isspace(*str)) {		++str;		--urlen;	}	while (str < uend && isspace(*(uend - 1))) {		--uend;		--urlen;	}	/* strip off "URL:" prefix */	if (urlen > 4 && sip_uri_url_casecmp(str, "URL:", 4) == 0) {		str += 4;		urlen -= 4;	}	/* parse the scheme name */	mark = scan = str;	while (scan < uend && *scan != ':')		++scan;	if (scan == uend || !sip_uri_parse_scheme(outurl, mark, scan)) {		outurl->sip_uri_errflags |= SIP_URIERR_SCHEME;		return;	}	if ((outurl->sip_uri_scheme.sip_str_len == SIP_SCHEME_LEN &&	    !memcmp(outurl->sip_uri_scheme.sip_str_ptr, SIP_SCHEME,	    SIP_SCHEME_LEN)) ||	    (outurl->sip_uri_scheme.sip_str_len == SIPS_SCHEME_LEN &&	    !memcmp(outurl->sip_uri_scheme.sip_str_ptr, SIPS_SCHEME,	    SIPS_SCHEME_LEN))) {		outurl->sip_uri_issip = B_TRUE;	} else {		outurl->sip_uri_issip = B_FALSE;	}	++scan; /* skip ':' */	if (outurl->sip_uri_issip) {		/* parse SIP URL */		sip_uri_parse_netpath(outurl, &scan, uend, B_TRUE);		/* parse parameters */		if (scan < uend && *scan == ';') {			mark = scan;			while (scan < uend && *scan != '?')				++scan;			sip_uri_parse_params(outurl, mark, scan);		}		/* parse headers */		if (scan < uend && *scan == '?')			sip_uri_parse_headers(outurl, scan, uend);	} else if (scan < uend && scan[0] == '/') {	 /* parse absoluteURL */		++scan;		/*		 * parse authority		 * authority	= srvr / reg-name		 * srvr		= [ [ userinfo "@" ] hostport ]		 * reg-name	= 1*(unreserved / escaped / "$" / ","		 *			/ ";" / ":" / "@" / "&" / "=" / "+")		 */		if (scan < uend && *scan == '/') {			++scan;			mark = scan;			/* take authority as srvr */			sip_uri_parse_netpath(outurl, &scan, uend, B_FALSE);			/*			 * if srvr failed, take it as reg-name			 * parse reg-name			 */			if (outurl->sip_uri_errflags & SIP_URIERR_USER ||			    outurl->sip_uri_errflags & SIP_URIERR_PASS ||			    outurl->sip_uri_errflags & SIP_URIERR_HOST ||			    outurl->sip_uri_errflags & SIP_URIERR_PORT) {				scan = mark;				while (scan < uend && *scan != '/' &&					*scan != '?') {					++scan;				}				sip_uri_parse_abs_regname(outurl, mark, scan);				if (!(outurl->sip_uri_errflags &				    SIP_URIERR_REGNAME)) {					/*					 * remove error info of user,					 * password, host, port					 */					outurl->sip_uri_user.sip_str_ptr = NULL;					outurl->sip_uri_user.sip_str_len = 0;					outurl->sip_uri_errflags &=					    ~SIP_URIERR_USER;					outurl->sip_uri_password.sip_str_ptr =					    NULL;					outurl->sip_uri_password.sip_str_len =					    0;					outurl->sip_uri_errflags &=					    ~SIP_URIERR_PASS;					outurl->sip_uri_host.sip_str_ptr = NULL;					outurl->sip_uri_host.sip_str_len = 0;					outurl->sip_uri_errflags &=					    ~SIP_URIERR_HOST;					outurl->sip_uri_port = 0;					outurl->sip_uri_errflags &=					    ~SIP_URIERR_PORT;				}			}		} else {			/* there is no net-path */			--scan;		}		/* parse abs-path */		if (scan < uend && *scan == '/') {			mark = scan;			while (scan < uend && *scan != '?')				++scan;			sip_uri_parse_abs_path(outurl, mark, scan);		}		/* parse query */		if (scan < uend && *scan == '?')			sip_uri_parse_abs_query(outurl, scan, uend);	} else {		/* parse opaque-part */		sip_uri_parse_abs_opaque(outurl, scan, uend);	}}

⌨️ 快捷键说明

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