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

📄 contact.c

📁 SIP Express Router, Linux下的SIP代理服务器,小巧实用,开发测试VoIP设备和应用的必备.
💻 C
字号:
/* * $Id: contact.c,v 1.9 2004/09/01 20:08:23 janakj Exp $ * * Parses one Contact in Contact HF body * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 General Public License for more details. * * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * History: * ------- *  2003-03-25 Adapted to use new parameter parser (janakj) */#include <string.h>        /* memset */#include "../../mem/mem.h" /* pkg_malloc, pkg_free */#include "../../dprint.h"#include "../../trim.h"    /* trim_leading, trim_trailing */#include "contact.h"#define ST1 1 /* Basic state */#define ST2 2 /* Quoted */#define ST3 3 /* Angle quoted */#define ST4 4 /* Angle quoted and quoted */#define ST5 5 /* Escape in quoted */#define ST6 6 /* Escape in angle quoted and quoted *//* * Skip URI, stops when , (next contact) * or ; (parameter) is found */static inline int skip_uri(str* _s){	register int st = ST1;	while(_s->len) {		switch(*(_s->s)) {		case ',':		case ';':			if (st == ST1) return 0;			break;		case '\"':			switch(st) {			case ST1: st = ST2; break;			case ST2: st = ST1; break;			case ST3: st = ST4; break;			case ST4: st = ST3; break;			case ST5: st = ST2; break;			case ST6: st = ST4; break;			}			break;		case '<':			switch(st) {			case ST1: st = ST3; break;			case ST3: 				LOG(L_ERR, "skip_uri(): Second < found\n");				return -1;			case ST5: st = ST2; break;			case ST6: st = ST4; break;			}			break;					case '>':			switch(st) {			case ST1: 				LOG(L_ERR, "skip_uri(): > is first\n");				return -2;			case ST3: st = ST1; break;			case ST5: st = ST2; break;			case ST6: st = ST4; break;			}			break;		case '\\':			switch(st) {			case ST2: st = ST5; break;			case ST4: st = ST6; break;			case ST5: st = ST2; break;			case ST6: st = ST4; break;			}			break;		default: break;		}		_s->s++;		_s->len--;	}	if (st != ST1) {		LOG(L_ERR, "skip_uri(): < or \" not closed\n");		return -3;	}	return 0;}/* * Skip name part * * _s will be adjusted to point at the beginning * of URI */static inline int skip_name(str* _s){	char* last_wsp, *p;	int i, quoted = 0;		if (!_s) {		LOG(L_ERR, "skip_name(): Invalid parameter value\n");		return -1;	}	p = _s->s;	last_wsp = 0;	for(i = 0; i < _s->len; i++) {		if (!quoted) {			if ((*p == ' ') || (*p == '\t')) {				last_wsp = p;			} else {				if (*p == '<') {					_s->s = p;					_s->len -= i;					return 0;				}								if (*p == ':') {					if (last_wsp) {						_s->s = last_wsp;						_s->len -= last_wsp - _s->s + 1;					}					return 0;				}				if (*p == '\"') {					quoted = 1;				}			}		} else {			if ((*p == '\"') && (*(p-1) != '\\')) quoted = 0;		}		p++;	}	if (quoted) {		LOG(L_ERR, "skip_name(): Closing quote missing in name part of Contact\n");	} else {		LOG(L_ERR, "skip_name(): Error in contact, scheme separator not found\n");	}	return -1;}/* * Parse contacts in a Contact HF */int parse_contacts(str* _s, contact_t** _c){	contact_t* c;	param_hooks_t hooks;	while(1) {		     /* Allocate and clear contact structure */		c = (contact_t*)pkg_malloc(sizeof(contact_t));		if (c == 0) {			LOG(L_ERR, "parse_contacts(): No memory left\n");			goto error;		}		memset(c, 0, sizeof(contact_t));				c->name.s = _s->s;		if (skip_name(_s) < 0) {			LOG(L_ERR, "parse_contacts(): Error while skipping name part\n");			goto error;		}		c->uri.s = _s->s;		c->name.len = _s->s - c->name.s;		trim_trailing(&c->name);				     /* Find the end of the URI */		if (skip_uri(_s) < 0) {			LOG(L_ERR, "parse_contacts(): Error while skipping URI\n");			goto error;		}				c->uri.len = _s->s - c->uri.s; /* Calculate URI length */		trim_trailing(&(c->uri));      /* Remove any trailing spaces from URI */		     /* Remove <> if any */		if ((c->uri.len >= 2) && (c->uri.s[0] == '<') && (c->uri.s[c->uri.len - 1] == '>')) {			c->uri.s++;			c->uri.len -= 2;		}		trim(&c->uri);				if (_s->len == 0) goto ok;				if (_s->s[0] == ';') {         /* Contact parameter found */			_s->s++;			_s->len--;			trim_leading(_s);						if (_s->len == 0) {				LOG(L_ERR, "parse_contacts(): Error while parsing params\n");				goto error;			}			if (parse_params(_s, CLASS_CONTACT, &hooks, &c->params) < 0) {				LOG(L_ERR, "parse_contacts(): Error while parsing parameters\n");				goto error;			}			c->q = hooks.contact.q;			c->expires = hooks.contact.expires;			c->received = hooks.contact.received;			c->method = hooks.contact.method;			if (_s->len == 0) goto ok;		}		     /* Next character is comma */		c->len = _s->s - c->name.s;		_s->s++;		_s->len--;		trim_leading(_s);		if (_s->len == 0) {			LOG(L_ERR, "parse_contacts(): Text after comma missing\n");			goto error;		}		c->next = *_c;		*_c = c;	} error:	if (c) pkg_free(c);	free_contacts(_c); /* Free any contacts created so far */	return -1; ok:	c->len = _s->s - c->name.s;	c->next = *_c;	*_c = c;	return 0;}/* * Free list of contacts * _c is head of the list */void free_contacts(contact_t** _c){	contact_t* ptr;	while(*_c) {		ptr = *_c;		*_c = (*_c)->next;		if (ptr->params) {			free_params(ptr->params);		}		pkg_free(ptr);	}}/* * Print list of contacts, just for debugging */void print_contacts(FILE* _o, contact_t* _c){	contact_t* ptr;	ptr = _c;	while(ptr) {		fprintf(_o, "---Contact---\n");		fprintf(_o, "name    : '%.*s'\n", ptr->name.len, ptr->name.s);		fprintf(_o, "URI     : '%.*s'\n", ptr->uri.len, ptr->uri.s);		fprintf(_o, "q       : %p\n", ptr->q);		fprintf(_o, "expires : %p\n", ptr->expires);		fprintf(_o, "received: %p\n", ptr->received);		fprintf(_o, "method  : %p\n", ptr->method);		fprintf(_o, "len     : %d\n", ptr->len);		if (ptr->params) {			print_params(_o, ptr->params);		}		fprintf(_o, "---/Contact---\n");		ptr = ptr->next;	}}

⌨️ 快捷键说明

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