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 #include <stdio.h>
00038 #include <string.h>
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #include <unistd.h>
00042 #include <fcntl.h>
00043 #include <signal.h>
00044
00045 #include "../../mem/shm_mem.h"
00046 #include "../../mem/mem.h"
00047 #include "../../sr_module.h"
00048 #include "../../str.h"
00049 #include "../../ut.h"
00050 #include "../../dprint.h"
00051 #include "../../data_lump_rpl.h"
00052 #include "../../pvar.h"
00053 #include "../../parser/parse_uri.h"
00054 #include "../../parser/parse_from.h"
00055 #include "../../parser/parse_content.h"
00056 #include "../../parser/parse_disposition.h"
00057 #include "../../lib/srdb1/db.h"
00058 #include "../../lib/kmi/mi.h"
00059 #include "../../modules/sl/sl.h"
00060 #include "cpl_run.h"
00061 #include "cpl_env.h"
00062 #include "cpl_db.h"
00063 #include "cpl_loader.h"
00064 #include "cpl_parser.h"
00065 #include "cpl_nonsig.h"
00066 #include "loc_set.h"
00067
00068
00069 #define MAX_PROXY_RECURSE 10
00070 #define MAX_USERHOST_LEN 256
00071
00072
00073
00074 static str db_url = str_init(DEFAULT_DB_URL);
00075 static str db_table = str_init("cpl");
00076 static char *dtd_file = 0;
00077 static char *lookup_domain = 0;
00078 static str timer_avp = {NULL, 0};
00079
00080
00081 struct cpl_enviroment cpl_env = {
00082 0,
00083 0,
00084 0,
00085 0,
00086 {0,0},
00087 {-1,-1},
00088 {0,0},
00089 0,
00090 0,
00091 0,
00092 {0},
00093 0
00094 };
00095
00096 struct cpl_functions cpl_fct;
00097 static str cpl_ok_rpl = str_init("OK");
00098
00099
00100 MODULE_VERSION
00101
00102
00103 static int cpl_invoke_script (struct sip_msg* msg, char* str, char* str2);
00104 static int w_process_register(struct sip_msg* msg, char* str, char* str2);
00105 static int w_process_register_norpl(struct sip_msg* msg, char* str,char* str2);
00106 static int cpl_process_register(struct sip_msg* msg, int no_rpl);
00107 static int fixup_cpl_run_script(void** param, int param_no);
00108 static int cpl_init(void);
00109 static int mi_child_init(void);
00110 static int cpl_child_init(int rank);
00111 static int cpl_exit(void);
00112 static void cpl_process(int rank);
00113
00114
00115
00116
00117
00118 static proc_export_t cpl_procs[] = {
00119 {"CPL Aux", 0, 0, cpl_process, 1 },
00120 {0,0,0,0,0}
00121 };
00122
00123
00124
00125
00126
00127 static cmd_export_t cmds[] = {
00128 {"cpl_run_script", (cmd_function)cpl_invoke_script, 2,
00129 fixup_cpl_run_script, 0, REQUEST_ROUTE},
00130 {"cpl_process_register", (cmd_function)w_process_register, 0,
00131 0, 0, REQUEST_ROUTE},
00132 {"cpl_process_register_norpl",(cmd_function)w_process_register_norpl, 0,
00133 0, 0, REQUEST_ROUTE},
00134 {0, 0, 0, 0, 0, 0}
00135 };
00136
00137
00138
00139
00140
00141 static param_export_t params[] = {
00142 {"db_url", STR_PARAM, &db_url.s },
00143 {"db_table", STR_PARAM, &db_table.s },
00144 {"cpl_dtd_file", STR_PARAM, &dtd_file },
00145 {"proxy_recurse", INT_PARAM, &cpl_env.proxy_recurse },
00146 {"proxy_route", INT_PARAM, &cpl_env.proxy_route },
00147 {"log_dir", STR_PARAM, &cpl_env.log_dir },
00148 {"case_sensitive", INT_PARAM, &cpl_env.case_sensitive },
00149 {"realm_prefix", STR_PARAM, &cpl_env.realm_prefix.s },
00150 {"lookup_domain", STR_PARAM, &lookup_domain },
00151 {"lookup_append_branches", INT_PARAM, &cpl_env.lu_append_branches},
00152 {"timer_avp", STR_PARAM, &timer_avp.s },
00153 {"username_column",STR_PARAM, &cpl_username_col },
00154 {"domain_column", STR_PARAM, &cpl_domain_col },
00155 {"cpl_xml_column", STR_PARAM, &cpl_xml_col },
00156 {"cpl_bin_column", STR_PARAM, &cpl_bin_col },
00157 {"use_domain", INT_PARAM, &cpl_env.use_domain },
00158 {0, 0, 0}
00159 };
00160
00161
00162
00163
00164
00165 static mi_export_t mi_cmds[] = {
00166 { "LOAD_CPL", mi_cpl_load, 0, 0, mi_child_init },
00167 { "REMOVE_CPL", mi_cpl_remove, 0, 0, 0 },
00168 { "GET_CPL", mi_cpl_get, 0, 0, 0 },
00169 { 0, 0, 0, 0, 0}
00170 };
00171
00172
00173
00174
00175 struct module_exports exports = {
00176 "cpl-c",
00177 DEFAULT_DLFLAGS,
00178 cmds,
00179 params,
00180 0,
00181 mi_cmds,
00182 0,
00183 cpl_procs,
00184 cpl_init,
00185 0,
00186 (destroy_function) cpl_exit,
00187 (child_init_function) cpl_child_init
00188 };
00189
00190
00191
00192 static int fixup_cpl_run_script(void** param, int param_no)
00193 {
00194 long flag;
00195
00196 if (param_no==1) {
00197 if (!strcasecmp( "incoming", *param))
00198 flag = CPL_RUN_INCOMING;
00199 else if (!strcasecmp( "outgoing", *param))
00200 flag = CPL_RUN_OUTGOING;
00201 else {
00202 LM_ERR("script directive \"%s\" unknown!\n",(char*)*param);
00203 return E_UNSPEC;
00204 }
00205 pkg_free(*param);
00206 *param=(void*)flag;
00207 return 0;
00208 } else if (param_no==2) {
00209 if ( !strcasecmp("is_stateless", *param) ) {
00210 flag = 0;
00211 } else if ( !strcasecmp("is_stateful", *param) ) {
00212 flag = CPL_IS_STATEFUL;
00213 } else if ( !strcasecmp("force_stateful", *param) ) {
00214 flag = CPL_FORCE_STATEFUL;
00215 } else {
00216 LM_ERR("flag \"%s\" (second param) unknown!\n",(char*)*param);
00217 return E_UNSPEC;
00218 }
00219 pkg_free(*param);
00220 *param=(void*)flag;
00221 }
00222 return 0;
00223 }
00224
00225
00226
00227 static int cpl_init(void)
00228 {
00229 bind_usrloc_t bind_usrloc;
00230 struct stat stat_t;
00231 char *ptr;
00232 int val;
00233 pv_spec_t avp_spec;
00234 unsigned short avp_type;
00235
00236 if(register_mi_mod(exports.name, mi_cmds)!=0)
00237 {
00238 LM_ERR("failed to register MI commands\n");
00239 return -1;
00240 }
00241
00242 db_url.len = strlen(db_url.s);
00243 db_table.len = strlen(db_table.s);
00244 if (timer_avp.s) timer_avp.len = strlen(timer_avp.s);
00245
00246 if (cpl_env.proxy_recurse>MAX_PROXY_RECURSE) {
00247 LM_CRIT("value of proxy_recurse param (%d) exceeds "
00248 "the maximum safety value (%d)\n",
00249 cpl_env.proxy_recurse,MAX_PROXY_RECURSE);
00250 goto error;
00251 }
00252
00253
00254 if (timer_avp.s && timer_avp.len > 0) {
00255 if (pv_parse_spec(&timer_avp, &avp_spec)==0
00256 || avp_spec.type!=PVT_AVP) {
00257 LM_ERR("malformed or non AVP %.*s AVP definition\n", timer_avp.len, timer_avp.s);
00258 return -1;
00259 }
00260
00261 if(pv_get_avp_name(0, &(avp_spec.pvp), &cpl_env.timer_avp,
00262 &avp_type)!=0)
00263 {
00264 LM_ERR("[%.*s]- invalid AVP definition\n", timer_avp.len, timer_avp.s);
00265 return -1;
00266 }
00267 cpl_env.timer_avp_type = avp_type;
00268 }
00269
00270 if (dtd_file==0) {
00271 LM_CRIT("mandatory parameter \"cpl_dtd_file\" found empty\n");
00272 goto error;
00273 } else {
00274
00275 if (stat( dtd_file, &stat_t)==-1) {
00276 LM_ERR("checking file \"%s\" status failed; stat returned %s\n",
00277 dtd_file,strerror(errno));
00278 goto error;
00279 }
00280 if ( !S_ISREG( stat_t.st_mode ) ) {
00281 LM_ERR("dir \"%s\" is not a regular file!\n", dtd_file);
00282 goto error;
00283 }
00284 if (access( dtd_file, R_OK )==-1) {
00285 LM_ERR("checking file \"%s\" for permissions "
00286 "failed; access returned %s\n",dtd_file,strerror(errno));
00287 goto error;
00288 }
00289 }
00290
00291 if (cpl_env.log_dir==0) {
00292 LM_INFO("log_dir param found empty -> logging disabled!\n");
00293 } else {
00294 if ( strlen(cpl_env.log_dir)>MAX_LOG_DIR_SIZE ) {
00295 LM_ERR("dir \"%s\" has a too long name :-(!\n", cpl_env.log_dir);
00296 goto error;
00297 }
00298
00299 if (stat( cpl_env.log_dir, &stat_t)==-1) {
00300 LM_ERR("checking dir \"%s\" status failed;"
00301 " stat returned %s\n",cpl_env.log_dir,strerror(errno));
00302 goto error;
00303 }
00304 if ( !S_ISDIR( stat_t.st_mode ) ) {
00305 LM_ERR("dir \"%s\" is not a directory!\n", cpl_env.log_dir);
00306 goto error;
00307 }
00308 if (access( cpl_env.log_dir, R_OK|W_OK )==-1) {
00309 LM_ERR("checking dir \"%s\" for permissions failed; access "
00310 "returned %s\n", cpl_env.log_dir, strerror(errno));
00311 goto error;
00312 }
00313 }
00314
00315
00316 if (cpl_db_bind(&db_url, &db_table)<0) goto error;
00317
00318
00319 if (load_tm_api(&cpl_fct.tmb)!=0) {
00320 LM_ERR("can't load TM API\n");
00321 goto error;
00322 }
00323
00324 if (sl_load_api(&cpl_fct.slb)!=0) {
00325 LM_ERR("cannot bind to SL API\n");
00326 return -1;
00327 }
00328
00329
00330 if (lookup_domain) {
00331
00332 bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
00333 if (!bind_usrloc) {
00334 LM_ERR("can't bind usrloc\n");
00335 goto error;
00336 }
00337 if (bind_usrloc( &(cpl_fct.ulb) ) < 0) {
00338 LM_ERR("importing usrloc failed\n");
00339 goto error;
00340 }
00341
00342 if (cpl_fct.ulb.register_udomain( lookup_domain, &cpl_env.lu_domain)
00343 < 0) {
00344 LM_ERR("failed to register domain <%s>\n",lookup_domain);
00345 goto error;
00346 }
00347 } else {
00348 LM_NOTICE("no lookup_domain given -> disable lookup node\n");
00349 }
00350
00351
00352 if ( pipe( cpl_env.cmd_pipe )==-1 ) {
00353 LM_CRIT("cannot create command pipe: %s!\n", strerror(errno) );
00354 goto error;
00355 }
00356
00357 if ( (val=fcntl(cpl_env.cmd_pipe[1], F_GETFL, 0))<0 ) {
00358 LM_ERR("getting flags from pipe[1] failed: fcntl said %s!\n",
00359 strerror(errno));
00360 goto error;
00361 }
00362 if ( fcntl(cpl_env.cmd_pipe[1], F_SETFL, val|O_NONBLOCK) ) {
00363 LM_ERR("setting flags to pipe[1] failed: fcntl said %s!\n",
00364 strerror(errno));
00365 goto error;
00366 }
00367
00368
00369 if (init_CPL_parser( dtd_file )!=1 ) {
00370 LM_ERR("init_CPL_parser failed!\n");
00371 goto error;
00372 }
00373
00374
00375 ptr = getenv("TZ");
00376 cpl_env.orig_tz.len = 3 + (ptr?(strlen(ptr)+1):0);
00377 if ( (cpl_env.orig_tz.s=shm_malloc( cpl_env.orig_tz.len ))==0 ) {
00378 LM_ERR("no more shm mem. for saving TZ!\n");
00379 goto error;
00380 }
00381 memcpy(cpl_env.orig_tz.s,"TZ=",3);
00382 if (ptr)
00383 strcpy(cpl_env.orig_tz.s+3,ptr);
00384
00385
00386 if (cpl_env.realm_prefix.s) {
00387 cpl_env.realm_prefix.len = strlen(cpl_env.realm_prefix.s);
00388
00389 strlower( &cpl_env.realm_prefix );
00390 }
00391
00392 return 0;
00393 error:
00394 return -1;
00395 }
00396
00397
00398
00399 static int cpl_child_init(int rank)
00400 {
00401 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00402 return 0;
00403
00404 return cpl_db_init(&db_url, &db_table);
00405 }
00406
00407
00408 static int mi_child_init(void)
00409 {
00410 return cpl_db_init(&db_url, &db_table);
00411 }
00412
00413
00414 static void cpl_process(int rank)
00415 {
00416 cpl_aux_process( cpl_env.cmd_pipe[0], cpl_env.log_dir);
00417 exit(-1);
00418 }
00419
00420
00421 static int cpl_exit(void)
00422 {
00423
00424 if (cpl_env.orig_tz.s)
00425 shm_free(cpl_env.orig_tz.s);
00426
00427 return 0;
00428 }
00429
00430
00431
00432 static inline int build_user_AOR(str *username, str *domain, str *uh, int sip)
00433 {
00434 unsigned char do_strip;
00435 char *p;
00436 int i;
00437
00438
00439 uh->len = 4*(sip!=0) + username->len;
00440 do_strip = 0;
00441
00442 if (sip || cpl_env.use_domain) {
00443
00444 if (cpl_env.realm_prefix.len && cpl_env.realm_prefix.len<domain->len){
00445 for( i=cpl_env.realm_prefix.len-1 ; i>=0 ; i-- )
00446 if ( cpl_env.realm_prefix.s[i]!=tolower(domain->s[i]) )
00447 break;
00448 if (i==-1)
00449 do_strip = 1;
00450 }
00451 uh->len += 1 + domain->len - do_strip*cpl_env.realm_prefix.len;
00452 }
00453
00454 uh->s = (char*)shm_malloc( uh->len + 1 );
00455 if (!uh->s) {
00456 LM_ERR("no more shm memory.\n");
00457 return -1;
00458 }
00459
00460
00461 p = uh->s;
00462 if (sip) {
00463 memcpy( uh->s, "sip:", 4);
00464 p += 4;
00465 }
00466
00467 if (cpl_env.case_sensitive) {
00468 memcpy( p, username->s, username->len);
00469 p += username->len;
00470 } else {
00471 for(i=0;i<username->len;i++)
00472 *(p++) = tolower(username->s[i]);
00473 }
00474 if (sip || cpl_env.use_domain) {
00475 *(p++) = '@';
00476
00477 for( i=do_strip*cpl_env.realm_prefix.len ; i< domain->len ; i++ )
00478 *(p++) = tolower(domain->s[i]);
00479 }
00480 *(p++) = 0;
00481
00482
00483 if (p-uh->s!=uh->len+1) {
00484 LM_CRIT("buffer overflow l=%d,w=%ld\n", uh->len,(long)(p-uh->s));
00485 return -1;
00486 }
00487 return 0;
00488 }
00489
00490
00491
00492 static inline int get_dest_user(struct sip_msg *msg, str *username, str *domain)
00493 {
00494 struct sip_uri uri;
00495
00496
00497 LM_DBG("trying to get user from new_uri\n");
00498 if ( !msg->new_uri.s || parse_uri( msg->new_uri.s,msg->new_uri.len,&uri)<0
00499 || !uri.user.len )
00500 {
00501 LM_DBG("trying to get user from R_uri\n");
00502 if ( parse_uri( msg->first_line.u.request.uri.s,
00503 msg->first_line.u.request.uri.len ,&uri)==-1 || !uri.user.len )
00504 {
00505 LM_DBG("trying to get user from To\n");
00506 if ( (!msg->to&&((parse_headers(msg,HDR_TO_F,0)==-1)||!msg->to))||
00507 parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)<0
00508 || !uri.user.len)
00509 {
00510 LM_ERR("unable to extract user name from RURI or To header!\n");
00511 return -1;
00512 }
00513 }
00514 }
00515 *username = uri.user;
00516 *domain = uri.host;
00517 return 0;
00518 }
00519
00520
00521
00522 static inline int get_orig_user(struct sip_msg *msg, str *username, str *domain)
00523 {
00524 struct to_body *from;
00525 struct sip_uri uri;
00526
00527
00528
00529 LM_DBG("trying to get user from From\n");
00530 if ( parse_from_header( msg )==-1 ) {
00531 LM_ERR("unable to extract URI from FROM header\n");
00532 return -1;
00533 }
00534 from = (struct to_body*)msg->from->parsed;
00535
00536 if (parse_uri( from->uri.s, from->uri.len, &uri)||!uri.user.len) {
00537 LM_ERR("unable to extract user name from URI (From header)\n");
00538 return -1;
00539 }
00540 *username = uri.user;
00541 *domain = uri.host;
00542 return 0;
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 static int cpl_invoke_script(struct sip_msg* msg, char* str1, char* str2)
00552 {
00553 struct cpl_interpreter *cpl_intr;
00554 str username = {0,0};
00555 str domain = {0,0};
00556 str loc;
00557 str script;
00558
00559
00560 if ( ((unsigned long)str1)&CPL_RUN_INCOMING ) {
00561
00562 if (get_dest_user( msg, &username, &domain)==-1)
00563 goto error0;
00564 } else {
00565
00566 if (get_orig_user( msg, &username, &domain)==-1)
00567 goto error0;
00568 }
00569
00570
00571 if (get_user_script(&username, cpl_env.use_domain?&domain:0,
00572 &script, &cpl_bin_col)==-1)
00573 goto error0;
00574
00575
00576
00577 if ( !script.s || !script.len )
00578 return 1;
00579
00580
00581 if ( (cpl_intr=new_cpl_interpreter(msg,&script))==0 )
00582 goto error1;
00583
00584 cpl_intr->flags =(unsigned int)((unsigned long)str1)|((unsigned long)str2);
00585
00586 if (build_user_AOR( &username, &domain, &(cpl_intr->user), 0)!=0 )
00587 goto error2;
00588
00589
00590 if ( ((unsigned long)str1)&CPL_RUN_OUTGOING ) {
00591
00592 if (get_dest_user( msg, &username, &domain)==-1)
00593 goto error2;
00594 if (build_user_AOR( &username, &domain, &loc, 1)!=0 )
00595 goto error2;
00596 if (add_location( &(cpl_intr->loc_set), &loc, 0, 10, 0)==-1)
00597 goto error2;
00598 }
00599
00600
00601 switch (cpl_run_script( cpl_intr )) {
00602 case SCRIPT_DEFAULT:
00603 free_cpl_interpreter( cpl_intr );
00604 return 1;
00605 case SCRIPT_END:
00606 free_cpl_interpreter( cpl_intr );
00607 case SCRIPT_TO_BE_CONTINUED:
00608 return 0;
00609 case SCRIPT_RUN_ERROR:
00610 case SCRIPT_FORMAT_ERROR:
00611 goto error2;
00612 }
00613
00614 return 1;
00615 error2:
00616 free_cpl_interpreter( cpl_intr );
00617 return -1;
00618 error1:
00619 shm_free(script.s);
00620 error0:
00621 return -1;
00622 }
00623
00624
00625
00626 #define CPL_SCRIPT "script"
00627 #define CPL_SCRIPT_LEN (sizeof(CPL_SCRIPT)-1)
00628 #define ACTION_PARAM "action"
00629 #define ACTION_PARAM_LEN (sizeof(ACTION_PARAM)-1)
00630 #define STORE_ACTION "store"
00631 #define STORE_ACTION_LEN (sizeof(STORE_ACTION)-1)
00632 #define REMOVE_ACTION "remove"
00633 #define REMOVE_ACTION_LEN (sizeof(REMOVE_ACTION)-1)
00634
00635 #define REMOVE_SCRIPT 0xcaca
00636 #define STORE_SCRIPT 0xbebe
00637
00638 #define CONTENT_TYPE_HDR ("Content-Type: application/cpl-xml"CRLF)
00639 #define CONTENT_TYPE_HDR_LEN (sizeof(CONTENT_TYPE_HDR)-1)
00640
00641 struct cpl_error {
00642 int err_code;
00643 str err_msg;
00644 };
00645
00646 static struct cpl_error bad_req = {400,str_init("Bad request")};
00647 static struct cpl_error intern_err = {500,str_init("Internal server error")};
00648 static struct cpl_error bad_cpl = {400,str_init("Bad CPL script")};
00649
00650 static struct cpl_error *cpl_err = &bad_req;
00651
00652
00653 static inline int do_script_action(struct sip_msg *msg, int action)
00654 {
00655 str body = {0,0};
00656 str bin = {0,0};
00657 str log = {0,0};
00658 str username = {0,0};
00659 str domain = {0,0};
00660
00661
00662 if ( !msg->content_length &&
00663 ((parse_headers(msg,HDR_CONTENTLENGTH_F,0)==-1)||!msg->content_length)) {
00664 LM_ERR("no Content-Length hdr found!\n");
00665 goto error;
00666 }
00667 body.len = get_content_length( msg );
00668
00669
00670 if (get_dest_user( msg, &username, &domain)==-1)
00671 goto error;
00672
00673
00674 switch (action) {
00675 case STORE_SCRIPT :
00676
00677 if (body.len==0) {
00678 LM_ERR("0 content-len found for store\n");
00679 goto error_1;
00680 }
00681
00682 body.s = get_body( msg );
00683 if (body.s==0) {
00684 LM_ERR("cannot extract body from msg!\n");
00685 goto error_1;
00686 }
00687
00688
00689 if ( encodeCPL( &body, &bin, &log)!=1) {
00690 cpl_err = &bad_cpl;
00691 goto error_1;
00692 }
00693
00694
00695 if (write_to_db( &username, cpl_env.use_domain?&domain:0,
00696 &body,&bin)!=1) {
00697 cpl_err = &intern_err;
00698 goto error_1;
00699 }
00700 break;
00701 case REMOVE_SCRIPT:
00702
00703 if (body.len!=0) {
00704 LM_ERR("non-0 content-len found for remove\n");
00705 goto error_1;
00706 }
00707
00708 if (rmv_from_db( &username, cpl_env.use_domain?&domain:0)!=1) {
00709 cpl_err = &intern_err;
00710 goto error_1;
00711 }
00712 break;
00713 }
00714
00715 if (log.s) pkg_free( log.s );
00716 return 0;
00717 error_1:
00718 if (log.s) pkg_free( log.s );
00719 error:
00720 return -1;
00721 }
00722
00723
00724
00725 static inline int do_script_download(struct sip_msg *msg)
00726 {
00727 str username = {0,0};
00728 str domain = {0,0};
00729 str script = {0,0};
00730
00731
00732 if (get_dest_user( msg, &username, &domain)!=0)
00733 goto error;
00734
00735
00736 if (get_user_script( &username, cpl_env.use_domain?&domain:0,
00737 &script, &cpl_xml_col)==-1)
00738 goto error;
00739
00740
00741 if (add_lump_rpl( msg, CONTENT_TYPE_HDR, CONTENT_TYPE_HDR_LEN,
00742 LUMP_RPL_HDR)==0) {
00743 LM_ERR("cannot build hdr lump\n");
00744 cpl_err = &intern_err;
00745 goto error;
00746 }
00747
00748 if (script.s!=0) {
00749
00750 if ( add_lump_rpl( msg, script.s, script.len, LUMP_RPL_BODY)==0) {
00751 LM_ERR("cannot build body lump\n");
00752 cpl_err = &intern_err;
00753 goto error;
00754 }
00755
00756 shm_free( script.s );
00757 }
00758
00759 return 0;
00760 error:
00761 if (script.s)
00762 shm_free(script.s);
00763 return -1;
00764 }
00765
00766
00767
00768 static int w_process_register(struct sip_msg* msg, char* str, char* str2)
00769 {
00770 return cpl_process_register( msg, 0);
00771 }
00772
00773
00774
00775 static int w_process_register_norpl(struct sip_msg* msg, char* str,char* str2)
00776 {
00777 return cpl_process_register( msg, 1);
00778 }
00779
00780
00781
00782 static int cpl_process_register(struct sip_msg* msg, int no_rpl)
00783 {
00784 struct disposition *disp;
00785 struct disposition_param *param;
00786 int ret;
00787 int mime;
00788 int *mimes;
00789
00790
00791
00792
00793
00794
00795 mime = parse_content_type_hdr( msg );
00796 if (mime==-1)
00797 goto error;
00798
00799
00800 LM_DBG("Content-Type mime found %u, %u\n",
00801 mime>>16,mime&0x00ff);
00802 if ( mime && mime==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) {
00803
00804
00805 LM_DBG("carrying CPL -> look at Content-Disposition\n");
00806 if (parse_content_disposition( msg )!=0) {
00807 LM_ERR("Content-Disposition missing or corrupted\n");
00808 goto error;
00809 }
00810 disp = get_content_disposition(msg);
00811 print_disposition( disp );
00812
00813 if (disp->type.len!=CPL_SCRIPT_LEN ||
00814 strncasecmp(disp->type.s,CPL_SCRIPT,CPL_SCRIPT_LEN) ) {
00815 LM_ERR("bogus message - Content-Type"
00816 "says CPL_SCRIPT, but Content-Disposition something else\n");
00817 goto error;
00818 }
00819
00820 for(param=disp->params;param;param=param->next) {
00821 if (param->name.len==ACTION_PARAM_LEN &&
00822 !strncasecmp(param->name.s,ACTION_PARAM,ACTION_PARAM_LEN))
00823 break;
00824 }
00825 if (param==0) {
00826 LM_ERR("bogus message - "
00827 "Content-Disposition has no action param\n");
00828 goto error;
00829 }
00830
00831 if (param->body.len==STORE_ACTION_LEN &&
00832 !strncasecmp( param->body.s, STORE_ACTION, STORE_ACTION_LEN)) {
00833
00834
00835 if (do_script_action( msg, STORE_SCRIPT)==-1)
00836 goto error;
00837 } else
00838 if (param->body.len==REMOVE_ACTION_LEN &&
00839 !strncasecmp( param->body.s, REMOVE_ACTION, REMOVE_ACTION_LEN)) {
00840
00841 if (do_script_action( msg, REMOVE_SCRIPT)==-1)
00842 goto error;
00843 } else {
00844 LM_ERR("unknown action <%.*s>\n",
00845 param->body.len,param->body.s);
00846 goto error;
00847 }
00848
00849
00850 if (no_rpl)
00851 goto resume_script;
00852
00853
00854 cpl_fct.slb.freply( msg, 200, &cpl_ok_rpl);
00855
00856
00857 goto stop_script;
00858 }
00859
00860
00861 if ( (ret=parse_accept_hdr(msg))<0)
00862 goto error;
00863 if (ret==0 || (mimes=get_accept(msg))==0 )
00864
00865 goto resume_script;
00866
00867
00868 while (*mimes) {
00869 LM_DBG("accept mime found %u, %u\n",
00870 (*mimes)>>16,(*mimes)&0x00ff);
00871 if (*mimes==(TYPE_ALL<<16)+SUBTYPE_ALL ||
00872 *mimes==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML )
00873 break;
00874 mimes++;
00875 }
00876 if (*mimes==0)
00877
00878 goto resume_script;
00879
00880
00881
00882 if (do_script_download( msg )==-1)
00883 goto error;
00884
00885
00886 if (no_rpl)
00887 goto resume_script;
00888
00889
00890 cpl_fct.slb.freply( msg, 200, &cpl_ok_rpl);
00891
00892 stop_script:
00893 return 0;
00894 resume_script:
00895 return 1;
00896 error:
00897
00898 cpl_fct.slb.freply( msg, cpl_err->err_code, &cpl_err->err_msg);
00899
00900 return 0;
00901 }