643a5f197c6e87e6440b6445a177c99cdbab1e80
[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  */
34
35
36 #include <string.h>
37 #include "dprint.h"
38 #include "mem/mem.h"
39 #include "data_lump_rpl.h"
40
41
42
43 struct lump_rpl* add_lump_rpl(struct sip_msg *msg, char *s, int len, int flags)
44 {
45         struct lump_rpl *lump = 0;
46         struct lump_rpl *foo;
47
48         /* some checkings */
49         if ( (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==(LUMP_RPL_HDR|LUMP_RPL_BODY)
50         || (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==0 || (flags&LUMP_RPL_SHMEM) ) {
51                 LOG(L_ERR,"ERROR:add_lump_rpl: bad flags combination (%d)!\n",flags);
52                 goto error;
53         }
54         if (len<=0 || s==0) {
55                 LOG(L_ERR,"ERROR:add_lump_rpl: I won't add an empty lump!\n");
56                 goto error;
57         }
58
59         /* build the lump */
60         lump = (struct lump_rpl*) pkg_malloc
61                 ( sizeof(struct lump_rpl) + ((flags&LUMP_RPL_NODUP)?0:len) );
62         if (!lump) {
63                 LOG(L_ERR,"ERROR:add_lump_rpl : no free pkg memory !\n");
64                 goto error;
65         }
66
67         if (flags&LUMP_RPL_NODUP) {
68                 lump->text.s = s;
69         } else {
70                 lump->text.s = ((char*)lump)+sizeof(struct lump_rpl);
71                 memcpy( lump->text.s, s, len);
72         }
73         lump->text.len = len;
74         lump->flags = flags;
75         lump->next = 0;
76
77         /* add the lump to the msg */
78         if (!msg->reply_lump) {
79                 msg->reply_lump = lump;
80         }else{
81                 if (!(flags&LUMP_RPL_BODY))
82                         for(foo=msg->reply_lump;foo->next;foo=foo->next);
83                 else
84                         for(foo=msg->reply_lump; ;foo=foo->next) {
85                                 if (foo->flags&LUMP_RPL_BODY) {
86                                         LOG(L_ERR,"ERROR:add_lump_rpl: LUMP_RPL_BODY "
87                                                 "already added!\n");
88                                         pkg_free(lump);
89                                         goto error;
90                                 }
91                                 if (foo->next==0)
92                                         break;
93                         }
94                 foo->next = lump;
95         }
96
97         return lump;
98 error:
99         return 0;
100 }
101
102
103
104 inline void free_lump_rpl(struct lump_rpl* lump)
105 {
106         if (lump) {
107                 if (!((lump->flags)&LUMP_RPL_NOFREE) && ((lump->flags)&LUMP_RPL_NODUP)
108                 && lump->text.s)
109                         pkg_free(lump->text.s);
110                 pkg_free(lump);
111         }
112 }
113
114
115 void unlink_lump_rpl(struct sip_msg * msg, struct lump_rpl* lump)
116 {
117         struct lump_rpl *foo,*prev;
118
119         /* look for the lump to be unlink */
120         foo = msg->reply_lump;
121         prev = 0;
122         while( foo && foo!=lump ) {
123                 prev = foo;
124                 foo = foo->next;
125         }
126
127         /* if the lump was found into the list -> unlink it */
128         if (foo) {
129                 if (prev)
130                         prev->next = foo->next;
131                 else
132                         msg->reply_lump = foo->next;
133         }
134 }
135
136
137
138 void del_nonshm_lump_rpl( struct lump_rpl **head_list)
139 {
140         struct lump_rpl *foo;
141
142         while( (*head_list) && (((*head_list)->flags&LUMP_RPL_SHMEM)==0) ) {
143                 foo = (*head_list);
144                 (*head_list) = foo->next;
145                 free_lump_rpl( foo );
146         }
147 }
148
149