Changeset c5bff81


Ignore:
Timestamp:
2010-07-09T23:24:23Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
b556e46
Parents:
debe871
Message:

More state consistency checks/error handling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ipc.c

    rdebe871 rc5bff81  
    3535static int ipc_child_recv_fd = -1;
    3636
     37static void ipc_master_takeover_fail( struct bitlbee_child *child, gboolean both );
     38static gboolean ipc_send_fd( int fd, int send_fd );
     39
    3740static void ipc_master_cmd_client( irc_t *data, char **cmd )
    3841{
     
    154157        {
    155158                /* Won't need the fd since we can't send it anywhere. */
    156                 close( child->to_fd );
     159                closesocket( child->to_fd );
    157160                child->to_fd = -1;
    158161                resp = "TAKEOVER NO\r\n";
     
    160163       
    161164        if( write( child->ipc_fd, resp, strlen( resp ) ) != strlen( resp ) )
    162         {
    163165                ipc_master_free_one( child );
    164                 child_list = g_slist_remove( child_list, child );
    165         }
    166 }
    167 
    168 static gboolean ipc_send_fd( int fd, int send_fd );
     166}
     167
    169168
    170169void ipc_master_cmd_takeover( irc_t *data, char **cmd )
     
    173172        char *fwd = NULL;
    174173       
    175         /* TODO: Check if child->to_child is still valid, etc. */
     174        if( child->to_child == NULL ||
     175            g_slist_find( child_list, child->to_child ) == NULL )
     176                return ipc_master_takeover_fail( child, FALSE );
     177       
    176178        if( strcmp( cmd[1], "AUTH" ) == 0 )
    177179        {
     180                /* New connection -> Master */
    178181                if( child->to_child &&
    179182                    child->nick && child->to_child->nick && cmd[2] &&
     
    188191                        fwd = irc_build_line( cmd );
    189192                        if( write( child->to_child->ipc_fd, fwd, strlen( fwd ) ) != strlen( fwd ) )
    190                         {
    191193                                ipc_master_free_one( child );
    192                                 child_list = g_slist_remove( child_list, child );
    193                         }
    194194                        g_free( fwd );
    195195                }
     196                else
     197                        return ipc_master_takeover_fail( child, TRUE );
    196198        }
    197199        else if( strcmp( cmd[1], "DONE" ) == 0 || strcmp( cmd[1], "FAIL" ) == 0 )
    198200        {
     201                /* Old connection -> Master */
    199202                int fd;
    200203               
    201204                /* The copy was successful (or not), we don't need it anymore. */
    202                 close( child->to_fd );
     205                closesocket( child->to_fd );
    203206                child->to_fd = -1;
    204207               
     
    209212                child->to_child = NULL;
    210213                if( write( fd, fwd, strlen( fwd ) ) != strlen( fwd ) )
    211                 {
    212214                        ipc_master_free_one( child );
    213                         child_list = g_slist_remove( child_list, child );
    214                 }
    215215                g_free( fwd );
    216216        }
     
    343343                        ipc_child_recv_fd = -1;
    344344                       
    345                         irc_write( irc, ":%s!%s@%s MODE %s :%s", irc->user->nick,
     345                        irc_write( irc, ":%s!%s@%s MODE %s :+%s", irc->user->nick,
    346346                                   irc->user->user, irc->user->host, irc->user->nick,
    347347                                   irc->umode );
     
    434434}
    435435
     436static void ipc_master_takeover_fail( struct bitlbee_child *child, gboolean both )
     437{
     438        if( child == NULL || g_slist_find( child_list, child ) == NULL )
     439                return;
     440       
     441        if( both && child->to_child != NULL )
     442                ipc_master_takeover_fail( child->to_child, FALSE );
     443       
     444        if( child->to_fd > -1 )
     445        {
     446                /* Send this error only to the new connection, which can be
     447                   recognised by to_fd being set. */
     448                if( write( child->ipc_fd, "TAKEOVER FAIL\r\n", 15 ) != 15 )
     449                {
     450                        ipc_master_free_one( child );
     451                        return;
     452                }
     453                close( child->to_fd );
     454                child->to_fd = -1;
     455        }
     456        child->to_child = NULL;
     457}
     458
    436459static void ipc_command_exec( void *data, char **cmd, const command_t *commands )
    437460{
     
    651674                        next = l->next;
    652675                        if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 )
    653                         {
    654676                                ipc_master_free_one( c );
    655                                 child_list = g_slist_remove( child_list, c );
    656                         }
    657677                }
    658678        }
     
    680700       
    681701        memset( &msg, 0, sizeof( msg ) );
    682         iov.iov_base = "0x90\r\n";
     702        iov.iov_base = "0x90\r\n";         /* Ja, noppes */
    683703        iov.iov_len = 6;
    684704        msg.msg_iov = &iov;
     
    699719void ipc_master_free_one( struct bitlbee_child *c )
    700720{
     721        GSList *l;
     722       
    701723        b_event_remove( c->ipc_inpa );
    702724        closesocket( c->ipc_fd );
     
    710732        g_free( c->password );
    711733        g_free( c );
     734       
     735        child_list = g_slist_remove( child_list, c );
     736       
     737        /* Also, if any child has a reference to this one, remove it. */
     738        for( l = child_list; l; l = l->next )
     739        {
     740                struct bitlbee_child *oc = l->data;
     741               
     742                if( oc->to_child == c )
     743                        ipc_master_takeover_fail( oc, FALSE );
     744        }
    712745}
    713746
     
    723756                {
    724757                        ipc_master_free_one( c );
    725                         child_list = g_slist_remove( child_list, c );
    726758                        break;
    727759                }
     
    731763void ipc_master_free_all()
    732764{
    733         GSList *l;
    734        
    735         for( l = child_list; l; l = l->next )
    736                 ipc_master_free_one( l->data );
    737        
    738         g_slist_free( child_list );
    739         child_list = NULL;
     765        while( child_list )
     766                ipc_master_free_one( child_list->data );
    740767}
    741768
Note: See TracChangeset for help on using the changeset viewer.