mirror of
https://github.com/weechat/weechat.git
synced 2026-07-07 10:13:12 +02:00
relay: add WeeChat protocol (for remote GUI), doc about protocol, new options
The protocol is partial, under development, and NOT ready for usage. New options added in relay.conf: - relay.network.allowed_ips: allow only some IPs on relay plugin (by default all IPs are allowed) - relay.network.compression_level: compression level used in WeeChat protocol (compression is made using zlib)
This commit is contained in:
@@ -21,8 +21,10 @@ ADD_LIBRARY(relay MODULE
|
||||
relay.c relay.h
|
||||
relay-buffer.c relay-buffer.h
|
||||
relay-client.c relay-client.h
|
||||
relay-client-irc.c relay-client-irc.h
|
||||
relay-client-weechat.c relay-client-weechat.h
|
||||
irc/relay-irc.c irc/relay-irc.h
|
||||
weechat/relay-weechat.c weechat/relay-weechat.h
|
||||
weechat/relay-weechat-msg.c weechat/relay-weechat-msg.h
|
||||
weechat/relay-weechat-protocol.c weechat/relay-weechat-protocol.h
|
||||
relay-command.c relay-command.h
|
||||
relay-completion.c relay-completion.h
|
||||
relay-config.c relay-config.h
|
||||
@@ -32,6 +34,12 @@ relay-server.c relay-server.h
|
||||
relay-upgrade.c relay-upgrade.h)
|
||||
SET_TARGET_PROPERTIES(relay PROPERTIES PREFIX "")
|
||||
|
||||
TARGET_LINK_LIBRARIES(relay)
|
||||
SET (LINK_LIBS)
|
||||
|
||||
IF(ZLIB_FOUND)
|
||||
LIST(APPEND LINK_LIBS ${ZLIB_LIBRARY})
|
||||
ENDIF(ZLIB_FOUND)
|
||||
|
||||
TARGET_LINK_LIBRARIES(relay ${LINK_LIBS})
|
||||
|
||||
INSTALL(TARGETS relay LIBRARY DESTINATION ${LIBDIR}/plugins)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(ZLIB_CFLAGS)
|
||||
|
||||
libdir = ${weechat_libdir}/plugins
|
||||
|
||||
@@ -29,10 +29,14 @@ relay_la_SOURCES = relay.c \
|
||||
relay-buffer.h \
|
||||
relay-client.c \
|
||||
relay-client.h \
|
||||
relay-client-irc.c \
|
||||
relay-client-irc.h \
|
||||
relay-client-weechat.c \
|
||||
relay-client-weechat.h \
|
||||
irc/relay-irc.c \
|
||||
irc/relay-irc.h \
|
||||
weechat/relay-weechat.c \
|
||||
weechat/relay-weechat.h \
|
||||
weechat/relay-weechat-msg.c \
|
||||
weechat/relay-weechat-msg.h \
|
||||
weechat/relay-weechat-protocol.c \
|
||||
weechat/relay-weechat-protocol.h \
|
||||
relay-command.c \
|
||||
relay-command.h \
|
||||
relay-completion.c \
|
||||
@@ -49,6 +53,6 @@ relay_la_SOURCES = relay.c \
|
||||
relay-upgrade.h
|
||||
|
||||
relay_la_LDFLAGS = -module
|
||||
relay_la_LIBADD = $(RELAY_LFLAGS)
|
||||
relay_la_LIBADD = $(RELAY_LFLAGS) $(ZLIB_LFLAGS)
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* relay-client-irc.c: IRC protocol for relay to client
|
||||
* (relay acting as an IRC proxy/bouncer)
|
||||
* relay-irc.c: IRC protocol for relay to client
|
||||
* (relay acting as an IRC proxy/bouncer)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -31,34 +31,33 @@
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
#include "relay-client-irc.h"
|
||||
#include "relay-client.h"
|
||||
#include "relay-config.h"
|
||||
#include "relay-raw.h"
|
||||
#include "../../weechat-plugin.h"
|
||||
#include "../relay.h"
|
||||
#include "relay-irc.h"
|
||||
#include "../relay-client.h"
|
||||
#include "../relay-config.h"
|
||||
#include "../relay-raw.h"
|
||||
|
||||
|
||||
char *relay_client_irc_relay_commands[] = { "privmsg", "notice", NULL };
|
||||
char *relay_client_irc_ignore_commands[] = { "pong", "quit", NULL };
|
||||
char *relay_irc_relay_commands[] = { "privmsg", "notice", NULL };
|
||||
char *relay_irc_ignore_commands[] = { "pong", "quit", NULL };
|
||||
|
||||
|
||||
/*
|
||||
* relay_client_irc_command_relayed: return 1 if IRC command has to be
|
||||
* relayed to client, or 0 if command
|
||||
* must NOT be relayed
|
||||
* relay_irc_command_relayed: return 1 if IRC command has to be relayed to
|
||||
* client, or 0 if command must NOT be relayed
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_command_relayed (const char *irc_command)
|
||||
relay_irc_command_relayed (const char *irc_command)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (irc_command)
|
||||
{
|
||||
for (i = 0; relay_client_irc_relay_commands[i]; i++)
|
||||
for (i = 0; relay_irc_relay_commands[i]; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (relay_client_irc_relay_commands[i], irc_command) == 0)
|
||||
if (weechat_strcasecmp (relay_irc_relay_commands[i], irc_command) == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -68,20 +67,20 @@ relay_client_irc_command_relayed (const char *irc_command)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_command_ignored: return 1 if IRC command from client
|
||||
* has to be ignored
|
||||
* relay_irc_command_ignored: return 1 if IRC command from client has to be
|
||||
* ignored
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_command_ignored (const char *irc_command)
|
||||
relay_irc_command_ignored (const char *irc_command)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (irc_command)
|
||||
{
|
||||
for (i = 0; relay_client_irc_ignore_commands[i]; i++)
|
||||
for (i = 0; relay_irc_ignore_commands[i]; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (relay_client_irc_ignore_commands[i], irc_command) == 0)
|
||||
if (weechat_strcasecmp (relay_irc_ignore_commands[i], irc_command) == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -91,11 +90,11 @@ relay_client_irc_command_ignored (const char *irc_command)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_message_parse: parse IRC message
|
||||
* relay_irc_message_parse: parse IRC message
|
||||
*/
|
||||
|
||||
struct t_hashtable *
|
||||
relay_client_irc_message_parse (const char *message)
|
||||
relay_irc_message_parse (const char *message)
|
||||
{
|
||||
struct t_hashtable *hash_msg, *hash_parsed;
|
||||
|
||||
@@ -133,11 +132,11 @@ end:
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_sendf: send formatted data to client
|
||||
* relay_irc_sendf: send formatted data to client
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_sendf (struct t_relay_client *client, const char *format, ...)
|
||||
relay_irc_sendf (struct t_relay_client *client, const char *format, ...)
|
||||
{
|
||||
int length, num_sent, total_sent, number;
|
||||
char *pos, hash_key[32], *message;
|
||||
@@ -180,7 +179,7 @@ relay_client_irc_sendf (struct t_relay_client *client, const char *format, ...)
|
||||
str_message = weechat_hashtable_get (hashtable_out, hash_key);
|
||||
if (!str_message)
|
||||
break;
|
||||
relay_raw_print (client, 1, str_message);
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_SEND, "%s", str_message);
|
||||
length = strlen (str_message) + 16 + 1;
|
||||
message = malloc (length);
|
||||
if (message)
|
||||
@@ -213,15 +212,15 @@ relay_client_irc_sendf (struct t_relay_client *client, const char *format, ...)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_signal_irc_in2_cb: callback for "irc_in2" signal
|
||||
* It is called when something is
|
||||
* received on IRC server, and message
|
||||
* can be relayed (or not) to client.
|
||||
* relay_irc_signal_irc_in2_cb: callback for "irc_in2" signal
|
||||
* It is called when something is received on IRC
|
||||
* server, and message can be relayed (or not) to
|
||||
* client.
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_signal_irc_in2_cb (void *data, const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
relay_irc_signal_irc_in2_cb (void *data, const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
{
|
||||
struct t_relay_client *client;
|
||||
const char *ptr_msg, *irc_nick, *irc_host, *irc_command, *irc_args;
|
||||
@@ -242,7 +241,7 @@ relay_client_irc_signal_irc_in2_cb (void *data, const char *signal,
|
||||
ptr_msg);
|
||||
}
|
||||
|
||||
hash_parsed = relay_client_irc_message_parse (ptr_msg);
|
||||
hash_parsed = relay_irc_message_parse (ptr_msg);
|
||||
if (hash_parsed)
|
||||
{
|
||||
irc_nick = weechat_hashtable_get (hash_parsed, "nick");
|
||||
@@ -267,10 +266,10 @@ relay_client_irc_signal_irc_in2_cb (void *data, const char *signal,
|
||||
&& (weechat_strcasecmp (irc_command, "ping") != 0)
|
||||
&& (weechat_strcasecmp (irc_command, "pong") != 0))
|
||||
{
|
||||
relay_client_irc_sendf (client, ":%s %s %s",
|
||||
(irc_host && irc_host[0]) ? irc_host : RELAY_IRC_DATA(client, address),
|
||||
irc_command,
|
||||
irc_args);
|
||||
relay_irc_sendf (client, ":%s %s %s",
|
||||
(irc_host && irc_host[0]) ? irc_host : RELAY_IRC_DATA(client, address),
|
||||
irc_command,
|
||||
irc_args);
|
||||
}
|
||||
|
||||
weechat_hashtable_free (hash_parsed);
|
||||
@@ -280,15 +279,15 @@ relay_client_irc_signal_irc_in2_cb (void *data, const char *signal,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_tag_relay_client_id: get id of client by looking for tag
|
||||
* "relay_client_NNN" in list of tags
|
||||
* (comma separated list)
|
||||
* Return number found, or -1 if tag
|
||||
* is not found.
|
||||
* relay_irc_tag_relay_client_id: get id of client by looking for tag
|
||||
* "relay_client_NNN" in list of tags
|
||||
* (comma separated list)
|
||||
* Return number found, or -1 if tag is not
|
||||
* found.
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_tag_relay_client_id (const char *tags)
|
||||
relay_irc_tag_relay_client_id (const char *tags)
|
||||
{
|
||||
char **argv, *error;
|
||||
int result, argc, i;
|
||||
@@ -322,16 +321,16 @@ relay_client_irc_tag_relay_client_id (const char *tags)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_signal_irc_outtags_cb: callback for "irc_out" signal
|
||||
* It is called when a message is sent
|
||||
* to IRC server (by irc plugin or any
|
||||
* other plugin/script).
|
||||
* relay_irc_signal_irc_outtags_cb: callback for "irc_out" signal
|
||||
* It is called when a message is sent to IRC
|
||||
* server (by irc plugin or any other
|
||||
* plugin/script).
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal,
|
||||
const char *type_data,
|
||||
void *signal_data)
|
||||
relay_irc_signal_irc_outtags_cb (void *data, const char *signal,
|
||||
const char *type_data,
|
||||
void *signal_data)
|
||||
{
|
||||
struct t_relay_client *client;
|
||||
struct t_hashtable *hash_parsed;
|
||||
@@ -379,10 +378,10 @@ relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal,
|
||||
* was sent from this same client!
|
||||
* This is to prevent message from being displayed twice on client.
|
||||
*/
|
||||
if (relay_client_irc_tag_relay_client_id (tags) == client->id)
|
||||
if (relay_irc_tag_relay_client_id (tags) == client->id)
|
||||
goto end;
|
||||
|
||||
hash_parsed = relay_client_irc_message_parse (ptr_message);
|
||||
hash_parsed = relay_irc_message_parse (ptr_message);
|
||||
if (hash_parsed)
|
||||
{
|
||||
irc_command = weechat_hashtable_get (hash_parsed, "command");
|
||||
@@ -395,7 +394,7 @@ relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal,
|
||||
/* if command has to be relayed, relay it to client */
|
||||
if (irc_command && irc_command[0]
|
||||
&& irc_channel && irc_channel[0]
|
||||
&& relay_client_irc_command_relayed (irc_command))
|
||||
&& relay_irc_command_relayed (irc_command))
|
||||
{
|
||||
/* get host for nick (it is self nick) */
|
||||
snprintf (str_infolist_args, sizeof (str_infolist_args) - 1,
|
||||
@@ -410,12 +409,12 @@ relay_client_irc_signal_irc_outtags_cb (void *data, const char *signal,
|
||||
host = weechat_infolist_string (infolist_nick, "host");
|
||||
|
||||
/* send message to client */
|
||||
relay_client_irc_sendf (client,
|
||||
":%s%s%s %s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
(host && host[0]) ? "!" : "",
|
||||
(host && host[0]) ? host : "",
|
||||
ptr_message);
|
||||
relay_irc_sendf (client,
|
||||
":%s%s%s %s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
(host && host[0]) ? "!" : "",
|
||||
(host && host[0]) ? host : "",
|
||||
ptr_message);
|
||||
|
||||
if (infolist_nick)
|
||||
weechat_infolist_free (infolist_nick);
|
||||
@@ -435,14 +434,14 @@ end:
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_signal_irc_disc_cb: callback for "irc_disconnected" signal
|
||||
* It is called when connection to a
|
||||
* server is lost.
|
||||
* relay_irc_signal_irc_disc_cb: callback for "irc_disconnected" signal
|
||||
* It is called when connection to a server is
|
||||
* lost.
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_signal_irc_disc_cb (void *data, const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
relay_irc_signal_irc_disc_cb (void *data, const char *signal,
|
||||
const char *type_data, void *signal_data)
|
||||
{
|
||||
struct t_relay_client *client;
|
||||
|
||||
@@ -462,12 +461,12 @@ relay_client_irc_signal_irc_disc_cb (void *data, const char *signal,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_send_join: send join for a channel to client
|
||||
* relay_irc_send_join: send join for a channel to client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_send_join (struct t_relay_client *client,
|
||||
const char *channel)
|
||||
relay_irc_send_join (struct t_relay_client *client,
|
||||
const char *channel)
|
||||
{
|
||||
char *infolist_name, *nicks, *nicks2;
|
||||
const char *nick, *prefix, *topic;
|
||||
@@ -497,11 +496,11 @@ relay_client_irc_send_join (struct t_relay_client *client,
|
||||
}
|
||||
weechat_infolist_free (infolist_nick);
|
||||
}
|
||||
relay_client_irc_sendf (client,
|
||||
":%s!%s JOIN %s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
(host && host[0]) ? host : "weechat@proxy",
|
||||
channel);
|
||||
relay_irc_sendf (client,
|
||||
":%s!%s JOIN %s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
(host && host[0]) ? host : "weechat@proxy",
|
||||
channel);
|
||||
if (host)
|
||||
free (host);
|
||||
snprintf (infolist_name, length, "%s,%s",
|
||||
@@ -516,11 +515,11 @@ relay_client_irc_send_join (struct t_relay_client *client,
|
||||
topic = weechat_infolist_string (infolist_channel, "topic");
|
||||
if (topic && topic[0])
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 332 %s %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel, topic);
|
||||
relay_irc_sendf (client,
|
||||
":%s 332 %s %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel, topic);
|
||||
}
|
||||
}
|
||||
weechat_infolist_free (infolist_channel);
|
||||
@@ -562,31 +561,30 @@ relay_client_irc_send_join (struct t_relay_client *client,
|
||||
}
|
||||
if (nicks)
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 353 %s = %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel, nicks);
|
||||
relay_irc_sendf (client,
|
||||
":%s 353 %s = %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel, nicks);
|
||||
free (nicks);
|
||||
}
|
||||
weechat_infolist_free (infolist_nicks);
|
||||
}
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 366 %s %s :End of /NAMES list.",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel);
|
||||
relay_irc_sendf (client,
|
||||
":%s 366 %s %s :End of /NAMES list.",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
channel);
|
||||
free (infolist_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_send_join_channels: send join for all channels of server to
|
||||
* client
|
||||
* relay_irc_send_join_channels: send join for all channels of server to client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_send_join_channels (struct t_relay_client *client)
|
||||
relay_irc_send_join_channels (struct t_relay_client *client)
|
||||
{
|
||||
struct t_infolist *infolist_channels;
|
||||
const char *channel;
|
||||
@@ -600,7 +598,7 @@ relay_client_irc_send_join_channels (struct t_relay_client *client)
|
||||
if (weechat_infolist_integer (infolist_channels, "nicks_count") > 0)
|
||||
{
|
||||
channel = weechat_infolist_string (infolist_channels, "name");
|
||||
relay_client_irc_send_join (client, channel);
|
||||
relay_irc_send_join (client, channel);
|
||||
}
|
||||
}
|
||||
weechat_infolist_free (infolist_channels);
|
||||
@@ -608,14 +606,12 @@ relay_client_irc_send_join_channels (struct t_relay_client *client)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_input_send: send text or command on an IRC buffer
|
||||
* relay_irc_input_send: send text or command on an IRC buffer
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_input_send (struct t_relay_client *client,
|
||||
const char *irc_channel,
|
||||
int flags,
|
||||
const char *format, ...)
|
||||
relay_irc_input_send (struct t_relay_client *client, const char *irc_channel,
|
||||
int flags, const char *format, ...)
|
||||
{
|
||||
char buf_beginning[1024], *buf;
|
||||
int length_beginning, length_vbuffer;
|
||||
@@ -655,11 +651,11 @@ relay_client_irc_input_send (struct t_relay_client *client,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_hook_signals: hook signals for a client
|
||||
* relay_irc_hook_signals: hook signals for a client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_hook_signals (struct t_relay_client *client)
|
||||
relay_irc_hook_signals (struct t_relay_client *client)
|
||||
{
|
||||
char str_signal_name[128];
|
||||
|
||||
@@ -672,7 +668,7 @@ relay_client_irc_hook_signals (struct t_relay_client *client)
|
||||
client->protocol_args);
|
||||
RELAY_IRC_DATA(client, hook_signal_irc_in2) =
|
||||
weechat_hook_signal (str_signal_name,
|
||||
&relay_client_irc_signal_irc_in2_cb,
|
||||
&relay_irc_signal_irc_in2_cb,
|
||||
client);
|
||||
|
||||
/*
|
||||
@@ -684,7 +680,7 @@ relay_client_irc_hook_signals (struct t_relay_client *client)
|
||||
client->protocol_args);
|
||||
RELAY_IRC_DATA(client, hook_signal_irc_outtags) =
|
||||
weechat_hook_signal (str_signal_name,
|
||||
&relay_client_irc_signal_irc_outtags_cb,
|
||||
&relay_irc_signal_irc_outtags_cb,
|
||||
client);
|
||||
|
||||
/*
|
||||
@@ -693,16 +689,16 @@ relay_client_irc_hook_signals (struct t_relay_client *client)
|
||||
*/
|
||||
RELAY_IRC_DATA(client, hook_signal_irc_disc) =
|
||||
weechat_hook_signal ("irc_server_disconnected",
|
||||
&relay_client_irc_signal_irc_disc_cb,
|
||||
&relay_irc_signal_irc_disc_cb,
|
||||
client);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_recv_one_msg: read one message from client
|
||||
* relay_irc_recv_one_msg: read one message from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
relay_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
{
|
||||
char *pos, str_time[128], *target;
|
||||
const char *irc_command, *irc_channel, *irc_args, *irc_args2;
|
||||
@@ -720,14 +716,15 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
/* display debug message */
|
||||
if (weechat_relay_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL, "%s: recv from client: \"%s\"",
|
||||
RELAY_PLUGIN_NAME, data);
|
||||
weechat_printf (NULL, "%s: recv from client %d: \"%s\"",
|
||||
RELAY_PLUGIN_NAME, client->id, data);
|
||||
}
|
||||
|
||||
relay_raw_print (client, 0, data);
|
||||
/* display message in raw buffer */
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_RECV, "%s", data);
|
||||
|
||||
/* parse IRC message */
|
||||
hash_parsed = relay_client_irc_message_parse (data);
|
||||
hash_parsed = relay_irc_message_parse (data);
|
||||
if (!hash_parsed)
|
||||
goto end;
|
||||
irc_command = weechat_hashtable_get (hash_parsed, "command");
|
||||
@@ -770,14 +767,14 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
if (!weechat_infolist_integer (infolist_server,
|
||||
"is_connected"))
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s ERROR :WeeChat: no "
|
||||
"connection to server \"%s\"",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
client->protocol_args);
|
||||
relay_client_irc_sendf (client,
|
||||
":%s ERROR :Closing Link",
|
||||
RELAY_IRC_DATA(client, address));
|
||||
relay_irc_sendf (client,
|
||||
":%s ERROR :WeeChat: no "
|
||||
"connection to server \"%s\"",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
client->protocol_args);
|
||||
relay_irc_sendf (client,
|
||||
":%s ERROR :Closing Link",
|
||||
RELAY_IRC_DATA(client, address));
|
||||
relay_client_set_status (client,
|
||||
RELAY_STATUS_DISCONNECTED);
|
||||
goto end;
|
||||
@@ -796,9 +793,9 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
/* disconnect client if password was not received or wrong */
|
||||
if (!RELAY_IRC_DATA(client, password_ok))
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s ERROR :WeeChat: password error",
|
||||
RELAY_IRC_DATA(client, address));
|
||||
relay_irc_sendf (client,
|
||||
":%s ERROR :WeeChat: password error",
|
||||
RELAY_IRC_DATA(client, address));
|
||||
relay_client_set_status (client,
|
||||
RELAY_STATUS_DISCONNECTED);
|
||||
goto end;
|
||||
@@ -813,42 +810,42 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
nick = weechat_info_get ("irc_nick", client->protocol_args);
|
||||
if (nick && (strcmp (nick, RELAY_IRC_DATA(client, nick)) != 0))
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s!proxy NICK :%s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
nick);
|
||||
relay_irc_sendf (client,
|
||||
":%s!proxy NICK :%s",
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
nick);
|
||||
free (RELAY_IRC_DATA(client, nick));
|
||||
RELAY_IRC_DATA(client, nick) = strdup (nick);
|
||||
}
|
||||
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 001 %s :Welcome to the Internet "
|
||||
"Relay Chat Network %s!%s@proxy",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
"weechat");
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 002 %s :Your host is "
|
||||
"weechat-relay-irc, running version %s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
weechat_info_get("version", NULL));
|
||||
relay_irc_sendf (client,
|
||||
":%s 001 %s :Welcome to the Internet "
|
||||
"Relay Chat Network %s!%s@proxy",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
"weechat");
|
||||
relay_irc_sendf (client,
|
||||
":%s 002 %s :Your host is "
|
||||
"weechat-relay-irc, running version %s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
weechat_info_get("version", NULL));
|
||||
snprintf (str_time, sizeof (str_time), "%s",
|
||||
ctime (&client->listen_start_time));
|
||||
if (str_time[0])
|
||||
str_time[strlen (str_time) - 1] = '\0';
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 003 %s :This server was created on %s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
str_time);
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 004 %s %s %s oirw abiklmnopqstv",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
RELAY_IRC_DATA(client, address),
|
||||
weechat_info_get("version", NULL));
|
||||
relay_irc_sendf (client,
|
||||
":%s 003 %s :This server was created on %s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
str_time);
|
||||
relay_irc_sendf (client,
|
||||
":%s 004 %s %s %s oirw abiklmnopqstv",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
RELAY_IRC_DATA(client, address),
|
||||
weechat_info_get("version", NULL));
|
||||
infolist_server = weechat_infolist_get ("irc_server", NULL,
|
||||
client->protocol_args);
|
||||
if (infolist_server)
|
||||
@@ -863,49 +860,49 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
{
|
||||
isupport++;
|
||||
}
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 005 %s %s :are supported "
|
||||
"by this server",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
isupport);
|
||||
relay_irc_sendf (client,
|
||||
":%s 005 %s %s :are supported "
|
||||
"by this server",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
isupport);
|
||||
}
|
||||
}
|
||||
weechat_infolist_free (infolist_server);
|
||||
}
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 251 %s :There are %d users and 0 "
|
||||
"invisible on 1 servers",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
relay_client_count);
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 255 %s :I have %d clients, 0 "
|
||||
"services and 0 servers",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
relay_client_count);
|
||||
relay_client_irc_sendf (client,
|
||||
":%s 422 %s :MOTD File is missing",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick));
|
||||
relay_irc_sendf (client,
|
||||
":%s 251 %s :There are %d users and 0 "
|
||||
"invisible on 1 servers",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
relay_client_count);
|
||||
relay_irc_sendf (client,
|
||||
":%s 255 %s :I have %d clients, 0 "
|
||||
"services and 0 servers",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick),
|
||||
relay_client_count);
|
||||
relay_irc_sendf (client,
|
||||
":%s 422 %s :MOTD File is missing",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, nick));
|
||||
|
||||
/* hook signals */
|
||||
relay_client_irc_hook_signals (client);
|
||||
relay_irc_hook_signals (client);
|
||||
|
||||
/* send JOIN for all channels on server to client */
|
||||
relay_client_irc_send_join_channels (client);
|
||||
relay_irc_send_join_channels (client);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (irc_command && weechat_strcasecmp (irc_command, "ping") == 0)
|
||||
{
|
||||
relay_client_irc_sendf (client,
|
||||
":%s PONG %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, address),
|
||||
irc_args);
|
||||
relay_irc_sendf (client,
|
||||
":%s PONG %s :%s",
|
||||
RELAY_IRC_DATA(client, address),
|
||||
RELAY_IRC_DATA(client, address),
|
||||
irc_args);
|
||||
}
|
||||
else if (irc_command && irc_channel && irc_channel[0]
|
||||
&& irc_args && irc_args[0]
|
||||
@@ -923,10 +920,10 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
}
|
||||
if (irc_args2[0] == ':')
|
||||
irc_args2++;
|
||||
relay_client_irc_input_send (client, NULL, 1,
|
||||
"/notice %s %s",
|
||||
target,
|
||||
irc_args2);
|
||||
relay_irc_input_send (client, NULL, 1,
|
||||
"/notice %s %s",
|
||||
target,
|
||||
irc_args2);
|
||||
free (target);
|
||||
}
|
||||
}
|
||||
@@ -947,21 +944,21 @@ relay_client_irc_recv_one_msg (struct t_relay_client *client, char *data)
|
||||
irc_is_channel = weechat_info_get ("irc_is_channel", irc_channel);
|
||||
if (irc_is_channel && (strcmp (irc_is_channel, "1") == 0))
|
||||
{
|
||||
relay_client_irc_input_send (client, irc_channel, 1,
|
||||
"%s", irc_args2);
|
||||
relay_irc_input_send (client, irc_channel, 1,
|
||||
"%s", irc_args2);
|
||||
}
|
||||
else
|
||||
{
|
||||
relay_client_irc_input_send (client, NULL, 1,
|
||||
"/query %s %s",
|
||||
irc_channel, irc_args2);
|
||||
relay_irc_input_send (client, NULL, 1,
|
||||
"/query %s %s",
|
||||
irc_channel, irc_args2);
|
||||
}
|
||||
}
|
||||
else if (!relay_client_irc_command_ignored (irc_command))
|
||||
else if (!relay_irc_command_ignored (irc_command))
|
||||
{
|
||||
relay_client_irc_input_send (client, NULL, 1,
|
||||
"/quote %s",
|
||||
data);
|
||||
relay_irc_input_send (client, NULL, 1,
|
||||
"/quote %s",
|
||||
data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,11 +968,11 @@ end:
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_recv: read data from client
|
||||
* relay_irc_recv: read data from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_recv (struct t_relay_client *client, const char *data)
|
||||
relay_irc_recv (struct t_relay_client *client, const char *data)
|
||||
{
|
||||
char **items;
|
||||
int items_count, i;
|
||||
@@ -983,19 +980,18 @@ relay_client_irc_recv (struct t_relay_client *client, const char *data)
|
||||
items = weechat_string_split (data, "\n", 0, 0, &items_count);
|
||||
for (i = 0; i < items_count; i++)
|
||||
{
|
||||
relay_client_irc_recv_one_msg (client, items[i]);
|
||||
relay_irc_recv_one_msg (client, items[i]);
|
||||
}
|
||||
if (items)
|
||||
weechat_string_free_split (items);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_close_connection: called when connection with client is
|
||||
* closed
|
||||
* relay_irc_close_connection: called when connection with client is closed
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_close_connection (struct t_relay_client *client)
|
||||
relay_irc_close_connection (struct t_relay_client *client)
|
||||
{
|
||||
RELAY_IRC_DATA(client, connected) = 0;
|
||||
if (RELAY_IRC_DATA(client, hook_signal_irc_in2))
|
||||
@@ -1016,13 +1012,13 @@ relay_client_irc_close_connection (struct t_relay_client *client)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_alloc: init relay data specific to IRC protocol
|
||||
* relay_irc_alloc: init relay data specific to IRC protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_alloc (struct t_relay_client *client)
|
||||
relay_irc_alloc (struct t_relay_client *client)
|
||||
{
|
||||
struct t_relay_client_irc_data *irc_data;
|
||||
struct t_relay_irc_data *irc_data;
|
||||
const char *password;
|
||||
|
||||
password = weechat_config_string (relay_config_network_password);
|
||||
@@ -1042,15 +1038,15 @@ relay_client_irc_alloc (struct t_relay_client *client)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_alloc_with_infolist: init relay data specific to IRC
|
||||
* protocol using an infolist
|
||||
* relay_irc_alloc_with_infolist: init relay data specific to IRC protocol
|
||||
* using an infolist
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist)
|
||||
relay_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist)
|
||||
{
|
||||
struct t_relay_client_irc_data *irc_data;
|
||||
struct t_relay_irc_data *irc_data;
|
||||
|
||||
client->protocol_data = malloc (sizeof (*irc_data));
|
||||
if (client->protocol_data)
|
||||
@@ -1065,7 +1061,7 @@ relay_client_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
RELAY_IRC_DATA(client, connected) = weechat_infolist_integer (infolist, "connected");
|
||||
if (RELAY_IRC_DATA(client, connected))
|
||||
{
|
||||
relay_client_irc_hook_signals (client);
|
||||
relay_irc_hook_signals (client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1077,11 +1073,11 @@ relay_client_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_free: free relay data specific to IRC protocol
|
||||
* relay_irc_free: free relay data specific to IRC protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_free (struct t_relay_client *client)
|
||||
relay_irc_free (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
{
|
||||
@@ -1103,13 +1099,13 @@ relay_client_irc_free (struct t_relay_client *client)
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_add_to_infolist: add client irc data in an infolist item
|
||||
* return 1 if ok, 0 if error
|
||||
* relay_irc_add_to_infolist: add client irc data in an infolist item
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_irc_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client)
|
||||
relay_irc_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client)
|
||||
{
|
||||
if (!item || !client)
|
||||
return 0;
|
||||
@@ -1135,12 +1131,11 @@ relay_client_irc_add_to_infolist (struct t_infolist_item *item,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_irc_print_log: print IRC client infos in log (usually for
|
||||
* crash dump)
|
||||
* relay_irc_print_log: print IRC client infos in log (usually for crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_irc_print_log (struct t_relay_client *client)
|
||||
relay_irc_print_log (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
{
|
||||
@@ -17,15 +17,15 @@
|
||||
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_RELAY_CLIENT_IRC_H
|
||||
#define __WEECHAT_RELAY_CLIENT_IRC_H 1
|
||||
#ifndef __WEECHAT_RELAY_IRC_H
|
||||
#define __WEECHAT_RELAY_IRC_H 1
|
||||
|
||||
struct t_relay_client;
|
||||
|
||||
#define RELAY_IRC_DATA(client, var) \
|
||||
(((struct t_relay_client_irc_data *)client->protocol_data)->var)
|
||||
#define RELAY_IRC_DATA(client, var) \
|
||||
(((struct t_relay_irc_data *)client->protocol_data)->var)
|
||||
|
||||
struct t_relay_client_irc_data
|
||||
struct t_relay_irc_data
|
||||
{
|
||||
char *address; /* client address (used when sending */
|
||||
/* data to client) */
|
||||
@@ -39,15 +39,15 @@ struct t_relay_client_irc_data
|
||||
struct t_hook *hook_signal_irc_disc; /* signal "irc_disconnected" */
|
||||
};
|
||||
|
||||
extern void relay_client_irc_recv (struct t_relay_client *client,
|
||||
extern void relay_irc_recv (struct t_relay_client *client,
|
||||
const char *data);
|
||||
extern void relay_client_irc_close_connection (struct t_relay_client *client);
|
||||
extern void relay_client_irc_alloc (struct t_relay_client *client);
|
||||
extern void relay_client_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist);
|
||||
extern void relay_client_irc_free (struct t_relay_client *client);
|
||||
extern int relay_client_irc_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client);
|
||||
extern void relay_client_irc_print_log (struct t_relay_client *client);
|
||||
extern void relay_irc_close_connection (struct t_relay_client *client);
|
||||
extern void relay_irc_alloc (struct t_relay_client *client);
|
||||
extern void relay_irc_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist);
|
||||
extern void relay_irc_free (struct t_relay_client *client);
|
||||
extern int relay_irc_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client);
|
||||
extern void relay_irc_print_log (struct t_relay_client *client);
|
||||
|
||||
#endif /* __WEECHAT_RELAY_CLIENT_IRC_H */
|
||||
#endif /* __WEECHAT_RELAY_IRC_H */
|
||||
@@ -64,11 +64,11 @@ relay_buffer_refresh (const char *hotlist)
|
||||
weechat_color("lightgreen"),
|
||||
/* disconnect */
|
||||
(client_selected
|
||||
&& !RELAY_CLIENT_HAS_ENDED(client_selected->status)) ?
|
||||
&& !RELAY_CLIENT_HAS_ENDED(client_selected)) ?
|
||||
_(" [D] Disconnect") : "",
|
||||
/* remove */
|
||||
(client_selected
|
||||
&& RELAY_CLIENT_HAS_ENDED(client_selected->status)) ?
|
||||
&& RELAY_CLIENT_HAS_ENDED(client_selected)) ?
|
||||
_(" [R] Remove") : "",
|
||||
/* purge old */
|
||||
_(" [P] Purge finished"),
|
||||
@@ -178,7 +178,7 @@ relay_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
|
||||
/* disconnect client */
|
||||
if (weechat_strcasecmp (input_data, "d") == 0)
|
||||
{
|
||||
if (client && !RELAY_CLIENT_HAS_ENDED(client->status))
|
||||
if (client && !RELAY_CLIENT_HAS_ENDED(client))
|
||||
{
|
||||
relay_client_disconnect (client);
|
||||
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
@@ -191,7 +191,7 @@ relay_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
|
||||
while (ptr_client)
|
||||
{
|
||||
next_client = ptr_client->next_client;
|
||||
if (RELAY_CLIENT_HAS_ENDED(ptr_client->status))
|
||||
if (RELAY_CLIENT_HAS_ENDED(ptr_client))
|
||||
relay_client_free (ptr_client);
|
||||
ptr_client = next_client;
|
||||
}
|
||||
@@ -205,7 +205,7 @@ relay_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
|
||||
/* remove client */
|
||||
else if (weechat_strcasecmp (input_data, "r") == 0)
|
||||
{
|
||||
if (client && RELAY_CLIENT_HAS_ENDED(client->status))
|
||||
if (client && RELAY_CLIENT_HAS_ENDED(client))
|
||||
{
|
||||
relay_client_free (client);
|
||||
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
|
||||
@@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* relay-client-weechat.c: WeeChat protocol for relay to client
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
#include "relay-client-weechat.h"
|
||||
#include "relay-client.h"
|
||||
#include "relay-config.h"
|
||||
|
||||
|
||||
/*
|
||||
* relay_client_weechat_sendf: send formatted data to client
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_weechat_sendf (struct t_relay_client *client,
|
||||
const char *format, ...)
|
||||
{
|
||||
char str_length[8];
|
||||
int length_vbuffer, num_sent, total_sent;
|
||||
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
weechat_va_format (format);
|
||||
if (!vbuffer)
|
||||
return 0;
|
||||
length_vbuffer = strlen (vbuffer);
|
||||
|
||||
total_sent = 0;
|
||||
|
||||
snprintf (str_length, sizeof (str_length), "%07d", length_vbuffer);
|
||||
|
||||
num_sent = send (client->sock, str_length, 7, 0);
|
||||
client->bytes_sent += 7;
|
||||
total_sent += num_sent;
|
||||
if (num_sent >= 0)
|
||||
{
|
||||
num_sent = send (client->sock, vbuffer, length_vbuffer, 0);
|
||||
client->bytes_sent += length_vbuffer;
|
||||
total_sent += num_sent;
|
||||
}
|
||||
|
||||
if (num_sent < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: error sending data to client %s"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
strerror (errno));
|
||||
}
|
||||
|
||||
return total_sent;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_send_infolist: send infolist to client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_send_infolist (struct t_relay_client *client,
|
||||
const char *name,
|
||||
struct t_infolist *infolist)
|
||||
{
|
||||
const char *fields;
|
||||
char **argv;
|
||||
int i, argc, size;
|
||||
|
||||
relay_client_weechat_sendf (client, "name %s", name);
|
||||
|
||||
while (weechat_infolist_next (infolist))
|
||||
{
|
||||
fields = weechat_infolist_fields (infolist);
|
||||
if (fields)
|
||||
{
|
||||
argv = weechat_string_split (fields, ",", 0, 0, &argc);
|
||||
if (argv && (argc > 0))
|
||||
{
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
switch (argv[i][0])
|
||||
{
|
||||
case 'i':
|
||||
relay_client_weechat_sendf (client, "%s %c %d",
|
||||
argv[i] + 2, argv[i][0],
|
||||
weechat_infolist_integer (infolist,
|
||||
argv[i] + 2));
|
||||
break;
|
||||
case 's':
|
||||
relay_client_weechat_sendf (client, "%s %c %s",
|
||||
argv[i] + 2, argv[i][0],
|
||||
weechat_infolist_string (infolist,
|
||||
argv[i] + 2));
|
||||
break;
|
||||
case 'p':
|
||||
relay_client_weechat_sendf (client, "%s %c %lx",
|
||||
argv[i] + 2, argv[i][0],
|
||||
(long unsigned int)weechat_infolist_pointer (infolist,
|
||||
argv[i] + 2));
|
||||
break;
|
||||
case 'b':
|
||||
relay_client_weechat_sendf (client, "%s %c %lx",
|
||||
argv[i] + 2, argv[i][0],
|
||||
(long unsigned int)weechat_infolist_buffer (infolist,
|
||||
argv[i] + 2,
|
||||
&size));
|
||||
break;
|
||||
case 't':
|
||||
relay_client_weechat_sendf (client, "%s %c %ld",
|
||||
argv[i] + 2, argv[i][0],
|
||||
weechat_infolist_time (infolist, argv[i] + 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argv)
|
||||
weechat_string_free_split (argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_recv_one_msg: read one message from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_recv_one_msg (struct t_relay_client *client,
|
||||
const char *data)
|
||||
{
|
||||
char *data2, *pos, **argv, **argv_eol, *args;
|
||||
int argc, rc;
|
||||
long unsigned int value;
|
||||
const char *info;
|
||||
struct t_infolist *infolist;
|
||||
|
||||
data2 = NULL;
|
||||
argv = NULL;
|
||||
argv_eol = NULL;
|
||||
|
||||
data2 = strdup (data);
|
||||
if (!data2)
|
||||
goto end;
|
||||
pos = strchr (data2, '\r');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
pos = strchr (data2, '\n');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
|
||||
if (weechat_relay_plugin->debug)
|
||||
{
|
||||
weechat_printf (NULL, "relay: weechat: \"%s\"", data2);
|
||||
}
|
||||
|
||||
argv = weechat_string_split (data2, " ", 0, 0, &argc);
|
||||
argv_eol = weechat_string_split (data2, " ", 1, 0, NULL);
|
||||
if (argv && argv_eol && (argc >= 1))
|
||||
{
|
||||
if (!RELAY_WEECHAT_DATA(client, password_ok))
|
||||
{
|
||||
if ((argc > 1)
|
||||
&& (strcmp (argv[0], "password") == 0)
|
||||
&& (strcmp (weechat_config_string (relay_config_network_password),
|
||||
argv_eol[1]) == 0))
|
||||
{
|
||||
RELAY_WEECHAT_DATA(client, password_ok) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!RELAY_WEECHAT_DATA(client, password_ok))
|
||||
{
|
||||
relay_client_set_status (client,
|
||||
RELAY_STATUS_DISCONNECTED);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp (argv[0], "quit") == 0)
|
||||
{
|
||||
relay_client_set_status (client, RELAY_STATUS_DISCONNECTED);
|
||||
}
|
||||
else if (strcmp (argv[0], "info") == 0)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
info = weechat_info_get (argv[1],
|
||||
(argc > 2) ? argv_eol[2] : NULL);
|
||||
relay_client_weechat_sendf (client, "%s", info);
|
||||
}
|
||||
}
|
||||
else if (strcmp (argv[0], "infolist") == 0)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
value = 0;
|
||||
args = NULL;
|
||||
if (argc > 2)
|
||||
{
|
||||
rc = sscanf (argv[2], "%lx", &value);
|
||||
if ((rc == EOF) || (rc == 0))
|
||||
value = 0;
|
||||
if (argc > 3)
|
||||
args = argv_eol[3];
|
||||
}
|
||||
infolist = weechat_infolist_get (argv[1], (void *)value, args);
|
||||
if (infolist)
|
||||
{
|
||||
relay_client_weechat_send_infolist (client, data, infolist);
|
||||
weechat_infolist_free (infolist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (data2)
|
||||
free (data2);
|
||||
if (argv)
|
||||
weechat_string_free_split (argv);
|
||||
if (argv_eol)
|
||||
weechat_string_free_split (argv_eol);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_recv: read data from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_recv (struct t_relay_client *client, const char *data)
|
||||
{
|
||||
char **items;
|
||||
int items_count, i;
|
||||
|
||||
items = weechat_string_split (data, "\n", 0, 0, &items_count);
|
||||
for (i = 0; i < items_count; i++)
|
||||
{
|
||||
relay_client_weechat_recv_one_msg (client, items[i]);
|
||||
}
|
||||
if (items)
|
||||
weechat_string_free_split (items);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_alloc: init relay data specific to weechat protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_alloc (struct t_relay_client *client)
|
||||
{
|
||||
struct t_relay_client_weechat_data *weechat_data;
|
||||
const char *password;
|
||||
|
||||
password = weechat_config_string (relay_config_network_password);
|
||||
|
||||
client->protocol_data = malloc (sizeof (*weechat_data));
|
||||
if (client->protocol_data)
|
||||
{
|
||||
RELAY_WEECHAT_DATA(client, password_ok) = (password && password[0]) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_alloc_with_infolist: init relay data specific to
|
||||
* weechat protocol with an infolist
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist)
|
||||
{
|
||||
struct t_relay_client_weechat_data *weechat_data;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) infolist;
|
||||
|
||||
client->protocol_data = malloc (sizeof (*weechat_data));
|
||||
if (client->protocol_data)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_free: free relay data specific to weechat protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_free (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
free (client->protocol_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_add_to_infolist: add client weechat data in an
|
||||
* infolist item
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
relay_client_weechat_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client)
|
||||
{
|
||||
if (!item || !client)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_client_weechat_print_log: print weechat client infos in log (usually
|
||||
* for crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
relay_client_weechat_print_log (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_RELAY_CLIENT_WEECHAT_H
|
||||
#define __WEECHAT_RELAY_CLIENT_WEECHAT_H 1
|
||||
|
||||
struct t_relay_client;
|
||||
|
||||
#define RELAY_WEECHAT_DATA(client, var) \
|
||||
(((struct t_relay_client_weechat_data *)client->protocol_data)->var)
|
||||
|
||||
struct t_relay_client_weechat_data
|
||||
{
|
||||
int password_ok; /* password received and ok? */
|
||||
};
|
||||
|
||||
extern void relay_client_weechat_recv (struct t_relay_client *client,
|
||||
const char *data);
|
||||
extern void relay_client_weechat_alloc (struct t_relay_client *client);
|
||||
extern void relay_client_weechat_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist);
|
||||
extern void relay_client_weechat_free (struct t_relay_client *client);
|
||||
extern int relay_client_weechat_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client);
|
||||
extern void relay_client_weechat_print_log (struct t_relay_client *client);
|
||||
|
||||
#endif /* __WEECHAT_RELAY_CLIENT_WEECHAT_H */
|
||||
@@ -34,8 +34,8 @@
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
#include "relay-client.h"
|
||||
#include "relay-client-irc.h"
|
||||
#include "relay-client-weechat.h"
|
||||
#include "irc/relay-irc.h"
|
||||
#include "weechat/relay-weechat.h"
|
||||
#include "relay-config.h"
|
||||
#include "relay-buffer.h"
|
||||
#include "relay-server.h"
|
||||
@@ -123,10 +123,10 @@ relay_client_recv_cb (void *arg_client, int fd)
|
||||
switch (client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_recv (client, buffer);
|
||||
relay_weechat_recv (client, buffer);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_recv (client, buffer);
|
||||
relay_irc_recv (client, buffer);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
@@ -146,7 +146,7 @@ relay_client_recv_cb (void *arg_client, int fd)
|
||||
*/
|
||||
|
||||
struct t_relay_client *
|
||||
relay_client_new (int sock, char *address, struct t_relay_server *server)
|
||||
relay_client_new (int sock, const char *address, struct t_relay_server *server)
|
||||
{
|
||||
struct t_relay_client *new_client;
|
||||
|
||||
@@ -171,10 +171,10 @@ relay_client_new (int sock, char *address, struct t_relay_server *server)
|
||||
switch (new_client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_alloc (new_client);
|
||||
relay_weechat_alloc (new_client);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_alloc (new_client);
|
||||
relay_irc_alloc (new_client);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
@@ -234,7 +234,7 @@ relay_client_set_status (struct t_relay_client *client,
|
||||
{
|
||||
client->status = status;
|
||||
|
||||
if (RELAY_CLIENT_HAS_ENDED(client->status))
|
||||
if (RELAY_CLIENT_HAS_ENDED(client))
|
||||
{
|
||||
client->end_time = time (NULL);
|
||||
|
||||
@@ -246,9 +246,10 @@ relay_client_set_status (struct t_relay_client *client,
|
||||
switch (client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_weechat_close_connection (client);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_close_connection (client);
|
||||
relay_irc_close_connection (client);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
@@ -327,10 +328,10 @@ relay_client_free (struct t_relay_client *client)
|
||||
switch (client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_free (client);
|
||||
relay_weechat_free (client);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_free (client);
|
||||
relay_irc_free (client);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
@@ -446,10 +447,10 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
|
||||
switch (client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_add_to_infolist (ptr_item, client);
|
||||
relay_weechat_add_to_infolist (ptr_item, client);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_add_to_infolist (ptr_item, client);
|
||||
relay_irc_add_to_infolist (ptr_item, client);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
@@ -493,10 +494,10 @@ relay_client_print_log ()
|
||||
switch (ptr_client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_print_log (ptr_client);
|
||||
relay_weechat_print_log (ptr_client);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_print_log (ptr_client);
|
||||
relay_irc_print_log (ptr_client);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
|
||||
@@ -37,8 +37,9 @@ enum t_relay_status
|
||||
|
||||
/* macros for status */
|
||||
|
||||
#define RELAY_CLIENT_HAS_ENDED(status) ((status == RELAY_STATUS_AUTH_FAILED) || \
|
||||
(status == RELAY_STATUS_DISCONNECTED))
|
||||
#define RELAY_CLIENT_HAS_ENDED(client) \
|
||||
((client->status == RELAY_STATUS_AUTH_FAILED) || \
|
||||
(client->status == RELAY_STATUS_DISCONNECTED))
|
||||
|
||||
/* relay client */
|
||||
|
||||
@@ -71,7 +72,7 @@ extern int relay_client_count;
|
||||
extern int relay_client_valid (struct t_relay_client *client);
|
||||
extern struct t_relay_client *relay_client_search_by_number (int number);
|
||||
extern int relay_client_recv_cb (void *arg_client, int fd);
|
||||
extern struct t_relay_client *relay_client_new (int sock, char *address,
|
||||
extern struct t_relay_client *relay_client_new (int sock, const char *address,
|
||||
struct t_relay_server *server);
|
||||
extern void relay_client_set_status (struct t_relay_client *client,
|
||||
enum t_relay_status status);
|
||||
|
||||
@@ -90,7 +90,7 @@ relay_command_client_list (int full)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RELAY_CLIENT_HAS_ENDED(ptr_client->status))
|
||||
if (!RELAY_CLIENT_HAS_ENDED(ptr_client))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_(" id: %d, %s%s%s, started on: %s"),
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
@@ -49,10 +50,16 @@ struct t_config_option *relay_config_color_status[RELAY_NUM_STATUS];
|
||||
|
||||
/* relay config, network section */
|
||||
|
||||
struct t_config_option *relay_config_network_allowed_ips;
|
||||
struct t_config_option *relay_config_network_bind_address;
|
||||
struct t_config_option *relay_config_network_compression_level;
|
||||
struct t_config_option *relay_config_network_max_clients;
|
||||
struct t_config_option *relay_config_network_password;
|
||||
|
||||
/* other */
|
||||
|
||||
regex_t *relay_config_regex_allowed_ips = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* relay_config_refresh_cb: callback called when user changes relay option that
|
||||
@@ -70,6 +77,42 @@ relay_config_refresh_cb (void *data, struct t_config_option *option)
|
||||
relay_buffer_refresh (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_config_change_network_allowed_ips: called when allowed ips changes
|
||||
*/
|
||||
|
||||
void
|
||||
relay_config_change_network_allowed_ips (void *data,
|
||||
struct t_config_option *option)
|
||||
{
|
||||
const char *allowed_ips;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) option;
|
||||
|
||||
if (relay_config_regex_allowed_ips)
|
||||
{
|
||||
regfree (relay_config_regex_allowed_ips);
|
||||
free (relay_config_regex_allowed_ips);
|
||||
relay_config_regex_allowed_ips = NULL;
|
||||
}
|
||||
|
||||
allowed_ips = weechat_config_string (relay_config_network_allowed_ips);
|
||||
if (allowed_ips && allowed_ips[0])
|
||||
{
|
||||
relay_config_regex_allowed_ips = malloc (sizeof (*relay_config_regex_allowed_ips));
|
||||
if (relay_config_regex_allowed_ips)
|
||||
{
|
||||
if (regcomp (relay_config_regex_allowed_ips, allowed_ips, REG_EXTENDED) != 0)
|
||||
{
|
||||
free (relay_config_regex_allowed_ips);
|
||||
relay_config_regex_allowed_ips = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_config_change_network_bind_address_cb: callback called when user changes
|
||||
* network bind address option
|
||||
@@ -370,6 +413,13 @@ relay_config_init ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
relay_config_network_allowed_ips = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"allowed_ips", "string",
|
||||
N_("regular expression with IPs allowed to use relay, example: "
|
||||
"\"^(123.45.67.89|192.160.*)$\""),
|
||||
NULL, 0, 0, "", NULL, 0, NULL, NULL,
|
||||
&relay_config_change_network_allowed_ips, NULL, NULL, NULL);
|
||||
relay_config_network_bind_address = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"bind_address", "string",
|
||||
@@ -378,6 +428,14 @@ relay_config_init ()
|
||||
"local machine only)"),
|
||||
NULL, 0, 0, "", NULL, 0, NULL, NULL,
|
||||
&relay_config_change_network_bind_address_cb, NULL, NULL, NULL);
|
||||
relay_config_network_compression_level = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"compression_level", "integer",
|
||||
N_("compression level for packets sent to client with WeeChat protocol "
|
||||
"(0 = disable compression, 1 = low compression ... 9 = best "
|
||||
"compression)"),
|
||||
NULL, 0, 9, "6", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
relay_config_network_max_clients = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"max_clients", "integer",
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __WEECHAT_RELAY_CONFIG_H
|
||||
#define __WEECHAT_RELAY_CONFIG_H 1
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#define RELAY_CONFIG_NAME "relay"
|
||||
|
||||
extern struct t_config_file *relay_config_file;
|
||||
@@ -36,6 +38,9 @@ extern struct t_config_option *relay_config_color_status[];
|
||||
extern struct t_config_option *relay_config_network_bind_address;
|
||||
extern struct t_config_option *relay_config_network_max_clients;
|
||||
extern struct t_config_option *relay_config_network_password;
|
||||
extern struct t_config_option *relay_config_network_compression_level;
|
||||
|
||||
extern regex_t *relay_config_regex_allowed_ips;
|
||||
|
||||
extern int relay_config_create_option_port (void *data,
|
||||
struct t_config_file *config_file,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -218,10 +219,10 @@ relay_raw_message_add_to_list (time_t date, const char *prefix,
|
||||
*/
|
||||
|
||||
struct t_relay_raw_message *
|
||||
relay_raw_message_add (struct t_relay_client *client, int send,
|
||||
relay_raw_message_add (struct t_relay_client *client, int flags,
|
||||
const char *message)
|
||||
{
|
||||
char *buf, *buf2, prefix[256];
|
||||
char *buf, *buf2, prefix[256], prefix_arrow[16];
|
||||
const unsigned char *ptr_buf;
|
||||
const char *hexa = "0123456789ABCDEF";
|
||||
int pos_buf, pos_buf2, char_size, i;
|
||||
@@ -255,27 +256,46 @@ relay_raw_message_add (struct t_relay_client *client, int send,
|
||||
buf2[pos_buf2] = '\0';
|
||||
}
|
||||
|
||||
/* build prefix with arrow */
|
||||
prefix_arrow[0] = '\0';
|
||||
switch (flags & (RELAY_RAW_FLAG_RECV | RELAY_RAW_FLAG_SEND))
|
||||
{
|
||||
case RELAY_RAW_FLAG_RECV:
|
||||
strcpy (prefix_arrow, RELAY_RAW_PREFIX_RECV);
|
||||
break;
|
||||
case RELAY_RAW_FLAG_SEND:
|
||||
strcpy (prefix_arrow, RELAY_RAW_PREFIX_SEND);
|
||||
break;
|
||||
default:
|
||||
if (flags & RELAY_RAW_FLAG_RECV)
|
||||
strcpy (prefix_arrow, RELAY_RAW_PREFIX_RECV);
|
||||
else
|
||||
strcpy (prefix_arrow, RELAY_RAW_PREFIX_SEND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (client)
|
||||
{
|
||||
snprintf (prefix, sizeof (prefix), "%s[%s%d%s] %s%s %s%s",
|
||||
snprintf (prefix, sizeof (prefix), "%s[%s%d%s] %s%s.%s %s%s",
|
||||
weechat_color ("chat_delimiters"),
|
||||
weechat_color ("chat"),
|
||||
client->id,
|
||||
weechat_color ("chat_delimiters"),
|
||||
weechat_color ("chat_server"),
|
||||
relay_protocol_string[client->protocol],
|
||||
client->protocol_args,
|
||||
(send) ?
|
||||
(flags & RELAY_RAW_FLAG_SEND) ?
|
||||
weechat_color ("chat_prefix_quit") :
|
||||
weechat_color ("chat_prefix_join"),
|
||||
(send) ? RELAY_RAW_PREFIX_SEND : RELAY_RAW_PREFIX_RECV);
|
||||
prefix_arrow);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (prefix, sizeof (prefix), "%s%s",
|
||||
(send) ?
|
||||
(flags & RELAY_RAW_FLAG_SEND) ?
|
||||
weechat_color ("chat_prefix_quit") :
|
||||
weechat_color ("chat_prefix_join"),
|
||||
(send) ? RELAY_RAW_PREFIX_SEND : RELAY_RAW_PREFIX_RECV);
|
||||
prefix_arrow);
|
||||
}
|
||||
|
||||
new_raw_message = relay_raw_message_add_to_list (time (NULL),
|
||||
@@ -295,18 +315,20 @@ relay_raw_message_add (struct t_relay_client *client, int send,
|
||||
*/
|
||||
|
||||
void
|
||||
relay_raw_print (struct t_relay_client *client, int send, const char *message)
|
||||
relay_raw_print (struct t_relay_client *client, int flags,
|
||||
const char *format, ...)
|
||||
{
|
||||
struct t_relay_raw_message *new_raw_message;
|
||||
|
||||
if (!message)
|
||||
weechat_va_format (format);
|
||||
if (!vbuffer)
|
||||
return;
|
||||
|
||||
/* auto-open Relay raw buffer if debug for irc plugin is >= 1 */
|
||||
if (!relay_raw_buffer && (weechat_relay_plugin->debug >= 1))
|
||||
relay_raw_open (0);
|
||||
|
||||
new_raw_message = relay_raw_message_add (client, send, message);
|
||||
new_raw_message = relay_raw_message_add (client, flags, vbuffer);
|
||||
if (new_raw_message)
|
||||
{
|
||||
if (relay_raw_buffer)
|
||||
@@ -314,6 +336,8 @@ relay_raw_print (struct t_relay_client *client, int send, const char *message)
|
||||
if (weechat_config_integer (relay_config_look_raw_messages) == 0)
|
||||
relay_raw_message_free (new_raw_message);
|
||||
}
|
||||
|
||||
free (vbuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#define RELAY_RAW_PREFIX_RECV "-->"
|
||||
#define RELAY_RAW_PREFIX_SEND "<--"
|
||||
|
||||
#define RELAY_RAW_FLAG_RECV 1
|
||||
#define RELAY_RAW_FLAG_SEND 2
|
||||
|
||||
struct t_relay_raw_message
|
||||
{
|
||||
time_t date; /* date/time of message */
|
||||
@@ -43,8 +46,8 @@ extern void relay_raw_open (int switch_to_buffer);
|
||||
extern struct t_relay_raw_message *relay_raw_message_add_to_list (time_t date,
|
||||
const char *prefix,
|
||||
const char *message);
|
||||
extern void relay_raw_print (struct t_relay_client *client, int send,
|
||||
const char *message);
|
||||
extern void relay_raw_print (struct t_relay_client *client, int flags,
|
||||
const char *format, ...);
|
||||
extern void relay_raw_message_free_all ();
|
||||
extern int relay_raw_add_to_infolist (struct t_infolist *infolist,
|
||||
struct t_relay_raw_message *raw_message);
|
||||
|
||||
@@ -199,6 +199,22 @@ relay_server_sock_cb (void *data, int fd)
|
||||
ptr_address = ipv4_address;
|
||||
}
|
||||
|
||||
/* check if IP is allowed, if not, just close socket */
|
||||
if (relay_config_regex_allowed_ips
|
||||
&& (regexec (relay_config_regex_allowed_ips, ptr_address, 0, NULL, 0) != 0))
|
||||
{
|
||||
if (weechat_relay_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: IP address \"%s\" not allowed for relay"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
ptr_address);
|
||||
}
|
||||
close (client_fd);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
relay_client_new (client_fd, ptr_address, server);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include "relay-upgrade.h"
|
||||
#include "relay-buffer.h"
|
||||
#include "relay-client.h"
|
||||
#include "relay-client-irc.h"
|
||||
#include "relay-client-weechat.h"
|
||||
#include "irc/relay-irc.h"
|
||||
#include "weechat/relay-weechat.h"
|
||||
#include "relay-raw.h"
|
||||
|
||||
|
||||
@@ -201,12 +201,12 @@ relay_upgrade_read_cb (void *data,
|
||||
switch (new_client->protocol)
|
||||
{
|
||||
case RELAY_PROTOCOL_WEECHAT:
|
||||
relay_client_weechat_alloc_with_infolist (new_client,
|
||||
infolist);
|
||||
relay_weechat_alloc_with_infolist (new_client,
|
||||
infolist);
|
||||
break;
|
||||
case RELAY_PROTOCOL_IRC:
|
||||
relay_client_irc_alloc_with_infolist (new_client,
|
||||
infolist);
|
||||
relay_irc_alloc_with_infolist (new_client,
|
||||
infolist);
|
||||
break;
|
||||
case RELAY_NUM_PROTOCOLS:
|
||||
break;
|
||||
|
||||
@@ -63,9 +63,7 @@ relay_protocol_search (const char *name)
|
||||
for (i = 0; i < RELAY_NUM_PROTOCOLS; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (relay_protocol_string[i], name) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* protocol not found */
|
||||
|
||||
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* relay-weechat-msg.c: build binary messages for WeeChat protocol
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "../../weechat-plugin.h"
|
||||
#include "../relay.h"
|
||||
#include "relay-weechat.h"
|
||||
#include "relay-weechat-msg.h"
|
||||
#include "../relay-client.h"
|
||||
#include "../relay-config.h"
|
||||
#include "../relay-raw.h"
|
||||
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_new: build a new message (for sending to client)
|
||||
*/
|
||||
|
||||
struct t_relay_weechat_msg *
|
||||
relay_weechat_msg_new (const char *id)
|
||||
{
|
||||
struct t_relay_weechat_msg *new_msg;
|
||||
|
||||
new_msg = malloc (sizeof (*new_msg));
|
||||
if (!new_msg)
|
||||
return NULL;
|
||||
|
||||
new_msg->id = (id) ? strdup (id) : NULL;
|
||||
new_msg->data = malloc (RELAY_WEECHAT_MSG_INITIAL_ALLOC);
|
||||
if (!new_msg->data)
|
||||
{
|
||||
free (new_msg);
|
||||
return NULL;
|
||||
}
|
||||
new_msg->data_alloc = RELAY_WEECHAT_MSG_INITIAL_ALLOC;
|
||||
new_msg->data_size = 0;
|
||||
|
||||
/* add size and compression flag (they will be set later) */
|
||||
relay_weechat_msg_add_int (new_msg, 0);
|
||||
relay_weechat_msg_add_char (new_msg, 0);
|
||||
|
||||
/* add id */
|
||||
relay_weechat_msg_add_string (new_msg, id);
|
||||
|
||||
return new_msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_bytes: add some bytes to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_bytes (struct t_relay_weechat_msg *msg,
|
||||
const void *buffer, int size)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (!msg || !msg->data)
|
||||
return;
|
||||
|
||||
while (msg->data_size + size > msg->data_alloc)
|
||||
{
|
||||
msg->data_alloc *= 2;
|
||||
ptr = realloc (msg->data, msg->data_alloc);
|
||||
if (!ptr)
|
||||
{
|
||||
free (msg->data);
|
||||
msg->data = NULL;
|
||||
msg->data_alloc = 0;
|
||||
msg->data_size = 0;
|
||||
return;
|
||||
}
|
||||
msg->data = ptr;
|
||||
}
|
||||
|
||||
memcpy (msg->data + msg->data_size, buffer, size);
|
||||
msg->data_size += size;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_set_bytes: set some bytes in a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_set_bytes (struct t_relay_weechat_msg *msg,
|
||||
int position, const void *buffer, int size)
|
||||
{
|
||||
if (!msg || !msg->data || (position + size) > msg->data_size)
|
||||
return;
|
||||
|
||||
memcpy (msg->data + position, buffer, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_type: add type to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_type (struct t_relay_weechat_msg *msg, const char *string)
|
||||
{
|
||||
if (string)
|
||||
relay_weechat_msg_add_bytes (msg, string, strlen (string));
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_char: add a char to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_char (struct t_relay_weechat_msg *msg, char c)
|
||||
{
|
||||
relay_weechat_msg_add_bytes (msg, &c, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_int: add an integer to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_int (struct t_relay_weechat_msg *msg, int value)
|
||||
{
|
||||
uint32_t value32;
|
||||
|
||||
value32 = htonl ((uint32_t)value);
|
||||
relay_weechat_msg_add_bytes (msg, &value32, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_long: add a long integer to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_long (struct t_relay_weechat_msg *msg, long value)
|
||||
{
|
||||
char str_long[128];
|
||||
unsigned char length;
|
||||
|
||||
snprintf (str_long, sizeof (str_long), "%ld", value);
|
||||
length = strlen (str_long);
|
||||
relay_weechat_msg_add_bytes (msg, &length, 1);
|
||||
relay_weechat_msg_add_bytes (msg, str_long, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_string: add length + string to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_string (struct t_relay_weechat_msg *msg,
|
||||
const char *string)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (string)
|
||||
{
|
||||
length = strlen (string);
|
||||
relay_weechat_msg_add_int (msg, length);
|
||||
if (length > 0)
|
||||
relay_weechat_msg_add_bytes (msg, string, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
relay_weechat_msg_add_int (msg, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_buffer: add buffer (length + data) to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_buffer (struct t_relay_weechat_msg *msg,
|
||||
void *buffer, int length)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
relay_weechat_msg_add_int (msg, length);
|
||||
if (length > 0)
|
||||
relay_weechat_msg_add_bytes (msg, buffer, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
relay_weechat_msg_add_int (msg, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_pointer: add a pointer to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_pointer (struct t_relay_weechat_msg *msg, void *pointer)
|
||||
{
|
||||
char str_pointer[128];
|
||||
unsigned char length;
|
||||
|
||||
snprintf (str_pointer, sizeof (str_pointer),
|
||||
"%lx", (long unsigned int)pointer);
|
||||
length = strlen (str_pointer);
|
||||
relay_weechat_msg_add_bytes (msg, &length, 1);
|
||||
relay_weechat_msg_add_bytes (msg, str_pointer, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_time: add a time to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_time (struct t_relay_weechat_msg *msg, time_t time)
|
||||
{
|
||||
char str_time[128];
|
||||
unsigned char length;
|
||||
|
||||
snprintf (str_time, sizeof (str_time), "%ld", time);
|
||||
length = strlen (str_time);
|
||||
relay_weechat_msg_add_bytes (msg, &length, 1);
|
||||
relay_weechat_msg_add_bytes (msg, str_time, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_hdata_path: recursively add hdata for a path
|
||||
* return number of hdata objects added in
|
||||
* message
|
||||
*/
|
||||
|
||||
int
|
||||
relay_weechat_msg_add_hdata_path (struct t_relay_weechat_msg *msg,
|
||||
char **list_path,
|
||||
int index_path,
|
||||
void **path_pointers,
|
||||
struct t_hdata *hdata,
|
||||
void *pointer,
|
||||
char **list_keys)
|
||||
{
|
||||
int num_added, i, count, count_all, type;
|
||||
char *pos, *pos2, *str_count, *error;
|
||||
void *sub_pointer;
|
||||
struct t_hdata *sub_hdata;
|
||||
const char *sub_hdata_name;
|
||||
|
||||
num_added = 0;
|
||||
|
||||
count_all = 0;
|
||||
count = 0;
|
||||
pos = strchr (list_path[index_path], '(');
|
||||
if (pos)
|
||||
{
|
||||
pos2 = strchr (pos + 1, ')');
|
||||
if (pos2 && (pos2 > pos + 1))
|
||||
{
|
||||
str_count = weechat_strndup (pos + 1, pos2 - (pos + 1));
|
||||
if (str_count)
|
||||
{
|
||||
if (strcmp (str_count, "*") == 0)
|
||||
count_all = 1;
|
||||
else
|
||||
{
|
||||
error = NULL;
|
||||
count = (int)strtol (str_count, &error, 10);
|
||||
if (error && !error[0])
|
||||
{
|
||||
if (count > 0)
|
||||
count--;
|
||||
else if (count < 0)
|
||||
count++;
|
||||
}
|
||||
else
|
||||
count = 0;
|
||||
}
|
||||
free (str_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (pointer)
|
||||
{
|
||||
path_pointers[index_path] = pointer;
|
||||
|
||||
if (list_path[index_path + 1])
|
||||
{
|
||||
/* recursive call with next path */
|
||||
pos = strchr (list_path[index_path + 1], '(');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
sub_pointer = weechat_hdata_pointer (hdata, pointer, list_path[index_path + 1]);
|
||||
sub_hdata_name = weechat_hdata_get_var_hdata (hdata, list_path[index_path + 1]);
|
||||
if (pos)
|
||||
pos[0] = '(';
|
||||
if (sub_pointer && sub_hdata_name)
|
||||
{
|
||||
sub_hdata = weechat_hdata_get (sub_hdata_name);
|
||||
if (sub_hdata)
|
||||
{
|
||||
num_added += relay_weechat_msg_add_hdata_path (msg,
|
||||
list_path,
|
||||
index_path + 1,
|
||||
path_pointers,
|
||||
sub_hdata,
|
||||
sub_pointer,
|
||||
list_keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* last path? then get pointer + values and fill message with them */
|
||||
for (i = 0; list_path[i]; i++)
|
||||
{
|
||||
relay_weechat_msg_add_pointer (msg, path_pointers[i]);
|
||||
}
|
||||
for (i = 0; list_keys[i]; i++)
|
||||
{
|
||||
type = weechat_hdata_get_var_type (hdata, list_keys[i]);
|
||||
if ((type >= 0) && (type != WEECHAT_HDATA_OTHER))
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WEECHAT_HDATA_CHAR:
|
||||
relay_weechat_msg_add_char (msg,
|
||||
weechat_hdata_char (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
case WEECHAT_HDATA_INTEGER:
|
||||
relay_weechat_msg_add_int (msg,
|
||||
weechat_hdata_integer (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
case WEECHAT_HDATA_LONG:
|
||||
relay_weechat_msg_add_long (msg,
|
||||
weechat_hdata_long (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
case WEECHAT_HDATA_STRING:
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
case WEECHAT_HDATA_POINTER:
|
||||
relay_weechat_msg_add_pointer (msg,
|
||||
weechat_hdata_pointer (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
case WEECHAT_HDATA_TIME:
|
||||
relay_weechat_msg_add_time (msg,
|
||||
weechat_hdata_time (hdata,
|
||||
pointer,
|
||||
list_keys[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
num_added++;
|
||||
}
|
||||
if (count_all)
|
||||
{
|
||||
pointer = weechat_hdata_move (hdata, pointer, 1);
|
||||
}
|
||||
else if (count == 0)
|
||||
pointer = NULL;
|
||||
else if (count > 0)
|
||||
{
|
||||
pointer = weechat_hdata_move (hdata, pointer, 1);
|
||||
count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointer = weechat_hdata_move (hdata, pointer, -1);
|
||||
count++;
|
||||
}
|
||||
if (!pointer)
|
||||
break;
|
||||
}
|
||||
|
||||
return num_added;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_hdata: add a hdata to a message
|
||||
* path has format:
|
||||
* hdata_head:ptr->var->var->...->var
|
||||
* where ptr can be a list name or a
|
||||
* pointer (0x12345)
|
||||
* keys is optional: if not NULL,
|
||||
* comma-separated list of keys to return
|
||||
* for hdata
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
|
||||
const char *path, const char *keys)
|
||||
{
|
||||
struct t_hdata *ptr_hdata_head, *ptr_hdata;
|
||||
char *hdata_head, *pos, **list_keys, *keys_types, **list_path;
|
||||
char *path_returned;
|
||||
const char *hdata_name;
|
||||
void *pointer, **path_pointers;
|
||||
long unsigned int value;
|
||||
int num_keys, num_path, i, type, pos_count, count, rc;
|
||||
uint32_t count32;
|
||||
|
||||
hdata_head = NULL;
|
||||
list_keys = NULL;
|
||||
num_keys = 0;
|
||||
keys_types = NULL;
|
||||
list_path = NULL;
|
||||
num_path = 0;
|
||||
path_returned = NULL;
|
||||
|
||||
/* extract hdata name (head) from path */
|
||||
pos = strchr (path, ':');
|
||||
if (!pos)
|
||||
goto end;
|
||||
hdata_head = weechat_strndup (path, pos - path);
|
||||
if (!hdata_head)
|
||||
goto end;
|
||||
ptr_hdata_head = weechat_hdata_get (hdata_head);
|
||||
if (!ptr_hdata_head)
|
||||
goto end;
|
||||
|
||||
/* split path */
|
||||
list_path = weechat_string_split (pos + 1, "/", 0, 0, &num_path);
|
||||
if (!list_path)
|
||||
goto end;
|
||||
|
||||
/* extract pointer from first path (direct pointer or list name) */
|
||||
pointer = NULL;
|
||||
pos = strchr (list_path[0], '(');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
if (strncmp (list_path[0], "0x", 2) == 0)
|
||||
{
|
||||
rc = sscanf (list_path[0], "%lx", &value);
|
||||
if ((rc != EOF) && (rc != 0))
|
||||
pointer = (void *)value;
|
||||
}
|
||||
else
|
||||
pointer = weechat_hdata_get_list (ptr_hdata_head, list_path[0]);
|
||||
if (pos)
|
||||
pos[0] = '(';
|
||||
if (!pointer)
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* build string with path where:
|
||||
* - counters are removed
|
||||
* - variable names are replaced by hdata name
|
||||
*/
|
||||
path_returned = malloc (strlen (path) * 2);
|
||||
if (!path_returned)
|
||||
goto end;
|
||||
ptr_hdata = ptr_hdata_head;
|
||||
strcpy (path_returned, hdata_head);
|
||||
hdata_name = hdata_head;
|
||||
for (i = 1; i < num_path; i++)
|
||||
{
|
||||
pos = strchr (list_path[i], '(');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
hdata_name = weechat_hdata_get_var_hdata (ptr_hdata, list_path[i]);
|
||||
if (!hdata_name)
|
||||
goto end;
|
||||
ptr_hdata = weechat_hdata_get (hdata_name);
|
||||
if (!ptr_hdata)
|
||||
goto end;
|
||||
strcat (path_returned, "/");
|
||||
strcat (path_returned, hdata_name);
|
||||
if (pos)
|
||||
pos[0] = '(';
|
||||
}
|
||||
|
||||
/* split keys */
|
||||
if (!keys)
|
||||
keys = weechat_hdata_get_string (ptr_hdata, "var_keys");
|
||||
list_keys = weechat_string_split (keys, ",", 0, 0, &num_keys);
|
||||
if (!list_keys)
|
||||
goto end;
|
||||
|
||||
/* build string with list of keys with types: "key1:type1,key2:type2,..." */
|
||||
keys_types = malloc (strlen (keys) + (num_keys * 8) + 1);
|
||||
if (!keys_types)
|
||||
goto end;
|
||||
keys_types[0] = '\0';
|
||||
for (i = 0; i < num_keys; i++)
|
||||
{
|
||||
type = weechat_hdata_get_var_type (ptr_hdata, list_keys[i]);
|
||||
if ((type >= 0) && (type != WEECHAT_HDATA_OTHER))
|
||||
{
|
||||
if (keys_types[0])
|
||||
strcat (keys_types, ",");
|
||||
strcat (keys_types, list_keys[i]);
|
||||
strcat (keys_types, ":");
|
||||
switch (type)
|
||||
{
|
||||
case WEECHAT_HDATA_CHAR:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_CHAR);
|
||||
break;
|
||||
case WEECHAT_HDATA_INTEGER:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_INT);
|
||||
break;
|
||||
case WEECHAT_HDATA_LONG:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_LONG);
|
||||
break;
|
||||
case WEECHAT_HDATA_STRING:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_STRING);
|
||||
break;
|
||||
case WEECHAT_HDATA_POINTER:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_POINTER);
|
||||
break;
|
||||
case WEECHAT_HDATA_TIME:
|
||||
strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_TIME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!keys_types[0])
|
||||
goto end;
|
||||
|
||||
/* start hdata in message */
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HDATA);
|
||||
relay_weechat_msg_add_string (msg, path_returned);
|
||||
relay_weechat_msg_add_string (msg, keys_types);
|
||||
|
||||
/* "count" will be set later, with number of objects in hdata */
|
||||
pos_count = msg->data_size;
|
||||
count = 0;
|
||||
relay_weechat_msg_add_int (msg, 0);
|
||||
path_pointers = malloc (sizeof (*path_pointers) * num_path);
|
||||
if (path_pointers)
|
||||
{
|
||||
count = relay_weechat_msg_add_hdata_path (msg,
|
||||
list_path,
|
||||
0,
|
||||
path_pointers,
|
||||
ptr_hdata_head,
|
||||
pointer,
|
||||
list_keys);
|
||||
}
|
||||
count32 = htonl ((uint32_t)count);
|
||||
relay_weechat_msg_set_bytes (msg, pos_count, &count32, 4);
|
||||
|
||||
end:
|
||||
if (list_keys)
|
||||
weechat_string_free_split (list_keys);
|
||||
if (keys_types)
|
||||
free (keys_types);
|
||||
if (list_path)
|
||||
weechat_string_free_split (list_path);
|
||||
if (path_returned)
|
||||
free (path_returned);
|
||||
if (hdata_head)
|
||||
free (hdata_head);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_infolist: add an infolist to a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg,
|
||||
const char *name,
|
||||
void *pointer,
|
||||
const char *arguments)
|
||||
{
|
||||
struct t_infolist *infolist;
|
||||
const char *fields;
|
||||
char **list_fields;
|
||||
void *buf_ptr;
|
||||
int num_fields, i, buf_size;
|
||||
int pos_count_items, count_items, pos_count_vars, count_vars;
|
||||
uint32_t count32;
|
||||
|
||||
infolist = weechat_infolist_get (name, pointer, arguments);
|
||||
if (!infolist)
|
||||
return;
|
||||
|
||||
/* start infolist in message */
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INFOLIST);
|
||||
relay_weechat_msg_add_string (msg, name);
|
||||
|
||||
/* count of items will be set later, with number of items in infolist */
|
||||
pos_count_items = msg->data_size;
|
||||
count_items = 0;
|
||||
relay_weechat_msg_add_int (msg, 0);
|
||||
|
||||
while (weechat_infolist_next (infolist))
|
||||
{
|
||||
fields = weechat_infolist_fields (infolist);
|
||||
if (fields)
|
||||
{
|
||||
list_fields = weechat_string_split (fields, ",", 0, 0, &num_fields);
|
||||
if (list_fields)
|
||||
{
|
||||
count_items++;
|
||||
pos_count_vars = msg->data_size;
|
||||
count_vars = 0;
|
||||
relay_weechat_msg_add_int (msg, 0);
|
||||
for (i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (strlen (list_fields[i]) > 2)
|
||||
{
|
||||
count_vars++;
|
||||
relay_weechat_msg_add_string (msg, list_fields[i] + 2);
|
||||
switch (list_fields[i][0])
|
||||
{
|
||||
case 'i':
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INT);
|
||||
relay_weechat_msg_add_int (msg,
|
||||
weechat_infolist_integer (infolist,
|
||||
list_fields[i] + 2));
|
||||
break;
|
||||
case 's':
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING);
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_infolist_string (infolist,
|
||||
list_fields[i] + 2));
|
||||
break;
|
||||
case 'p':
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_POINTER);
|
||||
relay_weechat_msg_add_pointer (msg,
|
||||
weechat_infolist_pointer (infolist,
|
||||
list_fields[i] + 2));
|
||||
break;
|
||||
case 'b':
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_BUFFER);
|
||||
buf_ptr = weechat_infolist_buffer (infolist,
|
||||
list_fields[i] + 2,
|
||||
&buf_size);
|
||||
relay_weechat_msg_add_buffer (msg, buf_ptr, buf_size);
|
||||
break;
|
||||
case 't':
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_TIME);
|
||||
relay_weechat_msg_add_time (msg,
|
||||
weechat_infolist_time (infolist,
|
||||
list_fields[i] + 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set count of variables in item */
|
||||
count32 = htonl ((uint32_t)count_vars);
|
||||
relay_weechat_msg_set_bytes (msg, pos_count_vars, &count32, 4);
|
||||
|
||||
weechat_string_free_split (list_fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set count of items */
|
||||
count32 = htonl ((uint32_t)count_items);
|
||||
relay_weechat_msg_set_bytes (msg, pos_count_items, &count32, 4);
|
||||
|
||||
weechat_infolist_free (infolist);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_nicklist_buffer: add nicklist for a buffer, as hdata
|
||||
* object
|
||||
* return number of nicks+groups added
|
||||
* in message
|
||||
*/
|
||||
|
||||
int
|
||||
relay_weechat_msg_add_nicklist_buffer (struct t_relay_weechat_msg *msg,
|
||||
struct t_gui_buffer *buffer)
|
||||
{
|
||||
int count;
|
||||
struct t_hdata *ptr_hdata_group, *ptr_hdata_nick;
|
||||
struct t_gui_nick_group *ptr_group;
|
||||
struct t_gui_nick *ptr_nick;
|
||||
|
||||
count = 0;
|
||||
|
||||
ptr_hdata_group = weechat_hdata_get ("nick_group");
|
||||
ptr_hdata_nick = weechat_hdata_get ("nick");
|
||||
|
||||
ptr_group = NULL;
|
||||
ptr_nick = NULL;
|
||||
weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick);
|
||||
while (ptr_group || ptr_nick)
|
||||
{
|
||||
if (ptr_nick)
|
||||
{
|
||||
relay_weechat_msg_add_pointer (msg, buffer);
|
||||
relay_weechat_msg_add_pointer (msg, ptr_nick);
|
||||
relay_weechat_msg_add_char (msg, 0); /* group */
|
||||
relay_weechat_msg_add_char (msg,
|
||||
(char)weechat_hdata_integer(ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"visible"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"name"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"color"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"prefix"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"prefix_color"));
|
||||
relay_weechat_msg_add_int (msg,
|
||||
weechat_hdata_integer (ptr_hdata_nick,
|
||||
ptr_nick,
|
||||
"level"));
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
relay_weechat_msg_add_pointer (msg, buffer);
|
||||
relay_weechat_msg_add_pointer (msg, ptr_group);
|
||||
relay_weechat_msg_add_char (msg, 1); /* group */
|
||||
relay_weechat_msg_add_char (msg,
|
||||
(char)weechat_hdata_integer(ptr_hdata_group,
|
||||
ptr_group,
|
||||
"visible"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_group,
|
||||
ptr_group,
|
||||
"name"));
|
||||
relay_weechat_msg_add_string (msg,
|
||||
weechat_hdata_string (ptr_hdata_group,
|
||||
ptr_group,
|
||||
"color"));
|
||||
relay_weechat_msg_add_string (msg, NULL); /* prefix */
|
||||
relay_weechat_msg_add_string (msg, NULL); /* prefix_color */
|
||||
relay_weechat_msg_add_int (msg,
|
||||
weechat_hdata_integer (ptr_hdata_group,
|
||||
ptr_group,
|
||||
"level"));
|
||||
count++;
|
||||
}
|
||||
weechat_nicklist_get_next_item (buffer, &ptr_group, &ptr_nick);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_add_nicklist: add nicklist for one or all buffers, as
|
||||
* hdata object
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg,
|
||||
struct t_gui_buffer *buffer)
|
||||
{
|
||||
struct t_hdata *ptr_hdata;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
int pos_count, count;
|
||||
uint32_t count32;
|
||||
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HDATA);
|
||||
relay_weechat_msg_add_string (msg, "buffer/nick_group");
|
||||
relay_weechat_msg_add_string (msg,
|
||||
"group:chr,visible:chr,name:str,color:str,"
|
||||
"prefix:str,prefix_color:str,level:int");
|
||||
|
||||
/* "count" will be set later, with number of objects in hdata */
|
||||
pos_count = msg->data_size;
|
||||
count = 0;
|
||||
relay_weechat_msg_add_int (msg, 0);
|
||||
|
||||
if (buffer)
|
||||
count += relay_weechat_msg_add_nicklist_buffer (msg, buffer);
|
||||
else
|
||||
{
|
||||
ptr_hdata = weechat_hdata_get ("buffer");
|
||||
ptr_buffer = weechat_hdata_get_list (ptr_hdata, "gui_buffers");
|
||||
while (ptr_buffer)
|
||||
{
|
||||
count += relay_weechat_msg_add_nicklist_buffer (msg, ptr_buffer);
|
||||
ptr_buffer = weechat_hdata_move (ptr_hdata, ptr_buffer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
count32 = htonl ((uint32_t)count);
|
||||
relay_weechat_msg_set_bytes (msg, pos_count, &count32, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_send: send a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_send (struct t_relay_client *client,
|
||||
struct t_relay_weechat_msg *msg)
|
||||
{
|
||||
uint32_t size32;
|
||||
char compression;
|
||||
#ifdef HAVE_ZLIB
|
||||
int rc, num_sent;
|
||||
Bytef *dest;
|
||||
uLongf dest_size;
|
||||
struct timeval tv1, tv2;
|
||||
long time_diff;
|
||||
|
||||
if (RELAY_WEECHAT_DATA(client, compression)
|
||||
&& (weechat_config_integer (relay_config_network_compression_level) > 0))
|
||||
{
|
||||
dest_size = compressBound (msg->data_size - 5);
|
||||
dest = malloc (dest_size + 5);
|
||||
if (dest)
|
||||
{
|
||||
gettimeofday (&tv1, NULL);
|
||||
rc = compress2 (dest + 5, &dest_size,
|
||||
(Bytef *)(msg->data + 5), msg->data_size - 5,
|
||||
weechat_config_integer (relay_config_network_compression_level));
|
||||
gettimeofday (&tv2, NULL);
|
||||
time_diff = weechat_util_timeval_diff (&tv1, &tv2);
|
||||
if ((rc == Z_OK) && ((int)dest_size + 5 < msg->data_size))
|
||||
{
|
||||
/* set size and compression flag */
|
||||
size32 = htonl ((uint32_t)(dest_size + 5));
|
||||
memcpy (dest, &size32, 4);
|
||||
dest[4] = 1;
|
||||
|
||||
/* send compressed data */
|
||||
num_sent = send (client->sock, dest, dest_size + 5, 0);
|
||||
|
||||
/* display message in raw buffer */
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_SEND,
|
||||
"obj: %d/%d bytes (%d%%, %ldms), id: %s",
|
||||
(int)dest_size + 5,
|
||||
msg->data_size,
|
||||
100 - ((((int)dest_size + 5) * 100) / msg->data_size),
|
||||
time_diff,
|
||||
msg->id);
|
||||
|
||||
if (num_sent < 0)
|
||||
{
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_SEND,
|
||||
"error: %s", strerror (errno));
|
||||
}
|
||||
|
||||
free (dest);
|
||||
return;
|
||||
}
|
||||
free (dest);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set size and compression flag */
|
||||
size32 = htonl ((uint32_t)msg->data_size);
|
||||
relay_weechat_msg_set_bytes (msg, 0, &size32, 4);
|
||||
compression = 0;
|
||||
relay_weechat_msg_set_bytes (msg, 4, &compression, 1);
|
||||
|
||||
/* send uncompressed data */
|
||||
num_sent = send (client->sock, msg->data, msg->data_size, 0);
|
||||
|
||||
/* display message in raw buffer */
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_SEND,
|
||||
"obj: %d bytes", msg->data_size);
|
||||
|
||||
if (num_sent < 0)
|
||||
{
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_SEND,
|
||||
"error: %s", strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_msg_free: free a message
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_msg_free (struct t_relay_weechat_msg *msg)
|
||||
{
|
||||
if (msg->id)
|
||||
free (msg->id);
|
||||
if (msg->data)
|
||||
free (msg->data);
|
||||
|
||||
free (msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_sendf: send formatted data to client
|
||||
*/
|
||||
|
||||
int
|
||||
relay_weechat_sendf (struct t_relay_client *client, const char *format, ...)
|
||||
{
|
||||
char str_length[8];
|
||||
int length_vbuffer, num_sent, total_sent;
|
||||
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
weechat_va_format (format);
|
||||
if (!vbuffer)
|
||||
return 0;
|
||||
length_vbuffer = strlen (vbuffer);
|
||||
|
||||
total_sent = 0;
|
||||
|
||||
snprintf (str_length, sizeof (str_length), "%07d", length_vbuffer);
|
||||
|
||||
num_sent = send (client->sock, str_length, 7, 0);
|
||||
client->bytes_sent += 7;
|
||||
total_sent += num_sent;
|
||||
if (num_sent >= 0)
|
||||
{
|
||||
num_sent = send (client->sock, vbuffer, length_vbuffer, 0);
|
||||
client->bytes_sent += length_vbuffer;
|
||||
total_sent += num_sent;
|
||||
}
|
||||
|
||||
if (num_sent < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: error sending data to client %d (%s)"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
client->id, strerror (errno));
|
||||
}
|
||||
|
||||
return total_sent;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_RELAY_WEECHAT_MSG_H
|
||||
#define __WEECHAT_RELAY_WEECHAT_MSG_H 1
|
||||
|
||||
#define RELAY_WEECHAT_MSG_INITIAL_ALLOC 4096
|
||||
|
||||
/* object ids in binary messages */
|
||||
#define RELAY_WEECHAT_MSG_OBJ_CHAR "chr"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_INT "int"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_LONG "lon"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_STRING "str"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_BUFFER "buf"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_POINTER "ptr"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_TIME "tim"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_HDATA "hda"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_INFO "inf"
|
||||
#define RELAY_WEECHAT_MSG_OBJ_INFOLIST "lis"
|
||||
|
||||
struct t_relay_weechat_msg
|
||||
{
|
||||
char *id; /* message id */
|
||||
char *data; /* binary buffer */
|
||||
int data_alloc; /* currently allocated size */
|
||||
int data_size; /* current size of buffer */
|
||||
};
|
||||
|
||||
extern struct t_relay_weechat_msg *relay_weechat_msg_new (const char *id);
|
||||
extern void relay_weechat_msg_add_bytes (struct t_relay_weechat_msg *msg,
|
||||
const void *buffer, int size);
|
||||
extern void relay_weechat_msg_set_bytes (struct t_relay_weechat_msg *msg,
|
||||
int position, const void *buffer,
|
||||
int size);
|
||||
extern void relay_weechat_msg_add_type (struct t_relay_weechat_msg *msg,
|
||||
const char *string);
|
||||
extern void relay_weechat_msg_add_char (struct t_relay_weechat_msg *msg,
|
||||
char c);
|
||||
extern void relay_weechat_msg_add_int (struct t_relay_weechat_msg *msg,
|
||||
int value);
|
||||
extern void relay_weechat_msg_add_long (struct t_relay_weechat_msg *msg,
|
||||
long value);
|
||||
extern void relay_weechat_msg_add_string (struct t_relay_weechat_msg *msg,
|
||||
const char *string);
|
||||
extern void relay_weechat_msg_add_buffer (struct t_relay_weechat_msg *msg,
|
||||
void *data, int length);
|
||||
extern void relay_weechat_msg_add_pointer (struct t_relay_weechat_msg *msg,
|
||||
void *pointer);
|
||||
extern void relay_weechat_msg_add_time (struct t_relay_weechat_msg *msg,
|
||||
time_t time);
|
||||
extern void relay_weechat_msg_add_hdata1 (struct t_relay_weechat_msg *msg,
|
||||
const char *name, const char *list,
|
||||
const char *keys);
|
||||
extern void relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
|
||||
const char *path, const char *keys);
|
||||
extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg,
|
||||
const char *name,
|
||||
void *pointer,
|
||||
const char *arguments);
|
||||
extern void relay_weechat_msg_add_nicklist (struct t_relay_weechat_msg *msg,
|
||||
struct t_gui_buffer *buffer);
|
||||
extern void relay_weechat_msg_send (struct t_relay_client *client,
|
||||
struct t_relay_weechat_msg *msg);
|
||||
extern void relay_weechat_msg_free (struct t_relay_weechat_msg *msg);
|
||||
|
||||
#endif /* __WEECHAT_RELAY_WEECHAT_MSG_H */
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* relay-weechat-protocol.c: WeeChat protocol for relay to client
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../weechat-plugin.h"
|
||||
#include "../relay.h"
|
||||
#include "relay-weechat.h"
|
||||
#include "relay-weechat-protocol.h"
|
||||
#include "relay-weechat-msg.h"
|
||||
#include "../relay-client.h"
|
||||
#include "../relay-config.h"
|
||||
#include "../relay-raw.h"
|
||||
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_get_buffer: get buffer pointer with argument from a
|
||||
* command, which can be a pointer
|
||||
* ("0x12345") or a full name
|
||||
* ("irc.freenode.#weechat")
|
||||
*/
|
||||
|
||||
struct t_gui_buffer *
|
||||
relay_weechat_protocol_get_buffer (const char *arg)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
long unsigned int value;
|
||||
int rc;
|
||||
char *pos, *plugin;
|
||||
|
||||
ptr_buffer = NULL;
|
||||
|
||||
if (strncmp (arg, "0x", 2) == 0)
|
||||
{
|
||||
rc = sscanf (arg, "%lx", &value);
|
||||
if ((rc != EOF) && (rc != 0))
|
||||
ptr_buffer = (void *)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = strchr (arg, '.');
|
||||
if (pos)
|
||||
{
|
||||
plugin = weechat_strndup (arg, pos - arg);
|
||||
if (plugin)
|
||||
{
|
||||
ptr_buffer = weechat_buffer_search (plugin, pos + 1);
|
||||
free (plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ptr_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_init: 'init' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
|
||||
{
|
||||
char **options, *pos;
|
||||
int num_options, i, compression;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(1);
|
||||
|
||||
options = weechat_string_split (argv_eol[0], ",", 0, 0, &num_options);
|
||||
if (options)
|
||||
{
|
||||
for (i = 0; i < num_options; i++)
|
||||
{
|
||||
pos = strchr (options[i], '=');
|
||||
if (pos)
|
||||
{
|
||||
pos[0] = '\0';
|
||||
pos++;
|
||||
if (strcmp (options[i], "password") == 0)
|
||||
{
|
||||
if (strcmp (weechat_config_string (relay_config_network_password),
|
||||
pos) == 0)
|
||||
{
|
||||
RELAY_WEECHAT_DATA(client, password_ok) = 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp (options[i], "compression") == 0)
|
||||
{
|
||||
compression = relay_weechat_compression_search (pos);
|
||||
if (compression >= 0)
|
||||
RELAY_WEECHAT_DATA(client, compression) = compression;
|
||||
}
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (options);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_hdata: 'hdata' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(hdata)
|
||||
{
|
||||
struct t_relay_weechat_msg *msg;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(1);
|
||||
|
||||
msg = relay_weechat_msg_new (id);
|
||||
if (msg)
|
||||
{
|
||||
relay_weechat_msg_add_hdata (msg, argv[0],
|
||||
(argc > 1) ? argv_eol[1] : NULL);
|
||||
relay_weechat_msg_send (client, msg);
|
||||
relay_weechat_msg_free (msg);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_info: 'info' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(info)
|
||||
{
|
||||
struct t_relay_weechat_msg *msg;
|
||||
const char *info;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(1);
|
||||
|
||||
msg = relay_weechat_msg_new (id);
|
||||
if (msg)
|
||||
{
|
||||
info = weechat_info_get (argv[0],
|
||||
(argc > 1) ? argv_eol[1] : NULL);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INFO);
|
||||
relay_weechat_msg_add_string (msg, argv[0]);
|
||||
relay_weechat_msg_add_string (msg, info);
|
||||
relay_weechat_msg_send (client, msg);
|
||||
relay_weechat_msg_free (msg);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_infolist: 'infolist' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(infolist)
|
||||
{
|
||||
struct t_relay_weechat_msg *msg;
|
||||
long unsigned int value;
|
||||
char *args;
|
||||
int rc;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(1);
|
||||
|
||||
msg = relay_weechat_msg_new (id);
|
||||
if (msg)
|
||||
{
|
||||
value = 0;
|
||||
args = NULL;
|
||||
if (argc > 1)
|
||||
{
|
||||
rc = sscanf (argv[1], "%lx", &value);
|
||||
if ((rc == EOF) || (rc == 0))
|
||||
value = 0;
|
||||
if (argc > 2)
|
||||
args = argv_eol[2];
|
||||
}
|
||||
relay_weechat_msg_add_infolist (msg, argv[0], (void *)value, args);
|
||||
relay_weechat_msg_send (client, msg);
|
||||
relay_weechat_msg_free (msg);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_nicklist: 'nicklist' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(nicklist)
|
||||
{
|
||||
struct t_relay_weechat_msg *msg;
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
|
||||
|
||||
ptr_buffer = NULL;
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
ptr_buffer = relay_weechat_protocol_get_buffer (argv[0]);
|
||||
if (!ptr_buffer)
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
msg = relay_weechat_msg_new (id);
|
||||
if (msg)
|
||||
{
|
||||
relay_weechat_msg_add_nicklist (msg, ptr_buffer);
|
||||
relay_weechat_msg_send (client, msg);
|
||||
relay_weechat_msg_free (msg);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_input: 'input' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(input)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(2);
|
||||
|
||||
ptr_buffer = relay_weechat_protocol_get_buffer (argv[0]);
|
||||
if (ptr_buffer)
|
||||
weechat_command (ptr_buffer, argv_eol[1]);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_test: 'test' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(test)
|
||||
{
|
||||
struct t_relay_weechat_msg *msg;
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
|
||||
|
||||
msg = relay_weechat_msg_new (id);
|
||||
if (msg)
|
||||
{
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_CHAR);
|
||||
relay_weechat_msg_add_char (msg, 'A');
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INT);
|
||||
relay_weechat_msg_add_int (msg, 123456789);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_LONG);
|
||||
relay_weechat_msg_add_long (msg, 123456789012345L);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING);
|
||||
relay_weechat_msg_add_string (msg, "a string");
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING);
|
||||
relay_weechat_msg_add_string (msg, "");
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING);
|
||||
relay_weechat_msg_add_string (msg, NULL);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_BUFFER);
|
||||
relay_weechat_msg_add_buffer (msg, "buffer", 6);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_BUFFER);
|
||||
relay_weechat_msg_add_buffer (msg, NULL, 0);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_POINTER);
|
||||
relay_weechat_msg_add_pointer (msg, &msg);
|
||||
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_TIME);
|
||||
relay_weechat_msg_add_time (msg, 1321993456);
|
||||
relay_weechat_msg_send (client, msg);
|
||||
relay_weechat_msg_free (msg);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_cb_quit: 'quit' command from client
|
||||
*/
|
||||
|
||||
RELAY_WEECHAT_PROTOCOL_CALLBACK(quit)
|
||||
{
|
||||
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
|
||||
|
||||
relay_client_set_status (client, RELAY_STATUS_DISCONNECTED);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_protocol_recv: read a command from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_protocol_recv (struct t_relay_client *client, char *data)
|
||||
{
|
||||
char *pos, *id, *command, **argv, **argv_eol;
|
||||
int i, argc, return_code;
|
||||
struct t_relay_weechat_protocol_cb protocol_cb[] =
|
||||
{ { "init", &relay_weechat_protocol_cb_init },
|
||||
{ "hdata", &relay_weechat_protocol_cb_hdata },
|
||||
{ "info", &relay_weechat_protocol_cb_info },
|
||||
{ "infolist", &relay_weechat_protocol_cb_infolist },
|
||||
{ "nicklist", &relay_weechat_protocol_cb_nicklist },
|
||||
{ "input", &relay_weechat_protocol_cb_input },
|
||||
{ "test", &relay_weechat_protocol_cb_test },
|
||||
{ "quit", &relay_weechat_protocol_cb_quit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
if (!data || !data[0] || RELAY_CLIENT_HAS_ENDED(client))
|
||||
return;
|
||||
|
||||
/* remove \r at the end of message */
|
||||
pos = strchr (data, '\r');
|
||||
if (pos)
|
||||
pos[0] = '\0';
|
||||
|
||||
/* display debug message */
|
||||
if (weechat_relay_plugin->debug >= 2)
|
||||
{
|
||||
weechat_printf (NULL, "%s: recv from client %d: \"%s\"",
|
||||
RELAY_PLUGIN_NAME, client->id, data);
|
||||
}
|
||||
|
||||
/* display message in raw buffer */
|
||||
relay_raw_print (client, RELAY_RAW_FLAG_RECV, "cmd: %s", data);
|
||||
|
||||
/* extract id */
|
||||
id = NULL;
|
||||
if (data[0] == '(')
|
||||
{
|
||||
pos = strchr (data, ')');
|
||||
if (pos)
|
||||
{
|
||||
id = weechat_strndup (data + 1, pos - data - 1);
|
||||
data = pos + 1;
|
||||
while (data[0] == ' ')
|
||||
{
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* search end of data */
|
||||
pos = strchr (data, ' ');
|
||||
if (pos)
|
||||
command = weechat_strndup (data, pos - data);
|
||||
else
|
||||
command = strdup (data);
|
||||
|
||||
if (!command)
|
||||
{
|
||||
if (id)
|
||||
free (id);
|
||||
return;
|
||||
}
|
||||
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
argv_eol = NULL;
|
||||
|
||||
if (pos)
|
||||
{
|
||||
while (pos[0] == ' ')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
argv = weechat_string_split (pos, " ", 0, 0, &argc);
|
||||
argv_eol = weechat_string_split (pos, " ", 1, 0, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; protocol_cb[i].name; i++)
|
||||
{
|
||||
if (strcmp (protocol_cb[i].name, command) == 0)
|
||||
{
|
||||
if ((strcmp (protocol_cb[i].name, "init") != 0)
|
||||
&& (!RELAY_WEECHAT_DATA(client, password_ok)))
|
||||
{
|
||||
/*
|
||||
* command is not "init" and password is not set?
|
||||
* then close connection!
|
||||
*/
|
||||
relay_client_set_status (client,
|
||||
RELAY_STATUS_DISCONNECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
return_code = (int) (protocol_cb[i].cmd_function) (client,
|
||||
id,
|
||||
protocol_cb[i].name,
|
||||
argc,
|
||||
argv,
|
||||
argv_eol);
|
||||
if ((weechat_relay_plugin->debug >= 1)
|
||||
&& (return_code == WEECHAT_RC_ERROR))
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: failed to execute command \"%s\" "
|
||||
"for client %d"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME, command, client->id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id)
|
||||
free (id);
|
||||
if (argv)
|
||||
weechat_string_free_split (argv);
|
||||
if (argv_eol)
|
||||
weechat_string_free_split (argv_eol);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_RELAY_WEECHAT_PROTOCOL_H
|
||||
#define __WEECHAT_RELAY_WEECHAT_PROTOCOL_H 1
|
||||
|
||||
#define RELAY_WEECHAT_PROTOCOL_CALLBACK(__command) \
|
||||
int \
|
||||
relay_weechat_protocol_cb_##__command ( \
|
||||
struct t_relay_client *client, \
|
||||
const char *id, \
|
||||
const char *command, \
|
||||
int argc, \
|
||||
char **argv, \
|
||||
char **argv_eol)
|
||||
|
||||
#define RELAY_WEECHAT_PROTOCOL_MIN_ARGS(__min_args) \
|
||||
(void) id; \
|
||||
(void) command; \
|
||||
(void) argv; \
|
||||
(void) argv_eol; \
|
||||
if ((weechat_relay_plugin->debug >= 1) && (argc < __min_args)) \
|
||||
{ \
|
||||
weechat_printf (NULL, \
|
||||
_("%s%s: too few arguments received from " \
|
||||
"client %d for command \"%s\" " \
|
||||
"(received: %d arguments, expected: at " \
|
||||
"least %d)"), \
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME, \
|
||||
client->id, command, argc, __min_args); \
|
||||
return WEECHAT_RC_ERROR; \
|
||||
}
|
||||
|
||||
typedef int (t_relay_weechat_cmd_func)(struct t_relay_client *client,
|
||||
const char *id, const char *command,
|
||||
int argc, char **argv, char **argv_eol);
|
||||
|
||||
struct t_relay_weechat_protocol_cb
|
||||
{
|
||||
char *name; /* relay command */
|
||||
t_relay_weechat_cmd_func *cmd_function; /* callback */
|
||||
};
|
||||
|
||||
extern void relay_weechat_protocol_recv (struct t_relay_client *client,
|
||||
char *data);
|
||||
|
||||
#endif /* __WEECHAT_RELAY_WEECHAT_PROTOCOL_H */
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* relay-weechat.c: WeeChat protocol for relay to client
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "../../weechat-plugin.h"
|
||||
#include "../relay.h"
|
||||
#include "relay-weechat.h"
|
||||
#include "relay-weechat-protocol.h"
|
||||
#include "../relay-client.h"
|
||||
#include "../relay-config.h"
|
||||
#include "../relay-raw.h"
|
||||
|
||||
|
||||
char *relay_weechat_compression_string[] = /* strings for compressions */
|
||||
{ "off", "gzip" };
|
||||
|
||||
char *relay_weechat_partial_message = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* relay_weechat_compression_search: search a compression by name
|
||||
*/
|
||||
|
||||
int
|
||||
relay_weechat_compression_search (const char *compression)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RELAY_WEECHAT_NUM_COMPRESSIONS; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (relay_weechat_compression_string[i], compression) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* compression not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_recv: read data from client
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_recv (struct t_relay_client *client, const char *data)
|
||||
{
|
||||
char *new_partial, *pos, *tmp, **commands;
|
||||
int num_commands, i;
|
||||
|
||||
if (relay_weechat_partial_message)
|
||||
{
|
||||
new_partial = realloc (relay_weechat_partial_message,
|
||||
strlen (relay_weechat_partial_message) +
|
||||
strlen (data) + 1);
|
||||
if (!new_partial)
|
||||
return;
|
||||
relay_weechat_partial_message = new_partial;
|
||||
strcat (relay_weechat_partial_message, data);
|
||||
}
|
||||
else
|
||||
relay_weechat_partial_message = strdup (data);
|
||||
|
||||
pos = strrchr (relay_weechat_partial_message, '\n');
|
||||
if (pos)
|
||||
{
|
||||
pos[0] = '\0';
|
||||
commands = weechat_string_split (relay_weechat_partial_message, "\n",
|
||||
0, 0, &num_commands);
|
||||
if (commands)
|
||||
{
|
||||
for (i = 0; i < num_commands; i++)
|
||||
{
|
||||
relay_weechat_protocol_recv (client, commands[i]);
|
||||
}
|
||||
weechat_string_free_split (commands);
|
||||
}
|
||||
if (pos[1])
|
||||
{
|
||||
tmp = strdup (pos + 1);
|
||||
free (relay_weechat_partial_message);
|
||||
relay_weechat_partial_message = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (relay_weechat_partial_message);
|
||||
relay_weechat_partial_message = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_close_connection: called when connection with client is closed
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_close_connection (struct t_relay_client *client)
|
||||
{
|
||||
(void) client;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_alloc: init relay data specific to weechat protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_alloc (struct t_relay_client *client)
|
||||
{
|
||||
struct t_relay_weechat_data *weechat_data;
|
||||
const char *password;
|
||||
|
||||
password = weechat_config_string (relay_config_network_password);
|
||||
|
||||
client->protocol_data = malloc (sizeof (*weechat_data));
|
||||
if (client->protocol_data)
|
||||
{
|
||||
RELAY_WEECHAT_DATA(client, password_ok) = (password && password[0]) ? 0 : 1;
|
||||
#ifdef HAVE_ZLIB
|
||||
RELAY_WEECHAT_DATA(client, compression) = 1;
|
||||
#else
|
||||
RELAY_WEECHAT_DATA(client, compression) = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_alloc_with_infolist: init relay data specific to weechat
|
||||
* protocol with an infolist
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist)
|
||||
{
|
||||
struct t_relay_weechat_data *weechat_data;
|
||||
|
||||
client->protocol_data = malloc (sizeof (*weechat_data));
|
||||
if (client->protocol_data)
|
||||
{
|
||||
RELAY_WEECHAT_DATA(client, password_ok) = weechat_infolist_integer (infolist, "password_ok");
|
||||
RELAY_WEECHAT_DATA(client, compression) = weechat_infolist_integer (infolist, "compression");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_free: free relay data specific to weechat protocol
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_free (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
free (client->protocol_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_add_to_infolist: add client weechat data in an infolist item
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
relay_weechat_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client)
|
||||
{
|
||||
if (!item || !client)
|
||||
return 0;
|
||||
|
||||
if (!weechat_infolist_new_var_integer (item, "password_ok", RELAY_WEECHAT_DATA(client, password_ok)))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (item, "compression", RELAY_WEECHAT_DATA(client, compression)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_weechat_print_log: print weechat client infos in log (usually for
|
||||
* crash dump)
|
||||
*/
|
||||
|
||||
void
|
||||
relay_weechat_print_log (struct t_relay_client *client)
|
||||
{
|
||||
if (client->protocol_data)
|
||||
{
|
||||
weechat_log_printf (" password_ok. . . . . . : %d", RELAY_WEECHAT_DATA(client, password_ok));
|
||||
weechat_log_printf (" compression. . . . . . : %d", RELAY_WEECHAT_DATA(client, compression));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2003-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/>.
|
||||
*/
|
||||
|
||||
#ifndef __WEECHAT_RELAY_WEECHAT_H
|
||||
#define __WEECHAT_RELAY_WEECHAT_H 1
|
||||
|
||||
struct t_relay_client;
|
||||
|
||||
#define RELAY_WEECHAT_DATA(client, var) \
|
||||
(((struct t_relay_weechat_data *)client->protocol_data)->var)
|
||||
|
||||
enum t_relay_weechat_compression
|
||||
{
|
||||
RELAY_WEECHAT_COMPRESSION_OFF = 0, /* no compression of binary objects */
|
||||
RELAY_WEECHAT_COMPRESSION_GZIP, /* gzip compression */
|
||||
/* number of compressions */
|
||||
RELAY_WEECHAT_NUM_COMPRESSIONS,
|
||||
};
|
||||
|
||||
struct t_relay_weechat_data
|
||||
{
|
||||
int password_ok; /* password received and ok? */
|
||||
int compression; /* compression type */
|
||||
};
|
||||
|
||||
extern int relay_weechat_compression_search (const char *compression);
|
||||
extern void relay_weechat_recv (struct t_relay_client *client,
|
||||
const char *data);
|
||||
extern void relay_weechat_close_connection (struct t_relay_client *client);
|
||||
extern void relay_weechat_alloc (struct t_relay_client *client);
|
||||
extern void relay_weechat_alloc_with_infolist (struct t_relay_client *client,
|
||||
struct t_infolist *infolist);
|
||||
extern void relay_weechat_free (struct t_relay_client *client);
|
||||
extern int relay_weechat_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_relay_client *client);
|
||||
extern void relay_weechat_print_log (struct t_relay_client *client);
|
||||
|
||||
#endif /* __WEECHAT_RELAY_WEECHAT_H */
|
||||
Reference in New Issue
Block a user