summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2002-11-21 17:48:40 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2002-11-21 17:48:40 +0000
commitdc8bd638e395eada4cdea03c5f1a1c28d506f003 (patch)
tree88d2a16cb750ef08c02975f41db3ea0bd149cd6d /src/irc
parentdc7efcb45bc7298a786bc8392adb488b3c704718 (diff)
downloadirssi-dc8bd638e395eada4cdea03c5f1a1c28d506f003.zip
Irssi now uses 64bit file offets if it's only supported by system. Also did
a few changes to DCC so that it should be possible to send >4GB files. DCC protocol uses 32bit "n bytes transferred" notifications, so I had to bend the protocol a bit to allow 64bit files by truncating the value to lowest 32bits. I'm not sure how other clients handle those notifications, but irssi uses it only to figure out when the DCC SEND transfer is complete, so it's quite safe to assume that if we've managed to write() all the bytes and we receive the last 32bit of file size, it means the total file size instead of the total - (n+1)*4GB. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3018 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/dcc/dcc-autoget.c2
-rw-r--r--src/irc/dcc/dcc-file-rec.h3
-rw-r--r--src/irc/dcc/dcc-get.c8
-rw-r--r--src/irc/dcc/dcc-rec.h2
-rw-r--r--src/irc/dcc/dcc-resume.c24
-rw-r--r--src/irc/dcc/dcc-send.c27
6 files changed, 33 insertions, 33 deletions
diff --git a/src/irc/dcc/dcc-autoget.c b/src/irc/dcc/dcc-autoget.c
index 459f2a75..87dd00d8 100644
--- a/src/irc/dcc/dcc-autoget.c
+++ b/src/irc/dcc/dcc-autoget.c
@@ -58,7 +58,7 @@ static void sig_dcc_request(GET_DCC_REC *dcc, const char *nickaddr)
/* check file size limit, NOTE: it's still possible to send a
bogus file size and then just send what ever sized file.. */
max_size = settings_get_int("dcc_autoget_max_size");
- if (max_size > 0 && (unsigned long) max_size*1024 < dcc->size)
+ if (max_size > 0 && (uoff_t)max_size*1024 < dcc->size)
return;
/* ok. but do we want/need to resume? */
diff --git a/src/irc/dcc/dcc-file-rec.h b/src/irc/dcc/dcc-file-rec.h
index a05dbc75..fe66a985 100644
--- a/src/irc/dcc/dcc-file-rec.h
+++ b/src/irc/dcc/dcc-file-rec.h
@@ -1,10 +1,9 @@
#include "dcc-rec.h"
-unsigned long size, skipped; /* file size / skipped at start */
+uoff_t size, skipped; /* file size / skipped at start */
int fhandle; /* file handle */
int queue; /* queue number */
/* counter buffer */
char count_buf[4];
int count_pos;
-
diff --git a/src/irc/dcc/dcc-get.c b/src/irc/dcc/dcc-get.c
index e8847698..9340645d 100644
--- a/src/irc/dcc/dcc-get.c
+++ b/src/irc/dcc/dcc-get.c
@@ -89,7 +89,7 @@ void dcc_get_send_received(GET_DCC_REC *dcc)
{
guint32 recd;
- recd = (guint32) htonl(dcc->transfd);
+ recd = (guint32) htonl(dcc->transfd & 0xffffffff);
memcpy(dcc->count_buf, &recd, 4);
dcc->count_pos =
@@ -133,7 +133,7 @@ static void sig_dccget_send(GET_DCC_REC *dcc)
}
memcpy(&recd, dcc->count_buf, 4);
- if (recd != (guint32) htonl(dcc->transfd))
+ if (recd != (guint32) htonl(dcc->transfd & 0xffffffff))
dcc_get_send_received(dcc);
}
@@ -323,7 +323,7 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data,
char **params, *fname;
int paramcount, fileparams;
int port, len, quoted = FALSE;
- long size;
+ uoff_t size;
/* SEND <file name> <address> <port> <size> [...] */
params = g_strsplit(data, " ", -1);
@@ -341,7 +341,7 @@ static void ctcp_msg_dcc_send(IRC_SERVER_REC *server, const char *data,
address = params[fileparams];
dcc_str2ip(address, &ip);
port = atoi(params[fileparams+1]);
- size = atol(params[fileparams+2]);
+ size = str_to_uofft(params[fileparams+2]);
params[fileparams] = NULL;
fname = g_strjoinv(" ", params);
diff --git a/src/irc/dcc/dcc-rec.h b/src/irc/dcc/dcc-rec.h
index 02cde37c..9fdd9582 100644
--- a/src/irc/dcc/dcc-rec.h
+++ b/src/irc/dcc/dcc-rec.h
@@ -18,7 +18,7 @@ int port; /* port we're connected in */
GIOChannel *handle; /* socket handle */
int tagconn, tagread, tagwrite;
time_t starttime; /* transfer start time */
-unsigned long transfd; /* bytes transferred */
+uoff_t transfd; /* bytes transferred */
unsigned int destroyed:1; /* We're about to destroy this DCC recond */
diff --git a/src/irc/dcc/dcc-resume.c b/src/irc/dcc/dcc-resume.c
index b273c54d..3cae3fa5 100644
--- a/src/irc/dcc/dcc-resume.c
+++ b/src/irc/dcc/dcc-resume.c
@@ -45,7 +45,7 @@ static FILE_DCC_REC *dcc_resume_find(int type, const char *nick, int port)
}
static int dcc_ctcp_resume_parse(int type, const char *data, const char *nick,
- FILE_DCC_REC **dcc, unsigned long *size)
+ FILE_DCC_REC **dcc, uoff_t *size)
{
char **params;
int paramcount;
@@ -57,7 +57,7 @@ static int dcc_ctcp_resume_parse(int type, const char *data, const char *nick,
if (paramcount >= 3) {
port = atoi(params[paramcount-2]);
- *size = strtoul(params[paramcount-1], NULL, 10);
+ *size = str_to_uofft(params[paramcount-1]);
*dcc = dcc_resume_find(type, nick, port);
}
@@ -66,14 +66,14 @@ static int dcc_ctcp_resume_parse(int type, const char *data, const char *nick,
}
static int dcc_resume_file_check(FILE_DCC_REC *dcc, IRC_SERVER_REC *server,
- unsigned long size)
+ uoff_t 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 */
+ } 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;
@@ -90,15 +90,15 @@ static void ctcp_msg_dcc_resume(IRC_SERVER_REC *server, const char *data,
{
FILE_DCC_REC *dcc;
char *str;
- unsigned long size;
+ uoff_t 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 ACCEPT \"%s\" %d %"PRIuUOFF_T :
+ "DCC ACCEPT %s %d %"PRIuUOFF_T,
dcc->arg, dcc->port, dcc->transfd);
dcc_ctcp_message(dcc->server, dcc->nick,
dcc->chat, FALSE, str);
@@ -112,7 +112,7 @@ static void ctcp_msg_dcc_accept(IRC_SERVER_REC *server, const char *data,
const char *target, DCC_REC *chat)
{
FILE_DCC_REC *dcc;
- unsigned long size;
+ uoff_t size;
if (!dcc_ctcp_resume_parse(DCC_GET_TYPE, data, nick, &dcc, &size) ||
(dcc != NULL && DCC_GET(dcc)->get_type != DCC_GET_RESUME)) {
@@ -141,7 +141,7 @@ static void dcc_send_resume(GET_DCC_REC *dcc)
dcc->get_type = DCC_GET_RESUME;
pos = lseek(dcc->fhandle, 0, SEEK_END);
- dcc->transfd = pos == (off_t)-1 ? 0 : (unsigned long) pos;
+ dcc->transfd = pos < 0 ? 0 : (uoff_t)pos;
dcc->skipped = dcc->transfd;
if (dcc->skipped == dcc->size) {
@@ -150,8 +150,8 @@ static void dcc_send_resume(GET_DCC_REC *dcc)
dcc_reject(DCC(dcc), NULL);
} else {
str = g_strdup_printf(dcc->file_quoted ?
- "DCC RESUME \"%s\" %d %lu" :
- "DCC RESUME %s %d %lu",
+ "DCC RESUME \"%s\" %d %"PRIuUOFF_T :
+ "DCC RESUME %s %d %"PRIuUOFF_T,
dcc->arg, dcc->port, dcc->transfd);
dcc_ctcp_message(dcc->server, dcc->nick,
dcc->chat, FALSE, str);
diff --git a/src/irc/dcc/dcc-send.c b/src/irc/dcc/dcc-send.c
index a75984ac..46e1dd4e 100644
--- a/src/irc/dcc/dcc-send.c
+++ b/src/irc/dcc/dcc-send.c
@@ -254,7 +254,6 @@ static void dcc_send_read_size(SEND_DCC_REC *dcc)
guint32 bytes;
int ret;
- /* we need to get 4 bytes.. */
ret = net_receive(dcc->handle, dcc->count_buf+dcc->count_pos,
4-dcc->count_pos);
if (ret == -1) {
@@ -267,14 +266,12 @@ static void dcc_send_read_size(SEND_DCC_REC *dcc)
if (dcc->count_pos != 4)
return;
- memcpy(&bytes, dcc->count_buf, 4);
- bytes = (guint32) ntohl(bytes);
-
- dcc->gotalldata = (unsigned long) bytes == dcc->transfd;
+ bytes = ntohl(*((guint32 *) dcc->count_buf));
dcc->count_pos = 0;
- if (dcc->waitforend && dcc->gotalldata) {
+ if (dcc->waitforend && bytes == (dcc->transfd & 0xffffffff)) {
/* file is sent */
+ dcc->gotalldata = TRUE;
dcc_close(DCC(dcc));
}
}
@@ -334,10 +331,10 @@ static char *dcc_send_get_file(const char *fname)
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;
- long fsize;
SEND_DCC_REC *dcc;
IPADDR own_ip;
GIOChannel *handle;
@@ -356,8 +353,12 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
GINT_TO_POINTER(errno));
return FALSE;
}
- fsize = lseek(hfile, 0, SEEK_END);
- lseek(hfile, 0, SEEK_SET);
+
+ 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 :
@@ -386,7 +387,7 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
dcc->handle = handle;
dcc->port = port;
- dcc->size = fsize;
+ dcc->size = st.st_size;
dcc->fhandle = hfile;
dcc->queue = queue;
dcc->file_quoted = strchr(fname, ' ') != NULL;
@@ -398,9 +399,9 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
dcc_ip2str(&own_ip, host);
str = g_strdup_printf(dcc->file_quoted ?
- "DCC SEND \"%s\" %s %d %lu" :
- "DCC SEND %s %s %d %lu",
- dcc->arg, host, port, fsize);
+ "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);