/* Resume a DCC GET */ static void dcc_send_resume(GET_DCC_REC *dcc) { char *str; g_return_if_fail(dcc != NULL); dcc->file = dcc_get_download_path(dcc->arg); dcc->fhandle = open(dcc->file, O_WRONLY); if (dcc->fhandle == -1) { signal_emit("dcc error file not found", 2, dcc, dcc->file); return; } dcc->get_type = DCC_GET_RESUME; dcc->transfd = lseek(dcc->fhandle, 0, SEEK_END); if (dcc->transfd < 0) dcc->transfd = 0; dcc->skipped = dcc->transfd; if (dcc->skipped == dcc->size) { /* already received whole file */ dcc->starttime = time(NULL); dcc_reject(DCC(dcc), NULL); } else { str = g_strdup_printf(dcc->file_quoted ? "DCC RESUME \"%s\" %d %lu" : "DCC RESUME %s %d %lu", dcc->arg, dcc->port, dcc->transfd); dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str); g_free(str); } }
/* Resume a DCC GET */ static void dcc_send_resume(GET_DCC_REC *dcc) { off_t pos; char *str; g_return_if_fail(dcc != NULL); dcc->file = dcc_get_download_path(dcc->arg); dcc->fhandle = open(dcc->file, O_WRONLY); if (dcc->fhandle == -1) { signal_emit("dcc error file open", 3, dcc->nick, dcc->file, GINT_TO_POINTER(errno)); return; } dcc->get_type = DCC_GET_RESUME; pos = lseek(dcc->fhandle, 0, SEEK_END); dcc->transfd = pos == (off_t)-1 ? 0 : (unsigned long) pos; dcc->skipped = dcc->transfd; if (dcc->skipped == dcc->size) { /* already received whole file */ dcc->starttime = time(NULL); dcc_reject(DCC(dcc), NULL); } else { str = g_strdup_printf(dcc->file_quoted ? "DCC RESUME \"%s\" %d %lu" : "DCC RESUME %s %d %lu", dcc->arg, dcc->port, dcc->transfd); dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str); g_free(str); } }
static int dcc_resume_file_check(FILE_DCC_REC *dcc, IRC_SERVER_REC *server, uoff_t size) { if (size >= dcc->size) { /* whole file sent */ dcc->starttime = time(NULL); dcc_reject(DCC(dcc), server); } else if (lseek(dcc->fhandle, (off_t)size, SEEK_SET) != (off_t)size) { /* error */ dcc_reject(DCC(dcc), server); } else { dcc->transfd = dcc->skipped = size; return TRUE; } return FALSE; }
static int dcc_resume_file_check(FILE_DCC_REC *dcc, IRC_SERVER_REC *server, unsigned long size) { if (size >= dcc->size) { /* whole file sent */ dcc->starttime = time(NULL); dcc_reject(DCC(dcc), server); } else if (lseek(dcc->fhandle, size, SEEK_SET) != (long)size) { /* error, or trying to seek after end of file */ dcc_reject(DCC(dcc), server); } else { dcc->transfd = dcc->skipped = size; return TRUE; } return FALSE; }
/* 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); }
static int dcc_timeout_func(void) { GSList *tmp, *next; time_t now; now = time(NULL)-settings_get_int("dcc_timeout"); for (tmp = dcc_conns; tmp != NULL; tmp = next) { DCC_REC *rec = tmp->data; next = tmp->next; if (rec->tagread == -1 && now > rec->created) { /* timed out. */ dcc_reject(rec, NULL); } } return 1; }
/* 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); }
/* DCC CLOSE CHAT <nick> - check only from chat_ids in open DCC chats, the default handler will check from DCC chat requests */ static void cmd_dcc_close(char *data, SERVER_REC *server) { GSList *tmp, *next; char *nick; void *free_arg; int found; g_return_if_fail(data != NULL); if (g_ascii_strncasecmp(data, "CHAT ", 5) != 0 || !cmd_get_params(data, &free_arg, 2, NULL, &nick)) return; if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); found = FALSE; for (tmp = dcc_conns; tmp != NULL; tmp = next) { CHAT_DCC_REC *dcc = tmp->data; next = tmp->next; if (IS_DCC_CHAT(dcc) && dcc->id != NULL && g_ascii_strcasecmp(dcc->id, nick) == 0) { found = TRUE; if (!dcc_is_connected(dcc) && IS_IRC_SERVER(server)) dcc_reject(DCC(dcc), IRC_SERVER(server)); else { /* don't send DCC REJECT after DCC chat is already open */ dcc_close(DCC(dcc)); } } } if (found) signal_stop(); cmd_params_free(free_arg); }