예제 #1
0
void BalancedBTreeRemove( BalancedBTree_t *btree, BalancedBTreeItem_t *item, 
                          Locked_t locked, bool rebalance )
{
    BalancedBTreeItem_t    *replace;

    if( btree == NULL )
    {
        return;
    }

    if( item != NULL && item->btree != btree )
    {
        LogPrint( LOG_CRIT, "Item %p not on btree %p! (on %p)", (void *)item, 
                  (void *)btree, (void *)item->btree );
        return;
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeLock( btree );
    }

    if( item == NULL ) {
        if( rebalance ) {
            BalancedBTreeRebalance( btree, btree->root );
        }

        if( locked == UNLOCKED ) {
            BalancedBTreeLock( btree );
        }
        return;
    }


    /* OK, it's on the btree, and we have it locked */
    if( BalancedBTreeWeight( item->left ) > 
        BalancedBTreeWeight( item->right ) ) {
        /* There's more stuff on the left subtree, relink taking
         * the greatest entry on the left subtree, moving it here
         */
        replace = BalancedBTreeFindGreatest( item->left );
    } else {
        /* Either more on the right subtree or they are balanced, relink
         * taking the least entry on the right subtree, moving it here
         */
        replace = BalancedBTreeFindLeast( item->right );
    }
    BalancedBTreeReplace( btree, item, replace );

    item->btree = NULL;

    if( rebalance ) {
        BalancedBTreeRebalance( btree, btree->root );
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeUnlock( btree );
    }
}
예제 #2
0
파일: main.c 프로젝트: Beirdo/beirdobot
void mainVersions( void *arg )
{
    BalancedBTreeLock( versionTree );
    versionShowRecurse( versionTree->root, 0 );
    BalancedBTreeUnlock( versionTree );
    cursesKeyhandleRegister( cursesDetailsKeyhandle );
}
예제 #3
0
파일: main.c 프로젝트: Beirdo/beirdobot
void mainSighup( int signum, void *arg )
{
    /*
     * Need to rescan the plugins
     */
    LogPrintNoArg( LOG_INFO, "Reloading plugins..." );
    plugins_sighup();

    /*
     * Reload server & channel info -- NOTE: this happens before the bot
     * threads get signalled
     */
    LogPrintNoArg( LOG_INFO, "Reloading servers & channels..." );
    BalancedBTreeLock( ServerTree );
    serverUnvisit( ServerTree->root );

    db_load_servers();
    db_load_channels();

    while( serverFlushUnvisited( ServerTree->root ) ) {
        /*
         * If an unvisited entry is found, we need to loop as removing it can
         * mess up the recursion
         */
    }

    BalancedBTreeAdd( ServerTree, NULL, LOCKED, TRUE );
    BalancedBTreeUnlock( ServerTree );
}
예제 #4
0
파일: bot.c 프로젝트: Beirdo/beirdobot
void bot_start(void)
{
    /* Create the server tree */
    ServerTree = BalancedBTreeCreate( BTREE_KEY_INT );

    versionAdd( "botnet", BN_GetVersion() );

    BalancedBTreeLock( ServerTree );

    /* Read the list of servers */
    cursesMenuItemAdd( 2, MENU_SERVERS, "New Server", cursesServerNew, NULL );
    db_load_servers();

    /* Read the list of channels */
    cursesMenuItemAdd( 2, MENU_CHANNELS, "New Channel", cursesChannelNew, 
                       NULL );

    db_load_channels();

    ChannelsLoaded = TRUE;

    serverStartTree( ServerTree->root );

    BalancedBTreeUnlock( ServerTree );
}
예제 #5
0
void plugins_initialize( void )
{
    static char        *command = "plugin";
    LinkedList_t       *list;

    extBlock = ProtectedDataCreate();
    if( !extBlock ) {
        LogPrintNoArg( LOG_CRIT, "No memory to create plugin extension "
                                 "protected structure!!");
        exit(1);
    }

    extBlock->data = NULL;

    pluginTree = BalancedBTreeCreate( BTREE_KEY_STRING );
    if( !pluginTree ) {
        return;
    }

    list = pluginFindPlugins( "plugin_", ".so" );
    db_check_plugins( list );
    LinkedListDestroy( list );

    LogPrint( LOG_NOTICE, "Plugin path: %s", PLUGIN_PATH );

    BalancedBTreeLock( pluginTree );

    db_get_plugins( pluginTree );
    pluginInitializeTree( pluginTree->root );

    BalancedBTreeUnlock( pluginTree );

    botCmd_add( (const char **)&command, botCmdPlugin, NULL, NULL );
}
예제 #6
0
void ThreadAllKill( int signum )
{
    BalancedBTreeLock( ThreadTree );

    ThreadRecurseKill( ThreadTree->root, signum );

    BalancedBTreeUnlock( ThreadTree );
}
예제 #7
0
void pluginUnloadAll( void )
{
    if( !pluginTree ) {
        return;
    }

    BalancedBTreeLock( pluginTree );
    pluginUnloadTree( pluginTree->root );
    BalancedBTreeUnlock( pluginTree );
}
예제 #8
0
파일: bot.c 프로젝트: Beirdo/beirdobot
int FindServerWithChannel( int channelId )
{
    IRCServer_t    *server;

    if( !ChannelsLoaded ) {
        return( -1 );
    }

    BalancedBTreeLock( ServerTree );
    server = RecurseFindServerWithChannel( ServerTree->root, channelId );
    BalancedBTreeUnlock( ServerTree );

    if( server ) {
        return( server->serverId );
    }

    return( -1 );
}
예제 #9
0
void plugins_sighup( void )
{
    BalancedBTreeLock( pluginTree );

    pluginUnvisitTree( pluginTree->root );
    db_get_plugins( pluginTree );
    pluginInitializeTree( pluginTree->root );
    while( pluginFlushUnvisited( pluginTree->root ) ) {
        /* 
         * Keep calling until nothing's been flushed.  This allows for the 
         * fact that the tree will shift around as we delete things, and the
         * recursion will be messed up by this.
         */
    }

    /* Rebalance the tree */
    BalancedBTreeAdd( pluginTree, NULL, LOCKED, TRUE );

    BalancedBTreeUnlock( pluginTree );
}
예제 #10
0
파일: bot.c 프로젝트: Beirdo/beirdobot
void *bot_shutdown(void *arg)
{
    if( ServerTree ) {
        BalancedBTreeLock( ServerTree );

        while( serverKillTree( ServerTree->root, FALSE ) ) {
            /*
             * This recurses and kills off every entry in the tree, which
             * messes up recursion, so needs restarting
             */
        }

        BalancedBTreeDestroy( ServerTree );
        ServerTree = NULL;
    }

    LogPrintNoArg( LOG_NOTICE, "Shutdown all bot threads" );
    BotDone = true;

    return( NULL );
}
예제 #11
0
void *BalancedBTreeFind( BalancedBTree_t *btree, void *key,
                         Locked_t locked )
{
    BalancedBTreeItem_t    *item;
    bool                    found;
    int                     res;

    if( btree == NULL || key == NULL ) {
        return( NULL );
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeLock( btree );
    }

    for( found = FALSE, item = btree->root; item && !found; ) {
        res = btree->keyCompare( key, item->key );
        if( res == 0 ) {
            /* Found it */
            found = TRUE;
            continue;
        } else if ( res < 0 ) {
            item = item->left;
        } else {
            item = item->right;
        }
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeUnlock( btree );
    }

    return( item );
}
예제 #12
0
void BalancedBTreeAdd( BalancedBTree_t *btree, BalancedBTreeItem_t *item, 
                       Locked_t locked, bool rebalance )
{
    int         res;

    if( btree == NULL )
    {
        return;
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeLock( btree );
    }

    if( item == NULL ) {
        if( rebalance ) {
            BalancedBTreeRebalance( btree, btree->root );
        }

        if( locked == UNLOCKED ) {
            BalancedBTreeUnlock( btree );
        }
        return;
    }

    item->btree = btree;

    item->left  = NULL;
    item->right = NULL;

    item->parent = BalancedBTreeFindParent( btree, item );
    if( item->parent == NULL) {
        btree->root = item;
    } else {
        res = btree->keyCompare( item->key, item->parent->key );
        if( res > 0 ) {
            /* item greater than parent */
            item->parent->right = item;
        } else if( res < 0 ) {
            /* item less than parent */
            item->parent->left  = item;
        } else {
            switch( btree->keyType ) {
            case BTREE_KEY_INT:
                LogPrint( LOG_CRIT, "Duplicate key (INT): %d", 
                                    *(int *)item->key );
                btree->keyCompare = KeyCompareInt;
                break;
            case BTREE_KEY_STRING:
                LogPrint( LOG_CRIT, "Duplicate key (STRING): %s", 
                                    *(char **)item->key );
                btree->keyCompare = KeyCompareString;
                break;
            case BTREE_KEY_PTHREAD:
                LogPrint( LOG_CRIT, "Duplicate key (PTHREAD): %d", 
                                    *(int *)item->key );
                break;
            default:
                LogPrintNoArg( LOG_CRIT, "Duplicate key" );
                break;
            }
        }
    }

    if( rebalance ) {
        BalancedBTreeRebalance( btree, btree->root );
    }

    if( locked == UNLOCKED )
    {
        BalancedBTreeUnlock( btree );
    }
}
예제 #13
0
파일: bot.c 프로젝트: Beirdo/beirdobot
void serverKill( BalancedBTreeItem_t *node, IRCServer_t *server, bool unalloc )
{
    LinkedListItem_t       *listItem, *next;
    IRCChannel_t           *channel;
    BalancedBTreeItem_t    *item;

    if( server->enabled || server->enabledChanged ) {
        server->threadAbort = TRUE;
        thread_deregister( server->txThreadId );
        thread_deregister( server->threadId );
        server->threadAbort = FALSE;
    }

    if( unalloc ) {
        BalancedBTreeRemove( node->btree, node, LOCKED, FALSE );
    } else {
        server->enabled = FALSE;
    }

    if( server->txQueue ) {
        /* This *might* leak the contents of any queue entries? */
        QueueClear( server->txQueue, TRUE );
        QueueLock( server->txQueue );
        QueueDestroy( server->txQueue );
        server->txQueue = NULL;
    }

    if( server->channels ) {
        LinkedListLock( server->channels );
        BalancedBTreeLock( server->channelName );
        BalancedBTreeLock( server->channelNum );

        for( listItem = server->channels->head; listItem; listItem = next ) {
            next = listItem->next;
            channel = (IRCChannel_t *)listItem;

            regexpBotCmdRemove( server, channel );
            LinkedListRemove( server->channels, listItem, LOCKED );

            item = BalancedBTreeFind( server->channelName, 
                                      &channel->channel, LOCKED );
            if( item ) {
                BalancedBTreeRemove( server->channelName, item, LOCKED, 
                                     FALSE );
            }

            item = BalancedBTreeFind( server->channelNum, 
                                      &channel->channelId, LOCKED );
            if( item ) {
                BalancedBTreeRemove( server->channelNum, item, LOCKED, 
                                     FALSE );
            }

            ThreadAllNotifyChannel( channel );

            cursesMenuItemRemove( 2, MENU_CHANNELS, channel->menuText );
            free( channel->menuText );
            free( channel->channel );
            free( channel->fullspec );
            free( channel->url );
            free( channel );
        }

        LinkedListDestroy( server->channels );
        BalancedBTreeDestroy( server->channelName );
        BalancedBTreeDestroy( server->channelNum );
        server->channels = NULL;
        server->channelName = NULL;
        server->channelNum = NULL;
    }

    if( unalloc ) {
        free( server->server );
        free( server->password );
        free( server->nick );
        free( server->username );
        free( server->realname );
        free( server->nickserv );
        free( server->nickservmsg );
        free( server->ircInfo.Server );
    }

    LinkedListLock( server->floodList );
    for( listItem = server->floodList->head; listItem; listItem = next ) {
        next = listItem->next;

        LinkedListRemove( server->floodList, listItem, LOCKED );
        free( listItem );
    }
    LinkedListDestroy( server->floodList );
    server->floodList = NULL;

    ThreadAllNotifyServer( server );

    if( unalloc ) {
        cursesMenuItemRemove( 2, MENU_SERVERS, server->menuText );
        free( server->menuText );
        free( server->threadName );
        free( server->txThreadName );
        free( server );
        free( node );
    }
}
예제 #14
0
파일: bot.c 프로젝트: Beirdo/beirdobot
void botSighup( int signum, void *arg )
{
    IRCServer_t            *server;
    LinkedListItem_t       *listItem, *next;
    BalancedBTreeItem_t    *item;
    IRCChannel_t           *channel;
    bool                    newChannel = FALSE;

    server = (IRCServer_t *)arg;
    if( !server ) {
        return;
    }

    /*
     * Check each channel on the server, leave those no longer needed
     */
    if( server->channels ) {
        LinkedListLock( server->channels );
        BalancedBTreeLock( server->channelName );
        BalancedBTreeLock( server->channelNum );

        for( listItem = server->channels->head; listItem; listItem = next ) {
            next = listItem->next;
            channel = (IRCChannel_t *)listItem;

            if( !channel->visited ) {
                channelLeave( server, channel, channel->channel );
                regexpBotCmdRemove( server, channel );
                LinkedListRemove( server->channels, listItem, LOCKED );

                item = BalancedBTreeFind( server->channelName, 
                                          &channel->channel, LOCKED );
                if( item ) {
                    BalancedBTreeRemove( server->channelName, item, LOCKED,
                                         FALSE );
                }

                item = BalancedBTreeFind( server->channelNum,
                                          &channel->channelId, LOCKED );
                if( item ) {
                    BalancedBTreeRemove( server->channelNum, item, LOCKED,
                                         FALSE );
                }

                ThreadAllNotifyChannel( channel );

                cursesMenuItemRemove( 2, MENU_CHANNELS, channel->menuText );
                free( channel->menuText );
                free( channel->channel );
                free( channel->fullspec );
                free( channel->url );
                free( channel );
            } else if( channel->newChannel && channel->enabled && 
                       !channel->joined && !newChannel ) {
                newChannel = TRUE;
                transmitMsg( server, TX_JOIN, channel->channel, NULL );
            } else if( channel->newChannel && !channel->enabled ) {
                channel->newChannel = FALSE;
            }
        }
        BalancedBTreeUnlock( server->channelNum );
        BalancedBTreeUnlock( server->channelName );
        LinkedListUnlock( server->channels );
    }
}
예제 #15
0
void botCmdPlugin( IRCServer_t *server, IRCChannel_t *channel, char *who, 
                   char *msg, void *tag )
{
    int             len;
    char           *line;
    char           *command;
    char           *message;
    bool            ret;
    static char    *notauth = "You are not authorized, you can't do that!";

    if( !server || channel ) {
        return;
    }

    if( !authenticate_check( server, who ) ) {
        transmitMsg( server, TX_PRIVMSG, who, notauth );
        return;
    }

    line = strstr( msg, " " );
    if( line ) {
        /* Command has trailing text, skip the space */
        len = line - msg;
        line++;

        command = (char *)malloc( len + 2 );
        strncpy( command, msg, len );
        command[len] = '\0';
    } else {
        /* Command is the whole line */
        command = strdup( msg );
    }

    /* Strip trailing spaces */
    if( line ) {
        for( len = strlen(line); len && line[len-1] == ' ';
             len = strlen(line) ) {
            line[len-1] = '\0';
        }

        if( *line == '\0' ) {
            line = NULL;
        }
    }

    if( !strcmp( command, "list" ) ) {
        BalancedBTreeLock( pluginTree );
        if( line && !strcmp( line, "all" ) ) {
            message = botCmdDepthFirst( pluginTree->root, false );
        } else {
            message = botCmdDepthFirst( pluginTree->root, true );
        }
        BalancedBTreeUnlock( pluginTree );
    } else if( !strcmp( command, "load" ) && line ) {
        ret = pluginLoad( line );
        message = (char *)malloc(strlen(line) + 32);
        if( ret ) {
            sprintf( message, "Loaded module %s", line );
        } else {
            sprintf( message, "Module %s already loaded", line );
        }
    } else if( !strcmp( command, "unload" ) && line ) {
        ret = pluginUnload( line );
        message = (char *)malloc(strlen(line) + 32);
        if( ret ) {
            sprintf( message, "Unloaded module %s", line );
        } else {
            sprintf( message, "Module %s already unloaded", line );
        }
    } else {
        message = NULL;
        free( command );
        return;
    }

    transmitMsg( server, TX_MESSAGE, who, message );

    free( message );
    free( command );
}