/* Handle incoming DCC CTCP replies */ static void dcc_ctcp_reply(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr) { char *params, *cmd, *subcmd, *args; int type; DCC_REC *dcc; g_return_if_fail(data != NULL); g_return_if_fail(sender != NULL); params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &cmd, &subcmd, &args); if (g_strcasecmp(cmd, "REJECT") == 0) { type = dcc_str2type(subcmd); dcc = dcc_find_item(type, sender, type == DCC_TYPE_CHAT ? NULL : args); if (dcc != NULL) { signal_emit("dcc closed", 1, dcc); dcc_destroy(dcc); } } else { /* unknown dcc ctcp reply */ signal_emit("dcc unknown reply", 3, data, sender, sendaddr); } g_free(params); }
/* CTCP REPLY: REJECT */ static void ctcp_reply_dcc_reject(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, DCC_REC *chat) { DCC_REC *dcc; char *type, *args; type = g_strdup(data); args = strchr(type, ' '); if (args != NULL) *args++ = '\0'; else args = ""; dcc = dcc_find_request(dcc_str2type(type), nick, args); if (dcc != NULL) dcc_close(dcc); g_free(type); }
/* SYNTAX: DCC CLOSE <type> <nick> [<file>] */ static void cmd_dcc_close(char *data, IRC_SERVER_REC *server) { GSList *tmp, *next; char *typestr, *nick, *arg, *fname; void *free_arg; int found, type; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &typestr, &nick, &arg)) return; if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); ascii_strup(typestr); type = dcc_str2type(typestr); if (type == -1) { signal_emit("dcc error unknown type", 1, typestr); cmd_params_free(free_arg); return; } fname = cmd_get_quoted_param(&arg); found = FALSE; for (tmp = dcc_conns; tmp != NULL; tmp = next) { DCC_REC *dcc = tmp->data; next = tmp->next; if (dcc->type == type && g_ascii_strcasecmp(dcc->nick, nick) == 0 && (*fname == '\0' || g_strcmp0(dcc->arg, fname) == 0)) { dcc_reject(dcc, server); found = TRUE; } } if (!found) { signal_emit("dcc error close not found", 3, typestr, nick, arg); } cmd_params_free(free_arg); }
/* SYNTAX: DCC CLOSE <type> <nick> [<file>] */ static void cmd_dcc_close(char *data, IRC_SERVER_REC *server) { DCC_REC *dcc; GSList *tmp, *next; char *type, *nick, *arg; void *free_arg; gboolean found; int itype; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 3, &type, &nick, &arg)) return; if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); g_strup(type); itype = dcc_str2type(type); if (itype == 0) { signal_emit("dcc error unknown type", 1, type); cmd_params_free(free_arg); return; } dcc = NULL; found = FALSE; for (tmp = dcc_conns; tmp != NULL; tmp = next) { dcc = tmp->data; next = tmp->next; if (dcc->type == itype && g_strcasecmp(nick, dcc->nick) == 0) { dcc_reject(dcc, server); found = TRUE; } } if (!found) signal_emit("dcc error close not found", 3, type, nick, arg); cmd_params_free(free_arg); }
static void dcc_error_close_not_found(const char *type, const char *nick, const char *fname) { g_return_if_fail(type != NULL); g_return_if_fail(nick != NULL); g_return_if_fail(fname != NULL); if (fname == '\0') fname = "(ANY)"; switch (dcc_str2type(type)) { case DCC_TYPE_CHAT: printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_CHAT_NOT_FOUND, nick); break; case DCC_TYPE_SEND: printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_SEND_NOT_FOUND, nick, fname); break; case DCC_TYPE_GET: printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_GET_NOT_FOUND, nick, fname); break; } }
/* Handle incoming DCC CTCP messages */ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr, char *target, DCC_REC *chat) { char *params, *type, *arg, *addrstr, *portstr, *sizestr, *str; const char *cstr; DCC_REC *dcc; gulong size; int port; g_return_if_fail(data != NULL); g_return_if_fail(sender != NULL); params = cmd_get_params(data, 5 | PARAM_FLAG_NOQUOTES, &type, &arg, &addrstr, &portstr, &sizestr); if (sscanf(portstr, "%d", &port) != 1) port = 0; if (sscanf(sizestr, "%lu", &size) != 1) size = 0; dcc = dcc_create(SWAP_SENDGET(dcc_str2type(type)), -1, sender, arg, server, chat); dcc_get_address(addrstr, &dcc->addr); net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; dcc->size = size; switch (dcc->type) { case DCC_TYPE_GET: cstr = settings_get_str("dcc_autoget_masks"); /* check that autoget masks match */ if (settings_get_bool("dcc_autoget") && (*cstr == '\0' || irc_masks_match(cstr, sender, sendaddr)) && /* check file size limit, FIXME: it's possible to send a bogus file size and then just send what ever sized file.. */ (settings_get_int("dcc_max_autoget_size") <= 0 || (settings_get_int("dcc_max_autoget_size") > 0 && size <= settings_get_int("dcc_max_autoget_size")*1024))) { /* automatically get */ str = g_strdup_printf("GET %s %s", dcc->nick, dcc->arg); signal_emit("command dcc", 2, str, server); g_free(str); } else { /* send request */ signal_emit("dcc request", 1, dcc); } break; case DCC_TYPE_CHAT: cstr = settings_get_str("dcc_autochat_masks"); if (*cstr != '\0' && irc_masks_match(cstr, sender, sendaddr)) { /* automatically accept chat */ str = g_strdup_printf("CHAT %s", dcc->nick); signal_emit("command dcc", 2, str, server); g_free(str); } else { /* send request */ signal_emit("dcc request", 1, dcc); } break; case DCC_TYPE_RESUME: case DCC_TYPE_ACCEPT: /* handle this in dcc-files.c */ dcc_destroy(dcc); break; default: /* unknown DCC command */ signal_emit("dcc unknown ctcp", 3, data, sender, sendaddr); dcc_destroy(dcc); break; } g_free(params); }
/* Handle incoming DCC CTCP messages */ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char *sendaddr, char *target, DCC_REC *chat) { char *type, *arg, *addrstr, *portstr, *sizestr, *str; void *free_arg; const char *cstr; DCC_REC *dcc, *olddcc; long size; int dcctype, port; g_return_if_fail(data != NULL); g_return_if_fail(sender != NULL); if (!cmd_get_params(data, &free_arg, 5 | PARAM_FLAG_NOQUOTES, &type, &arg, &addrstr, &portstr, &sizestr)) return; if (sscanf(portstr, "%d", &port) != 1) port = 0; if (sscanf(sizestr, "%ld", &size) != 1) size = 0; dcctype = SWAP_SENDGET(dcc_str2type(type)); olddcc = dcc_find_item(dcctype, sender, dcctype == DCC_TYPE_CHAT ? NULL : arg); if (olddcc != NULL) { /* same DCC request offered again */ if (olddcc->type == DCC_TYPE_CHAT && olddcc->handle != -1 && olddcc->starttime == 0) { /* we requested dcc chat, they requested dcc chat from us .. allow it. */ dcc_destroy(olddcc); } else { /* if the connection isn't open, update the port, otherwise just ignore */ if (olddcc->handle == -1) olddcc->port = port; cmd_params_free(free_arg); return; } } dcc = dcc_create(dcctype, -1, sender, arg, server, chat); dcc_get_address(addrstr, &dcc->addr); net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; dcc->size = size; switch (dcc->type) { case DCC_TYPE_GET: cstr = settings_get_str("dcc_autoget_masks"); /* check that autoget masks match */ if (settings_get_bool("dcc_autoget") && (*cstr == '\0' || masks_match(SERVER(server), cstr, sender, sendaddr)) && /* check file size limit, FIXME: it's possible to send a bogus file size and then just send what ever sized file.. */ (settings_get_int("dcc_max_autoget_size") <= 0 || (settings_get_int("dcc_max_autoget_size") > 0 && size <= settings_get_int("dcc_max_autoget_size")*1024))) { /* automatically get */ str = g_strdup_printf("GET %s %s", dcc->nick, dcc->arg); signal_emit("command dcc", 2, str, server); g_free(str); } else { /* send request */ signal_emit("dcc request", 1, dcc); } break; case DCC_TYPE_CHAT: cstr = settings_get_str("dcc_autochat_masks"); if (olddcc != NULL || (*cstr != '\0' && masks_match(SERVER(server), cstr, sender, sendaddr))) { /* automatically accept chat */ str = g_strdup_printf("CHAT %s", dcc->nick); signal_emit("command dcc", 2, str, server); g_free(str); } else { /* send request */ signal_emit("dcc request", 1, dcc); } break; case DCC_TYPE_RESUME: case DCC_TYPE_ACCEPT: /* handle this in dcc-files.c */ dcc_destroy(dcc); break; default: /* unknown DCC command */ signal_emit("dcc unknown ctcp", 3, data, sender, sendaddr); dcc_destroy(dcc); break; } cmd_params_free(free_arg); }