/src/opensips/data_lump.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2010-2014 OpenSIPS Solutions |
3 | | * Copyright (C) 2001-2003 FhG Fokus |
4 | | * |
5 | | * This file is part of opensips, a free SIP server. |
6 | | * |
7 | | * opensips is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version |
11 | | * |
12 | | * opensips is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | * |
21 | | * History: |
22 | | * -------- |
23 | | * 2003-01-19 support for duplication lump lists added (jiri) |
24 | | * 2003-03-31 added subst lumps --they expand in ip addr, port a.s.o (andrei) |
25 | | * 2003-04-01 added conditional lump support functions (andrei) |
26 | | * 2003-10-20 anchor_lump & del_lump will automatically choose the lump list |
27 | | * based on msg->eoh comparisons (andrei) |
28 | | * 2003-10-28 added extra checks (paranoia) for {anchor,del}_lump (andrei) |
29 | | * 2005-08-22 added init_lump_flags -initial flags- for all built lumps |
30 | | * (bogdan) |
31 | | * 2005-08-23 del_nonshm_lump() -> del_flaged_lumps(LUMPFLAG_SHMEM) (bogdan) |
32 | | */ |
33 | | |
34 | | /*! |
35 | | * \file data_lump.c |
36 | | * \brief OpenSIPS Lump (internal message manipulation) functions |
37 | | */ |
38 | | |
39 | | |
40 | | #include "data_lump.h" |
41 | | #include "dprint.h" |
42 | | #include "mem/mem.h" |
43 | | #include "globals.h" |
44 | | #include "error.h" |
45 | | |
46 | | #include <stdlib.h> |
47 | | #include <string.h> |
48 | | |
49 | | #ifdef DEBUG_DMALLOC |
50 | | #include <dmalloc.h> |
51 | | #endif |
52 | | |
53 | | /*! \note WARNING: all lump add/insert operations expect a pkg_malloc'ed char* |
54 | | * pointer the will be DEALLOCATED when the sip_msg is destroyed! */ |
55 | | |
56 | | enum lump_dir { LD_NEXT, LD_BEFORE, LD_AFTER }; |
57 | | |
58 | | int init_lump_flags = 0; |
59 | | |
60 | | /*! \brief adds a header to the end |
61 | | * \return returns pointer if success, 0 on error |
62 | | * |
63 | | * WARNING: currently broken! |
64 | | * - lumps_len() needs to properly handle LUMP_ADD along the main chain of |
65 | | * lumps before we can use this |
66 | | */ |
67 | | struct lump* append_new_lump(struct lump** list, char* new_hdr, |
68 | | unsigned int len, enum _hdr_types_t type) |
69 | 0 | { |
70 | 0 | struct lump** t; |
71 | 0 | struct lump* tmp; |
72 | |
|
73 | 0 | for (t=list;*t;t=&((*t)->next)); |
74 | |
|
75 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
76 | 0 | if (tmp==0){ |
77 | 0 | LM_ERR("out of pkg memory\n"); |
78 | 0 | return 0; |
79 | 0 | } |
80 | | |
81 | 0 | memset(tmp,0,sizeof(struct lump)); |
82 | 0 | tmp->type=type; |
83 | 0 | tmp->flags=init_lump_flags; |
84 | 0 | tmp->op=LUMP_ADD; |
85 | 0 | tmp->u.value=new_hdr; |
86 | 0 | tmp->len=len; |
87 | 0 | *t=tmp; |
88 | 0 | return tmp; |
89 | 0 | } |
90 | | |
91 | | |
92 | | |
93 | | /*! \brief inserts a header to the beginning |
94 | | * \return returns pointer if success, 0 on error |
95 | | * |
96 | | * WARNING: currently broken! |
97 | | * - lumps_len() needs to properly handle LUMP_ADD along the main chain of |
98 | | * lumps before we can use this |
99 | | */ |
100 | | struct lump* insert_new_lump(struct lump** list, char* new_hdr, |
101 | | unsigned int len, enum _hdr_types_t type) |
102 | 0 | { |
103 | 0 | struct lump* tmp; |
104 | |
|
105 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
106 | 0 | if (tmp==0){ |
107 | 0 | LM_ERR("out of pkg memory\n"); |
108 | 0 | return 0; |
109 | 0 | } |
110 | 0 | memset(tmp,0,sizeof(struct lump)); |
111 | 0 | tmp->next=*list; |
112 | 0 | tmp->type=type; |
113 | 0 | tmp->flags=init_lump_flags; |
114 | 0 | tmp->op=LUMP_ADD; |
115 | 0 | tmp->u.value=new_hdr; |
116 | 0 | tmp->len=len; |
117 | 0 | *list=tmp; |
118 | 0 | return tmp; |
119 | 0 | } |
120 | | |
121 | | |
122 | | |
123 | | /*! \brief inserts a header/data lump immediately after hdr |
124 | | * \return returns pointer on success, 0 on error */ |
125 | | struct lump* insert_new_lump_after( struct lump* after, char* new_hdr, |
126 | | unsigned int len, enum _hdr_types_t type) |
127 | 18.5k | { |
128 | 18.5k | struct lump* tmp; |
129 | | |
130 | 18.5k | tmp=pkg_malloc(sizeof(struct lump)); |
131 | 18.5k | if (tmp==0){ |
132 | 0 | ser_error=E_OUT_OF_MEM; |
133 | 0 | LM_ERR("out of pkg memory\n"); |
134 | 0 | return 0; |
135 | 0 | } |
136 | 18.5k | memset(tmp,0,sizeof(struct lump)); |
137 | 18.5k | tmp->after=after->after; |
138 | 18.5k | tmp->type=type; |
139 | 18.5k | tmp->flags=init_lump_flags; |
140 | 18.5k | tmp->op=LUMP_ADD; |
141 | 18.5k | tmp->u.value=new_hdr; |
142 | 18.5k | tmp->len=len; |
143 | 18.5k | after->after=tmp; |
144 | 18.5k | return tmp; |
145 | 18.5k | } |
146 | | |
147 | | |
148 | | |
149 | | /*! \brief inserts a header/data lump immediately before "before" |
150 | | * \return returns pointer on success, 0 on error */ |
151 | | struct lump* insert_new_lump_before( struct lump* before, char* new_hdr, |
152 | | unsigned int len, enum _hdr_types_t type) |
153 | 12.2k | { |
154 | 12.2k | struct lump* tmp; |
155 | | |
156 | 12.2k | tmp=pkg_malloc(sizeof(struct lump)); |
157 | 12.2k | if (tmp==0){ |
158 | 0 | ser_error=E_OUT_OF_MEM; |
159 | 0 | LM_ERR("out of pkg memory\n"); |
160 | 0 | return 0; |
161 | 0 | } |
162 | 12.2k | memset(tmp,0,sizeof(struct lump)); |
163 | 12.2k | tmp->before=before->before; |
164 | 12.2k | tmp->type=type; |
165 | 12.2k | tmp->flags=init_lump_flags; |
166 | 12.2k | tmp->op=LUMP_ADD; |
167 | 12.2k | tmp->u.value=new_hdr; |
168 | 12.2k | tmp->len=len; |
169 | 12.2k | before->before=tmp; |
170 | 12.2k | return tmp; |
171 | 12.2k | } |
172 | | |
173 | | |
174 | | |
175 | | /*! \brief inserts a subst lump immediately after hdr |
176 | | * \return returns pointer on success, 0 on error */ |
177 | | struct lump* insert_subst_lump_after( struct lump* after,enum lump_subst subst, |
178 | | enum _hdr_types_t type) |
179 | 0 | { |
180 | 0 | struct lump* tmp; |
181 | |
|
182 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
183 | 0 | if (tmp==0){ |
184 | 0 | ser_error=E_OUT_OF_MEM; |
185 | 0 | LM_ERR("out of pkg memory\n"); |
186 | 0 | return 0; |
187 | 0 | } |
188 | 0 | memset(tmp,0,sizeof(struct lump)); |
189 | 0 | tmp->after=after->after; |
190 | 0 | tmp->type=type; |
191 | 0 | tmp->flags=init_lump_flags; |
192 | 0 | tmp->op=LUMP_ADD_SUBST; |
193 | 0 | tmp->u.subst=subst; |
194 | 0 | tmp->len=0; |
195 | 0 | after->after=tmp; |
196 | 0 | return tmp; |
197 | 0 | } |
198 | | |
199 | | |
200 | | |
201 | | /*! \brief inserts a subst lump immediately before "before" |
202 | | * \return returns pointer on success, 0 on error */ |
203 | | struct lump* insert_subst_lump_before( struct lump* before, |
204 | | enum lump_subst subst, |
205 | | enum _hdr_types_t type) |
206 | 0 | { |
207 | 0 | struct lump* tmp; |
208 | |
|
209 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
210 | 0 | if (tmp==0){ |
211 | 0 | ser_error=E_OUT_OF_MEM; |
212 | 0 | LM_ERR("out of pkg memory\n"); |
213 | 0 | return 0; |
214 | 0 | } |
215 | 0 | memset(tmp,0,sizeof(struct lump)); |
216 | 0 | tmp->before=before->before; |
217 | 0 | tmp->type=type; |
218 | 0 | tmp->flags=init_lump_flags; |
219 | 0 | tmp->op=LUMP_ADD_SUBST; |
220 | 0 | tmp->u.subst=subst; |
221 | 0 | tmp->len=0; |
222 | 0 | before->before=tmp; |
223 | 0 | return tmp; |
224 | 0 | } |
225 | | |
226 | | |
227 | | |
228 | | /*! \brief inserts a cond lump immediately after hdr |
229 | | * \return returns pointer on success, 0 on error */ |
230 | | struct lump* insert_cond_lump_after( struct lump* after,enum lump_conditions c, |
231 | | enum _hdr_types_t type) |
232 | 0 | { |
233 | 0 | struct lump* tmp; |
234 | |
|
235 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
236 | 0 | if (tmp==0){ |
237 | 0 | ser_error=E_OUT_OF_MEM; |
238 | 0 | LM_ERR("out of pkg memory\n"); |
239 | 0 | return 0; |
240 | 0 | } |
241 | 0 | memset(tmp,0,sizeof(struct lump)); |
242 | 0 | tmp->after=after->after; |
243 | 0 | tmp->type=type; |
244 | 0 | tmp->flags=init_lump_flags; |
245 | 0 | tmp->op=LUMP_ADD_OPT; |
246 | 0 | tmp->u.cond=c; |
247 | 0 | tmp->len=0; |
248 | 0 | after->after=tmp; |
249 | 0 | return tmp; |
250 | 0 | } |
251 | | |
252 | | |
253 | | |
254 | | /*! \brief inserts a conditional lump immediately before "before" |
255 | | * \return returns pointer on success, 0 on error */ |
256 | | struct lump* insert_cond_lump_before( struct lump* before, |
257 | | enum lump_conditions c, |
258 | | enum _hdr_types_t type) |
259 | 0 | { |
260 | 0 | struct lump* tmp; |
261 | |
|
262 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
263 | 0 | if (tmp==0){ |
264 | 0 | ser_error=E_OUT_OF_MEM; |
265 | 0 | LM_ERR("out of pkg memory\n"); |
266 | 0 | return 0; |
267 | 0 | } |
268 | 0 | memset(tmp,0,sizeof(struct lump)); |
269 | 0 | tmp->before=before->before; |
270 | 0 | tmp->type=type; |
271 | 0 | tmp->flags=init_lump_flags; |
272 | 0 | tmp->op=LUMP_ADD_OPT; |
273 | 0 | tmp->u.cond=c; |
274 | 0 | tmp->len=0; |
275 | 0 | before->before=tmp; |
276 | 0 | return tmp; |
277 | 0 | } |
278 | | |
279 | | |
280 | | |
281 | | /*! \brief inserts a skip lump immediately after hdr |
282 | | * \return returns pointer on success, 0 on error */ |
283 | | struct lump* insert_skip_lump_after( struct lump* after) |
284 | 0 | { |
285 | 0 | struct lump* tmp; |
286 | |
|
287 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
288 | 0 | if (tmp==0){ |
289 | 0 | ser_error=E_OUT_OF_MEM; |
290 | 0 | LM_ERR("out of pkg memory\n"); |
291 | 0 | return 0; |
292 | 0 | } |
293 | 0 | memset(tmp,0,sizeof(struct lump)); |
294 | 0 | tmp->after=after->after; |
295 | 0 | tmp->flags=init_lump_flags; |
296 | 0 | tmp->op=LUMP_SKIP; |
297 | 0 | after->after=tmp; |
298 | 0 | return tmp; |
299 | 0 | } |
300 | | |
301 | | |
302 | | |
303 | | /*! \brief inserts a skip lump immediately before "before" |
304 | | * \return returns pointer on success, 0 on error */ |
305 | | struct lump* insert_skip_lump_before( struct lump* before ) |
306 | 0 | { |
307 | 0 | struct lump* tmp; |
308 | |
|
309 | 0 | tmp=pkg_malloc(sizeof(struct lump)); |
310 | 0 | if (tmp==0){ |
311 | 0 | ser_error=E_OUT_OF_MEM; |
312 | 0 | LM_ERR("out of pkg memory\n"); |
313 | 0 | return 0; |
314 | 0 | } |
315 | 0 | memset(tmp,0,sizeof(struct lump)); |
316 | 0 | tmp->before=before->before; |
317 | 0 | tmp->flags=init_lump_flags; |
318 | 0 | tmp->op=LUMP_SKIP; |
319 | 0 | before->before=tmp; |
320 | 0 | return tmp; |
321 | 0 | } |
322 | | |
323 | | |
324 | | |
325 | | /*! \brief removes an already existing header/data lump */ |
326 | | /* WARNING: this function adds the lump either to the msg->add_rm or |
327 | | * msg->body_lumps list, depending on the offset being greater than msg->eoh, |
328 | | * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump |
329 | | * might affect the body!! */ |
330 | | struct lump* del_lump(struct sip_msg* msg, unsigned int offset, |
331 | | unsigned int len, enum _hdr_types_t type) |
332 | 105 | { |
333 | 105 | struct lump* tmp; |
334 | 105 | struct lump* prev, *t; |
335 | 105 | struct lump** list; |
336 | | |
337 | | /* extra checks */ |
338 | 105 | if (offset>msg->len){ |
339 | 0 | LM_CRIT("offset exceeds message size (%d > %d)" |
340 | 0 | " aborting...\n", offset, msg->len); |
341 | 0 | abort(); |
342 | 0 | } |
343 | 105 | if (offset+len>msg->len){ |
344 | 0 | LM_CRIT("offset + len exceeds message" |
345 | 0 | " size (%d + %d > %d)\n", offset, len, msg->len); |
346 | 0 | abort(); |
347 | 0 | } |
348 | 105 | if (len==0){ |
349 | 0 | LM_WARN("called with 0 len (offset =%d)\n", offset); |
350 | 0 | } |
351 | | |
352 | 105 | tmp=pkg_malloc(sizeof(struct lump)); |
353 | 105 | if (tmp==0){ |
354 | 0 | LM_ERR("out of pkg memory\n"); |
355 | 0 | return 0; |
356 | 0 | } |
357 | 105 | memset(tmp,0,sizeof(struct lump)); |
358 | 105 | tmp->op=LUMP_DEL; |
359 | 105 | tmp->type=type; |
360 | 105 | tmp->flags=init_lump_flags; |
361 | 105 | tmp->u.offset=offset; |
362 | 105 | tmp->len=len; |
363 | 105 | prev=0; |
364 | | /* check to see whether this might be a body lump */ |
365 | 105 | if ((msg->eoh) && (offset>(unsigned long)(msg->eoh-msg->buf))) |
366 | 0 | list=&msg->body_lumps; |
367 | 105 | else |
368 | 105 | list=&msg->add_rm; |
369 | 238 | for (t=*list;t; prev=t, t=t->next){ |
370 | | /* insert it sorted after offset */ |
371 | 164 | if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset)) |
372 | 31 | break; |
373 | 164 | } |
374 | 105 | tmp->next=t; |
375 | 105 | if (prev) prev->next=tmp; |
376 | 0 | else *list=tmp; |
377 | 105 | return tmp; |
378 | 105 | } |
379 | | |
380 | | |
381 | | |
382 | | /*! \brief add an anchor |
383 | | * WARNING: this function adds the lump either to the msg->add_rm or |
384 | | * msg->body_lumps list, depending on the offset being greater than msg->eoh, |
385 | | * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump |
386 | | * might affect the body!! */ |
387 | | struct lump* anchor_lump(struct sip_msg* msg, unsigned int offset, |
388 | | enum _hdr_types_t type) |
389 | 24.4k | { |
390 | 24.4k | struct lump* tmp; |
391 | 24.4k | struct lump* prev, *t; |
392 | 24.4k | struct lump** list; |
393 | | |
394 | | |
395 | | /* extra checks */ |
396 | 24.4k | if (offset>msg->len){ |
397 | 0 | LM_CRIT("offset exceeds message size (%d > %d)" |
398 | 0 | " aborting...\n", offset, msg->len); |
399 | 0 | abort(); |
400 | 0 | } |
401 | | |
402 | 24.4k | tmp=pkg_malloc(sizeof(struct lump)); |
403 | 24.4k | if (tmp==0){ |
404 | 0 | ser_error=E_OUT_OF_MEM; |
405 | 0 | LM_ERR("out of pkg memory\n"); |
406 | 0 | return 0; |
407 | 0 | } |
408 | 24.4k | memset(tmp,0,sizeof(struct lump)); |
409 | 24.4k | tmp->op=LUMP_NOP; |
410 | 24.4k | tmp->type=type; |
411 | 24.4k | tmp->flags=init_lump_flags; |
412 | 24.4k | tmp->u.offset=offset; |
413 | 24.4k | prev=0; |
414 | | /* check to see whether this might be a body lump */ |
415 | 24.4k | if ((msg->eoh) && (offset> (unsigned long)(msg->eoh-msg->buf))) |
416 | 0 | list=&msg->body_lumps; |
417 | 24.4k | else |
418 | 24.4k | list=&msg->add_rm; |
419 | | |
420 | 36.5k | for (t=*list;t; prev=t, t=t->next){ |
421 | | /* insert it sorted after offset */ |
422 | 12.1k | if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset)) |
423 | 0 | break; |
424 | 12.1k | } |
425 | 24.4k | tmp->next=t; |
426 | | |
427 | 24.4k | if (prev) prev->next=tmp; |
428 | 12.2k | else *list=tmp; |
429 | 24.4k | return tmp; |
430 | 24.4k | } |
431 | | |
432 | | |
433 | | |
434 | | void free_lump(struct lump* lmp) |
435 | 55.3k | { |
436 | 55.3k | if (lmp && (lmp->op==LUMP_ADD)){ |
437 | 30.8k | if (lmp->u.value){ |
438 | 30.8k | if (lmp->flags &(LUMPFLAG_SHMEM)){ |
439 | 0 | LM_CRIT("called on a not free-able lump:" |
440 | 0 | "%p flags=%x\n", lmp, lmp->flags); |
441 | 0 | abort(); |
442 | 30.8k | }else{ |
443 | 30.8k | pkg_free(lmp->u.value); |
444 | 30.8k | lmp->u.value=0; |
445 | 30.8k | lmp->len=0; |
446 | 30.8k | } |
447 | 30.8k | } |
448 | 30.8k | } |
449 | 55.3k | } |
450 | | |
451 | | |
452 | | |
453 | | void free_lump_list(struct lump* l) |
454 | 12.2k | { |
455 | 12.2k | struct lump* t, *r, *foo,*crt; |
456 | 12.2k | t=l; |
457 | 36.7k | while(t){ |
458 | 24.5k | crt=t; |
459 | 24.5k | t=t->next; |
460 | | |
461 | 24.5k | r=crt->before; |
462 | 36.7k | while(r){ |
463 | 12.2k | foo=r; r=r->before; |
464 | 12.2k | free_lump(foo); |
465 | 12.2k | pkg_free(foo); |
466 | 12.2k | } |
467 | 24.5k | r=crt->after; |
468 | 43.1k | while(r){ |
469 | 18.5k | foo=r; r=r->after; |
470 | 18.5k | free_lump(foo); |
471 | 18.5k | pkg_free(foo); |
472 | 18.5k | } |
473 | | |
474 | | /*clean current elem*/ |
475 | 24.5k | free_lump(crt); |
476 | 24.5k | pkg_free(crt); |
477 | 24.5k | } |
478 | 12.2k | } |
479 | | |
480 | | |
481 | | /*! \brief* duplicate a lump list into pkg memory */ |
482 | | static struct lump *dup_lump_list_r( struct lump *l, |
483 | | enum lump_dir dir, int *error) |
484 | 0 | { |
485 | 0 | int deep_error; |
486 | 0 | struct lump *new_lump; |
487 | |
|
488 | 0 | deep_error=0; /* optimist: assume success in recursion */ |
489 | | /* if at list end, terminate recursion successfully */ |
490 | 0 | if (!l) { *error=0; return 0; } |
491 | | /* otherwise duplicate current element */ |
492 | 0 | new_lump=pkg_malloc(sizeof(struct lump)); |
493 | 0 | if (!new_lump) { *error=1; return 0; } |
494 | | |
495 | 0 | memcpy(new_lump, l, sizeof(struct lump)); |
496 | 0 | new_lump->flags=init_lump_flags; |
497 | 0 | new_lump->next=new_lump->before=new_lump->after=0; |
498 | 0 | if (new_lump->op==LUMP_ADD) { |
499 | 0 | new_lump->u.value = pkg_malloc(l->len); |
500 | 0 | if (!new_lump->u.value) { *error=1; return 0; } |
501 | 0 | memcpy(new_lump->u.value,l->u.value,l->len); |
502 | 0 | } |
503 | | |
504 | 0 | switch(dir) { |
505 | 0 | case LD_NEXT: |
506 | 0 | new_lump->before=dup_lump_list_r(l->before, |
507 | 0 | LD_BEFORE, &deep_error); |
508 | 0 | if (deep_error) goto deeperror; |
509 | 0 | new_lump->after=dup_lump_list_r(l->after, |
510 | 0 | LD_AFTER, &deep_error); |
511 | 0 | if (deep_error) goto deeperror; |
512 | 0 | new_lump->next=dup_lump_list_r(l->next, |
513 | 0 | LD_NEXT, &deep_error); |
514 | 0 | break; |
515 | 0 | case LD_BEFORE: |
516 | 0 | new_lump->before=dup_lump_list_r(l->before, |
517 | 0 | LD_BEFORE, &deep_error); |
518 | 0 | break; |
519 | 0 | case LD_AFTER: |
520 | 0 | new_lump->after=dup_lump_list_r(l->after, |
521 | 0 | LD_AFTER, &deep_error); |
522 | 0 | break; |
523 | 0 | default: |
524 | 0 | LM_CRIT("unknown dir: %d\n", dir ); |
525 | 0 | deep_error=1; |
526 | 0 | } |
527 | 0 | if (deep_error) goto deeperror; |
528 | | |
529 | 0 | *error=0; |
530 | 0 | return new_lump; |
531 | | |
532 | 0 | deeperror: |
533 | 0 | LM_ERR("out of pkg mem\n"); |
534 | 0 | free_lump(new_lump); |
535 | 0 | *error=1; |
536 | 0 | return 0; |
537 | 0 | } |
538 | | |
539 | | |
540 | | |
541 | | /*! \brief full pkg copy of a lump list |
542 | | * |
543 | | * \return if either original list empty or error occur returns, 0 |
544 | | * is returned, pointer to the copy otherwise |
545 | | */ |
546 | | struct lump* dup_lump_list( struct lump *l ) |
547 | 0 | { |
548 | 0 | int deep_error; |
549 | |
|
550 | 0 | deep_error=0; |
551 | 0 | return dup_lump_list_r(l, LD_NEXT, &deep_error); |
552 | 0 | } |
553 | | |
554 | | |
555 | | |
556 | | /*! \brief Delete flagged lumps |
557 | | */ |
558 | | void del_flaged_lumps( struct lump** lump_list, enum lump_flag flags ) |
559 | 0 | { |
560 | 0 | struct lump *r, *foo, *crt, **prev, *prev_r; |
561 | |
|
562 | 0 | prev = lump_list; |
563 | 0 | crt = *lump_list; |
564 | |
|
565 | 0 | while (crt) { |
566 | 0 | if ( crt->flags&flags ) { |
567 | | /* unlink it */ |
568 | 0 | foo = crt; |
569 | 0 | crt = crt->next; |
570 | 0 | foo->next = 0; |
571 | | /* update the 'next' link of the previous lump */ |
572 | 0 | *prev = crt; |
573 | | /* entire before/after list must be removed */ |
574 | 0 | free_lump_list( foo ); |
575 | 0 | } else { |
576 | | /* check on before and prev list for flaged lumps */ |
577 | 0 | r = crt->after; |
578 | 0 | prev_r = crt; |
579 | 0 | while(r){ |
580 | 0 | foo=r; r=r->after; |
581 | 0 | if ( foo->flags&flags ) { |
582 | 0 | prev_r->after = r; |
583 | 0 | free_lump(foo); |
584 | 0 | pkg_free(foo); |
585 | 0 | } else { |
586 | 0 | prev_r = foo; |
587 | 0 | } |
588 | 0 | } |
589 | | /* before */ |
590 | 0 | r = crt->before; |
591 | 0 | prev_r = crt; |
592 | 0 | while(r){ |
593 | 0 | foo=r; r=r->before; |
594 | 0 | if ( foo->flags&flags ) { |
595 | 0 | prev_r->before = r; |
596 | 0 | free_lump(foo); |
597 | 0 | pkg_free(foo); |
598 | 0 | } else { |
599 | 0 | prev_r = foo; |
600 | 0 | } |
601 | 0 | } |
602 | | /* go to next lump */ |
603 | 0 | prev = &(crt->next); |
604 | 0 | crt = crt->next; |
605 | 0 | } |
606 | 0 | } |
607 | 0 | } |
608 | | |
609 | | |
610 | | /*! \brief Delete not flagged lumps |
611 | | */ |
612 | | void del_notflaged_lumps( struct lump** lump_list, enum lump_flag not_flags ) |
613 | 0 | { |
614 | 0 | struct lump *r, *foo, *crt, **prev, *prev_r; |
615 | |
|
616 | 0 | prev = lump_list; |
617 | 0 | crt = *lump_list; |
618 | |
|
619 | 0 | while (crt) { |
620 | 0 | if ( (~crt->flags)¬_flags ) { |
621 | | /* unlink it */ |
622 | 0 | foo = crt; |
623 | 0 | crt = crt->next; |
624 | 0 | foo->next = 0; |
625 | | /* update the 'next' link of the previous lump */ |
626 | 0 | *prev = crt; |
627 | | /* entire before/after list must be removed */ |
628 | 0 | free_lump_list( foo ); |
629 | 0 | } else { |
630 | | /* check on after and before list for not_flaged lumps */ |
631 | 0 | r = crt->after; |
632 | 0 | prev_r = crt; |
633 | 0 | while(r){ |
634 | 0 | foo=r; r=r->after; |
635 | 0 | if ( (~foo->flags)¬_flags ) { |
636 | 0 | prev_r->after = r; |
637 | 0 | free_lump(foo); |
638 | 0 | pkg_free(foo); |
639 | 0 | } else { |
640 | 0 | prev_r = foo; |
641 | 0 | } |
642 | 0 | } |
643 | | /* before */ |
644 | 0 | r = crt->before; |
645 | 0 | prev_r = crt; |
646 | 0 | while(r){ |
647 | 0 | foo=r; r=r->before; |
648 | 0 | if ( (~foo->flags)¬_flags ) { |
649 | 0 | prev_r->before = r; |
650 | 0 | free_lump(foo); |
651 | 0 | pkg_free(foo); |
652 | 0 | } else { |
653 | 0 | prev_r = foo; |
654 | 0 | } |
655 | 0 | } |
656 | | /* go to next lump */ |
657 | 0 | prev = &(crt->next); |
658 | 0 | crt = crt->next; |
659 | 0 | } |
660 | 0 | } |
661 | 0 | } |
662 | | |