summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Makefile.am4
-rw-r--r--src/common/command.c32
-rw-r--r--src/common/command.h3
-rw-r--r--src/common/fifo.c302
-rw-r--r--src/common/fifo.h30
-rw-r--r--src/common/weechat.c3
-rw-r--r--src/common/weeconfig.c25
-rw-r--r--src/common/weeconfig.h2
8 files changed, 385 insertions, 16 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 8d425fd59..2ac2c1f6d 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -34,4 +34,6 @@ lib_weechat_main_a_SOURCES = weechat.c \
hotlist.c \
hotlist.h \
log.c \
- log.h
+ log.h \
+ fifo.c \
+ fifo.h
diff --git a/src/common/command.c b/src/common/command.c
index 97eee4e36..3f7644ccb 100644
--- a/src/common/command.c
+++ b/src/common/command.c
@@ -649,12 +649,13 @@ exec_weechat_command (t_irc_server *server, char *string)
*/
void
-user_command (t_irc_server *server, char *command)
+user_command (t_irc_server *server, t_gui_buffer *buffer, char *command)
{
t_irc_nick *ptr_nick;
if ((!command) || (!command[0]) || (command[0] == '\r') || (command[0] == '\n'))
return;
+
if ((command[0] == '/') && (command[1] != '/'))
{
/* WeeChat internal command (or IRC command) */
@@ -662,42 +663,45 @@ user_command (t_irc_server *server, char *command)
}
else
{
+ if (!buffer)
+ buffer = gui_current_window->buffer;
+
if ((command[0] == '/') && (command[1] == '/'))
command++;
- if (server && (!BUFFER_IS_SERVER(gui_current_window->buffer)))
+
+ if (server && (!BUFFER_IS_SERVER(buffer)))
{
- if (CHANNEL(gui_current_window->buffer)->dcc_chat)
- dcc_chat_sendf ((t_irc_dcc *)(CHANNEL(gui_current_window->buffer)->dcc_chat),
+ if (CHANNEL(buffer)->dcc_chat)
+ dcc_chat_sendf ((t_irc_dcc *)(CHANNEL(buffer)->dcc_chat),
"%s\r\n", command);
else
server_sendf (server, "PRIVMSG %s :%s\r\n",
- CHANNEL(gui_current_window->buffer)->name,
- command);
+ CHANNEL(buffer)->name, command);
- if (BUFFER_IS_PRIVATE(gui_current_window->buffer))
+ if (CHANNEL(buffer)->type == CHAT_PRIVATE)
{
- gui_printf_type_color (CHANNEL(gui_current_window->buffer)->buffer,
+ gui_printf_type_color (CHANNEL(buffer)->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "<");
- gui_printf_type_color (CHANNEL(gui_current_window->buffer)->buffer,
+ gui_printf_type_color (CHANNEL(buffer)->buffer,
MSG_TYPE_NICK,
COLOR_WIN_NICK_SELF,
"%s", server->nick);
- gui_printf_type_color (CHANNEL(gui_current_window->buffer)->buffer,
+ gui_printf_type_color (CHANNEL(buffer)->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "> ");
- gui_printf_type_color (CHANNEL(gui_current_window->buffer)->buffer,
+ gui_printf_type_color (CHANNEL(buffer)->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", command);
}
else
{
- ptr_nick = nick_search (CHANNEL(gui_current_window->buffer), server->nick);
+ ptr_nick = nick_search (CHANNEL(buffer), server->nick);
if (ptr_nick)
{
- irc_display_nick (CHANNEL(gui_current_window->buffer)->buffer, ptr_nick,
+ irc_display_nick (CHANNEL(buffer)->buffer, ptr_nick,
MSG_TYPE_NICK, 1, 1, 0);
- gui_printf_color (CHANNEL(gui_current_window->buffer)->buffer,
+ gui_printf_color (CHANNEL(buffer)->buffer,
COLOR_WIN_CHAT, "%s\n", command);
}
else
diff --git a/src/common/command.h b/src/common/command.h
index 635c26261..fa808aa1e 100644
--- a/src/common/command.h
+++ b/src/common/command.h
@@ -23,6 +23,7 @@
#include "weelist.h"
#include "../irc/irc.h"
+#include "../gui/gui.h"
#define MAX_ARGS 8192
@@ -60,7 +61,7 @@ extern void command_index_free ();
extern t_weechat_alias *alias_new (char *, char *);
extern void alias_free_all ();
extern int exec_weechat_command (t_irc_server *, char *);
-extern void user_command (t_irc_server *, char *);
+extern void user_command (t_irc_server *, t_gui_buffer *, char *);
extern int weechat_cmd_alias (char *);
extern int weechat_cmd_buffer (int, char **);
extern int weechat_cmd_clear (int, char **);
diff --git a/src/common/fifo.c b/src/common/fifo.c
new file mode 100644
index 000000000..36a6c850e
--- /dev/null
+++ b/src/common/fifo.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2003-2005 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * 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
+ */
+
+/* fifo.c: FIFO pipe for WeeChat remote control */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "weechat.h"
+#include "fifo.h"
+#include "command.h"
+#include "weeconfig.h"
+#include "../gui/gui.h"
+
+
+int weechat_fifo = -1;
+char *weechat_fifo_filename = NULL;
+char *weechat_fifo_unterminated = NULL;
+
+
+/*
+ * fifo_create: create FIFO pipe for remote control
+ */
+
+void
+fifo_create ()
+{
+ int filename_length;
+
+ if (cfg_irc_fifo_pipe)
+ {
+ /* build FIFO filename: "~/.weechat/weechat_fifo_" + process PID */
+ if (!weechat_fifo_filename)
+ {
+ 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);
+ wee_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);
+ wee_log_printf (_("%s unable to open FIFO pipe (%s) for reading\n"),
+ WEECHAT_ERROR, weechat_fifo_filename);
+ return;
+ }
+
+ wee_log_printf (_("FIFO pipe is open\n"));
+ }
+}
+
+/*
+ * fifo_exec: execute a command/text received by FIFO pipe
+ */
+
+void
+fifo_exec (char *text)
+{
+ char *pos_msg, *pos;
+ t_irc_server *ptr_server;
+ t_irc_channel *ptr_channel;
+ t_gui_buffer *ptr_buffer;
+
+ pos = NULL;
+ ptr_server = NULL;
+ ptr_channel = NULL;
+ ptr_buffer = NULL;
+
+ /* look for server/channel at beginning of text */
+ /* text may be: "server,channel *text" or "server *text" or "*text" */
+ if (text[0] == '*')
+ {
+ pos_msg = text + 1;
+ ptr_server = SERVER(gui_current_window->buffer);
+ ptr_buffer = gui_current_window->buffer;
+ }
+ else
+ {
+ pos_msg = strstr (text, " *");
+ if (!pos_msg)
+ {
+ irc_display_prefix (NULL, PREFIX_ERROR);
+ gui_printf (NULL, _("%s invalid text received on FIFO pipe\n"),
+ WEECHAT_WARNING);
+ return;
+ }
+ pos_msg[0] = '\0';
+ pos = pos_msg - 1;
+ pos_msg += 2;
+ while ((pos >= text) && (pos[0] == ' '))
+ {
+ pos[0] = '\0';
+ pos--;
+ }
+
+ if (text[0])
+ {
+ pos = strchr (text, ',');
+ if (pos)
+ pos[0] = '\0';
+ ptr_server = server_search (text);
+ if (!ptr_server || !ptr_server->buffer)
+ {
+ irc_display_prefix (NULL, PREFIX_ERROR);
+ gui_printf (NULL, _("%s server \"%s\" not found (FIFO pipe data)\n"),
+ WEECHAT_WARNING, text);
+ return;
+ }
+ if (ptr_server)
+ {
+ if (pos)
+ {
+ ptr_channel = channel_search (ptr_server, pos + 1);
+ if (!ptr_channel)
+ {
+ irc_display_prefix (NULL, PREFIX_ERROR);
+ gui_printf (NULL, _("%s channel \"%s\" not found (FIFO pipe data)\n"),
+ WEECHAT_WARNING, pos + 1);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ if (!ptr_server)
+ {
+ irc_display_prefix (NULL, PREFIX_ERROR);
+ gui_printf (NULL, _("%s invalid text received on FIFO pipe\n"),
+ WEECHAT_WARNING);
+ return;
+ }
+
+ if (!ptr_buffer)
+ {
+ if (ptr_channel)
+ ptr_buffer = ptr_channel->buffer;
+ else
+ ptr_buffer = ptr_server->buffer;
+ }
+
+ user_command (ptr_server, ptr_buffer, pos_msg);
+}
+
+/*
+ * fifo_read: read data in FIFO pipe
+ */
+
+void
+fifo_read ()
+{
+ static char buffer[4096 + 2];
+ char *buf2, *pos, *ptr_buf, *next_ptr_buf;
+ int num_read;
+
+ num_read = read (weechat_fifo, buffer, sizeof (buffer) - 2);
+ if (num_read > 0)
+ {
+ buffer[num_read] = '\0';
+
+ buf2 = NULL;
+ ptr_buf = buffer;
+ if (weechat_fifo_unterminated)
+ {
+ buf2 = (char *) malloc (strlen (weechat_fifo_unterminated) +
+ strlen (buffer) + 1);
+ if (buf2)
+ {
+ strcpy (buf2, weechat_fifo_unterminated);
+ strcat (buf2, buffer);
+ }
+ ptr_buf = buf2;
+ free (weechat_fifo_unterminated);
+ weechat_fifo_unterminated = NULL;
+ }
+
+ while (ptr_buf && ptr_buf[0])
+ {
+ next_ptr_buf = NULL;
+ pos = strstr (ptr_buf, "\r\n");
+ if (pos)
+ {
+ pos[0] = '\0';
+ next_ptr_buf = pos + 2;
+ }
+ else
+ {
+ pos = strstr (ptr_buf, "\n");
+ if (pos)
+ {
+ pos[0] = '\0';
+ next_ptr_buf = pos + 1;
+ }
+ else
+ {
+ weechat_fifo_unterminated = strdup (ptr_buf);
+ ptr_buf = NULL;
+ next_ptr_buf = NULL;
+ }
+ }
+
+ if (ptr_buf)
+ fifo_exec (ptr_buf);
+
+ ptr_buf = next_ptr_buf;
+ }
+
+ if (buf2)
+ free (buf2);
+ }
+ else
+ {
+ if (num_read < 0)
+ {
+ gui_printf (NULL,
+ _("%s error reading FIFO pipe, closing it\n"),
+ WEECHAT_ERROR);
+ wee_log_printf (_("%s error reading FIFO pipe, closing it\n"),
+ WEECHAT_ERROR);
+ fifo_remove ();
+ }
+ else
+ {
+ close (weechat_fifo);
+ weechat_fifo = open (weechat_fifo_filename, O_RDONLY | O_NONBLOCK);
+ }
+ }
+}
+
+/*
+ * fifo_remove: remove FIFO pipe
+ */
+
+void
+fifo_remove ()
+{
+ if (weechat_fifo != -1)
+ {
+ /* close FIFO pipe */
+ close (weechat_fifo);
+ weechat_fifo = -1;
+ }
+
+ /* remove FIFO from disk */
+ if (weechat_fifo_filename)
+ unlink (weechat_fifo_filename);
+
+ if (weechat_fifo_unterminated)
+ {
+ free (weechat_fifo_unterminated);
+ weechat_fifo_unterminated = NULL;
+ }
+
+ if (weechat_fifo_filename)
+ {
+ free (weechat_fifo_filename);
+ weechat_fifo_filename = NULL;
+ }
+
+ wee_log_printf (_("FIFO pipe is closed\n"));
+}
diff --git a/src/common/fifo.h b/src/common/fifo.h
new file mode 100644
index 000000000..9cfa3e91d
--- /dev/null
+++ b/src/common/fifo.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2003-2005 by FlashCode <flashcode@flashtux.org>
+ * See README for License detail, AUTHORS for developers list.
+ *
+ * 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
+ */
+
+
+#ifndef __WEECHAT_FIFO_H
+#define __WEECHAT_FIFO_H 1
+
+extern int weechat_fifo;
+
+extern void fifo_create ();
+extern void fifo_read ();
+extern void fifo_remove ();
+
+#endif /* fifo.h */
diff --git a/src/common/weechat.c b/src/common/weechat.c
index bafa7fbad..54e004316 100644
--- a/src/common/weechat.c
+++ b/src/common/weechat.c
@@ -57,6 +57,7 @@
#include "weechat.h"
#include "weeconfig.h"
#include "command.h"
+#include "fifo.h"
#include "../irc/irc.h"
#include "../gui/gui.h"
#include "../plugins/plugins.h"
@@ -593,6 +594,7 @@ wee_gui_shutdown ()
void
wee_shutdown (int return_code)
{
+ fifo_remove ();
if (weechat_home)
free (weechat_home);
if (weechat_log_file)
@@ -763,6 +765,7 @@ main (int argc, char *argv[])
weechat_welcome_message (); /* display WeeChat welcome message */
/* auto-connect to servers */
server_auto_connect (server_cmd_line);
+ fifo_create (); /* create FIFO pipe for remote control */
gui_main_loop (); /* WeeChat main loop */
diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c
index cfaa515e6..84b8f011c 100644
--- a/src/common/weeconfig.c
+++ b/src/common/weeconfig.c
@@ -38,6 +38,7 @@
#include "weechat.h"
#include "weeconfig.h"
#include "command.h"
+#include "fifo.h"
#include "../irc/irc.h"
#include "../gui/gui.h"
@@ -489,6 +490,7 @@ int cfg_irc_away_check;
int cfg_irc_lag_check;
int cfg_irc_lag_min_show;
int cfg_irc_lag_disconnect;
+int cfg_irc_fifo_pipe;
t_config_option weechat_options_irc[] =
{ { "irc_display_away", N_("display message to all channels when away"),
@@ -523,6 +525,10 @@ t_config_option weechat_options_irc[] =
N_("disconnect after important lag (in minutes, 0 = never disconnect)"),
OPTION_TYPE_INT, 0, INT_MAX, 5,
NULL, NULL, &cfg_irc_lag_disconnect, NULL, config_change_noop },
+ { "irc_fifo_pipe", N_("create a FIFO pipe for remote control"),
+ N_("create a FIFO pipe for remote control"),
+ OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
+ NULL, NULL, &cfg_irc_fifo_pipe, NULL, config_change_fifo_pipe },
{ NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }
};
@@ -800,6 +806,25 @@ config_change_away_check ()
}
/*
+ * config_change_fifo_pipe: called when FIFO pipe is changed
+ */
+
+void
+config_change_fifo_pipe ()
+{
+ if (cfg_irc_fifo_pipe)
+ {
+ if (weechat_fifo == -1)
+ fifo_create ();
+ }
+ else
+ {
+ if (weechat_fifo != -1)
+ fifo_remove ();
+ }
+}
+
+/*
* config_option_set_value: set new value for an option
* return: 0 if success
* -1 if error (bad value)
diff --git a/src/common/weeconfig.h b/src/common/weeconfig.h
index 369639101..1161d95df 100644
--- a/src/common/weeconfig.h
+++ b/src/common/weeconfig.h
@@ -163,6 +163,7 @@ extern int cfg_irc_away_check;
extern int cfg_irc_lag_check;
extern int cfg_irc_lag_min_show;
extern int cfg_irc_lag_disconnect;
+extern int cfg_irc_fifo_pipe;
extern int cfg_dcc_auto_accept_files;
extern int cfg_dcc_auto_accept_chats;
@@ -189,6 +190,7 @@ extern void config_change_buffers ();
extern void config_change_buffer_content ();
extern void config_change_color ();
extern void config_change_away_check ();
+extern void config_change_fifo_pipe ();
extern int config_option_set_value (t_config_option *, char *);
extern t_config_option *config_option_search (char *);
extern int config_set_value (char *, char *);