summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/irc-channel.c56
-rw-r--r--src/irc/irc-commands.c8
-rw-r--r--src/irc/irc-dcc.c631
-rw-r--r--src/irc/irc-display.c26
-rw-r--r--src/irc/irc-recv.c275
-rw-r--r--src/irc/irc-send.c65
-rw-r--r--src/irc/irc-server.c38
-rw-r--r--src/irc/irc.h19
8 files changed, 811 insertions, 307 deletions
diff --git a/src/irc/irc-channel.c b/src/irc/irc-channel.c
index c4ba4e9b2..10faf44b0 100644
--- a/src/irc/irc-channel.c
+++ b/src/irc/irc-channel.c
@@ -25,6 +25,7 @@
#endif
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
#include "../common/weechat.h"
@@ -53,6 +54,7 @@ channel_new (t_irc_server *server, int channel_type, char *channel_name,
/* initialize new channel */
new_channel->type = channel_type;
+ new_channel->dcc_chat = NULL;
new_channel->name = strdup (channel_name);
new_channel->topic = NULL;
memset (new_channel->modes, ' ', sizeof (new_channel->modes));
@@ -101,6 +103,14 @@ channel_free (t_irc_server *server, t_irc_channel *channel)
if (channel->next_channel)
(channel->next_channel)->prev_channel = channel->prev_channel;
+ /* close DCC CHAT */
+ if ((t_irc_dcc *)(channel->dcc_chat) &&
+ (!DCC_ENDED(((t_irc_dcc *)(channel->dcc_chat))->status)))
+ {
+ dcc_close ((t_irc_dcc *)(channel->dcc_chat), DCC_ABORTED);
+ dcc_redraw (1);
+ }
+
/* free data */
if (channel->name)
free (channel->name);
@@ -204,3 +214,49 @@ channel_set_away (t_irc_channel *channel, char *nick, int is_away)
nick_set_away (channel, ptr_nick, is_away);
}
}
+
+/*
+ * channel_create_dcc: create DCC CHAT channel
+ */
+
+int
+channel_create_dcc (t_irc_dcc *ptr_dcc)
+{
+ t_irc_channel *ptr_channel;
+
+ ptr_channel = channel_search (ptr_dcc->server, ptr_dcc->nick);
+ if (!ptr_channel)
+ ptr_channel = channel_new (ptr_dcc->server, CHAT_PRIVATE,
+ ptr_dcc->nick, 0);
+ if (!ptr_channel)
+ return 0;
+
+ if (ptr_channel->dcc_chat &&
+ (!DCC_ENDED(((t_irc_dcc *)(ptr_channel->dcc_chat))->status)))
+ return 0;
+
+ ptr_channel->dcc_chat = ptr_dcc;
+ ptr_dcc->channel = ptr_channel;
+ gui_redraw_buffer (ptr_channel->buffer);
+ return 1;
+}
+
+/*
+ * channel_remove_dcc: remove a DCC CHAT
+ */
+
+void
+channel_remove_dcc (t_irc_dcc *ptr_dcc)
+{
+ t_irc_channel *ptr_channel;
+
+ for (ptr_channel = ptr_dcc->server->channels; ptr_channel;
+ ptr_channel = ptr_channel->next_channel)
+ {
+ if ((t_irc_dcc *)(ptr_channel->dcc_chat) == ptr_dcc)
+ {
+ ptr_channel->dcc_chat = NULL;
+ gui_redraw_buffer (ptr_channel->buffer);
+ }
+ }
+}
diff --git a/src/irc/irc-commands.c b/src/irc/irc-commands.c
index 88cc8065b..54ea5c843 100644
--- a/src/irc/irc-commands.c
+++ b/src/irc/irc-commands.c
@@ -44,12 +44,12 @@ t_irc_command irc_commands[] =
N_("nickname type"),
N_("nickname: user to send ctcp to\ntype: \"action\" or \"version\""),
2, MAX_ARGS, 1, NULL, irc_cmd_send_ctcp, NULL },
- { "dcc", N_("starts DCC (file or chat)"),
- N_("action nickname [file]"),
- N_("action: 'send' (file) or 'chat'\n"
+ { "dcc", N_("starts DCC (file or chat) or close chat"),
+ N_("action [nickname [file]]"),
+ N_("action: 'send' (file) or 'chat' or 'close' (chat)\n"
"nickname: nickname to send file or chat\n"
"file: filename (on local host)"),
- 2, MAX_ARGS, 1, NULL, irc_cmd_send_dcc, NULL },
+ 1, MAX_ARGS, 1, NULL, irc_cmd_send_dcc, NULL },
{ "deop", N_("removes channel operator status from nickname(s)"),
N_("nickname [nickname]"), "",
1, MAX_ARGS, 1, irc_cmd_send_deop, NULL, NULL },
diff --git a/src/irc/irc-dcc.c b/src/irc/irc-dcc.c
index 2d51c7e1a..6cc21774f 100644
--- a/src/irc/irc-dcc.c
+++ b/src/irc/irc-dcc.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -70,7 +71,10 @@ dcc_connect (t_irc_dcc *ptr_dcc)
{
struct sockaddr_in addr;
- ptr_dcc->status = DCC_CONNECTING;
+ if (ptr_dcc->type == DCC_CHAT_SEND)
+ ptr_dcc->status = DCC_WAITING;
+ else
+ ptr_dcc->status = DCC_CONNECTING;
if (ptr_dcc->sock == -1)
{
@@ -81,8 +85,8 @@ dcc_connect (t_irc_dcc *ptr_dcc)
if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1)
return 0;
- /* for DCC SEND, listen to socket for a connection */
- if (ptr_dcc->type == DCC_FILE_SEND)
+ /* for sending (chat or file), listen to socket for a connection */
+ if (DCC_IS_SEND(ptr_dcc->type))
{
if (listen (ptr_dcc->sock, 1) == -1)
return 0;
@@ -90,8 +94,8 @@ dcc_connect (t_irc_dcc *ptr_dcc)
return 0;
}
- /* for DCC RECV, connect to listening host */
- if (ptr_dcc->type == DCC_FILE_RECV)
+ /* for receiving (chat or file), connect to listening host */
+ if (DCC_IS_RECV(ptr_dcc->type))
{
memset (&addr, 0, sizeof (addr));
addr.sin_port = htons (ptr_dcc->port);
@@ -125,6 +129,8 @@ dcc_free (t_irc_dcc *ptr_dcc)
if (ptr_dcc->nick)
free (ptr_dcc->nick);
+ if (ptr_dcc->unterminated_message)
+ free (ptr_dcc->unterminated_message);
if (ptr_dcc->filename)
free (ptr_dcc->filename);
@@ -143,7 +149,7 @@ dcc_close (t_irc_dcc *ptr_dcc, int status)
if (status == DCC_DONE)
{
- if ((ptr_dcc->type == DCC_FILE_SEND) || (ptr_dcc->type == DCC_FILE_RECV))
+ if (DCC_IS_FILE(ptr_dcc->type))
{
irc_display_prefix (ptr_dcc->server->buffer, PREFIX_INFO);
gui_printf (ptr_dcc->server->buffer, _("DCC: file "));
@@ -167,6 +173,25 @@ dcc_close (t_irc_dcc *ptr_dcc, int status)
gui_printf (ptr_dcc->server->buffer, _(": ok!\n"));
}
}
+ if (status == DCC_ABORTED)
+ {
+ if (DCC_IS_CHAT(ptr_dcc->type))
+ {
+ irc_display_prefix (ptr_dcc->channel->buffer, PREFIX_INFO);
+ gui_printf (ptr_dcc->channel->buffer, _("DCC chat closed with "));
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_NICK,
+ "%s", ptr_dcc->nick);
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_DARK, " (");
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_HOST,
+ "%d.%d.%d.%d",
+ ptr_dcc->addr >> 24, (ptr_dcc->addr >> 16) & 0xff,
+ (ptr_dcc->addr >> 8) & 0xff, ptr_dcc->addr & 0xff);
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_DARK, ")\n");
+ }
+ }
+
+ if (DCC_IS_CHAT(ptr_dcc->type))
+ channel_remove_dcc (ptr_dcc);
if (ptr_dcc->sock != -1)
{
@@ -181,6 +206,39 @@ dcc_close (t_irc_dcc *ptr_dcc, int status)
}
/*
+ * dcc_channel_for_chat: create channel for DCC chat
+ */
+
+void
+dcc_channel_for_chat (t_irc_dcc *ptr_dcc)
+{
+ if (!channel_create_dcc (ptr_dcc))
+ {
+ irc_display_prefix (ptr_dcc->server->buffer, PREFIX_ERROR);
+ gui_printf (ptr_dcc->server->buffer,
+ _("%s can't associate DCC chat with private buffer "
+ "(maybe private buffer has already DCC CHAT?)\n"),
+ WEECHAT_ERROR);
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+
+ irc_display_prefix (ptr_dcc->channel->buffer, PREFIX_INFO);
+ gui_printf_type (ptr_dcc->channel->buffer, MSG_TYPE_MSG,
+ _("Connected to "));
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_NICK,
+ "%s", ptr_dcc->nick);
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_DARK, " (");
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_HOST,
+ "%d.%d.%d.%d",
+ ptr_dcc->addr >> 24, (ptr_dcc->addr >> 16) & 0xff,
+ (ptr_dcc->addr >> 8) & 0xff, ptr_dcc->addr & 0xff);
+ gui_printf_color (ptr_dcc->channel->buffer, COLOR_WIN_CHAT_DARK, ") ");
+ gui_printf (ptr_dcc->channel->buffer, _("via DCC chat\n"));
+}
+
+/*
* dcc_accept: accepts a DCC file or chat request
*/
@@ -197,67 +255,77 @@ dcc_accept (t_irc_dcc *ptr_dcc)
else
{
ptr_dcc->status = DCC_ACTIVE;
- ptr_home = getenv ("HOME");
- ptr_dcc->local_filename = (char *) malloc (strlen (cfg_dcc_download_path) +
- strlen (ptr_dcc->nick) +
- strlen (ptr_dcc->filename) +
- ((cfg_dcc_download_path[0] == '~') ?
- strlen (ptr_home) : 0) +
- 4);
- if (!ptr_dcc->local_filename)
- {
- dcc_close (ptr_dcc, DCC_FAILED);
- dcc_redraw (1);
- return;
- }
- if (cfg_dcc_download_path[0] == '~')
- {
- strcpy (ptr_dcc->local_filename, ptr_home);
- strcat (ptr_dcc->local_filename, cfg_dcc_download_path + 1);
- }
- else
- strcpy (ptr_dcc->local_filename, cfg_dcc_download_path);
- if (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != DIR_SEPARATOR_CHAR)
- strcat (ptr_dcc->local_filename, DIR_SEPARATOR);
- strcat (ptr_dcc->local_filename, ptr_dcc->nick);
- strcat (ptr_dcc->local_filename, ".");
- strcat (ptr_dcc->local_filename, ptr_dcc->filename);
- /* file already exists? */
- if (access (ptr_dcc->local_filename, F_OK) == 0)
+ /* DCC file => look for local filename and open it in writing mode */
+ if (DCC_IS_FILE(ptr_dcc->type))
{
- /* if auto rename is not set, then abort DCC */
- if (!cfg_dcc_auto_rename)
+ ptr_home = getenv ("HOME");
+ ptr_dcc->local_filename = (char *) malloc (strlen (cfg_dcc_download_path) +
+ strlen (ptr_dcc->nick) +
+ strlen (ptr_dcc->filename) +
+ ((cfg_dcc_download_path[0] == '~') ?
+ strlen (ptr_home) : 0) +
+ 4);
+ if (!ptr_dcc->local_filename)
{
dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
return;
}
-
- filename2 = (char *) malloc (strlen (ptr_dcc->local_filename) + 16);
- if (!filename2)
+ if (cfg_dcc_download_path[0] == '~')
{
- dcc_close (ptr_dcc, DCC_FAILED);
- dcc_redraw (1);
- return;
+ strcpy (ptr_dcc->local_filename, ptr_home);
+ strcat (ptr_dcc->local_filename, cfg_dcc_download_path + 1);
}
- ptr_dcc->filename_suffix = 0;
- do
+ else
+ strcpy (ptr_dcc->local_filename, cfg_dcc_download_path);
+ if (ptr_dcc->local_filename[strlen (ptr_dcc->local_filename) - 1] != DIR_SEPARATOR_CHAR)
+ strcat (ptr_dcc->local_filename, DIR_SEPARATOR);
+ strcat (ptr_dcc->local_filename, ptr_dcc->nick);
+ strcat (ptr_dcc->local_filename, ".");
+ strcat (ptr_dcc->local_filename, ptr_dcc->filename);
+
+ /* file already exists? */
+ if (access (ptr_dcc->local_filename, F_OK) == 0)
{
- ptr_dcc->filename_suffix++;
- sprintf (filename2, "%s.%d",
- ptr_dcc->local_filename,
- ptr_dcc->filename_suffix);
+ /* if auto rename is not set, then abort DCC */
+ if (!cfg_dcc_auto_rename)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+
+ filename2 = (char *) malloc (strlen (ptr_dcc->local_filename) + 16);
+ if (!filename2)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ ptr_dcc->filename_suffix = 0;
+ do
+ {
+ ptr_dcc->filename_suffix++;
+ sprintf (filename2, "%s.%d",
+ ptr_dcc->local_filename,
+ ptr_dcc->filename_suffix);
+ }
+ while (access (filename2, F_OK) == 0);
+
+ free (ptr_dcc->local_filename);
+ ptr_dcc->local_filename = strdup (filename2);
+ free (filename2);
}
- while (access (filename2, F_OK) == 0);
-
- free (ptr_dcc->local_filename);
- ptr_dcc->local_filename = strdup (filename2);
- free (filename2);
+ ptr_dcc->file = open (ptr_dcc->local_filename,
+ O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
+ 0644);
+ }
+ else
+ {
+ /* DCC CHAT => associate DCC with channel */
+ dcc_channel_for_chat (ptr_dcc);
}
- ptr_dcc->file = open (ptr_dcc->local_filename,
- O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
- 0644);
}
dcc_redraw (1);
}
@@ -272,22 +340,31 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
{
t_irc_dcc *new_dcc;
+ /* create new DCC struct */
if ((new_dcc = (t_irc_dcc *) malloc (sizeof (t_irc_dcc))) == NULL)
{
- gui_printf_nolog (server->buffer,
- _("%s not enough memory for new DCC\n"),
- WEECHAT_ERROR);
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s not enough memory for new DCC\n"),
+ WEECHAT_ERROR);
return NULL;
}
+
+ /* initialize new DCC */
new_dcc->server = server;
+ new_dcc->channel = NULL;
new_dcc->type = type;
new_dcc->status = DCC_WAITING;
new_dcc->addr = addr;
new_dcc->port = port;
new_dcc->nick = strdup (nick);
new_dcc->sock = sock;
+ new_dcc->unterminated_message = NULL;
new_dcc->file = -1;
- new_dcc->filename = strdup (filename);
+ if (DCC_IS_CHAT(type))
+ new_dcc->filename = strdup (_("DCC chat"));
+ else
+ new_dcc->filename = (filename) ? strdup (filename) : NULL;
new_dcc->local_filename = (local_filename) ? strdup (local_filename) : NULL;
new_dcc->filename_suffix = -1;
new_dcc->size = size;
@@ -302,6 +379,7 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
gui_current_window->dcc_first = NULL;
gui_current_window->dcc_selected = NULL;
+ /* write info message on server buffer */
if (type == DCC_FILE_RECV)
{
irc_display_prefix (server->buffer, PREFIX_INFO);
@@ -318,17 +396,11 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);
gui_printf (server->buffer, _(" bytes\n"));
}
-
if (type == DCC_FILE_SEND)
{
irc_display_prefix (server->buffer, PREFIX_INFO);
gui_printf (server->buffer, _("Sending DCC file to "));
gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK, "%s", nick);
- gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, " (");
- gui_printf_color (server->buffer, COLOR_WIN_CHAT_HOST,
- "%d.%d.%d.%d",
- addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
- gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, ")");
gui_printf (server->buffer, ": ");
gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%s", filename);
gui_printf (server->buffer, _(" (local filename: "));
@@ -337,8 +409,26 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);
gui_printf (server->buffer, _(" bytes\n"));
}
+ if (type == DCC_CHAT_RECV)
+ {
+ irc_display_prefix (server->buffer, PREFIX_INFO);
+ gui_printf (server->buffer, _("Incoming DCC chat request from "));
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK, "%s", nick);
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, " (");
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_HOST,
+ "%d.%d.%d.%d",
+ addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_DARK, ")\n");
+ }
+ if (type == DCC_CHAT_SEND)
+ {
+ irc_display_prefix (server->buffer, PREFIX_INFO);
+ gui_printf (server->buffer, _("Sending DCC chat request to "));
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK, "%s\n", nick);
+ }
- if (type == DCC_FILE_SEND)
+ /* connect if needed and redraw DCC buffer */
+ if (DCC_IS_SEND(type))
{
if (!dcc_connect (new_dcc))
{
@@ -358,11 +448,11 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
}
/*
- * dcc_send: send DCC request (file or chat)
+ * dcc_send_request: send DCC request (file or chat)
*/
void
-dcc_send (t_irc_server *server, char *nick, char *filename)
+dcc_send_request (t_irc_server *server, int type, char *nick, char *filename)
{
char *ptr_home, *filename2, *short_filename, *pos;
int spaces;
@@ -371,57 +461,66 @@ dcc_send (t_irc_server *server, char *nick, char *filename)
struct sockaddr_in addr;
socklen_t length;
unsigned long local_addr;
+ t_irc_dcc *ptr_dcc;
- /* add home if filename not beginning with '/' (not for Win32) */
- #ifdef _WIN32
- filename2 = strdup (filename);
- #else
- if (filename[0] == '/')
- filename2 = strdup (filename);
- else
+ filename2 = NULL;
+ short_filename = NULL;
+ spaces = 0;
+
+ if (type == DCC_FILE_SEND)
{
- ptr_home = getenv ("HOME");
- filename2 = (char *) malloc (strlen (cfg_dcc_upload_path) +
- strlen (filename) +
- ((cfg_dcc_upload_path[0] == '~') ?
- strlen (ptr_home) : 0) +
- 4);
- if (!filename2)
+ /* add home if filename not beginning with '/' (not for Win32) */
+ #ifdef _WIN32
+ filename2 = strdup (filename);
+ #else
+ if (filename[0] == '/')
+ filename2 = strdup (filename);
+ else
{
- irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s not enough memory for DCC SEND\n"),
- WEECHAT_ERROR);
- return;
+ ptr_home = getenv ("HOME");
+ filename2 = (char *) malloc (strlen (cfg_dcc_upload_path) +
+ strlen (filename) +
+ ((cfg_dcc_upload_path[0] == '~') ?
+ strlen (ptr_home) : 0) +
+ 4);
+ if (!filename2)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s not enough memory for DCC SEND\n"),
+ WEECHAT_ERROR);
+ return;
+ }
+ if (cfg_dcc_upload_path[0] == '~')
+ {
+ strcpy (filename2, ptr_home);
+ strcat (filename2, cfg_dcc_upload_path + 1);
+ }
+ else
+ strcpy (filename2, cfg_dcc_upload_path);
+ if (filename2[strlen (filename2) - 1] != DIR_SEPARATOR_CHAR)
+ strcat (filename2, DIR_SEPARATOR);
+ strcat (filename2, filename);
}
- if (cfg_dcc_upload_path[0] == '~')
+ #endif
+
+ /* check if file exists */
+ if (stat (filename2, &st) == -1)
{
- strcpy (filename2, ptr_home);
- strcat (filename2, cfg_dcc_upload_path + 1);
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot access file \"%s\"\n"),
+ WEECHAT_ERROR, filename2);
+ if (filename2)
+ free (filename2);
+ return;
}
- else
- strcpy (filename2, cfg_dcc_upload_path);
- if (filename2[strlen (filename2) - 1] != DIR_SEPARATOR_CHAR)
- strcat (filename2, DIR_SEPARATOR);
- strcat (filename2, filename);
- }
- #endif
-
- /* check if file exists */
- if (stat (filename2, &st) == -1)
- {
- irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot access file \"%s\"\n"),
- WEECHAT_ERROR, filename2);
- free (filename2);
- return;
}
/* get local IP address */
memset (&addr, 0, sizeof (struct sockaddr_in));
length = sizeof (addr);
- getsockname (server->sock4, (struct sockaddr *) &addr, &length);
+ getsockname (server->sock, (struct sockaddr *) &addr, &length);
addr.sin_family = AF_INET;
local_addr = ntohl (addr.sin_addr.s_addr);
@@ -430,10 +529,11 @@ dcc_send (t_irc_server *server, char *nick, char *filename)
if (sock == -1)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot create socket for DCC\n"),
- WEECHAT_ERROR);
- free (filename2);
+ gui_printf (server->buffer,
+ _("%s cannot create socket for DCC\n"),
+ WEECHAT_ERROR);
+ if (filename2)
+ free (filename2);
return;
}
@@ -442,68 +542,243 @@ dcc_send (t_irc_server *server, char *nick, char *filename)
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot find port for DCC\n"),
- WEECHAT_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot find port for DCC\n"),
+ WEECHAT_ERROR);
close (sock);
- free (filename2);
+ if (filename2)
+ free (filename2);
return;
}
length = sizeof (addr);
getsockname (sock, (struct sockaddr *) &addr, &length);
port = ntohs (addr.sin_port);
- /* extract short filename (without path) */
- pos = strrchr (filename2, DIR_SEPARATOR_CHAR);
- if (pos)
- short_filename = strdup (pos + 1);
- else
- short_filename = strdup (filename2);
-
- /* convert spaces to underscore if asked and needed */
- pos = short_filename;
- spaces = 0;
- while (pos[0])
+ if (type == DCC_FILE_SEND)
{
- if (pos[0] == ' ')
+ /* extract short filename (without path) */
+ pos = strrchr (filename2, DIR_SEPARATOR_CHAR);
+ if (pos)
+ short_filename = strdup (pos + 1);
+ else
+ short_filename = strdup (filename2);
+
+ /* convert spaces to underscore if asked and needed */
+ pos = short_filename;
+ spaces = 0;
+ while (pos[0])
{
- if (cfg_dcc_convert_spaces)
- pos[0] = '_';
- else
- spaces = 1;
+ if (pos[0] == ' ')
+ {
+ if (cfg_dcc_convert_spaces)
+ pos[0] = '_';
+ else
+ spaces = 1;
+ }
+ pos++;
}
- pos++;
}
/* add DCC entry and listen to socket */
- if (!dcc_add (server, DCC_FILE_SEND, local_addr, port, nick, sock,
- short_filename, filename2, st.st_size))
+ if (type == DCC_CHAT_SEND)
+ ptr_dcc = dcc_add (server, DCC_CHAT_SEND, local_addr, port, nick, sock,
+ NULL, NULL, 0);
+ else
+ ptr_dcc = dcc_add (server, DCC_FILE_SEND, local_addr, port, nick, sock,
+ short_filename, filename2, st.st_size);
+ if (!ptr_dcc)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot send DCC\n"),
- WEECHAT_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot send DCC\n"),
+ WEECHAT_ERROR);
close (sock);
- free (short_filename);
- free (filename2);
+ if (short_filename)
+ free (short_filename);
+ if (filename2)
+ free (filename2);
return;
}
/* send DCC request to nick */
- server_sendf (server,
- (spaces) ?
- "PRIVMSG %s :\01DCC SEND \"%s\" %lu %d %u\01\r\n" :
- "PRIVMSG %s :\01DCC SEND %s %lu %d %u\01\r\n",
- nick, short_filename, local_addr, port,
- (unsigned long) st.st_size);
-
- free (short_filename);
- free (filename2);
+ if (type == DCC_CHAT_SEND)
+ server_sendf (server,
+ "PRIVMSG %s :\01DCC CHAT chat %lu %d\01\r\n",
+ nick, local_addr, port);
+ else
+ server_sendf (server,
+ (spaces) ?
+ "PRIVMSG %s :\01DCC SEND \"%s\" %lu %d %u\01\r\n" :
+ "PRIVMSG %s :\01DCC SEND %s %lu %d %u\01\r\n",
+ nick, short_filename, local_addr, port,
+ (unsigned long) st.st_size);
+
+ if (short_filename)
+ free (short_filename);
+ if (filename2)
+ free (filename2);
}
+/*
+ * dcc_chat_send: send data to remote host via DCC CHAT
+ */
+
+int
+dcc_chat_send (t_irc_dcc *ptr_dcc, char *buffer, int size_buf)
+{
+ if (!ptr_dcc)
+ return -1;
+
+ return send (ptr_dcc->sock, buffer, size_buf, 0);
+}
+
+/*
+ * dcc_chat_sendf: send formatted data to remote host via DCC CHAT
+ */
+
+void
+dcc_chat_sendf (t_irc_dcc *ptr_dcc, char *fmt, ...)
+{
+ va_list args;
+ static char buffer[4096];
+ char *buf2;
+ int size_buf;
+
+ if (!ptr_dcc || (ptr_dcc->sock == -1))
+ return;
+
+ va_start (args, fmt);
+ size_buf = vsnprintf (buffer, sizeof (buffer) - 1, fmt, args);
+ va_end (args);
+
+ if ((size_buf == 0) || (strcmp (buffer, "\r\n") == 0))
+ return;
+
+ buffer[sizeof (buffer) - 1] = '\0';
+ if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))
+ size_buf = strlen (buffer);
+ #ifdef DEBUG
+ buffer[size_buf - 2] = '\0';
+ gui_printf (ptr_dcc->server->buffer, "[DEBUG] Sending to remote host (DCC CHAT) >>> %s\n", buffer);
+ buffer[size_buf - 2] = '\r';
+ #endif
+ buf2 = weechat_convert_encoding ((cfg_look_charset_internal && cfg_look_charset_internal[0]) ?
+ cfg_look_charset_internal : local_charset,
+ cfg_look_charset_encode,
+ buffer);
+ if (dcc_chat_send (ptr_dcc, buf2, strlen (buf2)) <= 0)
+ {
+ irc_display_prefix (ptr_dcc->server->buffer, PREFIX_ERROR);
+ gui_printf (ptr_dcc->server->buffer, _("%s error sending data to \"%s\" via DCC CHAT\n"),
+ WEECHAT_ERROR, ptr_dcc->nick);
+ dcc_close (ptr_dcc, DCC_FAILED);
+ }
+ free (buf2);
+}
/*
- * dcc_handle: receive/send data for each active DCC
+ * dcc_chat_recv: receive data from DCC CHAT host
+ */
+
+void
+dcc_chat_recv (t_irc_dcc *ptr_dcc)
+{
+ static char buffer[4096 + 2];
+ char *buf2, *pos, *ptr_buf, *next_ptr_buf;
+ int num_read;
+
+ num_read = recv (ptr_dcc->sock, buffer, sizeof (buffer) - 2, 0);
+ if (num_read > 0)
+ {
+ buffer[num_read] = '\0';
+
+ buf2 = NULL;
+ ptr_buf = buffer;
+ if (ptr_dcc->unterminated_message)
+ {
+ buf2 = (char *) malloc (strlen (ptr_dcc->unterminated_message) +
+ strlen (buffer) + 1);
+ if (buf2)
+ {
+ strcpy (buf2, ptr_dcc->unterminated_message);
+ strcat (buf2, buffer);
+ }
+ ptr_buf = buf2;
+ free (ptr_dcc->unterminated_message);
+ ptr_dcc->unterminated_message = NULL;
+ }
+
+ while (ptr_buf && ptr_buf[0])
+ {
+ next_ptr_buf = NULL;
+ pos = strstr (ptr_buf, "\r\n");
+ if (pos)
+ {
+ pos[0] = '\0';
+ next_ptr_buf = pos + 2;
+ }
+ else
+ {
+ pos = strstr (ptr_buf, "\n");
+ if (pos)
+ {
+ pos[0] = '\0';
+ next_ptr_buf = pos + 1;
+ }
+ else
+ {
+ ptr_dcc->unterminated_message = strdup (ptr_buf);
+ ptr_buf = NULL;
+ next_ptr_buf = NULL;
+ }
+ }
+
+ if (ptr_buf)
+ {
+ gui_printf_type_color (ptr_dcc->channel->buffer,
+ MSG_TYPE_NICK,
+ COLOR_WIN_CHAT_DARK, "<");
+ if (strstr (ptr_buf, ptr_dcc->server->nick))
+ {
+ gui_printf_type_color (ptr_dcc->channel->buffer,
+ MSG_TYPE_NICK | MSG_TYPE_HIGHLIGHT,
+ COLOR_WIN_CHAT_HIGHLIGHT,
+ "%s", ptr_dcc->nick);
+ if ( (cfg_look_infobar_delay_highlight > 0)
+ && (ptr_dcc->channel->buffer != gui_current_window->buffer) )
+ gui_infobar_printf (cfg_look_infobar_delay_highlight,
+ COLOR_WIN_INFOBAR_HIGHLIGHT,
+ _("Private %s> %s"),
+ ptr_dcc->nick, ptr_buf);
+ }
+ else
+ gui_printf_type_color (ptr_dcc->channel->buffer,
+ MSG_TYPE_NICK,
+ COLOR_WIN_NICK_PRIVATE,
+ "%s", ptr_dcc->nick);
+ gui_printf_type_color (ptr_dcc->channel->buffer,
+ MSG_TYPE_NICK,
+ COLOR_WIN_CHAT_DARK, "> ");
+ gui_printf_type_color (ptr_dcc->channel->buffer,
+ MSG_TYPE_MSG,
+ COLOR_WIN_CHAT, "%s\n", ptr_buf);
+ }
+
+ ptr_buf = next_ptr_buf;
+ }
+
+ if (buf2)
+ free (buf2);
+ }
+ else
+ {
+ dcc_close (ptr_dcc, DCC_ABORTED);
+ dcc_redraw (1);
+ }
+}
+
+/*
+ * dcc_handle: receive/send data for each active DCC (files only)
*/
void
@@ -555,6 +830,47 @@ dcc_handle ()
ptr_dcc->addr = ntohl (addr.sin_addr.s_addr);
ptr_dcc->status = DCC_ACTIVE;
ptr_dcc->file = open (ptr_dcc->local_filename, O_RDONLY | O_NONBLOCK, 0644);
+ dcc_redraw (1);
+ }
+ }
+ }
+ }
+
+ if (ptr_dcc->status == DCC_WAITING)
+ {
+ if (ptr_dcc->type == DCC_CHAT_SEND)
+ {
+ FD_ZERO (&read_fd);
+ FD_SET (ptr_dcc->sock, &read_fd);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ /* something to read on socket? */
+ if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
+ {
+ if (FD_ISSET (ptr_dcc->sock, &read_fd))
+ {
+ length = sizeof (addr);
+ sock = accept (ptr_dcc->sock, (struct sockaddr *) &addr, &length);
+ close (ptr_dcc->sock);
+ ptr_dcc->sock = -1;
+ if (sock < 0)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ ptr_dcc->sock = sock;
+ if (fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK) == -1)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ ptr_dcc->addr = ntohl (addr.sin_addr.s_addr);
+ ptr_dcc->status = DCC_ACTIVE;
+ dcc_redraw (1);
+ dcc_channel_for_chat (ptr_dcc);
}
}
}
@@ -562,6 +878,20 @@ dcc_handle ()
if (ptr_dcc->status == DCC_ACTIVE)
{
+ if (DCC_IS_CHAT(ptr_dcc->type))
+ {
+ FD_ZERO (&read_fd);
+ FD_SET (ptr_dcc->sock, &read_fd);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ /* something to read on socket? */
+ if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
+ {
+ if (FD_ISSET (ptr_dcc->sock, &read_fd))
+ dcc_chat_recv (ptr_dcc);
+ }
+ }
if (ptr_dcc->type == DCC_FILE_RECV)
{
num_read = recv (ptr_dcc->sock, buffer, sizeof (buffer), 0);
@@ -596,6 +926,7 @@ dcc_handle ()
{
if (cfg_dcc_blocksize > (int) sizeof (buffer))
{
+ irc_display_prefix (NULL, PREFIX_ERROR);
gui_printf (NULL, _("%s DCC failed because blocksize is too "
"big. Check value of \"dcc_blocksize\" option, "
"max is %d.\n"),
diff --git a/src/irc/irc-display.c b/src/irc/irc-display.c
index ec5f135b0..4b5212fa3 100644
--- a/src/irc/irc-display.c
+++ b/src/irc/irc-display.c
@@ -52,9 +52,9 @@ irc_display_prefix (t_gui_buffer *buffer, char *prefix)
if (prefix[0] == prefix[2])
{
- gui_printf_color_type (buffer, type, COLOR_WIN_CHAT_PREFIX1, "%c", prefix[0]);
- gui_printf_color_type (buffer, type, COLOR_WIN_CHAT_PREFIX2, "%c", prefix[1]);
- gui_printf_color_type (buffer, type, COLOR_WIN_CHAT_PREFIX1, "%c ", prefix[2]);
+ gui_printf_type_color (buffer, type, COLOR_WIN_CHAT_PREFIX1, "%c", prefix[0]);
+ gui_printf_type_color (buffer, type, COLOR_WIN_CHAT_PREFIX2, "%c", prefix[1]);
+ gui_printf_type_color (buffer, type, COLOR_WIN_CHAT_PREFIX1, "%c ", prefix[2]);
}
else
gui_printf_color (buffer, COLOR_WIN_CHAT_PREFIX1, "%s ", prefix);
@@ -70,43 +70,43 @@ irc_display_nick (t_gui_buffer *buffer, t_irc_nick *nick, int message_type,
int display_around, int color_nick, int no_nickmode)
{
if (display_around)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type, COLOR_WIN_CHAT_DARK, "<");
if (cfg_look_nickmode)
{
if (nick->is_chanowner)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_NICK_OP, "~");
else if (nick->is_chanadmin)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_NICK_OP, "&");
else if (nick->is_op)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_NICK_OP, "@");
else if (nick->is_halfop)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_NICK_HALFOP, "%%");
else if (nick->has_voice)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_NICK_VOICE, "+");
else
if (cfg_look_nickmode_empty && !no_nickmode)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_CHAT, " ");
}
if (color_nick < 0)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
COLOR_WIN_CHAT_HIGHLIGHT,
"%s", nick->nick);
else
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type,
(color_nick) ?
((cfg_look_color_nicks) ?
@@ -115,7 +115,7 @@ irc_display_nick (t_gui_buffer *buffer, t_irc_nick *nick, int message_type,
"%s", nick->nick);
if (display_around)
- gui_printf_color_type (buffer,
+ gui_printf_type_color (buffer,
message_type, COLOR_WIN_CHAT_DARK, "> ");
}
diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c
index 6b34d4cd2..ab69abe8d 100644
--- a/src/irc/irc-recv.c
+++ b/src/irc/irc-recv.c
@@ -160,9 +160,9 @@ irc_cmd_recv_join (t_irc_server *server, char *host, char *arguments)
if (!ptr_channel)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot create new channel \"%s\"\n"),
- WEECHAT_ERROR, arguments);
+ gui_printf (server->buffer,
+ _("%s cannot create new channel \"%s\"\n"),
+ WEECHAT_ERROR, arguments);
return -1;
}
}
@@ -227,9 +227,9 @@ irc_cmd_recv_kick (t_irc_server *server, char *host, char *arguments)
if (!ptr_channel)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "kick");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "kick");
return -1;
}
@@ -260,9 +260,9 @@ irc_cmd_recv_kick (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "kick");
+ gui_printf (server->buffer,
+ _("%s nick not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "kick");
return -1;
}
if (strcmp (pos_nick, server->nick) == 0)
@@ -550,9 +550,9 @@ irc_cmd_recv_mode (t_irc_server *server, char *host, char *arguments)
if (host == NULL)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "mode");
return -1;
}
@@ -565,9 +565,9 @@ irc_cmd_recv_mode (t_irc_server *server, char *host, char *arguments)
if (!pos)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without channel or nickname\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without channel or nickname\n"),
+ WEECHAT_ERROR, "mode");
return -1;
}
pos[0] = '\0';
@@ -595,9 +595,9 @@ irc_cmd_recv_mode (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "mode");
return -1;
}
}
@@ -635,9 +635,9 @@ irc_cmd_recv_nick (t_irc_server *server, char *host, char *arguments)
if (host == NULL)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "nick");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "nick");
return -1;
}
@@ -753,9 +753,9 @@ irc_cmd_recv_notice (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s nickname not found for \"%s\" command\n"),
- WEECHAT_ERROR, "notice");
+ gui_printf (server->buffer,
+ _("%s nickname not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "notice");
return -1;
}
if (strncmp (pos, "\01VERSION", 8) == 0)
@@ -846,9 +846,9 @@ irc_cmd_recv_part (t_irc_server *server, char *host, char *arguments)
if (!host || !arguments)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without host or channel\n"),
- WEECHAT_ERROR, "part");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without host or channel\n"),
+ WEECHAT_ERROR, "part");
return -1;
}
@@ -921,9 +921,9 @@ irc_cmd_recv_part (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "part");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "part");
return -1;
}
@@ -995,9 +995,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (host == NULL)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
@@ -1036,7 +1036,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
irc_display_prefix (ptr_channel->buffer, PREFIX_ACTION_ME);
if (strstr (pos, server->nick))
{
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG | MSG_TYPE_HIGHLIGHT,
COLOR_WIN_CHAT_HIGHLIGHT,
"%s", host);
@@ -1050,7 +1050,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
host, pos);
}
else
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT_NICK, "%s", host);
gui_printf_color (ptr_channel->buffer,
@@ -1078,16 +1078,16 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
else
irc_display_nick (ptr_channel->buffer, ptr_nick,
MSG_TYPE_NICK, 1, 1, 0);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
}
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s nick not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
}
@@ -1095,9 +1095,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
}
@@ -1176,16 +1176,19 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
/* incoming DCC file */
if (strncmp (pos, "\01DCC SEND", 9) == 0)
{
- pos2 = strchr (pos, '\01');
+ /* check if DCC SEND is ok, i.e. with 0x01 at end */
+ pos2 = strchr (pos + 1, '\01');
if (!pos2)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2[0] = '\0';
+
+ /* DCC filename */
pos_file = pos + 9;
while (pos_file[0] == ' ')
pos_file++;
@@ -1195,9 +1198,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (!pos_size)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_size;
@@ -1211,9 +1214,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (!pos_port)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_port;
@@ -1222,14 +1225,14 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
pos2--;
pos2[1] = '\0';
- /* look for DCC address (IP) */
+ /* look for DCC IP address */
pos_addr = strrchr (pos_file, ' ');
if (!pos_addr)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_addr;
@@ -1244,6 +1247,74 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
return 0;
}
+ /* incoming DCC CHAT */
+ if (strncmp (pos, "\01DCC CHAT", 9) == 0)
+ {
+ /* check if DCC CHAT is ok, i.e. with 0x01 at end */
+ pos2 = strchr (pos + 1, '\01');
+ if (!pos2)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
+ return -1;
+ }
+ pos2[0] = '\0';
+
+ /* CHAT type */
+ pos_file = pos + 9;
+ while (pos_file[0] == ' ')
+ pos_file++;
+
+ /* DCC IP address */
+ pos_addr = strchr (pos_file, ' ');
+ if (!pos_addr)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
+ return -1;
+ }
+ pos_addr[0] = '\0';
+ pos_addr++;
+ while (pos_addr[0] == ' ')
+ pos_addr++;
+
+ /* look for DCC port */
+ pos_port = strchr (pos_addr, ' ');
+ if (!pos_port)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
+ return -1;
+ }
+ pos_port[0] = '\0';
+ pos_port++;
+ while (pos_port[0] == ' ')
+ pos_port++;
+
+ if (strcasecmp (pos_file, "chat") != 0)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf (server->buffer,
+ _("%s unknown DCC CHAT type received from "),
+ WEECHAT_ERROR);
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_NICK,
+ "%s", host);
+ gui_printf (server->buffer, ": \"%s\"\n", pos_file);
+ return -1;
+ }
+
+ dcc_add (server, DCC_CHAT_RECV, (unsigned long) atol (pos_addr),
+ atoi (pos_port), host, -1, NULL, NULL, 0);
+
+ return 0;
+ }
+
/* private message received => display it */
ptr_channel = channel_search (server, host);
if (!ptr_channel)
@@ -1252,9 +1323,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (!ptr_channel)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot create new private window \"%s\"\n"),
- WEECHAT_ERROR, host);
+ gui_printf (server->buffer,
+ _("%s cannot create new private window \"%s\"\n"),
+ WEECHAT_ERROR, host);
return -1;
}
}
@@ -1270,7 +1341,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
irc_display_prefix (ptr_channel->buffer, PREFIX_ACTION_ME);
if (strstr (pos, server->nick))
{
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG | MSG_TYPE_HIGHLIGHT,
COLOR_WIN_CHAT_HIGHLIGHT,
"%s", host);
@@ -1284,7 +1355,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
host, pos);
}
else
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT_NICK, "%s", host);
gui_printf_color (ptr_channel->buffer,
@@ -1292,12 +1363,12 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
}
else
{
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "<");
if (strstr (pos, server->nick))
{
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK | MSG_TYPE_HIGHLIGHT,
COLOR_WIN_CHAT_HIGHLIGHT,
"%s", host);
@@ -1309,14 +1380,14 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
host, pos);
}
else
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_NICK_PRIVATE,
"%s", host);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "> ");
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
}
@@ -1324,9 +1395,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
}
@@ -1348,9 +1419,9 @@ irc_cmd_recv_quit (t_irc_server *server, char *host, char *arguments)
if (host == NULL)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "quit");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "quit");
return -1;
}
@@ -1500,9 +1571,9 @@ irc_cmd_recv_topic (t_irc_server *server, char *host, char *arguments)
if (!string_is_channel (arguments))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s \"%s\" command received without channel\n"),
- WEECHAT_ERROR, "topic");
+ gui_printf (server->buffer,
+ _("%s \"%s\" command received without channel\n"),
+ WEECHAT_ERROR, "topic");
return -1;
}
@@ -2558,9 +2629,9 @@ irc_cmd_recv_332 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "332");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "332");
return -1;
}
}
@@ -2568,9 +2639,9 @@ irc_cmd_recv_332 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot identify channel for \"%s\" command\n"),
- WEECHAT_ERROR, "332");
+ gui_printf (server->buffer,
+ _("%s cannot identify channel for \"%s\" command\n"),
+ WEECHAT_ERROR, "332");
return -1;
}
return 0;
@@ -2625,36 +2696,36 @@ irc_cmd_recv_333 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "333");
return -1;
}
}
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot identify date/time for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf (server->buffer,
+ _("%s cannot identify date/time for \"%s\" command\n"),
+ WEECHAT_ERROR, "333");
return -1;
}
}
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot identify nickname for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf (server->buffer,
+ _("%s cannot identify nickname for \"%s\" command\n"),
+ WEECHAT_ERROR, "333");
return -1;
}
}
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot identify channel for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf (server->buffer,
+ _("%s cannot identify channel for \"%s\" command\n"),
+ WEECHAT_ERROR, "333");
return -1;
}
return 0;
@@ -2862,9 +2933,9 @@ irc_cmd_recv_353 (t_irc_server *server, char *host, char *arguments)
if (pos[0] != ':')
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "353");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "353");
return -1;
}
pos++;
@@ -2908,9 +2979,9 @@ irc_cmd_recv_353 (t_irc_server *server, char *host, char *arguments)
is_op, is_halfop, has_voice))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot create nick \"%s\" for channel \"%s\"\n"),
- WEECHAT_ERROR, pos_nick, ptr_channel->name);
+ gui_printf (server->buffer,
+ _("%s cannot create nick \"%s\" for channel \"%s\"\n"),
+ WEECHAT_ERROR, pos_nick, ptr_channel->name);
}
}
}
@@ -2919,9 +2990,9 @@ irc_cmd_recv_353 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "353");
+ gui_printf (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "353");
return -1;
}
return 0;
diff --git a/src/irc/irc-send.c b/src/irc/irc-send.c
index 1226df884..8fc1ec071 100644
--- a/src/irc/irc-send.c
+++ b/src/irc/irc-send.c
@@ -246,7 +246,7 @@ irc_cmd_send_ctcp (t_irc_server *server, char *arguments)
}
/*
- * irc_cmd_send_dcc: starts DCC (file or chat)
+ * irc_cmd_send_dcc: start DCC (file or chat)
*/
int
@@ -254,8 +254,6 @@ irc_cmd_send_dcc (t_irc_server *server, char *arguments)
{
char *pos_nick, *pos_file;
- /* TODO: develop DCC CHAT */
-
/* DCC SEND file */
if (strncasecmp (arguments, "send", 4) == 0)
{
@@ -270,6 +268,7 @@ irc_cmd_send_dcc (t_irc_server *server, char *arguments)
}
while (pos_nick[0] == ' ')
pos_nick++;
+
pos_file = strchr (pos_nick, ' ');
if (!pos_file)
{
@@ -284,13 +283,41 @@ irc_cmd_send_dcc (t_irc_server *server, char *arguments)
while (pos_file[0] == ' ')
pos_file++;
- dcc_send (server, pos_nick, pos_file);
+ dcc_send_request (server, DCC_FILE_SEND, pos_nick, pos_file);
}
else if (strncasecmp (arguments, "chat", 4) == 0)
{
+ pos_nick = strchr (arguments, ' ');
+ if (!pos_nick)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf_nolog (server->buffer,
+ _("%s wrong argument count for \"%s\" command\n"),
+ WEECHAT_ERROR, "dcc chat");
+ return -1;
+ }
+ while (pos_nick[0] == ' ')
+ pos_nick++;
+
+ dcc_send_request (server, DCC_CHAT_SEND, pos_nick, NULL);
+ }
+ else if (strcasecmp (arguments, "close") == 0)
+ {
+ if (BUFFER_IS_PRIVATE(gui_current_window->buffer) &&
+ CHANNEL(gui_current_window->buffer)->dcc_chat)
+ {
+ dcc_close ((t_irc_dcc *)(CHANNEL(gui_current_window->buffer)->dcc_chat),
+ DCC_ABORTED);
+ dcc_redraw (1);
+ }
+ }
+ else
+ {
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf_nolog (server->buffer, _("This command is not developed!\n"));
- return 0;
+ gui_printf_nolog (server->buffer,
+ _("%s wrong arguments for \"%s\" command\n"),
+ WEECHAT_ERROR, "dcc");
+ return -1;
}
return 0;
@@ -630,7 +657,7 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
{
irc_display_nick (ptr_channel->buffer, ptr_nick,
MSG_TYPE_NICK, 1, 1, 0);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
}
@@ -655,7 +682,7 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
{
irc_display_nick (ptr_channel->buffer, ptr_nick,
MSG_TYPE_NICK, 1, 1, 0);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
}
@@ -691,13 +718,13 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
}
}
irc_display_prefix (server->buffer, PREFIX_SERVER);
- gui_printf_color_type (server->buffer,
+ gui_printf_type_color (server->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "-");
- gui_printf_color_type (server->buffer,
+ gui_printf_type_color (server->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_NICK, "%s", arguments);
- gui_printf_color_type (server->buffer,
+ gui_printf_type_color (server->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "-");
gui_printf_color (server->buffer,
@@ -722,17 +749,17 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
gui_draw_buffer_title (ptr_channel->buffer, 1);
}
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "<");
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_NICK_SELF,
"%s", server->nick);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "> ");
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
server_sendf (server, "PRIVMSG %s :%s\r\n", arguments, pos);
@@ -1014,17 +1041,17 @@ irc_cmd_send_query (t_irc_server *server, char *arguments)
/* display text if given */
if (pos)
{
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "<");
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_NICK_SELF,
"%s", server->nick);
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_NICK,
COLOR_WIN_CHAT_DARK, "> ");
- gui_printf_color_type (ptr_channel->buffer,
+ gui_printf_type_color (ptr_channel->buffer,
MSG_TYPE_MSG,
COLOR_WIN_CHAT, "%s\n", pos);
server_sendf (server, "PRIVMSG %s :%s\r\n", arguments, pos);
diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c
index bb23fc956..191ef7dc9 100644
--- a/src/irc/irc-server.c
+++ b/src/irc/irc-server.c
@@ -82,7 +82,7 @@ server_init (t_irc_server *server)
server->child_pid = 0;
server->child_read = -1;
server->child_write = -1;
- server->sock4 = -1;
+ server->sock = -1;
server->is_connected = 0;
server->unterminated_message = NULL;
server->nick = NULL;
@@ -271,6 +271,10 @@ server_free (t_irc_server *server)
{
t_irc_server *new_irc_servers;
+ /* close any opened channel/private */
+ while (server->channels)
+ channel_free (server, server->channels);
+
/* remove server from queue */
if (last_irc_server == server)
last_irc_server = server->prev_server;
@@ -364,12 +368,12 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de
*/
int
-server_send (t_irc_server * server, char *buffer, int size_buf)
+server_send (t_irc_server *server, char *buffer, int size_buf)
{
if (!server)
return -1;
- return send (server->sock4, buffer, size_buf, 0);
+ return send (server->sock, buffer, size_buf, 0);
}
/*
@@ -377,23 +381,23 @@ server_send (t_irc_server * server, char *buffer, int size_buf)
*/
void
-server_sendf (t_irc_server * server, char *fmt, ...)
+server_sendf (t_irc_server *server, char *fmt, ...)
{
va_list args;
- static char buffer[1024];
+ static char buffer[4096];
char *buf2;
int size_buf;
-
+
if (!server)
return;
-
+
va_start (args, fmt);
size_buf = vsnprintf (buffer, sizeof (buffer) - 1, fmt, args);
va_end (args);
if ((size_buf == 0) || (strcmp (buffer, "\r\n") == 0))
return;
-
+
buffer[sizeof (buffer) - 1] = '\0';
if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1)))
size_buf = strlen (buffer);
@@ -632,7 +636,7 @@ server_recv (t_irc_server *server)
static char buffer[4096 + 2];
int num_read;
- num_read = recv (server->sock4, buffer, sizeof (buffer) - 2, 0);
+ num_read = recv (server->sock, buffer, sizeof (buffer) - 2, 0);
if (num_read > 0)
{
buffer[num_read] = '\0';
@@ -687,10 +691,10 @@ server_close_connection (t_irc_server *server)
server_kill_child (server);
/* close network socket */
- if (server->sock4 != -1)
+ if (server->sock != -1)
{
- close (server->sock4);
- server->sock4 = -1;
+ close (server->sock);
+ server->sock = -1;
}
/* free any pending message */
@@ -804,7 +808,7 @@ server_child (t_irc_server *server)
}
/* connect to server */
- error = connect (server->sock4, (struct sockaddr *) &addr, sizeof (addr));
+ error = connect (server->sock, (struct sockaddr *) &addr, sizeof (addr));
if (error != 0)
{
write (server->child_write, "3", 1);
@@ -849,8 +853,8 @@ server_connect (t_irc_server *server)
server->child_write = child_pipe[1];
/* create socket and set options */
- server->sock4 = socket (AF_INET, SOCK_STREAM, 0);
- if (server->sock4 == -1)
+ server->sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (server->sock == -1)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
gui_printf (server->buffer,
@@ -861,7 +865,7 @@ server_connect (t_irc_server *server)
/* set SO_REUSEADDR option for socket */
set = 1;
- if (setsockopt (server->sock4, SOL_SOCKET, SO_REUSEADDR,
+ if (setsockopt (server->sock, SOL_SOCKET, SO_REUSEADDR,
(void *) &set, sizeof (set)) == -1)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
@@ -872,7 +876,7 @@ server_connect (t_irc_server *server)
/* set SO_KEEPALIVE option for socket */
set = 1;
- if (setsockopt (server->sock4, SOL_SOCKET, SO_KEEPALIVE,
+ if (setsockopt (server->sock, SOL_SOCKET, SO_KEEPALIVE,
(void *) &set, sizeof (set)) == -1)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
diff --git a/src/irc/irc.h b/src/irc/irc.h
index 828bca973..755bb874b 100644
--- a/src/irc/irc.h
+++ b/src/irc/irc.h
@@ -71,6 +71,14 @@
#define DCC_FAILED 4 /* DCC failed */
#define DCC_ABORTED 5 /* DCC aborted by user */
+#define DCC_IS_CHAT(type) ((type == DCC_CHAT_RECV) || (type == DCC_CHAT_SEND))
+#define DCC_IS_FILE(type) ((type == DCC_FILE_RECV) || (type == DCC_FILE_SEND))
+#define DCC_IS_RECV(type) ((type == DCC_CHAT_RECV) || (type == DCC_FILE_RECV))
+#define DCC_IS_SEND(type) ((type == DCC_CHAT_SEND) || (type == DCC_FILE_SEND))
+
+#define DCC_ENDED(status) ((status == DCC_DONE) || (status == DCC_FAILED) || \
+ (status == DCC_ABORTED))
+
/* nick types */
typedef struct t_irc_nick t_irc_nick;
@@ -100,6 +108,7 @@ typedef struct t_irc_channel t_irc_channel;
struct t_irc_channel
{
int type; /* channel type */
+ void *dcc_chat; /* DCC CHAT pointer (NULL if not DCC) */
char *name; /* name of channel (exemple: "#abc") */
char *topic; /* topic of channel (host for private) */
char modes[NUM_CHANNEL_MODES+1];/* channel modes */
@@ -142,7 +151,7 @@ struct t_irc_server
pid_t child_pid; /* pid of child process (connecting) */
int child_read; /* to read into child pipe */
int child_write; /* to write into child pipe */
- int sock4; /* socket for server */
+ int sock; /* socket for server */
int is_connected; /* 1 if WeeChat is connected to server */
char *unterminated_message; /* beginning of a message in input buf */
char *nick; /* current nickname */
@@ -198,12 +207,14 @@ typedef struct t_irc_dcc t_irc_dcc;
struct t_irc_dcc
{
t_irc_server *server; /* irc server */
+ t_irc_channel *channel; /* irc channel (for DCC chat only) */
int type; /* DCC type (send or receive) */
int status; /* DCC status (waiting, sending, ..) */
unsigned long addr; /* IP address */
int port; /* port */
char *nick; /* remote nick */
int sock; /* socket for connection */
+ char *unterminated_message; /* beginning of a message in input buf */
int file; /* local file (for reading or writing) */
char *filename; /* filename (given by sender) */
char *local_filename; /* local filename (with path) */
@@ -260,6 +271,8 @@ extern int string_is_channel (char *);
extern void channel_remove_away (t_irc_channel *);
extern void channel_check_away (t_irc_server *, t_irc_channel *);
extern void channel_set_away (t_irc_channel *, char *, int);
+extern int channel_create_dcc (t_irc_dcc *);
+extern void channel_remove_dcc (t_irc_dcc *);
/* nick functions (irc-nick.c) */
@@ -275,13 +288,15 @@ extern void nick_set_away (t_irc_channel *, t_irc_nick *, int);
/* DCC functions (irc-dcc.c) */
+extern void dcc_redraw (int);
extern void dcc_free (t_irc_dcc *);
extern void dcc_close (t_irc_dcc *, int);
extern void dcc_accept (t_irc_dcc *);
extern t_irc_dcc *dcc_add (t_irc_server *, int, unsigned long, int, char *, int,
char *, char *, unsigned long);
+extern void dcc_send_request (t_irc_server *, int, char *, char *);
+extern void dcc_chat_sendf (t_irc_dcc *, char *, ...);
extern void dcc_handle ();
-extern void dcc_send (t_irc_server *, char *, char *);
extern void dcc_end ();
/* IRC display (irc-diplay.c) */