/* handle receiving DCC - GET/RESUME. */ void cmd_dcc_receive(const char *data, DCC_GET_FUNC accept_func, DCC_GET_FUNC pasv_accept_func) { GET_DCC_REC *dcc; GSList *tmp, *next; char *nick, *arg, *fname; void *free_arg; int found; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, &nick, &arg)) return; if (*nick == '\0') { dcc = DCC_GET(dcc_find_request_latest(DCC_GET_TYPE)); if (dcc != NULL) { if (!dcc_is_passive(dcc)) accept_func(dcc); else pasv_accept_func(dcc); } cmd_params_free(free_arg); return; } fname = cmd_get_quoted_param(&arg); found = FALSE; for (tmp = dcc_conns; tmp != NULL; tmp = next) { GET_DCC_REC *dcc = tmp->data; next = tmp->next; if (IS_DCC_GET(dcc) && g_ascii_strcasecmp(dcc->nick, nick) == 0 && (dcc_is_waiting_user(dcc) || dcc->from_dccserver) && (*fname == '\0' || g_strcmp0(dcc->arg, fname) == 0)) { found = TRUE; if (!dcc_is_passive(dcc)) accept_func(dcc); else pasv_accept_func(dcc); } } if (!found) signal_emit("dcc error get not found", 1, nick); cmd_params_free(free_arg); }
/* 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 void dcc_send_add(const char *servertag, CHAT_DCC_REC *chat, const char *nick, char *fileargs, int add_mode) { struct stat st; glob_t globbuf; char *fname; int i, ret, files, flags, queue, start_new_transfer; memset(&globbuf, 0, sizeof(globbuf)); flags = GLOB_NOCHECK | GLOB_TILDE; /* this loop parses all <file> parameters and adds them to glubbuf */ for (;;) { fname = cmd_get_quoted_param(&fileargs); if (*fname == '\0') break; if (glob(fname, flags, 0, &globbuf) < 0) break; /* this flag must not be set before first call to glob! (man glob) */ flags |= GLOB_APPEND; } files = 0; queue = -1; start_new_transfer = 0; /* add all globbed files to a proper queue */ for (i = 0; i < globbuf.gl_pathc; i++) { const char *fname = globbuf.gl_pathv[i]; ret = stat(fname, &st); if (ret == 0 && S_ISDIR(st.st_mode)) { /* we don't want directories */ errno = EISDIR; ret = -1; } if (ret < 0) { signal_emit("dcc error file open", 3, nick, fname, errno); continue; } if (queue < 0) { /* in append and prepend mode try to find an old queue. if an old queue is not found create a new queue. if not in append or prepend mode, create a new queue */ if (add_mode != DCC_QUEUE_NORMAL) queue = dcc_queue_old(nick, servertag); start_new_transfer = 0; if (queue < 0) { queue = dcc_queue_new(); start_new_transfer = 1; } } dcc_queue_add(queue, add_mode, nick, fname, servertag, chat); files++; } if (files > 0 && start_new_transfer) dcc_queue_send_next(queue); globfree(&globbuf); }