Definition in file irc.cpp.
#include <list>
#include <time.h>
#include <vector>
#include <map>
#include <string>
#include <stdlib.h>
#include "irc.h"
#include "log.h"
#include "sock.h"
#include "logic.h"
#include "dcc.h"
#include "shared.h"
#include "match.h"
#include "filesys.h"
#include "lang.h"
#include "conf.h"
#include "stats.h"
#include "params.h"
Include dependency graph for irc.cpp:
Go to the source code of this file.
Classes | |
struct | s_awaiting_response |
struct | s_key_chan |
Stores data about channel, which is +k, and we are trying all keys in whole history. More... | |
struct | s_log |
Stores data for repeat flood detection. More... | |
struct | s_mode_queue_entry |
One entry of mode queue (used when "compress_mode_wait" form conf.txt is more than zero). More... | |
struct | s_user_to_invite |
Stores informations about user to invite (+I). More... | |
Defines | |
#define | IRC_MSG_TOO_LONG 0x81234567L |
ERROR: msg is longer than 512 bytes. | |
#define | SOCK_SEND_ERROR 0x81234568L |
ERROR: not all the msg was sent. | |
Functions | |
int | cmp_strings_case_insensitive (string s1, string s2) |
Compares two strings, case in-sensitive. | |
void | dcc_loop () |
Check for pending connections and handles existing ones. | |
bool | irc_access_to_partyline (const char *hostmask, string &user_name_as_in_logic, string msg) |
Finds out if user has access to partyline; adds entry to tmp_users and performs WHOIS command if user is unknown yet. | |
void | irc_await_dcc_chat (string nick, string user_name_as_in_logic, int dcc_group) |
Called to await DCC connection from user. | |
bool | irc_ban (const char *channel, const char *mask) |
Bans (MODE #channel +b mask) host mask on channel. | |
void | irc_banned (string str) |
This is called on bot's JOIN, if the bot finds out that some user in logic.txt is banned; it forces on_banned event procedure to be called. | |
bool | irc_chan_mode (const char *channel, const char *mode, int priority) |
Sets mode of channel. | |
void | irc_check_bans (string channel) |
Checks ban list on channel after bot's JOIN by sending "MODE \#channel +b" command to server. | |
void | irc_check_flood (int type, string channel, string full_host, string msg) |
Checks flood limits and history for just received message. | |
void | irc_check_for_filesystem (string user_name, string channel, string nick) |
Check filesystem for new objects and notifies user if needed. | |
void | irc_check_for_not_invited (string channel) |
This is called on bot's JOIN, checks wheter some user in logic.txt is not invited; it forces on_not_invited event procedure to be called. | |
void | irc_check_for_not_reopped (string channel) |
This is called on bot's JOIN, checks wheter some user in logic.txt is not in +R list; it forces on_not_in_reopped procedure to be called. | |
void | irc_check_invites (string channel) |
Checks invites list on channel after bot's JOIN by sending "MODE \#channel +I" command to server. | |
bool | irc_check_last_msg (const char *start) |
Compares the beginning of message. | |
bool | irc_check_nick_on_channel (string nick, string channel) |
Checks wheter user is found on channel. | |
int | irc_connect (const char *bind_ip, const char *host_, unsigned short port) |
Connects to server. | |
bool | irc_deop (const char *channel, const char *nick, int priority) |
Sets -o (chan op) status to nick on channel. | |
bool | irc_devoice (const char *channel, const char *nick, int priority) |
Sets -v (voice) status to nick on channel. | |
int | irc_disconnect () |
Disconnects from server. | |
void | irc_end_of_excepted (string str) |
Called when bot after JOIN has received message indicating end of +e exceptions / or error, that irc network doesn't support +e exceptions. | |
void | irc_excepted (string str) |
Called as +e exception mask to ban is found out on channel after bot's JOIN. | |
s_online_user | irc_find_user (string nick) |
Finds s_online_user record in irc_channel list for user. | |
void | irc_get_005 (map< string, string > &raw, map< char, char > &prefix, string &chm_a, string &chm_b, string &chm_c, string &chm_d) |
Gets information from parsed RPL_ISUPPORT message (005 numeric). | |
string | irc_get_chan_mode (string channel, string &topic) |
Returns channel mode. | |
string | irc_get_fullname (string nick) |
Looks-up user from nick name and checks its full name. | |
string | irc_get_host (string nick) |
Looks-up host of online user. | |
string | irc_get_ident (string nick) |
Looks-up ident of online user. | |
string | irc_get_mode (string channel, string nick) |
Looks-up user from nick name and checks its mode on channel. | |
string | irc_get_modes_for_log (string channel, string nick) |
Looks-up user from nick name and returns their mode(s) for logging purposes to channel log. | |
string | irc_get_nick (string user) |
Looks-up user from name in logic.txt to nick name (if online). | |
bool | irc_get_online_channel (string channel_name, s_online_channel *&chan) |
Returns reference to channel that we are on. | |
bool | irc_got_op (string channel) |
Checks if bot has op (+o) on channel. | |
void | irc_in_reop (string str) |
Called as +R reop mask is found out on channel after bot's JOIN. | |
void | irc_internal_set_mode (string channel, string nick, char prefix, char mode) |
Resets user's old_mode atribute. | |
void | irc_invited (string str) |
Called as +I invitation mask to +i is found out on channel after bot's JOIN. | |
bool | irc_is_ircop (string nick) |
Looks-up user from name in logic.txt and checks if it is an irc operator (if online). | |
string | irc_is_online (string user) |
Looks-up user from name in logic.txt to nick name (if online). | |
bool | irc_join (const char *channel, const char *key) |
JOINs channel. | |
bool | irc_kick (const char *channel, const char *nick, const char *reason) |
Kicks nick on channel. | |
void | irc_kicked (string str) |
Called when user was KICKed and validates it (or calls on_kicked event). | |
void | irc_kill_command_wait (string command) |
Clears wait flag for sent command (reply has been received). | |
void | irc_kill_last_msg_wait (string resp) |
Clears wait flag for sent message (reply has been received). | |
int | irc_loop_process_input () |
This is called in loop to process messages from server. | |
bool | irc_loop_putserv () |
This function should be called in a loop to process send and receive to/from server. | |
void | irc_mode_change_ban (string channel, char prefix, string nick, string ident, string host, string mask) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-b to channel. | |
void | irc_mode_change_ban_exception (string channel, char prefix, string nick, string ident, string host, string mask) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-e to channel. | |
void | irc_mode_change_chan_key (string channel, char prefix, string nick, string ident, string host, string key) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-k KEY to channel. | |
void | irc_mode_change_chan_limit (string channel, char prefix, string nick, string ident, string host, string limit) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-l NUMBER to channel. | |
void | irc_mode_change_chan_status (string channel, char prefix, char mode, string nick, string ident, string host) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-a,i,m,n,q,p,s,r,t to channel. | |
void | irc_mode_change_creator (string channel, char prefix, string nick, string ident, string host, string whom) |
Evaluates, and validates (or accidentally calls specific event) MODE change +O/-O (creator) to user. | |
void | irc_mode_change_invitation (string channel, char prefix, string nick, string ident, string host, string mask) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-I to channel. | |
void | irc_mode_change_op (string channel, char prefix, string nick, string ident, string host, string whom) |
Evaluates, and validates (or accidentally calls specific event) MODE change +o/-o (op-erator) to user. | |
void | irc_mode_change_other (string channel, char prefix, char mode, string nick, string ident, string host, string whom) |
Evaluates, and validates (or accidentally calls specific event) MODE change with other modes to user. | |
void | irc_mode_change_other_mask (string channel, char prefix, string nick, string ident, string host, string mask) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/- other modes with mask (class A) to channel. | |
void | irc_mode_change_reop (string channel, char prefix, string nick, string ident, string host, string mask) |
Evaluates, and validates (or accidentally calls specific event) MODE change +/-R to channel. | |
void | irc_mode_change_voice (string channel, char prefix, string nick, string ident, string host, string whom) |
Evaluates, and validates (or accidentally calls specific event) MODE change +v/-v (voice) to user. | |
bool | irc_notice (const char *target, const char *msg, int priority) |
Sends NOTICE to user/channel. | |
void | irc_on_broadcast (string bcast_mask, int type, string full_host, string msg, string server, unsigned short port) |
Raises on_broadcast event. | |
void | irc_on_notice (string channel, string full_host, string msg) |
Raises on_notice event if defined for specific user and channel. | |
void | irc_on_privmsg (string channel, string full_host, string msg) |
Raises on_privmsg event if defined for specific user and channel. | |
bool | irc_op (const char *channel, const char *nick, int priority) |
Sets +o (chan op) status to nick on channel. | |
void | irc_parse_modes (string modes, map< char, string > &with_param, string &plain) |
Parses a channel mode. | |
bool | irc_part (const char *channel, const char *reason) |
PARTs channel. | |
bool | irc_privmsg (const char *target, const char *msg, int priority) |
Sends PRIVMSG to user/channel. | |
void | irc_put (string data, int priority) |
Raw-ly puts message to queue to send to server. | |
void | irc_put_multiple_lines (string command, string nick, string msg) |
Parses the message (scans for new line character) and sends it to the server. | |
bool | irc_putserv (const char *msg, bool wait_for_response, int priority) |
Puts message for server to queue to send. | |
int | irc_putserv_immediately (s_socket &socket, const char *msg, bool wait_for_response=false) |
Imeddiately sends message to server. | |
void | irc_quit (const char *reason) |
Quits the IRC. | |
void | irc_quoted_callback (const char *str, const char *nick, const char *host_mask) |
Called when 0x01-quoted PRIVMSG has been received to initialise DCC CHAT or DCC SEND connection. | |
void | irc_rehashed () |
Called from logic.cpp after rehashing. Deletes all online users and so applies new configuration. | |
void | irc_remove_redundant_mode (string channel, string nick, string mode) |
If "smart_mode" in conf.txt is non-zero, removes redundant modes from mode_queue. | |
void | irc_remove_redundant_mode2 () |
If "smart_mode" in conf.txt is non-zero, removes redundant modes from mode_queue. | |
void | irc_RPL_324 (string str) |
Called after receiving 324 numeric from server (channel modes after MODE #channel), and calls on_key, on_limit functions after parsing the message. | |
void | irc_RPL_ENDOFWHOIS (string str) |
This must be called as RPL_ENDOFWHOIS reply from server - the end of WHOIS list for user. | |
void | irc_RPL_ISUPPORT (string str) |
Parses and evaluates RPL_ISUPPORT reply (005 numerics). | |
void | irc_RPL_MODE (string str) |
Called after receiving RPL_MODE from server (someone has changed MODE for channel), and calls irc_mode_change_XXX functions after parsing the message. | |
void | irc_RPL_NAMREPLY (string str) |
Parses and evaluates RPL_NAMREPLY reply (reply to NAME command). | |
void | irc_RPL_TOPIC (string str) |
Called after receiving RPL_TOPIC from server (someone has changed TOPIC for channel), and calls logic_validate_topic function after parsing the message. | |
void | irc_RPL_WHOISCHANNELS (string str) |
void | irc_RPL_WHOISOPERATOR (string str) |
Parses and evaluates RPL_WHOISOPERATOR reply (partial reply to WHOIS command). | |
void | irc_RPL_WHOISUSER (string str) |
Parses and evaluates RPL_WHOISUSER reply (partial reply to WHOIS command). | |
void | irc_RPL_YOURID (string str) |
Parses and evaluates RPL_YOURID reply (your unique ID). | |
void | irc_set_redir (bool follow_redirs) |
Sets value of irc_follow_redirs flag. | |
string | irc_to_upper (string str) |
Converts string to UPPER case (using touppertab[] in match.cpp). | |
bool | irc_unban (const char *channel, const char *mask) |
Unbans (MODE #channel -b mask) host mask on channel. | |
void | irc_user_mode_change (string channel, string nick, string from_nick, char prefix, char mode) |
Adds/remove new mode for user on channel. | |
bool | irc_voice (const char *channel, const char *nick, int priority) |
Sets +v (voice) status to nick on channel. | |
bool | logic_botnet_get_user (string name, s_user &user) |
Gets user definition. | |
void | logic_get_flood_limits (string channel, string user, s_flood &msg_flood, s_flood ¬ice_flood, s_flood &repeat_flood, s_flood &nick_flood, s_flood &join_flood, s_flood &mode_flood, s_flood &ctcp_flood) |
Retrieves flood limits. | |
char * | ltoa (long value, char *buffer, int radix) |
ltoa() emulation for compiler which doesn't have it | |
void | sleep (int ms) |
Sleeps. | |
Variables | |
vector< s_dcc_awaiting_user > | dcc_awaiting_users |
Stores users who are waiting for DCC connection. | |
vector< s_dcc_request_whois > | dcc_request_whois |
Array, that stores DCC requests that are pending to establis, and waiting for whois result. | |
time_t | filesys_last_notify |
Timestam of last filesystem notification. | |
time_t | filesys_notify_interval |
Interval for filesystem notifications. | |
list< s_flood_history > | flood_history |
History of messages sent to server (for bot's flood control). | |
list< s_flood_history > | flood_history_other |
History of other messages sent to server (non-PRIVMSG && non-NOTICE) (for bot's flood protection). | |
vector< s_online_user > | gone_users |
Temporary list of users that have QUIT/PART/been KICK-ed. | |
size_t | irc_bot_flood_bytes |
Number of bytes considered as flood from bot. | |
unsigned int | irc_bot_flood_lines |
Number of lines maximum in irc_bot_flood_seconds. | |
time_t | irc_bot_flood_other_seconds |
Number of seconds to clear flood buffer for non-PRIVMSG && non-NOTICE messages (from bot). | |
time_t | irc_bot_flood_seconds |
Number of seconds to clear flood buffer (from bot). | |
vector< string > | irc_cannot_join_channels |
List of channels that i am banned. | |
vector< s_online_channel > | irc_channels |
List of channels we are on. | |
bool | irc_follow_redirs = false |
Stores "allow_redirect" state from logic.txt (true if bot should follow redirect hints from server). | |
char | irc_fullname [512] |
Bot's current full name. | |
string | irc_ident = "*" |
Bot's ident username. | |
s_005 | irc_isupport |
bool | irc_keepalive_sent |
Was WHOIS sent? | |
vector< s_key_chan > | irc_key_chans |
List of channels which we are not on, because they are +k and we are trying all keys in the history. | |
time_t | irc_last_join_try |
Timestamp of last try to join because of +b on myself, or +l, or +i. | |
time_t | irc_last_keepalive_detection |
Used for storing time of last command sent to server (for detection of lost connection). | |
char | irc_nick [512] |
Bot's current nick. | |
vector< string > | irc_nicks |
Bot's nicks available to try them if they are unused (from logic.txt). | |
unsigned short | irc_recommended_port |
Hint from server: recommended port (together with irc_recommended_server). | |
string | irc_recommended_server |
Hint from server: recommended server (together with irc_recommended_port). | |
string | irc_server_host |
Current IRC server host. | |
vector< s_irc_server >::iterator | irc_server_iterator |
Current irc server. | |
unsigned short | irc_server_port |
Current IRC server port. | |
vector< s_irc_server > | irc_servers |
List of irc servers. | |
s_socket | irc_socket |
Handle of socket connected to server (zero for disconnected state). | |
bool | irc_socket_error |
If true, then we have socket error on connection to IRC server. | |
char | irc_unique_id [512] |
Bot's unique ID. | |
s_msg_to_server | last_msg |
Last message sent to server. | |
list< s_mode_queue_entry > | mode_queue |
Mode queue used when "compress_mode_wait" form conf.txt is more than zero. | |
list< s_mode_queue_entry > | modes_from_server |
Modes that server set. | |
list< char * > | msgs_from_server |
Queue of messages from server to be processed. | |
list< s_msg_to_server > | msgs_to_server |
Queue of messages that are waiting to be sent to server (for bot's flood control). | |
list< s_msg_to_server > | msgs_to_server2 |
Queue of messages that are waiting to be sent to server (for bot's flood control), but these has lower priority (notifies). | |
vector< s_channel_def > | r_channel_defs |
List of real channel definitions (not temporary / compilation!). | |
vector< s_channel > | r_channels |
List of channels for real usage (not temporary / compilation!). | |
vector< s_user > | r_users |
List of users for real usage (not temporary / compilation!). | |
vector< s_online_user > | tmp_users |
Temporary list of users. | |
vector< s_online_channel > | unknown_users_on_channels |
Temporary list of user used ONLY for flood history. | |
vector< s_awaiting_response > | waiting_for_response |
Array of last messages to server. |
|
ERROR: msg is longer than 512 bytes.
Definition at line 327 of file irc.cpp. Referenced by irc_loop_putserv(), and irc_putserv_immediately(). |
|
ERROR: not all the msg was sent.
Definition at line 332 of file irc.cpp. Referenced by irc_loop_putserv(), and irc_putserv_immediately(). |
|
|
Check for pending connections and handles existing ones.
Definition at line 16339 of file dcc.cpp. References s_dcc_awaiting_user::addr4, s_dcc_awaiting_user::addr6, s_dcc_client::as_in_logic, botnet_partyline_join_channel(), botnet_partyline_leave_channel(), botnet_partyline_message(), botnet_received_data_from_telnet(), botnet_showbots(), s_flood_history::bytes, s_dcc_client::chat, s_socket::clear(), s_socket::cmp(), cmp_strings_case_insensitive(), conf_getvar(), conf_rehash(), DCC_ACCESS_DENIED, dcc_apply(), dcc_awaiting_send, dcc_awaiting_users, dcc_can_unassign(), dcc_check_for_filesystem(), dcc_check_limit(), dcc_clients, dcc_get_line(), dcc_get_password(), DCC_IO_ERROR, dcc_killing_user_eol, dcc_killing_user_lang, dcc_loop_edit_chan(), dcc_loop_edit_dynbans(), dcc_loop_edit_proc(), dcc_loop_edit_rproc(), dcc_loop_edit_user1(), dcc_loop_edit_user2(), dcc_loop_filesystem(), dcc_loop_get_rights(), dcc_loop_language(), dcc_loop_msg(), dcc_loop_new_user(), dcc_loop_private(), dcc_loop_replication(), dcc_loop_terminator(), DCC_NO_SUCH_FILE, s_dcc_client::dcc_send, dcc_send_file(), dcc_send_msg(), dcc_servers, dcc_set_password(), dcc_to_resume, dcc_upgrade(), dcc_users_to_lock_out, dcc_want_to_die, dcc_want_to_restart, dcc_want_to_upgrade, dcc_who_is_killing, s_dcc_client::edit_user, s_dcc_client_to_resume::file_name, s_dcc_client_to_resume::file_size, FILE_SLASH, files, filesys_add_file_raw(), filesys_check_add_file_raw(), filesys_dcc_check_for_notifies(), filesys_dcc_drop_notifies(), filesys_dcc_get_resume_info(), filesys_set_file_was_read(), s_dcc_client::filesystem, s_dcc_awaiting_user::fullname, s_dcc_client::fullname, s_dcc_client::got_passwd, s_dcc_client::got_user_name, s_socket::handle, s_dcc_awaiting_user::host, s_socket::host, s_dcc_client::host, s_dcc_awaiting_user::ident, s_dcc_client::ident, inet_ntop(), inet_pton(), s_dcc_client_to_resume::ip_addr4, s_dcc_client_to_resume::ip_addr6, irc_channels, irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_get_mode(), irc_get_nick(), irc_is_ircop(), irc_join(), irc_nick, irc_part(), irc_rehashed(), s_dcc_client::s_dcc_client_send::is_file_server_proto, s_dcc_client::lang, lang_get_string(), lang_rehash(), lang_subst(), last_new_instance_join, log_bot(), log_debug(), log_free_locks(), log_socket(), logic_access_to_filesystem(), logic_access_to_partyline(), logic_eval(), logic_execute(), logic_filesys_got_new(), logic_find_user(), logic_is_replication_partner(), logic_on_internal_event(), logic_partyline_backup(), logic_partyline_get_user(), logic_partyline_rehash(), logic_partyline_whois(), ltoa(), match(), MD5Final(), MD5Init(), MD5Update(), s_flood_history::msg, s_group::name, NEW_INSTANCE_TIMEOUT_AFTER_LAST_JOIN, s_dcc_client::new_user, s_dcc_awaiting_user::nick, s_dcc_client::nick, s_dcc_client::s_dcc_client_send::original_name, s_dcc_client_to_resume::port, PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL, r_all_groups, s_dcc_client::remote, s_user_to_lock_out::remote, s_dcc_client::replication_partner, s_dcc_client::resume_pos, s_dcc_client::send, s_dcc_client::send_file, s_dcc_client::send_from_filesystem, s_ssl_conf::server_cert, s_ssl_conf::server_key, s_dcc_client::server_socket, s_dcc_client::s_dcc_client_send::size, sock_accept(), sock_accept6(), sock_async(), sock_cancel_caching(), sock_close(), sock_connect(), sock_error(), sock_flush_later(), sock_get_last_io(), sock_get_receive_size(), sock_get_remote_addr(), sock_read(), sock_send(), sock_set_blocking(), s_dcc_client::socket, s_ssl_conf::ssl_bots, ssl_close(), ssl_server_accept(), ssl_server_connection(), s_dcc_awaiting_user::start_time, stats_dcc_chat_bytes_received(), stats_dcc_chat_bytes_sent(), stats_dcc_chat_new_connection(), stats_dcc_send_bytes_received(), stats_dcc_send_bytes_sent(), stats_dcc_send_new_connection(), stats_display(), s_dcc_client::telnet, telnet_servers, s_flood_history::time, s_user_to_lock_out::timestamp, s_dcc_client_to_resume::user_name, s_dcc_awaiting_user::user_name_as_in_logic, s_dcc_awaiting_user::using_ipv6, s_dcc_client_to_resume::using_ipv6, and VERSION. Referenced by irc_loop_process_input(), logic_exec(), and sleep(). 16340 { 16341 if(dcc_want_to_upgrade && last_new_instance_join+NEW_INSTANCE_TIMEOUT_AFTER_LAST_JOIN<time(NULL)) { 16342 dcc_want_to_upgrade=false; 16343 dcc_want_to_die=true; 16344 } 16345 16346 { 16347 vector<s_dcc_client_to_resume>::iterator i1; 16348 again__: 16349 for(i1=dcc_to_resume.begin(); i1!=dcc_to_resume.end(); i1++) { 16350 if((*i1).start_time+10<time(NULL)) { 16351 // client probably doesn't support resume 16352 // so connect 16353 16354 s_dcc_client_to_resume res=*i1; 16355 dcc_to_resume.erase(i1); 16356 16357 string ip_addr; 16358 if(!res.using_ipv6) 16359 ip_addr=res.ip_addr4; 16360 else 16361 ip_addr=res.ip_addr6; 16362 unsigned short port=res.port; 16363 16364 string dcc_bind_ip=conf_getvar("dcc_bind_ip"); 16365 if(dcc_bind_ip.empty()) 16366 dcc_bind_ip="0.0.0.0"; 16367 string dcc_bind_ip6=conf_getvar("dcc_bind_ip6"); 16368 if(dcc_bind_ip6.empty()) 16369 dcc_bind_ip6="::"; 16370 16371 int ec=0; 16372 s_socket s; 16373 if(!res.using_ipv6) 16374 s=sock_connect((char*)dcc_bind_ip.c_str(),(char*)ip_addr.c_str(),port,ec,true); 16375 else 16376 s=sock_connect((char*)dcc_bind_ip6.c_str(),(char*)ip_addr.c_str(),port,ec,true); 16377 if(s.cmp()==false || ec) { 16378 log_socket(ec,sock_error(ec),"while calling sock_connect in file " __FILE__ " in function " __FUNC__); 16379 goto again__; 16380 } 16381 16382 s_dcc_client c; 16383 16384 c.nick=(*i1).nick; 16385 c.ident=irc_get_ident((*i1).nick); 16386 c.host=irc_get_host((*i1).nick); 16387 c.fullname=irc_get_fullname((*i1).nick); 16388 16389 c.resume_pos=0; 16390 16391 c.chat=false; 16392 c.send=true; 16393 c.send_from_filesystem=false; 16394 c.socket=s; 16395 16396 c.server_socket.clear(); 16397 c.telnet=false; 16398 c.got_passwd=0; 16399 c.new_user=0; 16400 c.edit_user=0; 16401 c.filesystem=0; 16402 c.as_in_logic=res.user_name; 16403 c.got_user_name=(c.as_in_logic.empty()?false:true); 16404 16405 c.dcc_send.size=res.file_size; 16406 c.dcc_send.original_name=res.file_name; 16407 c.dcc_send.is_file_server_proto=false; 16408 16409 dcc_clients.push_back(c); 16410 dcc_check_limit(); 16411 16412 goto again__; 16413 } 16414 } 16415 } 16416 16417 vector<s_dcc_client>::iterator i; 16418 char dcc_eol[4]="\n\0"; 16419 char telnet_eol[4]="\r\n\0"; 16420 again: 16421 for(i=dcc_clients.begin(); i!=dcc_clients.end(); i++) { 16422 if((*i).replication_partner) { 16423 if(!(*i).telnet_botnet_called) { 16424 if((*i).telnet_buffer_pos) { 16425 unsigned int i1; 16426 for(i1=0; i1<(*i).telnet_buffer_pos; i1++) 16427 if((*i).telnet_buffer[i1]=='\r' || (*i).telnet_buffer[i1]=='\n') 16428 break; 16429 if((*i).telnet_buffer[i1]=='\r' || (*i).telnet_buffer[i1]=='\n') 16430 i1++; 16431 if((*i).telnet_buffer[i1]=='\r' || (*i).telnet_buffer[i1]=='\n') 16432 i1++; 16433 unsigned int begin=i1; 16434 (*i).telnet_buffer_pos-=begin; 16435 16436 botnet_received_data_from_telnet((*i).socket,(*i).as_in_logic,&(*i).telnet_buffer[begin],(*i).telnet_buffer_pos,(*i).ssl_connection?(*i).ssl:NULL,(*i).remote); 16437 (*i).telnet_buffer_pos=0; 16438 (*i).telnet_botnet_called=true; 16439 } else { 16440 botnet_received_data_from_telnet((*i).socket,(*i).as_in_logic,NULL,0,(*i).ssl_connection?(*i).ssl:NULL,(*i).remote); 16441 (*i).telnet_botnet_called=true; 16442 } 16443 if((*i).ssl_connection) { 16444 if(!ssl_server_accept((*i).ssl,&((*i).socket))) { 16445 continue; 16446 } 16447 } 16448 } 16449 if((*i).socket.cmp()==false) { 16450 if((*i).ssl_connection) { 16451 ssl_close((*i).ssl,&((*i).socket)); 16452 } 16453 dcc_clients.erase(i); 16454 goto again; 16455 } 16456 continue; 16457 } 16458 16459 string eol=(*i).telnet?telnet_eol:dcc_eol; 16460 if((*i).chat) { 16461 if((*i).lang.empty()) 16462 (*i).lang="en"; 16463 16464 long dcc_always_want_nick=atol(conf_getvar("dcc_always_want_nick").c_str()); 16465 if(dcc_always_want_nick && (*i).got_user_name) { 16466 (*i).got_user_name=false; 16467 (*i).supposed_to_be=(*i).as_in_logic; 16468 (*i).as_in_logic=""; 16469 16470 string disp=lang_get_string(1,(*i).lang,167)+eol; 16471 int ec=0; 16472 size_t sent=sock_send((*i).socket,disp.c_str(),disp.length(),ec); 16473 stats_dcc_chat_bytes_sent(sent); 16474 } 16475 if(!dcc_always_want_nick) 16476 (*i).supposed_to_be=(*i).as_in_logic; 16477 16478 { 16479 int ec=0; 16480 char buff[5*1024+1]; 16481 bool closed; 16482 int max_len=sizeof(buff)-1; 16483 if((*i).got_passwd<=1 && (*i).telnet) { 16484 max_len=1; 16485 if((*i).in_buff.length()>128) { 16486 // drop 16487 sock_close((*i).socket); 16488 dcc_clients.erase(i); 16489 goto again; 16490 } 16491 } 16492 size_t len=sock_read((*i).socket,buff,max_len,ec,closed); 16493 if(ec==0) { 16494 buff[len]=0; 16495 stats_dcc_chat_bytes_received(len); 16496 } 16497 if(closed || ec) { 16498 if((*i).partyline_channel.compare("")) 16499 botnet_partyline_leave_channel((*i).as_in_logic,(*i).partyline_channel); 16500 (*i).partyline_channel=""; 16501 if(dcc_killing_user_socket && (*i).socket.handle==dcc_killing_user_socket->handle) 16502 dcc_killing_user_socket=NULL; 16503 sock_close((*i).socket); 16504 dcc_clients.erase(i); 16505 goto again; 16506 } 16507 if(len) { 16508 (*i).last_input=time(NULL); 16509 if((*i).got_passwd==1) { 16510 string disp; 16511 unsigned int i1; 16512 for(i1=0; i1<len; i1++) 16513 disp+="\x08"; 16514 for(i1=0; i1<len; i1++) 16515 disp+=" "; 16516 for(i1=0; i1<len; i1++) 16517 disp+="\x08"; 16518 int ec=0; 16519 if((*i).telnet) 16520 dcc_send_msg((*i).socket,disp,ec); 16521 } 16522 (*i).in_buff+=buff; 16523 (*i).telnet_buffer_pos=len; 16524 if((*i).telnet_buffer_pos>sizeof((*i).telnet_buffer)) 16525 (*i).telnet_buffer_pos=sizeof((*i).telnet_buffer); 16526 memcpy((*i).telnet_buffer,buff,(*i).telnet_buffer_pos); 16527 } 16528 } 16529 16530 if((*i).as_in_logic.empty()) { 16531 string ln=dcc_get_line((*i).in_buff); 16532 if(!ln.empty() && match("### *",(char*)ln.c_str())) { 16533 (*i).as_in_logic=ln; 16534 (*i).got_passwd=0; 16535 16536 string pswd=dcc_get_password((*i).as_in_logic); 16537 if(pswd.empty()) { 16538 // do not hav password set yet 16539 if((*i).supposed_to_be.compare((*i).as_in_logic)) { 16540 // it is different user! SPOOFING! 16541 string disp=lang_get_string(1,"en",698)+eol; 16542 int ec=0; 16543 dcc_send_msg((*i).socket,disp,ec); 16544 sock_close((*i).socket); 16545 dcc_clients.erase(i); 16546 break; 16547 } 16548 } 16549 } 16550 } 16551 if((*i).got_passwd==0) { 16552 { 16553 int secs=atol(conf_getvar("lockout_duration").c_str()); 16554 vector<s_user_to_lock_out>::iterator i1; 16555 lock_a: 16556 for(i1=dcc_users_to_lock_out.begin(); i1!=dcc_users_to_lock_out.end(); i1++) 16557 if((*i1).timestamp+secs<time(NULL)) { 16558 dcc_users_to_lock_out.erase(i1); 16559 goto lock_a; 16560 } 16561 int num=0; 16562 for(i1=dcc_users_to_lock_out.begin(); i1!=dcc_users_to_lock_out.end(); i1++) 16563 if(!(*i1).remote.compare((*i).remote)) 16564 num++; 16565 int max=atol(conf_getvar("lockout_count").c_str()); 16566 if(max!=0 && num>=max) { 16567 string disp=lang_get_string(1,"en",612)+eol; 16568 int ec=0; 16569 dcc_send_msg((*i).socket,disp,ec); 16570 sock_close((*i).socket); 16571 dcc_clients.erase(i); 16572 break; 16573 } 16574 } 16575 16576 (*i).new_user=0; 16577 (*i).edit_user=0; 16578 (*i).edit_proc=0; 16579 (*i).edit_chan=0; 16580 (*i).filesystem=0; 16581 (*i).edit_proc=0; 16582 (*i).edit_chan=0; 16583 (*i).filesystem=0; 16584 (*i).msg=0; 16585 (*i).private_edit=0; 16586 (*i).replication=0; 16587 (*i).terminator=0; 16588 (*i).language=0; 16589 16590 if(logic_is_replication_partner((*i).as_in_logic)) { 16591 (*i).chat=false; 16592 (*i).replication_partner=true; 16593 (*i).telnet_botnet_called=false; 16594 vector<s_ssl_bot>::iterator i1; 16595 for(i1=ssl_conf.ssl_bots.begin(); i1!=ssl_conf.ssl_bots.end(); i1++) { 16596 if(!(*i).as_in_logic.compare((*i1).botname)) { 16597 sock_cancel_caching((*i).socket); 16598 (*i).replication_partner=true; 16599 (*i).ssl_connection=true; 16600 char err_str[1024]; 16601 size_t len; 16602 sock_set_blocking((*i).socket,true); 16603 do 16604 len=recv((*i).socket.handle,err_str,sizeof(err_str),0); 16605 while((signed)len>0); 16606 16607 int ec=0; 16608 bool closed=false; 16609 do 16610 len=sock_read((*i).socket,err_str,sizeof(err_str),ec,closed); 16611 while((signed)len>0); 16612 16613 if(ssl_server_connection((*i).ssl,&((*i).socket),err_str,(char*)ssl_conf.server_cert.c_str(),(char*)ssl_conf.server_key.c_str(),(char*)(*i1).cert.c_str())) { 16614 sock_close((*i).socket); 16615 dcc_clients.erase(i); 16616 goto again; 16617 } 16618 botnet_received_data_from_telnet((*i).socket,(*i).as_in_logic,(*i).telnet_buffer,0,(*i).ssl,(*i).remote); 16619 (*i).telnet_buffer_pos=0; 16620 (*i).telnet_botnet_called=true; 16621 char tmp=0x01; 16622 send((*i).socket.handle,&tmp,1,0); 16623 dcc_clients.erase(i); 16624 16625 sock_set_blocking((*i).socket,true); 16626 16627 goto again; 16628 } 16629 } 16630 continue; 16631 } 16632 16633 if((*i).as_in_logic.empty()) 16634 continue; 16635 16636 string pswd=dcc_get_password((*i).as_in_logic); 16637 (*i).lang="en"; 16638 string disp=lang_subst(lang_get_string(1,(*i).lang,1),conf_getvar("botname"))+eol+lang_subst(lang_get_string(1,(*i).lang,640),VERSION)+eol+lang_subst(lang_get_string(1,(*i).lang,2),conf_getvar("admin"))+eol; 16639 int ec=0; 16640 dcc_send_msg((*i).socket,disp,ec); 16641 if(!pswd.compare("")) 16642 disp=lang_get_string(1,(*i).lang,3)+eol; 16643 else 16644 disp=lang_get_string(1,(*i).lang,4)+eol; 16645 dcc_send_msg((*i).socket,disp,ec); 16646 (*i).got_passwd++; 16647 (*i).in_buff=""; 16648 continue; // very important 16649 } 16650 if((*i).got_passwd==1) { 16651 string pswd=dcc_get_password((*i).as_in_logic); 16652 string p=dcc_get_line((*i).in_buff); 16653 if(p.empty() || !match("### *",(char*)p.c_str())) 16654 continue; 16655 string disp=eol; 16656 int ec=0; 16657 dcc_send_msg((*i).socket,disp,ec); 16658 16659 if(!logic_access_to_partyline((*i).as_in_logic)) { 16660 s_user_to_lock_out u; 16661 u.timestamp=time(NULL); 16662 u.remote=(*i).remote; 16663 dcc_users_to_lock_out.push_back(u); 16664 16665 string disp=lang_get_string(1,(*i).lang,5)+eol; 16666 int ec=0; 16667 dcc_send_msg((*i).socket,disp,ec); 16668 sock_close((*i).socket); 16669 dcc_clients.erase(i); 16670 goto again; 16671 } 16672 16673 unsigned char signature[16]; 16674 16675 MD5Context md5c; 16676 MD5Init(&md5c); 16677 MD5Update(&md5c,(unsigned char *)p.c_str(),(unsigned int)p.length()); 16678 MD5Final(signature,&md5c); 16679 16680 char sig[128]; 16681 sig[0]=0; 16682 for(int i1=0; i1<16; i1++) { 16683 char tmp[16]; 16684 sprintf(tmp,"%02X",signature[i1]); 16685 strcat(sig,tmp); 16686 } 16687 16688 if(cmp_strings_case_insensitive(pswd,sig)!=0 && pswd.compare("")) { 16689 s_user_to_lock_out u; 16690 u.timestamp=time(NULL); 16691 u.remote=(*i).remote; 16692 dcc_users_to_lock_out.push_back(u); 16693 16694 string disp=lang_get_string(1,(*i).lang,5)+eol; 16695 int ec=0; 16696 dcc_send_msg((*i).socket,disp,ec); 16697 sock_close((*i).socket); 16698 dcc_clients.erase(i); 16699 break; 16700 } 16701 16702 if(!pswd.compare("")) { 16703 // we got a new password set now! 16704 if((*i).telnet) { 16705 string disp=lang_subst(lang_get_string(1,(*i).lang,689),conf_getvar("admin"))+eol; 16706 int ec=0; 16707 dcc_send_msg((*i).socket,disp,ec); 16708 sock_close((*i).socket); 16709 dcc_clients.erase(i); 16710 break; 16711 } else { 16712 if(dcc_want_to_upgrade) { 16713 string disp=lang_get_string(1,(*i).lang,642)+eol; 16714 int ec=0; 16715 dcc_send_msg((*i).socket,disp,ec); 16716 } else 16717 dcc_set_password((*i).as_in_logic,sig); 16718 } 16719 } 16720 16721 (*i).got_passwd++; 16722 } 16723 if((*i).got_passwd==2) { 16724 FILE* in=fopen("motd.txt","r"); 16725 char ln[10240+1]; 16726 while(in && !feof(in)) { 16727 if(fgets(ln,1024*10-1,in)==NULL) 16728 break; 16729 ln[10240]=0; 16730 if(ln[strlen(ln)-1]=='\r') 16731 ln[strlen(ln)-1]=0; 16732 if(ln[strlen(ln)-1]=='\n') 16733 ln[strlen(ln)-1]=0; 16734 if(ln[strlen(ln)-1]=='\r') 16735 ln[strlen(ln)-1]=0; 16736 if(ln[strlen(ln)-1]=='\n') 16737 ln[strlen(ln)-1]=0; 16738 string disp=(string)ln+eol; 16739 int ec=0; 16740 dcc_send_msg((*i).socket,disp,ec); 16741 } 16742 if(in) 16743 fclose(in); 16744 (*i).got_passwd++; 16745 dcc_loop_get_rights(i); 16746 16747 dcc_check_for_filesystem((*i).as_in_logic); 16748 16749 /*vector<s_dcc_notify> notify; 16750 filesys_dcc_check_for_notifies((*i).as_in_logic,notify); 16751 16752 string files; 16753 16754 vector<s_dcc_notify>::iterator i1; 16755 for(i1=notify.begin(); i1!=notify.end(); i1++) { 16756 if((*i1).unpublished) { 16757 if(!files.empty()) 16758 files+=", "; 16759 files+=(*i1).name; 16760 } 16761 } 16762 16763 if(!files.empty()) { 16764 string disp=lang_get_string(1,(*i).lang,274)+eol; 16765 int ec=0; 16766 dcc_send_msg((*i).socket,disp,ec); 16767 }*/ 16768 16769 (*i).partyline_channel=""; 16770 } 16771 16772 if((*i).got_passwd!=3) 16773 continue; 16774 16775 dcc_loop_new_user(i,eol); 16776 16777 dcc_loop_edit_user1(i,eol); 16778 dcc_loop_edit_user2(i,eol); 16779 16780 dcc_loop_edit_rproc(i,eol); 16781 16782 dcc_loop_edit_proc(i,eol); 16783 16784 dcc_loop_edit_chan(i,eol); 16785 16786 dcc_loop_filesystem(i,eol); 16787 16788 dcc_loop_msg(i,eol); 16789 16790 dcc_loop_private(i,eol); 16791 16792 dcc_loop_replication(i,eol); 16793 16794 dcc_loop_terminator(i,eol); 16795 16796 dcc_loop_language(i,eol); 16797 16798 dcc_loop_edit_dynbans(i,eol); 16799 16800 { 16801 int dcc_chat_ping_interval=atol(conf_getvar("dcc_chat_ping_interval").c_str()); 16802 if(dcc_chat_ping_interval && sock_get_last_io((*i).socket)+dcc_chat_ping_interval<=time(NULL)) { 16803 time_t last_read=sock_get_last_io((*i).socket,'r'); 16804 16805 string disp=lang_get_string(1,(*i).lang,611); 16806 16807 time_t diff=time(NULL)-last_read; 16808 time_t days=diff/(24*60*60); 16809 diff%=24*60*60; 16810 time_t hrs=diff/(60*60); 16811 diff%=60*60; 16812 time_t mins=diff/(60); 16813 diff%=60; 16814 time_t secs=diff; 16815 16816 string idle=lang_get_string(1,(*i).lang,695); 16817 char tmp[128]; 16818 idle=lang_subst(idle,ltoa((long)days,tmp,10)); 16819 idle=lang_subst(idle,ltoa((long)hrs,tmp,10)); 16820 idle=lang_subst(idle,ltoa((long)mins,tmp,10)); 16821 idle=lang_subst(idle,ltoa((long)secs,tmp,10)); 16822 16823 disp+=" "; 16824 disp+=idle; 16825 disp+=eol; 16826 16827 { 16828 time_t now=time(NULL); 16829 char* t1=ctime(&now); 16830 char t2[128]; 16831 strcpy(t2,t1); 16832 t2[strlen(t2)-1]=0; // get rid of \n 16833 string ts="["; 16834 ts+=t2; 16835 ts+="] "; 16836 disp=ts+disp; 16837 } 16838 16839 int ec=0; 16840 dcc_send_msg((*i).socket,disp,ec); 16841 } 16842 } 16843 16844 if((*i).last_filesys_lookup==0 || (*i).last_filesys_lookup+30<time(NULL)) { 16845 time(&(*i).last_filesys_lookup); 16846 vector<s_dcc_notify> notify; 16847 filesys_dcc_check_for_notifies((*i).as_in_logic,(*i).u,(*i).chs,"",notify,true,(*i).lang,eol); 16848 if(!notify.empty()) { 16849 filesys_dcc_drop_notifies((*i).as_in_logic,false); 16850 16851 string files; 16852 string msgs; 16853 string incomplete_files; 16854 16855 vector<s_dcc_notify>::iterator i1; 16856 for(i1=notify.begin(); i1!=notify.end(); i1++) { 16857 if((*i1).unpublished) { 16858 if(!files.empty()) 16859 files+=", "; 16860 files+="\""; 16861 files+=(*i1).name; 16862 files+="\""; 16863 } 16864 if((*i1).incomplete) { 16865 if(!incomplete_files.empty()) 16866 incomplete_files+=", "; 16867 incomplete_files+="\""; 16868 incomplete_files+=(*i1).name; 16869 incomplete_files+="\""; 16870 } 16871 if((*i1).notify_owner || (*i1).notify_user || (*i1).secure_notify_owner || (*i1).secure_notify_user) 16872 msgs+=(*i1).message; 16873 } 16874 // do not abuse user every time about incomplete files 16875 /*string disp=lang_get_string(1,(*i).lang,279)+eol; 16876 disp+=files; 16877 disp+=eol; 16878 disp+=lang_get_string(1,(*i).lang,401)+eol; 16879 disp+=incomplete_files; 16880 disp+=eol; 16881 disp+=lang_get_string(1,(*i).lang,324)+eol; 16882 disp+=lang_get_string(1,(*i).lang,280)+eol; 16883 disp+=lang_get_string(1,(*i).lang,281)+eol; 16884 disp+=msgs; 16885 disp+=lang_get_string(1,(*i).lang,469)+eol;*/ 16886 if(!msgs.empty()) { 16887 string disp=msgs+eol; 16888 int ec=0; 16889 dcc_send_msg((*i).socket,disp,ec); 16890 } 16891 } 16892 } 16893 16894 if((*i).new_user || 16895 (*i).edit_user || 16896 (*i).edit_proc || 16897 (*i).edit_chan || 16898 (*i).filesystem || 16899 (*i).msg || 16900 (*i).private_edit || 16901 (*i).replication || 16902 (*i).terminator || 16903 (*i).language) 16904 continue; 16905 16906 string c=dcc_get_line((*i).in_buff); 16907 string cmd, param1, param2; 16908 int pos=0; 16909 for(unsigned int i1=0; i1<c.length(); i1++) { 16910 if((pos==0 || pos==1 || pos==2) && c[i1]==0x20) { 16911 pos++; 16912 continue; 16913 } 16914 if(pos==0) 16915 cmd+=c[i1]; 16916 if(pos==1) 16917 param1+=c[i1]; 16918 if(pos==2) 16919 param2+=c[i1]; 16920 } 16921 16922 bool got_cmd=false; 16923 16924 if(!cmd.compare(".whois")) { 16925 got_cmd=true; 16926 if(!param1.compare("") || param2.compare("")) { 16927 string disp=lang_get_string(1,(*i).lang,8)+eol; 16928 int ec=0; 16929 dcc_send_msg((*i).socket,disp,ec); 16930 } else { 16931 string disp=lang_subst(lang_get_string(1,(*i).lang,6),param1)+eol; 16932 int ec=0; 16933 dcc_send_msg((*i).socket,disp,ec); 16934 16935 list<string> lines; 16936 int num=logic_partyline_whois((*i).lang,param1,lines); 16937 list<string>::iterator i1; 16938 for(i1=lines.begin(); i1!=lines.end(); i1++) { 16939 dcc_send_msg((*i).socket,*i1,ec); 16940 dcc_send_msg((*i).socket,eol,ec); 16941 } 16942 16943 char tmp[64]; 16944 ltoa(num,tmp,10); 16945 disp=lang_subst(lang_get_string(1,(*i).lang,7),tmp)+eol; 16946 disp=lang_subst(disp,param1); 16947 dcc_send_msg((*i).socket,disp,ec); 16948 } 16949 } 16950 if(!cmd.compare(".+user")) { 16951 got_cmd=true; 16952 if((*i).access_to_plususer) { 16953 if(param1.compare("") || param2.compare("")) { 16954 string disp=lang_get_string(1,(*i).lang,29)+eol; 16955 int ec=0; 16956 dcc_send_msg((*i).socket,disp,ec); 16957 } else { 16958 string disp=lang_get_string(1,(*i).lang,32)+eol; 16959 int ec=0; 16960 dcc_send_msg((*i).socket,disp,ec); 16961 (*i).new_user=1; 16962 } 16963 } else { 16964 string disp=lang_get_string(1,(*i).lang,183)+eol; 16965 int ec=0; 16966 dcc_send_msg((*i).socket,disp,ec); 16967 } 16968 } 16969 if(!cmd.compare(".edituser")) { 16970 got_cmd=true; 16971 if(param1.compare("") || param2.compare("")) { 16972 string disp=lang_get_string(1,(*i).lang,87)+eol; 16973 int ec=0; 16974 dcc_send_msg((*i).socket,disp,ec); 16975 } else { 16976 string disp=lang_get_string(1,(*i).lang,88)+eol; 16977 int ec=0; 16978 dcc_send_msg((*i).socket,disp,ec); 16979 16980 vector<string>::iterator i1; 16981 for(i1=(*i).access_to_users.begin(); i1!=(*i).access_to_users.end(); i1++) { 16982 if(!(*i1).compare("*")) 16983 continue; 16984 disp=*i1+eol; 16985 dcc_send_msg((*i).socket,disp,ec); 16986 } 16987 16988 disp=lang_get_string(1,(*i).lang,89)+eol; 16989 dcc_send_msg((*i).socket,disp,ec); 16990 16991 (*i).edit_user=1; 16992 } 16993 } 16994 if(!cmd.compare(".+proc")) { 16995 got_cmd=true; 16996 if((*i).access_to_plusproc) { 16997 if(param1.compare("") || param2.compare("")) { 16998 string disp=lang_get_string(1,(*i).lang,377)+eol; 16999 int ec=0; 17000 dcc_send_msg((*i).socket,disp,ec); 17001 } else { 17002 (*i).edit_proc=1000; 17003 } 17004 } else { 17005 string disp=lang_get_string(1,(*i).lang,192)+eol; 17006 int ec=0; 17007 dcc_send_msg((*i).socket,disp,ec); 17008 } 17009 } 17010 if(!cmd.compare(".editproc")) { 17011 got_cmd=true; 17012 if(param1.compare("") || param2.compare("")) { 17013 string disp=lang_get_string(1,(*i).lang,134)+eol; 17014 int ec=0; 17015 dcc_send_msg((*i).socket,disp,ec); 17016 } else { 17017 string disp=lang_get_string(1,(*i).lang,135)+eol; 17018 int ec=0; 17019 dcc_send_msg((*i).socket,disp,ec); 17020 17021 vector<string>::iterator i1; 17022 for(i1=(*i).access_to_procs.begin(); i1!=(*i).access_to_procs.end(); i1++) { 17023 if(!(*i1).compare("*")) 17024 continue; 17025 disp=*i1+eol; 17026 dcc_send_msg((*i).socket,disp,ec); 17027 } 17028 17029 disp=lang_get_string(1,(*i).lang,136)+eol; 17030 dcc_send_msg((*i).socket,disp,ec); 17031 17032 (*i).edit_proc=1; 17033 } 17034 } 17035 if(!cmd.compare(".editchan")) { 17036 got_cmd=true; 17037 if(param1.compare("") || param2.compare("")) { 17038 string disp=lang_get_string(1,(*i).lang,220)+eol; 17039 int ec=0; 17040 dcc_send_msg((*i).socket,disp,ec); 17041 } else { 17042 (*i).edit_chan=1; 17043 } 17044 } 17045 if(!cmd.compare(".+chan")) { 17046 got_cmd=true; 17047 if(param1.compare("") || param2.compare("")) { 17048 string disp=lang_get_string(1,(*i).lang,235)+eol; 17049 int ec=0; 17050 dcc_send_msg((*i).socket,disp,ec); 17051 } else { 17052 (*i).edit_chan=100; 17053 } 17054 } 17055 if(!cmd.compare(".quit")) { 17056 got_cmd=true; 17057 if((*i).partyline_channel.compare("")) 17058 botnet_partyline_leave_channel((*i).as_in_logic,(*i).partyline_channel); 17059 (*i).partyline_channel=""; 17060 string disp=lang_get_string(1,(*i).lang,71)+eol; 17061 int ec=0; 17062 dcc_send_msg((*i).socket,disp,ec); 17063 if(dcc_killing_user_socket && (*i).socket.handle==dcc_killing_user_socket->handle) 17064 dcc_killing_user_socket=NULL; 17065 sock_close((*i).socket); 17066 dcc_clients.erase(i); 17067 goto again; 17068 } 17069 if(!cmd.compare(".backup")) { 17070 got_cmd=true; 17071 if((*i).access_to_backup) { 17072 logic_partyline_backup((*i).as_in_logic); 17073 if(dcc_want_to_upgrade) { 17074 string disp=lang_get_string(1,(*i).lang,641)+eol; 17075 int ec=0; 17076 dcc_send_msg((*i).socket,disp,ec); 17077 } else { 17078 string disp=lang_get_string(1,(*i).lang,74)+eol; 17079 int ec=0; 17080 dcc_send_msg((*i).socket,disp,ec); 17081 } 17082 } else { 17083 string disp=lang_get_string(1,(*i).lang,188)+eol; 17084 int ec=0; 17085 dcc_send_msg((*i).socket,disp,ec); 17086 } 17087 } 17088 if(!cmd.compare(".rehash")) { 17089 got_cmd=true; 17090 if((*i).access_to_rehash) { 17091 string disp=lang_get_string(1,(*i).lang,348)+eol; 17092 int ec=0; 17093 dcc_send_msg((*i).socket,disp,ec); 17094 sock_flush_later((*i).socket); 17095 lang_rehash(); 17096 conf_rehash(); 17097 disp=logic_partyline_rehash((*i).lang,eol,(*i).as_in_logic); 17098 ec=0; 17099 dcc_send_msg((*i).socket,disp,ec); 17100 } else { 17101 string disp=lang_get_string(1,(*i).lang,347)+eol; 17102 int ec=0; 17103 dcc_send_msg((*i).socket,disp,ec); 17104 } 17105 } 17106 if(!cmd.compare(".apply")) { 17107 got_cmd=true; 17108 if((*i).access_to_apply) { 17109 irc_rehashed(); 17110 dcc_apply((*i).as_in_logic); 17111 17112 logic_on_internal_event("@apply@",(*i).as_in_logic,"","","",PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL,"",""); 17113 } else { 17114 string disp=lang_get_string(1,(*i).lang,682)+eol; 17115 int ec=0; 17116 dcc_send_msg((*i).socket,disp,ec); 17117 } 17118 } 17119 if(!cmd.compare(".filesystem")) { 17120 got_cmd=true; 17121 if(param1.compare("") || param2.compare("")) { 17122 string disp=lang_get_string(1,(*i).lang,628)+eol; 17123 int ec=0; 17124 dcc_send_msg((*i).socket,disp,ec); 17125 } else { 17126 if((*i).access_to_filesystem) { 17127 (*i).filesystem=1; 17128 } else { 17129 string disp=lang_get_string(1,(*i).lang,275)+eol; 17130 int ec=0; 17131 dcc_send_msg((*i).socket,disp,ec); 17132 } 17133 } 17134 } 17135 if(!cmd.compare(".upgrade")) { 17136 got_cmd=true; 17137 if(!param1.compare("") || param2.compare("")) { 17138 string disp=lang_get_string(1,(*i).lang,629)+eol; 17139 int ec=0; 17140 dcc_send_msg((*i).socket,disp,ec); 17141 } else { 17142 if((*i).access_to_upgrade) { 17143 bool ok=true; 17144 for(unsigned int i1=0; i1<param1.length(); i1++) { 17145 bool ok2=false; 17146 if(param1[i1]>='a' && param1[i1]<='z') 17147 ok2=true; 17148 if(param1[i1]>='A' && param1[i1]<='Z') 17149 ok2=true; 17150 if(param1[i1]>='0' && param1[i1]<='9') 17151 ok2=true; 17152 if(param1[i1]=='.' || param1[i1]=='_' || param1[i1]=='-') 17153 ok2=true; 17154 if(!ok2) { 17155 ok=false; 17156 break; 17157 } 17158 } 17159 if(ok) 17160 dcc_upgrade(i,eol,param1); 17161 else { 17162 string disp=lang_get_string(1,(*i).lang,665)+eol; 17163 int ec=0; 17164 dcc_send_msg((*i).socket,disp,ec); 17165 } 17166 } else { 17167 string disp=lang_get_string(1,(*i).lang,627)+eol; 17168 int ec=0; 17169 dcc_send_msg((*i).socket,disp,ec); 17170 } 17171 } 17172 } 17173 if(!cmd.compare(".msg")) { 17174 got_cmd=true; 17175 (*i).msg=1; 17176 } 17177 if(!cmd.compare(".rproc")) { 17178 got_cmd=true; 17179 if(param1.compare("") || param2.compare("")) { 17180 string disp=lang_get_string(1,(*i).lang,614)+eol; 17181 int ec=0; 17182 dcc_send_msg((*i).socket,disp,ec); 17183 } else { 17184 string disp=lang_get_string(1,(*i).lang,135)+eol; 17185 int ec=0; 17186 dcc_send_msg((*i).socket,disp,ec); 17187 17188 vector<string>::iterator i1; 17189 for(i1=(*i).access_to_procs.begin(); i1!=(*i).access_to_procs.end(); i1++) { 17190 if(!(*i1).compare("*")) 17191 continue; 17192 disp=*i1+eol; 17193 dcc_send_msg((*i).socket,disp,ec); 17194 } 17195 17196 disp=lang_get_string(1,(*i).lang,616)+eol; 17197 dcc_send_msg((*i).socket,disp,ec); 17198 17199 (*i).edit_rproc=1; 17200 } 17201 } 17202 if(!cmd.compare(".getfile")) { 17203 got_cmd=true; 17204 if((*i).access_to_filesystem) { 17205 int dcc_group=atol(param2.c_str()); 17206 int res=dcc_send_file(true,param1,irc_get_nick((*i).as_in_logic),dcc_group); 17207 string disp; 17208 switch(res) { 17209 case DCC_NO_SUCH_FILE: 17210 disp=lang_get_string(1,"en",334); 17211 break; 17212 case DCC_ACCESS_DENIED: 17213 disp=lang_get_string(1,"en",335); 17214 break; 17215 case DCC_IO_ERROR: 17216 disp=lang_get_string(1,"en",336); 17217 break; 17218 } 17219 if(!disp.empty()) { 17220 disp+=eol; 17221 int ec=0; 17222 dcc_send_msg((*i).socket,disp,ec); 17223 } 17224 } else { 17225 string disp=lang_get_string(1,(*i).lang,275)+eol; 17226 int ec=0; 17227 dcc_send_msg((*i).socket,disp,ec); 17228 } 17229 } 17230 if(!cmd.compare(".partyline")) { 17231 got_cmd=true; 17232 if(param2.compare("")) { 17233 string disp=lang_get_string(1,(*i).lang,203)+eol; 17234 int ec=0; 17235 dcc_send_msg((*i).socket,disp,ec); 17236 } else { 17237 string chan=param1; 17238 if(!chan.compare("")) 17239 chan="partyline"; 17240 if(chan.compare((*i).partyline_channel)) { 17241 if((*i).partyline_channel.compare("")) 17242 botnet_partyline_leave_channel((*i).as_in_logic,(*i).partyline_channel); 17243 (*i).partyline_channel=chan; 17244 string users=botnet_partyline_join_channel((*i).as_in_logic,(*i).partyline_channel); 17245 users=lang_get_string(1,(*i).lang,206)+" "+users+eol; 17246 int ec=0; 17247 dcc_send_msg((*i).socket,users,ec); 17248 } 17249 } 17250 } 17251 if(!cmd.compare(".leave")) { 17252 got_cmd=true; 17253 if(param1.compare("") || param2.compare("")) { 17254 string disp=lang_get_string(1,(*i).lang,204)+eol; 17255 int ec=0; 17256 dcc_send_msg((*i).socket,disp,ec); 17257 } else { 17258 if((*i).partyline_channel.compare("")) { 17259 botnet_partyline_leave_channel((*i).as_in_logic,(*i).partyline_channel); 17260 (*i).partyline_channel=""; 17261 } else { 17262 string disp=lang_get_string(1,(*i).lang,205)+eol; 17263 int ec=0; 17264 dcc_send_msg((*i).socket,disp,ec); 17265 } 17266 } 17267 } 17268 if(!cmd.compare(".restart")) { 17269 got_cmd=true; 17270 if(param1.compare("") || param2.compare("")) { 17271 string disp=lang_get_string(1,(*i).lang,270)+eol; 17272 int ec=0; 17273 dcc_send_msg((*i).socket,disp,ec); 17274 } else { 17275 if((*i).access_to_restart) { 17276 dcc_killing_user_eol=eol; 17277 dcc_killing_user_socket=&((*i).socket); 17278 17279 char* tmp=new char[(*i).as_in_logic.length()+128]; 17280 sprintf(tmp,"%s%s","RESTART by ",(*i).as_in_logic.c_str()); 17281 log_bot(tmp); 17282 17283 logic_on_internal_event("@restart@",(*i).as_in_logic,"","","",PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL,"",""); 17284 17285 string disp=(string)tmp; 17286 disp+=eol; 17287 int ec=0; 17288 dcc_send_msg((*i).socket,disp,ec); 17289 delete[] tmp; 17290 tmp=NULL; 17291 17292 dcc_who_is_killing=(*i).as_in_logic; 17293 dcc_killing_user_lang=(*i).lang; 17294 dcc_want_to_restart=true; 17295 17296 log_free_locks(); 17297 17298 logic_partyline_backup((*i).as_in_logic); 17299 } else { 17300 string disp=lang_get_string(1,(*i).lang,272)+eol; 17301 int ec=0; 17302 dcc_send_msg((*i).socket,disp,ec); 17303 } 17304 } 17305 } 17306 if(!cmd.compare(".die")) { 17307 got_cmd=true; 17308 if(param1.compare("") || param2.compare("")) { 17309 string disp=lang_get_string(1,(*i).lang,271)+eol; 17310 int ec=0; 17311 dcc_send_msg((*i).socket,disp,ec); 17312 } else { 17313 if((*i).access_to_die) { 17314 dcc_killing_user_eol=eol; 17315 dcc_killing_user_socket=&((*i).socket); 17316 17317 char* tmp=new char[(*i).as_in_logic.length()+128]; 17318 sprintf(tmp,"%s%s","DIE by ",(*i).as_in_logic.c_str()); 17319 log_bot(tmp); 17320 17321 logic_on_internal_event("@die@",(*i).as_in_logic,"","","",PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL,"",""); 17322 17323 string disp=(string)tmp; 17324 disp+=eol; 17325 int ec=0; 17326 dcc_send_msg((*i).socket,disp,ec); 17327 delete[] tmp; 17328 tmp=NULL; 17329 17330 dcc_who_is_killing=(*i).as_in_logic; 17331 dcc_killing_user_lang=(*i).lang; 17332 dcc_want_to_die=true; 17333 17334 logic_partyline_backup((*i).as_in_logic); 17335 } else { 17336 string disp=lang_get_string(1,(*i).lang,273)+eol; 17337 int ec=0; 17338 dcc_send_msg((*i).socket,disp,ec); 17339 } 17340 } 17341 } 17342 if(!cmd.compare(".help")) { 17343 got_cmd=true; 17344 if(param1.compare("") || param2.compare("")) { 17345 string disp=lang_get_string(1,(*i).lang,372)+eol; 17346 int ec=0; 17347 dcc_send_msg((*i).socket,disp,ec); 17348 } else { 17349 string disp; 17350 for(int ii=354; ii<=371; ii++) // !!! 17351 disp+=lang_get_string(1,(*i).lang,ii)+eol; 17352 disp+=lang_get_string(1,(*i).lang,396)+eol; 17353 disp+=lang_get_string(1,(*i).lang,410)+eol; 17354 disp+=lang_get_string(1,(*i).lang,418)+eol; 17355 disp+=lang_get_string(1,(*i).lang,454)+eol; 17356 disp+=lang_get_string(1,(*i).lang,453)+eol; 17357 disp+=lang_get_string(1,(*i).lang,535)+eol; 17358 disp+=lang_get_string(1,(*i).lang,566)+eol; 17359 disp+=lang_get_string(1,(*i).lang,571)+eol; 17360 disp+=lang_get_string(1,(*i).lang,579)+eol; 17361 disp+=lang_get_string(1,(*i).lang,615)+eol; 17362 disp+=lang_get_string(1,(*i).lang,636)+eol; 17363 disp+=lang_get_string(1,(*i).lang,643)+eol; 17364 disp+=lang_get_string(1,(*i).lang,645)+eol; 17365 disp+=lang_get_string(1,(*i).lang,679)+eol; 17366 int ec=0; 17367 dcc_send_msg((*i).socket,disp,ec); 17368 } 17369 } 17370 if(!cmd.compare(".showbots")) { 17371 got_cmd=true; 17372 if(param1.compare("") || param2.compare("")) { 17373 string disp=lang_get_string(1,(*i).lang,644)+eol; 17374 int ec=0; 17375 dcc_send_msg((*i).socket,disp,ec); 17376 } else { 17377 string disp=botnet_showbots((*i).lang,eol); 17378 int ec=0; 17379 dcc_send_msg((*i).socket,disp,ec); 17380 } 17381 } 17382 if(!cmd.compare(".broadcastping")) { 17383 got_cmd=true; 17384 if(param1.compare("") || param2.compare("")) { 17385 string disp=lang_get_string(1,(*i).lang,646)+eol; 17386 int ec=0; 17387 dcc_send_msg((*i).socket,disp,ec); 17388 } else { 17389 time_t now; 17390 time(&now); 17391 17392 string c="\x01" "BROADCAST_PING\x01 "; 17393 char tmp[128]; 17394 c+=ltoa((long)now,tmp,10); 17395 c+=" "; 17396 c+=(*i).as_in_logic; 17397 17398 // clean up flood buffers 17399 vector<s_flood_history>::iterator i4; 17400 l_flood: 17401 for(i4=(*i).msg_flood_hist.begin(); i4!=(*i).msg_flood_hist.end(); i4++) 17402 if(now-(*i4).time>(*i).partyline_msg_flood.seconds) { 17403 (*i).msg_flood_hist.erase(i4); 17404 goto l_flood; 17405 } 17406 17407 s_flood_history entry; 17408 entry.time=now; 17409 entry.bytes=c.length(); 17410 entry.msg=c; 17411 17412 (*i).msg_flood_hist.push_back(entry); 17413 unsigned int entries=0; 17414 for(i4=(*i).msg_flood_hist.begin(); i4!=(*i).msg_flood_hist.end(); i4++) 17415 entries++; 17416 if((*i).partyline_msg_flood.lines!=0 && entries>=(*i).partyline_msg_flood.lines) { 17417 char tmp[64]; 17418 ltoa((long)(*i).partyline_msg_flood.seconds,tmp,10); 17419 string disp=lang_subst(lang_get_string(1,(*i).lang,207),tmp)+eol; 17420 int ec=0; 17421 dcc_send_msg((*i).socket,disp,ec); 17422 } else { 17423 string disp=lang_get_string(1,(*i).lang,647); 17424 disp+=" "; 17425 disp+=ctime(&now); 17426 if(disp.length() && disp[disp.length()-1]=='\n') 17427 disp.erase(disp.length()-1,1); 17428 if(disp.length() && disp[disp.length()-1]=='\r') 17429 disp.erase(disp.length()-1,1); 17430 if(disp.length() && disp[disp.length()-1]=='\n') 17431 disp.erase(disp.length()-1,1); 17432 if(disp.length() && disp[disp.length()-1]=='\r') 17433 disp.erase(disp.length()-1,1); 17434 disp+=eol; 17435 int ec=0; 17436 dcc_send_msg((*i).socket,disp,ec); 17437 botnet_partyline_message((*i).as_in_logic,"",c); 17438 } 17439 } 17440 } 17441 if(!cmd.compare(".execute")) { 17442 got_cmd=true; 17443 if(param1.empty() || c.find(" ",0)==string::npos) { 17444 string disp=lang_get_string(1,(*i).lang,653)+eol; 17445 int ec=0; 17446 dcc_send_msg((*i).socket,disp,ec); 17447 } else { 17448 string proc=c; 17449 proc.erase(0,proc.find(" ",0)+1); 17450 if(dcc_can_unassign(i,eol,proc)) { 17451 map<string,string> vars; 17452 logic_execute(proc,vars); 17453 } else { 17454 string disp=lang_get_string(1,(*i).lang,654)+eol; 17455 int ec=0; 17456 dcc_send_msg((*i).socket,disp,ec); 17457 } 17458 } 17459 } 17460 if(!cmd.compare(".replication")) { 17461 got_cmd=true; 17462 if(param1.compare("") || param2.compare("")) { 17463 string disp=lang_get_string(1,(*i).lang,419)+eol; 17464 int ec=0; 17465 dcc_send_msg((*i).socket,disp,ec); 17466 } else { 17467 if((*i).access_to_replication) { 17468 (*i).replication=1; 17469 } else { 17470 string disp=lang_get_string(1,(*i).lang,420)+eol; 17471 int ec=0; 17472 dcc_send_msg((*i).socket,disp,ec); 17473 } 17474 } 17475 } 17476 if(!cmd.compare(".chpass")) { 17477 got_cmd=true; 17478 if(!param1.compare("") || !param2.compare("")) { 17479 string disp=lang_get_string(1,(*i).lang,637)+eol; 17480 int ec=0; 17481 dcc_send_msg((*i).socket,disp,ec); 17482 } else { 17483 unsigned char signature[16]; 17484 17485 MD5Context md5c; 17486 MD5Init(&md5c); 17487 MD5Update(&md5c,(unsigned char *)param2.c_str(),(unsigned int)param2.length()); 17488 MD5Final(signature,&md5c); 17489 17490 char sig[128]; 17491 sig[0]=0; 17492 for(int i1=0; i1<16; i1++) { 17493 char tmp[16]; 17494 sprintf(tmp,"%02X",signature[i1]); 17495 strcat(sig,tmp); 17496 } 17497 17498 bool got=false; 17499 if((*i).as_in_logic.compare(param1)) { 17500 vector<string>::iterator i1; 17501 for(i1=(*i).access_to_users.begin(); i1!=(*i).access_to_users.end(); i1++) { 17502 if(!(*i1).compare(param1)) { 17503 got=true; 17504 if(dcc_want_to_upgrade) { 17505 string disp=lang_get_string(1,(*i).lang,642)+eol; 17506 int ec=0; 17507 dcc_send_msg((*i).socket,disp,ec); 17508 } else 17509 dcc_set_password(param1,sig); 17510 break; 17511 } 17512 } 17513 } else { 17514 got=true; 17515 if(dcc_want_to_upgrade) { 17516 string disp=lang_get_string(1,(*i).lang,642)+eol; 17517 int ec=0; 17518 dcc_send_msg((*i).socket,disp,ec); 17519 } else 17520 dcc_set_password(param1,sig); 17521 } 17522 if(!got) { 17523 string disp=lang_get_string(1,(*i).lang,638)+eol; 17524 int ec=0; 17525 dcc_send_msg((*i).socket,disp,ec); 17526 } else { 17527 string disp=lang_get_string(1,(*i).lang,639)+eol; 17528 int ec=0; 17529 dcc_send_msg((*i).socket,disp,ec); 17530 } 17531 } 17532 } 17533 if(!cmd.compare(".terminator")) { 17534 got_cmd=true; 17535 if(param1.compare("") || param2.compare("")) { 17536 string disp=lang_get_string(1,(*i).lang,455)+eol; 17537 int ec=0; 17538 dcc_send_msg((*i).socket,disp,ec); 17539 } else { 17540 (*i).terminator=1; 17541 } 17542 } 17543 if(!cmd.compare(".+group")) { 17544 got_cmd=true; 17545 if(!param1.compare("") || param2.compare("")) { 17546 string disp=lang_get_string(1,(*i).lang,397)+eol; 17547 int ec=0; 17548 dcc_send_msg((*i).socket,disp,ec); 17549 } else { 17550 vector<s_group>::iterator i1; 17551 bool got=false; 17552 map<string,string> vars; 17553 for(i1=r_all_groups.begin(); i1!=r_all_groups.end(); i1++) { 17554 if(!logic_eval((*i1).name,vars).compare(param1)) { 17555 got=true; 17556 string disp=lang_get_string(1,(*i).lang,398)+eol; 17557 int ec=0; 17558 dcc_send_msg((*i).socket,disp,ec); 17559 break; 17560 } 17561 } 17562 if(!got) { 17563 s_group g; 17564 g.name=param1; 17565 g.name="\""+g.name+"\""; 17566 r_all_groups.push_back(g); 17567 string disp=lang_get_string(1,(*i).lang,399)+eol; 17568 int ec=0; 17569 dcc_send_msg((*i).socket,disp,ec); 17570 } 17571 } 17572 } 17573 if(!cmd.compare(".private")) { 17574 got_cmd=true; 17575 if(param1.compare("") || param2.compare("")) { 17576 string disp=lang_get_string(1,(*i).lang,411)+eol; 17577 int ec=0; 17578 dcc_send_msg((*i).socket,disp,ec); 17579 } else { 17580 if(!(*i).access_to_private) { 17581 string disp=lang_get_string(1,(*i).lang,412)+eol; 17582 int ec=0; 17583 dcc_send_msg((*i).socket,disp,ec); 17584 } else { 17585 (*i).private_edit=1; 17586 } 17587 } 17588 } 17589 if(!cmd.compare(".lang")) { 17590 got_cmd=true; 17591 if(param1.compare("") || param2.compare("")) { 17592 string disp=lang_get_string(1,(*i).lang,450)+eol; 17593 int ec=0; 17594 dcc_send_msg((*i).socket,disp,ec); 17595 } else { 17596 (*i).language=1; 17597 } 17598 } 17599 if(!cmd.compare(".stat")) { 17600 got_cmd=true; 17601 if(param1.compare("") || param2.compare("")) { 17602 string disp=lang_get_string(1,(*i).lang,534)+eol; 17603 int ec=0; 17604 dcc_send_msg((*i).socket,disp,ec); 17605 } else { 17606 list<string> lines; 17607 stats_display(lines,(*i).lang); 17608 list<string>::iterator i1; 17609 string disp; 17610 for(i1=lines.begin(); i1!=lines.end(); i1++) { 17611 disp+=*i1; 17612 disp+=eol; 17613 } 17614 disp+=eol; 17615 vector<s_online_channel>::iterator i2; 17616 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 17617 disp+=lang_subst(lang_subst(lang_get_string(1,(*i).lang,539),irc_get_mode((*i2).name,irc_nick)),(*i2).name)+eol; 17618 vector<s_online_user>::iterator i3; 17619 for(i3=(*i2).users.begin(); i3!=(*i2).users.end(); i3++) { 17620 disp+=" "; 17621 disp+=lang_subst(lang_get_string(1,(*i).lang,540),(*i3).mode); 17622 disp+=(*i3).nick; 17623 disp+=" = "; 17624 if((*i3).got_whois) 17625 disp+=(*i3).in_logic_as; 17626 else 17627 disp+=lang_get_string(1,(*i).lang,557); 17628 disp+=eol; 17629 17630 // display dynamic modes 17631 s_user u; 17632 vector<s_channel> chs; 17633 logic_partyline_get_user((*i3).in_logic_as,u,chs); 17634 vector<s_channel>::iterator i4; 17635 for(i4=chs.begin(); i4!=chs.end(); i4++) 17636 if(!cmp_strings_case_insensitive((*i4).channel_name,(*i2).name)) { 17637 if(!(*i4).dynamic_plus_modes.empty()) { 17638 disp+=" "; 17639 disp+=lang_get_string(1,(*i).lang,550); 17640 disp+=(*i4).dynamic_plus_modes; 17641 disp+=eol; 17642 } 17643 if(!(*i4).dynamic_minus_modes.empty()) { 17644 disp+=" "; 17645 disp+=lang_get_string(1,(*i).lang,551); 17646 disp+=(*i4).dynamic_minus_modes; 17647 disp+=eol; 17648 } 17649 break; 17650 } 17651 } 17652 } 17653 int ec=0; 17654 dcc_send_msg((*i).socket,disp,ec); 17655 } 17656 } 17657 if(!cmd.compare(".part")) { 17658 got_cmd=true; 17659 if(!param1.compare("")) { 17660 string disp=lang_get_string(1,(*i).lang,567)+eol; 17661 int ec=0; 17662 dcc_send_msg((*i).socket,disp,ec); 17663 } else { 17664 vector<string>::iterator i1; 17665 bool got=false; 17666 for(i1=(*i).access_to_channel.begin(); i1!=(*i).access_to_channel.end(); i1++) 17667 if(!cmp_strings_case_insensitive(param1,*i1)) { 17668 got=true; 17669 break; 17670 } 17671 if(!got) { 17672 string disp=lang_get_string(1,(*i).lang,568)+eol; 17673 int ec=0; 17674 dcc_send_msg((*i).socket,disp,ec); 17675 } else { 17676 got=false; 17677 vector<s_online_channel>::iterator i1; 17678 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) 17679 if(!cmp_strings_case_insensitive(param1,(*i1).name)) { 17680 got=true; 17681 irc_channels.erase(i1); 17682 string reason=param2; 17683 if(reason.compare("")) 17684 reason+=(string)" - "; 17685 reason+=(*i).as_in_logic; 17686 irc_part(param1.c_str(),reason.c_str()); 17687 break; 17688 } 17689 string disp; 17690 if(!got) { 17691 disp=lang_get_string(1,(*i).lang,569)+eol; 17692 } else { 17693 disp=lang_get_string(1,(*i).lang,570)+eol; 17694 } 17695 int ec=0; 17696 dcc_send_msg((*i).socket,disp,ec); 17697 } 17698 } 17699 } 17700 if(!cmd.compare(".join")) { 17701 got_cmd=true; 17702 if(!param1.compare("")) { 17703 string disp=lang_get_string(1,(*i).lang,572)+eol; 17704 int ec=0; 17705 dcc_send_msg((*i).socket,disp,ec); 17706 } else { 17707 vector<string>::iterator i1; 17708 bool got=false; 17709 for(i1=(*i).access_to_channel.begin(); i1!=(*i).access_to_channel.end(); i1++) 17710 if(!cmp_strings_case_insensitive(param1,*i1)) { 17711 got=true; 17712 break; 17713 } 17714 if(!got) { 17715 string disp=lang_get_string(1,(*i).lang,568)+eol; 17716 int ec=0; 17717 dcc_send_msg((*i).socket,disp,ec); 17718 } else { 17719 got=false; 17720 vector<s_online_channel>::iterator i1; 17721 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) 17722 if(!cmp_strings_case_insensitive(param1,(*i1).name)) { 17723 got=true; 17724 break; 17725 } 17726 string disp; 17727 if(!got) { 17728 irc_join(param1.c_str(),param2.c_str()); 17729 disp=lang_get_string(1,(*i).lang,574)+eol; 17730 } else { 17731 disp=lang_get_string(1,(*i).lang,573)+eol; 17732 } 17733 int ec=0; 17734 dcc_send_msg((*i).socket,disp,ec); 17735 } 17736 } 17737 } 17738 if(!cmd.compare(".dynbans")) { 17739 got_cmd=true; 17740 if(!param1.compare("") || !param2.empty()) { 17741 string disp=lang_get_string(1,(*i).lang,580)+eol; 17742 int ec=0; 17743 dcc_send_msg((*i).socket,disp,ec); 17744 } else { 17745 (*i).dynbans_channel=param1; 17746 (*i).dynbans=1; 17747 // the privilege check will be done in loop function 17748 } 17749 } 17750 if(!got_cmd && c.length()>0 && (c[0]=='.' || !(*i).partyline_channel.compare(""))) { 17751 string disp=lang_get_string(1,(*i).lang,449)+eol; 17752 int ec=0; 17753 dcc_send_msg((*i).socket,disp,ec); 17754 } 17755 if(c.length()>0 && c[0]!='.' && (*i).partyline_channel.compare("") && (*i).new_user==0 && (*i).edit_user==0 && (*i).edit_proc==0 && ((*i).chat || (*i).telnet) && !(*i).replication_partner && (*i).got_passwd==3) { 17756 time_t now; 17757 time(&now); 17758 // clean up flood buffers 17759 vector<s_flood_history>::iterator i4; 17760 l_flood2: 17761 for(i4=(*i).msg_flood_hist.begin(); i4!=(*i).msg_flood_hist.end(); i4++) 17762 if(now-(*i4).time>(*i).partyline_msg_flood.seconds) { 17763 (*i).msg_flood_hist.erase(i4); 17764 goto l_flood2; 17765 } 17766 17767 s_flood_history entry; 17768 entry.time=now; 17769 entry.bytes=c.length(); 17770 entry.msg=c; 17771 17772 (*i).msg_flood_hist.push_back(entry); 17773 unsigned int entries=0; 17774 for(i4=(*i).msg_flood_hist.begin(); i4!=(*i).msg_flood_hist.end(); i4++) 17775 entries++; 17776 if((*i).partyline_msg_flood.lines!=0 && entries>=(*i).partyline_msg_flood.lines) { 17777 char tmp[64]; 17778 ltoa((long)(*i).partyline_msg_flood.seconds,tmp,10); 17779 string disp=lang_subst(lang_get_string(1,(*i).lang,207),tmp)+eol; 17780 int ec=0; 17781 dcc_send_msg((*i).socket,disp,ec); 17782 } else { 17783 // don't allow users to send magic control messages 17784 if(c.length() && c[0]<0x20) // if it begins with character code lower than 0x20 17785 c=(string)" "+c; // prepend it by SPACE 17786 17787 if(!c.empty()) 17788 botnet_partyline_message((*i).as_in_logic,(*i).partyline_channel,c); 17789 } 17790 } 17791 } 17792 if((*i).send) { 17793 int ec=0; 17794 char buff[1024*10]; 17795 bool closed=false; 17796 size_t len=0; 17797 if((*i).dcc_send.f || (*i).dcc_send.is_file_server_proto) { 17798 len=sock_read((*i).socket,buff,sizeof(buff),ec,closed); 17799 stats_dcc_send_bytes_received(len); 17800 } 17801 17802 bool timeout=false; 17803 if((*i).dcc_send.last_packet==0) 17804 time(&(*i).dcc_send.last_packet); 17805 if((*i).dcc_send.last_packet+atol(conf_getvar("dcc_send_timeout").c_str())<time(NULL)) 17806 timeout=true; 17807 if(closed || ec || timeout) { 17808 sock_close((*i).socket); 17809 dcc_clients.erase(i); 17810 goto again; 17811 } 17812 17813 if((*i).dcc_send.is_file_server_proto && len>0) { 17814 (*i).dcc_send.is_file_server_proto=false; 17815 // 120 clientnickname filesize filename 17816 string msg; 17817 size_t i1; 17818 for(i1=0; i1<sizeof(buff) && i1<len && buff[i1]!=0 && buff[i1]!='\n' && buff[i1]!='\r'; i1++) 17819 msg+=buff[i1]; 17820 string code, nick, size, name; 17821 int pos=0; 17822 for(i1=0; i1<msg.length(); i1++) { 17823 if(msg[i1]==0x20 && pos!=3) { 17824 pos++; 17825 continue; 17826 } 17827 if(pos==0) 17828 code+=msg[i1]; 17829 if(pos==1) 17830 nick+=msg[i1]; 17831 if(pos==2) 17832 size+=msg[i1]; 17833 if(pos==3) 17834 name+=msg[i1]; 17835 } 17836 string user_name=logic_find_user(nick,irc_get_ident(nick),irc_get_host(nick),irc_get_fullname(nick),irc_is_ircop(nick)); 17837 if(code.compare("120") || !logic_access_to_filesystem(user_name)) { 17838 sock_close((*i).socket); 17839 dcc_clients.erase(i); 17840 goto again; 17841 } 17842 (*i).dcc_send.original_name=name; 17843 (*i).dcc_send.size=atol(size.c_str()); 17844 if(filesys_check_add_file_raw(name,user_name)!=0) { 17845 sock_close((*i).socket); 17846 dcc_clients.erase(i); 17847 goto again; 17848 } 17849 string resp="121 "; 17850 resp+=irc_nick; 17851 resp+=" 0\n"; 17852 int ec=0; 17853 dcc_send_msg((*i).socket,resp,ec); 17854 continue; 17855 } 17856 if((*i).dcc_send.is_file_server_proto && len==0) 17857 continue; 17858 if(closed || ec || timeout || ((*i).dcc_send.received+(*i).resume_pos)==(*i).dcc_send.size) { 17859 sock_close((*i).socket); 17860 if(ec) 17861 log_socket(ec,sock_error(ec),"while calling sock_read in file " __FILE__ " in function " __FUNC__); 17862 17863 if((*i).dcc_send.f!=NULL) { 17864 fclose((*i).dcc_send.f); 17865 (*i).dcc_send.f=NULL; 17866 17867 if(((*i).dcc_send.received+(*i).resume_pos)!=(*i).dcc_send.size) { 17868 string fn=(*i).dcc_send.tmp_file_name; 17869 while(fn.find("/",0)!=string::npos) 17870 fn.erase(0,fn.find("/",0)+1); 17871 while(fn.find("\\",0)!=string::npos) 17872 fn.erase(0,fn.find("\\",0)+1); 17873 17874 filesys_add_file_raw(fn,(*i).dcc_send.original_name,(*i).as_in_logic,false,(*i).resume_pos!=0); 17875 logic_filesys_got_new((*i).as_in_logic,(*i).nick,(*i).ident,(*i).host,fn); 17876 } else { 17877 string fn=(*i).dcc_send.tmp_file_name; 17878 while(fn.find("/",0)!=string::npos) 17879 fn.erase(0,fn.find("/",0)+1); 17880 while(fn.find("\\",0)!=string::npos) 17881 fn.erase(0,fn.find("\\",0)+1); 17882 17883 filesys_add_file_raw(fn,(*i).dcc_send.original_name,(*i).as_in_logic,true,(*i).resume_pos!=0); 17884 logic_filesys_got_new((*i).as_in_logic,(*i).nick,(*i).ident,(*i).host,fn); 17885 } 17886 } 17887 17888 dcc_clients.erase(i); 17889 goto again; 17890 } 17891 (*i).dcc_send.received+=len; 17892 if((*i).dcc_send.f==NULL && (*i).resume_pos==0) { 17893 char fn[1024]; 17894 time_t now=time(NULL); 17895 sprintf(fn,"%s",ctime(&now)); 17896 for(unsigned int i1=0; i1<strlen(fn); i1++) { 17897 bool ok=false; 17898 if(fn[i1]>='a' && fn[i1]<='z') 17899 ok=true; 17900 if(fn[i1]>='A' && fn[i1]<='Z') 17901 ok=true; 17902 if(fn[i1]>='0' && fn[i1]<='9') 17903 ok=true; 17904 if(!ok) 17905 fn[i1]='_'; 17906 } 17907 string new_fn="." FILE_SLASH "filesystem" FILE_SLASH; 17908 new_fn+=fn; 17909 new_fn+="_"; 17910 new_fn+=(*i).as_in_logic; 17911 new_fn+=".dat"; 17912 strcpy((*i).dcc_send.tmp_file_name,new_fn.c_str()); 17913 (*i).dcc_send.f=fopen((*i).dcc_send.tmp_file_name,"wb"); 17914 if(!(*i).dcc_send.f) { 17915 sock_close((*i).socket); 17916 dcc_clients.erase(i); 17917 goto again; 17918 } 17919 } else 17920 if((*i).dcc_send.f==NULL && (*i).resume_pos!=0) { 17921 string internal; 17922 filesys_dcc_get_resume_info((*i).as_in_logic,(*i).dcc_send.original_name,internal); 17923 if(internal.empty()) { 17924 // error! 17925 string err="Internal error while trying to DCC RESUME (receive file): function filesys_dcc_get_resume_info() returned an emty string as internal name of file. Closing DCC SEND connection. in file " __FILE__ " in function " __FUNC__; 17926 log_debug(err.c_str()); 17927 sock_close((*i).socket); 17928 dcc_clients.erase(i); 17929 goto again; 17930 } 17931 string new_fn="." FILE_SLASH "filesystem" FILE_SLASH; 17932 new_fn+=internal; 17933 strcpy((*i).dcc_send.tmp_file_name,new_fn.c_str()); 17934 (*i).dcc_send.f=fopen((*i).dcc_send.tmp_file_name,"ab"); 17935 if(!(*i).dcc_send.f) { 17936 sock_close((*i).socket); 17937 dcc_clients.erase(i); 17938 goto again; 17939 } 17940 fseek((*i).dcc_send.f,(long)(*i).resume_pos,SEEK_SET); 17941 } else { 17942 time_t now=time(NULL); 17943 if(len) 17944 (*i).dcc_send.last_packet=now; 17945 if(len) 17946 (*i).dcc_send.response_sent=false; 17947 size_t in_queue=sock_get_receive_size((*i).socket); 17948 if((in_queue==0 && len==0 && (*i).dcc_send.received%512==0 && !(*i).dcc_send.response_sent) || ((*i).dcc_send.received+(*i).resume_pos)==(*i).dcc_send.size) { 17949 (*i).dcc_send.response_sent=true; 17950 size_t s=(*i).dcc_send.received+(*i).resume_pos; 17951 17952 char tmp[4]; 17953 memcpy(tmp,&s,4); 17954 17955 #if !defined(HIGHFIRST) 17956 // switch bytes: BIG endian (network byte order) 17957 char x; 17958 17959 x=tmp[0]; 17960 tmp[0]=tmp[3]; 17961 tmp[3]=x; 17962 // 17963 x=tmp[1]; 17964 tmp[1]=tmp[2]; 17965 tmp[2]=x; 17966 #endif 17967 size_t sent=sock_send((*i).socket,tmp,4,ec); 17968 stats_dcc_send_bytes_sent(sent); 17969 } 17970 if(((*i).dcc_send.received+(*i).resume_pos)==(*i).dcc_send.size) { 17971 if(len) 17972 fwrite(buff,1,len,(*i).dcc_send.f); 17973 17974 fclose((*i).dcc_send.f); 17975 (*i).dcc_send.f=NULL; 17976 17977 string fn=(*i).dcc_send.tmp_file_name; 17978 while(fn.find("/",0)!=string::npos) 17979 fn.erase(0,fn.find("/",0)+1); 17980 while(fn.find("\\",0)!=string::npos) 17981 fn.erase(0,fn.find("\\",0)+1); 17982 17983 filesys_add_file_raw(fn,(*i).dcc_send.original_name,(*i).as_in_logic,true,(*i).resume_pos!=0); 17984 logic_filesys_got_new((*i).as_in_logic,(*i).nick,(*i).ident,(*i).host,fn); 17985 17986 sock_close((*i).socket); 17987 dcc_clients.erase(i); 17988 goto again; 17989 } 17990 } 17991 if(len) 17992 fwrite(buff,1,len,(*i).dcc_send.f); 17993 } 17994 17995 if((*i).send_from_filesystem) { 17996 if((*i).dcc_send.f==NULL) { 17997 (*i).dcc_send.f=fopen((*i).send_file.file_name.c_str(),"rb"); 17998 if((*i).dcc_send.f==NULL) { 17999 string str="in file " __FILE__ " in function " __FUNC__ " occurred error: "; 18000 str+="cannot open filesystem file to send. Filename: "; 18001 str+=(*i).send_file.file_name; 18002 log_debug(str.c_str()); 18003 18004 sock_close((*i).socket); 18005 dcc_clients.erase(i); 18006 goto again; 18007 } 18008 if((*i).resume_pos!=0) { 18009 fseek((*i).dcc_send.f,(long)(*i).resume_pos,SEEK_SET); 18010 (*i).dcc_send.response_sent=true; // there is "response_sent" used as if response were received 18011 } 18012 } 18013 // there is "response_sent" used as if response were received 18014 send_next: 18015 if((*i).dcc_send.response_sent || ftell((*i).dcc_send.f)==0) { 18016 (*i).dcc_send.response_sent=false; 18017 int ec=0; 18018 char buff[1024]; 18019 size_t len=fread(buff,1,1024,(*i).dcc_send.f); 18020 size_t sent=sock_send((*i).socket,buff,len,ec); 18021 stats_dcc_send_bytes_sent(sent); 18022 (*i).dcc_send.received+=len; 18023 if(len) 18024 time(&(*i).dcc_send.last_packet); 18025 if(ec) { 18026 sock_close((*i).socket); 18027 log_socket(ec,sock_error(ec),"while calling sock_send in file " __FILE__ " in function " __FUNC__); 18028 if((*i).dcc_send.f) 18029 fclose((*i).dcc_send.f); 18030 (*i).dcc_send.f=NULL; 18031 dcc_clients.erase(i); 18032 goto again; 18033 } 18034 } else { 18035 int ec=0; 18036 char tmp[4]; 18037 bool closed=false; 18038 size_t len=sock_read((*i).socket,tmp,sizeof(tmp),ec,closed); 18039 if(len) { 18040 time(&(*i).dcc_send.last_packet); 18041 stats_dcc_send_bytes_received(len); 18042 } 18043 if(ec || closed) { 18044 sock_close((*i).socket); 18045 log_socket(ec,sock_error(ec),"while calling sock_read in file " __FILE__ " in function " __FUNC__); 18046 if((*i).dcc_send.f) 18047 fclose((*i).dcc_send.f); 18048 (*i).dcc_send.f=NULL; 18049 dcc_clients.erase(i); 18050 goto again; 18051 } 18052 if(len==4) { 18053 #if !defined(HIGHFIRST) 18054 // switch bytes: BIG endian (network byte order) 18055 char x; 18056 18057 x=tmp[0]; 18058 tmp[0]=tmp[3]; 18059 tmp[3]=x; 18060 // 18061 x=tmp[1]; 18062 tmp[1]=tmp[2]; 18063 tmp[2]=x; 18064 #endif 18065 18066 unsigned int pos; 18067 memcpy(&pos,tmp,4); 18068 18069 if(pos!=ftell((*i).dcc_send.f)) { 18070 sock_close((*i).socket); 18071 if((*i).dcc_send.f) 18072 fclose((*i).dcc_send.f); 18073 (*i).dcc_send.f=NULL; 18074 dcc_clients.erase(i); 18075 goto again; 18076 } 18077 18078 if(pos==(*i).send_file.size) { 18079 filesys_set_file_was_read((*i).as_in_logic,(*i).send_file.public_name); 18080 sock_close((*i).socket); 18081 if((*i).dcc_send.f) 18082 fclose((*i).dcc_send.f); 18083 (*i).dcc_send.f=NULL; 18084 dcc_clients.erase(i); 18085 goto again; 18086 } 18087 18088 (*i).dcc_send.response_sent=true; 18089 goto send_next; 18090 } 18091 } 18092 if((*i).dcc_send.last_packet==0) 18093 time(&(*i).dcc_send.last_packet); 18094 if((*i).dcc_send.last_packet+atol(conf_getvar("dcc_send_timeout").c_str())<time(NULL)) { 18095 // timeout 18096 if((*i).dcc_send.f!=NULL) 18097 fclose((*i).dcc_send.f); 18098 filesys_set_file_was_read((*i).as_in_logic,(*i).send_file.public_name); 18099 sock_close((*i).socket); 18100 if((*i).dcc_send.f) 18101 fclose((*i).dcc_send.f); 18102 (*i).dcc_send.f=NULL; 18103 dcc_clients.erase(i); 18104 goto again; 18105 } 18106 } 18107 } 18108 18109 vector<s_dcc_server>::iterator i2; 18110 for(i2=dcc_servers.begin(); i2!=dcc_servers.end(); i2++) { 18111 if((*i2).socket.cmp()) { 18112 s_socket s; 18113 if(!(*i2).using_ipv6) 18114 s=sock_accept((*i2).socket); 18115 else 18116 s=sock_accept6((*i2).socket); 18117 if(s.cmp()) { 18118 if(!(*i2).server_type.compare("chat")) 18119 stats_dcc_chat_new_connection(); 18120 if(!(*i2).server_type.compare("send")) 18121 stats_dcc_send_new_connection(); 18122 if((*i2).server_type.empty()) 18123 stats_dcc_chat_new_connection(); 18124 18125 sock_async(s); 18126 18127 int ec=0; 18128 in_addr addr; 18129 #ifdef _WIN32 18130 addr.S_un.S_addr=(unsigned long)-1; 18131 #else 18132 addr.s_addr=(unsigned long)-1; 18133 #endif 18134 in_addr6_ addr6; 18135 memset(&addr6,0,sizeof(addr6)); 18136 ec=0; 18137 if(!(*i2).using_ipv6) 18138 addr=sock_get_remote_addr(s,ec); 18139 else 18140 inet_pton(AF_INET6,s.host,&addr6); 18141 if(!ec) { 18142 bool awaiting_send=false; 18143 { 18144 vector<s_dcc_send_file>::iterator i; 18145 for(i=dcc_awaiting_send.begin(); i!=dcc_awaiting_send.end(); i++) { 18146 if(!(*i).using_ipv6) { 18147 #ifdef _WIN32 18148 if(addr.S_un.S_un_b.s_b1==(*i).remote_ip.S_un.S_un_b.s_b1 && addr.S_un.S_un_b.s_b2==(*i).remote_ip.S_un.S_un_b.s_b2 && addr.S_un.S_un_b.s_b3==(*i).remote_ip.S_un.S_un_b.s_b3 && addr.S_un.S_un_b.s_b4==(*i).remote_ip.S_un.S_un_b.s_b4) { 18149 #else 18150 if(((char*)&addr.s_addr)[0]==((char*)&(*i).remote_ip.s_addr)[0] && ((char*)&addr.s_addr)[1]==((char*)&(*i).remote_ip.s_addr)[1] && ((char*)&addr.s_addr)[2]==((char*)&(*i).remote_ip.s_addr)[2] && ((char*)&addr.s_addr)[3]==((char*)&(*i).remote_ip.s_addr)[3]) { 18151 #endif 18152 awaiting_send=true; 18153 break; 18154 } 18155 } else { 18156 bool equal=true; 18157 for(unsigned i1=0; i1<sizeof((*i).remote_ip6); i1++) { 18158 if(((unsigned char*)&(*i).remote_ip6)[i1]!=((unsigned char*)&addr6)[i1]) { 18159 equal=false; 18160 break; 18161 } 18162 } 18163 if(equal) { 18164 awaiting_send=true; 18165 break; 18166 } 18167 } 18168 } 18169 } 18170 18171 bool got=false; 18172 if(!awaiting_send) { 18173 vector<s_dcc_awaiting_user>::iterator i; 18174 if(!(*i2).using_ipv6) { 18175 #ifdef _WIN32 18176 if(addr.S_un.S_un_b.s_b1==127 && addr.S_un.S_un_b.s_b2==0 && addr.S_un.S_un_b.s_b3==0 && addr.S_un.S_un_b.s_b4==1) { 18177 #else 18178 if(((char*)&addr.s_addr)[0]==127 && ((char*)&addr.s_addr)[1]==0 && ((char*)&addr.s_addr)[2]==0 && ((char*)&addr.s_addr)[3]==1) { 18179 #endif 18180 s_dcc_awaiting_user user; 18181 18182 user.nick=""; 18183 user.ident=""; 18184 user.host="127.0.0.1"; 18185 user.fullname=""; 18186 18187 user.using_ipv6=false; 18188 user.addr4=addr; 18189 time(&user.start_time); 18190 strcpy(user.user_name_as_in_logic,conf_getvar("127.0.0.1_dcc_user").c_str()); 18191 dcc_awaiting_users.push_back(user); 18192 } 18193 } else { 18194 if(addr6.bytes[0]==0 && addr6.bytes[1]==0 && addr6.bytes[2]==0 && addr6.bytes[3]==0 && 18195 addr6.bytes[4]==0 && addr6.bytes[5]==0 && addr6.bytes[6]==0 && addr6.bytes[7]==0 && 18196 addr6.bytes[8]==0 && addr6.bytes[9]==0 && addr6.bytes[10]==0 && addr6.bytes[11]==0 && 18197 addr6.bytes[12]==0 && addr6.bytes[13]==0 && addr6.bytes[14]==0 && addr6.bytes[15]==1) { 18198 s_dcc_awaiting_user user; 18199 18200 user.nick=""; 18201 user.ident=""; 18202 user.host="::1"; 18203 user.fullname=""; 18204 18205 user.using_ipv6=true; 18206 #ifdef _WIN32 18207 user.addr4.S_un.S_addr=(unsigned long)-1; 18208 #else 18209 user.addr4.s_addr=(unsigned long)-1; 18210 #endif 18211 memcpy(&user.addr6,&addr6,sizeof(user.addr6)); 18212 time(&user.start_time); 18213 strcpy(user.user_name_as_in_logic,conf_getvar("127.0.0.1_dcc_user").c_str()); 18214 dcc_awaiting_users.push_back(user); 18215 } 18216 } 18217 l1: 18218 for(i=dcc_awaiting_users.begin(); i!=dcc_awaiting_users.end(); i++) { 18219 time_t now; 18220 time(&now); 18221 if((*i).start_time+20<=now) { 18222 dcc_awaiting_users.erase(i); 18223 goto l1; 18224 } 18225 if(!(*i).using_ipv6 && !(*i2).using_ipv6) { 18226 #ifdef _WIN32 18227 if((*i).addr4.S_un.S_addr==addr.S_un.S_addr) { 18228 #else 18229 if((*i).addr4.s_addr==addr.s_addr) { 18230 #endif 18231 s_dcc_client c; 18232 c.server_socket=(*i2).socket; 18233 18234 char tmp[256]; 18235 #ifdef _WIN32 18236 inet_ntop(AF_INET,&(addr.S_un.S_addr),tmp,sizeof(tmp)-1); 18237 #else 18238 inet_ntop(AF_INET,&(addr.s_addr),tmp,sizeof(tmp)-1); 18239 #endif 18240 c.remote=tmp; 18241 18242 c.nick=(*i).nick; 18243 c.ident=irc_get_ident((*i).nick); 18244 c.host=irc_get_host((*i).nick); 18245 c.fullname=irc_get_fullname((*i).nick); 18246 18247 c.chat=true; 18248 c.send=false; 18249 c.telnet=false; 18250 c.send_from_filesystem=false; 18251 c.socket=s; 18252 c.got_passwd=0; 18253 c.new_user=0; 18254 c.edit_user=0; 18255 c.filesystem=0; 18256 c.as_in_logic=(*i).user_name_as_in_logic; 18257 c.got_user_name=(c.as_in_logic.empty()?false:true); 18258 if(!(*i2).server_type.empty()) { 18259 if(!(*i2).server_type.compare("chat")) { 18260 string gr="101 "; 18261 gr+=irc_nick; 18262 gr+="\n"; 18263 int ec=0; 18264 size_t sent=sock_send(c.socket,gr.c_str(),gr.length(),ec); 18265 stats_dcc_chat_bytes_sent(sent); 18266 } 18267 if(!(*i2).server_type.compare("send")) { 18268 c.dcc_send.is_file_server_proto=true; 18269 c.chat=false; 18270 c.send=true; 18271 } 18272 } 18273 dcc_clients.push_back(c); 18274 dcc_check_limit(); 18275 got=true; 18276 dcc_awaiting_users.erase(i); 18277 goto l1; 18278 } 18279 } else if((*i).using_ipv6 && (*i2).using_ipv6) { 18280 if((*i).addr6.bytes[0]==addr6.bytes[0] && (*i).addr6.bytes[1]==addr6.bytes[1] && 18281 (*i).addr6.bytes[2]==addr6.bytes[2] && (*i).addr6.bytes[3]==addr6.bytes[3] && 18282 (*i).addr6.bytes[4]==addr6.bytes[4] && (*i).addr6.bytes[5]==addr6.bytes[5] && 18283 (*i).addr6.bytes[6]==addr6.bytes[6] && (*i).addr6.bytes[7]==addr6.bytes[7] && 18284 (*i).addr6.bytes[8]==addr6.bytes[8] && (*i).addr6.bytes[9]==addr6.bytes[9] && 18285 (*i).addr6.bytes[10]==addr6.bytes[10] &&(*i).addr6.bytes[11]==addr6.bytes[11] && 18286 (*i).addr6.bytes[12]==addr6.bytes[12] &&(*i).addr6.bytes[13]==addr6.bytes[13] && 18287 (*i).addr6.bytes[14]==addr6.bytes[14] &&(*i).addr6.bytes[15]==addr6.bytes[15]) { 18288 s_dcc_client c; 18289 c.server_socket=(*i2).socket; 18290 18291 char tmp[256]; 18292 inet_ntop(AF_INET6,&addr6,tmp,sizeof(tmp)-1); 18293 c.remote=tmp; 18294 18295 c.chat=true; 18296 c.send=false; 18297 c.telnet=false; 18298 c.send_from_filesystem=false; 18299 c.socket=s; 18300 c.got_passwd=0; 18301 c.new_user=0; 18302 c.edit_user=0; 18303 c.filesystem=0; 18304 c.as_in_logic=(*i).user_name_as_in_logic; 18305 c.got_user_name=(c.as_in_logic.empty()?false:true); 18306 if(!(*i2).server_type.empty()) { 18307 if(!(*i2).server_type.compare("chat")) { 18308 string gr="101 "; 18309 gr+=irc_nick; 18310 gr+="\n"; 18311 int ec=0; 18312 size_t sent=sock_send(c.socket,gr.c_str(),gr.length(),ec); 18313 stats_dcc_chat_bytes_sent(sent); 18314 } 18315 if(!(*i2).server_type.compare("send")) { 18316 c.dcc_send.is_file_server_proto=true; 18317 c.chat=false; 18318 c.send=true; 18319 } 18320 } 18321 dcc_clients.push_back(c); 18322 dcc_check_limit(); 18323 got=true; 18324 dcc_awaiting_users.erase(i); 18325 goto l1; 18326 } 18327 } 18328 } 18329 } else { 18330 got=false; 18331 } 18332 if(!got) { 18333 vector<s_dcc_send_file>::iterator i; 18334 got=false; 18335 l2: 18336 for(i=dcc_awaiting_send.begin(); i!=dcc_awaiting_send.end(); i++) { 18337 time_t now; 18338 time(&now); 18339 if((*i).start_time+20<=now) { 18340 dcc_awaiting_send.erase(i); 18341 goto l2; 18342 } 18343 if(!(*i).using_ipv6 && !(*i2).using_ipv6) { 18344 #ifdef _WIN32 18345 if((*i).remote_ip.S_un.S_addr==addr.S_un.S_addr) { 18346 #else 18347 if((*i).remote_ip.s_addr==addr.s_addr) { 18348 #endif 18349 s_dcc_client c; 18350 c.server_socket=(*i2).socket; 18351 18352 char tmp[256]; 18353 #ifdef _WIN32 18354 inet_ntop(AF_INET,&(addr.S_un.S_addr),tmp,sizeof(tmp)-1); 18355 #else 18356 inet_ntop(AF_INET,&(addr.s_addr),tmp,sizeof(tmp)-1); 18357 #endif 18358 c.remote=tmp; 18359 18360 c.chat=false; 18361 c.send=false; 18362 c.telnet=false; 18363 c.send_file=*i; 18364 c.send_from_filesystem=true; 18365 c.socket=s; 18366 c.got_passwd=0; 18367 c.new_user=0; 18368 c.edit_user=0; 18369 c.filesystem=0; 18370 c.as_in_logic=(*i).user_name_as_in_logic; 18371 c.got_user_name=(c.as_in_logic.empty()?false:true); 18372 c.resume_pos=(*i).resume_pos; 18373 dcc_clients.push_back(c); 18374 dcc_check_limit(); 18375 got=true; 18376 dcc_awaiting_send.erase(i); 18377 goto l2; 18378 } 18379 } else if((*i).using_ipv6 && (*i2).using_ipv6) { 18380 if((*i).remote_ip6.bytes[0]==addr6.bytes[0] && (*i).remote_ip6.bytes[1]==addr6.bytes[1] && 18381 (*i).remote_ip6.bytes[2]==addr6.bytes[2] && (*i).remote_ip6.bytes[3]==addr6.bytes[3] && 18382 (*i).remote_ip6.bytes[4]==addr6.bytes[4] && (*i).remote_ip6.bytes[5]==addr6.bytes[5] && 18383 (*i).remote_ip6.bytes[6]==addr6.bytes[6] && (*i).remote_ip6.bytes[7]==addr6.bytes[7] && 18384 (*i).remote_ip6.bytes[8]==addr6.bytes[8] && (*i).remote_ip6.bytes[9]==addr6.bytes[9] && 18385 (*i).remote_ip6.bytes[10]==addr6.bytes[10] &&(*i).remote_ip6.bytes[11]==addr6.bytes[11] && 18386 (*i).remote_ip6.bytes[12]==addr6.bytes[12] &&(*i).remote_ip6.bytes[13]==addr6.bytes[13] && 18387 (*i).remote_ip6.bytes[14]==addr6.bytes[14] &&(*i).remote_ip6.bytes[15]==addr6.bytes[15]) { 18388 s_dcc_client c; 18389 c.server_socket=(*i2).socket; 18390 18391 char tmp[256]; 18392 inet_ntop(AF_INET6,&addr6,tmp,sizeof(tmp)-1); 18393 c.remote=tmp; 18394 18395 c.chat=false; 18396 c.send=false; 18397 c.telnet=false; 18398 c.send_file=*i; 18399 c.send_from_filesystem=true; 18400 c.socket=s; 18401 c.got_passwd=0; 18402 c.new_user=0; 18403 c.edit_user=0; 18404 c.filesystem=0; 18405 c.as_in_logic=(*i).user_name_as_in_logic; 18406 c.got_user_name=(c.as_in_logic.empty()?false:true); 18407 c.resume_pos=(*i).resume_pos; 18408 dcc_clients.push_back(c); 18409 dcc_check_limit(); 18410 got=true; 18411 dcc_awaiting_send.erase(i); 18412 goto l2; 18413 } 18414 } 18415 } 18416 } 18417 if(!got) 18418 sock_close(s); 18419 } 18420 } 18421 } 18422 } 18423 18424 vector<s_telnet_server>::iterator i3; 18425 for(i3=telnet_servers.begin(); i3!=telnet_servers.end(); i3++) { 18426 if((*i3).socket.cmp()) { 18427 s_socket s; 18428 s.clear(); 18429 if((*i3).telnet_addr!=-1) 18430 s=sock_accept((*i3).socket); 18431 else 18432 s=sock_accept6((*i3).socket); 18433 if(s.cmp()) { 18434 stats_dcc_chat_new_connection(); 18435 18436 sock_async(s); 18437 18438 int ec=0; 18439 //in_addr addr=sock_get_remote_addr(s,ec); 18440 s_dcc_client c; 18441 c.server_socket=(*i3).socket; 18442 18443 { 18444 int ec=0; 18445 in_addr addr; 18446 #ifdef _WIN32 18447 addr.S_un.S_addr=(unsigned long)-1; 18448 #else 18449 addr.s_addr=(unsigned long)-1; 18450 #endif 18451 in_addr6_ addr6; 18452 memset(&addr6,0,sizeof(addr6)); 18453 ec=0; 18454 if((*i3).telnet_addr!=-1) 18455 addr=sock_get_remote_addr(s,ec); 18456 else 18457 inet_pton(AF_INET6,s.host,&addr6); 18458 18459 char tmp[256]; 18460 #ifdef _WIN32 18461 inet_ntop(AF_INET,&(addr.S_un.S_addr),tmp,sizeof(tmp)-1); 18462 #else 18463 inet_ntop(AF_INET,&(addr.s_addr),tmp,sizeof(tmp)-1); 18464 #endif 18465 c.remote=tmp; 18466 } 18467 18468 c.chat=true; 18469 c.send=false; 18470 c.telnet=true; 18471 c.send_from_filesystem=false; 18472 c.socket=s; 18473 c.got_passwd=0; 18474 c.new_user=0; 18475 c.edit_user=0; 18476 c.filesystem=0; 18477 c.as_in_logic=""; 18478 c.got_user_name=false; 18479 c.replication_partner=false; 18480 18481 c.lang="en"; 18482 string disp=lang_get_string(1,c.lang,167)+"\r\n"; // always telnet! so \r\n 18483 size_t sent=sock_send(c.socket,disp.c_str(),disp.length(),ec); 18484 stats_dcc_chat_bytes_sent(sent); 18485 18486 dcc_clients.push_back(c); 18487 dcc_check_limit(); 18488 } 18489 } 18490 } 18491 }
Here is the call graph for this function: ![]() |
|
Finds out if user has access to partyline; adds entry to tmp_users and performs WHOIS command if user is unknown yet.
Definition at line 2011 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::dcc_msg, s_online_user::fullname, s_online_user::got_mode, s_online_user::got_whois, HIGH_PRIORITY, s_online_user::host, s_online_user::ident, s_online_user::in_logic_as, irc_channels, s_online_user::irc_op, irc_putserv(), s_online_user::just_joined, s_online_user::last_whois, logic_access_to_partyline(), s_online_user::mode, s_online_user::nick, s_online_user::old_mode, s_online_user::on_join_called, tmp_users, and s_online_user::whois_sent. Referenced by irc_loop_process_input(), and irc_RPL_ENDOFWHOIS(). 02012 { 02013 string str=hostmask; 02014 02015 string nick; 02016 unsigned int i1; 02017 for(i1=0; i1<str.length(); i1++) 02018 if(str[i1]=='!') 02019 break; 02020 else 02021 nick+=str[i1]; 02022 str.erase(0,i1+1); // erase nick name 02023 02024 string ident; 02025 for(i1=0; i1<str.length(); i1++) 02026 if(str[i1]=='@') 02027 break; 02028 else 02029 ident+=str[i1]; 02030 str.erase(0,i1+1); // erase ident 02031 02032 string host; 02033 for(i1=0; i1<str.length(); i1++) 02034 if(str[i1]==0x20) 02035 break; 02036 else 02037 host+=str[i1]; 02038 str.erase(0,i1+1); // erase host 02039 02040 vector<s_online_channel>::iterator i; 02041 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02042 vector<s_online_user>::iterator ii; 02043 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 02044 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 02045 return logic_access_to_partyline((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).irc_op,user_name_as_in_logic); 02046 } 02047 } 02048 } 02049 02050 vector<s_online_user>::iterator ii; 02051 for(ii=tmp_users.begin(); ii!=tmp_users.end(); ii++) { 02052 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 02053 return logic_access_to_partyline((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).irc_op,user_name_as_in_logic); 02054 } 02055 } 02056 02057 s_online_user u; 02058 u.nick=nick; 02059 u.got_whois=false; 02060 u.whois_sent=true; 02061 u.on_join_called=false; 02062 u.ident=ident; 02063 u.host=host; 02064 u.fullname=""; 02065 u.got_mode=false; 02066 u.mode="0"; 02067 u.irc_op=false; 02068 u.in_logic_as=""; 02069 time(&u.last_whois); 02070 u.dcc_msg=msg; 02071 u.just_joined=false; 02072 u.old_mode="INVALID"; 02073 tmp_users.push_back(u); 02074 02075 char tmp[1024]; 02076 strcpy(tmp,"WHOIS "); 02077 strcat(tmp,nick.c_str()); 02078 irc_putserv(tmp,true,HIGH_PRIORITY); 02079 02080 return false; 02081 }
Here is the call graph for this function: ![]() |
|
Called to await DCC connection from user.
Definition at line 6875 of file irc.cpp. References s_dcc_awaiting_user::addr4, s_dcc_awaiting_user::addr6, dcc_awaiting_users, s_dcc_awaiting_user::fullname, s_dcc_awaiting_user::host, s_dcc_awaiting_user::ident, inet_pton(), irc_get_fullname(), irc_get_host(), irc_get_ident(), logic_get_dcc_host(), s_dcc_awaiting_user::nick, sock_resolve(), s_dcc_awaiting_user::start_time, s_dcc_awaiting_user::user_name_as_in_logic, and s_dcc_awaiting_user::using_ipv6. Referenced by dcc_notify(). 06876 { 06877 string dcc_host=logic_get_dcc_host(dcc_group,user_name_as_in_logic); 06878 06879 s_dcc_awaiting_user user; 06880 06881 user.nick=nick; 06882 user.ident=irc_get_ident(nick); 06883 user.host=irc_get_host(nick); 06884 user.fullname=irc_get_fullname(nick); 06885 06886 size_t n=user_name_as_in_logic.length(); 06887 if(n>128-1) 06888 n=128-1; 06889 strncpy(user.user_name_as_in_logic,user_name_as_in_logic.c_str(),n); 06890 user.user_name_as_in_logic[n]=0; 06891 06892 in_addr6_ ip6; 06893 if(inet_pton(AF_INET6,dcc_host.c_str(),&ip6)!=1) { 06894 user.addr4=sock_resolve(dcc_host.c_str(),NULL); 06895 user.using_ipv6=false; 06896 } else { 06897 memcpy(&user.addr6,&ip6,sizeof(user.addr6)); 06898 #ifdef _WIN32 06899 user.addr4.S_un.S_addr=(unsigned long)-1; 06900 #else 06901 user.addr4.s_addr=(unsigned long)-1; 06902 #endif 06903 user.using_ipv6=true; 06904 } 06905 time(&user.start_time); 06906 dcc_awaiting_users.push_back(user); 06907 }
Here is the call graph for this function: ![]() |
|
Bans (MODE #channel +b mask) host mask on channel.
Definition at line 6721 of file irc.cpp. References s_005::chanmodes_a, HIGH_PRIORITY, and irc_putserv(). Referenced by logic_exec(). 06722 { 06723 if(strlen(channel)>128) 06724 return false; 06725 if(strlen(mask)>512-1) 06726 return false; 06727 06728 if(irc_isupport.chanmodes_a.find("b")==string::npos) 06729 return true; 06730 06731 char tmp[4096]; 06732 strcpy(tmp,"MODE "); 06733 strcat(tmp,channel); 06734 strcat(tmp," +b "); 06735 strcat(tmp,mask); 06736 06737 return irc_putserv(tmp,false,HIGH_PRIORITY); 06738 }
Here is the call graph for this function: ![]() |
|
This is called on bot's JOIN, if the bot finds out that some user in logic.txt is banned; it forces on_banned event procedure to be called.
Definition at line 2173 of file irc.cpp. References cmp_strings_case_insensitive(), irc_channels, and logic_on_banned(). Referenced by irc_loop_process_input(). 02174 { 02175 unsigned int i1; 02176 02177 for(i1=0; i1<str.length(); i1++) 02178 if(str[i1]==0x20) 02179 break; 02180 str.erase(0,i1+1); // erase everything before SPACE 02181 02182 for(i1=0; i1<str.length(); i1++) 02183 if(str[i1]==0x20) 02184 break; 02185 str.erase(0,i1+1); // erase numeric reply 02186 02187 for(i1=0; i1<str.length(); i1++) 02188 if(str[i1]==0x20) 02189 break; 02190 str.erase(0,i1+1); // erase my nick 02191 02192 string channel; 02193 for(i1=0; i1<str.length(); i1++) 02194 if(str[i1]==0x20) 02195 break; 02196 else 02197 channel+=str[i1]; 02198 str.erase(0,i1+1); // erase channel_name 02199 02200 string mask; 02201 for(i1=0; i1<str.length(); i1++) 02202 if(str[i1]==0x20) 02203 break; 02204 else 02205 mask+=str[i1]; 02206 str.erase(0,i1+1); // erase mask 02207 02208 vector<s_online_channel>::iterator i; 02209 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02210 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02211 (*i).bans.push_back(mask); 02212 logic_on_banned(channel, mask,(*i).excepts,(*i).invites,(*i).bans); 02213 break; 02214 } 02215 } 02216 }
Here is the call graph for this function: ![]() |
|
Sets mode of channel.
Definition at line 6839 of file irc.cpp. References irc_putserv(). Referenced by logic_exec(). 06840 { 06841 string msg="MODE "; 06842 msg+=channel; 06843 msg+=" "; 06844 msg+=mode; 06845 return !irc_putserv(msg.c_str(),false,priority); 06846 }
Here is the call graph for this function: ![]() |
|
Checks ban list on channel after bot's JOIN by sending "MODE \#channel +b" command to server.
Definition at line 2504 of file irc.cpp. References s_online_channel::b_bans_sent, s_005::chanmodes_a, cmp_strings_case_insensitive(), HIGH_PRIORITY, irc_channels, irc_get_online_channel(), and irc_putserv(). Referenced by irc_end_of_excepted(), irc_loop_process_input(), and irc_mode_change_op(). 02505 { 02506 vector<s_online_channel>::iterator i; 02507 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02508 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02509 (*i).got_excepts=true; 02510 s_online_channel* chan; 02511 if(irc_get_online_channel(channel,chan)) { 02512 if(!chan->b_bans_sent && irc_isupport.chanmodes_a.find("b")!=string::npos) { 02513 chan->b_bans_sent=true; 02514 string tmp="MODE "; 02515 tmp+=channel; 02516 tmp+=" +b"; 02517 irc_putserv(tmp.c_str(),true,HIGH_PRIORITY); 02518 } 02519 } 02520 break; 02521 } 02522 } 02523 }
Here is the call graph for this function: ![]() |
|
Checks flood limits and history for just received message.
Definition at line 3997 of file irc.cpp. References s_flood_history::bytes, cmp_strings_case_insensitive(), s_online_user::ctcp_flood_hist, gone_users, s_online_user::got_whois, s_online_user::in_logic_as, irc_channels, irc_nick, s_online_user::join_flood_hist, s_flood::lines, logic_check_mask(), logic_eval(), logic_get_flood_limits(), logic_on_flood(), match(), s_online_user::mode_flood_hist, s_log::msg, s_flood_history::msg, s_online_user::msg_flood_hist, s_online_user::nick_flood_hist, s_online_user::notice_flood_hist, s_log::num, s_online_user::quit_time, r_users, s_online_user::repeat_flood_hist, s_flood::seconds, s_log::time, s_flood_history::time, TYPE_CTCP, TYPE_JOIN, TYPE_MODE, TYPE_NICK, TYPE_NOTICE, TYPE_PRIVMSG, TYPE_QUIT_PART_KICK, and TYPE_REPEAT. Referenced by irc_loop_process_input(). 03998 { 03999 string str=full_host; 04000 04001 string nick; 04002 unsigned int i1; 04003 for(i1=0; i1<str.length(); i1++) 04004 if(str[i1]=='!') 04005 break; 04006 else 04007 nick+=str[i1]; 04008 str.erase(0,i1+1); // erase nick name 04009 04010 if(!cmp_strings_case_insensitive(nick,(string)irc_nick)) 04011 // it's me! the bot! 04012 return; 04013 04014 if(type==TYPE_NICK && !cmp_strings_case_insensitive(msg,(string)irc_nick)) 04015 // it's me while changing nick! 04016 return; 04017 04018 string ident; 04019 for(i1=0; i1<str.length(); i1++) 04020 if(str[i1]=='@') 04021 break; 04022 else 04023 ident+=str[i1]; 04024 str.erase(0,i1+1); // erase ident 04025 04026 string host; 04027 for(i1=0; i1<str.length(); i1++) 04028 if(str[i1]==0x20) 04029 break; 04030 else 04031 host+=str[i1]; 04032 str.erase(0,i1+1); // erase host 04033 04034 // check for myself 04035 { 04036 bool match=false; 04037 vector<s_user>::iterator i1; 04038 map<string,string> vars; 04039 for(i1=r_users.begin(); i1!=r_users.end(); i1++) { 04040 if(!(*i1).host_bot) 04041 continue; 04042 vector<string>::iterator i2; 04043 for(i2=(*i1).hostmask.begin(); i2!=(*i1).hostmask.end(); i2++) 04044 if(logic_check_mask(logic_eval(*i2,vars),nick+"!"+ident+"@"+host,"*","*")) { 04045 match=true; 04046 break; 04047 } 04048 break; 04049 } 04050 if(match) 04051 return; 04052 } 04053 04054 04055 s_online_user* user=NULL; 04056 04057 bool got_user=false; 04058 vector<s_online_channel>::iterator i2; 04059 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 04060 vector<s_online_user>::iterator i3; 04061 for(i3=(*i2).users.begin(); i3!=(*i2).users.end(); i3++) { 04062 if(!cmp_strings_case_insensitive((*i3).nick,nick) /*&& !(*i3).ident.compare(ident) && !(*i3).host.compare(host)*/) { 04063 user=&(*i3); 04064 got_user=true; 04065 break; 04066 } 04067 } 04068 if(got_user) 04069 break; 04070 } 04071 if(!got_user) { 04072 // type gone users (join/quit flood) 04073 vector<s_online_user>::iterator i3; 04074 for(i3=gone_users.begin(); i3!=gone_users.end(); i3++) { 04075 if(!cmp_strings_case_insensitive((*i3).nick,nick) && !cmp_strings_case_insensitive((*i3).ident,ident) && !cmp_strings_case_insensitive((*i3).host,host)) { 04076 user=&(*i3); 04077 got_user=true; 04078 break; 04079 } 04080 } 04081 } 04082 04083 time_t now; 04084 time(&now); 04085 04086 s_flood msg_flood; 04087 s_flood notice_flood; 04088 s_flood repeat_flood; 04089 s_flood nick_flood; 04090 s_flood join_flood; 04091 s_flood mode_flood; 04092 s_flood ctcp_flood; 04093 string username; 04094 if(!got_user || user==NULL || !user->got_whois) { 04095 // we don't got user (host_unknown not defined) or we don't have WHOIS yet 04096 return; 04097 } else { 04098 username=user->in_logic_as; 04099 } 04100 logic_get_flood_limits(channel,username,msg_flood,notice_flood,repeat_flood,nick_flood,join_flood,mode_flood,ctcp_flood); 04101 04102 // clean up flood buffers 04103 vector<s_flood_history>::iterator i4; 04104 l4: 04105 for(i4=user->msg_flood_hist.begin(); i4!=user->msg_flood_hist.end(); i4++) 04106 if(now-(*i4).time>(time_t)msg_flood.seconds) { 04107 user->msg_flood_hist.erase(i4); 04108 goto l4; 04109 } 04110 l5: 04111 for(i4=user->notice_flood_hist.begin(); i4!=user->notice_flood_hist.end(); i4++) 04112 if(now-(*i4).time>(time_t)notice_flood.seconds) { 04113 user->notice_flood_hist.erase(i4); 04114 goto l5; 04115 } 04116 l6: 04117 for(i4=user->repeat_flood_hist.begin(); i4!=user->repeat_flood_hist.end(); i4++) 04118 if(now-(*i4).time>(time_t)repeat_flood.seconds) { 04119 user->repeat_flood_hist.erase(i4); 04120 goto l6; 04121 } 04122 l7: 04123 for(i4=user->nick_flood_hist.begin(); i4!=user->nick_flood_hist.end(); i4++) 04124 if(now-(*i4).time>(time_t)nick_flood.seconds) { 04125 user->nick_flood_hist.erase(i4); 04126 goto l7; 04127 } 04128 l8: 04129 for(i4=user->join_flood_hist.begin(); i4!=user->join_flood_hist.end(); i4++) 04130 if(now-(*i4).time>(time_t)join_flood.seconds) { 04131 user->join_flood_hist.erase(i4); 04132 goto l8; 04133 } 04134 l9: 04135 for(i4=user->mode_flood_hist.begin(); i4!=user->mode_flood_hist.end(); i4++) 04136 if(now-(*i4).time>(time_t)mode_flood.seconds) { 04137 user->mode_flood_hist.erase(i4); 04138 goto l9; 04139 } 04140 l10: 04141 for(i4=user->ctcp_flood_hist.begin(); i4!=user->ctcp_flood_hist.end(); i4++) 04142 if(now-(*i4).time>(time_t)ctcp_flood.seconds) { 04143 user->ctcp_flood_hist.erase(i4); 04144 goto l10; 04145 } 04146 04147 s_flood_history entry; 04148 entry.time=now; 04149 entry.bytes=msg.length(); 04150 entry.msg=msg; 04151 if(type==TYPE_JOIN) 04152 entry.msg=channel; 04153 04154 bool got2=false; 04155 if(type==TYPE_PRIVMSG) { 04156 user->msg_flood_hist.push_back(entry); 04157 user->repeat_flood_hist.push_back(entry); 04158 unsigned int entries=0; 04159 time_t low_time=0; 04160 for(i4=user->msg_flood_hist.begin(); i4!=user->msg_flood_hist.end(); i4++) { 04161 entries++; 04162 if(low_time==0 || low_time>(*i4).time) 04163 low_time=(*i4).time; 04164 } 04165 time_t diff=time(NULL)-low_time; 04166 if(msg_flood.lines!=0 && entries>=msg_flood.lines) { 04167 user->msg_flood_hist.clear(); 04168 user->notice_flood_hist.clear(); 04169 user->repeat_flood_hist.clear(); 04170 user->nick_flood_hist.clear(); 04171 user->join_flood_hist.clear(); 04172 user->mode_flood_hist.clear(); 04173 user->ctcp_flood_hist.clear(); 04174 logic_on_flood(channel,username,nick,TYPE_PRIVMSG,entries,diff,msg_flood.seconds); 04175 got2=true; 04176 } 04177 } 04178 if(type==TYPE_NOTICE) { 04179 user->notice_flood_hist.push_back(entry); 04180 user->repeat_flood_hist.push_back(entry); 04181 unsigned int entries=0; 04182 time_t low_time=0; 04183 for(i4=user->notice_flood_hist.begin(); i4!=user->notice_flood_hist.end(); i4++) { 04184 entries++; 04185 if(low_time==0 || low_time>(*i4).time) 04186 low_time=(*i4).time; 04187 } 04188 time_t diff=time(NULL)-low_time; 04189 if(!got2 && notice_flood.lines!=0 && entries>=notice_flood.lines) { 04190 user->msg_flood_hist.clear(); 04191 user->notice_flood_hist.clear(); 04192 user->repeat_flood_hist.clear(); 04193 user->nick_flood_hist.clear(); 04194 user->join_flood_hist.clear(); 04195 user->mode_flood_hist.clear(); 04196 user->ctcp_flood_hist.clear(); 04197 logic_on_flood(channel,username,nick,TYPE_NOTICE,entries,diff,notice_flood.seconds); 04198 got2=true; 04199 } 04200 } 04201 if(type==TYPE_QUIT_PART_KICK) { 04202 user->join_flood_hist.push_back(entry); 04203 //user->repeat_flood_hist.push_back(entry); 04204 } 04205 if(type==TYPE_JOIN) { 04206 user->join_flood_hist.push_back(entry); 04207 unsigned int entries=0; 04208 time_t low_time=0; 04209 for(i4=user->join_flood_hist.begin(); i4!=user->join_flood_hist.end(); i4++) { 04210 if(!cmp_strings_case_insensitive((*i4).msg,channel)) { 04211 entries++; 04212 if(low_time==0 || low_time>(*i4).time) 04213 low_time=(*i4).time; 04214 } 04215 } 04216 time_t diff=time(NULL)-low_time; 04217 if(!got2 && join_flood.lines!=0 && entries>=join_flood.lines) { 04218 user->msg_flood_hist.clear(); 04219 user->notice_flood_hist.clear(); 04220 user->repeat_flood_hist.clear(); 04221 user->nick_flood_hist.clear(); 04222 user->join_flood_hist.clear(); 04223 user->mode_flood_hist.clear(); 04224 user->ctcp_flood_hist.clear(); 04225 logic_on_flood(channel,username,nick,TYPE_JOIN,entries,diff,join_flood.seconds); 04226 got2=true; 04227 } 04228 } 04229 if(type==TYPE_NICK) { 04230 user->nick_flood_hist.push_back(entry); 04231 user->repeat_flood_hist.push_back(entry); 04232 unsigned int entries=0; 04233 time_t low_time=0; 04234 for(i4=user->nick_flood_hist.begin(); i4!=user->nick_flood_hist.end(); i4++) { 04235 entries++; 04236 if(low_time==0 || low_time>(*i4).time) 04237 low_time=(*i4).time; 04238 } 04239 time_t diff=time(NULL)-low_time; 04240 if(!got2 && nick_flood.lines!=0 && entries>=nick_flood.lines) { 04241 user->msg_flood_hist.clear(); 04242 user->notice_flood_hist.clear(); 04243 user->repeat_flood_hist.clear(); 04244 user->nick_flood_hist.clear(); 04245 user->join_flood_hist.clear(); 04246 user->mode_flood_hist.clear(); 04247 user->ctcp_flood_hist.clear(); 04248 logic_on_flood(channel,username,nick,TYPE_NICK,entries,diff,nick_flood.seconds); 04249 got2=true; 04250 } 04251 } 04252 if(type==TYPE_MODE) { 04253 user->mode_flood_hist.push_back(entry); 04254 user->repeat_flood_hist.push_back(entry); 04255 unsigned int entries=0; 04256 time_t low_time=0; 04257 for(i4=user->mode_flood_hist.begin(); i4!=user->mode_flood_hist.end(); i4++) { 04258 entries++; 04259 if(low_time==0 || low_time>(*i4).time) 04260 low_time=(*i4).time; 04261 } 04262 time_t diff=time(NULL)-low_time; 04263 if(mode_flood.lines!=0 && entries>=mode_flood.lines) { 04264 user->msg_flood_hist.clear(); 04265 user->notice_flood_hist.clear(); 04266 user->repeat_flood_hist.clear(); 04267 user->nick_flood_hist.clear(); 04268 user->join_flood_hist.clear(); 04269 user->mode_flood_hist.clear(); 04270 logic_on_flood(channel,username,nick,TYPE_MODE,entries,diff,mode_flood.seconds); 04271 got2=true; 04272 } 04273 } 04274 if(type==TYPE_CTCP) { 04275 user->ctcp_flood_hist.push_back(entry); 04276 user->repeat_flood_hist.push_back(entry); 04277 unsigned int entries=0; 04278 time_t low_time=0; 04279 for(i4=user->ctcp_flood_hist.begin(); i4!=user->ctcp_flood_hist.end(); i4++) { 04280 entries++; 04281 if(low_time==0 || low_time>(*i4).time) 04282 low_time=(*i4).time; 04283 } 04284 time_t diff=time(NULL)-low_time; 04285 if(ctcp_flood.lines!=0 && entries>=ctcp_flood.lines) { 04286 user->msg_flood_hist.clear(); 04287 user->notice_flood_hist.clear(); 04288 user->repeat_flood_hist.clear(); 04289 user->nick_flood_hist.clear(); 04290 user->join_flood_hist.clear(); 04291 user->mode_flood_hist.clear(); 04292 user->ctcp_flood_hist.clear(); 04293 logic_on_flood(channel,username,nick,TYPE_CTCP,entries,diff,ctcp_flood.seconds); 04294 got2=true; 04295 } 04296 } 04297 // evaluate repeat 04298 if(type==TYPE_PRIVMSG || type==TYPE_NOTICE || /*type==TYPE_QUIT_PART_KICK ||*/ type==TYPE_NICK || type==TYPE_CTCP) { 04299 vector<s_log> repeat_log; 04300 vector<s_log>::iterator i5; 04301 time_t low_time=0; 04302 for(i4=user->repeat_flood_hist.begin(); i4!=user->repeat_flood_hist.end(); i4++) { 04303 bool got=false; 04304 for(i5=repeat_log.begin(); i5!=repeat_log.end(); i5++) 04305 if(!(*i5).msg.compare((*i4).msg)) { 04306 got=true; 04307 (*i5).num++; 04308 if(low_time==0 || low_time>(*i5).time) 04309 low_time=(*i5).time; 04310 break; 04311 } 04312 if(!got) { 04313 s_log e; 04314 e.msg=(*i4).msg; 04315 e.num=1; 04316 e.time=(*i4).time; 04317 repeat_log.push_back(e); 04318 } 04319 } 04320 time_t diff=time(NULL)-low_time; 04321 for(i5=repeat_log.begin(); i5!=repeat_log.end(); i5++) 04322 if(!got2 && repeat_flood.lines!=0 && (*i5).num>=repeat_flood.lines) { 04323 user->msg_flood_hist.clear(); 04324 user->notice_flood_hist.clear(); 04325 user->repeat_flood_hist.clear(); 04326 user->nick_flood_hist.clear(); 04327 user->join_flood_hist.clear(); 04328 user->mode_flood_hist.clear(); 04329 user->ctcp_flood_hist.clear(); 04330 logic_on_flood(channel,username,nick,TYPE_REPEAT,(*i5).num,diff,repeat_flood.seconds); 04331 got2=true; 04332 break; 04333 } 04334 } 04335 04336 // clean up gone_users 04337 vector<s_online_user>::iterator i3; 04338 l1: 04339 for(i3=gone_users.begin(); i3!=gone_users.end(); i3++) { 04340 if((*i3).quit_time+120<now) { 04341 // 120 seconds ought be enough! 04342 gone_users.erase(i3); 04343 goto l1; 04344 } 04345 } 04346 if(type==TYPE_QUIT_PART_KICK) { 04347 bool got=false; 04348 for(i3=gone_users.begin(); i3!=gone_users.end(); i3++) 04349 if(!(*i3).nick.compare(nick)) { 04350 got=true; 04351 break; 04352 } 04353 if(!got) { 04354 time(&user->quit_time); 04355 gone_users.push_back(*user); 04356 } 04357 } 04358 }
Here is the call graph for this function: ![]() |
|
Check filesystem for new objects and notifies user if needed.
Definition at line 1133 of file irc.cpp. References filesys_dcc_check_for_notifies(), filesys_dcc_drop_notifies(), irc_put_multiple_lines(), lang_get_string(), and logic_partyline_get_user(). Referenced by irc_loop_putserv(), irc_RPL_WHOISCHANNELS(), and irc_RPL_WHOISUSER(). 01134 { 01135 string lang="en"; // TODO: !!! 01136 01137 vector<s_dcc_notify> notifies; 01138 s_user u; 01139 vector<s_channel> chs; 01140 logic_partyline_get_user(user_name,u,chs); 01141 filesys_dcc_check_for_notifies(user_name,u,chs,channel,notifies,false,lang,"\n"); 01142 filesys_dcc_drop_notifies(user_name,true); 01143 vector<s_dcc_notify>::iterator i1; 01144 bool unpublished=false; 01145 bool notified=false; 01146 string incomplete_files; 01147 for(i1=notifies.begin(); i1!=notifies.end(); i1++) { 01148 if(!unpublished && (*i1).unpublished) { 01149 string msg=lang_get_string(1,lang,331); 01150 irc_put_multiple_lines("PRIVMSG",nick,msg); 01151 unpublished=true; 01152 } 01153 if((*i1).notify_owner) { 01154 string msg=(*i1).message; 01155 irc_put_multiple_lines("PRIVMSG",nick,msg); 01156 } 01157 if((*i1).notify_user) { 01158 string msg=(*i1).message; 01159 irc_put_multiple_lines("PRIVMSG",nick,msg); 01160 } 01161 if(!notified && ((*i1).secure_notify_owner || (*i1).secure_notify_user)) { 01162 string msg=lang_get_string(1,lang,332); 01163 irc_put_multiple_lines("PRIVMSG",nick,msg); 01164 notified=true; 01165 } 01166 if((*i1).incomplete) { 01167 if(!incomplete_files.empty()) 01168 incomplete_files+=", "; 01169 incomplete_files+="\""; 01170 incomplete_files+=(*i1).name; 01171 incomplete_files+="\""; 01172 } 01173 } 01174 if(!incomplete_files.empty()) { 01175 string msg=lang_get_string(1,lang,400)+"\n"; 01176 msg+=incomplete_files; 01177 irc_put_multiple_lines("PRIVMSG",nick,msg); 01178 } 01179 }
Here is the call graph for this function: ![]() |
|
This is called on bot's JOIN, checks wheter some user in logic.txt is not invited; it forces on_not_invited event procedure to be called.
Definition at line 2243 of file irc.cpp. References cmp_strings_case_insensitive(), s_user::hostmask, irc_channels, logic_botnet_get_user(), logic_eval(), logic_on_not_invited(), s_user_to_invite::mask, match(), s_user::name, r_channels, and s_user_to_invite::user_name. Referenced by irc_loop_process_input(). 02244 { 02245 vector<s_online_channel>::iterator i; 02246 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02247 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02248 vector<s_user_to_invite> invites; 02249 vector<s_channel>::iterator i1; 02250 map<string,string> vars; 02251 for(i1=r_channels.begin(); i1!=r_channels.end(); i1++) { 02252 if(!cmp_strings_case_insensitive(logic_eval((*i1).channel_name,vars),channel)) { 02253 if(!(*i1).host_unknown) { 02254 s_user user; 02255 if(logic_botnet_get_user((*i1).username,user)) { 02256 vector<string>::iterator i5; 02257 for(i5=user.hostmask.begin(); i5!=user.hostmask.end(); i5++) { 02258 s_user_to_invite u; 02259 u.mask=*i5; 02260 if(u.mask.length()>0 && u.mask[0]=='\"') 02261 u.mask.erase(0,1); 02262 if(u.mask.length()>0 && u.mask[u.mask.length()-1]=='\"') 02263 u.mask.erase(u.mask.length()-1,1); 02264 u.user_name=user.name; 02265 invites.push_back(u); 02266 } 02267 } 02268 } 02269 } 02270 } 02271 vector<s_user_to_invite>::iterator i4; 02272 for(i4=invites.begin(); i4!=invites.end(); i4++) { 02273 bool invited=false; 02274 vector<string>::iterator i3; 02275 for(i3=(*i).invites.begin(); i3!=(*i).invites.end(); i3++) { 02276 if(!match((char*)(*i3).c_str(),(char*)(*i4).mask.c_str())) { 02277 invited=true; 02278 break; 02279 } 02280 } 02281 if(!invited) { 02282 logic_on_not_invited(channel,(*i4).mask,(*i4).user_name); 02283 } 02284 } 02285 } 02286 } 02287 }
Here is the call graph for this function: ![]() |
|
This is called on bot's JOIN, checks wheter some user in logic.txt is not in +R list; it forces on_not_in_reopped procedure to be called.
Definition at line 2295 of file irc.cpp. References cmp_strings_case_insensitive(), s_user::hostmask, irc_channels, logic_botnet_get_user(), logic_eval(), logic_on_not_in_reop(), s_user_to_invite::mask, match(), s_user::name, r_channels, and s_user_to_invite::user_name. Referenced by irc_loop_process_input(). 02296 { 02297 vector<s_online_channel>::iterator i; 02298 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02299 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02300 vector<s_user_to_invite> invites; 02301 vector<s_channel>::iterator i1; 02302 map<string,string> vars; 02303 for(i1=r_channels.begin(); i1!=r_channels.end(); i1++) { 02304 if(!cmp_strings_case_insensitive(logic_eval((*i1).channel_name,vars),channel)) { 02305 if(!(*i1).host_unknown) { 02306 s_user user; 02307 if(logic_botnet_get_user((*i1).username,user)) { 02308 vector<string>::iterator i5; 02309 for(i5=user.hostmask.begin(); i5!=user.hostmask.end(); i5++) { 02310 s_user_to_invite u; 02311 u.mask=*i5; 02312 if(u.mask.length()>0 && u.mask[0]=='\"') 02313 u.mask.erase(0,1); 02314 if(u.mask.length()>0 && u.mask[u.mask.length()-1]=='\"') 02315 u.mask.erase(u.mask.length()-1,1); 02316 u.user_name=user.name; 02317 invites.push_back(u); 02318 } 02319 } 02320 } 02321 } 02322 } 02323 vector<s_user_to_invite>::iterator i4; 02324 for(i4=invites.begin(); i4!=invites.end(); i4++) { 02325 bool invited=false; 02326 vector<string>::iterator i3; 02327 for(i3=(*i).reops.begin(); i3!=(*i).reops.end(); i3++) { 02328 if(!match((char*)(*i3).c_str(),(char*)(*i4).mask.c_str())) { 02329 invited=true; 02330 break; 02331 } 02332 } 02333 if(!invited) { 02334 logic_on_not_in_reop(channel,(*i4).mask,(*i4).user_name); 02335 } 02336 } 02337 } 02338 } 02339 }
Here is the call graph for this function: ![]() |
|
Checks invites list on channel after bot's JOIN by sending "MODE \#channel +I" command to server.
Definition at line 2532 of file irc.cpp. References s_online_channel::b_invites_sent, s_005::chanmodes_a, cmp_strings_case_insensitive(), HIGH_PRIORITY, irc_channels, irc_get_online_channel(), and irc_putserv(). Referenced by irc_mode_change_op(). 02533 { 02534 vector<s_online_channel>::iterator i; 02535 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02536 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02537 (*i).got_invites=true; 02538 s_online_channel* chan; 02539 if(irc_get_online_channel(channel,chan)) { 02540 if(!chan->b_invites_sent && irc_isupport.chanmodes_a.find("I")!=string::npos) { 02541 chan->b_invites_sent=true; 02542 string tmp="MODE "; 02543 tmp+=channel; 02544 tmp+=" +I"; 02545 irc_putserv(tmp.c_str(),true,HIGH_PRIORITY); 02546 } 02547 } 02548 break; 02549 } 02550 } 02551 }
Here is the call graph for this function: ![]() |
|
Compares the beginning of message.
Definition at line 3913 of file irc.cpp. References s_msg_to_server::msg. Referenced by irc_loop_process_input(). 03914 { 03915 if(last_msg.msg==NULL) 03916 return false; 03917 if(strlen(last_msg.msg)<strlen(start)) 03918 return false; 03919 bool same=true; 03920 /*for(unsigned int i1=0; i1<strlen(start); i1++) 03921 if(last_msg.msg[i1]!=start[i1]) { 03922 same=false; 03923 break; 03924 }*/ 03925 if(strstr(last_msg.msg,start)!=last_msg.msg) 03926 same=false; 03927 return same; 03928 }
|
|
Checks wheter user is found on channel.
Definition at line 1636 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_loop_process_input(). 01637 { 01638 vector<s_online_channel>::iterator i1; 01639 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 01640 if(!cmp_strings_case_insensitive((*i1).name,channel)) { 01641 vector<s_online_user>::iterator i2; 01642 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 01643 if(!cmp_strings_case_insensitive((*i2).nick,nick)) 01644 return true; 01645 } 01646 } 01647 } 01648 return false; 01649 }
Here is the call graph for this function: ![]() |
|
Connects to server.
Definition at line 1223 of file irc.cpp. References s_socket::clear(), s_005::clear(), conf_getvar(), dcc_request_whois, filesys_last_notify, filesys_notify_interval, flood_history, flood_history_other, gone_users, irc_bot_flood_bytes, irc_bot_flood_lines, irc_bot_flood_other_seconds, irc_bot_flood_seconds, irc_cannot_join_channels, irc_channels, irc_fullname, irc_keepalive_sent, irc_key_chans, irc_last_join_try, irc_last_keepalive_detection, irc_nick, irc_nicks, irc_recommended_port, irc_recommended_server, irc_socket_error, irc_unique_id, log_irc(), log_socket(), ltoa(), mode_queue, modes_from_server, s_msg_to_server::msg, msgs_from_server, msgs_to_server, msgs_to_server2, s_msg_to_server::response, sock_connect(), sock_error(), stats_irc_new_connection(), tmp_users, unknown_users_on_channels, s_msg_to_server::wait_for_response, and waiting_for_response. Referenced by logic_exec(). 01224 { 01225 char host[1024]; 01226 if(strlen(host_)>sizeof(host)-1) 01227 return -1; 01228 strcpy(host,host_); 01229 01230 irc_socket_error=false; 01231 01232 irc_bot_flood_bytes=atol(conf_getvar("irc_bot_flood_bytes").c_str()); 01233 irc_bot_flood_seconds=atol(conf_getvar("irc_bot_flood_seconds").c_str()); 01234 irc_bot_flood_lines=atol(conf_getvar("irc_bot_flood_lines").c_str()); 01235 irc_bot_flood_other_seconds=atol(conf_getvar("irc_bot_flood_other_seconds").c_str()); 01236 01237 if(!irc_bot_flood_bytes) 01238 irc_bot_flood_bytes=64; 01239 if(!irc_bot_flood_seconds) 01240 irc_bot_flood_seconds=5; 01241 if(!irc_bot_flood_lines) 01242 irc_bot_flood_lines=2; 01243 if(!irc_bot_flood_other_seconds) 01244 irc_bot_flood_other_seconds=5; 01245 01246 // do NOT re-set this anymore! - Fixed bug in 1.0.12 01247 //irc_follow_redirs=false; 01248 01249 irc_recommended_server=""; 01250 irc_recommended_port=0; 01251 01252 irc_socket.clear(); 01253 irc_last_keepalive_detection=0; 01254 irc_keepalive_sent=false; 01255 01256 irc_nick[0]=0; 01257 irc_fullname[0]=0; 01258 irc_unique_id[0]=0; 01259 01260 irc_nicks.clear(); 01261 filesys_notify_interval=0; 01262 filesys_last_notify=0; 01263 01264 irc_key_chans.clear(); 01265 irc_channels.clear(); 01266 01267 tmp_users.clear(); 01268 01269 gone_users.clear(); 01270 01271 unknown_users_on_channels.clear(); 01272 01273 last_msg.wait_for_response=false; 01274 waiting_for_response.clear(); 01275 01276 msgs_to_server.clear(); 01277 msgs_to_server2.clear(); 01278 msgs_from_server.clear(); 01279 01280 mode_queue.clear(); 01281 01282 flood_history.clear(); 01283 flood_history_other.clear(); 01284 01285 irc_cannot_join_channels.clear(); 01286 irc_last_join_try=0; 01287 01288 last_msg.msg=NULL; 01289 last_msg.wait_for_response=false; 01290 last_msg.response[0]=0; 01291 01292 irc_channels.clear(); 01293 01294 dcc_request_whois.clear(); 01295 modes_from_server.clear(); 01296 01297 irc_isupport.clear(); 01298 01299 { 01300 string msg="Connecting to "; 01301 if(strstr(host,":")) 01302 msg+="["; 01303 msg+=host; 01304 if(strstr(host,":")) 01305 msg+="]"; 01306 msg+=":"; 01307 char tmp[64]; 01308 ltoa(port,tmp,10); 01309 msg+=tmp; 01310 msg+="..."; 01311 log_irc(false,msg.c_str()); 01312 } 01313 01314 int ec=0; 01315 /*char ip[128]; 01316 ip[0]=0; 01317 unsigned long ip_=sock_resolve(host,ip).S_un.S_addr; 01318 if(ip_!=0) {*/ 01319 irc_socket=sock_connect((char*)bind_ip,(char*)host,port,ec,true); 01320 irc_last_keepalive_detection=time(NULL); 01321 if(ec) { 01322 irc_socket.clear(); 01323 log_socket(ec,sock_error(ec),"while calling sock_connect in file " __FILE__ " in function " __FUNC__); 01324 return ec; 01325 } 01326 /*} else { 01327 irc_socket.clear(); 01328 string str="Cannot resolve host \""; 01329 str+=host; 01330 str+="\" to IP address in file " __FILE__ " in function " __FUNC__; 01331 log_socket(-1,"DNS",str.c_str()); 01332 return -1; 01333 }*/ 01334 01335 stats_irc_new_connection(host,port); 01336 01337 return 0; 01338 }
Here is the call graph for this function: ![]() |
|
Sets -o (chan op) status to nick on channel.
Definition at line 6293 of file irc.cpp. References irc_internal_set_mode(), and irc_putserv(). Referenced by logic_exec(). 06294 { 06295 if(strlen(channel)>128) 06296 return false; 06297 if(strlen(nick)>128) 06298 return false; 06299 06300 irc_internal_set_mode(channel,nick,'-','@'); 06301 06302 char msg[4096]; 06303 strcpy(msg,"MODE "); 06304 strcat(msg,channel); 06305 strcat(msg," -o "); 06306 strcat(msg,nick); 06307 06308 return irc_putserv(msg,true,priority); 06309 }
Here is the call graph for this function: ![]() |
|
Sets -v (voice) status to nick on channel.
Definition at line 6349 of file irc.cpp. References irc_internal_set_mode(), and irc_putserv(). Referenced by logic_exec(). 06350 { 06351 if(strlen(channel)>128) 06352 return false; 06353 if(strlen(nick)>128) 06354 return false; 06355 06356 irc_internal_set_mode(channel,nick,'-','+'); 06357 06358 char msg[4096]; 06359 strcpy(msg,"MODE "); 06360 strcat(msg,channel); 06361 strcat(msg," -v "); 06362 strcat(msg,nick); 06363 06364 return irc_putserv(msg,true,priority); 06365 }
Here is the call graph for this function: ![]() |
|
Disconnects from server.
Definition at line 1188 of file irc.cpp. References s_socket::clear(), irc_channels, irc_ident, irc_keepalive_sent, log_irc(), mode_queue, msgs_to_server, msgs_to_server2, sock_close(), sock_flush_later(), sock_send_cache(), s_msg_to_server::wait_for_response, and waiting_for_response. Referenced by irc_loop_process_input(), irc_loop_putserv(), logic_exec(), and main(). 01189 { 01190 { 01191 string msg="Disconnecting"; 01192 log_irc(false,msg.c_str()); 01193 } 01194 01195 while(irc_channels.begin()!=irc_channels.end()) 01196 irc_channels.erase(irc_channels.begin()); 01197 01198 irc_keepalive_sent=false; 01199 01200 sock_send_cache(); 01201 sock_flush_later(irc_socket); 01202 sock_close(irc_socket); 01203 irc_socket.clear(); 01204 msgs_to_server.clear(); 01205 msgs_to_server2.clear(); 01206 mode_queue.clear(); 01207 last_msg.wait_for_response=false; 01208 waiting_for_response.clear(); 01209 irc_ident="*"; 01210 return 0; 01211 }
Here is the call graph for this function: ![]() |
|
Called when bot after JOIN has received message indicating end of +e exceptions / or error, that irc network doesn't support +e exceptions.
Definition at line 2560 of file irc.cpp. References irc_check_bans(). Referenced by irc_loop_process_input(). 02561 { 02562 unsigned int i1; 02563 02564 for(i1=0; i1<str.length(); i1++) 02565 if(str[i1]==0x20) 02566 break; 02567 str.erase(0,i1+1); // erase everything before SPACE 02568 02569 for(i1=0; i1<str.length(); i1++) 02570 if(str[i1]==0x20) 02571 break; 02572 str.erase(0,i1+1); // erase numeric reply 02573 02574 for(i1=0; i1<str.length(); i1++) 02575 if(str[i1]==0x20) 02576 break; 02577 str.erase(0,i1+1); // erase my nick 02578 02579 string channel; 02580 for(i1=0; i1<str.length(); i1++) 02581 if(str[i1]==0x20) 02582 break; 02583 else 02584 channel+=str[i1]; 02585 str.erase(0,i1+1); // erase channel_name 02586 02587 irc_check_bans(channel); 02588 }
Here is the call graph for this function: ![]() |
|
Called as +e exception mask to ban is found out on channel after bot's JOIN.
Definition at line 2348 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_loop_process_input(). 02349 { 02350 unsigned int i1; 02351 02352 for(i1=0; i1<str.length(); i1++) 02353 if(str[i1]==0x20) 02354 break; 02355 str.erase(0,i1+1); // erase everything before SPACE 02356 02357 for(i1=0; i1<str.length(); i1++) 02358 if(str[i1]==0x20) 02359 break; 02360 str.erase(0,i1+1); // erase numeric reply 02361 02362 for(i1=0; i1<str.length(); i1++) 02363 if(str[i1]==0x20) 02364 break; 02365 str.erase(0,i1+1); // erase my nick 02366 02367 string channel; 02368 for(i1=0; i1<str.length(); i1++) 02369 if(str[i1]==0x20) 02370 break; 02371 else 02372 channel+=str[i1]; 02373 str.erase(0,i1+1); // erase channel_name 02374 02375 string mask; 02376 for(i1=0; i1<str.length(); i1++) 02377 if(str[i1]==0x20) 02378 break; 02379 else 02380 mask+=str[i1]; 02381 str.erase(0,i1+1); // erase mask 02382 02383 vector<s_online_channel>::iterator i; 02384 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02385 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02386 (*i).excepts.push_back(mask); 02387 (*i).got_excepts=false; 02388 break; 02389 } 02390 } 02391 }
Here is the call graph for this function: ![]() |
|
Finds s_online_user record in irc_channel list for user.
Definition at line 2598 of file irc.cpp. References cmp_strings_case_insensitive(), irc_channels, and s_online_user::nick. Referenced by irc_kicked(), irc_mode_change_ban(), irc_mode_change_ban_exception(), irc_mode_change_chan_key(), irc_mode_change_chan_limit(), irc_mode_change_chan_status(), irc_mode_change_creator(), irc_mode_change_invitation(), irc_mode_change_op(), irc_mode_change_other(), irc_mode_change_reop(), irc_mode_change_voice(), irc_RPL_TOPIC(), and irc_user_mode_change(). 02599 { 02600 vector<s_online_channel>::iterator i; 02601 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02602 vector<s_online_user>::iterator ii; 02603 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 02604 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 02605 return *ii; 02606 } 02607 } 02608 } 02609 s_online_user u; 02610 u.nick=""; // do panic! 02611 return u; 02612 }
Here is the call graph for this function: ![]() |
|
Gets information from parsed RPL_ISUPPORT message (005 numeric).
Definition at line 6984 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, s_005::chanmodes_d, s_005::prefix, and s_005::raw. Referenced by logic_exec_script(). 06985 { 06986 raw=irc_isupport.raw; 06987 prefix=irc_isupport.prefix; 06988 chm_a=irc_isupport.chanmodes_a; 06989 chm_b=irc_isupport.chanmodes_b; 06990 chm_c=irc_isupport.chanmodes_c; 06991 chm_d=irc_isupport.chanmodes_d; 06992 }
|
|
Returns channel mode.
Definition at line 6958 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by logic_exec(). 06959 { 06960 topic=""; 06961 vector<s_online_channel>::iterator i; 06962 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06963 if(!cmp_strings_case_insensitive((*i).name,channel)) { 06964 topic=(*i).topic; 06965 return (*i).modes; 06966 } 06967 } 06968 06969 return ""; 06970 }
Here is the call graph for this function: ![]() |
|
Looks-up user from nick name and checks its full name.
Definition at line 6657 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by dcc_file_has_been_read(), dcc_loop(), dcc_send_file(), irc_await_dcc_chat(), irc_loop_process_input(), irc_quoted_callback(), irc_RPL_ENDOFWHOIS(), irc_RPL_NAMREPLY(), irc_user_mode_change(), logic_exec(), logic_on_ircop(), logic_on_part(), and logic_validate(). 06658 { 06659 vector<s_online_channel>::iterator i; 06660 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06661 vector<s_online_user>::iterator ii; 06662 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06663 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 06664 if(!(*ii).got_whois) 06665 return ""; 06666 return (*ii).fullname; 06667 } 06668 } 06669 } 06670 06671 return ""; 06672 }
Here is the call graph for this function: ![]() |
|
Looks-up host of online user.
Definition at line 6792 of file irc.cpp. References cmp_strings_case_insensitive(), gone_users, and irc_channels. Referenced by dcc_file_has_been_read(), dcc_loop(), dcc_send_file(), irc_await_dcc_chat(), irc_loop_process_input(), irc_quoted_callback(), irc_RPL_ENDOFWHOIS(), irc_RPL_NAMREPLY(), irc_user_mode_change(), logic_exec(), logic_on_ircop(), logic_on_part(), and logic_validate(). 06793 { 06794 vector<s_online_channel>::iterator i1; 06795 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 06796 vector<s_online_user>::iterator i2; 06797 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 06798 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 06799 if(!(*i2).got_whois) 06800 break; 06801 return (*i2).host; 06802 } 06803 } 06804 } 06805 vector<s_online_user>::iterator i2; 06806 for(i2=gone_users.begin(); i2!=gone_users.end(); i2++) { 06807 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 06808 if(!(*i2).got_whois) 06809 break; 06810 return (*i2).host; 06811 } 06812 } 06813 return ""; 06814 }
Here is the call graph for this function: ![]() |
|
Looks-up ident of online user.
Definition at line 6760 of file irc.cpp. References cmp_strings_case_insensitive(), gone_users, and irc_channels. Referenced by dcc_file_has_been_read(), dcc_loop(), dcc_send_file(), irc_await_dcc_chat(), irc_loop_process_input(), irc_quoted_callback(), irc_RPL_ENDOFWHOIS(), irc_RPL_NAMREPLY(), irc_user_mode_change(), logic_exec(), logic_on_ircop(), logic_on_part(), and logic_validate(). 06761 { 06762 vector<s_online_channel>::iterator i1; 06763 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 06764 vector<s_online_user>::iterator i2; 06765 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 06766 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 06767 if(!(*i2).got_whois) 06768 break; 06769 return (*i2).ident; 06770 } 06771 } 06772 } 06773 vector<s_online_user>::iterator i2; 06774 for(i2=gone_users.begin(); i2!=gone_users.end(); i2++) { 06775 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 06776 if(!(*i2).got_whois) 06777 break; 06778 return (*i2).ident; 06779 } 06780 } 06781 return ""; 06782 }
Here is the call graph for this function: ![]() |
|
Looks-up user from nick name and checks its mode on channel.
Definition at line 6595 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by dcc_loop(), irc_got_op(), irc_loop_process_input(), logic_exec(), logic_on_nick_change(), and logic_on_nick_validate(). 06596 { 06597 vector<s_online_channel>::iterator i; 06598 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06599 if(!cmp_strings_case_insensitive((*i).name,channel)) { 06600 vector<s_online_user>::iterator ii; 06601 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06602 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 06603 if(!(*ii).got_mode) 06604 return "0"; 06605 return (*ii).mode; 06606 } 06607 } 06608 } 06609 } 06610 06611 return "0"; 06612 }
Here is the call graph for this function: ![]() |
|
Looks-up user from nick name and returns their mode(s) for logging purposes to channel log.
Definition at line 6624 of file irc.cpp. References cmp_strings_case_insensitive(), s_005::get_prefix2(), and irc_channels. Referenced by irc_loop_process_input(), and irc_RPL_WHOISOPERATOR(). 06625 { 06626 vector<s_online_channel>::iterator i; 06627 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06628 if(!cmp_strings_case_insensitive((*i).name,channel)) { 06629 vector<s_online_user>::iterator ii; 06630 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06631 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 06632 if(!(*ii).got_mode) 06633 return "?"; 06634 string res; 06635 if((*ii).irc_op) 06636 res+="!"; 06637 for(unsigned int i1=0; i1<(*ii).mode.length(); i1++) 06638 if((*ii).mode[i1]!='0') 06639 res+=(string)""+irc_isupport.get_prefix2((*ii).mode[i1]); 06640 return res; 06641 } 06642 } 06643 } 06644 } 06645 06646 return "?"; 06647 }
Here is the call graph for this function: ![]() |
|
Looks-up user from name in logic.txt to nick name (if online).
Definition at line 6521 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by dcc_loop(), dcc_loop_filesystem(), dcc_notify(), logic_exec_script(), and logic_validate_by_mask(). 06522 { 06523 vector<s_online_channel>::iterator i; 06524 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06525 vector<s_online_user>::iterator ii; 06526 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06527 if(!cmp_strings_case_insensitive((*ii).in_logic_as,user)) { 06528 return (*ii).nick; 06529 } 06530 } 06531 } 06532 06533 return user; 06534 }
Here is the call graph for this function: ![]() |
|
Returns reference to channel that we are on.
Definition at line 309 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_check_bans(), irc_check_invites(), irc_loop_process_input(), and irc_RPL_NAMREPLY(). 00310 { 00311 chan=NULL; 00312 00313 vector<s_online_channel>::iterator i1; 00314 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) 00315 if(!cmp_strings_case_insensitive((*i1).name,channel_name)) { 00316 chan=&(*i1); 00317 return true; 00318 } 00319 00320 return false; 00321 }
Here is the call graph for this function: ![]() |
|
Checks if bot has op (+o) on channel.
Definition at line 6943 of file irc.cpp. References s_005::get_prefix1(), irc_get_mode(), and irc_nick. Referenced by logic_exec(). 06944 { 06945 string m=irc_get_mode(channel,irc_nick); 06946 return m.find(irc_isupport.get_prefix1('o'),0)!=string::npos; 06947 }
Here is the call graph for this function: ![]() |
|
Called as +R reop mask is found out on channel after bot's JOIN.
Definition at line 2452 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_loop_process_input(). 02453 { 02454 unsigned int i1; 02455 02456 for(i1=0; i1<str.length(); i1++) 02457 if(str[i1]==0x20) 02458 break; 02459 str.erase(0,i1+1); // erase everything before SPACE 02460 02461 for(i1=0; i1<str.length(); i1++) 02462 if(str[i1]==0x20) 02463 break; 02464 str.erase(0,i1+1); // erase numeric reply 02465 02466 for(i1=0; i1<str.length(); i1++) 02467 if(str[i1]==0x20) 02468 break; 02469 str.erase(0,i1+1); // erase my nick 02470 02471 string channel; 02472 for(i1=0; i1<str.length(); i1++) 02473 if(str[i1]==0x20) 02474 break; 02475 else 02476 channel+=str[i1]; 02477 str.erase(0,i1+1); // erase channel_name 02478 02479 string mask; 02480 for(i1=0; i1<str.length(); i1++) 02481 if(str[i1]==0x20) 02482 break; 02483 else 02484 mask+=str[i1]; 02485 str.erase(0,i1+1); // erase mask 02486 02487 vector<s_online_channel>::iterator i; 02488 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02489 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02490 (*i).reops.push_back(mask); 02491 (*i).got_reops=false; 02492 break; 02493 } 02494 } 02495 }
Here is the call graph for this function: ![]() |
|
Resets user's old_mode atribute.
Definition at line 6233 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_deop(), irc_devoice(), irc_op(), and irc_voice(). 06234 { 06235 vector<s_online_channel>::iterator i1; 06236 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 06237 if(cmp_strings_case_insensitive((*i1).name,channel)) 06238 continue; 06239 vector<s_online_user>::iterator i2; 06240 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) 06241 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 06242 /*while((*i2).mode.find("0",0)!=string::npos) 06243 (*i2).mode.erase((*i2).mode.find("0",0),1); 06244 while((*i2).mode.find(mode,0)!=string::npos) 06245 (*i2).mode.erase((*i2).mode.find(mode,0),1); 06246 if(prefix=='+') 06247 (*i2).mode+=mode; 06248 if((*i2).mode.empty()) 06249 (*i2).mode="0";*/ 06250 (*i2).old_mode=(*i2).mode; 06251 } 06252 } 06253 }
Here is the call graph for this function: ![]() |
|
Called as +I invitation mask to +i is found out on channel after bot's JOIN.
Definition at line 2400 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by irc_loop_process_input(). 02401 { 02402 unsigned int i1; 02403 02404 for(i1=0; i1<str.length(); i1++) 02405 if(str[i1]==0x20) 02406 break; 02407 str.erase(0,i1+1); // erase everything before SPACE 02408 02409 for(i1=0; i1<str.length(); i1++) 02410 if(str[i1]==0x20) 02411 break; 02412 str.erase(0,i1+1); // erase numeric reply 02413 02414 for(i1=0; i1<str.length(); i1++) 02415 if(str[i1]==0x20) 02416 break; 02417 str.erase(0,i1+1); // erase my nick 02418 02419 string channel; 02420 for(i1=0; i1<str.length(); i1++) 02421 if(str[i1]==0x20) 02422 break; 02423 else 02424 channel+=str[i1]; 02425 str.erase(0,i1+1); // erase channel_name 02426 02427 string mask; 02428 for(i1=0; i1<str.length(); i1++) 02429 if(str[i1]==0x20) 02430 break; 02431 else 02432 mask+=str[i1]; 02433 str.erase(0,i1+1); // erase mask 02434 02435 vector<s_online_channel>::iterator i; 02436 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02437 if(!cmp_strings_case_insensitive((*i).name,channel)) { 02438 (*i).invites.push_back(mask); 02439 (*i).got_invites=false; 02440 break; 02441 } 02442 } 02443 }
Here is the call graph for this function: ![]() |
|
Looks-up user from name in logic.txt and checks if it is an irc operator (if online).
Definition at line 6567 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. Referenced by dcc_file_has_been_read(), dcc_loop(), dcc_send_file(), irc_quoted_callback(), irc_RPL_NAMREPLY(), irc_user_mode_change(), logic_exec(), logic_on_ircop(), and logic_on_part(). 06568 { 06569 vector<s_online_channel>::iterator i; 06570 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06571 vector<s_online_user>::iterator ii; 06572 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06573 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 06574 return (*ii).irc_op; 06575 } 06576 } 06577 } 06578 06579 return false; 06580 }
Here is the call graph for this function: ![]() |
|
Looks-up user from name in logic.txt to nick name (if online).
Definition at line 6544 of file irc.cpp. References cmp_strings_case_insensitive(), and irc_channels. 06545 { 06546 vector<s_online_channel>::iterator i; 06547 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06548 vector<s_online_user>::iterator ii; 06549 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 06550 if(!cmp_strings_case_insensitive((*ii).in_logic_as,user)) { 06551 return (*ii).nick; 06552 } 06553 } 06554 } 06555 06556 return ""; 06557 }
Here is the call graph for this function: ![]() |
|
JOINs channel.
Definition at line 6408 of file irc.cpp. References HIGH_PRIORITY, irc_nick, and irc_putserv(). Referenced by dcc_loop(), and logic_exec(). 06409 { 06410 if(strlen(channel)>128) 06411 return false; 06412 06413 char msg[4096]; 06414 strcpy(msg,"JOIN "); 06415 strcat(msg,channel); 06416 if(key[0]!=0) { 06417 strcat(msg," "); 06418 strcat(msg,key); 06419 } 06420 bool ok=irc_putserv(msg,false,HIGH_PRIORITY); 06421 strcpy(msg,"MODE "); 06422 strcat(msg,channel); 06423 ok&=irc_putserv(msg,true,HIGH_PRIORITY); 06424 strcpy(msg,"TOPIC "); 06425 strcat(msg,channel); 06426 ok&=irc_putserv(msg,true,HIGH_PRIORITY); 06427 strcpy(msg,"WHOIS "); 06428 strcat(msg,irc_nick); 06429 ok&=irc_putserv(msg,true,HIGH_PRIORITY); 06430 06431 return ok; 06432 }
Here is the call graph for this function: ![]() |
|
Kicks nick on channel.
Definition at line 6377 of file irc.cpp. References HIGH_PRIORITY, and irc_putserv(). Referenced by logic_exec(). 06378 { 06379 if(strlen(channel)>128) 06380 return false; 06381 if(strlen(nick)>128) 06382 return false; 06383 if(strlen(reason)>128) 06384 return false; 06385 06386 char msg[4096]; 06387 strcpy(msg,"KICK "); 06388 strcat(msg,channel); 06389 strcat(msg," "); 06390 strcat(msg,nick); 06391 if(reason!=NULL && strlen(reason)>0) { 06392 strcat(msg," :"); 06393 strcat(msg,reason); 06394 } 06395 06396 return irc_putserv(msg,false,HIGH_PRIORITY); 06397 }
Here is the call graph for this function: ![]() |
|
Called when user was KICKed and validates it (or calls on_kicked event).
Definition at line 3844 of file irc.cpp. References s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_find_user(), s_online_user::irc_op, logic_find_user(), logic_validate_kick(), and s_online_user::nick. Referenced by irc_loop_process_input(). 03845 { 03846 string log=str; 03847 unsigned int i1; 03848 03849 str.erase(0,1); // erase first ':' 03850 03851 string nick; 03852 for(i1=0; i1<str.length(); i1++) 03853 if(str[i1]=='!') 03854 break; 03855 else 03856 nick+=str[i1]; 03857 str.erase(0,i1+1); // erase nick name 03858 03859 string ident; 03860 for(i1=0; i1<str.length(); i1++) 03861 if(str[i1]=='@') 03862 break; 03863 else 03864 ident+=str[i1]; 03865 str.erase(0,i1+1); // erase ident 03866 03867 string host; 03868 for(i1=0; i1<str.length(); i1++) 03869 if(str[i1]==0x20) 03870 break; 03871 else 03872 host+=str[i1]; 03873 str.erase(0,i1+1); // erase host name 03874 03875 for(i1=0; i1<str.length(); i1++) 03876 if(str[i1]==0x20) 03877 break; 03878 str.erase(0,i1+1); // erase "KICK" 03879 03880 string channel; 03881 for(i1=0; i1<str.length(); i1++) 03882 if(str[i1]==0x20) 03883 break; 03884 else 03885 channel+=str[i1]; 03886 str.erase(0,i1+1); // erase channel 03887 03888 string target; 03889 for(i1=0; i1<str.length(); i1++) 03890 if(str[i1]==0x20) 03891 break; 03892 else 03893 target+=str[i1]; 03894 str.erase(0,i1+1); // erase target 03895 03896 s_online_user source_=irc_find_user(nick); 03897 string source_user=logic_find_user(source_.nick,source_.ident,source_.host,source_.fullname,source_.irc_op); 03898 03899 s_online_user target_=irc_find_user(target); 03900 string target_user=logic_find_user(target_.nick,target_.ident,target_.host,target_.fullname,target_.irc_op); 03901 03902 logic_validate_kick(channel,source_user,target_user,nick,target); 03903 }
Here is the call graph for this function: ![]() |
|
Clears wait flag for sent command (reply has been received).
Definition at line 3954 of file irc.cpp. References waiting_for_response. Referenced by irc_loop_process_input(). 03955 { 03956 char tmp[128]; 03957 unsigned int i1; 03958 for(i1=0; i1<64 && command[i1]!=0 && command[i1]!=0x20; i1++) 03959 tmp[i1]=command[i1]; 03960 tmp[i1]=0; 03961 03962 vector<s_awaiting_response>::iterator i2; 03963 for(i2=waiting_for_response.begin(); i2!=waiting_for_response.end(); i2++) { 03964 string cmd; 03965 for(unsigned int i3=0; i3<(*i2).message.length() && (*i2).message[i3]!=0x20; i3++) 03966 cmd+=(*i2).message[i3]; 03967 03968 if(!cmd.compare(tmp)) { 03969 waiting_for_response.erase(i2); 03970 break; 03971 } 03972 } 03973 }
|
|
Clears wait flag for sent message (reply has been received).
Definition at line 3937 of file irc.cpp. References s_msg_to_server::response, and s_msg_to_server::wait_for_response. Referenced by irc_loop_process_input(). 03938 { 03939 size_t n=resp.length(); 03940 if(n>sizeof(last_msg.response)-1) 03941 n=sizeof(last_msg.response)-1; 03942 strncpy(last_msg.response,resp.c_str(),n); 03943 last_msg.response[n]=0; 03944 last_msg.wait_for_response=false; 03945 }
|
|
This is called in loop to process messages from server.
Definition at line 4630 of file irc.cpp. References s_dcc_awaiting_user::addr4, s_dcc_awaiting_user::addr6, s_online_channel::b_bans_sent, s_online_channel::b_excepts_sent, s_online_channel::b_invites_sent, s_online_channel::bans, in_addr6_::bytes, s_005::chanmodes_a, s_key_chan::channel_name, cmp_strings_case_insensitive(), DCC_ACCESS_DENIED, dcc_awaiting_users, dcc_file_has_been_read(), dcc_get_string(), DCC_IO_ERROR, dcc_loop(), DCC_NO_SUCH_FILE, dcc_send_file(), s_online_channel::excepts, s_dcc_awaiting_user::fullname, s_online_user::fullname, gone_users, s_online_channel::got_excepts, s_online_channel::got_invites, s_online_user::got_mode, s_online_user::got_whois, HIGH_PRIORITY, s_dcc_awaiting_user::host, s_online_user::host, s_dcc_awaiting_user::ident, s_online_user::ident, s_online_user::in_logic_as, inet_pton(), s_online_channel::invites, irc_access_to_partyline(), irc_banned(), irc_cannot_join_channels, irc_channels, irc_check_bans(), irc_check_flood(), irc_check_for_not_invited(), irc_check_for_not_reopped(), irc_check_last_msg(), irc_check_nick_on_channel(), irc_disconnect(), irc_end_of_excepted(), irc_excepted(), irc_follow_redirs, irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_get_mode(), irc_get_modes_for_log(), irc_get_online_channel(), irc_in_reop(), irc_invited(), irc_key_chans, irc_kicked(), irc_kill_command_wait(), irc_kill_last_msg_wait(), irc_last_keepalive_detection, irc_nick, irc_on_broadcast(), irc_on_notice(), irc_on_privmsg(), s_online_user::irc_op, irc_privmsg(), irc_putserv(), irc_putserv_immediately(), irc_quoted_callback(), irc_recommended_port, irc_recommended_server, irc_RPL_324(), irc_RPL_ENDOFWHOIS(), irc_RPL_ISUPPORT(), irc_RPL_MODE(), irc_RPL_NAMREPLY(), irc_RPL_TOPIC(), irc_RPL_WHOISCHANNELS(), irc_RPL_WHOISOPERATOR(), irc_RPL_WHOISUSER(), irc_RPL_YOURID(), irc_server_host, irc_server_port, irc_unique_id, s_online_user::just_joined, s_online_user::just_joined_channel, s_key_chan::keys, lang_get_string(), log_bot(), log_broadcast(), log_channel(), log_debug(), log_irc(), logic_fnc(), logic_get_dcc_host(), logic_on_ircop(), logic_on_join(), logic_on_nick_change(), logic_on_part(), logic_on_server_msg(), LOW_PRIORITY, s_online_user::mode, s_online_channel::modes, msgs_from_server, s_online_channel::name, s_dcc_awaiting_user::nick, s_online_user::nick, s_online_user::old_mode, s_online_user::old_nick, s_online_user::on_join_called, r_channel_defs, s_005::raw, s_msg_to_server::response, sleep(), sock_resolve(), sock_resolve6(), s_dcc_awaiting_user::start_time, s_msg_to_server::timestamp, tmp_users, s_online_channel::topic, TYPE_CTCP, TYPE_IRCOP_JOIN, TYPE_IRCOP_LEFT, TYPE_JOIN, TYPE_KICK, TYPE_MODE, TYPE_NICK, TYPE_NOTICE, TYPE_PART, TYPE_PRIVMSG, TYPE_QUIT, TYPE_QUIT_PART_KICK, TYPE_TOPIC, s_dcc_awaiting_user::user_name_as_in_logic, s_online_channel::users, s_dcc_awaiting_user::using_ipv6, s_msg_to_server::wait_for_response, and s_online_user::whois_sent. Referenced by logic_exec(), and main(). 04631 { 04632 time_t now; 04633 time(&now); 04634 vector<s_online_user>::iterator ii; 04635 _label_1: 04636 for(ii=tmp_users.begin(); ii!=tmp_users.end(); ii++) { 04637 if((*ii).last_whois+10<=now) { 04638 tmp_users.erase(ii); 04639 goto _label_1; 04640 } 04641 } 04642 04643 list<char*>::iterator i; 04644 04645 l1: 04646 i=msgs_from_server.begin(); 04647 if(i!=msgs_from_server.end()) { 04648 irc_last_keepalive_detection=time(NULL); 04649 04650 log_irc(true,*i); 04651 04652 { 04653 string resp=*i; 04654 //bool b=false; 04655 if(resp.length()>=4) { 04656 if(resp[0]=='P' && resp[1]=='I' && resp[2]=='N' && resp[3]=='G') { 04657 string pong="PONG :"; 04658 for(unsigned int i1=6; i1<resp.length(); i1++) 04659 pong+=resp[i1]; 04660 pong+="\r\n"; 04661 04662 delete[] (*i); 04663 msgs_from_server.pop_front(); 04664 04665 irc_putserv_immediately(irc_socket,pong.c_str()); 04666 04667 goto l1; 04668 } 04669 04670 if(resp[0]=='E' && resp[1]=='R' && resp[2]=='R' && resp[3]=='O' && resp[4]=='R') { 04671 if(strstr(resp.c_str(),"Throttled") || 04672 strstr(resp.c_str(),"throttled") || 04673 strstr(resp.c_str(),"too fast") || 04674 strstr(resp.c_str(),"Overridden") || 04675 strstr(resp.c_str(),"overridden") 04676 ) { 04677 irc_disconnect(); 04678 return 2; 04679 } 04680 irc_disconnect(); 04681 sleep(60); 04682 04683 return 1; 04684 } 04685 04686 unsigned int i1; 04687 for(i1=0; i1<resp.length(); i1++) 04688 if(resp[i1]==0x20) 04689 break; 04690 i1++; 04691 04692 size_t len=resp.length()-i1; 04693 if(len>4*1024-1) { 04694 log_debug("one line from IRC server exceeded about 4 KB, in file " __FILE__ " in function "); 04695 goto l2; 04696 } 04697 04698 char tmp[4*1024]; 04699 strcpy(tmp,(char*)&((resp.c_str())[i1])); 04700 if(tmp[strlen(tmp)-1]=='\r' || tmp[strlen(tmp)-1]=='\n') 04701 tmp[strlen(tmp)-1]=0; 04702 if(tmp[strlen(tmp)-1]=='\r' || tmp[strlen(tmp)-1]=='\n') 04703 tmp[strlen(tmp)-1]=0; 04704 04705 string str=tmp; 04706 len=str.length(); 04707 04708 string hm; 04709 string nick, ident, host; 04710 string channel; 04711 string whom; // only for KICK 04712 string topic; // only for topic 04713 string notice; // only for NOTICE from server 04714 if(resp.length()>0 && resp[0]==':') { 04715 unsigned int i1; 04716 for(i1=1; i1<resp.length(); i1++) { 04717 if(resp[i1]==0x20) 04718 break; 04719 hm+=resp[i1]; 04720 } 04721 if(hm.find("!")!=string::npos && hm.find("@")!=string::npos) { 04722 i1++; 04723 int pos=0; 04724 for(i1=1; i1<resp.length(); i1++) { 04725 if(pos==0 && resp[i1]=='!') { 04726 pos++; 04727 continue; 04728 } 04729 if(pos==1 && resp[i1]=='@') { 04730 pos++; 04731 continue; 04732 } 04733 if(pos==2 && resp[i1]==0x20) { 04734 pos++; 04735 continue; 04736 } 04737 if(pos==3 && resp[i1]==0x20) { 04738 pos++; 04739 continue; 04740 } 04741 if(pos==4 && resp[i1]==0x20) { 04742 pos++; 04743 continue; 04744 } 04745 if(pos==5 && resp[i1]==':') { 04746 pos++; 04747 continue; 04748 } 04749 if(pos==0) 04750 nick+=resp[i1]; 04751 if(pos==1) 04752 ident+=resp[i1]; 04753 if(pos==2) 04754 host+=resp[i1]; 04755 if(pos==3) { 04756 // command 04757 } 04758 if(pos==4) 04759 channel+=resp[i1]; 04760 if(pos==5) 04761 whom+=resp[i1]; 04762 if(pos==6) 04763 topic+=resp[i1]; 04764 } 04765 } else { 04766 // message from server 04767 nick=""; 04768 ident=""; 04769 host=""; 04770 whom=""; 04771 channel=""; 04772 topic=""; 04773 notice=""; 04774 if(resp.length()>=i1+6 && resp[i1+1]=='M' && resp[i1+2]=='O' && resp[i1+3]=='D' && 04775 resp[i1+4]=='E' && resp[i1+5]==0x20) { 04776 channel=resp; 04777 channel.erase(0,i1+1+strlen("MODE ")); 04778 whom=channel; 04779 if(channel.find("\x20",0)!=string::npos) 04780 channel.erase(channel.find(0x20,0),channel.length()-channel.find(0x20,0)); 04781 if(whom.find(0x20,0)!=string::npos) 04782 whom.erase(0,whom.find(0x20,0)+1); 04783 } 04784 if(resp.length()>=i1+7 && resp[i1+1]=='T' && resp[i1+2]=='O' && resp[i1+3]=='P' && 04785 resp[i1+4]=='I' && resp[i1+5]=='C' && resp[i1+6]==0x20) { 04786 channel=resp; 04787 channel.erase(0,i1+1+strlen("TOPIC ")); 04788 whom=channel; 04789 if(channel.find("\x20",0)!=string::npos) 04790 channel.erase(channel.find(0x20,0),channel.length()-channel.find(0x20,0)); 04791 if(whom.find(0x20,0)!=string::npos) 04792 whom.erase(0,whom.find(0x20,0)+1); 04793 whom.erase(0,1); 04794 topic=whom; 04795 whom=""; 04796 } 04797 if(resp.length()>=i1+8 && resp[i1+1]=='N' && resp[i1+2]=='O' && resp[i1+3]=='T' && 04798 resp[i1+4]=='I' && resp[i1+5]=='C' && resp[i1+6]=='E' && resp[i1+7]==0x20) { 04799 channel=resp; 04800 channel.erase(0,i1+1+strlen("NOTICE ")); 04801 whom=channel; 04802 if(channel.find("\x20",0)!=string::npos) 04803 channel.erase(channel.find(0x20,0),channel.length()-channel.find(0x20,0)); 04804 if(whom.find(0x20,0)!=string::npos) 04805 whom.erase(0,whom.find(0x20,0)+1); 04806 whom.erase(0,1); 04807 notice=whom; 04808 whom=""; 04809 } 04810 } 04811 while(whom.length()>0 && whom[whom.length()-1]==0x20) 04812 whom.erase(whom.length()-1,1); 04813 } 04814 string quoted; 04815 string msg; 04816 bool sometihng=false; 04817 bool after_colon=false; 04818 for(i1=0; i1<len; i1++) { 04819 if(after_colon) 04820 msg+=str[i1]; 04821 if(str[i1]==':') 04822 after_colon=true; 04823 if(sometihng && str[i1]==0x01) 04824 break; 04825 if(!sometihng && str[i1]==0x01) { 04826 sometihng=true; 04827 continue; 04828 } 04829 if(sometihng) 04830 quoted+=str[i1]; 04831 } 04832 if(channel.length()>0 && channel[0]==':') 04833 channel.erase(0,1); 04834 04835 if(len>=4 && str[0]=='P' && str[1]=='O' && str[2]=='N' && str[3]=='G') { 04836 irc_kill_command_wait("PING"); 04837 } 04838 04839 if(len>=7 && str[0]=='P' && str[1]=='R' && str[2]=='I' && str[3]=='V' && str[4]=='M' && str[5]=='S' && str[6]=='G' && str[7]==' ') { 04840 string tmp=nick; 04841 tmp+="!"; 04842 tmp+=ident; 04843 tmp+="@"; 04844 tmp+=host; 04845 if(channel.find("$")!=-1 || channel.find("%")!=-1) { 04846 // we got broadcast PRIVMSG message 04847 log_broadcast(channel.c_str(),TYPE_PRIVMSG,tmp.c_str(),msg.c_str(),irc_server_host,irc_server_port); 04848 irc_on_broadcast(channel,TYPE_PRIVMSG,tmp,msg,irc_server_host,irc_server_port); 04849 } else if(!nick.empty()) { 04850 if(cmp_strings_case_insensitive(channel,irc_nick)) { 04851 log_channel(channel.c_str(),TYPE_PRIVMSG,tmp.c_str(),"",msg.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 04852 if(msg.find('\x01',0)!=-1 && msg.find("\x01" "ACTION ",0)==-1) 04853 irc_check_flood(TYPE_CTCP,channel,tmp,msg); 04854 else 04855 irc_check_flood(TYPE_PRIVMSG,channel,tmp,msg); 04856 irc_on_privmsg(channel,tmp,msg); 04857 } else { 04858 log_channel("private",TYPE_PRIVMSG,tmp.c_str(),"",msg.c_str(),""); 04859 irc_on_privmsg("",tmp,msg); 04860 } 04861 } else { 04862 // PRIVMSG from server 04863 if(cmp_strings_case_insensitive(channel,irc_nick)) { 04864 // it is for channel 04865 log_channel(channel.c_str(),TYPE_PRIVMSG,hm.c_str(),channel.c_str(),msg.c_str(),""); 04866 // we really don't want to check for flood now, since it is not likely 04867 // when server begins to flood channel, and there is a fact that we 04868 // cannot ban server ;-) 04869 // -- quote of VooDooMan on 2005-04-22 @ 14:30 GMT +01:00 (zopiclonum 7.5 mg per oral) 04870 04871 logic_on_server_msg(channel,hm,TYPE_PRIVMSG,msg,irc_server_host,irc_server_port); 04872 } else { 04873 // it is privately for bot 04874 log_channel("private",TYPE_PRIVMSG,hm.c_str(),channel.c_str(),msg.c_str(),""); 04875 04876 logic_on_server_msg("",hm,TYPE_PRIVMSG,msg,irc_server_host,irc_server_port); 04877 } 04878 } 04879 04880 if(!cmp_strings_case_insensitive(channel,irc_nick) && msg.length()>=3 && msg[0]=='d' && msg[1]=='c' && msg[2]=='c') { 04881 string user_name_as_in_logic; 04882 if(irc_access_to_partyline(hm.c_str(),user_name_as_in_logic,msg)) { 04883 int dcc_group=0; 04884 string dcc=dcc_get_string(msg,dcc_group); 04885 string dcc_host=logic_get_dcc_host(dcc_group,user_name_as_in_logic); 04886 if(!dcc.empty()) { 04887 string str="\x01"; 04888 str+=dcc; 04889 str+="\x01"; 04890 irc_privmsg(nick.c_str(),str.c_str(),LOW_PRIORITY); 04891 s_dcc_awaiting_user user; 04892 04893 user.nick=nick; 04894 user.ident=irc_get_ident(nick); 04895 user.host=irc_get_host(nick); 04896 user.fullname=irc_get_fullname(nick); 04897 04898 size_t n=user_name_as_in_logic.length(); 04899 if(n>128-1) 04900 n=128-1; 04901 strncpy(user.user_name_as_in_logic,user_name_as_in_logic.c_str(),n); 04902 user.user_name_as_in_logic[n]=0; 04903 04904 in_addr6_ ip6; 04905 if(inet_pton(AF_INET6,host.c_str(),&ip6)!=1) { 04906 user.using_ipv6=false; 04907 #ifdef _WIN32 04908 user.addr4.S_un.S_addr=0; 04909 #else 04910 user.addr4.s_addr=0; 04911 #endif 04912 user.addr4=sock_resolve(host.c_str(),NULL); 04913 #ifdef _WIN32 04914 if(!user.addr4.S_un.S_addr) { 04915 user.addr4.S_un.S_addr=(unsigned long)-1; 04916 #else 04917 if(!user.addr4.s_addr) { 04918 user.addr4.s_addr=(unsigned long)-1; 04919 #endif 04920 user.addr6=sock_resolve6((char*)host.c_str()); 04921 user.using_ipv6=true; 04922 } 04923 } else { 04924 memcpy(&user.addr6,&ip6,sizeof(user.addr6)); 04925 #ifdef _WIN32 04926 user.addr4.S_un.S_addr=(unsigned long)-1; 04927 #else 04928 user.addr4.s_addr=(unsigned long)-1; 04929 #endif 04930 user.using_ipv6=true; 04931 } 04932 04933 time(&user.start_time); 04934 04935 // security issue (two users from the same IP (proxy) connecting at the same time) 04936 vector<s_dcc_awaiting_user>::iterator i; 04937 again_: 04938 bool ignore=false; 04939 for(i=dcc_awaiting_users.begin(); i!=dcc_awaiting_users.end(); i++) { 04940 if((*i).start_time+20<time(NULL)) { 04941 dcc_awaiting_users.erase(i); 04942 goto again_; 04943 } 04944 if(!(*i).using_ipv6 && !user.using_ipv6) { 04945 #ifdef _WIN32 04946 if((*i).addr4.S_un.S_addr==user.addr4.S_un.S_addr) 04947 #else 04948 if((*i).addr4.s_addr==user.addr4.s_addr) 04949 #endif 04950 ignore=true; 04951 } 04952 if((*i).using_ipv6 && user.using_ipv6) { 04953 if((*i).addr6.bytes[0]==user.addr6.bytes[0] && 04954 (*i).addr6.bytes[1]==user.addr6.bytes[1] && 04955 (*i).addr6.bytes[2]==user.addr6.bytes[2] && 04956 (*i).addr6.bytes[3]==user.addr6.bytes[3] && 04957 (*i).addr6.bytes[4]==user.addr6.bytes[4] && 04958 (*i).addr6.bytes[5]==user.addr6.bytes[5] && 04959 (*i).addr6.bytes[6]==user.addr6.bytes[6] && 04960 (*i).addr6.bytes[7]==user.addr6.bytes[7] && 04961 (*i).addr6.bytes[8]==user.addr6.bytes[8] && 04962 (*i).addr6.bytes[9]==user.addr6.bytes[9] && 04963 (*i).addr6.bytes[10]==user.addr6.bytes[10] && 04964 (*i).addr6.bytes[11]==user.addr6.bytes[11] && 04965 (*i).addr6.bytes[12]==user.addr6.bytes[12] && 04966 (*i).addr6.bytes[13]==user.addr6.bytes[13] && 04967 (*i).addr6.bytes[14]==user.addr6.bytes[14] && 04968 (*i).addr6.bytes[15]==user.addr6.bytes[15]) 04969 ignore=true; 04970 } 04971 } 04972 04973 if(!ignore) 04974 dcc_awaiting_users.push_back(user); 04975 } 04976 } 04977 } 04978 04979 if((msg.length()>=7 && msg[0]=='g' && msg[1]=='e' && msg[2]=='t' && msg[3]=='f' && msg[4]=='i' && msg[5]=='l' && msg[6]=='e' && msg[7]==' ') 04980 || 04981 (msg.length()>=8 && msg[0]=='.' && msg[1]=='g' && msg[2]=='e' && msg[3]=='t' && msg[4]=='f' && msg[5]=='i' && msg[6]=='l' && msg[7]=='e' && msg[8]==' ') 04982 ) { 04983 string cmd=msg; 04984 while(cmd[0]!=' ') 04985 cmd.erase(0,1); 04986 string fn; 04987 string dcc_gr="0"; 04988 int pos=0; 04989 while(cmd.length()>0) { 04990 if(cmd[0]==' ') { 04991 cmd.erase(0,1); 04992 pos++; 04993 continue; 04994 } 04995 if(pos==1) { 04996 fn+=cmd[0]; 04997 cmd.erase(0,1); 04998 continue; 04999 } 05000 if(pos==2) { 05001 dcc_gr+=cmd[0]; 05002 cmd.erase(0,1); 05003 continue; 05004 } 05005 } 05006 int dcc_group=atol(dcc_gr.c_str()); 05007 int res=dcc_send_file(false,fn,nick,dcc_group); 05008 string disp; 05009 switch(res) { 05010 case DCC_NO_SUCH_FILE: 05011 disp=lang_get_string(1,"en",334); 05012 break; 05013 case DCC_ACCESS_DENIED: 05014 disp=lang_get_string(1,"en",335); 05015 break; 05016 case DCC_IO_ERROR: 05017 disp=lang_get_string(1,"en",336); 05018 break; 05019 } 05020 05021 if(!disp.empty()) { 05022 string m="PRIVMSG "; 05023 m+=nick; 05024 m+=" :"; 05025 m+=disp; 05026 irc_putserv(m.c_str(),false,LOW_PRIORITY); 05027 } else { 05028 dcc_file_has_been_read(fn,nick); 05029 } 05030 } 05031 05032 if(!quoted.empty()) { 05033 irc_quoted_callback(quoted.c_str(), nick.c_str(), hm.c_str()); 05034 } 05035 05036 delete[] (*i); 05037 msgs_from_server.pop_front(); 05038 05039 goto l1; 05040 } 05041 05042 if(len>=6 && str[0]=='N' && str[1]=='O' && str[2]=='T' && str[3]=='I' && str[4]=='C' && str[5]=='E' && str[6]==' ') { 05043 string tmp=nick; 05044 tmp+="!"; 05045 tmp+=ident; 05046 tmp+="@"; 05047 tmp+=host; 05048 if(channel.find("$")!=-1 || channel.find("%")!=-1) { 05049 // we got broadcast NOTICE message 05050 log_broadcast(channel,TYPE_NOTICE,tmp,msg,irc_server_host,irc_server_port); 05051 irc_on_broadcast(channel,TYPE_NOTICE,tmp,msg,irc_server_host,irc_server_port); 05052 } else if(!nick.empty()) { 05053 if(cmp_strings_case_insensitive(channel,irc_nick)) { 05054 log_channel(channel.c_str(),TYPE_NOTICE,hm.c_str(),channel.c_str(),msg.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05055 if(msg.find('\x01',0)!=-1 && msg.find("\x01" "ACTION ",0)==-1) 05056 irc_check_flood(TYPE_CTCP,channel,tmp,msg); 05057 else 05058 irc_check_flood(TYPE_NOTICE,channel,tmp,msg); 05059 irc_on_notice(channel,tmp,msg); 05060 } else { 05061 log_channel("private",TYPE_NOTICE,hm.c_str(),channel.c_str(),msg.c_str(),""); 05062 irc_on_notice("",tmp,msg); 05063 } 05064 } else { 05065 // NOTICE from server 05066 if(cmp_strings_case_insensitive(channel,irc_nick)) { 05067 // it is for channel 05068 log_channel(channel.c_str(),TYPE_NOTICE,hm.c_str(),channel.c_str(),msg.c_str(),""); 05069 // we really don't want to check for flood now, since it is not likely 05070 // when server begins to flood channel, and there is a fact that we 05071 // cannot ban server ;-) 05072 // -- quote of VooDooMan on 2005-04-22 @ 14:30 GMT +01:00 (zopiclonum 7.5 mg per oral) 05073 05074 logic_on_server_msg(channel,hm,TYPE_NOTICE,msg,irc_server_host,irc_server_port); 05075 } else { 05076 // it is privately for bot 05077 log_channel("private",TYPE_NOTICE,hm.c_str(),channel.c_str(),msg.c_str(),""); 05078 05079 logic_on_server_msg("",hm,TYPE_NOTICE,msg,irc_server_host,irc_server_port); 05080 } 05081 } 05082 } 05083 05084 if(len>4 && str[0]=='J' && str[1]=='O' && str[2]=='I' && str[3]=='N') { 05085 if(!nick.empty()) { 05086 string tmp=nick; 05087 tmp+="!"; 05088 tmp+=ident; 05089 tmp+="@"; 05090 tmp+=host; 05091 log_channel(channel.c_str(),TYPE_JOIN,tmp.c_str(),"","",irc_get_modes_for_log(channel,nick).c_str()); 05092 05093 irc_check_flood(TYPE_JOIN,channel,tmp,""); // !!! we (maybe) don't know who "tmp" is here! 05094 } 05095 05096 if(!nick.compare(irc_nick)) { 05097 irc_kill_command_wait("JOIN"); 05098 05099 vector<s_key_chan>::iterator i2; 05100 label_b: 05101 for(i2=irc_key_chans.begin(); i2!=irc_key_chans.end(); i2++) { 05102 if(!cmp_strings_case_insensitive((*i2).channel_name,channel)) { 05103 irc_key_chans.erase(i2); 05104 goto label_b; 05105 } 05106 } 05107 05108 vector<string>::iterator i1; 05109 erase_again: 05110 for(i1=irc_cannot_join_channels.begin(); i1!=irc_cannot_join_channels.end(); i1++) { 05111 if(!cmp_strings_case_insensitive(*i1,channel)) { 05112 irc_cannot_join_channels.erase(i1); 05113 goto erase_again; 05114 } 05115 } 05116 } 05117 05118 str.erase(0,5); 05119 unsigned int i1; 05120 for(i1=0; i1<str.length(); i1++) 05121 if(str[i1]==0x20) 05122 break; 05123 if(str.length()-i1>0) 05124 str.erase(i1,str.length()-i1); 05125 05126 for(i1=0; i1<str.length(); i1++) 05127 if(str[i1]==':') 05128 break; 05129 if(str[i1]==':') 05130 str.erase(0,i1+1); // erase everything before ':' 05131 05132 bool got_user=false; 05133 bool got_channel=false; 05134 l5: 05135 vector<s_online_channel>::iterator i2; 05136 vector<s_online_user>::iterator ii; 05137 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 05138 if(!cmp_strings_case_insensitive((*i2).name,str)) { 05139 got_channel=true; 05140 for(ii=(*i2).users.begin(); ii!=(*i2).users.end(); ii++) { 05141 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 05142 (*i2).users.erase(ii); 05143 got_user=false; 05144 goto l5; 05145 } 05146 } 05147 if(got_user) 05148 break; 05149 } 05150 } 05151 05152 l10: 05153 vector<s_online_channel>::iterator i; 05154 got_channel=false; 05155 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05156 if(!cmp_strings_case_insensitive((*i).name,str)) { 05157 got_channel=true; 05158 break; 05159 } 05160 } 05161 if(!got_channel) { 05162 s_online_channel chan; 05163 chan.b_excepts_sent=chan.b_invites_sent=chan.b_bans_sent=false; 05164 chan.name=str; 05165 chan.modes=""; 05166 chan.topic=""; 05167 chan.users.clear(); 05168 chan.bans.clear(); 05169 chan.got_excepts=false; 05170 chan.got_invites=false; 05171 chan.excepts.clear(); 05172 chan.invites.clear(); 05173 irc_channels.push_back(chan); 05174 05175 goto l10; 05176 } 05177 05178 if(!nick.compare(irc_nick)) { 05179 // we are new on channel, right after JOIN 05180 } 05181 05182 if(got_channel && !irc_check_nick_on_channel(nick,channel)) { 05183 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) 05184 if(!cmp_strings_case_insensitive((*i2).name,str)) 05185 break; 05186 05187 s_online_user u; 05188 u.nick=nick; 05189 u.got_whois=false; 05190 u.on_join_called=false; 05191 u.old_mode="INVALID"; 05192 05193 bool got_nick=false; 05194 vector<s_online_channel>::iterator ii1; 05195 vector<s_online_user>::iterator ii2; 05196 for(ii1=irc_channels.begin(); ii1!=irc_channels.end(); ii1++) { 05197 for(ii2=(*ii1).users.begin(); ii2!=(*ii1).users.end(); ii2++) { 05198 if(!(*ii2).nick.compare(nick)) { 05199 got_nick=true; 05200 break; 05201 } 05202 } 05203 if(got_nick) 05204 break; 05205 } 05206 05207 if(!got_nick) { 05208 hard_whois: 05209 string str="WHOIS "; 05210 str+=nick; 05211 irc_putserv(str.c_str(),true,HIGH_PRIORITY); 05212 05213 u.whois_sent=true; 05214 05215 u.ident=ident; 05216 u.host=host; 05217 u.fullname=""; 05218 u.got_mode=false; 05219 u.mode="0"; 05220 u.irc_op=false; 05221 u.in_logic_as=""; 05222 05223 u.just_joined=true; 05224 u.just_joined_channel=channel; 05225 } else { 05226 if(!(*ii2).got_whois) 05227 goto hard_whois; 05228 u.fullname=(*ii2).fullname; 05229 u.got_mode=true; 05230 u.got_whois=true; 05231 u.host=(*ii2).host; 05232 u.ident=(*ii2).ident; 05233 u.in_logic_as=(*ii2).in_logic_as; 05234 u.irc_op=(*ii2).irc_op; 05235 u.mode="0"; 05236 u.nick=(*ii2).nick; 05237 u.old_nick=u.nick; 05238 u.old_mode=u.mode; 05239 u.on_join_called=true; 05240 u.whois_sent=true; 05241 u.just_joined_channel=channel; 05242 05243 u.just_joined=true; 05244 if(nick.compare(irc_nick)) // only call if it is not me myself! 05245 logic_on_join(u.nick,u.ident,u.host,u.fullname,u.just_joined_channel,u.irc_op); 05246 if(u.irc_op) { 05247 logic_on_ircop(channel,u.nick,true); 05248 string host_mask=u.nick; 05249 host_mask+="!"; 05250 host_mask+=u.ident; 05251 host_mask+="@"; 05252 host_mask+=u.host; 05253 log_channel(channel.c_str(),TYPE_IRCOP_JOIN,host_mask.c_str(),"","",irc_get_modes_for_log(channel,nick).c_str()); 05254 } 05255 } 05256 (*i2).users.push_back(u); 05257 } 05258 05259 if(irc_check_last_msg("JOIN")) 05260 irc_kill_last_msg_wait(resp); 05261 05262 irc_kill_command_wait("JOIN"); 05263 } 05264 str=tmp; 05265 05266 if(len>4 && str[0]=='Q' && str[1]=='U' && str[2]=='I' && str[3]=='T') { 05267 string host_mask; 05268 if(!nick.empty()) { 05269 string tmp=nick; 05270 tmp+="!"; 05271 tmp+=ident; 05272 tmp+="@"; 05273 tmp+=host; 05274 host_mask=tmp; 05275 vector<s_online_channel>::iterator i1; 05276 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 05277 vector<s_online_user>::iterator i2; 05278 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) 05279 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 05280 log_channel((*i1).name.c_str(),TYPE_QUIT,tmp.c_str(),"",msg.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05281 if((*i2).irc_op) { 05282 logic_on_ircop((*i1).name,nick,false); 05283 log_channel((*i1).name.c_str(),TYPE_IRCOP_LEFT,host_mask.c_str(),"","",irc_get_modes_for_log((*i1).name,nick).c_str()); 05284 } 05285 irc_check_flood(TYPE_QUIT_PART_KICK,(*i1).name,tmp,msg); 05286 05287 logic_on_part((*i1).name,nick,msg,TYPE_QUIT); 05288 } 05289 } 05290 } 05291 05292 vector<s_online_channel>::iterator i; 05293 l6: 05294 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05295 vector<s_online_user>::iterator ii; 05296 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 05297 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 05298 time(&(*ii).quit_time); 05299 gone_users.push_back(*ii); 05300 (*i).users.erase(ii); 05301 goto l6; 05302 } 05303 } 05304 } 05305 cycle1: 05306 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05307 string my_modes=irc_get_mode((*i).name,irc_nick); 05308 if(my_modes.find('@',0)==-1 && cmp_strings_case_insensitive(nick,irc_nick)) { 05309 int users=0; 05310 vector<s_online_user>::iterator ii; 05311 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++, users++) 05312 ; 05313 if(users==1) { 05314 // try to get op 05315 string m=(*i).name; 05316 irc_kill_last_msg_wait(resp); 05317 string msg="PART "; 05318 msg+=m; 05319 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 05320 msg="JOIN "; 05321 msg+=m; 05322 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05323 msg="MODE "; 05324 msg+=m; 05325 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05326 msg="TOPIC "; 05327 msg+=m; 05328 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05329 msg="WHOIS "; 05330 msg+=irc_nick; 05331 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05332 05333 irc_channels.erase(i); 05334 goto cycle1; 05335 } 05336 } 05337 } 05338 } 05339 str=tmp; 05340 05341 if(len>4 && str[0]=='P' && str[1]=='A' && str[2]=='R' && str[3]=='T') { 05342 string host_mask; 05343 if(!nick.empty()) { 05344 string tmp=nick; 05345 tmp+="!"; 05346 tmp+=ident; 05347 tmp+="@"; 05348 tmp+=host; 05349 host_mask=tmp; 05350 log_channel(channel.c_str(),TYPE_PART,tmp.c_str(),"",msg.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05351 05352 irc_check_flood(TYPE_QUIT_PART_KICK,channel,tmp,msg); 05353 } 05354 05355 str.erase(0,5); 05356 unsigned int i1; 05357 for(i1=0; i1<str.length(); i1++) 05358 if(str[i1]==0x20) 05359 break; 05360 if(str.length()-i1>0) 05361 str.erase(i1,str.length()-i1); 05362 05363 l8: 05364 vector<s_online_channel>::iterator i; 05365 bool got_channel=false; 05366 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05367 if(!cmp_strings_case_insensitive((*i).name,str)) { 05368 got_channel=true; 05369 break; 05370 } 05371 } 05372 if(!got_channel /*&& nick.compare(irc_nick)*/) { 05373 // we are new on channel, right after JOIN 05374 // assume that irc server will send names reply 05375 s_online_channel chan; 05376 chan.b_excepts_sent=chan.b_invites_sent=chan.b_bans_sent=false; 05377 chan.name=str; 05378 chan.modes=""; 05379 chan.topic=""; 05380 chan.users.clear(); 05381 chan.bans.clear(); 05382 chan.got_excepts=false; 05383 chan.excepts.clear(); 05384 chan.got_invites=false; 05385 chan.invites.clear(); 05386 irc_channels.push_back(chan); 05387 05388 goto l8; 05389 } 05390 05391 l7: 05392 vector<s_online_user>::iterator ii; 05393 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 05394 if(!cmp_strings_case_insensitive((*ii).nick,nick) && !cmp_strings_case_insensitive((*i).name,str)) { 05395 logic_on_part(channel,nick,msg,TYPE_PART); 05396 if((*ii).irc_op) { 05397 logic_on_ircop(channel,nick,false); 05398 log_channel(channel.c_str(),TYPE_IRCOP_LEFT,host_mask.c_str(),"","",irc_get_modes_for_log((*i).name,nick).c_str()); 05399 } 05400 05401 if(cmp_strings_case_insensitive((*ii).ident,ident) || cmp_strings_case_insensitive((*ii).host,host)) { 05402 time(&(*ii).quit_time); 05403 gone_users.push_back(*ii); 05404 (*i).users.erase(ii); 05405 05406 goto l7; 05407 } 05408 (*i).users.erase(ii); 05409 goto l7; 05410 } 05411 } 05412 cycle2: 05413 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05414 string my_modes=irc_get_mode((*i).name,irc_nick); 05415 if(my_modes.find('@',0)==-1 && cmp_strings_case_insensitive(nick,irc_nick)) { 05416 int users=0; 05417 vector<s_online_user>::iterator ii; 05418 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++, users++) 05419 ; 05420 // if someone else has PART-ed, try to get op 05421 if(users==1 && cmp_strings_case_insensitive(nick,irc_nick)) { 05422 // try to get op 05423 string m=(*i).name; 05424 irc_kill_last_msg_wait(resp); 05425 string msg="PART "; 05426 msg+=m; 05427 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 05428 msg="JOIN "; 05429 msg+=m; 05430 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05431 msg="MODE "; 05432 msg+=m; 05433 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05434 msg="TOPIC "; 05435 msg+=m; 05436 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05437 msg="WHOIS "; 05438 msg+=irc_nick; 05439 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05440 05441 irc_channels.erase(i); 05442 goto cycle2; 05443 } 05444 } 05445 } 05446 if(!cmp_strings_case_insensitive(nick,irc_nick)) { 05447 // if I PART-ed 05448 irc_kill_last_msg_wait(resp); 05449 05450 irc_kill_command_wait("PART"); 05451 05452 again_e_chan2: 05453 vector<s_online_channel>::iterator i; 05454 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05455 if(!cmp_strings_case_insensitive((*i).name,channel)) { 05456 irc_channels.erase(i); 05457 goto again_e_chan2; 05458 } 05459 } 05460 } 05461 } 05462 str=tmp; 05463 05464 if(len>4 && str[0]=='K' && str[1]=='I' && str[2]=='C' && str[3]=='K') { 05465 irc_kill_command_wait("KICK"); 05466 05467 string host_mask; 05468 if(!nick.empty()) { 05469 string tmp=nick; 05470 tmp+="!"; 05471 tmp+=ident; 05472 tmp+="@"; 05473 tmp+=host; 05474 host_mask=tmp; 05475 log_channel(channel.c_str(),TYPE_KICK,tmp.c_str(),whom.c_str(),msg.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05476 05477 irc_check_flood(TYPE_QUIT_PART_KICK,channel,tmp,msg); 05478 05479 irc_kicked(resp); 05480 } 05481 05482 vector<s_online_channel>::iterator i; 05483 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05484 if(!cmp_strings_case_insensitive((*i).name,channel)) { 05485 vector<s_online_user>::iterator ii; 05486 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 05487 if(!cmp_strings_case_insensitive((*ii).nick,whom)) { 05488 logic_on_part(channel,whom,msg,TYPE_KICK); 05489 if((*ii).irc_op) { 05490 logic_on_ircop(channel,whom,false); 05491 log_channel(channel.c_str(),TYPE_IRCOP_LEFT,host_mask.c_str(),"","",irc_get_modes_for_log((*i).name,nick).c_str()); 05492 } 05493 05494 time(&(*ii).quit_time); 05495 gone_users.push_back(*ii); 05496 (*i).users.erase(ii); 05497 break; 05498 } 05499 } 05500 } 05501 } 05502 cycle3: 05503 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05504 string my_modes=irc_get_mode((*i).name,irc_nick); 05505 if(my_modes.find('@',0)==-1 && cmp_strings_case_insensitive(nick,irc_nick)) { 05506 int users=0; 05507 vector<s_online_user>::iterator ii; 05508 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++, users++) 05509 ; 05510 // if not KICK-ed me, but someone else, try to get op 05511 if(users==1 && cmp_strings_case_insensitive(whom,irc_nick)) { 05512 // try to get op 05513 string m=(*i).name; 05514 irc_kill_last_msg_wait(resp); 05515 05516 irc_kill_command_wait("KICK"); 05517 05518 string msg="PART "; 05519 msg+=m; 05520 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 05521 msg="JOIN "; 05522 msg+=m; 05523 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05524 msg="MODE "; 05525 msg+=m; 05526 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05527 msg="TOPIC "; 05528 msg+=m; 05529 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05530 msg="WHOIS "; 05531 msg+=irc_nick; 05532 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 05533 05534 irc_channels.erase(i); 05535 goto cycle3; 05536 } 05537 } 05538 } 05539 if(!cmp_strings_case_insensitive(whom,irc_nick)) { 05540 again_e_chan1: 05541 vector<s_online_channel>::iterator i; 05542 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05543 if(!cmp_strings_case_insensitive((*i).name,channel)) { 05544 irc_channels.erase(i); 05545 goto again_e_chan1; 05546 } 05547 } 05548 } 05549 irc_kill_last_msg_wait(resp); 05550 } 05551 str=tmp; 05552 05553 if(len>4 && str[0]=='N' && str[1]=='I' && str[2]=='C' && str[3]=='K') { 05554 irc_kill_command_wait("NICK"); 05555 05556 forced_nick_change: 05557 if(!nick.empty()) { 05558 string tmp=nick; 05559 tmp+="!"; 05560 tmp+=ident; 05561 tmp+="@"; 05562 tmp+=host; 05563 vector<s_online_channel>::iterator i1; 05564 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 05565 vector<s_online_user>::iterator ii; 05566 for(ii=(*i1).users.begin(); ii!=(*i1).users.end(); ii++) { 05567 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 05568 // msg contains new nick 05569 log_channel((*i1).name.c_str(),TYPE_NICK,tmp.c_str(),"",msg.c_str(),irc_get_modes_for_log((*i1).name,nick).c_str()); 05570 if(nick.compare(irc_nick)) { 05571 irc_check_flood(TYPE_NICK,(*i1).name,tmp,msg); 05572 // do NOT perform next line! we got it later 05573 //(*ii).nick=msg; 05574 char tmp[1024]; 05575 strcpy(tmp,"WHOIS "); 05576 strcat(tmp,msg.c_str()); 05577 irc_putserv(tmp,true,HIGH_PRIORITY); 05578 } else { 05579 if(msg.length()<sizeof(irc_nick)) { 05580 strcpy(irc_nick,msg.c_str()); 05581 char tmp[1024]; 05582 strcpy(tmp,"WHOIS "); 05583 strcat(tmp,irc_nick); 05584 irc_putserv(tmp,true,HIGH_PRIORITY); 05585 } 05586 } 05587 } 05588 } 05589 } 05590 if(!cmp_strings_case_insensitive(nick,irc_nick)) { 05591 if(msg.length()<sizeof(irc_nick)) 05592 strcpy(irc_nick,msg.c_str()); 05593 } 05594 } 05595 05596 vector<s_online_channel>::iterator i; 05597 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05598 vector<s_online_user>::iterator ii; 05599 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 05600 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 05601 string old_nick=(*ii).nick; 05602 (*ii).nick=msg; 05603 05604 // validate new nick 05605 logic_on_nick_change((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).just_joined_channel,(*ii).irc_op,old_nick); 05606 } 05607 } 05608 } 05609 } 05610 str=tmp; 05611 05612 // 433: nickname already in use 05613 if(len>4 && str[0]=='4' && str[1]=='3' && str[2]=='3' && str[3]==' ') { 05614 if(irc_check_last_msg("NICK")) 05615 irc_kill_last_msg_wait(resp); 05616 05617 irc_kill_command_wait("NICK"); 05618 } 05619 05620 if(len>4 && str[0]=='0' && str[1]=='0' && str[2]=='1' && str[3]==' ') { 05621 if(irc_check_last_msg("USER")) 05622 irc_kill_last_msg_wait(resp); 05623 05624 irc_kill_command_wait("USER"); 05625 } 05626 if(len>4 && str[0]=='0' && str[1]=='0' && str[2]=='2' && str[3]==' ') { 05627 if(irc_check_last_msg("USER")) 05628 irc_kill_last_msg_wait(resp); 05629 05630 irc_kill_command_wait("USER"); 05631 } 05632 if(len>4 && str[0]=='0' && str[1]=='0' && str[2]=='3' && str[3]==' ') { 05633 if(irc_check_last_msg("USER")) 05634 irc_kill_last_msg_wait(resp); 05635 05636 irc_kill_command_wait("USER"); 05637 } 05638 if(len>4 && str[0]=='0' && str[1]=='0' && str[2]=='4' && str[3]==' ') { 05639 if(irc_check_last_msg("USER")) 05640 irc_kill_last_msg_wait(resp); 05641 05642 irc_kill_command_wait("USER"); 05643 } 05644 if(len>4 && str[0]=='0' && str[1]=='0' && str[2]=='5' && str[3]==' ') { 05645 if(irc_check_last_msg("USER")) 05646 irc_kill_last_msg_wait(resp); 05647 05648 irc_kill_command_wait("USER"); 05649 05650 // check for string "Try server <server name>, port <port number>" 05651 str.erase(0,4); 05652 size_t len=str.length(); 05653 if(len>11 && str[1]=='r' && str[2]=='y' && str[3]==0x20 && str[4]=='s' && str[5]=='e' && 05654 str[6]=='r' && str[7]=='v' && str[8]=='e' && str[9]=='r' && str[10]==0x20) { 05655 str.erase(0,11); 05656 string p; 05657 p=str; 05658 05659 while(p.length()>0 && p[0]!=',') 05660 p.erase(0,1); 05661 while(p.length()>0 && (p[0]<'0' || p[0]>'9')) 05662 p.erase(0,1); 05663 05664 unsigned int i1; 05665 for(i1=0; i1<str.length(); i1++) 05666 if(str[i1]==',' || str[i1]==0x20) 05667 break; 05668 str.erase(0,i1+1); 05669 05670 unsigned short port=(unsigned short)atol(p.c_str()); 05671 if(irc_follow_redirs) { 05672 irc_recommended_server=str; 05673 irc_recommended_port=port; 05674 } 05675 } else { 05676 irc_RPL_ISUPPORT(str); 05677 } 05678 } 05679 05680 // NAMES reply 05681 if(len>4 && str[0]=='3' && str[1]=='5' && str[2]=='3' && str[3]==' ') { 05682 irc_RPL_NAMREPLY(str); 05683 } 05684 05685 // RPL_ENDOFNAMES 05686 if(len>4 && str[0]=='3' && str[1]=='6' && str[2]=='6' && str[3]==' ') { 05687 if(irc_check_last_msg("NAMES")) 05688 irc_kill_last_msg_wait(resp); 05689 05690 irc_kill_command_wait("NAMES"); 05691 } 05692 05693 // RPL_WHOISUSER 05694 // WHOIS reply 05695 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='1' && str[3]==' ') { 05696 irc_RPL_WHOISUSER(str); 05697 } 05698 05699 // RPL_WHOISOPERATOR 05700 // user is an IRC operator 05701 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='3' && str[3]==' ') { 05702 irc_RPL_WHOISOPERATOR(str); 05703 } 05704 05705 // RPL_ENDOFWHOIS 05706 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='8' && str[3]==' ') { 05707 irc_RPL_ENDOFWHOIS(str); 05708 if(irc_check_last_msg("WHOIS")) 05709 irc_kill_last_msg_wait(resp); 05710 05711 irc_kill_command_wait("WHOIS"); 05712 } 05713 05714 // RPL_WHOISCHANNELS 05715 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='9' && str[3]==' ') { 05716 irc_RPL_WHOISCHANNELS(str); 05717 } 05718 05719 // 471: Cannot join channel (+l) - limit 05720 // 473: Cannot join channel (+i) - invite only 05721 // 474: Cannot join channel (+b) - banned 05722 // 437: Channel/nick is temporarily unavailable (!!! also can be not channel, but nick!!!) 05723 if(len>4 && ( 05724 (str[0]=='4' && str[1]=='7' && str[2]=='1' && str[3]==' ') || 05725 (str[0]=='4' && str[1]=='7' && str[2]=='3' && str[3]==' ') || 05726 (str[0]=='4' && str[1]=='7' && str[2]=='4' && str[3]==' ') || 05727 (str[0]=='4' && str[1]=='3' && str[2]=='7' && str[3]==' '))) 05728 { 05729 irc_kill_command_wait("JOIN"); 05730 irc_kill_command_wait("MODE"); 05731 irc_kill_command_wait("TOPIC"); 05732 05733 string s=str; 05734 int i1=0; 05735 while(i1<2 && s.length()>0) { 05736 if(s[0]==0x20) 05737 i1++; 05738 s.erase(0,1); 05739 } 05740 string chan; 05741 while(s.length()>0 && s[0]!=0x20) { 05742 chan+=s[0]; 05743 s.erase(0,1); 05744 } 05745 05746 bool got=false; 05747 vector<string>::iterator i2; 05748 for(i2=irc_cannot_join_channels.begin(); i2!=irc_cannot_join_channels.end(); i2++) 05749 if(!cmp_strings_case_insensitive(*i2,chan)) { 05750 got=true; 05751 break; 05752 } 05753 05754 /*if(!got && chan.length()>0 && chan[0]!='#' && chan[0]!='&' && chan[0]!='+' && chan[0]!='!') 05755 got=true; // it is just a "437 nick teporarily unavailable" (not channel) 05756 */ 05757 string chantypes; 05758 map<string,string>::iterator iii; 05759 for(iii=irc_isupport.raw.begin(); iii!=irc_isupport.raw.end(); iii++) 05760 if(!(*iii).first.compare("CHANTYPES")) { 05761 chantypes=(*iii).second; 05762 break; 05763 } 05764 if(!got && chan.length()>0 && chantypes.find(chan[0])==-1) 05765 got=true; // it is just a "437 nick teporarily unavailable" (not channel) 05766 05767 if(!got) 05768 irc_cannot_join_channels.push_back(chan); 05769 05770 vector<s_online_channel>::iterator i; 05771 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) 05772 if(!cmp_strings_case_insensitive((*i).name,chan)) { 05773 irc_channels.erase(i); 05774 break; 05775 } 05776 05777 irc_kill_last_msg_wait(resp); 05778 } 05779 05780 //IRC IN :irc.server.com 442 BOT #channel :You're not on that channel 05781 if(len>4 && str[0]=='4' && str[1]=='4' && str[2]=='2' && str[3]==' ') { 05782 irc_kill_command_wait("MODE"); 05783 irc_kill_command_wait("TOPIC"); 05784 05785 irc_kill_last_msg_wait(resp); 05786 } 05787 05788 // IRC IN :irc.server.com 324 BOT #channel +nt 05789 // channel mode after JOIN 05790 if(len>4 && str[0]=='3' && str[1]=='2' && str[2]=='4' && str[3]==' ') { 05791 irc_RPL_324(str); 05792 05793 if(str.find(" ",0)!=string::npos) 05794 str.erase(0,str.find(" ")+1); // erase everything before and inclusive trailing SPACE - numeric reply 05795 if(str.find(" ",0)!=string::npos) 05796 str.erase(0,str.find(" ")+1); // erase everything before SPACE inclusive - my nick 05797 string chan; 05798 if(str.find(" ",0)!=string::npos) 05799 while(str.length() && str[0]!=0x20) { 05800 chan+=str[0]; 05801 str.erase(0,1); 05802 } 05803 str.erase(0,1); // erase space 05804 if(str.length() && str[0]=='+') 05805 str.erase(0,1); // erase leading '+' 05806 if(str.find(" ",0)!=string::npos) 05807 str.erase(str.find(" ",0),str.length()-str.find(" ",0)); // erase everything after SAPCE inclusive (possibly the topic) 05808 // in "str" we have channel modes now 05809 vector<s_online_channel>::iterator i; 05810 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05811 if(cmp_strings_case_insensitive((*i).name,chan)) 05812 continue; 05813 (*i).modes=str; 05814 break; 05815 } 05816 irc_kill_last_msg_wait(resp); 05817 05818 irc_kill_command_wait("MODE"); 05819 } 05820 str=tmp; 05821 05822 // IRC IN :irc.server.com 332 BOT #channel :topic 05823 // topic after join 05824 if(len>4 && str[0]=='3' && str[1]=='3' && str[2]=='2' && str[3]==' ') { 05825 irc_kill_command_wait("TOPIC"); 05826 05827 if(str.find(" ",0)!=string::npos) 05828 str.erase(0,str.find(" ")+1); // erase everything before and inclusive trailing SPACE - numeric reply 05829 if(str.find(" ",0)!=string::npos) 05830 str.erase(0,str.find(" ")+1); // erase everything before SPACE inclusive - my nick 05831 string chan; 05832 if(str.find(" ",0)!=string::npos) 05833 while(str.length() && str[0]!=0x20) { 05834 chan+=str[0]; 05835 str.erase(0,1); 05836 } 05837 str.erase(0,1); // erase space 05838 05839 if(str.find(":",0)!=string::npos) 05840 str.erase(0,str.find(":")+1); // erase everything before ':' inclusive 05841 05842 // in str we have topic 05843 vector<s_online_channel>::iterator i; 05844 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05845 if(cmp_strings_case_insensitive((*i).name,chan)) 05846 continue; 05847 (*i).topic=str; 05848 break; 05849 } 05850 irc_kill_last_msg_wait(resp); 05851 05852 irc_kill_command_wait("TOPIC"); 05853 } 05854 str=tmp; 05855 05856 // IRC IN :irc.server.com 331 BOT #channel :No topic is set. 05857 // NO topic after join 05858 if(len>4 && str[0]=='3' && str[1]=='3' && str[2]=='1' && str[3]==' ') { 05859 irc_kill_command_wait("TOPIC"); 05860 05861 if(str.find(" ",0)!=string::npos) 05862 str.erase(0,str.find(" ")+1); // erase everything before and inclusive trailing SPACE - numeric reply 05863 if(str.find(" ",0)!=string::npos) 05864 str.erase(0,str.find(" ")+1); // erase everything before SPACE inclusive - my nick 05865 string chan; 05866 if(str.find(" ",0)!=string::npos) 05867 while(str.length() && str[0]!=0x20) { 05868 chan+=str[0]; 05869 str.erase(0,1); 05870 } 05871 str.erase(0,1); // erase space 05872 05873 if(str.find(":",0)!=string::npos) 05874 str.erase(0,str.find(":")+1); // erase everything before ':' inclusive 05875 05876 vector<s_online_channel>::iterator i; 05877 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05878 if(cmp_strings_case_insensitive((*i).name,chan)) 05879 continue; 05880 (*i).topic=""; 05881 break; 05882 } 05883 irc_kill_last_msg_wait(resp); 05884 05885 irc_kill_command_wait("TOPIC"); 05886 } 05887 str=tmp; 05888 05889 if(len>4 && str[0]=='M' && str[1]=='O' && str[2]=='D' && str[3]=='E') { 05890 if(!nick.empty()) { 05891 string tmp=nick; 05892 tmp+="!"; 05893 tmp+=ident; 05894 tmp+="@"; 05895 tmp+=host; 05896 irc_check_flood(TYPE_MODE,channel,tmp,whom); 05897 } 05898 05899 if(!channel.length()) { 05900 whom=str; 05901 if(whom.find(":",0)!=string::npos) 05902 whom.erase(0,whom.find(":",0)+1); 05903 } 05904 log_channel(channel.c_str(),TYPE_MODE,hm.c_str(),"",whom.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05905 05906 if(irc_check_last_msg("MODE")) 05907 irc_kill_last_msg_wait(resp); 05908 05909 irc_kill_command_wait("MODE"); 05910 05911 irc_RPL_MODE(resp); 05912 } 05913 05914 if(len>4 && str[0]=='T' && str[1]=='O' && str[2]=='P' && str[3]=='I' && str[4]=='C') { 05915 if(!nick.empty()) { 05916 string tmp=nick; 05917 tmp+="!"; 05918 tmp+=ident; 05919 tmp+="@"; 05920 tmp+=host; 05921 irc_check_flood(TYPE_MODE,channel,tmp,topic); 05922 } 05923 05924 vector<s_online_channel>::iterator i; 05925 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05926 if(cmp_strings_case_insensitive((*i).name,channel)) 05927 continue; 05928 (*i).topic=topic; 05929 break; 05930 } 05931 05932 log_channel(channel.c_str(),TYPE_TOPIC,hm.c_str(),"TOPIC",topic.c_str(),irc_get_modes_for_log(channel,nick).c_str()); 05933 05934 if(irc_check_last_msg("TOPIC")) 05935 irc_kill_last_msg_wait(resp); 05936 05937 irc_kill_command_wait("TOPIC"); 05938 05939 irc_RPL_TOPIC(resp); 05940 } 05941 05942 // 472: unknown mode 05943 if(len>4 && str[0]=='4' && str[1]=='7' && str[2]=='2' && str[3]==' ') { 05944 if(irc_check_last_msg("MODE")) 05945 irc_kill_last_msg_wait(resp); 05946 05947 irc_kill_command_wait("MODE"); 05948 05949 // assume that error is on MODE #chan +e (some irc networks doesn't support +e exceptions to bans) 05950 vector<s_online_channel>::iterator i; 05951 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05952 (*i).got_excepts=true; 05953 irc_check_bans((*i).name); 05954 } 05955 05956 // assume that error is on MODE #chan +I (some irc networks doesn't support +I invitations) 05957 //vector<s_online_channel>::iterator i; 05958 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05959 (*i).got_invites=true; 05960 //irc_check_invites((*i).name); 05961 } 05962 05963 //vector<s_online_channel>::iterator i; 05964 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 05965 (*i).got_reops=true; 05966 } 05967 05968 s_online_channel* chan; 05969 if(irc_get_online_channel(channel,chan)) { 05970 if(!chan->b_excepts_sent && irc_isupport.chanmodes_a.find("e")!=string::npos) { 05971 chan->b_excepts_sent=true; 05972 string excepts="MODE "; 05973 excepts+=channel; 05974 excepts+=" +e"; 05975 irc_putserv(excepts.c_str(),true,HIGH_PRIORITY); 05976 } 05977 05978 if(!chan->b_bans_sent && irc_isupport.chanmodes_a.find("b")!=string::npos) { 05979 chan->b_bans_sent=true; 05980 string bans="MODE "; 05981 bans+=channel; 05982 bans+=" +b"; 05983 irc_putserv(bans.c_str(),true,HIGH_PRIORITY); 05984 } 05985 } 05986 05987 irc_end_of_excepted(resp); 05988 } 05989 05990 // 475: cannot join channel (+k) 05991 if(len>4 && str[0]=='4' && str[1]=='7' && str[2]=='5' && str[3]==' ') { 05992 irc_kill_command_wait("JOIN"); 05993 irc_kill_command_wait("MODE"); 05994 irc_kill_command_wait("TOPIC"); 05995 05996 string s=str; 05997 int i1=0; 05998 while(i1<2 && s.length()>0) { 05999 if(s[0]==0x20) 06000 i1++; 06001 s.erase(0,1); 06002 } 06003 string chan; 06004 while(s.length()>0 && s[0]!=0x20) { 06005 chan+=s[0]; 06006 s.erase(0,1); 06007 } 06008 06009 bool got=false; 06010 label_a: 06011 vector<s_key_chan>::iterator i2; 06012 for(i2=irc_key_chans.begin(); i2!=irc_key_chans.end(); i2++) { 06013 if(!cmp_strings_case_insensitive((*i2).channel_name,chan)) { 06014 if((*i2).keys.begin()==(*i2).keys.end()) { 06015 // :-( 06016 string log="Cannot join channel "; 06017 log+=chan; 06018 log+=" because it is +k, and I have tried all keys that I have in the history. Next retry is scheduled."; 06019 log_bot(log.c_str()); 06020 irc_key_chans.erase(i2); 06021 06022 { 06023 bool got=false; 06024 vector<string>::iterator ii; 06025 for(ii=irc_cannot_join_channels.begin(); ii!=irc_cannot_join_channels.end(); ii++) 06026 if(!chan.compare(*ii)) { 06027 got=true; 06028 } 06029 if(!got) 06030 irc_cannot_join_channels.push_back(chan); 06031 } 06032 06033 got=true; 06034 break; 06035 } 06036 string key=*((*i2).keys.begin()); 06037 (*i2).keys.erase((*i2).keys.begin()); 06038 06039 string msg="JOIN "; 06040 msg+=chan; 06041 msg+=" "; 06042 msg+=key; 06043 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 06044 msg="MODE "; 06045 msg+=chan; 06046 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 06047 msg="TOPIC "; 06048 msg+=chan; 06049 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 06050 msg="WHOIS "; 06051 msg+=irc_nick; 06052 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 06053 06054 irc_kill_last_msg_wait(resp); 06055 06056 got=true; 06057 } 06058 } 06059 if(!got) { 06060 s_key_chan kch; 06061 kch.channel_name=chan; 06062 kch.keys.clear(); 06063 vector<s_channel_def>::iterator i2; 06064 for(i2=r_channel_defs.begin(); i2!=r_channel_defs.end(); i2++) 06065 if(!cmp_strings_case_insensitive((*i2).channel_name,chan)) { 06066 vector<string>::iterator i3; 06067 for(i3=(*i2).keys.begin(); i3!=(*i2).keys.end(); i3++) 06068 kch.keys.push_back(*i3); 06069 irc_key_chans.push_back(kch); 06070 } 06071 got=true; // for case that we don't have a channel definition 06072 goto label_a; 06073 } 06074 } 06075 06076 // 348: exceptions 06077 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='8' && str[3]==' ') { 06078 if(irc_check_last_msg("MODE")) 06079 irc_kill_last_msg_wait(resp); 06080 irc_excepted(resp); 06081 } 06082 06083 // 349: end of exceptions 06084 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='9' && str[3]==' ') { 06085 if(irc_check_last_msg("MODE")) 06086 irc_kill_last_msg_wait(resp); 06087 irc_kill_command_wait("MODE"); 06088 irc_end_of_excepted(resp); 06089 } 06090 06091 // 367: ban list 06092 if(len>4 && str[0]=='3' && str[1]=='6' && str[2]=='7' && str[3]==' ') { 06093 irc_banned(resp); 06094 } 06095 06096 // 368: end of +b list 06097 if(len>4 && str[0]=='3' && str[1]=='6' && str[2]=='8' && str[3]==' ') { 06098 if(irc_check_last_msg("MODE")) 06099 irc_kill_last_msg_wait(resp); 06100 irc_kill_command_wait("MODE"); 06101 } 06102 06103 // 346: invited 06104 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='6' && str[3]==' ') { 06105 irc_invited(resp); 06106 } 06107 06108 // 347: end of +I list 06109 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='7' && str[3]==' ') { 06110 if(irc_check_last_msg("MODE")) 06111 irc_kill_last_msg_wait(resp); 06112 irc_kill_command_wait("MODE"); 06113 06114 string s=str; 06115 string channel; 06116 int pos=0; 06117 for(unsigned int i1=0; i1<len; i1++) { 06118 if(str[i1]==0x20) { 06119 pos++; 06120 continue; 06121 } 06122 if(pos==2) 06123 channel+=str[i1]; 06124 if(pos>2) 06125 break; 06126 } 06127 irc_check_for_not_invited(channel); 06128 06129 s_online_channel* chan; 06130 if(irc_get_online_channel(channel,chan)) { 06131 if(!chan->b_excepts_sent && irc_isupport.chanmodes_a.find("e")!=string::npos) { 06132 chan->b_excepts_sent=true; 06133 string excepts="MODE "; 06134 excepts+=channel; 06135 excepts+=" +e"; 06136 irc_putserv(excepts.c_str(),true,HIGH_PRIORITY); 06137 } 06138 } 06139 } 06140 06141 // 344: in reop list +R 06142 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='4' && str[3]==' ') { 06143 irc_in_reop(resp); 06144 } 06145 06146 // 345: end of +R list 06147 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='5' && str[3]==' ') { 06148 if(irc_check_last_msg("MODE")) 06149 irc_kill_last_msg_wait(resp); 06150 irc_kill_command_wait("MODE"); 06151 06152 string s=str; 06153 string channel; 06154 int pos=0; 06155 for(unsigned int i1=0; i1<len; i1++) { 06156 if(str[i1]==0x20) { 06157 pos++; 06158 continue; 06159 } 06160 if(pos==2) 06161 channel+=str[i1]; 06162 if(pos>2) 06163 break; 06164 } 06165 irc_check_for_not_reopped(channel); 06166 } 06167 06168 // :%s 042 %s %s :your unique ID 06169 if(len>4 && str[0]=='0' && str[1]=='4' && str[2]=='2' && str[3]==' ') { 06170 irc_RPL_YOURID(resp); 06171 } 06172 06173 // :%s 043 %s %s :nickname collision, forcing nick change to your unique ID. 06174 if(len>4 && str[0]=='0' && str[1]=='4' && str[2]=='3' && str[3]==' ') { 06175 static bool got=false; 06176 if(!got) { 06177 got=true; 06178 06179 nick=irc_nick; 06180 ident=irc_get_ident(nick); 06181 host=irc_get_host(nick); 06182 msg=irc_unique_id; 06183 logic_fnc(nick,irc_unique_id); 06184 goto forced_nick_change; 06185 } else 06186 got=false; 06187 } 06188 06189 // 482: you are not a channel operator 06190 if(len>4 && str[0]=='4' && str[1]=='8' && str[2]=='2' && str[3]==' ') { 06191 if(irc_check_last_msg("MODE")) 06192 irc_kill_last_msg_wait(resp); 06193 irc_kill_command_wait("MODE"); 06194 06195 if(irc_check_last_msg("KICK")) 06196 irc_kill_last_msg_wait(resp); 06197 irc_kill_command_wait("KICK"); 06198 } 06199 06200 if(last_msg.wait_for_response && last_msg.timestamp+20<time(NULL)) 06201 irc_kill_last_msg_wait(resp); 06202 } 06203 } 06204 06205 l2: 06206 06207 memset(last_msg.response,0,sizeof(last_msg.response)); 06208 strncpy(last_msg.response,*i,sizeof(last_msg.response)-1); 06209 06210 delete[] (*i); 06211 06212 msgs_from_server.pop_front(); 06213 06214 //goto l1; 06215 } 06216 06217 dcc_loop(); 06218 06219 return 0; 06220 }
Here is the call graph for this function: ![]() |
|
This function should be called in a loop to process send and receive to/from server.
Definition at line 633 of file irc.cpp. References s_flood_history::bytes, s_socket::clear(), s_socket::cmp(), cmp_strings_case_insensitive(), conf_getvar(), filesys_last_notify, filesys_notify_interval, flood_history, flood_history_other, s_msg_to_server::flood_protection, HIGH_PRIORITY, irc_bot_flood_bytes, irc_bot_flood_lines, irc_bot_flood_other_seconds, irc_bot_flood_seconds, irc_cannot_join_channels, irc_channels, irc_check_for_filesystem(), irc_disconnect(), irc_keepalive_sent, irc_last_join_try, irc_last_keepalive_detection, IRC_MSG_TOO_LONG, irc_nick, irc_putserv(), irc_putserv_immediately(), irc_remove_redundant_mode2(), log_debug(), log_socket(), logic_exec_from_work(), ltoa(), s_005::max_modes, mode_queue, s_msg_to_server::msg, s_flood_history::msg, msgs_from_server, msgs_to_server, msgs_to_server2, s_msg_to_server::response, sock_close(), sock_error(), sock_read(), SOCK_SEND_ERROR, stats_irc_bytes_received(), s_flood_history::time, s_msg_to_server::timestamp, s_msg_to_server::wait_for_response, and waiting_for_response. Referenced by logic_exec(), and main(). 00634 { 00635 if(!irc_socket.cmp()) 00636 return true; 00637 00638 if(irc_last_keepalive_detection+60*3<time(NULL) && irc_keepalive_sent) { 00639 irc_last_keepalive_detection=time(NULL); 00640 irc_keepalive_sent=false; 00641 irc_disconnect(); 00642 logic_exec_from_work(); 00643 return false; 00644 } 00645 if(irc_last_join_try+15<time(NULL)) { 00646 time(&irc_last_join_try); 00647 vector<string>::iterator i1; 00648 erase_again: 00649 for(i1=irc_cannot_join_channels.begin(); i1!=irc_cannot_join_channels.end(); i1++) { 00650 vector<s_online_channel>::iterator i; 00651 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) 00652 if(!cmp_strings_case_insensitive((*i).name,*i1)) { 00653 irc_cannot_join_channels.erase(i1); 00654 goto erase_again; 00655 } 00656 00657 string msg="JOIN "; 00658 msg+=*i1; 00659 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 00660 msg="MODE "; 00661 msg+=*i1; 00662 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 00663 msg="TOPIC "; 00664 msg+=*i1; 00665 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 00666 msg="WHOIS "; 00667 msg+=irc_nick; 00668 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 00669 } 00670 } 00671 00672 int compress_mode_wait=atol(conf_getvar("compress_mode_wait").c_str()); 00673 if(compress_mode_wait>0) { 00674 time_t now=time(NULL); 00675 list<s_mode_queue_entry> wait_elapsed; 00676 wait_elapsed.clear(); 00677 again: 00678 list<s_mode_queue_entry>::iterator i1; 00679 for(i1=mode_queue.begin(); i1!=mode_queue.end(); i1++) { 00680 if((*i1).submit+compress_mode_wait<now) { 00681 wait_elapsed.push_back(*i1); 00682 mode_queue.erase(i1); 00683 goto again; 00684 } 00685 } 00686 string chan=""; 00687 list<s_mode_queue_entry> single_channel; 00688 single_channel.clear(); 00689 again2: 00690 for(i1=wait_elapsed.begin(); i1!=wait_elapsed.end(); i1++) { 00691 if(chan.empty()) { 00692 chan=(*i1).channel; 00693 single_channel.clear(); 00694 single_channel.push_back(*i1); 00695 wait_elapsed.erase(i1); 00696 goto again2; 00697 } 00698 if(!cmp_strings_case_insensitive((*i1).channel,chan)) { 00699 single_channel.push_back(*i1); 00700 wait_elapsed.erase(i1); 00701 goto again2; 00702 } 00703 } 00704 { 00705 list<s_mode_queue_entry>::iterator i2; 00706 string cumulative1="MODE "; // chars 00707 cumulative1+=chan; 00708 cumulative1+=" "; 00709 string cumulative2=""; // params 00710 int cum_num=0; 00711 again3: 00712 if(cum_num==irc_isupport.max_modes) { 00713 jump_1: 00714 if(cumulative2.length() && cumulative2[cumulative2.length()-1]==0x20) 00715 cumulative2.erase(cumulative2.length()-1,1); 00716 if(!cumulative2.empty()) { 00717 cumulative1+=" "; 00718 cumulative1+=cumulative2; 00719 } 00720 00721 s_msg_to_server m; 00722 00723 size_t end; 00724 m.msg=new char[end=(cumulative1.length()+2+1)]; // +2 == CR/LF 00725 strcpy(m.msg,cumulative1.c_str()); 00726 m.msg[end-2-1+0]=0x0D; 00727 m.msg[end-2-1+1]=0x0A; 00728 m.msg[end-2-1+2]=0; 00729 00730 m.flood_protection=false; 00731 00732 m.wait_for_response=false; 00733 if(m.wait_for_response) 00734 m.response[0]=0; 00735 00736 msgs_to_server.push_back(m); 00737 00738 cumulative1="MODE "; // chars 00739 cumulative1+=chan; 00740 cumulative1+=" "; 00741 cumulative2=""; 00742 00743 cum_num=0; 00744 } 00745 for(i2=single_channel.begin(); i2!=single_channel.end(); i2++) { 00746 if(cum_num<irc_isupport.max_modes) { 00747 cum_num++; 00748 cumulative1+=(*i2).mode; 00749 if(!(*i2).param.empty()) { 00750 cumulative2+=(*i2).param; 00751 cumulative2+=" "; 00752 } 00753 single_channel.erase(i2); 00754 goto again3; 00755 } else 00756 break; 00757 } 00758 if(cum_num>0) 00759 goto jump_1; 00760 } 00761 if(!wait_elapsed.empty()) { 00762 chan=""; 00763 single_channel.clear(); 00764 goto again2; 00765 } 00766 } 00767 00768 irc_remove_redundant_mode2(); 00769 00770 char* buff2=new char[10240]; 00771 int buff2_pos=0; 00772 for(;;) { 00773 char buff[1024]; 00774 int ec=0; 00775 bool closed; 00776 size_t size=sock_read(irc_socket,buff,sizeof(buff),ec,closed); 00777 if(closed) { 00778 if(msgs_from_server.empty()) 00779 return true; 00780 } 00781 00782 if(ec) { 00783 log_socket(ec,sock_error(ec),"while reading from the socket, in file " __FILE__ " in function " __FUNC__); 00784 if(msgs_from_server.empty()) 00785 return true; 00786 } 00787 00788 if(!size) 00789 break; 00790 00791 stats_irc_bytes_received(size); 00792 00793 irc_last_keepalive_detection=time(NULL); 00794 irc_keepalive_sent=false; 00795 00796 for(size_t i1=0; i1<size; i1++) { 00797 if(buff[i1]==0 || buff[i1]=='\r' || buff[i1]=='\n') { 00798 l2: 00799 if((buff2_pos==1 && (buff2[0]==0 || buff2[0]=='\r' || buff2[0]=='\n')) || buff2_pos==0) 00800 buff2_pos=0; 00801 else { 00802 buff2[buff2_pos++]=0; 00803 char* tmp=new char[buff2_pos+16]; 00804 strcpy(tmp,buff2); 00805 msgs_from_server.push_back(tmp); 00806 buff2_pos=0; 00807 } 00808 } else { 00809 if(buff2_pos>=10240-16) { 00810 log_debug("one line from IRC server exceeded about 10 KB, in file " __FILE__ " in function " __FUNC__); 00811 goto l2; 00812 } 00813 buff2[buff2_pos++]=buff[i1]; 00814 } 00815 } 00816 } 00817 delete[] buff2; 00818 buff2=NULL; 00819 00820 if(irc_last_keepalive_detection+30<time(NULL) && !irc_keepalive_sent) { 00821 irc_keepalive_sent=true; 00822 string ping="PING :"; 00823 char tmp[64]; 00824 ltoa((long)time(NULL),tmp,10); 00825 ping+=tmp; 00826 irc_putserv(ping.c_str(),true,HIGH_PRIORITY); 00827 } 00828 00829 //--- 00830 if(last_msg.timestamp+20<time(NULL)) 00831 last_msg.wait_for_response=false; 00832 00833 if(last_msg.wait_for_response && last_msg.response[0]==0) 00834 return false; // still waiting 00835 00836 if(last_msg.msg) { 00837 delete[] last_msg.msg; 00838 last_msg.msg=NULL; 00839 } 00840 //--- 00841 00842 { 00843 vector<s_awaiting_response>::iterator i1; 00844 _again: 00845 for(i1=waiting_for_response.begin(); i1!=waiting_for_response.end(); i1++) { 00846 if((*i1).time+20<time(NULL)) { 00847 string msg="Timeout while waiting for response to command: "; 00848 msg+=(*i1).message; 00849 00850 while(msg.length() && msg[msg.length()-1]=='\r') 00851 msg.erase(msg.length()-1,1); 00852 while(msg.length() && msg[msg.length()-1]=='\n') 00853 msg.erase(msg.length()-1,1); 00854 while(msg.length() && msg[msg.length()-1]=='\r') 00855 msg.erase(msg.length()-1,1); 00856 while(msg.length() && msg[msg.length()-1]=='\n') 00857 msg.erase(msg.length()-1,1); 00858 00859 log_debug(msg.c_str()); 00860 00861 waiting_for_response.erase(i1); 00862 goto _again; 00863 } 00864 } 00865 00866 if(waiting_for_response.begin()!=waiting_for_response.end()) 00867 return false; // still waiting 00868 } 00869 00870 //--- 00871 00872 /*time_t now=time(NULL); 00873 00874 list<s_flood_history>::iterator i; 00875 l1: 00876 for(i=flood_history.begin(); i!=flood_history.end(); i++) { 00877 bool del=false; 00878 if((*i).time>now) // for case of changing system time 00879 del=true; 00880 else 00881 if(((unsigned)now-(*i).time)>irc_bot_flood_seconds) 00882 del=true; 00883 00884 if(del) { 00885 flood_history.erase(i); 00886 goto l1; 00887 } 00888 }*/ 00889 00890 size_t bytes=0; 00891 list<s_flood_history>::iterator i; 00892 for(i=flood_history.begin(); i!=flood_history.end(); i++) 00893 bytes+=(*i).bytes; 00894 00895 size_t all_1=0, all_2=0; 00896 size_t cnt=0; 00897 size_t cnt2=0; 00898 { 00899 list<s_flood_history>::iterator i2; 00900 fl_again1: 00901 for(i2=flood_history.begin(); i2!=flood_history.end(); i2++) { 00902 if((*i2).time+irc_bot_flood_seconds<time(NULL)) { 00903 flood_history.erase(i2); 00904 goto fl_again1; 00905 } 00906 all_1+=(*i2).msg.length(); 00907 cnt++; 00908 } 00909 } 00910 { 00911 list<s_flood_history>::iterator i2; 00912 fl_again2: 00913 for(i2=flood_history_other.begin(); i2!=flood_history_other.end(); i2++) { 00914 if((*i2).time+irc_bot_flood_other_seconds<time(NULL)) { 00915 flood_history_other.erase(i2); 00916 goto fl_again2; 00917 } 00918 all_2+=(*i2).msg.length(); 00919 cnt2++; 00920 } 00921 } 00922 00923 for(;;) { 00924 list<s_msg_to_server>::iterator ii; 00925 00926 int queue_num=1; 00927 00928 ii=msgs_to_server.begin(); 00929 if(ii==msgs_to_server.end()) { 00930 ii=msgs_to_server2.begin(); 00931 if(ii==msgs_to_server2.end()) 00932 break; 00933 queue_num=2; 00934 } 00935 00936 if(((queue_num==1?all_1:all_1+all_2)<irc_bot_flood_bytes && ((queue_num==1)?cnt<irc_bot_flood_lines:cnt2<1)) && (*ii).flood_protection) { 00937 bytes+=strlen((*ii).msg); 00938 00939 bool wait_for_response=(*ii).wait_for_response; 00940 if(wait_for_response) { 00941 last_msg=*ii; 00942 last_msg.timestamp=time(NULL); 00943 } 00944 // no flood should occur 00945 char* msg=(*ii).msg; 00946 int error=irc_putserv_immediately(irc_socket,msg,wait_for_response); 00947 00948 if(error==IRC_MSG_TOO_LONG) { 00949 log_debug("IRC_MSG_TOO_LONG error #1, in file " __FILE__ " in function " __FUNC__); 00950 } 00951 00952 if(error==SOCK_SEND_ERROR) { 00953 msgs_to_server.clear(); 00954 flood_history.clear(); 00955 00956 sock_close(irc_socket); 00957 irc_socket.clear(); 00958 00959 log_socket(0,"(socket closed)","in file " __FILE__ " in function " __FUNC__); 00960 00961 return true; 00962 } 00963 00964 bytes+=strlen(msg); 00965 00966 if((*ii).flood_protection) { 00967 s_flood_history entry; 00968 entry.bytes=strlen(msg); 00969 entry.msg=msg; 00970 time(&entry.time); 00971 flood_history.push_back(entry); 00972 } else { 00973 s_flood_history entry; 00974 entry.bytes=strlen(msg); 00975 entry.msg=msg; 00976 time(&entry.time); 00977 flood_history_other.push_back(entry); 00978 } 00979 if(queue_num==1) 00980 msgs_to_server.pop_front(); 00981 if(queue_num==2) 00982 msgs_to_server2.pop_front(); 00983 00984 if(wait_for_response) 00985 break; 00986 } else { 00987 if(((queue_num==1?all_1:all_1+all_2)<irc_bot_flood_bytes && ((queue_num==1)?cnt<irc_bot_flood_lines:cnt2<1)) && !(*ii).flood_protection) { 00988 00989 bytes+=strlen((*ii).msg); 00990 00991 bool wait_for_response=(*ii).wait_for_response; 00992 if(wait_for_response) { 00993 last_msg=*ii; 00994 last_msg.timestamp=time(NULL); 00995 } 00996 // no flood should occur 00997 char* msg=(*ii).msg; 00998 int error=irc_putserv_immediately(irc_socket,msg,wait_for_response); 00999 01000 if(error==IRC_MSG_TOO_LONG) { 01001 log_debug("IRC_MSG_TOO_LONG error #1, in file " __FILE__ " in function " __FUNC__); 01002 } 01003 01004 if(error==SOCK_SEND_ERROR) { 01005 msgs_to_server.clear(); 01006 flood_history.clear(); 01007 01008 sock_close(irc_socket); 01009 irc_socket.clear(); 01010 01011 log_socket(0,"(socket closed)","in file " __FILE__ " in function " __FUNC__); 01012 01013 return true; 01014 } 01015 01016 bytes+=strlen(msg); 01017 01018 if((*ii).flood_protection) { 01019 s_flood_history entry; 01020 entry.bytes=strlen(msg); 01021 entry.msg=msg; 01022 time(&entry.time); 01023 flood_history.push_back(entry); 01024 } else { 01025 s_flood_history entry; 01026 entry.bytes=strlen(msg); 01027 entry.msg=msg; 01028 time(&entry.time); 01029 flood_history_other.push_back(entry); 01030 } 01031 01032 if(queue_num==1) 01033 msgs_to_server.pop_front(); 01034 if(queue_num==2) 01035 msgs_to_server2.pop_front(); 01036 01037 if(wait_for_response) 01038 break; 01039 } 01040 } 01041 break; 01042 } 01043 01044 // notify for files on the filesystem 01045 if(filesys_notify_interval==0) { 01046 filesys_notify_interval=atol(conf_getvar("notify_interval").c_str())*60; 01047 if(filesys_notify_interval==0) 01048 filesys_notify_interval=5*60; 01049 } 01050 if(filesys_last_notify+filesys_notify_interval<=time(NULL)) { 01051 if(filesys_last_notify==0) { 01052 time(&filesys_last_notify); 01053 filesys_last_notify-=filesys_notify_interval; 01054 filesys_last_notify+=20; 01055 } else { 01056 time(&filesys_last_notify); 01057 vector<s_online_channel>::iterator i1; 01058 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 01059 vector<s_online_user>::iterator i2; 01060 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) 01061 irc_check_for_filesystem((*i2).in_logic_as,(*i1).name,(*i2).nick); 01062 } 01063 } 01064 } 01065 01066 return false; 01067 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-b to channel.
Definition at line 3059 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, log_debug(), logic_find_user(), logic_validate_by_mask(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 03060 { 03061 { 03062 vector<s_online_channel>::iterator i; 03063 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 03064 if(cmp_strings_case_insensitive((*i).name,channel)) 03065 continue; 03066 vector<string>::iterator i1; 03067 again1: 03068 for(i1=(*i).bans.begin(); i1!=(*i).bans.end(); i1++) 03069 if(!mask.compare(*i1)) { 03070 (*i).bans.erase(i1); 03071 goto again1; 03072 } 03073 if(prefix=='+') 03074 (*i).bans.push_back(mask); 03075 break; 03076 } 03077 } 03078 03079 s_online_user source=irc_find_user(nick); 03080 03081 if(!source.nick.compare("")) { 03082 string log; 03083 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #12: unknown nick "; 03084 log+=nick; 03085 log+="!"; 03086 log+=ident; 03087 log+="@"; 03088 log+=host; 03089 log_debug(log.c_str()); 03090 return; 03091 } 03092 03093 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03094 03095 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'b'); 03096 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-e to channel.
Definition at line 3111 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, log_debug(), logic_find_user(), logic_validate_by_mask(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 03112 { 03113 { 03114 vector<s_online_channel>::iterator i; 03115 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 03116 if(cmp_strings_case_insensitive((*i).name,channel)) 03117 continue; 03118 vector<string>::iterator i1; 03119 again1: 03120 for(i1=(*i).excepts.begin(); i1!=(*i).excepts.end(); i1++) 03121 if(!mask.compare(*i1)) { 03122 (*i).excepts.erase(i1); 03123 goto again1; 03124 } 03125 if(prefix=='+') 03126 (*i).excepts.push_back(mask); 03127 break; 03128 } 03129 } 03130 03131 s_online_user source=irc_find_user(nick); 03132 03133 if(!source.nick.compare("")) { 03134 string log; 03135 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #13: unknown nick "; 03136 log+=nick; 03137 log+="!"; 03138 log+=ident; 03139 log+="@"; 03140 log+=host; 03141 log_debug(log.c_str()); 03142 return; 03143 } 03144 03145 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03146 03147 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'e'); 03148 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-k KEY to channel.
Definition at line 2965 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, log_debug(), logic_find_user(), logic_validate_chan_key(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02966 { 02967 { 02968 vector<s_online_channel>::iterator i; 02969 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02970 if(cmp_strings_case_insensitive((*i).name,channel)) 02971 continue; 02972 if(prefix=='+') 02973 (*i).key=key; 02974 else 02975 (*i).key=""; 02976 break; 02977 } 02978 } 02979 02980 s_online_user source=irc_find_user(nick); 02981 02982 if(!source.nick.compare("")) { 02983 string log; 02984 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #10: unknown nick "; 02985 log+=nick; 02986 log+="!"; 02987 log+=ident; 02988 log+="@"; 02989 log+=host; 02990 log_debug(log.c_str()); 02991 return; 02992 } 02993 02994 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02995 02996 logic_validate_chan_key(channel,source_user,source.nick,prefix,key); 02997 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-l NUMBER to channel.
Definition at line 3012 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, log_debug(), logic_find_user(), logic_validate_chan_limit(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 03013 { 03014 { 03015 vector<s_online_channel>::iterator i; 03016 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 03017 if(cmp_strings_case_insensitive((*i).name,channel)) 03018 continue; 03019 if(prefix=='+') 03020 (*i).limit=limit; 03021 else 03022 (*i).limit=""; 03023 break; 03024 } 03025 } 03026 03027 s_online_user source=irc_find_user(nick); 03028 03029 if(!source.nick.compare("")) { 03030 string log; 03031 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #11: unknown nick "; 03032 log+=nick; 03033 log+="!"; 03034 log+=ident; 03035 log+="@"; 03036 log+=host; 03037 log_debug(log.c_str()); 03038 return; 03039 } 03040 03041 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03042 03043 logic_validate_chan_limit(channel,source_user,source.nick,prefix,limit); 03044 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-a,i,m,n,q,p,s,r,t to channel.
Definition at line 2918 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, log_debug(), logic_find_user(), logic_validate_chan_mode(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02919 { 02920 { 02921 vector<s_online_channel>::iterator i; 02922 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02923 if(cmp_strings_case_insensitive((*i).name,channel)) 02924 continue; 02925 while((*i).modes.find(mode,0)!=string::npos) 02926 (*i).modes.erase((*i).modes.find(mode,0),1); 02927 if(prefix=='+') 02928 (*i).modes+=(string)""+mode; 02929 break; 02930 } 02931 } 02932 02933 s_online_user source=irc_find_user(nick); 02934 02935 if(!source.nick.compare("")) { 02936 string log; 02937 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #9: unknown nick "; 02938 log+=nick; 02939 log+="!"; 02940 log+=ident; 02941 log+="@"; 02942 log+=host; 02943 log_debug(log.c_str()); 02944 return; 02945 } 02946 02947 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02948 02949 logic_validate_chan_mode(channel,source_user,source.nick,prefix,mode); 02950 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +O/-O (creator) to user.
Definition at line 2704 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_find_user(), irc_nick, s_online_user::irc_op, irc_user_mode_change(), log_debug(), logic_find_user(), logic_validate(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02705 { 02706 irc_user_mode_change(channel,whom,nick,prefix,'@'); 02707 s_online_user source=irc_find_user(nick); 02708 s_online_user target=irc_find_user(whom); 02709 02710 if(!source.nick.compare("")) { 02711 string log; 02712 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #1: unknown nick "; 02713 log+=nick; 02714 log+="!"; 02715 log+=ident; 02716 log+="@"; 02717 log+=host; 02718 log_debug(log.c_str()); 02719 return; 02720 } 02721 02722 if(!target.nick.compare("")) { 02723 string log; 02724 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #2: unknown nick "; 02725 log+=whom; 02726 log_debug(log.c_str()); 02727 return; 02728 } 02729 02730 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02731 string target_user=logic_find_user(target.nick,target.ident,target.host,target.fullname,target.irc_op); 02732 02733 if(cmp_strings_case_insensitive(whom,irc_nick)) // we have already called it above 02734 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,'O'); 02735 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-I to channel.
Definition at line 3163 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, logic_find_user(), logic_validate_by_mask(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 03164 { 03165 vector<s_online_channel>::iterator i1; 03166 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 03167 if(!cmp_strings_case_insensitive((*i1).name,channel)) { 03168 if(prefix=='+') { 03169 vector<string>::iterator i2; 03170 for(i2=(*i1).invites.begin(); i2!=(*i1).invites.end(); i2++) { 03171 if(!(*i2).compare(mask)) { 03172 // we already got it 03173 return; 03174 } 03175 } 03176 (*i1).invites.push_back(mask); 03177 s_online_user source=irc_find_user(nick); 03178 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03179 03180 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'I'); 03181 } 03182 if(prefix=='-') { 03183 vector<string>::iterator i2; 03184 l1: 03185 for(i2=(*i1).invites.begin(); i2!=(*i1).invites.end(); i2++) { 03186 if(!(*i2).compare(mask)) { 03187 (*i1).invites.erase(i2); 03188 goto l1; 03189 } 03190 } 03191 s_online_user source=irc_find_user(nick); 03192 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03193 03194 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'I'); 03195 } 03196 break; 03197 } 03198 } 03199 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +o/-o (op-erator) to user.
Definition at line 2750 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_check_bans(), irc_check_invites(), irc_find_user(), irc_nick, s_online_user::irc_op, irc_user_mode_change(), log_debug(), logic_find_user(), logic_on_nick_validate(), logic_validate(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02751 { 02752 irc_user_mode_change(channel,whom,nick,prefix,'@'); 02753 02754 if(!nick.compare(irc_nick)) 02755 return; 02756 02757 s_online_user source=irc_find_user(nick); 02758 s_online_user target=irc_find_user(whom); 02759 02760 if(prefix=='+' && !cmp_strings_case_insensitive(nick,irc_nick)) { 02761 vector<s_online_channel>::iterator i1; 02762 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 02763 vector<s_online_user>::iterator i2; 02764 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) 02765 if((*i2).got_whois) { 02766 if((*i2).mode.compare((*i2).old_mode)) 02767 logic_on_nick_validate((*i2).nick,(*i2).ident,(*i2).host,(*i2).fullname,(*i1).name,(*i2).irc_op,(*i2).on_join_called); 02768 (*i2).on_join_called=true; 02769 (*i2).old_mode=(*i2).mode; 02770 } 02771 } 02772 } 02773 02774 if(!source.nick.compare("")) { 02775 string log; 02776 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #3: unknown nick "; 02777 log+=nick; 02778 log+="!"; 02779 log+=ident; 02780 log+="@"; 02781 log+=host; 02782 log_debug(log.c_str()); 02783 return; 02784 } 02785 02786 if(!target.nick.compare("")) { 02787 string log; 02788 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #4: unknown nick "; 02789 log+=whom; 02790 log_debug(log.c_str()); 02791 return; 02792 } 02793 02794 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02795 string target_user=logic_find_user(target.nick,target.ident,target.host,target.fullname,target.irc_op); 02796 02797 if(cmp_strings_case_insensitive(whom,irc_nick)) // we have already called it above 02798 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,'@'); 02799 02800 if(prefix=='+') { 02801 if(!cmp_strings_case_insensitive(target.nick,(string)irc_nick)) { 02802 vector<s_online_channel>::iterator i; 02803 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02804 if((*i).got_excepts) { 02805 irc_check_bans((*i).name); 02806 } 02807 irc_check_invites((*i).name); 02808 } 02809 } 02810 } 02811 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change with other modes to user.
Definition at line 2872 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_find_user(), irc_nick, s_online_user::irc_op, irc_user_mode_change(), log_debug(), logic_find_user(), logic_validate(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02873 { 02874 irc_user_mode_change(channel,whom,nick,prefix,mode); 02875 s_online_user source=irc_find_user(nick); 02876 s_online_user target=irc_find_user(whom); 02877 02878 if(!source.nick.compare("")) { 02879 string log; 02880 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #7: unknown nick "; 02881 log+=nick; 02882 log+="!"; 02883 log+=ident; 02884 log+="@"; 02885 log+=host; 02886 log_debug(log.c_str()); 02887 return; 02888 } 02889 02890 if(!target.nick.compare("")) { 02891 string log; 02892 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #8: unknown nick "; 02893 log+=whom; 02894 log_debug(log.c_str()); 02895 return; 02896 } 02897 02898 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02899 string target_user=logic_find_user(target.nick,target.ident,target.host,target.fullname,target.irc_op); 02900 02901 if(cmp_strings_case_insensitive(whom,irc_nick)) // we have already called it above 02902 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,mode); 02903 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/- other modes with mask (class A) to channel.
Definition at line 3265 of file irc.cpp. Referenced by irc_RPL_MODE().
|
|
Evaluates, and validates (or accidentally calls specific event) MODE change +/-R to channel.
Definition at line 3214 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_channels, irc_find_user(), s_online_user::irc_op, logic_find_user(), logic_validate_by_mask(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 03215 { 03216 vector<s_online_channel>::iterator i1; 03217 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 03218 if(!cmp_strings_case_insensitive((*i1).name,channel)) { 03219 if(prefix=='+') { 03220 vector<string>::iterator i2; 03221 for(i2=(*i1).reops.begin(); i2!=(*i1).reops.end(); i2++) { 03222 if(!(*i2).compare(mask)) { 03223 // we already got it 03224 return; 03225 } 03226 } 03227 (*i1).reops.push_back(mask); 03228 s_online_user source=irc_find_user(nick); 03229 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03230 03231 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'R'); 03232 } 03233 if(prefix=='-') { 03234 vector<string>::iterator i2; 03235 l1: 03236 for(i2=(*i1).reops.begin(); i2!=(*i1).reops.end(); i2++) { 03237 if(!(*i2).compare(mask)) { 03238 (*i1).reops.erase(i2); 03239 goto l1; 03240 } 03241 } 03242 s_online_user source=irc_find_user(nick); 03243 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 03244 03245 logic_validate_by_mask(channel,source_user,nick,mask,prefix,'R'); 03246 } 03247 break; 03248 } 03249 } 03250 }
Here is the call graph for this function: ![]() |
|
Evaluates, and validates (or accidentally calls specific event) MODE change +v/-v (voice) to user.
Definition at line 2826 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_find_user(), irc_nick, s_online_user::irc_op, irc_user_mode_change(), log_debug(), logic_find_user(), logic_validate(), and s_online_user::nick. Referenced by irc_RPL_MODE(). 02827 { 02828 irc_user_mode_change(channel,whom,nick,prefix,'+'); 02829 s_online_user source=irc_find_user(nick); 02830 s_online_user target=irc_find_user(whom); 02831 02832 if(!source.nick.compare("")) { 02833 string log; 02834 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #5: unknown nick "; 02835 log+=nick; 02836 log+="!"; 02837 log+=ident; 02838 log+="@"; 02839 log+=host; 02840 log_debug(log.c_str()); 02841 return; 02842 } 02843 02844 if(!target.nick.compare("")) { 02845 string log; 02846 log="in file " __FILE__ " in function " __FUNC__ " occurred panic #6: unknown nick "; 02847 log+=whom; 02848 log_debug(log.c_str()); 02849 return; 02850 } 02851 02852 string source_user=logic_find_user(source.nick,source.ident,source.host,source.fullname,source.irc_op); 02853 string target_user=logic_find_user(target.nick,target.ident,target.host,target.fullname,target.irc_op); 02854 02855 if(cmp_strings_case_insensitive(whom,irc_nick)) // we have already called it above 02856 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,'+'); 02857 }
Here is the call graph for this function: ![]() |
|
Sends NOTICE to user/channel.
Definition at line 6497 of file irc.cpp. References irc_putserv(). Referenced by logic_exec(). 06498 { 06499 if(strlen(target)>128) 06500 return false; 06501 if(strlen(msg)>512-1) 06502 return false; 06503 06504 char tmp[4096]; 06505 strcpy(tmp,"NOTICE "); 06506 strcat(tmp,target); 06507 strcat(tmp," :"); 06508 strcat(tmp,msg); 06509 06510 return irc_putserv(tmp,false,priority); 06511 }
Here is the call graph for this function: ![]() |
|
Raises on_broadcast event.
Definition at line 4467 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::in_logic_as, irc_channels, and logic_on_broadcast(). Referenced by irc_loop_process_input(). 04468 { 04469 string str=full_host; 04470 04471 string nick; 04472 unsigned int i1; 04473 for(i1=0; i1<str.length(); i1++) 04474 if(str[i1]=='!') 04475 break; 04476 else 04477 nick+=str[i1]; 04478 str.erase(0,i1+1); // erase nick name 04479 04480 string ident; 04481 for(i1=0; i1<str.length(); i1++) 04482 if(str[i1]=='@') 04483 break; 04484 else 04485 ident+=str[i1]; 04486 str.erase(0,i1+1); // erase ident 04487 04488 string host; 04489 for(i1=0; i1<str.length(); i1++) 04490 if(str[i1]==0x20) 04491 break; 04492 else 04493 host+=str[i1]; 04494 str.erase(0,i1+1); // erase host 04495 04496 s_online_user* user=NULL; 04497 04498 bool got_user=false; 04499 vector<s_online_channel>::iterator i2; 04500 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 04501 vector<s_online_user>::iterator i3; 04502 for(i3=(*i2).users.begin(); i3!=(*i2).users.end(); i3++) { 04503 if(!cmp_strings_case_insensitive((*i3).nick,nick) && !cmp_strings_case_insensitive((*i3).ident,ident) && !cmp_strings_case_insensitive((*i3).host,host)) { 04504 user=&(*i3); 04505 got_user=true; 04506 break; 04507 } 04508 } 04509 if(got_user) 04510 break; 04511 } 04512 04513 time_t now; 04514 time(&now); 04515 04516 string username; 04517 if(!got_user) { 04518 // assume unknown user 04519 username=""; 04520 } else { 04521 username=user->in_logic_as; 04522 } 04523 04524 logic_on_broadcast(username,nick,ident,host,bcast_mask,type,msg,server,port); 04525 }
Here is the call graph for this function: ![]() |
|
Raises on_notice event if defined for specific user and channel.
Definition at line 4536 of file irc.cpp. References s_online_channel::b_bans_sent, s_online_channel::b_excepts_sent, s_online_channel::b_invites_sent, cmp_strings_case_insensitive(), s_online_user::in_logic_as, irc_channels, irc_nick, logic_on_notice(), s_online_channel::name, s_online_user::old_mode, unknown_users_on_channels, and s_online_channel::users. Referenced by irc_loop_process_input(). 04537 { 04538 string str=full_host; 04539 04540 string nick; 04541 unsigned int i1; 04542 for(i1=0; i1<str.length(); i1++) 04543 if(str[i1]=='!') 04544 break; 04545 else 04546 nick+=str[i1]; 04547 str.erase(0,i1+1); // erase nick name 04548 04549 if(!cmp_strings_case_insensitive(nick,(string)irc_nick)) // it's me! the bot! 04550 return; 04551 04552 string ident; 04553 for(i1=0; i1<str.length(); i1++) 04554 if(str[i1]=='@') 04555 break; 04556 else 04557 ident+=str[i1]; 04558 str.erase(0,i1+1); // erase ident 04559 04560 string host; 04561 for(i1=0; i1<str.length(); i1++) 04562 if(str[i1]==0x20) 04563 break; 04564 else 04565 host+=str[i1]; 04566 str.erase(0,i1+1); // erase host 04567 04568 s_online_user* user=NULL; 04569 04570 bool got_user=false; 04571 vector<s_online_channel>::iterator i2; 04572 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 04573 vector<s_online_user>::iterator i3; 04574 for(i3=(*i2).users.begin(); i3!=(*i2).users.end(); i3++) { 04575 if(!cmp_strings_case_insensitive((*i3).nick,nick) && !cmp_strings_case_insensitive((*i3).ident,ident) && !cmp_strings_case_insensitive((*i3).host,host)) { 04576 user=&(*i3); 04577 got_user=true; 04578 break; 04579 } 04580 } 04581 if(got_user) 04582 break; 04583 } 04584 04585 time_t now; 04586 time(&now); 04587 04588 string username; 04589 if(!got_user) { 04590 // assume unknown user 04591 username=""; 04592 04593 vector<s_online_channel>::iterator i1; 04594 l3: 04595 bool got_channel=false; 04596 for(i1=unknown_users_on_channels.begin(); i1!=unknown_users_on_channels.end(); i1++) 04597 if(!cmp_strings_case_insensitive((*i1).name,channel)) { 04598 user=&(*(*i1).users.begin()); // just first record only 04599 got_channel=true; 04600 break; 04601 } 04602 if(!got_channel) { 04603 s_online_channel ch; 04604 ch.name=channel; 04605 ch.b_excepts_sent=ch.b_invites_sent=ch.b_bans_sent=false; 04606 s_online_user u; 04607 u.old_mode="INVALID"; 04608 ch.users.push_back(u); 04609 unknown_users_on_channels.push_back(ch); 04610 goto l3; 04611 } 04612 } else { 04613 username=user->in_logic_as; 04614 } 04615 04616 logic_on_notice(channel,username,nick,msg); 04617 }
Here is the call graph for this function: ![]() |
|
Raises on_privmsg event if defined for specific user and channel.
Definition at line 4369 of file irc.cpp. References s_online_channel::b_bans_sent, s_online_channel::b_excepts_sent, s_online_channel::b_invites_sent, cmp_strings_case_insensitive(), s_online_user::in_logic_as, irc_channels, irc_nick, logic_on_privmsg(), logic_on_privmsg_query(), s_online_channel::name, s_online_user::old_mode, unknown_users_on_channels, and s_online_channel::users. Referenced by irc_loop_process_input(). 04370 { 04371 string str=full_host; 04372 04373 string nick; 04374 unsigned int i1; 04375 for(i1=0; i1<str.length(); i1++) 04376 if(str[i1]=='!') 04377 break; 04378 else 04379 nick+=str[i1]; 04380 str.erase(0,i1+1); // erase nick name 04381 04382 if(!cmp_strings_case_insensitive(nick,(string)irc_nick)) // it's me! the bot! 04383 return; 04384 04385 string ident; 04386 for(i1=0; i1<str.length(); i1++) 04387 if(str[i1]=='@') 04388 break; 04389 else 04390 ident+=str[i1]; 04391 str.erase(0,i1+1); // erase ident 04392 04393 string host; 04394 for(i1=0; i1<str.length(); i1++) 04395 if(str[i1]==0x20) 04396 break; 04397 else 04398 host+=str[i1]; 04399 str.erase(0,i1+1); // erase host 04400 04401 s_online_user* user=NULL; 04402 04403 bool got_user=false; 04404 vector<s_online_channel>::iterator i2; 04405 for(i2=irc_channels.begin(); i2!=irc_channels.end(); i2++) { 04406 vector<s_online_user>::iterator i3; 04407 for(i3=(*i2).users.begin(); i3!=(*i2).users.end(); i3++) { 04408 if(!cmp_strings_case_insensitive((*i3).nick,nick) && !cmp_strings_case_insensitive((*i3).ident,ident) && !cmp_strings_case_insensitive((*i3).host,host)) { 04409 user=&(*i3); 04410 got_user=true; 04411 break; 04412 } 04413 } 04414 if(got_user) 04415 break; 04416 } 04417 04418 time_t now; 04419 time(&now); 04420 04421 string username; 04422 if(!got_user) { 04423 // assume unknown user 04424 username=""; 04425 04426 vector<s_online_channel>::iterator i1; 04427 l3: 04428 bool got_channel=false; 04429 for(i1=unknown_users_on_channels.begin(); i1!=unknown_users_on_channels.end(); i1++) 04430 if(!cmp_strings_case_insensitive((*i1).name,channel)) { 04431 user=&(*(*i1).users.begin()); // just first record only 04432 got_channel=true; 04433 break; 04434 } 04435 if(!got_channel) { 04436 s_online_channel ch; 04437 ch.name=channel; 04438 ch.b_excepts_sent=ch.b_invites_sent=ch.b_bans_sent=false; 04439 s_online_user u; 04440 u.old_mode="INVALID"; 04441 ch.users.push_back(u); 04442 unknown_users_on_channels.push_back(ch); 04443 goto l3; 04444 } 04445 } else { 04446 username=user->in_logic_as; 04447 } 04448 04449 if(!channel.empty()) 04450 logic_on_privmsg(channel,username,nick,msg); 04451 else 04452 logic_on_privmsg_query(username,nick,msg); 04453 }
Here is the call graph for this function: ![]() |
|
Sets +o (chan op) status to nick on channel.
Definition at line 6265 of file irc.cpp. References irc_internal_set_mode(), and irc_putserv(). Referenced by irc_RPL_WHOISUSER(), and logic_exec(). 06266 { 06267 if(strlen(channel)>128) 06268 return false; 06269 if(strlen(nick)>128) 06270 return false; 06271 06272 irc_internal_set_mode(channel,nick,'+','@'); 06273 06274 char msg[4096]; 06275 strcpy(msg,"MODE "); 06276 strcat(msg,channel); 06277 strcat(msg," +o "); 06278 strcat(msg,nick); 06279 06280 return irc_putserv(msg,true,priority); 06281 }
Here is the call graph for this function: ![]() |
|
Parses a channel mode.
Definition at line 438 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, and s_005::chanmodes_d. 00439 { 00440 with_param.clear(); 00441 plain=""; 00442 00443 unsigned int i1=0; 00444 unsigned int i2=0; 00445 for(i2=0; i2<modes.length(); i2++) { 00446 if(modes[i2]==0x20) { 00447 i2++; 00448 break; 00449 } 00450 } 00451 00452 for(;;) { 00453 if(i1>=modes.length()) 00454 break; 00455 if(modes[i1]==0x20) 00456 break; 00457 if(modes[i1]=='+') { 00458 i1++; 00459 continue; 00460 } 00461 // however, CLASS A should never occur! 00462 if(irc_isupport.chanmodes_a.find(modes[i1],0)!=string::npos || 00463 irc_isupport.chanmodes_b.find(modes[i1],0)!=string::npos || 00464 irc_isupport.chanmodes_c.find(modes[i1],0)!=string::npos) { 00465 if(i2>=modes.length()) { 00466 i1++; 00467 continue; 00468 } 00469 pair<char,string> p; 00470 p.first=modes[i1]; 00471 p.second=""; 00472 for(; i2<modes.length(); i2++) { 00473 if(modes[i2]==0x20) { 00474 i2++; 00475 break; 00476 } 00477 p.second+=(string)""+modes[i2]; 00478 } 00479 with_param.insert(p); 00480 i1++; 00481 continue; 00482 } 00483 if(irc_isupport.chanmodes_d.find(modes[i1],0)!=string::npos) { 00484 plain+=(string)""+modes[i1]; 00485 i1++; 00486 continue; 00487 } 00488 // there it shouldn't go 00489 i1++; 00490 } 00491 }
|
|
PARTs channel.
Definition at line 6443 of file irc.cpp. References HIGH_PRIORITY, and irc_putserv(). Referenced by dcc_loop(), and logic_exec(). 06444 { 06445 if(strlen(channel)>128) 06446 return false; 06447 if(strlen(reason)>128) 06448 return false; 06449 06450 char msg[4096]; 06451 strcpy(msg,"PART "); 06452 strcat(msg,channel); 06453 if(reason[0]) { 06454 strcat(msg," :"); 06455 strcat(msg,reason); 06456 } 06457 06458 return irc_putserv(msg,false,HIGH_PRIORITY); 06459 }
Here is the call graph for this function: ![]() |
|
Sends PRIVMSG to user/channel.
Definition at line 6471 of file irc.cpp. References irc_putserv(). Referenced by irc_loop_process_input(), irc_RPL_ENDOFWHOIS(), and logic_exec(). 06472 { 06473 if(strlen(target)>128) 06474 return false; 06475 if(strlen(msg)>512-1) 06476 return false; 06477 06478 char tmp[4096]; 06479 strcpy(tmp,"PRIVMSG "); 06480 strcat(tmp,target); 06481 strcat(tmp," :"); 06482 strcat(tmp,msg); 06483 06484 return irc_putserv(tmp,false,priority); 06485 }
Here is the call graph for this function: ![]() |
|
Raw-ly puts message to queue to send to server.
Definition at line 6824 of file irc.cpp. References irc_putserv(). Referenced by dcc_notify(), logic_exec(), and logic_process_script_output(). 06825 { 06826 irc_putserv(data.c_str(),false,priority); 06827 }
Here is the call graph for this function: ![]() |
|
Parses the message (scans for new line character) and sends it to the server.
Definition at line 1078 of file irc.cpp. References irc_putserv(), and LOW_PRIORITY. Referenced by irc_check_for_filesystem(). 01079 { 01080 list<string> cmds; 01081 string m; 01082 unsigned int cnt=0;; 01083 for(unsigned int i1=0; i1<msg.length(); i1++) { 01084 if(msg[i1]=='\\') { 01085 if(!(i1+1<msg.length() && msg[i1+1]=='n')) { 01086 m+=msg[i1]; 01087 cnt++; 01088 } 01089 } else 01090 if(msg[i1]!='\n') { 01091 m+=msg[i1]; 01092 cnt++; 01093 } 01094 if((cnt>256 || i1==msg.length()-1) || (i1+1<msg.length() && msg[i1]=='\\' && msg[i1+1]=='n') || msg[i1]=='\n') { 01095 if((i1+1<msg.length() && msg[i1]=='\\' && msg[i1+1]=='n')) 01096 i1++; 01097 01098 if(!m.empty()) { 01099 string cmd=command; 01100 cmd+=" "; 01101 cmd+=nick; 01102 cmd+=" :"; 01103 01104 // check to avoid bot loops 01105 while(m.find("\x01",0)!=string::npos) 01106 m.erase(m.find("\x01",0),1); 01107 if(m.length()>0 && (m.find(".",0)==0 || m.find("!",0)==0 || m.find("?",0)==0 || m.find("dcc",0)==0 || m.find("getfile",0)==0)) 01108 m=(string)" "+m; 01109 01110 cmd+=m; 01111 01112 cmds.push_back(cmd); 01113 } 01114 m=""; 01115 cnt=0; 01116 } 01117 } 01118 01119 list<string>::iterator i2; 01120 for(i2=cmds.begin(); i2!=cmds.end(); i2++) 01121 irc_putserv((*i2).c_str(),false,LOW_PRIORITY); 01122 }
Here is the call graph for this function: ![]() |
|
Puts message for server to queue to send.
Definition at line 503 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, s_005::chanmodes_d, s_mode_queue_entry::channel, conf_getvar(), CRITICAL_PRIORITY, s_msg_to_server::flood_protection, s_005::get_prefix1(), HIGH_PRIORITY, irc_putserv_immediately(), LOW_PRIORITY, s_mode_queue_entry::mode, mode_queue, s_msg_to_server::msg, msgs_to_server, msgs_to_server2, s_mode_queue_entry::param, s_msg_to_server::response, s_mode_queue_entry::submit, and s_msg_to_server::wait_for_response. Referenced by dcc_send_file(), irc_access_to_partyline(), irc_ban(), irc_chan_mode(), irc_check_bans(), irc_check_invites(), irc_deop(), irc_devoice(), irc_join(), irc_kick(), irc_loop_process_input(), irc_loop_putserv(), irc_notice(), irc_op(), irc_part(), irc_privmsg(), irc_put(), irc_put_multiple_lines(), irc_quoted_callback(), irc_RPL_NAMREPLY(), irc_unban(), irc_voice(), logic_ctcp(), and logic_exec(). 00504 { 00505 if(strlen(msg)+2>512) { /* +2 == CR/LF */ 00506 return false; 00507 } 00508 00509 s_msg_to_server m; 00510 00511 size_t end; 00512 m.msg=new char[end=(strlen(msg)+2+1)]; // +2 == CR/LF 00513 strcpy(m.msg,msg); 00514 m.msg[end-2-1+0]=0x0D; 00515 m.msg[end-2-1+1]=0x0A; 00516 m.msg[end-2-1+2]=0; 00517 00518 int compress_mode_wait=atol(conf_getvar("compress_mode_wait").c_str()); 00519 if(compress_mode_wait>0 && strstr(msg,"MODE")==msg && priority==LOW_PRIORITY) { 00520 string chan; 00521 string mode; 00522 string param; 00523 unsigned int i1; 00524 int context=0; 00525 for(i1=0; i1<strlen(msg); i1++) { 00526 if(msg[i1]==0x20) { 00527 context++; 00528 continue; 00529 } 00530 if(msg[i1]==0x0D || msg[i1]==0x0A) 00531 break; 00532 if(context==1) 00533 chan+=msg[i1]; 00534 if(context==2) 00535 mode+=msg[i1]; 00536 if(context==3) 00537 param+=msg[i1]; 00538 } 00539 if(context<=3 && mode.length()==2 && (mode[0]=='+' || mode[0]=='-')) { 00540 // process only single mode 00541 int process=0; 00542 /*switch(mode[1]) { 00543 case 'o': 00544 case 'O': 00545 //case 'b': 00546 // do not precess bans, they should be put immediatelly 00547 case 'e': 00548 case 'I': 00549 case 'v': 00550 process=1; 00551 break; 00552 case 'k': 00553 case 'l': 00554 process=2; 00555 break; 00556 case 'n': 00557 case 't': 00558 process=3; 00559 break; 00560 default: 00561 process=0; 00562 break; 00563 }*/ 00564 if(irc_isupport.get_prefix1(mode[1])!='0') { 00565 process=1; 00566 } 00567 if(irc_isupport.chanmodes_a.find(mode[1])!=string::npos) { 00568 if(mode[1]=='b') { 00569 // do not precess bans, they should be put immediatelly 00570 process=0; 00571 } else { 00572 process=1; 00573 } 00574 } 00575 if(irc_isupport.chanmodes_b.find(mode[1])!=string::npos || irc_isupport.chanmodes_c.find(mode[1])!=string::npos) { 00576 process=2; 00577 } 00578 if(irc_isupport.chanmodes_d.find(mode[1])!=string::npos) { 00579 process=3; 00580 } 00581 if(process==0) { 00582 // do nothing! 00583 } 00584 if((process==1 || process==2) && !param.empty()) { 00585 // with parameter 00586 s_mode_queue_entry e; 00587 e.channel=chan; 00588 e.mode=mode; 00589 e.param=param; 00590 time(&e.submit); 00591 mode_queue.push_back(e); 00592 return true; 00593 } 00594 if(process==3 && param.empty()) { 00595 // without parameter 00596 s_mode_queue_entry e; 00597 e.channel=chan; 00598 e.mode=mode; 00599 e.param=""; 00600 time(&e.submit); 00601 mode_queue.push_back(e); 00602 return true; 00603 } 00604 } 00605 } 00606 00607 m.flood_protection=strstr(msg,"PRIVMSG")==msg || strstr(msg,"NOTICE")==msg; 00608 00609 m.wait_for_response=wait_for_response; 00610 if(wait_for_response) 00611 m.response[0]=0; 00612 00613 if(priority==HIGH_PRIORITY) 00614 msgs_to_server.push_back(m); 00615 else if(priority==LOW_PRIORITY) 00616 msgs_to_server2.push_back(m); 00617 else if(priority==CRITICAL_PRIORITY) 00618 irc_putserv_immediately(irc_socket,m.msg,wait_for_response); 00619 00620 return true; 00621 }
Here is the call graph for this function: ![]() |
|
Imeddiately sends message to server.
Definition at line 347 of file irc.cpp. References IRC_MSG_TOO_LONG, log_debug(), log_irc(), log_socket(), s_awaiting_response::message, sock_error(), sock_send(), SOCK_SEND_ERROR, stats_irc_bytes_sent(), s_awaiting_response::time, and waiting_for_response. Referenced by irc_loop_process_input(), irc_loop_putserv(), irc_putserv(), and irc_quit(). 00348 { 00349 if(strlen(msg)>512) { 00350 log_debug("in file " __FILE__ " in function " __FUNC__ " occurred error IRC_MSG_TOO_LONG"); 00351 return IRC_MSG_TOO_LONG; 00352 } 00353 00354 // BEGIN: sanity checks 00355 char tmp_msg[1024]; 00356 strcpy(tmp_msg,msg); 00357 for(unsigned int ii=0; ii<strlen(tmp_msg); ii++) { 00358 if(tmp_msg[ii]=='\r' && ii!=strlen(tmp_msg)-2) { 00359 tmp_msg[ii]=0; 00360 string log="Warning: in file " __FILE__ " in function " __FUNC__ ": Message to IRC server contained \\r character, truncated message is: \""; 00361 log+=tmp_msg; 00362 log+="\""; 00363 log_debug(log.c_str()); 00364 strcat(tmp_msg,"\r\n"); 00365 break; 00366 } 00367 if(tmp_msg[ii]=='\n' && ii!=strlen(tmp_msg)-1) { 00368 tmp_msg[ii]=0; 00369 string log="Warning: in file " __FILE__ " in function " __FUNC__ ": Message to IRC server contained \\n character, truncated message is: \""; 00370 log+=tmp_msg; 00371 log+="\""; 00372 log_debug(log.c_str()); 00373 strcat(tmp_msg,"\r\n"); 00374 break; 00375 } 00376 } 00377 if(tmp_msg[strlen(tmp_msg)-2]!='\r' || tmp_msg[strlen(tmp_msg)-1]!='\n') { 00378 while(strlen(tmp_msg) && (tmp_msg[strlen(tmp_msg)-1]=='\r' || tmp_msg[strlen(tmp_msg)-1]=='\n')) 00379 tmp_msg[strlen(tmp_msg)-1]=0; 00380 string log="Warning: in file " __FILE__ " in function " __FUNC__ ": Message to IRC server doesn't end with \\r\\n sequence, correcting to: \""; 00381 log+=tmp_msg; 00382 log+="\""; 00383 log_debug(log.c_str()); 00384 strcat(tmp_msg,"\r\n"); 00385 } 00386 if(!strcmp(tmp_msg,"\r\n")) { 00387 string log="Warning: in file " __FILE__ " in function " __FUNC__ ": Message to IRC server is empty!"; 00388 log_debug(log.c_str()); 00389 return 0; 00390 } 00391 msg=tmp_msg; 00392 // END: sanity checks 00393 00394 if(wait_for_response) { 00395 char tmp[128]; 00396 unsigned int i1; 00397 for(i1=0; i1<64 && msg[i1]!=0 && msg[i1]!=0x20; i1++) 00398 tmp[i1]=msg[i1]; 00399 tmp[i1]=0; 00400 if(strcmp(tmp,"PRIVMSG") && strcmp(tmp,"NOTICE") && strcmp(tmp,"PONG") && strcmp(tmp,"PASS") && strcmp(tmp,"USER")) { 00401 s_awaiting_response r; 00402 r.message=msg; 00403 r.time=time(NULL); 00404 waiting_for_response.push_back(r); 00405 } 00406 } 00407 00408 char tmp[1024]; 00409 strcpy(tmp,msg); 00410 tmp[strlen(tmp)-2]=0; // remove CR/LF 00411 log_irc(false,tmp); 00412 00413 int ec=0; 00414 size_t sent=sock_send(socket,msg,strlen(msg),ec); 00415 stats_irc_bytes_sent(sent); 00416 //irc_last_keepalive_detection=time(NULL); 00417 if(ec) { 00418 log_socket(ec,sock_error(ec),"in file " __FILE__ " in function " __FUNC__); 00419 return ec; 00420 } 00421 if(sent!=strlen(msg)) { 00422 log_socket(0,"(cannot send all buffer)","in file " __FILE__ " in function " __FUNC__); 00423 return SOCK_SEND_ERROR; 00424 } 00425 00426 return 0; 00427 }
Here is the call graph for this function: ![]() |
|
Quits the IRC.
Definition at line 6855 of file irc.cpp. References irc_putserv_immediately(), sock_flush_later(), and sock_send_cache(). Referenced by write_kill_log(). 06856 { 06857 string tmp="QUIT :"; 06858 tmp+=reason; 06859 tmp+=(string)"\r\n"; 06860 irc_putserv_immediately(irc_socket,tmp.c_str(),true); 06861 sock_send_cache(); 06862 sock_flush_later(irc_socket); 06863 //sleep(1000); 06864 }
Here is the call graph for this function: ![]() |
|
Called when 0x01-quoted PRIVMSG has been received to initialise DCC CHAT or DCC SEND connection.
Definition at line 1480 of file dcc.cpp. References s_user::access_to_filesystem, s_user::access_to_partyline, s_dcc_client::as_in_logic, byteReverse(), s_dcc_client::chat, s_socket::clear(), s_dcc_request_whois::clear(), s_socket::cmp(), s_user_to_lag::cnt, conf_getvar(), dcc_awaiting_send, dcc_check_limit(), dcc_clients, dcc_get_num_of_transfers(), dcc_request_whois, s_dcc_client::dcc_send, dcc_to_resume, s_dcc_client::edit_user, s_dcc_client_to_resume::file_name, s_dcc_client_to_resume::file_size, FILESYS_ALREADY_EXISTS, filesys_check_add_file_raw(), filesys_dcc_check_for_resume(), s_dcc_client::filesystem, s_dcc_client::fullname, s_dcc_client::got_passwd, s_dcc_client::got_user_name, HIGH_PRIORITY, s_dcc_client::host, s_dcc_request_whois::host_mask, s_dcc_client::ident, inet_ntop(), inet_pton(), s_dcc_client_to_resume::ip_4, s_dcc_client_to_resume::ip_6, s_dcc_client_to_resume::ip_addr4, s_dcc_client_to_resume::ip_addr6, irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_is_ircop(), irc_putserv(), s_dcc_client::s_dcc_client_send::is_file_server_proto, lang_get_string(), lang_subst(), s_user_to_lag::last_try, log_bot(), log_debug(), log_socket(), logic_find_user(), logic_partyline_get_user(), LOW_PRIORITY, ltoa(), s_dcc_client::new_user, s_dcc_client::nick, s_dcc_client_to_resume::nick, s_dcc_request_whois::nick, s_user_to_lag::notified, s_dcc_client::s_dcc_client_send::original_name, s_dcc_client_to_resume::port, s_dcc_client::resume_pos, s_dcc_client_to_resume::resume_position, s_dcc_client::send, s_dcc_client::send_from_filesystem, s_dcc_client::server_socket, s_dcc_client::s_dcc_client_send::size, sock_connect(), sock_error(), sock_resolve(), sock_resolve6(), s_dcc_client::socket, s_dcc_request_whois::start, s_dcc_client_to_resume::start_time, s_dcc_request_whois::str, s_dcc_client::telnet, s_dcc_client_to_resume::user_name, s_user_to_lag::user_name, users_to_lag, and s_dcc_client_to_resume::using_ipv6. Referenced by irc_loop_process_input(), and irc_RPL_WHOISUSER(). 01481 { 01482 if(strstr(str,"DCC ")==NULL) 01483 return; 01484 01485 string user_name; 01486 { 01487 if(irc_get_host(nick).empty()) { 01488 bool got=false; 01489 vector<s_dcc_request_whois>::iterator i1; 01490 l1: 01491 for(i1=dcc_request_whois.begin(); i1!=dcc_request_whois.end(); i1++) { 01492 if((*i1).start+120<time(NULL)) { 01493 dcc_request_whois.erase(i1); 01494 goto l1; 01495 } 01496 } 01497 for(i1=dcc_request_whois.begin(); i1!=dcc_request_whois.end(); i1++) { 01498 if(!(*i1).nick.compare(nick) && (*i1).got_whois) { 01499 user_name=logic_find_user(nick,(*i1).ident,(*i1).host,(*i1).full_name,(*i1).irc_op); 01500 got=true; 01501 break; 01502 } 01503 } 01504 01505 if(!got) { 01506 s_dcc_request_whois r; 01507 r.clear(); 01508 time(&r.start); 01509 r.str=str; 01510 r.nick=nick; 01511 r.host_mask=host_mask; 01512 dcc_request_whois.push_back(r); 01513 01514 string msg="WHOIS "; 01515 msg+=nick; 01516 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 01517 return; 01518 } 01519 } else 01520 user_name=logic_find_user(nick,irc_get_ident(nick), irc_get_host(nick), irc_get_fullname(nick), irc_is_ircop(nick)); 01521 vector<s_user_to_lag>::iterator i1; 01522 again: 01523 for(i1=users_to_lag.begin(); i1!=users_to_lag.end(); i1++) { 01524 if((*i1).last_try+atol(conf_getvar("ctcp_lag_user_seconds").c_str())<time(NULL)) { 01525 users_to_lag.erase(i1); 01526 goto again; 01527 } 01528 } 01529 bool got=false; 01530 for(i1=users_to_lag.begin(); i1!=users_to_lag.end(); i1++) { 01531 if(!(*i1).user_name.compare(user_name)) { 01532 (*i1).cnt++; 01533 (*i1).last_try=time(NULL); 01534 got=true; 01535 break; 01536 } 01537 } 01538 if(got) { 01539 if((*i1).cnt>atol(conf_getvar("ctcp_lag_user_msgs").c_str())) { 01540 time_t x=(*i1).last_try; 01541 time_t now=time(NULL); 01542 while((signed)x>0 && (*i1).cnt>0 && (signed)now-(signed)x>atol(conf_getvar("ctcp_lag_user_seconds").c_str())) { 01543 x-=atol(conf_getvar("ctcp_lag_user_seconds").c_str()); 01544 (*i1).cnt--; 01545 } 01546 if((*i1).cnt>atol(conf_getvar("ctcp_lag_user_msgs").c_str())) { 01547 if(!(*i1).notified) { 01548 (*i1).notified=true; 01549 string msg="PRIVMSG "; 01550 msg+=nick; 01551 msg+=" :"; 01552 string lang="en"; // TODO: !!! 01553 msg+=lang_get_string(1,lang,446); 01554 irc_putserv(msg.c_str(),false,LOW_PRIORITY); 01555 } 01556 return; 01557 } 01558 if((*i1).cnt==0) { 01559 (*i1).cnt=1; 01560 (*i1).notified=false; 01561 } 01562 } 01563 } else { 01564 s_user_to_lag u; 01565 u.cnt=1; 01566 u.last_try=time(NULL); 01567 u.user_name=user_name; 01568 u.notified=false; 01569 users_to_lag.push_back(u); 01570 } 01571 } 01572 01573 if((strlen(str)>=14 && str[0]=='D' && str[1]=='C' && str[2]=='C' && str[3]==' ' && str[4]=='C' && str[5]=='H' && str[6]=='A' && str[7]=='T' && str[8]==' ' && str[9]=='c' && str[10]=='h' && str[11]=='a' && str[12]=='t' && str[13]==' ') || 01574 (strlen(str)>=9 && str[0]=='D' && str[1]=='C' && str[2]=='C' && str[3]==' ' && str[4]=='S' && str[5]=='E' && str[6]=='N' && str[7]=='D' && str[8]==' ')) { 01575 bool send=str[4]=='S'; 01576 01577 string user_name_as_in_logic=user_name; 01578 01579 { 01580 s_user u; 01581 vector<s_channel> chs; 01582 logic_partyline_get_user(user_name_as_in_logic,u,chs); 01583 if(send && !u.access_to_filesystem) 01584 return; 01585 if(!send && !u.access_to_partyline) 01586 return; 01587 } 01588 01589 string file_name; 01590 01591 int begin_pos=14; 01592 01593 if(send) { 01594 if(dcc_get_num_of_transfers()>=atol(conf_getvar("dcc_max_transfers").c_str())) { 01595 string msg="PRIVMSG "; 01596 msg+=nick; 01597 msg+=" :"; 01598 string lang="en"; // TODO: !!! 01599 msg+=lang_get_string(1,lang,445); 01600 irc_putserv(msg.c_str(),false,LOW_PRIORITY); 01601 return; 01602 } 01603 01604 int i1=9; 01605 for(; str[i1]!=0; i1++) { 01606 if(str[i1]==0x20) 01607 break; 01608 file_name+=str[i1]; 01609 } 01610 if(str[i1]==0x20) 01611 i1++; 01612 begin_pos=i1; 01613 } 01614 01615 string ip_, port_; 01616 int i1=begin_pos; 01617 for(; str[i1]!=0; i1++) { 01618 if(str[i1]==0x20) 01619 break; 01620 ip_+=str[i1]; 01621 } 01622 if(str[i1]!=0) 01623 i1++; 01624 for(; str[i1]!=0; i1++) { 01625 if(str[i1]==0x20) 01626 break; 01627 port_+=str[i1]; 01628 } 01629 01630 if(str[i1]!=0) 01631 i1++; 01632 01633 string size; 01634 01635 if(send) { 01636 while(str[i1]!=0 && str[i1]==0x20) 01637 i1++; 01638 for(; str[i1]!=0; i1++) { 01639 if(str[i1]==0x20) 01640 break; 01641 size+=str[i1]; 01642 } 01643 } 01644 01645 long ip=0; 01646 string ip_addr; 01647 in_addr6_ ip6; 01648 memset(&ip6,0,sizeof(ip6)); 01649 bool got_ipv6=false; 01650 long i_size=atol(size.c_str()); 01651 unsigned short port=(unsigned short)atol(port_.c_str()); 01652 01653 if(ip_.find(":",0)==string::npos && ip_.find(".",0)==string::npos) { 01654 got_ipv6=false; 01655 01656 long ip=atol(ip_.c_str()); 01657 byteReverse((unsigned char*)&ip,1); // for BIG endian machines 01658 unsigned char* i=(unsigned char*)&ip; 01659 char tmp[64]; 01660 01661 ltoa(*i,tmp,10); 01662 ip_addr=(string)"."+tmp; 01663 i++; 01664 01665 ltoa(*i,tmp,10); 01666 ip_addr=(string)"."+tmp+ip_addr; 01667 i++; 01668 01669 ltoa(*i,tmp,10); 01670 ip_addr=(string)"."+tmp+ip_addr; 01671 i++; 01672 01673 ltoa(*i,tmp,10); 01674 ip_addr=(string)tmp+ip_addr; 01675 i++; 01676 } 01677 if(ip_.find(":",0)==string::npos && ip_.find(".",0)!=string::npos) { 01678 got_ipv6=false; 01679 if(inet_pton(AF_INET,ip_.c_str(),&ip)==1) { 01680 ip_addr=ip_; 01681 } else 01682 return; // error 01683 } 01684 if(ip_.find(":",0)!=string::npos) { 01685 got_ipv6=true; 01686 if(inet_pton(AF_INET6,ip_.c_str(),&ip6)==1) { 01687 ip_addr=ip_; 01688 } else 01689 return; // error 01690 } 01691 01692 string dcc_bind_ip=conf_getvar("dcc_bind_ip"); 01693 if(dcc_bind_ip.empty()) 01694 dcc_bind_ip="0.0.0.0"; 01695 string dcc_bind_ip6=conf_getvar("dcc_bind_ip6"); 01696 if(dcc_bind_ip6.empty()) 01697 dcc_bind_ip6="::"; 01698 01699 if(send) { 01700 size_t got_bytes; 01701 bool resume=filesys_dcc_check_for_resume(user_name_as_in_logic,file_name,got_bytes); 01702 if(resume) { 01703 string msg="PRIVMSG "; 01704 msg+=nick; 01705 msg+=" :\x01" "DCC RESUME "; 01706 msg+=file_name; 01707 msg+=" "; 01708 msg+=port_; 01709 msg+=" "; 01710 char tmp[64]; 01711 ltoa((long)got_bytes,tmp,10); 01712 msg+=tmp; 01713 msg+="\x01"; 01714 irc_putserv(msg.c_str(),false,LOW_PRIORITY); 01715 01716 s_dcc_client_to_resume res; 01717 res.file_name=file_name; 01718 res.file_size=i_size; 01719 res.using_ipv6=got_ipv6; 01720 if(!got_ipv6) { 01721 res.ip_addr4=ip_; 01722 res.ip_4=ip; 01723 01724 res.ip_addr6=""; 01725 memset(&res.ip_6,0,sizeof(res.ip_6)); 01726 } else { 01727 res.ip_addr4=""; 01728 res.ip_4=0; 01729 01730 res.ip_addr6=ip_; 01731 res.ip_6=ip6; 01732 } 01733 res.nick=nick; 01734 res.port=port; 01735 res.start_time=time(NULL); 01736 res.resume_position=got_bytes; 01737 res.user_name=user_name_as_in_logic; 01738 01739 dcc_to_resume.push_back(res); 01740 return; 01741 } else { 01742 int ec=filesys_check_add_file_raw(file_name,user_name_as_in_logic); 01743 if(ec==FILESYS_ALREADY_EXISTS) { 01744 string msg="PRIVMSG "; 01745 msg+=nick; 01746 msg+=" :"; 01747 01748 string lang="en"; // TODO: !!! 01749 string m=lang_subst(lang_get_string(1,lang,444),file_name); 01750 01751 msg+=m; 01752 irc_putserv(msg.c_str(),false,LOW_PRIORITY); 01753 return; 01754 } 01755 } 01756 } 01757 01758 { 01759 bool spoofing=false; 01760 in_addr6_ supplied6; 01761 in_addr6_ originator6; 01762 in_addr supplied4; 01763 in_addr originator4; 01764 if(got_ipv6) { 01765 supplied6=sock_resolve6((char*)ip_addr.c_str()); 01766 originator6=sock_resolve6((char*)irc_get_host(nick).c_str()); 01767 unsigned char sum_supplied=0; 01768 unsigned char sum_originator=0; 01769 for(int i1=0; i1<sizeof(supplied6); i1++) { 01770 sum_supplied|=((unsigned char*)&supplied6)[i1]; 01771 sum_originator|=((unsigned char*)&originator6)[i1]; 01772 if(((unsigned char*)&supplied6)[i1]!=((unsigned char*)&originator6)[i1]) { 01773 spoofing=true; 01774 break; 01775 } 01776 } 01777 if(!sum_supplied || !sum_originator) 01778 spoofing=true; // some of addresses are zero 01779 } else { 01780 supplied4=sock_resolve(ip_addr.c_str(),NULL); 01781 originator4=sock_resolve(irc_get_host(nick).c_str(),NULL); 01782 unsigned char sum_supplied=0; 01783 unsigned char sum_originator=0; 01784 for(int i1=0; i1<sizeof(supplied4); i1++) { 01785 sum_supplied|=((unsigned char*)&supplied4)[i1]; 01786 sum_originator|=((unsigned char*)&originator4)[i1]; 01787 if(((unsigned char*)&supplied4)[i1]!=((unsigned char*)&originator4)[i1]) { 01788 spoofing=true; 01789 break; 01790 } 01791 } 01792 if(!sum_supplied || !sum_originator) 01793 spoofing=true; // some of addresses are zero 01794 } 01795 if(spoofing) { 01796 string msg="DCC IP address spoofing from user "; 01797 msg+=host_mask; 01798 msg+=" with supplied IPv"; 01799 msg+=(got_ipv6?"6":"4"); 01800 msg+=" address \""; 01801 msg+=ip_; 01802 msg+="\" translated to "; 01803 char tmp[128+1]; 01804 tmp[0]=tmp[128]=0; 01805 if(got_ipv6) 01806 inet_ntop(AF_INET6,(const void*)&supplied6,tmp,128); 01807 else 01808 inet_ntop(AF_INET,(const void*)&supplied4,tmp,128); 01809 msg+=tmp; 01810 msg+=", but host of sender of CTCP message was decoded/and/or/DNS-translated to IPv"; 01811 msg+=(got_ipv6?"6":"4"); 01812 msg+=" address "; 01813 tmp[0]=tmp[128]=0; 01814 if(got_ipv6) 01815 inet_ntop(AF_INET6,(const void*)&originator6,tmp,128); 01816 else 01817 inet_ntop(AF_INET,(const void*)&originator4,tmp,128); 01818 msg+=tmp; 01819 log_bot(msg.c_str()); 01820 return; 01821 } 01822 } 01823 01824 int ec=0; 01825 s_socket s; 01826 if(!got_ipv6) 01827 s=sock_connect((char*)dcc_bind_ip.c_str(),(char*)ip_addr.c_str(),port,ec,true); 01828 else 01829 s=sock_connect((char*)dcc_bind_ip6.c_str(),(char*)ip_addr.c_str(),port,ec,true); 01830 if(s.cmp()==false || ec) { 01831 log_socket(ec,sock_error(ec),"while calling sock_connect in file " __FILE__ " in function " __FUNC__); 01832 return; 01833 } 01834 01835 s_dcc_client c; 01836 01837 c.nick=nick; 01838 c.ident=irc_get_ident(nick); 01839 c.host=irc_get_host(nick); 01840 c.fullname=irc_get_fullname(nick); 01841 01842 c.resume_pos=0; 01843 01844 c.chat=!send; 01845 c.send=send; 01846 c.send_from_filesystem=false; 01847 c.socket=s; 01848 01849 c.server_socket.clear(); 01850 c.telnet=false; 01851 c.got_passwd=0; 01852 c.new_user=0; 01853 c.edit_user=0; 01854 c.filesystem=0; 01855 c.as_in_logic=user_name_as_in_logic; 01856 c.got_user_name=(c.as_in_logic.empty()?false:true); 01857 01858 if(send) { 01859 c.dcc_send.size=i_size; 01860 c.dcc_send.original_name=file_name; 01861 c.dcc_send.is_file_server_proto=false; 01862 } 01863 01864 dcc_clients.push_back(c); 01865 dcc_check_limit(); 01866 } 01867 01868 if(strlen(str)>=11 && str[0]=='D' && str[1]=='C' && str[2]=='C' && str[3]==' ' && str[4]=='A' && str[5]=='C' && str[6]=='C' && str[7]=='E' && str[8]=='P' && str[9]=='T' && str[10]==' ') { 01869 if(dcc_get_num_of_transfers()>=atol(conf_getvar("dcc_max_transfers").c_str())) { 01870 string msg="PRIVMSG "; 01871 msg+=nick; 01872 msg+=" :"; 01873 string lang="en"; // TODO: !!! 01874 msg+=lang_get_string(1,lang,445); 01875 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 01876 return; 01877 } 01878 01879 string file_name; 01880 01881 int begin_pos=11; 01882 01883 bool send=true; 01884 if(send) { 01885 int i1=11; 01886 for(; str[i1]!=0; i1++) { 01887 if(str[i1]==0x20) 01888 break; 01889 file_name+=str[i1]; 01890 } 01891 if(str[i1]==0x20) 01892 i1++; 01893 begin_pos=i1; 01894 } 01895 01896 string user_name_as_in_logic=user_name; 01897 01898 { 01899 s_user u; 01900 vector<s_channel> chs; 01901 logic_partyline_get_user(user_name_as_in_logic,u,chs); 01902 if(send && !u.access_to_filesystem) 01903 return; 01904 if(!send && !u.access_to_partyline) 01905 return; 01906 } 01907 01908 string port_, position_; 01909 int i1=begin_pos; 01910 for(; str[i1]!=0; i1++) { 01911 if(str[i1]==0x20) 01912 break; 01913 port_+=str[i1]; 01914 } 01915 if(str[i1]!=0) 01916 i1++; 01917 for(; str[i1]!=0; i1++) { 01918 if(str[i1]==0x20) 01919 break; 01920 position_+=str[i1]; 01921 } 01922 01923 if(str[i1]!=0) 01924 i1++; 01925 01926 unsigned short port=(unsigned short)atol(port_.c_str()); 01927 01928 { 01929 bool got=false; 01930 vector<s_dcc_client_to_resume>::iterator i1; 01931 for(i1=dcc_to_resume.begin(); i1!=dcc_to_resume.end(); i1++) 01932 // BEGIN bug in mIRC workaround 01933 //if(!(*i1).file_name.compare(file_name) && (*i1).port==port && !(*i1).nick.compare(nick) && !(*i1).user_name.compare(user_name_as_in_logic)) { 01934 if(!(*i1).nick.compare(nick) && !(*i1).user_name.compare(user_name_as_in_logic)) { 01935 file_name=(*i1).file_name; 01936 port=(*i1).port; 01937 char tmp[64]; 01938 ltoa((long)(*i1).resume_position,tmp,10); 01939 position_=tmp; 01940 // END bug in mIRC workaround 01941 got=true; 01942 break; 01943 } 01944 01945 if(!got) { 01946 // huh! error! 01947 log_debug("in file " __FILE__ " in function " __FUNC__ " occurred panic: cannot find entry for DCC RESUME! huh?!"); 01948 return; 01949 } 01950 01951 s_dcc_client_to_resume res=*i1; 01952 dcc_to_resume.erase(i1); 01953 01954 size_t i_size=res.file_size; 01955 string ip_addr; 01956 if(!res.using_ipv6) 01957 ip_addr=res.ip_addr4; 01958 else 01959 ip_addr=res.ip_addr6; 01960 01961 string dcc_bind_ip=conf_getvar("dcc_bind_ip"); 01962 if(dcc_bind_ip.empty()) 01963 dcc_bind_ip="0.0.0.0"; 01964 string dcc_bind_ip6=conf_getvar("dcc_bind_ip6"); 01965 if(dcc_bind_ip6.empty()) 01966 dcc_bind_ip6="::"; 01967 01968 int ec=0; 01969 s_socket s; 01970 if(!res.using_ipv6) 01971 s=sock_connect((char*)dcc_bind_ip.c_str(),(char*)ip_addr.c_str(),port,ec,true); 01972 else 01973 s=sock_connect((char*)dcc_bind_ip6.c_str(),(char*)ip_addr.c_str(),port,ec,true); 01974 if(s.cmp()==false || ec) { 01975 log_socket(ec,sock_error(ec),"while calling sock_connect in file " __FILE__ " in function " __FUNC__); 01976 return; 01977 } 01978 01979 s_dcc_client c; 01980 01981 c.nick=nick; 01982 c.ident=irc_get_ident(nick); 01983 c.host=irc_get_host(nick); 01984 c.fullname=irc_get_fullname(nick); 01985 01986 c.resume_pos=atol(position_.c_str()); 01987 01988 c.chat=!send; 01989 c.send=send; 01990 c.send_from_filesystem=false; 01991 c.socket=s; 01992 01993 c.server_socket.clear(); 01994 c.telnet=false; 01995 c.got_passwd=0; 01996 c.new_user=0; 01997 c.edit_user=0; 01998 c.filesystem=0; 01999 c.as_in_logic=user_name_as_in_logic; 02000 c.got_user_name=(c.as_in_logic.empty()?false:true); 02001 02002 c.dcc_send.size=i_size; 02003 c.dcc_send.original_name=file_name; 02004 c.dcc_send.is_file_server_proto=false; 02005 02006 dcc_clients.push_back(c); 02007 dcc_check_limit(); 02008 } 02009 } 02010 02011 if((strlen(str)>=11 && str[0]=='D' && str[1]=='C' && str[2]=='C' && str[3]==' ' && str[4]=='R' && str[5]=='E' && str[6]=='S' && str[7]=='U' && str[8]=='M' && str[9]=='E' && str[10]==' ')) { 02012 if(dcc_get_num_of_transfers()>=atol(conf_getvar("dcc_max_transfers").c_str())) { 02013 string msg="PRIVMSG "; 02014 msg+=nick; 02015 msg+=" :"; 02016 string lang="en"; // TODO: !!! 02017 msg+=lang_get_string(1,lang,445); 02018 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 02019 return; 02020 } 02021 02022 //bool send=false; 02023 02024 string file_name; 02025 02026 int begin_pos=11; 02027 02028 string user_name_as_in_logic=user_name; 02029 02030 { 02031 s_user u; 02032 vector<s_channel> chs; 02033 logic_partyline_get_user(user_name_as_in_logic,u,chs); 02034 if(!u.access_to_filesystem) 02035 return; 02036 } 02037 02038 string port_, position_; 02039 int i1=begin_pos; 02040 02041 bool q=str[i1]=='\"'; 02042 for(; str[i1]!=0; i1++) { 02043 if(str[i1]==0x20 && !q) 02044 break; 02045 if(str[i1]=='\"') 02046 q=false; 02047 file_name+=str[i1]; 02048 } 02049 if(file_name.length()>0 && file_name[0]=='\"') 02050 file_name.erase(0,1); 02051 if(file_name.length()>0 && file_name[file_name.length()-1]=='\"') 02052 file_name.erase(file_name.length()-1,1); 02053 02054 if(str[i1]!=0) 02055 i1++; 02056 02057 for(; str[i1]!=0; i1++) { 02058 if(str[i1]==0x20) 02059 break; 02060 port_+=str[i1]; 02061 } 02062 if(str[i1]!=0) 02063 i1++; 02064 for(; str[i1]!=0; i1++) { 02065 if(str[i1]==0x20) 02066 break; 02067 position_+=str[i1]; 02068 } 02069 02070 if(str[i1]!=0) 02071 i1++; 02072 02073 //unsigned short port=(unsigned short)atol(port_.c_str()); 02074 long pos=atol(position_.c_str()); 02075 02076 string msg="PRIVMSG "; 02077 msg+=nick; 02078 msg+=" :\x01" "DCC ACCEPT "; 02079 msg+=(string)"\""+file_name+"\""; 02080 msg+=" "; 02081 msg+=port_; 02082 msg+=" "; 02083 msg+=position_; 02084 msg+="\x01"; 02085 irc_putserv(msg.c_str(),false,HIGH_PRIORITY); 02086 02087 { 02088 vector<s_dcc_send_file>::iterator i1; 02089 for(i1=dcc_awaiting_send.begin(); i1!=dcc_awaiting_send.end(); i1++) { 02090 if(!(*i1).user_name_as_in_logic.compare(user_name_as_in_logic) && !(*i1).public_name.compare(file_name)) { 02091 (*i1).resume_pos=pos; 02092 break; 02093 } 02094 } 02095 } 02096 } 02097 }
Here is the call graph for this function: ![]() |
|
Called from logic.cpp after rehashing. Deletes all online users and so applies new configuration.
Definition at line 6915 of file irc.cpp. References conf_getvar(), irc_bot_flood_bytes, irc_bot_flood_lines, irc_bot_flood_seconds, irc_channels, logic_find_user(), and logic_on_nick_validate(). Referenced by dcc_loop(), and logic_rehash(). 06916 { 06917 irc_bot_flood_bytes=atol(conf_getvar("irc_bot_flood_bytes").c_str()); 06918 irc_bot_flood_seconds=atol(conf_getvar("irc_bot_flood_seconds").c_str()); 06919 irc_bot_flood_lines=atol(conf_getvar("irc_bot_flood_lines").c_str()); 06920 06921 { 06922 vector<s_online_channel>::iterator i1; 06923 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 06924 vector<s_online_user>::iterator i2; 06925 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 06926 if((*i2).got_whois) 06927 (*i2).in_logic_as=logic_find_user((*i2).nick,(*i2).ident,(*i2).host,(*i2).fullname,(*i2).irc_op); 06928 logic_on_nick_validate((*i2).nick,(*i2).ident,(*i2).host,(*i2).fullname,(*i1).name,(*i2).irc_op,true); 06929 } 06930 } 06931 } 06932 }
Here is the call graph for this function: ![]() |
|
If "smart_mode" in conf.txt is non-zero, removes redundant modes from mode_queue.
Definition at line 198 of file irc.cpp. References cmp_strings_case_insensitive(), conf_getvar(), and mode_queue. Referenced by irc_RPL_MODE(). 00199 { 00200 if(atol(conf_getvar("smart_mode").c_str())) { 00201 if(mode.length()!=2) 00202 return; 00203 list<s_mode_queue_entry>::iterator i1; 00204 again: 00205 for(i1=mode_queue.begin(); i1!=mode_queue.end(); i1++) { 00206 if(!cmp_strings_case_insensitive((*i1).channel,channel) && !(*i1).mode.compare(mode) && !cmp_strings_case_insensitive((*i1).param,nick)) { 00207 mode_queue.erase(i1); 00208 goto again; 00209 } 00210 } 00211 } 00212 }
Here is the call graph for this function: ![]() |
|
If "smart_mode" in conf.txt is non-zero, removes redundant modes from mode_queue.
Definition at line 220 of file irc.cpp. References cmp_strings_case_insensitive(), conf_getvar(), mode_queue, and modes_from_server. Referenced by irc_loop_putserv(). 00221 { 00222 if(atol(conf_getvar("smart_mode").c_str())) { 00223 list<s_mode_queue_entry>::iterator i1; 00224 again: 00225 for(i1=mode_queue.begin(); i1!=mode_queue.end(); i1++) { 00226 list<s_mode_queue_entry>::iterator i2=i1; 00227 i2++; 00228 for(; i2!=mode_queue.end(); i2++) { 00229 if(!cmp_strings_case_insensitive((*i1).channel,(*i2).channel) && 00230 !(*i1).mode.compare((*i2).mode) && 00231 !(*i1).param.compare((*i2).param)) { 00232 mode_queue.erase(i2); 00233 goto again; 00234 } 00235 } 00236 } 00237 int compress_mode_wait=atol(conf_getvar("compress_mode_wait").c_str()); 00238 again2: 00239 // there is +5 seconds to wait, to ensure that mode from server will not be removed too soon 00240 for(i1=modes_from_server.begin(); i1!=modes_from_server.end(); i1++) { 00241 if((*i1).submit+compress_mode_wait+5<time(NULL)) { 00242 modes_from_server.erase(i1); 00243 goto again2; 00244 } 00245 } 00246 again3: 00247 for(i1=mode_queue.begin(); i1!=mode_queue.end(); i1++) { 00248 list<s_mode_queue_entry>::iterator i2; 00249 for(i2=modes_from_server.begin(); i2!=modes_from_server.end(); i2++) { 00250 if(!cmp_strings_case_insensitive((*i1).channel,(*i2).channel) && 00251 !(*i1).mode.compare((*i2).mode) && 00252 !(*i1).param.compare((*i2).param)) { 00253 mode_queue.erase(i1); 00254 goto again3; 00255 } 00256 } 00257 } 00258 } 00259 }
Here is the call graph for this function: ![]() |
|
Called after receiving 324 numeric from server (channel modes after MODE #channel), and calls on_key, on_limit functions after parsing the message.
Definition at line 3276 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, s_005::chanmodes_d, cmp_strings_case_insensitive(), s_005::get_prefix1(), irc_channels, log_debug(), logic_validate_chan_key(), logic_validate_chan_limit(), logic_validate_chan_mode(), and r_users. Referenced by irc_loop_process_input(). 03277 { 03278 // 324 my_nick #channel +ntlk 20 channel_key 03279 03280 string log=str; 03281 string old_str=str; 03282 unsigned int i1; 03283 03284 for(i1=0; i1<str.length(); i1++) 03285 if(str[i1]==' ') 03286 break; 03287 str.erase(0,i1+1); // erase 324 03288 03289 for(i1=0; i1<str.length(); i1++) 03290 if(str[i1]==' ') 03291 break; 03292 str.erase(0,i1+1); // erase my nick 03293 03294 string channel; 03295 for(i1=0; i1<str.length(); i1++) 03296 if(str[i1]==0x20) 03297 break; 03298 else 03299 channel+=str[i1]; 03300 str.erase(0,i1+1); // erase #channel 03301 03302 string flags; 03303 for(i1=0; i1<str.length(); i1++) 03304 if(str[i1]==0x20) 03305 break; 03306 else 03307 flags+=str[i1]; 03308 str.erase(0,i1+1); // erase flags 03309 03310 string parameters; 03311 for(i1=0; i1<str.length(); i1++) 03312 parameters+=str[i1]; 03313 03314 multimap<string,string> modes; 03315 03316 char prefix=0; 03317 unsigned int i2=0; 03318 for(i1=0; i1<flags.length(); i1++) { 03319 if(flags[i1]=='+') { 03320 prefix='+'; 03321 continue; 03322 } 03323 if(flags[i1]=='-') { 03324 prefix='-'; 03325 continue; 03326 } 03327 string p; 03328 int type=0; 03329 03330 type=0; 03331 if(irc_isupport.get_prefix1(flags[i1])!='0') 03332 type=1; 03333 if(irc_isupport.chanmodes_d.find(flags[i1])!=string::npos) 03334 type=2; 03335 if(irc_isupport.chanmodes_c.find(flags[i1])!=string::npos) 03336 type=3; 03337 if(irc_isupport.chanmodes_a.find(flags[i1])!=string::npos) 03338 type=4; 03339 if(irc_isupport.chanmodes_b.find(flags[i1])!=string::npos) 03340 type=5; 03341 03342 if(type==1 || type==4) { 03343 for(; i2<parameters.length(); i2++) { 03344 if(parameters[i2]==0x20) { 03345 i2++; 03346 break; 03347 } 03348 p+=parameters[i2]; 03349 } 03350 } 03351 if(type==3 && prefix=='+') { 03352 for(; i2<parameters.length(); i2++) { 03353 if(parameters[i2]==0x20) { 03354 i2++; 03355 break; 03356 } 03357 p+=parameters[i2]; 03358 } 03359 } 03360 if(type==5) { 03361 for(; i2<parameters.length(); i2++) { 03362 if(parameters[i2]==0x20) { 03363 i2++; 03364 break; 03365 } 03366 p+=parameters[i2]; 03367 } 03368 } 03369 if(type==2) 03370 p=""; 03371 if(type==0) { 03372 p=""; 03373 log="in file " __FILE__ " in function " __FUNC__ " occurred panic: unknown mode "; 03374 log+=prefix; 03375 log+=flags[i1]; 03376 log+=" = string: "; 03377 log+=old_str; 03378 log_debug(log.c_str()); 03379 } 03380 03381 pair<string,string> pr; 03382 pr.first=prefix; 03383 pr.first+=flags[i1]; 03384 pr.second=p; 03385 modes.insert(pr); 03386 } 03387 03388 multimap<string,string>::iterator im; 03389 for(im=modes.begin(); im!=modes.end(); im++) { 03390 char prefix=(*im).first[0]; 03391 char mode=(*im).first[1]; 03392 string param=(*im).second; 03393 03394 char class_='0'; 03395 if(irc_isupport.chanmodes_a.find(mode)!=string::npos) 03396 class_='A'; 03397 if(irc_isupport.chanmodes_b.find(mode)!=string::npos) 03398 class_='B'; 03399 if(irc_isupport.chanmodes_c.find(mode)!=string::npos) 03400 class_='C'; 03401 if(irc_isupport.chanmodes_d.find(mode)!=string::npos) 03402 class_='D'; 03403 if(irc_isupport.get_prefix1(mode)!='0') 03404 class_='x'; 03405 03406 string unknown=""; // name of host_unknown user 03407 { 03408 vector<s_user>::iterator i1; 03409 for(i1=r_users.begin(); i1!=r_users.end(); i1++) { 03410 if((*i1).host_unknown) { 03411 unknown=(*i1).name; 03412 break; 03413 } 03414 } 03415 } 03416 03417 bool got=false; 03418 03419 vector<s_online_channel>::iterator ii; 03420 for(ii=irc_channels.begin(); ii!=irc_channels.end(); ii++) 03421 if(!cmp_strings_case_insensitive(channel,(*ii).name)) 03422 break; 03423 if(ii==irc_channels.end()) 03424 continue; 03425 03426 if(!got && irc_isupport.chanmodes_d.find(mode)!=string::npos) { 03427 got=true; 03428 // these modes were handled elsewhere 03429 logic_validate_chan_mode(channel,unknown,"",prefix,mode); 03430 } 03431 if(!got && mode=='k' && irc_isupport.chanmodes_b.find(mode)!=string::npos) { 03432 got=true; 03433 (*ii).key=param; 03434 logic_validate_chan_key(channel,unknown,"",prefix,param); 03435 } 03436 if(!got && mode=='l' && irc_isupport.chanmodes_c.find(mode)!=string::npos) { 03437 got=true; 03438 (*ii).limit=param; 03439 logic_validate_chan_limit(channel,unknown,"",prefix,param); 03440 } 03441 if(!got) { 03442 log="in file " __FILE__ " in function " __FUNC__ " occurred panic: unsupported mode "; 03443 log+=prefix; 03444 log+=mode; 03445 log+=" "; 03446 log+=param; 03447 log+=" = string: "; 03448 log+=str; 03449 log_debug(log.c_str()); 03450 } 03451 } 03452 }
Here is the call graph for this function: ![]() |
|
This must be called as RPL_ENDOFWHOIS reply from server - the end of WHOIS list for user.
Definition at line 2090 of file irc.cpp. References s_dcc_awaiting_user::addr4, s_dcc_awaiting_user::addr6, cmp_strings_case_insensitive(), dcc_awaiting_users, dcc_get_string(), s_dcc_awaiting_user::fullname, s_dcc_awaiting_user::host, s_dcc_awaiting_user::ident, inet_pton(), irc_access_to_partyline(), irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_privmsg(), logic_get_dcc_host(), LOW_PRIORITY, s_dcc_awaiting_user::nick, sock_resolve(), s_dcc_awaiting_user::start_time, tmp_users, s_dcc_awaiting_user::user_name_as_in_logic, and s_dcc_awaiting_user::using_ipv6. Referenced by irc_loop_process_input(). 02091 { 02092 unsigned int i1; 02093 02094 for(i1=0; i1<str.length(); i1++) 02095 if(str[i1]==0x20) 02096 break; 02097 str.erase(0,i1+1); // erase numeric reply 02098 02099 for(i1=0; i1<str.length(); i1++) 02100 if(str[i1]==0x20) 02101 break; 02102 str.erase(0,i1+1); // erase my nick 02103 02104 string nick; 02105 for(i1=0; i1<str.length(); i1++) 02106 if(str[i1]==0x20) 02107 break; 02108 else 02109 nick+=str[i1]; 02110 str.erase(0,i1+1); // erase nick name 02111 02112 vector<s_online_user>::iterator ii; 02113 for(ii=tmp_users.begin(); ii!=tmp_users.end(); ii++) { 02114 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 02115 string hm=(*ii).nick; 02116 hm+="!"; 02117 hm+=(*ii).ident; 02118 hm+="@"; 02119 hm+=(*ii).host; 02120 string user_name_as_in_logic; 02121 if(irc_access_to_partyline(hm.c_str(),user_name_as_in_logic,(*ii).dcc_msg)) { 02122 int dcc_group=0; 02123 string dcc=dcc_get_string((*ii).dcc_msg,dcc_group); 02124 string dcc_host=logic_get_dcc_host(dcc_group,user_name_as_in_logic); 02125 if(dcc.compare("")) { 02126 string str="\x01"; 02127 str+=dcc; 02128 str+="\x01"; 02129 irc_privmsg(nick.c_str(),str.c_str(),LOW_PRIORITY); 02130 s_dcc_awaiting_user user; 02131 02132 user.nick=nick; 02133 user.ident=irc_get_ident(nick); 02134 user.host=irc_get_host(nick); 02135 user.fullname=irc_get_fullname(nick); 02136 02137 size_t n=user_name_as_in_logic.length(); 02138 if(n>128-1) 02139 n=128-1; 02140 strncpy(user.user_name_as_in_logic,user_name_as_in_logic.c_str(),n); 02141 user.user_name_as_in_logic[n]=0; 02142 in_addr6_ ip6; 02143 if(inet_pton(AF_INET6,dcc_host.c_str(),&ip6)!=1) { 02144 user.addr4=sock_resolve(dcc_host.c_str(),NULL); 02145 user.using_ipv6=false; 02146 } else { 02147 memcpy(&user.addr6,&ip6,sizeof(user.addr6)); 02148 #ifdef _WIN32 02149 user.addr4.S_un.S_addr=(unsigned long)-1; 02150 #else 02151 user.addr4.s_addr=(unsigned long)-1; 02152 #endif 02153 user.using_ipv6=true; 02154 } 02155 time(&user.start_time); 02156 dcc_awaiting_users.push_back(user); 02157 } 02158 } 02159 tmp_users.erase(ii); 02160 break; 02161 } 02162 } 02163 }
Here is the call graph for this function: ![]() |
|
Parses and evaluates RPL_ISUPPORT reply (005 numerics).
Definition at line 1347 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, s_005::chanmodes_d, s_005::max_modes, s_005::prefix, and s_005::raw. Referenced by irc_loop_process_input(). 01348 { 01349 // BotNick RFC2812 PREFIX=(ov)@+ CHANTYPES=#&!+ MODES=3 CHANLIMIT=#&!+:31 NICKLEN=9 TOPICLEN=160 KICKLEN=160 MAXLIST=beIR:42 CHANNELLEN=50 IDCHAN=!:5 CHANMODES=beIR,k,l,imnpstaqr :are supported by this server 01350 01351 unsigned int i1; 01352 01353 for(i1=0; i1<str.length(); i1++) 01354 if(str[i1]==0x20) 01355 break; 01356 str.erase(0,i1+1); // erase my nick 01357 01358 string feature1, feature2; 01359 while(str.length()>0) { 01360 feature1=""; 01361 feature2=""; 01362 int context=0; 01363 while(str.length()>0) { 01364 if(str[0]!=0x20) { 01365 if(str[0]=='=' && context==0) { 01366 context++; 01367 str.erase(0,1); 01368 continue; 01369 } 01370 if(context==0) 01371 feature1+=str[0]; 01372 else 01373 feature2+=str[0]; 01374 } else { 01375 str.erase(0,1); 01376 break; 01377 } 01378 str.erase(0,1); 01379 } 01380 if(feature1.length()>0 && feature1[0]==':') { 01381 // end of list - comment found 01382 break; 01383 } 01384 pair<string,string> p; 01385 p.first=feature1; 01386 p.second=feature2; 01387 irc_isupport.raw.insert(p); 01388 if(!feature1.compare("CHANMODES")) { 01389 int context=0; 01390 string str=feature2; 01391 while(str.length()>0) { 01392 if(str[0]==',') { 01393 context++; 01394 str.erase(0,1); 01395 continue; 01396 } 01397 if(context==0) 01398 irc_isupport.chanmodes_a+=str[0]; 01399 if(context==1) 01400 irc_isupport.chanmodes_b+=str[0]; 01401 if(context==2) 01402 irc_isupport.chanmodes_c+=str[0]; 01403 if(context==3) 01404 irc_isupport.chanmodes_d+=str[0]; 01405 str.erase(0,1); 01406 } 01407 } 01408 if(!feature1.compare("PREFIX")) { 01409 int context=0; 01410 string str=feature2; 01411 string first, second; 01412 while(str.length()>0) { 01413 if(str[0]=='(') { 01414 str.erase(0,1); 01415 continue; 01416 } 01417 if(str[0]==')') { 01418 context++; 01419 str.erase(0,1); 01420 continue; 01421 } 01422 if(context==0) 01423 first+=str[0]; 01424 if(context==1) 01425 second+=str[0]; 01426 str.erase(0,1); 01427 } 01428 for(unsigned int i1=0; i1<first.length() && i1<second.length(); i1++) { 01429 pair<char,char> p; 01430 p.first=first[i1]; 01431 p.second=second[i1]; 01432 irc_isupport.prefix.insert(p); 01433 } 01434 } 01435 if(!feature1.compare("MODES")) { 01436 long modes=atol(feature2.c_str()); 01437 if(modes==0) 01438 modes=3; 01439 irc_isupport.max_modes=modes; 01440 } 01441 } 01442 }
|
|
Called after receiving RPL_MODE from server (someone has changed MODE for channel), and calls irc_mode_change_XXX functions after parsing the message.
Definition at line 3461 of file irc.cpp. References s_005::chanmodes_a, s_005::chanmodes_b, s_005::chanmodes_c, s_005::chanmodes_d, s_mode_queue_entry::channel, cmp_strings_case_insensitive(), s_005::get_prefix1(), irc_mode_change_ban(), irc_mode_change_ban_exception(), irc_mode_change_chan_key(), irc_mode_change_chan_limit(), irc_mode_change_chan_status(), irc_mode_change_creator(), irc_mode_change_invitation(), irc_mode_change_op(), irc_mode_change_other(), irc_mode_change_other_mask(), irc_mode_change_reop(), irc_mode_change_voice(), irc_nick, irc_remove_redundant_mode(), log_debug(), s_mode_queue_entry::mode, modes_from_server, s_mode_queue_entry::param, and s_mode_queue_entry::submit. Referenced by irc_loop_process_input(). 03462 { 03463 string log=str; 03464 string old_str=str; 03465 unsigned int i1; 03466 03467 for(i1=0; i1<str.length(); i1++) 03468 if(str[i1]==':') 03469 break; 03470 str.erase(0,i1+1); // erase everything before ':' 03471 03472 string nick; 03473 for(i1=0; i1<str.length(); i1++) 03474 if(str[i1]=='!' || str[i1]==0x20) 03475 break; 03476 else 03477 nick+=str[i1]; 03478 bool by_server=str[i1]==0x20; 03479 str.erase(0,i1+1); // erase nick name 03480 03481 string ident; 03482 string host; 03483 if(!by_server) { 03484 for(i1=0; i1<str.length(); i1++) 03485 if(str[i1]=='@') 03486 break; 03487 else 03488 ident+=str[i1]; 03489 str.erase(0,i1+1); // erase ident 03490 03491 for(i1=0; i1<str.length(); i1++) 03492 if(str[i1]==0x20) 03493 break; 03494 else 03495 host+=str[i1]; 03496 str.erase(0,i1+1); // erase host name 03497 } 03498 03499 for(i1=0; i1<str.length(); i1++) 03500 if(str[i1]==0x20) 03501 break; 03502 str.erase(0,i1+1); // erase "MODE" 03503 03504 string target; 03505 for(i1=0; i1<str.length(); i1++) 03506 if(str[i1]==0x20) 03507 break; 03508 else 03509 target+=str[i1]; 03510 str.erase(0,i1+1); // erase target 03511 03512 if(!cmp_strings_case_insensitive(target,irc_nick)) { 03513 // it is user MODE for me 03514 return; 03515 } 03516 03517 string flags; 03518 for(i1=0; i1<str.length(); i1++) 03519 if(str[i1]==0x20) 03520 break; 03521 else 03522 flags+=str[i1]; 03523 str.erase(0,i1+1); // erase flags 03524 03525 string parameters; 03526 for(i1=0; i1<str.length(); i1++) 03527 parameters+=str[i1]; 03528 03529 multimap<string,string> modes; 03530 03531 char prefix=0; 03532 unsigned int i2=0; 03533 for(i1=0; i1<flags.length(); i1++) { 03534 if(flags[i1]=='+') { 03535 prefix='+'; 03536 continue; 03537 } 03538 if(flags[i1]=='-') { 03539 prefix='-'; 03540 continue; 03541 } 03542 string p; 03543 int type=0; 03544 /*switch(flags[i1]) { 03545 case 'O': // user status: channel creator 03546 case 'o': // user status: channel operator 03547 case 'v': // user status: voice 03548 case 'q': // user status: ~ 03549 case 'a': // user status: & 03550 case 'h': // user status: % 03551 type=1; 03552 break; 03553 03554 //case 'a': // channel status: anonymous 03555 case 'i': // channel status: invite-only 03556 case 'm': // channel status: moderated 03557 case 'n': // channel status: no external messages 03558 //case 'q': // channel status: quiet 03559 case 'p': // channel status: private 03560 case 's': // channel status: secret 03561 case 'r': // channel status: server reop 03562 case 't': // channel status: topic settable by channel operator 03563 type=2; 03564 break; 03565 03566 case 'k': // channel property: channel key 03567 type=5; 03568 break; 03569 case 'l': // channel property: user limit 03570 type=3; 03571 break; 03572 03573 case 'b': // channel: ban mask 03574 case 'e': // channel: exception mask to override ban mask 03575 case 'I': // channel: invitation mask to override +i flag 03576 case 'R': // channel: reop mask +/-R 03577 type=4; 03578 break; 03579 03580 default: 03581 type=0; 03582 str=log; 03583 log="in file " __FILE__ " in function " __FUNC__ " occurred panic: unknown mode "; 03584 log+=prefix; 03585 log+=flags[i1]; 03586 log+=" = string: "; 03587 log+=str; 03588 log_debug(log.c_str()); 03589 break; 03590 }*/ 03591 type=0; 03592 if(irc_isupport.get_prefix1(flags[i1])!='0') 03593 type=1; 03594 if(irc_isupport.chanmodes_d.find(flags[i1])!=string::npos) 03595 type=2; 03596 if(irc_isupport.chanmodes_c.find(flags[i1])!=string::npos) 03597 type=3; 03598 if(irc_isupport.chanmodes_a.find(flags[i1])!=string::npos) 03599 type=4; 03600 if(irc_isupport.chanmodes_b.find(flags[i1])!=string::npos) 03601 type=5; 03602 03603 if(type==1 || type==4) { 03604 for(; i2<parameters.length(); i2++) { 03605 if(parameters[i2]==0x20) { 03606 i2++; 03607 break; 03608 } 03609 p+=parameters[i2]; 03610 } 03611 } 03612 if(type==3 && prefix=='+') { 03613 for(; i2<parameters.length(); i2++) { 03614 if(parameters[i2]==0x20) { 03615 i2++; 03616 break; 03617 } 03618 p+=parameters[i2]; 03619 } 03620 } 03621 if(type==5) { 03622 for(; i2<parameters.length(); i2++) { 03623 if(parameters[i2]==0x20) { 03624 i2++; 03625 break; 03626 } 03627 p+=parameters[i2]; 03628 } 03629 } 03630 if(type==2) 03631 p=""; 03632 if(type==0) { 03633 p=""; 03634 log="in file " __FILE__ " in function " __FUNC__ " occurred panic: unknown mode "; 03635 log+=prefix; 03636 log+=flags[i1]; 03637 log+=" = string: "; 03638 log+=old_str; 03639 log_debug(log.c_str()); 03640 } 03641 03642 pair<string,string> pr; 03643 pr.first=prefix; 03644 pr.first+=flags[i1]; 03645 pr.second=p; 03646 modes.insert(pr); 03647 } 03648 03649 multimap<string,string>::iterator im; 03650 for(im=modes.begin(); im!=modes.end(); im++) { 03651 char prefix=(*im).first[0]; 03652 char mode=(*im).first[1]; 03653 bool got=false; 03654 string param=(*im).second; 03655 03656 char class_='0'; 03657 if(irc_isupport.chanmodes_a.find(mode)!=string::npos) 03658 class_='A'; 03659 if(irc_isupport.chanmodes_b.find(mode)!=string::npos) 03660 class_='B'; 03661 if(irc_isupport.chanmodes_c.find(mode)!=string::npos) 03662 class_='C'; 03663 if(irc_isupport.chanmodes_d.find(mode)!=string::npos) 03664 class_='D'; 03665 if(irc_isupport.get_prefix1(mode)!='0') 03666 class_='x'; 03667 03668 if(!got && mode=='O' && irc_isupport.get_prefix1(mode)!='0') { 03669 // +-O - channel creator 03670 got=true; 03671 irc_remove_redundant_mode(target,param,(string)""+prefix+mode); 03672 irc_mode_change_creator(target,prefix,nick,ident,host,param); 03673 if(ident.empty() && host.empty()) { 03674 s_mode_queue_entry e; 03675 e.channel=target; 03676 e.mode=(string)""+prefix+mode; 03677 e.param=param; 03678 e.submit=time(NULL); 03679 modes_from_server.push_back(e); 03680 } 03681 } 03682 if(!got && mode=='o' && irc_isupport.get_prefix1(mode)!='0') { 03683 got=true; 03684 // +-o - channel operator 03685 irc_remove_redundant_mode(target,param,(string)""+prefix+mode); 03686 irc_mode_change_op(target,prefix,nick,ident,host,param); 03687 if(ident.empty() && host.empty()) { 03688 s_mode_queue_entry e; 03689 e.channel=target; 03690 e.mode=(string)""+prefix+mode; 03691 e.param=param; 03692 e.submit=time(NULL); 03693 modes_from_server.push_back(e); 03694 } 03695 } 03696 if(!got && mode=='v' && irc_isupport.get_prefix1(mode)!='0') { 03697 got=true; 03698 // +-v - channel voice 03699 irc_remove_redundant_mode(target,param,(string)""+prefix+mode); 03700 irc_mode_change_voice(target,prefix,nick,ident,host,param); 03701 if(ident.empty() && host.empty()) { 03702 s_mode_queue_entry e; 03703 e.channel=target; 03704 e.mode=(string)""+prefix+mode; 03705 e.param=param; 03706 e.submit=time(NULL); 03707 modes_from_server.push_back(e); 03708 } 03709 } 03710 if(!got && irc_isupport.get_prefix1(mode)!='0') { 03711 got=true; 03712 irc_remove_redundant_mode(target,param,(string)""+prefix+mode); 03713 irc_mode_change_other(target,prefix,irc_isupport.get_prefix1(mode),nick,ident,host,param); 03714 if(ident.empty() && host.empty()) { 03715 s_mode_queue_entry e; 03716 e.channel=target; 03717 e.mode=(string)""+prefix+mode; 03718 e.param=param; 03719 e.submit=time(NULL); 03720 modes_from_server.push_back(e); 03721 } 03722 } 03723 if(!got && irc_isupport.chanmodes_d.find(mode)!=string::npos) { 03724 got=true; 03725 irc_mode_change_chan_status(target,prefix,mode,nick,ident,host); 03726 } 03727 if(!got && mode=='k' && irc_isupport.chanmodes_b.find(mode)!=string::npos) { 03728 got=true; 03729 irc_mode_change_chan_key(target,prefix,nick,ident,host,param); 03730 } 03731 if(!got && mode=='l' && irc_isupport.chanmodes_c.find(mode)!=string::npos) { 03732 got=true; 03733 irc_mode_change_chan_limit(target,prefix,nick,ident,host,param); 03734 } 03735 if(!got && mode=='b' && irc_isupport.chanmodes_a.find(mode)!=string::npos) { 03736 got=true; 03737 irc_mode_change_ban(target,prefix,nick,ident,host,param); 03738 } 03739 if(!got && mode=='e' && irc_isupport.chanmodes_a.find(mode)!=string::npos) { 03740 got=true; 03741 irc_mode_change_ban_exception(target,prefix,nick,ident,host,param); 03742 } 03743 if(!got && mode=='I' && irc_isupport.chanmodes_a.find(mode)!=string::npos) { 03744 got=true; 03745 irc_mode_change_invitation(target,prefix,nick,ident,host,param); 03746 } 03747 if(!got && mode=='R' && irc_isupport.chanmodes_a.find(mode)!=string::npos) { 03748 got=true; 03749 irc_mode_change_reop(target,prefix,nick,ident,host,param); 03750 } 03751 if(!got && irc_isupport.chanmodes_a.find(mode)!=string::npos) { 03752 got=true; 03753 irc_mode_change_other_mask(target,prefix,nick,ident,host,param); 03754 } 03755 if(!got) { 03756 log="in file " __FILE__ " in function " __FUNC__ " occurred panic: unsupported mode "; 03757 log+=prefix; 03758 log+=mode; 03759 log+=" "; 03760 log+=param; 03761 log+=" = string: "; 03762 log+=str; 03763 log_debug(log.c_str()); 03764 } 03765 } 03766 }
Here is the call graph for this function: ![]() |
|
Parses and evaluates RPL_NAMREPLY reply (reply to NAME command).
Definition at line 1451 of file irc.cpp. References s_online_channel::b_bans_sent, s_online_channel::b_excepts_sent, s_online_channel::b_invites_sent, s_online_channel::b_reops_sent, s_online_channel::bans, s_005::chanmodes_a, cmp_strings_case_insensitive(), s_online_channel::excepts, s_online_user::fullname, s_005::get_prefix2(), s_online_user::got_mode, s_online_user::got_whois, HIGH_PRIORITY, s_online_user::host, s_online_user::ident, irc_channels, irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_get_online_channel(), irc_is_ircop(), irc_nick, s_online_user::irc_op, irc_putserv(), s_online_user::just_joined, logic_find_user(), logic_validate(), s_online_user::mode, s_online_channel::modes, s_online_channel::name, s_online_user::nick, s_online_user::old_mode, s_online_user::on_join_called, s_online_channel::reops, s_online_channel::topic, s_online_channel::users, and s_online_user::whois_sent. Referenced by irc_loop_process_input(). 01452 { 01453 unsigned int i1; 01454 01455 for(i1=0; i1<str.length(); i1++) 01456 if(str[i1]==0x20) 01457 break; 01458 str.erase(0,i1+1); // erase numeric reply 01459 01460 for(i1=0; i1<str.length(); i1++) 01461 if(str[i1]==0x20) 01462 break; 01463 str.erase(0,i1+1); // erase my nick 01464 01465 for(i1=0; i1<str.length(); i1++) 01466 if(str[i1]==0x20) 01467 break; 01468 str.erase(0,i1+1); // erase '=' / '*' / '@' 01469 01470 string channame; 01471 for(i1=0; i1<str.length(); i1++) 01472 if(str[i1]==0x20) 01473 break; 01474 else 01475 channame+=str[i1]; 01476 str.erase(0,i1+1); // erase channel name 01477 01478 for(i1=0; i1<str.length(); i1++) 01479 if(str[i1]==':') 01480 break; 01481 str.erase(0,i1+1); // erase everything before ':' 01482 01483 l3: 01484 vector<s_online_channel>::iterator i; 01485 bool got_channel=false; 01486 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 01487 if(!cmp_strings_case_insensitive((*i).name,channame)) { 01488 got_channel=true; 01489 break; 01490 } 01491 } 01492 if(!got_channel) { 01493 // we are new on channel, right after JOIN 01494 s_online_channel chan; 01495 chan.name=channame; 01496 chan.modes=""; 01497 chan.topic=""; 01498 chan.users.clear(); 01499 chan.bans.clear(); 01500 chan.excepts.clear(); 01501 chan.reops.clear(); 01502 chan.b_reops_sent=chan.b_excepts_sent=chan.b_invites_sent=chan.b_bans_sent=false; 01503 irc_channels.push_back(chan); 01504 goto l3; 01505 } 01506 01507 while(str.length()>0) { 01508 while(str.length()>0 && str[0]==0x20) 01509 str.erase(0,1); 01510 01511 string nick; 01512 for(i1=0; i1<str.length(); i1++) 01513 if(str[i1]==0x20) 01514 break; 01515 else 01516 nick+=str[i1]; 01517 str.erase(0,i1); // erase nick 01518 01519 while(str.length()>0 && str[0]==0x20) 01520 str.erase(0,1); 01521 while(nick.length()>0 && nick[0]==0x20) 01522 str.erase(0,1); 01523 01524 char prefix='0'; 01525 /*if(nick[0]=='+') { 01526 prefix='+'; 01527 nick.erase(0,1); 01528 } else 01529 if(nick[0]=='@') { 01530 prefix='@'; 01531 nick.erase(0,1); 01532 } else 01533 if(nick[0]=='~') { 01534 prefix='~'; 01535 nick.erase(0,1); 01536 } else 01537 if(nick[0]=='&') { 01538 prefix='&'; 01539 nick.erase(0,1); 01540 } else 01541 if(nick[0]=='%') { 01542 prefix='%'; 01543 nick.erase(0,1); 01544 }*/ 01545 if(irc_isupport.get_prefix2(nick[0])!='0') { 01546 prefix=nick[0]; 01547 nick.erase(0,1); 01548 } 01549 01550 bool got_user=false; 01551 if(nick.length()>0) { 01552 l4: 01553 vector<s_online_user>::iterator ii; 01554 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 01555 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 01556 got_user=true; 01557 break; 01558 } 01559 } 01560 if(!got_user) { 01561 s_online_user user; 01562 user.nick=nick; 01563 user.got_whois=false; 01564 user.whois_sent=false; 01565 user.on_join_called=false; 01566 user.ident=""; 01567 user.host=""; 01568 user.fullname=""; 01569 user.got_mode=true; 01570 if(prefix!='0') 01571 user.mode=prefix; 01572 else 01573 user.mode="0"; 01574 user.irc_op=false; 01575 user.just_joined=false; 01576 user.old_mode="INVALID"; 01577 (*i).users.push_back(user); 01578 goto l4; 01579 } 01580 if(!(*ii).got_whois) { 01581 string str="WHOIS "; 01582 str+=(*ii).nick; 01583 (*ii).whois_sent=true; 01584 irc_putserv(str.c_str(),true,HIGH_PRIORITY); 01585 } else { 01586 if(!nick.compare(irc_nick) && prefix!='0') { 01587 string source_user=logic_find_user(nick,irc_get_ident(nick),irc_get_host(nick),irc_get_fullname(nick),irc_is_ircop(nick)); 01588 string target_user=source_user; 01589 logic_validate(channame,source_user,target_user,nick,nick,'+',prefix); 01590 } 01591 } 01592 } 01593 } 01594 01595 i1=0; 01596 vector<s_online_user>::iterator i2; 01597 s_online_channel* chan; 01598 if(irc_get_online_channel(channame,chan)) { 01599 i2=chan->users.begin(); 01600 for(; i2!=chan->users.end(); i2++) 01601 i1++; 01602 if(i1==1) { 01603 string msg="WHOIS "; 01604 msg+=irc_nick; 01605 irc_putserv(msg.c_str(),true,HIGH_PRIORITY); 01606 } 01607 01608 if(!chan->b_invites_sent && irc_isupport.chanmodes_a.find("I")!=string::npos) { 01609 chan->b_invites_sent=true; 01610 string inv="MODE "; 01611 inv+=channame; 01612 inv+=" +I"; 01613 irc_putserv(inv.c_str(),true,HIGH_PRIORITY); 01614 } 01615 01616 if(!chan->b_reops_sent && irc_isupport.chanmodes_a.find("R")!=string::npos) { 01617 chan->b_reops_sent=true; 01618 string inv="MODE "; 01619 inv+=channame; 01620 inv+=" +R"; 01621 irc_putserv(inv.c_str(),true,HIGH_PRIORITY); 01622 } 01623 } 01624 }
Here is the call graph for this function: ![]() |
|
Called after receiving RPL_TOPIC from server (someone has changed TOPIC for channel), and calls logic_validate_topic function after parsing the message.
Definition at line 3775 of file irc.cpp. References s_online_user::fullname, s_online_user::host, s_online_user::ident, irc_find_user(), s_online_user::irc_op, logic_find_user(), logic_validate_topic(), and s_online_user::nick. Referenced by irc_loop_process_input(). 03776 { 03777 string log=str; 03778 unsigned int i1; 03779 03780 for(i1=0; i1<str.length(); i1++) 03781 if(str[i1]==':') 03782 break; 03783 str.erase(0,i1+1); // erase everything before ':' 03784 03785 string nick; 03786 for(i1=0; i1<str.length(); i1++) 03787 if(str[i1]=='!') 03788 break; 03789 else 03790 nick+=str[i1]; 03791 str.erase(0,i1+1); // erase nick name 03792 03793 string ident; 03794 for(i1=0; i1<str.length(); i1++) 03795 if(str[i1]=='@') 03796 break; 03797 else 03798 ident+=str[i1]; 03799 str.erase(0,i1+1); // erase ident 03800 03801 string host; 03802 for(i1=0; i1<str.length(); i1++) 03803 if(str[i1]==0x20) 03804 break; 03805 else 03806 host+=str[i1]; 03807 str.erase(0,i1+1); // erase host name 03808 03809 for(i1=0; i1<str.length(); i1++) 03810 if(str[i1]==0x20) 03811 break; 03812 str.erase(0,i1+1); // erase "TOPIC" 03813 03814 string channel; 03815 for(i1=0; i1<str.length(); i1++) 03816 if(str[i1]==0x20) 03817 break; 03818 else 03819 channel+=str[i1]; 03820 str.erase(0,i1+1); // erase channel 03821 03822 for(i1=0; i1<str.length(); i1++) 03823 if(str[i1]==':') 03824 break; 03825 str.erase(0,i1+1); // erase everything before ':' 03826 03827 string topic; 03828 for(i1=0; i1<str.length(); i1++) 03829 topic+=str[i1]; 03830 03831 s_online_user source_=irc_find_user(nick); 03832 string source_user=logic_find_user(source_.nick,source_.ident,source_.host,source_.fullname,source_.irc_op); 03833 03834 logic_validate_topic(channel,source_user,nick,topic); 03835 }
Here is the call graph for this function: ![]() |
|
Definition at line 1898 of file irc.cpp. References cmp_strings_case_insensitive(), s_005::get_prefix2(), irc_channels, irc_check_for_filesystem(), irc_nick, logic_on_join(), logic_validate(), and s_005::raw. Referenced by irc_loop_process_input(). 01899 { 01900 unsigned int i1; 01901 01902 for(i1=0; i1<str.length(); i1++) 01903 if(str[i1]==0x20) 01904 break; 01905 str.erase(0,i1+1); // erase numeric reply 01906 01907 for(i1=0; i1<str.length(); i1++) 01908 if(str[i1]==0x20) 01909 break; 01910 str.erase(0,i1+1); // erase my nick 01911 01912 string nick; 01913 for(i1=0; i1<str.length(); i1++) 01914 if(str[i1]==0x20) 01915 break; 01916 else 01917 nick+=str[i1]; 01918 str.erase(0,i1+1); // erase nick name 01919 01920 for(i1=0; i1<str.length(); i1++) 01921 if(str[i1]==':') 01922 break; 01923 str.erase(0,i1+1); // erase everything before ':' 01924 01925 while(str.length()>0) { 01926 string chan; 01927 for(i1=0; i1<str.length(); i1++) 01928 if(str[i1]==0x20) 01929 break; 01930 else 01931 chan+=str[i1]; 01932 str.erase(0,i1+1); // erase [@]#channame 01933 01934 if(chan.length()==0) 01935 continue; 01936 01937 char prefix='0'; 01938 /*if(chan[0]=='@' || /*chan[0]=='+' ||*] chan[0]=='~' || chan[0]=='&' || chan[0]=='%') 01939 prefix=chan[0]; 01940 else 01941 if(chan[0]=='+') { 01942 if(chan.length()>1 && chan[1]!='#' && chan[1]!='!' && chan[1]!='&' && chan[1]!='+') 01943 // we got +channel = channel name is "+channel" of type '+' 01944 prefix='0'; 01945 else 01946 // we got +?channel = channel name is "#channel" or "!channel",..., but with mode of '+' - voice 01947 prefix='+'; 01948 }*/ 01949 if(irc_isupport.get_prefix2(chan[0])!='0') 01950 prefix=chan[0]; 01951 if(prefix=='+') { 01952 string chantypes; 01953 map<string,string>::iterator iii; 01954 for(iii=irc_isupport.raw.begin(); iii!=irc_isupport.raw.end(); iii++) 01955 if(!(*iii).first.compare("CHANTYPES")) { 01956 chantypes=(*iii).second; 01957 break; 01958 } 01959 if(chan.length()>1 && chantypes.find(chan[1])==string::npos) 01960 // we got +channel = channel name is "+channel" of type '+' 01961 prefix='0'; 01962 if(chan.length()>1 && chantypes.find(chan[1])!=string::npos) 01963 // we got +?channel = channel name is "#channel" or "!channel",..., but with mode of '+' - voice 01964 prefix='+'; 01965 if(chan.length()==1) 01966 // we got "+" = channel name is "+" of type '+' 01967 prefix='0'; 01968 } 01969 if(prefix!='0') 01970 chan.erase((unsigned int)0,(unsigned int)1); 01971 01972 vector<s_online_channel>::iterator i; 01973 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 01974 vector<s_online_user>::iterator ii; 01975 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 01976 if(!cmp_strings_case_insensitive((*ii).nick,nick) && !cmp_strings_case_insensitive((*i).name,chan)) { 01977 (*ii).got_mode=true; 01978 if(prefix!='0') 01979 (*ii).mode=prefix; 01980 else 01981 (*ii).mode="0"; 01982 01983 if((*ii).got_whois && !(*ii).on_join_called) { 01984 logic_on_join((*ii).nick, (*ii).ident, (*ii).host, (*ii).fullname, chan, (*ii).irc_op); 01985 01986 irc_check_for_filesystem((*ii).in_logic_as,(*i).name,(*ii).nick); 01987 } 01988 if(!(*ii).nick.compare(irc_nick) && (*ii).mode.compare((*ii).old_mode)) { 01989 // there it will go on channel cycle 01990 if((*ii).mode.length() && (*ii).mode.compare("0")) 01991 logic_validate((*i).name,"",(*ii).in_logic_as,"",(*ii).nick,'+',(*ii).mode[0]); 01992 (*ii).old_mode=(*ii).mode; 01993 } 01994 (*ii).on_join_called=true; 01995 } 01996 } 01997 } 01998 } 01999 }
Here is the call graph for this function: ![]() |
|
Parses and evaluates RPL_WHOISOPERATOR reply (partial reply to WHOIS command).
Definition at line 1825 of file irc.cpp. References cmp_strings_case_insensitive(), dcc_request_whois, irc_channels, irc_get_modes_for_log(), log_channel(), logic_on_ircop(), tmp_users, and TYPE_IRCOP_JOIN. Referenced by irc_loop_process_input(). 01826 { 01827 unsigned int i1; 01828 01829 for(i1=0; i1<str.length(); i1++) 01830 if(str[i1]==0x20) 01831 break; 01832 str.erase(0,i1+1); // erase numeric reply 01833 01834 for(i1=0; i1<str.length(); i1++) 01835 if(str[i1]==0x20) 01836 break; 01837 str.erase(0,i1+1); // erase my nick 01838 01839 string nick; 01840 for(i1=0; i1<str.length(); i1++) 01841 if(str[i1]==0x20) 01842 break; 01843 else 01844 nick+=str[i1]; 01845 str.erase(0,i1+1); // erase nick name 01846 01847 for(i1=0; i1<str.length(); i1++) 01848 if(str[i1]==':') 01849 break; 01850 str.erase(0,i1+1); // erase everything before ':' 01851 01852 string chan; 01853 01854 vector<s_online_channel>::iterator i; 01855 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 01856 vector<s_online_user>::iterator ii; 01857 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 01858 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 01859 if(!(*ii).irc_op) { 01860 string host_mask=nick; 01861 host_mask+="!"; 01862 host_mask+=(*ii).ident; 01863 host_mask+="@"; 01864 host_mask+=(*ii).host; 01865 log_channel((*i).name.c_str(),TYPE_IRCOP_JOIN,host_mask.c_str(),"","",irc_get_modes_for_log((*i).name,nick).c_str()); 01866 } 01867 (*ii).irc_op=true; 01868 chan=(*i).name; 01869 } 01870 } 01871 } 01872 01873 vector<s_online_user>::iterator ii; 01874 for(ii=tmp_users.begin(); ii!=tmp_users.end(); ii++) { 01875 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 01876 (*ii).irc_op=true; 01877 } 01878 } 01879 01880 logic_on_ircop(chan,nick,true); 01881 01882 vector<s_dcc_request_whois>::iterator i2; 01883 for(i2=dcc_request_whois.begin(); i2!=dcc_request_whois.end(); i2++) { 01884 if(!(*i2).nick.compare(nick)) { 01885 (*i2).irc_op=true; 01886 break; 01887 } 01888 } 01889 }
Here is the call graph for this function: ![]() |
|
Parses and evaluates RPL_WHOISUSER reply (partial reply to WHOIS command).
Definition at line 1658 of file irc.cpp. References cmp_strings_case_insensitive(), dcc_request_whois, irc_channels, irc_check_for_filesystem(), irc_nick, irc_op(), irc_quoted_callback(), logic_find_user(), logic_on_join(), logic_on_nick_validate(), logic_resolve(), logic_resolve6(), and tmp_users. Referenced by irc_loop_process_input(). 01659 { 01660 unsigned int i1; 01661 01662 for(i1=0; i1<str.length(); i1++) 01663 if(str[i1]==0x20) 01664 break; 01665 str.erase(0,i1+1); // erase numeric reply 01666 01667 for(i1=0; i1<str.length(); i1++) 01668 if(str[i1]==0x20) 01669 break; 01670 str.erase(0,i1+1); // erase my nick 01671 01672 string nick; 01673 for(i1=0; i1<str.length(); i1++) 01674 if(str[i1]==0x20) 01675 break; 01676 else 01677 nick+=str[i1]; 01678 str.erase(0,i1+1); // erase nick name 01679 01680 string ident; 01681 for(i1=0; i1<str.length(); i1++) 01682 if(str[i1]==0x20) 01683 break; 01684 else 01685 ident+=str[i1]; 01686 str.erase(0,i1+1); // erase ident 01687 01688 string host; 01689 for(i1=0; i1<str.length(); i1++) 01690 if(str[i1]==0x20) 01691 break; 01692 else 01693 host+=str[i1]; 01694 str.erase(0,i1+1); // erase host 01695 01696 logic_resolve(host); 01697 logic_resolve6(host); 01698 01699 for(i1=0; i1<str.length(); i1++) 01700 if(str[i1]==':') 01701 break; 01702 str.erase(0,i1+1); // erase everything before ':' 01703 01704 string fullname; 01705 for(i1=0; i1<str.length(); i1++) 01706 fullname+=str[i1]; 01707 01708 vector<s_online_channel>::iterator i; 01709 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 01710 vector<s_online_user>::iterator ii; 01711 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 01712 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 01713 (*ii).got_whois=true; 01714 (*ii).whois_sent=true; 01715 (*ii).ident=ident; 01716 (*ii).host=host; 01717 (*ii).fullname=fullname; 01718 01719 (*ii).in_logic_as=logic_find_user((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).irc_op); 01720 01721 if((*ii).just_joined && !(*ii).on_join_called) { 01722 (*ii).just_joined=false; 01723 logic_on_join((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).just_joined_channel,(*ii).irc_op); 01724 } else { 01725 if(((*ii).mode.compare((*ii).old_mode) && (*ii).old_mode.compare("INVALID")) || (*ii).nick.compare((*ii).old_nick)) 01726 if(!(*ii).on_join_called) 01727 logic_on_nick_validate((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*i).name,(*ii).irc_op,true); 01728 } 01729 irc_check_for_filesystem((*ii).in_logic_as,(*i).name,(*ii).nick); 01730 (*ii).on_join_called=true; 01731 (*ii).old_mode=(*ii).mode; 01732 (*ii).old_nick=(*ii).nick; 01733 } 01734 } 01735 } 01736 01737 vector<s_online_user>::iterator ii; 01738 for(ii=tmp_users.begin(); ii!=tmp_users.end(); ii++) { 01739 if(!cmp_strings_case_insensitive((*ii).nick,nick)) { 01740 (*ii).got_whois=true; 01741 (*ii).whois_sent=true; 01742 (*ii).ident=ident; 01743 (*ii).host=host; 01744 (*ii).fullname=fullname; 01745 01746 (*ii).in_logic_as=logic_find_user((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,(*ii).irc_op); 01747 } 01748 } 01749 01750 vector<s_dcc_request_whois>::iterator i2; 01751 for(i2=dcc_request_whois.begin(); i2!=dcc_request_whois.end(); i2++) { 01752 if(!(*i2).nick.compare(nick)) { 01753 (*i2).full_name=fullname; 01754 (*i2).got_whois=true; 01755 (*i2).host=host; 01756 (*i2).ident=ident; 01757 irc_quoted_callback((*i2).str.c_str(),(*i2).nick.c_str(),(*i2).host_mask.c_str()); 01758 break; 01759 } 01760 } 01761 01762 bool irc_op=false; // assume that it is not an irc operator 01763 01764 if(!cmp_strings_case_insensitive(nick,irc_nick)) { 01765 // after re-JOIN to get op 01766 logic_on_nick_validate(nick,ident,host,fullname,logic_find_user(nick,ident,host,fullname,irc_op),irc_op,true); 01767 01768 vector<s_online_channel>::iterator i1; 01769 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 01770 vector<s_online_user>::iterator i2; 01771 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 01772 if((*i2).got_whois) 01773 (*i2).in_logic_as=logic_find_user((*i2).nick,(*i2).ident,(*i2).host,(*i2).fullname,(*i2).irc_op); 01774 logic_on_nick_validate((*i2).nick,(*i2).ident,(*i2).host,(*i2).fullname,(*i1).name,(*i2).irc_op,true); 01775 } 01776 } 01777 } 01778 }
Here is the call graph for this function: ![]() |
|
Parses and evaluates RPL_YOURID reply (your unique ID).
Definition at line 1787 of file irc.cpp. References irc_unique_id. Referenced by irc_loop_process_input(). 01788 { 01789 unsigned int i1; 01790 01791 for(i1=0; i1<str.length(); i1++) 01792 if(str[i1]==0x20) 01793 break; 01794 str.erase(0,i1+1); // erase server name 01795 01796 for(i1=0; i1<str.length(); i1++) 01797 if(str[i1]==0x20) 01798 break; 01799 str.erase(0,i1+1); // erase numeric reply 01800 01801 for(i1=0; i1<str.length(); i1++) 01802 if(str[i1]==0x20) 01803 break; 01804 str.erase(0,i1+1); // erase my nick 01805 01806 string id; 01807 for(i1=0; i1<str.length(); i1++) 01808 if(str[i1]==0x20) 01809 break; 01810 else 01811 id+=str[i1]; 01812 str.erase(0,i1+1); // erase ID 01813 01814 if(id.length()<sizeof(irc_unique_id)) 01815 strcpy(irc_unique_id,id.c_str()); 01816 }
|
|
Sets value of irc_follow_redirs flag.
Definition at line 6747 of file irc.cpp. References irc_follow_redirs. Referenced by logic_exec(). 06748 { 06749 irc_follow_redirs=follow_redirs; 06750 }
|
|
Converts string to UPPER case (using touppertab[] in match.cpp).
Definition at line 269 of file irc.cpp. References touppertab. Referenced by cmp_strings_case_insensitive(). 00270 { 00271 extern unsigned char touppertab[]; 00272 00273 string res; 00274 for(unsigned int i1=0; i1<str.length(); i1++) 00275 res+=touppertab[str[i1]]; 00276 return res; 00277 }
|
|
Unbans (MODE #channel -b mask) host mask on channel.
Definition at line 6683 of file irc.cpp. References cmp_strings_case_insensitive(), HIGH_PRIORITY, irc_channels, and irc_putserv(). Referenced by logic_exec(). 06684 { 06685 if(strlen(channel)>128) 06686 return false; 06687 if(strlen(mask)>512-1) 06688 return false; 06689 06690 vector<s_online_channel>::iterator i; 06691 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 06692 if(!cmp_strings_case_insensitive((*i).name,(string)channel)) { 06693 vector<string>::iterator i2; 06694 for(i2=(*i).bans.begin(); i2!=(*i).bans.end(); i2++) { 06695 if(!cmp_strings_case_insensitive((*i2),(string)mask)) { 06696 (*i).bans.erase(i2); 06697 break; 06698 } 06699 } 06700 } 06701 } 06702 06703 char tmp[4096]; 06704 strcpy(tmp,"MODE "); 06705 strcat(tmp,channel); 06706 strcat(tmp," -b "); 06707 strcat(tmp,mask); 06708 06709 return irc_putserv(tmp,true,HIGH_PRIORITY); 06710 }
Here is the call graph for this function: ![]() |
|
Adds/remove new mode for user on channel.
Definition at line 2625 of file irc.cpp. References cmp_strings_case_insensitive(), s_online_user::in_logic_as, irc_channels, irc_find_user(), irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_is_ircop(), irc_nick, logic_find_user(), logic_on_nick_validate(), logic_set_dynamic(), and logic_validate(). Referenced by irc_mode_change_creator(), irc_mode_change_op(), irc_mode_change_other(), and irc_mode_change_voice(). 02626 { 02627 if(!cmp_strings_case_insensitive(nick,irc_nick)) { 02628 logic_validate(channel,irc_find_user(from_nick).in_logic_as,logic_find_user(irc_nick,irc_get_ident(irc_nick),irc_get_host(irc_nick),irc_get_fullname(irc_nick),irc_is_ircop(irc_nick)),from_nick,irc_nick,prefix,mode); 02629 02630 vector<s_online_channel>::iterator i; 02631 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) { 02632 if(cmp_strings_case_insensitive((*i).name,channel)) 02633 continue; 02634 vector<s_online_user>::iterator ii; 02635 for(ii=(*i).users.begin(); ii!=(*i).users.end(); ii++) { 02636 if((*ii).got_whois) { 02637 if(!(*ii).nick.compare(irc_nick)) { 02638 while((*ii).mode.find("0",0)!=string::npos) 02639 (*ii).mode.erase((*ii).mode.find("0",0),1); 02640 if(prefix=='+') { 02641 while((*ii).mode.find(mode,0)!=string::npos) 02642 (*ii).mode.erase((*ii).mode.find(mode,0),1); 02643 (*ii).mode+=mode; 02644 } else { 02645 while((*ii).mode.find(mode,0)!=string::npos) 02646 (*ii).mode.erase((*ii).mode.find(mode,0),1); 02647 } 02648 if((*ii).mode.empty()) 02649 (*ii).mode+="0"; 02650 } 02651 02652 logic_on_nick_validate((*ii).nick,(*ii).ident,(*ii).host,(*ii).fullname,channel,(*ii).irc_op,(*ii).on_join_called); 02653 (*ii).on_join_called=true; 02654 (*ii).old_mode=(*ii).mode; 02655 } 02656 } 02657 } 02658 } 02659 02660 string from_user=irc_find_user(from_nick).in_logic_as; 02661 02662 vector<s_online_channel>::iterator i1; 02663 for(i1=irc_channels.begin(); i1!=irc_channels.end(); i1++) { 02664 if(cmp_strings_case_insensitive((*i1).name,channel)) 02665 continue; 02666 vector<s_online_user>::iterator i2; 02667 for(i2=(*i1).users.begin(); i2!=(*i1).users.end(); i2++) { 02668 if(!cmp_strings_case_insensitive((*i2).nick,nick)) { 02669 string m=(*i2).mode; 02670 while(m.find("0",0)!=string::npos) 02671 m.erase(m.find("0",0),1); 02672 if(prefix=='+') { 02673 while(m.find(mode,0)!=string::npos) 02674 m.erase(m.find(mode,0),1); 02675 m+=mode; 02676 } else { 02677 while(m.find(mode,0)!=string::npos) 02678 m.erase(m.find(mode,0),1); 02679 } 02680 if(m.empty()) 02681 m+="0"; 02682 (*i2).mode=m; 02683 (*i2).got_mode=true; 02684 02685 logic_set_dynamic((*i2).in_logic_as,from_user,prefix,mode); 02686 } 02687 } 02688 } 02689 }
Here is the call graph for this function: ![]() |
|
Sets +v (voice) status to nick on channel.
Definition at line 6321 of file irc.cpp. References irc_internal_set_mode(), and irc_putserv(). Referenced by logic_exec(). 06322 { 06323 if(strlen(channel)>128) 06324 return false; 06325 if(strlen(nick)>128) 06326 return false; 06327 06328 irc_internal_set_mode(channel,nick,'+','+'); 06329 06330 char msg[4096]; 06331 strcpy(msg,"MODE "); 06332 strcat(msg,channel); 06333 strcat(msg," +v "); 06334 strcat(msg,nick); 06335 06336 return irc_putserv(msg,true,priority); 06337 }
Here is the call graph for this function: ![]() |
|
Gets user definition.
Definition at line 13403 of file logic.cpp. References r_terminators, r_user_templates, and r_users. 13404 { 13405 vector<s_user>::iterator i1; 13406 for(i1=r_users.begin(); i1!=r_users.end(); i1++) { 13407 if(!(*i1).name.compare(name)) { 13408 user=*i1; 13409 return true; 13410 } 13411 } 13412 for(i1=r_user_templates.begin(); i1!=r_user_templates.end(); i1++) { 13413 if(!(*i1).name.compare(name)) { 13414 user=*i1; 13415 return true; 13416 } 13417 } 13418 for(i1=r_terminators.begin(); i1!=r_terminators.end(); i1++) { 13419 if(!(*i1).name.compare(name)) { 13420 user=*i1; 13421 return true; 13422 } 13423 } 13424 return false; 13425 }
|
|
Retrieves flood limits.
Definition at line 12567 of file logic.cpp. References s_flood::lines, logic_cmp_strings_case_insensitive(), logic_eval(), and r_channels. Referenced by irc_check_flood(). 12568 { 12569 msg_flood.lines=0; 12570 notice_flood.lines=0; 12571 repeat_flood.lines=0; 12572 nick_flood.lines=0; 12573 join_flood.lines=0; 12574 mode_flood.lines=0; 12575 ctcp_flood.lines=0; 12576 12577 map<string,string> vars; 12578 12579 vector<s_channel>::iterator i1; 12580 for(i1=r_channels.begin(); i1!=r_channels.end(); i1++) { 12581 if(!user.compare((string)"") && !logic_cmp_strings_case_insensitive(logic_eval((*i1).channel_name,vars),channel) && (*i1).host_unknown) { 12582 msg_flood=(*i1).msg_flood; 12583 notice_flood=(*i1).notice_flood; 12584 repeat_flood=(*i1).repeat_flood; 12585 nick_flood=(*i1).nick_flood; 12586 join_flood=(*i1).join_flood; 12587 mode_flood=(*i1).mode_flood; 12588 ctcp_flood=(*i1).ctcp_flood; 12589 return; 12590 } 12591 if(!logic_cmp_strings_case_insensitive(logic_eval((*i1).channel_name,vars),channel) && !(*i1).username.compare(user)) { 12592 msg_flood=(*i1).msg_flood; 12593 notice_flood=(*i1).notice_flood; 12594 repeat_flood=(*i1).repeat_flood; 12595 nick_flood=(*i1).nick_flood; 12596 join_flood=(*i1).join_flood; 12597 mode_flood=(*i1).mode_flood; 12598 ctcp_flood=(*i1).ctcp_flood; 12599 return; 12600 } 12601 } 12602 12603 // consider as unknown host 12604 for(i1=r_channels.begin(); i1!=r_channels.end(); i1++) { 12605 if(!logic_cmp_strings_case_insensitive(logic_eval((*i1).channel_name,vars),channel) && (*i1).host_unknown) { 12606 msg_flood=(*i1).msg_flood; 12607 notice_flood=(*i1).notice_flood; 12608 repeat_flood=(*i1).repeat_flood; 12609 nick_flood=(*i1).nick_flood; 12610 join_flood=(*i1).join_flood; 12611 mode_flood=(*i1).mode_flood; 12612 ctcp_flood=(*i1).ctcp_flood; 12613 return; 12614 } 12615 } 12616 }
Here is the call graph for this function: ![]() |
|
ltoa() emulation for compiler which doesn't have it
Definition at line 171 of file dcc.cpp.
|
|
Sleeps.
Definition at line 226 of file irc_bot.cpp. 00227 { 00228 #ifdef _WIN32 00229 ProcessMessages(); 00230 sock_send_cache(); 00231 if(ms) { 00232 if(ms<1000) { 00233 long ms_remain=ms; 00234 while(ms_remain>0) { 00235 ProcessMessages(); 00236 sock_send_cache(); 00237 int s=ms_remain>50?50:ms_remain; 00238 Sleep(s); 00239 ms_remain-=s; 00240 ProcessMessages(); 00241 sock_send_cache(); 00242 } 00243 } else { 00244 time_t now=time(NULL); 00245 for(;;) { 00246 Sleep(1); 00247 ProcessMessages(); 00248 dcc_loop(); 00249 sock_send_cache(); 00250 if(now+ms/1000<time(NULL)) 00251 break; 00252 } 00253 } 00254 } 00255 ProcessMessages(); 00256 #else 00257 sock_send_cache(); 00258 if(ms) { 00259 if(ms<1000) { 00260 long ms_remain=ms; 00261 while(ms_remain>0) { 00262 sock_send_cache(); 00263 int s=ms_remain>50?50:ms_remain; 00264 timeval tv; 00265 tv.tv_sec=0; 00266 tv.tv_usec=ms*1000; 00267 select(1,NULL,NULL,NULL,&tv); 00268 ms_remain-=s; 00269 sock_send_cache(); 00270 } 00271 } else { 00272 time_t now=time(NULL); 00273 for(;;) { 00274 timeval tv; 00275 tv.tv_sec=0; 00276 tv.tv_usec=1*1000; 00277 select(1,NULL,NULL,NULL,&tv); 00278 dcc_loop(); 00279 sock_send_cache(); 00280 if(now+ms/1000<time(NULL)) 00281 break; 00282 } 00283 } 00284 } 00285 #endif 00286 }
|
|
Stores users who are waiting for DCC connection.
Definition at line 133 of file dcc.cpp. Referenced by dcc_loop(), irc_await_dcc_chat(), irc_loop_process_input(), and irc_RPL_ENDOFWHOIS(). |
|
Array, that stores DCC requests that are pending to establis, and waiting for whois result.
Definition at line 774 of file dcc.cpp. Referenced by irc_connect(), irc_quoted_callback(), irc_RPL_WHOISOPERATOR(), and irc_RPL_WHOISUSER(). |
|
Timestam of last filesystem notification.
Definition at line 126 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
Interval for filesystem notifications.
Definition at line 125 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
History of messages sent to server (for bot's flood control).
Definition at line 165 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
History of other messages sent to server (non-PRIVMSG && non-NOTICE) (for bot's flood protection).
Definition at line 166 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
Temporary list of users that have QUIT/PART/been KICK-ed.
Definition at line 145 of file irc.cpp. Referenced by irc_check_flood(), irc_connect(), irc_get_host(), irc_get_ident(), and irc_loop_process_input(). |
|
Number of bytes considered as flood from bot.
Definition at line 95 of file irc.cpp. Referenced by irc_connect(), irc_loop_putserv(), and irc_rehashed(). |
|
Number of lines maximum in irc_bot_flood_seconds.
Definition at line 97 of file irc.cpp. Referenced by irc_connect(), irc_loop_putserv(), and irc_rehashed(). |
|
Number of seconds to clear flood buffer for non-PRIVMSG && non-NOTICE messages (from bot).
Definition at line 98 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
Number of seconds to clear flood buffer (from bot).
Definition at line 96 of file irc.cpp. Referenced by irc_connect(), irc_loop_putserv(), and irc_rehashed(). |
|
List of channels that i am banned.
Definition at line 168 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), and irc_loop_putserv(). |
|
List of channels we are on.
|
|
Stores "allow_redirect" state from logic.txt (true if bot should follow redirect hints from server).
Definition at line 100 of file irc.cpp. Referenced by irc_loop_process_input(), irc_set_redir(), and logic_exec(). |
|
Bot's current full name.
Definition at line 109 of file irc.cpp. Referenced by irc_connect(), and logic_exec(). |
|
Bot's ident username.
Definition at line 111 of file irc.cpp. Referenced by irc_disconnect(), and logic_exec(). |
|
|
|
Was WHOIS sent?
Definition at line 106 of file irc.cpp. Referenced by irc_connect(), irc_disconnect(), and irc_loop_putserv(). |
|
List of channels which we are not on, because they are +k and we are trying all keys in the history.
Definition at line 139 of file irc.cpp. Referenced by irc_connect(), and irc_loop_process_input(). |
|
Timestamp of last try to join because of +b on myself, or +l, or +i.
Definition at line 169 of file irc.cpp. Referenced by irc_connect(), and irc_loop_putserv(). |
|
Used for storing time of last command sent to server (for detection of lost connection).
Definition at line 105 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), irc_loop_putserv(), and logic_exec(). |
|
Bot's current nick.
|
|
Bot's nicks available to try them if they are unused (from logic.txt).
Definition at line 121 of file irc.cpp. Referenced by irc_connect(), and logic_exec(). |
|
Hint from server: recommended port (together with irc_recommended_server).
Definition at line 102 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), and logic_exec(). |
|
Hint from server: recommended server (together with irc_recommended_port).
Definition at line 101 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), and logic_exec(). |
|
Current IRC server host.
Definition at line 113 of file irc.cpp. Referenced by irc_loop_process_input(), logic_exec(), logic_exec_script(), and logic_on_internal_event(). |
|
Current irc server.
Definition at line 123 of file irc.cpp. Referenced by logic_exec(). |
|
Current IRC server port.
Definition at line 114 of file irc.cpp. Referenced by irc_loop_process_input(), logic_exec(), logic_exec_script(), and logic_on_internal_event(). |
|
List of irc servers.
Definition at line 122 of file irc.cpp. Referenced by logic_exec(). |
|
Handle of socket connected to server (zero for disconnected state).
|
|
If true, then we have socket error on connection to IRC server.
Definition at line 163 of file irc.cpp. Referenced by irc_connect(). |
|
Bot's unique ID.
Definition at line 110 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), and irc_RPL_YOURID(). |
|
Last message sent to server.
|
|
Mode queue used when "compress_mode_wait" form conf.txt is more than zero.
Definition at line 186 of file irc.cpp. Referenced by irc_connect(), irc_disconnect(), irc_loop_putserv(), irc_putserv(), irc_remove_redundant_mode(), and irc_remove_redundant_mode2(). |
|
Modes that server set.
Definition at line 187 of file irc.cpp. Referenced by irc_connect(), irc_remove_redundant_mode2(), and irc_RPL_MODE(). |
|
Queue of messages from server to be processed.
Definition at line 162 of file irc.cpp. Referenced by irc_connect(), irc_loop_process_input(), irc_loop_putserv(), logic_exec(), and main(). |
|
Queue of messages that are waiting to be sent to server (for bot's flood control).
Definition at line 160 of file irc.cpp. Referenced by irc_connect(), irc_disconnect(), irc_loop_putserv(), irc_putserv(), and logic_exec(). |
|
Queue of messages that are waiting to be sent to server (for bot's flood control), but these has lower priority (notifies).
Definition at line 161 of file irc.cpp. Referenced by irc_connect(), irc_disconnect(), irc_loop_putserv(), and irc_putserv(). |
|
List of real channel definitions (not temporary / compilation!).
|
|
List of channels for real usage (not temporary / compilation!).
|
|
List of users for real usage (not temporary / compilation!).
|
|
Temporary list of users.
Definition at line 143 of file irc.cpp. Referenced by irc_access_to_partyline(), irc_connect(), irc_loop_process_input(), irc_RPL_ENDOFWHOIS(), irc_RPL_WHOISOPERATOR(), and irc_RPL_WHOISUSER(). |
|
Temporary list of user used ONLY for flood history.
Definition at line 147 of file irc.cpp. Referenced by irc_connect(), irc_on_notice(), and irc_on_privmsg(). |
|
Array of last messages to server.
Definition at line 158 of file irc.cpp. Referenced by irc_connect(), irc_disconnect(), irc_kill_command_wait(), irc_loop_putserv(), and irc_putserv_immediately(). |