mirror of
https://github.com/weechat/weechat.git
synced 2026-06-24 20:06:38 +02:00
1357 lines
46 KiB
C
1357 lines
46 KiB
C
/*
|
|
* Copyright (C) 2010-2011 Sebastien Helleu <flashcode@flashtux.org>
|
|
*
|
|
* This file is part of WeeChat, the extensible chat client.
|
|
*
|
|
* WeeChat 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* irc-redirect.c: redirection of IRC command output
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <time.h>
|
|
|
|
#include "../weechat-plugin.h"
|
|
#include "irc.h"
|
|
#include "irc-redirect.h"
|
|
#include "irc-server.h"
|
|
|
|
|
|
struct t_irc_redirect_pattern *irc_redirect_patterns = NULL;
|
|
struct t_irc_redirect_pattern *last_irc_redirect_pattern = NULL;
|
|
|
|
/* default redirect patterns */
|
|
struct t_irc_redirect_pattern irc_redirect_patterns_default[] =
|
|
{
|
|
{ "ison", 0, 0,
|
|
/*
|
|
* ison: start: -
|
|
* stop: 303: ison
|
|
* extra: -
|
|
*/
|
|
NULL,
|
|
"303",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "list", 0, 0,
|
|
/*
|
|
* list: start: 321: /list start
|
|
* stop: 323: end of /list
|
|
* extra: -
|
|
*/
|
|
"321",
|
|
"323",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "mode_channel", 0, 0,
|
|
/*
|
|
* mode_channel: start: -
|
|
* stop: 324: mode
|
|
* 403: no such channel
|
|
* 442: not on channel
|
|
* 479: cannot join channel (illegal name)
|
|
* extra: 329: channel creation date
|
|
*/
|
|
NULL,
|
|
"324:1,403:1,442:1,479:1",
|
|
"329:1",
|
|
NULL, NULL,
|
|
},
|
|
{ "mode_channel_ban", 0, 0, /* mode #channel b */
|
|
/*
|
|
* mode_channel_ban: start: 367: ban
|
|
* stop: 368: end of channel ban list
|
|
* 403: no such channel
|
|
* 442: not on channel
|
|
* 479: cannot join channel (illegal name)
|
|
* extra: -
|
|
*/
|
|
"367:1",
|
|
"368:1,403:1,442:1,479:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "mode_channel_ban_exception", 0, 0, /* mode #channel e */
|
|
/*
|
|
* mode_channel_ban_exception: start: 348: ban exception
|
|
* stop: 349: end of ban exceptions
|
|
* 403: no such channel
|
|
* 442: not on channel
|
|
* 472: unknown mode char to me
|
|
* 479: cannot join channel (illegal name)
|
|
* 482: you're not channel operator
|
|
* extra: -
|
|
*/
|
|
"348:1",
|
|
"349:1,403:1,442:1,472,479:1,482:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "mode_channel_invite", 0, 0, /* mode #channel I */
|
|
/*
|
|
* mode_channel_invite: start: 346: invite
|
|
* stop: 347: end of invite list
|
|
* 403: no such channel
|
|
* 442: not on channel
|
|
* 472: unknown mode char to me
|
|
* 479: cannot join channel (illegal name)
|
|
* 482: you're not channel operator
|
|
* extra: -
|
|
*/
|
|
"346:1",
|
|
"347:1,403:1,442:1,472,479:1,482:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "mode_user", 0, 0,
|
|
/*
|
|
* mode_user: start: -
|
|
* stop: mode: mode
|
|
* 221: user mode string
|
|
* 403: no such channel
|
|
* 501: unknown mode flag
|
|
* 502: can't change mode for other users
|
|
* extra; -
|
|
*/
|
|
NULL,
|
|
"mode:0,221:0,403:1,501,502",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "names", 0, 0,
|
|
/*
|
|
* names: start: 353: list of nicks on channel
|
|
* stop: 366: end of /names list
|
|
* extra; -
|
|
*/
|
|
"353:2",
|
|
"366:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "ping", 0, 0,
|
|
/*
|
|
* ping: start: -
|
|
* stop: pong: pong
|
|
* 402: no such server
|
|
* extra: -
|
|
*/
|
|
NULL,
|
|
"pong,402",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "time", 0, 0,
|
|
/*
|
|
* time: start: -
|
|
* stop: 391: local time from server
|
|
* extra: -
|
|
*/
|
|
NULL,
|
|
"391",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "topic", 0, 0,
|
|
/*
|
|
* topic: start: -
|
|
* stop: 331: no topic is set
|
|
* 332: topic
|
|
* 403: no such channel
|
|
* extra: 333: infos about topic (nick and date changed)
|
|
*/
|
|
NULL,
|
|
"331:1,332:1,403:1",
|
|
"333:1",
|
|
NULL, NULL,
|
|
},
|
|
{ "userhost", 0, 0,
|
|
/*
|
|
* userhost: start: 401: no such nick/channel
|
|
* stop: 302: userhost
|
|
* 461: not enough parameters
|
|
* extra: -
|
|
*/
|
|
"401:1",
|
|
"302,461",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "who", 0, 0,
|
|
/*
|
|
* who: start: 352: who
|
|
* 354: whox
|
|
* 401: no such nick/channel
|
|
* stop: 315: end of /who list
|
|
* 403: no such channel
|
|
* extra: -
|
|
*/
|
|
"352:1,354,401:1",
|
|
"315:1,403:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ "whois", 0, 0,
|
|
/*
|
|
* whois: start: 311: whois (user)
|
|
* stop: 318: whois (end)
|
|
* 401: no such nick/channel
|
|
* 402: no such server
|
|
* 431: no nickname given
|
|
* 461: not enough parameters
|
|
* extra: 318: whois (end)
|
|
*/
|
|
"311:1",
|
|
"318:1,401:1,402:1,431:1,461",
|
|
"318:1",
|
|
NULL, NULL,
|
|
},
|
|
{ "whowas", 0, 0,
|
|
/*
|
|
* whowas: start: 314: whowas (user)
|
|
* 406: there was no such nickname
|
|
* stop: 369: end of whowas
|
|
* extra: -
|
|
*/
|
|
"314:1,406:1",
|
|
"369:1",
|
|
NULL,
|
|
NULL, NULL,
|
|
},
|
|
{ NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* irc_redirect_pattern_search: search a redirect pattern in list of patterns
|
|
*/
|
|
|
|
struct t_irc_redirect_pattern *
|
|
irc_redirect_pattern_search (const char *name)
|
|
{
|
|
struct t_irc_redirect_pattern *ptr_redirect_pattern;
|
|
|
|
if (!name)
|
|
return NULL;
|
|
|
|
for (ptr_redirect_pattern = irc_redirect_patterns; ptr_redirect_pattern;
|
|
ptr_redirect_pattern = ptr_redirect_pattern->next_redirect)
|
|
{
|
|
if (strcmp (ptr_redirect_pattern->name, name) == 0)
|
|
return ptr_redirect_pattern;
|
|
}
|
|
|
|
/* redirect pattern not found */
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_new: create a new redirect pattern
|
|
*/
|
|
|
|
struct t_irc_redirect_pattern *
|
|
irc_redirect_pattern_new (const char *name, int temp_pattern, int timeout,
|
|
const char *cmd_start, const char *cmd_stop,
|
|
const char *cmd_extra)
|
|
{
|
|
struct t_irc_redirect_pattern *ptr_redirect_pattern, *new_redirect_pattern;
|
|
|
|
if (!name)
|
|
return NULL;
|
|
|
|
if (!cmd_stop || !cmd_stop[0])
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: missing argument \"%s\" for redirect pattern"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME,
|
|
"cmd_stop");
|
|
return NULL;
|
|
}
|
|
|
|
/* check if redirect pattern already exists */
|
|
ptr_redirect_pattern = irc_redirect_pattern_search (name);
|
|
if (ptr_redirect_pattern)
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: redirect pattern \"%s\" already exists"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME,
|
|
name);
|
|
return NULL;
|
|
}
|
|
|
|
new_redirect_pattern = malloc (sizeof (*new_redirect_pattern));
|
|
if (!new_redirect_pattern)
|
|
return NULL;
|
|
|
|
/* initialize new redirect */
|
|
new_redirect_pattern->name = strdup (name);
|
|
new_redirect_pattern->temp_pattern = temp_pattern;
|
|
new_redirect_pattern->timeout = (timeout > 0) ? timeout : IRC_REDIRECT_TIMEOUT_DEFAULT;
|
|
new_redirect_pattern->cmd_start = (cmd_start) ? strdup (cmd_start) : NULL;
|
|
new_redirect_pattern->cmd_stop = strdup (cmd_stop);
|
|
new_redirect_pattern->cmd_extra = (cmd_extra) ? strdup (cmd_extra) : NULL;
|
|
|
|
/* add redirect pattern to end of list */
|
|
new_redirect_pattern->prev_redirect = last_irc_redirect_pattern;
|
|
if (irc_redirect_patterns)
|
|
last_irc_redirect_pattern->next_redirect = new_redirect_pattern;
|
|
else
|
|
irc_redirect_patterns = new_redirect_pattern;
|
|
last_irc_redirect_pattern = new_redirect_pattern;
|
|
new_redirect_pattern->next_redirect = NULL;
|
|
|
|
return new_redirect_pattern;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_free: free a redirect pattern and remove it from list
|
|
*/
|
|
|
|
void
|
|
irc_redirect_pattern_free (struct t_irc_redirect_pattern *redirect_pattern)
|
|
{
|
|
struct t_irc_redirect_pattern *new_redirect_patterns;
|
|
|
|
if (!redirect_pattern)
|
|
return;
|
|
|
|
/* remove redirect */
|
|
if (last_irc_redirect_pattern == redirect_pattern)
|
|
last_irc_redirect_pattern = redirect_pattern->prev_redirect;
|
|
if (redirect_pattern->prev_redirect)
|
|
{
|
|
(redirect_pattern->prev_redirect)->next_redirect = redirect_pattern->next_redirect;
|
|
new_redirect_patterns = irc_redirect_patterns;
|
|
}
|
|
else
|
|
new_redirect_patterns = redirect_pattern->next_redirect;
|
|
|
|
if (redirect_pattern->next_redirect)
|
|
(redirect_pattern->next_redirect)->prev_redirect = redirect_pattern->prev_redirect;
|
|
|
|
/* free data */
|
|
if (redirect_pattern->name)
|
|
free (redirect_pattern->name);
|
|
if (redirect_pattern->cmd_start)
|
|
free (redirect_pattern->cmd_start);
|
|
if (redirect_pattern->cmd_stop)
|
|
free (redirect_pattern->cmd_stop);
|
|
if (redirect_pattern->cmd_extra)
|
|
free (redirect_pattern->cmd_extra);
|
|
|
|
free (redirect_pattern);
|
|
|
|
irc_redirect_patterns = new_redirect_patterns;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_free_all: free all redirect patterns
|
|
*/
|
|
|
|
void
|
|
irc_redirect_pattern_free_all ()
|
|
{
|
|
while (irc_redirect_patterns)
|
|
{
|
|
irc_redirect_pattern_free (irc_redirect_patterns);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_new_with_commands: create a new redirect for a command on a
|
|
* server (with start/stop/extra commands in
|
|
* arguments)
|
|
*/
|
|
|
|
struct t_irc_redirect *
|
|
irc_redirect_new_with_commands (struct t_irc_server *server,
|
|
const char *pattern, const char *signal,
|
|
int count, const char *string, int timeout,
|
|
const char *cmd_start,
|
|
const char *cmd_stop,
|
|
const char *cmd_extra,
|
|
const char *cmd_filter)
|
|
{
|
|
struct t_irc_redirect *new_redirect;
|
|
char **items[4], *pos, *error;
|
|
int i, j, num_items[4];
|
|
long value;
|
|
struct t_hashtable *hash_cmd[4];
|
|
|
|
new_redirect = malloc (sizeof (*new_redirect));
|
|
if (!new_redirect)
|
|
return NULL;
|
|
|
|
/* create hashtables with commands */
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
hash_cmd[i] = NULL;
|
|
items[i] = NULL;
|
|
}
|
|
if (cmd_start)
|
|
items[0] = weechat_string_split (cmd_start, ",", 0, 0, &num_items[0]);
|
|
if (cmd_stop)
|
|
items[1] = weechat_string_split (cmd_stop, ",", 0, 0, &num_items[1]);
|
|
if (cmd_extra)
|
|
items[2] = weechat_string_split (cmd_extra, ",", 0, 0, &num_items[2]);
|
|
if (cmd_filter)
|
|
items[3] = weechat_string_split (cmd_filter, ",", 0, 0, &num_items[3]);
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
if (items[i])
|
|
{
|
|
hash_cmd[i] = weechat_hashtable_new (8,
|
|
WEECHAT_HASHTABLE_STRING,
|
|
WEECHAT_HASHTABLE_INTEGER,
|
|
NULL,
|
|
NULL);
|
|
for (j = 0; j < num_items[i]; j++)
|
|
{
|
|
if (i < 3)
|
|
{
|
|
value = -1;
|
|
pos = strchr (items[i][j], ':');
|
|
if (pos)
|
|
{
|
|
pos[0] = '\0';
|
|
value = strtol (pos + 1, &error, 10);
|
|
if (!error || error[0])
|
|
value = -1;
|
|
}
|
|
weechat_string_toupper (items[i][j]);
|
|
weechat_hashtable_set (hash_cmd[i], items[i][j], &value);
|
|
}
|
|
else
|
|
{
|
|
weechat_hashtable_set (hash_cmd[i], items[i][j], NULL);
|
|
}
|
|
}
|
|
weechat_string_free_split (items[i]);
|
|
}
|
|
}
|
|
|
|
/* initialize new redirect */
|
|
new_redirect->server = server;
|
|
new_redirect->pattern = strdup (pattern);
|
|
new_redirect->signal = strdup (signal);
|
|
new_redirect->count = (count >= 1) ? count : 1;
|
|
new_redirect->current_count = 1;
|
|
new_redirect->string = (string) ? strdup (string) : NULL;
|
|
new_redirect->timeout = timeout;
|
|
new_redirect->command = NULL;
|
|
new_redirect->start_time = 0;
|
|
new_redirect->cmd_start = hash_cmd[0];
|
|
new_redirect->cmd_stop = hash_cmd[1];
|
|
new_redirect->cmd_extra = hash_cmd[2];
|
|
new_redirect->cmd_start_received = 0;
|
|
new_redirect->cmd_stop_received = 0;
|
|
new_redirect->cmd_filter = hash_cmd[3];
|
|
new_redirect->output = NULL;
|
|
new_redirect->output_size = 0;
|
|
|
|
/* add redirect to end of list */
|
|
new_redirect->prev_redirect = server->last_redirect;
|
|
if (server->redirects)
|
|
(server->last_redirect)->next_redirect = new_redirect;
|
|
else
|
|
server->redirects = new_redirect;
|
|
server->last_redirect = new_redirect;
|
|
new_redirect->next_redirect = NULL;
|
|
|
|
return new_redirect;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_new: create a new redirect for a command on a server
|
|
*/
|
|
|
|
struct t_irc_redirect *
|
|
irc_redirect_new (struct t_irc_server *server,
|
|
const char *pattern, const char *signal,
|
|
int count, const char *string, int timeout,
|
|
const char *cmd_filter)
|
|
{
|
|
struct t_irc_redirect_pattern *ptr_redirect_pattern;
|
|
struct t_irc_redirect *new_redirect;
|
|
|
|
if (!server->is_connected)
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: no connection to server \"%s\" for redirect"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME,
|
|
server->name);
|
|
return NULL;
|
|
}
|
|
|
|
if (!pattern || !pattern[0])
|
|
{
|
|
weechat_printf (NULL, _("%s%s: missing argument \"%s\" for redirect"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, "pattern");
|
|
return NULL;
|
|
}
|
|
if (!signal || !signal[0])
|
|
{
|
|
weechat_printf (NULL, _("%s%s: missing argument \"%s\" for redirect"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, "signal");
|
|
return NULL;
|
|
}
|
|
|
|
ptr_redirect_pattern = irc_redirect_pattern_search (pattern);
|
|
if (!ptr_redirect_pattern)
|
|
{
|
|
weechat_printf (NULL, _("%s%s: redirect pattern \"%s\" not found"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME,
|
|
pattern);
|
|
return NULL;
|
|
}
|
|
|
|
new_redirect = irc_redirect_new_with_commands (server, pattern, signal,
|
|
count, string,
|
|
(timeout > 0) ? timeout : ptr_redirect_pattern->timeout,
|
|
ptr_redirect_pattern->cmd_start,
|
|
ptr_redirect_pattern->cmd_stop,
|
|
ptr_redirect_pattern->cmd_extra,
|
|
cmd_filter);
|
|
|
|
/*
|
|
* remove redirect pattern if it is temporary (created by external
|
|
* plugin/script)
|
|
*/
|
|
if (new_redirect && ptr_redirect_pattern->temp_pattern)
|
|
irc_redirect_pattern_free (ptr_redirect_pattern);
|
|
|
|
return new_redirect;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_search_available: search first redirect available for server
|
|
*/
|
|
|
|
struct t_irc_redirect *
|
|
irc_redirect_search_available (struct t_irc_server *server)
|
|
{
|
|
struct t_irc_redirect *ptr_redirect;
|
|
|
|
if (!server)
|
|
return NULL;
|
|
|
|
for (ptr_redirect = server->redirects; ptr_redirect;
|
|
ptr_redirect = ptr_redirect->next_redirect)
|
|
{
|
|
if (ptr_redirect->start_time == 0)
|
|
return ptr_redirect;
|
|
}
|
|
|
|
/* no redirect available */
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_init_command: initalize a redirect with IRC command sent to
|
|
* server
|
|
*/
|
|
|
|
void
|
|
irc_redirect_init_command (struct t_irc_redirect *redirect,
|
|
const char *command)
|
|
{
|
|
char *pos;
|
|
|
|
if (!redirect)
|
|
return;
|
|
|
|
if (command)
|
|
{
|
|
pos = strchr (command, '\r');
|
|
if (!pos)
|
|
pos = strchr (command, '\n');
|
|
if (pos)
|
|
redirect->command = weechat_strndup (command, pos - command);
|
|
else
|
|
redirect->command = strdup (command);
|
|
}
|
|
else
|
|
redirect->command = NULL;
|
|
|
|
redirect->start_time = time (NULL);
|
|
|
|
if (weechat_irc_plugin->debug >= 2)
|
|
{
|
|
weechat_printf (redirect->server->buffer,
|
|
_("%s: starting redirection for command \"%s\" "
|
|
"on server \"%s\" (redirect pattern: \"%s\")"),
|
|
IRC_PLUGIN_NAME,
|
|
redirect->command,
|
|
redirect->server->name,
|
|
redirect->pattern);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_message_match_hash: return 1 if a message matches hashtable
|
|
* with commands, 0 if it doesn't match
|
|
*/
|
|
|
|
int
|
|
irc_redirect_message_match_hash (struct t_irc_redirect *redirect,
|
|
const char *command,
|
|
char **arguments_argv, int arguments_argc,
|
|
struct t_hashtable *cmd_hash)
|
|
{
|
|
int *value;
|
|
|
|
value = weechat_hashtable_get (cmd_hash, command);
|
|
if (!value)
|
|
return 0;
|
|
|
|
/*
|
|
* if string is in redirect and that this command requires string to
|
|
* be in message, then search for this string
|
|
*/
|
|
if (redirect->string && redirect->string[0] && (*value >= 0))
|
|
{
|
|
if (!arguments_argv || (*value >= arguments_argc))
|
|
return 0;
|
|
|
|
if (weechat_strcasecmp (arguments_argv[*value], redirect->string) != 0)
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_message_add: add a message to redirect output
|
|
*/
|
|
|
|
void
|
|
irc_redirect_message_add (struct t_irc_redirect *redirect, const char *message,
|
|
const char *command)
|
|
{
|
|
char *output2;
|
|
|
|
/*
|
|
* if command is not for output, then don't add message
|
|
* (it is silently ignored)
|
|
*/
|
|
if (redirect->cmd_filter
|
|
&& !weechat_hashtable_has_key (redirect->cmd_filter, command))
|
|
return;
|
|
|
|
/* add message to output */
|
|
if (redirect->output)
|
|
{
|
|
redirect->output_size += strlen("\n") + strlen (message);
|
|
output2 = realloc (redirect->output, redirect->output_size);
|
|
if (!output2)
|
|
{
|
|
free (redirect->output);
|
|
redirect->output = NULL;
|
|
redirect->output_size = 0;
|
|
return;
|
|
}
|
|
redirect->output = output2;
|
|
strcat (redirect->output, "\n");
|
|
}
|
|
else
|
|
{
|
|
redirect->output_size = strlen (message) + 1;
|
|
redirect->output = malloc (redirect->output_size);
|
|
if (redirect->output)
|
|
redirect->output[0] = '\0';
|
|
}
|
|
if (redirect->output)
|
|
strcat (redirect->output, message);
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_stop: end of a redirection: send data to callback and free
|
|
* redirect (if count has been reached)
|
|
*/
|
|
|
|
void
|
|
irc_redirect_stop (struct t_irc_redirect *redirect, const char *error)
|
|
{
|
|
struct t_hashtable *hashtable;
|
|
char signal_name[1024], str_int[64];
|
|
|
|
redirect->current_count++;
|
|
|
|
if (error || (redirect->current_count > redirect->count))
|
|
{
|
|
/*
|
|
* error or max count reached, then we run callback and remove
|
|
* redirect
|
|
*/
|
|
hashtable = weechat_hashtable_new (8,
|
|
WEECHAT_HASHTABLE_STRING,
|
|
WEECHAT_HASHTABLE_STRING,
|
|
NULL,
|
|
NULL);
|
|
if (hashtable)
|
|
{
|
|
/* set error and output (main fields) */
|
|
weechat_hashtable_set (hashtable, "error",
|
|
(error) ? (char *)error : "");
|
|
weechat_hashtable_set (hashtable, "output",
|
|
(redirect->output) ? redirect->output : "");
|
|
snprintf (str_int, sizeof (str_int), "%d", redirect->output_size);
|
|
weechat_hashtable_set (hashtable, "output_size", str_int);
|
|
|
|
/* set some other fields with values from redirect */
|
|
weechat_hashtable_set (hashtable, "server", redirect->server->name);
|
|
weechat_hashtable_set (hashtable, "pattern", redirect->pattern);
|
|
weechat_hashtable_set (hashtable, "signal", redirect->signal);
|
|
weechat_hashtable_set (hashtable, "command", redirect->command);
|
|
}
|
|
|
|
snprintf (signal_name, sizeof (signal_name), "irc_redirection_%s_%s",
|
|
redirect->signal, redirect->pattern);
|
|
weechat_hook_hsignal_send (signal_name, hashtable);
|
|
|
|
if (hashtable)
|
|
weechat_hashtable_free (hashtable);
|
|
|
|
irc_redirect_free (redirect);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* max count not yet reached, then we prepare redirect to continue
|
|
* redirection
|
|
*/
|
|
redirect->cmd_start_received = 0;
|
|
redirect->cmd_stop_received = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_message: try to redirect a received message (from IRC server)
|
|
* to a redirect in server
|
|
* return: 1 if message has been redirected
|
|
* 0 if no matching redirect was found
|
|
* if message has been redirected, irc plugin will
|
|
* discard it (do not display anything)
|
|
*/
|
|
|
|
int
|
|
irc_redirect_message (struct t_irc_server *server, const char *message,
|
|
const char *command, const char *arguments)
|
|
{
|
|
struct t_irc_redirect *ptr_redirect, *ptr_next_redirect;
|
|
int rc, match_stop, arguments_argc;
|
|
char **arguments_argv;
|
|
|
|
if (!server || !server->redirects || !message || !command)
|
|
return 0;
|
|
|
|
rc = 0;
|
|
|
|
if (arguments && arguments[0])
|
|
{
|
|
arguments_argv = weechat_string_split (arguments, " ", 0, 0,
|
|
&arguments_argc);
|
|
}
|
|
else
|
|
{
|
|
arguments_argv = NULL;
|
|
arguments_argc = 0;
|
|
}
|
|
|
|
ptr_redirect = server->redirects;
|
|
while (ptr_redirect)
|
|
{
|
|
ptr_next_redirect = ptr_redirect->next_redirect;
|
|
|
|
if (ptr_redirect->start_time > 0)
|
|
{
|
|
if (ptr_redirect->cmd_stop_received)
|
|
{
|
|
if (ptr_redirect->cmd_extra
|
|
&& irc_redirect_message_match_hash (ptr_redirect,
|
|
command,
|
|
arguments_argv,
|
|
arguments_argc,
|
|
ptr_redirect->cmd_extra))
|
|
{
|
|
irc_redirect_message_add (ptr_redirect, message, command);
|
|
irc_redirect_stop (ptr_redirect, NULL);
|
|
rc = 1;
|
|
goto end;
|
|
}
|
|
irc_redirect_stop (ptr_redirect, NULL);
|
|
}
|
|
else
|
|
{
|
|
/* message matches a start command? */
|
|
if (ptr_redirect->cmd_start
|
|
&& !ptr_redirect->cmd_start_received
|
|
&& irc_redirect_message_match_hash (ptr_redirect,
|
|
command,
|
|
arguments_argv,
|
|
arguments_argc,
|
|
ptr_redirect->cmd_start))
|
|
{
|
|
/*
|
|
* message is a start command for redirection, then add
|
|
* message to output for redirection and mark start
|
|
* command as "received" for this redirect
|
|
*/
|
|
irc_redirect_message_add (ptr_redirect, message, command);
|
|
ptr_redirect->cmd_start_received = 1;
|
|
rc = 1;
|
|
goto end;
|
|
}
|
|
/*
|
|
* if matching stop command, or start command received, we are
|
|
* in redirection: add message to output and close redirection
|
|
* if matching stop command
|
|
*/
|
|
match_stop = irc_redirect_message_match_hash (ptr_redirect,
|
|
command,
|
|
arguments_argv,
|
|
arguments_argc,
|
|
ptr_redirect->cmd_stop);
|
|
if (match_stop || ptr_redirect->cmd_start_received)
|
|
{
|
|
/*
|
|
* add message to output if matching stop of if command
|
|
* is numeric
|
|
*/
|
|
irc_redirect_message_add (ptr_redirect, message, command);
|
|
if (match_stop)
|
|
{
|
|
ptr_redirect->cmd_stop_received = 1;
|
|
if (ptr_redirect->cmd_extra)
|
|
{
|
|
if (irc_redirect_message_match_hash (ptr_redirect,
|
|
command,
|
|
arguments_argv,
|
|
arguments_argc,
|
|
ptr_redirect->cmd_extra))
|
|
{
|
|
/*
|
|
* this command is a stop and extra command,
|
|
* then remove redirect
|
|
*/
|
|
irc_redirect_stop (ptr_redirect, NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* no extra command after stop, then remove
|
|
* redirect
|
|
*/
|
|
irc_redirect_stop (ptr_redirect, NULL);
|
|
}
|
|
}
|
|
rc = 1;
|
|
goto end;
|
|
}
|
|
}
|
|
}
|
|
|
|
ptr_redirect = ptr_next_redirect;
|
|
}
|
|
|
|
end:
|
|
if (arguments_argv)
|
|
weechat_string_free_split (arguments_argv);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_free: free a redirect and remove it from list
|
|
*/
|
|
|
|
void
|
|
irc_redirect_free (struct t_irc_redirect *redirect)
|
|
{
|
|
struct t_irc_server *server;
|
|
struct t_irc_redirect *new_redirects;
|
|
int priority;
|
|
struct t_irc_outqueue *ptr_outqueue;
|
|
|
|
if (!redirect)
|
|
return;
|
|
|
|
server = redirect->server;
|
|
|
|
/* remove redirect */
|
|
if (server->last_redirect == redirect)
|
|
server->last_redirect = redirect->prev_redirect;
|
|
if (redirect->prev_redirect)
|
|
{
|
|
(redirect->prev_redirect)->next_redirect = redirect->next_redirect;
|
|
new_redirects = server->redirects;
|
|
}
|
|
else
|
|
new_redirects = redirect->next_redirect;
|
|
|
|
if (redirect->next_redirect)
|
|
(redirect->next_redirect)->prev_redirect = redirect->prev_redirect;
|
|
|
|
/* remove any pointer to this redirect */
|
|
for (priority = 0; priority < IRC_SERVER_NUM_OUTQUEUES_PRIO; priority++)
|
|
{
|
|
for (ptr_outqueue = server->outqueue[priority]; ptr_outqueue;
|
|
ptr_outqueue = ptr_outqueue->next_outqueue)
|
|
{
|
|
if (ptr_outqueue->redirect == redirect)
|
|
ptr_outqueue->redirect = NULL;
|
|
}
|
|
}
|
|
|
|
/* free data */
|
|
if (redirect->pattern)
|
|
free (redirect->pattern);
|
|
if (redirect->signal)
|
|
free (redirect->signal);
|
|
if (redirect->string)
|
|
free (redirect->string);
|
|
if (redirect->command)
|
|
free (redirect->command);
|
|
if (redirect->cmd_start)
|
|
weechat_hashtable_free (redirect->cmd_start);
|
|
if (redirect->cmd_stop)
|
|
weechat_hashtable_free (redirect->cmd_stop);
|
|
if (redirect->cmd_extra)
|
|
weechat_hashtable_free (redirect->cmd_extra);
|
|
if (redirect->cmd_filter)
|
|
weechat_hashtable_free (redirect->cmd_filter);
|
|
if (redirect->output)
|
|
free (redirect->output);
|
|
|
|
free (redirect);
|
|
|
|
server->redirects = new_redirects;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_free_all: free all redirects in list
|
|
*/
|
|
|
|
void
|
|
irc_redirect_free_all (struct t_irc_server *server)
|
|
{
|
|
while (server->redirects)
|
|
{
|
|
irc_redirect_free (server->redirects);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_hdata_redirect_pattern_cb: return hdata for redirect pattern
|
|
*/
|
|
|
|
struct t_hdata *
|
|
irc_redirect_hdata_redirect_pattern_cb (void *data, const char *hdata_name)
|
|
{
|
|
struct t_hdata *hdata;
|
|
|
|
/* make C compiler happy */
|
|
(void) data;
|
|
|
|
hdata = weechat_hdata_new (hdata_name, "prev_redirect", "next_redirect");
|
|
if (hdata)
|
|
{
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, name, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, temp_pattern, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, timeout, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, cmd_start, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, cmd_stop, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, cmd_extra, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, prev_redirect, POINTER, hdata_name);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect_pattern, next_redirect, POINTER, hdata_name);
|
|
WEECHAT_HDATA_LIST(irc_redirect_patterns);
|
|
WEECHAT_HDATA_LIST(last_irc_redirect_pattern);
|
|
}
|
|
return hdata;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_hdata_redirect_cb: return hdata for redirect
|
|
*/
|
|
|
|
struct t_hdata *
|
|
irc_redirect_hdata_redirect_cb (void *data, const char *hdata_name)
|
|
{
|
|
struct t_hdata *hdata;
|
|
|
|
/* make C compiler happy */
|
|
(void) data;
|
|
|
|
hdata = weechat_hdata_new (hdata_name, "prev_redirect", "next_redirect");
|
|
if (hdata)
|
|
{
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, server, POINTER, "irc_server");
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, pattern, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, signal, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, count, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, current_count, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, string, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, timeout, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, command, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, start_time, TIME, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_start, POINTER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_stop, POINTER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_extra, POINTER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_start_received, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_stop_received, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, cmd_filter, POINTER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, output, STRING, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, output_size, INTEGER, NULL);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, prev_redirect, POINTER, hdata_name);
|
|
WEECHAT_HDATA_VAR(struct t_irc_redirect, next_redirect, POINTER, hdata_name);
|
|
}
|
|
return hdata;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_add_to_infolist: add a redirect pattern in an infolist
|
|
* return 1 if ok, 0 if error
|
|
*/
|
|
|
|
int
|
|
irc_redirect_pattern_add_to_infolist (struct t_infolist *infolist,
|
|
struct t_irc_redirect_pattern *redirect_pattern)
|
|
{
|
|
struct t_infolist_item *ptr_item;
|
|
|
|
if (!infolist || !redirect_pattern)
|
|
return 0;
|
|
|
|
ptr_item = weechat_infolist_new_item (infolist);
|
|
if (!ptr_item)
|
|
return 0;
|
|
|
|
if (!weechat_infolist_new_var_string (ptr_item, "name", redirect_pattern->name))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "temp_pattern", redirect_pattern->temp_pattern))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "timeout", redirect_pattern->timeout))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_start", redirect_pattern->cmd_start))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_stop", redirect_pattern->cmd_stop))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_extra", redirect_pattern->cmd_extra))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_add_to_infolist: add a redirect in an infolist
|
|
* return 1 if ok, 0 if error
|
|
*/
|
|
|
|
int
|
|
irc_redirect_add_to_infolist (struct t_infolist *infolist,
|
|
struct t_irc_redirect *redirect)
|
|
{
|
|
struct t_infolist_item *ptr_item;
|
|
|
|
if (!infolist || !redirect)
|
|
return 0;
|
|
|
|
ptr_item = weechat_infolist_new_item (infolist);
|
|
if (!ptr_item)
|
|
return 0;
|
|
|
|
if (!weechat_infolist_new_var_pointer (ptr_item, "server", redirect->server))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "server_name", redirect->server->name))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "pattern", redirect->pattern))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "signal", redirect->signal))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "count", redirect->count))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "current_count", redirect->current_count))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "string", redirect->string))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "timeout", redirect->timeout))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "command", redirect->command))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_time (ptr_item, "start_time", redirect->start_time))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_start", weechat_hashtable_get_string (redirect->cmd_start, "keys_values")))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_stop", weechat_hashtable_get_string (redirect->cmd_stop, "keys_values")))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_extra", weechat_hashtable_get_string (redirect->cmd_extra, "keys_values")))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "cmd_start_received", redirect->cmd_start_received))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "cmd_stop_received", redirect->cmd_stop_received))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "cmd_filter", weechat_hashtable_get_string (redirect->cmd_filter, "keys_values")))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_string (ptr_item, "output", redirect->output))
|
|
return 0;
|
|
if (!weechat_infolist_new_var_integer (ptr_item, "output_size", redirect->output_size))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_print_log: print redirect infos in log (usually for
|
|
* crash dump)
|
|
*/
|
|
|
|
void
|
|
irc_redirect_pattern_print_log ()
|
|
{
|
|
struct t_irc_redirect_pattern *ptr_redirect_pattern;
|
|
|
|
for (ptr_redirect_pattern = irc_redirect_patterns; ptr_redirect_pattern;
|
|
ptr_redirect_pattern = ptr_redirect_pattern->next_redirect)
|
|
{
|
|
weechat_log_printf ("");
|
|
weechat_log_printf ("[redirect_pattern (addr:0x%lx)]", ptr_redirect_pattern);
|
|
weechat_log_printf (" name . . . . . . . . : '%s'", ptr_redirect_pattern->name);
|
|
weechat_log_printf (" temp_pattern . . . . : %d", ptr_redirect_pattern->temp_pattern);
|
|
weechat_log_printf (" timeout. . . . . . . : %d", ptr_redirect_pattern->timeout);
|
|
weechat_log_printf (" cmd_start. . . . . . : '%s'", ptr_redirect_pattern->cmd_start);
|
|
weechat_log_printf (" cmd_stop . . . . . . : '%s'", ptr_redirect_pattern->cmd_stop);
|
|
weechat_log_printf (" cmd_extra. . . . . . : '%s'", ptr_redirect_pattern->cmd_extra);
|
|
weechat_log_printf (" prev_redirect. . . . : 0x%lx", ptr_redirect_pattern->prev_redirect);
|
|
weechat_log_printf (" next_redirect. . . . : 0x%lx", ptr_redirect_pattern->next_redirect);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_print_log: print redirect infos in log (usually for crash dump)
|
|
*/
|
|
|
|
void
|
|
irc_redirect_print_log (struct t_irc_server *server)
|
|
{
|
|
struct t_irc_redirect *ptr_redirect;
|
|
|
|
for (ptr_redirect = server->redirects; ptr_redirect;
|
|
ptr_redirect = ptr_redirect->next_redirect)
|
|
{
|
|
weechat_log_printf ("");
|
|
weechat_log_printf (" => redirect (addr:0x%lx):", ptr_redirect);
|
|
weechat_log_printf (" server. . . . . . . : 0x%lx ('%s')",
|
|
ptr_redirect->server, ptr_redirect->server->name);
|
|
weechat_log_printf (" pattern . . . . . . : '%s'", ptr_redirect->pattern);
|
|
weechat_log_printf (" signal. . . . . . . : '%s'", ptr_redirect->signal);
|
|
weechat_log_printf (" count . . . . . . . : %d", ptr_redirect->count);
|
|
weechat_log_printf (" current_count . . . : %d", ptr_redirect->current_count);
|
|
weechat_log_printf (" string. . . . . . . : '%s'", ptr_redirect->string);
|
|
weechat_log_printf (" timeout . . . . . . : %d", ptr_redirect->timeout);
|
|
weechat_log_printf (" command . . . . . . : '%s'", ptr_redirect->command);
|
|
weechat_log_printf (" start_time. . . . . : %ld", ptr_redirect->start_time);
|
|
weechat_log_printf (" cmd_start . . . . . : 0x%lx (hashtable: '%s')",
|
|
ptr_redirect->cmd_start,
|
|
weechat_hashtable_get_string (ptr_redirect->cmd_start, "keys_values"));
|
|
weechat_log_printf (" cmd_stop. . . . . . : 0x%lx (hashtable: '%s')",
|
|
ptr_redirect->cmd_stop,
|
|
weechat_hashtable_get_string (ptr_redirect->cmd_stop, "keys_values"));
|
|
weechat_log_printf (" cmd_extra . . . . . : 0x%lx (hashtable: '%s')",
|
|
ptr_redirect->cmd_extra,
|
|
weechat_hashtable_get_string (ptr_redirect->cmd_extra, "keys_values"));
|
|
weechat_log_printf (" cmd_start_received. : %d", ptr_redirect->cmd_start_received);
|
|
weechat_log_printf (" cmd_stop_received . : %d", ptr_redirect->cmd_stop_received);
|
|
weechat_log_printf (" cmd_filter. . . . . : 0x%lx (hashtable: '%s')",
|
|
ptr_redirect->cmd_filter,
|
|
weechat_hashtable_get_string (ptr_redirect->cmd_filter, "keys_values"));
|
|
weechat_log_printf (" output. . . . . . . : '%s'", ptr_redirect->output);
|
|
weechat_log_printf (" output_size . . . . : %d", ptr_redirect->output_size);
|
|
weechat_log_printf (" prev_redirect . . . : 0x%lx", ptr_redirect->prev_redirect);
|
|
weechat_log_printf (" next_redirect . . . : 0x%lx", ptr_redirect->next_redirect);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_pattern_hsignal_cb: callback for hsignal "irc_redirect_pattern"
|
|
* It is called when other plugins/scripts are
|
|
* creating a redirect pattern (irc plugin
|
|
* itself does not use this function)
|
|
*/
|
|
|
|
int
|
|
irc_redirect_pattern_hsignal_cb (void *data, const char *signal,
|
|
struct t_hashtable *hashtable)
|
|
{
|
|
const char *pattern, *str_timeout, *cmd_start, *cmd_stop, *cmd_extra;
|
|
char *error;
|
|
int number, timeout;
|
|
|
|
/* make C compiler happy */
|
|
(void) data;
|
|
(void) signal;
|
|
|
|
if (!hashtable)
|
|
return WEECHAT_RC_ERROR;
|
|
|
|
pattern = weechat_hashtable_get (hashtable, "pattern");
|
|
str_timeout = weechat_hashtable_get (hashtable, "timeout");
|
|
cmd_start = weechat_hashtable_get (hashtable, "cmd_start");
|
|
cmd_stop = weechat_hashtable_get (hashtable, "cmd_stop");
|
|
cmd_extra = weechat_hashtable_get (hashtable, "cmd_extra");
|
|
|
|
if (!pattern || !pattern[0])
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: missing argument \"%s\" for redirect "
|
|
"pattern"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, "pattern");
|
|
return WEECHAT_RC_ERROR;
|
|
}
|
|
|
|
if (!cmd_stop || !cmd_stop[0])
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: missing argument \"%s\" for redirect "
|
|
"pattern"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, "cmd_stop");
|
|
return WEECHAT_RC_ERROR;
|
|
}
|
|
|
|
timeout = 0;
|
|
if (str_timeout && str_timeout[0])
|
|
{
|
|
number = (int)strtol (str_timeout, &error, 10);
|
|
if (error && !error[0])
|
|
timeout = number;
|
|
}
|
|
|
|
/*
|
|
* create a temporary redirect pattern (it will be removed when a
|
|
* redirect will use it)
|
|
*/
|
|
irc_redirect_pattern_new (pattern, 1, timeout,
|
|
cmd_start, cmd_stop, cmd_extra);
|
|
|
|
return WEECHAT_RC_OK;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_command_hsignal_cb: callback for hsignal "irc_redirect_command"
|
|
* It is called when other plugins/scripts are
|
|
* redirecting an IRC command (irc plugin
|
|
* itself does not use this function)
|
|
*/
|
|
|
|
int
|
|
irc_redirect_command_hsignal_cb (void *data, const char *signal,
|
|
struct t_hashtable *hashtable)
|
|
{
|
|
const char *server, *pattern, *redirect_signal, *str_count, *string;
|
|
const char *str_timeout, *cmd_filter;
|
|
char *error;
|
|
struct t_irc_server *ptr_server;
|
|
int number, count, timeout;
|
|
|
|
/* make C compiler happy */
|
|
(void) data;
|
|
(void) signal;
|
|
|
|
if (!hashtable)
|
|
return WEECHAT_RC_ERROR;
|
|
|
|
server = weechat_hashtable_get (hashtable, "server");
|
|
pattern = weechat_hashtable_get (hashtable, "pattern");
|
|
redirect_signal = weechat_hashtable_get (hashtable, "signal");
|
|
str_count = weechat_hashtable_get (hashtable, "count");
|
|
string = weechat_hashtable_get (hashtable, "string");
|
|
str_timeout = weechat_hashtable_get (hashtable, "timeout");
|
|
cmd_filter = weechat_hashtable_get (hashtable, "cmd_filter");
|
|
|
|
if (!server || !server[0])
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: missing argument \"%s\" for redirect"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, "server");
|
|
return WEECHAT_RC_ERROR;
|
|
}
|
|
ptr_server = irc_server_search (server);
|
|
if (!ptr_server)
|
|
{
|
|
weechat_printf (NULL,
|
|
_("%s%s: server \"%s\" not found for redirect"),
|
|
weechat_prefix ("error"), IRC_PLUGIN_NAME, server);
|
|
return WEECHAT_RC_ERROR;
|
|
}
|
|
|
|
count = 1;
|
|
if (str_count && str_count[0])
|
|
{
|
|
number = (int)strtol (str_count, &error, 10);
|
|
if (error && !error[0])
|
|
count = number;
|
|
}
|
|
|
|
timeout = 0;
|
|
if (str_timeout && str_timeout[0])
|
|
{
|
|
number = (int)strtol (str_timeout, &error, 10);
|
|
if (error && !error[0])
|
|
timeout = number;
|
|
}
|
|
|
|
irc_redirect_new (ptr_server, pattern, redirect_signal,
|
|
count, string, timeout, cmd_filter);
|
|
|
|
return WEECHAT_RC_OK;
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_init: create default redirect patterns
|
|
*/
|
|
|
|
void
|
|
irc_redirect_init ()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; irc_redirect_patterns_default[i].name; i++)
|
|
{
|
|
irc_redirect_pattern_new (irc_redirect_patterns_default[i].name,
|
|
0,
|
|
irc_redirect_patterns_default[i].timeout,
|
|
irc_redirect_patterns_default[i].cmd_start,
|
|
irc_redirect_patterns_default[i].cmd_stop,
|
|
irc_redirect_patterns_default[i].cmd_extra);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* irc_redirect_end: free all redirect patterns
|
|
*/
|
|
|
|
void
|
|
irc_redirect_end ()
|
|
{
|
|
irc_redirect_pattern_free_all ();
|
|
}
|