db_sqlite: rename database scheme files, to allow automatic updates
[sip-router] / data_lump_rpl.c
1 /*
2  * $Id$
3  *
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of ser, a free SIP server.
8  *
9  * ser is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * For a license to use the ser software under conditions
15  * other than those described here, or to purchase support for this
16  * software, please contact iptel.org by e-mail at the following addresses:
17  *    info@iptel.org
18  *
19  * ser is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License 
25  * along with this program; if not, write to the Free Software 
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28  * History:
29  * 2002-02-14 : created by bogdan
30  * 2003-09-11 : lump_rpl type added - LUMP_RPL_BODY & LUMP_RPL_HDR (bogdan)
31  * 2003-11-11 : build_lump_rpl merged into add_lump_rpl; types -> flags ;
32  *              flags LUMP_RPL_NODUP and LUMP_RPL_NOFREE added (bogdan)
33  * 2006-10-16   add_lump_rpl2 added: same as the old add_lump_rpl, but
34  *               returns a lump_rpl**, making a specific lump removal much
35  *               more easy (andrei)
36  */
37 /*!
38  * \file
39  * \brief SIP-router core :: 
40  * \ingroup core
41  * Module: \ref core
42  */
43
44
45
46 #include <string.h>
47 #include "dprint.h"
48 #include "mem/mem.h"
49 #include "data_lump_rpl.h"
50
51
52
53 struct lump_rpl** add_lump_rpl2(struct sip_msg *msg, char *s, 
54                                                                         int len, int flags)
55 {
56         struct lump_rpl *lump = 0;
57         struct lump_rpl *foo;
58         struct lump_rpl** ret;
59
60         /* some checking */
61         if ( (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==(LUMP_RPL_HDR|LUMP_RPL_BODY)
62         || (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==0 || (flags&LUMP_RPL_SHMEM) ) {
63                 LOG(L_ERR,"ERROR:add_lump_rpl: bad flags combination (%d)!\n",flags);
64                 goto error;
65         }
66         if (len<=0 || s==0) {
67                 LOG(L_ERR,"ERROR:add_lump_rpl: I won't add an empty lump!\n");
68                 goto error;
69         }
70
71         /* build the lump */
72         lump = (struct lump_rpl*) pkg_malloc
73                 ( sizeof(struct lump_rpl) + ((flags&LUMP_RPL_NODUP)?0:len) );
74         if (!lump) {
75                 LOG(L_ERR,"ERROR:add_lump_rpl : no free pkg memory !\n");
76                 goto error;
77         }
78
79         if (flags&LUMP_RPL_NODUP) {
80                 lump->text.s = s;
81         } else {
82                 lump->text.s = ((char*)lump)+sizeof(struct lump_rpl);
83                 memcpy( lump->text.s, s, len);
84         }
85         lump->text.len = len;
86         lump->flags = flags;
87         lump->next = 0;
88
89         /* add the lump to the msg */
90         if (!msg->reply_lump) {
91                 msg->reply_lump = lump;
92                 ret=&msg->reply_lump;
93         }else{
94                 if (!(flags&LUMP_RPL_BODY))
95                         for(foo=msg->reply_lump;foo->next;foo=foo->next);
96                 else
97                         for(foo=msg->reply_lump; ;foo=foo->next) {
98                                 if (foo->flags&LUMP_RPL_BODY) {
99                                         LOG(L_ERR,"ERROR:add_lump_rpl: LUMP_RPL_BODY "
100                                                 "already added!\n");
101                                         pkg_free(lump);
102                                         goto error;
103                                 }
104                                 if (foo->next==0)
105                                         break;
106                         }
107                 foo->next = lump;
108                 ret= &(foo->next);
109         }
110
111         return ret;
112 error:
113         return 0;
114 }
115
116
117
118 void free_lump_rpl(struct lump_rpl* lump)
119 {
120         if (lump) {
121                 if (!((lump->flags)&LUMP_RPL_NOFREE) && ((lump->flags)&LUMP_RPL_NODUP)
122                 && lump->text.s)
123                         pkg_free(lump->text.s);
124                 pkg_free(lump);
125         }
126 }
127
128
129 void unlink_lump_rpl(struct sip_msg * msg, struct lump_rpl* lump)
130 {
131         struct lump_rpl *foo,*prev;
132
133         /* look for the lump to be unlink */
134         foo = msg->reply_lump;
135         prev = 0;
136         while( foo && foo!=lump ) {
137                 prev = foo;
138                 foo = foo->next;
139         }
140
141         /* if the lump was found into the list -> unlink it */
142         if (foo) {
143                 if (prev)
144                         prev->next = foo->next;
145                 else
146                         msg->reply_lump = foo->next;
147         }
148 }
149
150 void del_nonshm_lump_rpl(struct lump_rpl** list)
151 {
152         struct lump_rpl* it, *tmp;
153         struct lump_rpl** pred;
154
155         it = *list;
156         pred = list;
157
158         while(it) {
159                 if (!(it->flags & LUMP_RPL_SHMEM)) {
160                         tmp = it;
161                         *pred = it->next;
162                         it = it->next;
163                         free_lump_rpl(tmp);
164                         continue;
165                 }
166
167                 pred = &it->next;
168                 it = it->next;
169         }
170 }
171