diff options
Diffstat (limited to 'src/plugins/irc')
-rw-r--r-- | src/plugins/irc/irc-ctcp.c | 323 |
1 files changed, 240 insertions, 83 deletions
diff --git a/src/plugins/irc/irc-ctcp.c b/src/plugins/irc/irc-ctcp.c index c5e1bfa7a..e86a14c90 100644 --- a/src/plugins/irc/irc-ctcp.c +++ b/src/plugins/irc/irc-ctcp.c @@ -747,7 +747,7 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, const char *arguments, const char *message) { char *dcc_args, *pos, *pos_file, *pos_addr, *pos_port, *pos_size; - char *pos_start_resume, *filename; + char *pos_start_resume, *pos_token, *filename; struct t_infolist *infolist; struct t_infolist_item *item; char charset_modifier[1024]; @@ -773,36 +773,58 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, return; } - /* DCC filename */ + /* + * DCC SEND <filename> <address> <port> <filesize> [<token>] + * ^^^^^^^^^^ + **/ pos_file = dcc_args; while (pos_file[0] == ' ') { pos_file++; } - - /* look for file size */ - pos_size = strrchr (pos_file, ' '); - if (!pos_size) + if (pos_file[0] == '"') { - weechat_printf ( - server->buffer, - _("%s%s: cannot parse \"%s\" command"), - weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); - free (dcc_args); - return; + /* The file name is wrapped in double-quotes; find the terminating double-quote. */ + pos = strrchr (pos_file, '"'); + if (!pos || (pos == pos_file)) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[1] = '\0'; + pos += 2; } - - pos = pos_size; - pos_size++; - while (pos[0] == ' ') + else { - pos--; + pos = strchr (pos_file, ' '); + if (!pos) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[0] = '\0'; + pos++; } - pos[1] = '\0'; - /* look for DCC port */ - pos_port = strrchr (pos_file, ' '); - if (!pos_port) + /* + * DCC SEND <filename> <address> <port> <filesize> [<token>] + * ^^^^^^^^^ + **/ + pos_addr = pos; + while (pos_addr[0] == ' ') + { + pos_addr++; + } + pos = strchr (pos_addr, ' '); + if (!pos) { weechat_printf ( server->buffer, @@ -811,18 +833,20 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, free (dcc_args); return; } + pos[0] = '\0'; + pos++; - pos = pos_port; - pos_port++; - while (pos[0] == ' ') + /* + * DCC SEND <filename> <address> <port> <filesize> [<token>] + * ^^^^^^ + **/ + pos_port = pos; + while (pos_port[0] == ' ') { - pos--; + pos_port++; } - pos[1] = '\0'; - - /* look for DCC IP address */ - pos_addr = strrchr (pos_file, ' '); - if (!pos_addr) + pos = strchr (pos_port, ' '); + if (!pos) { weechat_printf ( server->buffer, @@ -831,18 +855,56 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, free (dcc_args); return; } + pos[0] = '\0'; + pos++; - pos = pos_addr; - pos_addr++; - while (pos[0] == ' ') + /* + * DCC SEND <filename> <address> <port> <filesize> [<token>] + * ^^^^^^^^^^ + **/ + pos_size = pos; + while (pos_size[0] == ' ') { - pos--; + pos_size++; + } + pos = strchr (pos_size, ' '); + if (pos) + { + /* + * DCC SEND <filename> <address> <port> <filesize> [<token>] + * ^^^^^^^^^ + **/ + pos[0] = '\0'; + pos_token = ++pos; + while (pos_token[0] == ' ') + { + pos_token++; + } + } + else + { + pos_token = NULL; } - pos[1] = '\0'; /* remove double quotes around filename */ filename = irc_ctcp_dcc_filename_without_quotes (pos_file); + /* use the local interface, from the server socket */ + memset (&addr, 0, sizeof (addr)); + length = sizeof (addr); + getsockname (server->sock, (struct sockaddr *)&addr, &length); + rc = getnameinfo ((struct sockaddr *)&addr, length, str_address, + sizeof (str_address), NULL, 0, NI_NUMERICHOST); + if (rc != 0) + { + weechat_printf ( + server->buffer, + _("%s%s: unable to resolve local address of server socket: error " + "%d %s"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, rc, gai_strerror (rc)); + return; + } + /* add DCC file via xfer plugin */ infolist = weechat_infolist_new (); if (infolist) @@ -863,6 +925,7 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PROXY)); weechat_infolist_new_var_string (item, "remote_address", pos_addr); weechat_infolist_new_var_integer (item, "port", atoi (pos_port)); + weechat_infolist_new_var_string (item, "token", pos_token); (void) weechat_hook_signal_send ("xfer_add", WEECHAT_HOOK_SIGNAL_POINTER, infolist); @@ -897,35 +960,58 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, return; } - /* DCC filename */ + /* + * DCC RESUME <filename> <port> <start_resume> [<token>] + * ^^^^^^^^^^ + **/ pos_file = dcc_args; while (pos_file[0] == ' ') { pos_file++; } - - /* look for resume start position */ - pos_start_resume = strrchr (pos_file, ' '); - if (!pos_start_resume) + if (pos_file[0] == '"') { - weechat_printf ( - server->buffer, - _("%s%s: cannot parse \"%s\" command"), - weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); - free (dcc_args); - return; + /* The file name is wrapped in double-quotes; find the terminating double-quote. */ + pos = strrchr (pos_file, '"'); + if (!pos || (pos == pos_file)) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[1] = '\0'; + pos += 2; } - pos = pos_start_resume; - pos_start_resume++; - while (pos[0] == ' ') + else { - pos--; + pos = strchr (pos_file, ' '); + if (!pos) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[0] = '\0'; + pos++; } - pos[1] = '\0'; - /* look for DCC port */ - pos_port = strrchr (pos_file, ' '); - if (!pos_port) + /* + * DCC RESUME <filename> <port> <start_resume> [<token>] + * ^^^^^^ + **/ + pos_port = pos; + while (pos_port[0] == ' ') + { + pos_port++; + } + pos = strchr (pos_port, ' '); + if (!pos) { weechat_printf ( server->buffer, @@ -934,13 +1020,36 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, free (dcc_args); return; } - pos = pos_port; - pos_port++; - while (pos[0] == ' ') + pos[0] = '\0'; + pos++; + + /* + * DCC RESUME <filename> <port> <start_resume> [<token>] + * ^^^^^^^^^^^^^^ + **/ + pos_start_resume = pos; + while (pos_start_resume[0] == ' ') { - pos--; + pos_start_resume++; + } + pos = strchr (pos_start_resume, ' '); + if (pos) + { + /* + * DCC RESUME <filename> <port> <start_resume> [<token>] + * ^^^^^^^^^ + **/ + pos[0] = '\0'; + pos_token = ++pos; + while (pos_token[0] == ' ') + { + pos_token++; + } + } + else + { + pos_token = NULL; } - pos[1] = '\0'; /* remove double quotes around filename */ filename = irc_ctcp_dcc_filename_without_quotes (pos_file); @@ -959,6 +1068,7 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, (filename) ? filename : pos_file); weechat_infolist_new_var_integer (item, "port", atoi (pos_port)); weechat_infolist_new_var_string (item, "start_resume", pos_start_resume); + weechat_infolist_new_var_string (item, "token", pos_token); (void) weechat_hook_signal_send ("xfer_accept_resume", WEECHAT_HOOK_SIGNAL_POINTER, infolist); @@ -993,35 +1103,58 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, return; } - /* DCC filename */ + /* + * DCC ACCEPT <filename> <port> <start_resume> [<token>] + * ^^^^^^^^^^ + **/ pos_file = dcc_args; while (pos_file[0] == ' ') { pos_file++; } - - /* look for resume start position */ - pos_start_resume = strrchr (pos_file, ' '); - if (!pos_start_resume) + if (pos_file[0] == '"') { - weechat_printf ( - server->buffer, - _("%s%s: cannot parse \"%s\" command"), - weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); - free (dcc_args); - return; + /* The file name is wrapped in double-quotes; find the terminating double-quote. */ + pos = strrchr (pos_file, '"'); + if (!pos || (pos == pos_file)) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[1] = '\0'; + pos += 2; } - pos = pos_start_resume; - pos_start_resume++; - while (pos[0] == ' ') + else { - pos--; + pos = strchr (pos_file, ' '); + if (!pos) + { + weechat_printf ( + server->buffer, + _("%s%s: cannot parse \"%s\" command"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, "privmsg"); + free (dcc_args); + return; + } + pos[0] = '\0'; + pos++; } - pos[1] = '\0'; - /* look for DCC port */ - pos_port = strrchr (pos_file, ' '); - if (!pos_port) + /* + * DCC ACCEPT <filename> <port> <start_resume> [<token>] + * ^^^^^^ + **/ + pos_port = pos; + while (pos_port[0] == ' ') + { + pos_port++; + } + pos = strchr (pos_port, ' '); + if (!pos) { weechat_printf ( server->buffer, @@ -1030,13 +1163,36 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, free (dcc_args); return; } - pos = pos_port; - pos_port++; - while (pos[0] == ' ') + pos[0] = '\0'; + pos++; + + /* + * DCC ACCEPT <filename> <port> <start_resume> [<token>] + * ^^^^^^^^^^^^^^ + **/ + pos_start_resume = pos; + while (pos_start_resume[0] == ' ') + { + pos_start_resume++; + } + pos = strchr (pos_start_resume, ' '); + if (pos) + { + /* + * DCC ACCEPT <filename> <port> <filesize> [<token>] + * ^^^^^^^^^ + **/ + pos[0] = '\0'; + pos_token = ++pos; + while (pos_token[0] == ' ') + { + pos_token++; + } + } + else { - pos--; + pos_token = NULL; } - pos[1] = '\0'; /* remove double quotes around filename */ filename = irc_ctcp_dcc_filename_without_quotes (pos_file); @@ -1055,6 +1211,7 @@ irc_ctcp_recv_dcc (struct t_irc_server *server, const char *nick, (filename) ? filename : pos_file); weechat_infolist_new_var_integer (item, "port", atoi (pos_port)); weechat_infolist_new_var_string (item, "start_resume", pos_start_resume); + weechat_infolist_new_var_string (item, "token", pos_token); (void) weechat_hook_signal_send ("xfer_start_resume", WEECHAT_HOOK_SIGNAL_POINTER, infolist); |