/src/kamailio/src/core/parser/parse_event.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Event header field body parser. |
3 | | * |
4 | | * Copyright (C) 2001-2003 FhG Fokus |
5 | | * |
6 | | * This file is part of Kamailio, a free SIP server. |
7 | | * |
8 | | * Kamailio 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 |
12 | | * |
13 | | * Kamailio is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | * |
22 | | */ |
23 | | |
24 | | /*! \file |
25 | | * \brief Parser :: Event header field body parser. |
26 | | * |
27 | | * The parser was written for Presence Agent module only. |
28 | | * it recognize presence package only, no sub-packages, no parameters |
29 | | * It should be replaced by a more generic parser if sub-packages or |
30 | | * parameters should be parsed too. |
31 | | * |
32 | | * \ingroup parser |
33 | | */ |
34 | | |
35 | | |
36 | | #include "parse_event.h" |
37 | | #include "../mem/mem.h" /* pkg_malloc, pkg_free */ |
38 | | #include "../dprint.h" |
39 | | #include <string.h> /* memset */ |
40 | | #include "../trim.h" /* trim_leading */ |
41 | | #include <stdio.h> /* printf */ |
42 | | #include "../ut.h" |
43 | | |
44 | | static struct |
45 | | { |
46 | | str name; |
47 | | int type; |
48 | | } events[] = {{STR_STATIC_INIT("presence"), EVENT_PRESENCE}, |
49 | | {STR_STATIC_INIT("presence.winfo"), EVENT_PRESENCE_WINFO}, |
50 | | {STR_STATIC_INIT("xcap-change"), EVENT_XCAP_CHANGE}, |
51 | | {STR_STATIC_INIT("sip-profile"), EVENT_SIP_PROFILE}, |
52 | | {STR_STATIC_INIT("message-summary"), EVENT_MESSAGE_SUMMARY}, |
53 | | {STR_STATIC_INIT("dialog"), EVENT_DIALOG}, |
54 | | {STR_STATIC_INIT("ua-profile"), EVENT_UA_PROFILE}, |
55 | | /* The following must be the last element in the array */ |
56 | | {STR_NULL, EVENT_OTHER}}; |
57 | | |
58 | | |
59 | | static inline char *skip_token(char *_b, int _l) |
60 | 0 | { |
61 | 0 | int i = 0; |
62 | |
|
63 | 0 | for(i = 0; i < _l; i++) { |
64 | 0 | switch(_b[i]) { |
65 | 0 | case ' ': |
66 | 0 | case '\r': |
67 | 0 | case '\n': |
68 | 0 | case '\t': |
69 | 0 | case ';': |
70 | 0 | return _b + i; |
71 | 0 | } |
72 | 0 | } |
73 | | |
74 | 0 | return _b + _l; |
75 | 0 | } |
76 | | |
77 | | |
78 | | int event_parser(char *s, int len, event_t *e) |
79 | 0 | { |
80 | 0 | int i; |
81 | 0 | str tmp; |
82 | 0 | char *end; |
83 | 0 | param_hooks_t *phooks = NULL; |
84 | 0 | enum pclass pclass = CLASS_ANY; |
85 | |
|
86 | 0 | if(e == NULL) { |
87 | 0 | LM_ERR("Invalid parameter value\n"); |
88 | 0 | return -1; |
89 | 0 | } |
90 | | |
91 | 0 | tmp.s = s; |
92 | 0 | tmp.len = len; |
93 | 0 | trim_leading(&tmp); |
94 | |
|
95 | 0 | if(tmp.len == 0) { |
96 | 0 | LM_ERR("Empty body\n"); |
97 | 0 | return -1; |
98 | 0 | } |
99 | | |
100 | 0 | e->name.s = tmp.s; |
101 | 0 | end = skip_token(tmp.s, tmp.len); |
102 | 0 | e->name.len = end - tmp.s; |
103 | |
|
104 | 0 | e->type = EVENT_OTHER; |
105 | 0 | for(i = 0; events[i].name.len; i++) { |
106 | 0 | if(e->name.len == events[i].name.len |
107 | 0 | && !strncasecmp(e->name.s, events[i].name.s, e->name.len)) { |
108 | 0 | e->type = events[i].type; |
109 | 0 | break; |
110 | 0 | } |
111 | 0 | } |
112 | |
|
113 | 0 | tmp.len -= end - tmp.s; |
114 | 0 | tmp.s = end; |
115 | 0 | trim_leading(&tmp); |
116 | |
|
117 | 0 | e->params.list = NULL; |
118 | |
|
119 | 0 | if(tmp.len && (tmp.s[0] == ';')) { |
120 | | /* Shift the semicolon and skip any leading whitespace, this is needed |
121 | | * for parse_params to work correctly. */ |
122 | 0 | tmp.s++; |
123 | 0 | tmp.len--; |
124 | 0 | trim_leading(&tmp); |
125 | 0 | if(!tmp.len) |
126 | 0 | return 0; |
127 | | |
128 | | /* We have parameters to parse */ |
129 | 0 | if(e->type == EVENT_DIALOG) { |
130 | 0 | pclass = CLASS_EVENT_DIALOG; |
131 | 0 | phooks = (param_hooks_t *)&e->params.hooks; |
132 | 0 | } |
133 | |
|
134 | 0 | if(parse_params(&tmp, pclass, phooks, &e->params.list) < 0) { |
135 | 0 | LM_ERR("Error while parsing parameters parameters\n"); |
136 | 0 | return -1; |
137 | 0 | } |
138 | 0 | } |
139 | 0 | return 0; |
140 | 0 | } |
141 | | |
142 | | |
143 | | /*! \brief |
144 | | * Parse Event header field body |
145 | | */ |
146 | | int parse_event(struct hdr_field *_h) |
147 | 0 | { |
148 | 0 | event_t *e; |
149 | |
|
150 | 0 | if(_h->parsed != 0) { |
151 | 0 | return 0; |
152 | 0 | } |
153 | | |
154 | 0 | e = (event_t *)pkg_malloc(sizeof(event_t)); |
155 | 0 | if(e == 0) { |
156 | 0 | PKG_MEM_ERROR; |
157 | 0 | return -1; |
158 | 0 | } |
159 | | |
160 | 0 | memset(e, 0, sizeof(event_t)); |
161 | |
|
162 | 0 | if(event_parser(_h->body.s, _h->body.len, e) < 0) { |
163 | 0 | LM_ERR("Error in event_parser\n"); |
164 | 0 | pkg_free(e); |
165 | 0 | return -2; |
166 | 0 | } |
167 | | |
168 | 0 | _h->parsed = (void *)e; |
169 | 0 | return 0; |
170 | 0 | } |
171 | | |
172 | | |
173 | | /*! \brief |
174 | | * Free all memory |
175 | | */ |
176 | | void free_event(event_t **_e) |
177 | 0 | { |
178 | 0 | if(*_e) { |
179 | 0 | if((*_e)->params.list) |
180 | 0 | free_params((*_e)->params.list); |
181 | 0 | pkg_free(*_e); |
182 | 0 | *_e = NULL; |
183 | 0 | } |
184 | 0 | } |
185 | | |
186 | | |
187 | | /*! \brief |
188 | | * Print structure, for debugging only |
189 | | */ |
190 | | void print_event(event_t *e) |
191 | 0 | { |
192 | 0 | fprintf(stderr, "===Event===\n"); |
193 | 0 | fprintf(stderr, "name : \'%.*s\'\n", STR_FMT(&e->name)); |
194 | 0 | fprintf(stderr, "type: %d\n", e->type); |
195 | 0 | if(e->params.list) { |
196 | 0 | print_params(stderr, e->params.list); |
197 | 0 | } |
198 | 0 | fprintf(stderr, "===/Event===\n"); |
199 | 0 | } |