1
0
mirror of https://github.com/irssi/irssi.git synced 2024-06-23 06:35:36 +00:00

Added DCC SERVER support by Mark Trumbull

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3127 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2003-10-01 16:02:43 +00:00 committed by cras
parent 579c1c2efd
commit 65463924d2
12 changed files with 506 additions and 21 deletions

View File

@ -22,6 +22,10 @@ files.
queues them. File names may contain shell expansion characters: * ? [] ~ queues them. File names may contain shell expansion characters: * ? [] ~
(~ expansion may not be supported on all platforms). Files with spaces (~ expansion may not be supported on all platforms). Files with spaces
in their names need to be quoted (eg. "file name"). in their names need to be quoted (eg. "file name").
/DCC SERVER [<+|-scf> <port>]
- Starts a DCC SERVER on the specified port. The remote can connect to this
server and initiate chat, send and fserve requests. You can specify + or -
using any combination of the flags 's' (Send), 'c' (Chat), or 'f' (Fserver).
/DCC CLOSE <type> <nick> [<file>] /DCC CLOSE <type> <nick> [<file>]
- Closes a DCC-connection. Type can be either SEND, GET or CHAT. - Closes a DCC-connection. Type can be either SEND, GET or CHAT.

View File

@ -16,7 +16,8 @@ libfe_irc_dcc_a_SOURCES = \
fe-dcc-chat-messages.c \ fe-dcc-chat-messages.c \
fe-dcc-get.c \ fe-dcc-get.c \
fe-dcc-send.c \ fe-dcc-send.c \
module-formats.c module-formats.c \
fe-dcc-server.c
noinst_HEADERS = \ noinst_HEADERS = \
module.h \ module.h \

View File

@ -42,6 +42,9 @@ void fe_dcc_get_deinit(void);
void fe_dcc_send_init(void); void fe_dcc_send_init(void);
void fe_dcc_send_deinit(void); void fe_dcc_send_deinit(void);
void fe_dcc_server_init(void);
void fe_dcc_server_deinit(void);
char *dcc_get_size_str(uoff_t size) char *dcc_get_size_str(uoff_t size)
{ {
if (size < 1024) if (size < 1024)
@ -155,6 +158,7 @@ void fe_irc_dcc_init(void)
fe_dcc_chat_init(); fe_dcc_chat_init();
fe_dcc_get_init(); fe_dcc_get_init();
fe_dcc_send_init(); fe_dcc_send_init();
fe_dcc_server_init();
signal_add("dcc request", (SIGNAL_FUNC) dcc_request); signal_add("dcc request", (SIGNAL_FUNC) dcc_request);
signal_add("dcc rejected", (SIGNAL_FUNC) dcc_rejected); signal_add("dcc rejected", (SIGNAL_FUNC) dcc_rejected);
@ -173,6 +177,7 @@ void fe_irc_dcc_deinit(void)
fe_dcc_chat_deinit(); fe_dcc_chat_deinit();
fe_dcc_get_deinit(); fe_dcc_get_deinit();
fe_dcc_send_deinit(); fe_dcc_send_deinit();
fe_dcc_server_deinit();
theme_unregister(); theme_unregister();

View File

@ -71,6 +71,9 @@ FORMAT_REC fecommon_irc_dcc_formats[] = {
{ "dcc_list_line_file", "{dcc $0 $1: %|$2 of $3 ($4%%) - $5kB/s - ETA $7 - $6}", 8, { 0, 0, 0, 0, 1, 3, 0, 0 } }, { "dcc_list_line_file", "{dcc $0 $1: %|$2 of $3 ($4%%) - $5kB/s - ETA $7 - $6}", 8, { 0, 0, 0, 0, 1, 3, 0, 0 } },
{ "dcc_list_line_queued_send", "{dcc - $0 $2 (queued)}", 3, { 0, 0, 0 } }, { "dcc_list_line_queued_send", "{dcc - $0 $2 (queued)}", 3, { 0, 0, 0 } },
{ "dcc_list_footer", "", 0 }, { "dcc_list_footer", "", 0 },
{ "dcc_list_line_server", "{dcc $0: Port($1) - Send($2) - Chat($3) - Fserve($4)}", 5, { 0, 1, 0, 0, 0 } },
{ "dcc_server_started", "{dcc DCC SERVER started on port {hilight $0}}", 1, { 1 } },
{ "dcc_server_closed", "{dcc DCC SERVER on port {hilight $0} closed}", 1, { 1 } },
{ NULL, NULL, 0 } { NULL, NULL, 0 }
}; };

View File

@ -48,7 +48,10 @@ enum {
IRCTXT_DCC_LIST_LINE_CHAT, IRCTXT_DCC_LIST_LINE_CHAT,
IRCTXT_DCC_LIST_LINE_FILE, IRCTXT_DCC_LIST_LINE_FILE,
IRCTXT_DCC_LIST_LINE_QUEUED_SEND, IRCTXT_DCC_LIST_LINE_QUEUED_SEND,
IRCTXT_DCC_LIST_FOOTER IRCTXT_DCC_LIST_FOOTER,
IRCTXT_DCC_LIST_LINE_SERVER,
IRCTXT_DCC_SERVER_STARTED,
IRCTXT_DCC_SERVER_CLOSED
}; };
extern FORMAT_REC fecommon_irc_dcc_formats[]; extern FORMAT_REC fecommon_irc_dcc_formats[];

View File

@ -13,7 +13,8 @@ libirc_dcc_a_SOURCES = \
dcc-send.c \ dcc-send.c \
dcc-resume.c \ dcc-resume.c \
dcc-autoget.c \ dcc-autoget.c \
dcc-queue.c dcc-queue.c \
dcc-server.c
noinst_HEADERS = \ noinst_HEADERS = \
dcc-rec.h \ dcc-rec.h \
@ -24,4 +25,5 @@ noinst_HEADERS = \
dcc-get.h \ dcc-get.h \
dcc-send.h \ dcc-send.h \
dcc-queue.h \ dcc-queue.h \
module.h module.h \
dcc-server.h

View File

@ -55,7 +55,7 @@ static char *dcc_chat_get_new_id(const char *nick)
} }
} }
static CHAT_DCC_REC *dcc_chat_create(IRC_SERVER_REC *server, CHAT_DCC_REC *dcc_chat_create(IRC_SERVER_REC *server,
CHAT_DCC_REC *chat, CHAT_DCC_REC *chat,
const char *nick, const char *arg) const char *nick, const char *arg)
{ {
@ -285,7 +285,7 @@ static void cmd_ctcp(const char *data, SERVER_REC *server)
} }
/* input function: DCC CHAT received some data.. */ /* input function: DCC CHAT received some data.. */
static void dcc_chat_input(CHAT_DCC_REC *dcc) void dcc_chat_input(CHAT_DCC_REC *dcc)
{ {
char tmpbuf[512], *str; char tmpbuf[512], *str;
int recvlen, ret; int recvlen, ret;

View File

@ -31,7 +31,7 @@
static int dcc_file_create_mode; static int dcc_file_create_mode;
static GET_DCC_REC *dcc_get_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat, GET_DCC_REC *dcc_get_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat,
const char *nick, const char *arg) const char *nick, const char *arg)
{ {
GET_DCC_REC *dcc; GET_DCC_REC *dcc;
@ -172,21 +172,23 @@ static void sig_dccget_receive(GET_DCC_REC *dcc)
} }
/* callback: net_connect() finished for DCC GET */ /* callback: net_connect() finished for DCC GET */
static void sig_dccget_connected(GET_DCC_REC *dcc) void sig_dccget_connected(GET_DCC_REC *dcc)
{ {
struct stat statbuf; struct stat statbuf;
char *fname, *tempfname; char *fname, *tempfname, *str;
int ret, ret_errno, temphandle, old_umask; int ret, ret_errno, temphandle, old_umask;
if (net_geterror(dcc->handle) != 0) { if (!dcc->from_dccserver) {
/* error connecting */ if (net_geterror(dcc->handle) != 0) {
signal_emit("dcc error connect", 1, dcc); /* error connecting */
dcc_destroy(DCC(dcc)); signal_emit("dcc error connect", 1, dcc);
return; dcc_destroy(DCC(dcc));
} return;
}
g_source_remove(dcc->tagconn); g_source_remove(dcc->tagconn);
dcc->tagconn = -1; dcc->tagconn = -1;
}
g_free_not_null(dcc->file); g_free_not_null(dcc->file);
dcc->file = dcc_get_download_path(dcc->arg); dcc->file = dcc_get_download_path(dcc->arg);
@ -253,6 +255,12 @@ static void sig_dccget_connected(GET_DCC_REC *dcc)
dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ,
(GInputFunction) sig_dccget_receive, dcc); (GInputFunction) sig_dccget_receive, dcc);
signal_emit("dcc connected", 1, dcc); signal_emit("dcc connected", 1, dcc);
if (dcc->from_dccserver) {
str = g_strdup_printf("121 %s %d\n",
dcc->server ? dcc->server->nick : "??", 0);
net_transmit(dcc->handle, str, strlen(str));
}
} }
void dcc_get_connect(GET_DCC_REC *dcc) void dcc_get_connect(GET_DCC_REC *dcc)
@ -262,7 +270,13 @@ void dcc_get_connect(GET_DCC_REC *dcc)
DCC_GET_RENAME : DCC_GET_OVERWRITE; DCC_GET_RENAME : DCC_GET_OVERWRITE;
} }
if (dcc->from_dccserver) {
sig_dccget_connected(dcc);
return;
}
dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port); dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port);
if (dcc->handle != NULL) { if (dcc->handle != NULL) {
dcc->tagconn = dcc->tagconn =
g_input_add(dcc->handle, g_input_add(dcc->handle,
@ -408,8 +422,8 @@ void cmd_dcc_receive(const char *data, DCC_GET_FUNC accept_func)
GET_DCC_REC *dcc = tmp->data; GET_DCC_REC *dcc = tmp->data;
next = tmp->next; next = tmp->next;
if (IS_DCC_GET(dcc) && dcc_is_waiting_user(dcc) && if (IS_DCC_GET(dcc) && g_strcasecmp(dcc->nick, nick) == 0 &&
g_strcasecmp(dcc->nick, nick) == 0 && (dcc_is_waiting_user(dcc) || dcc->from_dccserver) &&
(*fname == '\0' || strcmp(dcc->arg, fname) == 0)) { (*fname == '\0' || strcmp(dcc->arg, fname) == 0)) {
found = TRUE; found = TRUE;
accept_func(dcc); accept_func(dcc);

View File

@ -24,6 +24,7 @@ typedef struct {
char *file; /* file name we're really moving, arg is just the reference */ char *file; /* file name we're really moving, arg is just the reference */
unsigned int file_quoted:1; /* file name was received quoted ("file name") */ unsigned int file_quoted:1; /* file name was received quoted ("file name") */
unsigned int from_dccserver:1; /* get is using dccserver method */
} GET_DCC_REC; } GET_DCC_REC;
#define DCC_GET_TYPE module_get_uniq_id_str("DCC", "GET") #define DCC_GET_TYPE module_get_uniq_id_str("DCC", "GET")

416
src/irc/dcc/dcc-server.c Normal file
View File

@ -0,0 +1,416 @@
/*
dcc-server.c : irssi
Copyright (C) 2003 Mark Trumbull
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "module.h"
#include "signals.h"
#include "commands.h"
#include "network.h"
#include "net-sendbuffer.h"
#include "line-split.h"
#include "misc.h"
#include "irc-servers.h"
#include "dcc-chat.h"
#include "dcc-get.h"
#include "dcc-server.h"
void sig_dccget_connected(GET_DCC_REC *dcc);
GET_DCC_REC *dcc_get_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat,
const char *nick, const char *arg);
void dcc_chat_input(CHAT_DCC_REC *dcc);
CHAT_DCC_REC *dcc_chat_create(IRC_SERVER_REC *server, CHAT_DCC_REC *chat,
const char *nick, const char *arg);
static void sig_dcc_destroyed(SERVER_DCC_REC *dcc)
{
if (!IS_DCC_SERVER(dcc))
return;
if (dcc->sendbuf != NULL)
net_sendbuffer_destroy(dcc->sendbuf, FALSE);
line_split_free(dcc->readbuf);
}
/* Start listening for incoming connections */
static GIOChannel *dcc_listen_port(GIOChannel *iface, IPADDR *ip, int port)
{
if (net_getsockname(iface, ip, NULL) == -1)
return NULL;
if (IPADDR_IS_V6(ip))
return net_listen(NULL, &port);
else
return net_listen(&ip4_any, &port);
}
/* input function: DCC SERVER received some data.. */
static void dcc_server_input(SERVER_DCC_REC *dcc)
{
char tmpbuf[512], *str;
int recvlen, ret;
g_return_if_fail(IS_DCC_SERVER(dcc));
do {
recvlen = net_receive(dcc->handle, tmpbuf, sizeof(tmpbuf));
ret = line_split(tmpbuf, recvlen, &str, &dcc->readbuf);
if (ret == -1) {
/* connection lost */
dcc_close(DCC(dcc));
break;
}
if (ret > 0) {
dcc->transfd += ret;
signal_emit("dcc server message", 2, dcc, str);
}
if (dcc->connection_established) {
/* We set handle to NULL first because the new (chat/get) is using the same */
/* handle and we don't want dcc_close to disconnect it.*/
dcc->handle = NULL;
dcc_close(DCC(dcc));
break;
}
} while (ret > 0);
}
static void dcc_server_update_flags(SERVER_DCC_REC *dcc, const char *flags)
{
g_return_if_fail(dcc != NULL);
g_return_if_fail(IS_DCC_SERVER(dcc));
if (*flags == '+' || *flags == '-') {
const char *ptr = flags + 1;
unsigned int value = (*flags == '+') ? 1 : 0;
while (*ptr) {
if (*ptr == 's' || *ptr == 'S') { dcc->accept_send = value; }
else if (*ptr == 'c' || *ptr == 'C') { dcc->accept_chat = value; }
else if (*ptr == 'f' || *ptr == 'F') { dcc->accept_fserve = value; }
ptr++;
}
}
}
/* Initialize DCC record */
static void dcc_init_server_rec(SERVER_DCC_REC *dcc, IRC_SERVER_REC *server)
{
g_return_if_fail(dcc != NULL);
g_return_if_fail(server != NULL);
g_return_if_fail(IS_DCC_SERVER(dcc));
MODULE_DATA_INIT(dcc);
dcc->created = time(NULL);
dcc->chat = NULL;
dcc->arg = NULL;
dcc->nick = NULL;
dcc->tagconn = dcc->tagread = dcc->tagwrite = -1;
dcc->server = server;
dcc->mynick = g_strdup(server != NULL ? server->nick : "??");
dcc->servertag = server != NULL ? g_strdup(server->tag) : NULL;
dcc_conns = g_slist_append(dcc_conns, dcc);
signal_emit("dcc created", 1, dcc);
}
static SERVER_DCC_REC *dcc_server_create(IRC_SERVER_REC *server, const char *flags)
{
SERVER_DCC_REC *dcc;
dcc = g_new0(SERVER_DCC_REC, 1);
dcc->orig_type = dcc->type = DCC_SERVER_TYPE;
dcc_server_update_flags(dcc, flags);
dcc_init_server_rec(dcc, server);
return dcc;
}
static SERVER_DCC_REC *dcc_server_clone(SERVER_DCC_REC *dcc)
{
SERVER_DCC_REC *newdcc;
g_return_val_if_fail(IS_DCC_SERVER(dcc), NULL);
newdcc = g_new0(SERVER_DCC_REC, 1);
newdcc->orig_type = newdcc->type = DCC_SERVER_TYPE;
newdcc->accept_send = dcc->accept_send;
newdcc->accept_chat = dcc->accept_chat;
newdcc->accept_fserve = dcc->accept_fserve;
dcc_init_server_rec(newdcc, dcc->server);
return newdcc;
}
/* input function: DCC SERVER - someone tried to connect to our socket */
static void dcc_server_listen(SERVER_DCC_REC *dcc)
{
SERVER_DCC_REC *newdcc;
IPADDR ip;
GIOChannel *handle;
int port;
g_return_if_fail(IS_DCC_SERVER(dcc));
/* accept connection */
handle = net_accept(dcc->handle, &ip, &port);
if (handle == NULL)
return;
/* Create a new DCC SERVER to handle this connection */
newdcc = dcc_server_clone(dcc);
newdcc->starttime = time(NULL);
newdcc->handle = handle;
newdcc->sendbuf = net_sendbuffer_create(handle, 0);
memcpy(&newdcc->addr, &ip, sizeof(IPADDR));
net_ip2host(&newdcc->addr, newdcc->addrstr);
newdcc->port = port;
newdcc->tagread = g_input_add(handle, G_INPUT_READ,
(GInputFunction) dcc_server_input, newdcc);
signal_emit("dcc connected", 1, newdcc);
}
/* DCC SERVER: text received */
static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg)
{
g_return_if_fail(IS_DCC_SERVER(dcc));
g_return_if_fail(msg != NULL);
/* Check for CHAT protocol */
if (g_strncasecmp(msg, "100 ", 4) == 0) {
msg += 4;
/* Check if this server is accepting chat requests.*/
if (dcc->accept_chat) {
/* Connect and start DCC Chat */
char *str;
CHAT_DCC_REC *dccchat = dcc_chat_create(dcc->server, NULL, msg, "chat");
dccchat->starttime = time(NULL);
dccchat->handle = dcc->handle;
dccchat->sendbuf = net_sendbuffer_create(dccchat->handle, 0);
memcpy(&dccchat->addr, &dcc->addr, sizeof(IPADDR));
net_ip2host(&dccchat->addr, dccchat->addrstr);
dccchat->port = dcc->port;
dccchat->tagread = g_input_add(dccchat->handle, G_INPUT_READ,
(GInputFunction) dcc_chat_input, dccchat);
dcc->connection_established = 1;
signal_emit("dcc connected", 1, dccchat);
str = g_strdup_printf("101 %s\n",
(dccchat->server) ? dccchat->server->nick : "??");
net_sendbuffer_send(dccchat->sendbuf, str, strlen(str));
g_free(str);
}
}
/* Check for FSERVE protocol */
if (g_strncasecmp(msg, "110 ", 4) == 0) {
msg += 4;
/* Check if this server is accepting fserve requests.*/
if (dcc->accept_fserve) {
/* TODO - Connect and start DCC Fserve */
}
}
/* Check for SEND protocol */
if (g_strncasecmp(msg, "120 ", 4) == 0) {
msg += 4;
/* Check if this server is accepting send requests.*/
if (dcc->accept_send) {
/* Connect and start DCC Send */
GET_DCC_REC *dccget;
char **params, *fname, *nick;
int paramcount, len, quoted = FALSE;
uoff_t size;
/* 120 clientnickname filesize filename */
params = g_strsplit(msg, " ", -1);
paramcount = strarray_length(params);
if (paramcount < 3) {
g_strfreev(params);
signal_stop();
return;
}
nick = params[0];
size = str_to_uofft(params[1]);
fname = g_strjoinv(" ", &params[2]);
len = strlen(fname);
if (len > 1 && *fname == '"' && fname[len-1] == '"') {
/* "file name" - MIRC sends filenames with spaces like this */
fname[len-1] = '\0';
g_memmove(fname, fname+1, len);
quoted = TRUE;
}
dccget = dcc_get_create(dcc->server, NULL, nick, fname);
dccget->handle = dcc->handle;
dccget->target = g_strdup(dcc->server ? dcc->server->nick : "??");
memcpy(&dccget->addr, &dcc->addr, sizeof(dcc->addr));
if (dccget->addr.family == AF_INET) {
net_ip2host(&dccget->addr, dccget->addrstr);
} else {
/* with IPv6, show it to us as it was sent */
memcpy(dccget->addrstr, dcc->addrstr, sizeof(dccget->addrstr));
}
dccget->port = dcc->port;
dccget->size = size;
dccget->file_quoted = quoted;
dccget->from_dccserver = 1;
dcc->connection_established = 1;
signal_emit("dcc request", 2, dccget, dccget->addrstr);
g_strfreev(params);
g_free(fname);
}
}
signal_stop();
}
SERVER_DCC_REC *dcc_server_find_port(const char *port_str)
{
GSList *tmp;
unsigned int port = 0;
g_return_val_if_fail(port_str != NULL, NULL);
port = atoi(port_str);
for (tmp = dcc_conns; tmp != NULL; tmp = tmp->next) {
SERVER_DCC_REC *dcc = tmp->data;
if (IS_DCC_SERVER(dcc) && dcc->port == port)
return dcc;
}
return NULL;
}
/* SYNTAX: DCC SERVER [+|-scf] [port] */
static void cmd_dcc_server(const char *data, IRC_SERVER_REC *server)
{
void *free_arg;
GIOChannel *handle;
SERVER_DCC_REC *dcc;
IPADDR own_ip;
char *flags, *port;
g_return_if_fail(data != NULL);
if (!cmd_get_params(data, &free_arg, 2, &flags, &port))
return;
dcc = dcc_server_find_port(port);
if (dcc != NULL) {
/* Server is already running, update it */
dcc_server_update_flags(dcc, flags);
cmd_params_free(free_arg);
return;
}
/* start listening */
if (!IS_IRC_SERVER(server) || !server->connected) {
cmd_param_error(CMDERR_NOT_CONNECTED);
}
handle = dcc_listen_port(net_sendbuffer_handle(server->handle),
&own_ip, atoi(port));
if (handle == NULL) {
cmd_param_error(CMDERR_ERRNO);
}
dcc = dcc_server_create(server, flags);
dcc->handle = handle;
dcc->port = atoi(port);
dcc->tagconn = g_input_add(dcc->handle, G_INPUT_READ,
(GInputFunction) dcc_server_listen, dcc);
signal_emit("dcc server started", 1, dcc);
cmd_params_free(free_arg);
}
/* DCC CLOSE SERVER <port> */
static void cmd_dcc_close(char *data, SERVER_REC *server)
{
GSList *tmp, *next;
char *port_str;
void *free_arg;
int found, port;
g_return_if_fail(data != NULL);
if (g_strncasecmp(data, "SERVER ", 7) != 0 ||
!cmd_get_params(data, &free_arg, 2, NULL, &port_str)) {
return;
}
if (*port_str == '\0') {
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
}
port = atoi(port_str);
found = FALSE;
for (tmp = dcc_conns; tmp != NULL; tmp = next) {
SERVER_DCC_REC *dcc = tmp->data;
next = tmp->next;
if (IS_DCC_SERVER(dcc) && dcc->port == port) {
found = TRUE;
dcc_close(DCC(dcc));
}
}
if (found) {
signal_stop();
}
cmd_params_free(free_arg);
}
void dcc_server_init(void)
{
dcc_register_type("SERVER");
command_bind("dcc server", NULL, (SIGNAL_FUNC) cmd_dcc_server);
command_bind("dcc close", NULL, (SIGNAL_FUNC) cmd_dcc_close);
signal_add("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
signal_add_first("dcc server message", (SIGNAL_FUNC) dcc_server_msg);
}
void dcc_server_deinit(void)
{
dcc_unregister_type("SERVER");
command_unbind("dcc server", (SIGNAL_FUNC) cmd_dcc_server);
command_unbind("dcc close", (SIGNAL_FUNC) cmd_dcc_close);
signal_remove("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
signal_remove("dcc server message", (SIGNAL_FUNC) dcc_server_msg);
}

30
src/irc/dcc/dcc-server.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef __DCC_SERVER_H
#define __DCC_SERVER_H
#include "dcc.h"
#define DCC_SERVER(dcc) \
MODULE_CHECK_CAST_MODULE(dcc, SERVER_DCC_REC, type, "DCC", "SERVER")
#define IS_DCC_SERVER(dcc) \
(DCC_SERVER(dcc) ? TRUE : FALSE)
struct SERVER_DCC_REC {
#include "dcc-rec.h"
LINEBUF_REC *readbuf;
NET_SENDBUF_REC *sendbuf;
unsigned int accept_send:1; /* Accept SEND connections */
unsigned int accept_chat:1; /* Accept CHAT connections */
unsigned int accept_fserve:1; /* Accept FSERVE connections */
unsigned int connection_established:1; /* We have made a connection */
};
#define DCC_SERVER_TYPE module_get_uniq_id_str("DCC", "SERVER")
typedef struct SERVER_DCC_REC SERVER_DCC_REC;
void dcc_server_init(void);
void dcc_server_deinit(void);
#endif

View File

@ -34,6 +34,7 @@
#include "dcc-chat.h" #include "dcc-chat.h"
#include "dcc-get.h" #include "dcc-get.h"
#include "dcc-send.h" #include "dcc-send.h"
#include "dcc-server.h"
void dcc_resume_init(void); void dcc_resume_init(void);
void dcc_resume_deinit(void); void dcc_resume_deinit(void);
@ -431,11 +432,13 @@ static int dcc_timeout_func(void)
DCC_REC *dcc = tmp->data; DCC_REC *dcc = tmp->data;
next = tmp->next; next = tmp->next;
if (dcc->tagread == -1 && now > dcc->created) { if (dcc->tagread == -1 && now > dcc->created && !IS_DCC_SERVER(dcc)) {
/* Timed out - don't send DCC REJECT CTCP so CTCP /* Timed out - don't send DCC REJECT CTCP so CTCP
flooders won't affect us and it really doesn't flooders won't affect us and it really doesn't
matter that much anyway if the other side doen't matter that much anyway if the other side doen't
get it.. */ get it..
We don't want dcc servers to time out. */
dcc_close(dcc); dcc_close(dcc);
} }
} }
@ -540,6 +543,7 @@ void irc_dcc_init(void)
dcc_send_init(); dcc_send_init();
dcc_resume_init(); dcc_resume_init();
dcc_autoget_init(); dcc_autoget_init();
dcc_server_init();
module_register("dcc", "irc"); module_register("dcc", "irc");
} }
@ -554,6 +558,7 @@ void irc_dcc_deinit(void)
dcc_send_deinit(); dcc_send_deinit();
dcc_resume_deinit(); dcc_resume_deinit();
dcc_autoget_deinit(); dcc_autoget_deinit();
dcc_server_deinit();
signal_remove("event connected", (SIGNAL_FUNC) sig_connected); signal_remove("event connected", (SIGNAL_FUNC) sig_connected);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected); signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
@ -569,3 +574,4 @@ void irc_dcc_deinit(void)
g_source_remove(dcc_timeouttag); g_source_remove(dcc_timeouttag);
} }