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 "../../db/db.h"
00058 #include "../../mi/mi.h"
00059 #include "../sl/sl_api.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 db_url.len = strlen(db_url.s);
00237 db_table.len = strlen(db_table.s);
00238 if (timer_avp.s) timer_avp.len = strlen(timer_avp.s);
00239
00240 if (cpl_env.proxy_recurse>MAX_PROXY_RECURSE) {
00241 LM_CRIT("value of proxy_recurse param (%d) exceeds "
00242 "the maximum safety value (%d)\n",
00243 cpl_env.proxy_recurse,MAX_PROXY_RECURSE);
00244 goto error;
00245 }
00246
00247
00248 if (timer_avp.s && timer_avp.len > 0) {
00249 if (pv_parse_spec(&timer_avp, &avp_spec)==0
00250 || avp_spec.type!=PVT_AVP) {
00251 LM_ERR("malformed or non AVP %.*s AVP definition\n", timer_avp.len, timer_avp.s);
00252 return -1;
00253 }
00254
00255 if(pv_get_avp_name(0, &(avp_spec.pvp), &cpl_env.timer_avp,
00256 &avp_type)!=0)
00257 {
00258 LM_ERR("[%.*s]- invalid AVP definition\n", timer_avp.len, timer_avp.s);
00259 return -1;
00260 }
00261 cpl_env.timer_avp_type = avp_type;
00262 }
00263
00264 if (dtd_file==0) {
00265 LM_CRIT("mandatory parameter \"cpl_dtd_file\" found empty\n");
00266 goto error;
00267 } else {
00268
00269 if (stat( dtd_file, &stat_t)==-1) {
00270 LM_ERR("checking file \"%s\" status failed; stat returned %s\n",
00271 dtd_file,strerror(errno));
00272 goto error;
00273 }
00274 if ( !S_ISREG( stat_t.st_mode ) ) {
00275 LM_ERR("dir \"%s\" is not a regular file!\n", dtd_file);
00276 goto error;
00277 }
00278 if (access( dtd_file, R_OK )==-1) {
00279 LM_ERR("checking file \"%s\" for permissions "
00280 "failed; access returned %s\n",dtd_file,strerror(errno));
00281 goto error;
00282 }
00283 }
00284
00285 if (cpl_env.log_dir==0) {
00286 LM_INFO("log_dir param found empty -> logging disabled!\n");
00287 } else {
00288 if ( strlen(cpl_env.log_dir)>MAX_LOG_DIR_SIZE ) {
00289 LM_ERR("dir \"%s\" has a too long name :-(!\n", cpl_env.log_dir);
00290 goto error;
00291 }
00292
00293 if (stat( cpl_env.log_dir, &stat_t)==-1) {
00294 LM_ERR("checking dir \"%s\" status failed;"
00295 " stat returned %s\n",cpl_env.log_dir,strerror(errno));
00296 goto error;
00297 }
00298 if ( !S_ISDIR( stat_t.st_mode ) ) {
00299 LM_ERR("dir \"%s\" is not a directory!\n", cpl_env.log_dir);
00300 goto error;
00301 }
00302 if (access( cpl_env.log_dir, R_OK|W_OK )==-1) {
00303 LM_ERR("checking dir \"%s\" for permissions failed; access "
00304 "returned %s\n", cpl_env.log_dir, strerror(errno));
00305 goto error;
00306 }
00307 }
00308
00309
00310 if (cpl_db_bind(&db_url, &db_table)<0) goto error;
00311
00312
00313 if (load_tm_api(&cpl_fct.tmb)!=0) {
00314 LM_ERR("can't load TM API\n");
00315 goto error;
00316 }
00317
00318 if (load_sl_api(&cpl_fct.slb)!=0) {
00319 LM_ERR("can't load SL API\n");
00320 goto error;
00321 }
00322
00323
00324 if (lookup_domain) {
00325
00326 bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
00327 if (!bind_usrloc) {
00328 LM_ERR("can't bind usrloc\n");
00329 goto error;
00330 }
00331 if (bind_usrloc( &(cpl_fct.ulb) ) < 0) {
00332 LM_ERR("importing usrloc failed\n");
00333 goto error;
00334 }
00335
00336 if (cpl_fct.ulb.register_udomain( lookup_domain, &cpl_env.lu_domain)
00337 < 0) {
00338 LM_ERR("failed to register domain <%s>\n",lookup_domain);
00339 goto error;
00340 }
00341 } else {
00342 LM_NOTICE("no lookup_domain given -> disable lookup node\n");
00343 }
00344
00345
00346 if ( pipe( cpl_env.cmd_pipe )==-1 ) {
00347 LM_CRIT("cannot create command pipe: %s!\n", strerror(errno) );
00348 goto error;
00349 }
00350
00351 if ( (val=fcntl(cpl_env.cmd_pipe[1], F_GETFL, 0))<0 ) {
00352 LM_ERR("getting flags from pipe[1] failed: fcntl said %s!\n",
00353 strerror(errno));
00354 goto error;
00355 }
00356 if ( fcntl(cpl_env.cmd_pipe[1], F_SETFL, val|O_NONBLOCK) ) {
00357 LM_ERR("setting flags to pipe[1] failed: fcntl said %s!\n",
00358 strerror(errno));
00359 goto error;
00360 }
00361
00362
00363 if (init_CPL_parser( dtd_file )!=1 ) {
00364 LM_ERR("init_CPL_parser failed!\n");
00365 goto error;
00366 }
00367
00368
00369 ptr = getenv("TZ");
00370 cpl_env.orig_tz.len = 3 + (ptr?(strlen(ptr)+1):0);
00371 if ( (cpl_env.orig_tz.s=shm_malloc( cpl_env.orig_tz.len ))==0 ) {
00372 LM_ERR("no more shm mem. for saving TZ!\n");
00373 goto error;
00374 }
00375 memcpy(cpl_env.orig_tz.s,"TZ=",3);
00376 if (ptr)
00377 strcpy(cpl_env.orig_tz.s+3,ptr);
00378
00379
00380 if (cpl_env.realm_prefix.s) {
00381 cpl_env.realm_prefix.len = strlen(cpl_env.realm_prefix.s);
00382
00383 strlower( &cpl_env.realm_prefix );
00384 }
00385
00386 return 0;
00387 error:
00388 return -1;
00389 }
00390
00391
00392
00393 static int cpl_child_init(int rank)
00394 {
00395 return cpl_db_init(&db_url, &db_table);
00396 }
00397
00398
00399 static int mi_child_init(void)
00400 {
00401 return cpl_db_init(&db_url, &db_table);
00402 }
00403
00404
00405 static void cpl_process(int rank)
00406 {
00407 cpl_aux_process( cpl_env.cmd_pipe[0], cpl_env.log_dir);
00408 exit(-1);
00409 }
00410
00411
00412 static int cpl_exit(void)
00413 {
00414
00415 if (cpl_env.orig_tz.s)
00416 shm_free(cpl_env.orig_tz.s);
00417
00418 return 0;
00419 }
00420
00421
00422
00423 static inline int build_user_AOR(str *username, str *domain, str *uh, int sip)
00424 {
00425 unsigned char do_strip;
00426 char *p;
00427 int i;
00428
00429
00430 uh->len = 4*(sip!=0) + username->len;
00431 do_strip = 0;
00432
00433 if (sip || cpl_env.use_domain) {
00434
00435 if (cpl_env.realm_prefix.len && cpl_env.realm_prefix.len<domain->len){
00436 for( i=cpl_env.realm_prefix.len-1 ; i>=0 ; i-- )
00437 if ( cpl_env.realm_prefix.s[i]!=tolower(domain->s[i]) )
00438 break;
00439 if (i==-1)
00440 do_strip = 1;
00441 }
00442 uh->len += 1 + domain->len - do_strip*cpl_env.realm_prefix.len;
00443 }
00444
00445 uh->s = (char*)shm_malloc( uh->len + 1 );
00446 if (!uh->s) {
00447 LM_ERR("no more shm memory.\n");
00448 return -1;
00449 }
00450
00451
00452 p = uh->s;
00453 if (sip) {
00454 memcpy( uh->s, "sip:", 4);
00455 p += 4;
00456 }
00457
00458 if (cpl_env.case_sensitive) {
00459 memcpy( p, username->s, username->len);
00460 p += username->len;
00461 } else {
00462 for(i=0;i<username->len;i++)
00463 *(p++) = tolower(username->s[i]);
00464 }
00465 if (sip || cpl_env.use_domain) {
00466 *(p++) = '@';
00467
00468 for( i=do_strip*cpl_env.realm_prefix.len ; i< domain->len ; i++ )
00469 *(p++) = tolower(domain->s[i]);
00470 }
00471 *(p++) = 0;
00472
00473
00474 if (p-uh->s!=uh->len+1) {
00475 LM_CRIT("buffer overflow l=%d,w=%ld\n", uh->len,(long)(p-uh->s));
00476 return -1;
00477 }
00478 return 0;
00479 }
00480
00481
00482
00483 static inline int get_dest_user(struct sip_msg *msg, str *username, str *domain)
00484 {
00485 struct sip_uri uri;
00486
00487
00488 LM_DBG("trying to get user from new_uri\n");
00489 if ( !msg->new_uri.s || parse_uri( msg->new_uri.s,msg->new_uri.len,&uri)<0
00490 || !uri.user.len )
00491 {
00492 LM_DBG("trying to get user from R_uri\n");
00493 if ( parse_uri( msg->first_line.u.request.uri.s,
00494 msg->first_line.u.request.uri.len ,&uri)==-1 || !uri.user.len )
00495 {
00496 LM_DBG("trying to get user from To\n");
00497 if ( (!msg->to&&((parse_headers(msg,HDR_TO_F,0)==-1)||!msg->to))||
00498 parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)<0
00499 || !uri.user.len)
00500 {
00501 LM_ERR("unable to extract user name from RURI or To header!\n");
00502 return -1;
00503 }
00504 }
00505 }
00506 *username = uri.user;
00507 *domain = uri.host;
00508 return 0;
00509 }
00510
00511
00512
00513 static inline int get_orig_user(struct sip_msg *msg, str *username, str *domain)
00514 {
00515 struct to_body *from;
00516 struct sip_uri uri;
00517
00518
00519
00520 LM_DBG("trying to get user from From\n");
00521 if ( parse_from_header( msg )==-1 ) {
00522 LM_ERR("unable to extract URI from FROM header\n");
00523 return -1;
00524 }
00525 from = (struct to_body*)msg->from->parsed;
00526
00527 if (parse_uri( from->uri.s, from->uri.len, &uri)||!uri.user.len) {
00528 LM_ERR("unable to extract user name from URI (From header)\n");
00529 return -1;
00530 }
00531 *username = uri.user;
00532 *domain = uri.host;
00533 return 0;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542 static int cpl_invoke_script(struct sip_msg* msg, char* str1, char* str2)
00543 {
00544 struct cpl_interpreter *cpl_intr;
00545 str username = {0,0};
00546 str domain = {0,0};
00547 str loc;
00548 str script;
00549
00550
00551 if ( ((unsigned long)str1)&CPL_RUN_INCOMING ) {
00552
00553 if (get_dest_user( msg, &username, &domain)==-1)
00554 goto error0;
00555 } else {
00556
00557 if (get_orig_user( msg, &username, &domain)==-1)
00558 goto error0;
00559 }
00560
00561
00562 if (get_user_script(&username, cpl_env.use_domain?&domain:0,
00563 &script, &cpl_bin_col)==-1)
00564 goto error0;
00565
00566
00567
00568 if ( !script.s || !script.len )
00569 return 1;
00570
00571
00572 if ( (cpl_intr=new_cpl_interpreter(msg,&script))==0 )
00573 goto error1;
00574
00575 cpl_intr->flags =(unsigned int)((unsigned long)str1)|((unsigned long)str2);
00576
00577 if (build_user_AOR( &username, &domain, &(cpl_intr->user), 0)!=0 )
00578 goto error2;
00579
00580
00581 if ( ((unsigned long)str1)&CPL_RUN_OUTGOING ) {
00582
00583 if (get_dest_user( msg, &username, &domain)==-1)
00584 goto error2;
00585 if (build_user_AOR( &username, &domain, &loc, 1)!=0 )
00586 goto error2;
00587 if (add_location( &(cpl_intr->loc_set), &loc, 0, 10, 0)==-1)
00588 goto error2;
00589 }
00590
00591
00592 switch (cpl_run_script( cpl_intr )) {
00593 case SCRIPT_DEFAULT:
00594 free_cpl_interpreter( cpl_intr );
00595 return 1;
00596 case SCRIPT_END:
00597 free_cpl_interpreter( cpl_intr );
00598 case SCRIPT_TO_BE_CONTINUED:
00599 return 0;
00600 case SCRIPT_RUN_ERROR:
00601 case SCRIPT_FORMAT_ERROR:
00602 goto error2;
00603 }
00604
00605 return 1;
00606 error2:
00607 free_cpl_interpreter( cpl_intr );
00608 return -1;
00609 error1:
00610 shm_free(script.s);
00611 error0:
00612 return -1;
00613 }
00614
00615
00616
00617 #define CPL_SCRIPT "script"
00618 #define CPL_SCRIPT_LEN (sizeof(CPL_SCRIPT)-1)
00619 #define ACTION_PARAM "action"
00620 #define ACTION_PARAM_LEN (sizeof(ACTION_PARAM)-1)
00621 #define STORE_ACTION "store"
00622 #define STORE_ACTION_LEN (sizeof(STORE_ACTION)-1)
00623 #define REMOVE_ACTION "remove"
00624 #define REMOVE_ACTION_LEN (sizeof(REMOVE_ACTION)-1)
00625
00626 #define REMOVE_SCRIPT 0xcaca
00627 #define STORE_SCRIPT 0xbebe
00628
00629 #define CONTENT_TYPE_HDR ("Content-Type: application/cpl-xml"CRLF)
00630 #define CONTENT_TYPE_HDR_LEN (sizeof(CONTENT_TYPE_HDR)-1)
00631
00632 struct cpl_error {
00633 int err_code;
00634 str err_msg;
00635 };
00636
00637 static struct cpl_error bad_req = {400,str_init("Bad request")};
00638 static struct cpl_error intern_err = {500,str_init("Internal server error")};
00639 static struct cpl_error bad_cpl = {400,str_init("Bad CPL script")};
00640
00641 static struct cpl_error *cpl_err = &bad_req;
00642
00643
00644 static inline int do_script_action(struct sip_msg *msg, int action)
00645 {
00646 str body = {0,0};
00647 str bin = {0,0};
00648 str log = {0,0};
00649 str username = {0,0};
00650 str domain = {0,0};
00651
00652
00653 if ( !msg->content_length &&
00654 ((parse_headers(msg,HDR_CONTENTLENGTH_F,0)==-1)||!msg->content_length)) {
00655 LM_ERR("no Content-Length hdr found!\n");
00656 goto error;
00657 }
00658 body.len = get_content_length( msg );
00659
00660
00661 if (get_dest_user( msg, &username, &domain)==-1)
00662 goto error;
00663
00664
00665 switch (action) {
00666 case STORE_SCRIPT :
00667
00668 if (body.len==0) {
00669 LM_ERR("0 content-len found for store\n");
00670 goto error_1;
00671 }
00672
00673 body.s = get_body( msg );
00674 if (body.s==0) {
00675 LM_ERR("cannot extract body from msg!\n");
00676 goto error_1;
00677 }
00678
00679
00680 if ( encodeCPL( &body, &bin, &log)!=1) {
00681 cpl_err = &bad_cpl;
00682 goto error_1;
00683 }
00684
00685
00686 if (write_to_db( &username, cpl_env.use_domain?&domain:0,
00687 &body,&bin)!=1) {
00688 cpl_err = &intern_err;
00689 goto error_1;
00690 }
00691 break;
00692 case REMOVE_SCRIPT:
00693
00694 if (body.len!=0) {
00695 LM_ERR("non-0 content-len found for remove\n");
00696 goto error_1;
00697 }
00698
00699 if (rmv_from_db( &username, cpl_env.use_domain?&domain:0)!=1) {
00700 cpl_err = &intern_err;
00701 goto error_1;
00702 }
00703 break;
00704 }
00705
00706 if (log.s) pkg_free( log.s );
00707 return 0;
00708 error_1:
00709 if (log.s) pkg_free( log.s );
00710 error:
00711 return -1;
00712 }
00713
00714
00715
00716 static inline int do_script_download(struct sip_msg *msg)
00717 {
00718 str username = {0,0};
00719 str domain = {0,0};
00720 str script = {0,0};
00721
00722
00723 if (get_dest_user( msg, &username, &domain)!=0)
00724 goto error;
00725
00726
00727 if (get_user_script( &username, cpl_env.use_domain?&domain:0,
00728 &script, &cpl_xml_col)==-1)
00729 goto error;
00730
00731
00732 if (add_lump_rpl( msg, CONTENT_TYPE_HDR, CONTENT_TYPE_HDR_LEN,
00733 LUMP_RPL_HDR)==0) {
00734 LM_ERR("cannot build hdr lump\n");
00735 cpl_err = &intern_err;
00736 goto error;
00737 }
00738
00739 if (script.s!=0) {
00740
00741 if ( add_lump_rpl( msg, script.s, script.len, LUMP_RPL_BODY)==0) {
00742 LM_ERR("cannot build body lump\n");
00743 cpl_err = &intern_err;
00744 goto error;
00745 }
00746
00747 shm_free( script.s );
00748 }
00749
00750 return 0;
00751 error:
00752 if (script.s)
00753 shm_free(script.s);
00754 return -1;
00755 }
00756
00757
00758
00759 static int w_process_register(struct sip_msg* msg, char* str, char* str2)
00760 {
00761 return cpl_process_register( msg, 0);
00762 }
00763
00764
00765
00766 static int w_process_register_norpl(struct sip_msg* msg, char* str,char* str2)
00767 {
00768 return cpl_process_register( msg, 1);
00769 }
00770
00771
00772
00773 static int cpl_process_register(struct sip_msg* msg, int no_rpl)
00774 {
00775 struct disposition *disp;
00776 struct disposition_param *param;
00777 int ret;
00778 int mime;
00779 int *mimes;
00780
00781
00782
00783
00784
00785
00786 mime = parse_content_type_hdr( msg );
00787 if (mime==-1)
00788 goto error;
00789
00790
00791 LM_DBG("Content-Type mime found %u, %u\n",
00792 mime>>16,mime&0x00ff);
00793 if ( mime && mime==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) {
00794
00795
00796 LM_DBG("carrying CPL -> look at Content-Disposition\n");
00797 if (parse_content_disposition( msg )!=0) {
00798 LM_ERR("Content-Disposition missing or corrupted\n");
00799 goto error;
00800 }
00801 disp = get_content_disposition(msg);
00802 print_disposition( disp );
00803
00804 if (disp->type.len!=CPL_SCRIPT_LEN ||
00805 strncasecmp(disp->type.s,CPL_SCRIPT,CPL_SCRIPT_LEN) ) {
00806 LM_ERR("bogus message - Content-Type"
00807 "says CPL_SCRIPT, but Content-Disposition something else\n");
00808 goto error;
00809 }
00810
00811 for(param=disp->params;param;param=param->next) {
00812 if (param->name.len==ACTION_PARAM_LEN &&
00813 !strncasecmp(param->name.s,ACTION_PARAM,ACTION_PARAM_LEN))
00814 break;
00815 }
00816 if (param==0) {
00817 LM_ERR("bogus message - "
00818 "Content-Disposition has no action param\n");
00819 goto error;
00820 }
00821
00822 if (param->body.len==STORE_ACTION_LEN &&
00823 !strncasecmp( param->body.s, STORE_ACTION, STORE_ACTION_LEN)) {
00824
00825
00826 if (do_script_action( msg, STORE_SCRIPT)==-1)
00827 goto error;
00828 } else
00829 if (param->body.len==REMOVE_ACTION_LEN &&
00830 !strncasecmp( param->body.s, REMOVE_ACTION, REMOVE_ACTION_LEN)) {
00831
00832 if (do_script_action( msg, REMOVE_SCRIPT)==-1)
00833 goto error;
00834 } else {
00835 LM_ERR("unknown action <%.*s>\n",
00836 param->body.len,param->body.s);
00837 goto error;
00838 }
00839
00840
00841 if (no_rpl)
00842 goto resume_script;
00843
00844
00845 cpl_fct.slb.send_reply( msg, 200, &cpl_ok_rpl);
00846
00847
00848 goto stop_script;
00849 }
00850
00851
00852 if ( (ret=parse_accept_hdr(msg))<0)
00853 goto error;
00854 if (ret==0 || (mimes=get_accept(msg))==0 )
00855
00856 goto resume_script;
00857
00858
00859 while (*mimes) {
00860 LM_DBG("accept mime found %u, %u\n",
00861 (*mimes)>>16,(*mimes)&0x00ff);
00862 if (*mimes==(TYPE_ALL<<16)+SUBTYPE_ALL ||
00863 *mimes==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML )
00864 break;
00865 mimes++;
00866 }
00867 if (*mimes==0)
00868
00869 goto resume_script;
00870
00871
00872
00873 if (do_script_download( msg )==-1)
00874 goto error;
00875
00876
00877 if (no_rpl)
00878 goto resume_script;
00879
00880
00881 cpl_fct.slb.send_reply( msg, 200, &cpl_ok_rpl);
00882
00883 stop_script:
00884 return 0;
00885 resume_script:
00886 return 1;
00887 error:
00888
00889 cpl_fct.slb.send_reply( msg, cpl_err->err_code, &cpl_err->err_msg);
00890
00891 return 0;
00892 }