Esempio n. 1
0
/**
 * \brief This function add session (client) to the list of clients that are
 * subscribed this node.
 */
static int vs_node_subscribe(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct VSNode *node,
		uint32 version)
{
	struct VSNode				*child_node;
	struct VSNodePermission		*perm;
	struct VSNodeSubscriber		*node_subscriber;
	struct VSLink				*link;
	struct VBucket				*bucket;
	struct VSTagGroup			*tg;
	struct VSLayer				*layer;
	int							user_can_read = 0;

	/* Can user subscribe to this node? */
	user_can_read = vs_node_can_read(vs_ctx, vsession, node);

	/* Add current session to the list of node subscribers */
	node_subscriber = (struct VSNodeSubscriber*)calloc(1, sizeof(struct VSNodeSubscriber));
	node_subscriber->session = vsession;
	node_subscriber->prio = VRS_DEFAULT_PRIORITY;
	v_list_add_tail(&node->node_subs, node_subscriber);

	/* TODO: send node_subscribe with version and commands with difference
	 * between this version and current state, when versing will be supported */
	if(version != 0) {
		v_print_log(VRS_PRINT_WARNING, "Version: %d != 0, versing is not supported yet\n", version);
	}

	/* Send node_perm commands to the new subscriber */
	perm = node->permissions.first;
	while(perm != NULL) {
		vs_node_send_perm(node_subscriber, node, perm->user, perm->permissions);
		perm = perm->next;
	}

	/* If the node is locked, then send node_lock to the subscriber */
	if(node->lock.session != NULL) {
		vs_node_send_lock(node_subscriber, node->lock.session, node);
	}

	/* If user doesn't have permission to subscribe to this node, then send
	 * only node_perm command explaining, why user can't rest of this
	 * node */
	if(user_can_read == 0) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Insufficient permission to read content of the node: %d\n", node->id);
		return 0;
	}

	/* Send node_create of all child nodes of this node and corresponding
	 * links */
	link = node->children_links.first;
	while(link!=NULL) {
		child_node = link->child;
		vs_node_send_create(node_subscriber, child_node, NULL);
		link = link->next;
	}

	/* Send taggroup_create of all tag_groups in this node */
	bucket = node->tag_groups.lb.first;
	while(bucket != NULL) {
		tg = (struct VSTagGroup*)bucket->data;
		if(tg->state == ENTITY_CREATING || tg->state == ENTITY_CREATED) {
			vs_taggroup_send_create(node_subscriber, node, tg);
		}
		bucket = bucket->next;
	}

	/* Send layer_create for all layers in this node */
	bucket = node->layers.lb.first;
	while(bucket != NULL) {
		layer = (struct VSLayer*)bucket->data;
		if(layer->state == ENTITY_CREATING || layer->state == ENTITY_CREATED) {
			vs_layer_send_create(node_subscriber, node, layer);
		}
		bucket = bucket->next;
	}

	return 1;
}
Esempio n. 2
0
/**
 * \brief This function tries to handle node_create command
 */
int vs_handle_taggroup_create(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *taggroup_create_cmd)
{
	struct VSNode			*node;
	struct VSTagGroup		*tg;
	struct VBucket			*vbucket;
	uint32 					node_id = UINT32(taggroup_create_cmd->data[0]);
	uint16 					taggroup_id = UINT16(taggroup_create_cmd->data[UINT32_SIZE]);
	uint16 					type = UINT16(taggroup_create_cmd->data[UINT32_SIZE+UINT16_SIZE]);
	int						ret = 0;

	/* Client has to send taggroup_create command with taggroup_id equal to
	 * the value 0xFFFF */
	if(taggroup_id != VRS_RESERVED_TAGGROUP_ID) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() taggroup_id: %d is not 0xFFFF\n",
				__FUNCTION__, taggroup_id);
		return 0;
	}

	/* Try to find node */
	if((node = vs_node_find(vs_ctx, node_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) not found\n",
				__FUNCTION__, node_id);
		return 0;
	}

	pthread_mutex_lock(&node->mutex);

	/* Node has to be created */
	if( vs_node_is_created(node) != 1 ) {
		goto end;
	}

	vbucket = node->tag_groups.lb.first;
	/* Check, if there isn't tag group with the same type */
	while(vbucket != NULL) {
		tg = vbucket->data;
		if(tg->custom_type == type) {
			v_print_log(VRS_PRINT_DEBUG_MSG,
					"%s() taggroup type: %d is already used in node: %d\n",
					__FUNCTION__, type, node->id);
			goto end;
		}
		vbucket = vbucket->next;
	}

	/* Is user owner of this node or can user write to this node? */
	if(vs_node_can_write(vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s(): user: %s can't write to node: %d\n",
				__FUNCTION__,
				((struct VSUser *)vsession->user)->username,
				node->id);
		goto end;
	}

	/* Try to create new tag group */
	tg = vs_taggroup_create(node, VRS_RESERVED_TAGGROUP_ID, type);
	if(tg == NULL) {
		goto end;
	} else {
		struct VSNodeSubscriber *node_subscriber;

		/* Set state for this entity */
		tg->state = ENTITY_CREATING;

		ret = 1;

		/* Send tag group create command to all subscribers to the node
		 * that can read this node */
		for(node_subscriber = node->node_subs.first;
				node_subscriber != NULL;
				node_subscriber = node_subscriber->next)
		{
			if( vs_node_can_read(node_subscriber->session, node) == 1) {
				if(vs_taggroup_send_create(node_subscriber, node, tg) != 1) {
					ret = 0;
				}
			}
		}
	}

end:

	pthread_mutex_unlock(&node->mutex);

	return ret;
}