00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <list>
00038 #include <time.h>
00039 #include <vector>
00040 #include <map>
00041 #include <string>
00042 #include <stdlib.h>
00043
00044 #include "irc.h"
00045 #include "log.h"
00046 #include "sock.h"
00047 #include "logic.h"
00048 #include "dcc.h"
00049 #include "shared.h"
00050 #include "match.h"
00051 #include "filesys.h"
00052 #include "lang.h"
00053 #include "conf.h"
00054 #include "stats.h"
00055
00056 #pragma hdrstop
00057
00058 #ifdef _MSC_VER
00059 # define __FUNC__ __FUNCTION__
00060 #endif
00061
00062 #ifdef __GNUC__
00063 #define __FUNC__ "<unknown>"
00064 #endif
00065
00066 #include "irc.h"
00067
00068 #include "params.h"
00069
00070
00071 #ifdef __BORLANDC__
00072 #pragma package(smart_init)
00073 #endif
00074
00075 using namespace std;
00076
00077 #ifndef _WIN32
00078 #ifndef HAVE_LTOA
00079 extern char *ltoa(long value, char *buffer, int radix);
00080 #endif
00081 #endif
00082
00083 extern 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);
00084 extern bool logic_botnet_get_user(string name, s_user& user);
00085
00086 extern vector<s_dcc_awaiting_user> dcc_awaiting_users;
00087
00088 extern vector<s_channel> r_channels;
00089 extern vector<s_channel_def> r_channel_defs;
00090
00091 extern vector<s_user> r_users;
00092
00093
00094
00095 size_t irc_bot_flood_bytes;
00096 time_t irc_bot_flood_seconds;
00097 unsigned int irc_bot_flood_lines;
00098 time_t irc_bot_flood_other_seconds;
00099
00100 bool irc_follow_redirs=false;
00101 string irc_recommended_server;
00102 unsigned short irc_recommended_port;
00103
00104 s_socket irc_socket;
00105 time_t irc_last_keepalive_detection;
00106 bool irc_keepalive_sent;
00107
00108 char irc_nick[512];
00109 char irc_fullname[512];
00110 char irc_unique_id[512];
00111 string irc_ident="*";
00112
00113 string irc_server_host;
00114 unsigned short irc_server_port;
00115
00116 extern void irc_quoted_callback(const char* str, const char* nick, const char* host_mask);
00117 extern void dcc_loop();
00118
00119 extern vector<s_dcc_request_whois> dcc_request_whois;
00120
00121 vector<string> irc_nicks;
00122 vector<s_irc_server> irc_servers;
00123 vector<s_irc_server>::iterator irc_server_iterator;
00124
00125 time_t filesys_notify_interval;
00126 time_t filesys_last_notify;
00127
00128
00129
00130
00131
00132
00133
00134 struct s_key_chan {
00135 string channel_name;
00136 vector<string> keys;
00137 };
00138
00139 vector<s_key_chan> irc_key_chans;
00140
00141 vector<s_online_channel> irc_channels;
00142
00143 vector<s_online_user> tmp_users;
00144
00145 vector<s_online_user> gone_users;
00146
00147 vector<s_online_channel> unknown_users_on_channels;
00148
00149
00150
00151 s_msg_to_server last_msg;
00152
00153 struct s_awaiting_response {
00154 string message;
00155 time_t time;
00156 };
00157
00158 vector<s_awaiting_response> waiting_for_response;
00159
00160 list<s_msg_to_server> msgs_to_server;
00161 list<s_msg_to_server> msgs_to_server2;
00162 list<char*> msgs_from_server;
00163 bool irc_socket_error;
00164
00165 list<s_flood_history> flood_history;
00166 list<s_flood_history> flood_history_other;
00167
00168 vector<string> irc_cannot_join_channels;
00169 time_t irc_last_join_try;
00170
00171 s_005 irc_isupport;
00172
00173
00174
00175
00176
00177
00178
00179 struct s_mode_queue_entry {
00180 string channel;
00181 string mode;
00182 string param;
00183 time_t submit;
00184 };
00185
00186 list<s_mode_queue_entry> mode_queue;
00187 list<s_mode_queue_entry> modes_from_server;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 void irc_remove_redundant_mode(string channel, string nick, string 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 }
00213
00214
00215
00216
00217
00218
00219
00220 void irc_remove_redundant_mode2()
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
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 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 string irc_to_upper(string str)
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 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 int cmp_strings_case_insensitive(string s1, string s2)
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 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 bool irc_get_online_channel(string channel_name, s_online_channel* &chan)
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 }
00322
00323
00324
00325
00326
00327 #define IRC_MSG_TOO_LONG 0x81234567L
00328
00329
00330
00331
00332 #define SOCK_SEND_ERROR 0x81234568L
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 int irc_putserv_immediately(s_socket& socket, const char* msg, bool wait_for_response=false)
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
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
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;
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
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 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 void irc_parse_modes(string modes, map<char,string>& with_param, string& plain)
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
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
00489 i1++;
00490 }
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 bool irc_putserv(const char* msg, bool wait_for_response, int priority)
00504 {
00505 if(strlen(msg)+2>512) {
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)];
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
00541 int process=0;
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
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
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
00583 }
00584 if((process==1 || process==2) && !param.empty()) {
00585
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
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 }
00622
00623 void irc_check_for_filesystem(string user_name, string channel, string nick);
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 bool irc_loop_putserv()
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 ";
00707 cumulative1+=chan;
00708 cumulative1+=" ";
00709 string cumulative2="";
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)];
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 ";
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;
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;
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
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
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
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
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 }
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 void irc_put_multiple_lines(string command, string nick, string msg)
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
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 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 void irc_check_for_filesystem(string user_name, string channel, string nick)
01134 {
01135 string lang="en";
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 }
01180
01181
01182
01183
01184
01185
01186
01187
01188 int irc_disconnect()
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 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 int irc_connect(const char* bind_ip, const char* host_, unsigned short port)
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
01247
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
01316
01317
01318
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
01327
01328
01329
01330
01331
01332
01333
01334
01335 stats_irc_new_connection(host,port);
01336
01337 return 0;
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347 void irc_RPL_ISUPPORT(string str)
01348 {
01349
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);
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
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 }
01443
01444
01445
01446
01447
01448
01449
01450
01451 void irc_RPL_NAMREPLY(string str)
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);
01459
01460 for(i1=0; i1<str.length(); i1++)
01461 if(str[i1]==0x20)
01462 break;
01463 str.erase(0,i1+1);
01464
01465 for(i1=0; i1<str.length(); i1++)
01466 if(str[i1]==0x20)
01467 break;
01468 str.erase(0,i1+1);
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);
01477
01478 for(i1=0; i1<str.length(); i1++)
01479 if(str[i1]==':')
01480 break;
01481 str.erase(0,i1+1);
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
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);
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
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
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 }
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636 bool irc_check_nick_on_channel(string nick, string channel)
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 }
01650
01651
01652
01653
01654
01655
01656
01657
01658 void irc_RPL_WHOISUSER(string str)
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);
01666
01667 for(i1=0; i1<str.length(); i1++)
01668 if(str[i1]==0x20)
01669 break;
01670 str.erase(0,i1+1);
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);
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);
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);
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);
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;
01763
01764 if(!cmp_strings_case_insensitive(nick,irc_nick)) {
01765
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 }
01779
01780
01781
01782
01783
01784
01785
01786
01787 void irc_RPL_YOURID(string str)
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);
01795
01796 for(i1=0; i1<str.length(); i1++)
01797 if(str[i1]==0x20)
01798 break;
01799 str.erase(0,i1+1);
01800
01801 for(i1=0; i1<str.length(); i1++)
01802 if(str[i1]==0x20)
01803 break;
01804 str.erase(0,i1+1);
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);
01813
01814 if(id.length()<sizeof(irc_unique_id))
01815 strcpy(irc_unique_id,id.c_str());
01816 }
01817
01818
01819
01820
01821
01822
01823
01824
01825 void irc_RPL_WHOISOPERATOR(string str)
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);
01833
01834 for(i1=0; i1<str.length(); i1++)
01835 if(str[i1]==0x20)
01836 break;
01837 str.erase(0,i1+1);
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);
01846
01847 for(i1=0; i1<str.length(); i1++)
01848 if(str[i1]==':')
01849 break;
01850 str.erase(0,i1+1);
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 }
01890
01891
01892
01893
01894
01895
01896
01897
01898 void irc_RPL_WHOISCHANNELS(string str)
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);
01906
01907 for(i1=0; i1<str.length(); i1++)
01908 if(str[i1]==0x20)
01909 break;
01910 str.erase(0,i1+1);
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);
01919
01920 for(i1=0; i1<str.length(); i1++)
01921 if(str[i1]==':')
01922 break;
01923 str.erase(0,i1+1);
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);
01933
01934 if(chan.length()==0)
01935 continue;
01936
01937 char prefix='0';
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
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
01961 prefix='0';
01962 if(chan.length()>1 && chantypes.find(chan[1])!=string::npos)
01963
01964 prefix='+';
01965 if(chan.length()==1)
01966
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
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 }
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 bool irc_access_to_partyline(const char* hostmask, string& user_name_as_in_logic, string msg)
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);
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);
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);
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 }
02082
02083
02084
02085
02086
02087
02088
02089
02090 void irc_RPL_ENDOFWHOIS(string str)
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);
02098
02099 for(i1=0; i1<str.length(); i1++)
02100 if(str[i1]==0x20)
02101 break;
02102 str.erase(0,i1+1);
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);
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 }
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173 void irc_banned(string str)
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);
02181
02182 for(i1=0; i1<str.length(); i1++)
02183 if(str[i1]==0x20)
02184 break;
02185 str.erase(0,i1+1);
02186
02187 for(i1=0; i1<str.length(); i1++)
02188 if(str[i1]==0x20)
02189 break;
02190 str.erase(0,i1+1);
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);
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);
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 }
02217
02218
02219
02220
02221
02222
02223
02224
02225 struct s_user_to_invite {
02226 string mask;
02227 string user_name;
02228
02229 s_user_to_invite()
02230 {
02231 mask="";
02232 user_name="";
02233 }
02234 };
02235
02236
02237
02238
02239
02240
02241
02242
02243 void irc_check_for_not_invited(string channel)
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 }
02288
02289
02290
02291
02292
02293
02294
02295 void irc_check_for_not_reopped(string channel)
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 }
02340
02341
02342
02343
02344
02345
02346
02347
02348 void irc_excepted(string str)
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);
02356
02357 for(i1=0; i1<str.length(); i1++)
02358 if(str[i1]==0x20)
02359 break;
02360 str.erase(0,i1+1);
02361
02362 for(i1=0; i1<str.length(); i1++)
02363 if(str[i1]==0x20)
02364 break;
02365 str.erase(0,i1+1);
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);
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);
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 }
02392
02393
02394
02395
02396
02397
02398
02399
02400 void irc_invited(string str)
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);
02408
02409 for(i1=0; i1<str.length(); i1++)
02410 if(str[i1]==0x20)
02411 break;
02412 str.erase(0,i1+1);
02413
02414 for(i1=0; i1<str.length(); i1++)
02415 if(str[i1]==0x20)
02416 break;
02417 str.erase(0,i1+1);
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);
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);
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 }
02444
02445
02446
02447
02448
02449
02450
02451
02452 void irc_in_reop(string str)
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);
02460
02461 for(i1=0; i1<str.length(); i1++)
02462 if(str[i1]==0x20)
02463 break;
02464 str.erase(0,i1+1);
02465
02466 for(i1=0; i1<str.length(); i1++)
02467 if(str[i1]==0x20)
02468 break;
02469 str.erase(0,i1+1);
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);
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);
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 }
02496
02497
02498
02499
02500
02501
02502
02503
02504 void irc_check_bans(string channel)
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 }
02524
02525
02526
02527
02528
02529
02530
02531
02532 void irc_check_invites(string channel)
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 }
02552
02553
02554
02555
02556
02557
02558
02559
02560 void irc_end_of_excepted(string str)
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);
02568
02569 for(i1=0; i1<str.length(); i1++)
02570 if(str[i1]==0x20)
02571 break;
02572 str.erase(0,i1+1);
02573
02574 for(i1=0; i1<str.length(); i1++)
02575 if(str[i1]==0x20)
02576 break;
02577 str.erase(0,i1+1);
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);
02586
02587 irc_check_bans(channel);
02588 }
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598 s_online_user irc_find_user(string nick)
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="";
02611 return u;
02612 }
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625 void irc_user_mode_change(string channel, string nick, string from_nick, char prefix, char mode)
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 }
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704 void irc_mode_change_creator(string channel, char prefix, string nick, string ident, string host, string whom)
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))
02734 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,'O');
02735 }
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750 void irc_mode_change_op(string channel, char prefix, string nick, string ident, string host, string whom)
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))
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 }
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826 void irc_mode_change_voice(string channel, char prefix, string nick, string ident, string host, string whom)
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))
02856 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,'+');
02857 }
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 void irc_mode_change_other(string channel, char prefix, char mode, string nick, string ident, string host, string whom)
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))
02902 logic_validate(channel,source_user,target_user,source.nick,target.nick,prefix,mode);
02903 }
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918 void irc_mode_change_chan_status(string channel, char prefix, char mode, string nick, string ident, string host)
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 }
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965 void irc_mode_change_chan_key(string channel, char prefix, string nick, string ident, string host, string key)
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 }
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012 void irc_mode_change_chan_limit(string channel, char prefix, string nick, string ident, string host, string limit)
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 }
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059 void irc_mode_change_ban(string channel, char prefix, string nick, string ident, string host, string mask)
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 }
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111 void irc_mode_change_ban_exception(string channel, char prefix, string nick, string ident, string host, string mask)
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 }
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163 void irc_mode_change_invitation(string channel, char prefix, string nick, string ident, string host, string mask)
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
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 }
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214 void irc_mode_change_reop(string channel, char prefix, string nick, string ident, string host, string mask)
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
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 }
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265 void irc_mode_change_other_mask(string channel, char prefix, string nick, string ident, string host, string mask)
03266 {
03267 }
03268
03269
03270
03271
03272
03273
03274
03275
03276 void irc_RPL_324(string str)
03277 {
03278
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);
03288
03289 for(i1=0; i1<str.length(); i1++)
03290 if(str[i1]==' ')
03291 break;
03292 str.erase(0,i1+1);
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);
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);
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="";
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
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 }
03453
03454
03455
03456
03457
03458
03459
03460
03461 void irc_RPL_MODE(string str)
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);
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);
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);
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);
03497 }
03498
03499 for(i1=0; i1<str.length(); i1++)
03500 if(str[i1]==0x20)
03501 break;
03502 str.erase(0,i1+1);
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);
03511
03512 if(!cmp_strings_case_insensitive(target,irc_nick)) {
03513
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);
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
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
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
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
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
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 }
03767
03768
03769
03770
03771
03772
03773
03774
03775 void irc_RPL_TOPIC(string str)
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);
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);
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);
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);
03808
03809 for(i1=0; i1<str.length(); i1++)
03810 if(str[i1]==0x20)
03811 break;
03812 str.erase(0,i1+1);
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);
03821
03822 for(i1=0; i1<str.length(); i1++)
03823 if(str[i1]==':')
03824 break;
03825 str.erase(0,i1+1);
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 }
03836
03837
03838
03839
03840
03841
03842
03843
03844 void irc_kicked(string str)
03845 {
03846 string log=str;
03847 unsigned int i1;
03848
03849 str.erase(0,1);
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);
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);
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);
03874
03875 for(i1=0; i1<str.length(); i1++)
03876 if(str[i1]==0x20)
03877 break;
03878 str.erase(0,i1+1);
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);
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);
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 }
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913 bool irc_check_last_msg(const char* start)
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
03921
03922
03923
03924
03925 if(strstr(last_msg.msg,start)!=last_msg.msg)
03926 same=false;
03927 return same;
03928 }
03929
03930
03931
03932
03933
03934
03935
03936
03937 void irc_kill_last_msg_wait(string resp)
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 }
03946
03947
03948
03949
03950
03951
03952
03953
03954 void irc_kill_command_wait(string command)
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 }
03974
03975
03976
03977
03978
03979
03980
03981 struct s_log {
03982 string msg;
03983 unsigned int num;
03984 time_t time;
03985 };
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997 void irc_check_flood(int type, string channel, string full_host, string msg)
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);
04009
04010 if(!cmp_strings_case_insensitive(nick,(string)irc_nick))
04011
04012 return;
04013
04014 if(type==TYPE_NICK && !cmp_strings_case_insensitive(msg,(string)irc_nick))
04015
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);
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);
04033
04034
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) ) {
04063 user=&(*i3);
04064 got_user=true;
04065 break;
04066 }
04067 }
04068 if(got_user)
04069 break;
04070 }
04071 if(!got_user) {
04072
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
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
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
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
04298 if(type==TYPE_PRIVMSG || type==TYPE_NOTICE || 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
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
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 }
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369 void irc_on_privmsg(string channel, string full_host, string msg)
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);
04381
04382 if(!cmp_strings_case_insensitive(nick,(string)irc_nick))
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);
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);
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
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());
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 }
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467 void irc_on_broadcast(string bcast_mask, int type, string full_host, string msg, string server, unsigned short port)
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);
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);
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);
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
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 }
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536 void irc_on_notice(string channel, string full_host, string msg)
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);
04548
04549 if(!cmp_strings_case_insensitive(nick,(string)irc_nick))
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);
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);
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
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());
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 }
04618
04619 extern void sleep(int ms);
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630 int irc_loop_process_input()
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
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;
04712 string topic;
04713 string notice;
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
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
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
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
04863 if(cmp_strings_case_insensitive(channel,irc_nick)) {
04864
04865 log_channel(channel.c_str(),TYPE_PRIVMSG,hm.c_str(),channel.c_str(),msg.c_str(),"");
04866
04867
04868
04869
04870
04871 logic_on_server_msg(channel,hm,TYPE_PRIVMSG,msg,irc_server_host,irc_server_port);
04872 } else {
04873
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
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
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
05066 if(cmp_strings_case_insensitive(channel,irc_nick)) {
05067
05068 log_channel(channel.c_str(),TYPE_NOTICE,hm.c_str(),channel.c_str(),msg.c_str(),"");
05069
05070
05071
05072
05073
05074 logic_on_server_msg(channel,hm,TYPE_NOTICE,msg,irc_server_host,irc_server_port);
05075 } else {
05076
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,"");
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);
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
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))
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
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 ) {
05373
05374
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
05421 if(users==1 && cmp_strings_case_insensitive(nick,irc_nick)) {
05422
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
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
05511 if(users==1 && cmp_strings_case_insensitive(whom,irc_nick)) {
05512
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
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
05573
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
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
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
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
05681 if(len>4 && str[0]=='3' && str[1]=='5' && str[2]=='3' && str[3]==' ') {
05682 irc_RPL_NAMREPLY(str);
05683 }
05684
05685
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
05694
05695 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='1' && str[3]==' ') {
05696 irc_RPL_WHOISUSER(str);
05697 }
05698
05699
05700
05701 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='3' && str[3]==' ') {
05702 irc_RPL_WHOISOPERATOR(str);
05703 }
05704
05705
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
05715 if(len>4 && str[0]=='3' && str[1]=='1' && str[2]=='9' && str[3]==' ') {
05716 irc_RPL_WHOISCHANNELS(str);
05717 }
05718
05719
05720
05721
05722
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
05755
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;
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
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
05789
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);
05795 if(str.find(" ",0)!=string::npos)
05796 str.erase(0,str.find(" ")+1);
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);
05804 if(str.length() && str[0]=='+')
05805 str.erase(0,1);
05806 if(str.find(" ",0)!=string::npos)
05807 str.erase(str.find(" ",0),str.length()-str.find(" ",0));
05808
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
05823
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);
05829 if(str.find(" ",0)!=string::npos)
05830 str.erase(0,str.find(" ")+1);
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);
05838
05839 if(str.find(":",0)!=string::npos)
05840 str.erase(0,str.find(":")+1);
05841
05842
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
05857
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);
05863 if(str.find(" ",0)!=string::npos)
05864 str.erase(0,str.find(" ")+1);
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);
05872
05873 if(str.find(":",0)!=string::npos)
05874 str.erase(0,str.find(":")+1);
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
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
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
05957
05958 for(i=irc_channels.begin(); i!=irc_channels.end(); i++) {
05959 (*i).got_invites=true;
05960
05961 }
05962
05963
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
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;
06072 goto label_a;
06073 }
06074 }
06075
06076
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
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
06092 if(len>4 && str[0]=='3' && str[1]=='6' && str[2]=='7' && str[3]==' ') {
06093 irc_banned(resp);
06094 }
06095
06096
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
06104 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='6' && str[3]==' ') {
06105 irc_invited(resp);
06106 }
06107
06108
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
06142 if(len>4 && str[0]=='3' && str[1]=='4' && str[2]=='4' && str[3]==' ') {
06143 irc_in_reop(resp);
06144 }
06145
06146
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
06169 if(len>4 && str[0]=='0' && str[1]=='4' && str[2]=='2' && str[3]==' ') {
06170 irc_RPL_YOURID(resp);
06171 }
06172
06173
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
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
06215 }
06216
06217 dcc_loop();
06218
06219 return 0;
06220 }
06221
06222
06223
06224
06225
06226
06227
06228
06229
06230
06231
06232
06233 void irc_internal_set_mode(string channel, string nick, char prefix, char mode)
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
06243
06244
06245
06246
06247
06248
06249
06250 (*i2).old_mode=(*i2).mode;
06251 }
06252 }
06253 }
06254
06255
06256
06257
06258
06259
06260
06261
06262
06263
06264
06265 bool irc_op(const char* channel, const char* nick, int priority)
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 }
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293 bool irc_deop(const char* channel, const char* nick, int priority)
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 }
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321 bool irc_voice(const char* channel, const char* nick, int priority)
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 }
06338
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349 bool irc_devoice(const char* channel, const char* nick, int priority)
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 }
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377 bool irc_kick(const char* channel, const char* nick, const char* reason)
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 }
06398
06399
06400
06401
06402
06403
06404
06405
06406
06407
06408 bool irc_join(const char* channel, const char* key)
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 }
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443 bool irc_part(const char* channel, const char* reason)
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 }
06460
06461
06462
06463
06464
06465
06466
06467
06468
06469
06470
06471 bool irc_privmsg(const char* target, const char* msg, int priority)
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 }
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496
06497 bool irc_notice(const char* target, const char* msg, int priority)
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 }
06512
06513
06514
06515
06516
06517
06518
06519
06520
06521 string irc_get_nick(string user)
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 }
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544 string irc_is_online(string user)
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 }
06558
06559
06560
06561
06562
06563
06564
06565
06566
06567 bool irc_is_ircop(string nick)
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 }
06581
06582
06583
06584
06585
06586
06587
06588
06589
06590
06591
06592
06593
06594
06595 string irc_get_mode(string channel, string nick)
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 }
06613
06614
06615
06616
06617
06618
06619
06620
06621
06622
06623
06624 string irc_get_modes_for_log(string channel, string nick)
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 }
06648
06649
06650
06651
06652
06653
06654
06655
06656
06657 string irc_get_fullname(string nick)
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 }
06673
06674
06675
06676
06677
06678
06679
06680
06681
06682
06683 bool irc_unban(const char* channel, const char* mask)
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 }
06711
06712
06713
06714
06715
06716
06717
06718
06719
06720
06721 bool irc_ban(const char* channel, const char* mask)
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 }
06739
06740
06741
06742
06743
06744
06745
06746
06747 void irc_set_redir(bool follow_redirs)
06748 {
06749 irc_follow_redirs=follow_redirs;
06750 }
06751
06752
06753
06754
06755
06756
06757
06758
06759
06760 string irc_get_ident(string nick)
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 }
06783
06784
06785
06786
06787
06788
06789
06790
06791
06792 string irc_get_host(string nick)
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 }
06815
06816
06817
06818
06819
06820
06821
06822
06823
06824 void irc_put(string data, int priority)
06825 {
06826 irc_putserv(data.c_str(),false,priority);
06827 }
06828
06829
06830
06831
06832
06833
06834
06835
06836
06837
06838
06839 bool irc_chan_mode(const char* channel, const char* mode,int priority)
06840 {
06841 string msg="MODE ";
06842 msg+=channel;
06843 msg+=" ";
06844 msg+=mode;
06845 return !irc_putserv(msg.c_str(),false,priority);
06846 }
06847
06848
06849
06850
06851
06852
06853
06854
06855 void irc_quit(const char* reason)
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
06864 }
06865
06866
06867
06868
06869
06870
06871
06872
06873
06874
06875 void irc_await_dcc_chat(string nick, string user_name_as_in_logic, int dcc_group)
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 }
06908
06909
06910
06911
06912
06913
06914
06915 void irc_rehashed()
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 }
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943 bool irc_got_op(string channel)
06944 {
06945 string m=irc_get_mode(channel,irc_nick);
06946 return m.find(irc_isupport.get_prefix1('o'),0)!=string::npos;
06947 }
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958 string irc_get_chan_mode(string channel, string& topic)
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 }
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984 void irc_get_005(map<string,string>& raw, map<char,char>& prefix, string& chm_a, string& chm_b, string& chm_c, string& chm_d)
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 }
06993