--- a/mcabber/configure.ac Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/configure.ac Mon Feb 18 22:59:37 2008 +0100
@@ -227,10 +227,18 @@
CFLAGS="-O2 $CFLAGS"
fi
+AC_ARG_ENABLE(fifo,
+ [AC_HELP_STRING(--enable-fifo, Enable FIFO named pipe)],
+ fifo=$enableval, fifo="")
+AM_CONDITIONAL([FIFO], [test x$fifo = xyes])
+if test x"${fifo}" = x"yes"; then
+ AC_DEFINE_UNQUOTED([ENABLE_FIFO],[1],[Named pipe support])
+fi
+
AC_ARG_ENABLE(hgcset,
[AC_HELP_STRING(--disable-hgcset, Do not use Mercurial changeset value)],
hgcset=$enableval, hgcset="yes")
-AM_CONDITIONAL(HGCSET, test x$hgcset = xyes)
+AM_CONDITIONAL(HGCSET, [test x$hgcset = xyes])
if test "${hgcset}" = "yes"; then
AC_DEFINE(ENABLE_HGCSET, 1, [Use Mercurial changeset])
fi
--- a/mcabber/mcabberrc.example Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/mcabberrc.example Mon Feb 18 22:59:37 2008 +0100
@@ -212,6 +212,11 @@
# the server.
#set hook-pre-disconnect = say_to foo@bar Goodbye!
+# FIFO
+# mcabber can create a FIFO named pipe and listen to this pipe for commands.
+# (The FIFO support has to be compiled in.) Default: disabled.
+#set fifo_name = ~/.mcabber/mcabber.fifo
+
# Traces logging
# If you want advanced traces, please specify a file and a level here.
# There are currently 2 traceloglog levels:
--- a/mcabber/src/Makefile.am Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/src/Makefile.am Mon Feb 18 22:59:37 2008 +0100
@@ -7,6 +7,10 @@
histolog.c histolog.h utils.c utils.h pgp.c pgp.h \
help.c help.h
+if FIFO
+mcabber_SOURCES += fifo.c fifo.h
+endif
+
if OTR
mcabber_SOURCES += otr.c otr.h
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/fifo.c Mon Feb 18 22:59:37 2008 +0100
@@ -0,0 +1,174 @@
+/*
+ * fifo.c -- Read commands from a named pipe
+ *
+ * Copyright (C) 2008 Mikael Berthe <mikael@lilotux.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "commands.h"
+#include "logprint.h"
+#include "utils.h"
+
+#include "hbuf.h" // For HBB_BLOCKSIZE
+
+static FILE *sfd;
+static char *fifo_name;
+
+
+// fifo_init(fifo_path)
+// Create and open the FIFO file.
+// If fifo_path is NULL, reopen the current pipe.
+// Return 0 (success) or -1 (failure).
+int fifo_init(const char *fifo_path)
+{
+ struct stat buf;
+ int fd;
+ char *fifo_path_xp;
+
+ if (!sfd && !fifo_path)
+ return -1; // Nothing to do...
+
+ if (sfd && !fifo_path) { // We want to reinitialize the pipe
+ fclose(sfd);
+ sfd = NULL;
+ if (fifo_name)
+ goto fifo_init_open;
+ }
+ sfd = NULL;
+
+ fifo_path_xp = expand_filename(fifo_path);
+
+ if (!stat(fifo_path_xp, &buf)) {
+ if (!S_ISFIFO(buf.st_mode)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO. "
+ "%s already exists and is not a pipe", fifo_path_xp);
+ g_free(fifo_path_xp);
+ return -1;
+ }
+
+ if (unlink(fifo_path_xp)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Unable to unlink FIFO %s [%s]",
+ fifo_path_xp, g_strerror(errno));
+ g_free(fifo_path_xp);
+ return -1;
+ }
+ }
+
+ if (mkfifo(fifo_path_xp, S_IWUSR | S_IRUSR)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO [%s]",
+ g_strerror(errno));
+ g_free(fifo_path_xp);
+ return -1;
+ }
+
+ fifo_name = fifo_path_xp;
+
+fifo_init_open:
+ fd = open(fifo_name, O_RDONLY | O_NONBLOCK);
+ if (!fd)
+ return -1;
+
+ sfd = fdopen(fd, "r");
+ if (fifo_path)
+ scr_LogPrint(LPRINT_LOGNORM, "FIFO initialized (%s)", fifo_name);
+ return 0;
+}
+
+// fifo_deinit()
+// Close the current FIFO pipe and delete it.
+void fifo_deinit(void)
+{
+ if (sfd) {
+ fclose(sfd);
+ sfd = NULL;
+ }
+ if (fifo_name) {
+ unlink(fifo_name);
+ g_free(fifo_name);
+ fifo_name = NULL;
+ }
+}
+
+// fifo_read()
+// Read a line from the FIFO pipe (if available), and execute it.
+void fifo_read(void)
+{
+ struct timeval tv;
+ fd_set fds;
+ char *getbuf;
+ char buf[HBB_BLOCKSIZE+1];
+ int fd;
+
+ if (!sfd) {
+ return;
+ }
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ fd = fileno(sfd);
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ select(fd + 1, &fds, NULL, NULL, &tv);
+
+ if (!FD_ISSET(fd, &fds)) {
+ return;
+ }
+
+ getbuf = fgets(buf, HBB_BLOCKSIZE, sfd);
+ if (getbuf) {
+ char *eol = buf;
+
+ // Strip trailing newlines
+ for ( ; *eol ; eol++)
+ ;
+ if (eol > buf)
+ eol--;
+ while (eol > buf && *eol == '\n')
+ *eol-- = 0;
+
+ scr_LogPrint(LPRINT_LOGNORM, "Executing FIFO command: %s", buf);
+ if (process_command(buf, TRUE) == 255)
+ mcabber_set_terminate_ui();
+ } else {
+ if (feof(sfd))
+ fifo_init(NULL); // Reopen the FIFO on EOF
+ }
+}
+
+// fifo_get_fd()
+// Return the FIFO file descriptor (-1 if none).
+int fifo_get_fd(void)
+{
+ if (sfd)
+ return fileno(sfd);
+ return -1;
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/fifo.h Mon Feb 18 22:59:37 2008 +0100
@@ -0,0 +1,11 @@
+#ifndef __FIFO_H__
+#define __FIFO_H__ 1
+
+int fifo_init(const char *fifo_path);
+void fifo_deinit(void);
+void fifo_read(void);
+int fifo_get_fd(void);
+
+#endif /* __FIFO_H__ */
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
--- a/mcabber/src/hooks.c Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/src/hooks.c Mon Feb 18 22:59:37 2008 +0100
@@ -33,6 +33,10 @@
#include "utf8.h"
#include "commands.h"
+#ifdef ENABLE_FIFO
+# include "fifo.h"
+#endif
+
static char *extcmd;
static const char *COMMAND_ME = "/me ";
@@ -50,6 +54,9 @@
last = now;
}
*/
+#ifdef ENABLE_FIFO
+ fifo_read();
+#endif
}
void hk_message_in(const char *bjid, const char *resname,
--- a/mcabber/src/jabglue.c Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/src/jabglue.c Mon Feb 18 22:59:37 2008 +0100
@@ -35,6 +35,10 @@
#include "pgp.h"
#include "otr.h"
+#ifdef ENABLE_FIFO
+# include "fifo.h"
+#endif
+
#define JABBERPORT 5222
#define JABBERSSLPORT 5223
@@ -231,6 +235,10 @@
long tmout;
struct timeval tv;
static time_t last_eviqs_check = 0L;
+ int maxfd;
+#ifdef ENABLE_FIFO
+ int fifofd;
+#endif
if (!online) {
safe_usleep(10000);
@@ -247,6 +255,15 @@
FD_ZERO(&fds);
FD_SET(0, &fds);
FD_SET(jc->fd, &fds);
+ maxfd = jc->fd;
+
+#ifdef ENABLE_FIFO
+ fifofd = fifo_get_fd();
+ if (fifofd > 0) {
+ FD_SET(fifofd, &fds);
+ maxfd = MAX(maxfd, fifofd);
+ }
+#endif
tv.tv_sec = 60;
tv.tv_usec = 0;
@@ -276,7 +293,7 @@
tv.tv_usec = 350000;
scr_DoUpdate();
- if (select(jc->fd + 1, &fds, NULL, NULL, &tv) > 0) {
+ if (select(maxfd + 1, &fds, NULL, NULL, &tv) > 0) {
if (FD_ISSET(jc->fd, &fds))
jab_poll(jc, 0);
}
--- a/mcabber/src/main.c Sun Feb 17 21:19:58 2008 +0100
+++ b/mcabber/src/main.c Mon Feb 18 22:59:37 2008 +0100
@@ -43,6 +43,10 @@
#include "pgp.h"
#include "otr.h"
+#ifdef ENABLE_FIFO
+# include "fifo.h"
+#endif
+
#ifdef ENABLE_HGCSET
# include "hgcset.h"
#endif
@@ -291,6 +295,9 @@
#ifdef WITH_ASPELL
puts("Compiled with Aspell support.");
#endif
+#ifdef ENABLE_FIFO
+ puts("Compiled with FIFO support.");
+#endif
#ifdef ENABLE_DEBUG
puts("Compiled with debugging support.");
#endif
@@ -487,6 +494,11 @@
chatstates_disabled = settings_opt_get_int("disable_chatstates");
+#ifdef ENABLE_FIFO
+ /* Initialize FIFO named pipe */
+ fifo_init(settings_opt_get("fifo_name"));
+#endif
+
if (ret < 0) {
scr_LogPrint(LPRINT_NORMAL, "No configuration file has been found.");
scr_ShowBuddyWindow();
@@ -515,6 +527,9 @@
}
scr_TerminateCurses();
+#ifdef ENABLE_FIFO
+ fifo_deinit();
+#endif
#ifdef HAVE_LIBOTR
otr_terminate();
#endif