/src/opensips/data_lump_rpl.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2001-2003 FhG Fokus |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | * History: |
21 | | * -------- |
22 | | * 2002-02-14 : created by bogdan |
23 | | * 2003-09-11 : lump_rpl type added - LUMP_RPL_BODY & LUMP_RPL_HDR (bogdan) |
24 | | * 2003-11-11 : build_lump_rpl merged into add_lump_rpl; types -> flags ; |
25 | | * flags LUMP_RPL_NODUP and LUMP_RPL_NOFREE added (bogdan) |
26 | | */ |
27 | | |
28 | | /*! |
29 | | * \file |
30 | | * \brief OpenSIPS Generic lump functions for replies |
31 | | */ |
32 | | |
33 | | |
34 | | #include <string.h> |
35 | | #include "dprint.h" |
36 | | #include "mem/mem.h" |
37 | | #include "data_lump_rpl.h" |
38 | | |
39 | | |
40 | | |
41 | | struct lump_rpl* add_lump_rpl(struct sip_msg *msg, char *s, int len, int flags) |
42 | 0 | { |
43 | 0 | struct lump_rpl *lump = 0; |
44 | 0 | struct lump_rpl *foo; |
45 | | |
46 | | /* some checking */ |
47 | 0 | if ( (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==(LUMP_RPL_HDR|LUMP_RPL_BODY) |
48 | 0 | || (flags&(LUMP_RPL_HDR|LUMP_RPL_BODY))==0 || (flags&LUMP_RPL_SHMEM) ) { |
49 | 0 | LM_ERR("bad flags combination (%d)!\n",flags); |
50 | 0 | goto error; |
51 | 0 | } |
52 | 0 | if (len<=0 || s==0) { |
53 | 0 | LM_ERR("I won't add an empty lump!\n"); |
54 | 0 | goto error; |
55 | 0 | } |
56 | | |
57 | | /* build the lump */ |
58 | 0 | lump = (struct lump_rpl*) pkg_malloc |
59 | 0 | ( sizeof(struct lump_rpl) + ((flags&LUMP_RPL_NODUP)?0:len) ); |
60 | 0 | if (!lump) { |
61 | 0 | LM_ERR("no free pkg memory !\n"); |
62 | 0 | goto error; |
63 | 0 | } |
64 | | |
65 | 0 | if (flags&LUMP_RPL_NODUP) { |
66 | 0 | lump->text.s = s; |
67 | 0 | } else { |
68 | 0 | lump->text.s = ((char*)lump)+sizeof(struct lump_rpl); |
69 | 0 | memcpy( lump->text.s, s, len); |
70 | 0 | } |
71 | 0 | lump->text.len = len; |
72 | 0 | lump->flags = flags; |
73 | 0 | lump->next = 0; |
74 | | |
75 | | /* add the lump to the msg */ |
76 | 0 | if (!msg->reply_lump) { |
77 | 0 | msg->reply_lump = lump; |
78 | 0 | }else{ |
79 | 0 | if (!(flags&LUMP_RPL_BODY)) |
80 | 0 | for(foo=msg->reply_lump;foo->next;foo=foo->next); |
81 | 0 | else |
82 | 0 | for(foo=msg->reply_lump; ;foo=foo->next) { |
83 | 0 | if (foo->flags&LUMP_RPL_BODY) { |
84 | 0 | LM_ERR("LUMP_RPL_BODY already added!\n"); |
85 | 0 | pkg_free(lump); |
86 | 0 | goto error; |
87 | 0 | } |
88 | 0 | if (foo->next==0) |
89 | 0 | break; |
90 | 0 | } |
91 | 0 | foo->next = lump; |
92 | 0 | } |
93 | | |
94 | 0 | return lump; |
95 | 0 | error: |
96 | 0 | return 0; |
97 | 0 | } |
98 | | |
99 | | |
100 | | |
101 | | void free_lump_rpl(struct lump_rpl* lump) |
102 | 0 | { |
103 | 0 | if (lump) { |
104 | 0 | if (!((lump->flags)&LUMP_RPL_NOFREE) && ((lump->flags)&LUMP_RPL_NODUP) |
105 | 0 | && lump->text.s) |
106 | 0 | pkg_free(lump->text.s); |
107 | 0 | pkg_free(lump); |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | |
112 | | struct lump_rpl* get_lump_rpl(struct sip_msg *msg, int flags) |
113 | 0 | { |
114 | 0 | struct lump_rpl *lump; |
115 | |
|
116 | 0 | for (lump = msg->reply_lump; lump; lump = lump->next) { |
117 | 0 | if (lump->flags & flags) |
118 | 0 | return lump; |
119 | 0 | } |
120 | 0 | return NULL; |
121 | 0 | } |
122 | | |
123 | | |
124 | | int replace_lump_rpl(struct lump_rpl *lump, char *s, int len, int flags) |
125 | 0 | { |
126 | 0 | if ((flags & LUMP_RPL_NODUP) == 0) { |
127 | 0 | LM_ERR("replacing lump should have its own buffer\n"); |
128 | 0 | return -1; |
129 | 0 | } |
130 | 0 | if (!((lump->flags)&LUMP_RPL_NOFREE) && ((lump->flags)&LUMP_RPL_NODUP) |
131 | 0 | && lump->text.s) |
132 | 0 | pkg_free(lump->text.s); |
133 | 0 | lump->flags |= flags; |
134 | 0 | lump->text.s = s; |
135 | 0 | lump->text.len = len; |
136 | 0 | return 0; |
137 | 0 | } |
138 | | |
139 | | |
140 | | void unlink_lump_rpl(struct sip_msg * msg, struct lump_rpl* lump) |
141 | 0 | { |
142 | 0 | struct lump_rpl *foo,*prev; |
143 | | |
144 | | /* look for the lump to be unlink */ |
145 | 0 | foo = msg->reply_lump; |
146 | 0 | prev = 0; |
147 | 0 | while( foo && foo!=lump ) { |
148 | 0 | prev = foo; |
149 | 0 | foo = foo->next; |
150 | 0 | } |
151 | | |
152 | | /* if the lump was found into the list -> unlink it */ |
153 | 0 | if (foo) { |
154 | 0 | if (prev) |
155 | 0 | prev->next = foo->next; |
156 | 0 | else |
157 | 0 | msg->reply_lump = foo->next; |
158 | 0 | } |
159 | 0 | } |
160 | | |
161 | | |
162 | | void del_nonshm_lump_rpl(struct lump_rpl** list) |
163 | 0 | { |
164 | 0 | struct lump_rpl* it, *tmp; |
165 | 0 | struct lump_rpl** pred; |
166 | |
|
167 | 0 | it = *list; |
168 | 0 | pred = list; |
169 | |
|
170 | 0 | while(it) { |
171 | 0 | if (!(it->flags & LUMP_RPL_SHMEM)) { |
172 | 0 | tmp = it; |
173 | 0 | *pred = it->next; |
174 | 0 | it = it->next; |
175 | 0 | free_lump_rpl(tmp); |
176 | 0 | continue; |
177 | 0 | } |
178 | | |
179 | 0 | pred = &it->next; |
180 | 0 | it = it->next; |
181 | 0 | } |
182 | 0 | } |
183 | | |