diff options
-rw-r--r-- | bitlbee.c | 4 | ||||
-rwxr-xr-x | configure | 8 | ||||
-rw-r--r-- | ipc.c | 72 | ||||
-rw-r--r-- | ipc.h | 2 | ||||
-rwxr-xr-x | utils/bitlbee-ctl.pl | 59 |
5 files changed, 142 insertions, 3 deletions
@@ -117,6 +117,10 @@ int bitlbee_daemon_init() if( global.conf->runmode == RUNMODE_FORKDAEMON ) ipc_master_load_state(); + + if( global.conf->runmode == RUNMODE_DAEMON || + global.conf->runmode == RUNMODE_FORKDAEMON ) + ipc_master_listen_socket(); if( ( fp = fopen( global.conf->pidfile, "w" ) ) ) { @@ -14,6 +14,7 @@ mandir='$prefix/share/man/' datadir='$prefix/share/bitlbee/' config='/var/lib/bitlbee/' pidfile='/var/run/bitlbee.pid' +ipcsocket='/var/run/bitlbee' plugindir='$prefix/lib/bitlbee' msn=1 @@ -48,6 +49,7 @@ Option Description Default --plugindir=... $plugindir --pidfile=... $pidfile --config=... $config +--ipcsocket=... $ipcsocket --msn=0/1 Disable/enable MSN part $msn --jabber=0/1 Disable/enable Jabber part $jabber @@ -75,7 +77,8 @@ mandir=`eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'` datadir=`eval echo "$datadir/" | sed 's/\/\{1,\}/\//g'` config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'` plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'` -pidfile=`eval echo "$pidfile/" | sed 's/\/\{1,\}/\//g'` +pidfile=`eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'` +ipcsocket=`eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'` cat<<EOF>Makefile.settings ## BitlBee settings, generated by configure @@ -85,8 +88,8 @@ ETCDIR=$etcdir MANDIR=$mandir DATADIR=$datadir PLUGINDIR=$plugindir -PIDFILE=$pidfile CONFIG=$config +IPCSOCKET=$ipcsocket ARCH=$arch CPU=$cpu @@ -108,6 +111,7 @@ cat<<EOF>config.h #define VARDIR "$datadir" #define PLUGINDIR "$plugindir" #define PIDFILE "$pidfile" +#define IPCSOCKET "$ipcsocket" #define ARCH "$arch" #define CPU "$cpu" EOF @@ -27,6 +27,9 @@ #include "bitlbee.h" #include "ipc.h" #include "commands.h" +#ifndef _WIN32 +#include <sys/un.h> +#endif GSList *child_list = NULL; static char *statefile = NULL; @@ -460,6 +463,75 @@ void ipc_master_set_statefile( char *fn ) statefile = g_strdup( fn ); } + +static gboolean new_ipc_client (GIOChannel *gio, GIOCondition cond, gpointer data) +{ + struct bitlbee_child *child = g_new0( struct bitlbee_child, 1 ); + int serversock; + + serversock = g_io_channel_unix_get_fd(gio); + + child->ipc_fd = accept(serversock, NULL, 0); + + if (child->ipc_fd == -1) { + log_message( LOGLVL_WARNING, "Unable to accept connection on UNIX domain socket: %s", strerror(errno) ); + return TRUE; + } + + child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); + + child_list = g_slist_append( child_list, child ); + + return TRUE; +} + +#ifndef _WIN32 +int ipc_master_listen_socket() +{ + struct sockaddr_un un_addr; + int serversock; + GIOChannel *gio; + + /* Clean up old socket files that were hanging around.. */ + if (unlink(IPCSOCKET) == -1 && errno != ENOENT) { + log_message( LOGLVL_ERROR, "Could not remove old IPC socket at %s: %s", IPCSOCKET, strerror(errno) ); + return 0; + } + + un_addr.sun_family = AF_UNIX; + strcpy(un_addr.sun_path, IPCSOCKET); + + serversock = socket(AF_UNIX, SOCK_STREAM, PF_UNIX); + + if (serversock == -1) { + log_message( LOGLVL_WARNING, "Unable to create UNIX socket: %s", strerror(errno) ); + return 0; + } + + if (bind(serversock, &un_addr, sizeof(un_addr)) == -1) { + log_message( LOGLVL_WARNING, "Unable to bind UNIX socket to %s: %s", IPCSOCKET, strerror(errno) ); + return 0; + } + + if (listen(serversock, 5) == -1) { + log_message( LOGLVL_WARNING, "Unable to listen on UNIX socket: %s", strerror(errno) ); + return 0; + } + + gio = g_io_channel_unix_new(serversock); + + if (gio == NULL) { + log_message( LOGLVL_WARNING, "Unable to create IO channel for unix socket" ); + return 0; + } + + g_io_add_watch(gio, G_IO_IN, new_ipc_client, NULL); + return 1; +} +#else + /* FIXME: Open named pipe \\.\BITLBEE */ +#endif + int ipc_master_load_state() { struct bitlbee_child *child; @@ -56,6 +56,6 @@ void ipc_master_cmd_rehash( irc_t *data, char **cmd ); char *ipc_master_save_state(); void ipc_master_set_statefile( char *fn ); int ipc_master_load_state(); - +int ipc_master_listen_socket(); extern GSList *child_list; diff --git a/utils/bitlbee-ctl.pl b/utils/bitlbee-ctl.pl new file mode 100755 index 00000000..32f0a81e --- /dev/null +++ b/utils/bitlbee-ctl.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# Simple front-end to BitlBee's administration commands +# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org> + +use IO::Socket; +use Getopt::Long; +use strict; +use warnings; + +my $opt_help; +my $opt_socketfile = "/var/run/bitlbee"; + +sub ShowHelp +{ + print +"bitlbee-ctl.pl [options] command ... + +Available options: + + --ipc-socket=SOCKET Override path to IPC socket [$opt_socketfile] + --help Show this help message + +Available commands: + + die + +"; + exit (0); +} + +GetOptions ( + 'help|h|?' => \&ShowHelp, + 'ipc-socket=s' => \$opt_socketfile + ) or exit(1); + +my $client = IO::Socket::UNIX->new(Peer => $opt_socketfile, + Type => SOCK_STREAM, + Timeout => 10); + +if (not $client) { + print "Error connecting to $opt_socketfile: $@\n"; + exit(1); +} + +my $cmd = shift @ARGV; + +if (not defined($cmd)) { + print "Usage: bitlbee-ctl.pl [options] command ...\n"; + exit(1); +} + +if ($cmd eq "die") { + $client->send("DIE\r\n"); +} else { + print "No such command: $cmd\n"; + exit(1); +} + +$client->close(); |