summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2005-02-20 00:08:22 +0000
committerSebastien Helleu <flashcode@flashtux.org>2005-02-20 00:08:22 +0000
commit3e816667526bebf7366e56ca9661c57b20dcb535 (patch)
tree61517cfef86ff23d72b190adc5a0c1bf240936b8 /src
parent6d0be7db4b417663ddc40c77978a354415dc82d7 (diff)
downloadweechat-3e816667526bebf7366e56ca9661c57b20dcb535.zip
Added DCC send
Diffstat (limited to 'src')
-rw-r--r--src/common/weechat.h4
-rw-r--r--src/common/weeconfig.c9
-rw-r--r--src/common/weeconfig.h1
-rw-r--r--src/gui/curses/gui-display.c48
-rw-r--r--src/gui/curses/gui-input.c49
-rw-r--r--src/irc/irc-commands.c2
-rw-r--r--src/irc/irc-dcc.c468
-rw-r--r--src/irc/irc-recv.c183
-rw-r--r--src/irc/irc-send.c148
-rw-r--r--src/irc/irc-server.c5
-rw-r--r--src/irc/irc.h23
11 files changed, 639 insertions, 301 deletions
diff --git a/src/common/weechat.h b/src/common/weechat.h
index 16504a3d3..34f72dc4b 100644
--- a/src/common/weechat.h
+++ b/src/common/weechat.h
@@ -47,8 +47,8 @@
#define WEECHAT_COPYRIGHT_DATE "(c) 2003-2005"
#define WEECHAT_WEBSITE "http://weechat.flashtux.org"
-#define WEECHAT_ERROR _(PACKAGE_NAME " Error:")
-#define WEECHAT_WARNING _(PACKAGE_NAME " Warning:")
+#define WEECHAT_ERROR _("WeeChat Error:")
+#define WEECHAT_WARNING _("WeeChat Warning:")
/* log file */
diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c
index a9d14c674..643f7f123 100644
--- a/src/common/weeconfig.c
+++ b/src/common/weeconfig.c
@@ -534,6 +534,7 @@ int cfg_dcc_timeout;
int cfg_dcc_blocksize;
char *cfg_dcc_download_path;
char *cfg_dcc_upload_path;
+int cfg_dcc_convert_spaces;
int cfg_dcc_auto_rename;
int cfg_dcc_auto_resume;
@@ -544,7 +545,7 @@ t_config_option weechat_options_dcc[] =
NULL, NULL, &cfg_dcc_auto_accept_files, NULL, config_change_noop },
{ "dcc_auto_accept_chats", N_("automatically accept dcc chats"),
N_("automatically accept dcc chats (use carefully!)"),
- OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE,
+ OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
NULL, NULL, &cfg_dcc_auto_accept_chats, NULL, config_change_noop },
{ "dcc_timeout", N_("timeout for dcc request"),
N_("timeout for dcc request (in seconds)"),
@@ -552,7 +553,7 @@ t_config_option weechat_options_dcc[] =
NULL, NULL, &cfg_dcc_timeout, NULL, config_change_noop },
{ "dcc_blocksize", N_("block size for dcc packets"),
N_("block size for dcc packets in bytes (default: 1024)"),
- OPTION_TYPE_INT, 1024, 102400, 1024,
+ OPTION_TYPE_INT, 1024, 102400, 65536,
NULL, NULL, &cfg_dcc_blocksize, NULL, config_change_noop },
{ "dcc_download_path", N_("path for incoming files with dcc"),
N_("path for writing incoming files with dcc (default: user home)"),
@@ -562,6 +563,10 @@ t_config_option weechat_options_dcc[] =
N_("path for reading files when sending thru dcc (when no path is specified)"),
OPTION_TYPE_STRING, 0, 0, 0, "~",
NULL, NULL, &cfg_dcc_upload_path, config_change_noop },
+ { "dcc_convert_spaces", N_("convert spaces to underscores when sending files"),
+ N_("convert spaces to underscores when sending files"),
+ OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE,
+ NULL, NULL, &cfg_dcc_convert_spaces, NULL, config_change_noop },
{ "dcc_auto_rename", N_("automatically rename dcc files if already exists"),
N_("rename incoming files if already exists (add '.1', '.2', ...)"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE,
diff --git a/src/common/weeconfig.h b/src/common/weeconfig.h
index f69d010af..369639101 100644
--- a/src/common/weeconfig.h
+++ b/src/common/weeconfig.h
@@ -170,6 +170,7 @@ extern int cfg_dcc_timeout;
extern int cfg_dcc_blocksize;
extern char *cfg_dcc_download_path;
extern char *cfg_dcc_upload_path;
+extern int cfg_dcc_convert_spaces;
extern int cfg_dcc_auto_rename;
extern int cfg_dcc_auto_resume;
diff --git a/src/gui/curses/gui-display.c b/src/gui/curses/gui-display.c
index 6fa24e0aa..346335e19 100644
--- a/src/gui/curses/gui-display.c
+++ b/src/gui/curses/gui-display.c
@@ -365,7 +365,6 @@ gui_draw_buffer_title (t_gui_buffer *buffer, int erase)
{
if (!buffer->dcc)
{
- /* TODO: change this copyright as title? */
mvwprintw (ptr_win->win_title, 0, 0,
format,
PACKAGE_STRING " " WEECHAT_COPYRIGHT_DATE " - "
@@ -595,7 +594,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase)
{
t_gui_window *ptr_win;
t_gui_line *ptr_line;
- t_dcc *dcc_first, *dcc_selected, *ptr_dcc;
+ t_irc_dcc *dcc_first, *dcc_selected, *ptr_dcc;
char format_empty[32];
int i, j, lines_used, num_bars;
char *unit_name[] = { N_("bytes"), N_("Kb"), N_("Mb"), N_("Gb") };
@@ -627,8 +626,8 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase)
if (buffer->dcc)
{
i = 0;
- dcc_first = (ptr_win->dcc_first) ? (t_dcc *) ptr_win->dcc_first : dcc_list;
- dcc_selected = (ptr_win->dcc_selected) ? (t_dcc *) ptr_win->dcc_selected : dcc_list;
+ dcc_first = (ptr_win->dcc_first) ? (t_irc_dcc *) ptr_win->dcc_first : dcc_list;
+ dcc_selected = (ptr_win->dcc_selected) ? (t_irc_dcc *) ptr_win->dcc_selected : dcc_list;
for (ptr_dcc = dcc_first; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
{
if (i >= ptr_win->win_chat_height - 1)
@@ -640,7 +639,7 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase)
(ptr_dcc == dcc_selected) ?
COLOR_DCC_SELECTED : COLOR_WIN_CHAT);
mvwprintw (ptr_win->win_chat, i, 0, "%s %-16s %s",
- (ptr_dcc == dcc_selected) ? ">>" : " ",
+ (ptr_dcc == dcc_selected) ? "**" : " ",
ptr_dcc->nick, ptr_dcc->filename);
if (ptr_dcc->filename_suffix > 0)
wprintw (ptr_win->win_chat, " (.%d)",
@@ -649,9 +648,8 @@ gui_draw_buffer_chat (t_gui_buffer *buffer, int erase)
(ptr_dcc == dcc_selected) ?
COLOR_DCC_SELECTED : COLOR_WIN_CHAT);
mvwprintw (ptr_win->win_chat, i + 1, 0, "%s %s ",
- (ptr_dcc == dcc_selected) ? ">>" : " ",
- (ptr_dcc->type == DCC_FILE_RECV) ?
- "--->" : "<---");
+ (ptr_dcc == dcc_selected) ? "**" : " ",
+ (ptr_dcc->type == DCC_FILE_RECV) ? "-->>" : "<<--");
gui_window_set_color (ptr_win->win_chat,
COLOR_DCC_WAITING + ptr_dcc->status);
wprintw (ptr_win->win_chat, "%-10s",
@@ -1231,7 +1229,7 @@ gui_draw_buffer_input (t_gui_buffer *buffer, int erase)
char format[32];
char *ptr_nickname;
int input_width;
- t_dcc *dcc_selected;
+ t_irc_dcc *dcc_selected;
if (!gui_ok)
return;
@@ -1300,7 +1298,8 @@ gui_draw_buffer_input (t_gui_buffer *buffer, int erase)
{
if (buffer->dcc)
{
- dcc_selected = (ptr_win->dcc_selected) ? (t_dcc *) ptr_win->dcc_selected : dcc_list;
+ dcc_selected = (ptr_win->dcc_selected) ? (t_irc_dcc *) ptr_win->dcc_selected : dcc_list;
+ wmove (ptr_win->win_input, 0, 0);
if (dcc_selected)
{
switch (dcc_selected->status)
@@ -1308,36 +1307,22 @@ gui_draw_buffer_input (t_gui_buffer *buffer, int erase)
case DCC_WAITING:
if ((dcc_selected->type == DCC_CHAT_RECV)
|| (dcc_selected->type == DCC_FILE_RECV))
- {
- mvwprintw (ptr_win->win_input, 0, 0,
- _(" [A] Accept"));
- wprintw (ptr_win->win_input, _(" [C] Cancel"));
- wprintw (ptr_win->win_input, _(" [Q] Close DCC view"));
- }
- else
- {
- mvwprintw (ptr_win->win_input, 0, 0,
- _(" [C] Cancel"));
- wprintw (ptr_win->win_input, _(" [Q] Close DCC view"));
- }
+ wprintw (ptr_win->win_input, _(" [A] Accept"));
+ wprintw (ptr_win->win_input, _(" [C] Cancel"));
break;
case DCC_CONNECTING:
case DCC_ACTIVE:
- mvwprintw (ptr_win->win_input, 0, 0,
- _(" [C] Cancel"));
- wprintw (ptr_win->win_input, _(" [Q] Close DCC view"));
+ wprintw (ptr_win->win_input, _(" [C] Cancel"));
break;
case DCC_DONE:
case DCC_FAILED:
case DCC_ABORTED:
- mvwprintw (ptr_win->win_input, 0, 0,
- _(" [R] Remove"));
- wprintw (ptr_win->win_input, _(" [Q] Close DCC view"));
+ wprintw (ptr_win->win_input, _(" [R] Remove"));
break;
}
}
- else
- mvwprintw (ptr_win->win_input, 0, 0, _(" [Q] Close DCC view"));
+ wprintw (ptr_win->win_input, _(" [P] Purge old DCC"));
+ wprintw (ptr_win->win_input, _(" [Q] Close DCC view"));
wclrtoeol (ptr_win->win_input);
if (ptr_win == gui_current_window)
move (ptr_win->win_y + ptr_win->win_height - 1,
@@ -2290,6 +2275,9 @@ gui_printf_color_type (t_gui_buffer *buffer, int type, int color, char *message,
buffer = SERVER(gui_current_window->buffer)->buffer;
else
buffer = gui_current_window->buffer;
+
+ if (buffer->dcc)
+ buffer = gui_buffers;
}
if (buffer == NULL)
diff --git a/src/gui/curses/gui-input.c b/src/gui/curses/gui-input.c
index ab300f047..1ca34b5b6 100644
--- a/src/gui/curses/gui-input.c
+++ b/src/gui/curses/gui-input.c
@@ -52,8 +52,9 @@ gui_read_keyb ()
int key, i;
t_gui_buffer *ptr_buffer;
t_irc_server *ptr_server;
+ t_irc_dcc *ptr_dcc;
char new_char[3], *decoded_string;
- t_dcc *dcc_selected;
+ t_irc_dcc *dcc_selected;
key = getch ();
if (key != ERR)
@@ -98,14 +99,14 @@ gui_read_keyb ()
if (dcc_list)
{
if (gui_current_window->dcc_selected
- && ((t_dcc *)(gui_current_window->dcc_selected))->prev_dcc)
+ && ((t_irc_dcc *)(gui_current_window->dcc_selected))->prev_dcc)
{
if (gui_current_window->dcc_selected ==
gui_current_window->dcc_first)
gui_current_window->dcc_first =
- ((t_dcc *)(gui_current_window->dcc_first))->prev_dcc;
+ ((t_irc_dcc *)(gui_current_window->dcc_first))->prev_dcc;
gui_current_window->dcc_selected =
- ((t_dcc *)(gui_current_window->dcc_selected))->prev_dcc;
+ ((t_irc_dcc *)(gui_current_window->dcc_selected))->prev_dcc;
gui_draw_buffer_chat (gui_current_window->buffer, 1);
gui_draw_buffer_input (gui_current_window->buffer, 1);
}
@@ -144,7 +145,7 @@ gui_read_keyb ()
if (dcc_list)
{
if (!gui_current_window->dcc_selected
- || ((t_dcc *)(gui_current_window->dcc_selected))->next_dcc)
+ || ((t_irc_dcc *)(gui_current_window->dcc_selected))->next_dcc)
{
if (gui_current_window->dcc_last_displayed
&& (gui_current_window->dcc_selected ==
@@ -152,14 +153,14 @@ gui_read_keyb ()
{
if (gui_current_window->dcc_first)
gui_current_window->dcc_first =
- ((t_dcc *)(gui_current_window->dcc_first))->next_dcc;
+ ((t_irc_dcc *)(gui_current_window->dcc_first))->next_dcc;
else
gui_current_window->dcc_first =
dcc_list->next_dcc;
}
if (gui_current_window->dcc_selected)
gui_current_window->dcc_selected =
- ((t_dcc *)(gui_current_window->dcc_selected))->next_dcc;
+ ((t_irc_dcc *)(gui_current_window->dcc_selected))->next_dcc;
else
gui_current_window->dcc_selected =
dcc_list->next_dcc;
@@ -558,7 +559,7 @@ gui_read_keyb ()
if (gui_current_window->buffer->dcc)
{
dcc_selected = (gui_current_window->dcc_selected) ?
- (t_dcc *) gui_current_window->dcc_selected : dcc_list;
+ (t_irc_dcc *) gui_current_window->dcc_selected : dcc_list;
switch (key)
{
/* accept DCC */
@@ -584,10 +585,30 @@ gui_read_keyb ()
gui_redraw_buffer (gui_current_window->buffer);
}
break;
+ /* purge old DCC */
+ case 'p':
+ case 'P':
+ gui_current_window->dcc_selected = NULL;
+ for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
+ {
+ if ((dcc_selected->status == DCC_DONE)
+ || (dcc_selected->status == DCC_FAILED)
+ || (dcc_selected->status == DCC_ABORTED))
+ dcc_free (ptr_dcc);
+ }
+ gui_redraw_buffer (gui_current_window->buffer);
+ break;
/* close DCC window */
case 'q':
case 'Q':
- gui_buffer_free (gui_current_window->buffer, 1);
+ if (buffer_before_dcc)
+ {
+ gui_buffer_free (gui_current_window->buffer, 1);
+ gui_switch_to_buffer (gui_current_window,
+ buffer_before_dcc);
+ }
+ else
+ gui_buffer_free (gui_current_window->buffer, 1);
gui_redraw_buffer (gui_current_window->buffer);
break;
/* remove from DCC list */
@@ -595,7 +616,8 @@ gui_read_keyb ()
case 'R':
if (dcc_selected
&& (((dcc_selected->type == DCC_CHAT_RECV)
- || (dcc_selected->type == DCC_FILE_RECV))
+ || (dcc_selected->type == DCC_FILE_RECV)
+ || (dcc_selected->type == DCC_FILE_SEND))
&& ((dcc_selected->status == DCC_DONE)
|| (dcc_selected->status == DCC_FAILED)
|| (dcc_selected->status == DCC_ABORTED))))
@@ -703,10 +725,11 @@ gui_main_loop ()
}
}
- timeout.tv_sec = 0;
- timeout.tv_usec = 10000;
FD_ZERO (&read_fd);
FD_SET (STDIN_FILENO, &read_fd);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10000;
+
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
@@ -749,7 +772,7 @@ gui_main_loop ()
FD_SET (ptr_server->sock4, &read_fd);
}
}
- if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout))
+ if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
{
if (FD_ISSET (STDIN_FILENO, &read_fd))
{
diff --git a/src/irc/irc-commands.c b/src/irc/irc-commands.c
index 1cbff48bb..f6bd3de77 100644
--- a/src/irc/irc-commands.c
+++ b/src/irc/irc-commands.c
@@ -49,7 +49,7 @@ t_irc_command irc_commands[] =
N_("action: 'send' (file) or 'chat'\n"
"nickname: nickname to send file or chat\n"
"file: filename (on local host)"),
- 2, 3, 1, NULL, irc_cmd_send_dcc, NULL },
+ 2, 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 565e28128..2d51c7e1a 100644
--- a/src/irc/irc-dcc.c
+++ b/src/irc/irc-dcc.c
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -39,7 +40,7 @@
#include "../gui/gui.h"
-t_dcc *dcc_list = NULL; /* DCC files & chat list */
+t_irc_dcc *dcc_list = NULL; /* DCC files & chat list */
char *dcc_status_string[] = /* strings for DCC status */
{ N_("Waiting"), N_("Connecting"), N_("Active"), N_("Done"), N_("Failed"),
N_("Aborted") };
@@ -64,31 +65,42 @@ dcc_redraw (int highlight)
* dcc_connect: connect to another host
*/
-void
-dcc_connect (t_dcc *ptr_dcc)
+int
+dcc_connect (t_irc_dcc *ptr_dcc)
{
struct sockaddr_in addr;
ptr_dcc->status = DCC_CONNECTING;
- ptr_dcc->sock = socket (AF_INET, SOCK_STREAM, 0);
if (ptr_dcc->sock == -1)
- return;
- memset (&addr, 0, sizeof (addr));
- addr.sin_port = htons (ptr_dcc->port);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl (ptr_dcc->addr);
- fcntl (ptr_dcc->sock, F_SETFL, O_NONBLOCK);
- connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr));
-}
-
-/*
- * dcc_send: send DCC request (file or chat)
- */
-
-void
-dcc_send ()
-{
+ {
+ ptr_dcc->sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (ptr_dcc->sock == -1)
+ return 0;
+ }
+ 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)
+ {
+ if (listen (ptr_dcc->sock, 1) == -1)
+ return 0;
+ if (fcntl (ptr_dcc->sock, F_SETFL, 0) == -1)
+ return 0;
+ }
+
+ /* for DCC RECV, connect to listening host */
+ if (ptr_dcc->type == DCC_FILE_RECV)
+ {
+ memset (&addr, 0, sizeof (addr));
+ addr.sin_port = htons (ptr_dcc->port);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl (ptr_dcc->addr);
+ connect (ptr_dcc->sock, (struct sockaddr *) &addr, sizeof (addr));
+ }
+
+ return 1;
}
/*
@@ -96,9 +108,9 @@ dcc_send ()
*/
void
-dcc_free (t_dcc *ptr_dcc)
+dcc_free (t_irc_dcc *ptr_dcc)
{
- t_dcc *new_dcc_list;
+ t_irc_dcc *new_dcc_list;
if (ptr_dcc->prev_dcc)
{
@@ -125,9 +137,37 @@ dcc_free (t_dcc *ptr_dcc)
*/
void
-dcc_close (t_dcc *ptr_dcc, int status)
+dcc_close (t_irc_dcc *ptr_dcc, int status)
{
ptr_dcc->status = status;
+
+ if (status == DCC_DONE)
+ {
+ if ((ptr_dcc->type == DCC_FILE_SEND) || (ptr_dcc->type == DCC_FILE_RECV))
+ {
+ irc_display_prefix (ptr_dcc->server->buffer, PREFIX_INFO);
+ gui_printf (ptr_dcc->server->buffer, _("DCC: file "));
+ gui_printf_color (ptr_dcc->server->buffer,
+ COLOR_WIN_CHAT_CHANNEL,
+ "%s",
+ ptr_dcc->filename);
+ gui_printf (ptr_dcc->server->buffer, _(" (local filename: "));
+ gui_printf_color (ptr_dcc->server->buffer,
+ COLOR_WIN_CHAT_CHANNEL,
+ "%s",
+ ptr_dcc->local_filename);
+ if (ptr_dcc->type == DCC_FILE_SEND)
+ gui_printf (ptr_dcc->server->buffer, _(") sent to "));
+ else
+ gui_printf (ptr_dcc->server->buffer, _(") received from "));
+ gui_printf_color (ptr_dcc->server->buffer,
+ COLOR_WIN_CHAT_NICK,
+ "%s",
+ ptr_dcc->nick);
+ gui_printf (ptr_dcc->server->buffer, _(": ok!\n"));
+ }
+ }
+
if (ptr_dcc->sock != -1)
{
close (ptr_dcc->sock);
@@ -145,13 +185,15 @@ dcc_close (t_dcc *ptr_dcc, int status)
*/
void
-dcc_accept (t_dcc *ptr_dcc)
+dcc_accept (t_irc_dcc *ptr_dcc)
{
char *ptr_home, *filename2;
- dcc_connect (ptr_dcc);
- if (ptr_dcc->sock == -1)
- ptr_dcc->status = DCC_FAILED;
+ if (!dcc_connect (ptr_dcc))
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ }
else
{
ptr_dcc->status = DCC_ACTIVE;
@@ -164,7 +206,7 @@ dcc_accept (t_dcc *ptr_dcc)
4);
if (!ptr_dcc->local_filename)
{
- ptr_dcc->status = DCC_FAILED;
+ dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
return;
}
@@ -187,7 +229,7 @@ dcc_accept (t_dcc *ptr_dcc)
/* if auto rename is not set, then abort DCC */
if (!cfg_dcc_auto_rename)
{
- ptr_dcc->status = DCC_FAILED;
+ dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
return;
}
@@ -195,7 +237,7 @@ dcc_accept (t_dcc *ptr_dcc)
filename2 = (char *) malloc (strlen (ptr_dcc->local_filename) + 16);
if (!filename2)
{
- ptr_dcc->status = DCC_FAILED;
+ dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
return;
}
@@ -214,7 +256,7 @@ dcc_accept (t_dcc *ptr_dcc)
free (filename2);
}
ptr_dcc->file = open (ptr_dcc->local_filename,
- O_CREAT | O_TRUNC | O_WRONLY,
+ O_CREAT | O_TRUNC | O_WRONLY | O_NONBLOCK,
0644);
}
dcc_redraw (1);
@@ -224,15 +266,17 @@ dcc_accept (t_dcc *ptr_dcc)
* dcc_add: add a DCC file to queue
*/
-t_dcc *
-dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nick, char *filename,
- unsigned int size)
+t_irc_dcc *
+dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nick,
+ int sock, char *filename, char *local_filename, unsigned long size)
{
- t_dcc *new_dcc;
+ t_irc_dcc *new_dcc;
- if ((new_dcc = (t_dcc *) malloc (sizeof (t_dcc))) == NULL)
+ if ((new_dcc = (t_irc_dcc *) malloc (sizeof (t_irc_dcc))) == NULL)
{
- gui_printf (NULL, _("%s not enough memory for new DCC\n"), WEECHAT_ERROR);
+ gui_printf_nolog (server->buffer,
+ _("%s not enough memory for new DCC\n"),
+ WEECHAT_ERROR);
return NULL;
}
new_dcc->server = server;
@@ -241,13 +285,14 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
new_dcc->addr = addr;
new_dcc->port = port;
new_dcc->nick = strdup (nick);
- new_dcc->sock = -1;
+ new_dcc->sock = sock;
new_dcc->file = -1;
new_dcc->filename = strdup (filename);
- new_dcc->local_filename = NULL;
+ new_dcc->local_filename = (local_filename) ? strdup (local_filename) : NULL;
new_dcc->filename_suffix = -1;
new_dcc->size = size;
new_dcc->pos = 0;
+ new_dcc->ack = 0;
new_dcc->prev_dcc = NULL;
new_dcc->next_dcc = dcc_list;
if (dcc_list)
@@ -261,33 +306,47 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
{
irc_display_prefix (server->buffer, PREFIX_INFO);
gui_printf (server->buffer, _("Incoming DCC file 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,
+ 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_color (server->buffer, COLOR_WIN_CHAT_DARK, ")");
gui_printf (server->buffer, ": ");
- gui_printf_color (server->buffer,
- COLOR_WIN_CHAT_CHANNEL,
- "%s",
- filename);
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%s", filename);
gui_printf (server->buffer, ", ");
- gui_printf_color (server->buffer,
- COLOR_WIN_CHAT_CHANNEL,
- "%lu",
- size);
+ 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: "));
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%s", local_filename);
+ gui_printf (server->buffer, "), ");
+ gui_printf_color (server->buffer, COLOR_WIN_CHAT_CHANNEL, "%lu", size);
+ gui_printf (server->buffer, _(" bytes\n"));
+ }
+
+ if (type == DCC_FILE_SEND)
+ {
+ if (!dcc_connect (new_dcc))
+ {
+ dcc_close (new_dcc, DCC_FAILED);
+ return NULL;
+ }
+ }
+
if ( ( (type == DCC_CHAT_RECV) && (cfg_dcc_auto_accept_chats) )
|| ( (type == DCC_FILE_RECV) && (cfg_dcc_auto_accept_files) ) )
dcc_accept (new_dcc);
@@ -299,67 +358,298 @@ dcc_add (t_irc_server *server, int type, unsigned long addr, int port, char *nic
}
/*
+ * dcc_send: send DCC request (file or chat)
+ */
+
+void
+dcc_send (t_irc_server *server, char *nick, char *filename)
+{
+ char *ptr_home, *filename2, *short_filename, *pos;
+ int spaces;
+ struct stat st;
+ int sock, port;
+ struct sockaddr_in addr;
+ socklen_t length;
+ unsigned long local_addr;
+
+ /* add home if filename not beginning with '/' (not for Win32) */
+ #ifdef _WIN32
+ filename2 = strdup (filename);
+ #else
+ if (filename[0] == '/')
+ filename2 = strdup (filename);
+ else
+ {
+ 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_nolog (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);
+ }
+ #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);
+ addr.sin_family = AF_INET;
+ local_addr = ntohl (addr.sin_addr.s_addr);
+
+ /* open socket for DCC */
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ 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);
+ return;
+ }
+
+ /* find port automatically */
+ addr.sin_port = 0;
+ 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);
+ close (sock);
+ 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 (pos[0] == ' ')
+ {
+ if (cfg_dcc_convert_spaces)
+ pos[0] = '_';
+ else
+ spaces = 1;
+ }
+ 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))
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf_nolog (server->buffer,
+ _("%s cannot send DCC\n"),
+ WEECHAT_ERROR);
+ close (sock);
+ free (short_filename);
+ 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);
+}
+
+
+/*
* dcc_handle: receive/send data for each active DCC
*/
void
dcc_handle ()
{
- t_dcc *ptr_dcc;
- int num;
- char buffer[8192];
+ t_irc_dcc *ptr_dcc;
+ int num_read, num_sent;
+ static char buffer[102400];
uint32_t pos;
+ fd_set read_fd;
+ static struct timeval timeout;
+ int sock;
+ struct sockaddr_in addr;
+ socklen_t length;
for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
{
+ if (ptr_dcc->status == DCC_CONNECTING)
+ {
+ if (ptr_dcc->type == DCC_FILE_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;
+ ptr_dcc->file = open (ptr_dcc->local_filename, O_RDONLY | O_NONBLOCK, 0644);
+ }
+ }
+ }
+ }
+
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)
+ num_read = recv (ptr_dcc->sock, buffer, sizeof (buffer), 0);
+ if (num_read != -1)
{
- if (num == 0)
+ if (num_read == 0)
{
dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
+ return;
+ }
+
+ if (write (ptr_dcc->file, buffer, num_read) == -1)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ ptr_dcc->pos += (unsigned long) num_read;
+ pos = htonl (ptr_dcc->pos);
+ send (ptr_dcc->sock, (char *) &pos, 4, 0);
+ if (ptr_dcc->pos >= ptr_dcc->size)
+ {
+ dcc_close (ptr_dcc, DCC_DONE);
+ dcc_redraw (1);
}
else
+ dcc_redraw (0);
+ }
+ }
+ if (ptr_dcc->type == DCC_FILE_SEND)
+ {
+ if (cfg_dcc_blocksize > (int) sizeof (buffer))
+ {
+ gui_printf (NULL, _("%s DCC failed because blocksize is too "
+ "big. Check value of \"dcc_blocksize\" option, "
+ "max is %d.\n"),
+ sizeof (buffer));
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ if (ptr_dcc->pos > ptr_dcc->ack)
+ {
+ /* we should receive ACK for packets sent previously */
+ num_read = recv (ptr_dcc->sock, (char *) &pos, 4, MSG_PEEK);
+ if (num_read != -1)
{
- if (write (ptr_dcc->file, buffer, num) == -1)
+ if (num_read == 0)
{
dcc_close (ptr_dcc, DCC_FAILED);
dcc_redraw (1);
return;
}
- 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)
+ if (num_read < 4)
+ return;
+ recv (ptr_dcc->sock, (char *) &pos, 4, 0);
+ ptr_dcc->ack = ntohl (pos);
+
+ if ((ptr_dcc->pos >= ptr_dcc->size)
+ && (ptr_dcc->ack >= ptr_dcc->size))
{
- irc_display_prefix (ptr_dcc->server->buffer, PREFIX_INFO);
- gui_printf (ptr_dcc->server->buffer, _("DCC: file "));
- gui_printf_color (ptr_dcc->server->buffer,
- COLOR_WIN_CHAT_CHANNEL,
- "%s",
- ptr_dcc->filename);
- gui_printf (ptr_dcc->server->buffer, _(" (local filename: "));
- gui_printf_color (ptr_dcc->server->buffer,
- COLOR_WIN_CHAT_CHANNEL,
- "%s",
- ptr_dcc->local_filename);
- gui_printf (ptr_dcc->server->buffer, _(") from "));
- gui_printf_color (ptr_dcc->server->buffer,
- COLOR_WIN_CHAT_NICK,
- "%s",
- ptr_dcc->nick);
- gui_printf (ptr_dcc->server->buffer, _(": ok!\n"));
dcc_close (ptr_dcc, DCC_DONE);
dcc_redraw (1);
+ return;
}
- dcc_redraw (0);
}
}
+ if (ptr_dcc->pos <= ptr_dcc->ack)
+ {
+ lseek (ptr_dcc->file, ptr_dcc->pos, SEEK_SET);
+ num_read = read (ptr_dcc->file, buffer, cfg_dcc_blocksize);
+ if (num_read < 1)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ num_sent = send (ptr_dcc->sock, buffer, num_read, 0);
+ if (num_sent < 0)
+ {
+ dcc_close (ptr_dcc, DCC_FAILED);
+ dcc_redraw (1);
+ return;
+ }
+ ptr_dcc->pos += (unsigned long) num_sent;
+ dcc_redraw (0);
+ }
}
}
}
@@ -372,7 +662,7 @@ dcc_handle ()
void
dcc_end ()
{
- t_dcc *ptr_dcc;
+ t_irc_dcc *ptr_dcc;
for (ptr_dcc = dcc_list; ptr_dcc; ptr_dcc = ptr_dcc->next_dcc)
{
diff --git a/src/irc/irc-recv.c b/src/irc/irc-recv.c
index 09feddf7e..8e83dee93 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 (server->buffer,
- _("%s cannot create new channel \"%s\"\n"),
- WEECHAT_ERROR, arguments);
+ gui_printf_nolog (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 (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "kick");
+ gui_printf_nolog (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 (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "kick");
+ gui_printf_nolog (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 (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf_nolog (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 (server->buffer,
- _("%s \"%s\" command received without channel or nickname\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf_nolog (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 (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "mode");
+ gui_printf_nolog (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 (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "nick");
+ gui_printf_nolog (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 (server->buffer,
- _("%s nickname not found for \"%s\" command\n"),
- WEECHAT_ERROR, "notice");
+ gui_printf_nolog (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 (server->buffer,
- _("%s \"%s\" command received without host or channel\n"),
- WEECHAT_ERROR, "part");
+ gui_printf_nolog (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 (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "part");
+ gui_printf_nolog (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 (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
@@ -1085,9 +1085,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (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 (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
}
@@ -1180,9 +1180,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (!pos2)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2[0] = '\0';
@@ -1195,9 +1195,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 (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_size;
@@ -1211,9 +1211,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 (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_port;
@@ -1227,9 +1227,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
if (!pos_addr)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
pos2 = pos_addr;
@@ -1239,7 +1239,8 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
pos2[1] = '\0';
dcc_add (server, DCC_FILE_RECV, (unsigned long) atol (pos_addr),
- atoi (pos_port), host, pos_file, (unsigned int) atoi (pos_size));
+ atoi (pos_port), host, -1, pos_file, NULL,
+ (unsigned long) atol (pos_size));
return 0;
}
@@ -1251,9 +1252,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 (server->buffer,
- _("%s cannot create new private window \"%s\"\n"),
- WEECHAT_ERROR, host);
+ gui_printf_nolog (server->buffer,
+ _("%s cannot create new private window \"%s\"\n"),
+ WEECHAT_ERROR, host);
return -1;
}
}
@@ -1323,9 +1324,9 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "privmsg");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "privmsg");
return -1;
}
}
@@ -1347,9 +1348,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 (server->buffer,
- _("%s \"%s\" command received without host\n"),
- WEECHAT_ERROR, "quit");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command received without host\n"),
+ WEECHAT_ERROR, "quit");
return -1;
}
@@ -1500,9 +1501,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 (server->buffer,
- _("%s \"%s\" command received without channel\n"),
- WEECHAT_ERROR, "topic");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command received without channel\n"),
+ WEECHAT_ERROR, "topic");
return -1;
}
@@ -2558,9 +2559,9 @@ irc_cmd_recv_332 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "332");
+ gui_printf_nolog (server->buffer,
+ _("%s channel not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "332");
return -1;
}
}
@@ -2568,9 +2569,9 @@ irc_cmd_recv_332 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot identify channel for \"%s\" command\n"),
- WEECHAT_ERROR, "332");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot identify channel for \"%s\" command\n"),
+ WEECHAT_ERROR, "332");
return -1;
}
return 0;
@@ -2625,36 +2626,36 @@ irc_cmd_recv_333 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s channel not found for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf_nolog (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 (server->buffer,
- _("%s cannot identify date/time for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf_nolog (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 (server->buffer,
- _("%s cannot identify nickname for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf_nolog (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 (server->buffer,
- _("%s cannot identify channel for \"%s\" command\n"),
- WEECHAT_ERROR, "333");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot identify channel for \"%s\" command\n"),
+ WEECHAT_ERROR, "333");
return -1;
}
return 0;
@@ -2862,9 +2863,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 (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "353");
+ gui_printf_nolog (server->buffer,
+ _("%s cannot parse \"%s\" command\n"),
+ WEECHAT_ERROR, "353");
return -1;
}
pos++;
@@ -2908,9 +2909,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 (server->buffer,
- _("%s cannot create nick \"%s\" for channel \"%s\"\n"),
- WEECHAT_ERROR, pos_nick, ptr_channel->name);
+ gui_printf_nolog (server->buffer,
+ _("%s cannot create nick \"%s\" for channel \"%s\"\n"),
+ WEECHAT_ERROR, pos_nick, ptr_channel->name);
}
}
}
@@ -2919,9 +2920,9 @@ irc_cmd_recv_353 (t_irc_server *server, char *host, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot parse \"%s\" command\n"),
- WEECHAT_ERROR, "353");
+ gui_printf_nolog (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 6d5deee76..87dcd822b 100644
--- a/src/irc/irc-send.c
+++ b/src/irc/irc-send.c
@@ -252,14 +252,46 @@ irc_cmd_send_ctcp (t_irc_server *server, char *arguments)
int
irc_cmd_send_dcc (t_irc_server *server, char *arguments)
{
- /* TODO: write this command! */
+ char *pos_nick, *pos_file;
- /* make gcc happy */
- (void) server;
- (void) arguments;
+ /* TODO: develop DCC CHAT */
- irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer, _("This command is not developed!\n"));
+ /* DCC SEND file */
+ if (strncasecmp (arguments, "send", 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 send");
+ return -1;
+ }
+ while (pos_nick[0] == ' ')
+ pos_nick++;
+ pos_file = strchr (pos_nick, ' ');
+ if (!pos_file)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf_nolog (server->buffer,
+ _("%s wrong argument count for \"%s\" command\n"),
+ WEECHAT_ERROR, "dcc send");
+ return -1;
+ }
+ pos_file[0] = '\0';
+ pos_file++;
+ while (pos_file[0] == ' ')
+ pos_file++;
+
+ dcc_send (server, pos_nick, pos_file);
+ }
+ else if (strncasecmp (arguments, "chat", 4) == 0)
+ {
+ irc_display_prefix (server->buffer, PREFIX_ERROR);
+ gui_printf_nolog (server->buffer, _("This command is not developed!\n"));
+ return 0;
+ }
return 0;
}
@@ -283,9 +315,9 @@ irc_cmd_send_deop (t_irc_server *server, int argc, char **argv)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "deop");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "deop");
}
return 0;
}
@@ -309,9 +341,9 @@ irc_cmd_send_devoice (t_irc_server *server, int argc, char **argv)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "devoice");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "devoice");
return -1;
}
return 0;
@@ -410,9 +442,9 @@ irc_cmd_send_kick (t_irc_server *server, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "kick");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "kick");
return -1;
}
}
@@ -520,9 +552,9 @@ irc_cmd_send_me (t_irc_server *server, char *arguments)
if (BUFFER_IS_SERVER(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can not be executed on a server window\n"),
- WEECHAT_ERROR, "me");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can not be executed on a server window\n"),
+ WEECHAT_ERROR, "me");
return -1;
}
irc_send_me (server, CHANNEL(gui_current_window->buffer), arguments);
@@ -587,9 +619,9 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
if (BUFFER_IS_SERVER(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can not be executed on a server window\n"),
- WEECHAT_ERROR, "msg *");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can not be executed on a server window\n"),
+ WEECHAT_ERROR, "msg *");
return -1;
}
ptr_channel = CHANNEL(gui_current_window->buffer);
@@ -605,9 +637,9 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "msg");
+ gui_printf_nolog (server->buffer,
+ _("%s nick not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "msg");
}
server_sendf (server, "PRIVMSG %s :%s\r\n", ptr_channel->name, pos);
}
@@ -630,9 +662,9 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s nick not found for \"%s\" command\n"),
- WEECHAT_ERROR, "msg");
+ gui_printf_nolog (server->buffer,
+ _("%s nick not found for \"%s\" command\n"),
+ WEECHAT_ERROR, "msg");
}
}
server_sendf (server, "PRIVMSG %s :%s\r\n", arguments, pos);
@@ -682,10 +714,9 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
if (!ptr_channel)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot create new private window \"%s\"\n"),
- WEECHAT_ERROR,
- arguments);
+ gui_printf_nolog (server->buffer,
+ _("%s cannot create new private window \"%s\"\n"),
+ WEECHAT_ERROR, arguments);
return -1;
}
gui_draw_buffer_title (ptr_channel->buffer, 1);
@@ -713,9 +744,9 @@ irc_cmd_send_msg (t_irc_server *server, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s wrong argument count for \"%s\" command\n"),
- WEECHAT_ERROR, "msg");
+ gui_printf_nolog (server->buffer,
+ _("%s wrong argument count for \"%s\" command\n"),
+ WEECHAT_ERROR, "msg");
return -1;
}
return 0;
@@ -735,9 +766,9 @@ irc_cmd_send_names (t_irc_server *server, char *arguments)
if (!BUFFER_IS_CHANNEL(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "names");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "names");
return -1;
}
else
@@ -787,9 +818,9 @@ irc_cmd_send_notice (t_irc_server *server, char *arguments)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s wrong argument count for \"%s\" command\n"),
- WEECHAT_ERROR, "notice");
+ gui_printf_nolog (server->buffer,
+ _("%s wrong argument count for \"%s\" command\n"),
+ WEECHAT_ERROR, "notice");
return -1;
}
return 0;
@@ -814,9 +845,9 @@ irc_cmd_send_op (t_irc_server *server, int argc, char **argv)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "op");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "op");
return -1;
}
return 0;
@@ -862,9 +893,9 @@ irc_cmd_send_part (t_irc_server *server, char *arguments)
if (BUFFER_IS_SERVER(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can not be executed on a server window\n"),
- WEECHAT_ERROR, "part");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can not be executed on a server window\n"),
+ WEECHAT_ERROR, "part");
return -1;
}
channel_name = CHANNEL(gui_current_window->buffer)->name;
@@ -876,9 +907,9 @@ irc_cmd_send_part (t_irc_server *server, char *arguments)
if (BUFFER_IS_SERVER(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can not be executed on a server window\n"),
- WEECHAT_ERROR, "part");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can not be executed on a server window\n"),
+ WEECHAT_ERROR, "part");
return -1;
}
if (BUFFER_IS_PRIVATE(gui_current_window->buffer))
@@ -960,10 +991,9 @@ irc_cmd_send_query (t_irc_server *server, char *arguments)
if (!ptr_channel)
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s cannot create new private window \"%s\"\n"),
- WEECHAT_ERROR,
- arguments);
+ gui_printf_nolog (server->buffer,
+ _("%s cannot create new private window \"%s\"\n"),
+ WEECHAT_ERROR, arguments);
return -1;
}
gui_draw_buffer_title (ptr_channel->buffer, 1);
@@ -1209,9 +1239,9 @@ irc_cmd_send_topic (t_irc_server *server, char *arguments)
if (BUFFER_IS_SERVER(gui_current_window->buffer))
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can not be executed on a server window\n"),
- WEECHAT_ERROR, "topic");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can not be executed on a server window\n"),
+ WEECHAT_ERROR, "topic");
return -1;
}
channel_name = CHANNEL(gui_current_window->buffer)->name;
@@ -1315,9 +1345,9 @@ irc_cmd_send_voice (t_irc_server *server, int argc, char **argv)
else
{
irc_display_prefix (server->buffer, PREFIX_ERROR);
- gui_printf (server->buffer,
- _("%s \"%s\" command can only be executed in a channel window\n"),
- WEECHAT_ERROR, "voice");
+ gui_printf_nolog (server->buffer,
+ _("%s \"%s\" command can only be executed in a channel window\n"),
+ WEECHAT_ERROR, "voice");
return -1;
}
return 0;
diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c
index 781ce79a7..2edf085d2 100644
--- a/src/irc/irc-server.c
+++ b/src/irc/irc-server.c
@@ -527,8 +527,7 @@ server_msgq_flush ()
t_irc_message *next;
char *entire_line, *ptr_data, *pos, *pos2;
char *host, *command, *args;
-
- /* TODO: optimize this function, parse only a few messages (for low CPU time!) */
+
while (recv_msgq)
{
if (recv_msgq->data)
@@ -596,7 +595,7 @@ server_msgq_flush ()
irc_display_prefix (recv_msgq->server->buffer, PREFIX_ERROR);
gui_printf (recv_msgq->server->buffer,
_("%s Unknown command: cmd=%s, args=%s\n"),
- WEECHAT_ERROR, command, args);
+ WEECHAT_WARNING, command, args);
break;
}
diff --git a/src/irc/irc.h b/src/irc/irc.h
index d0aef2aac..e48ff289c 100644
--- a/src/irc/irc.h
+++ b/src/irc/irc.h
@@ -191,9 +191,9 @@ struct t_irc_message
/* DCC */
-typedef struct t_dcc t_dcc;
+typedef struct t_irc_dcc t_irc_dcc;
-struct t_dcc
+struct t_irc_dcc
{
t_irc_server *server; /* irc server */
int type; /* DCC type (send or receive) */
@@ -208,15 +208,16 @@ struct t_dcc
int filename_suffix; /* suffix (.1 for ex) if renaming file */
unsigned long size; /* file size */
unsigned long pos; /* number of bytes received/sent */
- t_dcc *prev_dcc; /* link to previous dcc file/chat */
- t_dcc *next_dcc; /* link to next dcc file/chat */
+ unsigned long ack; /* number of bytes received OK */
+ t_irc_dcc *prev_dcc; /* link to previous dcc file/chat */
+ t_irc_dcc *next_dcc; /* link to next dcc file/chat */
};
extern t_irc_command irc_commands[];
extern t_irc_server *irc_servers;
extern t_irc_message *recv_msgq, *msgq_last_msg;
extern int check_away;
-extern t_dcc *dcc_list;
+extern t_irc_dcc *dcc_list;
extern char *dcc_status_string[6];
extern char *channel_modes;
@@ -271,13 +272,13 @@ extern void nick_set_away (t_irc_channel *, t_irc_nick *, int);
/* DCC functions (irc-dcc.c) */
-extern void dcc_send ();
-extern void dcc_free (t_dcc *);
-extern void dcc_close (t_dcc *, int);
-extern void dcc_accept (t_dcc *);
-extern t_dcc *dcc_add (t_irc_server *, int, unsigned long, int, char *, char *,
- unsigned 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_handle ();
+extern void dcc_send (t_irc_server *, char *, char *);
extern void dcc_end ();
/* IRC display (irc-diplay.c) */