Coverage Report

Created: 2024-02-25 06:34

/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
}