aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitlbee.c4
-rwxr-xr-xconfigure8
-rw-r--r--ipc.c72
-rw-r--r--ipc.h2
-rwxr-xr-xutils/bitlbee-ctl.pl59
5 files changed, 142 insertions, 3 deletions
diff --git a/bitlbee.c b/bitlbee.c
index ddd8d2ea..47064382 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -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" ) ) )
{
diff --git a/configure b/configure
index 2731d5b1..751e5b32 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/ipc.c b/ipc.c
index 60caba3e..1b813e7f 100644
--- a/ipc.c
+++ b/ipc.c
@@ -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;
diff --git a/ipc.h b/ipc.h
index e8ad2a0d..7ff74a15 100644
--- a/ipc.h
+++ b/ipc.h
@@ -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();