Introduce a struct dcc_ops to contain all functions pointers for a custom DCC type

Modules now must pass a pointer to a struct dcc_ops when calling add_dcc_bind() instead of
a list of function pointers.
This commit is contained in:
Kevin Easton
2018-02-08 17:48:34 +11:00
parent 64ec300d5d
commit 61a926a766
9 changed files with 73 additions and 82 deletions

View File

@@ -1,5 +1,8 @@
[Changes 1.2.2]
* Change add_dcc_bind() to collect all function pointer arguments into a
single struct. (caf)
* Fix redirecting to DCC CHATs with /REL* commands. (caf)
* Update arcfour example module to use exported dcc_chat_socketread()

View File

@@ -118,9 +118,11 @@ static inline char *arcfourCrypt(arckey *arc, char *data, int len)
int Arcfour_Init(IrcCommandDll **intp, Function_ptr *global_table)
{
static const struct dcc_ops schat_ops = { NULL, start_dcc_crypt, dcc_schat_input, send_dcc_encrypt, end_dcc_crypt };
initialize_module("arcfour");
memset(keyboxes, 0, sizeof(keyboxes));
typenum = add_dcc_bind("SCHAT", "schat", NULL, start_dcc_crypt, dcc_schat_input, send_dcc_encrypt, end_dcc_crypt);
typenum = add_dcc_bind("SCHAT", "schat", &schat_ops);
add_module_proc(DCC_PROC, "schat", "schat", "Secure DCC Chat", 0, 0, dcc_sdcc, NULL);
return 0;
}
@@ -183,8 +185,7 @@ static int dcc_schat_input(int type, int sock, char *buf, int parm, int buf_size
* an encrypted connection.
*/
static int start_dcc_crypt (int s, int type, unsigned long d_addr, int d_port)
static int start_dcc_crypt (int s, int type, unsigned long d_addr, unsigned short d_port)
{
arclist *tmpbox;
put_it("start_dcc_crypt");
@@ -214,7 +215,7 @@ static int start_dcc_crypt (int s, int type, unsigned long d_addr, int d_port)
return -1;
}
static int end_dcc_crypt (int s, unsigned long d_addr, int d_port)
static int end_dcc_crypt(int s, unsigned long d_addr, unsigned short d_port)
{
int i;
for(i = 0; i < 16; i++) {
@@ -228,7 +229,6 @@ static int end_dcc_crypt (int s, unsigned long d_addr, int d_port)
return -1;
}
static void start_dcc_chat(int s)
{
struct sockaddr_in remaddr;

View File

@@ -9,6 +9,6 @@ static inline void arcfourInit(arckey *, void *, unsigned short);
static inline char *arcfourCrypt(arckey *, char *, int);
static int send_dcc_encrypt (int, int, char *, int);
static int dcc_schat_input (int, int, char *, int, int);
static int start_dcc_crypt (int, int, unsigned long, int);
static int end_dcc_crypt (int, unsigned long, int);
static int start_dcc_crypt (int, int, unsigned long, unsigned short);
static int end_dcc_crypt (int, unsigned long, unsigned short);
void dcc_sdcc (char *, char *);

View File

@@ -130,8 +130,10 @@ int new_dcc_output(int type, int s, char *buf, int len)
int Pkga_Init(IrcCommandDll **intp, Function_ptr *global_table)
{
static const struct dcc_ops pkga_ops = { NULL, NULL, NULL, new_dcc_output, NULL };
int i;
Server *sptr;
initialize_module("pkga");
sptr = get_server_list();
for (i = 0; i < server_list_size(); i++)
@@ -144,6 +146,6 @@ Server *sptr;
add_module_proc(HOOK_PROC, "pkga", NULL, NULL, 1, 0, Pkga_numeric, NULL);
add_module_proc(VAR_PROC, "pkga", "new_variable", "TEST VALUE", STR_TYPE_VAR, 0, NULL, NULL);
add_module_proc(RAW_PROC, "pkga", "PRIVMSG", NULL, 0, 0, Pkga_raw, NULL);
add_dcc_bind("CHAT", "pkga", NULL, NULL, NULL, new_dcc_output, NULL);
add_dcc_bind("CHAT", "pkga", &pkga_ops);
return 0;
}

View File

@@ -159,7 +159,26 @@ struct dcc_offer {
int BX_remove_all_dcc_binds(char *);
int BX_remove_dcc_bind(char *, int);
int BX_add_dcc_bind(char *, char *, void *, void *, void *, void *, void *);
/* Function pointers for the operations implementing a DCC type.
* This structure is part of the module ABI - if you change it,
* you need to roll MODULE_VERSION in <module.h>.
*
* .init() is called when a matching DCC offer is received over IRC
* .open() is called when a DCC connection is established
* .input() is called to fetch some data when the socket becomes readable
* .output() is called to write a message to the socket
* .close() is called when the DCC connection is closed
*/
struct dcc_ops
{
int (*init)(const char *, const char *, const char *, const char *, const char *, const char *, unsigned long, unsigned short);
int (*open)(int, int, unsigned long, unsigned short);
int (*input)(int, int, char *, int, int);
int (*output)(int, int, char *, int);
int (*close)(int, unsigned long, unsigned short);
};
int BX_add_dcc_bind(char *, char *, const struct dcc_ops *);
/* add_socketread() callbacks for ordinary CHAT and SEND DCCs */
extern void BX_dcc_chat_socketread(int);
extern void BX_dcc_send_socketread(int);

View File

@@ -10,7 +10,7 @@
* if we change the table below, we change this module number to the
* current date (YYYYMMDDxx where xx is a serial number).
*/
#define MODULE_VERSION 2017122001UL
#define MODULE_VERSION 2018020801UL
#include "struct.h"

View File

@@ -604,7 +604,7 @@ extern Function_ptr *global;
#define dcc_create (*(DCC_int *(*)(char *, char *, char *, unsigned long, int, int, unsigned long, void (*)(int)))global[DCC_CREATE_FUNC])
#define find_dcc (*(SocketList *(*)(const char *, const char *, const char *, int, int, int, int))global[FIND_DCC_FUNC])
#define erase_dcc_info (*(void (*)(int, int, char *, ...))global[ERASE_DCC_INFO])
#define add_dcc_bind (*(int (*)(char *, char *, void *, void *, void *, void *, void *))global[ADD_DCC_BIND])
#define add_dcc_bind (*(int (*)(char *, char *, const struct dcc_ops *))global[ADD_DCC_BIND])
#define remove_dcc_bind (*(int (*)(char *, int ))global[REMOVE_DCC_BIND])
#define remove_all_dcc_binds (*(int (*)(char *))global[REMOVE_ALL_DCC_BINDS])
#define get_active_count (*(int (*)(void ))global[GET_ACTIVE_COUNT])

View File

@@ -79,28 +79,26 @@ struct _dcc_types_
char *name;
char *module;
int type;
int (*init_func)(const char *, const char *, const char *, const char *, const char *, const char *, unsigned long, unsigned short);
int (*open_func)(int, int, unsigned long, unsigned short);
int (*input)(int, int, char *, int, int);
int (*output)(int, int, char *, int);
int (*close_func)(int, unsigned long, unsigned short);
const struct dcc_ops *dcc_ops;
};
const struct dcc_ops null_ops = { NULL, NULL, NULL, NULL, NULL };
struct _dcc_types_ _dcc_types[] =
{
{"<none>", NULL, 0, NULL, NULL, NULL, NULL, NULL},
{"CHAT", NULL, DCC_CHAT, NULL, NULL, NULL, NULL, NULL},
{"SEND", NULL, DCC_FILEOFFER, NULL, NULL, NULL, NULL, NULL},
{"GET", NULL, DCC_FILEREAD, NULL, NULL, NULL, NULL, NULL},
{"RAW_LISTEN", NULL, DCC_RAW_LISTEN, NULL, NULL, NULL, NULL, NULL},
{"RAW", NULL, DCC_RAW, NULL, NULL, NULL, NULL, NULL},
{"RESEND", NULL, DCC_REFILEOFFER, NULL, NULL, NULL, NULL, NULL},
{"REGET", NULL, DCC_REFILEREAD, NULL, NULL, NULL, NULL, NULL},
{"BOT", NULL, DCC_BOTMODE, NULL, NULL, NULL, NULL, NULL},
{"FTP", NULL, DCC_FTPOPEN, NULL, NULL, NULL, NULL, NULL},
{"FTPGET", NULL, DCC_FTPGET, NULL, NULL, NULL, NULL, NULL},
{"FTPSEND", NULL, DCC_FTPSEND, NULL, NULL, NULL, NULL, NULL},
{NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL}
{"<none>", NULL, 0, NULL},
{"CHAT", NULL, DCC_CHAT, &null_ops},
{"SEND", NULL, DCC_FILEOFFER, &null_ops},
{"GET", NULL, DCC_FILEREAD, &null_ops},
{"RAW_LISTEN", NULL, DCC_RAW_LISTEN, &null_ops},
{"RAW", NULL, DCC_RAW, &null_ops},
{"RESEND", NULL, DCC_REFILEOFFER, &null_ops},
{"REGET", NULL, DCC_REFILEREAD, &null_ops},
{"BOT", NULL, DCC_BOTMODE, &null_ops},
{"FTP", NULL, DCC_FTPOPEN, &null_ops},
{"FTPGET", NULL, DCC_FTPGET, &null_ops},
{"FTPSEND", NULL, DCC_FTPSEND, &null_ops},
{NULL, NULL, 0, NULL}
};
struct _dcc_types_ **dcc_types = NULL;
@@ -160,23 +158,6 @@ static void output_reject_ctcp (UserhostItem *, char *, char *);
extern int use_nat_address;
extern struct in_addr nat_address;
#if 0
/* sock num, type, address, port */
int (*dcc_open_func) (int, int, struct sockaddr_foobar, int) = NULL;
/* type, sock num, buffer, buff_len */
int (*dcc_output_func) (int, int, char *, int) = NULL;
/* sock num, type, buffer, new line, len buffer */
int (*dcc_input_func) (int, int, char *, int, int) = NULL;
/* socket num, address, port */
int (*dcc_close_func) (int, sockaddr_foobar, int) = NULL;
#endif
#define DCC_OPEN 1
#define DCC_INPUT 2
#define DCC_OUTPUT 3
#define DCC_CLOSE 4
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -334,8 +315,8 @@ static time_t last_reject = 0;
s1 = get_socket(s);
if (check_dcc_socket(s) && (n = (DCC_int *)get_socketinfo(s)))
{
if (dcc_types[s1->flags & DCC_TYPES]->close_func)
(*dcc_types[s1->flags & DCC_TYPES]->close_func)(s, n->remote.s_addr, n->remport);
if (dcc_types[s1->flags & DCC_TYPES]->dcc_ops->close)
(*dcc_types[s1->flags & DCC_TYPES]->dcc_ops->close)(s, n->remote.s_addr, n->remport);
if (reject && ((now - last_reject) < 2))
send_reject_ctcp(s1->server,
(((s1->flags & DCC_TYPES) == DCC_FILEOFFER) ? "GET" :
@@ -568,8 +549,8 @@ DCC_List *new_i;
inet_ntoa(remaddr.sin_addr), (int)ntohs(remaddr.sin_port)));
}
}
if (dcc_types[type]->open_func)
(*dcc_types[type]->open_func)(new_s, type, new->remote.s_addr, ntohs(remaddr.sin_port));
if (dcc_types[type]->dcc_ops->open)
(*dcc_types[type]->dcc_ops->open)(new_s, type, new->remote.s_addr, ntohs(remaddr.sin_port));
if (type == DCC_REFILEREAD)
refileread_send_start(new_s, new);
if (get_int_var(DCC_FAST_VAR)
@@ -757,8 +738,8 @@ void (*func)(int) = dcc_chat_socketread;
get_time(&n->starttime);
close_socketread(s);
if (dcc_types[type]->open_func)
(*dcc_types[type]->open_func)(new_s, type, n->remote.s_addr, ntohs(remaddr.sin_port));
if (dcc_types[type]->dcc_ops->open)
(*dcc_types[type]->dcc_ops->open)(new_s, type, n->remote.s_addr, ntohs(remaddr.sin_port));
reset_display_target();
}
@@ -781,8 +762,8 @@ void BX_dcc_chat_socketread(int s)
type = flags & DCC_TYPES;
sl = get_socket(s);
bufptr = tmp;
if (dcc_types[type]->input)
bytesread = (*dcc_types[type]->input)(s, type, bufptr, 1, BIG_BUFFER_SIZE);
if (dcc_types[type]->dcc_ops->input)
bytesread = (*dcc_types[type]->dcc_ops->input)(s, type, bufptr, 1, BIG_BUFFER_SIZE);
else
#ifdef HAVE_LIBSSL
bytesread = dgets(bufptr, s, 1, BIG_BUFFER_SIZE, sl->ssl_fd);
@@ -909,8 +890,8 @@ SocketList *sl;
sl = get_socket(s);
bufptr = tmp;
if (dcc_types[type]->input)
bytesread = (*dcc_types[type]->input) (type, s, bufptr, 1, BIG_BUFFER_SIZE);
if (dcc_types[type]->dcc_ops->input)
bytesread = (*dcc_types[type]->dcc_ops->input) (type, s, bufptr, 1, BIG_BUFFER_SIZE);
else
#ifdef HAVE_LIBSSL
bytesread = dgets(bufptr, s, 1, BIG_BUFFER_SIZE, sl->ssl_fd);
@@ -1009,8 +990,8 @@ char thing = 0;
len = strlen(tmp);
my_encrypt(tmp, len, n->encrypt);
if (dcc_types[type]->output)
(*dcc_types[type]->output) (type, s->is_read, tmp, len);
if (dcc_types[type]->dcc_ops->output)
(*dcc_types[type]->dcc_ops->output)(type, s->is_read, tmp, len);
else
#ifdef HAVE_LIBSSL
if(s->ssl_fd)
@@ -1516,14 +1497,14 @@ static int check_dcc_init(const struct dcc_offer *offer)
break;
}
if (dcc_types[i]->name && dcc_types[i]->init_func)
if (dcc_types[i]->name && dcc_types[i]->dcc_ops->init)
{
unsigned long filesize;
unsigned long address;
unsigned short port;
if (parse_offer_params(offer, &address, &port, &filesize))
return dcc_types[i]->init_func(offer->type, offer->nick, offer->userhost, offer->description, offer->size, offer->extra, address, port);
return dcc_types[i]->dcc_ops->init(offer->type, offer->nick, offer->userhost, offer->description, offer->size, offer->extra, address, port);
}
return 0;
}
@@ -4263,7 +4244,7 @@ char *nick,
}
}
int BX_add_dcc_bind(char *name, char *module, void *init_func, void *open_func, void *input, void *output, void *close_func)
int BX_add_dcc_bind(char *name, char *module, const struct dcc_ops *dcc_ops)
{
int i;
for (i = 0; dcc_types[i]->name; i++)
@@ -4280,11 +4261,7 @@ int i;
if (!dcc_types[i]->name)
malloc_strcpy(&dcc_types[i]->name, name);
malloc_strcpy(&dcc_types[i]->module, module);
dcc_types[i]->init_func = init_func;
dcc_types[i]->open_func = open_func;
dcc_types[i]->input = input;
dcc_types[i]->output = output;
dcc_types[i]->close_func = close_func;
dcc_types[i]->dcc_ops = dcc_ops;
dcc_types[i]->type = i;
return i;
}
@@ -4294,12 +4271,8 @@ int BX_remove_dcc_bind(char *name, int type)
int i = type & DCC_TYPES;
if (!dcc_types[i]->module)
return 0;
dcc_types[i]->init_func = NULL;
dcc_types[i]->open_func = NULL;
dcc_types[i]->input = NULL;
dcc_types[i]->output = NULL;
dcc_types[i]->close_func = NULL;
new_free(&dcc_types[i]->module);
dcc_types[i]->dcc_ops = &null_ops;
if (i > DCC_FTPSEND)
{
new_free(&dcc_types[i]->name);
@@ -4324,13 +4297,12 @@ int i, j;
void init_dcc_table(void)
{
int i;
for (i = 0; _dcc_types[i].name; i++);
RESIZE(dcc_types, struct _dcc_types_ *, i + 1);
for (i = 0; _dcc_types[i].name; i++)
{
dcc_types[i] = new_malloc(sizeof(struct _dcc_types_));
dcc_types[i]->name = m_strdup(_dcc_types[i].name);
dcc_types[i]->type = _dcc_types[i].type;
dcc_types[i] = &_dcc_types[i];
}
dcc_types[i] = new_malloc(sizeof(struct _dcc_types_));
}

View File

@@ -78,11 +78,6 @@ extern int BX_read_sockets();
extern int identd;
extern int doing_notice;
extern int (*dcc_open_func) (int, int, unsigned long, int);
extern int (*dcc_output_func) (int, int, char *, int);
extern int (*dcc_input_func) (int, int, char *, int, int);
extern int (*dcc_close_func) (int, unsigned long, int);
int (*serv_open_func) (int, unsigned long, int);
extern int (*serv_output_func) (int, int, char *, int);
extern int (*serv_input_func) (int, char *, int, int, int);