diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2005-02-20 00:08:22 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2005-02-20 00:08:22 +0000 |
commit | 3e816667526bebf7366e56ca9661c57b20dcb535 (patch) | |
tree | 61517cfef86ff23d72b190adc5a0c1bf240936b8 /src | |
parent | 6d0be7db4b417663ddc40c77978a354415dc82d7 (diff) | |
download | weechat-3e816667526bebf7366e56ca9661c57b20dcb535.zip |
Added DCC send
Diffstat (limited to 'src')
-rw-r--r-- | src/common/weechat.h | 4 | ||||
-rw-r--r-- | src/common/weeconfig.c | 9 | ||||
-rw-r--r-- | src/common/weeconfig.h | 1 | ||||
-rw-r--r-- | src/gui/curses/gui-display.c | 48 | ||||
-rw-r--r-- | src/gui/curses/gui-input.c | 49 | ||||
-rw-r--r-- | src/irc/irc-commands.c | 2 | ||||
-rw-r--r-- | src/irc/irc-dcc.c | 468 | ||||
-rw-r--r-- | src/irc/irc-recv.c | 183 | ||||
-rw-r--r-- | src/irc/irc-send.c | 148 | ||||
-rw-r--r-- | src/irc/irc-server.c | 5 | ||||
-rw-r--r-- | src/irc/irc.h | 23 |
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) */ |