abf1a7127004db2ba131a02fd5f5baaa7ded043b
[sip-router] / modules_k / presence / event_list.c
1 /*
2  * $Id: presence.c 1953 2007-04-04 08:50:33Z anca_vamanu $
3  *
4  * presence module - presence server implementation
5  *
6  * Copyright (C) 2006 Voice Sistem S.R.L.
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License 
21  * along with this program; if not, write to the Free Software 
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * History:
25  * --------
26  *  2007-04-04  initial version (anca)
27  */
28
29 /*! \file
30  * \brief Kamailio presence module
31  * \ref event_list.h
32  * \ingroup presence 
33  */
34
35
36 #include <stdlib.h>
37 #include<stdio.h>
38 #include <string.h>
39 #include "../../str.h"
40 #include "../../dprint.h"
41 #include "../../parser/parse_event.h" 
42 #include "../../mem/shm_mem.h" 
43 #include "../../mem/mem.h" 
44 #include "event_list.h"
45 #include "hash.h"
46
47 #define MAX_EVNAME_SIZE 20
48
49 int search_event_params(event_t* ev, event_t* searched_ev);
50
51 event_t* shm_copy_event(event_t* e)
52 {
53         event_t* ev= NULL;
54         param_t* p1, *p2;
55         int size;
56
57         ev= (event_t*)shm_malloc(sizeof(event_t));
58         if(ev== NULL)
59         {
60                 ERR_MEM(SHARE_MEM);
61         }
62         memset(ev, 0, sizeof(event_t));
63
64         ev->text.s= (char*)shm_malloc(e->text.len* sizeof(char));
65         if(ev->text.s== NULL)
66         {
67                 ERR_MEM(SHARE_MEM);
68         }
69         memcpy(ev->text.s, e->text.s, e->text.len);
70         ev->text.len= e->text.len;
71
72         p1= e->params;
73         while(p1)
74         {
75                 size= sizeof(param_t)+ (p1->name.len+ p1->body.len)* sizeof(char);
76                 p2= (param_t*)shm_malloc(size);
77                 if(p2== NULL)
78                 {
79                         ERR_MEM(SHARE_MEM);
80                 }
81                 memset(p2, 0, size);
82
83                 size= sizeof(param_t);
84                 CONT_COPY(p2, p2->name, p1->name);
85                 if(p1->body.s && p1->body.len)
86                         CONT_COPY(p2, p2->body, p1->body);
87                 p2->next= ev->params;
88                 ev->params= p2;
89                 p1= p1->next;
90         }
91         ev->parsed= e->parsed;
92
93         return ev;
94
95 error:
96         shm_free_event(ev);
97         return NULL;
98 }
99
100 void shm_free_event(event_t* ev)
101 {
102         if(ev== NULL)
103                 return;
104         
105         if(ev->text.s)
106                 shm_free(ev->text.s);
107
108         free_event_params(ev->params, SHM_MEM_TYPE);
109
110         shm_free(ev);
111 }
112
113
114 int add_event(pres_ev_t* event)
115 {
116         pres_ev_t* ev= NULL;
117         event_t parsed_event;
118         str wipeer_name;
119         char* sep;
120         char buf[50];
121         int not_in_list= 0;
122
123         memset(&parsed_event, 0, sizeof(event_t));
124
125         if(event->name.s== NULL || event->name.len== 0)
126         {
127                 LM_ERR("NULL event name\n");
128                 return -1;
129         }
130
131         if(event->content_type.s== NULL || event->content_type.len== 0)
132         {
133                 LM_ERR("NULL content_type param\n");
134                 return -1;
135         }
136         
137         ev= contains_event(&event->name, &parsed_event);
138         if(ev== NULL)
139         {
140                 not_in_list= 1;
141                 ev= (pres_ev_t*)shm_malloc(sizeof(pres_ev_t));
142                 if(ev== NULL)
143                 {
144                         free_event_params(parsed_event.params, PKG_MEM_TYPE);
145                         ERR_MEM(SHARE_MEM);
146                 }
147                 memset(ev, 0, sizeof(pres_ev_t));
148                 ev->name.s= (char*)shm_malloc(event->name.len* sizeof(char));
149                 if(ev->name.s== NULL)
150                 {
151                         free_event_params(parsed_event.params, PKG_MEM_TYPE);
152                         ERR_MEM(SHARE_MEM);
153                 }
154                 memcpy(ev->name.s, event->name.s, event->name.len);
155                 ev->name.len= event->name.len;
156
157                 ev->evp= shm_copy_event(&parsed_event);
158                 if(ev->evp== NULL)
159                 {
160                         LM_ERR("copying event_t structure\n");
161                         free_event_params(parsed_event.params, PKG_MEM_TYPE);
162                         goto error;
163                 }
164                 free_event_params(parsed_event.params, PKG_MEM_TYPE);
165         }
166         else
167         {
168                 free_event_params(parsed_event.params, PKG_MEM_TYPE);
169                 if(ev->content_type.s)
170                 {
171                         LM_DBG("Event already registered\n");
172                         return 0;
173                 }
174         }
175
176         ev->content_type.s=(char*)shm_malloc(event->content_type.len* sizeof(char)) ;
177         if(ev->content_type.s== NULL)
178         {
179                 ERR_MEM(SHARE_MEM);
180         }       
181         ev->content_type.len= event->content_type.len;
182         memcpy(ev->content_type.s, event->content_type.s, event->content_type.len);
183
184         sep= strchr(event->name.s, '.');
185         if(sep && strncmp(sep+1, "winfo", 5)== 0)
186         {       
187                 ev->type= WINFO_TYPE;
188                 wipeer_name.s= event->name.s;
189                 wipeer_name.len= sep - event->name.s;
190                 ev->wipeer= contains_event(&wipeer_name, NULL);
191                 if (ev->wipeer) {
192                         LM_DBG("Found wipeer event [%.*s] for event [%.*s]\n",wipeer_name.len,wipeer_name.s,event->name.len,event->name.s);
193                 }
194         }
195         else
196         {       
197                 ev->type= PUBL_TYPE;
198                 if (event->name.len + 6 > 50) {
199                         LM_ERR("buffer too small\n");
200                         goto error;
201                 }
202                 wipeer_name.s= buf;
203                 memcpy(wipeer_name.s, event->name.s, event->name.len);
204                 wipeer_name.len= event->name.len;
205                 memcpy(wipeer_name.s+ wipeer_name.len, ".winfo", 6);
206                 wipeer_name.len+= 6;
207                 ev->wipeer= contains_event(&wipeer_name, NULL);
208                 if (ev->wipeer) {
209                         LM_DBG("Found wipeer event [%.*s] for event [%.*s]\n",wipeer_name.len,wipeer_name.s,event->name.len,event->name.s);
210                 }
211         }
212         
213         if(ev->wipeer)  
214                 ev->wipeer->wipeer= ev;
215
216         if(event->req_auth && 
217                 ( event->get_auth_status==0 ||event->get_rules_doc== 0))
218         {
219                 LM_ERR("bad event structure\n");
220                 goto error;
221         }
222         ev->req_auth= event->req_auth;
223         ev->agg_nbody= event->agg_nbody;
224         ev->apply_auth_nbody= event->apply_auth_nbody;
225         ev->get_auth_status= event->get_auth_status;
226         ev->get_rules_doc= event->get_rules_doc;
227         ev->evs_publ_handl= event->evs_publ_handl;
228         ev->etag_not_new= event->etag_not_new;
229         ev->aux_body_processing= event->aux_body_processing;
230         ev->aux_free_body= event->aux_free_body;
231         ev->free_body= event->free_body;
232         ev->default_expires= event->default_expires;
233
234         if(not_in_list)
235         {
236                 ev->next= EvList->events;
237                 EvList->events= ev;
238         }
239         EvList->ev_count++;
240         
241         LM_DBG("succesfully added event: %.*s - len= %d\n",ev->name.len,
242                         ev->name.s, ev->name.len);
243         return 0;
244 error:
245         if(ev && not_in_list)
246         {
247                 free_pres_event(ev);    
248         }
249         return -1;
250 }
251
252 void free_pres_event(pres_ev_t* ev)
253 {
254         if(ev== NULL)
255                 return;
256
257         if(ev->name.s)
258                 shm_free(ev->name.s);
259         if(ev->content_type.s)
260                 shm_free(ev->content_type.s);
261         if(ev->wipeer)
262                 ev->wipeer->wipeer = 0;
263         shm_free_event(ev->evp);
264         shm_free(ev);
265
266 }
267
268 evlist_t* init_evlist(void)
269 {
270         evlist_t*  list= NULL;
271
272         list= (evlist_t*)shm_malloc(sizeof(evlist_t));
273         if(list== NULL)
274         {
275                 LM_ERR("no more share memory\n");
276                 return NULL;
277         }
278         list->ev_count= 0;
279         list->events= NULL;
280         
281         return list;
282 }       
283
284 pres_ev_t* contains_event(str* sname, event_t* parsed_event)
285 {
286         event_t event;
287         pres_ev_t* e;
288         
289         memset(&event, 0, sizeof(event_t));
290         if(event_parser(sname->s, sname->len, &event)< 0)
291         {
292                 LM_ERR("parsing event\n");
293                 return NULL;
294         }
295         if(parsed_event)
296                 *parsed_event= event;
297         else
298         {
299                 free_event_params(event.params, PKG_MEM_TYPE);
300         }
301         e= search_event(&event);
302
303         return e;
304 }
305
306 void free_event_params(param_t* params, int mem_type)
307 {
308         param_t* t1, *t2;
309         t2= t1= params;
310
311         while(t1)
312         {
313                 t2= t1->next;
314                 if(mem_type == SHM_MEM_TYPE)
315                         shm_free(t1);
316                 else
317                         pkg_free(t1);
318                 t1= t2;
319         }
320         
321 }
322
323 pres_ev_t* search_event(event_t* event)
324 {
325         pres_ev_t* pres_ev;
326         pres_ev= EvList->events;
327
328         LM_DBG("start event= [%.*s]\n", event->text.len, event->text.s);
329
330         while(pres_ev)
331         {
332                 if(pres_ev->evp->parsed== event->parsed)
333                 {
334                         if(event->params== NULL && pres_ev->evp->params== NULL)
335                         {
336                                 return pres_ev;
337                         }
338         
339                         /* search all parameters in event in ev */
340                         if(search_event_params(event, pres_ev->evp)< 0)
341                                 goto cont;
342                         
343                         /* search all parameters in ev in event */
344                         if(search_event_params(pres_ev->evp, event)< 0)
345                                 goto cont;
346
347                         return pres_ev;
348                 }
349 cont:           pres_ev= pres_ev->next;
350         }
351         return NULL;
352
353 }
354
355 int search_event_params(event_t* ev, event_t* searched_ev)
356 {
357         param_t* ps, *p;
358         int found;
359
360         ps= ev->params;
361
362         while(ps)
363         {
364                 p= searched_ev->params;
365                 found= 0;
366         
367                 while(p)
368                 {
369                         if(p->name.len== ps->name.len && 
370                                 strncmp(p->name.s,ps->name.s, ps->name.len)== 0)
371                                 if((p->body.s== 0 && ps->body.s== 0) ||
372                                         (p->body.len== ps->body.len && 
373                                         strncmp(p->body.s,ps->body.s,ps->body.len)== 0))
374                                 {
375                                         found= 1;
376                                         break;
377                                 }
378                                 p= p->next;
379                 }
380                 if(found== 0)
381                         return -1;
382                 ps= ps->next;
383         }
384
385         return 1;
386
387 }
388 int get_event_list(str** ev_list)
389 {       
390         pres_ev_t* ev= EvList->events;
391         int i;
392         str* list;
393         *ev_list= NULL;
394         
395         if(EvList->ev_count== 0)
396                 return 0;
397         
398         list= (str*)pkg_malloc(sizeof(str));
399         if(list== NULL)
400         {
401                 LM_ERR("No more memory\n");
402                 return -1;
403         }
404         memset(list, 0, sizeof(str));
405         list->s= (char*)pkg_malloc(EvList->ev_count* MAX_EVNAME_SIZE);
406         if(list->s== NULL)
407         {
408                 LM_ERR("No more memory\n");
409                 pkg_free(list);
410                 return -1;
411         }
412         list->s[0]= '\0';
413         
414         for(i= 0; i< EvList->ev_count; i++)
415         {
416                 if(i> 0)
417                 {
418                         memcpy(list->s+ list->len, ", ", 2);
419                         list->len+= 2;
420                 }       
421                 memcpy(list->s+ list->len, ev->name.s, ev->name.len );
422                 list->len+= ev->name.len ;
423                 ev= ev->next;
424         }
425         
426         *ev_list= list;
427         return 0;
428 }
429
430 void destroy_evlist(void)
431 {
432     pres_ev_t* e1, *e2;
433     if (EvList) 
434         {
435                 e1= EvList->events;
436                 while(e1)
437             {
438                         e2= e1->next;
439                         free_pres_event(e1);
440                         e1= e2;
441             }   
442                 shm_free(EvList);
443     }
444 }
445