summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2004-09-08 16:56:56 +0000
committerSebastien Helleu <flashcode@flashtux.org>2004-09-08 16:56:56 +0000
commit92eb995917d43a7e4fe9afeb8516424ba7e72fc7 (patch)
treec0d3574874721fb6ea80e042cf0d99dae1059527 /src/irc
parent1425ee40f48630dd5e040b1123760b3aa903245c (diff)
downloadweechat-92eb995917d43a7e4fe9afeb8516424ba7e72fc7.zip
Receive DCC packets (for DCC file)
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/irc-dcc.c104
-rw-r--r--src/irc/irc.h1
2 files changed, 103 insertions, 2 deletions
diff --git a/src/irc/irc-dcc.c b/src/irc/irc-dcc.c
index d2276ef7c..6b6bf97bc 100644
--- a/src/irc/irc-dcc.c
+++ b/src/irc/irc-dcc.c
@@ -25,7 +25,12 @@
#endif
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
#include "../common/weechat.h"
#include "irc.h"
@@ -44,8 +49,21 @@ char *dcc_status_string[] = /* strings for DCC status */
*/
void
-dcc_connect ()
+dcc_connect (t_dcc *dcc)
{
+ struct sockaddr_in addr;
+
+ dcc->status = DCC_CONNECTING;
+
+ dcc->sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (dcc->sock == -1)
+ return;
+ memset (&addr, 0, sizeof (addr));
+ addr.sin_port = htons (dcc->port);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl (dcc->addr);
+ fcntl (dcc->sock, F_SETFL, O_NONBLOCK);
+ connect (dcc->sock, (struct sockaddr *) &addr, sizeof (addr));
}
/*
@@ -87,10 +105,11 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
}
new_dcc->server = server;
new_dcc->type = type;
- new_dcc->status = DCC_ACTIVE;
+ new_dcc->status = DCC_WAITING;
new_dcc->addr = addr;
new_dcc->port = port;
new_dcc->nick = strdup (nick);
+ new_dcc->sock = -1;
new_dcc->file = -1;
new_dcc->filename = strdup (filename);
new_dcc->size = size;
@@ -103,5 +122,86 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
type, nick,
addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff,
port, filename, size);
+
+ if (type == DCC_FILE_RECV)
+ {
+ dcc_connect (new_dcc);
+ if (new_dcc->sock == -1)
+ new_dcc->status = DCC_FAILED;
+ else
+ new_dcc->status = DCC_ACTIVE;
+ }
+
+
return new_dcc;
}
+
+/*
+ * dcc_handle: receive/send data for each active DCC
+ */
+
+void
+dcc_handle ()
+{
+ t_dcc *ptr_dcc;
+ int num;
+ char buffer[8192];
+ uint32_t pos;
+
+ for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
+ {
+ if (ptr_dcc->status == DCC_ACTIVE)
+ {
+ if (ptr_dcc->type == DCC_FILE_RECV)
+ {
+ num = recv (ptr_dcc->sock, buffer, sizeof (buffer), 0);
+ if (num != -1)
+ {
+ if (num == 0)
+ {
+ ptr_dcc->status = DCC_FAILED;
+ close (ptr_dcc->sock);
+ ptr_dcc->sock = -1;
+ }
+ else
+ {
+ gui_printf (NULL, "DCC: file \"%s\": %d bytes received\n",
+ ptr_dcc->filename, num);
+ ptr_dcc->pos += (unsigned long) num;
+ pos = htonl (ptr_dcc->pos);
+ send (ptr_dcc->sock, (char *) &pos, 4, 0);
+ if (ptr_dcc->pos >= ptr_dcc->size)
+ {
+ ptr_dcc->status = DCC_DONE;
+ gui_printf (NULL, "DCC: file \"%s\": done!\n",
+ ptr_dcc->filename);
+ close (ptr_dcc->sock);
+ ptr_dcc->sock = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * dcc_end: close all opened sockets (called when WeeChat is exiting)
+ */
+
+void
+dcc_end ()
+{
+ t_dcc *ptr_dcc;
+
+ for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
+ {
+ if (ptr_dcc->sock != -1)
+ {
+ if (ptr_dcc->status == DCC_ACTIVE)
+ wee_log_printf (_("aborting active DCC: \"%s\" from %s\n"),
+ ptr_dcc->filename, ptr_dcc->nick);
+ close (ptr_dcc->sock);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/irc/irc.h b/src/irc/irc.h
index e3f08440a..905e87952 100644
--- a/src/irc/irc.h
+++ b/src/irc/irc.h
@@ -184,6 +184,7 @@ struct t_dcc
unsigned long addr; /* IP address */
int port; /* port */
char *nick; /* remote nick */
+ int sock; /* socket for connection */
int file; /* local file (for reading or writing) */
char *filename; /* local filename */
unsigned long size; /* file size */