void free_cpl_interpreter(struct cpl_interpreter *intr) { if (intr) { empty_location_set( &(intr->loc_set) ); if (intr->script.s) shm_free( intr->script.s); if (intr->user.s) shm_free(intr->user.s); if (intr->flags&CPL_RURI_DUPLICATED) shm_free(intr->ruri); if (intr->flags&CPL_TO_DUPLICATED) shm_free(intr->to); if (intr->flags&CPL_FROM_DUPLICATED) shm_free(intr->from); if (intr->flags&CPL_SUBJECT_DUPLICATED) shm_free(intr->subject); if (intr->flags&CPL_ORGANIZATION_DUPLICATED) shm_free(intr->organization); if (intr->flags&CPL_USERAGENT_DUPLICATED) shm_free(intr->user_agent); if (intr->flags&CPL_ACCEPTLANG_DUPLICATED) shm_free(intr->accept_language); if (intr->flags&CPL_PRIORITY_DUPLICATED) shm_free(intr->priority); shm_free(intr); } }
/* UPDATED + CHECKED */ static inline char *run_remove_location( struct cpl_interpreter *intr ) { unsigned short attr_name; unsigned short n; char *p; str url; int i; url.s = (char*)UNDEF_CHAR; /* sanity check */ if (NR_OF_KIDS(intr->ip)>1) { LOG(L_ERR,"ERROR:cpl_c:run_remove_location: REMOVE_LOCATION node " "suppose to have max one child, not %d!\n", NR_OF_KIDS(intr->ip)); goto script_error; } /* dirty hack to speed things up in when loc set is already empty */ if (intr->loc_set==0) goto done; for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) { get_basic_attr(p,attr_name,n,intr,script_error); switch (attr_name) { case LOCATION_ATTR: url.len = n; get_str_attr( p, url.s, url.len, intr, script_error,1); break; default: LOG(L_ERR,"ERROR:run_remove_location: unknown attribute " "(%d) in REMOVE_LOCATION node\n",attr_name); goto script_error; } } if (url.s==(char*)UNDEF_CHAR) { DBG("DEBUG:run_remove_location: remove all locs from loc_set\n"); empty_location_set( &(intr->loc_set) ); } else { remove_location( &(intr->loc_set), url.s, url.len ); } /* set the flag for modifing the location set */ intr->flags |= CPL_LOC_SET_MODIFIED; done: return get_first_child(intr->ip); script_error: return CPL_SCRIPT_ERROR; }
/* UPDATED + CHECKED */ static inline char *run_location( struct cpl_interpreter *intr ) { unsigned short attr_name; unsigned short n; char *p; unsigned char prio; unsigned char clear; str url; int i; clear = NO_VAL; prio = 10; url.s = (char*)UNDEF_CHAR; url.len = 0; /* sanity check */ if (NR_OF_KIDS(intr->ip)>1) { LM_ERR("LOCATION node suppose to have max " "one child, not %d!\n",NR_OF_KIDS(intr->ip)); goto script_error; } for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) { get_basic_attr(p,attr_name,n,intr,script_error); switch (attr_name) { case URL_ATTR: url.len = n; get_str_attr( p, url.s, url.len, intr, script_error,1); break; case PRIORITY_ATTR: if ( n>10) LM_WARN("invalid value (%u) found" " for param. PRIORITY in LOCATION node -> using " "default (%u)!\n",n,prio); else prio = n; break; case CLEAR_ATTR: if (n!=YES_VAL && n!=NO_VAL) LM_WARN("invalid value (%u) found" " for param. CLEAR in LOCATION node -> using " "default (%u)!\n",n,clear); else clear = n; break; default: LM_ERR("unknown attribute (%d) in " "LOCATION node\n",attr_name); goto script_error; } } if (url.s==(char*)UNDEF_CHAR) { LM_ERR("param. URL missing in LOCATION node\n"); goto script_error; } if (clear) empty_location_set( &(intr->loc_set) ); if (add_location( &(intr->loc_set), &url, 0, prio, 0/*no dup*/ )==-1) { LM_ERR("unable to add location to set :-(\n"); goto runtime_error; } /* set the flag for modifying the location set */ intr->flags |= CPL_LOC_SET_MODIFIED; return get_first_child(intr->ip); runtime_error: return CPL_RUNTIME_ERROR; script_error: return CPL_SCRIPT_ERROR; }
/* UPDATED + CHECKED */ static inline char *run_lookup( struct cpl_interpreter *intr ) { unsigned short attr_name; unsigned short n; unsigned char clear; char *p; char *kid; char *failure_kid = 0; char *success_kid = 0; char *notfound_kid = 0; int i; time_t tc; urecord_t* r; ucontact_t* contact; clear = NO_VAL; /* check the params */ for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) { get_basic_attr(p,attr_name,n,intr,script_error); switch (attr_name) { case CLEAR_ATTR: if (n!=YES_VAL && n!=NO_VAL) LM_WARN("invalid value (%u) found" " for param. CLEAR in LOOKUP node -> using " "default (%u)!\n",n,clear); else clear = n; break; default: LM_ERR("unknown attribute (%d) in LOOKUP node\n",attr_name); goto script_error; } } /* check the kids */ for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) { kid = intr->ip + KID_OFFSET(intr->ip,i); check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error); switch ( NODE_TYPE(kid) ) { case SUCCESS_NODE : success_kid = kid; break; case NOTFOUND_NODE: notfound_kid = kid; break; case FAILURE_NODE: failure_kid = kid; break; default: LM_ERR("unknown output node type" " (%d) for LOOKUP node\n",NODE_TYPE(kid)); goto script_error; } } kid = failure_kid; if (cpl_env.lu_domain) { /* fetch user's contacts via usrloc */ tc = time(0); cpl_fct.ulb.lock_udomain( cpl_env.lu_domain, &intr->user ); i = cpl_fct.ulb.get_urecord( cpl_env.lu_domain, &intr->user, &r); if (i < 0) { /* failure */ LM_ERR("failed to query usrloc\n"); cpl_fct.ulb.unlock_udomain( cpl_env.lu_domain, &intr->user ); } else if (i > 0) { /* not found */ LM_DBG("'%.*s' Not found in usrloc\n", intr->user.len, intr->user.s); cpl_fct.ulb.unlock_udomain( cpl_env.lu_domain, &intr->user ); kid = notfound_kid; } else { contact = r->contacts; /* skip expired contacts */ while ((contact) && (contact->expires <= tc)) contact = contact->next; /* any contacts left? */ if (contact) { /* clear loc set if requested */ if (clear) empty_location_set( &(intr->loc_set) ); /* start adding locations to set */ do { LM_DBG("adding <%.*s>q=%d\n", contact->c.len,contact->c.s,(int)(10*contact->q)); if (add_location( &(intr->loc_set), &contact->c, &contact->received, (int)(10*contact->q), CPL_LOC_DUPL| ((contact->cflags&cpl_fct.ulb.nat_flag)?CPL_LOC_NATED:0) )==-1) { LM_ERR("unable to add location to set :-(\n"); cpl_fct.ulb.unlock_udomain( cpl_env.lu_domain, &intr->user ); goto runtime_error; } contact = contact->next; }while( contact && cpl_env.lu_append_branches); /* set the flag for modifying the location set */ intr->flags |= CPL_LOC_SET_MODIFIED; /* we found a valid contact */ kid = success_kid; } else { /* no valid contact found */ kid = notfound_kid; } cpl_fct.ulb.unlock_udomain( cpl_env.lu_domain, &intr->user ); } } if (kid) return get_first_child(kid); return DEFAULT_ACTION; runtime_error: return CPL_RUNTIME_ERROR; script_error: return CPL_SCRIPT_ERROR; }