diff options
74 files changed, 8082 insertions, 166 deletions
@@ -1,7 +1,7 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -WeeChat known bugs, 2003-10-09 +WeeChat known bugs, 2003-10-25 - too much nicks in the channel (> height of window) => display bug - some IRC commands are marked as 'unknown' when received @@ -12,3 +12,4 @@ WeeChat known bugs, 2003-10-09 - when function key (non used by WeeChat) is pressed, prompt is deleted - when quitting WeeChat term title is not restored (if look_set_title is ON) - command name for /server can not contain spaces +- wrong alias is not created and not saved when quitting WeeChat @@ -1,10 +1,11 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2003-10-12 +ChangeLog - 2003-10-25 Version 0.0.3 (under dev!): + * ./configure script to build WeeChat (now multi-platform) * nicks are now correctly sorted (op, halfop, voice, other) * fixed crash when entering text without any server connection * fixed display bug (text was blinking when scrolling) @@ -1,10 +1,12 @@ WeeChat - Installation instructions =================================== -1) Run 'make' +1) Run './configure' -2) As root, run 'make install' +2) Run 'make' -3) Enjoy ! :-) +3) As root, run 'make install' + +4) Enjoy ! :-) See AUTHORS for any support, feel free to contact us for any problem ;) diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..1124df70f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,18 @@ +# Copyright (c) 2003 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 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 +# + +SUBDIRS = src @@ -10,7 +10,7 @@ It is customizable and extensible with scripts. Features -------- * IRC chat client with multi-server connection - * many GUI (curses, Gtk, QT) (1) + * many GUI (curses, Gtk, Qt) (1) * small, fast and very light * customizable and extensible with scripts (Perl, Python, Ruby) (2) * compliant with RFC 1459,2810,2811,2812,2813 @@ -46,6 +46,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --- -(1) only curses & text interfaces are available today +(1) only curses interface is available today (2) plugin interfaces are not yet developed (3) only GNU/Linux version is available today @@ -1,7 +1,7 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -TODO - 2003-10-12 +TODO - 2003-10-25 Legend: # done @@ -13,6 +13,9 @@ Legend: v0.0.3: ------ + * General: + + use of ./configure for building WeeChat + * IRC protocol: # implement RFC 2812 + "/mode" command: change the user/channels modes @@ -20,29 +23,15 @@ v0.0.3: persons with the flag +w enable * WeeChat commands: - - "/reload" command: reload the WeeChat's config file - - "/highlight" command: highlight a given word when it appears on - channels/privates + "/set" command: allow the user to set the WeeChat variables under WeeChat without editing the config file (colours, time format, etc) * Interface: - + Gtk GUI - - display current channel modes (example : #weechat(+nt)) - - interpret special chars in messages (color & bold for example) + internationalization (traduce WeeChat in many languages) - - log chats to file - - * TCP/IP communication: - - proxy support * Configuration: - - add missing options for config file - - wrong alias is not created and not saved when quitting WeeChat # do not stop program if problem with options in config file - - load config file after GUI (so init values by default (colors, ...) before - loading config) Future versions: @@ -60,6 +49,9 @@ Future versions: nick/host connect to the given irc network * WeeChat commands: + - "/reload" command: reload the WeeChat's config file + - "/highlight" command: highlight a given word when it appears on + channels/privates - "/completion" command: do shortcuts (for example when we type "u" in the text bar it send it to the server as "you") - "/exec" command: execute a command as if we was in shell @@ -68,6 +60,9 @@ Future versions: channel/private * Interface: + + Gtk GUI + - display current channel modes (example : #weechat(+nt)) + - interpret special chars in messages (color & bold for example) - many channel windows in one window/term (window split) - add lag indicator - forget some old lines that were displayed long time ago (now all is saved, @@ -75,15 +70,20 @@ Future versions: - improve completion (for example complete command parameters when possible) - understand incomplete commands if unambigous (for example: /he for /help is ok) - add clock (in status bar?) + - log chats to file ? Qt GUI * TCP/IP communication: - connect to server with child process (background) + - proxy support - SSL support - IPv6 protocol implementation * Configuration: - add key bindings to config file + - add missing options for config file + - load config file after GUI (so init values by default (colors, ...) before + loading config) * Plugins: - add Perl plugin diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..5b049e4b3 --- /dev/null +++ b/configure.in @@ -0,0 +1,126 @@ +# Copyright (c) 2003 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 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 +# + +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.56) +AC_INIT(WeeChat, 0.0.3, flashcode@flashtux.org) +AC_CONFIG_SRCDIR([src/common/weechat.c]) +AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([weechat], [0.0.3]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_RANLIB + +# Checks for libraries. +# AC_CHECK_LIB([curses], [initscr]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h libintl.h limits.h locale.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_TIME +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday inet_ntoa memset mkdir select setlocale socket strcasecmp strchr strdup strncasecmp strpbrk strrchr strstr uname]) + +AC_ARG_ENABLE(curses, [ --disable-curses Turn off Curses interface (default=auto)],,enable_curses=yes) +AC_ARG_ENABLE(gtk, [ --disable-gtk Turn off Gtk+ interface (default=auto)],,enable_gtk=yes) +AC_ARG_ENABLE(qt, [ --disable-qt Turn off Qt interface (default=auto)],,enable_qt=yes) + +enable_plugins=no +enable_perl=no +PERL_CFLAGS= +enable_python=no +PYTHON_CFLAGS= +enable_ruby=no +RUBY_CFLAGS= +enable_debug=no +DEBUG_CFLAGS= + + +AM_CONDITIONAL(GUI_CURSES, test "$enable_curses" = "yes") +AM_CONDITIONAL(GUI_GTK, test "$enable_gtk" = "yes") +AM_CONDITIONAL(GUI_QT, test "$enable_qt" = "yes") + +#if test "x$enable_gtk" = "xyes" ; then +# AM_PATH_GTK_2_0(2.0.0, havegtk=yes, havegtk=no) +# if test "$havegtk" = no; then +# enable_gtk="no" +# echo +# echo Cannot find Gtk+\! Not building Gtk+ interface... +# echo +# fi +#fi + +CURSES_LIBS=-lcurses + +GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` +GTK_LIBS=`pkg-config --libs gtk+-2.0` + +AC_SUBST(CURSES_LIBS) +AC_SUBST(GTK_CFLAGS) +AC_SUBST(GTK_LIBS) + +CFLAGS="-Wall -W -pipe -O2" + +AC_OUTPUT([Makefile + src/Makefile + src/common/Makefile + src/irc/Makefile + src/gui/Makefile + src/gui/curses/Makefile + src/gui/gtk/Makefile + src/gui/qt/Makefile]) + +echo +echo $PACKAGE $VERSION + +listgui= +if test "x$enable_curses" = "xyes" ; then + listgui="$listgui Curses" +fi +if test "x$enable_gtk" = "xyes" ; then + listgui="$listgui Gtk+" +fi +if test "x$enable_qt" = "xyes" ; then + listgui="$listgui Qt" +fi + +echo +echo Interfaces.................... :$listgui +echo +echo Build with Plugin support..... : $enable_plugins +echo Build with Perl support....... : $enable_perl +echo Build with Python support..... : $enable_python +echo Build with Ruby support....... : $enable_ruby +echo +echo Print debugging messages...... : $enable_debug +echo +eval eval echo WeeChat will be installed in $bindir. +echo +echo configure complete, now type \'make\' to build WeeChat +echo diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 000000000..f7441490b --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,18 @@ +# Copyright (c) 2003 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 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 +# + +SUBDIRS = common irc gui diff --git a/src/common/Makefile.am b/src/common/Makefile.am new file mode 100644 index 000000000..4d4764c31 --- /dev/null +++ b/src/common/Makefile.am @@ -0,0 +1,24 @@ +# Copyright (c) 2003 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 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 +# + +noinst_LIBRARIES = lib_weechat_main.a + +lib_weechat_main_a_SOURCES = weechat.c \ + command.c \ + completion.c \ + config.c \ + history.c diff --git a/src/common/command.c b/src/common/command.c new file mode 100644 index 000000000..a60152123 --- /dev/null +++ b/src/common/command.c @@ -0,0 +1,1387 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* command.c: WeeChat internal commands */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "command.h" +#include "config.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* WeeChat internal commands */ + +t_weechat_command weechat_commands[] = +{ { "alias", N_("create an alias for a command"), + N_("[alias_name [command [arguments]]"), + N_("alias_name: name of alias\ncommand: command name (WeeChat " + "or IRC command, without first '/')\n" "arguments: arguments for command"), + 0, MAX_ARGS, NULL, weechat_cmd_alias }, + { "clear", N_("clear window(s)"), + N_("[-all]"), + N_("-all: clear all windows"), + 0, 1, weechat_cmd_clear, NULL }, + { "connect", N_("connect to a server"), + N_("servername"), + N_("servername: server name to connect"), + 1, 1, weechat_cmd_connect, NULL }, + { "disconnect", N_("disconnect from a server"), + N_("servername"), + N_("servername: server name to disconnect"), + 1, 1, weechat_cmd_disconnect, NULL }, + { "help", N_("display help about commands"), + N_("[command]"), N_("command: name of a WeeChat or IRC command"), + 0, 1, weechat_cmd_help, NULL }, + { "server", N_("list, add or remove servers"), + N_("[list] | " + "[servername hostname port [-auto | -noauto] [-pwd password] [-nicks nick1 " + "[nick2 [nick3]]] [-username username] [-realname realname] " + "[-command command] [-autojoin channel[,channel]] ] | " + "[del servername]"), + N_("servername: server name, for internal & display use\n" + "hostname: name or IP address of server\n" + "port: port for server (integer)\n" + "password: password for server\n" + "nick1: first nick for server\n" + "nick2: alternate nick for server\n" + "nick3: second alternate nick for server\n" + "username: user name\n" + "realname: real name of user\n"), + 0, MAX_ARGS, weechat_cmd_server, NULL }, + { "save", N_("save config to disk"), + N_("[file]"), N_("file: filename for writing config"), + 0, 1, weechat_cmd_save, NULL }, + { "set", N_("set config parameters"), + N_("[option [value]]"), N_("option: name of an option\nvalue: value for option"), + 0, 2, weechat_cmd_set, NULL }, + { "unalias", N_("remove an alias"), + N_("alias_name"), N_("alias_name: name of alias to remove"), + 1, 1, NULL, weechat_cmd_unalias }, + { NULL, NULL, NULL, NULL, 0, 0, NULL, NULL } +}; + +t_weechat_alias *weechat_alias = NULL; +t_weechat_alias *weechat_last_alias = NULL; + +t_index_command *index_commands; +t_index_command *last_index_command; + + +/* + * index_command_search: search a command + */ + +t_index_command * +index_command_search (char *command) +{ + t_index_command *ptr_index; + + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strcasecmp (command, ptr_index->command_name) == 0) + return ptr_index; + } + return NULL; +} + +/* + * index_command_find_pos: find position for a command index (for sorting index) + */ + +t_index_command * +index_command_find_pos (char *command) +{ + t_index_command *ptr_index; + + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strcasecmp (command, ptr_index->command_name) < 0) + return ptr_index; + } + return NULL; +} + +/* + * index_command_insert_sorted: insert index into sorted list + */ + +void +index_command_insert_sorted (t_index_command *index) +{ + t_index_command *pos_index; + + pos_index = index_command_find_pos (index->command_name); + + if (index_commands) + { + if (pos_index) + { + /* insert index into the list (before index found) */ + index->prev_index = pos_index->prev_index; + index->next_index = pos_index; + if (pos_index->prev_index) + pos_index->prev_index->next_index = index; + else + index_commands = index; + pos_index->prev_index = index; + } + else + { + /* add index to the end */ + index->prev_index = last_index_command; + index->next_index = NULL; + last_index_command->next_index = index; + last_index_command = index; + } + } + else + { + index->prev_index = NULL; + index->next_index = NULL; + index_commands = index; + last_index_command = index; + } +} + +/* + * index_command_new: create new index command and add it to index list + */ + +t_index_command * +index_command_new (char *command_name) +{ + t_index_command *new_index; + + if ((new_index = ((t_index_command *) malloc (sizeof (t_index_command))))) + { + new_index->command_name = strdup (command_name); + index_command_insert_sorted (new_index); + return new_index; + } + return NULL; +} + +/* + * index_command_build: build an index of commands (internal, irc and alias) + * This list will be sorted, and used for completion + */ + +void +index_command_build () +{ + int i; + + index_commands = NULL; + last_index_command = NULL; + i = 0; + while (weechat_commands[i].command_name) + { + index_command_new (weechat_commands[i].command_name); + i++; + } + i = 0; + while (irc_commands[i].command_name) + { + if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg) + index_command_new (irc_commands[i].command_name); + i++; + } +} + +/* + * index_command_free: free an index command and reomve it from list + */ + +void +index_command_free (t_index_command *index) +{ + t_index_command *new_index_commands; + + /* remove index command from list */ + if (last_index_command == index) + last_index_command = index->prev_index; + if (index->prev_index) + { + (index->prev_index)->next_index = index->next_index; + new_index_commands = index_commands; + } + else + new_index_commands = index->next_index; + + if (index->next_index) + (index->next_index)->prev_index = index->prev_index; + + /* free data */ + if (index->command_name) + free (index->command_name); + free (index); + index_commands = new_index_commands; +} + +/* + * alias_search: search an alias + */ + +t_weechat_alias * +alias_search (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (alias_name, ptr_alias->alias_name) == 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_find_pos: find position for an alias (for sorting aliases) + */ + +t_weechat_alias * +alias_find_pos (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (alias_name, ptr_alias->alias_name) < 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_insert_sorted: insert alias into sorted list + */ + +void +alias_insert_sorted (t_weechat_alias *alias) +{ + t_weechat_alias *pos_alias; + + pos_alias = alias_find_pos (alias->alias_name); + + if (weechat_alias) + { + if (pos_alias) + { + /* insert alias into the list (before alias found) */ + alias->prev_alias = pos_alias->prev_alias; + alias->next_alias = pos_alias; + if (pos_alias->prev_alias) + pos_alias->prev_alias->next_alias = alias; + else + weechat_alias = alias; + pos_alias->prev_alias = alias; + } + else + { + /* add alias to the end */ + alias->prev_alias = weechat_last_alias; + alias->next_alias = NULL; + weechat_last_alias->next_alias = alias; + weechat_last_alias = alias; + } + } + else + { + alias->prev_alias = NULL; + alias->next_alias = NULL; + weechat_alias = alias; + weechat_last_alias = alias; + } +} + +/* + * alias_new: create new alias and add it to alias list + */ + +t_weechat_alias * +alias_new (char *alias_name, char *alias_command) +{ + char *pos; + t_weechat_alias *new_alias; + + if (index_command_search (alias_name)) + { + gui_printf (NULL, _("%s alias or command \"%s\" already exists!\n"), + WEECHAT_ERROR, alias_name); + return NULL; + } + pos = strchr (alias_command, ' '); + if (pos) + pos[0] = '\0'; + if (alias_search (alias_command)) + { + gui_printf (NULL, _("%s alias cannot run another alias!\n"), + WEECHAT_ERROR); + return NULL; + } + if (!index_command_search (alias_command)) + { + gui_printf (NULL, _("%s target command \"%s\" does not exist!\n"), + WEECHAT_ERROR, alias_command); + return NULL; + } + if (pos) + pos[0] = ' '; + + if ((new_alias = ((t_weechat_alias *) malloc (sizeof (t_weechat_alias))))) + { + new_alias->alias_name = strdup (alias_name); + new_alias->alias_command = (char *)malloc (strlen (alias_command) + 2); + new_alias->alias_command[0] = '/'; + strcpy (new_alias->alias_command + 1, alias_command); + alias_insert_sorted (new_alias); + return new_alias; + } + else + return NULL; +} + +/* + * alias_free: free an alias and reomve it from list + */ + +void +alias_free (t_weechat_alias *alias) +{ + t_weechat_alias *new_weechat_alias; + + /* remove alias from list */ + if (weechat_last_alias == alias) + weechat_last_alias = alias->prev_alias; + if (alias->prev_alias) + { + (alias->prev_alias)->next_alias = alias->next_alias; + new_weechat_alias = weechat_alias; + } + else + new_weechat_alias = alias->next_alias; + + if (alias->next_alias) + (alias->next_alias)->prev_alias = alias->prev_alias; + + /* free data */ + if (alias->alias_name) + free (alias->alias_name); + if (alias->alias_command) + free (alias->alias_command); + free (alias); + weechat_alias = new_weechat_alias; +} + +/* + * explode_string: explode a string according to separators + */ + +char ** +explode_string (char *string, char *separators, int num_items_max, + int *num_items) +{ + int i, n_items; + char **array; + char *ptr, *ptr1, *ptr2; + + if (num_items != NULL) + *num_items = 0; + + n_items = num_items_max; + + if (string == NULL) + return NULL; + + if (num_items_max == 0) + { + /* calculate number of items */ + ptr = string; + i = 1; + while ((ptr = strpbrk (ptr, separators))) + { + while (strchr (separators, ptr[0]) != NULL) + ptr++; + i++; + } + n_items = i; + } + + array = + (char **) malloc ((num_items_max ? n_items : n_items + 1) * + sizeof (char *)); + + ptr1 = string; + ptr2 = string; + + for (i = 0; i < n_items; i++) + { + while (strchr (separators, ptr1[0]) != NULL) + ptr1++; + if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) + if ((ptr2 = strchr (ptr1, '\r')) == NULL) + if ((ptr2 = strchr (ptr1, '\n')) == NULL) + ptr2 = strchr (ptr1, '\0'); + + if ((ptr1 == NULL) || (ptr2 == NULL)) + { + array[i] = NULL; + } + else + { + if (ptr2 - ptr1 > 0) + { + array[i] = + (char *) malloc ((ptr2 - ptr1 + 1) * sizeof (char)); + array[i] = strncpy (array[i], ptr1, ptr2 - ptr1); + array[i][ptr2 - ptr1] = '\0'; + ptr1 = ++ptr2; + } + else + { + array[i] = NULL; + } + } + } + if (num_items_max == 0) + { + array[i] = NULL; + if (num_items != NULL) + *num_items = i; + } + else + { + if (num_items != NULL) + *num_items = num_items_max; + } + + return array; +} + +/* + * exec_weechat_command: executes a command (WeeChat internal or IRC) + * returns: 1 if command was executed succesfully + * 0 if error (command not executed) + */ + +int +exec_weechat_command (t_irc_server *server, char *string) +{ + int i, j, argc, return_code, length1, length2; + char *command, *pos, *ptr_args, **argv, *alias_command; + t_weechat_alias *ptr_alias; + + if ((!string[0]) || (string[0] != '/')) + return 0; + + command = strdup (string); + + /* look for end of command */ + ptr_args = NULL; + pos = strchr (command, ' '); + if (pos) + { + pos[0] = '\0'; + pos++; + while (pos[0] == ' ') + pos++; + ptr_args = pos; + if (!ptr_args[0]) + ptr_args = NULL; + } + + argv = explode_string (ptr_args, " ", 0, &argc); + + for (i = 0; weechat_commands[i].command_name; i++) + { + if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) + { + if ((argc < weechat_commands[i].min_arg) + || (argc > weechat_commands[i].max_arg)) + { + if (weechat_commands[i].min_arg == + weechat_commands[i].max_arg) + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, WEECHAT_NAME, + command + 1, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + else + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, WEECHAT_NAME, + command + 1, + weechat_commands[i].min_arg, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + } + else + { + if (weechat_commands[i].cmd_function_args) + return_code = (int) (weechat_commands[i].cmd_function_args) + (argc, argv); + else + return_code = (int) (weechat_commands[i].cmd_function_1arg) + (ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s %s command \"%s\" failed\n"), + WEECHAT_ERROR, WEECHAT_NAME, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + for (i = 0; irc_commands[i].command_name; i++) + { + if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && + ((irc_commands[i].cmd_function_args) || + (irc_commands[i].cmd_function_1arg))) + { + if ((argc < irc_commands[i].min_arg) + || (argc > irc_commands[i].max_arg)) + { + if (irc_commands[i].min_arg == irc_commands[i].max_arg) + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + else + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].min_arg, irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + } + else + { + if ((irc_commands[i].need_connection) && + ((!server) || (!server->is_connected))) + { + gui_printf (NULL, + _("%s command \"%s\" needs a server connection!\n"), + WEECHAT_ERROR, irc_commands[i].command_name); + return 0; + } + if (irc_commands[i].cmd_function_args) + return_code = (int) (irc_commands[i].cmd_function_args) + (server, argc, argv); + else + return_code = (int) (irc_commands[i].cmd_function_1arg) + (server, ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s IRC command \"%s\" failed\n"), + WEECHAT_ERROR, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) + { + if (ptr_args) + { + length1 = strlen (ptr_alias->alias_command); + length2 = strlen (ptr_args); + alias_command = (char *)malloc (length1 + 1 + length2 + 1); + strcpy (alias_command, ptr_alias->alias_command); + alias_command[length1] = ' '; + strcpy (alias_command + length1 + 1, ptr_args); + exec_weechat_command (server, alias_command); + free (alias_command); + } + else + exec_weechat_command (server, ptr_alias->alias_command); + + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + gui_printf (NULL, + _("%s unknown command \"%s\" (type /help for help)\n"), + WEECHAT_ERROR, + command + 1); + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 0; +} + +/* + * user_command: interprets user command (if beginning with '/') + * any other text is sent to the server, if connected + */ + +void +user_command (t_irc_server *server, 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) */ + exec_weechat_command (server, command); + } + else + { + if ((command[0] == '/') && (command[1] == '/')) + command++; + if (server && (!WIN_IS_SERVER(gui_current_window))) + { + server_sendf (server, "PRIVMSG %s :%s\r\n", + CHANNEL(gui_current_window)->name, + command); + + if (WIN_IS_PRIVATE(gui_current_window)) + { + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_CHAT_DARK, "<"); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_NICK_SELF, + "%s", server->nick); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_CHAT_DARK, "> "); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_MSG, + COLOR_WIN_CHAT, "%s\n", command); + } + else + { + ptr_nick = nick_search (CHANNEL(gui_current_window), server->nick); + if (ptr_nick) + { + irc_display_nick (CHANNEL(gui_current_window)->window, ptr_nick, + MSG_TYPE_NICK, 1, 1, 0); + gui_printf_color (CHANNEL(gui_current_window)->window, + COLOR_WIN_CHAT, "%s\n", command); + } + else + gui_printf (server->window, + _("%s cannot find nick for sending message\n"), + WEECHAT_ERROR); + } + } + else + gui_printf ((server) ? server->window : NULL, + _("This window is not a channel!\n")); + } +} + +/* + * weechat_cmd_alias: display or create alias + */ + +int +weechat_cmd_alias (char *arguments) +{ + char *pos; + t_weechat_alias *ptr_alias; + + if (arguments && arguments[0]) + { + /* Define new alias */ + pos = strchr (arguments, ' '); + if (pos) + { + pos[0] = '\0'; + pos++; + while (pos[0] == ' ') + pos++; + if (!pos[0]) + { + gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), + WEECHAT_ERROR, "alias"); + return -1; + } + index_command_new (arguments); + if (!alias_new (arguments, pos)) + return -1; + gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"), + arguments, pos); + } + else + { + gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), + WEECHAT_ERROR, "alias"); + return -1; + } + } + else + { + /* List all aliases */ + if (weechat_alias) + { + gui_printf (NULL, _("List of aliases:\n")); + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + gui_printf (NULL, " %s => %s\n", + ptr_alias->alias_name, + ptr_alias->alias_command + 1); + } + } + else + gui_printf (NULL, _("No alias defined.\n")); + } + return 0; +} + +/* + * weechat_cmd_clear: display or create alias + */ + +int +weechat_cmd_clear (int argc, char **argv) +{ + if (argc == 1) + { + if (strcmp (argv[0], "-all") == 0) + gui_window_clear_all (); + else + { + gui_printf (NULL, + _("unknown parameter \"%s\" for \"%s\" command\n"), + argv[0], "clear"); + return -1; + } + } + else + gui_window_clear (gui_current_window); + return 0; +} + +/* + * weechat_cmd_connect: connect to a server + */ + +int +weechat_cmd_connect (int argc, char **argv) +{ + t_irc_server *ptr_server; + t_irc_channel *ptr_channel; + + /* make gcc happy */ + (void) argc; + + ptr_server = server_search (argv[0]); + if (ptr_server) + { + if (ptr_server->is_connected) + { + gui_printf (NULL, + _("%s already connected to server \"%s\"!\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + if (!ptr_server->window) + gui_window_new (ptr_server, NULL); + if (server_connect (ptr_server)) + { + irc_login (ptr_server); + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + if (ptr_channel->type == CHAT_CHANNEL) + server_sendf (ptr_server, "JOIN %s\r\n", ptr_channel->name); + } + } + } + else + { + gui_printf (NULL, + _("%s server \"%s\" not found\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + return 0; +} + +/* + * weechat_cmd_disconnect: disconnect from a server + */ + +int +weechat_cmd_disconnect (int argc, char **argv) +{ + t_irc_server *ptr_server; + + /* make gcc happy */ + (void) argc; + + ptr_server = server_search (argv[0]); + if (ptr_server) + { + if (!ptr_server->is_connected) + { + gui_printf (NULL, + _("%s not connected to server \"%s\"!\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + server_disconnect (ptr_server); + gui_redraw_window_status (gui_current_window); + } + else + { + gui_printf (NULL, + _("%s server \"%s\" not found\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + return 0; +} + +/* + * weechat_cmd_help: display help + */ + +int +weechat_cmd_help (int argc, char **argv) +{ + int i; + + if (argc == 0) + { + gui_printf (NULL, + _("> List of %s internal commands:\n"), WEECHAT_NAME); + for (i = 0; weechat_commands[i].command_name; i++) + gui_printf (NULL, " %s - %s\n", + weechat_commands[i].command_name, + weechat_commands[i].command_description); + gui_printf (NULL, _("> List of IRC commands:\n")); + for (i = 0; irc_commands[i].command_name; i++) + if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg) + gui_printf (NULL, " %s - %s\n", + irc_commands[i].command_name, + irc_commands[i].command_description); + } + if (argc == 1) + { + for (i = 0; weechat_commands[i].command_name; i++) + { + if (strcasecmp (weechat_commands[i].command_name, argv[0]) == 0) + { + gui_printf + (NULL, + _("> Help on %s internal command \"%s\":\n"), + WEECHAT_NAME, weechat_commands[i].command_name); + gui_printf (NULL, + _("Syntax: /%s %s\n"), + weechat_commands[i].command_name, + (weechat_commands[i]. + arguments) ? weechat_commands[i]. + arguments : ""); + if (weechat_commands[i].arguments_description) + { + gui_printf (NULL, "%s\n", + weechat_commands[i]. + arguments_description); + } + return 0; + } + } + for (i = 0; irc_commands[i].command_name; i++) + { + if (strcasecmp (irc_commands[i].command_name, argv[0]) == 0) + { + gui_printf (NULL, + _("> Help on IRC command \"%s\":\n"), + irc_commands[i].command_name); + gui_printf (NULL, _("Syntax: /%s %s\n"), + irc_commands[i].command_name, + (irc_commands[i].arguments) ? + irc_commands[i].arguments : ""); + if (irc_commands[i].arguments_description) + { + gui_printf (NULL, "%s\n", + irc_commands[i]. + arguments_description); + } + return 0; + } + } + gui_printf (NULL, + _("No help available, \"%s\" is an unknown command\n"), + argv[0]); + } + return 0; +} + +/* + * weechat_cmd_server: list, add or remove server(s) + */ + +int +weechat_cmd_server (int argc, char **argv) +{ + int i; + t_irc_server server, *ptr_server, *server_found, *new_server; + + if ((argc == 0) || ((argc == 1) && (strcasecmp (argv[0], "list") == 0))) + { + /* list all servers */ + if (irc_servers) + { + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _("Server: ")); + gui_printf_color (NULL, + COLOR_WIN_CHAT_CHANNEL, + "%s", ptr_server->name); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " ["); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s", + (ptr_server->is_connected) ? + _("connected") : _("not connected")); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + "]\n"); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Autoconnect: %s\n"), + (ptr_server->autoconnect) ? _("yes") : _("no")); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Hostname : %s\n"), + ptr_server->address); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Port : %d\n"), + ptr_server->port); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->password && ptr_server->password[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Password : (hidden)\n")); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Password : (none)\n")); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Nicks : %s"), + ptr_server->nick1); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " / "); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s", ptr_server->nick2); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " / "); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s\n", ptr_server->nick3); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Username : %s\n"), + ptr_server->username); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Realname : %s\n"), + ptr_server->realname); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->command && ptr_server->command[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Command : %s\n"), + ptr_server->command); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Command : (none)\n")); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->autojoin && ptr_server->autojoin[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Auto-join : %s\n"), + ptr_server->autojoin); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Auto-join : (none)\n")); + } + } + else + gui_printf (NULL, _("No server.\n")); + } + else + { + if (strcasecmp (argv[0], "del") == 0) + { + if (argc < 2) + { + gui_printf (NULL, + _("%s missing servername for \"%s\" command\n"), + WEECHAT_ERROR, "server del"); + return -1; + } + if (argc > 2) + gui_printf (NULL, + _("%s too much arguments for \"%s\" command, ignoring arguments\n"), + WEECHAT_WARNING, "server del"); + + /* look for server by name */ + server_found = NULL; + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + if (strcmp (ptr_server->name, argv[1]) == 0) + { + server_found = ptr_server; + break; + } + } + if (!server_found) + { + gui_printf (NULL, + _("%s server \"%s\" not found for \"%s\" command\n"), + WEECHAT_ERROR, argv[1], "server del"); + return -1; + } + + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("Server")); + gui_printf_color (NULL, COLOR_WIN_CHAT_CHANNEL, + " %s ", server_found->name); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("has been deleted\n")); + + server_free (server_found); + gui_redraw_window (gui_current_window); + + return 0; + } + + /* init server struct */ + server_init (&server); + + if (argc < 3) + { + gui_printf (NULL, + _("%s missing parameters for \"%s\" command\n"), + WEECHAT_ERROR, "server"); + server_destroy (&server); + return -1; + } + + if (server_name_already_exists (argv[0])) + { + gui_printf (NULL, + _("%s server \"%s\" already exists, can't create it!\n"), + WEECHAT_ERROR, argv[0]); + server_destroy (&server); + return -1; + } + + server.name = strdup (argv[0]); + server.address = strdup (argv[1]); + server.port = atoi (argv[2]); + + /* parse arguments */ + for (i = 3; i < argc; i++) + { + if (argv[i][0] == '-') + { + if (strcasecmp (argv[i], "-auto") == 0) + server.autoconnect = 1; + if (strcasecmp (argv[i], "-noauto") == 0) + server.autoconnect = 0; + if (strcasecmp (argv[i], "-pwd") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-pwd"); + server_destroy (&server); + return -1; + } + server.password = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-nicks") == 0) + { + if (i >= (argc - 3)) + { + gui_printf (NULL, + _("%s missing nick(s) for \"%s\" parameter\n"), + WEECHAT_ERROR, "-nicks"); + server_destroy (&server); + return -1; + } + server.nick1 = strdup (argv[++i]); + server.nick2 = strdup (argv[++i]); + server.nick3 = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-username") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-username"); + server_destroy (&server); + return -1; + } + server.username = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-realname") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-realname"); + server_destroy (&server); + return -1; + } + server.realname = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-command") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing command for \"%s\" parameter\n"), + WEECHAT_ERROR, "-command"); + server_destroy (&server); + return -1; + } + server.command = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-autojoin") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-autojoin"); + server_destroy (&server); + return -1; + } + server.autojoin = strdup (argv[++i]); + } + } + } + + /* create new server */ + new_server = server_new (server.name, server.autoconnect, server.address, + server.port, server.password, server.nick1, + server.nick2, server.nick3, server.username, + server.realname, server.command, + server.autojoin); + if (new_server) + { + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("Server")); + gui_printf_color (NULL, COLOR_WIN_CHAT_CHANNEL, + " %s ", server.name); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("created\n")); + } + else + { + gui_printf (NULL, + _("%s unable to create server\n"), + WEECHAT_ERROR); + server_destroy (&server); + return -1; + } + + if (new_server->autoconnect) + { + gui_window_new (new_server, NULL); + if (server_connect (new_server)) + irc_login (new_server); + } + + server_destroy (&server); + } + return 0; +} + +/* + * weechat_cmd_save: set options + */ + +int +weechat_cmd_save (int argc, char **argv) +{ + return (config_write ((argc == 1) ? argv[0] : NULL)); +} + +/* + * weechat_cmd_set: set options + */ + +int +weechat_cmd_set (int argc, char **argv) +{ + int i, j, section_displayed; + char *color_name; + + /* TODO: complete /set command */ + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + section_displayed = 0; + if (i != CONFIG_SECTION_SERVER) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + if ((argc == 0) || + ((argc > 0) + && (strstr (weechat_options[i][j].option_name, argv[0]) + != NULL))) + { + if (!section_displayed) + { + gui_printf (NULL, "[%s]\n", + config_sections[i].section_name); + section_displayed = 1; + } + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + gui_printf (NULL, " %s = %s\n", + weechat_options[i][j].option_name, + (*weechat_options[i][j].ptr_int) ? + "ON" : "OFF"); + break; + case OPTION_TYPE_INT: + gui_printf (NULL, + " %s = %d\n", + weechat_options[i][j].option_name, + *weechat_options[i][j].ptr_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + gui_printf (NULL, + " %s = %s\n", + weechat_options[i][j].option_name, + weechat_options[i][j].array_values[*weechat_options[i][j].ptr_int]); + break; + case OPTION_TYPE_COLOR: + color_name = gui_get_color_by_value (*weechat_options[i][j].ptr_int); + gui_printf (NULL, + " %s = %s\n", + weechat_options[i][j].option_name, + (color_name) ? color_name : _("(unknown)")); + break; + case OPTION_TYPE_STRING: + gui_printf (NULL, " %s = %s\n", + weechat_options[i][j]. + option_name, + (*weechat_options[i][j]. + ptr_string) ? + *weechat_options[i][j]. + ptr_string : ""); + break; + } + } + } + } + } + gui_printf (NULL, "(TODO) \"/set\" command not developed!\n"); + return 0; +} + +/* + * cmd_unalias: remove an alias + */ + +int +weechat_cmd_unalias (char *arguments) +{ + t_index_command *ptr_index; + t_weechat_alias *ptr_alias; + + ptr_index = index_command_search (arguments); + if (!ptr_index) + { + gui_printf (NULL, _("%s alias or command \"%s\" not found\n"), + WEECHAT_ERROR, arguments); + return -1; + } + + index_command_free (ptr_index); + ptr_alias = alias_search (arguments); + if (ptr_alias) + alias_free (ptr_alias); + gui_printf (NULL, _("Alias \"%s\" removed\n"), + arguments); + return 0; +} diff --git a/src/common/command.h b/src/common/command.h new file mode 100644 index 000000000..2be48eded --- /dev/null +++ b/src/common/command.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_COMMAND_H +#define __WEECHAT_COMMAND_H 1 + +#include "../irc/irc.h" + +#define MAX_ARGS 8192 + +typedef struct t_weechat_command t_weechat_command; + +struct t_weechat_command +{ + char *command_name; + char *command_description; + char *arguments; + char *arguments_description; + int min_arg, max_arg; + int (*cmd_function_args)(int, char **); + int (*cmd_function_1arg)(char *); +}; + +typedef struct t_weechat_alias t_weechat_alias; + +struct t_weechat_alias +{ + char *alias_name; + char *alias_command; + t_weechat_alias *prev_alias; + t_weechat_alias *next_alias; +}; + +typedef struct t_index_command t_index_command; + +struct t_index_command +{ + char *command_name; + t_index_command *prev_index; + t_index_command *next_index; +}; + +extern t_weechat_alias *weechat_alias; +extern t_index_command *index_commands; + +extern t_index_command *index_command_new (char *); +extern void index_command_build (); +extern t_weechat_alias *alias_new (char *, char *); +extern int exec_weechat_command (t_irc_server *, char *); +extern void user_command (t_irc_server *, char *); +extern int weechat_cmd_alias (char *); +extern int weechat_cmd_clear (int, char **); +extern int weechat_cmd_connect (int, char **); +extern int weechat_cmd_disconnect (int, char **); +extern int weechat_cmd_help (int, char **); +extern int weechat_cmd_server (int, char **); +extern int weechat_cmd_save (int, char **); +extern int weechat_cmd_set (int, char **); +extern int weechat_cmd_unalias (char *); + +#endif /* command.h */ diff --git a/src/common/completion.c b/src/common/completion.c new file mode 100644 index 000000000..a050e2f0b --- /dev/null +++ b/src/common/completion.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* completion.c: completes words according to context (cmd/nick) */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "completion.h" +#include "../irc/irc.h" +#include "command.h" + + +/* + * completion_init: init completion + */ + +void +completion_init (t_completion *completion) +{ + completion->position = -1; + completion->base_word = NULL; +} + +/* + * completion_free: free completion + */ + +void +completion_free (t_completion *completion) +{ + if (completion->base_word) + free (completion->base_word); +} + +/* + * completion_command: complete a command + */ + +void +completion_command (t_completion *completion) +{ + int length, word_found_seen; + t_index_command *ptr_index; + + length = strlen (completion->base_word) - 1; + word_found_seen = 0; + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strncasecmp (ptr_index->command_name, completion->base_word + 1, length) == 0) + { + if ((!completion->word_found) || word_found_seen) + { + completion->word_found = ptr_index->command_name; + return; + } + } + if (completion->word_found && + (strcasecmp (ptr_index->command_name, completion->word_found) == 0)) + word_found_seen = 1; + } + if (completion->word_found) + { + completion->word_found = NULL; + completion_command (completion); + } +} + +/* + * completion_nick: complete a nick + */ + +void +completion_nick (t_completion *completion, t_irc_channel *channel) +{ + int length, word_found_seen; + t_irc_nick *ptr_nick; + + length = strlen (completion->base_word); + word_found_seen = 0; + for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + { + if (strncasecmp (ptr_nick->nick, completion->base_word, length) == 0) + { + if ((!completion->word_found) || word_found_seen) + { + completion->word_found = ptr_nick->nick; + return; + } + } + if (completion->word_found && + (strcasecmp (ptr_nick->nick, completion->word_found) == 0)) + word_found_seen = 1; + } + if (completion->word_found) + { + completion->word_found = NULL; + completion_nick (completion, channel); + } +} + +/* + * completion_search: complete word according to context + */ + +void +completion_search (t_completion *completion, void *channel, + char *buffer, int size, int pos) +{ + int i, pos_start, pos_end; + char *old_word_found; + + /* TODO: complete when no word is there with command according to context */ + if (size == 0) + { + completion->word_found = NULL; + return; + } + + /* if new complation => look for base word */ + if (pos != completion->position) + { + completion->word_found = NULL; + + if ((pos == size) || (buffer[pos-1] != ' ')) + pos--; + if ((pos > 0) && (buffer[pos] == ' ')) + return; + + i = pos; + while ((i >= 0) && (buffer[i] != ' ')) + i--; + pos_start = i + 1; + i = pos; + while ((i < size) && (buffer[i] != ' ')) + i++; + pos_end = i - 1; + + if (pos_start > pos_end) + return; + + completion->base_word_pos = pos_start; + + if (completion->base_word) + free (completion->base_word); + completion->base_word = (char *) malloc (pos_end - pos_start + 2); + + for (i = pos_start; i <= pos_end; i++) + completion->base_word[i - pos_start] = buffer[i]; + completion->base_word[pos_end - pos_start + 1] = '\0'; + + if (completion->base_word[0] == '/') + completion->position_replace = pos_start + 1; + else + completion->position_replace = pos_start; + } + + /* completion */ + old_word_found = completion->word_found; + if (completion->base_word[0] == '/') + { + completion_command (completion); + if (completion->word_found) + { + if (old_word_found) + completion->diff_size = strlen (completion->word_found) - + strlen (old_word_found); + else + completion->diff_size = strlen (completion->word_found) - + strlen (completion->base_word) + 1; + } + } + else + { + if (channel) + { + completion_nick (completion, (t_irc_channel *)channel); + if (completion->word_found) + { + if (old_word_found) + completion->diff_size = strlen (completion->word_found) - + strlen (old_word_found); + else + completion->diff_size = strlen (completion->word_found) - + strlen (completion->base_word); + } + } + } +} diff --git a/src/common/completion.h b/src/common/completion.h new file mode 100644 index 000000000..d1111dbaa --- /dev/null +++ b/src/common/completion.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_COMPLETION_H +#define __WEECHAT_COMPLETION_H 1 + +typedef struct t_completion t_completion; + +struct t_completion +{ + char *base_word; /* word to complete (when Tab was pressed) */ + int base_word_pos; /* beggining of base word */ + int position; /* position where we shoud complete */ + char *word_found; /* word found (to replace base word) */ + int position_replace; /* position where word should be replaced */ + int diff_size; /* size difference (< 0 = char(s) deleted) */ +}; + +extern void completion_init (t_completion *); +extern void completion_free (t_completion *); +extern void completion_search (t_completion *, void *, char *, int, int); + +#endif /* completion.h */ diff --git a/src/common/config.c b/src/common/config.c new file mode 100644 index 000000000..a3b88ad43 --- /dev/null +++ b/src/common/config.c @@ -0,0 +1,1198 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* config.c: WeeChat configuration */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <time.h> + +#include "weechat.h" +#include "config.h" +#include "command.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* config sections */ + +t_config_section config_sections[CONFIG_NUMBER_SECTIONS] = +{ { CONFIG_SECTION_LOOK, "look" }, + { CONFIG_SECTION_COLORS, "colors" }, + { CONFIG_SECTION_HISTORY, "history" }, + { CONFIG_SECTION_LOG, "log" }, + { CONFIG_SECTION_DCC, "dcc" }, + { CONFIG_SECTION_PROXY, "proxy" }, + { CONFIG_SECTION_ALIAS, "alias" }, + { CONFIG_SECTION_SERVER, "server" } +}; + +/* config, look & feel section */ + +int cfg_look_set_title; +int cfg_look_startup_logo; +int cfg_look_startup_version; +char *cfg_look_weechat_slogan; +int cfg_look_color_nicks; +int cfg_look_color_actions; +int cfg_look_remove_colors_from_msgs; +int cfg_look_nicklist; +int cfg_look_nicklist_position; +char *cfg_look_nicklist_position_values[] = +{ "left", "right", "top", "bottom", NULL }; +int cfg_look_nicklist_min_size; +int cfg_look_nicklist_max_size; +int cfg_look_nickmode; +int cfg_look_nickmode_empty; +char *cfg_look_no_nickname; +char *cfg_look_completor; + +t_config_option weechat_options_look[] = +{ { "look_set_title", N_("set title for terminal window (curses GUI) with name & version"), + N_("set title for terminal window (curses GUI) with name & version"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_set_title, NULL, NULL }, + { "look_startup_logo", N_("display WeeChat logo at startup"), + N_("display WeeChat logo at startup"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_startup_logo, NULL, NULL }, + { "look_startup_version", N_("display WeeChat version at startup"), + N_("display WeeChat version at startup"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_startup_version, NULL, NULL }, + { "look_weechat_slogan", N_("WeeChat slogan"), + N_("WeeChat slogan (if empty, slogan is not used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "the geekest IRC client!", NULL, NULL, &cfg_look_weechat_slogan, NULL }, + { "look_color_nicks", N_("display nick names with different colors"), + N_("display nick names with different colors"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_color_nicks, NULL, NULL }, + { "look_color_actions", N_("display actions with different colors"), + N_("display actions with different colors"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_color_actions, NULL, NULL }, + { "look_remove_colors_from_msgs", N_("remove colors from incoming messages"), + N_("remove colors from incoming messages"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_remove_colors_from_msgs, NULL, NULL }, + { "look_nicklist", N_("display nicklist window"), + N_("display nicklist window (for channel windows)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_nicklist, NULL, NULL }, + { "look_nicklist_position", N_("nicklist position"), + N_("nicklist position (top, left, right (default), bottom)"), + OPTION_TYPE_INT_WITH_STRING, 0, 0, 0, + "right", cfg_look_nicklist_position_values, &cfg_look_nicklist_position, NULL, NULL }, + { "look_nicklist_min_size", N_("min size for nicklist"), + N_("min size for nicklist (width or height, depending on look_nicklist_position " + "(0 = no min size))"), + OPTION_TYPE_INT, 0, 100, 0, + NULL, NULL, &cfg_look_nicklist_min_size, NULL, NULL }, + { "look_nicklist_max_size", N_("max size for nicklist"), + N_("max size for nicklist (width or height, depending on look_nicklist_position " + "(0 = no max size; if min == max and > 0, then size is fixed))"), + OPTION_TYPE_INT, 0, 100, 0, + NULL, NULL, &cfg_look_nicklist_max_size, NULL, NULL }, + { "look_no_nickname", N_("text to display instead of nick when not connected"), + N_("text to display instead of nick when not connected"), + OPTION_TYPE_STRING, 0, 0, 0, + "-cmd-", NULL, NULL, &cfg_look_no_nickname, NULL }, + { "look_nickmode", N_("display nick mode ((half)op/voice) before each nick"), + N_("display nick mode ((half)op/voice) before each nick"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_nickmode, NULL, NULL }, + { "look_nickmode_empty", N_("display space if nick mode is not (half)op/voice"), + N_("display space if nick mode is not (half)op/voice"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, + NULL, NULL, &cfg_look_nickmode_empty, NULL, NULL }, + { "look_nick_completor", N_("the string inserted after nick completion"), + N_("the string inserted after nick completion"), + OPTION_TYPE_STRING, 0, 0, 0, + ":", NULL, NULL, &cfg_look_completor, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, colors section */ + +int cfg_col_title; +int cfg_col_title_bg; +int cfg_col_chat; +int cfg_col_chat_time; +int cfg_col_chat_time_sep; +int cfg_col_chat_prefix1; +int cfg_col_chat_prefix2; +int cfg_col_chat_nick; +int cfg_col_chat_host; +int cfg_col_chat_channel; +int cfg_col_chat_dark; +int cfg_col_chat_bg; +int cfg_col_status; +int cfg_col_status_active; +int cfg_col_status_data_msg; +int cfg_col_status_data_other; +int cfg_col_status_more; +int cfg_col_status_bg; +int cfg_col_input; +int cfg_col_input_channel; +int cfg_col_input_nick; +int cfg_col_input_bg; +int cfg_col_nick; +int cfg_col_nick_op; +int cfg_col_nick_halfop; +int cfg_col_nick_voice; +int cfg_col_nick_sep; +int cfg_col_nick_self; +int cfg_col_nick_private; +int cfg_col_nick_bg; + +t_config_option weechat_options_colors[] = +{ /* title window */ + { "col_title", N_("color for title bar"), + N_("color for title bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_title, NULL, NULL }, + { "col_title_bg", N_("background for title bar"), + N_("background for title bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_title_bg, NULL, NULL }, + + /* chat window */ + { "col_chat", N_("color for chat text"), + N_("color for chat text"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_chat, NULL, NULL }, + { "col_chat_time", N_("color for time"), + N_("color for time in chat window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_chat_time, NULL, NULL }, + { "col_chat_time_sep", N_("color for time separator"), + N_("color for time separator (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "brown", NULL, &cfg_col_chat_time_sep, NULL, NULL }, + { "col_chat_prefix1", N_("color for 1st and 3rd char of prefix"), + N_("color for 1st and 3rd char of prefix"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightcyan", NULL, &cfg_col_chat_prefix1, NULL, NULL }, + { "col_chat_prefix2", N_("color for middle char of prefix"), + N_("color for middle char of prefix"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_chat_prefix2, NULL, NULL }, + { "col_chat_nick", N_("color for nicks in actions"), + N_("color for nicks in actions (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightcyan", NULL, &cfg_col_chat_nick, NULL, NULL }, + { "col_chat_host", N_("color for hostnames"), + N_("color for hostnames (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "cyan", NULL, &cfg_col_chat_host, NULL, NULL }, + { "col_chat_channel", N_("color for channel names in actions"), + N_("color for channel names in actions (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_chat_channel, NULL, NULL }, + { "col_chat_dark", N_("color for dark separators"), + N_("color for dark separators (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "green", NULL, &cfg_col_chat_dark, NULL, NULL }, + { "col_chat_bg", N_("background for chat"), + N_("background for chat window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_chat_bg, NULL, NULL }, + + /* status window */ + { "col_status", N_("color for status bar"), + N_("color for status bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_status, NULL, NULL }, + { "col_status_active", N_("color for active window"), + N_("color for active window (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "yellow", NULL, &cfg_col_status_active, NULL, NULL }, + { "col_status_data_msg", N_("color for window with new messages"), + N_("color for window with new messages (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightred", NULL, &cfg_col_status_data_msg, NULL, NULL }, + { "col_status_data_other", N_("color for window with new data (not messages)"), + N_("color for window with new data (not messages) (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightmagenta", NULL, &cfg_col_status_data_other, NULL, NULL }, + { "col_status_more", N_("color for \"*MORE*\" text"), + N_("color for window with new data (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_status_more, NULL, NULL }, + { "col_status_bg", N_("background for status window"), + N_("background for status window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_status_bg, NULL, NULL }, + + /* input window */ + { "col_input", N_("color for input text"), + N_("color for input text"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_input, NULL, NULL }, + { "col_input_channel", N_("color for input text (channel name)"), + N_("color for input text (channel name)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_input_channel, NULL, NULL }, + { "col_input_nick", N_("color for input text (nick name)"), + N_("color for input text (nick name)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightgreen", NULL, &cfg_col_input_nick, NULL, NULL }, + { "col_input_bg", N_("background for input window"), + N_("background for input window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_input_bg, NULL, NULL }, + + /* nick window */ + { "col_nick", N_("color for nicknames"), + N_("color for nicknames"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_nick, NULL, NULL }, + { "col_nick_op", N_("color for operator symbol"), + N_("color for operator symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightgreen", NULL, &cfg_col_nick_op, NULL, NULL }, + { "col_nick_halfop", N_("color for half-operator symbol"), + N_("color for half-operator symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightmagenta", NULL, &cfg_col_nick_halfop, NULL, NULL }, + { "col_nick_voice", N_("color for voice symbol"), + N_("color for voice symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "yellow", NULL, &cfg_col_nick_voice, NULL, NULL }, + { "col_nick_sep", N_("color for nick separator"), + N_("color for nick separator"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_nick_sep, NULL, NULL }, + { "col_nick_self", N_("color for local nick"), + N_("color for local nick"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_nick_self, NULL, NULL }, + { "col_nick_private", N_("color for other nick in private window"), + N_("color for other nick in private window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "brown", NULL, &cfg_col_nick_private, NULL, NULL }, + { "col_nick_bg", N_("background for nicknames"), + N_("background for nicknames"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_nick_bg, NULL, NULL }, + + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, history section */ + +int cfg_history_max_lines; +int cfg_history_max_commands; + +t_config_option weechat_options_history[] = +{ { "history_max_lines", N_("max lines in history (per window)"), + N_("maximum number of lines in history " + "for one server/channel/private window (0 = unlimited)"), + OPTION_TYPE_INT, 0, INT_MAX, 4096, + NULL, NULL, &cfg_history_max_lines, NULL, NULL }, + { "history_max_commands", N_("max user commands in history"), + N_("maximum number of user commands in history (0 = unlimited)"), + OPTION_TYPE_INT, 0, INT_MAX, 100, + NULL, NULL, &cfg_history_max_commands, NULL, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, log section */ + +int cfg_log_auto_channels; +int cfg_log_auto_private; +char *cfg_log_path; +char *cfg_log_name; +char *cfg_log_timestamp; +char *cfg_log_start_string; +char *cfg_log_end_string; + +t_config_option weechat_options_log[] = +{ { "log_auto_channels", N_("automatically log channel chats"), + N_("automatically log channel chats"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_log_auto_channels, NULL, NULL }, + { "log_auto_private", N_("automatically log private chats"), + N_("automatically log private chats"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_log_auto_private, NULL, NULL }, + { "log_path", N_("path for log files"), + N_("path for WeeChat log files"), + OPTION_TYPE_STRING, 0, 0, 0, + "~/.weechat/logs/", NULL, NULL, &cfg_log_path, NULL }, + { "log_name", N_("name for log files"), + N_("name for log files (%S == irc server name, " + "%N == channel name (or nickname if private chat)"), + OPTION_TYPE_STRING, 0, 0, 0, + "%S,%N.weechatlog", NULL, NULL, &cfg_log_name, NULL }, + { "log_timestamp", N_("timestamp for log"), + N_("timestamp for log (see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "~", NULL, NULL, &cfg_log_timestamp, NULL }, + { "log_start_string", N_("start string for log files"), + N_("text written when starting new log file " + "(see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "--- Log started %a %b %d %Y %H:%M:%s", NULL, NULL, &cfg_log_start_string, NULL }, + { "log_end_string", N_("end string for log files"), + N_("text written when ending log file " + "(see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "--- Log ended %a %b %d %Y %H:%M:%s", NULL, NULL, &cfg_log_end_string, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, dcc section */ + +int cfg_dcc_auto_accept_files; +int cfg_dcc_auto_accept_max_size; +int cfg_dcc_auto_accept_chats; +int cfg_dcc_timeout; +char *cfg_dcc_download_path; +char *cfg_dcc_upload_path; +int cfg_dcc_auto_rename; +int cfg_dcc_auto_resume; + +t_config_option weechat_options_dcc[] = +{ { "dcc_auto_accept_files", N_("automatically accept dcc files"), + N_("automatically accept incoming dcc files"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_accept_files, NULL, NULL }, + { "dcc_auto_accept_max_size", N_("max size when auto accepting file"), + N_("maximum size for incoming file when automatically accepted"), + OPTION_TYPE_INT, 0, INT_MAX, 0, + NULL, NULL, &cfg_dcc_auto_accept_max_size, NULL, NULL }, + { "dcc_auto_accept_chats", N_("automatically accept dcc chats"), + N_("automatically accept dcc chats (use carefully!)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_accept_chats, NULL, NULL }, + { "dcc_timeout", N_("timeout for dcc request"), + N_("timeout for dcc request (in seconds)"), + OPTION_TYPE_INT, 1, INT_MAX, 300, + NULL, NULL, &cfg_dcc_timeout, NULL, NULL }, + { "dcc_download_path", N_("path for incoming files with dcc"), + N_("path for writing incoming files with dcc (default: user home)"), + OPTION_TYPE_STRING, 0, 0, 0, "~", + NULL, NULL, &cfg_dcc_download_path, NULL }, + { "dcc_upload_path", N_("default path for sending files with dcc"), + N_("path for reading files when sending thru dcc (when no path is specified)"), + OPTION_TYPE_STRING, 0, 0, 0, "~", + NULL, NULL, &cfg_dcc_upload_path, NULL }, + { "dcc_auto_rename", N_("automatically rename dcc files if already exists"), + N_("rename incoming files if already exists (add '.1', '.2', ...)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_rename, NULL, NULL }, + { "dcc_auto_resume", N_("automatically resume aborted transfers"), + N_("automatically resume dcc transfer if connection with remote host is loosed"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_resume, NULL, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, proxy section */ + +int cfg_proxy_use; +char *cfg_proxy_address; +int cfg_proxy_port; +char *cfg_proxy_password; + +t_config_option weechat_options_proxy[] = +{ { "proxy_use", N_("use proxy"), + N_("use a proxy server to connect to irc server"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, + NULL, NULL, &cfg_proxy_use, NULL, NULL }, + { "proxy_address", N_("proxy address"), + N_("proxy server address (IP or hostname)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &cfg_proxy_address, NULL }, + { "proxy_port", N_("port for proxy"), + N_("port for connecting to proxy server"), + OPTION_TYPE_INT, 0, 65535, 1080, + NULL, NULL, &cfg_proxy_port, NULL, NULL }, + { "proxy_password", N_("proxy password"), + N_("password for proxy server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &cfg_proxy_password, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, server section */ + +static t_irc_server cfg_server; + +t_config_option weechat_options_server[] = +{ { "server_name", N_("server name"), + N_("name associated to IRC server (for display only)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.name), NULL }, + { "server_autoconnect", N_("automatically connect to server"), + N_("automatically connect to server when WeeChat is starting"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &(cfg_server.autoconnect), NULL, NULL }, + { "server_address", N_("server address or hostname"), + N_("IP address or hostname of IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.address), NULL }, + { "server_port", N_("port for IRC server"), + N_("port for connecting to server"), + OPTION_TYPE_INT, 0, 65535, 6667, + NULL, NULL, &(cfg_server.port), NULL, NULL }, + { "server_password", N_("server password"), + N_("password for IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.password), NULL }, + { "server_nick1", N_("nickname for server"), + N_("nickname to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick1), NULL }, + { "server_nick2", N_("alternate nickname for server"), + N_("alternate nickname to use on IRC server (if nickname is already used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick2), NULL }, + { "server_nick3", N_("2nd alternate nickname for server"), + N_("2nd alternate nickname to use on IRC server (if alternate nickname is already used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick3), NULL }, + { "server_username", N_("user name for server"), + N_("user name to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.username), NULL }, + { "server_realname", N_("real name for server"), + N_("real name to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.realname), NULL }, + { "server_command", N_("first command to run when connected to server"), + N_("first command to run when connected to server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.command), NULL }, + { "server_autojoin", N_("list of channels to join when connected to server"), + N_("comma separated list of channels to join when connected to server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.autojoin), NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* all weechat options */ + +t_config_option *weechat_options[CONFIG_NUMBER_SECTIONS] = +{ weechat_options_look, weechat_options_colors, weechat_options_history, + weechat_options_log, weechat_options_dcc, weechat_options_proxy, + NULL, weechat_options_server +}; + + +/* + * get_pos_array_values: returns position of a string in an array of values + * returns -1 if not found, otherwise position + */ + +int +get_pos_array_values (char **array, char *string) +{ + int i; + + i = 0; + while (array[i]) + { + if (strcasecmp (array[i], string) == 0) + return i; + i++; + } + /* string not found in array */ + return -1; +} + +/* + * config_option_set_value: set new value for an option + * return: 0 if success + * -1 if error (bad value) + */ + +int +config_option_set_value (t_config_option *option, char *value) +{ + int int_value; + + switch (option->option_type) + { + case OPTION_TYPE_BOOLEAN: + if (strcasecmp (value, "on") == 0) + *(option->ptr_int) = BOOL_TRUE; + else if (strcasecmp (value, "off") == 0) + *(option->ptr_int) = BOOL_FALSE; + else + return -1; + break; + case OPTION_TYPE_INT: + int_value = atoi (value); + if ((int_value < option->min) || (int_value > option->max)) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = get_pos_array_values (option->array_values, value); + if (int_value < 0) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_COLOR: + if (!gui_assign_color (option->ptr_int, value)) + return -1; + break; + case OPTION_TYPE_STRING: + if (*(option->ptr_string)) + free (*(option->ptr_string)); + *(option->ptr_string) = strdup (value); + break; + } + return 0; +} + +/* + * config_set_value: set new value for an option (found by name) + * return: 0 if success + * -1 if bad value for option + * -2 if option is not found + */ + +int +config_set_value (char *option_name, char *value) +{ + int i, j; + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + /* if option found, assign value and exit */ + if (strcasecmp (weechat_options[i][j].option_name, option_name) == 0) + return config_option_set_value (&weechat_options[i][j], value); + } + } + } + /* option not found */ + return -2; +} + +/* + * config_allocate_server: allocate a new server + */ + +int +config_allocate_server (char *filename, int line_number) +{ + if (!cfg_server.name + || !cfg_server.address + || cfg_server.port < 0 + || !cfg_server.nick1 + || !cfg_server.nick2 + || !cfg_server.nick3 + || !cfg_server.username + || !cfg_server.realname) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: new server, but previous was incomplete\n"), + WEECHAT_WARNING, filename, line_number); + return 0; + + } + if (server_name_already_exists (cfg_server.name)) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: server '%s' already exists\n"), + WEECHAT_WARNING, filename, line_number, cfg_server.name); + return 0; + } + if (!server_new (cfg_server.name, + cfg_server.autoconnect, cfg_server.address, cfg_server.port, + cfg_server.password, cfg_server.nick1, cfg_server.nick2, + cfg_server.nick3, cfg_server.username, cfg_server.realname, + cfg_server.command, cfg_server.autojoin)) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: unable to create server\n"), + WEECHAT_WARNING, filename, line_number); + return 0; + } + + server_destroy (&cfg_server); + server_init (&cfg_server); + + return 1; +} + +/* + * config_default_values: initialize config variables with default values + */ + +void +config_default_values () +{ + int i, j, int_value; + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + case OPTION_TYPE_INT: + *weechat_options[i][j].ptr_int = + weechat_options[i][j].default_int; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = get_pos_array_values ( + weechat_options[i][j].array_values, + weechat_options[i][j].default_string); + if (int_value < 0) + gui_printf (NULL, + _("%s unable to assign default int with string (\"%s\")\n"), + weechat_options[i][j].default_string); + else + *weechat_options[i][j].ptr_int = + int_value; + break; + case OPTION_TYPE_COLOR: + if (!gui_assign_color ( + weechat_options[i][j].ptr_int, + weechat_options[i][j].default_string)) + gui_printf (NULL, + _("%s unable to assign default color (\"%s\")\n"), + weechat_options[i][j].default_string); + break; + case OPTION_TYPE_STRING: + *weechat_options[i][j].ptr_string = + strdup (weechat_options[i][j].default_string); + break; + } + } + } + } +} + +/* + * config_read: read WeeChat configuration + * returns: 0 = successful + * -1 = config file file not found + * < -1 = other error (fatal) + */ + +int +config_read () +{ + char *filename; + FILE *file; + int section, line_number, i, option_number; + int server_found; + char line[1024], *ptr_line, *pos, *pos2; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + if ((file = fopen (filename, "rt")) == NULL) + { + gui_printf (NULL, _("%s config file \"%s\" not found.\n"), + WEECHAT_WARNING, filename); + free (filename); + return -1; + } + + config_default_values (); + server_init (&cfg_server); + + /* read config file */ + section = CONFIG_SECTION_NONE; + server_found = 0; + line_number = 0; + while (!feof (file)) + { + ptr_line = fgets (line, sizeof (line) - 1, file); + line_number++; + if (ptr_line) + { + /* skip spaces */ + while (ptr_line[0] == ' ') + ptr_line++; + /* not a comment and not an empty line */ + if ((ptr_line[0] != '#') && (ptr_line[0] != '\r') + && (ptr_line[0] != '\n')) + { + /* beginning of section */ + if (ptr_line[0] == '[') + { + pos = strchr (line, ']'); + if (pos == NULL) + gui_printf (NULL, + _("%s %s, line %d: invalid syntax, missing \"]\"\n"), + WEECHAT_WARNING, filename, line_number); + else + { + pos[0] = '\0'; + pos = ptr_line + 1; + section = CONFIG_SECTION_NONE; + for (i = 0; config_sections[i].section_name; i++) + { + if (strcmp (config_sections[i].section_name, pos) == 0) + { + section = i; + break; + } + } + if (section == CONFIG_SECTION_NONE) + gui_printf (NULL, + _("%s %s, line %d: unknown section identifier (\"%s\")\n"), + WEECHAT_WARNING, filename, line_number, pos); + else + { + if (server_found) + { + /* if server already started => create it */ + config_allocate_server (filename, line_number); + } + server_found = (section == CONFIG_SECTION_SERVER) ? 1 : 0; + } + } + } + else + { + pos = strchr (line, '='); + if (pos == NULL) + gui_printf (NULL, + _("%s %s, line %d: invalid syntax, missing \"=\"\n"), + WEECHAT_WARNING, filename, line_number); + else + { + pos[0] = '\0'; + pos++; + pos2 = strchr (pos, '\r'); + if (pos2 != NULL) + pos2[0] = '\0'; + pos2 = strchr (pos, '\n'); + if (pos2 != NULL) + pos2[0] = '\0'; + + if (section == CONFIG_SECTION_ALIAS) + { + if (alias_new (line, pos)) + index_command_new (pos); + } + else + { + option_number = -1; + for (i = 0; + weechat_options[section][i].option_name; i++) + { + if (strcmp + (weechat_options[section][i].option_name, + ptr_line) == 0) + { + option_number = i; + break; + } + } + if (option_number < 0) + gui_printf (NULL, + _("%s %s, line %d: invalid option \"%s\"\n"), + WEECHAT_WARNING, filename, line_number, ptr_line); + else + { + if (config_option_set_value (&weechat_options[section][option_number], pos) < 0) + { + switch (weechat_options[section] + [option_number].option_type) + { + case OPTION_TYPE_BOOLEAN: + gui_printf (NULL, + _("%s %s, line %d: invalid value for" + "option '%s'\n" + "Expected: boolean value: " + "'off' or 'on'\n"), + WEECHAT_WARNING, filename, + line_number, ptr_line); + break; + case OPTION_TYPE_INT: + gui_printf (NULL, + _("%s %s, line %d: invalid value for " + "option '%s'\n" + "Expected: integer between %d " + "and %d\n"), + WEECHAT_WARNING, filename, + line_number, ptr_line, + weechat_options[section][option_number].min, + weechat_options[section][option_number].max); + break; + case OPTION_TYPE_INT_WITH_STRING: + gui_printf (NULL, + _("%s %s, line %d: invalid value for " + "option '%s'\n" + "Expected: one of these strings: "), + WEECHAT_WARNING, filename, + line_number, ptr_line); + i = 0; + while (weechat_options[section][option_number].array_values[i]) + { + gui_printf (NULL, "\"%s\" ", + weechat_options[section][option_number].array_values[i]); + i++; + } + gui_printf (NULL, "\n"); + break; + case OPTION_TYPE_COLOR: + gui_printf (NULL, + _("%s %s, line %d: invalid color " + "name for option '%s'\n"), + WEECHAT_WARNING, filename, + line_number, + ptr_line); + break; + } + } + } + } + } + } + } + } + } + + if (server_found) + { + if (!config_allocate_server (filename, line_number)) + { + fclose (file); + free (filename); + return -2; + } + } + + /* set default colors for colors not set */ + /*for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if (i != CONFIG_SECTION_SERVER) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + if ((weechat_options[i][j].option_type == OPTION_TYPE_COLOR) && + (*weechat_options[i][j].ptr_int == COLOR_NOT_SET)) + *weechat_options[i][j].ptr_int = + gui_get_color_by_name (weechat_options[i][j].default_string); + } + } + }*/ + + fclose (file); + free (filename); + + return 0; +} + + +/* + * config_create_default: create default WeeChat config + * return: 0 if ok + * < 0 if error + */ + +int +config_create_default () +{ + char *filename; + char line[1024]; + FILE *file; + int i, j; + time_t current_time; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + if ((file = fopen (filename, "wt")) == NULL) + { + gui_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename); + free (filename); + return -1; + } + + printf (_("%s: creating default config file...\n"), WEECHAT_NAME); + log_printf (_("creating default config file\n")); + + current_time = time (NULL); + sprintf (line, _("#\n# %s configuration file, created by " + "%s v%s on %s#\n"), + WEECHAT_NAME, WEECHAT_NAME, WEECHAT_VERSION, + ctime (¤t_time)); + fputs (line, file); + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + sprintf (line, "\n[%s]\n", config_sections[i].section_name); + fputs (line, file); + if ((i == CONFIG_SECTION_HISTORY) || (i == CONFIG_SECTION_LOG) || + (i == CONFIG_SECTION_DCC) || (i == CONFIG_SECTION_PROXY)) + { + sprintf (line, + "# WARNING!!! Options for section \"%s\" are not developed!\n", + config_sections[i].section_name); + fputs (line, file); + } + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].default_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + sprintf (line, "%s=%d\n", + weechat_options[i][j].option_name, + weechat_options[i][j].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + case OPTION_TYPE_COLOR: + case OPTION_TYPE_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + weechat_options[i][j].default_string); + break; + } + fputs (line, file); + } + } + } + + /* default aliases */ + /* TODO: remove comments when missing commands will be ok */ + fputs ("\n[alias]\n", file); + fputs ("SAY=msg *\n", file); + fputs ("BYE=quit\n", file); + fputs ("EXIT=quit\n", file); + fputs ("SIGNOFF=quit\n", file); + fputs ("C=clear\n", file); + fputs ("CL=clear\n", file); + fputs ("# CHAT=dcc chat\n", file); + fputs ("# GET=dcc get\n", file); + fputs ("# IG=ignore\n", file); + fputs ("J=join\n", file); + fputs ("K=kick\n", file); + fputs ("# KB=kickban\n", file); + fputs ("# KN=knockout\n", file); + fputs ("LEAVE=part\n", file); + fputs ("M=msg\n", file); + fputs ("# MUB=unban *\n", file); + fputs ("N=names\n", file); + fputs ("T=topic\n", file); + fputs ("# UB=unban\n", file); + fputs ("# UNIG=unignore\n", file); + fputs ("# W=who\n", file); + fputs ("WC=part\n", file); + fputs ("WI=whois\n", file); + fputs ("# WW=whowas\n", file); + + /* default server is freenode */ + fputs ("\n[server]\n", file); + fputs ("server_name=freenode\n", file); + fputs ("server_autoconnect=on\n", file); + fputs ("server_address=irc.freenode.net\n", file); + fputs ("server_port=6667\n", file); + fputs ("server_password=\n", file); + fputs ("server_nick1=weechat_user\n", file); + fputs ("server_nick2=weechat2\n", file); + fputs ("server_nick3=weechat3\n", file); + fputs ("server_username=weechat\n", file); + fputs ("server_realname=WeeChat default realname\n", file); + fputs ("server_command=\n", file); + fputs ("server_autojoin=\n", file); + + fclose (file); + free (filename); + return 0; +} + +/* + * config_write: write WeeChat configurtion + * return: 0 if ok + * < 0 if error + */ + +int +config_write (char *config_name) +{ + char *filename; + char line[1024]; + FILE *file; + int i, j; + time_t current_time; + t_irc_server *ptr_server; + t_weechat_alias *ptr_alias; + + if (config_name) + filename = strdup (config_name); + else + { + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + } + + if ((file = fopen (filename, "wt")) == NULL) + { + gui_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename); + free (filename); + return -1; + } + + log_printf (_("saving config to disk\n")); + + current_time = time (NULL); + sprintf (line, _("#\n# %s configuration file, created by " + "%s v%s on %s#\n"), + WEECHAT_NAME, WEECHAT_NAME, WEECHAT_VERSION, + ctime (¤t_time)); + fputs (line, file); + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + sprintf (line, "\n[%s]\n", config_sections[i].section_name); + fputs (line, file); + if ((i == CONFIG_SECTION_HISTORY) || (i == CONFIG_SECTION_LOG) || + (i == CONFIG_SECTION_DCC) || (i == CONFIG_SECTION_PROXY)) + { + sprintf (line, + "# WARNING!!! Options for section \"%s\" are not developed!\n", + config_sections[i].section_name); + fputs (line, file); + } + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int && + *weechat_options[i][j].ptr_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + sprintf (line, "%s=%d\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + *weechat_options[i][j].ptr_int : + weechat_options[i][j].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + weechat_options[i][j].array_values[*weechat_options[i][j].ptr_int] : + weechat_options[i][j].array_values[weechat_options[i][j].default_int]); + break; + case OPTION_TYPE_COLOR: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + gui_get_color_by_value (*weechat_options[i][j].ptr_int) : + weechat_options[i][j].default_string); + break; + case OPTION_TYPE_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_string) ? + *weechat_options[i][j].ptr_string : + weechat_options[i][j].default_string); + break; + } + fputs (line, file); + } + } + } + + /* alias section */ + fputs ("\n[alias]\n", file); + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + sprintf (line, "%s=%s\n", + ptr_alias->alias_name, ptr_alias->alias_command + 1); + fputs (line, file); + } + + /* server section */ + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + /* default server is freenode */ + fputs ("\n[server]\n", file); + sprintf (line, "server_name=%s\n", ptr_server->name); + fputs (line, file); + sprintf (line, "server_autoconnect=%s\n", + (ptr_server->autoconnect) ? "on" : "off"); + fputs (line, file); + sprintf (line, "server_address=%s\n", ptr_server->address); + fputs (line, file); + sprintf (line, "server_port=%d\n", ptr_server->port); + fputs (line, file); + sprintf (line, "server_password=%s\n", + (ptr_server->password) ? ptr_server->password : ""); + fputs (line, file); + sprintf (line, "server_nick1=%s\n", ptr_server->nick1); + fputs (line, file); + sprintf (line, "server_nick2=%s\n", ptr_server->nick2); + fputs (line, file); + sprintf (line, "server_nick3=%s\n", ptr_server->nick3); + fputs (line, file); + sprintf (line, "server_username=%s\n", ptr_server->username); + fputs (line, file); + sprintf (line, "server_realname=%s\n", ptr_server->realname); + fputs (line, file); + sprintf (line, "server_command=%s\n", + (ptr_server->command) ? ptr_server->command : ""); + fputs (line, file); + sprintf (line, "server_autojoin=%s\n", + (ptr_server->autojoin) ? ptr_server->autojoin : ""); + fputs (line, file); + } + + fclose (file); + free (filename); + return 0; +} diff --git a/src/common/config.h b/src/common/config.h new file mode 100644 index 000000000..692698797 --- /dev/null +++ b/src/common/config.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_CONFIG_H +#define __WEECHAT_CONFIG_H 1 + +#define WEECHAT_CONFIG_NAME "weechat.rc" + +#define CONFIG_SECTION_NONE -1 +#define CONFIG_SECTION_LOOK 0 +#define CONFIG_SECTION_COLORS 1 +#define CONFIG_SECTION_HISTORY 2 +#define CONFIG_SECTION_LOG 3 +#define CONFIG_SECTION_DCC 4 +#define CONFIG_SECTION_PROXY 5 +#define CONFIG_SECTION_ALIAS 6 +#define CONFIG_SECTION_SERVER 7 +#define CONFIG_NUMBER_SECTIONS 8 + +#define OPTION_TYPE_BOOLEAN 1 /* values: on/off */ +#define OPTION_TYPE_INT 2 /* values: from min to max */ +#define OPTION_TYPE_INT_WITH_STRING 3 /* values: one from **array_values */ +#define OPTION_TYPE_COLOR 4 /* values: a color name */ +#define OPTION_TYPE_STRING 5 /* values: any string, may be empty */ + +#define BOOL_FALSE 0 +#define BOOL_TRUE 1 + +#define CFG_LOOK_NICKLIST_LEFT 0 +#define CFG_LOOK_NICKLIST_RIGHT 1 +#define CFG_LOOK_NICKLIST_TOP 2 +#define CFG_LOOK_NICKLIST_BOTTOM 3 + +typedef struct t_config_section t_config_section; + +struct t_config_section +{ + int section_number; + char *section_name; +}; + +typedef struct t_config_option t_config_option; + +struct t_config_option +{ + char *option_name; + char *short_description; + char *long_description; + int option_type; + int min, max; + int default_int; + char *default_string; + char **array_values; + int *ptr_int; + char **ptr_string; + int (*handler_change)(int *, char **); +}; + +extern int cfg_look_set_title; +extern int cfg_look_startup_logo; +extern int cfg_look_startup_version; +extern char *cfg_look_weechat_slogan; +extern int cfg_look_color_nicks; +extern int cfg_look_color_actions; +extern int cfg_look_remove_colors_from_msgs; +extern int cfg_look_nicklist; +extern int cfg_look_nicklist_position; +extern int cfg_look_nicklist_min_size; +extern int cfg_look_nicklist_max_size; +extern int cfg_look_nickmode; +extern int cfg_look_nickmode_empty; +extern char *cfg_look_no_nickname; +extern char *cfg_look_completor; + +extern int cfg_col_title; +extern int cfg_col_title_bg; +extern int cfg_col_chat; +extern int cfg_col_chat_time; +extern int cfg_col_chat_time_sep; +extern int cfg_col_chat_prefix1; +extern int cfg_col_chat_prefix2; +extern int cfg_col_chat_nick; +extern int cfg_col_chat_host; +extern int cfg_col_chat_channel; +extern int cfg_col_chat_dark; +extern int cfg_col_chat_bg; +extern int cfg_col_status; +extern int cfg_col_status_active; +extern int cfg_col_status_data_msg; +extern int cfg_col_status_data_other; +extern int cfg_col_status_more; +extern int cfg_col_status_bg; +extern int cfg_col_input; +extern int cfg_col_input_channel; +extern int cfg_col_input_nick; +extern int cfg_col_input_bg; +extern int cfg_col_nick; +extern int cfg_col_nick_op; +extern int cfg_col_nick_halfop; +extern int cfg_col_nick_voice; +extern int cfg_col_nick_sep; +extern int cfg_col_nick_self; +extern int cfg_col_nick_private; +extern int cfg_col_nick_bg; + +extern int cfg_history_max_lines; +extern int cfg_history_max_commands; + +extern int cfg_log_auto_channels; +extern int cfg_log_auto_private; +extern char *cfg_log_path; +extern char *cfg_log_name; +extern char *cfg_log_timestamp; +extern char *cfg_log_start_string; +extern char *cfg_log_end_string; + +extern int cfg_dcc_auto_accept_files; +extern int cfg_dcc_auto_accept_max_size; +extern int cfg_dcc_auto_accept_chats; +extern int cfg_dcc_timeout; +extern char *cfg_dcc_download_path; +extern char *cfg_dcc_upload_path; +extern int cfg_dcc_auto_rename; +extern int cfg_dcc_auto_resume; + +extern int cfg_proxy_use; +extern char *cfg_proxy_address; +extern int cfg_proxy_port; +extern char *cfg_proxy_password; + +extern t_config_section config_sections [CONFIG_NUMBER_SECTIONS]; +extern t_config_option * weechat_options [CONFIG_NUMBER_SECTIONS]; + +extern int config_read (); +extern int config_create_default (); +extern int config_write (); + +#endif /* config.h */ diff --git a/src/common/history.c b/src/common/history.c new file mode 100644 index 000000000..fed419219 --- /dev/null +++ b/src/common/history.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* history.c: memorize and call again commands or text */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "history.h" +#include "../gui/gui.h" + + +t_history *history_general = NULL; +t_history *history_general_ptr = NULL; + + +/* + * history_add: add a text/command to history + */ + +void +history_add (void *window, char *string) +{ + t_history *new_history; + + new_history = (t_history *)malloc (sizeof (t_history)); + if (new_history) + { + new_history->text = strdup (string); + + /* add history to general history */ + if (history_general) + history_general->prev_history = new_history; + new_history->next_history = history_general; + new_history->prev_history = NULL; + history_general = new_history; + + /* add history to local history */ + if (((t_gui_window *)(window))->history) + ((t_gui_window *)(window))->history->prev_history = new_history; + new_history->next_history = ((t_gui_window *)(window))->history; + new_history->prev_history = NULL; + ((t_gui_window *)window)->history = new_history; + } +} diff --git a/src/common/history.h b/src/common/history.h new file mode 100644 index 000000000..946f2e792 --- /dev/null +++ b/src/common/history.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_HISTORY_H +#define __WEECHAT_HISTORY_H 1 + +typedef struct t_history t_history; + +struct t_history +{ + char *text; /* text or command (as entered by user) */ + t_history *next_history; /* link to next text/command */ + t_history *prev_history; /* link to previous text/command */ +}; + +extern void history_add (void *, char *); + +#endif /* history.h */ diff --git a/src/common/weechat.c b/src/common/weechat.c new file mode 100644 index 000000000..1e4866c02 --- /dev/null +++ b/src/common/weechat.c @@ -0,0 +1,324 @@ +/* ############################################################################ + * ### ___ __ ______________ _____ ### + * ### __ | / /___________ ____/__ /_______ __ /_ ### + * ### __ | /| / /_ _ \ _ \ / __ __ \ __ `/ __/ ### + * ### __ |/ |/ / / __/ __/ /___ _ / / / /_/ // /_ ### + * ### ____/|__/ \___/\___/\____/ /_/ /_/\__,_/ \__/ ### + * ### ### + * ### WeeChat - Wee Enhanced Environment for Chat ### + * ### Fast & light environment for Chat ### + * ### ### + * ### By: FlashCode <flashcode@flashtux.org> ### + * ### Bounga <bounga@altern.org> ### + * ### Xahlexx <xahlexx@tuxisland.org> ### + * ### ### + * ### http://weechat.flashtux.org ### + * ### ### + * ############################################################################ + * + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* weechat.c: core functions for WeeChat */ + + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> + +#include "weechat.h" +#include "config.h" +#include "command.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* char *display_name; */ +int quit_weechat; /* = 1 if quit request from user... why ? :'( */ + +FILE *log_file; /* WeeChat log file (~/.weechat/weechat.log */ + + +/* + * log_printf: displays a message in WeeChat log (~/.weechat/weechat.log) + */ + +void +log_printf (char *message, ...) +{ + static char buffer[4096]; + va_list argptr; + static time_t seconds; + struct tm *date_tmp; + + if (!log_file) + return; + + va_start (argptr, message); + vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); + va_end (argptr); + + seconds = time (NULL); + date_tmp = localtime (&seconds); + fprintf (log_file, "[%04d-%02d-%02d %02d:%02d:%02d] %s", + date_tmp->tm_year + 1900, date_tmp->tm_mon + 1, date_tmp->tm_mday, + date_tmp->tm_hour, date_tmp->tm_min, date_tmp->tm_sec, + buffer); + fflush (log_file); +} + +/* + * wee_parse_args: parse command line args + */ + +void +wee_parse_args (int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) + { + if ((strcmp (argv[i], "-h") == 0) + || (strcmp (argv[i], "--help") == 0)) + { + printf ("\n%s%s", WEE_USAGE); + exit (0); + } + else if ((strcmp (argv[i], "-l") == 0) + || (strcmp (argv[i], "--license") == 0)) + { + printf ("\n%s%s", WEE_LICENSE); + exit (0); + } + /*else if ((strcmp (argv[i], "-d") == 0) + || (strcmp (argv[i], "--display") == 0)) + { + if (i == (argc - 1)) + fprintf (stderr, + _("%s no display specified (parameter '%s'), ignored\n"), + WEECHAT_WARNING, argv[i]); + else + { + display_name = argv[i + 1]; + i++; + } + }*/ + else if ((strcmp (argv[i], "-v") == 0) + || (strcmp (argv[i], "--version") == 0)) + { + printf (WEECHAT_VERSION "\n"); + exit (0); + } + else + { + fprintf (stderr, + _("%s unknown parameter '%s', ignored\n"), + WEECHAT_WARNING, argv[i]); + } + } +} + +/* + * wee_create_home_dir: create weechat home directory (if not found) + */ + +void +wee_create_home_dir () +{ + char *weechat_home_dir; + int return_code; + + weechat_home_dir = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (weechat_home_dir, "%s/.weechat", getenv ("HOME")); + return_code = mkdir (weechat_home_dir, 0755); + if (return_code < 0) + { + if (errno != EEXIST) + { + fprintf (stderr, _("%s cannot create directory \"%s\"\n"), + WEECHAT_ERROR, weechat_home_dir); + free (weechat_home_dir); + exit (1); + } + } + free (weechat_home_dir); +} + +/* + * wee_init_vars: initialize some variables + */ + +void +wee_init_vars () +{ + /* GUI not yet initialized */ + gui_ready = 0; + + /* init received messages queue */ + recv_msgq = NULL; + msgq_last_msg = NULL; +} + +/* + * wee_init_log: initialize log file + */ + +void +wee_init_log () +{ + char *filename; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_LOG_NAME, getenv ("HOME")); + if ((log_file = fopen (filename, "wt")) == NULL) + { + free (filename); + fprintf (stderr, + _("%s unable to create/append to log file (~/.weechat/" + WEECHAT_LOG_NAME), WEECHAT_ERROR); + } + free (filename); +} + +/* + * wee_shutdown: shutdown WeeChat + */ + +void +wee_shutdown () +{ + server_free_all (); + gui_end (); + if (log_file) + fclose (log_file); + exit (0); +} + +/* + * main: WeeChat startup + */ + +int +main (int argc, char *argv[]) +{ + t_irc_server *ptr_server; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, "/usr/share/locale"); + textdomain (PACKAGE); + + /* pre-initiliaze interface */ + gui_pre_init (&argc, &argv); + + /* initialize variables */ + wee_init_vars (); + + /* parse command line args */ + wee_parse_args (argc, argv); + + /* create weechat home directory */ + wee_create_home_dir (); + + /* init log file */ + wee_init_log (); + + /* build commands index (sorted), for completion */ + index_command_build (); + + /* read configuration */ + switch (config_read ()) + { + case 0: /* success */ + break; + case -1: /* config file not found */ + config_create_default (); + config_read (); + break; + default: /* other error (fatal) */ + server_free_all (); + return 1; + } + + /* init gui */ + gui_init (); + + /* Welcome message - yeah! */ + if (cfg_look_startup_logo) + { + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX1, + " ___ __ ______________ _____ \n" + " __ | / /___________ ____/__ /_______ __ /_\n" + " __ | /| / /_ _ \\ _ \\ / __ __ \\ __ `/ __/\n" + " __ |/ |/ / / __/ __/ /___ _ / / / /_/ // /_ \n" + " ____/|__/ \\___/\\___/\\____/ /_/ /_/\\__,_/ \\__/ \n"); + } + if (cfg_look_weechat_slogan && cfg_look_weechat_slogan[0]) + { + gui_printf_color (NULL, COLOR_WIN_CHAT, _("%sWelcome to "), + (cfg_look_startup_logo) ? " " : ""); + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX2, WEECHAT_NAME); + gui_printf_color (NULL, COLOR_WIN_CHAT, + ", %s\n", cfg_look_weechat_slogan); + } + if (cfg_look_startup_version) + { + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX2, + "%s" WEECHAT_NAME_AND_VERSION, + (cfg_look_startup_logo) ? " " : ""); + gui_printf_color (NULL, COLOR_WIN_CHAT, + ", %s %s %s\n", + _("compiled on"), __DATE__, __TIME__); + } + if (cfg_look_startup_logo || + (cfg_look_weechat_slogan && cfg_look_weechat_slogan[0]) || + cfg_look_startup_version) + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX1, + "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); + + /* connect to all servers (with autoconnect flag) */ + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + if (ptr_server->autoconnect) + { + gui_window_new (ptr_server, NULL); + if (server_connect (ptr_server)) + irc_login (ptr_server); + } + } + gui_main_loop (); + server_disconnect_all (); + + /* save config file */ + config_write (NULL); + + /* program ending */ + wee_shutdown (); + + /* make gcc happy (statement never executed) */ + return 0; +} diff --git a/src/common/weechat.h b/src/common/weechat.h new file mode 100644 index 000000000..adc0bf04e --- /dev/null +++ b/src/common/weechat.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_H +#define __WEECHAT_H 1 + +#include <stdio.h> +#include <locale.h> +#include <libintl.h> + +#define PACKAGE "weechat" +#define _(string) gettext(string) +#define N_(string) (string) + +#define WEECHAT_NAME "WeeChat" +#define WEECHAT_VERSION "0.0.3-pre2" + +#define WEECHAT_NAME_AND_VERSION WEECHAT_NAME " " WEECHAT_VERSION +#define WEECHAT_COPYRIGHT WEECHAT_NAME " (c) 2003 by Wee Team" +#define WEECHAT_WEBSITE "http://weechat.flashtux.org" + +#define WEECHAT_ERROR _(WEECHAT_NAME " Error:") +#define WEECHAT_WARNING _(WEECHAT_NAME " Warning:") + +/* debug mode, 0=normal use, 1=some debug msg, 2=full debug (developers only) */ +#define DEBUG 0 + +/* log file */ + +#define WEECHAT_LOG_NAME "weechat.log" + +/* license */ + +#define WEE_LICENSE \ + WEECHAT_NAME_AND_VERSION " (c) Copyright 2003, compiled on " __DATE__ __TIME__ \ + "Developed by FlashCode <flashcode@flashtux.org>\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + "This program is free software; you can redistribute it and/or modify\n" \ + "it under the terms of the GNU General Public License as published by\n" \ + "the Free Software Foundation; either version 2 of the License, or\n" \ + "(at your option) any later version.\n" \ + "\n", \ + \ + "This program is distributed in the hope that it will be useful,\n" \ + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ + "GNU General Public License for more details.\n" \ + "\n" \ + "You should have received a copy of the GNU General Public License\n" \ + "along with this program; if not, write to the Free Software\n" \ + "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n" + +#define WEE_USAGE \ + WEECHAT_NAME_AND_VERSION " (c) Copyright 2003, compiled on " __DATE__ __TIME__ \ + "Developed by FlashCode <flashcode@flashtux.org>\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + " -h, --help this help screen\n", \ + " -l, --license display WeeChat license\n" \ + " -v, --version display WeeChat version\n\n" + +/* " -d, --display choose X display\n" \*/ + + +/*#define DEFAULT_DISPLAY ":0" */ + + +/*extern char *display_name; */ +int quit_weechat; + +extern int quit_weechat; + +extern void log_printf (char *, ...); +extern void wee_shutdown (); + +#endif /* weechat.h */ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am new file mode 100644 index 000000000..797d3e624 --- /dev/null +++ b/src/gui/Makefile.am @@ -0,0 +1,30 @@ +# Copyright (c) 2003 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 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 +# + +if GUI_CURSES +curses_dir=curses +endif + +if GUI_GTK +gtk_dir=gtk +endif + +if GUI_QT +qt_dir=qt +endif + +SUBDIRS = $(curses_dir) $(gtk_dir) $(qt_dir) diff --git a/src/gui/curses/Makefile.am b/src/gui/curses/Makefile.am new file mode 100644 index 000000000..7a8aaacc3 --- /dev/null +++ b/src/gui/curses/Makefile.am @@ -0,0 +1,26 @@ +# Copyright (c) 2003 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 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 +# + +bin_PROGRAMS = weechat-curses + +weechat_curses_LDADD = ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(CURSES_LIBS) + +weechat_curses_SOURCES = ../gui-common.c \ + gui-display.c \ + gui-input.c diff --git a/src/gui/curses/gui-display.c b/src/gui/curses/gui-display.c index f4a88e859..99ab1994c 100644 --- a/src/gui/curses/gui-display.c +++ b/src/gui/curses/gui-display.c @@ -29,10 +29,11 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <curses.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" +#include "../../common/config.h" #include "../../irc/irc.h" @@ -151,6 +152,17 @@ gui_window_set_color (WINDOW *window, int num_color) } /* + * gui_window_has_nicklist: returns 1 if window has nicklist + */ + +int +gui_window_has_nicklist (t_gui_window *window) +{ + return (window->win_nick != NULL); +} + + +/* * gui_calculate_pos_size: calculate position and size for a window & sub-win */ @@ -1246,6 +1258,18 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_pre_init: pre-initialize GUI (called before gui_init) + */ + +void +gui_pre_init (int *argc, char **argv[]) +{ + /* nothing for Curses interface */ + (void) argc; + (void) argv; +} + +/* * gui_init_colors: init GUI colors */ diff --git a/src/gui/curses/gui-input.c b/src/gui/curses/gui-input.c index 134ec8d20..61a5243d5 100644 --- a/src/gui/curses/gui-input.c +++ b/src/gui/curses/gui-input.c @@ -30,13 +30,15 @@ #include <signal.h> #include <time.h> #include <sys/socket.h> +#include <curses.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" -#include "../../command.h" +#include "../../common/config.h" +#include "../../common/command.h" #include "../../irc/irc.h" +#define KEY_ESCAPE 27 /* * gui_read_keyb: read keyboard line diff --git a/src/gui/gtk/Makefile.am b/src/gui/gtk/Makefile.am new file mode 100644 index 000000000..8f2e52569 --- /dev/null +++ b/src/gui/gtk/Makefile.am @@ -0,0 +1,28 @@ +# Copyright (c) 2003 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 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 +# + +bin_PROGRAMS = weechat-gtk + +INCLUDES = $(GTK_CFLAGS) + +weechat_gtk_LDADD = ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(GTK_LIBS) + +weechat_gtk_SOURCES = ../gui-common.c \ + gui-display.c \ + gui-input.c diff --git a/src/gui/gtk/gui-display.c b/src/gui/gtk/gui-display.c index 673f414f3..d2d12fc39 100644 --- a/src/gui/gtk/gui-display.c +++ b/src/gui/gtk/gui-display.c @@ -29,10 +29,11 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <gtk/gtk.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" +#include "../../common/config.h" #include "../../irc/irc.h" @@ -144,6 +145,16 @@ gui_get_color_by_value (int color_value) } /* + * gui_window_has_nicklist: returns 1 if window has nicklist + */ + +int +gui_window_has_nicklist (t_gui_window *window) +{ + return (window->textbuffer_nicklist != NULL); +} + +/* * gui_calculate_pos_size: calculate position and size for a window & sub-win */ @@ -379,7 +390,7 @@ gui_redraw_window (t_gui_window *window) gui_redraw_window_title (window); gui_redraw_window_chat (window); - if (WIN_HAS_NICKLIST(window)) + if (gui_window_has_nicklist (window)) gui_redraw_window_nick (window); gui_redraw_window_status (window); gui_redraw_window_input (window); @@ -538,6 +549,17 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_pre_init: pre-initialize GUI (called before gui_init) + */ + +void +gui_pre_init (int *argc, char **argv[]) +{ + /* Initialise Gtk+ */ + gtk_init (argc, argv); +} + +/* * gui_init_colors: init GUI colors */ diff --git a/src/gui/gtk/gui-input.c b/src/gui/gtk/gui-input.c index 4ded0a91b..db30e6523 100644 --- a/src/gui/gtk/gui-input.c +++ b/src/gui/gtk/gui-input.c @@ -30,11 +30,12 @@ #include <signal.h> #include <time.h> #include <sys/socket.h> +#include <gtk/gtk.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" -#include "../../command.h" +#include "../../common/config.h" +#include "../../common/command.h" #include "../../irc/irc.h" diff --git a/src/gui/gui-common.c b/src/gui/gui-common.c index b6e4c7b86..7d626024d 100644 --- a/src/gui/gui-common.c +++ b/src/gui/gui-common.c @@ -31,7 +31,7 @@ #include <time.h> #include <curses.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "gui.h" #include "../irc/irc.h" diff --git a/src/gui/gui.h b/src/gui/gui.h index 11f326926..b1584f05e 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -23,19 +23,8 @@ #ifndef __WEECHAT_GUI_H #define __WEECHAT_GUI_H 1 -#ifdef WEE_CURSES -#include <curses.h> -#endif -#ifdef WEE_GTK -#include <gtk/gtk.h> -#endif - -#include "../completion.h" -#include "../history.h" - -#ifdef WEE_CURSES -#define KEY_ESCAPE 27 -#endif +#include "../common/completion.h" +#include "../common/history.h" #define INPUT_BUFFER_BLOCK_SIZE 256 @@ -77,10 +66,10 @@ #define WIN_IS_PRIVATE(window) (CHANNEL(window) && (CHANNEL(window)->type == CHAT_PRIVATE)) #ifdef WEE_CURSES - #define WIN_HAS_NICKLIST(window) (window->win_nick) + //#define WIN_HAS_NICKLIST(window) (window->win_nick) #endif #ifdef WEE_GTK - #define WIN_HAS_NICKLIST(window) (window->textbuffer_nicklist) + //#define WIN_HAS_NICKLIST(window) (window->textbuffer_nicklist) #endif #define MSG_TYPE_TIME 0 @@ -152,24 +141,27 @@ struct t_gui_window int win_nick_width; /* width of chat window */ int win_nick_height; /* height of chat window */ - /* windows */ - #ifdef WEE_CURSES - WINDOW *win_title; /* title window */ - WINDOW *win_chat; /* chat window (exemple: channel) */ - WINDOW *win_nick; /* nick window */ - WINDOW *win_status; /* status window */ - WINDOW *win_input; /* input window */ - #endif - #ifdef WEE_GTK - GtkWidget *textview_chat; /* textview widget for chat */ - GtkTextBuffer *textbuffer_chat; /* textbuffer widget for chat */ - GtkTextTag *texttag_chat; /* texttag widget for chat */ - GtkWidget *textview_nicklist; /* textview widget for nicklist */ - GtkTextBuffer *textbuffer_nicklist; /* textbuffer widget for nicklist */ - #endif - #ifdef WEE_QT + /* windows for Curses GUI */ + void *win_title; /* title window */ + void *win_chat; /* chat window (exemple: channel) */ + void *win_nick; /* nick window */ + void *win_status; /* status window */ + void *win_input; /* input window */ + + /* windows for Curses GUI */ + //GtkWidget *textview_chat; /* textview widget for chat */ + //GtkTextBuffer *textbuffer_chat; /* textbuffer widget for chat */ + //GtkTextTag *texttag_chat; /* texttag widget for chat */ + //GtkWidget *textview_nicklist; /* textview widget for nicklist */ + //GtkTextBuffer *textbuffer_nicklist; /* textbuffer widget for nicklist */ + void *textview_chat; /* textview widget for chat */ + void *textbuffer_chat; /* textbuffer widget for chat */ + void *texttag_chat; /* texttag widget for chat */ + void *textview_nicklist; /* textview widget for nicklist */ + void *textbuffer_nicklist; /* textbuffer widget for nicklist */ + + /* windows for Curses GUI */ /* TODO: declare Qt window */ - #endif /* chat content (lines, line is composed by many messages) */ t_gui_line *lines; /* lines of chat window */ @@ -222,6 +214,7 @@ extern void gui_buffer_insert_string (char *, int); extern int gui_assign_color (int *, char *); extern int gui_get_color_by_name (char *); extern char *gui_get_color_by_value (int); +extern int gui_window_has_nicklist (t_gui_window *); extern void gui_calculate_pos_size (t_gui_window *); extern void gui_draw_window_title (t_gui_window *); extern void gui_redraw_window_title (t_gui_window *); @@ -240,7 +233,8 @@ extern void gui_switch_to_next_window (); extern void gui_move_page_up (); extern void gui_move_page_down (); extern void gui_window_init_subwindows (t_gui_window *); -extern void gui_init_colors (); +extern void gui_pre_init (int *, char **[]); +//extern void gui_init_colors (); extern void gui_init (); extern void gui_window_free (t_gui_window *); extern void gui_end (); diff --git a/src/gui/qt/Makefile.am b/src/gui/qt/Makefile.am new file mode 100644 index 000000000..a0d82e32a --- /dev/null +++ b/src/gui/qt/Makefile.am @@ -0,0 +1,16 @@ +# Copyright (c) 2003 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 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 +# diff --git a/src/irc/Makefile.am b/src/irc/Makefile.am new file mode 100644 index 000000000..d7e85d1ee --- /dev/null +++ b/src/irc/Makefile.am @@ -0,0 +1,26 @@ +# Copyright (c) 2003 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 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 +# + +noinst_LIBRARIES = lib_weechat_irc.a + +lib_weechat_irc_a_SOURCES = irc-commands.c \ + irc-send.c \ + irc-recv.c \ + irc-server.c \ + irc-channel.c \ + irc-nick.c \ + irc-display.c diff --git a/src/irc/irc-channel.c b/src/irc/irc-channel.c index bdad12265..7d426210c 100644 --- a/src/irc/irc-channel.c +++ b/src/irc/irc-channel.c @@ -26,7 +26,7 @@ #include <stdlib.h> #include <string.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" diff --git a/src/irc/irc-commands.c b/src/irc/irc-commands.c index 0d58f59ec..ae0854181 100644 --- a/src/irc/irc-commands.c +++ b/src/irc/irc-commands.c @@ -24,9 +24,9 @@ RFC 1459,2810,2811,2812 */ -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" +#include "../common/command.h" t_irc_command irc_commands[] = diff --git a/src/irc/irc-display.c b/src/irc/irc-display.c index 2f2f9931b..69ca1dea7 100644 --- a/src/irc/irc-display.c +++ b/src/irc/irc-display.c @@ -28,9 +28,9 @@ #include <stdio.h> #include <string.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../config.h" +#include "../common/config.h" #include "../gui/gui.h" diff --git a/src/irc/irc-nick.c b/src/irc/irc-nick.c index ef0814e4e..4365ce23f 100644 --- a/src/irc/irc-nick.c +++ b/src/irc/irc-nick.c @@ -27,7 +27,7 @@ #include <string.h> #include <limits.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c index 99772abf4..ccd6832c8 100644 --- a/src/irc/irc-recv.c +++ b/src/irc/irc-recv.c @@ -32,10 +32,10 @@ #include <time.h> #include <sys/utsname.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" -#include "../config.h" +#include "../common/command.h" +#include "../common/config.h" #include "../gui/gui.h" @@ -501,7 +501,7 @@ irc_cmd_recv_nick (t_irc_server *server, char *host, char *arguments) COLOR_WIN_CHAT_NICK, "%s\n", arguments); - if (WIN_HAS_NICKLIST(ptr_channel->window)) + if (gui_window_has_nicklist (ptr_channel->window)) gui_redraw_window_nick (ptr_channel->window); } } @@ -692,7 +692,7 @@ irc_cmd_recv_part (t_irc_server *server, char *host, char *arguments) gui_printf (ptr_channel->window, "\n"); /* redraw nick list if this is current window */ - if (WIN_HAS_NICKLIST(ptr_channel->window)) + if (gui_window_has_nicklist (ptr_channel->window)) gui_redraw_window_nick (ptr_channel->window); } } @@ -978,7 +978,7 @@ irc_cmd_recv_quit (t_irc_server *server, char *host, char *arguments) gui_printf_color (ptr_channel->window, COLOR_WIN_CHAT_DARK, ")\n"); if ((ptr_channel->window == gui_current_window) && - (WIN_HAS_NICKLIST(ptr_channel->window))) + (gui_window_has_nicklist (ptr_channel->window))) gui_redraw_window_nick (ptr_channel->window); } } diff --git a/src/irc/irc-send.c b/src/irc/irc-send.c index c672f7fbb..147cfa19b 100644 --- a/src/irc/irc-send.c +++ b/src/irc/irc-send.c @@ -32,10 +32,10 @@ #include <time.h> #include <sys/utsname.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" -#include "../config.h" +#include "../common/command.h" +#include "../common/config.h" #include "../gui/gui.h" diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c index acc6f5a88..ee1ead0e3 100644 --- a/src/irc/irc-server.c +++ b/src/irc/irc-server.c @@ -34,7 +34,7 @@ #include <arpa/inet.h> #include <netdb.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" #include "../gui/gui.h" diff --git a/weechat/BUGS b/weechat/BUGS index b3ead766f..863c9e08e 100644 --- a/weechat/BUGS +++ b/weechat/BUGS @@ -1,7 +1,7 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -WeeChat known bugs, 2003-10-09 +WeeChat known bugs, 2003-10-25 - too much nicks in the channel (> height of window) => display bug - some IRC commands are marked as 'unknown' when received @@ -12,3 +12,4 @@ WeeChat known bugs, 2003-10-09 - when function key (non used by WeeChat) is pressed, prompt is deleted - when quitting WeeChat term title is not restored (if look_set_title is ON) - command name for /server can not contain spaces +- wrong alias is not created and not saved when quitting WeeChat diff --git a/weechat/ChangeLog b/weechat/ChangeLog index 33b3952e1..cca8cc4fa 100644 --- a/weechat/ChangeLog +++ b/weechat/ChangeLog @@ -1,10 +1,11 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2003-10-12 +ChangeLog - 2003-10-25 Version 0.0.3 (under dev!): + * ./configure script to build WeeChat (now multi-platform) * nicks are now correctly sorted (op, halfop, voice, other) * fixed crash when entering text without any server connection * fixed display bug (text was blinking when scrolling) diff --git a/weechat/INSTALL b/weechat/INSTALL index 8ef31434c..cd03a808b 100644 --- a/weechat/INSTALL +++ b/weechat/INSTALL @@ -1,10 +1,12 @@ WeeChat - Installation instructions =================================== -1) Run 'make' +1) Run './configure' -2) As root, run 'make install' +2) Run 'make' -3) Enjoy ! :-) +3) As root, run 'make install' + +4) Enjoy ! :-) See AUTHORS for any support, feel free to contact us for any problem ;) diff --git a/weechat/Makefile.am b/weechat/Makefile.am new file mode 100644 index 000000000..1124df70f --- /dev/null +++ b/weechat/Makefile.am @@ -0,0 +1,18 @@ +# Copyright (c) 2003 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 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 +# + +SUBDIRS = src diff --git a/weechat/README b/weechat/README index 6400d4826..8b7d33ce4 100644 --- a/weechat/README +++ b/weechat/README @@ -10,7 +10,7 @@ It is customizable and extensible with scripts. Features -------- * IRC chat client with multi-server connection - * many GUI (curses, Gtk, QT) (1) + * many GUI (curses, Gtk, Qt) (1) * small, fast and very light * customizable and extensible with scripts (Perl, Python, Ruby) (2) * compliant with RFC 1459,2810,2811,2812,2813 @@ -46,6 +46,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --- -(1) only curses & text interfaces are available today +(1) only curses interface is available today (2) plugin interfaces are not yet developed (3) only GNU/Linux version is available today diff --git a/weechat/TODO b/weechat/TODO index 8eade4453..962af8625 100644 --- a/weechat/TODO +++ b/weechat/TODO @@ -1,7 +1,7 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -TODO - 2003-10-12 +TODO - 2003-10-25 Legend: # done @@ -13,6 +13,9 @@ Legend: v0.0.3: ------ + * General: + + use of ./configure for building WeeChat + * IRC protocol: # implement RFC 2812 + "/mode" command: change the user/channels modes @@ -20,29 +23,15 @@ v0.0.3: persons with the flag +w enable * WeeChat commands: - - "/reload" command: reload the WeeChat's config file - - "/highlight" command: highlight a given word when it appears on - channels/privates + "/set" command: allow the user to set the WeeChat variables under WeeChat without editing the config file (colours, time format, etc) * Interface: - + Gtk GUI - - display current channel modes (example : #weechat(+nt)) - - interpret special chars in messages (color & bold for example) + internationalization (traduce WeeChat in many languages) - - log chats to file - - * TCP/IP communication: - - proxy support * Configuration: - - add missing options for config file - - wrong alias is not created and not saved when quitting WeeChat # do not stop program if problem with options in config file - - load config file after GUI (so init values by default (colors, ...) before - loading config) Future versions: @@ -60,6 +49,9 @@ Future versions: nick/host connect to the given irc network * WeeChat commands: + - "/reload" command: reload the WeeChat's config file + - "/highlight" command: highlight a given word when it appears on + channels/privates - "/completion" command: do shortcuts (for example when we type "u" in the text bar it send it to the server as "you") - "/exec" command: execute a command as if we was in shell @@ -68,6 +60,9 @@ Future versions: channel/private * Interface: + + Gtk GUI + - display current channel modes (example : #weechat(+nt)) + - interpret special chars in messages (color & bold for example) - many channel windows in one window/term (window split) - add lag indicator - forget some old lines that were displayed long time ago (now all is saved, @@ -75,15 +70,20 @@ Future versions: - improve completion (for example complete command parameters when possible) - understand incomplete commands if unambigous (for example: /he for /help is ok) - add clock (in status bar?) + - log chats to file ? Qt GUI * TCP/IP communication: - connect to server with child process (background) + - proxy support - SSL support - IPv6 protocol implementation * Configuration: - add key bindings to config file + - add missing options for config file + - load config file after GUI (so init values by default (colors, ...) before + loading config) * Plugins: - add Perl plugin diff --git a/weechat/configure.in b/weechat/configure.in new file mode 100644 index 000000000..5b049e4b3 --- /dev/null +++ b/weechat/configure.in @@ -0,0 +1,126 @@ +# Copyright (c) 2003 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 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 +# + +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.56) +AC_INIT(WeeChat, 0.0.3, flashcode@flashtux.org) +AC_CONFIG_SRCDIR([src/common/weechat.c]) +AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([weechat], [0.0.3]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_RANLIB + +# Checks for libraries. +# AC_CHECK_LIB([curses], [initscr]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h libintl.h limits.h locale.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_TIME +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday inet_ntoa memset mkdir select setlocale socket strcasecmp strchr strdup strncasecmp strpbrk strrchr strstr uname]) + +AC_ARG_ENABLE(curses, [ --disable-curses Turn off Curses interface (default=auto)],,enable_curses=yes) +AC_ARG_ENABLE(gtk, [ --disable-gtk Turn off Gtk+ interface (default=auto)],,enable_gtk=yes) +AC_ARG_ENABLE(qt, [ --disable-qt Turn off Qt interface (default=auto)],,enable_qt=yes) + +enable_plugins=no +enable_perl=no +PERL_CFLAGS= +enable_python=no +PYTHON_CFLAGS= +enable_ruby=no +RUBY_CFLAGS= +enable_debug=no +DEBUG_CFLAGS= + + +AM_CONDITIONAL(GUI_CURSES, test "$enable_curses" = "yes") +AM_CONDITIONAL(GUI_GTK, test "$enable_gtk" = "yes") +AM_CONDITIONAL(GUI_QT, test "$enable_qt" = "yes") + +#if test "x$enable_gtk" = "xyes" ; then +# AM_PATH_GTK_2_0(2.0.0, havegtk=yes, havegtk=no) +# if test "$havegtk" = no; then +# enable_gtk="no" +# echo +# echo Cannot find Gtk+\! Not building Gtk+ interface... +# echo +# fi +#fi + +CURSES_LIBS=-lcurses + +GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` +GTK_LIBS=`pkg-config --libs gtk+-2.0` + +AC_SUBST(CURSES_LIBS) +AC_SUBST(GTK_CFLAGS) +AC_SUBST(GTK_LIBS) + +CFLAGS="-Wall -W -pipe -O2" + +AC_OUTPUT([Makefile + src/Makefile + src/common/Makefile + src/irc/Makefile + src/gui/Makefile + src/gui/curses/Makefile + src/gui/gtk/Makefile + src/gui/qt/Makefile]) + +echo +echo $PACKAGE $VERSION + +listgui= +if test "x$enable_curses" = "xyes" ; then + listgui="$listgui Curses" +fi +if test "x$enable_gtk" = "xyes" ; then + listgui="$listgui Gtk+" +fi +if test "x$enable_qt" = "xyes" ; then + listgui="$listgui Qt" +fi + +echo +echo Interfaces.................... :$listgui +echo +echo Build with Plugin support..... : $enable_plugins +echo Build with Perl support....... : $enable_perl +echo Build with Python support..... : $enable_python +echo Build with Ruby support....... : $enable_ruby +echo +echo Print debugging messages...... : $enable_debug +echo +eval eval echo WeeChat will be installed in $bindir. +echo +echo configure complete, now type \'make\' to build WeeChat +echo diff --git a/weechat/src/Makefile.am b/weechat/src/Makefile.am new file mode 100644 index 000000000..f7441490b --- /dev/null +++ b/weechat/src/Makefile.am @@ -0,0 +1,18 @@ +# Copyright (c) 2003 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 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 +# + +SUBDIRS = common irc gui diff --git a/weechat/src/common/Makefile.am b/weechat/src/common/Makefile.am new file mode 100644 index 000000000..4d4764c31 --- /dev/null +++ b/weechat/src/common/Makefile.am @@ -0,0 +1,24 @@ +# Copyright (c) 2003 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 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 +# + +noinst_LIBRARIES = lib_weechat_main.a + +lib_weechat_main_a_SOURCES = weechat.c \ + command.c \ + completion.c \ + config.c \ + history.c diff --git a/weechat/src/common/command.c b/weechat/src/common/command.c new file mode 100644 index 000000000..a60152123 --- /dev/null +++ b/weechat/src/common/command.c @@ -0,0 +1,1387 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* command.c: WeeChat internal commands */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "command.h" +#include "config.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* WeeChat internal commands */ + +t_weechat_command weechat_commands[] = +{ { "alias", N_("create an alias for a command"), + N_("[alias_name [command [arguments]]"), + N_("alias_name: name of alias\ncommand: command name (WeeChat " + "or IRC command, without first '/')\n" "arguments: arguments for command"), + 0, MAX_ARGS, NULL, weechat_cmd_alias }, + { "clear", N_("clear window(s)"), + N_("[-all]"), + N_("-all: clear all windows"), + 0, 1, weechat_cmd_clear, NULL }, + { "connect", N_("connect to a server"), + N_("servername"), + N_("servername: server name to connect"), + 1, 1, weechat_cmd_connect, NULL }, + { "disconnect", N_("disconnect from a server"), + N_("servername"), + N_("servername: server name to disconnect"), + 1, 1, weechat_cmd_disconnect, NULL }, + { "help", N_("display help about commands"), + N_("[command]"), N_("command: name of a WeeChat or IRC command"), + 0, 1, weechat_cmd_help, NULL }, + { "server", N_("list, add or remove servers"), + N_("[list] | " + "[servername hostname port [-auto | -noauto] [-pwd password] [-nicks nick1 " + "[nick2 [nick3]]] [-username username] [-realname realname] " + "[-command command] [-autojoin channel[,channel]] ] | " + "[del servername]"), + N_("servername: server name, for internal & display use\n" + "hostname: name or IP address of server\n" + "port: port for server (integer)\n" + "password: password for server\n" + "nick1: first nick for server\n" + "nick2: alternate nick for server\n" + "nick3: second alternate nick for server\n" + "username: user name\n" + "realname: real name of user\n"), + 0, MAX_ARGS, weechat_cmd_server, NULL }, + { "save", N_("save config to disk"), + N_("[file]"), N_("file: filename for writing config"), + 0, 1, weechat_cmd_save, NULL }, + { "set", N_("set config parameters"), + N_("[option [value]]"), N_("option: name of an option\nvalue: value for option"), + 0, 2, weechat_cmd_set, NULL }, + { "unalias", N_("remove an alias"), + N_("alias_name"), N_("alias_name: name of alias to remove"), + 1, 1, NULL, weechat_cmd_unalias }, + { NULL, NULL, NULL, NULL, 0, 0, NULL, NULL } +}; + +t_weechat_alias *weechat_alias = NULL; +t_weechat_alias *weechat_last_alias = NULL; + +t_index_command *index_commands; +t_index_command *last_index_command; + + +/* + * index_command_search: search a command + */ + +t_index_command * +index_command_search (char *command) +{ + t_index_command *ptr_index; + + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strcasecmp (command, ptr_index->command_name) == 0) + return ptr_index; + } + return NULL; +} + +/* + * index_command_find_pos: find position for a command index (for sorting index) + */ + +t_index_command * +index_command_find_pos (char *command) +{ + t_index_command *ptr_index; + + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strcasecmp (command, ptr_index->command_name) < 0) + return ptr_index; + } + return NULL; +} + +/* + * index_command_insert_sorted: insert index into sorted list + */ + +void +index_command_insert_sorted (t_index_command *index) +{ + t_index_command *pos_index; + + pos_index = index_command_find_pos (index->command_name); + + if (index_commands) + { + if (pos_index) + { + /* insert index into the list (before index found) */ + index->prev_index = pos_index->prev_index; + index->next_index = pos_index; + if (pos_index->prev_index) + pos_index->prev_index->next_index = index; + else + index_commands = index; + pos_index->prev_index = index; + } + else + { + /* add index to the end */ + index->prev_index = last_index_command; + index->next_index = NULL; + last_index_command->next_index = index; + last_index_command = index; + } + } + else + { + index->prev_index = NULL; + index->next_index = NULL; + index_commands = index; + last_index_command = index; + } +} + +/* + * index_command_new: create new index command and add it to index list + */ + +t_index_command * +index_command_new (char *command_name) +{ + t_index_command *new_index; + + if ((new_index = ((t_index_command *) malloc (sizeof (t_index_command))))) + { + new_index->command_name = strdup (command_name); + index_command_insert_sorted (new_index); + return new_index; + } + return NULL; +} + +/* + * index_command_build: build an index of commands (internal, irc and alias) + * This list will be sorted, and used for completion + */ + +void +index_command_build () +{ + int i; + + index_commands = NULL; + last_index_command = NULL; + i = 0; + while (weechat_commands[i].command_name) + { + index_command_new (weechat_commands[i].command_name); + i++; + } + i = 0; + while (irc_commands[i].command_name) + { + if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg) + index_command_new (irc_commands[i].command_name); + i++; + } +} + +/* + * index_command_free: free an index command and reomve it from list + */ + +void +index_command_free (t_index_command *index) +{ + t_index_command *new_index_commands; + + /* remove index command from list */ + if (last_index_command == index) + last_index_command = index->prev_index; + if (index->prev_index) + { + (index->prev_index)->next_index = index->next_index; + new_index_commands = index_commands; + } + else + new_index_commands = index->next_index; + + if (index->next_index) + (index->next_index)->prev_index = index->prev_index; + + /* free data */ + if (index->command_name) + free (index->command_name); + free (index); + index_commands = new_index_commands; +} + +/* + * alias_search: search an alias + */ + +t_weechat_alias * +alias_search (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (alias_name, ptr_alias->alias_name) == 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_find_pos: find position for an alias (for sorting aliases) + */ + +t_weechat_alias * +alias_find_pos (char *alias_name) +{ + t_weechat_alias *ptr_alias; + + for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (alias_name, ptr_alias->alias_name) < 0) + return ptr_alias; + } + return NULL; +} + +/* + * alias_insert_sorted: insert alias into sorted list + */ + +void +alias_insert_sorted (t_weechat_alias *alias) +{ + t_weechat_alias *pos_alias; + + pos_alias = alias_find_pos (alias->alias_name); + + if (weechat_alias) + { + if (pos_alias) + { + /* insert alias into the list (before alias found) */ + alias->prev_alias = pos_alias->prev_alias; + alias->next_alias = pos_alias; + if (pos_alias->prev_alias) + pos_alias->prev_alias->next_alias = alias; + else + weechat_alias = alias; + pos_alias->prev_alias = alias; + } + else + { + /* add alias to the end */ + alias->prev_alias = weechat_last_alias; + alias->next_alias = NULL; + weechat_last_alias->next_alias = alias; + weechat_last_alias = alias; + } + } + else + { + alias->prev_alias = NULL; + alias->next_alias = NULL; + weechat_alias = alias; + weechat_last_alias = alias; + } +} + +/* + * alias_new: create new alias and add it to alias list + */ + +t_weechat_alias * +alias_new (char *alias_name, char *alias_command) +{ + char *pos; + t_weechat_alias *new_alias; + + if (index_command_search (alias_name)) + { + gui_printf (NULL, _("%s alias or command \"%s\" already exists!\n"), + WEECHAT_ERROR, alias_name); + return NULL; + } + pos = strchr (alias_command, ' '); + if (pos) + pos[0] = '\0'; + if (alias_search (alias_command)) + { + gui_printf (NULL, _("%s alias cannot run another alias!\n"), + WEECHAT_ERROR); + return NULL; + } + if (!index_command_search (alias_command)) + { + gui_printf (NULL, _("%s target command \"%s\" does not exist!\n"), + WEECHAT_ERROR, alias_command); + return NULL; + } + if (pos) + pos[0] = ' '; + + if ((new_alias = ((t_weechat_alias *) malloc (sizeof (t_weechat_alias))))) + { + new_alias->alias_name = strdup (alias_name); + new_alias->alias_command = (char *)malloc (strlen (alias_command) + 2); + new_alias->alias_command[0] = '/'; + strcpy (new_alias->alias_command + 1, alias_command); + alias_insert_sorted (new_alias); + return new_alias; + } + else + return NULL; +} + +/* + * alias_free: free an alias and reomve it from list + */ + +void +alias_free (t_weechat_alias *alias) +{ + t_weechat_alias *new_weechat_alias; + + /* remove alias from list */ + if (weechat_last_alias == alias) + weechat_last_alias = alias->prev_alias; + if (alias->prev_alias) + { + (alias->prev_alias)->next_alias = alias->next_alias; + new_weechat_alias = weechat_alias; + } + else + new_weechat_alias = alias->next_alias; + + if (alias->next_alias) + (alias->next_alias)->prev_alias = alias->prev_alias; + + /* free data */ + if (alias->alias_name) + free (alias->alias_name); + if (alias->alias_command) + free (alias->alias_command); + free (alias); + weechat_alias = new_weechat_alias; +} + +/* + * explode_string: explode a string according to separators + */ + +char ** +explode_string (char *string, char *separators, int num_items_max, + int *num_items) +{ + int i, n_items; + char **array; + char *ptr, *ptr1, *ptr2; + + if (num_items != NULL) + *num_items = 0; + + n_items = num_items_max; + + if (string == NULL) + return NULL; + + if (num_items_max == 0) + { + /* calculate number of items */ + ptr = string; + i = 1; + while ((ptr = strpbrk (ptr, separators))) + { + while (strchr (separators, ptr[0]) != NULL) + ptr++; + i++; + } + n_items = i; + } + + array = + (char **) malloc ((num_items_max ? n_items : n_items + 1) * + sizeof (char *)); + + ptr1 = string; + ptr2 = string; + + for (i = 0; i < n_items; i++) + { + while (strchr (separators, ptr1[0]) != NULL) + ptr1++; + if (i == (n_items - 1) || (ptr2 = strpbrk (ptr1, separators)) == NULL) + if ((ptr2 = strchr (ptr1, '\r')) == NULL) + if ((ptr2 = strchr (ptr1, '\n')) == NULL) + ptr2 = strchr (ptr1, '\0'); + + if ((ptr1 == NULL) || (ptr2 == NULL)) + { + array[i] = NULL; + } + else + { + if (ptr2 - ptr1 > 0) + { + array[i] = + (char *) malloc ((ptr2 - ptr1 + 1) * sizeof (char)); + array[i] = strncpy (array[i], ptr1, ptr2 - ptr1); + array[i][ptr2 - ptr1] = '\0'; + ptr1 = ++ptr2; + } + else + { + array[i] = NULL; + } + } + } + if (num_items_max == 0) + { + array[i] = NULL; + if (num_items != NULL) + *num_items = i; + } + else + { + if (num_items != NULL) + *num_items = num_items_max; + } + + return array; +} + +/* + * exec_weechat_command: executes a command (WeeChat internal or IRC) + * returns: 1 if command was executed succesfully + * 0 if error (command not executed) + */ + +int +exec_weechat_command (t_irc_server *server, char *string) +{ + int i, j, argc, return_code, length1, length2; + char *command, *pos, *ptr_args, **argv, *alias_command; + t_weechat_alias *ptr_alias; + + if ((!string[0]) || (string[0] != '/')) + return 0; + + command = strdup (string); + + /* look for end of command */ + ptr_args = NULL; + pos = strchr (command, ' '); + if (pos) + { + pos[0] = '\0'; + pos++; + while (pos[0] == ' ') + pos++; + ptr_args = pos; + if (!ptr_args[0]) + ptr_args = NULL; + } + + argv = explode_string (ptr_args, " ", 0, &argc); + + for (i = 0; weechat_commands[i].command_name; i++) + { + if (strcasecmp (weechat_commands[i].command_name, command + 1) == 0) + { + if ((argc < weechat_commands[i].min_arg) + || (argc > weechat_commands[i].max_arg)) + { + if (weechat_commands[i].min_arg == + weechat_commands[i].max_arg) + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, WEECHAT_NAME, + command + 1, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + else + gui_printf (NULL, + _("%s wrong argument count for %s command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, WEECHAT_NAME, + command + 1, + weechat_commands[i].min_arg, + weechat_commands[i].max_arg, + (weechat_commands[i].max_arg > + 1) ? "s" : ""); + } + else + { + if (weechat_commands[i].cmd_function_args) + return_code = (int) (weechat_commands[i].cmd_function_args) + (argc, argv); + else + return_code = (int) (weechat_commands[i].cmd_function_1arg) + (ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s %s command \"%s\" failed\n"), + WEECHAT_ERROR, WEECHAT_NAME, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + for (i = 0; irc_commands[i].command_name; i++) + { + if ((strcasecmp (irc_commands[i].command_name, command + 1) == 0) && + ((irc_commands[i].cmd_function_args) || + (irc_commands[i].cmd_function_1arg))) + { + if ((argc < irc_commands[i].min_arg) + || (argc > irc_commands[i].max_arg)) + { + if (irc_commands[i].min_arg == irc_commands[i].max_arg) + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + else + gui_printf + (NULL, + _("%s wrong argument count for IRC command \"%s\" " + "(expected: between %d and %d arg%s)\n"), + WEECHAT_ERROR, + command + 1, + irc_commands[i].min_arg, irc_commands[i].max_arg, + (irc_commands[i].max_arg > 1) ? "s" : ""); + } + else + { + if ((irc_commands[i].need_connection) && + ((!server) || (!server->is_connected))) + { + gui_printf (NULL, + _("%s command \"%s\" needs a server connection!\n"), + WEECHAT_ERROR, irc_commands[i].command_name); + return 0; + } + if (irc_commands[i].cmd_function_args) + return_code = (int) (irc_commands[i].cmd_function_args) + (server, argc, argv); + else + return_code = (int) (irc_commands[i].cmd_function_1arg) + (server, ptr_args); + if (return_code < 0) + gui_printf (NULL, + _("%s IRC command \"%s\" failed\n"), + WEECHAT_ERROR, command + 1); + } + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + if (strcasecmp (ptr_alias->alias_name, command + 1) == 0) + { + if (ptr_args) + { + length1 = strlen (ptr_alias->alias_command); + length2 = strlen (ptr_args); + alias_command = (char *)malloc (length1 + 1 + length2 + 1); + strcpy (alias_command, ptr_alias->alias_command); + alias_command[length1] = ' '; + strcpy (alias_command + length1 + 1, ptr_args); + exec_weechat_command (server, alias_command); + free (alias_command); + } + else + exec_weechat_command (server, ptr_alias->alias_command); + + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 1; + } + } + gui_printf (NULL, + _("%s unknown command \"%s\" (type /help for help)\n"), + WEECHAT_ERROR, + command + 1); + if (argv) + { + for (j = 0; argv[j]; j++) + free (argv[j]); + free (argv); + } + return 0; +} + +/* + * user_command: interprets user command (if beginning with '/') + * any other text is sent to the server, if connected + */ + +void +user_command (t_irc_server *server, 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) */ + exec_weechat_command (server, command); + } + else + { + if ((command[0] == '/') && (command[1] == '/')) + command++; + if (server && (!WIN_IS_SERVER(gui_current_window))) + { + server_sendf (server, "PRIVMSG %s :%s\r\n", + CHANNEL(gui_current_window)->name, + command); + + if (WIN_IS_PRIVATE(gui_current_window)) + { + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_CHAT_DARK, "<"); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_NICK_SELF, + "%s", server->nick); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_NICK, + COLOR_WIN_CHAT_DARK, "> "); + gui_printf_color_type (CHANNEL(gui_current_window)->window, + MSG_TYPE_MSG, + COLOR_WIN_CHAT, "%s\n", command); + } + else + { + ptr_nick = nick_search (CHANNEL(gui_current_window), server->nick); + if (ptr_nick) + { + irc_display_nick (CHANNEL(gui_current_window)->window, ptr_nick, + MSG_TYPE_NICK, 1, 1, 0); + gui_printf_color (CHANNEL(gui_current_window)->window, + COLOR_WIN_CHAT, "%s\n", command); + } + else + gui_printf (server->window, + _("%s cannot find nick for sending message\n"), + WEECHAT_ERROR); + } + } + else + gui_printf ((server) ? server->window : NULL, + _("This window is not a channel!\n")); + } +} + +/* + * weechat_cmd_alias: display or create alias + */ + +int +weechat_cmd_alias (char *arguments) +{ + char *pos; + t_weechat_alias *ptr_alias; + + if (arguments && arguments[0]) + { + /* Define new alias */ + pos = strchr (arguments, ' '); + if (pos) + { + pos[0] = '\0'; + pos++; + while (pos[0] == ' ') + pos++; + if (!pos[0]) + { + gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), + WEECHAT_ERROR, "alias"); + return -1; + } + index_command_new (arguments); + if (!alias_new (arguments, pos)) + return -1; + gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"), + arguments, pos); + } + else + { + gui_printf (NULL, _("%s missing arguments for \"%s\" command\n"), + WEECHAT_ERROR, "alias"); + return -1; + } + } + else + { + /* List all aliases */ + if (weechat_alias) + { + gui_printf (NULL, _("List of aliases:\n")); + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + gui_printf (NULL, " %s => %s\n", + ptr_alias->alias_name, + ptr_alias->alias_command + 1); + } + } + else + gui_printf (NULL, _("No alias defined.\n")); + } + return 0; +} + +/* + * weechat_cmd_clear: display or create alias + */ + +int +weechat_cmd_clear (int argc, char **argv) +{ + if (argc == 1) + { + if (strcmp (argv[0], "-all") == 0) + gui_window_clear_all (); + else + { + gui_printf (NULL, + _("unknown parameter \"%s\" for \"%s\" command\n"), + argv[0], "clear"); + return -1; + } + } + else + gui_window_clear (gui_current_window); + return 0; +} + +/* + * weechat_cmd_connect: connect to a server + */ + +int +weechat_cmd_connect (int argc, char **argv) +{ + t_irc_server *ptr_server; + t_irc_channel *ptr_channel; + + /* make gcc happy */ + (void) argc; + + ptr_server = server_search (argv[0]); + if (ptr_server) + { + if (ptr_server->is_connected) + { + gui_printf (NULL, + _("%s already connected to server \"%s\"!\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + if (!ptr_server->window) + gui_window_new (ptr_server, NULL); + if (server_connect (ptr_server)) + { + irc_login (ptr_server); + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + if (ptr_channel->type == CHAT_CHANNEL) + server_sendf (ptr_server, "JOIN %s\r\n", ptr_channel->name); + } + } + } + else + { + gui_printf (NULL, + _("%s server \"%s\" not found\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + return 0; +} + +/* + * weechat_cmd_disconnect: disconnect from a server + */ + +int +weechat_cmd_disconnect (int argc, char **argv) +{ + t_irc_server *ptr_server; + + /* make gcc happy */ + (void) argc; + + ptr_server = server_search (argv[0]); + if (ptr_server) + { + if (!ptr_server->is_connected) + { + gui_printf (NULL, + _("%s not connected to server \"%s\"!\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + server_disconnect (ptr_server); + gui_redraw_window_status (gui_current_window); + } + else + { + gui_printf (NULL, + _("%s server \"%s\" not found\n"), + WEECHAT_ERROR, argv[0]); + return -1; + } + return 0; +} + +/* + * weechat_cmd_help: display help + */ + +int +weechat_cmd_help (int argc, char **argv) +{ + int i; + + if (argc == 0) + { + gui_printf (NULL, + _("> List of %s internal commands:\n"), WEECHAT_NAME); + for (i = 0; weechat_commands[i].command_name; i++) + gui_printf (NULL, " %s - %s\n", + weechat_commands[i].command_name, + weechat_commands[i].command_description); + gui_printf (NULL, _("> List of IRC commands:\n")); + for (i = 0; irc_commands[i].command_name; i++) + if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg) + gui_printf (NULL, " %s - %s\n", + irc_commands[i].command_name, + irc_commands[i].command_description); + } + if (argc == 1) + { + for (i = 0; weechat_commands[i].command_name; i++) + { + if (strcasecmp (weechat_commands[i].command_name, argv[0]) == 0) + { + gui_printf + (NULL, + _("> Help on %s internal command \"%s\":\n"), + WEECHAT_NAME, weechat_commands[i].command_name); + gui_printf (NULL, + _("Syntax: /%s %s\n"), + weechat_commands[i].command_name, + (weechat_commands[i]. + arguments) ? weechat_commands[i]. + arguments : ""); + if (weechat_commands[i].arguments_description) + { + gui_printf (NULL, "%s\n", + weechat_commands[i]. + arguments_description); + } + return 0; + } + } + for (i = 0; irc_commands[i].command_name; i++) + { + if (strcasecmp (irc_commands[i].command_name, argv[0]) == 0) + { + gui_printf (NULL, + _("> Help on IRC command \"%s\":\n"), + irc_commands[i].command_name); + gui_printf (NULL, _("Syntax: /%s %s\n"), + irc_commands[i].command_name, + (irc_commands[i].arguments) ? + irc_commands[i].arguments : ""); + if (irc_commands[i].arguments_description) + { + gui_printf (NULL, "%s\n", + irc_commands[i]. + arguments_description); + } + return 0; + } + } + gui_printf (NULL, + _("No help available, \"%s\" is an unknown command\n"), + argv[0]); + } + return 0; +} + +/* + * weechat_cmd_server: list, add or remove server(s) + */ + +int +weechat_cmd_server (int argc, char **argv) +{ + int i; + t_irc_server server, *ptr_server, *server_found, *new_server; + + if ((argc == 0) || ((argc == 1) && (strcasecmp (argv[0], "list") == 0))) + { + /* list all servers */ + if (irc_servers) + { + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _("Server: ")); + gui_printf_color (NULL, + COLOR_WIN_CHAT_CHANNEL, + "%s", ptr_server->name); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " ["); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s", + (ptr_server->is_connected) ? + _("connected") : _("not connected")); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + "]\n"); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Autoconnect: %s\n"), + (ptr_server->autoconnect) ? _("yes") : _("no")); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Hostname : %s\n"), + ptr_server->address); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Port : %d\n"), + ptr_server->port); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->password && ptr_server->password[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Password : (hidden)\n")); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Password : (none)\n")); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Nicks : %s"), + ptr_server->nick1); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " / "); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s", ptr_server->nick2); + gui_printf_color (NULL, + COLOR_WIN_CHAT_DARK, + " / "); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + "%s\n", ptr_server->nick3); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Username : %s\n"), + ptr_server->username); + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Realname : %s\n"), + ptr_server->realname); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->command && ptr_server->command[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Command : %s\n"), + ptr_server->command); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Command : (none)\n")); + irc_display_prefix (NULL, PREFIX_INFO); + if (ptr_server->autojoin && ptr_server->autojoin[0]) + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Auto-join : %s\n"), + ptr_server->autojoin); + else + gui_printf_color (NULL, + COLOR_WIN_CHAT, + _(" Auto-join : (none)\n")); + } + } + else + gui_printf (NULL, _("No server.\n")); + } + else + { + if (strcasecmp (argv[0], "del") == 0) + { + if (argc < 2) + { + gui_printf (NULL, + _("%s missing servername for \"%s\" command\n"), + WEECHAT_ERROR, "server del"); + return -1; + } + if (argc > 2) + gui_printf (NULL, + _("%s too much arguments for \"%s\" command, ignoring arguments\n"), + WEECHAT_WARNING, "server del"); + + /* look for server by name */ + server_found = NULL; + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + if (strcmp (ptr_server->name, argv[1]) == 0) + { + server_found = ptr_server; + break; + } + } + if (!server_found) + { + gui_printf (NULL, + _("%s server \"%s\" not found for \"%s\" command\n"), + WEECHAT_ERROR, argv[1], "server del"); + return -1; + } + + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("Server")); + gui_printf_color (NULL, COLOR_WIN_CHAT_CHANNEL, + " %s ", server_found->name); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("has been deleted\n")); + + server_free (server_found); + gui_redraw_window (gui_current_window); + + return 0; + } + + /* init server struct */ + server_init (&server); + + if (argc < 3) + { + gui_printf (NULL, + _("%s missing parameters for \"%s\" command\n"), + WEECHAT_ERROR, "server"); + server_destroy (&server); + return -1; + } + + if (server_name_already_exists (argv[0])) + { + gui_printf (NULL, + _("%s server \"%s\" already exists, can't create it!\n"), + WEECHAT_ERROR, argv[0]); + server_destroy (&server); + return -1; + } + + server.name = strdup (argv[0]); + server.address = strdup (argv[1]); + server.port = atoi (argv[2]); + + /* parse arguments */ + for (i = 3; i < argc; i++) + { + if (argv[i][0] == '-') + { + if (strcasecmp (argv[i], "-auto") == 0) + server.autoconnect = 1; + if (strcasecmp (argv[i], "-noauto") == 0) + server.autoconnect = 0; + if (strcasecmp (argv[i], "-pwd") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-pwd"); + server_destroy (&server); + return -1; + } + server.password = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-nicks") == 0) + { + if (i >= (argc - 3)) + { + gui_printf (NULL, + _("%s missing nick(s) for \"%s\" parameter\n"), + WEECHAT_ERROR, "-nicks"); + server_destroy (&server); + return -1; + } + server.nick1 = strdup (argv[++i]); + server.nick2 = strdup (argv[++i]); + server.nick3 = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-username") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-username"); + server_destroy (&server); + return -1; + } + server.username = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-realname") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-realname"); + server_destroy (&server); + return -1; + } + server.realname = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-command") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing command for \"%s\" parameter\n"), + WEECHAT_ERROR, "-command"); + server_destroy (&server); + return -1; + } + server.command = strdup (argv[++i]); + } + if (strcasecmp (argv[i], "-autojoin") == 0) + { + if (i == (argc - 1)) + { + gui_printf (NULL, + _("%s missing password for \"%s\" parameter\n"), + WEECHAT_ERROR, "-autojoin"); + server_destroy (&server); + return -1; + } + server.autojoin = strdup (argv[++i]); + } + } + } + + /* create new server */ + new_server = server_new (server.name, server.autoconnect, server.address, + server.port, server.password, server.nick1, + server.nick2, server.nick3, server.username, + server.realname, server.command, + server.autojoin); + if (new_server) + { + irc_display_prefix (NULL, PREFIX_INFO); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("Server")); + gui_printf_color (NULL, COLOR_WIN_CHAT_CHANNEL, + " %s ", server.name); + gui_printf_color (NULL, COLOR_WIN_CHAT, _("created\n")); + } + else + { + gui_printf (NULL, + _("%s unable to create server\n"), + WEECHAT_ERROR); + server_destroy (&server); + return -1; + } + + if (new_server->autoconnect) + { + gui_window_new (new_server, NULL); + if (server_connect (new_server)) + irc_login (new_server); + } + + server_destroy (&server); + } + return 0; +} + +/* + * weechat_cmd_save: set options + */ + +int +weechat_cmd_save (int argc, char **argv) +{ + return (config_write ((argc == 1) ? argv[0] : NULL)); +} + +/* + * weechat_cmd_set: set options + */ + +int +weechat_cmd_set (int argc, char **argv) +{ + int i, j, section_displayed; + char *color_name; + + /* TODO: complete /set command */ + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + section_displayed = 0; + if (i != CONFIG_SECTION_SERVER) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + if ((argc == 0) || + ((argc > 0) + && (strstr (weechat_options[i][j].option_name, argv[0]) + != NULL))) + { + if (!section_displayed) + { + gui_printf (NULL, "[%s]\n", + config_sections[i].section_name); + section_displayed = 1; + } + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + gui_printf (NULL, " %s = %s\n", + weechat_options[i][j].option_name, + (*weechat_options[i][j].ptr_int) ? + "ON" : "OFF"); + break; + case OPTION_TYPE_INT: + gui_printf (NULL, + " %s = %d\n", + weechat_options[i][j].option_name, + *weechat_options[i][j].ptr_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + gui_printf (NULL, + " %s = %s\n", + weechat_options[i][j].option_name, + weechat_options[i][j].array_values[*weechat_options[i][j].ptr_int]); + break; + case OPTION_TYPE_COLOR: + color_name = gui_get_color_by_value (*weechat_options[i][j].ptr_int); + gui_printf (NULL, + " %s = %s\n", + weechat_options[i][j].option_name, + (color_name) ? color_name : _("(unknown)")); + break; + case OPTION_TYPE_STRING: + gui_printf (NULL, " %s = %s\n", + weechat_options[i][j]. + option_name, + (*weechat_options[i][j]. + ptr_string) ? + *weechat_options[i][j]. + ptr_string : ""); + break; + } + } + } + } + } + gui_printf (NULL, "(TODO) \"/set\" command not developed!\n"); + return 0; +} + +/* + * cmd_unalias: remove an alias + */ + +int +weechat_cmd_unalias (char *arguments) +{ + t_index_command *ptr_index; + t_weechat_alias *ptr_alias; + + ptr_index = index_command_search (arguments); + if (!ptr_index) + { + gui_printf (NULL, _("%s alias or command \"%s\" not found\n"), + WEECHAT_ERROR, arguments); + return -1; + } + + index_command_free (ptr_index); + ptr_alias = alias_search (arguments); + if (ptr_alias) + alias_free (ptr_alias); + gui_printf (NULL, _("Alias \"%s\" removed\n"), + arguments); + return 0; +} diff --git a/weechat/src/common/command.h b/weechat/src/common/command.h new file mode 100644 index 000000000..2be48eded --- /dev/null +++ b/weechat/src/common/command.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_COMMAND_H +#define __WEECHAT_COMMAND_H 1 + +#include "../irc/irc.h" + +#define MAX_ARGS 8192 + +typedef struct t_weechat_command t_weechat_command; + +struct t_weechat_command +{ + char *command_name; + char *command_description; + char *arguments; + char *arguments_description; + int min_arg, max_arg; + int (*cmd_function_args)(int, char **); + int (*cmd_function_1arg)(char *); +}; + +typedef struct t_weechat_alias t_weechat_alias; + +struct t_weechat_alias +{ + char *alias_name; + char *alias_command; + t_weechat_alias *prev_alias; + t_weechat_alias *next_alias; +}; + +typedef struct t_index_command t_index_command; + +struct t_index_command +{ + char *command_name; + t_index_command *prev_index; + t_index_command *next_index; +}; + +extern t_weechat_alias *weechat_alias; +extern t_index_command *index_commands; + +extern t_index_command *index_command_new (char *); +extern void index_command_build (); +extern t_weechat_alias *alias_new (char *, char *); +extern int exec_weechat_command (t_irc_server *, char *); +extern void user_command (t_irc_server *, char *); +extern int weechat_cmd_alias (char *); +extern int weechat_cmd_clear (int, char **); +extern int weechat_cmd_connect (int, char **); +extern int weechat_cmd_disconnect (int, char **); +extern int weechat_cmd_help (int, char **); +extern int weechat_cmd_server (int, char **); +extern int weechat_cmd_save (int, char **); +extern int weechat_cmd_set (int, char **); +extern int weechat_cmd_unalias (char *); + +#endif /* command.h */ diff --git a/weechat/src/common/completion.c b/weechat/src/common/completion.c new file mode 100644 index 000000000..a050e2f0b --- /dev/null +++ b/weechat/src/common/completion.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* completion.c: completes words according to context (cmd/nick) */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "completion.h" +#include "../irc/irc.h" +#include "command.h" + + +/* + * completion_init: init completion + */ + +void +completion_init (t_completion *completion) +{ + completion->position = -1; + completion->base_word = NULL; +} + +/* + * completion_free: free completion + */ + +void +completion_free (t_completion *completion) +{ + if (completion->base_word) + free (completion->base_word); +} + +/* + * completion_command: complete a command + */ + +void +completion_command (t_completion *completion) +{ + int length, word_found_seen; + t_index_command *ptr_index; + + length = strlen (completion->base_word) - 1; + word_found_seen = 0; + for (ptr_index = index_commands; ptr_index; ptr_index = ptr_index->next_index) + { + if (strncasecmp (ptr_index->command_name, completion->base_word + 1, length) == 0) + { + if ((!completion->word_found) || word_found_seen) + { + completion->word_found = ptr_index->command_name; + return; + } + } + if (completion->word_found && + (strcasecmp (ptr_index->command_name, completion->word_found) == 0)) + word_found_seen = 1; + } + if (completion->word_found) + { + completion->word_found = NULL; + completion_command (completion); + } +} + +/* + * completion_nick: complete a nick + */ + +void +completion_nick (t_completion *completion, t_irc_channel *channel) +{ + int length, word_found_seen; + t_irc_nick *ptr_nick; + + length = strlen (completion->base_word); + word_found_seen = 0; + for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + { + if (strncasecmp (ptr_nick->nick, completion->base_word, length) == 0) + { + if ((!completion->word_found) || word_found_seen) + { + completion->word_found = ptr_nick->nick; + return; + } + } + if (completion->word_found && + (strcasecmp (ptr_nick->nick, completion->word_found) == 0)) + word_found_seen = 1; + } + if (completion->word_found) + { + completion->word_found = NULL; + completion_nick (completion, channel); + } +} + +/* + * completion_search: complete word according to context + */ + +void +completion_search (t_completion *completion, void *channel, + char *buffer, int size, int pos) +{ + int i, pos_start, pos_end; + char *old_word_found; + + /* TODO: complete when no word is there with command according to context */ + if (size == 0) + { + completion->word_found = NULL; + return; + } + + /* if new complation => look for base word */ + if (pos != completion->position) + { + completion->word_found = NULL; + + if ((pos == size) || (buffer[pos-1] != ' ')) + pos--; + if ((pos > 0) && (buffer[pos] == ' ')) + return; + + i = pos; + while ((i >= 0) && (buffer[i] != ' ')) + i--; + pos_start = i + 1; + i = pos; + while ((i < size) && (buffer[i] != ' ')) + i++; + pos_end = i - 1; + + if (pos_start > pos_end) + return; + + completion->base_word_pos = pos_start; + + if (completion->base_word) + free (completion->base_word); + completion->base_word = (char *) malloc (pos_end - pos_start + 2); + + for (i = pos_start; i <= pos_end; i++) + completion->base_word[i - pos_start] = buffer[i]; + completion->base_word[pos_end - pos_start + 1] = '\0'; + + if (completion->base_word[0] == '/') + completion->position_replace = pos_start + 1; + else + completion->position_replace = pos_start; + } + + /* completion */ + old_word_found = completion->word_found; + if (completion->base_word[0] == '/') + { + completion_command (completion); + if (completion->word_found) + { + if (old_word_found) + completion->diff_size = strlen (completion->word_found) - + strlen (old_word_found); + else + completion->diff_size = strlen (completion->word_found) - + strlen (completion->base_word) + 1; + } + } + else + { + if (channel) + { + completion_nick (completion, (t_irc_channel *)channel); + if (completion->word_found) + { + if (old_word_found) + completion->diff_size = strlen (completion->word_found) - + strlen (old_word_found); + else + completion->diff_size = strlen (completion->word_found) - + strlen (completion->base_word); + } + } + } +} diff --git a/weechat/src/common/completion.h b/weechat/src/common/completion.h new file mode 100644 index 000000000..d1111dbaa --- /dev/null +++ b/weechat/src/common/completion.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_COMPLETION_H +#define __WEECHAT_COMPLETION_H 1 + +typedef struct t_completion t_completion; + +struct t_completion +{ + char *base_word; /* word to complete (when Tab was pressed) */ + int base_word_pos; /* beggining of base word */ + int position; /* position where we shoud complete */ + char *word_found; /* word found (to replace base word) */ + int position_replace; /* position where word should be replaced */ + int diff_size; /* size difference (< 0 = char(s) deleted) */ +}; + +extern void completion_init (t_completion *); +extern void completion_free (t_completion *); +extern void completion_search (t_completion *, void *, char *, int, int); + +#endif /* completion.h */ diff --git a/weechat/src/common/config.c b/weechat/src/common/config.c new file mode 100644 index 000000000..a3b88ad43 --- /dev/null +++ b/weechat/src/common/config.c @@ -0,0 +1,1198 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* config.c: WeeChat configuration */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <time.h> + +#include "weechat.h" +#include "config.h" +#include "command.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* config sections */ + +t_config_section config_sections[CONFIG_NUMBER_SECTIONS] = +{ { CONFIG_SECTION_LOOK, "look" }, + { CONFIG_SECTION_COLORS, "colors" }, + { CONFIG_SECTION_HISTORY, "history" }, + { CONFIG_SECTION_LOG, "log" }, + { CONFIG_SECTION_DCC, "dcc" }, + { CONFIG_SECTION_PROXY, "proxy" }, + { CONFIG_SECTION_ALIAS, "alias" }, + { CONFIG_SECTION_SERVER, "server" } +}; + +/* config, look & feel section */ + +int cfg_look_set_title; +int cfg_look_startup_logo; +int cfg_look_startup_version; +char *cfg_look_weechat_slogan; +int cfg_look_color_nicks; +int cfg_look_color_actions; +int cfg_look_remove_colors_from_msgs; +int cfg_look_nicklist; +int cfg_look_nicklist_position; +char *cfg_look_nicklist_position_values[] = +{ "left", "right", "top", "bottom", NULL }; +int cfg_look_nicklist_min_size; +int cfg_look_nicklist_max_size; +int cfg_look_nickmode; +int cfg_look_nickmode_empty; +char *cfg_look_no_nickname; +char *cfg_look_completor; + +t_config_option weechat_options_look[] = +{ { "look_set_title", N_("set title for terminal window (curses GUI) with name & version"), + N_("set title for terminal window (curses GUI) with name & version"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_set_title, NULL, NULL }, + { "look_startup_logo", N_("display WeeChat logo at startup"), + N_("display WeeChat logo at startup"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_startup_logo, NULL, NULL }, + { "look_startup_version", N_("display WeeChat version at startup"), + N_("display WeeChat version at startup"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_startup_version, NULL, NULL }, + { "look_weechat_slogan", N_("WeeChat slogan"), + N_("WeeChat slogan (if empty, slogan is not used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "the geekest IRC client!", NULL, NULL, &cfg_look_weechat_slogan, NULL }, + { "look_color_nicks", N_("display nick names with different colors"), + N_("display nick names with different colors"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_color_nicks, NULL, NULL }, + { "look_color_actions", N_("display actions with different colors"), + N_("display actions with different colors"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_color_actions, NULL, NULL }, + { "look_remove_colors_from_msgs", N_("remove colors from incoming messages"), + N_("remove colors from incoming messages"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_remove_colors_from_msgs, NULL, NULL }, + { "look_nicklist", N_("display nicklist window"), + N_("display nicklist window (for channel windows)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_nicklist, NULL, NULL }, + { "look_nicklist_position", N_("nicklist position"), + N_("nicklist position (top, left, right (default), bottom)"), + OPTION_TYPE_INT_WITH_STRING, 0, 0, 0, + "right", cfg_look_nicklist_position_values, &cfg_look_nicklist_position, NULL, NULL }, + { "look_nicklist_min_size", N_("min size for nicklist"), + N_("min size for nicklist (width or height, depending on look_nicklist_position " + "(0 = no min size))"), + OPTION_TYPE_INT, 0, 100, 0, + NULL, NULL, &cfg_look_nicklist_min_size, NULL, NULL }, + { "look_nicklist_max_size", N_("max size for nicklist"), + N_("max size for nicklist (width or height, depending on look_nicklist_position " + "(0 = no max size; if min == max and > 0, then size is fixed))"), + OPTION_TYPE_INT, 0, 100, 0, + NULL, NULL, &cfg_look_nicklist_max_size, NULL, NULL }, + { "look_no_nickname", N_("text to display instead of nick when not connected"), + N_("text to display instead of nick when not connected"), + OPTION_TYPE_STRING, 0, 0, 0, + "-cmd-", NULL, NULL, &cfg_look_no_nickname, NULL }, + { "look_nickmode", N_("display nick mode ((half)op/voice) before each nick"), + N_("display nick mode ((half)op/voice) before each nick"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_look_nickmode, NULL, NULL }, + { "look_nickmode_empty", N_("display space if nick mode is not (half)op/voice"), + N_("display space if nick mode is not (half)op/voice"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, + NULL, NULL, &cfg_look_nickmode_empty, NULL, NULL }, + { "look_nick_completor", N_("the string inserted after nick completion"), + N_("the string inserted after nick completion"), + OPTION_TYPE_STRING, 0, 0, 0, + ":", NULL, NULL, &cfg_look_completor, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, colors section */ + +int cfg_col_title; +int cfg_col_title_bg; +int cfg_col_chat; +int cfg_col_chat_time; +int cfg_col_chat_time_sep; +int cfg_col_chat_prefix1; +int cfg_col_chat_prefix2; +int cfg_col_chat_nick; +int cfg_col_chat_host; +int cfg_col_chat_channel; +int cfg_col_chat_dark; +int cfg_col_chat_bg; +int cfg_col_status; +int cfg_col_status_active; +int cfg_col_status_data_msg; +int cfg_col_status_data_other; +int cfg_col_status_more; +int cfg_col_status_bg; +int cfg_col_input; +int cfg_col_input_channel; +int cfg_col_input_nick; +int cfg_col_input_bg; +int cfg_col_nick; +int cfg_col_nick_op; +int cfg_col_nick_halfop; +int cfg_col_nick_voice; +int cfg_col_nick_sep; +int cfg_col_nick_self; +int cfg_col_nick_private; +int cfg_col_nick_bg; + +t_config_option weechat_options_colors[] = +{ /* title window */ + { "col_title", N_("color for title bar"), + N_("color for title bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_title, NULL, NULL }, + { "col_title_bg", N_("background for title bar"), + N_("background for title bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_title_bg, NULL, NULL }, + + /* chat window */ + { "col_chat", N_("color for chat text"), + N_("color for chat text"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_chat, NULL, NULL }, + { "col_chat_time", N_("color for time"), + N_("color for time in chat window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_chat_time, NULL, NULL }, + { "col_chat_time_sep", N_("color for time separator"), + N_("color for time separator (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "brown", NULL, &cfg_col_chat_time_sep, NULL, NULL }, + { "col_chat_prefix1", N_("color for 1st and 3rd char of prefix"), + N_("color for 1st and 3rd char of prefix"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightcyan", NULL, &cfg_col_chat_prefix1, NULL, NULL }, + { "col_chat_prefix2", N_("color for middle char of prefix"), + N_("color for middle char of prefix"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_chat_prefix2, NULL, NULL }, + { "col_chat_nick", N_("color for nicks in actions"), + N_("color for nicks in actions (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightcyan", NULL, &cfg_col_chat_nick, NULL, NULL }, + { "col_chat_host", N_("color for hostnames"), + N_("color for hostnames (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "cyan", NULL, &cfg_col_chat_host, NULL, NULL }, + { "col_chat_channel", N_("color for channel names in actions"), + N_("color for channel names in actions (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_chat_channel, NULL, NULL }, + { "col_chat_dark", N_("color for dark separators"), + N_("color for dark separators (chat window)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "green", NULL, &cfg_col_chat_dark, NULL, NULL }, + { "col_chat_bg", N_("background for chat"), + N_("background for chat window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_chat_bg, NULL, NULL }, + + /* status window */ + { "col_status", N_("color for status bar"), + N_("color for status bar"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_status, NULL, NULL }, + { "col_status_active", N_("color for active window"), + N_("color for active window (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "yellow", NULL, &cfg_col_status_active, NULL, NULL }, + { "col_status_data_msg", N_("color for window with new messages"), + N_("color for window with new messages (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightred", NULL, &cfg_col_status_data_msg, NULL, NULL }, + { "col_status_data_other", N_("color for window with new data (not messages)"), + N_("color for window with new data (not messages) (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightmagenta", NULL, &cfg_col_status_data_other, NULL, NULL }, + { "col_status_more", N_("color for \"*MORE*\" text"), + N_("color for window with new data (status bar)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_status_more, NULL, NULL }, + { "col_status_bg", N_("background for status window"), + N_("background for status window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_status_bg, NULL, NULL }, + + /* input window */ + { "col_input", N_("color for input text"), + N_("color for input text"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_input, NULL, NULL }, + { "col_input_channel", N_("color for input text (channel name)"), + N_("color for input text (channel name)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_input_channel, NULL, NULL }, + { "col_input_nick", N_("color for input text (nick name)"), + N_("color for input text (nick name)"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightgreen", NULL, &cfg_col_input_nick, NULL, NULL }, + { "col_input_bg", N_("background for input window"), + N_("background for input window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_input_bg, NULL, NULL }, + + /* nick window */ + { "col_nick", N_("color for nicknames"), + N_("color for nicknames"), + OPTION_TYPE_COLOR, 0, 0, 0, + "gray", NULL, &cfg_col_nick, NULL, NULL }, + { "col_nick_op", N_("color for operator symbol"), + N_("color for operator symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightgreen", NULL, &cfg_col_nick_op, NULL, NULL }, + { "col_nick_halfop", N_("color for half-operator symbol"), + N_("color for half-operator symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "lightmagenta", NULL, &cfg_col_nick_halfop, NULL, NULL }, + { "col_nick_voice", N_("color for voice symbol"), + N_("color for voice symbol"), + OPTION_TYPE_COLOR, 0, 0, 0, + "yellow", NULL, &cfg_col_nick_voice, NULL, NULL }, + { "col_nick_sep", N_("color for nick separator"), + N_("color for nick separator"), + OPTION_TYPE_COLOR, 0, 0, 0, + "blue", NULL, &cfg_col_nick_sep, NULL, NULL }, + { "col_nick_self", N_("color for local nick"), + N_("color for local nick"), + OPTION_TYPE_COLOR, 0, 0, 0, + "white", NULL, &cfg_col_nick_self, NULL, NULL }, + { "col_nick_private", N_("color for other nick in private window"), + N_("color for other nick in private window"), + OPTION_TYPE_COLOR, 0, 0, 0, + "brown", NULL, &cfg_col_nick_private, NULL, NULL }, + { "col_nick_bg", N_("background for nicknames"), + N_("background for nicknames"), + OPTION_TYPE_COLOR, 0, 0, 0, + "default", NULL, &cfg_col_nick_bg, NULL, NULL }, + + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, history section */ + +int cfg_history_max_lines; +int cfg_history_max_commands; + +t_config_option weechat_options_history[] = +{ { "history_max_lines", N_("max lines in history (per window)"), + N_("maximum number of lines in history " + "for one server/channel/private window (0 = unlimited)"), + OPTION_TYPE_INT, 0, INT_MAX, 4096, + NULL, NULL, &cfg_history_max_lines, NULL, NULL }, + { "history_max_commands", N_("max user commands in history"), + N_("maximum number of user commands in history (0 = unlimited)"), + OPTION_TYPE_INT, 0, INT_MAX, 100, + NULL, NULL, &cfg_history_max_commands, NULL, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, log section */ + +int cfg_log_auto_channels; +int cfg_log_auto_private; +char *cfg_log_path; +char *cfg_log_name; +char *cfg_log_timestamp; +char *cfg_log_start_string; +char *cfg_log_end_string; + +t_config_option weechat_options_log[] = +{ { "log_auto_channels", N_("automatically log channel chats"), + N_("automatically log channel chats"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_log_auto_channels, NULL, NULL }, + { "log_auto_private", N_("automatically log private chats"), + N_("automatically log private chats"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_log_auto_private, NULL, NULL }, + { "log_path", N_("path for log files"), + N_("path for WeeChat log files"), + OPTION_TYPE_STRING, 0, 0, 0, + "~/.weechat/logs/", NULL, NULL, &cfg_log_path, NULL }, + { "log_name", N_("name for log files"), + N_("name for log files (%S == irc server name, " + "%N == channel name (or nickname if private chat)"), + OPTION_TYPE_STRING, 0, 0, 0, + "%S,%N.weechatlog", NULL, NULL, &cfg_log_name, NULL }, + { "log_timestamp", N_("timestamp for log"), + N_("timestamp for log (see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "~", NULL, NULL, &cfg_log_timestamp, NULL }, + { "log_start_string", N_("start string for log files"), + N_("text written when starting new log file " + "(see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "--- Log started %a %b %d %Y %H:%M:%s", NULL, NULL, &cfg_log_start_string, NULL }, + { "log_end_string", N_("end string for log files"), + N_("text written when ending log file " + "(see man strftime for date/time specifiers)"), + OPTION_TYPE_STRING, 0, 0, 0, + "--- Log ended %a %b %d %Y %H:%M:%s", NULL, NULL, &cfg_log_end_string, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, dcc section */ + +int cfg_dcc_auto_accept_files; +int cfg_dcc_auto_accept_max_size; +int cfg_dcc_auto_accept_chats; +int cfg_dcc_timeout; +char *cfg_dcc_download_path; +char *cfg_dcc_upload_path; +int cfg_dcc_auto_rename; +int cfg_dcc_auto_resume; + +t_config_option weechat_options_dcc[] = +{ { "dcc_auto_accept_files", N_("automatically accept dcc files"), + N_("automatically accept incoming dcc files"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_accept_files, NULL, NULL }, + { "dcc_auto_accept_max_size", N_("max size when auto accepting file"), + N_("maximum size for incoming file when automatically accepted"), + OPTION_TYPE_INT, 0, INT_MAX, 0, + NULL, NULL, &cfg_dcc_auto_accept_max_size, NULL, NULL }, + { "dcc_auto_accept_chats", N_("automatically accept dcc chats"), + N_("automatically accept dcc chats (use carefully!)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_accept_chats, NULL, NULL }, + { "dcc_timeout", N_("timeout for dcc request"), + N_("timeout for dcc request (in seconds)"), + OPTION_TYPE_INT, 1, INT_MAX, 300, + NULL, NULL, &cfg_dcc_timeout, NULL, NULL }, + { "dcc_download_path", N_("path for incoming files with dcc"), + N_("path for writing incoming files with dcc (default: user home)"), + OPTION_TYPE_STRING, 0, 0, 0, "~", + NULL, NULL, &cfg_dcc_download_path, NULL }, + { "dcc_upload_path", N_("default path for sending files with dcc"), + N_("path for reading files when sending thru dcc (when no path is specified)"), + OPTION_TYPE_STRING, 0, 0, 0, "~", + NULL, NULL, &cfg_dcc_upload_path, NULL }, + { "dcc_auto_rename", N_("automatically rename dcc files if already exists"), + N_("rename incoming files if already exists (add '.1', '.2', ...)"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_rename, NULL, NULL }, + { "dcc_auto_resume", N_("automatically resume aborted transfers"), + N_("automatically resume dcc transfer if connection with remote host is loosed"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &cfg_dcc_auto_resume, NULL, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, proxy section */ + +int cfg_proxy_use; +char *cfg_proxy_address; +int cfg_proxy_port; +char *cfg_proxy_password; + +t_config_option weechat_options_proxy[] = +{ { "proxy_use", N_("use proxy"), + N_("use a proxy server to connect to irc server"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, + NULL, NULL, &cfg_proxy_use, NULL, NULL }, + { "proxy_address", N_("proxy address"), + N_("proxy server address (IP or hostname)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &cfg_proxy_address, NULL }, + { "proxy_port", N_("port for proxy"), + N_("port for connecting to proxy server"), + OPTION_TYPE_INT, 0, 65535, 1080, + NULL, NULL, &cfg_proxy_port, NULL, NULL }, + { "proxy_password", N_("proxy password"), + N_("password for proxy server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &cfg_proxy_password, NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* config, server section */ + +static t_irc_server cfg_server; + +t_config_option weechat_options_server[] = +{ { "server_name", N_("server name"), + N_("name associated to IRC server (for display only)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.name), NULL }, + { "server_autoconnect", N_("automatically connect to server"), + N_("automatically connect to server when WeeChat is starting"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE, + NULL, NULL, &(cfg_server.autoconnect), NULL, NULL }, + { "server_address", N_("server address or hostname"), + N_("IP address or hostname of IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.address), NULL }, + { "server_port", N_("port for IRC server"), + N_("port for connecting to server"), + OPTION_TYPE_INT, 0, 65535, 6667, + NULL, NULL, &(cfg_server.port), NULL, NULL }, + { "server_password", N_("server password"), + N_("password for IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.password), NULL }, + { "server_nick1", N_("nickname for server"), + N_("nickname to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick1), NULL }, + { "server_nick2", N_("alternate nickname for server"), + N_("alternate nickname to use on IRC server (if nickname is already used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick2), NULL }, + { "server_nick3", N_("2nd alternate nickname for server"), + N_("2nd alternate nickname to use on IRC server (if alternate nickname is already used)"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.nick3), NULL }, + { "server_username", N_("user name for server"), + N_("user name to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.username), NULL }, + { "server_realname", N_("real name for server"), + N_("real name to use on IRC server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.realname), NULL }, + { "server_command", N_("first command to run when connected to server"), + N_("first command to run when connected to server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.command), NULL }, + { "server_autojoin", N_("list of channels to join when connected to server"), + N_("comma separated list of channels to join when connected to server"), + OPTION_TYPE_STRING, 0, 0, 0, + "", NULL, NULL, &(cfg_server.autojoin), NULL }, + { NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } +}; + +/* all weechat options */ + +t_config_option *weechat_options[CONFIG_NUMBER_SECTIONS] = +{ weechat_options_look, weechat_options_colors, weechat_options_history, + weechat_options_log, weechat_options_dcc, weechat_options_proxy, + NULL, weechat_options_server +}; + + +/* + * get_pos_array_values: returns position of a string in an array of values + * returns -1 if not found, otherwise position + */ + +int +get_pos_array_values (char **array, char *string) +{ + int i; + + i = 0; + while (array[i]) + { + if (strcasecmp (array[i], string) == 0) + return i; + i++; + } + /* string not found in array */ + return -1; +} + +/* + * config_option_set_value: set new value for an option + * return: 0 if success + * -1 if error (bad value) + */ + +int +config_option_set_value (t_config_option *option, char *value) +{ + int int_value; + + switch (option->option_type) + { + case OPTION_TYPE_BOOLEAN: + if (strcasecmp (value, "on") == 0) + *(option->ptr_int) = BOOL_TRUE; + else if (strcasecmp (value, "off") == 0) + *(option->ptr_int) = BOOL_FALSE; + else + return -1; + break; + case OPTION_TYPE_INT: + int_value = atoi (value); + if ((int_value < option->min) || (int_value > option->max)) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = get_pos_array_values (option->array_values, value); + if (int_value < 0) + return -1; + *(option->ptr_int) = int_value; + break; + case OPTION_TYPE_COLOR: + if (!gui_assign_color (option->ptr_int, value)) + return -1; + break; + case OPTION_TYPE_STRING: + if (*(option->ptr_string)) + free (*(option->ptr_string)); + *(option->ptr_string) = strdup (value); + break; + } + return 0; +} + +/* + * config_set_value: set new value for an option (found by name) + * return: 0 if success + * -1 if bad value for option + * -2 if option is not found + */ + +int +config_set_value (char *option_name, char *value) +{ + int i, j; + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + /* if option found, assign value and exit */ + if (strcasecmp (weechat_options[i][j].option_name, option_name) == 0) + return config_option_set_value (&weechat_options[i][j], value); + } + } + } + /* option not found */ + return -2; +} + +/* + * config_allocate_server: allocate a new server + */ + +int +config_allocate_server (char *filename, int line_number) +{ + if (!cfg_server.name + || !cfg_server.address + || cfg_server.port < 0 + || !cfg_server.nick1 + || !cfg_server.nick2 + || !cfg_server.nick3 + || !cfg_server.username + || !cfg_server.realname) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: new server, but previous was incomplete\n"), + WEECHAT_WARNING, filename, line_number); + return 0; + + } + if (server_name_already_exists (cfg_server.name)) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: server '%s' already exists\n"), + WEECHAT_WARNING, filename, line_number, cfg_server.name); + return 0; + } + if (!server_new (cfg_server.name, + cfg_server.autoconnect, cfg_server.address, cfg_server.port, + cfg_server.password, cfg_server.nick1, cfg_server.nick2, + cfg_server.nick3, cfg_server.username, cfg_server.realname, + cfg_server.command, cfg_server.autojoin)) + { + server_free_all (); + gui_printf (NULL, + _("%s %s, line %d: unable to create server\n"), + WEECHAT_WARNING, filename, line_number); + return 0; + } + + server_destroy (&cfg_server); + server_init (&cfg_server); + + return 1; +} + +/* + * config_default_values: initialize config variables with default values + */ + +void +config_default_values () +{ + int i, j, int_value; + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + case OPTION_TYPE_INT: + *weechat_options[i][j].ptr_int = + weechat_options[i][j].default_int; + break; + case OPTION_TYPE_INT_WITH_STRING: + int_value = get_pos_array_values ( + weechat_options[i][j].array_values, + weechat_options[i][j].default_string); + if (int_value < 0) + gui_printf (NULL, + _("%s unable to assign default int with string (\"%s\")\n"), + weechat_options[i][j].default_string); + else + *weechat_options[i][j].ptr_int = + int_value; + break; + case OPTION_TYPE_COLOR: + if (!gui_assign_color ( + weechat_options[i][j].ptr_int, + weechat_options[i][j].default_string)) + gui_printf (NULL, + _("%s unable to assign default color (\"%s\")\n"), + weechat_options[i][j].default_string); + break; + case OPTION_TYPE_STRING: + *weechat_options[i][j].ptr_string = + strdup (weechat_options[i][j].default_string); + break; + } + } + } + } +} + +/* + * config_read: read WeeChat configuration + * returns: 0 = successful + * -1 = config file file not found + * < -1 = other error (fatal) + */ + +int +config_read () +{ + char *filename; + FILE *file; + int section, line_number, i, option_number; + int server_found; + char line[1024], *ptr_line, *pos, *pos2; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + if ((file = fopen (filename, "rt")) == NULL) + { + gui_printf (NULL, _("%s config file \"%s\" not found.\n"), + WEECHAT_WARNING, filename); + free (filename); + return -1; + } + + config_default_values (); + server_init (&cfg_server); + + /* read config file */ + section = CONFIG_SECTION_NONE; + server_found = 0; + line_number = 0; + while (!feof (file)) + { + ptr_line = fgets (line, sizeof (line) - 1, file); + line_number++; + if (ptr_line) + { + /* skip spaces */ + while (ptr_line[0] == ' ') + ptr_line++; + /* not a comment and not an empty line */ + if ((ptr_line[0] != '#') && (ptr_line[0] != '\r') + && (ptr_line[0] != '\n')) + { + /* beginning of section */ + if (ptr_line[0] == '[') + { + pos = strchr (line, ']'); + if (pos == NULL) + gui_printf (NULL, + _("%s %s, line %d: invalid syntax, missing \"]\"\n"), + WEECHAT_WARNING, filename, line_number); + else + { + pos[0] = '\0'; + pos = ptr_line + 1; + section = CONFIG_SECTION_NONE; + for (i = 0; config_sections[i].section_name; i++) + { + if (strcmp (config_sections[i].section_name, pos) == 0) + { + section = i; + break; + } + } + if (section == CONFIG_SECTION_NONE) + gui_printf (NULL, + _("%s %s, line %d: unknown section identifier (\"%s\")\n"), + WEECHAT_WARNING, filename, line_number, pos); + else + { + if (server_found) + { + /* if server already started => create it */ + config_allocate_server (filename, line_number); + } + server_found = (section == CONFIG_SECTION_SERVER) ? 1 : 0; + } + } + } + else + { + pos = strchr (line, '='); + if (pos == NULL) + gui_printf (NULL, + _("%s %s, line %d: invalid syntax, missing \"=\"\n"), + WEECHAT_WARNING, filename, line_number); + else + { + pos[0] = '\0'; + pos++; + pos2 = strchr (pos, '\r'); + if (pos2 != NULL) + pos2[0] = '\0'; + pos2 = strchr (pos, '\n'); + if (pos2 != NULL) + pos2[0] = '\0'; + + if (section == CONFIG_SECTION_ALIAS) + { + if (alias_new (line, pos)) + index_command_new (pos); + } + else + { + option_number = -1; + for (i = 0; + weechat_options[section][i].option_name; i++) + { + if (strcmp + (weechat_options[section][i].option_name, + ptr_line) == 0) + { + option_number = i; + break; + } + } + if (option_number < 0) + gui_printf (NULL, + _("%s %s, line %d: invalid option \"%s\"\n"), + WEECHAT_WARNING, filename, line_number, ptr_line); + else + { + if (config_option_set_value (&weechat_options[section][option_number], pos) < 0) + { + switch (weechat_options[section] + [option_number].option_type) + { + case OPTION_TYPE_BOOLEAN: + gui_printf (NULL, + _("%s %s, line %d: invalid value for" + "option '%s'\n" + "Expected: boolean value: " + "'off' or 'on'\n"), + WEECHAT_WARNING, filename, + line_number, ptr_line); + break; + case OPTION_TYPE_INT: + gui_printf (NULL, + _("%s %s, line %d: invalid value for " + "option '%s'\n" + "Expected: integer between %d " + "and %d\n"), + WEECHAT_WARNING, filename, + line_number, ptr_line, + weechat_options[section][option_number].min, + weechat_options[section][option_number].max); + break; + case OPTION_TYPE_INT_WITH_STRING: + gui_printf (NULL, + _("%s %s, line %d: invalid value for " + "option '%s'\n" + "Expected: one of these strings: "), + WEECHAT_WARNING, filename, + line_number, ptr_line); + i = 0; + while (weechat_options[section][option_number].array_values[i]) + { + gui_printf (NULL, "\"%s\" ", + weechat_options[section][option_number].array_values[i]); + i++; + } + gui_printf (NULL, "\n"); + break; + case OPTION_TYPE_COLOR: + gui_printf (NULL, + _("%s %s, line %d: invalid color " + "name for option '%s'\n"), + WEECHAT_WARNING, filename, + line_number, + ptr_line); + break; + } + } + } + } + } + } + } + } + } + + if (server_found) + { + if (!config_allocate_server (filename, line_number)) + { + fclose (file); + free (filename); + return -2; + } + } + + /* set default colors for colors not set */ + /*for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if (i != CONFIG_SECTION_SERVER) + { + for (j = 0; weechat_options[i][j].option_name; j++) + { + if ((weechat_options[i][j].option_type == OPTION_TYPE_COLOR) && + (*weechat_options[i][j].ptr_int == COLOR_NOT_SET)) + *weechat_options[i][j].ptr_int = + gui_get_color_by_name (weechat_options[i][j].default_string); + } + } + }*/ + + fclose (file); + free (filename); + + return 0; +} + + +/* + * config_create_default: create default WeeChat config + * return: 0 if ok + * < 0 if error + */ + +int +config_create_default () +{ + char *filename; + char line[1024]; + FILE *file; + int i, j; + time_t current_time; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + if ((file = fopen (filename, "wt")) == NULL) + { + gui_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename); + free (filename); + return -1; + } + + printf (_("%s: creating default config file...\n"), WEECHAT_NAME); + log_printf (_("creating default config file\n")); + + current_time = time (NULL); + sprintf (line, _("#\n# %s configuration file, created by " + "%s v%s on %s#\n"), + WEECHAT_NAME, WEECHAT_NAME, WEECHAT_VERSION, + ctime (¤t_time)); + fputs (line, file); + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + sprintf (line, "\n[%s]\n", config_sections[i].section_name); + fputs (line, file); + if ((i == CONFIG_SECTION_HISTORY) || (i == CONFIG_SECTION_LOG) || + (i == CONFIG_SECTION_DCC) || (i == CONFIG_SECTION_PROXY)) + { + sprintf (line, + "# WARNING!!! Options for section \"%s\" are not developed!\n", + config_sections[i].section_name); + fputs (line, file); + } + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].default_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + sprintf (line, "%s=%d\n", + weechat_options[i][j].option_name, + weechat_options[i][j].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + case OPTION_TYPE_COLOR: + case OPTION_TYPE_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + weechat_options[i][j].default_string); + break; + } + fputs (line, file); + } + } + } + + /* default aliases */ + /* TODO: remove comments when missing commands will be ok */ + fputs ("\n[alias]\n", file); + fputs ("SAY=msg *\n", file); + fputs ("BYE=quit\n", file); + fputs ("EXIT=quit\n", file); + fputs ("SIGNOFF=quit\n", file); + fputs ("C=clear\n", file); + fputs ("CL=clear\n", file); + fputs ("# CHAT=dcc chat\n", file); + fputs ("# GET=dcc get\n", file); + fputs ("# IG=ignore\n", file); + fputs ("J=join\n", file); + fputs ("K=kick\n", file); + fputs ("# KB=kickban\n", file); + fputs ("# KN=knockout\n", file); + fputs ("LEAVE=part\n", file); + fputs ("M=msg\n", file); + fputs ("# MUB=unban *\n", file); + fputs ("N=names\n", file); + fputs ("T=topic\n", file); + fputs ("# UB=unban\n", file); + fputs ("# UNIG=unignore\n", file); + fputs ("# W=who\n", file); + fputs ("WC=part\n", file); + fputs ("WI=whois\n", file); + fputs ("# WW=whowas\n", file); + + /* default server is freenode */ + fputs ("\n[server]\n", file); + fputs ("server_name=freenode\n", file); + fputs ("server_autoconnect=on\n", file); + fputs ("server_address=irc.freenode.net\n", file); + fputs ("server_port=6667\n", file); + fputs ("server_password=\n", file); + fputs ("server_nick1=weechat_user\n", file); + fputs ("server_nick2=weechat2\n", file); + fputs ("server_nick3=weechat3\n", file); + fputs ("server_username=weechat\n", file); + fputs ("server_realname=WeeChat default realname\n", file); + fputs ("server_command=\n", file); + fputs ("server_autojoin=\n", file); + + fclose (file); + free (filename); + return 0; +} + +/* + * config_write: write WeeChat configurtion + * return: 0 if ok + * < 0 if error + */ + +int +config_write (char *config_name) +{ + char *filename; + char line[1024]; + FILE *file; + int i, j; + time_t current_time; + t_irc_server *ptr_server; + t_weechat_alias *ptr_alias; + + if (config_name) + filename = strdup (config_name); + else + { + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_CONFIG_NAME, getenv ("HOME")); + } + + if ((file = fopen (filename, "wt")) == NULL) + { + gui_printf (NULL, _("%s cannot create file \"%s\"\n"), + WEECHAT_ERROR, filename); + free (filename); + return -1; + } + + log_printf (_("saving config to disk\n")); + + current_time = time (NULL); + sprintf (line, _("#\n# %s configuration file, created by " + "%s v%s on %s#\n"), + WEECHAT_NAME, WEECHAT_NAME, WEECHAT_VERSION, + ctime (¤t_time)); + fputs (line, file); + + for (i = 0; i < CONFIG_NUMBER_SECTIONS; i++) + { + if ((i != CONFIG_SECTION_ALIAS) && (i != CONFIG_SECTION_SERVER)) + { + sprintf (line, "\n[%s]\n", config_sections[i].section_name); + fputs (line, file); + if ((i == CONFIG_SECTION_HISTORY) || (i == CONFIG_SECTION_LOG) || + (i == CONFIG_SECTION_DCC) || (i == CONFIG_SECTION_PROXY)) + { + sprintf (line, + "# WARNING!!! Options for section \"%s\" are not developed!\n", + config_sections[i].section_name); + fputs (line, file); + } + for (j = 0; weechat_options[i][j].option_name; j++) + { + switch (weechat_options[i][j].option_type) + { + case OPTION_TYPE_BOOLEAN: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int && + *weechat_options[i][j].ptr_int) ? + "on" : "off"); + break; + case OPTION_TYPE_INT: + sprintf (line, "%s=%d\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + *weechat_options[i][j].ptr_int : + weechat_options[i][j].default_int); + break; + case OPTION_TYPE_INT_WITH_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + weechat_options[i][j].array_values[*weechat_options[i][j].ptr_int] : + weechat_options[i][j].array_values[weechat_options[i][j].default_int]); + break; + case OPTION_TYPE_COLOR: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_int) ? + gui_get_color_by_value (*weechat_options[i][j].ptr_int) : + weechat_options[i][j].default_string); + break; + case OPTION_TYPE_STRING: + sprintf (line, "%s=%s\n", + weechat_options[i][j].option_name, + (weechat_options[i][j].ptr_string) ? + *weechat_options[i][j].ptr_string : + weechat_options[i][j].default_string); + break; + } + fputs (line, file); + } + } + } + + /* alias section */ + fputs ("\n[alias]\n", file); + for (ptr_alias = weechat_alias; ptr_alias; + ptr_alias = ptr_alias->next_alias) + { + sprintf (line, "%s=%s\n", + ptr_alias->alias_name, ptr_alias->alias_command + 1); + fputs (line, file); + } + + /* server section */ + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + /* default server is freenode */ + fputs ("\n[server]\n", file); + sprintf (line, "server_name=%s\n", ptr_server->name); + fputs (line, file); + sprintf (line, "server_autoconnect=%s\n", + (ptr_server->autoconnect) ? "on" : "off"); + fputs (line, file); + sprintf (line, "server_address=%s\n", ptr_server->address); + fputs (line, file); + sprintf (line, "server_port=%d\n", ptr_server->port); + fputs (line, file); + sprintf (line, "server_password=%s\n", + (ptr_server->password) ? ptr_server->password : ""); + fputs (line, file); + sprintf (line, "server_nick1=%s\n", ptr_server->nick1); + fputs (line, file); + sprintf (line, "server_nick2=%s\n", ptr_server->nick2); + fputs (line, file); + sprintf (line, "server_nick3=%s\n", ptr_server->nick3); + fputs (line, file); + sprintf (line, "server_username=%s\n", ptr_server->username); + fputs (line, file); + sprintf (line, "server_realname=%s\n", ptr_server->realname); + fputs (line, file); + sprintf (line, "server_command=%s\n", + (ptr_server->command) ? ptr_server->command : ""); + fputs (line, file); + sprintf (line, "server_autojoin=%s\n", + (ptr_server->autojoin) ? ptr_server->autojoin : ""); + fputs (line, file); + } + + fclose (file); + free (filename); + return 0; +} diff --git a/weechat/src/common/config.h b/weechat/src/common/config.h new file mode 100644 index 000000000..692698797 --- /dev/null +++ b/weechat/src/common/config.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_CONFIG_H +#define __WEECHAT_CONFIG_H 1 + +#define WEECHAT_CONFIG_NAME "weechat.rc" + +#define CONFIG_SECTION_NONE -1 +#define CONFIG_SECTION_LOOK 0 +#define CONFIG_SECTION_COLORS 1 +#define CONFIG_SECTION_HISTORY 2 +#define CONFIG_SECTION_LOG 3 +#define CONFIG_SECTION_DCC 4 +#define CONFIG_SECTION_PROXY 5 +#define CONFIG_SECTION_ALIAS 6 +#define CONFIG_SECTION_SERVER 7 +#define CONFIG_NUMBER_SECTIONS 8 + +#define OPTION_TYPE_BOOLEAN 1 /* values: on/off */ +#define OPTION_TYPE_INT 2 /* values: from min to max */ +#define OPTION_TYPE_INT_WITH_STRING 3 /* values: one from **array_values */ +#define OPTION_TYPE_COLOR 4 /* values: a color name */ +#define OPTION_TYPE_STRING 5 /* values: any string, may be empty */ + +#define BOOL_FALSE 0 +#define BOOL_TRUE 1 + +#define CFG_LOOK_NICKLIST_LEFT 0 +#define CFG_LOOK_NICKLIST_RIGHT 1 +#define CFG_LOOK_NICKLIST_TOP 2 +#define CFG_LOOK_NICKLIST_BOTTOM 3 + +typedef struct t_config_section t_config_section; + +struct t_config_section +{ + int section_number; + char *section_name; +}; + +typedef struct t_config_option t_config_option; + +struct t_config_option +{ + char *option_name; + char *short_description; + char *long_description; + int option_type; + int min, max; + int default_int; + char *default_string; + char **array_values; + int *ptr_int; + char **ptr_string; + int (*handler_change)(int *, char **); +}; + +extern int cfg_look_set_title; +extern int cfg_look_startup_logo; +extern int cfg_look_startup_version; +extern char *cfg_look_weechat_slogan; +extern int cfg_look_color_nicks; +extern int cfg_look_color_actions; +extern int cfg_look_remove_colors_from_msgs; +extern int cfg_look_nicklist; +extern int cfg_look_nicklist_position; +extern int cfg_look_nicklist_min_size; +extern int cfg_look_nicklist_max_size; +extern int cfg_look_nickmode; +extern int cfg_look_nickmode_empty; +extern char *cfg_look_no_nickname; +extern char *cfg_look_completor; + +extern int cfg_col_title; +extern int cfg_col_title_bg; +extern int cfg_col_chat; +extern int cfg_col_chat_time; +extern int cfg_col_chat_time_sep; +extern int cfg_col_chat_prefix1; +extern int cfg_col_chat_prefix2; +extern int cfg_col_chat_nick; +extern int cfg_col_chat_host; +extern int cfg_col_chat_channel; +extern int cfg_col_chat_dark; +extern int cfg_col_chat_bg; +extern int cfg_col_status; +extern int cfg_col_status_active; +extern int cfg_col_status_data_msg; +extern int cfg_col_status_data_other; +extern int cfg_col_status_more; +extern int cfg_col_status_bg; +extern int cfg_col_input; +extern int cfg_col_input_channel; +extern int cfg_col_input_nick; +extern int cfg_col_input_bg; +extern int cfg_col_nick; +extern int cfg_col_nick_op; +extern int cfg_col_nick_halfop; +extern int cfg_col_nick_voice; +extern int cfg_col_nick_sep; +extern int cfg_col_nick_self; +extern int cfg_col_nick_private; +extern int cfg_col_nick_bg; + +extern int cfg_history_max_lines; +extern int cfg_history_max_commands; + +extern int cfg_log_auto_channels; +extern int cfg_log_auto_private; +extern char *cfg_log_path; +extern char *cfg_log_name; +extern char *cfg_log_timestamp; +extern char *cfg_log_start_string; +extern char *cfg_log_end_string; + +extern int cfg_dcc_auto_accept_files; +extern int cfg_dcc_auto_accept_max_size; +extern int cfg_dcc_auto_accept_chats; +extern int cfg_dcc_timeout; +extern char *cfg_dcc_download_path; +extern char *cfg_dcc_upload_path; +extern int cfg_dcc_auto_rename; +extern int cfg_dcc_auto_resume; + +extern int cfg_proxy_use; +extern char *cfg_proxy_address; +extern int cfg_proxy_port; +extern char *cfg_proxy_password; + +extern t_config_section config_sections [CONFIG_NUMBER_SECTIONS]; +extern t_config_option * weechat_options [CONFIG_NUMBER_SECTIONS]; + +extern int config_read (); +extern int config_create_default (); +extern int config_write (); + +#endif /* config.h */ diff --git a/weechat/src/common/history.c b/weechat/src/common/history.c new file mode 100644 index 000000000..fed419219 --- /dev/null +++ b/weechat/src/common/history.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* history.c: memorize and call again commands or text */ + + +#include <stdlib.h> +#include <string.h> + +#include "weechat.h" +#include "history.h" +#include "../gui/gui.h" + + +t_history *history_general = NULL; +t_history *history_general_ptr = NULL; + + +/* + * history_add: add a text/command to history + */ + +void +history_add (void *window, char *string) +{ + t_history *new_history; + + new_history = (t_history *)malloc (sizeof (t_history)); + if (new_history) + { + new_history->text = strdup (string); + + /* add history to general history */ + if (history_general) + history_general->prev_history = new_history; + new_history->next_history = history_general; + new_history->prev_history = NULL; + history_general = new_history; + + /* add history to local history */ + if (((t_gui_window *)(window))->history) + ((t_gui_window *)(window))->history->prev_history = new_history; + new_history->next_history = ((t_gui_window *)(window))->history; + new_history->prev_history = NULL; + ((t_gui_window *)window)->history = new_history; + } +} diff --git a/weechat/src/common/history.h b/weechat/src/common/history.h new file mode 100644 index 000000000..946f2e792 --- /dev/null +++ b/weechat/src/common/history.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_HISTORY_H +#define __WEECHAT_HISTORY_H 1 + +typedef struct t_history t_history; + +struct t_history +{ + char *text; /* text or command (as entered by user) */ + t_history *next_history; /* link to next text/command */ + t_history *prev_history; /* link to previous text/command */ +}; + +extern void history_add (void *, char *); + +#endif /* history.h */ diff --git a/weechat/src/common/weechat.c b/weechat/src/common/weechat.c new file mode 100644 index 000000000..1e4866c02 --- /dev/null +++ b/weechat/src/common/weechat.c @@ -0,0 +1,324 @@ +/* ############################################################################ + * ### ___ __ ______________ _____ ### + * ### __ | / /___________ ____/__ /_______ __ /_ ### + * ### __ | /| / /_ _ \ _ \ / __ __ \ __ `/ __/ ### + * ### __ |/ |/ / / __/ __/ /___ _ / / / /_/ // /_ ### + * ### ____/|__/ \___/\___/\____/ /_/ /_/\__,_/ \__/ ### + * ### ### + * ### WeeChat - Wee Enhanced Environment for Chat ### + * ### Fast & light environment for Chat ### + * ### ### + * ### By: FlashCode <flashcode@flashtux.org> ### + * ### Bounga <bounga@altern.org> ### + * ### Xahlexx <xahlexx@tuxisland.org> ### + * ### ### + * ### http://weechat.flashtux.org ### + * ### ### + * ############################################################################ + * + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* weechat.c: core functions for WeeChat */ + + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> + +#include "weechat.h" +#include "config.h" +#include "command.h" +#include "../irc/irc.h" +#include "../gui/gui.h" + + +/* char *display_name; */ +int quit_weechat; /* = 1 if quit request from user... why ? :'( */ + +FILE *log_file; /* WeeChat log file (~/.weechat/weechat.log */ + + +/* + * log_printf: displays a message in WeeChat log (~/.weechat/weechat.log) + */ + +void +log_printf (char *message, ...) +{ + static char buffer[4096]; + va_list argptr; + static time_t seconds; + struct tm *date_tmp; + + if (!log_file) + return; + + va_start (argptr, message); + vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); + va_end (argptr); + + seconds = time (NULL); + date_tmp = localtime (&seconds); + fprintf (log_file, "[%04d-%02d-%02d %02d:%02d:%02d] %s", + date_tmp->tm_year + 1900, date_tmp->tm_mon + 1, date_tmp->tm_mday, + date_tmp->tm_hour, date_tmp->tm_min, date_tmp->tm_sec, + buffer); + fflush (log_file); +} + +/* + * wee_parse_args: parse command line args + */ + +void +wee_parse_args (int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) + { + if ((strcmp (argv[i], "-h") == 0) + || (strcmp (argv[i], "--help") == 0)) + { + printf ("\n%s%s", WEE_USAGE); + exit (0); + } + else if ((strcmp (argv[i], "-l") == 0) + || (strcmp (argv[i], "--license") == 0)) + { + printf ("\n%s%s", WEE_LICENSE); + exit (0); + } + /*else if ((strcmp (argv[i], "-d") == 0) + || (strcmp (argv[i], "--display") == 0)) + { + if (i == (argc - 1)) + fprintf (stderr, + _("%s no display specified (parameter '%s'), ignored\n"), + WEECHAT_WARNING, argv[i]); + else + { + display_name = argv[i + 1]; + i++; + } + }*/ + else if ((strcmp (argv[i], "-v") == 0) + || (strcmp (argv[i], "--version") == 0)) + { + printf (WEECHAT_VERSION "\n"); + exit (0); + } + else + { + fprintf (stderr, + _("%s unknown parameter '%s', ignored\n"), + WEECHAT_WARNING, argv[i]); + } + } +} + +/* + * wee_create_home_dir: create weechat home directory (if not found) + */ + +void +wee_create_home_dir () +{ + char *weechat_home_dir; + int return_code; + + weechat_home_dir = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (weechat_home_dir, "%s/.weechat", getenv ("HOME")); + return_code = mkdir (weechat_home_dir, 0755); + if (return_code < 0) + { + if (errno != EEXIST) + { + fprintf (stderr, _("%s cannot create directory \"%s\"\n"), + WEECHAT_ERROR, weechat_home_dir); + free (weechat_home_dir); + exit (1); + } + } + free (weechat_home_dir); +} + +/* + * wee_init_vars: initialize some variables + */ + +void +wee_init_vars () +{ + /* GUI not yet initialized */ + gui_ready = 0; + + /* init received messages queue */ + recv_msgq = NULL; + msgq_last_msg = NULL; +} + +/* + * wee_init_log: initialize log file + */ + +void +wee_init_log () +{ + char *filename; + + filename = + (char *) malloc ((strlen (getenv ("HOME")) + 64) * sizeof (char)); + sprintf (filename, "%s/.weechat/" WEECHAT_LOG_NAME, getenv ("HOME")); + if ((log_file = fopen (filename, "wt")) == NULL) + { + free (filename); + fprintf (stderr, + _("%s unable to create/append to log file (~/.weechat/" + WEECHAT_LOG_NAME), WEECHAT_ERROR); + } + free (filename); +} + +/* + * wee_shutdown: shutdown WeeChat + */ + +void +wee_shutdown () +{ + server_free_all (); + gui_end (); + if (log_file) + fclose (log_file); + exit (0); +} + +/* + * main: WeeChat startup + */ + +int +main (int argc, char *argv[]) +{ + t_irc_server *ptr_server; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, "/usr/share/locale"); + textdomain (PACKAGE); + + /* pre-initiliaze interface */ + gui_pre_init (&argc, &argv); + + /* initialize variables */ + wee_init_vars (); + + /* parse command line args */ + wee_parse_args (argc, argv); + + /* create weechat home directory */ + wee_create_home_dir (); + + /* init log file */ + wee_init_log (); + + /* build commands index (sorted), for completion */ + index_command_build (); + + /* read configuration */ + switch (config_read ()) + { + case 0: /* success */ + break; + case -1: /* config file not found */ + config_create_default (); + config_read (); + break; + default: /* other error (fatal) */ + server_free_all (); + return 1; + } + + /* init gui */ + gui_init (); + + /* Welcome message - yeah! */ + if (cfg_look_startup_logo) + { + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX1, + " ___ __ ______________ _____ \n" + " __ | / /___________ ____/__ /_______ __ /_\n" + " __ | /| / /_ _ \\ _ \\ / __ __ \\ __ `/ __/\n" + " __ |/ |/ / / __/ __/ /___ _ / / / /_/ // /_ \n" + " ____/|__/ \\___/\\___/\\____/ /_/ /_/\\__,_/ \\__/ \n"); + } + if (cfg_look_weechat_slogan && cfg_look_weechat_slogan[0]) + { + gui_printf_color (NULL, COLOR_WIN_CHAT, _("%sWelcome to "), + (cfg_look_startup_logo) ? " " : ""); + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX2, WEECHAT_NAME); + gui_printf_color (NULL, COLOR_WIN_CHAT, + ", %s\n", cfg_look_weechat_slogan); + } + if (cfg_look_startup_version) + { + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX2, + "%s" WEECHAT_NAME_AND_VERSION, + (cfg_look_startup_logo) ? " " : ""); + gui_printf_color (NULL, COLOR_WIN_CHAT, + ", %s %s %s\n", + _("compiled on"), __DATE__, __TIME__); + } + if (cfg_look_startup_logo || + (cfg_look_weechat_slogan && cfg_look_weechat_slogan[0]) || + cfg_look_startup_version) + gui_printf_color (NULL, COLOR_WIN_CHAT_PREFIX1, + "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); + + /* connect to all servers (with autoconnect flag) */ + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + if (ptr_server->autoconnect) + { + gui_window_new (ptr_server, NULL); + if (server_connect (ptr_server)) + irc_login (ptr_server); + } + } + gui_main_loop (); + server_disconnect_all (); + + /* save config file */ + config_write (NULL); + + /* program ending */ + wee_shutdown (); + + /* make gcc happy (statement never executed) */ + return 0; +} diff --git a/weechat/src/common/weechat.h b/weechat/src/common/weechat.h new file mode 100644 index 000000000..adc0bf04e --- /dev/null +++ b/weechat/src/common/weechat.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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_H +#define __WEECHAT_H 1 + +#include <stdio.h> +#include <locale.h> +#include <libintl.h> + +#define PACKAGE "weechat" +#define _(string) gettext(string) +#define N_(string) (string) + +#define WEECHAT_NAME "WeeChat" +#define WEECHAT_VERSION "0.0.3-pre2" + +#define WEECHAT_NAME_AND_VERSION WEECHAT_NAME " " WEECHAT_VERSION +#define WEECHAT_COPYRIGHT WEECHAT_NAME " (c) 2003 by Wee Team" +#define WEECHAT_WEBSITE "http://weechat.flashtux.org" + +#define WEECHAT_ERROR _(WEECHAT_NAME " Error:") +#define WEECHAT_WARNING _(WEECHAT_NAME " Warning:") + +/* debug mode, 0=normal use, 1=some debug msg, 2=full debug (developers only) */ +#define DEBUG 0 + +/* log file */ + +#define WEECHAT_LOG_NAME "weechat.log" + +/* license */ + +#define WEE_LICENSE \ + WEECHAT_NAME_AND_VERSION " (c) Copyright 2003, compiled on " __DATE__ __TIME__ \ + "Developed by FlashCode <flashcode@flashtux.org>\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + "This program is free software; you can redistribute it and/or modify\n" \ + "it under the terms of the GNU General Public License as published by\n" \ + "the Free Software Foundation; either version 2 of the License, or\n" \ + "(at your option) any later version.\n" \ + "\n", \ + \ + "This program is distributed in the hope that it will be useful,\n" \ + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ + "GNU General Public License for more details.\n" \ + "\n" \ + "You should have received a copy of the GNU General Public License\n" \ + "along with this program; if not, write to the Free Software\n" \ + "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n" + +#define WEE_USAGE \ + WEECHAT_NAME_AND_VERSION " (c) Copyright 2003, compiled on " __DATE__ __TIME__ \ + "Developed by FlashCode <flashcode@flashtux.org>\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + " Bounga <bounga@altern.org>\n" \ + " Xahlexx <xahlexx@tuxisland.org>\n\n" \ + " -h, --help this help screen\n", \ + " -l, --license display WeeChat license\n" \ + " -v, --version display WeeChat version\n\n" + +/* " -d, --display choose X display\n" \*/ + + +/*#define DEFAULT_DISPLAY ":0" */ + + +/*extern char *display_name; */ +int quit_weechat; + +extern int quit_weechat; + +extern void log_printf (char *, ...); +extern void wee_shutdown (); + +#endif /* weechat.h */ diff --git a/weechat/src/gui/Makefile.am b/weechat/src/gui/Makefile.am new file mode 100644 index 000000000..797d3e624 --- /dev/null +++ b/weechat/src/gui/Makefile.am @@ -0,0 +1,30 @@ +# Copyright (c) 2003 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 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 +# + +if GUI_CURSES +curses_dir=curses +endif + +if GUI_GTK +gtk_dir=gtk +endif + +if GUI_QT +qt_dir=qt +endif + +SUBDIRS = $(curses_dir) $(gtk_dir) $(qt_dir) diff --git a/weechat/src/gui/curses/Makefile.am b/weechat/src/gui/curses/Makefile.am new file mode 100644 index 000000000..7a8aaacc3 --- /dev/null +++ b/weechat/src/gui/curses/Makefile.am @@ -0,0 +1,26 @@ +# Copyright (c) 2003 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 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 +# + +bin_PROGRAMS = weechat-curses + +weechat_curses_LDADD = ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(CURSES_LIBS) + +weechat_curses_SOURCES = ../gui-common.c \ + gui-display.c \ + gui-input.c diff --git a/weechat/src/gui/curses/gui-display.c b/weechat/src/gui/curses/gui-display.c index f4a88e859..99ab1994c 100644 --- a/weechat/src/gui/curses/gui-display.c +++ b/weechat/src/gui/curses/gui-display.c @@ -29,10 +29,11 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <curses.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" +#include "../../common/config.h" #include "../../irc/irc.h" @@ -151,6 +152,17 @@ gui_window_set_color (WINDOW *window, int num_color) } /* + * gui_window_has_nicklist: returns 1 if window has nicklist + */ + +int +gui_window_has_nicklist (t_gui_window *window) +{ + return (window->win_nick != NULL); +} + + +/* * gui_calculate_pos_size: calculate position and size for a window & sub-win */ @@ -1246,6 +1258,18 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_pre_init: pre-initialize GUI (called before gui_init) + */ + +void +gui_pre_init (int *argc, char **argv[]) +{ + /* nothing for Curses interface */ + (void) argc; + (void) argv; +} + +/* * gui_init_colors: init GUI colors */ diff --git a/weechat/src/gui/curses/gui-input.c b/weechat/src/gui/curses/gui-input.c index 134ec8d20..61a5243d5 100644 --- a/weechat/src/gui/curses/gui-input.c +++ b/weechat/src/gui/curses/gui-input.c @@ -30,13 +30,15 @@ #include <signal.h> #include <time.h> #include <sys/socket.h> +#include <curses.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" -#include "../../command.h" +#include "../../common/config.h" +#include "../../common/command.h" #include "../../irc/irc.h" +#define KEY_ESCAPE 27 /* * gui_read_keyb: read keyboard line diff --git a/weechat/src/gui/gtk/Makefile.am b/weechat/src/gui/gtk/Makefile.am new file mode 100644 index 000000000..8f2e52569 --- /dev/null +++ b/weechat/src/gui/gtk/Makefile.am @@ -0,0 +1,28 @@ +# Copyright (c) 2003 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 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 +# + +bin_PROGRAMS = weechat-gtk + +INCLUDES = $(GTK_CFLAGS) + +weechat_gtk_LDADD = ../../common/lib_weechat_main.a \ + ../../irc/lib_weechat_irc.a \ + $(GTK_LIBS) + +weechat_gtk_SOURCES = ../gui-common.c \ + gui-display.c \ + gui-input.c diff --git a/weechat/src/gui/gtk/gui-display.c b/weechat/src/gui/gtk/gui-display.c index 673f414f3..d2d12fc39 100644 --- a/weechat/src/gui/gtk/gui-display.c +++ b/weechat/src/gui/gtk/gui-display.c @@ -29,10 +29,11 @@ #include <string.h> #include <signal.h> #include <time.h> +#include <gtk/gtk.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" +#include "../../common/config.h" #include "../../irc/irc.h" @@ -144,6 +145,16 @@ gui_get_color_by_value (int color_value) } /* + * gui_window_has_nicklist: returns 1 if window has nicklist + */ + +int +gui_window_has_nicklist (t_gui_window *window) +{ + return (window->textbuffer_nicklist != NULL); +} + +/* * gui_calculate_pos_size: calculate position and size for a window & sub-win */ @@ -379,7 +390,7 @@ gui_redraw_window (t_gui_window *window) gui_redraw_window_title (window); gui_redraw_window_chat (window); - if (WIN_HAS_NICKLIST(window)) + if (gui_window_has_nicklist (window)) gui_redraw_window_nick (window); gui_redraw_window_status (window); gui_redraw_window_input (window); @@ -538,6 +549,17 @@ gui_window_init_subwindows (t_gui_window *window) } /* + * gui_pre_init: pre-initialize GUI (called before gui_init) + */ + +void +gui_pre_init (int *argc, char **argv[]) +{ + /* Initialise Gtk+ */ + gtk_init (argc, argv); +} + +/* * gui_init_colors: init GUI colors */ diff --git a/weechat/src/gui/gtk/gui-input.c b/weechat/src/gui/gtk/gui-input.c index 4ded0a91b..db30e6523 100644 --- a/weechat/src/gui/gtk/gui-input.c +++ b/weechat/src/gui/gtk/gui-input.c @@ -30,11 +30,12 @@ #include <signal.h> #include <time.h> #include <sys/socket.h> +#include <gtk/gtk.h> -#include "../../weechat.h" +#include "../../common/weechat.h" #include "../gui.h" -#include "../../config.h" -#include "../../command.h" +#include "../../common/config.h" +#include "../../common/command.h" #include "../../irc/irc.h" diff --git a/weechat/src/gui/gui-common.c b/weechat/src/gui/gui-common.c index b6e4c7b86..7d626024d 100644 --- a/weechat/src/gui/gui-common.c +++ b/weechat/src/gui/gui-common.c @@ -31,7 +31,7 @@ #include <time.h> #include <curses.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "gui.h" #include "../irc/irc.h" diff --git a/weechat/src/gui/gui.h b/weechat/src/gui/gui.h index 11f326926..b1584f05e 100644 --- a/weechat/src/gui/gui.h +++ b/weechat/src/gui/gui.h @@ -23,19 +23,8 @@ #ifndef __WEECHAT_GUI_H #define __WEECHAT_GUI_H 1 -#ifdef WEE_CURSES -#include <curses.h> -#endif -#ifdef WEE_GTK -#include <gtk/gtk.h> -#endif - -#include "../completion.h" -#include "../history.h" - -#ifdef WEE_CURSES -#define KEY_ESCAPE 27 -#endif +#include "../common/completion.h" +#include "../common/history.h" #define INPUT_BUFFER_BLOCK_SIZE 256 @@ -77,10 +66,10 @@ #define WIN_IS_PRIVATE(window) (CHANNEL(window) && (CHANNEL(window)->type == CHAT_PRIVATE)) #ifdef WEE_CURSES - #define WIN_HAS_NICKLIST(window) (window->win_nick) + //#define WIN_HAS_NICKLIST(window) (window->win_nick) #endif #ifdef WEE_GTK - #define WIN_HAS_NICKLIST(window) (window->textbuffer_nicklist) + //#define WIN_HAS_NICKLIST(window) (window->textbuffer_nicklist) #endif #define MSG_TYPE_TIME 0 @@ -152,24 +141,27 @@ struct t_gui_window int win_nick_width; /* width of chat window */ int win_nick_height; /* height of chat window */ - /* windows */ - #ifdef WEE_CURSES - WINDOW *win_title; /* title window */ - WINDOW *win_chat; /* chat window (exemple: channel) */ - WINDOW *win_nick; /* nick window */ - WINDOW *win_status; /* status window */ - WINDOW *win_input; /* input window */ - #endif - #ifdef WEE_GTK - GtkWidget *textview_chat; /* textview widget for chat */ - GtkTextBuffer *textbuffer_chat; /* textbuffer widget for chat */ - GtkTextTag *texttag_chat; /* texttag widget for chat */ - GtkWidget *textview_nicklist; /* textview widget for nicklist */ - GtkTextBuffer *textbuffer_nicklist; /* textbuffer widget for nicklist */ - #endif - #ifdef WEE_QT + /* windows for Curses GUI */ + void *win_title; /* title window */ + void *win_chat; /* chat window (exemple: channel) */ + void *win_nick; /* nick window */ + void *win_status; /* status window */ + void *win_input; /* input window */ + + /* windows for Curses GUI */ + //GtkWidget *textview_chat; /* textview widget for chat */ + //GtkTextBuffer *textbuffer_chat; /* textbuffer widget for chat */ + //GtkTextTag *texttag_chat; /* texttag widget for chat */ + //GtkWidget *textview_nicklist; /* textview widget for nicklist */ + //GtkTextBuffer *textbuffer_nicklist; /* textbuffer widget for nicklist */ + void *textview_chat; /* textview widget for chat */ + void *textbuffer_chat; /* textbuffer widget for chat */ + void *texttag_chat; /* texttag widget for chat */ + void *textview_nicklist; /* textview widget for nicklist */ + void *textbuffer_nicklist; /* textbuffer widget for nicklist */ + + /* windows for Curses GUI */ /* TODO: declare Qt window */ - #endif /* chat content (lines, line is composed by many messages) */ t_gui_line *lines; /* lines of chat window */ @@ -222,6 +214,7 @@ extern void gui_buffer_insert_string (char *, int); extern int gui_assign_color (int *, char *); extern int gui_get_color_by_name (char *); extern char *gui_get_color_by_value (int); +extern int gui_window_has_nicklist (t_gui_window *); extern void gui_calculate_pos_size (t_gui_window *); extern void gui_draw_window_title (t_gui_window *); extern void gui_redraw_window_title (t_gui_window *); @@ -240,7 +233,8 @@ extern void gui_switch_to_next_window (); extern void gui_move_page_up (); extern void gui_move_page_down (); extern void gui_window_init_subwindows (t_gui_window *); -extern void gui_init_colors (); +extern void gui_pre_init (int *, char **[]); +//extern void gui_init_colors (); extern void gui_init (); extern void gui_window_free (t_gui_window *); extern void gui_end (); diff --git a/weechat/src/gui/qt/Makefile.am b/weechat/src/gui/qt/Makefile.am new file mode 100644 index 000000000..a0d82e32a --- /dev/null +++ b/weechat/src/gui/qt/Makefile.am @@ -0,0 +1,16 @@ +# Copyright (c) 2003 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 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 +# diff --git a/weechat/src/irc/Makefile.am b/weechat/src/irc/Makefile.am new file mode 100644 index 000000000..d7e85d1ee --- /dev/null +++ b/weechat/src/irc/Makefile.am @@ -0,0 +1,26 @@ +# Copyright (c) 2003 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 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 +# + +noinst_LIBRARIES = lib_weechat_irc.a + +lib_weechat_irc_a_SOURCES = irc-commands.c \ + irc-send.c \ + irc-recv.c \ + irc-server.c \ + irc-channel.c \ + irc-nick.c \ + irc-display.c diff --git a/weechat/src/irc/irc-channel.c b/weechat/src/irc/irc-channel.c index bdad12265..7d426210c 100644 --- a/weechat/src/irc/irc-channel.c +++ b/weechat/src/irc/irc-channel.c @@ -26,7 +26,7 @@ #include <stdlib.h> #include <string.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" diff --git a/weechat/src/irc/irc-commands.c b/weechat/src/irc/irc-commands.c index 0d58f59ec..ae0854181 100644 --- a/weechat/src/irc/irc-commands.c +++ b/weechat/src/irc/irc-commands.c @@ -24,9 +24,9 @@ RFC 1459,2810,2811,2812 */ -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" +#include "../common/command.h" t_irc_command irc_commands[] = diff --git a/weechat/src/irc/irc-display.c b/weechat/src/irc/irc-display.c index 2f2f9931b..69ca1dea7 100644 --- a/weechat/src/irc/irc-display.c +++ b/weechat/src/irc/irc-display.c @@ -28,9 +28,9 @@ #include <stdio.h> #include <string.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../config.h" +#include "../common/config.h" #include "../gui/gui.h" diff --git a/weechat/src/irc/irc-nick.c b/weechat/src/irc/irc-nick.c index ef0814e4e..4365ce23f 100644 --- a/weechat/src/irc/irc-nick.c +++ b/weechat/src/irc/irc-nick.c @@ -27,7 +27,7 @@ #include <string.h> #include <limits.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" diff --git a/weechat/src/irc/irc-recv.c b/weechat/src/irc/irc-recv.c index 99772abf4..ccd6832c8 100644 --- a/weechat/src/irc/irc-recv.c +++ b/weechat/src/irc/irc-recv.c @@ -32,10 +32,10 @@ #include <time.h> #include <sys/utsname.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" -#include "../config.h" +#include "../common/command.h" +#include "../common/config.h" #include "../gui/gui.h" @@ -501,7 +501,7 @@ irc_cmd_recv_nick (t_irc_server *server, char *host, char *arguments) COLOR_WIN_CHAT_NICK, "%s\n", arguments); - if (WIN_HAS_NICKLIST(ptr_channel->window)) + if (gui_window_has_nicklist (ptr_channel->window)) gui_redraw_window_nick (ptr_channel->window); } } @@ -692,7 +692,7 @@ irc_cmd_recv_part (t_irc_server *server, char *host, char *arguments) gui_printf (ptr_channel->window, "\n"); /* redraw nick list if this is current window */ - if (WIN_HAS_NICKLIST(ptr_channel->window)) + if (gui_window_has_nicklist (ptr_channel->window)) gui_redraw_window_nick (ptr_channel->window); } } @@ -978,7 +978,7 @@ irc_cmd_recv_quit (t_irc_server *server, char *host, char *arguments) gui_printf_color (ptr_channel->window, COLOR_WIN_CHAT_DARK, ")\n"); if ((ptr_channel->window == gui_current_window) && - (WIN_HAS_NICKLIST(ptr_channel->window))) + (gui_window_has_nicklist (ptr_channel->window))) gui_redraw_window_nick (ptr_channel->window); } } diff --git a/weechat/src/irc/irc-send.c b/weechat/src/irc/irc-send.c index c672f7fbb..147cfa19b 100644 --- a/weechat/src/irc/irc-send.c +++ b/weechat/src/irc/irc-send.c @@ -32,10 +32,10 @@ #include <time.h> #include <sys/utsname.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" -#include "../command.h" -#include "../config.h" +#include "../common/command.h" +#include "../common/config.h" #include "../gui/gui.h" diff --git a/weechat/src/irc/irc-server.c b/weechat/src/irc/irc-server.c index acc6f5a88..ee1ead0e3 100644 --- a/weechat/src/irc/irc-server.c +++ b/weechat/src/irc/irc-server.c @@ -34,7 +34,7 @@ #include <arpa/inet.h> #include <netdb.h> -#include "../weechat.h" +#include "../common/weechat.h" #include "irc.h" #include "../gui/gui.h" |