📄 textops.c
字号:
/*$Id: textops.c,v 1.40 2004/11/12 16:58:58 andrei Exp $ * * Example ser module, it implements the following commands: * search_append("key", "txt") - insert a "txt" after "key" * replace("txt1", "txt2") - replaces txt1 with txt2 (txt1 can be a re) * search("txt") - searches for txt (txt can be a regular expression) * append_to_reply("txt") - appends txt to the reply? * append_hf("P-foo: bar\r\n"); * * * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * History: * ------- * 2003-02-28 scratchpad compatibility abandoned (jiri) * 2003-01-29: - rewriting actions (replace, search_append) now begin * at the second line -- previously, they could affect * first line too, which resulted in wrong calculation of * forwarded requests and an error consequently * - replace_all introduced * 2003-01-28 scratchpad removed (jiri) * 2003-01-18 append_urihf introduced (jiri) * 2003-03-10 module export interface updated to the new format (andrei) * 2003-03-16 flags export parameter added (janakj) * 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei) * 2003-04-97 actions permitted to be used from failure/reply routes (jiri) * 2003-04-21 remove_hf and is_present_hf introduced (jiri) * 2003-08-19 subst added (support for sed like res:s/re/repl/flags) (andrei) * 2003-08-20 subst_uri added (like above for uris) (andrei) * 2003-09-11 updated to new build_lump_rpl() interface (bogdan) * 2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags (bogdan) * 2004-05-09: append_time introduced (jiri) * 2004-07-06 subst_user added (like subst_uri but only for user) (sobomax) * 2004-11-12 subst_user changes (old serdev mails) (andrei) */#include "../../comp_defs.h"#include "../../action.h"#include "../../sr_module.h"#include "../../dprint.h"#include "../../data_lump.h"#include "../../data_lump_rpl.h"#include "../../error.h"#include "../../mem/mem.h"#include "../../re.h"#include "../../parser/parse_uri.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h> /* for regex */#include <regex.h>#include <time.h>#include <sys/time.h>MODULE_VERSION/* RFC822-conforming dates format: %a -- abbreviated week of day name (locale), %d day of month as decimal number, %b abbreviated month name (locale), %Y year with century, %T time in 24h notation*/#define TIME_FORMAT "Date: %a, %d %b %Y %H:%M:%S GMT"#define MAX_TIME 64static int search_f(struct sip_msg*, char*, char*);static int replace_f(struct sip_msg*, char*, char*);static int subst_f(struct sip_msg*, char*, char*);static int subst_uri_f(struct sip_msg*, char*, char*);static int subst_user_f(struct sip_msg*, char*, char*);static int remove_hf_f(struct sip_msg* msg, char* str_hf, char* foo);static int is_present_hf_f(struct sip_msg* msg, char* str_hf, char* foo);static int replace_all_f(struct sip_msg* msg, char* key, char* str);static int search_append_f(struct sip_msg*, char*, char*);static int append_to_reply_f(struct sip_msg* msg, char* key, char* str);static int append_hf(struct sip_msg* msg, char* str1, char* str2);static int append_urihf(struct sip_msg* msg, char* str1, char* str2);static int append_time_f(struct sip_msg* msg, char* , char *);static int fixup_regex(void**, int);static int fixup_substre(void**, int);static int str_fixup(void** param, int param_no);static int mod_init(void);static cmd_export_t cmds[]={ {"search", search_f, 1, fixup_regex, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"search_append", search_append_f, 2, fixup_regex, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"replace", replace_f, 2, fixup_regex, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"replace_all", replace_all_f, 2, fixup_regex, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"append_to_reply", append_to_reply_f, 1, 0, REQUEST_ROUTE}, {"append_hf", append_hf, 1, str_fixup, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"append_urihf", append_urihf, 2, str_fixup, REQUEST_ROUTE|FAILURE_ROUTE}, {"remove_hf", remove_hf_f, 1, str_fixup, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"is_present_hf", is_present_hf_f, 1, str_fixup, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"subst", subst_f, 1, fixup_substre, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"subst_uri", subst_uri_f, 1, fixup_substre, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"subst_user", subst_user_f, 1, fixup_substre, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE}, {"append_time", append_time_f, 0, 0, REQUEST_ROUTE }, {0,0,0,0,0}};static param_export_t params[]={ {0,0,0} }; /* no params */struct module_exports exports= { "textops", cmds, params, mod_init, /* module initialization function */ 0, /* response function */ 0, /* destroy function */ 0, /* on_cancel function */ 0, /* per-child init function */};static int mod_init(void){ fprintf(stderr, "%s - initializing\n", exports.name); return 0;}static char *get_header(struct sip_msg *msg){ return msg->buf+msg->first_line.len;}static int search_f(struct sip_msg* msg, char* key, char* str2){ /*we registered only 1 param, so we ignore str2*/ regmatch_t pmatch; if (regexec((regex_t*) key, msg->buf, 1, &pmatch, 0)!=0) return -1; return 1;}static int search_append_f(struct sip_msg* msg, char* key, char* str){ struct lump* l; regmatch_t pmatch; char* s; int len; char *begin; int off; begin=get_header(msg); /* msg->orig/buf previously .. uri problems */ off=begin-msg->buf; if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1; if (pmatch.rm_so!=-1){ if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0, 0))==0) return -1; len=strlen(str); s=pkg_malloc(len); if (s==0){ LOG(L_ERR, "ERROR: search_append_f: mem. allocation failure\n"); return -1; } memcpy(s, str, len); if (insert_new_lump_after(l, s, len, 0)==0){ LOG(L_ERR, "ERROR: could not insert new lump\n"); pkg_free(s); return -1; } return 1; } return -1;}static int replace_all_f(struct sip_msg* msg, char* key, char* str){ struct lump* l; regmatch_t pmatch; char* s; int len; char* begin; int off; int ret; int eflags; begin=get_header(msg); /* msg->orig previously .. uri problems */ ret=-1; /* pessimist: we will not find any */ len=strlen(str); eflags=0; /* match ^ at the beginning of the string*/ while (begin<msg->buf+msg->len && regexec((regex_t*) key, begin, 1, &pmatch, eflags)==0) { off=begin-msg->buf; /* change eflags, not to match any more at string start */ eflags|=REG_NOTBOL; if (pmatch.rm_so==-1){ LOG(L_ERR, "ERROR: replace_all_f: offset unknown\n"); return -1; } if ((l=del_lump(msg, pmatch.rm_so+off, pmatch.rm_eo-pmatch.rm_so, 0))==0) { LOG(L_ERR, "ERROR: replace_all_f: del_lump failed\n"); return -1; } s=pkg_malloc(len); if (s==0){ LOG(L_ERR, "ERROR: replace_f: mem. allocation failure\n"); return -1; } memcpy(s, str, len); if (insert_new_lump_after(l, s, len, 0)==0){ LOG(L_ERR, "ERROR: could not insert new lump\n"); pkg_free(s); return -1; } /* new cycle */ begin=begin+pmatch.rm_eo; ret=1; } /* while found ... */ return ret;}static int replace_f(struct sip_msg* msg, char* key, char* str){ struct lump* l; regmatch_t pmatch; char* s; int len; char* begin; int off; begin=get_header(msg); /* msg->orig previously .. uri problems */ if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1; off=begin-msg->buf; if (pmatch.rm_so!=-1){ if ((l=del_lump(msg, pmatch.rm_so+off, pmatch.rm_eo-pmatch.rm_so, 0))==0) return -1; len=strlen(str); s=pkg_malloc(len); if (s==0){ LOG(L_ERR, "ERROR: replace_f: mem. allocation failure\n"); return -1; } memcpy(s, str, len); if (insert_new_lump_after(l, s, len, 0)==0){ LOG(L_ERR, "ERROR: could not insert new lump\n"); pkg_free(s); return -1; } return 1; } return -1;}/* 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){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -