Exemple #1
0
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 );
}
Exemple #2
0
void MainDelayExit( void )
{
    int         i;

    LogPrintNoArg( LOG_CRIT, "Shutting down" );

    /* Signal to all that we are aborting */
    BotDone = FALSE;

    GlobalAbort = true;

    /* Send out signals from all queues waking up anything waiting on them so
     * the listeners can unblock and die
     */
    QueueKillAll();

    /* Delay to allow all the other tasks to finish (esp. logging!) */
    for( i = 2; i && !BotDone; i-- ) {
        sleep(1);
    }

    LogPrintNoArg(LOG_DEBUG, "Shutdown complete!" );
    LogFlushOutput();

    /* And finally... die */
    _exit( 0 );
}
Exemple #3
0
/**
 * @brief Thread to handle WebService requests
 * @return never returns until shutdown
 *
 * Receives requests over a web socket and acts on them.
 */
void *WebServiceThread( void *arg )
{
    char               *port;
    char               *logdir;
    char                buf[1024];
    char              **options;
    struct mg_context  *ctx;

    pthread_mutex_lock( startupMutex );

    port = pb_get_setting( "webServicePort" );
    if( !port || !atoi(port) ) {
        LogPrintNoArg( LOG_CRIT, "No WebService Port defined.  Aborting!" );
        return;
    }

    logdir = pb_get_setting( "webServiceLogDir" );
    if( !logdir ) {
        logdir = memstrlink( "/tmp" );
    }

    LogPrint( LOG_DEBUG, "Web Service listening on port %s", port );
    LogPrint( LOG_DEBUG, "Web Logs in %s", logdir );

    options = CREATEN(char *, 7);
    options[0] = memstrlink("ports");
    options[1] = memstrdup(port);
    options[2] = memstrlink("access_log");
    sprintf( buf, "%s/access.log", logdir );
    options[3] = memstrdup(buf);
    options[4] = memstrlink("error_log");
    sprintf( buf, "%s/error.log", logdir );
    options[5] = memstrdup(buf);
    options[6] = NULL;

    memfree( port );
    memfree( logdir );

    mg_set_allocs( &webServiceAllocs );

    /*
     * Initialize mongoose context.
     * Start listening on port specified.
     */
    ctx = mg_start(webServiceCallback, NULL, (const char **)options);

    while( !GlobalAbort ) {
        sleep(1);
    }
    
    mg_stop(ctx);

    LogPrintNoArg(LOG_INFO, "Ending WebServiceThread");
    return( NULL );
}
Exemple #4
0
void ProcOnWhois(BN_PInfo I, const char *Chans[])
{
    int             i;

    if( verbose ) {
        LogPrintNoArg( LOG_DEBUG, "Whois Infos:");
        for (i = 0; i < WHOIS_INFO_COUNT; i++) {
            LogPrint( LOG_DEBUG, "\t(%s)", Chans[i]);
        }
        LogPrintNoArg( LOG_DEBUG, "End of list");
    }
}
Exemple #5
0
BalancedBTree_t *BalancedBTreeCreate( BalancedBTreeKeyType_t type )
{
    BalancedBTree_t *btree;

    btree = (BalancedBTree_t *)malloc(sizeof(BalancedBTree_t));
    if( btree == NULL )
    {
        LogPrintNoArg( LOG_CRIT, "Couldn't create btree" );
        return( NULL );
    }

    btree->root = NULL;
    btree->keyType = type;
    switch( type ) {
    case BTREE_KEY_INT:
        btree->keyCompare = KeyCompareInt;
        break;
    case BTREE_KEY_STRING:
        btree->keyCompare = KeyCompareString;
        break;
    case BTREE_KEY_PTHREAD:
        btree->keyCompare = KeyComparePthread;
        break;
    default:
        btree->keyCompare = NULL;
        break;
    }

    pthread_mutex_init( &btree->mutex, NULL );

    return( btree );
}
Exemple #6
0
void ProcOnRegistered(BN_PInfo I)
{
    bool                found;
    LinkedListItem_t   *item;
    IRCServer_t        *server;
    IRCChannel_t       *channel;

    server = (IRCServer_t *)I->User;

    if( verbose ) {
        LogPrintNoArg( LOG_DEBUG, "Event Registered");
    }

    if( strcmp(server->nickserv, "") ) {
        /* We need to register with nickserv */
        transmitMsg( server, TX_PRIVMSG, server->nickserv, 
                     server->nickservmsg );
    }

    if( server->channels ) {
        LinkedListLock( server->channels );
        for( found = false, item = server->channels->head; 
             item && !found; item = item->next ) {
            channel = (IRCChannel_t *)item;
            if( channel->joined || !channel->enabled ) {
                continue;
            }

            transmitMsg( server, TX_JOIN, channel->channel, NULL );
            found = true;
        }
        LinkedListUnlock( server->channels );
    }
}
Exemple #7
0
bool LogSyslogAdd( int facility )
{
    openlog( "beirdobot", LOG_NDELAY | LOG_PID, facility );
    LogOutputAdd( -1, LT_SYSLOG, NULL );
    LogPrintNoArg( LOG_INFO, "Added syslog logging" );
    return( TRUE );
}
Exemple #8
0
void chain_save_pc( MYSQL_RES *res, QueryItem_t *item )
{
    int                 count;
    MYSQL_BIND         *data;
    MYSQL_BIND          temp[1];
    ProtectedData_t    *protect;
    int                *id;
    
    data = item->queryData;
    if( !res || !(count = mysql_num_rows(res)) ) {
        count = 0;
    }

    protect = (ProtectedData_t *)data[3].buffer;
    id  = (int *)protect->data;
    *id = *(int *)data[0].buffer;

    /* swap argument order */
    memcpy(  temp,     &data[0], sizeof(MYSQL_BIND) );
    memmove( &data[0], &data[1], sizeof(MYSQL_BIND) * 2 );
    memcpy(  &data[2], temp,     sizeof(MYSQL_BIND) );
    
    if( count ) {
        /* update */
        ProtectedDataUnlock( protect );
        LogPrint(LOG_DEBUG, "Updating id %d", *id);
        db_queue_query( 11, QueryTable, data, 3, NULL, NULL, NULL );
    } else {
        /* insert */
        *id = 0;
        LogPrintNoArg(LOG_DEBUG, "Inserting");
        db_queue_query( 12, QueryTable, data, 2, result_insert_id, protect, 
                        NULL );
    }
}
Exemple #9
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 );
}
Exemple #10
0
/**
 * @brief Thread to handle all protobuf accesses
 * @param arg unused
 * @return never returns until shutdown
 *
 * Receives protobuf requests via a queue, returns results via callbacks
 */
void *ProtobufThread( void *arg )
{
    ProtobufItem_t     *item;

    pthread_mutex_lock( startupMutex );

    /* Setup to use our own memory allocator */
    protobuf_c_default_allocator.alloc     = protobufMemalloc;
    protobuf_c_default_allocator.free      = protobufMemfree;
    protobuf_c_default_allocator.tmp_alloc = NULL;

    pthread_mutex_unlock( startupMutex );

    while( !GlobalAbort ) {
        item = (ProtobufItem_t *)QueueDequeueItem( ProtobufQ, -1 );
        if( !item ) {
            continue;
        }

        item->response = protobufHandle( item->request );
        if( item->callback ) {
            item->callback( item->response, item->callbackArg );
        }

        if( item->mutex ) {
            pthread_mutex_unlock( item->mutex );
        } else {
            protobufDestroyItem( item );
            protobufDestroyMessage( (ProtobufCMessage *)item->response );
        }
    }

    LogPrintNoArg( LOG_NOTICE, "Ending ProtobufThread" );
    return(NULL);
}
Exemple #11
0
void logging_toggle_debug( int signum, void *info, void *secret )
{
    if( !pthread_equal( pthread_self(), mainThreadId ) ) {
        return;
    }

    if( Debug ) {
        /* We are turning OFF debug logging */
        LogPrintNoArg( LOG_CRIT, "Received SIGUSR1, disabling debug logging" );
        LogFileRemove( DEBUG_FILE );
        Debug = false;
    } else {
        /* We are turning ON debug logging */
        LogPrintNoArg( LOG_CRIT, "Received SIGUSR1, enabling debug logging" );
        LogFileAdd( DEBUG_FILE );
        Debug = true;
    }
}
Exemple #12
0
bool LogNcursesAdd( void )
{
    if( Daemon ) {
        return( FALSE );
    }

    LogOutputAdd( -1, LT_NCURSES, NULL );
    LogPrintNoArg( LOG_INFO, "Added logging to ncurses" );

    return( TRUE );
}
Exemple #13
0
bool LogStdoutAdd( void )
{
    /* STDOUT corresponds to file descriptor 1 */
    if( Daemon ) {
        return( FALSE );
    }

    LogOutputAdd( 1, LT_CONSOLE, NULL );
    LogPrintNoArg( LOG_INFO, "Added console logging" );
    return( TRUE );
}
Exemple #14
0
void MainDelayExit( void )
{
    int         i;
    pthread_t   shutdownThreadId;

    LogPrintNoArg( LOG_CRIT, "Shutting down" );

    /* Signal to all that we are aborting */
    BotDone = FALSE;

    GlobalAbort = true;

    /* Unload all plugins (which should kill all associated threads) */
    pluginUnloadAll();

    /* Send out signals from all queues waking up anything waiting on them so
     * the listeners can unblock and die
     */
    QueueKillAll();

    /* Shut down IRC connections */
    thread_create( &shutdownThreadId, bot_shutdown, NULL, "thread_shutdown",
                   NULL );

    /* Delay to allow all the other tasks to finish (esp. logging!) */
    for( i = 15; i && !BotDone; i-- ) {
        sleep(1);
    }

    LogPrintNoArg(LOG_DEBUG, "Shutdown complete!" );
    LogFlushOutput();

    cursesAtExit();

    /* And finally... die */
    _exit( 0 );
}
Exemple #15
0
void *protobufMemalloc(void *allocator_data, size_t size)
{
    void       *buf;

    (void)allocator_data;

    if( size == 0 ) {
        return( NULL );
    }

    buf = CREATEN(char, size);
    if( !buf ) {
        LogPrintNoArg( LOG_CRIT, "Out of memory in protobufMemalloc" );
    }
    return( buf );
}
Exemple #16
0
void LogBanner( void )
{
    LogPrintNoArg( LOG_CRIT, "beirdobot  (c) 2010 Gavin Hurlbut" );
    LogPrint( LOG_CRIT, "%s", git_version() );

    cursesTextAdd( WINDOW_HEADER, ALIGN_LEFT, 1, 0, "beirdobot" );
    cursesTextAdd( WINDOW_HEADER, ALIGN_LEFT, 11, 0, (char *)git_version() );
    cursesTextAdd( WINDOW_HEADER, ALIGN_FROM_CENTER, 1, 0, 
                   "(c) 2010 Gavin Hurlbut" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_RIGHT, 1, 0, "Ctrl-C to exit" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_LEFT, 1, 0, 
                   "Use arrow keys for menus" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_CENTER, 0, 0, 
                   "PgUp/PgDn to scroll logs" );

    versionAdd( "beirdobot", (char *)git_version() );
}
Exemple #17
0
void LogBanner( void )
{
    LogPrintNoArg( LOG_CRIT, "havokmud  (c) 2010 Gavin Hurlbut" );
    LogPrint( LOG_CRIT, "%s", svn_version() );

#if 0
    cursesTextAdd( WINDOW_HEADER, ALIGN_LEFT, 1, 0, "havokmud" );
    cursesTextAdd( WINDOW_HEADER, ALIGN_LEFT, 10, 0, (char *)svn_version() );
    cursesTextAdd( WINDOW_HEADER, ALIGN_FROM_CENTER, 1, 0, 
                   "(c) 2009 Gavin Hurlbut" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_RIGHT, 1, 0, "Ctrl-C to exit" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_LEFT, 1, 0, 
                   "Use arrow keys for menus" );
    cursesTextAdd( WINDOW_TAILER, ALIGN_CENTER, 0, 0, 
                   "PgUp/PgDn to scroll logs" );
#endif

    versionAdd( "havokmud", (char *)svn_version() );
}
Exemple #18
0
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 );
}
Exemple #19
0
/**
 * @brief Prints the log messages to the console (and logfile)
 * @param arg unused
 * @return never returns until shutdown
 * @todo Add support for a logfile as well as console output.
 *
 * Dequeues log messages from the LoggingQ and outputs them to the console.
 * If the message's log level is lower (higher numerically) than the current
 * system log level, the message will be dumped and not displayed.
 * In the future, it will also log to a logfile.
 */
void *LoggingThread( void *arg )
{
    LoggingItem_t      *item;
    struct timespec     delay;

    /* 100ms delay */
    delay.tv_sec = 0;
    delay.tv_nsec = 100000L;

    LogPrintNoArg( LOG_NOTICE, "Started LoggingThread" );

    while( 1 ) {
        item = (LoggingItem_t *)QueueDequeueItem( LoggingQ, -1 );
        if( !item ) {
            nanosleep( &delay, NULL );
            continue;
        }

        LogItemOutput( (void *)item );
    }

    return( NULL );
}
Exemple #20
0
/**
 * @brief Handles all network connections
 * @param arg a pointer to a structure containing port number and timeout
 * @return never returns until shutdown
 *
 * @todo be sure this handles linkdead without removing all player structures
 *       so the player can log back in and be where they were
 *
 * Brings up a TCP listener on the MUD's assigned port and accepts connections.
 * Also reads all data from connected clients and hands the data off to the
 * Input thread.  When there is output to be sent, this thread handles writing
 * to the sockets after the first write has completed.  This thread also
 * handles the disconnection of clients gracefully.
 */
void *ConnectionThread( void *arg )
{
    connectThreadArgs_t    *argStruct;
    int                     portNum;
    char                   *port;
    struct sockaddr_in6     sa;
    int                     count;
    int                     fdCount;
    int                     newFd;
    socklen_t               salen;
    struct timeval          timeout;
    ConnectionItem_t       *item;
    PlayerStruct_t         *player;
    ConnInputItem_t        *connItem;
    ConnDnsItem_t          *dnsItem;
    uint32                  i;
    int                     on;
    int                     retval;
    char                    ch;

    argStruct = (connectThreadArgs_t *)arg;
    portNum = argStruct->port;

    pthread_mutex_lock( startupMutex );

    if( portNum == -1 ) {
        port = pb_get_setting( "listenPort" );
        if( !port ) {
            portNum = 4000;
        } else {
            portNum = atoi(port);
            memfree(port);
        }
    }

    /*
     * Start listening
     */
    listenFd = socket( AF_INET6, SOCK_STREAM, 0 );
    if( listenFd < 0 ) {
        perror("Opening listener socket");
        exit(1);
    }

    on = 1;
    if( setsockopt( listenFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) ) {
        perror("Setting socket to reuse");
        exit(1);
    }

    memset(&sa, 0, sizeof(sa));
    sa.sin6_family = AF_INET6;
    sa.sin6_port = htons(portNum);
    sa.sin6_addr = in6addr_any;

    if (bind(listenFd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        perror("Binding listener socket");
        close(listenFd);
        exit(1);
    }

    if (listen(listenFd, 10)) {
        perror("Listening to socket");
        close(listenFd);
        exit(1);
    }

    FD_ZERO(&saveReadFds);
    FD_ZERO(&saveWriteFds);
    FD_ZERO(&saveExceptFds);

    connAddFd(listenFd, &saveReadFds);

    ConnectionList = LinkedListCreate(NULL);

    LogPrint( LOG_NOTICE, "Listening on port %d", portNum );
    pthread_mutex_unlock( startupMutex );


    while( !GlobalAbort ) {
        /*
         * Select on connected and listener
         */
        readFds   = saveReadFds;
        writeFds  = saveWriteFds;
        exceptFds = saveExceptFds;
        timeout.tv_sec  = argStruct->timeout_sec;
        timeout.tv_usec = argStruct->timeout_usec;

        fdCount = select(maxFd+1, &readFds, &writeFds, &exceptFds, &timeout);


        if( GlobalAbort ) {
            continue;
        }

        recalcMaxFd = FALSE;

        /*
         * Open a connection for listener
         */
        if( FD_ISSET(listenFd, &readFds) ) {
            salen = sizeof(struct sockaddr_in6);
            newFd = accept(listenFd, (struct sockaddr *)&sa, &salen);

            connAddFd(newFd, &saveReadFds);
            connAddFd(newFd, &saveExceptFds);

            item = CREATE(ConnectionItem_t);
            if( !item ) {
                /*
                 * No memory!
                 */
                LogPrintNoArg( LOG_EMERG, "Out of memory!" );
                close(newFd);
            } else {
                item->fd = newFd;
                item->buffer = BufferCreate(MAX_BUFSIZE);

                item->hostName = ProtectedDataCreate();
                ProtectedDataLock( item->hostName );
                item->hostName->data = CREATEN(char, 50);
                inet_ntop(AF_INET6, &sa.sin6_addr, item->hostName->data, 50);
                if( !strncmp(item->hostName->data, "::ffff:", 7) ) {
                    bcopy((char *)item->hostName->data + 7,
                          item->hostName->data, 43);
                }
                ProtectedDataUnlock( item->hostName );

                if (!IS_SET(SystemFlags, SYS_SKIPDNS)) {
                    dnsItem = CREATE(ConnDnsItem_t);
                    if( dnsItem ) {
                        dnsItem->connection = item;
                        memcpy(dnsItem->ipAddr, &sa.sin6_addr, 16);
                        QueueEnqueueItem(ConnectDnsQ, dnsItem);
                    }
                }

                player = CREATE(PlayerStruct_t);
                if( !player ) {
                    /*
                     * No memory!
                     */
                    LogPrintNoArg( LOG_EMERG, "Out of memory!" );
                    BufferDestroy(item->buffer);
                    close(newFd);
                    memfree(item);
                } else {
                    item->player = player;
                    player->connection = item;
                    player->in_buffer = item->buffer;

                    LinkedListAdd( ConnectionList, (LinkedListItem_t *)item,
                                   UNLOCKED, AT_TAIL );
                    /*
                     * Pass the info on to the other threads...
                     */
#ifdef DEBUG_CONNECT
                    LogPrint( LOG_INFO, "New connection: %p", player );
#endif
                    connItem = CREATE(ConnInputItem_t);
                    if( connItem ) {
                        connItem->type = CONN_NEW_CONNECT;
                        connItem->player = player;

                        QueueEnqueueItem(ConnectInputQ, (QueueItem_t)connItem);
                    }
                }
            }

            fdCount--;
        }

        if( fdCount ) {
            LinkedListLock( ConnectionList );

            for( item = (ConnectionItem_t *)(ConnectionList->head);
                    item && fdCount;
                    item = (item ? (ConnectionItem_t *)item->link.next
                            : (ConnectionItem_t *)ConnectionList->head) ) {
                if( FD_ISSET( item->fd, &exceptFds ) ) {
                    /*
                     * This connection's borked, close it, remove it, move on
                     */
                    if( FD_ISSET( item->fd, &readFds ) ) {
                        fdCount--;
                    }

                    if( FD_ISSET( item->fd, &writeFds ) ) {
                        fdCount--;
                    }

                    BufferLock( item->buffer );
                    item = connRemove(item);
                    fdCount--;
                    continue;
                }

                if( item && FD_ISSET( item->fd, &readFds ) ) {
                    /*
                     * This connection has data ready
                     */
                    count = BufferAvailWrite( item->buffer, TRUE );
                    if( !count ) {
                        /*
                         * No buffer space, the buffer's unlocked, move on
                         */
                        LogPrint( LOG_INFO, "No buffer space: %p", item );
                        continue;
                    }

                    /*
                     * The buffer's locked
                     */
                    count = read( item->fd, BufferGetWrite( item->buffer ),
                                  count );
                    if( !count ) {
                        LogPrint( LOG_DEBUG, "EOF on %d", item->fd );
                        /*
                         * We hit EOF, close and remove
                         */
                        if( FD_ISSET( item->fd, &writeFds ) ) {
                            fdCount--;
                        }

                        item = connRemove(item);
                        fdCount--;
                        continue;
                    }

                    BufferWroteBytes( item->buffer, count );
                    BufferUnlock( item->buffer );

                    /*
                     * Tell the input thread
                     */
                    connItem = CREATE(ConnInputItem_t);
                    if( connItem ) {
#ifdef DEBUG_INPUT
                        LogPrint( LOG_INFO, "New data: %p", item->player );
#endif
                        connItem->type = CONN_INPUT_AVAIL;
                        connItem->player = item->player;

                        QueueEnqueueItem(ConnectInputQ, (QueueItem_t)connItem);
                    }
                }

                if( item && FD_ISSET( item->fd, &writeFds ) ) {
                    /*
                     * We have space to output, so write if we have anything
                     * to write
                     */
#ifdef DEBUG_OUTPUT
                    LogPrint( LOG_INFO, "Output sent to: %p", item );
#endif
                    if( item->outBufDesc ) {
                        /* TODO: deal with partial block writes */
                        retval = write( item->fd, item->outBufDesc->buf,
                                        item->outBufDesc->len );
                        memfree( item->outBufDesc->buf );
                        memfree( item->outBufDesc );
                        item->outBufDesc = NULL;
                    }
                    /*
                     * Kick the next output
                     */
                    connKickOutput( item );
                    fdCount--;
                }
            }
            LinkedListUnlock( ConnectionList );
        }

        if( recalcMaxFd ) {
            LinkedListLock( ConnectionList );
            maxFd = listenFd;

            for( item = (ConnectionItem_t *)(ConnectionList->head); item;
                    item = (ConnectionItem_t *)item->link.next ) {
                if( item->fd > maxFd ) {
                    maxFd = item->fd;
                }
            }
            LinkedListUnlock( ConnectionList );
        }
    }
Exemple #21
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 );
    }
}
Exemple #22
0
QueueObject_t * QueueCreate( uint32 numElements )
{
    QueueObject_t *queue;
    QueueItem_t *items;
    int status;
    uint32 i;

    if( numElements == 0 )
    {
        return( NULL );
    }

    /* Round the numElements to a power of 2 for efficiency */
    for( i = 0; i < 32 && (uint64)numElements > (uint64)(1<<i); i++ );

    if( i == 32 )
    {
        LogPrint( LOG_CRIT, "Queue too large.  Rounded from %d to %d",
                  numElements, 1 << 31 );
        i = 31;
    }
    else
    {
        if( numElements != (1<<i) )
        {
            LogPrint( LOG_CRIT, "Queue item count rounded from %d to %d",
                      numElements, (1 << i) );
        }
    }
    numElements = 1 << i;

    queue = (QueueObject_t *)malloc(sizeof(QueueObject_t));
    items = (QueueItem_t *)malloc(numElements * sizeof(QueueItem_t));

    queue->numElements = numElements;
    queue->numMask     = numElements - 1;
    queue->head = 0;
    queue->tail = 0;

    for( i = 0; i < numElements; i++ )
    {
        items[i] = NULL;
    }
    queue->itemTable = items;

    /* Initialize the mutex */
    queue->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
    status = pthread_mutex_init( queue->mutex, NULL );

    /* Initialize the condition variables */
    queue->full = FALSE;
    queue->cNotFull = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
    status = pthread_cond_init( queue->cNotFull, NULL );

    queue->empty = TRUE;
    queue->cNotEmpty = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
    status = pthread_cond_init( queue->cNotEmpty, NULL );

    if( !QueueList ) {
        QueueList = LinkedListCreate();
        if( !QueueList ) {
            LogPrintNoArg( LOG_CRIT, "Couldn't create the list of queues!" );
            exit(1);
        }
    }

    /* Allows us to flush all queues at shutdown */
    LinkedListAdd( QueueList, (LinkedListItem_t *)queue, UNLOCKED, AT_TAIL );

    return( queue );
}
Exemple #23
0
HavokResponse *protobufHandle( HavokRequest *req )
{
    int                 retval;
    PlayerAccount_t    *acct;
    HavokResponse      *resp;

    if( !req ) {
        return( NULL );
    }

    if( req->protocol_version != PROTOBUF_API_VERSION ) {
        LogPrint( LOG_DEBUG, "Bad protobuf API version: %d, expected %d",
                             req->protocol_version, PROTOBUF_API_VERSION );
        return( NULL );
    }

    switch( req->request_type ) {
        case REQ_TYPE__GET_SETTING:
            if( !req->settings_data ) {
                LogPrintNoArg( LOG_DEBUG, "No settings data on GET_SETTING" );
                return( NULL );
            }

            return( db_get_setting( req ) );
            break;
        case REQ_TYPE__SET_SETTING:
            if( !req->settings_data ) {
                LogPrintNoArg( LOG_DEBUG, "No settings data on SET_SETTING" );
                return( NULL );
            }
            return( db_set_setting( req ) );
            break;
        case REQ_TYPE__LOAD_ACCOUNT:
            if( !req->account_data ) {
                LogPrintNoArg( LOG_DEBUG, "No account data on LOAD_ACCOUNT" );
                return( NULL );
            }

            return( db_load_account( req ) );
            break;
        case REQ_TYPE__LOAD_ACCOUNT_BY_CONFIRM:
            if( !req->account_data ) {
                LogPrintNoArg( LOG_DEBUG, "No account data on "
                                          "LOAD_ACCOUNT_BY_CONFIRM" );
                return( NULL );
            }

            return( db_load_account_by_confirm( req ) );
            break;
        case REQ_TYPE__SAVE_ACCOUNT:
            if( !req->account_data ) {
                LogPrintNoArg( LOG_DEBUG, "No account data on SAVE_ACCOUNT" );
                return( NULL );
            }
            return( db_save_account( req ) );
            break;
        case REQ_TYPE__GET_PC_LIST:
            if( !req->account_data ) {
                LogPrintNoArg( LOG_DEBUG, "No account data on GET_PC_LIST" );
                return( NULL );
            }
            return( db_get_pc_list( req ) );
            break;
        case REQ_TYPE__LOAD_PC:
            if( !req->pc_data ) {
                LogPrintNoArg( LOG_DEBUG, "No PC data on LOAD_PC" );
                return( NULL );
            }
            return( db_load_pc( req ) );
            break;
        case REQ_TYPE__SAVE_PC:
            if( !req->pc_data ) {
                LogPrintNoArg( LOG_DEBUG, "No PC data on SAVE_PC" );
                return( NULL );
            }
            return( db_save_pc( req ) );
            break;
        case REQ_TYPE__FIND_PC:
            if( !req->pc_data ) {
                LogPrintNoArg( LOG_DEBUG, "No PC data on FIND_PC" );
                return( NULL );
            }
            return( db_find_pc( req ) );
            break;
        default:
            /* Not handled yet */
            return( NULL );
    }

    /* Should never get here, but just in case! */
    return( NULL );
}
Exemple #24
0
void LogBanner( void )
{
    LogPrintNoArg( LOG_CRIT, "importdb from beirdobot  "
                             "(c) 2010 Gavin Hurlbut" );
    LogPrint( LOG_CRIT, "%s", git_version() );
}