From 61a926a766030259a229a95c9994b984a54f8be1 Mon Sep 17 00:00:00 2001 From: Kevin Easton Date: Thu, 8 Feb 2018 17:48:34 +1100 Subject: [PATCH] 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. --- Changelog | 3 ++ dll/arcfour/arcfour.c | 10 ++--- dll/arcfour/arcfour.h | 4 +- dll/pkga/pkga.c | 8 ++-- include/dcc.h | 21 ++++++++- include/module.h | 2 +- include/modval.h | 2 +- source/dcc.c | 100 +++++++++++++++--------------------------- source/modules.c | 5 --- 9 files changed, 73 insertions(+), 82 deletions(-) diff --git a/Changelog b/Changelog index f21b801..8d70872 100644 --- a/Changelog +++ b/Changelog @@ -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() diff --git a/dll/arcfour/arcfour.c b/dll/arcfour/arcfour.c index 1767b83..e9fd773 100644 --- a/dll/arcfour/arcfour.c +++ b/dll/arcfour/arcfour.c @@ -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; diff --git a/dll/arcfour/arcfour.h b/dll/arcfour/arcfour.h index f934085..738885c 100644 --- a/dll/arcfour/arcfour.h +++ b/dll/arcfour/arcfour.h @@ -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 *); diff --git a/dll/pkga/pkga.c b/dll/pkga/pkga.c index 83fb40a..cbc9489 100644 --- a/dll/pkga/pkga.c +++ b/dll/pkga/pkga.c @@ -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) { -int i; -Server *sptr; + 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; } diff --git a/include/dcc.h b/include/dcc.h index 876e400..ed58ad1 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -158,8 +158,27 @@ struct dcc_offer { void init_dcc_table(void); int BX_remove_all_dcc_binds(char *); int BX_remove_dcc_bind(char *, int); + +/* 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 . + * + * .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 *, void *, void *, void *, void *, void *); + 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); diff --git a/include/module.h b/include/module.h index de01bb7..e97bf10 100644 --- a/include/module.h +++ b/include/module.h @@ -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" diff --git a/include/modval.h b/include/modval.h index 99d4013..c8bad3e 100644 --- a/include/modval.h +++ b/include/modval.h @@ -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]) diff --git a/source/dcc.c b/source/dcc.c index 84b2269..898197b 100644 --- a/source/dcc.c +++ b/source/dcc.c @@ -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[] = { - {"", 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} + {"", 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); @@ -4323,14 +4296,13 @@ int i, j; void init_dcc_table(void) { -int i; + 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_)); } diff --git a/source/modules.c b/source/modules.c index 64d0af0..776bdb1 100644 --- a/source/modules.c +++ b/source/modules.c @@ -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);