Changes in / [87de505:57c4fc0]


Ignore:
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r87de505 r57c4fc0  
    111111#endif
    112112       
     113        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     114                ipc_master_load_state();
     115       
    113116        return( 0 );
    114117}
     
    235238        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    236239        pid_t client_pid = 0;
     240       
     241        if( new_socket == -1 )
     242        {
     243                log_message( LOGLVL_WARNING, "Could not accept new connection: %s", strerror( errno ) );
     244                return TRUE;
     245        }
    237246       
    238247        if( global.conf->runmode == RUNMODE_FORKDAEMON )
  • bitlbee.h

    r87de505 r57c4fc0  
    121121        char *helpfile;
    122122        GMainLoop *loop;
     123        int restart;
    123124} global_t;
    124125
  • conf.c

    r87de505 r57c4fc0  
    3232#include "ini.h"
    3333#include "url.h"
     34#include "ipc.h"
    3435
    3536#include "protocols/proxy.h"
     
    7778        }
    7879       
    79         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:nvIDFc:d:h" ) ) >= 0 )
     80        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:nvIDFc:d:hR:" ) ) >= 0 )
    8081        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8182        {
     
    141142                                "  -h  Show this help page.\n" );
    142143                        return( NULL );
     144                }
     145                else if( opt == 'R' )
     146                {
     147                        /* We can't load the statefile yet (and should make very sure we do this
     148                           only once), so set the filename here and load the state information
     149                           when initializing ForkDaemon. (This option only makes sense in that
     150                           mode anyway!) */
     151                        ipc_master_set_statefile( optarg );
    143152                }
    144153        }
  • ipc.c

    r87de505 r57c4fc0  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    3030
    3131GSList *child_list = NULL;
    32 
     32static char *statefile = NULL;
    3333
    3434static void ipc_master_cmd_client( irc_t *data, char **cmd )
     
    3636        struct bitlbee_child *child = (void*) data;
    3737       
    38         if( child )
     38        if( child && cmd[1] )
    3939        {
    4040                child->host = g_strdup( cmd[1] );
     
    4343        }
    4444       
    45         ipc_to_children_str( "OPERMSG :Client connecting (PID=%d): %s@%s (%s)\r\n",
    46                              child ? child->pid : -1, cmd[2], cmd[1], cmd[3] );
     45        if( g_strcasecmp( cmd[0], "CLIENT" ) == 0 )
     46                ipc_to_children_str( "OPERMSG :Client connecting (PID=%d): %s@%s (%s)\r\n",
     47                                     child ? child->pid : -1, cmd[2], cmd[1], cmd[3] );
    4748}
    4849
     
    7475}
    7576
     77void ipc_master_cmd_restart( irc_t *data, char **cmd )
     78{
     79        struct bitlbee_child *child = (void*) data;
     80       
     81        if( global.conf->runmode != RUNMODE_FORKDAEMON )
     82        {
     83                /* Tell child that this is unsupported. */
     84                return;
     85        }
     86       
     87        global.restart = -1;
     88        bitlbee_shutdown( NULL );
     89}
     90
    7691static const command_t ipc_master_commands[] = {
    7792        { "client",     3, ipc_master_cmd_client,     0 },
     93        { "hello",      0, ipc_master_cmd_client,     0 },
    7894        { "die",        0, ipc_master_cmd_die,        0 },
    7995        { "wallops",    1, NULL,                      IPC_CMD_TO_CHILDREN },
     
    8298        { "rehash",     0, ipc_master_cmd_rehash,     0 },
    8399        { "kill",       2, NULL,                      IPC_CMD_TO_CHILDREN },
     100        { "restart",    0, ipc_master_cmd_restart,    0 },
    84101        { NULL }
    85102};
     
    140157        irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->mynick, irc->mynick, irc->myhost, irc->nick, cmd[2] );
    141158        irc_abort( irc, 0, "Killed by operator: %s", cmd[2] );
     159}
     160
     161static void ipc_child_cmd_hello( irc_t *irc, char **cmd )
     162{
     163        if( irc->status < USTATUS_LOGGED_IN )
     164                ipc_to_master_str( "HELLO\r\n" );
     165        else
     166                ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->host, irc->nick, irc->realname );
    142167}
    143168
     
    149174        { "rehash",     0, ipc_child_cmd_rehash,      0 },
    150175        { "kill",       2, ipc_child_cmd_kill,        0 },
     176        { "hello",      0, ipc_child_cmd_hello,       0 },
    151177        { NULL }
    152178};
     
    385411        child_list = NULL;
    386412}
     413
     414char *ipc_master_save_state()
     415{
     416        char *fn = g_strdup( "/tmp/bee-restart.XXXXXX" );
     417        int fd = mkstemp( fn );
     418        GSList *l;
     419        FILE *fp;
     420        int i;
     421       
     422        if( fd == -1 )
     423        {
     424                log_message( LOGLVL_ERROR, "Could not create temporary file: %s", strerror( errno ) );
     425                g_free( fn );
     426                return NULL;
     427        }
     428       
     429        /* This is more convenient now. */
     430        fp = fdopen( fd, "w" );
     431       
     432        for( l = child_list, i = 0; l; l = l->next )
     433                i ++;
     434       
     435        /* Number of client processes. */
     436        fprintf( fp, "%d\n", i );
     437       
     438        for( l = child_list; l; l = l->next )
     439                fprintf( fp, "%d %d\n", ((struct bitlbee_child*)l->data)->pid,
     440                                        ((struct bitlbee_child*)l->data)->ipc_fd );
     441       
     442        if( fclose( fp ) == 0 )
     443        {
     444                return fn;
     445        }
     446        else
     447        {
     448                unlink( fn );
     449                g_free( fn );
     450                return NULL;
     451        }
     452}
     453
     454void ipc_master_set_statefile( char *fn )
     455{
     456        statefile = g_strdup( fn );
     457}
     458
     459int ipc_master_load_state()
     460{
     461        struct bitlbee_child *child;
     462        FILE *fp;
     463        int i, n;
     464       
     465        if( statefile == NULL )
     466                return 0;
     467        fp = fopen( statefile, "r" );
     468        unlink( statefile );    /* Why do it later? :-) */
     469        if( fp == NULL )
     470                return 0;
     471       
     472        if( fscanf( fp, "%d", &n ) != 1 )
     473        {
     474                log_message( LOGLVL_WARNING, "Could not import state information for child processes." );
     475                fclose( fp );
     476                return 0;
     477        }
     478       
     479        log_message( LOGLVL_INFO, "Importing information for %d child processes.", n );
     480        for( i = 0; i < n; i ++ )
     481        {
     482                child = g_new0( struct bitlbee_child, 1 );
     483               
     484                if( fscanf( fp, "%d %d", &child->pid, &child->ipc_fd ) != 2 )
     485                {
     486                        log_message( LOGLVL_WARNING, "Unexpected end of file: Only processed %d clients.", i );
     487                        g_free( child );
     488                        fclose( fp );
     489                        return 0;
     490                }
     491                child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );
     492               
     493                child_list = g_slist_append( child_list, child );
     494        }
     495       
     496        ipc_to_children_str( "HELLO\r\n" );
     497        ipc_to_children_str( "OPERMSG :New BitlBee master process started (version " BITLBEE_VERSION ")\r\n" );
     498       
     499        return 1;
     500}
  • ipc.h

    r87de505 r57c4fc0  
    5454void ipc_master_cmd_rehash( irc_t *data, char **cmd );
    5555
     56char *ipc_master_save_state();
     57void ipc_master_set_statefile( char *fn );
     58int ipc_master_load_state();
     59
    5660
    5761extern GSList *child_list;
  • irc_commands.c

    r87de505 r57c4fc0  
    573573        { "lilo",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    574574        { "rehash",      0, irc_cmd_rehash,      IRC_CMD_OPER_ONLY },
     575        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    575576        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    576577        { NULL }
  • unix.c

    r87de505 r57c4fc0  
    2929#include "protocols/nogaim.h"
    3030#include "help.h"
     31#include "ipc.h"
    3132#include <signal.h>
    3233#include <unistd.h>
     
    3839static void sighandler( int signal );
    3940
    40 int main( int argc, char *argv[] )
     41int main( int argc, char *argv[], char **envp )
    4142{
    4243        int i = 0;
     44        char *old_cwd;
    4345        struct sigaction sig, old;
    4446       
     
    7375        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    7476        {
     77                /* In case the operator requests a restart, we need this. */
     78                old_cwd = g_malloc( 256 );
     79                if( getcwd( old_cwd, 255 ) == NULL )
     80                {
     81                        log_message( LOGLVL_WARNING, "Could not save current directory: %s", strerror( errno ) );
     82                        g_free( old_cwd );
     83                        old_cwd = NULL;
     84                }
     85               
    7586                i = bitlbee_daemon_init();
    7687                log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION );
     
    108119        g_main_run( global.loop );
    109120       
     121        if( global.restart )
     122        {
     123                char *fn = ipc_master_save_state();
     124                char **args;
     125                int n, i;
     126               
     127                chdir( old_cwd );
     128               
     129                n = 0;
     130                args = g_new0( char *, argc + 3 );
     131                args[n++] = argv[0];
     132                if( fn )
     133                {
     134                        args[n++] = "-R";
     135                        args[n++] = fn;
     136                }
     137                for( i = 1; argv[i] && i < argc; i ++ )
     138                {
     139                        if( strcmp( argv[i], "-R" ) == 0 )
     140                                i += 2;
     141                       
     142                        args[n++] = argv[i];
     143                }
     144               
     145                close( global.listen_socket );
     146               
     147                execve( args[0], args, envp );
     148        }
     149       
    110150        return( 0 );
    111151}
Note: See TracChangeset for help on using the changeset viewer.