summaryrefslogtreecommitdiff
path: root/src/irc/dcc
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-01-02 16:14:19 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-01-02 16:14:19 +0000
commitbe4b473be51c11d071803870aee90e470028b8ae (patch)
tree6cb1ac0374f26f8c9db5271807f52a1713e3bbd7 /src/irc/dcc
parentd58ea58abcc0805f1b8ed2039db0bade7857d3f7 (diff)
downloadirssi-be4b473be51c11d071803870aee90e470028b8ae.zip
/SET dcc_autoresume - like /SET dcc_autoget, but resume the files if
they're already found. Also fixed file transfer being stuck when resuming file that was already fully sent (happened with both send and get). /dcc close was also broken. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1051 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc/dcc')
-rw-r--r--src/irc/dcc/dcc-files.c67
-rw-r--r--src/irc/dcc/dcc.c38
-rw-r--r--src/irc/dcc/dcc.h3
3 files changed, 74 insertions, 34 deletions
diff --git a/src/irc/dcc/dcc-files.c b/src/irc/dcc/dcc-files.c
index 04e393d7..37bec340 100644
--- a/src/irc/dcc/dcc-files.c
+++ b/src/irc/dcc/dcc-files.c
@@ -297,10 +297,14 @@ static void dcc_ctcp_msg(IRC_SERVER_REC *server, const char *data,
return;
}
- if (lseek(dcc->fhandle, size, SEEK_SET) != size) {
+ if (lseek(dcc->fhandle, 0, SEEK_END) == size) {
+ /* whole file sent */
+ dcc->starttime = time(NULL);
+ dcc_reject(dcc, server);
+ }
+ else if (lseek(dcc->fhandle, size, SEEK_SET) != size) {
/* error, or trying to seek after end of file */
- signal_emit("dcc closed", 1, dcc);
- dcc_destroy(dcc);
+ dcc_reject(dcc, server);
} else {
dcc->transfd = dcc->skipped = size;
@@ -319,20 +323,26 @@ static void dcc_resume_rec(DCC_REC *dcc)
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->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, NULL);
+ return;
+ }
+
str = g_strdup_printf("DCC RESUME %s %d %lu",
dcc->arg, dcc->port, dcc->transfd);
dcc_ctcp_message(dcc->server, dcc->nick, dcc->chat, FALSE, str);
@@ -343,7 +353,7 @@ static void dcc_resume_rec(DCC_REC *dcc)
static void cmd_dcc_resume(const char *data)
{
DCC_REC *dcc;
- GSList *tmp;
+ GSList *tmp, *next;
char *nick, *fname;
void *free_arg;
int found;
@@ -355,9 +365,10 @@ static void cmd_dcc_resume(const char *data)
if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
dcc = NULL; found = FALSE;
- for (tmp = dcc_conns; tmp != NULL; tmp = tmp->next) {
+ for (tmp = dcc_conns; tmp != NULL; tmp = next) {
dcc = tmp->data;
+ next = tmp->next;
if (dcc_is_unget(dcc) && g_strcasecmp(dcc->nick, nick) == 0 &&
(*fname == '\0' || strcmp(dcc->arg, fname) == 0)) {
dcc_resume_rec(dcc);
@@ -589,6 +600,44 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item)
cmd_params_free(free_arg);
}
+static void sig_dcc_request(DCC_REC *dcc, const char *nickaddr)
+{
+ struct stat statbuf;
+ const char *masks;
+ char *str, *file;
+ int max_size;
+
+ g_return_if_fail(dcc != NULL);
+ if (dcc->type != DCC_TYPE_GET) return;
+
+ /* check if we want to autoget file offer */
+ if (!settings_get_bool("dcc_autoget") &&
+ !settings_get_bool("dcc_autoresume"))
+ return;
+
+ /* check that autoget masks match */
+ masks = settings_get_str("dcc_autoget_masks");
+ if (*masks != '\0' &&
+ !masks_match(SERVER(dcc->server), masks, dcc->nick, nickaddr))
+ return;
+
+ /* check file size limit, FIXME: it's still possible to send a
+ bogus file size and then just send what ever sized file.. */
+ max_size = settings_get_int("dcc_max_autoget_size");
+ if (max_size > 0 && max_size*1024 < dcc->size)
+ return;
+
+ /* ok. but do we want/need to resume? */
+ file = dcc_get_download_path(dcc->arg);
+ str = g_strdup_printf(settings_get_bool("dcc_autoresume") &&
+ stat(file, &statbuf) == 0 ?
+ "RESUME %s %s" : "GET %s %s",
+ dcc->nick, dcc->arg);
+ signal_emit("command dcc", 2, str, dcc->server);
+ g_free(file);
+ g_free(str);
+}
+
static void read_settings(void)
{
dcc_file_create_mode = octal2dec(settings_get_int("dcc_file_create_mode"));
@@ -598,6 +647,7 @@ void dcc_files_init(void)
{
signal_add("ctcp msg dcc", (SIGNAL_FUNC) dcc_ctcp_msg);
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
+ signal_add_last("dcc request", (SIGNAL_FUNC) sig_dcc_request);
signal_add("irssi init finished", (SIGNAL_FUNC) read_settings);
command_bind("dcc send", NULL, (SIGNAL_FUNC) cmd_dcc_send);
command_bind("dcc get", NULL, (SIGNAL_FUNC) cmd_dcc_get);
@@ -608,6 +658,7 @@ void dcc_files_deinit(void)
{
signal_remove("ctcp msg dcc", (SIGNAL_FUNC) dcc_ctcp_msg);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
+ signal_remove("dcc request", (SIGNAL_FUNC) sig_dcc_request);
signal_remove("irssi init finished", (SIGNAL_FUNC) read_settings);
command_unbind("dcc send", (SIGNAL_FUNC) cmd_dcc_send);
command_unbind("dcc get", (SIGNAL_FUNC) cmd_dcc_get);
diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c
index de8601d5..1d0fc2dc 100644
--- a/src/irc/dcc/dcc.c
+++ b/src/irc/dcc/dcc.c
@@ -287,7 +287,7 @@ static void dcc_ctcp_msg(IRC_SERVER_REC *server, char *data,
{
char *type, *arg, *addrstr, *portstr, *sizestr, *str;
void *free_arg;
- const char *cstr;
+ const char *masks;
DCC_REC *dcc, *olddcc;
long size;
int dcctype, port;
@@ -331,39 +331,23 @@ static void dcc_ctcp_msg(IRC_SERVER_REC *server, char *data,
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);
- }
+ /* send request */
+ signal_emit("dcc request", 2, dcc, sendaddr);
break;
case DCC_TYPE_CHAT:
- cstr = settings_get_str("dcc_autochat_masks");
+ /* send request */
+ signal_emit("dcc request", 2, dcc, sendaddr);
+
+ masks = settings_get_str("dcc_autochat_masks");
if (olddcc != NULL ||
- (*cstr != '\0' && masks_match(SERVER(server), cstr, sender, sendaddr)))
+ (*masks != '\0' && masks_match(SERVER(server), masks, 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:
@@ -416,7 +400,8 @@ static void dcc_ctcp_reply(IRC_SERVER_REC *server, char *data,
cmd_params_free(free_arg);
}
-static void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server)
+/* reject DCC request */
+void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server)
{
char *str;
@@ -438,7 +423,7 @@ static void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server)
}
/* SYNTAX: DCC CLOSE <type> <nick> [<file>] */
-static void cmd_dcc_close(IRC_SERVER_REC *server, char *data)
+static void cmd_dcc_close(char *data, IRC_SERVER_REC *server)
{
DCC_REC *dcc;
GSList *tmp, *next;
@@ -540,6 +525,7 @@ void irc_dcc_init(void)
settings_add_bool("dcc", "dcc_autorename", FALSE);
settings_add_bool("dcc", "dcc_autoget", FALSE);
+ settings_add_bool("dcc", "dcc_autoresume", FALSE);
settings_add_int("dcc", "dcc_max_autoget_size", 1000);
settings_add_str("dcc", "dcc_download_path", "~");
settings_add_int("dcc", "dcc_file_create_mode", 644);
diff --git a/src/irc/dcc/dcc.h b/src/irc/dcc/dcc.h
index 8aef0c82..686f65a5 100644
--- a/src/irc/dcc/dcc.h
+++ b/src/irc/dcc/dcc.h
@@ -94,4 +94,7 @@ void dcc_chat_send(DCC_REC *dcc, const char *data);
/* If `item' is a query of a =nick, return DCC chat record of nick */
DCC_REC *item_get_dcc(void *item);
+/* reject DCC request */
+void dcc_reject(DCC_REC *dcc, IRC_SERVER_REC *server);
+
#endif