|
@@ -1,371 +0,0 @@
|
|
|
-/*
|
|
|
- * $Id$
|
|
|
- *
|
|
|
- *
|
|
|
- * 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:
|
|
|
- * [email protected]
|
|
|
- *
|
|
|
- * 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
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
-#include "cparam.h"
|
|
|
-#include "../../mem/mem.h"
|
|
|
-#include <stdio.h> /* printf */
|
|
|
-#include "../../ut.h" /* q_memchr */
|
|
|
-#include <string.h> /* memset */
|
|
|
-#include "../../trim.h"
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse quoted string in a parameter body
|
|
|
- * return the string without quotes in _r
|
|
|
- * parameter and update _s to point behind the
|
|
|
- * closing quote
|
|
|
- */
|
|
|
-static inline int parse_quoted(str* _s, str* _r)
|
|
|
-{
|
|
|
- char* end_quote;
|
|
|
-
|
|
|
- /* The string must have at least
|
|
|
- * surrounding quotes
|
|
|
- */
|
|
|
- if (_s->len < 2) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Skip opening quote */
|
|
|
- _s->s++;
|
|
|
- _s->len--;
|
|
|
-
|
|
|
-
|
|
|
- /* Find closing quote */
|
|
|
- end_quote = q_memchr(_s->s, '\"', _s->len);
|
|
|
-
|
|
|
- /* Not found, return error */
|
|
|
- if (!end_quote) {
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- /* Let _r point to the string without
|
|
|
- * surrounding quotes
|
|
|
- */
|
|
|
- _r->s = _s->s;
|
|
|
- _r->len = end_quote - _s->s;
|
|
|
-
|
|
|
- /* Update _s parameter to point
|
|
|
- * behind the closing quote
|
|
|
- */
|
|
|
- _s->len -= (end_quote - _s->s + 1);
|
|
|
- _s->s = end_quote + 1;
|
|
|
-
|
|
|
- /* Everything went OK */
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse unquoted token in a parameter body
|
|
|
- * let _r point to the token and update _s
|
|
|
- * to point right behind the token
|
|
|
- */
|
|
|
-static inline int parse_token(str* _s, str* _r)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- /* There is nothing to parse,
|
|
|
- * return error
|
|
|
- */
|
|
|
- if (_s->len == 0) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Save the begining of the
|
|
|
- * token in _r->s
|
|
|
- */
|
|
|
- _r->s = _s->s;
|
|
|
-
|
|
|
- /* Iterate throught the
|
|
|
- * token body
|
|
|
- */
|
|
|
- for(i = 0; i < _s->len; i++) {
|
|
|
-
|
|
|
- /* All these characters
|
|
|
- * mark end of the token
|
|
|
- */
|
|
|
- switch(_s->s[i]) {
|
|
|
- case ' ':
|
|
|
- case '\t':
|
|
|
- case '\r':
|
|
|
- case '\n':
|
|
|
- case ',':
|
|
|
- case ';':
|
|
|
- /* So if you find
|
|
|
- * any of them
|
|
|
- * stop iterating
|
|
|
- */
|
|
|
- goto out;
|
|
|
- }
|
|
|
- }
|
|
|
- out:
|
|
|
- if (i == 0) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Save length of the token */
|
|
|
- _r->len = i;
|
|
|
-
|
|
|
- /* Update _s parameter so it points
|
|
|
- * right behind the end of the token
|
|
|
- */
|
|
|
- _s->s = _s->s + i;
|
|
|
- _s->len -= i;
|
|
|
-
|
|
|
- /* Everything went OK */
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse type of a parameter
|
|
|
- */
|
|
|
-static inline int parse_param_type(cparam_t* _c)
|
|
|
-{
|
|
|
- switch(_c->name.s[0]) {
|
|
|
- case 'q':
|
|
|
- case 'Q':
|
|
|
- if (_c->name.len == 1) {
|
|
|
- _c->type = CP_Q;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-
|
|
|
- case 'e':
|
|
|
- case 'E':
|
|
|
- if ((_c->name.len == 7) &&
|
|
|
- (!strncasecmp(_c->name.s + 1, "xpires", 6))) {
|
|
|
- _c->type = CP_EXPIRES;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-
|
|
|
- case 'm':
|
|
|
- case 'M':
|
|
|
- if ((_c->name.len == 6) &&
|
|
|
- (!strncasecmp(_c->name.s + 1, "ethod", 5))) {
|
|
|
- _c->type = CP_METHOD;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse body of a parameter. It can be quoted string or
|
|
|
- * a single token.
|
|
|
- */
|
|
|
-static inline int parse_body(str* _s, cparam_t* _c)
|
|
|
-{
|
|
|
- if (_s->s[0] == '\"') {
|
|
|
- if (parse_quoted(_s, &(_c->body)) < 0) {
|
|
|
- LOG(L_ERR, "parse_body(): Error while parsing quoted string\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (parse_token(_s, &(_c->body)) < 0) {
|
|
|
- LOG(L_ERR, "parse_body(): Error while parsing token\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse a parameter name
|
|
|
- */
|
|
|
-static inline int parse_param_name(str* _s, cparam_t* _p)
|
|
|
-{
|
|
|
- _p->name.s = _s->s;
|
|
|
-
|
|
|
- while(_s->len) {
|
|
|
- switch(_s->s[0]) {
|
|
|
- case ' ':
|
|
|
- case '\t':
|
|
|
- case '\r':
|
|
|
- case '\n':
|
|
|
- case ';':
|
|
|
- case ',':
|
|
|
- case '=':
|
|
|
- goto out;
|
|
|
- }
|
|
|
- _s->s++;
|
|
|
- _s->len--;
|
|
|
- }
|
|
|
-
|
|
|
- out:
|
|
|
- _p->name.len = _s->s - _p->name.s;
|
|
|
-
|
|
|
- if (parse_param_type(_p) < 0) {
|
|
|
- LOG(L_ERR, "parse_param_name(): Error while parsing type\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Parse contact parameters
|
|
|
- */
|
|
|
-int parse_cparams(str* _s, cparam_t** _p, cparam_t** _q, cparam_t** _e, cparam_t** _m)
|
|
|
-{
|
|
|
- cparam_t* c;
|
|
|
-
|
|
|
- while(1) {
|
|
|
- c = (cparam_t*)pkg_malloc(sizeof(cparam_t));
|
|
|
- if (c == 0) {
|
|
|
- LOG(L_ERR, "parse_cparams(): No memory left\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memset(c, 0, sizeof(cparam_t));
|
|
|
-
|
|
|
- if (parse_param_name(_s, c) < 0) {
|
|
|
- LOG(L_ERR, "parse_cparams(): Error while parsing param name\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- trim_leading(_s);
|
|
|
-
|
|
|
- if (_s->len == 0) { /* The last parameter without body */
|
|
|
- goto ok;
|
|
|
- }
|
|
|
-
|
|
|
- if (_s->s[0] == '=') {
|
|
|
- _s->s++;
|
|
|
- _s->len--;
|
|
|
- trim_leading(_s);
|
|
|
-
|
|
|
- if (_s->len == 0) {
|
|
|
- LOG(L_ERR, "parse_cparams(): Body missing\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- if (parse_body(_s, c) < 0) {
|
|
|
- LOG(L_ERR, "parse_cparams(): Error while parsing param body\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- trim_leading(_s);
|
|
|
- if (_s->len == 0) {
|
|
|
- goto ok;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (_s->s[0] == ',') goto ok;
|
|
|
-
|
|
|
- if (_s->s[0] != ';') {
|
|
|
- LOG(L_ERR, "parse_cparams(): Invalid character, ; expected\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- _s->s++;
|
|
|
- _s->len--;
|
|
|
- trim_leading(_s);
|
|
|
-
|
|
|
- if (_s->len == 0) {
|
|
|
- LOG(L_ERR, "parse_cparams(): Param name missing after ;\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- c->next = *_p;
|
|
|
- *_p = c;
|
|
|
- switch(c->type) { /* Update hook pointers */
|
|
|
- case CP_Q: *_q = c; break;
|
|
|
- case CP_EXPIRES: *_e = c; break;
|
|
|
- case CP_METHOD: *_m = c; break;
|
|
|
- case CP_OTHER: break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- error:
|
|
|
- if (c) pkg_free(c);
|
|
|
- free_cparams(_p);
|
|
|
- return -1;
|
|
|
-
|
|
|
- ok:
|
|
|
- c->next = *_p;
|
|
|
- *_p = c;
|
|
|
- switch(c->type) { /* Update hook pointers */
|
|
|
- case CP_Q: *_q = c; break;
|
|
|
- case CP_EXPIRES: *_e = c; break;
|
|
|
- case CP_METHOD: *_m = c; break;
|
|
|
- case CP_OTHER: ; break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Free the whole contact parameter list
|
|
|
- */
|
|
|
-void free_cparams(cparam_t** _p)
|
|
|
-{
|
|
|
- cparam_t* ptr;
|
|
|
-
|
|
|
- while(*_p) {
|
|
|
- ptr = *_p;
|
|
|
- pkg_free(ptr);
|
|
|
- *_p = (*_p)->next;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Print contact parameter list
|
|
|
- */
|
|
|
-void print_cparams(cparam_t* _p)
|
|
|
-{
|
|
|
- cparam_t* ptr;
|
|
|
- char* type;
|
|
|
-
|
|
|
- ptr = _p;
|
|
|
-
|
|
|
- while(ptr) {
|
|
|
- printf("...cparam(%p)...\n", ptr);
|
|
|
-
|
|
|
- switch(ptr->type) {
|
|
|
- case CP_OTHER: type = "CP_OTHER"; break;
|
|
|
- case CP_Q: type = "CP_Q"; break;
|
|
|
- case CP_EXPIRES: type = "CP_EXPIRES"; break;
|
|
|
- case CP_METHOD: type = "CP_METHOD"; break;
|
|
|
- default: type = "UNKNOWN"; break;
|
|
|
- }
|
|
|
-
|
|
|
- printf("type: %s\n", type);
|
|
|
- printf("name: \'%.*s\'\n", ptr->name.len, ptr->name.s);
|
|
|
- printf("body: \'%.*s\'\n", ptr->body.len, ptr->body.s);
|
|
|
-
|
|
|
- printf(".../cparam...\n");
|
|
|
-
|
|
|
- ptr = ptr->next;
|
|
|
- }
|
|
|
-}
|