1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-26 21:06:38 +02:00

Add new plugin "relay", new function "string_format_size" in plugin API

This commit is contained in:
Sebastien Helleu
2008-12-10 17:08:56 +01:00
parent 09fdd1ace3
commit 20a1360bd8
55 changed files with 4019 additions and 447 deletions
+4
View File
@@ -66,6 +66,10 @@ IF(NOT DISABLE_NOTIFY)
ADD_SUBDIRECTORY( notify )
ENDIF(NOT DISABLE_NOTIFY)
IF(NOT DISABLE_RELAY)
ADD_SUBDIRECTORY( relay )
ENDIF(NOT DISABLE_RELAY)
IF(NOT DISABLE_SCRIPTS AND NOT DISABLE_PERL AND NOT DISABLE_PYTHON AND NOT DISABLE_RUBY AND NOT DISABLE_LUA AND NOT DISABLE_TCL)
ADD_SUBDIRECTORY( scripts )
ENDIF(NOT DISABLE_SCRIPTS AND NOT DISABLE_PERL AND NOT DISABLE_PYTHON AND NOT DISABLE_RUBY AND NOT DISABLE_LUA AND NOT DISABLE_TCL)
+5 -1
View File
@@ -58,6 +58,10 @@ if PLUGIN_NOTIFY
notify_dir = notify
endif
if PLUGIN_RELAY
relay_dir = relay
endif
if PLUGIN_PERL
script_dir = scripts
endif
@@ -87,5 +91,5 @@ xfer_dir = xfer
endif
SUBDIRS = . $(alias_dir) $(aspell_dir) $(charset_dir) $(demo_dir) $(fifo_dir) \
$(irc_dir) $(logger_dir) $(notify_dir) $(script_dir) \
$(irc_dir) $(logger_dir) $(notify_dir) $(relay_dir) $(script_dir) \
$(trigger_dir) $(xfer_dir)
+1 -3
View File
@@ -346,6 +346,7 @@ plugin_load (const char *filename)
new_plugin->string_build_with_exploded = &string_build_with_exploded;
new_plugin->string_split_command = &string_split_command;
new_plugin->string_free_splitted_command = &string_free_splitted_command;
new_plugin->string_format_size = &string_format_size;
new_plugin->utf8_has_8bits = &utf8_has_8bits;
new_plugin->utf8_is_valid = &utf8_is_valid;
@@ -829,9 +830,6 @@ plugin_reload_name (const char *name)
if (filename)
{
plugin_unload (ptr_plugin);
gui_chat_printf (NULL,
_("Plugin \"%s\" unloaded"),
name);
plugin_load (filename);
free (filename);
}
+30
View File
@@ -0,0 +1,30 @@
# Copyright (c) 2003-2008 FlashCode <flashcode@flashtux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
ADD_LIBRARY(relay MODULE
relay.c relay.h
relay-buffer.c relay-buffer.h
relay-client.c relay-client.h
relay-command.c relay-command.h
relay-config.c relay-config.h
relay-info.c relay-info.h
relay-network.c relay-network.h
relay-upgrade.c relay-upgrade.h)
SET_TARGET_PROPERTIES(relay PROPERTIES PREFIX "")
TARGET_LINK_LIBRARIES(relay)
INSTALL(TARGETS relay LIBRARY DESTINATION lib/${PROJECT_NAME}/plugins)
+41
View File
@@ -0,0 +1,41 @@
# Copyright (c) 2003-2008 FlashCode <flashcode@flashtux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\"
libdir = ${weechat_libdir}/plugins
lib_LTLIBRARIES = relay.la
relay_la_SOURCES = relay.c \
relay.h \
relay-buffer.c \
relay-buffer.h \
relay-client.c \
relay-client.h \
relay-command.c \
relay-command.h \
relay-config.c \
relay-config.h \
relay-info.c \
relay-info.h \
relay-network.c \
relay-network.h \
relay-upgrade.c \
relay-upgrade.h
relau_la_LDFLAGS = -module
relay_la_LIBADD = $(RELAY_LFLAGS)
+227
View File
@@ -0,0 +1,227 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-buffer.c: display clients list on relay buffer */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-client.h"
#include "relay-config.h"
struct t_gui_buffer *relay_buffer = NULL;
int relay_buffer_selected_line = 0;
/*
* relay_buffer_refresh: update a client in buffer and update hotlist for
* relay buffer
*/
void
relay_buffer_refresh (const char *hotlist)
{
struct t_relay_client *ptr_client, *client_selected;
char str_color[256], status[64], date_start[128];
char *str_recv, *str_sent;
int i, length, line;
struct tm *date_tmp;
if (relay_buffer)
{
weechat_buffer_clear (relay_buffer);
line = 0;
client_selected = relay_client_search_by_number (relay_buffer_selected_line);
if (client_selected)
{
weechat_printf_y (relay_buffer, 0,
"%s%s%s%s%s%s%s",
weechat_color("green"),
_("Actions (letter+enter):"),
weechat_color("lightgreen"),
/* disconnect */
(RELAY_CLIENT_HAS_ENDED(client_selected->status)) ?
"" : _(" [D] Disconnect"),
/* remove */
(RELAY_CLIENT_HAS_ENDED(client_selected->status)) ?
_(" [R] Remove") : "",
/* purge old */
_(" [P] Purge finished"),
/* quit */
_(" [Q] Close this buffer"));
}
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
snprintf (str_color, sizeof (str_color),
"%s,%s",
(line == relay_buffer_selected_line) ?
weechat_config_string (relay_config_color_text_selected) :
weechat_config_string (relay_config_color_text),
weechat_config_string (relay_config_color_text_bg));
snprintf (status, sizeof (status),
"%s", _(relay_client_status_string[ptr_client->status]));
length = weechat_utf8_strlen_screen (status);
if (length < 20)
{
for (i = 0; i < 20 - length; i++)
{
strcat (status, " ");
}
}
date_tmp = localtime (&(ptr_client->start_time));
strftime (date_start, sizeof (date_start),
"%a, %d %b %Y %H:%M:%S", date_tmp);
/* first line with status and start time */
weechat_printf_y (relay_buffer, (line * 2) + 2,
_("%s%s[%s%s%s%s] %s (started on: %s)"),
weechat_color(str_color),
(line == relay_buffer_selected_line) ?
"*** " : " ",
weechat_color(weechat_config_string (relay_config_color_status[ptr_client->status])),
status,
weechat_color ("reset"),
weechat_color (str_color),
ptr_client->address,
date_start);
/* second line with bytes recv/sent */
str_recv = weechat_string_format_size (ptr_client->bytes_recv);
str_sent = weechat_string_format_size (ptr_client->bytes_sent);
weechat_printf_y (relay_buffer, (line * 2) + 3,
_("%s%-26s received: %s, sent: %s"),
weechat_color(str_color),
" ",
(str_recv) ? str_recv : "?",
(str_sent) ? str_sent : "?");
if (str_recv)
free (str_recv);
if (str_sent)
free (str_sent);
line++;
}
if (hotlist)
weechat_buffer_set (relay_buffer, "hotlist", hotlist);
}
}
/*
* relay_buffer_input_cb: callback called when user send data to client list
* buffer
*/
int
relay_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
const char *input_data)
{
struct t_relay_client *client, *ptr_client, *next_client;
/* make C compiler happy */
(void) data;
client = relay_client_search_by_number (relay_buffer_selected_line);
/* disconnect client */
if (weechat_strcasecmp (input_data, "d") == 0)
{
if (client && !RELAY_CLIENT_HAS_ENDED(client->status))
{
relay_client_disconnect (client);
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
}
/* purge old clients */
else if (weechat_strcasecmp (input_data, "p") == 0)
{
ptr_client = relay_clients;
while (ptr_client)
{
next_client = ptr_client->next_client;
if (RELAY_CLIENT_HAS_ENDED(ptr_client->status))
relay_client_free (ptr_client);
ptr_client = next_client;
}
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
/* quit relay buffer (close it) */
else if (weechat_strcasecmp (input_data, "q") == 0)
{
weechat_buffer_close (buffer);
}
/* remove client */
else if (weechat_strcasecmp (input_data, "r") == 0)
{
if (client && RELAY_CLIENT_HAS_ENDED(client->status))
{
relay_client_free (client);
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
}
return WEECHAT_RC_OK;
}
/*
* relay_buffer_close_cb: callback called when relay buffer is closed
*/
int
relay_buffer_close_cb (void *data, struct t_gui_buffer *buffer)
{
/* make C compiler happy */
(void) data;
(void) buffer;
relay_buffer = NULL;
return WEECHAT_RC_OK;
}
/*
* relay_buffer_open: open relay buffer (to display list of clients)
*/
void
relay_buffer_open ()
{
if (!relay_buffer)
{
relay_buffer = weechat_buffer_new ("relay.list",
&relay_buffer_input_cb, NULL,
&relay_buffer_close_cb, NULL);
/* failed to create buffer ? then exit */
if (!relay_buffer)
return;
weechat_buffer_set (relay_buffer, "type", "free");
weechat_buffer_set (relay_buffer, "title", _("List of clients for relay"));
weechat_buffer_set (relay_buffer, "key_bind_meta2-A", "/relay up");
weechat_buffer_set (relay_buffer, "key_bind_meta2-B", "/relay down");
}
}
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_DISPLAY_H
#define __WEECHAT_RELAY_DISPLAY_H 1
extern struct t_gui_buffer *relay_buffer;
extern int relay_buffer_selected_line;
extern void relay_buffer_refresh (const char *hotlist);
extern int relay_buffer_input_cb (void *data, struct t_gui_buffer *buffer,
const char *input_data);
extern int relay_buffer_close_cb (void *data, struct t_gui_buffer *buffer);
extern void relay_buffer_open ();
#endif /* relay-buffer.h */
+506
View File
@@ -0,0 +1,506 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-client.c: client functions for relay plugin */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-client.h"
#include "relay-config.h"
#include "relay-buffer.h"
char *relay_client_status_string[] = /* strings for status */
{ N_("connecting"), N_("waiting auth"),
N_("connected"), N_("auth failed"), N_("disconnected")
};
struct t_relay_client *relay_clients = NULL;
struct t_relay_client *last_relay_client = NULL;
int relay_client_count = 0; /* number of clients */
/*
* relay_client_valid: check if a client pointer exists
* return 1 if client exists
* 0 if client is not found
*/
int
relay_client_valid (struct t_relay_client *client)
{
struct t_relay_client *ptr_client;
if (!client)
return 0;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
if (ptr_client == client)
return 1;
}
/* client not found */
return 0;
}
/*
* relay_client_search_by_number: search a client by number (first client is 0)
*/
struct t_relay_client *
relay_client_search_by_number (int number)
{
struct t_relay_client *ptr_client;
int i;
i = 0;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
if (i == number)
return ptr_client;
i++;
}
/* client not found */
return NULL;
}
/*
* relay_client_sendf: send formatted data to client
*/
int
relay_client_sendf (struct t_relay_client *client, const char *format, ...)
{
va_list args;
static char buffer[4096];
char str_length[8];
int length, num_sent;
if (!client)
return 0;
va_start (args, format);
vsnprintf (buffer + 7, sizeof (buffer) - 7 - 1, format, args);
va_end (args);
length = strlen (buffer + 7);
snprintf (str_length, sizeof (str_length), "%07d", length);
memcpy (buffer, str_length, 7);
num_sent = send (client->sock, buffer, length + 7, 0);
client->bytes_sent += length + 7;
if (num_sent < 0)
{
weechat_printf (NULL,
_("%s%s: error sending data to client %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
strerror (errno));
}
return num_sent;
}
/*
* relay_client_send_infolist: send infolist to client
*/
void
relay_client_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_sendf (client, "name %s", name);
while (weechat_infolist_next (infolist))
{
fields = weechat_infolist_fields (infolist);
if (fields)
{
argv = weechat_string_explode (fields, ",", 0, 0, &argc);
if (argv && (argc > 0))
{
for (i = 0; i < argc; i++)
{
switch (argv[i][0])
{
case 'i':
relay_client_sendf (client, "%s %c %d",
argv[i] + 2, argv[i][0],
weechat_infolist_integer (infolist,
argv[i] + 2));
break;
case 's':
relay_client_sendf (client, "%s %c %s",
argv[i] + 2, argv[i][0],
weechat_infolist_string (infolist,
argv[i] + 2));
break;
case 'p':
relay_client_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_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_sendf (client, "%s %c %ld",
argv[i] + 2, argv[i][0],
weechat_infolist_time (infolist, argv[i] + 2));
break;
}
}
}
if (argv)
weechat_string_free_exploded (argv);
}
}
}
/*
* relay_client_recv_cb: read data from a client
*/
int
relay_client_recv_cb (void *arg_client)
{
struct t_relay_client *client;
static char buffer[4096 + 2];
struct t_infolist *infolist;
int num_read;
client = (struct t_relay_client *)arg_client;
num_read = recv (client->sock, buffer, sizeof (buffer) - 1, 0);
if (num_read > 0)
{
client->bytes_recv += num_read;
buffer[num_read] = '\0';
if (buffer[num_read - 1] == '\n')
buffer[--num_read] = '\0';
if (buffer[num_read - 1] == '\r')
buffer[--num_read] = '\0';
if (weechat_relay_plugin->debug)
{
weechat_printf (NULL, "%s: data received from %s: \"%s\"",
RELAY_PLUGIN_NAME, client->address, buffer);
}
if (weechat_strcasecmp (buffer, "quit") == 0)
relay_client_set_status (client, RELAY_STATUS_DISCONNECTED);
else
{
infolist = weechat_infolist_get (buffer, NULL, NULL);
if (infolist)
{
relay_client_send_infolist (client, buffer, infolist);
weechat_infolist_free (infolist);
}
}
relay_buffer_refresh (NULL);
}
else
{
relay_client_set_status (client, RELAY_STATUS_DISCONNECTED);
}
return WEECHAT_RC_OK;
}
/*
* relay_client_new: create a new client
*/
struct t_relay_client *
relay_client_new (int sock, char *address)
{
struct t_relay_client *new_client;
new_client = malloc (sizeof (*new_client));
if (new_client)
{
new_client->sock = sock;
new_client->address = strdup ((address) ? address : "?");
new_client->status = RELAY_STATUS_CONNECTED;
new_client->start_time = time (NULL);
new_client->hook_fd = NULL;
new_client->hook_timer = NULL;
new_client->last_activity = new_client->start_time;
new_client->bytes_recv = 0;
new_client->bytes_sent = 0;
new_client->prev_client = NULL;
new_client->next_client = relay_clients;
if (relay_clients)
relay_clients->prev_client = new_client;
else
last_relay_client = new_client;
relay_clients = new_client;
weechat_printf (NULL,
_("%s: new client @ %s"),
RELAY_PLUGIN_NAME,
new_client->address);
new_client->hook_fd = weechat_hook_fd (new_client->sock,
1, 0, 0,
&relay_client_recv_cb,
new_client);
relay_client_count++;
if (!relay_buffer
&& weechat_config_boolean (relay_config_look_auto_open_buffer))
{
relay_buffer_open ();
}
relay_buffer_refresh (WEECHAT_HOTLIST_PRIVATE);
}
else
{
weechat_printf (NULL,
_("%s%s: not enough memory for new client"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
}
return new_client;
}
/*
* relay_client_set_status: set status for a client
*/
void
relay_client_set_status (struct t_relay_client *client,
enum t_relay_status status)
{
client->status = status;
if (RELAY_CLIENT_HAS_ENDED(client->status))
{
if (client->hook_fd)
{
weechat_unhook (client->hook_fd);
client->hook_fd = NULL;
}
if (client->hook_timer)
{
weechat_unhook (client->hook_timer);
client->hook_timer = NULL;
}
switch (client->status)
{
case RELAY_STATUS_AUTH_FAILED:
weechat_printf (NULL,
_("%s%s: authentication failed with client @ %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
client->address);
break;
case RELAY_STATUS_DISCONNECTED:
weechat_printf (NULL,
_("%s: disconnected from client @ %s"),
RELAY_PLUGIN_NAME, client->address);
break;
default:
break;
}
if (client->sock >= 0)
{
close (client->sock);
client->sock = -1;
}
}
relay_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
}
/*
* relay_client_free: remove a client
*/
void
relay_client_free (struct t_relay_client *client)
{
struct t_relay_client *new_relay_clients;
if (!client)
return;
/* remove client from list */
if (last_relay_client == client)
last_relay_client = client->prev_client;
if (client->prev_client)
{
(client->prev_client)->next_client = client->next_client;
new_relay_clients = relay_clients;
}
else
new_relay_clients = client->next_client;
if (client->next_client)
(client->next_client)->prev_client = client->prev_client;
/* free data */
if (client->address)
free (client->address);
if (client->hook_fd)
weechat_unhook (client->hook_fd);
if (client->hook_timer)
weechat_unhook (client->hook_timer);
free (client);
relay_clients = new_relay_clients;
relay_client_count--;
if (relay_buffer_selected_line >= relay_client_count)
{
relay_buffer_selected_line = (relay_client_count == 0) ?
0 : relay_client_count - 1;
}
}
/*
* relay_client_disconnect: disconnect one client
*/
void
relay_client_disconnect (struct t_relay_client *client)
{
if (client->sock >= 0)
{
relay_client_set_status (client, RELAY_STATUS_DISCONNECTED);
}
}
/*
* relay_client_disconnect_all: disconnect from all clients
*/
void
relay_client_disconnect_all ()
{
struct t_relay_client *ptr_client;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
relay_client_disconnect (ptr_client);
}
}
/*
* relay_client_add_to_infolist: add a client in an infolist
* return 1 if ok, 0 if error
*/
int
relay_client_add_to_infolist (struct t_infolist *infolist,
struct t_relay_client *client)
{
struct t_infolist_item *ptr_item;
char value[128];
if (!infolist || !client)
return 0;
ptr_item = weechat_infolist_new_item (infolist);
if (!ptr_item)
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "sock", client->sock))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "address", client->address))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "status", client->status))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "status_string", relay_client_status_string[client->status]))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "start_time", client->start_time))
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "hook_fd", client->hook_fd))
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "hook_timer", client->hook_timer))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "last_activity", client->last_activity))
return 0;
snprintf (value, sizeof (value), "%lu", client->bytes_recv);
if (!weechat_infolist_new_var_string (ptr_item, "bytes_recv", value))
return 0;
snprintf (value, sizeof (value), "%lu", client->bytes_sent);
if (!weechat_infolist_new_var_string (ptr_item, "bytes_sent", value))
return 0;
return 1;
}
/*
* relay_client_print_log: print client infos in log (usually for crash dump)
*/
void
relay_client_print_log ()
{
struct t_relay_client *ptr_client;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
weechat_log_printf ("");
weechat_log_printf ("[relay client (addr:0x%lx)]", ptr_client);
weechat_log_printf (" sock. . . . . . . . : %d", ptr_client->sock);
weechat_log_printf (" address . . . . . . : '%s'", ptr_client->address);
weechat_log_printf (" status. . . . . . . : %d (%s)",
ptr_client->status,
relay_client_status_string[ptr_client->status]);
weechat_log_printf (" start_time. . . . . : %ld", ptr_client->start_time);
weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_client->hook_fd);
weechat_log_printf (" hook_timer. . . . . : 0x%lx", ptr_client->hook_timer);
weechat_log_printf (" last_activity . . . : %ld", ptr_client->last_activity);
weechat_log_printf (" bytes_recv. . . . . : %lu", ptr_client->bytes_recv);
weechat_log_printf (" bytes_sent. . . . . : %lu", ptr_client->bytes_sent);
weechat_log_printf (" prev_client . . . . : 0x%lx", ptr_client->prev_client);
weechat_log_printf (" next_client . . . . : 0x%lx", ptr_client->next_client);
}
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_CLIENT_H
#define __WEECHAT_RELAY_CLIENT_H 1
/* relay status */
enum t_relay_status
{
RELAY_STATUS_CONNECTING = 0, /* connecting to client */
RELAY_STATUS_WAITING_AUTH, /* waiting AUTH from client */
RELAY_STATUS_CONNECTED, /* connected to client */
RELAY_STATUS_AUTH_FAILED, /* AUTH failed with client */
RELAY_STATUS_DISCONNECTED, /* disconnected from client */
/* number of relay status */
RELAY_NUM_STATUS,
};
/* macros for status */
#define RELAY_CLIENT_HAS_ENDED(status) ((status == RELAY_STATUS_AUTH_FAILED) || \
(status == RELAY_STATUS_DISCONNECTED))
/* relay client */
struct t_relay_client
{
int sock; /* socket for connection */
char *address; /* string with IP address */
enum t_relay_status status; /* status (connecting, active,..) */
time_t start_time; /* time of client connection */
struct t_hook *hook_fd; /* hook for socket or child pipe */
struct t_hook *hook_timer; /* timeout for recever accept */
time_t last_activity; /* time of last byte received/sent */
unsigned long bytes_recv; /* bytes received from client */
unsigned long bytes_sent; /* bytes sent to client */
struct t_relay_client *prev_client;/* link to previous client */
struct t_relay_client *next_client;/* link to next client */
};
extern char *relay_client_status_string[];
extern struct t_relay_client *relay_clients;
extern struct t_relay_client *last_relay_client;
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 struct t_relay_client *relay_client_new (int sock, char *address);
extern void relay_client_set_status (struct t_relay_client *client,
enum t_relay_status status);
extern void relay_client_free (struct t_relay_client *client);
extern void relay_client_disconnect (struct t_relay_client *client);
extern void relay_client_disconnect_all ();
extern int relay_client_add_to_infolist (struct t_infolist *infolist,
struct t_relay_client *client);
extern void relay_client_print_log ();
#endif /* relay-client.h */
+154
View File
@@ -0,0 +1,154 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-command.c: relay command */
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-buffer.h"
#include "relay-client.h"
#include "relay-config.h"
/*
* relay_command_client_list: list clients
*/
void
relay_command_client_list (int full)
{
struct t_relay_client *ptr_client;
int i;
char date_start[128], date_activity[128];
struct tm *date_tmp;
if (relay_clients)
{
weechat_printf (NULL, "");
weechat_printf (NULL, _("Clients for relay:"));
i = 1;
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
date_tmp = localtime (&(ptr_client->start_time));
strftime (date_start, sizeof (date_start),
"%a, %d %b %Y %H:%M:%S", date_tmp);
date_tmp = localtime (&(ptr_client->last_activity));
strftime (date_activity, sizeof (date_activity),
"%a, %d %b %Y %H:%M:%S", date_tmp);
if (full)
{
weechat_printf (NULL,
_("%3d. %s, started on: %s, last activity: %s, "
"bytes: %lu recv, %lu sent"),
i,
ptr_client->address,
date_start,
date_activity,
ptr_client->bytes_recv,
ptr_client->bytes_sent);
}
else
{
weechat_printf (NULL,
_("%3d. %s, started on: %s"),
i,
ptr_client->address);
}
i++;
}
}
else
weechat_printf (NULL, _("No client for relay"));
}
/*
* relay_command_relay: command /relay
*/
int
relay_command_relay (void *data, struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
/* make C compiler happy */
(void) data;
(void) buffer;
(void) argv_eol;
if ((argc > 1) && (weechat_strcasecmp (argv[1], "list") == 0))
{
relay_command_client_list (0);
return WEECHAT_RC_OK;
}
if ((argc > 1) && (weechat_strcasecmp (argv[1], "listfull") == 0))
{
relay_command_client_list (1);
return WEECHAT_RC_OK;
}
if (!relay_buffer)
relay_buffer_open ();
if (relay_buffer)
{
weechat_buffer_set (relay_buffer, "display", "1");
if (argc > 1)
{
if (strcmp (argv[1], "up") == 0)
{
if (relay_buffer_selected_line > 0)
relay_buffer_selected_line--;
}
else if (strcmp (argv[1], "down") == 0)
{
if (relay_buffer_selected_line < relay_client_count - 1)
relay_buffer_selected_line++;
}
}
}
relay_buffer_refresh (NULL);
return WEECHAT_RC_OK;
}
/*
* relay_command_init: add /relay command
*/
void
relay_command_init ()
{
weechat_hook_command ("relay",
N_("relay control"),
"[list | listfull]",
N_(" list: list relay clients\n"
"listfull: list relay clients (verbose)\n\n"
"Without argument, this command opens buffer "
"with list of relay clients."),
"list|listfull", &relay_command_relay, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_COMMAND_H
#define __WEECHAT_RELAY_COMMAND_H 1
extern void relay_command_init ();
#endif /* relay-command.h */
+211
View File
@@ -0,0 +1,211 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-config.c: relay configuration options */
#include <stdlib.h>
#include <limits.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-config.h"
#include "relay-client.h"
#include "relay-buffer.h"
struct t_config_file *relay_config_file = NULL;
/* relay config, look section */
struct t_config_option *relay_config_look_auto_open_buffer;
/* relay config, color section */
struct t_config_option *relay_config_color_text;
struct t_config_option *relay_config_color_text_bg;
struct t_config_option *relay_config_color_text_selected;
struct t_config_option *relay_config_color_status[RELAY_NUM_STATUS];
/* relay config, network section */
struct t_config_option *relay_config_network_listen_port_range;
/*
* relay_config_refresh_cb: callback called when user changes relay option that
* needs a refresh of relay list
*/
void
relay_config_refresh_cb (void *data, struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
if (relay_buffer)
relay_buffer_refresh (NULL);
}
/*
* relay_config_reload: reload relay configuration file
*/
int
relay_config_reload (void *data, struct t_config_file *config_file)
{
/* make C compiler happy */
(void) data;
return weechat_config_reload (config_file);
}
/*
* relay_config_init: init relay configuration file
* return: 1 if ok, 0 if error
*/
int
relay_config_init ()
{
struct t_config_section *ptr_section;
relay_config_file = weechat_config_new (RELAY_CONFIG_NAME,
&relay_config_reload, NULL);
if (!relay_config_file)
return 0;
ptr_section = weechat_config_new_section (relay_config_file, "look",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (relay_config_file);
return 0;
}
relay_config_look_auto_open_buffer = weechat_config_new_option (
relay_config_file, ptr_section,
"auto_open_buffer", "boolean",
N_("auto open relay buffer when a new client is connecting"),
NULL, 0, 0, "on", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
ptr_section = weechat_config_new_section (relay_config_file, "color",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (relay_config_file);
return 0;
}
relay_config_color_text = weechat_config_new_option (
relay_config_file, ptr_section,
"text", "color",
N_("text color"),
NULL, 0, 0, "default", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_text_bg = weechat_config_new_option (
relay_config_file, ptr_section,
"text_bg", "color",
N_("background color"),
NULL, 0, 0, "default", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_text_selected = weechat_config_new_option (
relay_config_file, ptr_section,
"text_selected", "color",
N_("text color of selected client line"),
NULL, 0, 0, "white", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_status[RELAY_STATUS_CONNECTING] = weechat_config_new_option (
relay_config_file, ptr_section,
"status_connecting", "color",
N_("text color for \"connecting\" status"),
NULL, 0, 0, "yellow", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_status[RELAY_STATUS_WAITING_AUTH] = weechat_config_new_option (
relay_config_file, ptr_section,
"status_waiting_auth", "color",
N_("text color for \"waiting authentication\" status"),
NULL, 0, 0, "brown", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_status[RELAY_STATUS_CONNECTED] = weechat_config_new_option (
relay_config_file, ptr_section,
"status_active", "color",
N_("text color for \"connected\" status"),
NULL, 0, 0, "lightblue", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_status[RELAY_STATUS_AUTH_FAILED] = weechat_config_new_option (
relay_config_file, ptr_section,
"status_auth_failed", "color",
N_("text color for \"authentication failed\" status"),
NULL, 0, 0, "lightred", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
relay_config_color_status[RELAY_STATUS_DISCONNECTED] = weechat_config_new_option (
relay_config_file, ptr_section,
"status_disconnected", "color",
N_("text color for \"disconnected\" status"),
NULL, 0, 0, "lightred", NULL,
NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
ptr_section = weechat_config_new_section (relay_config_file, "network",
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL);
if (!ptr_section)
{
weechat_config_free (relay_config_file);
return 0;
}
relay_config_network_listen_port_range = weechat_config_new_option (
relay_config_file, ptr_section,
"listen_port_range", "string",
N_("port number (or range of ports) that relay plugin listens on "
"(syntax: a single port, ie. 5000 or a port "
"range, ie. 5000-5015)"),
NULL, 0, 0, "22373-22400", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return 1;
}
/*
* relay_config_read: read relay configuration file
*/
int
relay_config_read ()
{
return weechat_config_read (relay_config_file);
}
/*
* relay_config_write: write relay configuration file
*/
int
relay_config_write ()
{
return weechat_config_write (relay_config_file);
}
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_CONFIG_H
#define __WEECHAT_RELAY_CONFIG_H 1
#define RELAY_CONFIG_NAME "relay"
extern struct t_config_file *relay_config;
extern struct t_config_option *relay_config_look_auto_open_buffer;
extern struct t_config_option *relay_config_color_text;
extern struct t_config_option *relay_config_color_text_bg;
extern struct t_config_option *relay_config_color_text_selected;
extern struct t_config_option *relay_config_color_status[];
extern struct t_config_option *relay_config_network_listen_port_range;
extern int relay_config_init ();
extern int relay_config_read ();
extern int relay_config_write ();
#endif /* relay-config.h */
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-info.c: info and infolist hooks for relay plugin */
#include <stdlib.h>
#include <stdio.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-client.h"
/*
* relay_info_get_infolist_cb: callback called when relay infolist is asked
*/
struct t_infolist *
relay_info_get_infolist_cb (void *data, const char *infolist_name,
void *pointer, const char *arguments)
{
struct t_infolist *ptr_infolist;
struct t_relay_client *ptr_client;
/* make C compiler happy */
(void) data;
(void) arguments;
if (!infolist_name || !infolist_name[0])
return NULL;
if (weechat_strcasecmp (infolist_name, "relay") == 0)
{
if (pointer && !relay_client_valid (pointer))
return NULL;
ptr_infolist = weechat_infolist_new ();
if (ptr_infolist)
{
if (pointer)
{
/* build list with only one relay */
if (!relay_client_add_to_infolist (ptr_infolist, pointer))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
return ptr_infolist;
}
else
{
/* build list with all relays */
for (ptr_client = relay_clients; ptr_client;
ptr_client = ptr_client->next_client)
{
if (!relay_client_add_to_infolist (ptr_infolist, ptr_client))
{
weechat_infolist_free (ptr_infolist);
return NULL;
}
}
return ptr_infolist;
}
}
}
return NULL;
}
/*
* relay_info_init: initialize info and infolist hooks for relay plugin
*/
void
relay_info_init ()
{
/* relay infolist hooks */
weechat_hook_infolist ("relay", N_("list of relay clients"),
&relay_info_get_infolist_cb, NULL);
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_INFO_H
#define __WEECHAT_RELAY_INFO_H 1
extern void relay_info_init ();
#endif /* relay-info.h */
+227
View File
@@ -0,0 +1,227 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-network.c: network functions for relay plugin */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-buffer.h"
#include "relay-client.h"
#include "relay-config.h"
int relay_network_sock = -1; /* socket used for listening and */
/* waiting for clients */
struct t_hook *relay_network_hook_fd = NULL;
int relay_network_listen_port = -1; /* listening port */
/*
* relay_network_close_socket: close socket
*/
void
relay_network_close_socket ()
{
if (relay_network_hook_fd)
{
weechat_unhook (relay_network_hook_fd);
relay_network_hook_fd = NULL;
}
if (relay_network_sock >= 0)
{
close (relay_network_sock);
relay_network_sock = -1;
}
}
/*
* relay_network_sock_cb: read data from a client which is connecting on socket
*/
int
relay_network_sock_cb (void *data)
{
struct sockaddr_in client_addr;
unsigned int client_length;
int client_fd;
char ipv4_address[INET_ADDRSTRLEN + 1], *ptr_address;
/* make C compiler happy */
(void) data;
client_length = sizeof (client_addr);
memset (&client_addr, 0, client_length);
client_fd = accept (relay_network_sock, (struct sockaddr *) &client_addr,
&client_length);
if (client_fd < 0)
{
weechat_printf (NULL,
_("%s%s: cannot accept client"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
return WEECHAT_RC_OK;
}
ptr_address = NULL;
if (inet_ntop (AF_INET,
&(client_addr.sin_addr),
ipv4_address,
INET_ADDRSTRLEN))
{
ptr_address = ipv4_address;
}
relay_client_new (client_fd, ptr_address);
return WEECHAT_RC_OK;
}
/*
* relay_network_init: init socket and listen on port
* return 1 if ok, 0 if error
*/
int
relay_network_init ()
{
int set, args, port, port_start, port_end;
struct sockaddr_in server_addr;
const char *port_range;
relay_network_close_socket ();
port_range = weechat_config_string (relay_config_network_listen_port_range);
if (!port_range || !port_range[0])
{
weechat_printf (NULL,
_("%s%s: option \"listen_port_range\" is not defined"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
return 0;
}
relay_network_sock = socket (AF_INET, SOCK_STREAM, 0);
if (relay_network_sock < 0)
{
weechat_printf (NULL,
_("%s%s: cannot create socket"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
return 0;
}
set = 1;
if (setsockopt (relay_network_sock, SOL_SOCKET, SO_REUSEADDR,
(void *) &set, sizeof (set)) < 0)
{
weechat_printf (NULL,
_("%s%s: cannot set socket option "
"\"SO_REUSEADDR\""),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
close (relay_network_sock);
relay_network_sock = -1;
return 0;
}
set = 1;
if (setsockopt (relay_network_sock, SOL_SOCKET, SO_KEEPALIVE,
(void *) &set, sizeof (set)) < 0)
{
weechat_printf (NULL,
_("%s%s: cannot set socket option "
"\"SO_KEEPALIVE\""),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
close (relay_network_sock);
relay_network_sock = -1;
return 0;
}
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
port = -1;
/* find a free port in the specified range */
args = sscanf (weechat_config_string (relay_config_network_listen_port_range),
"%d-%d", &port_start, &port_end);
if (args > 0)
{
port = port_start;
if (args == 1)
port_end = port_start;
/* loop through the entire allowed port range */
while (port <= port_end)
{
/* attempt to bind to the free port */
server_addr.sin_port = htons (port);
if (bind (relay_network_sock, (struct sockaddr *) &server_addr,
sizeof (server_addr)) == 0)
break;
port++;
}
if (port > port_end)
port = -1;
}
if (port < 0)
{
weechat_printf (NULL,
_("%s%s: cannot find available port for listening"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
close (relay_network_sock);
relay_network_sock = -1;
return 0;
}
relay_network_listen_port = port;
listen (relay_network_sock, 5);
weechat_printf (NULL,
_("%s: listening on port %d"),
RELAY_PLUGIN_NAME, relay_network_listen_port);
relay_network_hook_fd = weechat_hook_fd (relay_network_sock,
1, 0, 0,
&relay_network_sock_cb,
NULL);
return 1;
}
/*
* relay_network_end: close main socket
*/
void
relay_network_end ()
{
relay_network_close_socket ();
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_NETWORK_H
#define __WEECHAT_RELAY_NETWORK_H 1
extern int relay_network_init ();
extern void relay_network_end ();
#endif /* relay-network.h */
+121
View File
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay-upgrade.c: save/restore relay plugin data */
#include <stdlib.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-upgrade.h"
#include "relay-buffer.h"
/*
* relay_upgrade_save_clients: save clients info to upgrade file
*/
int
relay_upgrade_save_clients (struct t_upgrade_file *upgrade_file)
{
/* TODO: save relay data */
(void) upgrade_file;
return 1;
}
/*
* relay_upgrade_save: save upgrade file
* return 1 if ok, 0 if error
*/
int
relay_upgrade_save ()
{
int rc;
struct t_upgrade_file *upgrade_file;
upgrade_file = weechat_upgrade_create (RELAY_UPGRADE_FILENAME, 1);
if (!upgrade_file)
return 0;
rc = relay_upgrade_save_clients (upgrade_file);
weechat_upgrade_close (upgrade_file);
return rc;
}
/*
* relay_upgrade_set_buffer_callbacks: restore buffers callbacks (input and
* close) for buffers created by relay plugin
*/
void
relay_upgrade_set_buffer_callbacks ()
{
struct t_infolist *infolist;
struct t_gui_buffer *ptr_buffer;
infolist = weechat_infolist_get ("buffer", NULL, NULL);
if (infolist)
{
while (weechat_infolist_next (infolist))
{
if (weechat_infolist_pointer (infolist, "plugin") == weechat_relay_plugin)
{
ptr_buffer = weechat_infolist_pointer (infolist, "pointer");
weechat_buffer_set_pointer (ptr_buffer, "close_callback", &relay_buffer_close_cb);
weechat_buffer_set_pointer (ptr_buffer, "input_callback", &relay_buffer_input_cb);
}
}
}
}
/*
* relay_upgrade_read_cb: read callback for relay upgrade file
*/
int
relay_upgrade_read_cb (int object_id,
struct t_infolist *infolist)
{
/* TODO: write relay read cb */
(void) object_id;
(void) infolist;
return WEECHAT_RC_OK;
}
/*
* relay_upgrade_load: load upgrade file
* return 1 if ok, 0 if error
*/
int
relay_upgrade_load ()
{
int rc;
struct t_upgrade_file *upgrade_file;
relay_upgrade_set_buffer_callbacks ();
upgrade_file = weechat_upgrade_create (RELAY_UPGRADE_FILENAME, 0);
rc = weechat_upgrade_read (upgrade_file, &relay_upgrade_read_cb);
return rc;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_UPGRADE_H
#define __WEECHAT_RELAY_UPGRADE_H 1
#define RELAY_UPGRADE_FILENAME "relay"
/* For developers: please add new values ONLY AT THE END of enums */
enum t_relay_upgrade_type
{
RELAY_UPGRADE_TYPE_RELAY = 0,
};
extern int relay_upgrade_save ();
extern int relay_upgrade_load ();
#endif /* relay-upgrade.h */
+144
View File
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* relay.c: network communication between WeeChat and remote application */
#include <stdlib.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-client.h"
#include "relay-command.h"
#include "relay-config.h"
#include "relay-info.h"
#include "relay-network.h"
#include "relay-upgrade.h"
WEECHAT_PLUGIN_NAME(RELAY_PLUGIN_NAME);
WEECHAT_PLUGIN_DESCRIPTION("Network communication between WeeChat and "
"remote application");
WEECHAT_PLUGIN_AUTHOR("FlashCode <flashcode@flashtux.org>");
WEECHAT_PLUGIN_VERSION(WEECHAT_VERSION);
WEECHAT_PLUGIN_WEECHAT_VERSION(WEECHAT_VERSION);
WEECHAT_PLUGIN_LICENSE("GPL3");
struct t_weechat_plugin *weechat_relay_plugin = NULL;
int relay_signal_upgrade_received = 0; /* signal "upgrade" received ? */
/*
* relay_signal_upgrade_cb: callback for "upgrade" signal
*/
int
relay_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
void *signal_data)
{
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
(void) signal_data;
relay_signal_upgrade_received = 1;
return WEECHAT_RC_OK;
}
/*
* relay_debug_dump_cb: callback for "debug_dump" signal
*/
int
relay_debug_dump_cb (void *data, const char *signal, const char *type_data,
void *signal_data)
{
/* make C compiler happy */
(void) data;
(void) signal;
(void) type_data;
(void) signal_data;
weechat_log_printf ("");
weechat_log_printf ("***** \"%s\" plugin dump *****",
weechat_plugin->name);
relay_client_print_log ();
weechat_log_printf ("");
weechat_log_printf ("***** End of \"%s\" plugin dump *****",
weechat_plugin->name);
return WEECHAT_RC_OK;
}
/*
* weechat_plugin_init: initialize relay plugin
*/
int
weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
{
/* make C compiler happy */
(void) argc;
(void) argv;
weechat_plugin = plugin;
if (!relay_config_init ())
return WEECHAT_RC_ERROR;
if (relay_config_read () < 0)
return WEECHAT_RC_ERROR;
relay_command_init ();
weechat_hook_signal ("upgrade", &relay_signal_upgrade_cb, NULL);
weechat_hook_signal ("debug_dump", &relay_debug_dump_cb, NULL);
relay_info_init ();
relay_network_init ();
return WEECHAT_RC_OK;
}
/*
* weechat_plugin_end: end relay plugin
*/
int
weechat_plugin_end (struct t_weechat_plugin *plugin)
{
/* make C compiler happy */
(void) plugin;
relay_config_write ();
relay_network_end ();
if (relay_signal_upgrade_received)
relay_upgrade_save ();
else
relay_client_disconnect_all ();
return WEECHAT_RC_OK;
}
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2003-2008 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_RELAY_H
#define __WEECHAT_RELAY_H 1
#define weechat_plugin weechat_relay_plugin
#define RELAY_PLUGIN_NAME "relay"
extern struct t_weechat_plugin *weechat_relay_plugin;
#endif /* relay.h */
+3
View File
@@ -155,6 +155,7 @@ struct t_weechat_plugin
const char *separator);
char **(*string_split_command) (const char *command, char separator);
void (*string_free_splitted_command) (char **splitted_command);
char *(*string_format_size) (unsigned long size);
/* UTF-8 strings */
int (*utf8_has_8bits) (const char *string);
@@ -651,6 +652,8 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
weechat_plugin->string_split_command(__command, __separator)
#define weechat_string_free_splitted_command(__splitted_command) \
weechat_plugin->string_free_splitted_command(__splitted_command)
#define weechat_string_format_size(__size) \
weechat_plugin->string_format_size(__size)
/* UTF-8 strings */
#define weechat_utf8_has_8bits(__string) \
+20 -48
View File
@@ -42,14 +42,10 @@ void
xfer_buffer_refresh (const char *hotlist)
{
struct t_xfer *ptr_xfer, *xfer_selected;
char str_color[256], suffix[32], status[64], date[128], *progress_bar;
char format[128], format_per_sec[128], bytes_per_sec[256], eta[128];
int i, length, line, progress_bar_size, num_bars, num_unit;
int num_unit_per_sec;
char str_color[256], suffix[32], status[64], date[128], eta[128];
char *progress_bar, *str_pos, *str_total, *str_bytes_per_sec;
int i, length, line, progress_bar_size, num_bars;
unsigned long pct_complete;
char *unit_name[] = { N_("bytes"), N_("KB"), N_("MB"), N_("GB") };
char *unit_format[] = { "%.0f", "%.1f", "%.02f", "%.02f" };
float unit_divide[] = { 1, 1024, 1024*1024, 1024*1024*1024 };
struct tm *date_tmp;
if (xfer_buffer)
@@ -77,7 +73,7 @@ xfer_buffer_refresh (const char *hotlist)
/* purge old */
_(" [P] Purge finished"),
/* quit */
_(" [Q] Close xfer list"));
_(" [Q] Close this buffer"));
}
for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
{
@@ -170,14 +166,6 @@ xfer_buffer_refresh (const char *hotlist)
}
/* computes percentage */
if (ptr_xfer->size < 1024*10)
num_unit = 0;
else if (ptr_xfer->size < 1024*1024)
num_unit = 1;
else if (ptr_xfer->size < 1024*1024*1024)
num_unit = 2;
else
num_unit = 3;
if (ptr_xfer->size == 0)
{
if (ptr_xfer->status == XFER_STATUS_DONE)
@@ -188,28 +176,10 @@ xfer_buffer_refresh (const char *hotlist)
else
pct_complete = (unsigned long)(((float)(ptr_xfer->pos)/(float)(ptr_xfer->size)) * 100);
snprintf (format, sizeof (format),
"%%s%%s%%s %%s%%s%%s%%s%%3lu%%%% %s %%s / %s %%s (%%s%%s)",
unit_format[num_unit],
unit_format[num_unit]);
/* bytes per second */
bytes_per_sec[0] = '\0';
if (ptr_xfer->bytes_per_sec < 1024*10)
num_unit_per_sec = 0;
else if (ptr_xfer->bytes_per_sec < 1024*1024)
num_unit_per_sec = 1;
else if (ptr_xfer->bytes_per_sec < 1024*1024*1024)
num_unit_per_sec = 2;
else
num_unit_per_sec = 3;
snprintf (format_per_sec, sizeof (format_per_sec),
"%s %%s/s",
unit_format[num_unit_per_sec]);
snprintf (bytes_per_sec, sizeof (bytes_per_sec),
format_per_sec,
((float)ptr_xfer->bytes_per_sec) / ((float)(unit_divide[num_unit_per_sec])),
_(unit_name[num_unit_per_sec]));
/* position, total and bytes per second */
str_pos = weechat_string_format_size (ptr_xfer->pos);
str_total = weechat_string_format_size (ptr_xfer->size);
str_bytes_per_sec = weechat_string_format_size (ptr_xfer->bytes_per_sec);
/* ETA */
eta[0] = '\0';
@@ -225,23 +195,25 @@ xfer_buffer_refresh (const char *hotlist)
/* display second line for file with status, progress bar and estimated time */
weechat_printf_y (xfer_buffer, (line * 2) + 3,
format,
"%s%s%s %s%s%s%s%3lu%% %s / %s (%s%s/s)",
weechat_color(str_color),
(line == xfer_buffer_selected_line) ?
"*** " : " ",
(XFER_IS_SEND(ptr_xfer->type)) ?
"<<--" : "-->>",
(line == xfer_buffer_selected_line) ? "*** " : " ",
(XFER_IS_SEND(ptr_xfer->type)) ? "<<--" : "-->>",
weechat_color(weechat_config_string (xfer_config_color_status[ptr_xfer->status])),
status,
weechat_color (str_color),
(progress_bar) ? progress_bar : "",
pct_complete,
((float)(ptr_xfer->pos)) / unit_divide[num_unit],
_(unit_name[num_unit]),
((float)(ptr_xfer->size)) / unit_divide[num_unit],
_(unit_name[num_unit]),
(str_pos) ? str_pos : "?",
(str_total) ? str_total : "?",
eta,
bytes_per_sec);
str_bytes_per_sec);
if (str_pos)
free (str_pos);
if (str_total)
free (str_total);
if (str_bytes_per_sec)
free (str_bytes_per_sec);
}
line++;
}
+6 -3
View File
@@ -189,7 +189,7 @@ xfer_command_xfer (void *data, struct t_gui_buffer *buffer, int argc,
}
/*
* xfer_command: xfer command
* xfer_command_init: add /xfer command
*/
void
@@ -197,7 +197,10 @@ xfer_command_init ()
{
weechat_hook_command ("xfer",
N_("xfer control"),
"",
N_("Open buffer with xfer list"),
"[list | listfull]",
N_(" list: list xfer\n"
"listfull: list xfer (verbose)\n\n"
"Without argument, this command opens buffer "
"with xfer list."),
"list|listfull", &xfer_command_xfer, NULL);
}
+2 -2
View File
@@ -213,7 +213,7 @@ xfer_network_send_file_fork (struct t_xfer *xfer)
xfer->child_pid = pid;
xfer->hook_fd = weechat_hook_fd (xfer->child_read,
1, 0, 0,
xfer_network_child_read_cb,
&xfer_network_child_read_cb,
xfer);
}
@@ -268,7 +268,7 @@ xfer_network_recv_file_fork (struct t_xfer *xfer)
xfer->child_pid = pid;
xfer->hook_fd = weechat_hook_fd (xfer->child_read,
1, 0, 0,
xfer_network_child_read_cb,
&xfer_network_child_read_cb,
xfer);
}
+8 -2
View File
@@ -1277,7 +1277,7 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
}
/*
* xfer_print_log: print DCC infos in log (usually for crash dump)
* xfer_print_log: print xfer infos in log (usually for crash dump)
*/
void
@@ -1294,6 +1294,9 @@ xfer_print_log ()
weechat_log_printf (" type. . . . . . . . : %d (%s)",
ptr_xfer->type,
xfer_type_string[ptr_xfer->type]);
weechat_log_printf (" protocol. . . . . . : %d (%s)",
ptr_xfer->protocol,
xfer_protocol_string[ptr_xfer->protocol]);
weechat_log_printf (" remote_nick . . . . : '%s'", ptr_xfer->remote_nick);
weechat_log_printf (" local_nick. . . . . : '%s'", ptr_xfer->local_nick);
weechat_log_printf (" filename. . . . . . : '%s'", ptr_xfer->filename);
@@ -1314,6 +1317,8 @@ xfer_print_log ()
weechat_log_printf (" child_pid . . . . . : %d", ptr_xfer->child_pid);
weechat_log_printf (" child_read. . . . . : %d", ptr_xfer->child_read);
weechat_log_printf (" child_write . . . . : %d", ptr_xfer->child_write);
weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_xfer->hook_fd);
weechat_log_printf (" hook_timer. . . . . : 0x%lx", ptr_xfer->hook_timer);
weechat_log_printf (" unterminated_message: '%s'", ptr_xfer->unterminated_message);
weechat_log_printf (" file. . . . . . . . : %d", ptr_xfer->file);
weechat_log_printf (" local_filename. . . : '%s'", ptr_xfer->local_filename);
@@ -1380,7 +1385,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
xfer_create_directories ();
xfer_command_init ();
weechat_hook_signal ("upgrade", &xfer_signal_upgrade_cb, NULL);
weechat_hook_signal ("xfer_add", &xfer_add_cb, NULL);
weechat_hook_signal ("xfer_start_resume", &xfer_start_resume_cb, NULL);
weechat_hook_signal ("xfer_accept_resume", &xfer_accept_resume_cb, NULL);