Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • ipc.c

    r8a56e52 r87de505  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2006 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2828#include "ipc.h"
    2929#include "commands.h"
    30 #ifndef _WIN32
    31 #include <sys/un.h>
    32 #endif
    3330
    3431GSList *child_list = NULL;
    35 static char *statefile = NULL;
     32
    3633
    3734static void ipc_master_cmd_client( irc_t *data, char **cmd )
     
    3936        struct bitlbee_child *child = (void*) data;
    4037       
    41         if( child && cmd[1] )
     38        if( child )
    4239        {
    4340                child->host = g_strdup( cmd[1] );
     
    4643        }
    4744       
    48         if( g_strcasecmp( cmd[0], "CLIENT" ) == 0 )
    49                 ipc_to_children_str( "OPERMSG :Client connecting (PID=%d): %s@%s (%s)\r\n",
    50                                      child ? child->pid : -1, cmd[2], cmd[1], cmd[3] );
     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] );
    5147}
    5248
     
    7874}
    7975
    80 void ipc_master_cmd_restart( irc_t *data, char **cmd )
    81 {
    82         struct bitlbee_child *child = (void*) data;
    83        
    84         if( global.conf->runmode != RUNMODE_FORKDAEMON )
    85         {
    86                 /* Tell child that this is unsupported. */
    87                 return;
    88         }
    89        
    90         global.restart = -1;
    91         bitlbee_shutdown( NULL );
    92 }
    93 
    9476static const command_t ipc_master_commands[] = {
    9577        { "client",     3, ipc_master_cmd_client,     0 },
    96         { "hello",      0, ipc_master_cmd_client,     0 },
    9778        { "die",        0, ipc_master_cmd_die,        0 },
    9879        { "wallops",    1, NULL,                      IPC_CMD_TO_CHILDREN },
     
    10182        { "rehash",     0, ipc_master_cmd_rehash,     0 },
    10283        { "kill",       2, NULL,                      IPC_CMD_TO_CHILDREN },
    103         { "restart",    0, ipc_master_cmd_restart,    0 },
    10484        { NULL }
    10585};
     
    160140        irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->mynick, irc->mynick, irc->myhost, irc->nick, cmd[2] );
    161141        irc_abort( irc, 0, "Killed by operator: %s", cmd[2] );
    162 }
    163 
    164 static void ipc_child_cmd_hello( irc_t *irc, char **cmd )
    165 {
    166         if( irc->status < USTATUS_LOGGED_IN )
    167                 ipc_to_master_str( "HELLO\r\n" );
    168         else
    169                 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->host, irc->nick, irc->realname );
    170142}
    171143
     
    177149        { "rehash",     0, ipc_child_cmd_rehash,      0 },
    178150        { "kill",       2, ipc_child_cmd_kill,        0 },
    179         { "hello",      0, ipc_child_cmd_hello,       0 },
    180151        { NULL }
    181152};
     
    414385        child_list = NULL;
    415386}
    416 
    417 char *ipc_master_save_state()
    418 {
    419         char *fn = g_strdup( "/tmp/bee-restart.XXXXXX" );
    420         int fd = mkstemp( fn );
    421         GSList *l;
    422         FILE *fp;
    423         int i;
    424        
    425         if( fd == -1 )
    426         {
    427                 log_message( LOGLVL_ERROR, "Could not create temporary file: %s", strerror( errno ) );
    428                 g_free( fn );
    429                 return NULL;
    430         }
    431        
    432         /* This is more convenient now. */
    433         fp = fdopen( fd, "w" );
    434        
    435         for( l = child_list, i = 0; l; l = l->next )
    436                 i ++;
    437        
    438         /* Number of client processes. */
    439         fprintf( fp, "%d\n", i );
    440        
    441         for( l = child_list; l; l = l->next )
    442                 fprintf( fp, "%d %d\n", ((struct bitlbee_child*)l->data)->pid,
    443                                         ((struct bitlbee_child*)l->data)->ipc_fd );
    444        
    445         if( fclose( fp ) == 0 )
    446         {
    447                 return fn;
    448         }
    449         else
    450         {
    451                 unlink( fn );
    452                 g_free( fn );
    453                 return NULL;
    454         }
    455 }
    456 
    457 void ipc_master_set_statefile( char *fn )
    458 {
    459         statefile = g_strdup( fn );
    460 }
    461 
    462 
    463 static gboolean new_ipc_client (GIOChannel *gio, GIOCondition cond, gpointer data)
    464 {
    465         struct bitlbee_child *child = g_new0( struct bitlbee_child, 1 );
    466         int serversock;
    467 
    468         serversock = g_io_channel_unix_get_fd(gio);
    469 
    470         child->ipc_fd = accept(serversock, NULL, 0);
    471 
    472         if (child->ipc_fd == -1) {
    473                 log_message( LOGLVL_WARNING, "Unable to accept connection on UNIX domain socket: %s", strerror(errno) );
    474                 return TRUE;
    475         }
    476                
    477         child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );
    478                
    479         child_list = g_slist_append( child_list, child );
    480 
    481         return TRUE;
    482 }
    483 
    484 #ifndef _WIN32
    485 int ipc_master_listen_socket()
    486 {
    487         struct sockaddr_un un_addr;
    488         int serversock;
    489         GIOChannel *gio;
    490 
    491         /* Clean up old socket files that were hanging around.. */
    492         if (unlink(IPCSOCKET) == -1 && errno != ENOENT) {
    493                 log_message( LOGLVL_ERROR, "Could not remove old IPC socket at %s: %s", IPCSOCKET, strerror(errno) );
    494                 return 0;
    495         }
    496 
    497         un_addr.sun_family = AF_UNIX;
    498         strcpy(un_addr.sun_path, IPCSOCKET);
    499 
    500         serversock = socket(AF_UNIX, SOCK_STREAM, PF_UNIX);
    501 
    502         if (serversock == -1) {
    503                 log_message( LOGLVL_WARNING, "Unable to create UNIX socket: %s", strerror(errno) );
    504                 return 0;
    505         }
    506 
    507         if (bind(serversock, &un_addr, sizeof(un_addr)) == -1) {
    508                 log_message( LOGLVL_WARNING, "Unable to bind UNIX socket to %s: %s", IPCSOCKET, strerror(errno) );
    509                 return 0;
    510         }
    511 
    512         if (listen(serversock, 5) == -1) {
    513                 log_message( LOGLVL_WARNING, "Unable to listen on UNIX socket: %s", strerror(errno) );
    514                 return 0;
    515         }
    516        
    517         gio = g_io_channel_unix_new(serversock);
    518        
    519         if (gio == NULL) {
    520                 log_message( LOGLVL_WARNING, "Unable to create IO channel for unix socket" );
    521                 return 0;
    522         }
    523 
    524         g_io_add_watch(gio, G_IO_IN, new_ipc_client, NULL);
    525         return 1;
    526 }
    527 #else
    528         /* FIXME: Open named pipe \\.\BITLBEE */
    529 #endif
    530 
    531 int ipc_master_load_state()
    532 {
    533         struct bitlbee_child *child;
    534         FILE *fp;
    535         int i, n;
    536        
    537         if( statefile == NULL )
    538                 return 0;
    539         fp = fopen( statefile, "r" );
    540         unlink( statefile );    /* Why do it later? :-) */
    541         if( fp == NULL )
    542                 return 0;
    543        
    544         if( fscanf( fp, "%d", &n ) != 1 )
    545         {
    546                 log_message( LOGLVL_WARNING, "Could not import state information for child processes." );
    547                 fclose( fp );
    548                 return 0;
    549         }
    550        
    551         log_message( LOGLVL_INFO, "Importing information for %d child processes.", n );
    552         for( i = 0; i < n; i ++ )
    553         {
    554                 child = g_new0( struct bitlbee_child, 1 );
    555                
    556                 if( fscanf( fp, "%d %d", &child->pid, &child->ipc_fd ) != 2 )
    557                 {
    558                         log_message( LOGLVL_WARNING, "Unexpected end of file: Only processed %d clients.", i );
    559                         g_free( child );
    560                         fclose( fp );
    561                         return 0;
    562                 }
    563                 child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );
    564                
    565                 child_list = g_slist_append( child_list, child );
    566         }
    567        
    568         ipc_to_children_str( "HELLO\r\n" );
    569         ipc_to_children_str( "OPERMSG :New BitlBee master process started (version " BITLBEE_VERSION ")\r\n" );
    570        
    571         return 1;
    572 }
Note: See TracChangeset for help on using the changeset viewer.