예제 #1
0
char* MQTTSProtocol_getPreDefinedTopicName(Clients* client, int topicId)
{
	Node* node;
	char* rc = NULL;

	FUNC_ENTRY;
	// Read client specific mappings first
	if ( (node = TreeFind(bstate->client_predefined_topics, client->clientID)) != NULL){
		Tree *topic = ((Client_Predefined_Topics*)(node->content))->topics ;
		if ( (node = TreeFind( topic , &topicId)) != NULL){
			rc = ((Predefined_Topic*)(node->content))->topicName;
		}
	}

	// If client specific pre-defined topic not found, read broker wide mapping
	if ( rc == NULL ) {
		if ( (node = TreeFind(bstate->default_predefined_topics, &topicId)) == NULL) {
			goto exit;
		}
		rc = ((Predefined_Topic*)(node->content))->topicName;
	}
exit:
	FUNC_EXIT;
	return rc;
}
예제 #2
0
파일: dbase.c 프로젝트: skewray/skewray_old
DBDAT* DbaseSet( TAG* list, DBDAT* dbdat )
    {
    FOLDER* folder ;

    if( !dbdat )
	{
	IOerror( IO_WARN, "DbaseFind", "setting null value" ) ;
	return (DBDAT*) 0 ;
	}

    if( !*list )
	{
	IOerror( IO_WARN, "DbaseFind", "null taglist" ) ;
	return (DBDAT*) 0 ;
	}

    for( folder = &DbaseRoot ; *(list + 1) ; list++ )
	{
	FOLDER* son = (FOLDER*) TreeFind( folder->kids, kid_cmp, *list ) ;
	if( !son )
	    {
	    DbaseAddFolder( folder, *list ) ;
	    son = (FOLDER*) TreeFind( folder->kids, kid_cmp, *list ) ;
	    }
	folder = son ;
	}

    return folder->EntryOverwrite( *list, dbdat ) ;
    }
예제 #3
0
/**
 * Process an incoming pubrel packet for a socket
 * @param pack pointer to the publish packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handlePubrels(void* pack, int sock, Clients* client)
{
	Pubrel* pubrel = (Pubrel*)pack;
	//Clients* client = (Clients*)(TreeFind(bstate->clients, &sock)->content);
	int rc = TCPSOCKET_COMPLETE;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 17, NULL, sock, client->clientID, pubrel->msgId);

	/* look for the message by message id in the records of inbound messages for this client */
	if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL)
	{
		if (pubrel->header.bits.dup == 0)
			Log(LOG_WARNING, 50, NULL, "PUBREL", client->clientID, pubrel->msgId);
		/* Apparently this is "normal" behaviour, so we don't need to issue a warning */
		rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID);
	}
	else
	{
		Messages* m = (Messages*)(client->inboundMsgs->current->content);
		if (m->qos != 2)
			Log(LOG_WARNING, 51, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos);
		else if (m->nextMessageType != PUBREL)
			Log(LOG_WARNING, 52, NULL, "PUBREL", client->clientID, pubrel->msgId);
		else
		{
			Publish publish;
			char* saved_clientid = malloc(strlen(client->clientID) + 1);

			strcpy(saved_clientid, client->clientID);
			/* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */
			rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID);
			publish.header.bits.qos = m->qos;
			publish.header.bits.retain = m->retain;
			publish.msgId = m->msgid;
			publish.topic = m->publish->topic;
			publish.payload = m->publish->payload;
			publish.payloadlen = m->publish->payloadlen;
			++(bstate->msgs_received);
			bstate->bytes_received += m->publish->payloadlen;
			Protocol_processPublication(&publish, client->clientID);

			/* The client structure might have been removed in processPublication, on error */
			if (TreeFind(bstate->clients, &sock) || TreeFind(bstate->disconnected_clients, saved_clientid))
			{
				ListRemove(client->inboundMsgs, m);
				MQTTProtocol_removePublication(m->publish);
			}
			free(saved_clientid);
		}
	}
	free(pack);
	FUNC_EXIT_RC(rc);
	return rc;
}
예제 #4
0
파일: dbase.c 프로젝트: skewray/skewray_old
DBDAT* DbaseLookup( char* opath, TAG keytag )
    {
    static char path[1000] ;
    DBDAT* dbdat = (DBDAT*) 0 ;

    FOLDER* folder = &DbaseRoot ;
    (void) strcpy( path, DataBasePath ) ;
    dbdat = folder->EntryFind( keytag ) ;
    for( TAG* list = DbasePathtoList( opath ) ; *list ; list++ )
	{
	(void) strcat( path, "/" ) ;
	(void) strcat( path, TagString( *list ) ) ;

	FOLDER* son = (FOLDER*) TreeFind( folder->kids, kid_cmp, *list ) ;
	if( !son )
	    {
	    IOerror( IO_WARN, "DbaseLookup", "no such directory %s\n", path ) ;
	    return dbdat ;
	    }

	if( !son->loaded )
	    DbaseLoadDir( path, son ) ;

	folder = son ;
	if( DBDAT* new_dbdat = folder->EntryFind( keytag ) )
	    dbdat = new_dbdat ;
	}

    return dbdat ;
    }
예제 #5
0
/**
 * Utility to find an item in the heap.  Lets you know if the heap already contains
 * the memory location in question.
 * @param p pointer to a memory location
 * @return pointer to the storage element if found, or NULL
 */
void* Heap_findItem(void* p)
{
	Node* e = NULL;

	Thread_lock_mutex(heap_mutex);
	e = TreeFind(&heap, ((int*)p)-1);
	Thread_unlock_mutex(heap_mutex);
	return (e == NULL) ? NULL : e->content;
}
예제 #6
0
Clients* Protocol_getoutboundclient(int sock)
{
	Node* node = NULL;
	Clients* client = NULL;

	FUNC_ENTRY;
	if ((node = TreeFind(bstate->clients, &sock)) != NULL)
		client = (Clients*)(node->content);
	FUNC_EXIT;
	return client;
}
예제 #7
0
Clients* Protocol_getclientbyaddr(char* addr)
{
	Node* node = NULL;
	Clients* client = NULL;

	FUNC_ENTRY;
	if ((node = TreeFind(bstate->mqtts_clients, addr)) != NULL)
		client = (Clients*)(node->content);
	FUNC_EXIT;
	return client;
}
예제 #8
0
파일: dbase.c 프로젝트: skewray/skewray_old
DBDAT* DbaseFind( TAG* list )
    {
    FOLDER* folder ;

    if( !*list )
	{
	IOerror( IO_WARN, "DbaseFind", "null taglist" ) ;
	return (DBDAT*) 0 ;
	}

    for( folder = &DbaseRoot ; *(list + 1) ; list++ )
	{
	FOLDER* son = (FOLDER*) TreeFind( folder->kids, kid_cmp, *list ) ;
	if( !son )
	    {
	    DbaseAddFolder( folder, *list ) ;
	    son = (FOLDER*) TreeFind( folder->kids, kid_cmp, *list ) ;
	    }
	folder = son ;
	}

    return folder->EntryFind( *list ) ;
    }
예제 #9
0
파일: tract.c 프로젝트: clojit/rust-mps-obj
Bool ChunkOfAddr(Chunk *chunkReturn, Arena arena, Addr addr)
{
  Tree tree;

  AVER_CRITICAL(chunkReturn != NULL);
  AVERT_CRITICAL(Arena, arena);
  /* addr is arbitrary */

  if (TreeFind(&tree, ArenaChunkTree(arena), TreeKeyOfAddrVar(addr),
               ChunkCompare)
      == CompareEQUAL)
  {
    Chunk chunk = ChunkOfTree(tree);
    AVER_CRITICAL(chunk->base <= addr);
    AVER_CRITICAL(addr < chunk->limit);
    *chunkReturn = chunk;
    return TRUE;
  }
  return FALSE;
}
예제 #10
0
/**
 * Remove an item from the recorded heap without actually freeing it.
 * Use sparingly!
 * @param file use the __FILE__ macro to indicate which file this item was allocated in
 * @param line use the __LINE__ macro to indicate which line this item was allocated at
 * @param p pointer to the item to be removed
 */
static int Internal_heap_unlink(char* file, int line, void* p)
{
	Node* e = NULL;
	int rc = 0;

	e = TreeFind(&heap, ((int*)p)-1);
	if (e == NULL)
		Log(LOG_ERROR, 13, "Failed to remove heap item at file %s line %d", file, line);
	else
	{
		storageElement* s = (storageElement*)(e->content);
		Log(TRACE_MAX, -1, "Freeing %d bytes in heap at file %s line %d, heap use now %d bytes\n",
											 s->size, file, line, state.current_size);
		checkEyecatchers(file, line, p, s->size);
		/* free(s->ptr); */
		free(s->file);
		state.current_size -= s->size;
		TreeRemoveNodeIndex(&heap, e, 0);
		free(s);
		rc = 1;
	}
	return rc;
}
예제 #11
0
Bool TreeInsert(Tree *treeReturn, Tree root, Tree node,
                TreeKey key, TreeCompare compare)
{
  Tree parent;
  Compare cmp;
  
  AVER(treeReturn != NULL);
  AVER(Tree, root);
  AVER(TreeCheckLeaf(node));
  AVER(FUNCHECK(compare));
  /* key is arbitrary */

  cmp = TreeFind(&parent, root, key, compare);
  switch (cmp) {
  case CompareLESS:
    parent->left = node;
    break;
  case CompareEQUAL:
    if (parent != NULL) {
      *treeReturn = parent;
      return FALSE;
    }
    AVER(root == TreeEMPTY);
    root = node;
    break;
  case CompareGREATER:
    parent->right = node;
    break;
  default:
    NOTREACHED;
    *treeReturn = NULL;
    return FALSE;
  }
  
  *treeReturn = root;
  return TRUE;
}
예제 #12
0
/**
 * Originates a new publication - sends it to all clients subscribed.
 * @param publish pointer to a stucture which contains all the publication information
 * @param originator the originating client
 */
void Protocol_processPublication(Publish* publish, char* originator)
{
	Messages* stored = NULL; /* to avoid duplication of data where possible */
	List* clients;
	ListElement* current = NULL;
	int savedMsgId = publish->msgId;
	int clean_needed = 0;

	FUNC_ENTRY;
	
	if (Topics_hasWildcards(publish->topic))
	{
		Log(LOG_INFO, 12, NULL, publish->topic, originator);
		goto exit;
	}

	if ((strcmp(INTERNAL_CLIENTID, originator) != 0) && bstate->password_file && bstate->acl_file)
	{
		Clients* client = (Clients*)(TreeFindIndex(bstate->clients, originator, 1)->content);
		
		if (Users_authorise(client->user, publish->topic, ACL_WRITE) == false)
		{
			Log(LOG_AUDIT, 149, NULL, originator, publish->topic);
			goto exit;
		}
	}

	if (publish->header.bits.retain)
	{
		SubscriptionEngines_setRetained(bstate->se, publish->topic, publish->header.bits.qos, publish->payload, publish->payloadlen);
		if (bstate->persistence == 1 && bstate->autosave_on_changes == 1 && bstate->autosave_interval > 0
			&& bstate->se->retained_changes >= bstate->autosave_interval)
		{
			Log(LOG_INFO, 100, NULL, bstate->autosave_interval);
			SubscriptionEngines_save(bstate->se);
		}
	}

	clients = SubscriptionEngines_getSubscribers(bstate->se, publish->topic, originator);
	if (strncmp(publish->topic, "$SYS/client/", 12) == 0)
	{ /* default subscription for a client */
		Node* node = TreeFindIndex(bstate->clients, &publish->topic[12], 1);
		if (node == NULL)
			node = TreeFind(bstate->disconnected_clients, &publish->topic[12]);
		if (node && node->content)
		{
			Subscriptions* rcs = malloc(sizeof(Subscriptions));
			rcs->clientName = &publish->topic[12];
			rcs->qos = 2;
			rcs->priority = PRIORITY_NORMAL;
			rcs->topicName = publish->topic;
			ListAppend(clients, rcs, sizeof(Subscriptions));
		}
	}
	current = NULL;
	while (ListNextElement(clients, &current))
	{
		Node* curnode = NULL;
		unsigned int qos = ((Subscriptions*)(current->content))->qos;
		int priority = ((Subscriptions*)(current->content))->priority;
		char* clientName = ((Subscriptions*)(current->content))->clientName;
		
		if (publish->header.bits.qos < qos) /* reduce qos if > subscribed qos */
			qos = publish->header.bits.qos;
			
		if ((curnode = TreeFindIndex(bstate->clients, clientName, 1)) == NULL)
			curnode = TreeFind(bstate->disconnected_clients, clientName);
#if defined(MQTTS)
		if (curnode == NULL && ((curnode = TreeFindIndex(bstate->mqtts_clients, clientName, 1)) == NULL))
			curnode = TreeFind(bstate->disconnected_mqtts_clients, clientName);
#endif

		if (curnode)
		{
			Clients* pubclient = (Clients*)(curnode->content);
			int retained = 0;
			Messages* saved = NULL;
			char* original_topic = publish->topic;
			
#if !defined(NO_BRIDGE)
			if (pubclient->outbound || pubclient->noLocal)
			{
				retained = publish->header.bits.retain; /* outbound and noLocal mean outward/inward bridge client,
																							so keep retained flag */
				if (pubclient->outbound)
				{
					Bridge_handleOutbound(pubclient, publish);
					if (publish->topic != original_topic)
					{ /* handleOutbound has changed the topic, so we musn't used the stored pub which
					        contains the original topic */
						saved = stored;
						stored = NULL;
					}
				}
			}
#endif
			if (Protocol_startOrQueuePublish(pubclient, publish, qos, retained, priority, &stored) == SOCKET_ERROR)
			{
				pubclient->good = pubclient->connected = 0; /* flag this client as needing to be cleaned up */
				clean_needed = 1;
			}
			if (publish->topic != original_topic)
			{
				stored = saved;  /* restore the stored pointer for the next loop iteration */
				free(publish->topic);
				publish->topic = original_topic;
			}
		}
	}
	publish->msgId = savedMsgId;
	/* INTERNAL_CLIENTID means that we are publishing data to the log,
			and we don't want to interfere with other close processing */
	if (clean_needed && strcmp(originator, INTERNAL_CLIENTID) != 0)
		MQTTProtocol_clean_clients(bstate->clients);
	ListFree(clients);
exit:
	FUNC_EXIT;
}
예제 #13
0
/**
 * Timeslice function to run protocol exchanges
 */
void Protocol_timeslice()
{
	int sock;
	int bridge_connection = 0;
	static int more_work = 0;

	FUNC_ENTRY;
	if ((sock = Socket_getReadySocket(more_work, NULL)) == SOCKET_ERROR)
	{
#if defined(WIN32)
		int errno;
		errno = WSAGetLastError();
#endif
		if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK)
		{
			Log(LOG_SEVERE, 0, "Restarting MQTT protocol to resolve socket problems");
			MQTTProtocol_shutdown(0);
			SubscriptionEngines_save(bstate->se);
			MQTTProtocol_reinitialize();
			goto exit;
		}
	}

	MQTTProtocol_checkPendingWrites();
	if (sock > 0)
	{
		Clients* client = NULL;
		Node* curnode = TreeFind(bstate->clients, &sock);

		if (curnode)
		{
			client = (Clients*)(curnode->content);
#if !defined(NO_BRIDGE)
			if (client->outbound && client->connect_state == 1)
			{
				Bridge_handleConnection(client);
				bridge_connection = 1;
			}
#endif
		}
		
		if (bridge_connection == 0)
#if defined(MQTTS)
		{
			int protocol = PROTOCOL_MQTT;
			if (client == NULL)
				protocol = Socket_getParentListener(sock)->protocol;
			else
				protocol = client->protocol;

			if (protocol == PROTOCOL_MQTT)
#endif
				MQTTProtocol_timeslice(sock, client);
#if defined(MQTTS)
			else if (protocol == PROTOCOL_MQTTS)
			    MQTTSProtocol_timeslice(sock);
		}
#endif
	}
	if (bstate->state != BROKER_STOPPING)
#if !defined(NO_ADMIN_COMMANDS)
		Persistence_read_command(bstate);
#else
		;
#endif
	else
예제 #14
0
파일: ubi_BinTree.c 프로젝트: mbethke/hsc
ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
                            ubi_btItemPtr FindMe,
                            ubi_trCompOps CompOp )
/* ------------------------------------------------------------------------ **
 * The purpose of ubi_btLocate() is to find a node or set of nodes given
 * a target value and a "comparison operator".  The Locate() function is
 * more flexible and (in the case of trees that may contain dupicate keys)
 * more precise than the ubi_btFind() function.  The latter is faster,
 * but it only searches for exact matches and, if the tree contains
 * duplicates, Find() may return a pointer to any one of the duplicate-
 * keyed records.
 *
 *  Input:
 *     RootPtr  -  A pointer to the header of the tree to be searched.
 *     FindMe   -  An ubi_btItemPtr that indicates the key for which to
 *                 search.
 *     CompOp   -  One of the following:
 *                    CompOp     Return a pointer to the node with
 *                    ------     ---------------------------------
 *                   ubi_trLT - the last key value that is less
 *                              than FindMe.
 *                   ubi_trLE - the first key matching FindMe, or
 *                              the last key that is less than
 *                              FindMe.
 *                   ubi_trEQ - the first key matching FindMe.
 *                   ubi_trGE - the first key matching FindMe, or the
 *                              first key greater than FindMe.
 *                   ubi_trGT - the first key greater than FindMe.
 *  Output:
 *     A pointer to the node matching the criteria listed above under
 *     CompOp, or NULL if no node matched the criteria.
 *
 *  Notes:
 *     In the case of trees with duplicate keys, Locate() will behave as
 *     follows:
 *
 *     Find:  3                       Find: 3
 *     Keys:  1 2 2 2 3 3 3 3 3 4 4   Keys: 1 1 2 2 2 4 4 5 5 5 6
 *                  ^ ^         ^                   ^ ^
 *                 LT EQ        GT                 LE GE
 *
 *     That is, when returning a pointer to a node with a key that is LESS
 *     THAN the target key (FindMe), Locate() will return a pointer to the
 *     LAST matching node.
 *     When returning a pointer to a node with a key that is GREATER
 *     THAN the target key (FindMe), Locate() will return a pointer to the
 *     FIRST matching node.
 *
 *  See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf().
 * ------------------------------------------------------------------------ **
 */
{
    register ubi_btNodePtr p;
    ubi_btNodePtr   parent;
    char            whichkid;

    /* Start by searching for a matching node. */
    p = TreeFind( FindMe,
                  RootPtr->root,
                  &parent,
                  &whichkid,
                  RootPtr->cmp );

    if( NULL != p )    /* If we have found a match, we can resolve as follows:  */
    {
        switch( CompOp )
        {
        case ubi_trLT:            /* It's just a jump to the left...  */
            p = Border( RootPtr, FindMe, p, ubi_trLEFT );
            return( Neighbor( p, ubi_trLEFT ) );
        case ubi_trGT:            /* ...and then a jump to the right. */
            p = Border( RootPtr, FindMe, p, ubi_trRIGHT );
            return( Neighbor( p, ubi_trRIGHT ) );
        default:
            p = Border( RootPtr, FindMe, p, ubi_trLEFT );
            return( p );
        }
    }

    /* Else, no match. */
    if( ubi_trEQ == CompOp )    /* If we were looking for an exact match... */
        return( NULL );           /* ...forget it.                            */

    /* We can still return a valid result for GT, GE, LE, and LT.
     * <parent> points to a node with a value that is either just before or
     * just after the target value.
     * Remaining possibilities are LT and GT (including LE & GE).
     */
    if( (ubi_trLT == CompOp) || (ubi_trLE == CompOp) )
        return( (ubi_trLEFT == whichkid) ? Neighbor( parent, whichkid ) : parent );
    else
        return( (ubi_trRIGHT == whichkid) ? Neighbor( parent, whichkid ) : parent );
} /* ubi_btLocate */
예제 #15
0
파일: ubi_BinTree.c 프로젝트: mbethke/hsc
ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
                         ubi_btNodePtr  NewNode,
                         ubi_btItemPtr  ItemPtr,
                         ubi_btNodePtr *OldNode )
/* ------------------------------------------------------------------------ **
 * This function uses a non-recursive algorithm to add a new element to the
 * tree.
 *
 *  Input:   RootPtr  -  a pointer to the ubi_btRoot structure that indicates
 *                       the root of the tree to which NewNode is to be added.
 *           NewNode  -  a pointer to an ubi_btNode structure that is NOT
 *                       part of any tree.
 *           ItemPtr  -  A pointer to the sort key that is stored within
 *                       *NewNode.  ItemPtr MUST point to information stored
 *                       in *NewNode or an EXACT DUPLICATE.  The key data
 *                       indicated by ItemPtr is used to place the new node
 *                       into the tree.
 *           OldNode  -  a pointer to an ubi_btNodePtr.  When searching
 *                       the tree, a duplicate node may be found.  If
 *                       duplicates are allowed, then the new node will
 *                       be simply placed into the tree.  If duplicates
 *                       are not allowed, however, then one of two things
 *                       may happen.
 *                       1) if overwritting *is not* allowed, this
 *                          function will return FALSE (indicating that
 *                          the new node could not be inserted), and
 *                          *OldNode will point to the duplicate that is
 *                          still in the tree.
 *                       2) if overwritting *is* allowed, then this
 *                          function will swap **OldNode for *NewNode.
 *                          In this case, *OldNode will point to the node
 *                          that was removed (thus allowing you to free
 *                          the node).
 *                          **  If you are using overwrite mode, ALWAYS  **
 *                          ** check the return value of this parameter! **
 *                 Note: You may pass NULL in this parameter, the
 *                       function knows how to cope.  If you do this,
 *                       however, there will be no way to return a
 *                       pointer to an old (ie. replaced) node (which is
 *                       a problem if you are using overwrite mode).
 *
 *  Output:  a boolean value indicating success or failure.  The function
 *           will return FALSE if the node could not be added to the tree.
 *           Such failure will only occur if duplicates are not allowed,
 *           nodes cannot be overwritten, AND a duplicate key was found
 *           within the tree.
 * ------------------------------------------------------------------------ **
 */
{
    ubi_btNodePtr OtherP,
                  parent = NULL;
    char          tmp;

    if( NULL == OldNode ) /* If they didn't give us a pointer, supply our own.  */
        OldNode = &OtherP;

    (void)ubi_btInitNode( NewNode );     /* Init the new node's BinTree fields. */

    /* Find a place for the new node. */
    *OldNode = TreeFind(ItemPtr, (RootPtr->root), &parent, &tmp, (RootPtr->cmp));

    /* Now add the node to the tree... */
    if( NULL == (*OldNode) )  /* The easy one: we have a space for a new node!  */
    {
        if( NULL == parent )
            RootPtr->root = NewNode;
        else
        {
            parent->Link[(int)tmp]      = NewNode;
            NewNode->Link[ubi_trPARENT] = parent;
            NewNode->gender             = tmp;
        }
        (RootPtr->count)++;
        return( ubi_trTRUE );
    }

    /* If we reach this point, we know that a duplicate node exists.  This
     * section adds the node to the tree if duplicate keys are allowed.
     */
    if( ubi_trDups_OK(RootPtr) )    /* Key exists, add duplicate */
    {
        ubi_btNodePtr q;

        tmp = ubi_trRIGHT;
        q = (*OldNode);
        *OldNode = NULL;
        while( NULL != q )
        {
            parent = q;
            if( tmp == ubi_trEQUAL )
                tmp = ubi_trRIGHT;
            q = q->Link[(int)tmp];
            if ( q )
                tmp = ubi_trAbNormal( (*(RootPtr->cmp))(ItemPtr, q) );
        }
        parent->Link[(int)tmp]       = NewNode;
        NewNode->Link[ubi_trPARENT]  = parent;
        NewNode->gender              = tmp;
        (RootPtr->count)++;
        return( ubi_trTRUE );
    }

    /* If we get to *this* point, we know that we are not allowed to have
     * duplicate nodes, but our node keys match, so... may we replace the
     * old one?
     */
    if( ubi_trOvwt_OK(RootPtr) )    /* Key exists, we replace */
    {
        if( NULL == parent )
            ReplaceNode( &(RootPtr->root), *OldNode, NewNode );
        else
            ReplaceNode( &(parent->Link[(int)((*OldNode)->gender)]),
                         *OldNode, NewNode );
        return( ubi_trTRUE );
    }

    return( ubi_trFALSE );      /* Failure: could not replace an existing node. */
} /* ubi_btInsert */
예제 #16
0
int test(int limit)
{
	int i, *ip, *todelete;
	Node* current = NULL;
	Tree* t = TreeInitialize(TreeIntCompare);
	int rc = 0;

	printf("Tree initialized\n");

	srand(time(NULL));

	ip = malloc(sizeof(int));
	*ip = 2;
	TreeAdd(t, (void*)ip, sizeof(int));

	check(t);

	i = 2;
	void* result = TreeRemove(t, (void*)&i);
	if (result)
		free(result);

	int actual[limit];
	for (i = 0; i < limit; i++)
	{
		void* replaced = NULL;

		ip = malloc(sizeof(int));
		*ip = rand();
		replaced = TreeAdd(t, (void*)ip, sizeof(int));
		if (replaced) /* duplicate */
		{
			free(replaced);
			actual[i] = -1;
		}
		else
			actual[i] = *ip;
		if (i==5)
			todelete = ip;
		printf("Tree element added %d\n",  *ip);
		if (1 % 1000 == 0)
		{
			rc = check(t);
			printf("%d elements, check result %d\n", i+1, rc);
			if (rc != 0)
				return 88;
		}
	}

	check(t);

	for (i = 0; i < limit; i++)
	{
		int parm = actual[i];

		if (parm == -1)
			continue;

		Node* found = TreeFind(t, (void*)&parm);
		if (found)
			printf("Tree find %d %d\n", parm, *(int*)(found->content));
		else
		{
			printf("%d not found\n", parm);
			traverse(t, parm);
			return -2;
		}
	}

	check(t);

	for (i = limit -1; i >= 0; i--)
	{
		int parm = actual[i];
		void *found;

		if (parm == -1) /* skip duplicate */
			continue;

		found = TreeRemove(t, (void*)&parm);
		if (found)
		{
			printf("%d Tree remove %d %d\n", i, parm, *(int*)(found));
			free(found);
		}
		else
		{
			int count = 0;
			printf("%d %d not found\n", i, parm);
			traverse(t, parm);
			for (i = 0; i < limit; i++)
				if (actual[i] == parm)
					++count;
			printf("%d occurs %d times\n", parm, count);
			return -2;
		}
		if (i % 1000 == 0)
		{
			rc = check(t);
			printf("%d elements, check result %d\n", i+1, rc);
			if (rc != 0)
				return 88;
		}
	}
	printf("finished\n");
	return 0;
}
예제 #17
0
/**
 * MQTT protocol timeslice for one packet and client - must not take too long!
 * @param sock the socket which is ready for the packet to be read from
 * @param client the client structure which corresponds to the socket
 */
void MQTTProtocol_timeslice(int sock, Clients* client)
{
	int error;
	MQTTPacket* pack;

	FUNC_ENTRY;

	Log(TRACE_MIN, -1, "%d %s About to read packet for peer address %s",
			sock, (client == NULL) ? "unknown" : client->clientID, Socket_getpeer(sock));
	in_MQTTPacket_Factory = sock;
	pack = MQTTPacket_Factory(sock, &error);
	in_MQTTPacket_Factory = -1;
	if (pack == NULL)
	{ /* there was an error on the socket, so clean it up */
		if (error == SOCKET_ERROR || error == BAD_MQTT_PACKET)
		{
			if (client != NULL)
			{
				client->good = 0; /* make sure we don't try and send messages to ourselves */
				if (error == SOCKET_ERROR)
					Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock));
				else
					Log(LOG_WARNING, 19, NULL, client->clientID, sock, Socket_getpeer(sock));
				MQTTProtocol_closeSession(client, 1);
			}
			else
			{
				if (error == SOCKET_ERROR)
					/* Don't do a Socket_getpeer in the case of SOCKET_ERROR -
					 * otherwise another SOCKET_ERROR will be hit  */
					Log(LOG_WARNING, 20, NULL, sock, "unknown");
				else
					Log(LOG_WARNING, 21, NULL, sock, Socket_getpeer(sock));
				Socket_close(sock);
			}
		}
	}
	else if (handle_packets[pack->header.bits.type] == NULL)
		Log(LOG_WARNING, 22, NULL, pack->header.bits.type, sock);
	else
	{
		if (client == NULL && pack->header.bits.type != CONNECT)
		{
			Log(LOG_WARNING, 23, NULL, sock, Socket_getpeer(sock), MQTTPacket_name(pack->header.bits.type));
			MQTTPacket_free_packet(pack);
			Socket_close(sock);
		}
		else
		{
			Node* elem = NULL;
			/* incoming publish at QoS 0 does not result in outgoing communication, so we don't want to count it as contact,
			   for PING processing on outbound connections */
			int update_time = (pack->header.bits.type == PUBLISH && pack->header.bits.qos == 0) ? 0 : 1;
			if (client && (update_time || (client->outbound == 0)))
				time(&(client->lastContact));
			if ((*handle_packets[pack->header.bits.type])(pack, sock, client) == SOCKET_ERROR)
			{
				/* the client could have been closed during handle_packet, so check to see if it's still in the client list */
				elem = TreeFind(bstate->clients, &sock);
				if (elem == NULL && client && client->clientID)
					elem = TreeFind(bstate->disconnected_clients, client->clientID);
				if (elem != NULL)
				{
					client = (Clients*)(elem->content);
					client->good = 0; /* make sure we don't try and send messages to ourselves */
					Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock));
					MQTTProtocol_closeSession(client, 1);
				}
				else
				{
					Log(LOG_WARNING, 20, NULL, sock, Socket_getpeer(sock));
					Socket_close(sock);
				}
			}
		}
	}
	/*MQTTProtocol_housekeeping(); move to Protocol_timeslice*/
	FUNC_EXIT;
}