Esempio n. 1
0
/* returns the substitution result in a str, input must be 0 term
 *  0 on no match or malloc error */ 
str* subst_str(char *input, struct sip_msg* msg, struct subst_expr* se)
{
	str* res;
	struct replace_lst *lst;
	struct replace_lst* l;
	int len;
	int size;
	char* p;
	char* dest;
	char* end;
	
	
	/* compute the len */
	len=strlen(input);
	end=input+len;
	lst=subst_run(se, input, msg);
	if (lst==0){
		DBG("subst_str: no match\n");
		return 0;
	}
	for (l=lst; l; l=l->next)
		len+=(int)(l->rpl.len)-l->size;
	res=pkg_malloc(sizeof(str));
	if (res==0){
		LOG(L_ERR, "ERROR: subst_str: mem. allocation error\n");
		goto error;
	}
	res->s=pkg_malloc(len+1); /* space for null termination */
	res->s[len]=0;
	if (res->s==0){
		LOG(L_ERR, "ERROR: subst_str: mem. allocation error (res->s)\n");
		goto error;
	}
	res->len=len;
	
	/* replace */
	dest=res->s;
	p=input;
	for(l=lst; l; l=l->next){
		size=l->offset+input-p;
		memcpy(dest, p, size); /* copy till offset */
		p+=size + l->size; /* skip l->size bytes */
		dest+=size;
		if (l->rpl.len){
			memcpy(dest, l->rpl.s, l->rpl.len);
			dest+=l->rpl.len;
		}
	}
	memcpy(dest, p, end-p);
	if(lst) replace_lst_free(lst);
	return res;
error:
	if (lst) replace_lst_free(lst);
	if (res){
		if (res->s) pkg_free(res->s);
		pkg_free(res);
	}
	return 0;
}
Esempio n. 2
0
/* sed-perl style re: s/regular expression/replacement/flags */
static int subst_body_f(struct sip_msg* msg, char*  subst, char* ignored)
{
	struct lump* l;
	struct replace_lst* lst;
	struct replace_lst* rpl;
	char* begin;
	struct subst_expr* se;
	int off;
	int ret;
	int nmatches;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	se=(struct subst_expr*)subst;
	begin=body.s;

	off=begin-msg->buf;
	ret=-1;
	if ((lst=subst_run(se, begin, msg, &nmatches))==0)
		goto error; /* not found */
	for (rpl=lst; rpl; rpl=rpl->next){
		LM_DBG("%s replacing at offset %d [%.*s] with [%.*s]\n",
				exports.name, rpl->offset+off,
				rpl->size, rpl->offset+off+msg->buf,
				rpl->rpl.len, rpl->rpl.s);
		if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
			goto error;
		/* hack to avoid re-copying rpl, possible because both
		 * replace_lst & lumps use pkg_malloc */
		if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
			LM_ERR("%s could not insert new lump\n",
					exports.name);
			goto error;
		}
		/* hack continued: set rpl.s to 0 so that replace_lst_free will
		 * not free it */
		rpl->rpl.s=0;
		rpl->rpl.len=0;
	}
	ret=1;
error:
	LM_DBG("lst was %p\n", lst);
	if (lst) replace_lst_free(lst);
	if (nmatches<0)
		LM_ERR("%s subst_run failed\n", exports.name);
	return ret;
}
Esempio n. 3
0
/* sed-perl style re: s/regular expression/replacement/flags */
static int subst_f(struct sip_msg* msg, char*  subst, char* ignored)
{
	struct lump* l;
	struct replace_lst* lst;
	struct replace_lst* rpl;
	char* begin;
	struct subst_expr* se;
	int off;
	int ret;
	int nmatches;
	
	se=(struct subst_expr*)subst;
	begin=get_header(msg);  /* start after first line to avoid replacing
							   the uri */
	off=begin-msg->buf;
	ret=-1;
	if ((lst=subst_run(se, begin, msg, &nmatches))==0)
		goto error; /* not found */
	for (rpl=lst; rpl; rpl=rpl->next){
		DBG(" %s: subst_f: replacing at offset %d [%.*s] with [%.*s]\n",
				exports.name, rpl->offset+off,
				rpl->size, rpl->offset+off+msg->buf,
				rpl->rpl.len, rpl->rpl.s);
		if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
			goto error;
		/* hack to avoid re-copying rpl, possible because both 
		 * replace_lst & lumps use pkg_malloc */
		if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
			LOG(L_ERR, "ERROR: %s: subst_f: could not insert new lump\n",
					exports.name);
			goto error;
		}
		/* hack continued: set rpl.s to 0 so that replace_lst_free will
		 * not free it */
		rpl->rpl.s=0;
		rpl->rpl.len=0;
	}
	ret=1;
error:
	DBG("subst_f: lst was %p\n", lst);
	if (lst) replace_lst_free(lst);
	if (nmatches<0)
		LOG(L_ERR, "ERROR: %s: subst_run failed\n", exports.name);
	return ret;
}
Esempio n. 4
0
/* WARNING: input must be 0 terminated! */
struct replace_lst* subst_run(struct subst_expr* se, char* input,
								struct sip_msg* msg)
{
	struct replace_lst *head;
	struct replace_lst **crt;
	char *p;
	int r;
	regmatch_t* pmatch;
	int nmatch;
	int eflags;
	
	
	/* init */
	head=0;
	crt=&head;
	p=input;
	nmatch=se->max_pmatch+1;
	/* no of () referenced + 1 for the whole string: pmatch[0] */
	pmatch=pkg_malloc(nmatch*sizeof(regmatch_t));
	if (pmatch==0){
		LOG(L_ERR, "ERROR: subst_run_ out of mem. (pmatch)\n");
		goto error;
	}
	eflags=0;
	do{
		r=regexec(se->re, p, nmatch, pmatch, eflags);
		DBG("subst_run: running. r=%d\n", r);
		/* subst */
		if (r==0){ /* != REG_NOMATCH */
			/* change eflags, not to match any more at string start */
			eflags|=REG_NOTBOL;
			*crt=pkg_malloc(sizeof(struct replace_lst));
			if (*crt==0){
				LOG(L_ERR, "ERROR: subst_run: out of mem (crt)\n");
				goto error;
			}
			memset(*crt, 0, sizeof(struct replace_lst));
			if (pmatch[0].rm_so==-1){
				LOG(L_ERR, "ERROR: subst_run: unknown offset?\n");
				goto error;
			}
			(*crt)->offset=pmatch[0].rm_so+(int)(p-input);
			(*crt)->size=pmatch[0].rm_eo-pmatch[0].rm_so;
			DBG("subst_run: matched (%d, %d): [%.*s]\n",
					(*crt)->offset, (*crt)->size, 
					(*crt)->size, input+(*crt)->offset);
			/* create subst. string */
			/* construct the string from replace[] */
			if (replace_build(p, nmatch, pmatch, se, msg, &((*crt)->rpl))<0){
				goto error;
			}
			crt=&((*crt)->next);
			p+=pmatch[0].rm_eo;
		}
	}while((r==0) && se->replace_all);
	pkg_free(pmatch);
	return head;
error:
	if (head) replace_lst_free(head);
	if (pmatch) pkg_free(pmatch);
	return 0;
}
Esempio n. 5
0
/*! \brief run substitutions
 * \return 0 if no match or error, or subst result; if count!=0
 *           it will be set to 0 (no match), the number of matches
 *           or -1 (error).
 * \note WARNING: input must be 0 terminated!
 */
struct replace_lst* subst_run(struct subst_expr* se, const char* input,
								struct sip_msg* msg, int* count)
{
	struct replace_lst *head;
	struct replace_lst **crt;
	const char *p;
	int r;
	regmatch_t* pmatch;
	int nmatch;
	int eflags;
	int cnt;
	
	
	/* init */
	head=0;
	cnt=0;
	crt=&head;
	p=input;
	nmatch=se->max_pmatch+1;
	/* no of () referenced + 1 for the whole string: pmatch[0] */
	pmatch=pkg_malloc(nmatch*sizeof(regmatch_t));
	if (pmatch==0){
		LM_ERR("out of pkg mem. (pmatch)\n");
		goto error;
	}
	eflags=0;
	do{
		r=regexec(se->re, p, nmatch, pmatch, eflags);
		LM_DBG("running. r=%d\n", r);
		/* subst */
		if (r==0){ /* != REG_NOMATCH */
			/* some checks */
			if (pmatch[0].rm_so==-1){
				LM_ERR("unknown offset?\n");
				goto error;
			}
			if (pmatch[0].rm_so==pmatch[0].rm_eo){
				LM_ERR("matched string is empty... invalid regexp?\n");
				goto error;
			}
			*crt=pkg_malloc(sizeof(struct replace_lst));
			if (*crt==0){
				LM_ERR("out of pkg mem (crt)\n");
				goto error;
			}
			memset(*crt, 0, sizeof(struct replace_lst));
			(*crt)->offset=pmatch[0].rm_so+(int)(p-input);
			(*crt)->size=pmatch[0].rm_eo-pmatch[0].rm_so;
			LM_DBG("matched (%d, %d): [%.*s]\n",
					(*crt)->offset, (*crt)->size, 
					(*crt)->size, input+(*crt)->offset);
			/* create subst. string */
			/* construct the string from replace[] */
			if (replace_build(p, nmatch, pmatch, se, msg, &((*crt)->rpl))<0){
				goto error;
			}
			crt=&((*crt)->next);
			p+=pmatch[0].rm_eo;
			/* is it still a string start? */
			if (*(p-1)=='\n' || *(p-1)=='\r')
				eflags&=~REG_NOTBOL;
			else
				eflags|=REG_NOTBOL;
			cnt++;
		}
	}while((r==0) && se->replace_all);
	pkg_free(pmatch);
	if (count)*count=cnt;
	return head;
error:
	if (head) replace_lst_free(head);
	if (pmatch) pkg_free(pmatch);
	if (count) *count=-1;
	return 0;
}