예제 #1
0
파일: dialog.c 프로젝트: ihassin/opensips
int pv_set_dlg_timeout(struct sip_msg *msg, pv_param_t *param,
		int op, pv_value_t *val)
{
	struct dlg_cell *dlg;
	int timeout, db_update = 0, timer_update = 0;

	if (val==NULL || val->flags & PV_VAL_NULL) {
		LM_ERR("cannot assign dialog timeout to NULL\n");
		return -1;
	}

	if (!(val->flags&PV_VAL_INT)){
		/* try parsing the string */
		if (str2sint(&val->rs, &timeout) < 0) {
			LM_ERR("assigning non-int value to dialog flags\n");
			return -1;
		}
	} else {
		timeout = val->ri;
	}

	if (timeout < 0) {
		LM_ERR("cannot set a negative timeout\n");
		return -1;
	}
	if ((dlg = get_current_dialog()) != NULL) {
		dlg_lock_dlg(dlg);
		dlg->lifetime = timeout;
		/* update now only if realtime and the dialog is confirmed */
		if (dlg->state >= DLG_STATE_CONFIRMED && dlg_db_mode == DB_MODE_REALTIME)
			db_update = 1;
		else
			dlg->flags |= DLG_FLAG_CHANGED;

		if (dlg->state == DLG_STATE_CONFIRMED_NA ||
		dlg->state == DLG_STATE_CONFIRMED)
			timer_update = 1;

		dlg_unlock_dlg(dlg);

		if (db_update)
			update_dialog_timeout_info(dlg);

		if (replication_dests)
			replicate_dialog_updated(dlg);

		if (timer_update && update_dlg_timer(&dlg->tl, timeout) < 0) {
			LM_ERR("failed to update timer\n");
			return -1;
		}
	} else if (current_processing_ctx) {
		/* store it until we match the dialog */
		ctx_timeout_set( timeout );
	} else {
		LM_CRIT("BUG - no proicessing context found !\n");
		return -1;
	}

	return 0;
}
예제 #2
0
/* NOTE: assumes that the pipe has been locked. If fails, releases the lock */
static int rl_get_counter(str *name, rl_pipe_t * pipe)
{
	str res;
	unsigned int hid = RL_GET_INDEX(*name);
	int new_counter;

	RL_SET_PENDING(pipe);
	RL_RELEASE_LOCK(hid);

	if (rl_set_name(name) < 0)
		return -1;
	if (cdbf.get(cdbc, &rl_name_buffer, &res) < 0) {
		LM_ERR("cannot retrieve key\n");
		return -1;
	}
	if (str2sint(&res, &new_counter) < 0) {
		LM_ERR("invalid value %.*s - should be integer\n", res.len, res.s);
		return -1;
	}
	if (res.s)
		pkg_free(res.s);
	RL_GET_LOCK(hid);
	RL_RESET_PENDING(pipe);
	pipe->counter = new_counter;
	return 0;
}
예제 #3
0
int
fixup_var_str_int(void **param, int param_no)
{
    int ret;
    pv_elem_t *model;
    str s;

    if (param_no == 1) {
        model = NULL;
        s.s = (char *)(*param);
        s.len = strlen(s.s);
        if (pv_parse_format(&s, &model) < 0) {
            LM_ERR("wrong format[%s]!\n", (char *)(*param));
            return E_UNSPEC;
        }
        if (model == NULL) {
            LM_ERR("empty parameter!\n");
            return E_UNSPEC;
        }
        *param = (void *)model;
    } else if (param_no == 2) {
        s.s = (char *)(*param);
        s.len = strlen(s.s);
        if (str2sint(&s, &ret) < 0) {
            LM_ERR("bad number <%s>\n", (char *)(*param));
            return E_CFG;
		}
        pkg_free(*param);
        *param = (void *)(long)ret;
    }
    return 0;
}
예제 #4
0
static struct mi_root *mi_debug(struct mi_root *cmd, void *param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node;
	char *p;
	int len;
	int new_debug;

	node = cmd->node.kids;
	if (node!=NULL) {
		if (str2sint( &node->value, &new_debug) < 0)
			return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
	} else
		new_debug = debug;

	rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
	if (rpl_tree==0)
		return 0;

	p = sint2str((long)new_debug, &len);
	node = add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE,
		MI_SSTR("DEBUG"),p, len);
	if (node==0) {
		free_mi_tree(rpl_tree);
		return 0;
	}

	debug = new_debug;

	return rpl_tree;
}
예제 #5
0
파일: cfg_parser.c 프로젝트: 2pac/kamailio
int cfg_parse_int(void* param, cfg_parser_t* st, unsigned int flags)
{
	int* val;
	int ret, tmp;
	cfg_token_t t;

	val = (int*)param;

	ret = cfg_get_token(&t, st, flags);
	if (ret != 0) return ret;

	if (t.type != CFG_TOKEN_ALPHA && t.type != CFG_TOKEN_STRING) {
		ERR("%s:%d:%d: Invalid integer value '%.*s'\n", 
		    st->file, t.start.line, t.start.col, STR_FMT(&t.val));
		return -1;
	}

	if (str2sint(&t.val, &tmp) < 0) {
		ERR("%s:%d:%d: Invalid integer value '%.*s'\n",
			st->file, t.start.line, t.start.col, STR_FMT(&t.val));
		return -1;
	}

	if (val) *val = tmp;
	return 0;
}
예제 #6
0
int sql_parse_index(str *in, gparam_t *gp)
{
	if(in->s[0]==PV_MARKER)
	{
		gp->type = GPARAM_TYPE_PVS;
		gp->v.pvs = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
		if (gp->v.pvs == NULL)
		{
			LM_ERR("no pkg memory left for pv_spec_t\n");
		    pkg_free(gp);
		    return -1;
		}

		if(pv_parse_spec(in, gp->v.pvs)==NULL)
		{
			LM_ERR("invalid PV identifier\n");
		    pkg_free(gp->v.pvs);
		    pkg_free(gp);
			return -1;
		}
	} else {
		gp->type = GPARAM_TYPE_INT;
		if(str2sint(in, &gp->v.i) != 0)
		{
			LM_ERR("bad number <%.*s>\n", in->len, in->s);
			return -1;
		}
	}
	return 0;
}
예제 #7
0
static struct mi_root* mi_set_dbg_mod_level(struct mi_root *cmd_tree, void *param) {
    struct mi_node *node;
    str mod_str, level_str;
    int l;

    /* get first param */
    node = cmd_tree->node.kids;
    if (node == NULL) {
        return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
    }

    if (node->value.s == NULL || node->value.len == 0) {
        return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
    }

    /* get module str */
    mod_str = node->value;

    /* get second param */
    node = node->next;
    if (node == NULL) {
        return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
    }

    if (node->value.s == NULL || node->value.len == 0) {
        return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
    }

    /* get level str */
    level_str = node->value;

    /* no further params expected */
    node = node->next;
    if (node != NULL) {
        return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
    }

    /* get level int */
    if (str2sint(&level_str, &l) < 0) {
        LM_ERR("invalid parameter - level value: %.*s\n",
               level_str.len, level_str.s);
        return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
    }

    /* set level int */
    if (default_dbg_cfg.mod_hash_size <= 0 || default_dbg_cfg.mod_level_mode <= 0) {
        LM_ERR("can't set level for module=%.*s; enable mod_hash_size and mod_level_mode config parameters!\n",
               mod_str.len, mod_str.s);
        return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
    } else if (dbg_set_mod_debug_level(mod_str.s, mod_str.len, &l) < 0) {
        LM_ERR("failed set level for module=%.*s\n", mod_str.len, mod_str.s);
        return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
    } else {
        LM_DBG("module=%.*s level_str=%.*s level_int=%d\n",
               mod_str.len, mod_str.s, level_str.len, level_str.s, l);
    }

    return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
}
예제 #8
0
파일: hash.c 프로젝트: leedm777/opensips
int lcache_htable_fetch_counter(cachedb_con* con,str* attr,int *val)
{
	int hash_code;
	lcache_entry_t* it = NULL, *it_aux = NULL;
	int ret;
	struct timeval start;

	start_expire_timer(start,local_exec_threshold);

	hash_code= core_hash( attr, 0, cache_htable_size);
	lock_get(&cache_htable[hash_code].lock);

	it = cache_htable[hash_code].entries;

	while(it)
	{
		if(it->attr.len == attr->len && 
				(strncmp(it->attr.s, attr->s, attr->len) == 0))
		{
			if( it->expires != 0 && it->expires < get_ticks())
			{
				/* found an expired entry  -> delete it */
				if(it_aux)
					it_aux->next = it->next;
				else
					cache_htable[hash_code].entries = it->next;
				
				shm_free(it);

				lock_release(&cache_htable[hash_code].lock);
				stop_expire_timer(start,local_exec_threshold,
				"cachedb_local fetch_counter",attr->s,attr->len,0);
				return -2;
			}
			if (str2sint(&it->value,&ret) != 0) {
				LM_ERR("Not a counter key\n");
				lock_release(&cache_htable[hash_code].lock);
				stop_expire_timer(start,local_exec_threshold,
				"cachedb_local fetch_counter",attr->s,attr->len,0);
				return -3;
			}
			if (val)
				*val = ret;
			lock_release(&cache_htable[hash_code].lock);
			stop_expire_timer(start,local_exec_threshold,
			"cachedb_local fetch_counter",attr->s,attr->len,0);
			return 1;
		}

		it_aux = it;
		it = it->next;
	}
	
	lock_release(&cache_htable[hash_code].lock);
	stop_expire_timer(start,local_exec_threshold,
	"cachedb_local fetch_counter",attr->s,attr->len,0);
	return -2;
}
예제 #9
0
파일: shvar.c 프로젝트: GeorgeShaw/opensips
int param_set_xvar( modparam_t type, void* val, int mode)
{
	str s;
	char *p;
	int_str isv;
	int flags;
	int ival;
	script_var_t *sv;

	if(shvar_initialized!=0)
		goto error;

	s.s = (char*)val;
	if(s.s == NULL || s.s[0] == '\0')
		goto error;

	p = s.s;
	while(*p && *p!='=') p++;

	if(*p!='=')
		goto error;

	s.len = p - s.s;
	if(s.len == 0)
		goto error;
	p++;
	flags = 0;
	if(*p!='s' && *p!='S' && *p!='i' && *p!='I')
		goto error;

	if(*p=='s' || *p=='S')
		flags = VAR_VAL_STR;
	p++;
	if(*p!=':')
		goto error;
	p++;
	isv.s.s = p;
	isv.s.len = strlen(p);
	if(flags != VAR_VAL_STR) {
		if(str2sint(&isv.s, &ival)<0)
			goto error;
		isv.n = ival;
	}
	if(mode==0)
		sv = add_var(&s);
	else
		sv = add_local_shvar(&s);
	if(sv==NULL)
		goto error;
	if(set_var_value(sv, &isv, flags)==NULL)
		goto error;

	return 0;
error:
	LM_ERR("unable to set %s parameter [%s]\n",
			(mode == 0 ? "var" : "shv"), s.s);
	return -1;
}
예제 #10
0
static inline int ldap_int2db_int(int* dst, str* src)
{
	if (str2sint(src, dst) != 0) {
		ERR("ldap: Error while converting value '%.*s' to integer\n",
			src->len, ZSW(src->s));
		return -1;
	}
	return 0;
}
예제 #11
0
int mq_param(modparam_t type, void *val)
{
	str mqs;
	param_t* params_list = NULL;
	param_hooks_t phooks;
	param_t *pit=NULL;
	str qname = {0, 0};
	int msize = 0;

	if(val==NULL)
		return -1;

	if(!shm_initialized())
	{
		LM_ERR("shm not initialized - cannot define mqueue now\n");
		return 0;
	}

	mqs.s = (char*)val;
	mqs.len = strlen(mqs.s);
	if(mqs.s[mqs.len-1]==';')
		mqs.len--;
	if (parse_params(&mqs, CLASS_ANY, &phooks, &params_list)<0)
		return -1;
	for (pit = params_list; pit; pit=pit->next)
	{
		if (pit->name.len==4
				&& strncasecmp(pit->name.s, "name", 4)==0) {
			qname = pit->body;
		} else if(pit->name.len==4
				&& strncasecmp(pit->name.s, "size", 4)==0) {
			str2sint(&pit->body, &msize);
		}  else {
			LM_ERR("unknown param: %.*s\n", pit->name.len, pit->name.s);
			free_params(params_list);
			return -1;
		}
	}
	if(qname.len<=0)
	{
		LM_ERR("mqueue name not defined: %.*s\n", mqs.len, mqs.s);
		free_params(params_list);
		return -1;
	}
	if(mq_head_add(&qname, msize)<0)
	{
		LM_ERR("cannot add mqueue: %.*s\n", mqs.len, mqs.s);
		free_params(params_list);
		return -1;
	}
	free_params(params_list);
	return 0;
}
예제 #12
0
int wrap_memcached_get_counter(cachedb_con *connection,str* attr, int* res)
{
	memcached_return_t  rc;
	char * ret;
	size_t ret_len;
	uint32_t fl;
	char * err;
	memcached_con *con;
	struct timeval start;
	str rpl;

	start_expire_timer(start,memcache_exec_threshold);
	con = (memcached_con *)connection->data;

	ret = memcached_get(con->memc,attr->s, attr->len,
				&ret_len,&fl,&rc);

	if(ret == NULL)
	{
		if(rc == MEMCACHED_NOTFOUND)
		{
			stop_expire_timer(start,memcache_exec_threshold,
			"cachedb_memcached counter fetch",attr->s,attr->len,0);
			return -2;
		}
		else
		{
			err = (char*)memcached_strerror(con->memc,rc);
			LM_ERR("Failed to get: %s\n",err );
			stop_expire_timer(start,memcache_exec_threshold,
			"cachedb_memcached counter fetch",attr->s,attr->len,0);
			return -1;
		}
	}

	rpl.len = (int)ret_len;
	rpl.s = ret;
	
	if (str2sint(&rpl,res) < 0) {
		LM_ERR("Failed to convert %.*s to int\n",(int)ret_len,ret);
		stop_expire_timer(start,memcache_exec_threshold,
			"cachedb_memcached counter fetch",attr->s,attr->len,0);
		free(ret);
		return -1;
		
	}

	stop_expire_timer(start,memcache_exec_threshold,
		"cachedb_memcached counter fetch",attr->s,attr->len,0);
	free(ret);
	return 0;
}
예제 #13
0
/*
 * set pv_value_t in pkg to pv_value_t from extra in shm
 *
 * * if it's an integer then convert it to string and set the string value
 * to the shm pv_value_t
 * * if it's a string then try converting it to it
 */
int set_value_shm(pv_value_t* pvt, extra_value_t* extra)
{
	if (pvt == NULL) {
		LM_ERR("bad value!\n");
		return -1;
	}

	if (pvt->flags&PV_TYPE_INT || pvt->flags&PV_VAL_STR) {
		if (pvt->flags&PV_TYPE_INT || pvt->flags&PV_VAL_INT) {
			/* transform the int value into a string */
			pvt->rs.s = int2str(pvt->ri, &pvt->rs.len);
			pvt->flags |= PV_VAL_STR;
		} else { /* it's PV_VAL_STR; check whether it is an integer value */
			if (str2sint(&pvt->rs, &pvt->ri) == 0) {
				pvt->flags |= PV_TYPE_INT|PV_VAL_INT;
			}
		}

		if (extra->shm_buf_len == 0) {
			extra->value.s = shm_malloc(pvt->rs.len);
			extra->shm_buf_len = extra->value.len = pvt->rs.len;
		} else if (extra->shm_buf_len < pvt->rs.len) {
			extra->value.s = shm_realloc(extra->value.s, pvt->rs.len);
			extra->shm_buf_len = extra->value.len = pvt->rs.len;
		} else {
			extra->value.len = pvt->rs.len;
		}

		if (extra->value.s == NULL)
			goto memerr;

		memcpy(extra->value.s, pvt->rs.s, pvt->rs.len);
	}  else if (pvt->flags&PV_VAL_NULL) {
		if (extra->shm_buf_len) {
			shm_free(extra->value.s);
			extra->shm_buf_len = 0;
		}
		extra->value.s = NULL;
		extra->value.len = 0;
	} else {
		LM_ERR("invalid pvt value!\n");
		return -1;
	}

	return 0;

memerr:
	LM_ERR("No more shm!\n");
	return -1;
}
예제 #14
0
/**
 * @brief dmq notification callback
 */
int dmq_notification_callback(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* dmq_node)
{
	int nodes_recv;
	str* response_body = NULL;
	int maxforwards = 0;
	/* received dmqnode list */
	LM_DBG("dmq triggered from dmq_notification_callback\n");
	
	/* extract the maxforwards value, if any */
	if(msg->maxforwards) {
		if (msg->maxforwards->parsed > 0) {
			/* maxfwd module has parsed and decreased the value in the msg buf */
			/* maxforwards->parsed contains the original value */
			maxforwards = (int)(long)(msg->maxforwards->parsed) - 1;
		} else {
			str2sint(&msg->maxforwards->body, &maxforwards);
			maxforwards--;
		}
	}
	nodes_recv = extract_node_list(node_list, msg);
	LM_DBG("received %d new or changed nodes\n", nodes_recv);
	response_body = build_notification_body();
	if(response_body==NULL) {
		LM_ERR("no response body\n");
		goto error;
	}
	resp->content_type = notification_content_type;
	resp->reason = dmq_200_rpl;
	resp->body = *response_body;
	resp->resp_code = 200;
	
	/* if we received any new nodes tell about them to the others */
	if(nodes_recv > 0 && maxforwards > 0) {
		/* maxforwards is set to 0 so that the message is will not be in a spiral */
		bcast_dmq_message(dmq_notification_peer, response_body, 0,
				&notification_callback, maxforwards, &notification_content_type);
	}
	pkg_free(response_body);
	if (dmq_init_callback_done && !*dmq_init_callback_done) {
		*dmq_init_callback_done = 1;
		run_init_callbacks();
	}
	return 0;
error:
	return -1;
}
예제 #15
0
static int dbg_mod_level_param(modparam_t type, void *val)
{
	char *p;
	str s;
	int l;
	if(val==NULL)
		return -1;

	p = strchr((char*)val, '=');
	if(p==NULL) {
		LM_ERR("invalid parameter value: %s\n", (char*)val);
		return -1;
	}
	s.s = p + 1;
	s.len = strlen(s.s);

	if(str2sint(&s, &l)<0) {
		LM_ERR("invalid parameter - level value: %s\n", (char*)val);
		return -1;
	}
	s.s = (char*)val;
	s.len = p - s.s;

	if (!dbg_cfg) {
		return -1;
	}

	LM_DBG("cfg level_mode:%d hash_size:%d\n",
		cfg_get(dbg, dbg_cfg, mod_level_mode),
		cfg_get(dbg, dbg_cfg, mod_hash_size));

	if(dbg_init_mod_levels(cfg_get(dbg, dbg_cfg, mod_hash_size))<0)
	{
		LM_ERR("failed to init per module log level\n");
		return -1;
	}

	if(dbg_set_mod_debug_level(s.s, s.len, &l)<0)
	{
		LM_ERR("cannot store parameter: %s\n", (char*)val);
		return -1;
	}

	return 0;

}
예제 #16
0
int pv_parse_acc_leg_index(pv_spec_p sp, str* in)
{
	int idx;
	pv_spec_p e;

	if (in == NULL || in->s == NULL || in->len == 0) {
		LM_ERR("bad index!\n");
		return -1;
	}

	if (sp == NULL) {
		LM_ERR("bad pv spec!\n");
		return -1;
	}

	str_trim_spaces_lr(*in);

	if (in->s[0] == PV_MARKER) {
		e=pkg_malloc(sizeof(pv_spec_t));
		if (e==NULL) {
			LM_ERR("no more pkg mem!\n");
			return -1;
		}
		memset(e, 0, sizeof(pv_spec_t));

		if (pv_parse_spec(in, e) == NULL) {
			LM_ERR("failed to parse index variable!\n");
			pv_spec_free(e);
			return -1;
		}

		sp->pvp.pvi.type = PV_IDX_PVAR;
		sp->pvp.pvi.u.dval = (void *)e;
	} else {
		if (str2sint(in, &idx) < 0) {
			LM_ERR("bad index! not a number! <%.*s>!\n", in->len, in->s);
			return -1;
		}

		sp->pvp.pvi.type = PV_IDX_INT;
		sp->pvp.pvi.u.ival = idx;
	}

	return 0;
}
예제 #17
0
static struct mi_root *mi_debug(struct mi_root *cmd, void *param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node;
	char *p;
	int len;
	int new_debug = 0;
	str group_name = {"core", 4};
	str var_name = {"debug", 5};
	void *vval = 0;
	int set = 0;
	unsigned int val_type;

	node = cmd->node.kids;
	if (node!=NULL) {
		if (str2sint( &node->value, &new_debug) < 0)
			return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
		set = 1;
	} else {
		if(cfg_get_by_name(_kex_cfg_ctx, &group_name, NULL /* group id */, &var_name, &vval,
					&val_type)!=0)
			return init_mi_tree( 500, MI_SSTR(MI_INTERNAL_ERR));
		new_debug = (int)(long)vval;
	}
	rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
	if (rpl_tree==0)
		return 0;

	p = sint2str((long)new_debug, &len);
	node = add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE,
		MI_SSTR("DEBUG"),p, len);
	if (node==0) {
		free_mi_tree(rpl_tree);
		return 0;
	}

	if(set==1) {
		cfg_set_now(_kex_cfg_ctx, &group_name, NULL /* group id */, &var_name,
				(void *)(long)new_debug, CFG_VAR_INT);
	}

	return rpl_tree;
}
예제 #18
0
static int dp_get_ivalue(struct sip_msg* msg, dp_param_p dp, int *val)
{
	pv_value_t value;

	switch (dp->type) {
		case DP_VAL_STR :
			*val = dp->v.id;
			return 0;
		case DP_VAL_INT :
			*val = dp->v.pv_id.id;
			return 0;
		default :
			break;
	}

	LM_DBG("searching %d\n",dp->v.sp[0].type);

	if (pv_get_spec_value( msg, &dp->v.sp[0], &value)!=0) {
		LM_ERR("no PV found (error in script)\n");
		return -1;
	}

	if (value.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) {
		LM_ERR("NULL or empty val found (error in script)\n");
		return -1;
	}

	if (value.flags&PV_VAL_INT) {
		*val = value.ri;
	} else if (value.flags&PV_VAL_STR) {
		if (str2sint(&value.rs, val) != 0) {
			LM_ERR("Unbale to convert to INT [%.*s]\n", value.rs.len, value.rs.s);
			return -1;
		}
	} else {
		LM_ERR("non-INT/STR val found (error in script)\n");
		return -1;
	}

	return 0;
}
예제 #19
0
int redis_get_counter(cachedb_con *connection,str *attr,int *val)
{
	redis_con *con;
	cluster_node *node;
	redisReply *reply;
	int i,ret;
	str response;

	if (!attr || !val || !connection) {
		LM_ERR("null parameter\n");
		return -1;
	}

	redis_run_command(con,attr,"GET %b",attr->s,attr->len);

	if (reply->type == REDIS_REPLY_NIL || reply->str == NULL
			|| reply->len == 0) {
		LM_DBG("no such key - %.*s\n",attr->len,attr->s);
		return -2;
	}

	LM_DBG("GET %.*s  - %.*s\n",attr->len,attr->s,reply->len,reply->str);

	response.s=reply->str;
	response.len=reply->len;

	if (str2sint(&response,&ret) != 0) {
		LM_ERR("Not a counter \n");
		freeReplyObject(reply);
		return -3;
	}

	if (val)
		*val = ret;

	freeReplyObject(reply);
	return 0;
}
예제 #20
0
int msrp_parse_hdr_expires(msrp_frame_t *mf)
{
	msrp_hdr_t *hdr;
	str hbody;
	int expires;

	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_EXPIRES);
	if(hdr==NULL)
		return -1;
	if(hdr->parsed.flags&MSRP_DATA_SET)
		return 0;
	hbody = hdr->body;
	trim(&hbody);
	if(str2sint(&hbody, &expires)<0) {
		LM_ERR("invalid expires value\n");
		return -1;
	}
	hdr->parsed.flags |= MSRP_DATA_SET;
	hdr->parsed.free_fn = NULL;
	hdr->parsed.data = (void*)(long)expires;

	return 0;
}
예제 #21
0
	int
fixup_var_str_int(void **param, int param_no)
{
	int ret;
	pv_elem_t *model;
	str s;

	if (param_no == 1) {
		model = NULL;
		s.s = (char *)(*param);
		s.len = strlen(s.s);
		if (pv_parse_format(&s, &model) < 0) {
			LM_ERR("wrong format[%s]!\n", (char *)(*param));
			return E_UNSPEC;
		}
		if (model == NULL) {
			LM_ERR("empty parameter!\n");
			return E_UNSPEC;
		}
		*param = (void *)model;
	} else if (param_no == 2) {
		/* According to
		 * http://www.kamailio.org/docs/modules/1.5.x/nathelper.html#rtpproxy_stream2xxx
		 * this could be -1 */
		s.s = (char *)(*param);
		s.len = strlen(s.s);
		if (str2sint(&s, &ret)==0) {
			pkg_free(*param);
			*param = (void *)(long)ret;
		} else {
			LM_ERR("bad number <%s>\n", (char *)(*param));
			return E_CFG;
		}
	}
	return 0;
}
예제 #22
0
파일: ht_api.c 프로젝트: kingsumos/kamailio
int ht_count_cells_re(str *sre, ht_t *ht, int mode)
{
	ht_cell_t *it;
	ht_cell_t *it0;
	int i;
	regex_t re;
	regmatch_t pmatch;
	int cnt = 0;
	int op = 0;
	str sval;
	str tval;
	int ival = 0;

	if(sre==NULL || sre->len<=0 || ht==NULL)
		return 0;

	if(sre->len>=2)
	{
		switch(sre->s[0]) {
			case '~':
				switch(sre->s[1]) {
					case '~':
						op = 1; /* regexp */
					break;
					case '%':
						op = 2; /* rlike */
					break;
				}
			break;
			case '%':
				switch(sre->s[1]) {
					case '~':
						op = 3; /* llike */
					break;
				}
			break;
			case '=':
				switch(sre->s[1]) {
					case '=':
						op = 4; /* str eq */
					break;
				}
			break;
			case 'e':
				switch(sre->s[1]) {
					case 'q':
						op = 5; /* int eq */
					break;
				}
			break;
			case '*':
				switch(sre->s[1]) {
					case '*':
						op = 6; /* int eq */
					break;
				}
			break;
		}
	}

	if(op==6) {
		/* count all */
		for(i=0; i<ht->htsize; i++)
			cnt += ht->entries[i].esize;
		return cnt;
	}

	if(op > 0) {
		if(sre->len<=2)
			return 0;
		sval = *sre;
		sval.s += 2;
		sval.len -= 2;
		if(op==5) {
			if(mode==0)
			{
				/* match by name */
				return 0;
			}
			str2sint(&sval, &ival);
		}
	} else {
		sval = *sre;
		op = 1;
	}

	if(op==1)
	{
		if (regcomp(&re, sval.s, REG_EXTENDED|REG_ICASE|REG_NEWLINE))
		{
			LM_ERR("bad re %s\n", sre->s);
			return 0;
		}
	}

	for(i=0; i<ht->htsize; i++)
	{
		/* free entries */
		lock_get(&ht->entries[i].lock);
		it = ht->entries[i].first;
		while(it)
		{
			it0 = it->next;
			if(op==5)
			{
				if(!(it->flags&AVP_VAL_STR))
					if( it->value.n==ival)
						cnt++;
			} else {
				tval.len = -1;
				if(mode==0)
				{
					/* match by name */
					tval = it->name;
				} else {
					if(it->flags&AVP_VAL_STR)
						tval = it->value.s;
				}
				if(tval.len>-1) {
					switch(op) {
						case 1: /* regexp */
							if (regexec(&re, tval.s, 1, &pmatch, 0)==0)
								cnt++;
						break;
						case 2: /* rlike */
							if(sval.len<=tval.len 
									&& strncmp(sval.s,
										tval.s+tval.len-sval.len, sval.len)==0)
								cnt++;
						break;
						case 3: /* llike */
							if(sval.len<=tval.len 
									&& strncmp(sval.s, tval.s, sval.len)==0)
								cnt++;
						break;
						case 4: /* str eq */
							if(sval.len==tval.len 
									&& strncmp(sval.s, tval.s, sval.len)==0)
								cnt++;
						break;
					}
				}
			}
			it = it0;
		}
		lock_release(&ht->entries[i].lock);
	}
	if(op==1)
		regfree(&re);
	return cnt;
}
예제 #23
0
파일: cr_fifo.c 프로젝트: 2pac/kamailio
/**
 * parses the command line argument for options
 *
 * @param buf the command line argument
 * @param opts fifo options
 * @param opt_set set of the options
 *
 * @return 0 on success, -1 on failure
 *
 * @see dump_fifo()
 */
static int get_fifo_opts(str * buf, fifo_opt_t * opts, unsigned int opt_set[]) {
	int opt_argc = 0;
	str opt_argv[20];
	int i, op = -1;
	unsigned int used_opts = 0;
	int toklen;

	memset(opt_argv, 0, sizeof(opt_argv));
	memset(opts, 0, sizeof(fifo_opt_t));
	opts->prob = -1;

	while((toklen = str_toklen(buf, " \t\r\n")) >=0 && opt_argc < 20) {
		buf->s[toklen] = '\0'; /* insert zero termination, since strtod might be used later on it */
		opt_argv[opt_argc].len = toklen;
		opt_argv[opt_argc].s = buf->s;
		buf->s += toklen + 1;
		buf->len -= toklen + 1;
		LM_DBG("found arg[%i]: %.*s\n", opt_argc, opt_argv[opt_argc].len, opt_argv[opt_argc].s);
		opt_argc++;
	}
	for (i=0; i<opt_argc; i++) {
		LM_DBG("token %.*s", opt_argv[i].len, opt_argv[i].s);
		if (opt_argv[i].len >= 1) {
			switch(*opt_argv[i].s) {
					case '-': switch(opt_argv[i].s[1]) {
							case OPT_DOMAIN_CHR:
							op = OPT_DOMAIN;
							used_opts |= O_DOMAIN;
							break;
							case OPT_PREFIX_CHR:
							op = OPT_PREFIX;
							used_opts |= O_PREFIX;
							break;
							case OPT_HOST_CHR:
							op = OPT_HOST;
							used_opts |= O_HOST;
							break;
							case OPT_NEW_TARGET_CHR:
							op = OPT_NEW_TARGET;
							used_opts |= O_NEW_TARGET;
							break;
							case OPT_PROB_CHR:
							op = OPT_PROB;
							used_opts |= O_PROB;
							break;
							case OPT_R_PREFIX_CHR:
							op = OPT_R_PREFIX;
							used_opts |= O_R_PREFIX;
							break;
							case OPT_R_SUFFIX_CHR:
							op = OPT_R_SUFFIX;
							used_opts |= O_R_SUFFIX;
							break;
							case OPT_HASH_INDEX_CHR:
							op = OPT_HASH_INDEX;
							used_opts |= O_H_INDEX;
							break;
							case OPT_HELP_CHR:
							FIFO_ERR(E_HELP);
							return -1;
							default: {
								FIFO_ERR(E_WRONGOPT);
								LM_DBG("Unknown option: %.*s\n", opt_argv[i].len, opt_argv[i].s);
								return -1;
							}
					}
					break;
					default: switch(op) {
							case OPT_DOMAIN:
							opts->domain = opt_argv[i];
							op = -1;
							break;
							case OPT_PREFIX:
							if (str_strcasecmp(&opt_argv[i], &CR_EMPTY_PREFIX) == 0) {
								opts->prefix.s = NULL;
								opts->prefix.len = 0;
							} else {
								opts->prefix = opt_argv[i];
							}
							op = -1;
							break;
							case OPT_HOST:
							opts->host = opt_argv[i];
							op = -1;
							break;
							case OPT_NEW_TARGET:
							opts->new_host = opt_argv[i];
							op = -1;
							break;
							case OPT_PROB:
							opts->prob = strtod(opt_argv[i].s, NULL); /* we can use str.s since we zero terminated it earlier */
							op = -1;
							break;
							case OPT_R_PREFIX:
							opts->rewrite_prefix = opt_argv[i];
							op = -1;
							break;
							case OPT_STRIP:
							str2sint(&opt_argv[i], &opts->strip);
							op = -1;
							break;
							case OPT_R_SUFFIX:
							opts->rewrite_suffix = opt_argv[i];
							op = -1;
							break;
							case OPT_HASH_INDEX:
							str2sint(&opt_argv[i], &opts->hash_index);
							op = -1;
							break;
							default: {
								LM_DBG("No option given\n");
								FIFO_ERR(E_NOOPT);
								return -1;
							}
					}
					break;
			}
		}
	}
	if((used_opts & opt_set[OPT_INVALID]) != 0) {
		LM_DBG("invalid option\n");
		FIFO_ERR(E_INVALIDOPT);
		return -1;
	}
	if((used_opts & opt_set[OPT_MANDATORY]) != opt_set[OPT_MANDATORY]) {
		LM_DBG("option missing\n");
		FIFO_ERR(E_MISSOPT);
		return -1;
	}
	return 0;
}
예제 #24
0
/** Get the function parameter value as string or/and integer (if possible).
 *  @return  0 - Success
 *          -1 - Cannot get value
 */
int get_is_fparam(int* i_dst, str* s_dst, struct sip_msg* msg, fparam_t* param, unsigned int *flags)
{
	int_str val;
	int ret;
	avp_t* avp;
	str tmp;
	pv_value_t pv_val;

	*flags = 0;
	switch(param->type) {
		case FPARAM_INT:
			*i_dst = param->v.i;
			*flags |= PARAM_INT;
			return 0;
		case FPARAM_REGEX:
		case FPARAM_UNSPEC:
		case FPARAM_STRING:
			s_dst->s = param->v.asciiz;
			s_dst->len = strlen(param->v.asciiz);
			*flags |= PARAM_STR;
			break;
		case FPARAM_STR:
			*s_dst = param->v.str;
			*flags |= PARAM_STR;
			break;
		case FPARAM_AVP:
			avp = search_first_avp(param->v.avp.flags, param->v.avp.name,
									&val, 0);
			if (unlikely(!avp)) {
				LM_DBG("Could not find AVP from function parameter '%s'\n",
						param->orig);
				return -1;
			}
			if (avp->flags & AVP_VAL_STR) {
				*s_dst = val.s;
				*flags |= PARAM_STR;
				if (str2int(&val.s, (unsigned int*)i_dst) < 0) {
					LM_ERR("Could not convert AVP string value to int\n");
					return -1;
				}
			} else {
				*i_dst = val.n;
				*flags |= PARAM_INT;
			}
			break;
		case FPARAM_SELECT:
			ret = run_select(&tmp, param->v.select, msg);
			if (unlikely(ret < 0 || ret > 0)) return -1;
			if (unlikely(str2int(&tmp, (unsigned int*)i_dst) < 0)) {
				LM_ERR("Could not convert select result to int\n");
				return -1;
			}
			*flags |= PARAM_INT;
			break;
		case FPARAM_PVS:
			if (likely(pv_get_spec_value(msg, param->v.pvs, &pv_val)==0)) {
				if ((pv_val.flags&(PV_VAL_NULL|PV_VAL_INT))==PV_VAL_INT){
					*i_dst=pv_val.ri;
					*flags |= PARAM_INT;
				}
				if ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR){
					*s_dst=pv_val.rs;
					*flags |= PARAM_STR;
				}
			}else{
				LM_ERR("Could not get PV\n");
				return -1;
			}
			break;
		case FPARAM_PVE:
			s_dst->s=pv_get_buffer();
			s_dst->len=pv_get_buffer_size();
			if (unlikely(pv_printf(msg, param->v.pve, s_dst->s, &s_dst->len)!=0)){
				LM_ERR("Could not convert the PV-formated string to str\n");
				s_dst->len=0;
				return -1;
			}
			*flags |= PARAM_STR;
			break;
	}

	/* Let's convert to int, if possible */
	if (!(*flags & PARAM_INT) && (*flags & PARAM_STR) && str2sint(s_dst, i_dst) == 0)
		*flags |= PARAM_INT;

	if (!*flags) return -1;

	return 0;
}
예제 #25
0
파일: shvar.c 프로젝트: GeorgeShaw/opensips
struct mi_root* mi_shvar_set(struct mi_root* cmd_tree, void* param)
{
	str sp;
	str name;
	int ival;
	int_str isv;
	int flags;
	struct mi_node* node;
	sh_var_t *shv = NULL;

	node = cmd_tree->node.kids;
	if(node == NULL)
		return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM_S));
	name = node->value;
	if(name.len<=0 || name.s==NULL)
	{
		LM_ERR("bad shv name\n");
		return init_mi_tree( 500, MI_SSTR("bad shv name"));
	}
	shv = get_shvar_by_name(&name);
	if(shv==NULL)
		return init_mi_tree(404, MI_SSTR("Not found"));

	node = node->next;
	if(node == NULL)
		return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM_S));
	sp = node->value;
	if(sp.s == NULL)
		return init_mi_tree(500, MI_SSTR("type not found"));
	flags = 0;
	if(sp.s[0]=='s' || sp.s[0]=='S')
		flags = VAR_VAL_STR;

	node= node->next;
	if(node == NULL)
		return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM_S));

	sp = node->value;
	if(sp.s == NULL)
	{
		return init_mi_tree(500, MI_SSTR("value not found"));
	}
	if(flags == 0)
	{
		if(str2sint(&sp, &ival))
		{
			LM_ERR("bad integer value\n");
			return init_mi_tree( 500, MI_SSTR("bad integer value"));
		}
		isv.n = ival;
	} else {
		isv.s = sp;
	}

	lock_shvar(shv);
	if(set_shvar_value(shv, &isv, flags)==NULL)
	{
		unlock_shvar(shv);
		LM_ERR("cannot set shv value\n");
		return init_mi_tree( 500, MI_SSTR("cannot set shv value"));
	}

	unlock_shvar(shv);
	LM_DBG("$shv(%.*s) updated\n", name.len, name.s);
	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
}
예제 #26
0
struct fis_param* parse_intstr_value(char *p, int len)
{
	struct fis_param *vp;
	unsigned int uint;
	str val_str;
	int flags;

	if (p==0 || len==0)
			goto error;

	if (len>1 && *(p+1)==':')
	{
		if (*p=='i' || *p=='I')
			flags = AVPOPS_VAL_INT;
		else if (*p=='s' || *p=='S')
			flags = AVPOPS_VAL_STR;
		else
		{
			LM_ERR("unknown value type <%c>\n",*p);
			goto error;
		}
		p += 2;
		len -= 2;
		if (*p==0 || len<=0 )
		{
			LM_ERR("parse error arround <%.*s>\n",len,p);
				goto error;
		}
	} else {
		flags = AVPOPS_VAL_STR;
	}
	/* get the value */
	vp = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
	if (vp==0)
	{
		LM_ERR("no more pkg mem\n");
		goto error;;
	}
	memset( vp, 0, sizeof(struct fis_param));
	vp->opd = flags;
	val_str.s = p;
	val_str.len = len;
	if (flags&AVPOPS_VAL_INT) {
		/* convert the value to integer */
		if(val_str.len>2 && p[0]=='0' && (p[1]=='x' || p[1]=='X'))
		{
			if(hexstr2int(val_str.s+2, val_str.len-2, &uint))
			{
				LM_ERR("value is not hex int as type says <%.*s>\n", 
						val_str.len, val_str.s);
				goto error;
			}
		} else {
			if(str2sint( &val_str, (int*)&uint)==-1)
			{
				LM_ERR("value is not int"
					" as type says <%.*s>\n", val_str.len, val_str.s);
				goto error;
			}
		}
		vp->u.n = (int)uint;
		vp->type = AVPOPS_VAL_INT;
	} else {
		/* duplicate the value as string */
		vp->u.s.s = (char*)pkg_malloc((val_str.len+1)*sizeof(char));
		if (vp->u.s.s==0)
		{
			LM_ERR("no more pkg mem\n");
			goto error;
		}
		vp->u.s.len = val_str.len;
		memcpy(vp->u.s.s, val_str.s, val_str.len);
		vp->u.s.s[vp->u.s.len] = 0;
		vp->type = AVPOPS_VAL_STR;
	}

	return vp;
error:
	return 0;
}
예제 #27
0
파일: ht_api.c 프로젝트: kingsumos/kamailio
int ht_table_spec(char *spec)
{
	keyvalue_t kval;
	str name;
	str dbtable = {0, 0};
	unsigned int autoexpire = 0;
	unsigned int size = 4;
	unsigned int dbmode = 0;
	unsigned int updateexpire = 1;
	unsigned int dmqreplicate = 0;
	str in;
	str tok;
	param_t *pit=NULL;
	int_str ival;
	int itype;

	if(!shm_initialized())
	{
		LM_ERR("shared memory was not initialized\n");
		return -1;
	}
	/* parse: name=>dbtable=abc;autoexpire=123;size=123 */
	in.s = spec;
	in.len = strlen(in.s);
	if(keyvalue_parse_str(&in, KEYVALUE_TYPE_PARAMS, &kval)<0)
	{
		LM_ERR("failed parsing: %.*s\n", in.len, in.s);
		return -1;
	}
	name = kval.key;
	itype = PV_VAL_NONE;
	memset(&ival, 0, sizeof(int_str));

	for (pit = kval.u.params; pit; pit=pit->next)
	{
		tok = pit->body;
		if(pit->name.len==7 && strncmp(pit->name.s, "dbtable", 7)==0) {
			dbtable = tok;
			LM_DBG("htable [%.*s] - dbtable [%.*s]\n", name.len, name.s,
					dbtable.len, dbtable.s);
		} else if(pit->name.len==10 && strncmp(pit->name.s, "autoexpire", 10)==0) {
			if(str2int(&tok, &autoexpire)!=0)
				goto error;
			LM_DBG("htable [%.*s] - expire [%u]\n", name.len, name.s,
					autoexpire);
		} else if(pit->name.len==4 && strncmp(pit->name.s, "size", 4)==0) {
			if(str2int(&tok, &size)!=0)
				goto error;
			LM_DBG("htable [%.*s] - size [%u]\n", name.len, name.s,
					size);
		} else if(pit->name.len==6 && strncmp(pit->name.s, "dbmode", 6)==0) {
			if(str2int(&tok, &dbmode)!=0)
				goto error;
			LM_DBG("htable [%.*s] - dbmode [%u]\n", name.len, name.s,
					dbmode);
		} else if(pit->name.len==7 && strncmp(pit->name.s, "initval", 7)==0) {
			if(str2sint(&tok, &ival.n)!=0)
				goto error;
			itype = PV_VAL_INT;
			LM_DBG("htable [%.*s] - initval [%d]\n", name.len, name.s,
					ival.n);
		} else if(pit->name.len == 12 && strncmp(pit->name.s, "updateexpire", 12) == 0) {
			if(str2int(&tok, &updateexpire) != 0)
				goto error;

			LM_DBG("htable [%.*s] - updateexpire [%u]\n", name.len, name.s, updateexpire); 
		} else if(pit->name.len == 12 && strncmp(pit->name.s, "dmqreplicate", 12) == 0) {
			if(str2int(&tok, &dmqreplicate) != 0)
				goto error;

			LM_DBG("htable [%.*s] - dmqreplicate [%u]\n", name.len, name.s, dmqreplicate); 
		} else { goto error; }
	}

	return ht_add_table(&name, autoexpire, &dbtable, size, dbmode,
			itype, &ival, updateexpire, dmqreplicate);

error:
	LM_ERR("invalid htable parameter [%.*s]\n", in.len, in.s);
	return -1;
}
예제 #28
0
int_list_t *set_list_from_pvs(struct sip_msg *msg, pv_spec_t *pvs, int_list_t *end)
{
	int_list_t *result = end, *new_el;
	pv_value_t value;

	if (pv_get_spec_value(msg, pvs, &value) != 0 || value.flags&PV_VAL_NULL
		|| (!(value.flags&PV_VAL_INT) && !(value.flags&PV_VAL_STR))) {

		LM_ERR("no valid PV value found (error in scripts)\n");
		return NULL;
	}

	if (value.flags & PV_VAL_INT) {
		/* Just one element */

		new_el = pkg_malloc(sizeof(int_list_t));
		if (new_el == NULL) {
			LM_ERR("no more shared memory\n");
			return NULL;
		}

		new_el->v.ival = value.ri;
		new_el->type = GPARAM_TYPE_INT;
		new_el->next = end;

		return new_el;
	}

	str sval = value.rs;

	if (sval.s == NULL)
		goto wrong_value;

	char * delim;
	do{
		delim = q_memchr(sval.s, LIST_DELIM, sval.len);
		str s_num = {sval.s, delim ? delim - sval.s : sval.len};
		sval.len -= s_num.len + 1;
		sval.s = delim + 1;
		trim(&s_num);

		int u_num;
		if (s_num.len == 0 || str2sint(&s_num, &u_num) != 0)
			goto wrong_value;

		new_el = pkg_malloc(sizeof(int_list_t));
		if (new_el == NULL) {
			goto no_memory;
		}

		new_el->v.ival = u_num;
		new_el->type = GPARAM_TYPE_INT;
		new_el->next = result;
		result = new_el;

	} while (delim);

	if (sval.len > 0)
		goto wrong_value;

return result;

no_memory:
	while(result != end) {
		if (result->type == GPARAM_TYPE_PVS)
			pkg_free(result->v.pvs);
		int_list_t *aux = result;
		result = result->next;
		pkg_free(aux);
	}
	LM_ERR("no more private memory\n");
	return NULL;

wrong_value:
	while(result != end) {
		if (result->type == GPARAM_TYPE_PVS)
			pkg_free(result->v.pvs);
		int_list_t *aux = result;
		result = result->next;
		pkg_free(aux);
	}
	LM_ERR("wrong var value <%.*s>\n", value.rs.len, value.rs.s);
	return NULL;

}
예제 #29
0
int set_list_from_string(str input, int_list_t **result)
{
	str original_input = input;
	int_list_t *new_el=NULL;
	int flags=0;
	int uset;

	*result = NULL;
	if (input.s == NULL || input.len == 0)
		return 0;

	if (str2sint(&input, &uset) == 0) {
		/* Just one set in the list */
		*result = shm_malloc(sizeof(int_list_t));
		if (*result == NULL)
			goto no_memory;
		(*result)->v.ival = uset;
		(*result)->type = GPARAM_TYPE_INT;
		(*result)->next = NULL;
		return 0;
	}

	char * delim, *pvdelim, *flagsdelim=NULL;
	str flg_tok;

	unsigned int u_num=0;
	int def_val = -1;
	do{
		delim = q_memchr(input.s, LIST_DELIM, input.len);
		str s_tok = {input.s, delim ? delim - input.s : input.len};
		int full_tok_len = s_tok.len;

		trim(&s_tok);

		/* search if only max results */
		if (s_tok.s[0] >= '0' && s_tok.s[0] <= '9') {
			flags = 0;
			goto only_max_res;
		}

		/*search for flags flags/maxlist delimiter*/
		flagsdelim=q_memchr(s_tok.s, FLAGS_DELIM, s_tok.len);
		if (flagsdelim == NULL) {
			/* search for only flags */
			if ((s_tok.s[0] >= 'a' && s_tok.s[0] <= 'z') ||
					(s_tok.s[0] >= 'A' && s_tok.s[0] <= 'Z')) {
				flg_tok.s = s_tok.s;
				flg_tok.len=0;
				if ((flg_tok.s[flg_tok.len] >= 'a' && flg_tok.s[flg_tok.len] <= 'z') ||
							(flg_tok.s[flg_tok.len] >= 'A' && flg_tok.s[flg_tok.len] <= 'Z'))
					flg_tok.len=s_tok.len;
				goto only_flags00;
			}
		}
		/* if found parse the flags */
		if (flagsdelim != NULL) {
			flg_tok.s = s_tok.s;
			flg_tok.len = flagsdelim - s_tok.s;

only_flags00:
			/* update list token */
			s_tok.s += flg_tok.len +1;
			s_tok.len -= (flg_tok.len +1);

			new_el = shm_malloc(sizeof(int_list_t));
			if (new_el == NULL)
				goto no_memory;

			memset(new_el, 0, sizeof(int_list_t));

			trim(&flg_tok);

			/* must fixup flags string value */
			if ((flags = fixup_flags(&flg_tok)) < 0) {
				LM_ERR("cannot fixup flags\n");
				return -1;
			}

			trim(&s_tok);

			/* default value for max results */
			def_val = 1000;
		}

only_max_res:
		if (s_tok.len == 0) {
			if (flags > 0) {
				goto only_flags01;
			} else
				goto wrong_value;
		}
		else if (s_tok.s[0] == PV_MARKER) {
			new_el = shm_malloc(sizeof(int_list_t));
			if (new_el == NULL)
				goto no_memory;

			new_el->type = GPARAM_TYPE_PVS;
			new_el->v.pvs = shm_malloc(sizeof(pv_spec_t));
			if (new_el->v.pvs == NULL) {
				shm_free(new_el);
				goto no_memory;
			}

			if ((pvdelim = pv_parse_spec(&s_tok, new_el->v.pvs)) == NULL) {
				shm_free(new_el->v.pvs);
				shm_free(new_el);
				goto wrong_value;
			}

			new_el->next = *result;
			*result = new_el;

			if (delim)
				if (delim != pvdelim)
					goto wrong_value;
				else {
					input.len -= delim - input.s + 1;
					input.s = delim + 1;
				}
			else {
				input.len -= pvdelim - input.s + 1;
				input.s = pvdelim;
			}
		}
		else if (str2int(&s_tok, &u_num) == 0) {
			new_el = shm_malloc(sizeof(int_list_t));
			if (new_el == NULL)
				goto no_memory;

only_flags01:
			new_el->v.ival = def_val > 0 ? def_val : u_num;
			new_el->type = GPARAM_TYPE_INT;
			if (flags>0)
				new_el->flags = flags;
			new_el->next = *result;
			*result = new_el;

			input.len -= full_tok_len + 1;
			input.s = delim + 1;
		}
		else goto wrong_value;
	} while (delim);

	if (input.len > 0)
		goto wrong_value;

	return 0;

no_memory:
	while(*result) {
		if ((*result)->type == GPARAM_TYPE_PVS)
			shm_free((*result)->v.pvs);
		int_list_t *aux = *result;
		*result = (*result)->next;
		shm_free(aux);
	}
	LM_ERR("no more shared memory\n");
	return -1;

wrong_value:
	while(*result) {
		if ((*result)->type == GPARAM_TYPE_PVS)
			shm_free((*result)->v.pvs);
		int_list_t *aux = *result;
		*result = (*result)->next;
		shm_free(aux);
	}
	LM_ERR("wrong format for set/set list. Token <%.*s>\n", original_input.len, original_input.s);
	return -1;
}
예제 #30
0
static int ds_parse_reply_codes() {
	param_t* params_list = NULL;
	param_t *pit=NULL;
	int list_size = 0;
	int i = 0;
	int pos = 0;
	int code = 0;
	str input = {0, 0};
	int* ds_ping_reply_codes_new = NULL;
	int* ds_ping_reply_codes_old = NULL;

	/* Validate String: */
	if (cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).s == 0 
			|| cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).len<=0)
		return 0;

	/* parse_params will modify the string pointer of .s, so we need to make a copy. */
	input.s = cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).s;
	input.len = cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).len;

	/* Parse the parameters: */
	if (parse_params(&input, CLASS_ANY, 0, &params_list)<0)
		return -1;

	/* Get the number of entries in the list */
	for (pit = params_list; pit; pit=pit->next)
	{
		if (pit->name.len==4
				&& strncasecmp(pit->name.s, "code", 4)==0) {
			str2sint(&pit->body, &code);
			if ((code >= 100) && (code < 700))
				list_size += 1;
		} else if (pit->name.len==5
				&& strncasecmp(pit->name.s, "class", 5)==0) {
			str2sint(&pit->body, &code);
			if ((code >= 1) && (code < 7))
				list_size += 100;
		}
	}
	LM_DBG("Should be %d Destinations.\n", list_size);

	if (list_size > 0) {
		/* Allocate Memory for the new list: */
		ds_ping_reply_codes_new = (int*)shm_malloc(list_size * sizeof(int));
		if(ds_ping_reply_codes_new== NULL)
		{
			free_params(params_list);
			LM_ERR("no more memory\n");
			return -1;
		}

		/* Now create the list of valid reply-codes: */
		for (pit = params_list; pit; pit=pit->next)
		{
			if (pit->name.len==4
					&& strncasecmp(pit->name.s, "code", 4)==0) {
				str2sint(&pit->body, &code);
				if ((code >= 100) && (code < 700))
					ds_ping_reply_codes_new[pos++] = code;
			} else if (pit->name.len==5
					&& strncasecmp(pit->name.s, "class", 5)==0) {
				str2sint(&pit->body, &code);
				if ((code >= 1) && (code < 7)) {
					/* Add every code from this class, e.g. 100 to 199 */
					for (i = (code*100); i <= ((code*100)+99); i++) 
						ds_ping_reply_codes_new[pos++] = i;
				}
			}
		}
	} else {
		ds_ping_reply_codes_new = 0;
	}
	free_params(params_list);

	/* More reply-codes? Change Pointer and then set number of codes. */
	if (list_size > *ds_ping_reply_codes_cnt) {
		// Copy Pointer
		ds_ping_reply_codes_old = *ds_ping_reply_codes;
		*ds_ping_reply_codes = ds_ping_reply_codes_new;
		// Done: Set new Number of entries:
		*ds_ping_reply_codes_cnt = list_size;
		// Free the old memory area:
		if(ds_ping_reply_codes_old)
			shm_free(ds_ping_reply_codes_old);	
		/* Less or equal? Set the number of codes first. */
	} else {
		// Done:
		*ds_ping_reply_codes_cnt = list_size;
		// Copy Pointer
		ds_ping_reply_codes_old = *ds_ping_reply_codes;
		*ds_ping_reply_codes = ds_ping_reply_codes_new;
		// Free the old memory area:
		if(ds_ping_reply_codes_old)
			shm_free(ds_ping_reply_codes_old);	
	}
	/* Print the list as INFO: */
	for (i =0; i< *ds_ping_reply_codes_cnt; i++)
	{
		LM_DBG("Dispatcher: Now accepting Reply-Code %d (%d/%d) as valid\n",
				(*ds_ping_reply_codes)[i], (i+1), *ds_ping_reply_codes_cnt);
	}
	return 0;
}