diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2005-03-12 03:16:30 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2005-03-12 03:16:30 +0000 |
commit | c3f5e88286c6d7c2d00c241e0f7899f717dd78b8 (patch) | |
tree | 530f08e94e51e9d30fe7d484f4039addc5977ac3 /src/common | |
parent | 89c311646f1175fcaf6dd38d057be8c48fe5a09f (diff) | |
download | weechat-c3f5e88286c6d7c2d00c241e0f7899f717dd78b8.zip |
Added FIFO pipe for remote control
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Makefile.am | 4 | ||||
-rw-r--r-- | src/common/command.c | 32 | ||||
-rw-r--r-- | src/common/command.h | 3 | ||||
-rw-r--r-- | src/common/fifo.c | 302 | ||||
-rw-r--r-- | src/common/fifo.h | 30 | ||||
-rw-r--r-- | src/common/weechat.c | 3 | ||||
-rw-r--r-- | src/common/weeconfig.c | 25 | ||||
-rw-r--r-- | src/common/weeconfig.h | 2 |
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 *); |