Browse code

data lumps: two new add lump functions

The following new functions are introduces that can be used
to add new lumps:

- add_new_lump(): Add a data lump right after the anchor point
into the main lump list. Every "before" lump of the same
anchor point will preceed, every "after" lump will
follow this lump.

- anchor_lump2(): Return the anchor point at the given offset
if exists, otherwise create a new anchor.

Miklos Tirpak authored on 19/04/2010 10:44:05
Showing 2 changed files
... ...
@@ -81,6 +81,33 @@ struct lump* append_new_lump(struct lump** list, char* new_hdr,
81 81
 	return tmp;
82 82
 }
83 83
 
84
+/* adds a header right after an anchor point if exists
85
+ * returns  pointer on success, 0 on error */
86
+struct lump* add_new_lump(struct lump** list, char* new_hdr,
87
+							 int len, enum _hdr_types_t type)
88
+{
89
+	struct lump** t;
90
+	struct lump* tmp;
91
+	
92
+
93
+	t = (*list) ? &((*list)->next) : list;
94
+
95
+	tmp=pkg_malloc(sizeof(struct lump));
96
+	if (tmp==0){
97
+		LOG(L_ERR, "ERROR: add_new_lump: out of memory\n");
98
+		return 0;
99
+	}
100
+		
101
+	memset(tmp,0,sizeof(struct lump));
102
+	tmp->type=type;
103
+	tmp->op=LUMP_ADD;
104
+	tmp->u.value=new_hdr;
105
+	tmp->len=len;
106
+	tmp->next=*t;
107
+	*t=tmp;
108
+	return tmp;
109
+}
110
+
84 111
 
85 112
 
86 113
 /* inserts a header to the beginning 
... ...
@@ -343,7 +370,7 @@ struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, enum _hdr_typ
343 343
 	tmp=pkg_malloc(sizeof(struct lump));
344 344
 	if (tmp==0){
345 345
 		ser_error=E_OUT_OF_MEM;
346
-		LOG(L_ERR, "ERROR: insert_new_lump_before: out of memory\n");
346
+		LOG(L_ERR, "ERROR: anchor_lump: out of memory\n");
347 347
 		return 0;
348 348
 	}
349 349
 	memset(tmp,0,sizeof(struct lump));
... ...
@@ -370,6 +397,74 @@ struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, enum _hdr_typ
370 370
 	return tmp;
371 371
 }
372 372
 
373
+/* add an anchor
374
+ * Similar to anchor_lump() but this function checks whether or not a lump
375
+ * has already been added to the same position. If an existing lump is found
376
+ * then it is returned without adding a new one and is_ref is set to 1.
377
+ *
378
+ * WARNING: this function adds the lump either to the msg->add_rm or
379
+ * msg->body_lumps list, depending on the offset being greater than msg->eoh,
380
+ * so msg->eoh must be parsed (parse with HDR_EOH) if you think your lump
381
+ *  might affect the body!! */
382
+struct lump* anchor_lump2(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type,
383
+		int *is_ref)
384
+{
385
+	struct lump* tmp;
386
+	struct lump* prev, *t;
387
+	struct lump** list;
388
+
389
+	
390
+	/* extra checks */
391
+	if (offset>msg->len){
392
+		LOG(L_CRIT, "BUG: anchor_lump2: offset exceeds message size (%d > %d)"
393
+					" aborting...\n", offset, msg->len);
394
+		abort();
395
+	}
396
+	if (len){
397
+		LOG(L_WARN, "WARNING: anchor_lump2: called with len !=0 (%d)\n", len);
398
+		if (offset+len>msg->len)
399
+			LOG(L_WARN, "WARNING: anchor_lump2: offset + len exceeds message"
400
+					" size (%d + %d > %d)\n", offset, len,  msg->len);
401
+	}
402
+	
403
+	prev=0;
404
+	/* check to see whether this might be a body lump */
405
+	if ((msg->eoh) && (offset> (int)(msg->eoh-msg->buf)))
406
+		list=&msg->body_lumps;
407
+	else
408
+		list=&msg->add_rm;
409
+		
410
+	for (t=*list;t; prev=t, t=t->next){
411
+		/* insert it sorted after offset */
412
+		if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>=offset))
413
+			break;
414
+	}
415
+	if (t && (t->u.offset==offset)) {
416
+		/* A lump with the same offset is found */
417
+		*is_ref=1;
418
+		return t;
419
+	}
420
+
421
+	tmp=pkg_malloc(sizeof(struct lump));
422
+	if (tmp==0){
423
+		ser_error=E_OUT_OF_MEM;
424
+		LOG(L_ERR, "ERROR: anchor_lump2: out of memory\n");
425
+		return 0;
426
+	}
427
+	memset(tmp,0,sizeof(struct lump));
428
+	tmp->op=LUMP_NOP;
429
+	tmp->type=type;
430
+	tmp->u.offset=offset;
431
+	tmp->len=len;
432
+
433
+	tmp->next=t;
434
+	
435
+	if (prev) prev->next=tmp;
436
+	else *list=tmp;
437
+
438
+	*is_ref=0;
439
+	return tmp;
440
+}
373 441
 
374 442
 
375 443
 void free_lump(struct lump* lmp)
... ...
@@ -48,6 +48,11 @@
48 48
 #include "parser/msg_parser.h"
49 49
 #include "parser/hf.h"
50 50
 
51
+
52
+/* adds a header right after an anchor point if exists */
53
+struct lump* add_new_lump(struct lump** list, char* new_hdr,
54
+							 int len, enum _hdr_types_t type);
55
+
51 56
 /*! \brief adds a header to the end */
52 57
 struct lump* append_new_lump(struct lump** list, char* new_hdr,
53 58
 							 int len, enum _hdr_types_t type);
... ...
@@ -71,6 +76,10 @@ struct lump* insert_cond_lump_before(struct lump* after, enum lump_conditions c,
71 71
 									enum _hdr_types_t type);
72 72
 
73 73
 /*! \brief removes an already existing header */
74
+/* set an anchor if there is no existing one at the given offset,
75
+ * otherwise return the existing anchor */
76
+struct lump* anchor_lump2(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type,
77
+								int *is_ref);
74 78
 struct lump* del_lump(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type);
75 79
 /*! \brief set an anchor */
76 80
 struct lump* anchor_lump(struct sip_msg* msg, int offset, int len, enum _hdr_types_t type);