Exemple #1
0
/**
 * the initiating function
 */
int add_from_db(void)
{
	imc_member_p member = NULL;
	int i, j, flag;
	db_key_t mq_result_cols[4], mquery_cols[2];
	db_key_t rq_result_cols[4];
	db_val_t mquery_vals[2];
	db1_res_t *r_res= NULL;
	db1_res_t *m_res= NULL;
	db_row_t *m_row = NULL, *r_row = NULL;
	db_val_t *m_row_vals, *r_row_vals = NULL;
	str name, domain;
	imc_room_p room = NULL;
	int er_ret = -1;

	rq_result_cols[0] = &imc_col_name;
	rq_result_cols[1] = &imc_col_domain;
	rq_result_cols[2] = &imc_col_flag;

	mq_result_cols[0] = &imc_col_username;
	mq_result_cols[1] = &imc_col_domain;
	mq_result_cols[2] = &imc_col_flag;

	mquery_cols[0] = &imc_col_room;
	mquery_vals[0].type = DB1_STR;
	mquery_vals[0].nul = 0;

	if(imc_dbf.use_table(imc_db, &rooms_table)< 0)
	{
		LM_ERR("use_table failed\n");
		return -1;
	}

	if(imc_dbf.query(imc_db,0, 0, 0, rq_result_cols,0, 3, 0,&r_res)< 0)
	{
		LM_ERR("failed to querry table\n");
		return -1;
	}
	if(r_res==NULL || r_res->n<=0)
	{
		LM_INFO("the query returned no result\n");
		if(r_res) imc_dbf.free_result(imc_db, r_res);
		r_res = NULL;
		return 0;
	}

	LM_DBG("found %d rooms\n", r_res->n);

	for(i =0 ; i< r_res->n ; i++)
	{
		/*add rooms*/
		r_row = &r_res->rows[i];
		r_row_vals = ROW_VALUES(r_row);

		name.s = 	r_row_vals[0].val.str_val.s;
		name.len = strlen(name.s);

		domain.s = 	r_row_vals[1].val.str_val.s;
		domain.len = strlen(domain.s);

		flag = 	r_row_vals[2].val.int_val;

		room = imc_add_room(&name, &domain, flag);
		if(room == NULL)
		{
			LM_ERR("failed to add room\n ");
			goto error;
		}

		/* add members */
		if(imc_dbf.use_table(imc_db, &members_table)< 0)
		{
			LM_ERR("use_table failed\n ");
			goto error;
		}

		mquery_vals[0].val.str_val= room->uri;

		if(imc_dbf.query(imc_db, mquery_cols, 0, mquery_vals, mq_result_cols,
					1, 3, 0, &m_res)< 0)
		{
			LM_ERR("failed to querry table\n");
			goto error;
		}

		if(m_res==NULL || m_res->n<=0)
		{
			LM_INFO("the query returned no result\n");
			er_ret = 0;
			goto error; /* each room must have at least one member*/
		}
		for(j =0; j< m_res->n; j++)
		{
			m_row = &m_res->rows[j];
			m_row_vals = ROW_VALUES(m_row);

			name.s = m_row_vals[0].val.str_val.s;
			name.len = strlen(name.s);

			domain.s = m_row_vals[1].val.str_val.s;
			domain.len = strlen(domain.s);

			flag = m_row_vals[2].val.int_val;

			LM_DBG("adding memeber: [name]=%.*s [domain]=%.*s"
					" in [room]= %.*s\n",name.len, name.s, domain.len,domain.s,
					room->uri.len, room->uri.s);

			member = imc_add_member(room, &name, &domain, flag);
			if(member == NULL)
			{
				LM_ERR("failed to adding member\n ");
				goto error;
			}
			imc_release_room(room);
		}

		if(m_res)
		{
			imc_dbf.free_result(imc_db, m_res);
			m_res = NULL;
		}
	}

	if(imc_dbf.use_table(imc_db, &members_table)< 0)
	{
		LM_ERR("use table failed\n ");
		goto error;
	}

	if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("failed to delete information from db\n");
		goto error;
	}

	if(imc_dbf.use_table(imc_db, &rooms_table)< 0)
	{
		LM_ERR("use table failed\n ");
		goto error;
	}

	if(imc_dbf.delete(imc_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("failed to delete information from db\n");
		goto error;
	}

	if(r_res)
	{
		imc_dbf.free_result(imc_db, r_res);
		r_res = NULL;
	}

	return 0;

error:
	if(r_res)
	{
		imc_dbf.free_result(imc_db, r_res);
		r_res = NULL;
	}
	if(m_res)
	{
		imc_dbf.free_result(imc_db, m_res);
		m_res = NULL;
	}
	if(room)
		imc_release_room(room);
	return er_ret;

}
int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_room = 0;
	int flag_member = 0;
	str room_name;
	str body;

	room_name = cmd->param[0].s?cmd->param[0]:dst->user;
	room=imc_get_room(&room_name, &dst->host);
	if(room== NULL || (room->flags&IMC_ROOM_DELETED))
	{			
		LM_DBG("could not find room [%.*s]- adding\n", 
				room_name.len, room_name.s);
		room= imc_add_room(&room_name, &dst->host, flag_room);
		if(room == NULL)
		{
			LM_ERR("failed to add new room [%.*s]\n",
				room_name.len, room_name.s);
			goto error;
		}
		LM_DBG("created a new room [%.*s]\n", room->name.len, room->name.s);

		flag_member |= IMC_MEMBER_OWNER;
		member= imc_add_member(room, &src->user, &src->host, flag_member);
		if(member == NULL)
		{
			LM_ERR("failed to add new member [%.*s]\n",
				src->user.len, src->user.s);
			goto error;
		}
		/* send info message */
		body.s = "*** room was created";
		body.len = sizeof("*** room was created")-1;
		imc_send_message(&room->uri, &member->uri, &all_hdrs, &body);
		goto done;
	}

	/* room exists */
	LM_DBG("found room [%.*s]\n", room_name.len, room_name.s);

	member= imc_get_member(room, &src->user, &src->host);
	if(!(room->flags & IMC_ROOM_PRIV))
	{
		LM_DBG("room [%.*s] is public\n", room_name.len, room_name.s);
		if(member== NULL)
		{					
			LM_DBG("adding new member [%.*s]\n", src->user.len, src->user.s);
			member= imc_add_member(room, &src->user,
									&src->host, flag_member);	
			if(member == NULL)
			{
				LM_ERR("adding new user [%.*s]\n", src->user.len, src->user.s);
				goto error;
			}	
			goto build_inform;
		} else {	
			LM_DBG("member [%.*s] is in room already\n",
				member->uri.len,member->uri.s );
		}
	} else {
		if(member==NULL)
		{
			LM_ERR("attept to join private room [%.*s] from user [%.*s]\n",
					room_name.len, room_name.s,	src->user.len, src->user.s);
			goto build_inform;

		}

		if(member->flags & IMC_MEMBER_INVITED) 
			member->flags &= ~IMC_MEMBER_INVITED;
	}

build_inform:
	/* send info message */
	body.s = imc_body_buf;
	if(member!=NULL)
	{
		body.len = snprintf(body.s, IMC_BUF_SIZE,
				"*** <%.*s@%.*s> has joined the room",
				src->user.len, src->user.s, src->host.len, src->host.s);

	} else {
		body.len = snprintf(body.s, IMC_BUF_SIZE,
				"*** <%.*s@%.*s> attempted to join the room",
				src->user.len, src->user.s, src->host.len, src->host.s);
	}
	if(body.len>0)
		imc_room_broadcast(room, &all_hdrs, &body);
	if(body.len>=IMC_BUF_SIZE)
		LM_ERR("member name %.*s@%.*s truncated\n",
				src->user.len, src->user.s, src->host.len, src->host.s);

done:
	if(room!=NULL)
		imc_release_room(room);
	return 0;

error:
	if(room!=NULL)
		imc_release_room(room);
	return -1;
}
int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_member = 0;
	int size = 0;
	int i = 0;
	int add_domain = 0;
	int add_sip = 0;
	str uri = {0, 0};
	str body;
	str room_name;
	struct sip_uri inv_uri;
	del_member_t *cback_param = NULL;
	int result;
	uac_req_t uac_r;

	size = cmd->param[0].len+2 ;	
	add_domain = 1;
	add_sip = 0;
	while (i<size )
	{
		if(cmd->param[0].s[i]== '@')
		{	
			add_domain = 0;
			break;
		}
		i++;
	}

	if(add_domain)
		size += dst->host.len;
	if(cmd->param[0].len<4 || strncmp(cmd->param[0].s, "sip:", 4)!=0)
	{
		size += 4;
		add_sip = 1;
	}
		
	uri.s = (char*)pkg_malloc(size *sizeof(char));
	if(uri.s == NULL)
	{
		LM_ERR("no more pkg memory\n");
		goto error;
	}
	size= 0;
	if(add_sip)
	{	
		strcpy(uri.s, "sip:");
		size=4;
	}
		
	memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
	size += cmd->param[0].len;

	if(add_domain)
	{	
		uri.s[size] = '@';
		size++;
		memcpy(uri.s+ size, dst->host.s, dst->host.len);
		size+= dst->host.len;
	}
	uri.len = size;

	if(parse_uri(uri.s, uri.len, &inv_uri)!=0)
	{
		LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s);
		goto error;
	}
					
	room_name = (cmd->param[1].s)?cmd->param[1]:dst->user;
	room = imc_get_room(&room_name, &dst->host);				
	if(room== NULL || (room->flags&IMC_ROOM_DELETED))
	{
		LM_ERR("the room does not exist [%.*s]!\n",
				room_name.len, room_name.s);
		goto error;
	}			
	member= imc_get_member(room, &src->user, &src->host);

	if(member==NULL)
	{
		LM_ERR("user [%.*s] is not member of[%.*s]!\n",
			src->user.len, src->user.s, room_name.len, room_name.s);
		goto error;
	}
	if(!(member->flags & IMC_MEMBER_OWNER) &&
			!(member->flags & IMC_MEMBER_ADMIN))
	{
		LM_ERR("user [%.*s] has no right to invite"
				" other users!\n", src->user.len, src->user.s);
		goto error;
	}
    
	member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
	if(member!=NULL)
	{
		LM_ERR("user [%.*s] is already member"
				" of the room!\n", inv_uri.user.len, inv_uri.user.s);
		goto error;
	}
		
	flag_member |= IMC_MEMBER_INVITED;		
	member=imc_add_member(room, &inv_uri.user, &inv_uri.host, flag_member);
	if(member == NULL)
	{
		LM_ERR("adding member [%.*s]\n",
				inv_uri.user.len, inv_uri.user.s);
		goto error;	
	}
	
	body.len = 13 + member->uri.len - 4/* sip: */ + 28;	
	if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE
			|| room->uri.len>=IMC_BUF_SIZE)
	{
		LM_ERR("buffer size overflow\n");
		goto error;	
	}

	body.s = imc_body_buf;
	memcpy(body.s, "INVITE from: ", 13);
	memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4);
	memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28);	
	body.s[body.len] = '\0';			

	LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n", 
			member->uri.len,member->uri.s,room->uri.len, room->uri.s,
			body.len, body.s);
				
	cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t));
	if(cback_param==NULL)
	{
		LM_ERR("no more shm\n");
		goto error;	
	}
	memset(cback_param, 0, sizeof(del_member_t));
	cback_param->room_name = room->name;
	cback_param->room_domain = room->domain;
	cback_param->member_name = member->user;
	cback_param->member_domain = member->domain;
	cback_param->inv_uri = member->uri;
	/*?!?! possible race with 'remove user' */

	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, TMCB_LOCAL_COMPLETED,
				imc_inv_callback, (void*)(cback_param));
	result= tmb.t_request(&uac_r,
				&member->uri,							/* Request-URI */
				&member->uri,							/* To */
				&room->uri,								/* From */
				(outbound_proxy.s)?&outbound_proxy:NULL/* outbound proxy*/
			);				
	if(result< 0)
	{
		LM_ERR("in tm send request\n");
		shm_free(cback_param);
		goto error;
	}
	if(uri.s!=NULL)
		pkg_free(uri.s);

	imc_release_room(room);

	return 0;

error:
	if(uri.s!=0)
		pkg_free(uri.s);
	if(room!=NULL)
		imc_release_room(room);
	return -1;
}
int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_room = 0;
	int flag_member = 0;
	str body;

	room = imc_get_room(&cmd->param[0], &dst->host);
	if(room== NULL)
	{
		LM_DBG("new room [%.*s]\n",	cmd->param[0].len, cmd->param[0].s);
		if(cmd->param[1].len==IMC_ROOM_PRIVATE_LEN
			&& !strncasecmp(cmd->param[1].s, IMC_ROOM_PRIVATE,
				cmd->param[1].len))
		{
			flag_room |= IMC_ROOM_PRIV;					
			LM_DBG("room with private flag on\n");
		}
			
		room= imc_add_room(&cmd->param[0], &dst->host, flag_room);
		if(room == NULL)
		{
			LM_ERR("failed to add new room\n");
			goto error;
		}	
		LM_DBG("added room uri= %.*s\n", room->uri.len, room->uri.s);
		flag_member |= IMC_MEMBER_OWNER;
		/* adding the owner as the forst member*/
		member= imc_add_member(room, &src->user, &src->host, flag_member);
		if(member == NULL)
		{
			LM_ERR("failed to add owner [%.*s]\n", src->user.len, src->user.s);
			goto error;
		}
		LM_DBG("added the owner as the first member "
				"[%.*s]\n",member->uri.len, member->uri.s);
	
		/* send info message */
		body.s = "*** room was created";
		body.len = sizeof("*** room was created")-1;
		imc_send_message(&room->uri, &member->uri, &all_hdrs, &body);
		goto done;
	}
	
	/* room already exists */

	LM_DBG("room [%.*s] already created\n",	cmd->param[0].len, cmd->param[0].s);
	if(!(room->flags & IMC_ROOM_PRIV)) 
	{
		LM_DBG("checking if the user [%.*s] is a member\n",
				src->user.len, src->user.s);
		member= imc_get_member(room, &src->user, &src->host);
		if(member== NULL)
		{					
			member= imc_add_member(room, &src->user, &src->host, flag_member);
			if(member == NULL)
			{
				LM_ERR("failed to add member [%.*s]\n",
					src->user.len, src->user.s);
				goto error;
			}
			LM_DBG("added as member [%.*s]\n",member->uri.len, member->uri.s);
			/* send info message */
			body.s = imc_body_buf;
			body.len = snprintf(body.s, IMC_BUF_SIZE,
				"*** <%.*s> has joined the room",
				member->uri.len, member->uri.s);
			if(body.len>0)
				imc_room_broadcast(room, &all_hdrs, &body);

			if(body.len>=IMC_BUF_SIZE)
				LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
		}
	}

done:
	if(room!=NULL)
		imc_release_room(room);
	return 0;

error:
	if(room!=NULL)
		imc_release_room(room);
	return -1;
}