• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

data_lump.c

Go to the documentation of this file.
00001 /* $Id$
00002  *
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of SIP-router, a free SIP server.
00007  *
00008  * SIP-router is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * SIP-router is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  *  2003-01-19  support for duplication lump lists added (jiri)
00025  *  2003-03-31  added subst lumps --they expand in ip addr, port a.s.o (andrei)
00026  *  2003-04-01  added conditional lump support functions (andrei)
00027  *  2003-10-20  anchor_lump & del_lump will automatically choose the lump list
00028  *              based on  msg->eoh comparisons (andrei)
00029  *  2003-10-28  added extra checks (paranoia) for {anchor,del}_lump (andrei)
00030  *  2005-03-24  the type of type attribute changed to enum _hdr_types_t (janakj)
00031  */
00041 #include "data_lump.h"
00042 #include "dprint.h"
00043 #include "mem/mem.h"
00044 #include "globals.h"
00045 #include "error.h"
00046 
00047 #include <stdlib.h>
00048 #include <string.h>
00049 
00050 #ifdef DEBUG_DMALLOC
00051 #include <dmalloc.h>
00052 #endif
00053 
00054 /* WARNING: all lump add/insert operations expect a pkg_malloc'ed char* 
00055  * pointer the will be DEALLOCATED when the sip_msg is destroyed! */
00056 
00057 enum lump_dir { LD_NEXT, LD_BEFORE, LD_AFTER };
00058 
00059 /* adds a header to the end
00060  * returns  pointer on success, 0 on error */
00061 struct lump* append_new_lump(struct lump** list, char* new_hdr,
00062                                                          int len, enum _hdr_types_t type)
00063 {
00064         struct lump** t;
00065         struct lump* tmp;
00066         
00067         for (t=list;*t;t=&((*t)->next));
00068 
00069         tmp=pkg_malloc(sizeof(struct lump));
00070         if (tmp==0){
00071                 LOG(L_ERR, "ERROR: append_new_lump: out of memory\n");
00072                 return 0;
00073         }
00074                 
00075         memset(tmp,0,sizeof(struct lump));
00076         tmp->type=type;
00077         tmp->op=LUMP_ADD;
00078         tmp->u.value=new_hdr;
00079         tmp->len=len;
00080         *t=tmp;
00081         return tmp;
00082 }
00083 
00084 /* adds a header right after an anchor point if exists
00085  * returns  pointer on success, 0 on error */
00086 struct lump* add_new_lump(struct lump** list, char* new_hdr,
00087                                                          int len, enum _hdr_types_t type)
00088 {
00089         struct lump** t;
00090         struct lump* tmp;
00091         
00092 
00093         t = (*list) ? &((*list)->next) : list;
00094 
00095         tmp=pkg_malloc(sizeof(struct lump));
00096         if (tmp==0){
00097                 LOG(L_ERR, "ERROR: add_new_lump: out of memory\n");
00098                 return 0;
00099         }
00100                 
00101         memset(tmp,0,sizeof(struct lump));
00102         tmp->type=type;
00103         tmp->op=LUMP_ADD;
00104         tmp->u.value=new_hdr;
00105         tmp->len=len;
00106         tmp->next=*t;
00107         *t=tmp;
00108         return tmp;
00109 }
00110 
00111 
00112 
00113 /* inserts a header to the beginning 
00114  * returns pointer if success, 0 on error */
00115 struct lump* insert_new_lump(struct lump** list, char* new_hdr,
00116                                                                 int len, enum _hdr_types_t type)
00117 {
00118         struct lump* tmp;
00119 
00120         tmp=pkg_malloc(sizeof(struct lump));
00121         if (tmp==0){
00122                 LOG(L_ERR, "ERROR: insert_new_lump: out of memory\n");
00123                 return 0;
00124         }
00125         memset(tmp,0,sizeof(struct lump));
00126         tmp->next=*list;
00127         tmp->type=type;
00128         tmp->op=LUMP_ADD;
00129         tmp->u.value=new_hdr;
00130         tmp->len=len;
00131         *list=tmp;
00132         return tmp;
00133 }
00134 
00135 
00136 
00137 /* inserts a  header/data lump immediately after hdr 
00138  * returns pointer on success, 0 on error */
00139 struct lump* insert_new_lump_after( struct lump* after, char* new_hdr,
00140                                                         int len, enum _hdr_types_t type)
00141 {
00142         struct lump* tmp;
00143 
00144         tmp=pkg_malloc(sizeof(struct lump));
00145         if (tmp==0){
00146                 ser_error=E_OUT_OF_MEM;
00147                 LOG(L_ERR, "ERROR: insert_new_lump_after: out of memory\n");
00148                 return 0;
00149         }
00150         memset(tmp,0,sizeof(struct lump));
00151         tmp->after=after->after;
00152         tmp->type=type;
00153         tmp->op=LUMP_ADD;
00154         tmp->u.value=new_hdr;
00155         tmp->len=len;
00156         after->after=tmp;
00157         return tmp;
00158 }
00159 
00160 
00161 
00162 /* inserts a  header/data lump immediately before "before" 
00163  * returns pointer on success, 0 on error */
00164 struct lump* insert_new_lump_before( struct lump* before, char* new_hdr,
00165                                                         int len, enum _hdr_types_t type)
00166 {
00167         struct lump* tmp;
00168 
00169         tmp=pkg_malloc(sizeof(struct lump));
00170         if (tmp==0){
00171                 ser_error=E_OUT_OF_MEM;
00172                 LOG(L_ERR,"ERROR: insert_new_lump_before: out of memory\n");
00173                 return 0;
00174         }
00175         memset(tmp,0,sizeof(struct lump));
00176         tmp->before=before->before;
00177         tmp->type=type;
00178         tmp->op=LUMP_ADD;
00179         tmp->u.value=new_hdr;
00180         tmp->len=len;
00181         before->before=tmp;
00182         return tmp;
00183 }
00184 
00185 
00186 
00187 /* inserts a  subst lump immediately after hdr 
00188  * returns pointer on success, 0 on error */
00189 struct lump* insert_subst_lump_after( struct lump* after, enum lump_subst subst,
00190                                                                                 enum _hdr_types_t type)
00191 {
00192         struct lump* tmp;
00193         
00194         tmp=pkg_malloc(sizeof(struct lump));
00195         if (tmp==0){
00196                 ser_error=E_OUT_OF_MEM;
00197                 LOG(L_ERR, "ERROR: insert_new_lump_after: out of memory\n");
00198                 return 0;
00199         }
00200         memset(tmp,0,sizeof(struct lump));
00201         tmp->after=after->after;
00202         tmp->type=type;
00203         tmp->op=LUMP_ADD_SUBST;
00204         tmp->u.subst=subst;
00205         tmp->len=0;
00206         after->after=tmp;
00207         return tmp;
00208 }
00209 
00210 
00211 
00212 /* inserts a  subst lump immediately before "before" 
00213  * returns pointer on success, 0 on error */
00214 struct lump* insert_subst_lump_before(  struct lump* before, 
00215                                                                                 enum lump_subst subst,
00216                                                                                 enum _hdr_types_t type)
00217 {
00218         struct lump* tmp;
00219         
00220         tmp=pkg_malloc(sizeof(struct lump));
00221         if (tmp==0){
00222                 ser_error=E_OUT_OF_MEM;
00223                 LOG(L_ERR,"ERROR: insert_new_lump_before: out of memory\n");
00224                 return 0;
00225         }
00226         memset(tmp,0,sizeof(struct lump));
00227         tmp->before=before->before;
00228         tmp->type=type;
00229         tmp->op=LUMP_ADD_SUBST;
00230         tmp->u.subst=subst;
00231         tmp->len=0;
00232         before->before=tmp;
00233         return tmp;
00234 }
00235 
00236 
00237 
00238 /* inserts a  cond lump immediately after hdr 
00239  * returns pointer on success, 0 on error */
00240 struct lump* insert_cond_lump_after( struct lump* after, enum lump_conditions c,
00241                                                                                 enum _hdr_types_t type)
00242 {
00243         struct lump* tmp;
00244         
00245         tmp=pkg_malloc(sizeof(struct lump));
00246         if (tmp==0){
00247                 ser_error=E_OUT_OF_MEM;
00248                 LOG(L_ERR, "ERROR: insert_new_lump_after: out of memory\n");
00249                 return 0;
00250         }
00251         memset(tmp,0,sizeof(struct lump));
00252         tmp->after=after->after;
00253         tmp->type=type;
00254         tmp->op=LUMP_ADD_OPT;
00255         tmp->u.cond=c;
00256         tmp->len=0;
00257         after->after=tmp;
00258         return tmp;
00259 }
00260 
00261 
00262 
00263 /* inserts a  conditional lump immediately before "before" 
00264  * returns pointer on success, 0 on error */
00265 struct lump* insert_cond_lump_before(   struct lump* before, 
00266                                                                                 enum lump_conditions c,
00267                                                                                 enum _hdr_types_t type)
00268 {
00269         struct lump* tmp;
00270         
00271         tmp=pkg_malloc(sizeof(struct lump));
00272         if (tmp==0){
00273                 ser_error=E_OUT_OF_MEM;
00274                 LOG(L_ERR,"ERROR: insert_new_lump_before: out of memory\n");
00275                 return 0;
00276         }
00277         memset(tmp,0,sizeof(struct lump));
00278         tmp->before=before->before;
00279         tmp->type=type;
00280         tmp->op=LUMP_ADD_OPT;
00281         tmp->u.cond=c;
00282         tmp->len=0;
00283         before->before=tmp;
00284         return tmp;
00285 }
00286 
00287 
00288 
00289 /* removes an already existing header/data lump */
00290 /* WARNING: this function adds the lump either to the msg->add_rm or
00291  * msg->body_lumps list, depending on the offset being greater than msg->eoh,
00292  * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
00293  *  might affect the body!! */
00294 struct lump* del_lump(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type)
00295 {
00296         struct lump* tmp;
00297         struct lump* prev, *t;
00298         struct lump** list;
00299 
00300         /* extra checks */
00301         if (offset>msg->len){
00302                 LOG(L_CRIT, "BUG: del_lump: offset exceeds message size (%d > %d)"
00303                                         " aborting...\n", offset, msg->len);
00304                 abort();
00305         }
00306         if (offset+len>msg->len){
00307                 LOG(L_CRIT, " BUG: del_lump: offset + len exceeds message"
00308                                 " size (%d + %d > %d)\n", offset, len,  msg->len);
00309                 abort();
00310         }
00311         if (len==0){
00312                 LOG(L_WARN, "WARNING: del_lump: called with 0 len (offset =%d)\n",
00313                                 offset);
00314         }
00315         
00316         tmp=pkg_malloc(sizeof(struct lump));
00317         if (tmp==0){
00318                 LOG(L_ERR, "ERROR: del_lump: out of memory\n");
00319                 return 0;
00320         }
00321         memset(tmp,0,sizeof(struct lump));
00322         tmp->op=LUMP_DEL;
00323         tmp->type=type;
00324         tmp->u.offset=offset;
00325         tmp->len=len;
00326         prev=0;
00327         /* check to see whether this might be a body lump */
00328         if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
00329                 list=&msg->body_lumps;
00330         else
00331                 list=&msg->add_rm;
00332         for (t=*list;t; prev=t, t=t->next){
00333                 /* insert it sorted after offset */
00334                 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
00335                         break;
00336         }
00337         tmp->next=t;
00338         if (prev) prev->next=tmp;
00339         else *list=tmp;
00340         return tmp;
00341 }
00342 
00343 
00344 
00345 /* add an anchor
00346  * WARNING: this function adds the lump either to the msg->add_rm or
00347  * msg->body_lumps list, depending on the offset being greater than msg->eoh,
00348  * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
00349  *  might affect the body!! */
00350 struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type)
00351 {
00352         struct lump* tmp;
00353         struct lump* prev, *t;
00354         struct lump** list;
00355 
00356         
00357         /* extra checks */
00358         if (offset>msg->len){
00359                 LOG(L_CRIT, "BUG: anchor_lump: offset exceeds message size (%d > %d)"
00360                                         " aborting...\n", offset, msg->len);
00361                 abort();
00362         }
00363         if (len){
00364                 LOG(L_WARN, "WARNING: anchor_lump: called with len !=0 (%d)\n", len);
00365                 if (offset+len>msg->len)
00366                         LOG(L_WARN, "WARNING: anchor_lump: offset + len exceeds message"
00367                                         " size (%d + %d > %d)\n", offset, len,  msg->len);
00368         }
00369         
00370         tmp=pkg_malloc(sizeof(struct lump));
00371         if (tmp==0){
00372                 ser_error=E_OUT_OF_MEM;
00373                 LOG(L_ERR, "ERROR: anchor_lump: out of memory\n");
00374                 return 0;
00375         }
00376         memset(tmp,0,sizeof(struct lump));
00377         tmp->op=LUMP_NOP;
00378         tmp->type=type;
00379         tmp->u.offset=offset;
00380         tmp->len=len;
00381         prev=0;
00382         /* check to see whether this might be a body lump */
00383         if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
00384                 list=&msg->body_lumps;
00385         else
00386                 list=&msg->add_rm;
00387                 
00388         for (t=*list;t; prev=t, t=t->next){
00389                 /* insert it sorted after offset */
00390                 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
00391                         break;
00392         }
00393         tmp->next=t;
00394         
00395         if (prev) prev->next=tmp;
00396         else *list=tmp;
00397         return tmp;
00398 }
00399 
00400 /* add an anchor
00401  * Similar to anchor_lump() but this function checks whether or not a lump
00402  * has already been added to the same position. If an existing lump is found
00403  * then it is returned without adding a new one and is_ref is set to 1.
00404  *
00405  * WARNING: this function adds the lump either to the msg->add_rm or
00406  * msg->body_lumps list, depending on the offset being greater than msg->eoh,
00407  * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
00408  *  might affect the body!! */
00409 struct lump* anchor_lump2(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type,
00410                 int *is_ref)
00411 {
00412         struct lump* tmp;
00413         struct lump* prev, *t;
00414         struct lump** list;
00415 
00416         
00417         /* extra checks */
00418         if (offset>msg->len){
00419                 LOG(L_CRIT, "BUG: anchor_lump2: offset exceeds message size (%d > %d)"
00420                                         " aborting...\n", offset, msg->len);
00421                 abort();
00422         }
00423         if (len){
00424                 LOG(L_WARN, "WARNING: anchor_lump2: called with len !=0 (%d)\n", len);
00425                 if (offset+len>msg->len)
00426                         LOG(L_WARN, "WARNING: anchor_lump2: offset + len exceeds message"
00427                                         " size (%d + %d > %d)\n", offset, len,  msg->len);
00428         }
00429         
00430         prev=0;
00431         /* check to see whether this might be a body lump */
00432         if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
00433                 list=&msg->body_lumps;
00434         else
00435                 list=&msg->add_rm;
00436                 
00437         for (t=*list;t; prev=t, t=t->next){
00438                 /* insert it sorted after offset */
00439                 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>=offset))
00440                         break;
00441         }
00442         if (t && (t->u.offset==offset)) {
00443                 /* A lump with the same offset is found */
00444                 *is_ref=1;
00445                 return t;
00446         }
00447 
00448         tmp=pkg_malloc(sizeof(struct lump));
00449         if (tmp==0){
00450                 ser_error=E_OUT_OF_MEM;
00451                 LOG(L_ERR, "ERROR: anchor_lump2: out of memory\n");
00452                 return 0;
00453         }
00454         memset(tmp,0,sizeof(struct lump));
00455         tmp->op=LUMP_NOP;
00456         tmp->type=type;
00457         tmp->u.offset=offset;
00458         tmp->len=len;
00459 
00460         tmp->next=t;
00461         
00462         if (prev) prev->next=tmp;
00463         else *list=tmp;
00464 
00465         *is_ref=0;
00466         return tmp;
00467 }
00468 
00469 
00470 void free_lump(struct lump* lmp)
00471 {
00472         if (lmp && (lmp->op==LUMP_ADD)){
00473                 if (lmp->u.value){
00474                         if (lmp->flags &(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)){
00475                                 LOG(L_CRIT, "BUG: free_lump: called on a not free-able lump:"
00476                                                 "%p flags=%x\n", lmp, lmp->flags);
00477                                 abort();
00478                         }else{
00479                                 pkg_free(lmp->u.value);
00480                                 lmp->u.value=0;
00481                                 lmp->len=0;
00482                         }
00483                 }
00484         }
00485 }
00486 
00487 
00488 
00489 void free_lump_list(struct lump* l)
00490 {
00491         struct lump* t, *r, *foo,*crt;
00492         t=l;
00493         while(t){
00494                 crt=t;
00495                 t=t->next;
00496         /*
00497                  dangerous recursive clean
00498                 if (crt->before) free_lump_list(crt->before);
00499                 if (crt->after)  free_lump_list(crt->after);
00500         */
00501                 /* no more recursion, clean after and before and that's it */
00502                 r=crt->before;
00503                 while(r){
00504                         foo=r; r=r->before;
00505                         free_lump(foo);
00506                         pkg_free(foo);
00507                 }
00508                 r=crt->after;
00509                 while(r){
00510                         foo=r; r=r->after;
00511                         free_lump(foo);
00512                         pkg_free(foo);
00513                 }
00514                 
00515                 /*clean current elem*/
00516                 free_lump(crt);
00517                 pkg_free(crt);
00518         }
00519 }
00520 
00521 /* free (shallow-ly) a lump and its after/before lists */
00522 static void free_shallow_lump( struct lump *l )
00523 {
00524         struct lump *r, *foo;
00525 
00526         r=l->before;
00527         while(r){
00528                 foo=r; r=r->before;
00529                 pkg_free(foo);
00530         }
00531         r=l->after;
00532         while(r){
00533                 foo=r; r=r->after;
00534                 pkg_free(foo);
00535         }
00536         pkg_free(l);
00537 }
00538 
00539 /* duplicate (shallow-ly) a lump list into pkg memory */
00540 static struct lump *dup_lump_list_r( struct lump *l, 
00541                                 enum lump_dir dir, int *error)
00542 {
00543         int deep_error;
00544         struct lump *new_lump;
00545 
00546         deep_error=0; /* optimist: assume success in recursion */
00547         /* if at list end, terminate recursion successfully */
00548         if (!l) { *error=0; return 0; }
00549         /* otherwise duplicate current element */
00550         new_lump=pkg_malloc(sizeof(struct lump));
00551         if (!new_lump) { *error=1; return 0; }
00552 
00553         memcpy(new_lump, l, sizeof(struct lump));
00554         new_lump->flags=LUMPFLAG_DUPED;
00555         new_lump->next=new_lump->before=new_lump->after=0;
00556 
00557         switch(dir) {
00558                 case LD_NEXT:   
00559                                 new_lump->before=dup_lump_list_r(l->before, 
00560                                                                 LD_BEFORE, &deep_error);
00561                                 if (deep_error) goto deeperror;
00562                                 new_lump->after=dup_lump_list_r(l->after, 
00563                                                                 LD_AFTER, &deep_error);
00564                                 if (deep_error) goto deeperror;
00565                                 new_lump->next=dup_lump_list_r(l->next, 
00566                                                                 LD_NEXT, &deep_error);
00567                                 break;
00568                 case LD_BEFORE:
00569                                 new_lump->before=dup_lump_list_r(l->before, 
00570                                                                 LD_BEFORE, &deep_error);
00571                                 break;
00572                 case LD_AFTER:
00573                                 new_lump->after=dup_lump_list_r(l->after, 
00574                                                                 LD_AFTER, &deep_error);
00575                                 break;
00576                 default:
00577                                 LOG(L_CRIT, "BUG: dup_limp_list_r: unknown dir: "
00578                                                 "%d\n", dir );
00579                                 deep_error=1;
00580         }
00581         if (deep_error) goto deeperror;
00582 
00583         *error=0;
00584         return new_lump;
00585 
00586 deeperror:
00587         LOG(L_ERR, "ERROR: dup_lump_list_r: out of mem\n");
00588         free_shallow_lump(new_lump);
00589         *error=1;
00590         return 0;
00591 }
00592 
00593 
00594 
00595 /* shallow pkg copy of a lump list
00596  *
00597  * if either original list empty or error occur returns, 0
00598  * is returned, pointer to the copy otherwise
00599  */
00600 struct lump* dup_lump_list( struct lump *l )
00601 {
00602         int deep_error;
00603 
00604         deep_error=0;
00605         return dup_lump_list_r(l, LD_NEXT, &deep_error);
00606 }
00607 
00608 
00609 
00610 void free_duped_lump_list(struct lump* l)
00611 {
00612         struct lump *r, *foo,*crt;
00613         while(l){
00614                 crt=l;
00615                 l=l->next;
00616 
00617                 r=crt->before;
00618                 while(r){
00619                         foo=r; r=r->before;
00620                         /* (+): if a new item was introduced to the shallow-ly
00621                          * duped list, remove it completely, preserve it
00622                          * otherwise (it is still referred by original list)
00623                          */
00624                         if (foo->flags!=LUMPFLAG_DUPED) 
00625                                         free_lump(foo);
00626                         pkg_free(foo);
00627                 }
00628                 r=crt->after;
00629                 while(r){
00630                         foo=r; r=r->after;
00631                         if (foo->flags!=LUMPFLAG_DUPED) /* (+) ... see above */
00632                                 free_lump(foo);
00633                         pkg_free(foo);
00634                 }
00635                 
00636                 /*clean current elem*/
00637                 if (crt->flags!=LUMPFLAG_DUPED) /* (+) ... see above */
00638                         free_lump(crt);
00639                 pkg_free(crt);
00640         }
00641 }
00642 
00643 
00644 
00645 void del_nonshm_lump( struct lump** lump_list )
00646 {
00647         struct lump *r, *foo, *crt, **prev, *prev_r;
00648 
00649         prev = lump_list;
00650         crt = *lump_list;
00651 
00652         while (crt) {
00653                 if (!(crt->flags&LUMPFLAG_SHMEM)) {
00654                         /* unlink it */
00655                         foo = crt;
00656                         crt = crt->next;
00657                         foo->next = 0;
00658                         /* update the 'next' link of the previous lump */
00659                         *prev = crt;
00660                         /* entire before/after list must be removed */
00661                         free_lump_list( foo );
00662                 } else {
00663                         /* check on before and prev list for non-shmem lumps */
00664                         r = crt->after;
00665                         prev_r = crt;
00666                         while(r){
00667                                 foo=r; r=r->after;
00668                                 if (!(foo->flags&LUMPFLAG_SHMEM)) {
00669                                         prev_r->after = r;
00670                                         free_lump(foo);
00671                                         pkg_free(foo);
00672                                 } else {
00673                                         prev_r = foo;
00674                                 }
00675                         }
00676                         /* before */
00677                         r = crt->before;
00678                         prev_r = crt;
00679                         while(r){
00680                                 foo=r; r=r->before;
00681                                 if (!(foo->flags&LUMPFLAG_SHMEM)) {
00682                                         prev_r->before = r;
00683                                         free_lump(foo);
00684                                         pkg_free(foo);
00685                                 } else {
00686                                         prev_r = foo;
00687                                 }
00688                         }
00689                         /* go to next lump */
00690                         prev = &(crt->next);
00691                         crt = crt->next;
00692                 }
00693         }
00694 }
00695 
00696 unsigned int count_applied_lumps(struct lump *ll, int type)
00697 {
00698         unsigned int n = 0;
00699         struct lump *l = 0;
00700 
00701         for(l=ll; l; l=l->next) {
00702                 if (l->op==LUMP_NOP && l->type==type) {
00703                         if (l->after && l->after->op==LUMP_ADD_OPT) {
00704                                 if (LUMP_IS_COND_TRUE(l->after)) {
00705                                         n++;
00706                                 }
00707                         } else {
00708                                 n++;
00709                         }
00710                 }
00711         }
00712         return n;
00713 }
00714 

Generated on Tue May 22 2012 13:10:05 for SIP Router by  doxygen 1.7.1