00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "../../action.h"
00053 #include "../../sr_module.h"
00054 #include "../../dprint.h"
00055 #include "../../data_lump.h"
00056 #include "../../data_lump_rpl.h"
00057 #include "../../error.h"
00058 #include "../../mem/mem.h"
00059 #include "../../str.h"
00060 #include "../../re.h"
00061 #include "../../mod_fix.h"
00062 #include "../../parser/parse_uri.h"
00063 #include "../../parser/parse_hname2.h"
00064 #include "../../parser/parse_methods.h"
00065 #include "../../parser/parse_content.h"
00066 #include "../../parser/parse_privacy.h"
00067 #include "../../mod_fix.h"
00068 #include "../../ut.h"
00069 #include "../../cmpapi.h"
00070 #include <stdio.h>
00071 #include <stdlib.h>
00072 #include <string.h>
00073 #include <sys/types.h>
00074 #include <regex.h>
00075 #include <time.h>
00076 #include <sys/time.h>
00077
00078 #include "textops.h"
00079 #include "txt_var.h"
00080 #include "api.h"
00081
00082 MODULE_VERSION
00083
00084
00085
00086
00087
00088
00089
00090
00091 #define TIME_FORMAT "Date: %a, %d %b %Y %H:%M:%S GMT"
00092 #define MAX_TIME 64
00093
00094
00095 static int search_body_f(struct sip_msg*, char*, char*);
00096 static int replace_f(struct sip_msg*, char*, char*);
00097 static int replace_body_f(struct sip_msg*, char*, char*);
00098 static int replace_all_f(struct sip_msg*, char*, char*);
00099 static int replace_body_all_f(struct sip_msg*, char*, char*);
00100 static int replace_body_atonce_f(struct sip_msg*, char*, char*);
00101 static int subst_f(struct sip_msg*, char*, char*);
00102 static int subst_uri_f(struct sip_msg*, char*, char*);
00103 static int subst_user_f(struct sip_msg*, char*, char*);
00104 static int subst_body_f(struct sip_msg*, char*, char*);
00105 static int filter_body_f(struct sip_msg*, char*, char*);
00106 static int is_present_hf_f(struct sip_msg* msg, char* str_hf, char* foo);
00107 static int search_append_body_f(struct sip_msg*, char*, char*);
00108 static int append_to_reply_f(struct sip_msg* msg, char* key, char* str);
00109 static int append_hf_1(struct sip_msg* msg, char* str1, char* str2);
00110 static int append_hf_2(struct sip_msg* msg, char* str1, char* str2);
00111 static int insert_hf_1(struct sip_msg* msg, char* str1, char* str2);
00112 static int insert_hf_2(struct sip_msg* msg, char* str1, char* str2);
00113 static int append_urihf(struct sip_msg* msg, char* str1, char* str2);
00114 static int append_time_f(struct sip_msg* msg, char* , char *);
00115 static int set_body_f(struct sip_msg* msg, char*, char *);
00116 static int set_rpl_body_f(struct sip_msg* msg, char*, char *);
00117 static int is_method_f(struct sip_msg* msg, char* , char *);
00118 static int has_body_f(struct sip_msg *msg, char *type, char *str2 );
00119 static int is_privacy_f(struct sip_msg *msg, char *privacy, char *str2 );
00120 static int cmp_str_f(struct sip_msg *msg, char *str1, char *str2 );
00121 static int cmp_istr_f(struct sip_msg *msg, char *str1, char *str2 );
00122 static int remove_hf_re_f(struct sip_msg* msg, char* key, char* foo);
00123 static int is_present_hf_re_f(struct sip_msg* msg, char* key, char* foo);
00124
00125 static int fixup_substre(void**, int);
00126 static int hname_fixup(void** param, int param_no);
00127 static int free_hname_fixup(void** param, int param_no);
00128 static int fixup_method(void** param, int param_no);
00129 static int add_header_fixup(void** param, int param_no);
00130 static int fixup_body_type(void** param, int param_no);
00131 static int fixup_privacy(void** param, int param_no);
00132
00133 static int mod_init(void);
00134
00135 static tr_export_t mod_trans[] = {
00136 { {"re", sizeof("re")-1},
00137 tr_txt_parse_re },
00138
00139 { { 0, 0 }, 0 }
00140 };
00141
00142 static cmd_export_t cmds[]={
00143 {"search", (cmd_function)search_f, 1,
00144 fixup_regexp_null, fixup_free_regexp_null,
00145 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00146 {"search_body", (cmd_function)search_body_f, 1,
00147 fixup_regexp_null, fixup_free_regexp_null,
00148 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00149 {"search_append", (cmd_function)search_append_f, 2,
00150 fixup_regexp_none,fixup_free_regexp_none,
00151 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00152 {"search_append_body", (cmd_function)search_append_body_f, 2,
00153 fixup_regexp_none, fixup_free_regexp_none,
00154 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00155 {"replace", (cmd_function)replace_f, 2,
00156 fixup_regexp_none, fixup_free_regexp_none,
00157 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00158 {"replace_body", (cmd_function)replace_body_f, 2,
00159 fixup_regexp_none, fixup_free_regexp_none,
00160 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00161 {"replace_all", (cmd_function)replace_all_f, 2,
00162 fixup_regexp_none, fixup_free_regexp_none,
00163 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00164 {"replace_body_all", (cmd_function)replace_body_all_f,2,
00165 fixup_regexp_none, fixup_free_regexp_none,
00166 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00167 {"replace_body_atonce", (cmd_function)replace_body_atonce_f,2,
00168 fixup_regexpNL_none, fixup_free_regexp_none,
00169 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00170 {"append_to_reply", (cmd_function)append_to_reply_f, 1,
00171 fixup_spve_null, 0,
00172 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ERROR_ROUTE},
00173 {"append_hf", (cmd_function)append_hf_1, 1,
00174 add_header_fixup, 0,
00175 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00176 {"append_hf", (cmd_function)append_hf_2, 2,
00177 add_header_fixup, 0,
00178 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00179 {"insert_hf", (cmd_function)insert_hf_1, 1,
00180 add_header_fixup, 0,
00181 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00182 {"insert_hf", (cmd_function)insert_hf_2, 2,
00183 add_header_fixup, 0,
00184 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00185 {"append_urihf", (cmd_function)append_urihf, 2,
00186 fixup_str_str, fixup_free_str_str,
00187 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
00188 {"remove_hf", (cmd_function)remove_hf_f, 1,
00189 hname_fixup, free_hname_fixup,
00190 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00191 {"remove_hf_re", (cmd_function)remove_hf_re_f, 1,
00192 fixup_regexp_null, fixup_free_regexp_null,
00193 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00194 {"is_present_hf", (cmd_function)is_present_hf_f, 1,
00195 hname_fixup, free_hname_fixup,
00196 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00197 {"is_present_hf_re", (cmd_function)is_present_hf_re_f,1,
00198 fixup_regexp_null, fixup_free_regexp_null,
00199 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00200 {"subst", (cmd_function)subst_f, 1,
00201 fixup_substre, 0,
00202 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00203 {"subst_uri", (cmd_function)subst_uri_f, 1,
00204 fixup_substre, 0,
00205 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
00206 {"subst_user", (cmd_function)subst_user_f, 1,
00207 fixup_substre, 0,
00208 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
00209 {"subst_body", (cmd_function)subst_body_f, 1,
00210 fixup_substre, 0,
00211 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00212 {"filter_body", (cmd_function)filter_body_f, 1,
00213 fixup_str_null, 0,
00214 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00215 {"append_time", (cmd_function)append_time_f, 0,
00216 0, 0,
00217 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00218 {"set_body", (cmd_function)set_body_f, 2,
00219 fixup_spve_spve, 0,
00220 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE },
00221 {"set_reply_body", (cmd_function)set_rpl_body_f, 2,
00222 fixup_spve_spve, 0,
00223 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00224 {"is_method", (cmd_function)is_method_f, 1,
00225 fixup_method, 0,
00226 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00227 {"has_body", (cmd_function)has_body_f, 0,
00228 0, 0,
00229 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00230 {"has_body", (cmd_function)has_body_f, 1,
00231 fixup_body_type, 0,
00232 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00233 {"is_privacy", (cmd_function)is_privacy_f, 1,
00234 fixup_privacy, 0,
00235 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00236 {"cmp_str", (cmd_function)cmp_str_f, 2,
00237 fixup_spve_spve, 0,
00238 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00239 {"cmp_istr", (cmd_function)cmp_istr_f, 2,
00240 fixup_spve_spve, 0,
00241 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00242
00243 {0,0,0,0,0,0}
00244 };
00245
00246
00247 struct module_exports exports= {
00248 "textops",
00249 DEFAULT_DLFLAGS,
00250 cmds,
00251 0,
00252 0,
00253 0,
00254 0,
00255 0,
00256 mod_init,
00257 0,
00258 0,
00259 0,
00260 };
00261
00262
00263 static int mod_init(void)
00264 {
00265 return 0;
00266 }
00267
00268 int mod_register(char *path, int *dlflags, void *p1, void *p2)
00269 {
00270 return register_trans_mod(path, mod_trans);
00271 }
00272
00273 static char *get_header(struct sip_msg *msg)
00274 {
00275 return msg->buf+msg->first_line.len;
00276 }
00277
00278
00279
00280 int search_f(struct sip_msg* msg, char* key, char* str2)
00281 {
00282
00283 regmatch_t pmatch;
00284
00285 if (regexec((regex_t*) key, msg->buf, 1, &pmatch, 0)!=0) return -1;
00286 return 1;
00287 }
00288
00289
00290 static int search_body_f(struct sip_msg* msg, char* key, char* str2)
00291 {
00292 str body;
00293
00294 regmatch_t pmatch;
00295
00296 body.s = get_body(msg);
00297 if (body.s==0) {
00298 LM_ERR("failed to get the message body\n");
00299 return -1;
00300 }
00301 body.len = msg->len -(int)(body.s-msg->buf);
00302 if (body.len==0) {
00303 LM_DBG("message body has zero length\n");
00304 return -1;
00305 }
00306
00307 if (regexec((regex_t*) key, body.s, 1, &pmatch, 0)!=0) return -1;
00308 return 1;
00309 }
00310
00311
00312 int search_append_f(struct sip_msg* msg, char* key, char* str2)
00313 {
00314 struct lump* l;
00315 regmatch_t pmatch;
00316 char* s;
00317 int len;
00318 char *begin;
00319 int off;
00320
00321 begin=get_header(msg);
00322 off=begin-msg->buf;
00323
00324 if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
00325 if (pmatch.rm_so!=-1){
00326 if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0, 0))==0)
00327 return -1;
00328 len=strlen(str2);
00329 s=pkg_malloc(len);
00330 if (s==0){
00331 LM_ERR("memory allocation failure\n");
00332 return -1;
00333 }
00334 memcpy(s, str2, len);
00335 if (insert_new_lump_after(l, s, len, 0)==0){
00336 LM_ERR("could not insert new lump\n");
00337 pkg_free(s);
00338 return -1;
00339 }
00340 return 1;
00341 }
00342 return -1;
00343 }
00344
00345 static int search_append_body_f(struct sip_msg* msg, char* key, char* str2)
00346 {
00347 struct lump* l;
00348 regmatch_t pmatch;
00349 char* s;
00350 int len;
00351 int off;
00352 str body;
00353
00354 body.s = get_body(msg);
00355 if (body.s==0) {
00356 LM_ERR("failed to get the message body\n");
00357 return -1;
00358 }
00359 body.len = msg->len -(int)(body.s-msg->buf);
00360 if (body.len==0) {
00361 LM_DBG("message body has zero length\n");
00362 return -1;
00363 }
00364
00365 off=body.s-msg->buf;
00366
00367 if (regexec((regex_t*) key, body.s, 1, &pmatch, 0)!=0) return -1;
00368 if (pmatch.rm_so!=-1){
00369 if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0, 0))==0)
00370 return -1;
00371 len=strlen(str2);
00372 s=pkg_malloc(len);
00373 if (s==0){
00374 LM_ERR("memory allocation failure\n");
00375 return -1;
00376 }
00377 memcpy(s, str2, len);
00378 if (insert_new_lump_after(l, s, len, 0)==0){
00379 LM_ERR("could not insert new lump\n");
00380 pkg_free(s);
00381 return -1;
00382 }
00383 return 1;
00384 }
00385 return -1;
00386 }
00387
00388
00389 static int replace_all_f(struct sip_msg* msg, char* key, char* str2)
00390 {
00391 struct lump* l;
00392 regmatch_t pmatch;
00393 char* s;
00394 int len;
00395 char* begin;
00396 int off;
00397 int ret;
00398 int eflags;
00399
00400 begin = get_header(msg);
00401 ret=-1;
00402 len=strlen(str2);
00403 eflags=0;
00404
00405 while (begin<msg->buf+msg->len
00406 && regexec((regex_t*) key, begin, 1, &pmatch, eflags)==0) {
00407 off=begin-msg->buf;
00408 if (pmatch.rm_so==-1){
00409 LM_ERR("offset unknown\n");
00410 return -1;
00411 }
00412 if (pmatch.rm_so==pmatch.rm_eo){
00413 LM_ERR("matched string is empty... invalid regexp?\n");
00414 return -1;
00415 }
00416 if ((l=del_lump(msg, pmatch.rm_so+off,
00417 pmatch.rm_eo-pmatch.rm_so, 0))==0) {
00418 LM_ERR("del_lump failed\n");
00419 return -1;
00420 }
00421 s=pkg_malloc(len);
00422 if (s==0){
00423 LM_ERR("memory allocation failure\n");
00424 return -1;
00425 }
00426 memcpy(s, str2, len);
00427 if (insert_new_lump_after(l, s, len, 0)==0){
00428 LM_ERR("could not insert new lump\n");
00429 pkg_free(s);
00430 return -1;
00431 }
00432
00433 begin=begin+pmatch.rm_eo;
00434
00435 if (*(begin-1)=='\n' || *(begin-1)=='\r')
00436 eflags&=~REG_NOTBOL;
00437 else
00438 eflags|=REG_NOTBOL;
00439 ret=1;
00440 }
00441 return ret;
00442 }
00443
00444 static int do_replace_body_f(struct sip_msg* msg, char* key, char* str2, int nobol)
00445 {
00446 struct lump* l;
00447 regmatch_t pmatch;
00448 char* s;
00449 int len;
00450 char* begin;
00451 int off;
00452 int ret;
00453 int eflags;
00454 str body;
00455
00456 body.s = get_body(msg);
00457 if (body.s==0) {
00458 LM_ERR("failed to get the message body\n");
00459 return -1;
00460 }
00461 body.len = msg->len -(int)(body.s-msg->buf);
00462 if (body.len==0) {
00463 LM_DBG("message body has zero length\n");
00464 return -1;
00465 }
00466
00467 begin=body.s;
00468 ret=-1;
00469 len=strlen(str2);
00470 eflags=0;
00471
00472 while (begin<msg->buf+msg->len
00473 && regexec((regex_t*) key, begin, 1, &pmatch, eflags)==0) {
00474 off=begin-msg->buf;
00475 if (pmatch.rm_so==-1){
00476 LM_ERR("offset unknown\n");
00477 return -1;
00478 }
00479 if (pmatch.rm_so==pmatch.rm_eo){
00480 LM_ERR("matched string is empty... invalid regexp?\n");
00481 return -1;
00482 }
00483 if ((l=del_lump(msg, pmatch.rm_so+off,
00484 pmatch.rm_eo-pmatch.rm_so, 0))==0) {
00485 LM_ERR("del_lump failed\n");
00486 return -1;
00487 }
00488 s=pkg_malloc(len);
00489 if (s==0){
00490 LM_ERR("memory allocation failure\n");
00491 return -1;
00492 }
00493 memcpy(s, str2, len);
00494 if (insert_new_lump_after(l, s, len, 0)==0){
00495 LM_ERR("could not insert new lump\n");
00496 pkg_free(s);
00497 return -1;
00498 }
00499
00500 begin=begin+pmatch.rm_eo;
00501
00502 if (nobol && (*(begin-1)=='\n' || *(begin-1)=='\r'))
00503 eflags&=~REG_NOTBOL;
00504 else
00505 eflags|=REG_NOTBOL;
00506 ret=1;
00507 }
00508 return ret;
00509 }
00510
00511 static int replace_body_all_f(struct sip_msg* msg, char* key, char* str2)
00512 {
00513 return do_replace_body_f(msg, key, str2, 1);
00514 }
00515
00516 static int replace_body_atonce_f(struct sip_msg* msg, char* key, char* str2)
00517 {
00518 return do_replace_body_f(msg, key, str2, 0);
00519 }
00520
00521 static int replace_f(struct sip_msg* msg, char* key, char* str2)
00522 {
00523 struct lump* l;
00524 regmatch_t pmatch;
00525 char* s;
00526 int len;
00527 char* begin;
00528 int off;
00529
00530 begin=get_header(msg);
00531
00532 if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
00533 off=begin-msg->buf;
00534
00535 if (pmatch.rm_so!=-1){
00536 if ((l=del_lump(msg, pmatch.rm_so+off,
00537 pmatch.rm_eo-pmatch.rm_so, 0))==0)
00538 return -1;
00539 len=strlen(str2);
00540 s=pkg_malloc(len);
00541 if (s==0){
00542 LM_ERR("memory allocation failure\n");
00543 return -1;
00544 }
00545 memcpy(s, str2, len);
00546 if (insert_new_lump_after(l, s, len, 0)==0){
00547 LM_ERR("could not insert new lump\n");
00548 pkg_free(s);
00549 return -1;
00550 }
00551
00552 return 1;
00553 }
00554 return -1;
00555 }
00556
00557 static int replace_body_f(struct sip_msg* msg, char* key, char* str2)
00558 {
00559 struct lump* l;
00560 regmatch_t pmatch;
00561 char* s;
00562 int len;
00563 char* begin;
00564 int off;
00565 str body;
00566
00567 body.s = get_body(msg);
00568 if (body.s==0) {
00569 LM_ERR("failed to get the message body\n");
00570 return -1;
00571 }
00572 body.len = msg->len -(int)(body.s-msg->buf);
00573 if (body.len==0) {
00574 LM_DBG("message body has zero length\n");
00575 return -1;
00576 }
00577
00578 begin=body.s;
00579
00580 if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
00581 off=begin-msg->buf;
00582
00583 if (pmatch.rm_so!=-1){
00584 if ((l=del_lump(msg, pmatch.rm_so+off,
00585 pmatch.rm_eo-pmatch.rm_so, 0))==0)
00586 return -1;
00587 len=strlen(str2);
00588 s=pkg_malloc(len);
00589 if (s==0){
00590 LM_ERR("memory allocation failure\n");
00591 return -1;
00592 }
00593 memcpy(s, str2, len);
00594 if (insert_new_lump_after(l, s, len, 0)==0){
00595 LM_ERR("could not insert new lump\n");
00596 pkg_free(s);
00597 return -1;
00598 }
00599
00600 return 1;
00601 }
00602 return -1;
00603 }
00604
00605
00606
00607 static int subst_f(struct sip_msg* msg, char* subst, char* ignored)
00608 {
00609 struct lump* l;
00610 struct replace_lst* lst;
00611 struct replace_lst* rpl;
00612 char* begin;
00613 struct subst_expr* se;
00614 int off;
00615 int ret;
00616 int nmatches;
00617
00618 se=(struct subst_expr*)subst;
00619 begin=get_header(msg);
00620
00621 off=begin-msg->buf;
00622 ret=-1;
00623 if ((lst=subst_run(se, begin, msg, &nmatches))==0)
00624 goto error;
00625 for (rpl=lst; rpl; rpl=rpl->next){
00626 LM_DBG("%s: replacing at offset %d [%.*s] with [%.*s]\n",
00627 exports.name, rpl->offset+off,
00628 rpl->size, rpl->offset+off+msg->buf,
00629 rpl->rpl.len, rpl->rpl.s);
00630 if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
00631 goto error;
00632
00633
00634 if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
00635 LM_ERR("%s: could not insert new lump\n", exports.name);
00636 goto error;
00637 }
00638
00639
00640 rpl->rpl.s=0;
00641 rpl->rpl.len=0;
00642 }
00643 ret=1;
00644 error:
00645 LM_DBG("lst was %p\n", lst);
00646 if (lst) replace_lst_free(lst);
00647 if (nmatches<0)
00648 LM_ERR("%s: subst_run failed\n", exports.name);
00649 return ret;
00650 }
00651
00652
00653
00654
00655
00656 static int subst_uri_f(struct sip_msg* msg, char* subst, char* ignored)
00657 {
00658 char* tmp;
00659 int len;
00660 char c;
00661 struct subst_expr* se;
00662 str* result;
00663
00664 se=(struct subst_expr*)subst;
00665 if (msg->new_uri.s){
00666 len=msg->new_uri.len;
00667 tmp=msg->new_uri.s;
00668 }else{
00669 tmp=msg->first_line.u.request.uri.s;
00670 len =msg->first_line.u.request.uri.len;
00671 };
00672
00673
00674
00675
00676 c=tmp[len];
00677 tmp[len]=0;
00678 result=subst_str(tmp, msg, se, 0);
00679 tmp[len]=c;
00680 if (result){
00681 LM_DBG("%s match - old uri= [%.*s], new uri= [%.*s]\n",
00682 exports.name, len, tmp,
00683 (result->len)?result->len:0,(result->s)?result->s:"");
00684 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
00685 msg->new_uri=*result;
00686 msg->parsed_uri_ok=0;
00687 pkg_free(result);
00688 return 1;
00689 }
00690 return -1;
00691 }
00692
00693
00694
00695
00696
00697 static int subst_user_f(struct sip_msg* msg, char* subst, char* ignored)
00698 {
00699 int rval;
00700 str* result;
00701 struct subst_expr* se;
00702 struct action act;
00703 str user;
00704 char c;
00705 int nmatches;
00706
00707 c=0;
00708 if (parse_sip_msg_uri(msg)<0){
00709 return -1;
00710 }
00711 if (msg->parsed_uri.user.s==0){
00712
00713 user.s="";
00714 user.len=0;
00715 }else{
00716 user=msg->parsed_uri.user;
00717 c=user.s[user.len];
00718 user.s[user.len]=0;
00719 }
00720 se=(struct subst_expr*)subst;
00721 result=subst_str(user.s, msg, se, &nmatches);
00722 if (c) user.s[user.len]=c;
00723 if (result == NULL) {
00724 if (nmatches<0)
00725 LM_ERR("subst_user(): subst_str() failed\n");
00726 return -1;
00727 }
00728
00729 memset(&act, 0, sizeof(act));
00730 act.type = SET_USER_T;
00731 act.elem[0].type = STRING_ST;
00732 act.elem[0].u.string = result->s;
00733 rval = do_action(&act, msg);
00734 pkg_free(result->s);
00735 pkg_free(result);
00736 return rval;
00737 }
00738
00739
00740
00741 static int subst_body_f(struct sip_msg* msg, char* subst, char* ignored)
00742 {
00743 struct lump* l;
00744 struct replace_lst* lst;
00745 struct replace_lst* rpl;
00746 char* begin;
00747 struct subst_expr* se;
00748 int off;
00749 int ret;
00750 int nmatches;
00751 str body;
00752
00753 body.s = get_body(msg);
00754 if (body.s==0) {
00755 LM_ERR("failed to get the message body\n");
00756 return -1;
00757 }
00758 body.len = msg->len -(int)(body.s-msg->buf);
00759 if (body.len==0) {
00760 LM_DBG("message body has zero length\n");
00761 return -1;
00762 }
00763
00764 se=(struct subst_expr*)subst;
00765 begin=body.s;
00766
00767 off=begin-msg->buf;
00768 ret=-1;
00769 if ((lst=subst_run(se, begin, msg, &nmatches))==0)
00770 goto error;
00771 for (rpl=lst; rpl; rpl=rpl->next){
00772 LM_DBG("%s replacing at offset %d [%.*s] with [%.*s]\n",
00773 exports.name, rpl->offset+off,
00774 rpl->size, rpl->offset+off+msg->buf,
00775 rpl->rpl.len, rpl->rpl.s);
00776 if ((l=del_lump(msg, rpl->offset+off, rpl->size, 0))==0)
00777 goto error;
00778
00779
00780 if (insert_new_lump_after(l, rpl->rpl.s, rpl->rpl.len, 0)==0){
00781 LM_ERR("%s could not insert new lump\n",
00782 exports.name);
00783 goto error;
00784 }
00785
00786
00787 rpl->rpl.s=0;
00788 rpl->rpl.len=0;
00789 }
00790 ret=1;
00791 error:
00792 LM_DBG("lst was %p\n", lst);
00793 if (lst) replace_lst_free(lst);
00794 if (nmatches<0)
00795 LM_ERR("%s subst_run failed\n", exports.name);
00796 return ret;
00797 }
00798
00799
00800 static inline int find_line_start(char *text, unsigned int text_len,
00801 char **buf, unsigned int *buf_len)
00802 {
00803 char *ch, *start;
00804 unsigned int len;
00805
00806 start = *buf;
00807 len = *buf_len;
00808
00809 while (text_len <= len) {
00810 if (strncmp(text, start, text_len) == 0) {
00811 *buf = start;
00812 *buf_len = len;
00813 return 1;
00814 }
00815 if ((ch = memchr(start, 13, len - 1))) {
00816 if (*(ch + 1) != 10) {
00817 LM_ERR("No LF after CR\n");
00818 return 0;
00819 }
00820 len = len - (ch - start + 2);
00821 start = ch + 2;
00822 } else {
00823 LM_ERR("No CRLF found\n");
00824 return 0;
00825 }
00826 }
00827 return 0;
00828 }
00829
00830
00831
00832
00833 static int filter_body_f(struct sip_msg* msg, char* _content_type,
00834 char* ignored)
00835 {
00836 char *start;
00837 unsigned int len;
00838 str *content_type, body;
00839
00840 body.s = get_body(msg);
00841 if (body.s == 0) {
00842 LM_ERR("Failed to get the message body\n");
00843 return -1;
00844 }
00845 body.len = msg->len - (int)(body.s - msg->buf);
00846 if (body.len == 0) {
00847 LM_DBG("Message body has zero length\n");
00848 return -1;
00849 }
00850
00851 content_type = (str *)_content_type;
00852 start = body.s;
00853 len = body.len;
00854
00855 while (find_line_start("Content-Type: ", 14, &start, &len)) {
00856 start = start + 14;
00857 len = len - 14;
00858 if (len > content_type->len + 2) {
00859 if (strncasecmp(start, content_type->s, content_type->len)
00860 == 0) {
00861 start = start + content_type->len;
00862 if ((*start != 13) || (*(start + 1) != 10)) {
00863 LM_ERR("No CRLF found after content type\n");
00864 return -1;
00865 }
00866 start = start + 2;
00867 len = len - content_type->len - 2;
00868 while ((len > 0) && ((*start == 13) || (*start == 10))) {
00869 len = len - 1;
00870 start = start + 1;
00871 }
00872 if (del_lump(msg, body.s - msg->buf, start - body.s, 0)
00873 == 0) {
00874 LM_ERR("Deleting lump <%.*s> failed\n",
00875 (int)(start - body.s), body.s);
00876 return -1;
00877 }
00878 if (find_line_start("--Boundary", 10, &start, &len)) {
00879 if (del_lump(msg, start - msg->buf, len, 0) == 0) {
00880 LM_ERR("Deleting lump <%.*s> failed\n",
00881 len, start);
00882 return -1;
00883 } else {
00884 return 1;
00885 }
00886 } else {
00887 LM_ERR("Boundary not found after content\n");
00888 return -1;
00889 }
00890 }
00891 } else {
00892 return -1;
00893 }
00894 }
00895 return -1;
00896 }
00897
00898
00899 int remove_hf_f(struct sip_msg* msg, char* str_hf, char* foo)
00900 {
00901 struct hdr_field *hf;
00902 struct lump* l;
00903 int cnt;
00904 gparam_p gp;
00905
00906 gp = (gparam_p)str_hf;
00907 cnt=0;
00908
00909
00910 parse_headers(msg, HDR_EOH_F, 0);
00911 for (hf=msg->headers; hf; hf=hf->next) {
00912
00913
00914
00915 if(gp->type==GPARAM_TYPE_INT)
00916 {
00917 if (gp->v.ival!=hf->type)
00918 continue;
00919 } else {
00920 if (hf->name.len!=gp->v.sval.len)
00921 continue;
00922 if (cmp_hdrname_str(&hf->name, &gp->v.sval)!=0)
00923 continue;
00924 }
00925 l=del_lump(msg, hf->name.s-msg->buf, hf->len, 0);
00926 if (l==0) {
00927 LM_ERR("no memory\n");
00928 return -1;
00929 }
00930 cnt++;
00931 }
00932 return cnt==0 ? -1 : 1;
00933 }
00934
00935 static int remove_hf_re_f(struct sip_msg* msg, char* key, char* foo)
00936 {
00937 struct hdr_field *hf;
00938 struct lump* l;
00939 int cnt;
00940 regex_t *re;
00941 char c;
00942 regmatch_t pmatch;
00943
00944 re = (regex_t*)key;
00945 cnt=0;
00946
00947
00948 parse_headers(msg, HDR_EOH_F, 0);
00949 for (hf=msg->headers; hf; hf=hf->next)
00950 {
00951 c = hf->name.s[hf->name.len];
00952 hf->name.s[hf->name.len] = '\0';
00953 if (regexec(re, hf->name.s, 1, &pmatch, 0)!=0)
00954 {
00955 hf->name.s[hf->name.len] = c;
00956 continue;
00957 }
00958 hf->name.s[hf->name.len] = c;
00959 l=del_lump(msg, hf->name.s-msg->buf, hf->len, 0);
00960 if (l==0)
00961 {
00962 LM_ERR("cannot remove header\n");
00963 return -1;
00964 }
00965 cnt++;
00966 }
00967
00968 return cnt==0 ? -1 : 1;
00969 }
00970
00971 static int is_present_hf_f(struct sip_msg* msg, char* str_hf, char* foo)
00972 {
00973 struct hdr_field *hf;
00974 gparam_p gp;
00975
00976 gp = (gparam_p)str_hf;
00977
00978
00979 parse_headers(msg, HDR_EOH_F, 0);
00980 for (hf=msg->headers; hf; hf=hf->next) {
00981 if(gp->type==GPARAM_TYPE_INT)
00982 {
00983 if (gp->v.ival!=hf->type)
00984 continue;
00985 } else {
00986 if (hf->name.len!=gp->v.sval.len)
00987 continue;
00988 if (cmp_hdrname_str(&hf->name,&gp->v.sval)!=0)
00989 continue;
00990 }
00991 return 1;
00992 }
00993 return -1;
00994 }
00995
00996 static int is_present_hf_re_f(struct sip_msg* msg, char* key, char* foo)
00997 {
00998 struct hdr_field *hf;
00999 regex_t *re;
01000 regmatch_t pmatch;
01001 char c;
01002
01003 re = (regex_t*)key;
01004
01005
01006 parse_headers(msg, HDR_EOH_F, 0);
01007 for (hf=msg->headers; hf; hf=hf->next)
01008 {
01009 c = hf->name.s[hf->name.len];
01010 hf->name.s[hf->name.len] = '\0';
01011 if (regexec(re, hf->name.s, 1, &pmatch, 0)!=0)
01012 {
01013 hf->name.s[hf->name.len] = c;
01014 continue;
01015 }
01016 hf->name.s[hf->name.len] = c;
01017 return 1;
01018 }
01019
01020 return -1;
01021 }
01022
01023
01024 static int fixup_substre(void** param, int param_no)
01025 {
01026 struct subst_expr* se;
01027 str subst;
01028
01029 LM_DBG("%s module -- fixing %s\n", exports.name, (char*)(*param));
01030 if (param_no!=1) return 0;
01031 subst.s=*param;
01032 subst.len=strlen(*param);
01033 se=subst_parser(&subst);
01034 if (se==0){
01035 LM_ERR("%s: bad subst. re %s\n", exports.name,
01036 (char*)*param);
01037 return E_BAD_RE;
01038 }
01039
01040
01041
01042 *param=se;
01043 return 0;
01044 }
01045
01046
01047 static int append_time_f(struct sip_msg* msg, char* p1, char *p2)
01048 {
01049
01050
01051 size_t len;
01052 char time_str[MAX_TIME];
01053 time_t now;
01054 struct tm *bd_time;
01055
01056 now=time(0);
01057
01058 bd_time=gmtime(&now);
01059 if (bd_time==NULL) {
01060 LM_ERR("gmtime failed\n");
01061 return -1;
01062 }
01063
01064 len=strftime(time_str, MAX_TIME, TIME_FORMAT, bd_time);
01065 if (len>MAX_TIME-2 || len==0) {
01066 LM_ERR("unexpected time length\n");
01067 return -1;
01068 }
01069
01070 time_str[len]='\r';
01071 time_str[len+1]='\n';
01072
01073
01074 if (add_lump_rpl(msg, time_str, len+2, LUMP_RPL_HDR)==0)
01075 {
01076 LM_ERR("unable to add lump\n");
01077 return -1;
01078 }
01079
01080 return 1;
01081 }
01082
01083
01084 static int set_body_f(struct sip_msg* msg, char* p1, char* p2)
01085 {
01086 struct lump *anchor;
01087 char* buf;
01088 int len;
01089 char* value_s;
01090 int value_len;
01091 str body = {0,0};
01092 str nb = {0,0};
01093 str nc = {0,0};
01094
01095 if(p1==0 || p2==0)
01096 {
01097 LM_ERR("invalid parameters\n");
01098 return -1;
01099 }
01100
01101 if(fixup_get_svalue(msg, (gparam_p)p1, &nb)!=0)
01102 {
01103 LM_ERR("unable to get p1\n");
01104 return -1;
01105 }
01106 if(nb.s==NULL || nb.len == 0)
01107 {
01108 LM_ERR("invalid body parameter\n");
01109 return -1;
01110 }
01111 if(fixup_get_svalue(msg, (gparam_p)p2, &nc)!=0)
01112 {
01113 LM_ERR("unable to get p2\n");
01114 return -1;
01115 }
01116 if(nc.s==NULL || nc.len == 0)
01117 {
01118 LM_ERR("invalid content-type parameter\n");
01119 return -1;
01120 }
01121
01122 body.len = 0;
01123 body.s = get_body(msg);
01124 if (body.s==0)
01125 {
01126 LM_ERR("malformed sip message\n");
01127 return -1;
01128 }
01129
01130 free_lump_list(msg->body_lumps);
01131 msg->body_lumps = NULL;
01132
01133 if (msg->content_length)
01134 {
01135 body.len = get_content_length( msg );
01136 if(body.len > 0)
01137 {
01138 if(body.s+body.len>msg->buf+msg->len)
01139 {
01140 LM_ERR("invalid content length: %d\n", body.len);
01141 return -1;
01142 }
01143 if(del_lump(msg, body.s - msg->buf, body.len, 0) == 0)
01144 {
01145 LM_ERR("cannot delete existing body");
01146 return -1;
01147 }
01148 }
01149 }
01150
01151 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
01152
01153 if (anchor == 0)
01154 {
01155 LM_ERR("failed to get anchor\n");
01156 return -1;
01157 }
01158
01159 if (msg->content_length==0)
01160 {
01161
01162 len = nb.len;
01163 value_s=int2str(len, &value_len);
01164 LM_DBG("content-length: %d (%s)\n", value_len, value_s);
01165
01166 len=CONTENT_LENGTH_LEN+value_len+CRLF_LEN;
01167 buf=pkg_malloc(sizeof(char)*(len));
01168
01169 if (buf==0)
01170 {
01171 LM_ERR("out of pkg memory\n");
01172 return -1;
01173 }
01174
01175 memcpy(buf, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
01176 memcpy(buf+CONTENT_LENGTH_LEN, value_s, value_len);
01177 memcpy(buf+CONTENT_LENGTH_LEN+value_len, CRLF, CRLF_LEN);
01178 if (insert_new_lump_after(anchor, buf, len, 0) == 0)
01179 {
01180 LM_ERR("failed to insert content-length lump\n");
01181 pkg_free(buf);
01182 return -1;
01183 }
01184 }
01185
01186
01187 if(msg->content_type==NULL || msg->content_type->body.len!=nc.len
01188 || strncmp(msg->content_type->body.s, nc.s, nc.len)!=0)
01189 {
01190 if(msg->content_type!=NULL)
01191 if(del_lump(msg, msg->content_type->name.s-msg->buf,
01192 msg->content_type->len, 0) == 0)
01193 {
01194 LM_ERR("failed to delete content type\n");
01195 return -1;
01196 }
01197 value_len = nc.len;
01198 len=sizeof("Content-Type: ") - 1 + value_len + CRLF_LEN;
01199 buf=pkg_malloc(sizeof(char)*(len));
01200
01201 if (buf==0)
01202 {
01203 LM_ERR("out of pkg memory\n");
01204 return -1;
01205 }
01206 memcpy(buf, "Content-Type: ", sizeof("Content-Type: ") - 1);
01207 memcpy(buf+sizeof("Content-Type: ") - 1, nc.s, value_len);
01208 memcpy(buf+sizeof("Content-Type: ") - 1 + value_len, CRLF, CRLF_LEN);
01209 if (insert_new_lump_after(anchor, buf, len, 0) == 0)
01210 {
01211 LM_ERR("failed to insert content-type lump\n");
01212 pkg_free(buf);
01213 return -1;
01214 }
01215 }
01216 anchor = anchor_lump(msg, body.s - msg->buf, 0, 0);
01217
01218 if (anchor == 0)
01219 {
01220 LM_ERR("failed to get body anchor\n");
01221 return -1;
01222 }
01223
01224 buf=pkg_malloc(sizeof(char)*(nb.len));
01225 if (buf==0)
01226 {
01227 LM_ERR("out of pkg memory\n");
01228 return -1;
01229 }
01230 memcpy(buf, nb.s, nb.len);
01231 if (insert_new_lump_after(anchor, buf, nb.len, 0) == 0)
01232 {
01233 LM_ERR("failed to insert body lump\n");
01234 pkg_free(buf);
01235 return -1;
01236 }
01237 LM_DBG("new body: [%.*s]", nb.len, nb.s);
01238 return 1;
01239 }
01240
01241 static int set_rpl_body_f(struct sip_msg* msg, char* p1, char* p2)
01242 {
01243 char* buf;
01244 int len;
01245 int value_len;
01246 str nb = {0,0};
01247 str nc = {0,0};
01248
01249 if(p1==0 || p2==0)
01250 {
01251 LM_ERR("invalid parameters\n");
01252 return -1;
01253 }
01254
01255 if(fixup_get_svalue(msg, (gparam_p)p1, &nb)!=0)
01256 {
01257 LM_ERR("unable to get p1\n");
01258 return -1;
01259 }
01260 if(nb.s==NULL || nb.len == 0)
01261 {
01262 LM_ERR("invalid body parameter\n");
01263 return -1;
01264 }
01265 if(fixup_get_svalue(msg, (gparam_p)p2, &nc)!=0)
01266 {
01267 LM_ERR("unable to get p2\n");
01268 return -1;
01269 }
01270 if(nc.s==NULL || nc.len == 0)
01271 {
01272 LM_ERR("invalid content-type parameter\n");
01273 return -1;
01274 }
01275
01276
01277 value_len = nc.len;
01278 len=sizeof("Content-Type: ") - 1 + value_len + CRLF_LEN;
01279 buf=pkg_malloc(sizeof(char)*(len));
01280
01281 if (buf==0)
01282 {
01283 LM_ERR("out of pkg memory\n");
01284 return -1;
01285 }
01286 memcpy(buf, "Content-Type: ", sizeof("Content-Type: ") - 1);
01287 memcpy(buf+sizeof("Content-Type: ") - 1, nc.s, value_len);
01288 memcpy(buf+sizeof("Content-Type: ") - 1 + value_len, CRLF, CRLF_LEN);
01289 if (add_lump_rpl(msg, buf, len, LUMP_RPL_HDR) == 0)
01290 {
01291 LM_ERR("failed to insert content-type lump\n");
01292 pkg_free(buf);
01293 return -1;
01294 }
01295 pkg_free(buf);
01296
01297 if (add_lump_rpl( msg, nb.s, nb.len, LUMP_RPL_BODY)==0) {
01298 LM_ERR("cannot add body lump\n");
01299 return -1;
01300 }
01301
01302 return 1;
01303 }
01304
01305
01306
01307 static int append_to_reply_f(struct sip_msg* msg, char* key, char* str0)
01308 {
01309 str s0;
01310
01311 if(key==NULL)
01312 {
01313 LM_ERR("bad parameters\n");
01314 return -1;
01315 }
01316
01317 if(fixup_get_svalue(msg, (gparam_p)key, &s0)!=0)
01318 {
01319 LM_ERR("cannot print the format\n");
01320 return -1;
01321 }
01322
01323 if ( add_lump_rpl( msg, s0.s, s0.len, LUMP_RPL_HDR)==0 )
01324 {
01325 LM_ERR("unable to add lump_rl\n");
01326 return -1;
01327 }
01328
01329 return 1;
01330 }
01331
01332
01333
01334
01335 int add_hf_helper(struct sip_msg* msg, str *str1, str *str2,
01336 gparam_p hfval, int mode, gparam_p hfanc)
01337 {
01338 struct lump* anchor;
01339 struct hdr_field *hf;
01340 char *s;
01341 int len;
01342 str s0;
01343
01344 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
01345 LM_ERR("error while parsing message\n");
01346 return -1;
01347 }
01348
01349 hf = 0;
01350 if(hfanc!=NULL) {
01351 for (hf=msg->headers; hf; hf=hf->next) {
01352 if(hfanc->type==GPARAM_TYPE_INT)
01353 {
01354 if (hfanc->v.ival!=hf->type)
01355 continue;
01356 } else {
01357 if (hf->name.len!=hfanc->v.sval.len)
01358 continue;
01359 if (cmp_hdrname_str(&hf->name,&hfanc->v.sval)!=0)
01360 continue;
01361 }
01362 break;
01363 }
01364 }
01365
01366 if(mode == 0) {
01367 if(hf==0) {
01368 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
01369 } else {
01370 anchor = anchor_lump(msg, hf->name.s + hf->len - msg->buf, 0, 0);
01371 }
01372 } else {
01373 if(hf==0) {
01374 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
01375 } else {
01376 anchor = anchor_lump(msg, hf->name.s - msg->buf, 0, 0);
01377 }
01378 }
01379
01380 if(anchor == 0) {
01381 LM_ERR("can't get anchor\n");
01382 return -1;
01383 }
01384
01385 if(str1) {
01386 s0 = *str1;
01387 } else {
01388 if(hfval) {
01389 if(fixup_get_svalue(msg, hfval, &s0)!=0)
01390 {
01391 LM_ERR("cannot print the format\n");
01392 return -1;
01393 }
01394 } else {
01395 s0.len = 0;
01396 s0.s = 0;
01397 }
01398 }
01399
01400 len=s0.len;
01401 if (str2) len+= str2->len + REQ_LINE(msg).uri.len;
01402
01403 s = (char*)pkg_malloc(len);
01404 if (!s) {
01405 LM_ERR("no pkg memory left\n");
01406 return -1;
01407 }
01408
01409 memcpy(s, s0.s, s0.len);
01410 if (str2) {
01411 memcpy(s+str1->len, REQ_LINE(msg).uri.s, REQ_LINE(msg).uri.len);
01412 memcpy(s+str1->len+REQ_LINE(msg).uri.len, str2->s, str2->len );
01413 }
01414
01415 if (insert_new_lump_before(anchor, s, len, 0) == 0) {
01416 LM_ERR("can't insert lump\n");
01417 pkg_free(s);
01418 return -1;
01419 }
01420 return 1;
01421 }
01422
01423 static int append_hf_1(struct sip_msg *msg, char *str1, char *str2 )
01424 {
01425 return add_hf_helper(msg, 0, 0, (gparam_p)str1, 0, 0);
01426 }
01427
01428 static int append_hf_2(struct sip_msg *msg, char *str1, char *str2 )
01429 {
01430 return add_hf_helper(msg, 0, 0, (gparam_p)str1, 0,
01431 (gparam_p)str2);
01432 }
01433
01434 static int insert_hf_1(struct sip_msg *msg, char *str1, char *str2 )
01435 {
01436 return add_hf_helper(msg, 0, 0, (gparam_p)str1, 1, 0);
01437 }
01438
01439 static int insert_hf_2(struct sip_msg *msg, char *str1, char *str2 )
01440 {
01441 return add_hf_helper(msg, 0, 0, (gparam_p)str1, 1,
01442 (gparam_p)str2);
01443 }
01444
01445 static int append_urihf(struct sip_msg *msg, char *str1, char *str2)
01446 {
01447 return add_hf_helper(msg, (str*)str1, (str*)str2, 0, 0, 0);
01448 }
01449
01450 static int is_method_f(struct sip_msg *msg, char *meth, char *str2 )
01451 {
01452 str *m;
01453
01454 m = (str*)meth;
01455 if(msg->first_line.type==SIP_REQUEST)
01456 {
01457 if(m->s==0)
01458 return (msg->first_line.u.request.method_value&m->len)?1:-1;
01459 else
01460 return (msg->first_line.u.request.method_value==METHOD_OTHER
01461 && msg->first_line.u.request.method.len==m->len
01462 && (strncasecmp(msg->first_line.u.request.method.s, m->s,
01463 m->len)==0))?1:-1;
01464 }
01465 if(parse_headers(msg, HDR_CSEQ_F, 0)!=0 || msg->cseq==NULL)
01466 {
01467 LM_ERR("cannot parse cseq header\n");
01468 return -1;
01469 }
01470 if(m->s==0)
01471 return (get_cseq(msg)->method_id&m->len)?1:-1;
01472 else
01473 return (get_cseq(msg)->method_id==METHOD_OTHER
01474 && get_cseq(msg)->method.len==m->len
01475 && (strncasecmp(get_cseq(msg)->method.s, m->s,
01476 m->len)==0))?1:-1;
01477 }
01478
01479
01480
01481
01482
01483 static int hname_fixup(void** param, int param_no)
01484 {
01485 char c;
01486 struct hdr_field hdr;
01487 gparam_p gp = NULL;
01488
01489 gp = (gparam_p)pkg_malloc(sizeof(gparam_t));
01490 if(gp == NULL)
01491 {
01492 LM_ERR("no more memory\n");
01493 return E_UNSPEC;
01494 }
01495 memset(gp, 0, sizeof(gparam_t));
01496
01497 gp->v.sval.s = (char*)*param;
01498 gp->v.sval.len = strlen(gp->v.sval.s);
01499 if(gp->v.sval.len==0)
01500 {
01501 LM_ERR("empty header name parameter\n");
01502 pkg_free(gp);
01503 return E_UNSPEC;
01504 }
01505
01506 c = gp->v.sval.s[gp->v.sval.len];
01507 gp->v.sval.s[gp->v.sval.len] = ':';
01508 gp->v.sval.len++;
01509
01510 if (parse_hname2(gp->v.sval.s, gp->v.sval.s
01511 + ((gp->v.sval.len<4)?4:gp->v.sval.len), &hdr)==0)
01512 {
01513 LM_ERR("error parsing header name\n");
01514 pkg_free(gp);
01515 return E_UNSPEC;
01516 }
01517
01518 gp->v.sval.len--;
01519 gp->v.sval.s[gp->v.sval.len] = c;
01520
01521 if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
01522 {
01523 LM_INFO("using hdr type (%d) instead of <%.*s>\n",
01524 hdr.type, gp->v.sval.len, gp->v.sval.s);
01525 pkg_free(gp->v.sval.s);
01526 gp->v.sval.s = NULL;
01527 gp->v.ival = hdr.type;
01528 gp->type = GPARAM_TYPE_INT;
01529 } else {
01530 gp->type = GPARAM_TYPE_STR;
01531 LM_INFO("using hdr type name <%.*s>\n", gp->v.sval.len, gp->v.sval.s);
01532 }
01533
01534 *param = (void*)gp;
01535 return 0;
01536 }
01537
01538 static int free_hname_fixup(void** param, int param_no)
01539 {
01540 if(*param)
01541 {
01542 if(((gparam_p)(*param))->type==GPARAM_TYPE_STR)
01543 pkg_free(((gparam_p)(*param))->v.sval.s);
01544 pkg_free(*param);
01545 *param = 0;
01546 }
01547 return 0;
01548 }
01549
01550
01551
01552
01553 static int fixup_method(void** param, int param_no)
01554 {
01555 str* s;
01556 char *p;
01557 int m;
01558 unsigned int method;
01559
01560 s = (str*)pkg_malloc(sizeof(str));
01561 if (!s) {
01562 LM_ERR("no pkg memory left\n");
01563 return E_UNSPEC;
01564 }
01565
01566 s->s = (char*)*param;
01567 s->len = strlen(s->s);
01568 if(s->len==0)
01569 {
01570 LM_ERR("empty method name\n");
01571 pkg_free(s);
01572 return E_UNSPEC;
01573 }
01574 m=0;
01575 p=s->s;
01576 while(*p)
01577 {
01578 if(*p=='|')
01579 {
01580 *p = ',';
01581 m=1;
01582 }
01583 p++;
01584 }
01585 if(parse_methods(s, &method)!=0)
01586 {
01587 LM_ERR("bad method names\n");
01588 pkg_free(s);
01589 return E_UNSPEC;
01590 }
01591
01592 if(m==1)
01593 {
01594 if(method==METHOD_UNDEF || method&METHOD_OTHER)
01595 {
01596 LM_ERR("unknown method in list [%.*s/%d] - must be only defined methods\n",
01597 s->len, s->s, method);
01598 return E_UNSPEC;
01599 }
01600 LM_DBG("using id for methods [%.*s/%d]\n",
01601 s->len, s->s, method);
01602 s->s = 0;
01603 s->len = method;
01604 } else {
01605 if(method!=METHOD_UNDEF && method!=METHOD_OTHER)
01606 {
01607 LM_DBG("using id for method [%.*s/%d]\n",
01608 s->len, s->s, method);
01609 s->s = 0;
01610 s->len = method;
01611 } else
01612 LM_DBG("name for method [%.*s/%d]\n",
01613 s->len, s->s, method);
01614 }
01615
01616 *param = (void*)s;
01617 return 0;
01618 }
01619
01620
01621
01622
01623 static int fixup_privacy(void** param, int param_no)
01624 {
01625 str p;
01626 unsigned int val;
01627
01628 p.s = (char*)*param;
01629 p.len = strlen(p.s);
01630
01631 if (p.len == 0) {
01632 LM_ERR("empty privacy value\n");
01633 return E_UNSPEC;
01634 }
01635
01636 if (parse_priv_value(p.s, p.len, &val) != p.len) {
01637 LM_ERR("invalid privacy value\n");
01638 return E_UNSPEC;
01639 }
01640
01641 *param = (void *)(long)val;
01642 return 0;
01643 }
01644
01645 static int add_header_fixup(void** param, int param_no)
01646 {
01647 if(param_no==1)
01648 {
01649 return fixup_spve_null(param, param_no);
01650 } else if(param_no==2) {
01651 return hname_fixup(param, param_no);
01652 } else {
01653 LM_ERR("wrong number of parameters\n");
01654 return E_UNSPEC;
01655 }
01656 }
01657
01658
01659 static int fixup_body_type(void** param, int param_no)
01660 {
01661 char *p;
01662 char *r;
01663 unsigned int type;
01664
01665 if(param_no==1) {
01666 p = (char*)*param;
01667 if (p==0 || p[0]==0) {
01668 type = 0;
01669 } else {
01670 r = decode_mime_type( p, p+strlen(p) , &type);
01671 if (r==0) {
01672 LM_ERR("unsupported mime <%s>\n",p);
01673 return E_CFG;
01674 }
01675 if ( r!=p+strlen(p) ) {
01676 LM_ERR("multiple mimes not supported!\n");
01677 return E_CFG;
01678 }
01679 }
01680 pkg_free(*param);
01681 *param = (void*)(long)type;
01682 }
01683 return 0;
01684
01685 }
01686
01687
01688 static int has_body_f(struct sip_msg *msg, char *type, char *str2 )
01689 {
01690 int mime;
01691
01692
01693 if ( msg->content_length==NULL &&
01694 (parse_headers(msg,HDR_CONTENTLENGTH_F, 0)==-1||msg->content_length==NULL))
01695 return -1;
01696
01697 if (get_content_length (msg)==0) {
01698 LM_DBG("content length is zero\n");
01699
01700 return -1;
01701 }
01702
01703
01704 if (type==0)
01705 return 1;
01706
01707
01708 mime = parse_content_type_hdr (msg);
01709 if (mime<0) {
01710 LM_ERR("failed to extract content type hdr\n");
01711 return -1;
01712 }
01713 if (mime==0) {
01714
01715
01716 mime = ((TYPE_APPLICATION << 16) + SUBTYPE_SDP);
01717 }
01718 LM_DBG("content type is %d\n",mime);
01719
01720 if ( (unsigned int)mime!=(unsigned int)(unsigned long)type )
01721 return -1;
01722
01723 return 1;
01724 }
01725
01726
01727 static int is_privacy_f(struct sip_msg *msg, char *_privacy, char *str2 )
01728 {
01729 if (parse_privacy(msg) == -1)
01730 return -1;
01731
01732 return get_privacy_values(msg) & ((unsigned int)(long)_privacy) ? 1 : -1;
01733
01734 }
01735
01736 static int cmp_str_f(struct sip_msg *msg, char *str1, char *str2 )
01737 {
01738 str s1;
01739 str s2;
01740 int ret;
01741
01742 if(fixup_get_svalue(msg, (gparam_p)str1, &s1)!=0)
01743 {
01744 LM_ERR("cannot get first parameter\n");
01745 return -8;
01746 }
01747 if(fixup_get_svalue(msg, (gparam_p)str2, &s2)!=0)
01748 {
01749 LM_ERR("cannot get second parameter\n");
01750 return -8;
01751 }
01752 ret = cmp_str(&s1, &s2);
01753 if(ret==0)
01754 return 1;
01755 if(ret>0)
01756 return -1;
01757 return -2;
01758 }
01759
01760 static int cmp_istr_f(struct sip_msg *msg, char *str1, char *str2)
01761 {
01762 str s1;
01763 str s2;
01764 int ret;
01765
01766 if(fixup_get_svalue(msg, (gparam_p)str1, &s1)!=0)
01767 {
01768 LM_ERR("cannot get first parameter\n");
01769 return -8;
01770 }
01771 if(fixup_get_svalue(msg, (gparam_p)str2, &s2)!=0)
01772 {
01773 LM_ERR("cannot get second parameter\n");
01774 return -8;
01775 }
01776 ret = cmpi_str(&s1, &s2);
01777 if(ret==0)
01778 return 1;
01779 if(ret>0)
01780 return -1;
01781 return -2;
01782 }
01783