irc.cpp File Reference


Detailed Description

Handles core communication with IRC server.

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 &notice_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_userdcc_awaiting_users
 Stores users who are waiting for DCC connection.
vector< s_dcc_request_whoisdcc_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_historyflood_history
 History of messages sent to server (for bot's flood control).
list< s_flood_historyflood_history_other
 History of other messages sent to server (non-PRIVMSG && non-NOTICE) (for bot's flood protection).
vector< s_online_usergone_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_channelirc_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_chanirc_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_serverirc_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_entrymode_queue
 Mode queue used when "compress_mode_wait" form conf.txt is more than zero.
list< s_mode_queue_entrymodes_from_server
 Modes that server set.
list< char * > msgs_from_server
 Queue of messages from server to be processed.
list< s_msg_to_servermsgs_to_server
 Queue of messages that are waiting to be sent to server (for bot's flood control).
list< s_msg_to_servermsgs_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_defr_channel_defs
 List of real channel definitions (not temporary / compilation!).
vector< s_channelr_channels
 List of channels for real usage (not temporary / compilation!).
vector< s_userr_users
 List of users for real usage (not temporary / compilation!).
vector< s_online_usertmp_users
 Temporary list of users.
vector< s_online_channelunknown_users_on_channels
 Temporary list of user used ONLY for flood history.
vector< s_awaiting_responsewaiting_for_response
 Array of last messages to server.


Define Documentation

#define IRC_MSG_TOO_LONG   0x81234567L
 

ERROR: msg is longer than 512 bytes.

Definition at line 327 of file irc.cpp.

Referenced by irc_loop_putserv(), and irc_putserv_immediately().

#define SOCK_SEND_ERROR   0x81234568L
 

ERROR: not all the msg was sent.

Definition at line 332 of file irc.cpp.

Referenced by irc_loop_putserv(), and irc_putserv_immediately().


Function Documentation

int cmp_strings_case_insensitive string  s1,
string  s2
 

Compares two strings, case in-sensitive.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
s1 String 1
s2 String 2
Returns:
Zero if strings are the same (case in-sensitive)
Return values:
0 Strings are the same (case in-sensitive)

Definition at line 289 of file irc.cpp.

References irc_to_upper().

Referenced by dcc_loop(), dcc_loop_edit_dynbans(), dcc_loop_edit_user1(), dcc_loop_filesystem(), dcc_loop_msg(), filesys_dcc_check_for_notifies(), irc_access_to_partyline(), irc_banned(), irc_check_bans(), irc_check_flood(), irc_check_for_not_invited(), irc_check_for_not_reopped(), irc_check_invites(), irc_check_nick_on_channel(), irc_excepted(), irc_find_user(), irc_get_chan_mode(), irc_get_fullname(), irc_get_host(), irc_get_ident(), irc_get_mode(), irc_get_modes_for_log(), irc_get_nick(), irc_get_online_channel(), irc_in_reop(), irc_internal_set_mode(), irc_invited(), irc_is_ircop(), irc_is_online(), irc_loop_process_input(), irc_loop_putserv(), 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_on_broadcast(), irc_on_notice(), irc_on_privmsg(), irc_remove_redundant_mode(), irc_remove_redundant_mode2(), irc_RPL_324(), irc_RPL_ENDOFWHOIS(), irc_RPL_MODE(), irc_RPL_NAMREPLY(), irc_RPL_WHOISCHANNELS(), irc_RPL_WHOISOPERATOR(), irc_RPL_WHOISUSER(), irc_unban(), irc_user_mode_change(), logic_cmp_strings_case_insensitive(), logic_ctcp(), logic_exec(), logic_exec_script(), logic_on_banned(), logic_on_flood(), logic_on_ircop(), logic_on_join(), logic_on_nick_change(), logic_on_nick_validate(), logic_on_not_in_reop(), logic_on_not_invited(), logic_on_notice(), logic_on_part(), logic_on_privmsg(), logic_on_server_msg(), logic_partyline_access(), logic_partyline_get_channel_def(), logic_validate(), logic_validate_by_mask(), logic_validate_chan_key(), logic_validate_chan_limit(), logic_validate_chan_mode(), logic_validate_kick(), and logic_validate_topic().

00290 {
00291     s1=irc_to_upper(s1);
00292     s2=irc_to_upper(s2);
00293     if((s1.empty() && !s2.empty()) || (!s1.empty() && s2.empty()))
00294         return -1;
00295     return s1.compare(s2);
00296 }

Here is the call graph for this function:

void dcc_loop  ) 
 

Check for pending connections and handles existing ones.

Author:
VooDooMan
Version:
1
Date:
2004

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
hostmask Host mask of user ("nick!ident@host")
user_name_as_in_logic Returns user's name as defined in logic.txt
msg Sets this string to dcc_msg member to tmp_users entry if user is not known yet
Returns:
Returns true if user has access to partyline

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:

void irc_await_dcc_chat string  nick,
string  user_name_as_in_logic,
int  dcc_group
 

Called to await DCC connection from user.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick of user
dcc_group DCC-group ID
user_name_as_in_logic User name from "logic.txt"

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:

bool irc_ban const char *  channel,
const char *  mask
 

Bans (MODE #channel +b mask) host mask on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
mask Ban mask
Returns:
Returns false if socket I/O error occured, or channel is longer than 128 chars, or mask is longer than 511 bytes

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial message from server containing numeric reply, channel name and mask
Warning:
Must be called after irc_excepted() was called to ensure exceptions (+e) to bans were evaluated

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:

bool irc_chan_mode const char *  channel,
const char *  mode,
int  priority
 

Sets mode of channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
mode Mode to set
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)
Returns:
Returns irc_putserv() result

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:

void irc_check_bans string  channel  ) 
 

Checks ban list on channel after bot's JOIN by sending "MODE \#channel +b" command to server.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel

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:

void irc_check_flood int  type,
string  channel,
string  full_host,
string  msg
 

Checks flood limits and history for just received message.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
type Type of message - one of following: TYPE_PRIVMSG, TYPE_NOTICE, TYPE_QUIT_PART_KICK, TYPE_JOIN, TYPE_NICK, TYPE_MODE, TYPE_CTCP
channel Name of channel
full_host Host of originator of message ("nick!ident@host")
msg Additional "sub-message": for TYPE_PRIVMSG whole message, for TYPE_NOTICE notice message, for TYPE_QUIT_PART_KICK quit message/part message/kick reason (if any), for TYPE_NICK new nick name, and for TYPE_MODE mode string (parameter to MODE command), and for TYPE_MODE, when topic was changed, there is new topic, for TYPE_CTCP - the whole PRIVMSG

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:

void irc_check_for_filesystem string  user_name,
string  channel,
string  nick
 

Check filesystem for new objects and notifies user if needed.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
user_name User name from "logic.txt"
nick Nick name
channel Name of channel that is the user on

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Warning:
Must be called after irc_invited() was called to ensure invitations (+I) to override +i mode are in vector

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004

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:

void irc_check_invites string  channel  ) 
 

Checks invites list on channel after bot's JOIN by sending "MODE \#channel +I" command to server.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel

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:

bool irc_check_last_msg const char *  start  ) 
 

Compares the beginning of message.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
start The beginning of the message to be compared with last received message
Returns:
Returns true if it mathes

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 }

bool irc_check_nick_on_channel string  nick,
string  channel
 

Checks wheter user is found on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick name
channel Channel name
Return values:
true If user is on channel
false If user isn't 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:

int irc_connect const char *  bind_ip,
const char *  host_,
unsigned short  port
 

Connects to server.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
bind_ip IPv4 address to bind to (client address)
host_ DNS host of server
port Port of server
Returns:
Returns zero for no error, or OS's socket I/O error code

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:

bool irc_deop const char *  channel,
const char *  nick,
int  priority
 

Sets -o (chan op) status to nick on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
Returns:
Returns false if socket I/O error occured
Parameters:
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)

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:

bool irc_devoice const char *  channel,
const char *  nick,
int  priority
 

Sets -v (voice) status to nick on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)
Returns:
Returns false if socket I/O error occured

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:

int irc_disconnect  ) 
 

Disconnects from server.

Author:
VooDooMan
Version:
1
Date:
2004
Returns:
Returns zero for no error

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial reply from server, also containing channel name

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:

void irc_excepted string  str  ) 
 

Called as +e exception mask to ban is found out on channel after bot's JOIN.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial reply from server containing numeric reply, channel name and +e mask

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:

s_online_user irc_find_user string  nick  ) 
 

Finds s_online_user record in irc_channel list for user.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick of user
Returns:
User entry

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:

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).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
raw Assiciative array with all features
prefix Associative array with prefixes (user modes: 'o'=='@', 'v'=='+', etc.)
chm_a Channel modes class A - +b, +e, ...
chm_b Channel modes class B - +k
chm_c Channel modes class C - +l
chm_d Channel modes class D - +n, +t, ...

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 }

string irc_get_chan_mode string  channel,
string &  topic
 

Returns channel mode.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
topic Returns topic of channel
Returns:
Returns mode (i.e. "", "nt", "nts", "ntp", "n",..)

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:

string irc_get_fullname string  nick  ) 
 

Looks-up user from nick name and checks its full name.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick name
Returns:
Returns full name if online, if not, empty string

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:

string irc_get_host string  nick  ) 
 

Looks-up host of online user.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick name of user
Returns:
Returns host of user, or empty string if there's no such nick online

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:

string irc_get_ident string  nick  ) 
 

Looks-up ident of online user.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick name of user
Returns:
Returns ident of user, or empty string if there's no such nick online

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:

string irc_get_mode string  channel,
string  nick
 

Looks-up user from nick name and checks its mode on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
Returns:
Returns mode (i.e. "+", "@", "~", "@+", "+@", or "0")
Return values:
+ User has voice
@ User is channel operator
0 Normal user
@+ both +o and +v

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:

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.

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
channel Channel name
nick Nick name
Returns:
Returns mode(s) (i.e. "o", "v", "a", "ov", or "" - an empty string for none, or "?" for not-got-WHOIS-yet/unknown nick)
Return values:
'?' if we don't have WHOIS yet, or nick is unknown

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:

string irc_get_nick string  user  ) 
 

Looks-up user from name in logic.txt to nick name (if online).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
user User name as in logic.txt
Returns:
If user is online, returns its nick name, if not, returns user parameter

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:

bool irc_get_online_channel string  channel_name,
s_online_channel *&  chan
 

Returns reference to channel that we are on.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel_name Name of channel
chan Returns pointer to channel we are on, or NULL if channel was not found
Returns:
Returns true if found
Return values:
true Channel found
false Channel not found

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:

bool irc_got_op string  channel  ) 
 

Checks if bot has op (+o) on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel to check
Return values:
true If bot got +o
false If bot got -o

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:

void irc_in_reop string  str  ) 
 

Called as +R reop mask is found out on channel after bot's JOIN.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial reply from server containing numeric reply, channel name and +R mask

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:

void irc_internal_set_mode string  channel,
string  nick,
char  prefix,
char  mode
 

Resets user's old_mode atribute.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
channel Name of channel
nick Nick name
prefix '-' or '+'
mode '@' or '+'
Warning:
Behaviour of this function changed in version 1.0.40: Now it just resets old_mode

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:

void irc_invited string  str  ) 
 

Called as +I invitation mask to +i is found out on channel after bot's JOIN.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial reply from server containing numeric reply, channel name and +I mask

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:

bool irc_is_ircop string  nick  ) 
 

Looks-up user from name in logic.txt and checks if it is an irc operator (if online).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
nick Nick name
Returns:
If user is online, returns true for irc operator, if it is not online, returns false

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:

string irc_is_online string  user  ) 
 

Looks-up user from name in logic.txt to nick name (if online).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
user User name as in logic.txt
Returns:
If user is online, returns its nick name, if not, returns empty string

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:

bool irc_join const char *  channel,
const char *  key
 

JOINs channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
key Key to channel (can be empty)
Returns:
Returns false if socket I/O error occured

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:

bool irc_kick const char *  channel,
const char *  nick,
const char *  reason
 

Kicks nick on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
reason Kick message (reason of kick)
Returns:
Returns false if socket I/O error occured

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:

void irc_kicked string  str  ) 
 

Called when user was KICKed and validates it (or calls on_kicked event).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial message from server containing channel name and nick of kicked user

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:

void irc_kill_command_wait string  command  ) 
 

Clears wait flag for sent command (reply has been received).

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
command Command that should be cleared

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 }

void irc_kill_last_msg_wait string  resp  ) 
 

Clears wait flag for sent message (reply has been received).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
resp Received message from server

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 }

int irc_loop_process_input  ) 
 

This is called in loop to process messages from server.

Author:
VooDooMan
Version:
1
Date:
2004
Return values:
0 Okay
1 Error occured and bot should reconnect to server
2 Throttled - should be sleep for a couple of seconds

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:

bool irc_loop_putserv  ) 
 

This function should be called in a loop to process send and receive to/from server.

Author:
VooDooMan
Version:
1
Date:
2004
Returns:
Returns true if socket I/O error occured

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
mask Parameter to +/-b mode (mask)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
mask Parameter to +/-e mode (mask)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
key Parameter to +/-k mode (key)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
limit Parameter to +/-l mode (limit - number)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
mode One of followig: 'a', 'i', 'm', 'n', 'q', 'p', 's', 'r', 't'
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
whom Nick of target 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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
mask Parameter to +/-I mode (mask)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
whom Nick of target 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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
mode '~', '&', or ''
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
whom Nick of target 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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
mask Parameter to mode (mask)
Todo:
Not supported yet.

Definition at line 3265 of file irc.cpp.

Referenced by irc_RPL_MODE().

03266 {
03267 }

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
mask Parameter to +/-R mode (mask)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
prefix Contains '+' or '-' prefix
nick Nick of originator of MODE change
ident Ident of originator of MODE change
host Host of originator of MODE change
whom Nick of target 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:

bool irc_notice const char *  target,
const char *  msg,
int  priority
 

Sends NOTICE to user/channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
target Nick name / channel name of target
msg Whole message
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)
Returns:
Returns false if socket I/O error occured

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:

void irc_on_broadcast string  bcast_mask,
int  type,
string  full_host,
string  msg,
string  server,
unsigned short  port
 

Raises on_broadcast event.

Author:
VooDooMan
Version:
1
Date:
2005-04-22
Parameters:
bcast_mask Broadcast mask ("$$irc.someserver.net")
type Type: TYPE_PRIVMSG, TYPE_NOTICE
full_host Host of originator ("nick!ident@host")
msg The message
server IRC server host we are on
port IRC server port we are on

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:

void irc_on_notice string  channel,
string  full_host,
string  msg
 

Raises on_notice event if defined for specific user and channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
full_host Host of originator ("nick!ident@host")
msg The message (NOTICE message)

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:

void irc_on_privmsg string  channel,
string  full_host,
string  msg
 

Raises on_privmsg event if defined for specific user and channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
full_host Host of originator ("nick!ident@host")
msg The message (PRIVMSG message)

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:

bool irc_op const char *  channel,
const char *  nick,
int  priority
 

Sets +o (chan op) status to nick on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)
Returns:
Returns false if socket I/O error occured

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:

void irc_parse_modes string  modes,
map< char, string > &  with_param,
string &  plain
 

Parses a channel mode.

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
modes String with modes
with_param Returns map of modes with parameter (e.g. "k" -> "channel key")
plain Returns string of modes without parameter (e.g. "nt")

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 }

bool irc_part const char *  channel,
const char *  reason
 

PARTs channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
reason PART message (reason of PART)
Returns:
Returns false if socket I/O error occured

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:

bool irc_privmsg const char *  target,
const char *  msg,
int  priority
 

Sends PRIVMSG to user/channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
target Nick name / channel name of target
msg Whole message
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)
Returns:
Returns false if socket I/O error occured

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:

void irc_put string  data,
int  priority
 

Raw-ly puts message to queue to send to server.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
data Raw message (i.e. "PRIVMSG nick hello!")
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
command Command to use (for example "PRIVMSG")
nick Whom to send the message?
msg Message to parse

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:

bool irc_putserv const char *  msg,
bool  wait_for_response,
int  priority
 

Puts message for server to queue to send.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
msg Message
wait_for_response Set this to true if message has to be marked as wait for response and then send next message
priority CRITICAL_PRIORITY, HIGH_PRIORITY, or LOW_PRIORITY
Returns:
Returns false if socket I/O error occured

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:

int irc_putserv_immediately s_socket socket,
const char *  msg,
bool  wait_for_response = false
 

Imeddiately sends message to server.

Author:
VooDooMan
Version:
2
Date:
2005
Parameters:
socket Socket handle of connection to server
msg Message to be sent
wait_for_response Set to true if we want to wait for response from IRC server to this command
Returns:
Returns zero for no error, IRC_MSG_TOO_LONG if msg is too long (>512 bytes), SOCK_SEND_ERROR is not all the msg was sent, or OS's socket I/O error
Return values:
0 No error
IRC_MSG_TOO_LONG msg is too long (>512 bytes)
SOCK_SEND_ERROR Not all the msg was sent

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:

void irc_quit const char *  reason  ) 
 

Quits the IRC.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
reason Quit message

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Message content to parse
nick Nick name of sender
host_mask Host mask of sender

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:

void irc_rehashed  ) 
 

Called from logic.cpp after rehashing. Deletes all online users and so applies new configuration.

Author:
VooDooMan
Version:
1
Date:
2004

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick that mode is applied to
mode Mode (+o, -v, ...)

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:

void irc_remove_redundant_mode2  ) 
 

If "smart_mode" in conf.txt is non-zero, removes redundant modes from mode_queue.

Author:
VooDooMan
Version:
1
Date:
2004

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial message from server

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:

void irc_RPL_ENDOFWHOIS string  str  ) 
 

This must be called as RPL_ENDOFWHOIS reply from server - the end of WHOIS list for user.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Message line from server

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:

void irc_RPL_ISUPPORT string  str  ) 
 

Parses and evaluates RPL_ISUPPORT reply (005 numerics).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Line of message from server

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 }

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial message from server

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:

void irc_RPL_NAMREPLY string  str  ) 
 

Parses and evaluates RPL_NAMREPLY reply (reply to NAME command).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Line of message from server

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:

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.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Partial message from server

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:

void irc_RPL_WHOISCHANNELS string  str  ) 
 

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:

void irc_RPL_WHOISOPERATOR string  str  ) 
 

Parses and evaluates RPL_WHOISOPERATOR reply (partial reply to WHOIS command).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Line of message from server

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:

void irc_RPL_WHOISUSER string  str  ) 
 

Parses and evaluates RPL_WHOISUSER reply (partial reply to WHOIS command).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Line of message from server

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:

void irc_RPL_YOURID string  str  ) 
 

Parses and evaluates RPL_YOURID reply (your unique ID).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Line of message from server

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 }

void irc_set_redir bool  follow_redirs  ) 
 

Sets value of irc_follow_redirs flag.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
follow_redirs flag to set

Definition at line 6747 of file irc.cpp.

References irc_follow_redirs.

Referenced by logic_exec().

06748 {
06749     irc_follow_redirs=follow_redirs;
06750 }

string irc_to_upper string  str  ) 
 

Converts string to UPPER case (using touppertab[] in match.cpp).

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
str Source string
Returns:
Returns UPPERcase string (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 }

bool irc_unban const char *  channel,
const char *  mask
 

Unbans (MODE #channel -b mask) host mask on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
mask Ban mask
Returns:
Returns false if socket I/O error occured, or channel is longer than 128 chars, or mask is longer than 511 bytes

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:

void irc_user_mode_change string  channel,
string  nick,
string  from_nick,
char  prefix,
char  mode
 

Adds/remove new mode for user on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
nick Nick name
from_nick Which nick set the mode?
prefix '-' or '+'
mode '@' for +o and or '+' for +v, or '&', '', etc.

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:

bool irc_voice const char *  channel,
const char *  nick,
int  priority
 

Sets +v (voice) status to nick on channel.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Channel name
nick Nick name
Returns:
Returns false if socket I/O error occured
Parameters:
priority Priority class (LOW_PRIORITY, HIGH_PRIORITY, or CRITICAL_PRIORITY)

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:

bool logic_botnet_get_user string  name,
s_user user
 

Gets user definition.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
name User name from "logic.txt"
user Returns user
Returns:
Returns true if user was found

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 }

void logic_get_flood_limits string  channel,
string  user,
s_flood msg_flood,
s_flood notice_flood,
s_flood repeat_flood,
s_flood nick_flood,
s_flood join_flood,
s_flood mode_flood,
s_flood ctcp_flood
 

Retrieves flood limits.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
channel Name of channel
user Name of user as defined in logic.txt
msg_flood Returns PRIVMSG flood limit
notice_flood Returns NOTICE flood limit
repeat_flood Returns repeat flood limit
nick_flood Returns NICK flood limit
join_flood Returns JOIN flood limit
mode_flood Returns MODE flood limit
ctcp_flood Returns CTCP flood limit

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:

char* ltoa long  value,
char *  buffer,
int  radix
 

ltoa() emulation for compiler which doesn't have it

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
value Value to convert to string
buffer Output string
radix *MUST* be 10
Returns:
Returns buffer
Bug:
radix MUST be 10!

Definition at line 171 of file dcc.cpp.

00172 {
00173     sprintf(buffer,"%ld",value);
00174     return buffer;
00175 }

void sleep int  ms  ) 
 

Sleeps.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
ms Mili-seconds to sleep

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 }


Variable Documentation

vector<s_dcc_awaiting_user> dcc_awaiting_users
 

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().

vector<s_dcc_request_whois> dcc_request_whois
 

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().

time_t filesys_last_notify
 

Timestam of last filesystem notification.

Definition at line 126 of file irc.cpp.

Referenced by irc_connect(), and irc_loop_putserv().

time_t filesys_notify_interval
 

Interval for filesystem notifications.

Definition at line 125 of file irc.cpp.

Referenced by irc_connect(), and irc_loop_putserv().

list<s_flood_history> flood_history
 

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().

list<s_flood_history> flood_history_other
 

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().

vector<s_online_user> gone_users
 

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().

size_t irc_bot_flood_bytes
 

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().

unsigned int irc_bot_flood_lines
 

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().

time_t irc_bot_flood_other_seconds
 

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().

time_t irc_bot_flood_seconds
 

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().

vector<string> irc_cannot_join_channels
 

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().

vector<s_online_channel> irc_channels
 

List of channels we are on.

Definition at line 141 of file irc.cpp.

bool irc_follow_redirs = false
 

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().

char irc_fullname[512]
 

Bot's current full name.

Definition at line 109 of file irc.cpp.

Referenced by irc_connect(), and logic_exec().

string irc_ident = "*"
 

Bot's ident username.

Definition at line 111 of file irc.cpp.

Referenced by irc_disconnect(), and logic_exec().

s_005 irc_isupport
 

Definition at line 171 of file irc.cpp.

bool irc_keepalive_sent
 

Was WHOIS sent?

Definition at line 106 of file irc.cpp.

Referenced by irc_connect(), irc_disconnect(), and irc_loop_putserv().

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.

Definition at line 139 of file irc.cpp.

Referenced by irc_connect(), and irc_loop_process_input().

time_t irc_last_join_try
 

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().

time_t irc_last_keepalive_detection
 

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().

char irc_nick[512]
 

Bot's current nick.

Definition at line 108 of file irc.cpp.

vector<string> irc_nicks
 

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().

unsigned short irc_recommended_port
 

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().

string irc_recommended_server
 

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().

string irc_server_host
 

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().

vector<s_irc_server>::iterator irc_server_iterator
 

Current irc server.

Definition at line 123 of file irc.cpp.

Referenced by logic_exec().

unsigned short irc_server_port
 

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().

vector<s_irc_server> irc_servers
 

List of irc servers.

Definition at line 122 of file irc.cpp.

Referenced by logic_exec().

s_socket irc_socket
 

Handle of socket connected to server (zero for disconnected state).

Definition at line 104 of file irc.cpp.

bool irc_socket_error
 

If true, then we have socket error on connection to IRC server.

Definition at line 163 of file irc.cpp.

Referenced by irc_connect().

char irc_unique_id[512]
 

Bot's unique ID.

Definition at line 110 of file irc.cpp.

Referenced by irc_connect(), irc_loop_process_input(), and irc_RPL_YOURID().

s_msg_to_server last_msg
 

Last message sent to server.

Definition at line 151 of file irc.cpp.

list<s_mode_queue_entry> mode_queue
 

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().

list<s_mode_queue_entry> modes_from_server
 

Modes that server set.

Definition at line 187 of file irc.cpp.

Referenced by irc_connect(), irc_remove_redundant_mode2(), and irc_RPL_MODE().

list<char*> msgs_from_server
 

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().

list<s_msg_to_server> msgs_to_server
 

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().

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).

Definition at line 161 of file irc.cpp.

Referenced by irc_connect(), irc_disconnect(), irc_loop_putserv(), and irc_putserv().

vector<s_channel_def> r_channel_defs
 

List of real channel definitions (not temporary / compilation!).

Definition at line 222 of file logic.cpp.

vector<s_channel> r_channels
 

List of channels for real usage (not temporary / compilation!).

Definition at line 218 of file logic.cpp.

vector<s_user> r_users
 

List of users for real usage (not temporary / compilation!).

Definition at line 215 of file logic.cpp.

vector<s_online_user> tmp_users
 

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().

vector<s_online_channel> unknown_users_on_channels
 

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().

vector<s_awaiting_response> waiting_for_response
 

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().


Generated on Sun Jul 10 04:26:24 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo