Changes in / [9fae35c:ec3e411]


Ignore:
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r9fae35c rec3e411  
    4545        int i;
    4646        GIOChannel *ch;
     47        FILE *fp;
    4748       
    4849        log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
     
    104105                else if( i != 0 )
    105106                        exit( 0 );
    106                 close( 0 );
    107                 close( 1 );
    108                 close( 2 );
     107               
    109108                chdir( "/" );
     109               
     110                /* Sometimes std* are already closed (for example when we're in a RESTARTed
     111                   BitlBee process. So let's only close TTY-fds. */
     112                if( isatty( 0 ) ) close( 0 );
     113                if( isatty( 0 ) ) close( 1 );
     114                if( isatty( 0 ) ) close( 2 );
    110115        }
    111116#endif
     117       
     118        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     119                ipc_master_load_state();
     120       
     121        if( ( fp = fopen( global.conf->pidfile, "w" ) ) )
     122        {
     123                fprintf( fp, "%d\n", (int) getpid() );
     124                fclose( fp );
     125        }
     126        else
     127        {
     128                log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile );
     129        }
    112130       
    113131        return( 0 );
     
    235253        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    236254        pid_t client_pid = 0;
     255       
     256        if( new_socket == -1 )
     257        {
     258                log_message( LOGLVL_WARNING, "Could not accept new connection: %s", strerror( errno ) );
     259                return TRUE;
     260        }
    237261       
    238262        if( global.conf->runmode == RUNMODE_FORKDAEMON )
  • bitlbee.h

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

    r9fae35c rec3e411  
    3232#include "ini.h"
    3333#include "url.h"
     34#include "ipc.h"
    3435
    3536#include "protocols/proxy.h"
     
    6162        conf->configdir = g_strdup( CONFIG );
    6263        conf->plugindir = g_strdup( PLUGINDIR );
     64        conf->pidfile = g_strdup( "/var/run/bitlbee.pid" );
    6365        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
    6466        conf->ping_interval = 180;
     
    7779        }
    7880       
    79         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:nvIDFc:d:h" ) ) >= 0 )
     81        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 )
    8082        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8183        {
     
    9294                        }
    9395                        conf->port = i;
     96                }
     97                else if( opt == 'p' )
     98                {
     99                        g_free( conf->pidfile );
     100                        conf->pidfile = g_strdup( optarg );
    94101                }
    95102                else if( opt == 'n' )
     
    142149                        return( NULL );
    143150                }
     151                else if( opt == 'R' )
     152                {
     153                        /* We can't load the statefile yet (and should make very sure we do this
     154                           only once), so set the filename here and load the state information
     155                           when initializing ForkDaemon. (This option only makes sense in that
     156                           mode anyway!) */
     157                        ipc_master_set_statefile( optarg );
     158                }
    144159        }
    145160       
     
    175190                                else
    176191                                        conf->runmode = RUNMODE_INETD;
     192                        }
     193                        else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
     194                        {
     195                                g_free( conf->pidfile );
     196                                conf->pidfile = g_strdup( ini->value );
    177197                        }
    178198                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
  • conf.h

    r9fae35c rec3e411  
    4343        char *configdir;
    4444        char *plugindir;
     45        char *pidfile;
    4546        char *motdfile;
    4647        char *primary_storage;
  • configure

    r9fae35c rec3e411  
    1414datadir='$prefix/share/bitlbee/'
    1515config='/var/lib/bitlbee/'
     16pidfile='/var/run/bitlbee.pid'
    1617plugindir='$prefix/lib/bitlbee'
    1718
     
    4647--datadir=...                                           $datadir
    4748--plugindir=...                                         $plugindir
     49--pidfile=...                                           $pidfile
    4850--config=...                                            $config
    4951
     
    7476config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'`
    7577plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'`
     78pidfile=`eval echo "$pidfile/" | sed 's/\/\{1,\}/\//g'`
    7679
    7780cat<<EOF>Makefile.settings
     
    8386DATADIR=$datadir
    8487PLUGINDIR=$plugindir
     88PIDFILE=$pidfile
    8589CONFIG=$config
    8690
     
    104108#define VARDIR "$datadir"
    105109#define PLUGINDIR "$plugindir"
     110#define PIDFILE "$pidfile"
    106111#define ARCH "$arch"
    107112#define CPU "$cpu"
  • ipc.c

    r9fae35c rec3e411  
    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

    r9fae35c rec3e411  
    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

    r9fae35c rec3e411  
    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 }
  • protocols/msn/msn.c

    r9fae35c rec3e411  
    8484                {
    8585                        m = l->data;
     86               
     87                        serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message to %s, you'll have to resend it.", m->who );
    8688                        g_free( m->who );
    8789                        g_free( m->text );
     
    8991                }
    9092                g_slist_free( md->msgq );
    91                
    92                 serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message(s), you'll have to resend them." );
    9393        }
    9494       
  • protocols/msn/sb.c

    r9fae35c rec3e411  
    213213                {
    214214                        m = l->data;
     215
    215216                        g_free( m->who );
    216217                        g_free( m->text );
     
    219220                g_slist_free( sb->msgq );
    220221               
    221                 serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with unsent message(s), you'll have to resend them." );
     222                serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with "
     223                                   "unsent message to %s, you'll have to resend it.",
     224                                   m->who ? m->who : "(unknown)" );
    222225        }
    223226       
  • root_commands.c

    r9fae35c rec3e411  
    601601        {
    602602                set_setstr( irc, cmd[1], cmd[2] );
     603               
     604                if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] )
     605                        irc_usermsg( irc, "Warning: Correct syntax: \002set <variable> <value>\002 (without =)" );
    603606        }
    604607        if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */
  • unix.c

    r9fae35c rec3e411  
    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.