Changes in / [de3e100:0431ea1]


Ignore:
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rde3e100 r0431ea1  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o irc_commands.o log.o nick.o query.o set.o storage.o storage_text.o unix.o url.o user.o util.o
     12objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o log.o nick.o query.o set.o storage.o storage_text.o unix.o url.o user.o util.o
    1313subdirs = protocols
    1414
  • bitlbee.c

    rde3e100 r0431ea1  
    2929#include "protocols/nogaim.h"
    3030#include "help.h"
     31#include "ipc.h"
    3132#include <signal.h>
    3233#include <stdio.h>
    3334#include <errno.h>
    3435
    35 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
    36 {
    37         size_t size = sizeof( struct sockaddr_in );
    38         struct sockaddr_in conn_info;
    39         int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    40         pid_t client_pid = 0;
    41        
    42         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    43                 client_pid = fork();
    44        
    45         if( client_pid == 0 )
    46         {
    47                 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
    48                 irc_new( new_socket );
    49                
    50                 if( global.conf->runmode == RUNMODE_FORKDAEMON )
    51                 {
    52                         /* Close the listening socket, we're a client. */
    53                         close( global.listen_socket );
    54                         g_source_remove( global.listen_watch_source_id );
    55                 }
    56         }
    57         else
    58         {
    59                 /* We don't need this one, only the client does. */
    60                 close( new_socket );
    61                
    62                 /* Or maybe we didn't even get a child process... */
    63                 if( client_pid == -1 )
    64                         log_message( LOGLVL_ERROR, "Failed to fork() subprocess for client: %s", strerror( errno ) );
    65         }
    66        
    67         return TRUE;
    68 }
    69  
    70 
     36gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data );
    7137
    7238int bitlbee_daemon_init()
     
    258224}
    259225
     226gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
     227{
     228        size_t size = sizeof( struct sockaddr_in );
     229        struct sockaddr_in conn_info;
     230        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
     231        pid_t client_pid = 0;
     232       
     233        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     234        {
     235                int fds[2];
     236               
     237                if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 )
     238                {
     239                        log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) );
     240                        fds[0] = fds[1] = -1;
     241                }
     242               
     243                sock_make_nonblocking( fds[0] );
     244                sock_make_nonblocking( fds[1] );
     245               
     246                client_pid = fork();
     247               
     248                if( client_pid > 0 && fds[0] != -1 )
     249                {
     250                        struct bitlbee_child *child;
     251                       
     252                        child = g_new0( struct bitlbee_child, 1 );
     253                        child->pid = client_pid;
     254                        child->ipc_fd = fds[0];
     255                        child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );
     256                        child_list = g_slist_append( child_list, child );
     257                       
     258                        log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", client_pid );
     259                       
     260                        /* Close some things we don't need in the parent process. */
     261                        close( new_socket );
     262                        close( fds[1] );
     263                }
     264                else if( client_pid == 0 )
     265                {
     266                        irc_t *irc;
     267                       
     268                        /* Close the listening socket, we're a client. */
     269                        close( global.listen_socket );
     270                        g_source_remove( global.listen_watch_source_id );
     271                       
     272                        /* Make the connection. */
     273                        irc = irc_new( new_socket );
     274                       
     275                        /* We can store the IPC fd there now. */
     276                        global.listen_socket = fds[1];
     277                        global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc );
     278                       
     279                        close( fds[0] );
     280                }
     281        }
     282        else
     283        {
     284                log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
     285                irc_new( new_socket );
     286        }
     287       
     288        return TRUE;
     289}
     290
    260291void bitlbee_shutdown( gpointer data )
    261292{
  • bitlbee.h

    rde3e100 r0431ea1  
    112112#include "sock.h"
    113113
    114 typedef struct global_t {
     114typedef struct global {
     115        /* In forked mode, child processes store the fd of the IPC socket here. */
    115116        int listen_socket;
    116117        gint listen_watch_source_id;
  • commands.h

    rde3e100 r0431ea1  
    4242#define IRC_CMD_LOGGED_IN       2
    4343#define IRC_CMD_OPER_ONLY       4
     44#define IRC_CMD_TO_MASTER       8
    4445
    4546#endif
  • irc.c

    rde3e100 r0431ea1  
    311311                        }                       
    312312                       
    313                         if( ( cmd = irc_parse_line( irc, lines[i] ) ) == NULL )
     313                        if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    314314                                continue;
    315315                        if( !irc_exec( irc, cmd ) )
     
    326326                {
    327327                        g_free( irc->readbuffer );
    328                         irc->readbuffer = NULL; 
     328                        irc->readbuffer = NULL;
    329329                }
    330330               
     
    375375}
    376376
    377 char **irc_parse_line( irc_t *irc, char *line )
     377char **irc_parse_line( char *line )
    378378{
    379379        int i, j;
  • irc.h

    rde3e100 r0431ea1  
    3333#define IRC_PING_STRING "PinglBee"
    3434
    35 #define UMODES "ias"
     35#define UMODES "iasw"
    3636#define UMODES_PRIV "Ro"
    3737#define CMODES "nt"
     
    108108int irc_exec( irc_t *irc, char **cmd );
    109109int irc_process( irc_t *irc );
    110 char **irc_parse_line( irc_t *irc, char *line );
     110char **irc_parse_line( char *line );
    111111
    112112void irc_vawrite( irc_t *irc, char *format, va_list params );
  • irc_commands.c

    rde3e100 r0431ea1  
    2626#define BITLBEE_CORE
    2727#include "bitlbee.h"
     28#include "ipc.h"
    2829
    2930static int irc_cmd_pass( irc_t *irc, char **cmd )
     
    606607        { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
    607608        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
     609        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
     610        { "wallop",      0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    608611        { NULL }
    609612};
     
    642645                                }
    643646                       
    644                         return irc_commands[i].execute( irc, cmd );
    645                 }
    646        
    647         return( 1 );
    648 }
     647                        if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
     648                                ipc_to_master( cmd );
     649                        else
     650                                return irc_commands[i].execute( irc, cmd );
     651                }
     652       
     653        return( 1 );
     654}
Note: See TracChangeset for help on using the changeset viewer.