2 * $Id: parse_methods.c,v 1.2.2.1 2005/07/20 17:11:52 andrei Exp $
4 * Copyright (c) 2004 Juha Heinanen
6 * This file is part of ser, a free SIP server.
8 * ser is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
13 * For a license to use the ser software under conditions
14 * other than those described here, or to purchase support for this
15 * software, please contact iptel.org by e-mail at the following addresses:
18 * ser is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "../dprint.h"
31 #include "parse_methods.h"
35 * Check if argument is valid RFC3261 token character.
37 static int token_char(char _c)
39 return (_c >= 65 && _c <= 90) || /* upper alpha */
40 (_c >= 97 && _c <= 122) || /* lower aplha */
41 (_c >= 48 && _c <= 57) || /* digits */
42 (_c == '-') || (_c == '.') || (_c == '!') || (_c == '%') ||
43 (_c == '*') || (_c == '_') || (_c == '+') || (_c == '`') ||
44 (_c == '\'') || (_c == '~') || (_c == '+') || (_c == '`');
49 * Parse a method pointed by _next, assign its enum bit to _method, and update
50 * _next past the method. Returns 1 if parse succeeded and 0 otherwise.
52 static int parse_method(str* _next, unsigned int* _method)
54 if (!_next || !_method) {
55 LOG(L_ERR, "parse_method: Invalid parameter value\n");
59 if (!_next->len || !_next->s) {
60 DBG("parse_method: No input\n");
64 switch ((_next->s)[0]) {
67 if ((_next->len > 2) && !strncasecmp(_next->s + 1, "ck", 2)) {
78 if ((_next->len > 2) && !strncasecmp(_next->s + 1, "ye", 2)) {
89 if ((_next->len > 5) && !strncasecmp(_next->s + 1, "ancel", 5)) {
90 *_method = METH_CANCEL;
100 if ((_next->len > 3) &&
101 ((*(_next->s + 1) == 'N') || (*(_next->s + 1) == 'n'))) {
102 if (!strncasecmp(_next->s + 2, "fo", 2)) {
103 *_method = METH_INFO;
109 if ((_next->len > 5) && !strncasecmp(_next->s + 2, "vite", 4)) {
110 *_method = METH_INVITE;
120 if ((_next->len > 6) && !strncasecmp(_next->s + 1, "essage", 6)) {
121 *_method = METH_MESSAGE;
131 if ((_next->len > 5) && !strncasecmp(_next->s + 1, "otify", 5)) {
132 *_method = METH_NOTIFY;
142 if ((_next->len > 6) && !strncasecmp(_next->s + 1, "ptions", 6)) {
143 *_method = METH_OPTIONS;
153 if ((_next->len > 4) && !strncasecmp(_next->s + 1, "rack", 4)) {
154 *_method = METH_PRACK;
164 if ((_next->len > 4) &&
165 ((*(_next->s + 1) == 'E') || (*(_next->s + 1) == 'e'))) {
166 if (!strncasecmp(_next->s + 2, "fer", 3)) {
167 *_method = METH_REFER;
173 if ((_next->len > 7) && !strncasecmp(_next->s + 2, "gister", 6)) {
174 *_method = METH_REGISTER;
184 if ((_next->len > 8) && !strncasecmp(_next->s + 1, "ubscribe", 8)) {
185 *_method = METH_SUBSCRIBE;
195 if ((_next->len > 5) && !strncasecmp(_next->s + 1, "pdate", 5)) {
196 *_method = METH_UPDATE;
209 if (token_char(*(_next->s))) {
213 } while (_next->len && token_char(*(_next->s)));
214 *_method = METH_UNKNOWN;
223 * Parse comma separated list of methods pointed by _body and assign their
224 * enum bits to _methods. Returns 1 on success and 0 on failure.
226 int parse_methods(str* _body, unsigned int* _methods)
231 method=0; /* fixes silly gcc 4.x warning */
233 if (!_body || !_methods) {
234 LOG(L_ERR, "parse_methods: Invalid parameter value\n");
238 next.len = _body->len;
244 LOG(L_ERR, "ERROR: parse_methods: Empty body\n");
251 if (parse_method(&next, &method)) {
254 LOG(L_ERR, "ERROR: parse_methods: Invalid method\n");
260 if (next.s[0] == ',') {
265 LOG(L_ERR, "ERROR: parse_methods: Method expected\n");
269 LOG(L_ERR, "ERROR: parse_methods: Comma expected\n");