1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-28 13:56:37 +02:00

Added anti-flood option (irc_anti_flood) (task #5442)

This commit is contained in:
Sebastien Helleu
2006-12-04 09:44:23 +00:00
parent c774d9eb00
commit 10ab4b0a20
34 changed files with 6182 additions and 5340 deletions
+1
View File
@@ -5,6 +5,7 @@ ChangeLog - 2006-12-04
Version 0.2.2 (under dev!):
* added anti-flood option (irc_anti_flood) (task #5442)
* fixed bug with "set_config" function in plugins API (bug #18448)
* plugins: "add_message_handler" now accepts "*" for all IRC messages
* added keys (F9/F10) to scroll topic (task #6030)
+8 -1
View File
@@ -901,10 +901,17 @@
<entry>5</entry>
<entry>Maximal-Lag bis zum Trennen der Verbindung (in Minuten - 0: nie trennen)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>Ganzzahl</entry>
<entry>zwischen 0 und 5</entry>
<entry>2</entry>
<entry>Anti-flood: # seconds between two user messages (0 = no anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>Boolean</entry>
<entry>zwischen 0 und 2147483647</entry>
<entry>zwischen 0 und 5</entry>
<entry>'off'</entry>
<entry>Einen FIFO zur Fernsteuerung des Clients von anderen Prozessen öffnen</entry>
</row>
+7
View File
@@ -901,6 +901,13 @@
<entry>5</entry>
<entry>Disconnect after important lag (in minutes, 0 = never disconnect)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>integer</entry>
<entry>between 0 and 5</entry>
<entry>2</entry>
<entry>Anti-flood: # seconds between two user messages (0 = no anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>boolean</entry>
+7
View File
@@ -901,6 +901,13 @@
<entry>5</entry>
<entry>Déconnexion après un lag important (en minutes, 0 = ne jamais se déconnecter)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>entier</entry>
<entry>entre 0 et 5</entry>
<entry>2</entry>
<entry>Anti-flood: nombre de secondes entre deux messages utilisateur (0 = pas d'anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>booléen</entry>
+311 -296
View File
File diff suppressed because it is too large Load Diff
+313 -296
View File
File diff suppressed because it is too large Load Diff
+311 -296
View File
File diff suppressed because it is too large Load Diff
+316 -297
View File
File diff suppressed because it is too large Load Diff
+313 -296
View File
File diff suppressed because it is too large Load Diff
+958 -876
View File
File diff suppressed because it is too large Load Diff
+314 -299
View File
File diff suppressed because it is too large Load Diff
+22 -1
View File
@@ -731,7 +731,7 @@ user_message (t_irc_server *server, t_gui_buffer *buffer, char *text)
next = pos;
}
server_sendf (server, "PRIVMSG %s :%s", CHANNEL(buffer)->name, text);
server_sendf_queued (server, "PRIVMSG %s :%s", CHANNEL(buffer)->name, text);
user_message_display (server, buffer, text);
if (next)
@@ -1616,6 +1616,8 @@ int
weechat_cmd_debug (t_irc_server *server, t_irc_channel *channel,
int argc, char **argv)
{
t_irc_server *ptr_server;
/* make gcc happy */
(void) server;
(void) channel;
@@ -1639,6 +1641,16 @@ weechat_cmd_debug (t_irc_server *server, t_irc_channel *channel,
gui_printf_nolog (NULL, "DEBUG: windows tree:\n");
weechat_cmd_debug_display_windows (gui_windows_tree, 1);
}
else if (ascii_strcasecmp (argv[0], "deloutq") == 0)
{
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
server_outqueue_free_all (ptr_server);
}
gui_printf_nolog (NULL, "\n");
gui_printf_nolog (NULL, "DEBUG: outqueue DELETED for all servers.\n");
}
else
{
irc_display_prefix (NULL, NULL, PREFIX_ERROR);
@@ -3521,6 +3533,15 @@ weechat_cmd_upgrade (t_irc_server *server, t_irc_channel *channel,
WEECHAT_ERROR);
return -1;
}
if (ptr_server->outqueue)
{
irc_display_prefix (NULL, NULL, PREFIX_ERROR);
gui_printf_nolog (NULL,
_("%s can't upgrade: anti-flood is active on "
"at least one server (sending many lines)\n"),
WEECHAT_ERROR);
return -1;
}
}
filename_length = strlen (weechat_home) + strlen (WEECHAT_SESSION_NAME) + 2;
+5
View File
@@ -717,6 +717,7 @@ int cfg_irc_away_check_max_nicks;
int cfg_irc_lag_check;
int cfg_irc_lag_min_show;
int cfg_irc_lag_disconnect;
int cfg_irc_anti_flood;
int cfg_irc_fifo_pipe;
char *cfg_irc_highlight;
int cfg_irc_colors_receive;
@@ -765,6 +766,10 @@ t_config_option weechat_options_irc[] =
N_("disconnect after important lag (in minutes, 0 = never disconnect)"),
OPTION_TYPE_INT, 0, INT_MAX, 5,
NULL, NULL, &cfg_irc_lag_disconnect, NULL, &config_change_noop },
{ "irc_anti_flood", N_("anti-flood"),
N_("anti-flood: # seconds between two user messages (0 = no anti-flood)"),
OPTION_TYPE_INT, 0, 5, 2,
NULL, NULL, &cfg_irc_anti_flood, NULL, &config_change_noop },
{ "irc_fifo_pipe", N_("create a FIFO pipe for remote control"),
N_("create a FIFO pipe for remote control"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
+1
View File
@@ -210,6 +210,7 @@ extern int cfg_irc_away_check_max_nicks;
extern int cfg_irc_lag_check;
extern int cfg_irc_lag_min_show;
extern int cfg_irc_lag_disconnect;
extern int cfg_irc_anti_flood;
extern int cfg_irc_fifo_pipe;
extern char *cfg_irc_highlight;
extern int cfg_irc_colors_receive;
+11
View File
@@ -132,7 +132,18 @@ gui_main_loop ()
if (local_time->tm_sec != old_sec)
{
old_sec = local_time->tm_sec;
/* send queued messages */
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
if (ptr_server->is_connected)
{
server_outqueue_send (ptr_server);
}
}
/* display time in infobar (if seconds displayed) */
if (cfg_look_infobar_seconds)
{
gui_infobar_draw_time (gui_current_window->buffer);
+167 -11
View File
@@ -115,6 +115,10 @@ server_init (t_irc_server *server)
server->lag_check_time.tv_usec = 0;
server->lag_next_check = time (NULL) + cfg_irc_lag_check;
server->cmd_list_regexp = NULL;
server->queue_msg = 0;
server->last_user_message = 0;
server->outqueue = NULL;
server->last_outqueue = NULL;
server->buffer = NULL;
server->saved_buffer = NULL;
server->channels = NULL;
@@ -279,6 +283,74 @@ server_alloc ()
return new_server;
}
/*
* server_outqueue_add: add a message in out queue
*/
void
server_outqueue_add (t_irc_server *server, char *msg1, char *msg2, int modified)
{
t_irc_outqueue *new_outqueue;
new_outqueue = (t_irc_outqueue *)malloc (sizeof (t_irc_outqueue));
if (new_outqueue)
{
new_outqueue->message_before_mod = (msg1) ? strdup (msg1) : NULL;
new_outqueue->message_after_mod = (msg2) ? strdup (msg2) : NULL;
new_outqueue->modified = modified;
new_outqueue->prev_outqueue = server->last_outqueue;
new_outqueue->next_outqueue = NULL;
if (server->outqueue)
server->last_outqueue->next_outqueue = new_outqueue;
else
server->outqueue = new_outqueue;
server->last_outqueue = new_outqueue;
}
}
/*
* server_outqueue_free: free a message in out queue
*/
void
server_outqueue_free (t_irc_server *server, t_irc_outqueue *outqueue)
{
t_irc_outqueue *new_outqueue;
/* remove outqueue message */
if (server->last_outqueue == outqueue)
server->last_outqueue = outqueue->prev_outqueue;
if (outqueue->prev_outqueue)
{
(outqueue->prev_outqueue)->next_outqueue = outqueue->next_outqueue;
new_outqueue = server->outqueue;
}
else
new_outqueue = outqueue->next_outqueue;
if (outqueue->next_outqueue)
(outqueue->next_outqueue)->prev_outqueue = outqueue->prev_outqueue;
if (outqueue->message_before_mod)
free (outqueue->message_before_mod);
if (outqueue->message_after_mod)
free (outqueue->message_after_mod);
free (outqueue);
server->outqueue = new_outqueue;
}
/*
* server_outqueue_free_all: free all outqueued messages
*/
void
server_outqueue_free_all (t_irc_server *server)
{
while (server->outqueue)
server_outqueue_free (server, server->outqueue);
}
/*
* server_destroy: free server data (not struct himself)
*/
@@ -322,6 +394,8 @@ server_destroy (t_irc_server *server)
free (server->nick_modes);
if (server->away_message)
free (server->away_message);
if (server->outqueue)
server_outqueue_free_all (server);
if (server->channels)
channel_free_all (server);
}
@@ -456,6 +530,54 @@ server_send (t_irc_server *server, char *buffer, int size_buf)
return send (server->sock, buffer, size_buf, 0);
}
/*
* server_outqueue_send: send a message from outqueue
*/
void
server_outqueue_send (t_irc_server *server)
{
time_t time_now;
char *pos;
if (server->outqueue)
{
time_now = time (NULL);
if (time_now >= server->last_user_message + cfg_irc_anti_flood)
{
if (server->outqueue->message_before_mod)
{
pos = strchr (server->outqueue->message_before_mod, '\r');
if (pos)
pos[0] = '\0';
gui_printf_raw_data (server, 1, 0,
server->outqueue->message_before_mod);
if (pos)
pos[0] = '\r';
}
if (server->outqueue->message_after_mod)
{
pos = strchr (server->outqueue->message_after_mod, '\r');
if (pos)
pos[0] = '\0';
gui_printf_raw_data (server, 1, server->outqueue->modified,
server->outqueue->message_after_mod);
if (pos)
pos[0] = '\r';
}
if (server_send (server, server->outqueue->message_after_mod,
strlen (server->outqueue->message_after_mod)) <= 0)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
}
server->last_user_message = time_now;
server_outqueue_free (server, server->outqueue);
}
}
}
/*
* server_send_one_msg: send one message to IRC server
*/
@@ -465,11 +587,11 @@ server_send_one_msg (t_irc_server *server, char *message)
{
static char buffer[4096];
char *new_msg, *ptr_msg, *pos;
int rc;
int rc, queue, first_message;
time_t time_now;
rc = 1;
gui_printf_raw_data (server, 1, 0, message);
#ifdef DEBUG
gui_printf (server->buffer, "[DEBUG] Sending to server >>> %s\n", message);
#endif
@@ -491,24 +613,52 @@ server_send_one_msg (t_irc_server *server, char *message)
/* message not dropped? */
if (!new_msg || new_msg[0])
{
first_message = 1;
ptr_msg = (new_msg) ? new_msg : message;
while (rc && ptr_msg && ptr_msg[0])
{
pos = strchr (ptr_msg, '\n');
if (pos)
pos[0] = '\0';
if (new_msg)
gui_printf_raw_data (server, 1, 1, ptr_msg);
snprintf (buffer, sizeof (buffer) - 1, "%s\r\n", ptr_msg);
if (server_send (server, buffer, strlen (buffer)) <= 0)
/* anti-flood: look whether we should queue outgoing message or not */
time_now = time (NULL);
queue = 0;
if ((server->queue_msg)
&& ((server->outqueue)
|| ((cfg_irc_anti_flood > 0)
&& (time_now - server->last_user_message < cfg_irc_anti_flood))))
queue = 1;
/* if queue, then only queue message and send nothing now */
if (queue)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
rc = 0;
server_outqueue_add (server,
(new_msg && first_message) ? message : NULL,
buffer,
(new_msg) ? 1 : 0);
}
else
{
if (first_message)
gui_printf_raw_data (server, 1, 0, message);
if (new_msg)
gui_printf_raw_data (server, 1, 1, ptr_msg);
if (server_send (server, buffer, strlen (buffer)) <= 0)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
rc = 0;
}
else
{
if (server->queue_msg)
server->last_user_message = time_now;
}
}
if (pos)
{
@@ -517,6 +667,8 @@ server_send_one_msg (t_irc_server *server, char *message)
}
else
ptr_msg = NULL;
first_message = 0;
}
}
else
@@ -956,6 +1108,7 @@ server_close_connection (t_irc_server *server)
free (server->unterminated_message);
server->unterminated_message = NULL;
}
server_outqueue_free_all (server);
/* server is now disconnected */
server->is_connected = 0;
@@ -2062,6 +2215,9 @@ server_print_log (t_irc_server *server)
server->lag_check_time.tv_sec,
server->lag_check_time.tv_usec);
weechat_log_printf (" lag_next_check. . . : %ld\n", server->lag_next_check);
weechat_log_printf (" last_user_message . : %ld\n", server->last_user_message);
weechat_log_printf (" outqueue. . . . . . : 0x%X\n", server->outqueue);
weechat_log_printf (" last_outqueue . . . : 0x%X\n", server->last_outqueue);
weechat_log_printf (" buffer. . . . . . . : 0x%X\n", server->buffer);
weechat_log_printf (" channels. . . . . . : 0x%X\n", server->channels);
weechat_log_printf (" last_channel. . . . : 0x%X\n", server->last_channel);
+26 -1
View File
@@ -69,6 +69,14 @@
else \
nick->flags &= 0xFFFF - flag;
#define server_sendf_queued(server, fmt, argz...) \
if (server) \
{ \
server->queue_msg = 1; \
server_sendf(server, fmt, ##argz); \
server->queue_msg = 0; \
}
typedef struct t_irc_nick t_irc_nick;
struct t_irc_nick
@@ -117,6 +125,17 @@ struct t_irc_channel
/* server types */
typedef struct t_irc_outqueue t_irc_outqueue;
struct t_irc_outqueue
{
char *message_before_mod; /* message before any modifier */
char *message_after_mod; /* message after modifier(s) */
int modified; /* message was modified by modifier(s) */
t_irc_outqueue *next_outqueue; /* pointer to next message in queue */
t_irc_outqueue *prev_outqueue; /* pointer to previous message in queue */
};
typedef struct t_irc_server t_irc_server;
struct t_irc_server
@@ -165,7 +184,11 @@ struct t_irc_server
int lag; /* lag (in milliseconds) */
struct timeval lag_check_time; /* last time lag was checked (ping sent) */
time_t lag_next_check; /* time for next check */
regex_t *cmd_list_regexp; /* compiled Regular Expression for /list */
regex_t *cmd_list_regexp; /* compiled Regular Expression for /list */
int queue_msg; /* set to 1 when queue (out) is required */
time_t last_user_message; /* time of last user message (anti flood) */
t_irc_outqueue *outqueue; /* queue for outgoing user messages */
t_irc_outqueue *last_outqueue; /* last outgoing user message */
t_gui_buffer *buffer; /* GUI buffer allocated for server */
t_gui_buffer *saved_buffer; /* channel before jumping to next server */
t_irc_channel *channels; /* opened channels on server */
@@ -332,6 +355,7 @@ extern t_irc_ignore *irc_last_ignore;
extern void server_init (t_irc_server *);
extern int server_init_with_url (char *, t_irc_server *);
extern t_irc_server *server_alloc ();
extern void server_outqueue_free_all (t_irc_server *);
extern void server_destroy (t_irc_server *);
extern void server_free (t_irc_server *);
extern void server_free_all ();
@@ -342,6 +366,7 @@ extern char *server_get_charset_decode_iso (t_irc_server *);
extern char *server_get_charset_decode_utf (t_irc_server *);
extern char *server_get_charset_encode (t_irc_server *);
extern int server_send (t_irc_server *, char *, int);
extern void server_outqueue_send (t_irc_server *);
extern void server_sendf (t_irc_server *, char *, ...);
extern void server_parse_message (char *, char **, char **, char **);
extern void server_recv (t_irc_server *);
+1
View File
@@ -5,6 +5,7 @@ ChangeLog - 2006-12-04
Version 0.2.2 (under dev!):
* added anti-flood option (irc_anti_flood) (task #5442)
* fixed bug with "set_config" function in plugins API (bug #18448)
* plugins: "add_message_handler" now accepts "*" for all IRC messages
* added keys (F9/F10) to scroll topic (task #6030)
+8 -1
View File
@@ -901,10 +901,17 @@
<entry>5</entry>
<entry>Maximal-Lag bis zum Trennen der Verbindung (in Minuten - 0: nie trennen)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>Ganzzahl</entry>
<entry>zwischen 0 und 5</entry>
<entry>2</entry>
<entry>Anti-flood: # seconds between two user messages (0 = no anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>Boolean</entry>
<entry>zwischen 0 und 2147483647</entry>
<entry>zwischen 0 und 5</entry>
<entry>'off'</entry>
<entry>Einen FIFO zur Fernsteuerung des Clients von anderen Prozessen öffnen</entry>
</row>
+7
View File
@@ -901,6 +901,13 @@
<entry>5</entry>
<entry>Disconnect after important lag (in minutes, 0 = never disconnect)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>integer</entry>
<entry>between 0 and 5</entry>
<entry>2</entry>
<entry>Anti-flood: # seconds between two user messages (0 = no anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>boolean</entry>
+7
View File
@@ -901,6 +901,13 @@
<entry>5</entry>
<entry>Déconnexion après un lag important (en minutes, 0 = ne jamais se déconnecter)</entry>
</row>
<row>
<entry><option>irc_anti_flood</option></entry>
<entry>entier</entry>
<entry>entre 0 et 5</entry>
<entry>2</entry>
<entry>Anti-flood: nombre de secondes entre deux messages utilisateur (0 = pas d'anti-flood)</entry>
</row>
<row>
<entry><option>irc_fifo_pipe</option></entry>
<entry>booléen</entry>
+311 -296
View File
File diff suppressed because it is too large Load Diff
+313 -296
View File
File diff suppressed because it is too large Load Diff
+311 -296
View File
File diff suppressed because it is too large Load Diff
+316 -297
View File
File diff suppressed because it is too large Load Diff
+313 -296
View File
File diff suppressed because it is too large Load Diff
+958 -876
View File
File diff suppressed because it is too large Load Diff
+314 -299
View File
File diff suppressed because it is too large Load Diff
+22 -1
View File
@@ -731,7 +731,7 @@ user_message (t_irc_server *server, t_gui_buffer *buffer, char *text)
next = pos;
}
server_sendf (server, "PRIVMSG %s :%s", CHANNEL(buffer)->name, text);
server_sendf_queued (server, "PRIVMSG %s :%s", CHANNEL(buffer)->name, text);
user_message_display (server, buffer, text);
if (next)
@@ -1616,6 +1616,8 @@ int
weechat_cmd_debug (t_irc_server *server, t_irc_channel *channel,
int argc, char **argv)
{
t_irc_server *ptr_server;
/* make gcc happy */
(void) server;
(void) channel;
@@ -1639,6 +1641,16 @@ weechat_cmd_debug (t_irc_server *server, t_irc_channel *channel,
gui_printf_nolog (NULL, "DEBUG: windows tree:\n");
weechat_cmd_debug_display_windows (gui_windows_tree, 1);
}
else if (ascii_strcasecmp (argv[0], "deloutq") == 0)
{
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
server_outqueue_free_all (ptr_server);
}
gui_printf_nolog (NULL, "\n");
gui_printf_nolog (NULL, "DEBUG: outqueue DELETED for all servers.\n");
}
else
{
irc_display_prefix (NULL, NULL, PREFIX_ERROR);
@@ -3521,6 +3533,15 @@ weechat_cmd_upgrade (t_irc_server *server, t_irc_channel *channel,
WEECHAT_ERROR);
return -1;
}
if (ptr_server->outqueue)
{
irc_display_prefix (NULL, NULL, PREFIX_ERROR);
gui_printf_nolog (NULL,
_("%s can't upgrade: anti-flood is active on "
"at least one server (sending many lines)\n"),
WEECHAT_ERROR);
return -1;
}
}
filename_length = strlen (weechat_home) + strlen (WEECHAT_SESSION_NAME) + 2;
+5
View File
@@ -717,6 +717,7 @@ int cfg_irc_away_check_max_nicks;
int cfg_irc_lag_check;
int cfg_irc_lag_min_show;
int cfg_irc_lag_disconnect;
int cfg_irc_anti_flood;
int cfg_irc_fifo_pipe;
char *cfg_irc_highlight;
int cfg_irc_colors_receive;
@@ -765,6 +766,10 @@ t_config_option weechat_options_irc[] =
N_("disconnect after important lag (in minutes, 0 = never disconnect)"),
OPTION_TYPE_INT, 0, INT_MAX, 5,
NULL, NULL, &cfg_irc_lag_disconnect, NULL, &config_change_noop },
{ "irc_anti_flood", N_("anti-flood"),
N_("anti-flood: # seconds between two user messages (0 = no anti-flood)"),
OPTION_TYPE_INT, 0, 5, 2,
NULL, NULL, &cfg_irc_anti_flood, NULL, &config_change_noop },
{ "irc_fifo_pipe", N_("create a FIFO pipe for remote control"),
N_("create a FIFO pipe for remote control"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
+1
View File
@@ -210,6 +210,7 @@ extern int cfg_irc_away_check_max_nicks;
extern int cfg_irc_lag_check;
extern int cfg_irc_lag_min_show;
extern int cfg_irc_lag_disconnect;
extern int cfg_irc_anti_flood;
extern int cfg_irc_fifo_pipe;
extern char *cfg_irc_highlight;
extern int cfg_irc_colors_receive;
+11
View File
@@ -132,7 +132,18 @@ gui_main_loop ()
if (local_time->tm_sec != old_sec)
{
old_sec = local_time->tm_sec;
/* send queued messages */
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
if (ptr_server->is_connected)
{
server_outqueue_send (ptr_server);
}
}
/* display time in infobar (if seconds displayed) */
if (cfg_look_infobar_seconds)
{
gui_infobar_draw_time (gui_current_window->buffer);
+167 -11
View File
@@ -115,6 +115,10 @@ server_init (t_irc_server *server)
server->lag_check_time.tv_usec = 0;
server->lag_next_check = time (NULL) + cfg_irc_lag_check;
server->cmd_list_regexp = NULL;
server->queue_msg = 0;
server->last_user_message = 0;
server->outqueue = NULL;
server->last_outqueue = NULL;
server->buffer = NULL;
server->saved_buffer = NULL;
server->channels = NULL;
@@ -279,6 +283,74 @@ server_alloc ()
return new_server;
}
/*
* server_outqueue_add: add a message in out queue
*/
void
server_outqueue_add (t_irc_server *server, char *msg1, char *msg2, int modified)
{
t_irc_outqueue *new_outqueue;
new_outqueue = (t_irc_outqueue *)malloc (sizeof (t_irc_outqueue));
if (new_outqueue)
{
new_outqueue->message_before_mod = (msg1) ? strdup (msg1) : NULL;
new_outqueue->message_after_mod = (msg2) ? strdup (msg2) : NULL;
new_outqueue->modified = modified;
new_outqueue->prev_outqueue = server->last_outqueue;
new_outqueue->next_outqueue = NULL;
if (server->outqueue)
server->last_outqueue->next_outqueue = new_outqueue;
else
server->outqueue = new_outqueue;
server->last_outqueue = new_outqueue;
}
}
/*
* server_outqueue_free: free a message in out queue
*/
void
server_outqueue_free (t_irc_server *server, t_irc_outqueue *outqueue)
{
t_irc_outqueue *new_outqueue;
/* remove outqueue message */
if (server->last_outqueue == outqueue)
server->last_outqueue = outqueue->prev_outqueue;
if (outqueue->prev_outqueue)
{
(outqueue->prev_outqueue)->next_outqueue = outqueue->next_outqueue;
new_outqueue = server->outqueue;
}
else
new_outqueue = outqueue->next_outqueue;
if (outqueue->next_outqueue)
(outqueue->next_outqueue)->prev_outqueue = outqueue->prev_outqueue;
if (outqueue->message_before_mod)
free (outqueue->message_before_mod);
if (outqueue->message_after_mod)
free (outqueue->message_after_mod);
free (outqueue);
server->outqueue = new_outqueue;
}
/*
* server_outqueue_free_all: free all outqueued messages
*/
void
server_outqueue_free_all (t_irc_server *server)
{
while (server->outqueue)
server_outqueue_free (server, server->outqueue);
}
/*
* server_destroy: free server data (not struct himself)
*/
@@ -322,6 +394,8 @@ server_destroy (t_irc_server *server)
free (server->nick_modes);
if (server->away_message)
free (server->away_message);
if (server->outqueue)
server_outqueue_free_all (server);
if (server->channels)
channel_free_all (server);
}
@@ -456,6 +530,54 @@ server_send (t_irc_server *server, char *buffer, int size_buf)
return send (server->sock, buffer, size_buf, 0);
}
/*
* server_outqueue_send: send a message from outqueue
*/
void
server_outqueue_send (t_irc_server *server)
{
time_t time_now;
char *pos;
if (server->outqueue)
{
time_now = time (NULL);
if (time_now >= server->last_user_message + cfg_irc_anti_flood)
{
if (server->outqueue->message_before_mod)
{
pos = strchr (server->outqueue->message_before_mod, '\r');
if (pos)
pos[0] = '\0';
gui_printf_raw_data (server, 1, 0,
server->outqueue->message_before_mod);
if (pos)
pos[0] = '\r';
}
if (server->outqueue->message_after_mod)
{
pos = strchr (server->outqueue->message_after_mod, '\r');
if (pos)
pos[0] = '\0';
gui_printf_raw_data (server, 1, server->outqueue->modified,
server->outqueue->message_after_mod);
if (pos)
pos[0] = '\r';
}
if (server_send (server, server->outqueue->message_after_mod,
strlen (server->outqueue->message_after_mod)) <= 0)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
}
server->last_user_message = time_now;
server_outqueue_free (server, server->outqueue);
}
}
}
/*
* server_send_one_msg: send one message to IRC server
*/
@@ -465,11 +587,11 @@ server_send_one_msg (t_irc_server *server, char *message)
{
static char buffer[4096];
char *new_msg, *ptr_msg, *pos;
int rc;
int rc, queue, first_message;
time_t time_now;
rc = 1;
gui_printf_raw_data (server, 1, 0, message);
#ifdef DEBUG
gui_printf (server->buffer, "[DEBUG] Sending to server >>> %s\n", message);
#endif
@@ -491,24 +613,52 @@ server_send_one_msg (t_irc_server *server, char *message)
/* message not dropped? */
if (!new_msg || new_msg[0])
{
first_message = 1;
ptr_msg = (new_msg) ? new_msg : message;
while (rc && ptr_msg && ptr_msg[0])
{
pos = strchr (ptr_msg, '\n');
if (pos)
pos[0] = '\0';
if (new_msg)
gui_printf_raw_data (server, 1, 1, ptr_msg);
snprintf (buffer, sizeof (buffer) - 1, "%s\r\n", ptr_msg);
if (server_send (server, buffer, strlen (buffer)) <= 0)
/* anti-flood: look whether we should queue outgoing message or not */
time_now = time (NULL);
queue = 0;
if ((server->queue_msg)
&& ((server->outqueue)
|| ((cfg_irc_anti_flood > 0)
&& (time_now - server->last_user_message < cfg_irc_anti_flood))))
queue = 1;
/* if queue, then only queue message and send nothing now */
if (queue)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
rc = 0;
server_outqueue_add (server,
(new_msg && first_message) ? message : NULL,
buffer,
(new_msg) ? 1 : 0);
}
else
{
if (first_message)
gui_printf_raw_data (server, 1, 0, message);
if (new_msg)
gui_printf_raw_data (server, 1, 1, ptr_msg);
if (server_send (server, buffer, strlen (buffer)) <= 0)
{
irc_display_prefix (server, server->buffer, PREFIX_ERROR);
gui_printf (server->buffer, _("%s error sending data to IRC server\n"),
WEECHAT_ERROR);
rc = 0;
}
else
{
if (server->queue_msg)
server->last_user_message = time_now;
}
}
if (pos)
{
@@ -517,6 +667,8 @@ server_send_one_msg (t_irc_server *server, char *message)
}
else
ptr_msg = NULL;
first_message = 0;
}
}
else
@@ -956,6 +1108,7 @@ server_close_connection (t_irc_server *server)
free (server->unterminated_message);
server->unterminated_message = NULL;
}
server_outqueue_free_all (server);
/* server is now disconnected */
server->is_connected = 0;
@@ -2062,6 +2215,9 @@ server_print_log (t_irc_server *server)
server->lag_check_time.tv_sec,
server->lag_check_time.tv_usec);
weechat_log_printf (" lag_next_check. . . : %ld\n", server->lag_next_check);
weechat_log_printf (" last_user_message . : %ld\n", server->last_user_message);
weechat_log_printf (" outqueue. . . . . . : 0x%X\n", server->outqueue);
weechat_log_printf (" last_outqueue . . . : 0x%X\n", server->last_outqueue);
weechat_log_printf (" buffer. . . . . . . : 0x%X\n", server->buffer);
weechat_log_printf (" channels. . . . . . : 0x%X\n", server->channels);
weechat_log_printf (" last_channel. . . . : 0x%X\n", server->last_channel);
+26 -1
View File
@@ -69,6 +69,14 @@
else \
nick->flags &= 0xFFFF - flag;
#define server_sendf_queued(server, fmt, argz...) \
if (server) \
{ \
server->queue_msg = 1; \
server_sendf(server, fmt, ##argz); \
server->queue_msg = 0; \
}
typedef struct t_irc_nick t_irc_nick;
struct t_irc_nick
@@ -117,6 +125,17 @@ struct t_irc_channel
/* server types */
typedef struct t_irc_outqueue t_irc_outqueue;
struct t_irc_outqueue
{
char *message_before_mod; /* message before any modifier */
char *message_after_mod; /* message after modifier(s) */
int modified; /* message was modified by modifier(s) */
t_irc_outqueue *next_outqueue; /* pointer to next message in queue */
t_irc_outqueue *prev_outqueue; /* pointer to previous message in queue */
};
typedef struct t_irc_server t_irc_server;
struct t_irc_server
@@ -165,7 +184,11 @@ struct t_irc_server
int lag; /* lag (in milliseconds) */
struct timeval lag_check_time; /* last time lag was checked (ping sent) */
time_t lag_next_check; /* time for next check */
regex_t *cmd_list_regexp; /* compiled Regular Expression for /list */
regex_t *cmd_list_regexp; /* compiled Regular Expression for /list */
int queue_msg; /* set to 1 when queue (out) is required */
time_t last_user_message; /* time of last user message (anti flood) */
t_irc_outqueue *outqueue; /* queue for outgoing user messages */
t_irc_outqueue *last_outqueue; /* last outgoing user message */
t_gui_buffer *buffer; /* GUI buffer allocated for server */
t_gui_buffer *saved_buffer; /* channel before jumping to next server */
t_irc_channel *channels; /* opened channels on server */
@@ -332,6 +355,7 @@ extern t_irc_ignore *irc_last_ignore;
extern void server_init (t_irc_server *);
extern int server_init_with_url (char *, t_irc_server *);
extern t_irc_server *server_alloc ();
extern void server_outqueue_free_all (t_irc_server *);
extern void server_destroy (t_irc_server *);
extern void server_free (t_irc_server *);
extern void server_free_all ();
@@ -342,6 +366,7 @@ extern char *server_get_charset_decode_iso (t_irc_server *);
extern char *server_get_charset_decode_utf (t_irc_server *);
extern char *server_get_charset_encode (t_irc_server *);
extern int server_send (t_irc_server *, char *, int);
extern void server_outqueue_send (t_irc_server *);
extern void server_sendf (t_irc_server *, char *, ...);
extern void server_parse_message (char *, char **, char **, char **);
extern void server_recv (t_irc_server *);