/* 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; }
/* 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; }
/* 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; }