Esempio n. 1
0
/*! \brief Adds the proxies in the proxy list & resolves the hostnames 
 * \return 0 if ok, <0 on error */
static int fix_actions(struct action* a)
{
	struct action *t;
	int ret;
	cmd_export_t* cmd;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	str host;
	int proto=PROTO_NONE, port;
	struct proxy_l *p;
	struct bl_head *blh;
	int i;
	str s;
	pv_elem_t *model=NULL;
	pv_elem_t *models[5]; 
	xl_level_p xlp;

	if (a==0){
		LM_CRIT("null pointer\n");
		return E_BUG;
	}
	for(t=a; t!=0; t=t->next){
		switch(t->type){
			case ROUTE_T:
				if (t->elem[0].type!=NUMBER_ST){
					LM_ALERT("BUG in route() type %d\n",
						t->elem[0].type);
					ret = E_BUG;
					goto error;
				}
				if ((t->elem[0].u.number>RT_NO)||(t->elem[0].u.number<0)){
					LM_ALERT("invalid routing table number in"
							"route(%lu)\n", t->elem[0].u.number);
					ret = E_CFG;
					goto error;
				}
				if ( rlist[t->elem[0].u.number].a==NULL ) {
					LM_ERR("called route %d is not defined\n",
						(int)t->elem[0].u.number);
					ret = E_CFG;
					goto error;
				}
				break;
			case FORWARD_T:
				if (sl_fwd_disabled>0) {
					LM_ERR("stateless forwarding disabled, but forward() "
						"is used!!\n");
					ret = E_CFG;
					goto error;
				}
				sl_fwd_disabled = 0;
				if (t->elem[0].type==NOSUBTYPE)
					break;
			case SEND_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("invalid type %d (should be string)\n", t->type);
					ret = E_BUG;
					goto error;
				}
				ret = parse_phostport( t->elem[0].u.string,
						strlen(t->elem[0].u.string),
						&host.s, &host.len, &port, &proto);
				if (ret!=0) {
					LM_ERR("ERROR:fix_actions: FORWARD/SEND bad "
						"argument\n");
					ret = E_CFG;
					goto error;
				}
				p = add_proxy( &host,(unsigned short)port, proto);
				if (p==0) {
					LM_ERR("forward/send failed to add proxy");
					ret = E_CFG;
					goto error;
				}
				t->elem[0].type = PROXY_ST;
				t->elem[0].u.data = (void*)p;
				break;
			case IF_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for if (should be expr)\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {...} (should be"
								"action)\n", t->elem[1].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[2].type!=ACTIONS_ST)
						&&(t->elem[2].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {} else{...}(should"
							"be action)\n", t->elem[2].type);
					ret = E_BUG;
					goto error;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				if ( (t->elem[2].type==ACTIONS_ST)&&(t->elem[2].u.data) ){
					if((ret=fix_actions((struct action*)t->elem[2].u.data))<0)
						return ret;
				}
				break;
			case WHILE_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for while (should be expr)\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for while() {...} (should be"
								"action)\n", t->elem[1].type);
					ret = E_BUG;
					goto error;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case SWITCH_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case CASE_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case DEFAULT_T:
				if ( (t->elem[0].type==ACTIONS_ST)&&(t->elem[0].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[0].u.data))<0)
						return ret;
				}
				break;
			case MODULE_T:
				cmd = (cmd_export_t*)t->elem[0].u.data;
				LM_DBG("fixing %s, line %d\n", cmd->name, t->line);
				if (cmd->fixup){
					if (cmd->param_no==0){
						ret=cmd->fixup( 0, 0);
						if (ret<0) goto error;
					}
					else {
						for (i=1; i<=cmd->param_no; i++) {
							ret=cmd->fixup(&t->elem[i].u.data, i);
							t->elem[i].type=MODFIXUP_ST;
							if (ret<0) goto error;
						}
					}
				}
				break;
			case FORCE_SEND_SOCKET_T:
				if (t->elem[0].type!=SOCKID_ST){
					LM_CRIT("invalid subtype %d for force_send_socket\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}
				he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0);
				if (he==0){
					LM_ERR(" could not resolve %s\n",
								((struct socket_id*)t->elem[0].u.data)->name);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				hostent2ip_addr(&ip, he, 0);
				si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port,
								((struct socket_id*)t->elem[0].u.data)->proto);
				if (si==0){
					LM_ERR("bad force_send_socket"
						" argument: %s:%d (opensips doesn't listen on it)\n",
						((struct socket_id*)t->elem[0].u.data)->name,
						((struct socket_id*)t->elem[0].u.data)->port);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				t->elem[0].u.data=si;
				t->elem[0].type=SOCKETINFO_ST;
				break;
			case SET_DEBUG_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("fix_actions: BUG in setdebug() type %d\n",
						t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				/* normalize the value */
				if (t->elem[0].u.number>L_DBG)
					t->elem[0].u.number = L_DBG;
				else if (t->elem[0].u.number<L_ALERT)
					t->elem[0].u.number = L_ALERT;
				break;
			case SETFLAG_T:
			case RESETFLAG_T:
			case ISFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				if (!flag_in_range( t->elem[0].u.number )) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETSFLAG_T:
			case RESETSFLAG_T:
			case ISSFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxsflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				t->elem[0].u.number = fixup_flag( t->elem[0].u.number );
				if (t->elem[0].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETBFLAG_T:
			case RESETBFLAG_T:
			case ISBFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST || t->elem[1].type!=NUMBER_ST) {
					LM_CRIT("bad xxxbflag() type "
						"%d,%d\n", t->elem[0].type, t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				t->elem[1].u.number = fixup_flag( t->elem[1].u.number );
				if (t->elem[1].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case EQ_T:
			case COLONEQ_T:
			case PLUSEQ_T:
			case MINUSEQ_T:
			case DIVEQ_T:
			case MULTEQ_T:
			case MODULOEQ_T:
			case BANDEQ_T:
			case BOREQ_T:
			case BXOREQ_T:
				if (t->elem[1].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case USE_BLACKLIST_T:
			case UNUSE_BLACKLIST_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("bad [UN]USE_BLACKLIST type %d\n",t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				host.s = t->elem[0].u.string;
				host.len = strlen(host.s);
				if ( strcasecmp(host.s,"all")==0 ) {
					blh = NULL;
				} else {
					blh = get_bl_head_by_name(&host);
					if (blh==NULL) {
						LM_ERR("[UN]USE_BLACKLIST - list "
							"%s not configured\n", t->elem[0].u.string);
						ret=E_CFG;
						goto error;
					}
				}
				t->elem[0].type = BLACKLIST_ST;
				t->elem[0].u.data = blh;
				break;
			case CACHE_STORE_T:
			case CACHE_FETCH_T:
			case CACHE_REMOVE_T:
				/* attr name */
				s.s = (char*)t->elem[1].u.data;
				s.len = strlen(s.s);
				if(s.len==0) {
					LM_ERR("param 2 is empty string!\n");
					return E_CFG;
				}

				if(pv_parse_format(&s ,&model) || model==NULL) {
						LM_ERR("wrong format [%s] for value param!\n", s.s);
						ret=E_BUG;
						goto error;
				}
				t->elem[1].u.data = (void*)model;

				if (t->type==CACHE_REMOVE_T)
					break;

				/* value */
				if (t->type==CACHE_FETCH_T) {
					if(((pv_spec_p)t->elem[2].u.data)->type!= PVT_AVP)
					{
						LM_ERR("Wrong type for the third argument - "
							"must be an AVP\n");
						ret=E_BUG;
						goto error;
					}
				} else {
					s.s = (char*)t->elem[2].u.data;
					s.len = strlen(s.s);
					if(s.len==0) {
						LM_ERR("param 2 is empty string!\n");
						return E_CFG;
					}

					if(pv_parse_format(&s ,&model) || model==NULL) {
						LM_ERR("wrong format [%s] for value param!\n",s.s);
						ret=E_BUG;
						goto error;
					}
					t->elem[2].u.data = (void*)model;
				}

				break;
			case XDBG_T:
			case XLOG_T:
				s.s = (char*)t->elem[1].u.data;
				if (s.s == NULL)
				{
					/* commands have only one parameter */
					s.s = (char *)t->elem[0].u.data;
					s.len = strlen(s.s);
					if(s.len==0)
					{
						LM_ERR("param is empty string!\n");
						return E_CFG;
					}

					if(pv_parse_format(&s ,&model) || model==NULL)
					{
						LM_ERR("wrong format [%s] for value param!\n", s.s);
						ret=E_BUG;
						goto error;
					}
					
					t->elem[0].u.data = (void*)model;
					t->elem[0].type = SCRIPTVAR_ELEM_ST;
				}
				else
				{
					/* there are two parameters */
					s.s = (char *)t->elem[0].u.data;
					s.len = strlen(s.s);
					if (s.len == 0)
					{
						LM_ERR("param is empty string\n");
						return E_CFG;
					}
					xlp = (xl_level_p)pkg_malloc(sizeof(xl_level_t));
					if(xlp == NULL)
					{
						LM_ERR("no more memory\n");
						return E_UNSPEC;
					}

					memset(xlp, 0, sizeof(xl_level_t));
					if(s.s[0]==PV_MARKER)
					{
						xlp->type = 1;
						if(pv_parse_spec(&s, &xlp->v.sp)==NULL)
						{
							LM_ERR("invalid level param\n");
							return E_UNSPEC;
						}
					} 
					else 
					{
						xlp->type = 0;
						switch(s.s[2])
						{
							case 'A': xlp->v.level = L_ALERT; break;
							case 'C': xlp->v.level = L_CRIT; break;
							case 'E': xlp->v.level = L_ERR; break;
							case 'W': xlp->v.level = L_WARN; break;
							case 'N': xlp->v.level = L_NOTICE; break;
							case 'I': xlp->v.level = L_INFO; break;
							case 'D': xlp->v.level = L_DBG; break;
							default:
								LM_ERR("unknown log level\n");
								return E_UNSPEC;
						}
					}
					t->elem[0].u.data = xlp;

					s.s = t->elem[1].u.data;
					s.len = strlen(s.s);
					if (pv_parse_format(&s, &model) || model == NULL)
					{
						LM_ERR("wrong fomat [%s] for value param\n",s.s);
						ret=E_BUG;
						goto error;
					}

					t->elem[1].u.data = model;
					t->elem[1].type = SCRIPTVAR_ELEM_ST;
				}
				break;
			case CONSTRUCT_URI_T:
				for (i=0;i<5;i++)
				{	
					s.s = (char*)t->elem[i].u.data;
					s.len = strlen(s.s);
					if(s.len==0) 
						continue;

					if(pv_parse_format(&s ,&(models[i])) || models[i]==NULL) 
					{
						LM_ERR("wrong format [%s] for value param!\n",s.s);
						ret=E_BUG;
						goto error;
					}

					t->elem[i].u.data = (void*)models[i];
				}
				
				if (((pv_spec_p)t->elem[5].u.data)->type != PVT_AVP)
				{
					LM_ERR("Wrong type for the third argument - "
						"must be an AVP\n");
					ret=E_BUG;
					goto error;
				}

				break;
		}
	}
	return 0;
error:
	LM_ERR("fixing failed (code=%d) at cfg line %d\n", ret, t->line);
	return ret;
}
Esempio n. 2
0
struct bl_head *create_bl_head(int owner, int flags, struct bl_rule *head,
											struct bl_rule *tail, str *name)
{
	unsigned int i;

	i = used_heads;
	if (i==max_heads) {
		LM_ERR("too many lists\n");
		return NULL;
	}

	if (get_bl_head_by_name(name)!=NULL) {
		LM_CRIT("duplicated name!\n");
		return NULL;
	}

	if ( flags&BL_READONLY_LIST && flags&BL_DO_EXPIRE){
		LM_CRIT("RO lists cannot accept EXPIRES!\n");
		return NULL;
	}

	/* copy list name */
	if (no_shm)
		blst_heads[i].name.s = (char*)pkg_malloc(name->len + 1);
	else
		blst_heads[i].name.s = (char*)shm_malloc(name->len + 1);
	if (blst_heads[i].name.s==NULL) {
		LM_ERR("no more pkg memory!\n");
		return NULL;
	}
	memcpy( blst_heads[i].name.s, name->s, name->len);
	blst_heads[i].name.s[name->len] = '\0';
	blst_heads[i].name.len = name->len;

	/* build lock? */
	if (!no_shm && !(flags&BL_READONLY_LIST)) {
		if ( (blst_heads[i].lock=lock_alloc())==NULL ) {
			LM_ERR("failed to create lock!\n");
			shm_free(blst_heads[i].name.s);
			return NULL;
		}
		if ( lock_init(blst_heads[i].lock)==NULL ) {
			LM_ERR("failed to init lock!\n");
			shm_free(blst_heads[i].name.s);
			lock_dealloc(blst_heads[i].lock);
			return NULL;
		}
	}

	used_heads++;

	blst_heads[i].owner = owner;
	blst_heads[i].flags = flags;
	blst_heads[i].first = head;
	blst_heads[i].last = tail;

	if (flags&BL_BY_DEFAULT)
		bl_default_marker |= (1<<i);

	return blst_heads + i;
}
Esempio n. 3
0
/* returns 0 if ok, <0 on error */
static int fix_actions(struct action* a)
{
	struct action *t;
	int ret;
	cmd_export_t* cmd;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	str host;
	int proto=PROTO_NONE, port;
	struct proxy_l *p;
	struct bl_head *blh;

	if (a==0){
		LM_CRIT("null pointer\n");
		return E_BUG;
	}
	for(t=a; t!=0; t=t->next){
		switch(t->type){
			case FORWARD_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
			case SEND_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("invalid type %d (should be string)\n", t->type);
					return E_BUG;
				}
				ret = parse_phostport( t->elem[0].u.string,
						strlen(t->elem[0].u.string),
						&host.s, &host.len, &port, &proto);
				if (ret!=0) {
					LM_ERR("ERROR:fix_actions: FORWARD/SEND bad "
						"argument\n");
					return E_CFG;
				}
				p = add_proxy( &host,(unsigned short)port, proto);
				if (p==0) {
					LM_ERR("forward/send failed to add proxy");
					return E_CFG;
				}
				t->elem[0].type = PROXY_ST;
				t->elem[0].u.data = (void*)p;
				break;
			case IF_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for if (should be expr)\n",
								t->elem[0].type);
					return E_BUG;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {...} (should be"
								"action)\n", t->elem[1].type);
					return E_BUG;
				}else if( (t->elem[2].type!=ACTIONS_ST)
						&&(t->elem[2].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {} else{...}(should"
							"be action)\n", t->elem[2].type);
					return E_BUG;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				if ( (t->elem[2].type==ACTIONS_ST)&&(t->elem[2].u.data) ){
					if((ret=fix_actions((struct action*)t->elem[2].u.data))<0)
						return ret;
				}
				break;
			case WHILE_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for while (should be expr)\n",
								t->elem[0].type);
					return E_BUG;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for while() {...} (should be"
								"action)\n", t->elem[1].type);
					return E_BUG;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case SWITCH_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case CASE_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case DEFAULT_T:
				if ( (t->elem[0].type==ACTIONS_ST)&&(t->elem[0].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[0].u.data))<0)
						return ret;
				}
				break;
			case MODULE_T:
				cmd = (cmd_export_t*)t->elem[0].u.data;
				LM_DBG("fixing %s, line %d\n", cmd->name, t->line);
				if (cmd->fixup){
					if (cmd->param_no>0){
						ret=cmd->fixup(&t->elem[1].u.data, 1);
						t->elem[1].type=MODFIXUP_ST;
						if (ret<0) goto error;
					}
					if (cmd->param_no>1){
						ret=cmd->fixup(&t->elem[2].u.data, 2);
						t->elem[2].type=MODFIXUP_ST;
						if (ret<0) goto error;
					}
					if (cmd->param_no==0){
						ret=cmd->fixup( 0, 0);
						if (ret<0) goto error;
					}
				}
				break;
			case FORCE_SEND_SOCKET_T:
				if (t->elem[0].type!=SOCKID_ST){
					LM_CRIT("invalid subtype %d for force_send_socket\n",
								t->elem[0].type);
					return E_BUG;
				}
				he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0);
				if (he==0){
					LM_ERR(" could not resolve %s\n",
								((struct socket_id*)t->elem[0].u.data)->name);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				hostent2ip_addr(&ip, he, 0);
				si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port,
								((struct socket_id*)t->elem[0].u.data)->proto);
				if (si==0){
					LM_ERR("bad force_send_socket"
							" argument: %s:%d (ser doesn't listen on it)\n",
							((struct socket_id*)t->elem[0].u.data)->name,
							((struct socket_id*)t->elem[0].u.data)->port);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				t->elem[0].u.data=si;
				t->elem[0].type=SOCKETINFO_ST;
				break;
			case SET_DEBUG_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("fix_actions: BUG in setdebug() type %d\n",
						t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				/* normalize the value */
				if (t->elem[0].u.number>L_DBG)
					t->elem[0].u.number = L_DBG;
				else if (t->elem[0].u.number<L_ALERT)
					t->elem[0].u.number = L_ALERT;
				break;
			case SETFLAG_T:
			case RESETFLAG_T:
			case ISFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				if (!flag_in_range( t->elem[0].u.number )) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETSFLAG_T:
			case RESETSFLAG_T:
			case ISSFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxsflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				t->elem[0].u.number = fixup_flag( t->elem[0].u.number );
				if (t->elem[0].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETBFLAG_T:
			case RESETBFLAG_T:
			case ISBFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST || t->elem[1].type!=NUMBER_ST) {
					LM_CRIT("bad xxxbflag() type "
						"%d,%d\n", t->elem[0].type, t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				t->elem[1].u.number = fixup_flag( t->elem[1].u.number );
				if (t->elem[1].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case EQ_T:
			case COLONEQ_T:
			case PLUSEQ_T:
			case MINUSEQ_T:
			case DIVEQ_T:
			case MULTEQ_T:
			case MODULOEQ_T:
			case BANDEQ_T:
			case BOREQ_T:
			case BXOREQ_T:
				if (t->elem[1].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case USE_BLACKLIST_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("bad USE_BLACKLIST type %d\n", t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				host.s = t->elem[0].u.string;
				host.len = strlen(host.s);
				blh = get_bl_head_by_name(&host);
				if (blh==NULL) {
					LM_ERR("USE_BLACKLIST - list "
						"%s not configured\n", t->elem[0].u.string);
					ret=E_CFG;
					goto error;
				}
				t->elem[0].type = BLACKLIST_ST;
				t->elem[0].u.data = blh;
				break;
		}
	}
	return 0;
error:
	LM_ERR("fixing failed (code=%d) at cfg line %d\n", ret, t->line);
	return ret;
}