📄 contact.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 + -