* Fixed bugs in invite list handling in INVITE command.
Affected files silcd/command.c and silcd/server_util.c.
+ * Merged with Irssi 0.8.6.
+
Mon Nov 25 18:21:43 EET 2002 Pekka Riikonen <priikone@silcnet.org>
* The silc_argument_get_[first/next] now return the argument
fi
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(Irssi-SILC, 0.8.6)
+AM_INIT_AUTOMAKE(Irssi-SILC, 0.8.6+)
AM_MAINTAINER_MODE
fi
AC_MSG_RESULT($irssi_cv_type_socklen_t)
+dnl * off_t checks, try to make it 64bit
+AC_DEFINE_UNQUOTED(_FILE_OFFSET_BITS, $preferred_off_t_bits)
+
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+
+if test $sizeof_off_t = 8; then
+ offt_64bit=yes
+else
+ offt_64bit=no
+fi
+
+if test x$sizeof_off_t = x$ac_cv_sizeof_long; then
+ # try to use unsigned long always first
+ AC_DEFINE_UNQUOTED(PRIuUOFF_T, "lu")
+ AC_DEFINE(UOFF_T_LONG)
+elif test x$sizeof_off_t = x$ac_cv_sizeof_int; then
+ # next try int
+ AC_DEFINE_UNQUOTED(PRIuUOFF_T, "u")
+ AC_DEFINE(UOFF_T_INT)
+elif test x$sizeof_off_t = x$ac_cv_sizeof_long_long; then
+ # and finally long long
+ AC_DEFINE_UNQUOTED(PRIuUOFF_T, "llu")
+ AC_DEFINE(UOFF_T_LONG_LONG)
+else
+ AC_ERROR([Couldn't find integer type for off_t])
+fi
+
dnl **
dnl ** check for socks
dnl **
docdir = $(silc_docdir)
-doc_DATA = signals.txt formats.txt manual.txt startup-HOWTO.html
+doc_DATA = signals.txt formats.txt manual.txt startup-HOWTO.html \
+ special_vars.txt
# faq.txt
# startup-HOWTO.txt
modes.c:
"channel mode changed", CHANNEL_REC, char *setby
- "nick mode changed", CHANNEL_REC, NICK_REC, char *setby
+ "nick mode changed", CHANNEL_REC, NICK_REC, char *setby, char *mode, char *type
"user mode changed", SERVER_REC, char *old
"away mode changed", SERVER_REC
Text FE
-------
+gui-readline.c:
+ "gui key pressed", int key
+
gui-printtext.c:
"beep"
-
-statusbar-items.c:
- "mail counter"
$$ a literal '$'
$versiontim prints time of the irssi version in HHMM format
- $sysname system name (eg. Linux)
- $sysrelease system release (eg. 2.2.18)
- $sysarch system architecture (eg. i686)
- $topic channel topic
- $usermode user mode
- $cumode own channel user mode
- $cumode_space like $cumode, but gives space if there's no mode.
- $tag server tag
- $chatnet chat network of server
- $winref window reference number
- $winname window name
+ $sysname system name (eg. Linux)
+ $sysrelease system release (eg. 2.2.18)
+ $sysarch system architecture (eg. i686)
+ $topic channel topic
+ $usermode user mode
+ $cumode own channel user mode
+ $cumode_space like $cumode, but gives space if there's no mode.
+ $tag server tag
+ $chatnet chat network of server
+ $winref window reference number
+ $winname window name
+ $itemname like $T, but use item's visible_name which may be
+ different (eg. $T = !12345chan, $itemname = !chan)
For example, assume you have the following alias:
# include <gmodule.h>
#endif
+#if defined (UOFF_T_INT)
+typedef unsigned int uoff_t;
+#elif defined (UOFF_T_LONG)
+typedef unsigned long uoff_t;
+#elif defined (UOFF_T_LONGLONG)
+typedef unsigned long long uoff_t;
+#else
+# error uoff_t size not set
+#endif
+
/* input functions */
#define G_INPUT_READ (1 << 0)
#define G_INPUT_WRITE (1 << 1)
return conn;
}
-/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
+/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-noproxy] [-ircnet <ircnet>]
+ [-host <hostname>] [-rawlog <file>]
<address>|<chatnet> [<port> [<password> [<nick>]]] */
static void cmd_connect(const char *data)
{
signal_emit("command server connect", 3, data, server, item);
}
-/* SYNTAX: SERVER [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
+/* SYNTAX: SERVER [-4 | -6] [-ssl] [-noproxy] [-ircnet <ircnet>]
+ [-host <hostname>] [-rawlog <file>]
[+]<address>|<chatnet> [<port> [<password> [<nick>]]] */
static void cmd_server_connect(const char *data, SERVER_REC *server)
{
return pos;
}
-static char *cmd_get_quoted_param(char **data)
+char *cmd_get_quoted_param(char **data)
{
char *pos, quote;
quote = **data; (*data)++;
pos = *data;
- while (**data != '\0' && (**data != quote || (*data)[1] != ' ')) {
+ while (**data != '\0' && (**data != quote ||
+ ((*data)[1] != ' ' && (*data)[1] != '\0'))) {
if (**data == '\\' && (*data)[1] != '\0')
g_memmove(*data, (*data)+1, strlen(*data));
(*data)++;
#define PARAM_FLAG_OPTCHAN_NAME (0x00020000|PARAM_FLAG_OPTCHAN)
char *cmd_get_param(char **data);
+char *cmd_get_quoted_param(char **data);
/* get parameters from command - you should point free_me somewhere and
cmd_params_free() it after you don't use any of the parameters anymore.
const char *log_timestamp;
static int log_file_create_mode;
+static int log_dir_create_mode;
static int rotate_tag;
static int log_item_str2type(const char *type)
/* path may contain variables (%time, $vars),
make sure the directory is created */
dir = g_dirname(log->real_fname);
- mkpath(dir, LOG_DIR_CREATE_MODE);
+ mkpath(dir, log_dir_create_mode);
g_free(dir);
}
{
log_timestamp = settings_get_str("log_timestamp");
log_file_create_mode = octal2dec(settings_get_int("log_create_mode"));
+
+ log_dir_create_mode = log_file_create_mode;
+ if (log_file_create_mode & 0400) log_dir_create_mode |= 0100;
+ if (log_file_create_mode & 0040) log_dir_create_mode |= 0010;
+ if (log_file_create_mode & 0004) log_dir_create_mode |= 0001;
}
void log_init(void)
#ifndef __LOG_H
#define __LOG_H
-#define LOG_DIR_CREATE_MODE 0700
-
enum {
LOG_ITEM_TARGET, /* channel, query, .. */
LOG_ITEM_WINDOW_REFNUM
return octal;
}
+/* string -> uoff_t */
+uoff_t str_to_uofft(const char *str)
+{
+ uoff_t ret;
+
+ ret = 0;
+ while (*str != '\0') {
+ ret = ret*10 + (*str - '0');
+ str++;
+ }
+
+ return ret;
+}
+
/* convert all low-ascii (<32) to ^<A..> combinations */
char *show_lowascii(const char *channel)
{
int octal2dec(int octal);
int dec2octal(int decimal);
+/* string -> uoff_t */
+uoff_t str_to_uofft(const char *str);
+
/* convert all low-ascii (<32) to ^<A..> combinations */
char *show_lowascii(const char *channel);
static int last_reconnect_tag;
static int reconnect_timeout_tag;
static int reconnect_time;
+static int connect_timeout;
void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server)
{
static int server_reconnect_timeout(void)
{
SERVER_CONNECT_REC *conn;
- GSList *list, *tmp;
+ GSList *list, *tmp, *next;
time_t now;
+ now = time(NULL);
+
+ /* timeout any connections that haven't gotten to connected-stage */
+ for (tmp = servers; tmp != NULL; tmp = next) {
+ SERVER_REC *server = tmp->data;
+
+ next = tmp->next;
+ if (!server->connected &&
+ server->connect_time + connect_timeout < now &&
+ connect_timeout > 0) {
+ server->connection_lost = TRUE;
+ server_disconnect(server);
+ }
+ }
+
/* If server_connect() removes the next reconnection in queue,
we're screwed. I don't think this should happen anymore, but just
to be sure we don't crash, do this safely. */
list = g_slist_copy(reconnects);
- now = time(NULL);
for (tmp = list; tmp != NULL; tmp = tmp->next) {
RECONNECT_REC *rec = tmp->data;
static void read_settings(void)
{
reconnect_time = settings_get_int("server_reconnect_time");
+ connect_timeout = settings_get_int("server_connect_timeout");
}
void servers_reconnect_init(void)
{
settings_add_int("server", "server_reconnect_time", 300);
+ settings_add_int("server", "server_connect_timeout", 300);
reconnects = NULL;
last_reconnect_tag = 0;
}
nest_free = FALSE; nest_value = NULL;
- if (**cmd == '(') {
+ if (**cmd == '(' && (*cmd)[1] != '\0') {
/* subvariable */
int toplevel = nested_orig_cmd == NULL;
flags);
}
+ if (nest_value == NULL || *nest_value == '\0')
+ return NULL;
+
while ((*nested_orig_cmd)[1] != '\0') {
(*nested_orig_cmd)++;
if (**nested_orig_cmd == ')')
brackets = FALSE;
else {
/* special value is inside {...} (foo${test}bar -> fooXXXbar) */
+ if ((*cmd)[1] == '\0')
+ return NULL;
(*cmd)++;
brackets = TRUE;
}
}
/* Complete /MSG - if `find_server' is NULL, complete nicks from all servers */
-static GList *completion_msg(SERVER_REC *win_server,
+GList *completion_msg(SERVER_REC *win_server,
SERVER_REC *find_server,
const char *nick, const char *prefix)
{
GList *completion_get_servertags(const char *word);
GList *completion_get_channels(SERVER_REC *server, const char *word);
GList *completion_get_aliases(const char *word);
+GList *completion_msg(SERVER_REC *win_server, SERVER_REC *find_server,
+ const char *nick, const char *prefix);
void completion_last_message_add(const char *nick);
void completion_last_message_remove(const char *nick);
static int skip_next_printtext;
static const char *log_theme_name;
+static int log_dir_create_mode;
+
static char *log_colorizer_strip(const char *str)
{
return strip_codes(str);
log_item_add(log, LOG_ITEM_TARGET, target, server_tag);
dir = g_dirname(log->real_fname);
- mkpath(dir, LOG_DIR_CREATE_MODE);
+ mkpath(dir, log_dir_create_mode);
g_free(dir);
log->temp = TRUE;
static void read_settings(void)
{
int old_autolog = autolog_level;
+ int log_file_create_mode;
autolog_path = settings_get_str("autolog_path");
autolog_level = !settings_get_bool("autolog") ? 0 :
log_theme = log_theme_name == NULL ? NULL :
theme_load(log_theme_name);
+
+ log_file_create_mode = octal2dec(settings_get_int("log_create_mode"));
+ log_dir_create_mode = log_file_create_mode;
+ if (log_file_create_mode & 0400) log_dir_create_mode |= 0100;
+ if (log_file_create_mode & 0040) log_dir_create_mode |= 0010;
+ if (log_file_create_mode & 0004) log_dir_create_mode |= 0001;
}
void fe_log_init(void)
WINDOW_REC *window_find_level(void *server, int level)
{
GSList *tmp;
+ WINDOW_REC *match;
- /* prefer active window if possible */
- if (active_win != NULL &&
- WINDOW_LEVEL_MATCH(active_win, server, level))
- return active_win;
-
+ match = NULL;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
- if (WINDOW_LEVEL_MATCH(rec, server, level))
- return rec;
+ if (WINDOW_LEVEL_MATCH(rec, server, level)) {
+ /* prefer windows without any items */
+ if (rec->items == NULL)
+ return rec;
+
+ if (match == NULL)
+ match = rec;
+ else if (active_win == rec) {
+ /* prefer active window over others */
+ match = rec;
+ }
+ }
}
- return NULL;
+ return match;
}
WINDOW_REC *window_find_closest(void *server, const char *name, int level)
{
WINDOW_REC *window,*namewindow=NULL;
WI_ITEM_REC *item;
+ int i;
/* match by name */
item = name == NULL ? NULL :
window_item_find(server, name);
if (item != NULL) {
namewindow = window_item_window(item);
- if (namewindow != NULL && ((namewindow->level & level) != 0 ||
- !settings_get_bool("window_check_level_first")))
- return namewindow;
+ if (namewindow != NULL &&
+ ((namewindow->level & level) != 0 ||
+ !settings_get_bool("window_check_level_first"))) {
+ /* match, but if multiple windows have the same level
+ we could be choosing a bad one here, eg.
+ name=nick1 would get nick2's query instead of
+ generic msgs window. */
+ if (g_strcasecmp(name, item->visible_name) == 0)
+ return namewindow;
+ }
}
- /* match by level */
- if (level != MSGLEVEL_HILIGHT)
- level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT);
- window = window_find_level(server, level);
- if (window != NULL) return window;
-
- /* match by level - ignore server */
- window = window_find_level(NULL, level);
- if (window != NULL) return window;
+ /* prefer windows without items */
+ for (i = 0; i < 2; i++) {
+ /* match by level */
+ if (level != MSGLEVEL_HILIGHT)
+ level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT);
+ window = window_find_level(server, level);
+ if (window != NULL && (i == 1 || window->items == NULL))
+ return window;
+
+ /* match by level - ignore server */
+ window = window_find_level(NULL, level);
+ if (window != NULL && (i == 1 || window->items == NULL))
+ return window;
+ }
/* still return item's window if we didnt find anything */
if (namewindow != NULL) return namewindow;
/* SYNTAX: WINDOW NAME <name> */
static void cmd_window_name(const char *data)
{
- if (window_find_name(data) == NULL)
+ WINDOW_REC *win;
+
+ win = window_find_name(data);
+ if (win == NULL || win == active_win)
window_set_name(active_win, data);
else if (active_win->name == NULL ||
strcmp(active_win->name, data) != 0) {
data = redir->data;
g_free_and_null(redir);
+ gui_entry_set_prompt(active_entry, "");
+
if (func != NULL)
func(key, data, active_win->active_server, active_win->active);
-
- gui_entry_set_prompt(active_entry, "");
}
static void handle_entry_redirect(const char *line)
data = redir->data;
g_free_and_null(redir);
+ gui_entry_set_prompt(active_entry, "");
+
if (func != NULL) {
func(line, data, active_win->active_server,
active_win->active);
}
-
- gui_entry_set_prompt(active_entry, "");
}
static int get_scroll_count(void)
gui_window_scroll(active_win, get_scroll_count());
}
-void handle_key(unichar key)
+static void sig_gui_key_pressed(gpointer keyp)
{
+ unichar key;
char str[20];
- idle_time = time(NULL);
+ key = GPOINTER_TO_INT(keyp);
if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HOTKEY) {
handle_key_redirect(key);
return;
}
+ idle_time = time(NULL);
+
if (key < 32) {
/* control key */
str[0] = '^';
if (!term_detached)
signal_emit("command quit", 1, "Lost terminal");
} else {
- for (i = 0; i < ret; i++)
- handle_key(buffer[i]);
+ for (i = 0; i < ret; i++) {
+ signal_emit("gui key pressed", 1,
+ GINT_TO_POINTER(buffer[i]));
+ }
}
}
signal_add("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
signal_add("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
+ signal_add("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
}
void gui_readline_deinit(void)
signal_remove("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
signal_remove("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
+ signal_remove("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
}
TEXT_BUFFER_VIEW_REC *view;
view = WINDOW_GUI(active_win)->view;
- if (view->bottom_startline == NULL)
+ if (view->bottom_startline == NULL ||
+ (view->bottom_startline == view->startline &&
+ view->bottom_subline == view->subline))
return;
textbuffer_view_scroll_line(view, view->bottom_startline);
#include "irssi-version.h"
#include "core.h"
+#include "pidwait.h"
+
#define DEFAULT_COMMAND_CATEGORY "Perl scripts' commands"
void perl_signal_add_hash(int priority, SV *sv)
SV *func
SV *data
CODE:
- RETVAL = perl_input_add(source, condition, func, data);
+ RETVAL = perl_input_add(source, condition, func, data, FALSE);
OUTPUT:
RETVAL
retcount = perl_call_sv(rec->func, G_EVAL|G_SCALAR);
SPAGAIN;
+ ret = NULL;
if (SvTRUE(ERRSV)) {
/* make sure we don't get back here */
if (rec->script != NULL)
script_unregister_expandos(rec->script);
signal_emit("script error", 2, rec->script, SvPV(ERRSV, PL_na));
- ret = NULL;
} else if (retcount > 0) {
ret = g_strdup(POPp);
*free_ret = TRUE;
static int initialized = FALSE;
+void perl_expando_init(void);
+void perl_expando_deinit(void);
+
+void perl_settings_init(void);
+void perl_settings_deinit(void);
+
MODULE = Irssi PACKAGE = Irssi
PROTOTYPES: ENABLE
#include "perl/perl-core.h"
#include "perl/perl-common.h"
#include "perl/perl-signals.h"
+#include "perl/perl-sources.h"
typedef COMMAND_REC *Irssi__Command;
typedef LOG_REC *Irssi__Log;
char *perl_get_use_list(void);
+void perl_command(const char *cmd, SERVER_REC *server, WI_ITEM_REC *item);
+
+void perl_chatnet_fill_hash(HV *hv, CHATNET_REC *chatnet);
+void perl_connect_fill_hash(HV *hv, SERVER_CONNECT_REC *conn);
+void perl_server_fill_hash(HV *hv, SERVER_REC *server);
+void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item);
+void perl_channel_fill_hash(HV *hv, CHANNEL_REC *channel);
+void perl_query_fill_hash(HV *hv, QUERY_REC *query);
+void perl_nick_fill_hash(HV *hv, NICK_REC *nick);
+
#define irssi_boot(x) { \
extern void boot_Irssi__##x(pTHX_ CV *cv); \
irssi_callXS(boot_Irssi__##x, cv, mark); \
void perl_command_unbind(const char *cmd, SV *func);
+void perl_command_runsub(const char *cmd, const char *data,
+ SERVER_REC *server, WI_ITEM_REC *item);
+
void perl_signals_start(void);
void perl_signals_stop(void);
#include "perl-core.h"
#include "perl-common.h"
+#include "perl-sources.h"
typedef struct {
PERL_SCRIPT_REC *script;
#ifndef __PERL_SOURCES_H
#define __PERL_SOURCES_H
-int perl_timeout_add(int msecs, SV *func, SV *data);
-int perl_input_add(int source, int condition, SV *func, SV *data);
+int perl_timeout_add(int msecs, SV *func, SV *data, int once);
+int perl_input_add(int source, int condition, SV *func, SV *data, int once);
void perl_source_remove(int tag);
/* remove all sources used by script */
#include "module.h"
+void perl_statusbar_init(void);
+void perl_statusbar_deinit(void);
+
static int initialized = FALSE;
static void perl_main_window_fill_hash(HV *hv, MAIN_WINDOW_REC *window)
#include "module.h"
+void perl_themes_init(void);
+void perl_themes_deinit(void);
+
static int initialized = FALSE;
static void perl_process_fill_hash(HV *hv, PROCESS_REC *process)
#include "module.h"
+#include "window-activity.h"
+
MODULE = Irssi::UI::Window PACKAGE = Irssi
PROTOTYPES: ENABLE