FIFO feature rewritten as plugin

This commit is contained in:
Sebastien Helleu 2007-10-31 17:33:09 +01:00
parent 1b9f91849e
commit c008e6474d
4 changed files with 235 additions and 130 deletions

View File

@ -0,0 +1,22 @@
# Copyright (c) 2003-2007 FlashCode <flashcode@flashtux.org>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
ADD_LIBRARY(fifo MODULE fifo.c fifo.h)
SET_TARGET_PROPERTIES(fifo PROPERTIES PREFIX "")
TARGET_LINK_LIBRARIES(fifo)
INSTALL(TARGETS fifo LIBRARY DESTINATION lib/${PROJECT_NAME}/plugins)

View File

@ -0,0 +1,25 @@
# Copyright (c) 2003-2007 FlashCode <flashcode@flashtux.org>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(FIFO_CFLAGS)
libdir = ${weechat_libdir}/plugins
lib_LTLIBRARIES = fifo.la
fifo_la_SOURCES = fifo.c fifo.h
fifo_la_LDFLAGS = -module
fifo_la_LIBADD = $(FIFO_LFLAGS)

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* fifo.c: FIFO pipe for WeeChat remote control */ /* fifo.c: FIFO pipe plugin for WeeChat remote control */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -25,111 +25,153 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include "weechat.h" #include "../weechat-plugin.h"
#include "fifo.h" #include "fifo.h"
#include "command.h"
#include "log.h"
#include "weeconfig.h"
#include "../gui/gui.h"
int weechat_fifo = -1; static struct t_weechat_plugin *weechat_plugin = NULL;
char *weechat_fifo_filename = NULL; static int fifo_fd = -1;
char *weechat_fifo_unterminated = NULL; static struct t_hook *fifo_fd_hook = NULL;
static char *fifo_filename;
static char *fifo_unterminated = NULL;
/* /*
* fifo_create: create FIFO pipe for remote control * fifo_create: create FIFO pipe for remote control
*/ */
void static void
fifo_create () fifo_create ()
{ {
int filename_length; int filename_length;
char *fifo_option, *weechat_home;
if (cfg_irc_fifo_pipe)
fifo_option = weechat_plugin_config_get ("fifo");
if (!fifo_option)
{ {
/* build FIFO filename: "<weechat_home>/weechat_fifo_" + process PID */ weechat_plugin_config_set ("fifo", "on");
if (!weechat_fifo_filename) fifo_option = weechat_plugin_config_get ("fifo");
{
filename_length = strlen (weechat_home) + 64;
weechat_fifo_filename = (char *) malloc (filename_length * sizeof (char));
snprintf (weechat_fifo_filename, filename_length, "%s/weechat_fifo_%d",
weechat_home, (int) getpid());
}
/* create FIFO pipe, writable for user only */
if ((weechat_fifo = mkfifo (weechat_fifo_filename, 0600)) != 0)
{
weechat_fifo = -1;
gui_printf (NULL,
_("%s unable to create FIFO pipe for remote control (%s)\n"),
WEECHAT_ERROR, weechat_fifo_filename);
weechat_log_printf (_("%s unable to create FIFO pipe for "
"remote control (%s)\n"),
WEECHAT_ERROR, weechat_fifo_filename);
return;
}
/* open FIFO pipe in read-only (for WeeChat), non nlobking mode */
if ((weechat_fifo = open (weechat_fifo_filename, O_RDONLY | O_NONBLOCK)) == -1)
{
gui_printf (NULL,
_("%s unable to open FIFO pipe (%s) for reading\n"),
WEECHAT_ERROR, weechat_fifo_filename);
weechat_log_printf (_("%s unable to open FIFO pipe (%s) for reading\n"),
WEECHAT_ERROR, weechat_fifo_filename);
return;
}
weechat_log_printf (_("FIFO pipe is open\n"));
} }
weechat_home = weechat_info_get ("weechat_dir");
if (fifo_option && weechat_home)
{
if (weechat_strcasecmp (fifo_option, "on") == 0)
{
/* build FIFO filename: "<weechat_home>/weechat_fifo_" + process
PID */
if (!fifo_filename)
{
filename_length = strlen (weechat_home) + 64;
fifo_filename = (char *) malloc (filename_length *
sizeof (char));
snprintf (fifo_filename, filename_length,
"%s/weechat_fifo_%d",
weechat_home, (int) getpid());
}
fifo_fd = -1;
/* create FIFO pipe, writable for user only */
if (mkfifo (fifo_filename, 0600) == 0)
{
/* open FIFO pipe in read-only, non blockingmode */
if ((fifo_fd = open (fifo_filename,
O_RDONLY | O_NONBLOCK)) != -1)
weechat_printf (NULL,
_("%sFifo: pipe is open\n"),
weechat_prefix ("info"));
else
weechat_printf (NULL,
_("%sFifo: unable to open pipe (%s) for "
"reading"),
weechat_prefix ("error"),
fifo_filename);
}
else
weechat_printf (NULL,
_("%sFifo: unable to create pipe for remote "
"control (%s)"),
weechat_prefix ("error"),
fifo_filename);
}
}
if (fifo_option)
free (fifo_option);
if (weechat_home)
free (weechat_home);
}
/*
* fifo_remove: remove FIFO pipe
*/
static void
fifo_remove ()
{
if (fifo_fd != -1)
{
/* close FIFO pipe */
close (fifo_fd);
fifo_fd = -1;
}
/* remove FIFO from disk */
if (fifo_filename)
unlink (fifo_filename);
if (fifo_unterminated)
{
free (fifo_unterminated);
fifo_unterminated = NULL;
}
if (fifo_filename)
{
free (fifo_filename);
fifo_filename = NULL;
}
weechat_printf (NULL,
_("%sFifo: pipe is closed"),
weechat_prefix ("info"));
} }
/* /*
* fifo_exec: execute a command/text received by FIFO pipe * fifo_exec: execute a command/text received by FIFO pipe
*/ */
void static void
fifo_exec (char *text) fifo_exec (char *text)
{ {
char *pos_msg, *pos; char *pos_msg, *pos;
t_irc_server *ptr_server; struct t_gui_buffer *ptr_buffer;
t_irc_channel *ptr_channel;
pos = NULL; pos = NULL;
ptr_server = NULL; ptr_buffer = NULL;
ptr_channel = NULL;
/* look for server/channel at beginning of text */ /* look for category/name at beginning of text
/* text may be: "server,channel *text" or "server *text" or "*text" */ text may be: "category,name *text" or "name *text" or "*text" */
if (text[0] == '*') if (text[0] == '*')
{ {
pos_msg = text + 1; pos_msg = text + 1;
if (gui_current_window->buffer->has_input) ptr_buffer = weechat_buffer_search (NULL, NULL);
{
ptr_server = GUI_SERVER(gui_current_window->buffer);
ptr_channel = GUI_CHANNEL(gui_current_window->buffer);
}
else
{
ptr_server = GUI_SERVER(gui_buffers);
ptr_channel = NULL;
}
} }
else else
{ {
pos_msg = strstr (text, " *"); pos_msg = strstr (text, " *");
if (!pos_msg) if (!pos_msg)
{ {
irc_display_prefix (NULL, NULL, GUI_PREFIX_ERROR); weechat_printf (NULL,
gui_printf (NULL, _("%s invalid text received on FIFO pipe\n"), _("%sFifo error: invalid text received on pipe"),
WEECHAT_WARNING); weechat_prefix ("error"));
return; return;
} }
pos_msg[0] = '\0'; pos_msg[0] = '\0';
@ -145,63 +187,56 @@ fifo_exec (char *text)
{ {
pos = strchr (text, ','); pos = strchr (text, ',');
if (pos) if (pos)
{
pos[0] = '\0'; pos[0] = '\0';
ptr_server = irc_server_search (text); ptr_buffer = weechat_buffer_search (text, pos + 1);
if (!ptr_server || !ptr_server->buffer)
{
irc_display_prefix (NULL, NULL, GUI_PREFIX_ERROR);
gui_printf (NULL, _("%s server \"%s\" not found (FIFO pipe data)\n"),
WEECHAT_WARNING, text);
return;
}
if (ptr_server && pos)
{
ptr_channel = irc_channel_search_any (ptr_server, pos + 1);
if (!ptr_channel)
{
irc_display_prefix (NULL, NULL, GUI_PREFIX_ERROR);
gui_printf (NULL,
_("%s channel \"%s\" not found (FIFO pipe data)\n"),
WEECHAT_WARNING, pos + 1);
return;
}
} }
else
ptr_buffer = weechat_buffer_search (NULL, text);
} }
} }
user_command (ptr_server, ptr_channel, pos_msg, 0); if (!ptr_buffer)
{
weechat_printf (NULL,
_("%sFifo error: buffer not found for pipe data"),
weechat_prefix ("error"));
return;
}
weechat_command (ptr_buffer, pos_msg);
} }
/* /*
* fifo_read: read data in FIFO pipe * fifo_read: read data in FIFO pipe
*/ */
void static int
fifo_read () fifo_read ()
{ {
static char buffer[4096 + 2]; static char buffer[4096 + 2];
char *buf2, *pos, *ptr_buf, *next_ptr_buf; char *buf2, *pos, *ptr_buf, *next_ptr_buf;
int num_read; int num_read;
num_read = read (weechat_fifo, buffer, sizeof (buffer) - 2); num_read = read (fifo_fd, buffer, sizeof (buffer) - 2);
if (num_read > 0) if (num_read > 0)
{ {
buffer[num_read] = '\0'; buffer[num_read] = '\0';
buf2 = NULL; buf2 = NULL;
ptr_buf = buffer; ptr_buf = buffer;
if (weechat_fifo_unterminated) if (fifo_unterminated)
{ {
buf2 = (char *) malloc (strlen (weechat_fifo_unterminated) + buf2 = (char *) malloc (strlen (fifo_unterminated) +
strlen (buffer) + 1); strlen (buffer) + 1);
if (buf2) if (buf2)
{ {
strcpy (buf2, weechat_fifo_unterminated); strcpy (buf2, fifo_unterminated);
strcat (buf2, buffer); strcat (buf2, buffer);
} }
ptr_buf = buf2; ptr_buf = buf2;
free (weechat_fifo_unterminated); free (fifo_unterminated);
weechat_fifo_unterminated = NULL; fifo_unterminated = NULL;
} }
while (ptr_buf && ptr_buf[0]) while (ptr_buf && ptr_buf[0])
@ -223,7 +258,7 @@ fifo_read ()
} }
else else
{ {
weechat_fifo_unterminated = strdup (ptr_buf); fifo_unterminated = strdup (ptr_buf);
ptr_buf = NULL; ptr_buf = NULL;
next_ptr_buf = NULL; next_ptr_buf = NULL;
} }
@ -242,50 +277,75 @@ fifo_read ()
{ {
if (num_read < 0) if (num_read < 0)
{ {
gui_printf (NULL, weechat_printf (NULL,
_("%s error reading FIFO pipe, closing it\n"), _("%sFifo: error reading pipe, closing it"),
WEECHAT_ERROR); weechat_prefix ("error"));
weechat_log_printf (_("%s error reading FIFO pipe, closing it\n"),
WEECHAT_ERROR);
fifo_remove (); fifo_remove ();
} }
else else
{ {
close (weechat_fifo); weechat_unhook (fifo_fd_hook);
weechat_fifo = open (weechat_fifo_filename, O_RDONLY | O_NONBLOCK); close (fifo_fd);
fifo_fd = open (fifo_filename, O_RDONLY | O_NONBLOCK);
fifo_fd_hook = weechat_hook_fd (fifo_fd, 1, 0, 0, fifo_read, NULL);
} }
} }
return PLUGIN_RC_SUCCESS;
} }
/* /*
* fifo_remove: remove FIFO pipe * fifo_config: fifo config callback (called when fifo option is changed)
*/ */
void static int
fifo_remove () fifo_config (void *data, char *type, char *option, char *value)
{ {
if (weechat_fifo != -1) /* make C compiler happy */
(void) data;
(void) type;
(void) option;
if (weechat_strcasecmp (value, "on") == 0)
{ {
/* close FIFO pipe */ if (fifo_fd < 0)
close (weechat_fifo); fifo_create ();
weechat_fifo = -1; }
else
{
if (fifo_fd >= 0)
fifo_remove ();
} }
/* remove FIFO from disk */ return PLUGIN_RC_SUCCESS;
if (weechat_fifo_filename) }
unlink (weechat_fifo_filename);
/*
if (weechat_fifo_unterminated) * weechat_plugin_init: init fifo plugin
{ */
free (weechat_fifo_unterminated);
weechat_fifo_unterminated = NULL; int
} weechat_plugin_init (struct t_weechat_plugin *plugin)
{
if (weechat_fifo_filename) weechat_plugin = plugin;
{
free (weechat_fifo_filename); fifo_create ();
weechat_fifo_filename = NULL;
} fifo_fd_hook = weechat_hook_fd (fifo_fd, 1, 0, 0, fifo_read, NULL);
weechat_log_printf (_("FIFO pipe is closed\n")); weechat_hook_config ("plugin", "fifo.fifo", fifo_config, NULL);
return PLUGIN_RC_SUCCESS;
}
/*
* weechat_plugin_end: end fifo plugin
*/
int
weechat_plugin_end ()
{
fifo_remove ();
return PLUGIN_RC_SUCCESS;
} }

View File

@ -20,10 +20,8 @@
#ifndef __WEECHAT_FIFO_H #ifndef __WEECHAT_FIFO_H
#define __WEECHAT_FIFO_H 1 #define __WEECHAT_FIFO_H 1
extern int weechat_fifo; char plugin_name[] = "fifo";
char plugin_version[] = "0.1";
extern void fifo_create (); char plugin_description[] = "Fifo plugin for WeeChat";
extern void fifo_read ();
extern void fifo_remove ();
#endif /* fifo.h */ #endif /* fifo.h */