/* CTCP: DCC RESUME - requesting to resume DCC SEND */ static void ctcp_msg_dcc_resume(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target, DCC_REC *chat) { FILE_DCC_REC *dcc; char *str; uoff_t size; int pasv_id = -1; if (!dcc_ctcp_resume_parse(DCC_SEND_TYPE, data, nick, &dcc, &size, &pasv_id)) { signal_emit("dcc error ctcp", 5, "RESUME", data, nick, addr, target); } else if (dcc != NULL && dcc_resume_file_check(dcc, server, size)) { if (!dcc_is_passive(dcc)) { str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ? "DCC ACCEPT \"%s\" %d %"PRIuUOFF_T : "DCC ACCEPT %s %d %"PRIuUOFF_T, dcc->arg, dcc->port, dcc->transfd); } else { str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ? "DCC ACCEPT \"%s\" 0 %"PRIuUOFF_T" %d" : "DCC ACCEPT %s 0 %"PRIuUOFF_T" %d", dcc->arg, dcc->transfd, dcc->pasv_id); } dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str); g_free(str); } }
static void dcc_resume_rec(DCC_REC *dcc) { char *str; g_return_if_fail(dcc != NULL); dcc->get_type = DCC_GET_RESUME; dcc->file = dcc_get_download_path(dcc->arg); dcc->fhandle = open(dcc->file, O_WRONLY, dcc_file_create_mode); if (dcc->fhandle == -1) { signal_emit("dcc error file not found", 2, dcc, dcc->file); dcc_destroy(dcc); return; } dcc->transfd = lseek(dcc->fhandle, 0, SEEK_END); if (dcc->transfd < 0) dcc->transfd = 0; dcc->skipped = dcc->transfd; str = g_strdup_printf("DCC RESUME %s %d %lu", dcc->arg, dcc->port, dcc->transfd); dcc_ctcp_message(dcc->nick, dcc->server, dcc->chat, FALSE, str); g_free(str); }
/* 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); } }
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server) { CHAT_DCC_REC *dcc; char *target, *ctcpcmd, *ctcpdata, *str; void *free_arg; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata)) return; if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target != '=') { /* handle only DCC CTCPs */ cmd_params_free(free_arg); return; } dcc = dcc_chat_find_id(target+1); if (dcc != NULL) { ascii_strup(ctcpcmd); str = g_strconcat(ctcpcmd, " ", ctcpdata, NULL); dcc_ctcp_message(server, dcc->nick, dcc, FALSE, str); g_free(str); } cmd_params_free(free_arg); signal_stop(); }
static void cmd_action(const char *data, IRC_SERVER_REC *server) { char *params, *target, *text; DCC_REC *dcc; char *str; g_return_if_fail(data != NULL); if (*data != '=') { /* handle only DCC actions */ return; } params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &text); if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL); if (dcc != NULL) { str = g_strdup_printf("ACTION %s", text); dcc_ctcp_message(dcc->nick, NULL, dcc, FALSE, str); g_free(str); } g_free(params); signal_stop(); }
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server) { char *params, *target, *ctcpcmd, *ctcpdata; DCC_REC *dcc; char *str; g_return_if_fail(data != NULL); if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata); if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target != '=') { /* handle only DCC CTCPs */ g_free(params); return; } dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL); if (dcc != NULL) { g_strup(ctcpcmd); str = g_strdup_printf("%s %s", ctcpcmd, ctcpdata); dcc_ctcp_message(dcc->nick, NULL, dcc, FALSE, str); g_free(str); } g_free(params); signal_stop(); }
static void cmd_action(const char *data, IRC_SERVER_REC *server) { CHAT_DCC_REC *dcc; char *target, *text, *str; void *free_arg; g_return_if_fail(data != NULL); if (*data != '=') { /* handle only DCC actions */ return; } if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text)) return; if (*target == '\0' || *text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); dcc = dcc_chat_find_id(target+1); if (dcc != NULL) { str = g_strconcat("ACTION ", text, NULL); dcc_ctcp_message(server, dcc->nick, dcc, FALSE, str); g_free(str); } cmd_params_free(free_arg); signal_stop(); }
/* 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 void dcc_resume_send(DCC_REC *dcc, int port) { char *str; g_return_if_fail(dcc != NULL); g_return_if_fail(dcc->type == DCC_TYPE_SEND); str = g_strdup_printf("DCC ACCEPT %s %d %lu", dcc->arg, port, dcc->transfd); dcc_ctcp_message(dcc->nick, dcc->server, dcc->chat, FALSE, str); g_free(str); }
static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) { DCC_REC *dcc; char *str; g_return_if_fail(data != NULL); dcc = item_get_dcc(item); if (dcc == NULL) return; str = g_strdup_printf("ACTION %s", data); dcc_ctcp_message(dcc->nick, NULL, dcc, FALSE, str); g_free(str); signal_stop(); }
static void cmd_me(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { CHAT_DCC_REC *dcc; char *str; g_return_if_fail(data != NULL); dcc = item_get_dcc(item); if (dcc == NULL) return; str = g_strconcat("ACTION ", data, NULL); dcc_ctcp_message(server, dcc->nick, dcc, FALSE, str); g_free(str); signal_stop(); }
/* CTCP: DCC RESUME - requesting to resume DCC SEND */ static void ctcp_msg_dcc_resume(IRC_SERVER_REC *server, const char *data, const char *nick, const char *addr, const char *target, DCC_REC *chat) { FILE_DCC_REC *dcc; char *str; unsigned long size; if (!dcc_ctcp_resume_parse(DCC_SEND_TYPE, data, nick, &dcc, &size)) { signal_emit("dcc error ctcp", 5, "RESUME", data, nick, addr, target); } else if (dcc != NULL && dcc_resume_file_check(dcc, server, size)) { str = g_strdup_printf(DCC_SEND(dcc)->file_quoted ? "DCC ACCEPT \"%s\" %d %lu" : "DCC ACCEPT %s %d %lu", dcc->arg, dcc->port, dcc->transfd); dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str); g_free(str); } }
/* command: DCC SEND */ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item) { char *params, *target, *fname, *str, *ptr; char host[MAX_IP_LEN]; int hfile, hlisten, port; long fsize; DCC_REC *dcc, *chat; IPADDR own_ip; g_return_if_fail(data != NULL); params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &fname); if (*target == '\0' || *fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); /* if we're in dcc chat, send the request via it. */ chat = item_get_dcc(item); if (chat != NULL && (chat->mirc_ctcp || g_strcasecmp(target, chat->nick) != 0)) chat = NULL; if ((server == NULL || !server->connected) && chat == NULL) cmd_param_error(CMDERR_NOT_CONNECTED); if (dcc_find_item(DCC_TYPE_SEND, target, fname)) { signal_emit("dcc error send exists", 2, target, fname); g_free(params); return; } str = convert_home(fname); if (!g_path_is_absolute(str)) { char *path; g_free(str); path = convert_home(settings_get_str("dcc_upload_path")); str = g_strconcat(path, G_DIR_SEPARATOR_S, fname, NULL); g_free(path); } hfile = open(str, O_RDONLY); g_free(str); if (hfile == -1) { signal_emit("dcc error file not found", 2, target, fname); g_free(params); return; } fsize = lseek(hfile, 0, SEEK_END); lseek(hfile, 0, SEEK_SET); /* get the IP address we use with IRC server */ if (net_getsockname(chat != NULL ? chat->handle : server->handle, &own_ip, NULL) == -1) { close(hfile); cmd_param_error(CMDERR_ERRNO); } /* start listening */ port = settings_get_int("dcc_port"); hlisten = net_listen(&own_ip, &port); if (hlisten == -1) { close(hfile); cmd_param_error(CMDERR_ERRNO); } /* skip path, change all spaces to _ */ fname = g_strdup(g_basename(fname)); for (ptr = fname; *ptr != '\0'; ptr++) if (*ptr == ' ') *ptr = '_'; dcc = dcc_create(DCC_TYPE_SEND, hlisten, target, fname, server, chat); dcc->port = port; dcc->size = fsize; dcc->fhandle = hfile; dcc->tagread = g_input_add(hlisten, G_INPUT_READ, (GInputFunction) dcc_send_init, dcc); /* send DCC request */ dcc_make_address(&own_ip, host); str = g_strdup_printf("DCC SEND %s %s %d %lu", fname, host, port, fsize); dcc_ctcp_message(target, server, chat, FALSE, str); g_free(str); g_free(fname); g_free(params); }
static int dcc_send_one_file(int queue, const char *target, const char *fname, IRC_SERVER_REC *server, CHAT_DCC_REC *chat) { struct stat st; char *str; char host[MAX_IP_LEN]; int hfile, port; SEND_DCC_REC *dcc; IPADDR own_ip; GIOChannel *handle; if (dcc_find_request(DCC_SEND_TYPE, target, fname)) { signal_emit("dcc error send exists", 2, target, fname); return FALSE; } str = dcc_send_get_file(fname); hfile = open(str, O_RDONLY); g_free(str); if (hfile == -1) { signal_emit("dcc error file open", 3, target, fname, GINT_TO_POINTER(errno)); return FALSE; } if (fstat(hfile, &st) < 0) { g_warning("fstat() failed: %s", strerror(errno)); close(hfile); return FALSE; } /* start listening */ handle = dcc_listen(chat != NULL ? chat->handle : net_sendbuffer_handle(server->handle), &own_ip, &port); if (handle == NULL) { close(hfile); g_warning("dcc_listen() failed: %s", strerror(errno)); return FALSE; } fname = g_basename(fname); /* Replace all the spaces with underscore so that lesser intellgent clients can communicate.. */ if (!settings_get_bool("dcc_send_replace_space_with_underscore")) str = NULL; else { str = g_strdup(fname); g_strdelimit(str, " ", '_'); fname = str; } dcc = dcc_send_create(server, chat, target, fname); g_free(str); dcc->handle = handle; dcc->port = port; dcc->size = st.st_size; dcc->fhandle = hfile; dcc->queue = queue; dcc->file_quoted = strchr(fname, ' ') != NULL; dcc->tagconn = g_input_add(handle, G_INPUT_READ, (GInputFunction) dcc_send_connected, dcc); /* send DCC request */ signal_emit("dcc request send", 1, dcc); dcc_ip2str(&own_ip, host); str = g_strdup_printf(dcc->file_quoted ? "DCC SEND \"%s\" %s %d %"PRIuUOFF_T : "DCC SEND %s %s %d %"PRIuUOFF_T, dcc->arg, host, port, dcc->size); dcc_ctcp_message(server, target, chat, FALSE, str); g_free(str); return TRUE; }