irc_bot.cpp File Reference


Detailed Description

Main file containing entry point.

Definition in file irc_bot.cpp.

#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
#include <map>
#include <list>
#include <string.h>
#include "log.h"
#include "sock.h"
#include "irc.h"
#include "logic.h"
#include "dcc.h"
#include "botnet.h"
#include "conf.h"
#include "stats.h"
#include "identd.h"
#include "ssl.h"
#include "win_sock.h"
#include "exec.h"
#include "filesys.h"
#include "match.h"
#include "params.h"

Include dependency graph for irc_bot.cpp:

Go to the source code of this file.

Defines

#define BOT_DIE   0
 Bot requests to die.
#define BOT_ERROR   1
 Bot requests restart due to internal error.
#define BOT_RESTART   2
 Bot requests restart from parent process.
#define FILE_SLASH   "/"

Functions

void closeall (int fd)
 Close all FDs >= a specified value.
int daemon (bool nochdir, bool noclose, bool stdout_new_pid)
 Detach process from user and disappear into the background returns -1 on failure, but you can't do much except exit in that case since we may already have forked. This is based on the BSD version, so the caller is responsible for things like the umask, etc.
void dcc_broadcast (string msg)
void dcc_close_all ()
 Closes all DCC/telnet connections.
void dcc_close_servers ()
 Closes listening sockets.
void dcc_flush_all ()
 Flushes all pending DCC/telnet connection caches.
void dcc_send_msg (s_socket &socket, string msg, int &ec)
 Sends a message to DCC CHAT / telnet connection and updates statistics.
void disp_license ()
 Displays license information and version.
void handler_sighup (int sig)
 UNIX handler for SIGHUP.
void handler_sigpipe (int sig)
 UNIX handler for SIGPIPE.
void handler_sigterm (int sig)
 UNIX handler for SIGTERM.
char * ltoa (long value, char *buffer, int radix)
 ltoa() emulation for compiler which doesn't have it
int main (int argc, char *argv[])
 Entry point.
void sleep (int ms)
 Sleeps.
void sock_send_cache ()
 Sends and receive all pending data (in the cache), should be called in loop.
string write_kill_log ()
 Writes to log file that bot was asked via DCC / telnet connection to die or restart.

Variables

string binary_name
 Name of binary file (expected how to be the file called).
bool copy_me_to_upper_dir = false
 Contains true if this binary of us should be copied to upper dir (after .upgrade command).
string dcc_killing_user_eol
 EOL string for user (DCC/telnet) who is killing the bot (.die/.restart).
s_socketdcc_killing_user_socket
 Socket of DCC/telnet user who is killing the bot (.die/.restart), or NULL; (will be sent log to it).
bool dcc_want_to_die
 Set to true if .die command wants to kill the bot.
bool dcc_want_to_restart
 Set to true if .restart command wants to restart the bot.
bool dcc_want_to_upgrade
 Set to true if .upgrade command wants to upgrade the bot.
string dcc_who_is_killing
 Name of user (from "logic.txt") who invoked .restart/.die command.
s_socket irc_socket
 Handle of socket connected to server (zero for disconnected state).
bool spawned_by_service = false
 Contains true if the bot is spawned by service.
s_ssl_conf ssl_conf
 Configuration of SSL.
string this_instance_binary
 Contains name of this instance's binary file.


Define Documentation

#define BOT_DIE   0
 

Bot requests to die.

Definition at line 80 of file irc_bot.cpp.

Referenced by daemon(), and main().

#define BOT_ERROR   1
 

Bot requests restart due to internal error.

Definition at line 85 of file irc_bot.cpp.

Referenced by main().

#define BOT_RESTART   2
 

Bot requests restart from parent process.

Definition at line 90 of file irc_bot.cpp.

Referenced by main().

#define FILE_SLASH   "/"
 

Definition at line 291 of file irc_bot.cpp.


Function Documentation

void closeall int  fd  ) 
 

Close all FDs >= a specified value.

Author:
Andrew Gierth
Version:
1
Date:
1997

Definition at line 347 of file irc_bot.cpp.

Referenced by daemon(), and main().

00348 {
00349 #ifndef _WIN32
00350     int fdlimit=sysconf(_SC_OPEN_MAX);
00351 
00352     while(fd<fdlimit)
00353         close(fd++);
00354 #endif
00355 }

int daemon bool  nochdir,
bool  noclose,
bool  stdout_new_pid
 

Detach process from user and disappear into the background returns -1 on failure, but you can't do much except exit in that case since we may already have forked. This is based on the BSD version, so the caller is responsible for things like the umask, etc.

Author:
Andrew Gierth, VooDooMan
Version:
2
Date:
1997, 2004, 2005
Returns:
Returns zero for no error
Note:
Believed to work on all Posix systems
Return values:
0 Okay
-1 Error

Definition at line 370 of file irc_bot.cpp.

References BOT_DIE, closeall(), and sleep().

Referenced by main().

00371 {
00372 #ifndef _WIN32
00373     switch(fork()) {
00374         case 0:  break;
00375         case -1: return -1;
00376         default:
00377             sleep(1000);
00378             _exit(BOT_DIE);          /* exit the original process */
00379     }
00380 
00381     if(setsid()<0)               /* shoudn't fail */
00382         return -1;
00383 
00384     /* dyke out this switch if you want to acquire a control tty in */
00385     /* the future - not normally advisable for daemons */
00386 
00387     switch(fork()) {
00388         case 0:  break;
00389         case -1: return -1;
00390         default:
00391             sleep(1000);
00392             _exit(BOT_DIE);
00393     }
00394 
00395     if(!nochdir)
00396         chdir("/");
00397         
00398     if(stdout_new_pid)
00399         printf("Background process PID is %d\n\n",getpid());
00400 
00401     if(!noclose) {
00402         closeall(0);
00403         open("/dev/null",O_RDWR);
00404         dup(0); dup(0);
00405     }
00406 
00407 #endif
00408     return 0;
00409 }

Here is the call graph for this function:

void dcc_broadcast string  msg  ) 
 

void dcc_close_all  ) 
 

Closes all DCC/telnet connections.

Author:
VooDooMan
Version:
1
Date:
2004

Definition at line 19314 of file dcc.cpp.

References dcc_clients, and sock_close().

Referenced by main().

19315 {
19316     vector<s_dcc_client>::iterator i;
19317     for(i=dcc_clients.begin(); i!=dcc_clients.end(); i++)
19318         sock_close((*i).socket);
19319 }

Here is the call graph for this function:

void dcc_close_servers  ) 
 

Closes listening sockets.

Author:
VooDooMan
Version:
1
Date:
2005

Definition at line 805 of file dcc.cpp.

References dcc_servers, sock_close(), and telnet_servers.

Referenced by dcc_upgrade(), and main().

00806 {
00807     {
00808         vector<s_dcc_server>::iterator i1;
00809     again_a:
00810         for(i1=dcc_servers.begin(); i1!=dcc_servers.end(); i1++) {
00811             sock_close((*i1).socket);
00812             dcc_servers.erase(i1);
00813             goto again_a;
00814         }
00815     }
00816     {
00817         vector<s_telnet_server>::iterator i1;
00818     again_b:
00819         for(i1=telnet_servers.begin(); i1!=telnet_servers.end(); i1++) {
00820             sock_close((*i1).socket);
00821             telnet_servers.erase(i1);
00822             goto again_b;
00823         }
00824     }
00825 }

Here is the call graph for this function:

void dcc_flush_all  ) 
 

Flushes all pending DCC/telnet connection caches.

Author:
VooDooMan
Version:
1
Date:
2004

Definition at line 19300 of file dcc.cpp.

References dcc_clients, sock_flush_later(), and sock_send_cache().

Referenced by main().

19301 {
19302     sock_send_cache();
19303     vector<s_dcc_client>::iterator i;
19304     for(i=dcc_clients.begin(); i!=dcc_clients.end(); i++)
19305         sock_flush_later((*i).socket);
19306 }

Here is the call graph for this function:

void dcc_send_msg s_socket socket,
string  msg,
int &  ec
 

Sends a message to DCC CHAT / telnet connection and updates statistics.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
socket Socket handle
msg Message to send
ec Returns socket I/O error code

Definition at line 791 of file dcc.cpp.

References sock_send(), and stats_dcc_chat_bytes_sent().

Referenced by dcc_apply(), dcc_broadcast(), dcc_check_for_filesystem(), dcc_check_limit(), dcc_loop(), dcc_loop_edit_chan(), dcc_loop_edit_dynbans(), dcc_loop_edit_proc(), dcc_loop_edit_rproc(), dcc_loop_edit_user1(), dcc_loop_edit_user2(), dcc_loop_filesystem(), dcc_loop_language(), dcc_loop_msg(), dcc_loop_new_user(), dcc_loop_private(), dcc_loop_replication(), dcc_loop_terminator(), dcc_notify(), dcc_rehashed(), dcc_upgrade(), dcc_upgrade_bot_join(), dcc_upgrade_bot_mode(), dcc_upgrade_bot_nick(), dcc_user_pong(), and main().

00792 {
00793     ec=0;
00794     size_t sent=sock_send(socket,msg.c_str(),msg.length(),ec);
00795     if(!ec)
00796         stats_dcc_chat_bytes_sent(sent);
00797 }

Here is the call graph for this function:

void disp_license  ) 
 

Displays license information and version.

Author:
VooDooMan
Version:
1
Date:
2004

Definition at line 300 of file irc_bot.cpp.

References VERSION.

Referenced by main().

00301 {
00302     char lic[]="VooDoo cIRCle version " VERSION "\nCopyright (C) 2004 by "
00303         "Marian VooDooMan Meravy (vdmfun@hotmail.com)\n\n"
00304         "VooDoo cIRCle comes with ABSOLUTELY NO WARRANTY; for details "
00305         "see\n`license.html'. This is free software, and you are welcome "
00306         "to redistribute\nit under certain conditions; see the license for details.\n\n"
00307         "This product includes software developed by the OpenSSL Project "
00308         "for use in the\nOpenSSL Toolkit. (http://www.openssl.org/)\n"
00309         "This product includes cryptographic software written by Eric Young\n"
00310         "(eay@cryptsoft.com). This product includes software written by\nTim "
00311         "Hudson (tjh@cryptsoft.com).\n\n\0";
00312     printf(lic);
00313 }

void handler_sighup int  sig  ) 
 

UNIX handler for SIGHUP.

Author:
VooDooMan
Version:
1
Date:
2005
Parameters:
sig Signal type

Definition at line 154 of file irc_bot.cpp.

References dcc_want_to_die, dcc_who_is_killing, and logic_partyline_backup().

Referenced by main().

00155 {
00156     dcc_want_to_die=true;
00157     dcc_who_is_killing="root";
00158     logic_partyline_backup("root");
00159 }

Here is the call graph for this function:

void handler_sigpipe int  sig  ) 
 

UNIX handler for SIGPIPE.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
sig Signal type

Definition at line 128 of file irc_bot.cpp.

References log_debug().

Referenced by main().

00129 {
00130     log_debug("SIGPIPE handler: Broken pipe");
00131 }

Here is the call graph for this function:

void handler_sigterm int  sig  ) 
 

UNIX handler for SIGTERM.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
sig Signal type

Definition at line 140 of file irc_bot.cpp.

References dcc_want_to_die, dcc_who_is_killing, and logic_partyline_backup().

Referenced by main().

00141 {
00142     dcc_want_to_die=true;
00143     dcc_who_is_killing="root";
00144     logic_partyline_backup("root");
00145 }

Here is the call graph for this function:

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

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

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

Definition at line 171 of file dcc.cpp.

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

int main int  argc,
char *  argv[]
 

Entry point.

Author:
VooDooMan
Version:
1
Date:
2004
Parameters:
argc Argument count
argv Array of arguments
Returns:
Returns result action
Return values:
BOT_DIE Zero if bot should die (.die command)
BOT_RESTART If bot wants to be restarted
BOT_ERROR If there's an error

Definition at line 423 of file irc_bot.cpp.

References s_ssl_conf::accept_ca_certs, binary_name, BOT_DIE, BOT_ERROR, BOT_RESTART, botnet_loop(), closeall(), conf_init(), conf_ssl_init(), copy_me_to_upper_dir, daemon(), dcc_broadcast(), dcc_close_all(), dcc_close_servers(), dcc_flush_all(), dcc_killing_user_eol, dcc_send_msg(), dcc_want_to_die, dcc_want_to_restart, dcc_who_is_killing, disp_license(), s_exec_handle::error, exec_async_exec2(), FILE_SLASH, filesys_flush(), handler_sighup(), handler_sigpipe(), handler_sigterm(), irc_disconnect(), irc_loop_process_input(), irc_loop_putserv(), log_bot(), log_done(), log_init(), logic_call_proc_ex2(), logic_exec_from_work(), logic_load_conf(), logic_loop(), logic_loop_identd(), LOGIC_NO_SERVER, logic_on_internal_event(), logic_partyline_backup(), LOGIC_RESTART, LOGIC_SOCKET_ERROR, ltoa(), msgs_from_server, PRIVATE_EVENT_SEVERITY_CODE_FATAL_ERROR, PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL, sleep(), sock_flush_later(), sock_send_cache(), sock_shutdown(), sock_startup(), spawned_by_service, ssl_init(), stats_init(), this_instance_binary, VERSION, and write_kill_log().

00424 {
00425     this_instance_binary=argv[0];
00426     binary_name=argv[0];
00427 #ifndef _WIN32
00428     bool b_interactive=false;
00429 #endif
00430     for(int i1=1; i1<argc; i1++) {
00431         if(!strcmp("--hush",argv[i1])) {
00432 #ifndef _WIN32
00433             closeall(0);
00434             open("/dev/null",O_RDWR);
00435             dup(0); dup(0);
00436 #endif
00437             continue;
00438         }
00439         if(!strcmp("-h",argv[i1]) ||
00440            !strcmp("--help",argv[i1])) {
00441         usage:
00442                disp_license();
00443                printf("%s%s%s\n\n","USAGE: ",argv[0]," [options]");
00444                printf("Options: -h, --help         : this message\n");
00445                printf("         -v, --version      : prints out version only\n");
00446                printf("         -i, --interactive  : run in interactive mode\n");
00447                printf("                              (default on win32)\n");
00448                printf("         -d, --daemon       : run in background, exit immediately\n");
00449                printf("                              (default on non-win32, unused in win32)\n");
00450                printf("\n");
00451                return BOT_DIE;
00452             }
00453         if(!strcmp("-i",argv[i1]) ||
00454            !strcmp("--interactive",argv[i1])) {
00455 #ifndef _WIN32
00456                b_interactive=true;
00457 #endif
00458                continue;
00459            }
00460         if(!strcmp("-v",argv[i1]) ||
00461             !strcmp("--version",argv[i1])) {
00462                 printf("%s\n",VERSION);
00463                 return BOT_DIE;
00464             }
00465         if(!strcmp("-d",argv[i1]) ||
00466             !strcmp("--daemon",argv[i1])) {
00467 #ifndef _WIN32
00468                 b_interactive=false;
00469 #endif
00470                 continue;
00471             }
00472         if(!strncmp("--upgrade=",argv[i1],strlen("--upgrade="))) {
00473             copy_me_to_upper_dir=true;
00474             string tmp=argv[i1];
00475             if(tmp.find("=",0)!=string::npos)
00476                 tmp.erase(0,tmp.find("=",0)+1);
00477             binary_name=tmp;
00478             continue;
00479         }
00480         if(!strcmp("--service",argv[i1])) {
00481             spawned_by_service=true;
00482 #ifndef _WIN32
00483             spawned_by_service=false;
00484 #endif
00485             continue;
00486         }
00487         goto usage;
00488     }
00489     disp_license();
00490 #ifndef _WIN32
00491     if(!b_interactive)
00492         daemon(true,false,true);
00493     signal(SIGPIPE,handler_sigpipe);
00494     signal(SIGTERM,handler_sigterm);
00495     signal(SIGHUP,handler_sighup);
00496 #endif
00497 
00498     srand((unsigned)time(NULL));
00499 
00500     if(conf_init()) {
00501         printf("Cannot open file \"conf.txt\"!\n");
00502         return BOT_ERROR;
00503     }
00504 
00505     if(!log_init()) {
00506         printf("Another instance is running! Exiting with code 0.\n");
00507         return 0;
00508     }
00509 
00510     stats_init();
00511 
00512     sock_startup();
00513 
00514     if(conf_ssl_init()) {
00515         printf("Cannot open file \"ssl.txt\"!\n");
00516         return BOT_ERROR;
00517     }
00518     {
00519         char err_str[1024];
00520         if(ssl_init(err_str,(char*)ssl_conf.accept_ca_certs.c_str())) {
00521             char tmp[2048];
00522             sprintf(tmp,"%s %s","OpenSSL error:",err_str);
00523             log_bot(tmp);
00524             printf("%s\n",tmp);
00525             return BOT_ERROR;
00526         }
00527     }
00528     
00529     int errorline=1;
00530     const char* reason=NULL;
00531     if(logic_load_conf("logic.txt",errorline,reason)) {
00532         char msg[1024];
00533         sprintf(msg,"%s%d","Error in \"logic.txt\" on line #",errorline);
00534         if(reason) {
00535             char m[1024];
00536             sprintf(m," - %s%s","Reason: ",reason);
00537             strcat(msg,m);
00538         }
00539         printf("%s\n",msg);
00540         log_bot(msg);
00541         log_done(BOT_ERROR,"");
00542         return BOT_ERROR;
00543     }
00544 
00545     {
00546         FILE* f=fopen("logs" FILE_SLASH "irc_bot.pid","w");
00547         if(f) {
00548             fprintf(f,"%d\n",getpid());
00549             fclose(f);
00550         }
00551 
00552         unlink("logs" FILE_SLASH "irc_bot.action");
00553     }
00554 
00555 #ifdef _WIN32
00556     SetConsoleCtrlHandler(HandlerRoutine,true);
00557 #endif
00558 
00559     {
00560         string proc="_sys_startup($pid)";
00561         map<string,string> vars;
00562         list<string> parms;
00563         char ch[64];
00564         ch[0]=0;
00565         ltoa(getpid(),ch,10);
00566         parms.push_back(ch);
00567         switch(logic_call_proc_ex2(proc.c_str(),vars,parms,false)) {
00568             case LOGIC_SOCKET_ERROR:
00569             case LOGIC_RESTART:
00570                 dcc_want_to_restart=true;
00571                 dcc_who_is_killing="self";
00572                 logic_partyline_backup("self");
00573                 break;
00574             case LOGIC_NO_SERVER:
00575                 dcc_want_to_die=true;
00576                 dcc_who_is_killing="self";
00577                 logic_partyline_backup("self");
00578                 break;
00579             default:
00580                 break;
00581         }
00582         if(dcc_want_to_die || dcc_want_to_restart) {
00583             string log=write_kill_log();
00584             dcc_broadcast(log);
00585             dcc_flush_all();
00586             irc_disconnect();
00587         }
00588     }
00589 
00590 again:
00591     bool error=false;
00592     while(!dcc_want_to_die && !dcc_want_to_restart) {
00593         if(irc_loop_process_input())
00594             break;
00595         logic_loop();
00596 
00597         logic_loop_identd();
00598 
00599         error=irc_loop_putserv();
00600         if(error)
00601             break;
00602 
00603         botnet_loop();
00604 
00605         {
00606             FILE* f=fopen("logs" FILE_SLASH "irc_bot.action","r");
00607             if(f) {
00608                 char tmp[1024];
00609                 tmp[0]=0;
00610                 fgets(tmp,1024-16,f);
00611                 if(!strcmp(tmp,"die\n") || !strcmp(tmp,"die\r\n") || !strcmp(tmp,"die\r")) {
00612                     dcc_want_to_die=true;
00613                     dcc_who_is_killing="root";
00614                     fclose(f);
00615                     f=NULL;
00616                     unlink("logs" FILE_SLASH "irc_bot.action");
00617                     logic_partyline_backup("root");
00618                 }
00619                 if(!strcmp(tmp,"restart\n") || !strcmp(tmp,"restart\r\n") || !strcmp(tmp,"restart\r")) {
00620                     dcc_want_to_restart=true;
00621                     dcc_who_is_killing="root";
00622                     fclose(f);
00623                     f=NULL;
00624                     unlink("logs" FILE_SLASH "irc_bot.action");
00625                     logic_partyline_backup("root");
00626                 }
00627                 if(f)
00628                     fclose(f);
00629                 f=NULL;
00630             }
00631         }
00632 
00633         {
00634             extern list<char*> msgs_from_server;
00635             if(msgs_from_server.empty())
00636                 sleep(50);
00637             else
00638                 sleep(1);
00639         }
00640         static time_t last_copy_attemp=0;
00641         static bool copy_attemp_successful=false;
00642         if(!copy_attemp_successful && copy_me_to_upper_dir && last_copy_attemp+10<time(NULL)) {
00643             last_copy_attemp=time(NULL);
00644             FILE* f1=fopen(this_instance_binary.c_str(),"rb");
00645             if(f1) {
00646                 FILE* f2=fopen(binary_name.c_str(),"wb");
00647                 if(f2) {
00648                     char tmp[1024];
00649                     while(!feof(f1)) {
00650                         fread(tmp,1,sizeof(tmp),f1);
00651                         fwrite(tmp,1,sizeof(tmp),f2);
00652                     }
00653                     fclose(f2);
00654 #ifndef _WIN32
00655                     chmod(binary_name.c_str(),S_IRWXU);
00656 #endif
00657                     copy_attemp_successful=true;
00658                 }
00659                 fclose(f1);
00660             }
00661         }
00662 #ifdef _WIN32
00663         ProcessMessages();
00664 #endif
00665     }
00666 
00667     if(dcc_want_to_die || dcc_want_to_restart) {
00668         string log=write_kill_log();
00669         dcc_broadcast(log);
00670 
00671         if(dcc_want_to_die)
00672             logic_on_internal_event("@die@",dcc_who_is_killing,"","","",PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL,"","");
00673         if(dcc_want_to_restart)
00674             logic_on_internal_event("@restart@",dcc_who_is_killing,"","","",PRIVATE_EVENT_SEVERITY_CODE_INFORMATIONAL,"","");
00675 
00676         dcc_flush_all();
00677         irc_disconnect();
00678     }
00679 
00680     if(!dcc_want_to_restart && !dcc_want_to_die) {
00681         logic_exec_from_work();
00682         goto again;
00683     }
00684 
00685     if(dcc_want_to_restart) {
00686         dcc_close_servers();
00687         filesys_flush();
00688         dcc_flush_all();
00689 
00690         int ec=0;
00691 
00692         if(!spawned_by_service) {
00693             string tmp=binary_name;
00694             s_exec_handle* h=exec_async_exec2(tmp.c_str(),"--hush",NULL);
00695 
00696             int exit_code;
00697             string disp_log, disp_dcc;
00698             if(h->error) {
00699                 exit_code=BOT_RESTART;
00700 
00701                 disp_log=disp_dcc="RESTART: Error spawning new instance. Something should run it.";
00702                 disp_dcc+=dcc_killing_user_eol;
00703 
00704                 log_bot(disp_log.c_str());
00705 
00706                 logic_on_internal_event("@restart_error@",dcc_who_is_killing,"","","",PRIVATE_EVENT_SEVERITY_CODE_FATAL_ERROR,disp_log,"");
00707 
00708                 if(dcc_killing_user_socket)
00709                     dcc_send_msg(*dcc_killing_user_socket,disp_dcc,ec);
00710             } else
00711                 exit_code=BOT_DIE;
00712 
00713             string log=log_done(exit_code,dcc_killing_user_eol);
00714             ec=0;
00715             if(dcc_killing_user_socket)
00716                 dcc_send_msg(*dcc_killing_user_socket,log,ec);
00717             sock_send_cache();
00718             if(dcc_killing_user_socket)
00719                 sock_flush_later(*dcc_killing_user_socket);
00720 
00721             if(!disp_log.empty() || !disp_dcc.empty()) {
00722                 log_bot(disp_log.c_str());
00723                 if(dcc_killing_user_socket)
00724                     dcc_send_msg(*dcc_killing_user_socket,disp_dcc,ec);
00725             }
00726 
00727             dcc_flush_all();
00728             sleep(1000);
00729             dcc_close_all();
00730             sleep(1000);
00731             sock_shutdown();
00732 
00733             return exit_code;
00734         }
00735 
00736         // it was spawned by service
00737         string log=log_done(BOT_RESTART,dcc_killing_user_eol);
00738         ec=0;
00739         if(dcc_killing_user_socket)
00740             dcc_send_msg(*dcc_killing_user_socket,log,ec);
00741         sock_send_cache();
00742         if(dcc_killing_user_socket)
00743             sock_flush_later(*dcc_killing_user_socket);
00744 
00745         dcc_flush_all();
00746         sleep(1000);
00747         dcc_close_all();
00748         sleep(1000);
00749         sock_shutdown();
00750 
00751         return BOT_RESTART;
00752     }
00753 
00754     string log=log_done(BOT_DIE,dcc_killing_user_eol);
00755     int ec=0;
00756     if(dcc_killing_user_socket)
00757         dcc_send_msg(*dcc_killing_user_socket,log,ec);
00758     sock_send_cache();
00759     if(dcc_killing_user_socket)
00760         sock_flush_later(*dcc_killing_user_socket);
00761 
00762     filesys_flush();
00763 
00764     dcc_flush_all();
00765     sleep(1000);
00766     dcc_close_all();
00767     sleep(1000);
00768     sock_shutdown();
00769     return BOT_DIE;
00770 }

Here is the call graph for this function:

void sleep int  ms  ) 
 

Sleeps.

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

Definition at line 226 of file irc_bot.cpp.

References dcc_loop(), and sock_send_cache().

00227 {
00228 #ifdef _WIN32
00229     ProcessMessages();
00230     sock_send_cache();
00231     if(ms) {
00232         if(ms<1000) {
00233             long ms_remain=ms;
00234             while(ms_remain>0) {
00235                 ProcessMessages();
00236                 sock_send_cache();
00237                 int s=ms_remain>50?50:ms_remain;
00238                 Sleep(s);
00239                 ms_remain-=s;
00240                 ProcessMessages();
00241                 sock_send_cache();
00242             }
00243         } else {
00244             time_t now=time(NULL);
00245             for(;;) {
00246                 Sleep(1);
00247                 ProcessMessages();
00248                 dcc_loop();
00249                 sock_send_cache();
00250                 if(now+ms/1000<time(NULL))
00251                     break;
00252             }
00253         }
00254     }
00255     ProcessMessages();
00256 #else
00257     sock_send_cache();
00258     if(ms) {
00259         if(ms<1000) {
00260             long ms_remain=ms;
00261             while(ms_remain>0) {
00262                 sock_send_cache();
00263                 int s=ms_remain>50?50:ms_remain;
00264                 timeval tv;
00265                 tv.tv_sec=0;
00266                 tv.tv_usec=ms*1000;
00267                 select(1,NULL,NULL,NULL,&tv);
00268                 ms_remain-=s;
00269                 sock_send_cache();
00270             }
00271         } else {
00272             time_t now=time(NULL);
00273             for(;;) {
00274                 timeval tv;
00275                 tv.tv_sec=0;
00276                 tv.tv_usec=1*1000;
00277                 select(1,NULL,NULL,NULL,&tv);
00278                 dcc_loop();
00279                 sock_send_cache();
00280                 if(now+ms/1000<time(NULL))
00281                     break;
00282             }
00283         }
00284     }
00285 #endif
00286 }

Here is the call graph for this function:

void sock_send_cache  ) 
 

Sends and receive all pending data (in the cache), should be called in loop.

Author:
VooDooMan
Version:
2
Date:
2005

Definition at line 488 of file sock.cpp.

Referenced by dcc_broadcast(), dcc_flush_all(), irc_disconnect(), irc_quit(), logic_exec(), main(), and sleep().

00489 {
00490     unsigned int _tmp_size_=1024*64;
00491     char* _tmp_=new char[_tmp_size_];
00492 
00493     vector<s_receive_later>::iterator i2;
00494     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++) {
00495         {
00496             {
00497                 // do a dummy operation
00498                 size_t res=sock_lo_get_input_amount((*i2).socket,_tmp_,_tmp_size_);
00499 
00500                 int error_code=WSAGetLastError();
00501                 if(res!=SOCKET_ERROR)
00502                     error_code=0;
00503                 if(error_code && error_code!=WSAEWOULDBLOCK) {
00504                     if(!(*i2).has_error) {
00505                         (*i2).has_error=true;
00506                         (*i2).last_error=error_code;
00507                     }
00508                 }
00509             }
00510         }
00511 
00512         if((*i2).using_window)
00513             continue;
00514         char tmp[1024];
00515         socklen_t tmp2=1024;
00516         getsockopt((*i2).socket.handle,SOL_SOCKET,SO_ERROR,tmp,&tmp2);
00517 
00518         for(;;) {
00519             {
00520                 // do a dummy operation
00521                 size_t res=sock_lo_get_input_amount((*i2).socket,_tmp_,_tmp_size_);
00522 
00523                 int error_code=WSAGetLastError();
00524                 if(res!=SOCKET_ERROR)
00525                     error_code=0;
00526                 if(error_code && error_code!=WSAEWOULDBLOCK) {
00527                     if(!(*i2).has_error) {
00528                         (*i2).has_error=true;
00529                         (*i2).last_error=error_code;
00530                     }
00531                 }
00532             }
00533 
00534             fd_set a;
00535             timeval t;
00536 
00537             t.tv_sec=0;
00538             t.tv_usec=1;
00539 
00540             FD_ZERO(&a);
00541             FD_SET((*i2).socket.handle,&a);
00542 
00543             int i=select((int)(*i2).socket.handle+1,&a,NULL,NULL,&t);
00544             if(i==0)
00545                 break;
00546 
00547             unsigned int max_size=1024*64;
00548             char* buf=new char[max_size];
00549             //max_size=sock_lo_get_input_amount((*i2).socket,buf,max_size);
00550             size_t size_=sock_lo_recv((*i2).socket,buf,max_size);
00551             if(size_==SOCKET_ERROR) {
00552                 delete[] buf;
00553                 int error_code=WSAGetLastError();
00554                 if(error_code==WSAEWOULDBLOCK)
00555                     break;
00556                 if(!(*i2).has_error) {
00557                     (*i2).has_error=true;
00558                     (*i2).last_error=error_code;
00559                     break;
00560                 }
00561                 break;
00562             }
00563             if(size_>0) {
00564                 (*i2).socket.last_io=time(NULL);
00565                 /*
00566                 vector<s_send_later>::iterator i1;
00567                 i1=send_later.begin();
00568                 if(i1!=send_later.end()) {
00569                     (*i1).socket.last_io=time(NULL);
00570                     (*i1).last_send=time(NULL);
00571                 }
00572                 */
00573                 (*i2).socket.last_io=time(NULL);
00574                 (*i2).last_recv=time(NULL);
00575             }
00576             if(size_==0) {
00577                 delete[] buf;
00578                 if(!(*i2).has_error) {
00579                     s_data d;
00580                     d.closed=true;
00581                     //d.error=0;
00582                     (*i2).data.push_back(d);
00583                     (*i2).has_error=true;
00584                 }
00585                 break;
00586             }
00587             if(size_) {
00588                 s_data d;
00589                 d.closed=false;
00590                 //d.error=0;
00591                 d.len=size_;
00592                 d.data=buf;
00593                 (*i2).data.push_back(d);
00594             }
00595         }
00596     }
00597 
00598     vector<s_send_later>::iterator i1;
00599     for(i1=send_later.begin(); i1!=send_later.end(); i1++) {
00600     again:
00601         list<s_data>::iterator i2;
00602         try {
00603             i2=(*i1).data.begin();
00604         } catch(...) {
00605             continue;
00606         }
00607         for(i2=(*i1).data.begin(); i2!=(*i1).data.end(); i2++) {
00608             size_t l=1024;
00609             if((*i2).len<l)
00610                 l=(*i2).len;
00611             size_t Sent=sock_lo_send((*i1).socket,(*i2).data,l);
00612             if(Sent==SOCKET_ERROR) {
00613                 int la=WSAGetLastError();
00614                 if(la==WSAEWOULDBLOCK)
00615                     break;
00616                 /*if(!(*i1).has_error)*/ {
00617                     vector<s_receive_later>::iterator i2;
00618                     for(i2=receive_later.begin(); i2!=receive_later.end(); i2++)
00619                         if((*i2).socket.handle==(*i1).socket.handle) {
00620                             (*i2).has_error=true;
00621                             if((*i2).last_error==0)
00622                                 (*i2).last_error=la;
00623                             break;
00624                         }
00625                     /*s_data d;
00626                     d.closed=false;
00627                     d.error=la;
00628                     (*i1).data.push_back(d);
00629                     (*i1).has_error=true;*/
00630                 }
00631                 break;
00632             }
00633             if(Sent>0) {
00634                 (*i1).socket.last_io=time(NULL);
00635                 /*
00636                 vector<s_receive_later>::iterator i2;
00637                 i2=receive_later.begin();
00638                 if(i2!=receive_later.end())
00639                     (*i2).socket.last_io=time(NULL);
00640                 */
00641                 (*i1).socket.last_io=time(NULL);
00642                 (*i1).last_send=time(NULL);
00643             }
00644             if(Sent<(*i2).len) {
00645                 char* buf=new char[(*i2).len-Sent];
00646                 memcpy(buf,&(*i2).data[Sent],(*i2).len-Sent);
00647                 delete[] (*i2).data;
00648                 (*i2).len-=Sent;
00649                 (*i2).data=buf;
00650             } else {
00651                 delete[] (*i2).data;
00652                 (*i1).data.pop_front();
00653             }
00654             goto again;
00655         }
00656     }
00657     delete[] _tmp_;
00658 }

string write_kill_log  ) 
 

Writes to log file that bot was asked via DCC / telnet connection to die or restart.

Author:
VooDooMan
Version:
1
Date:
2004
Returns:
Returns log from kill

Definition at line 322 of file irc_bot.cpp.

References dcc_want_to_die, dcc_want_to_restart, dcc_want_to_upgrade, dcc_who_is_killing, irc_quit(), and log_bot().

Referenced by main().

00323 {
00324     string s;
00325     if(dcc_want_to_die)
00326         s="Die by ";
00327     else if(dcc_want_to_restart)
00328         s="Restart by ";
00329     else if(dcc_want_to_upgrade)
00330         s="Upgrade by ";
00331     s+=dcc_who_is_killing;
00332     irc_quit(s.c_str());
00333     if(!dcc_want_to_upgrade)
00334         s=(string)"*** "+s;
00335     else
00336         s=(string)"*** [previous instance] "+s;
00337     log_bot(s.c_str());
00338     return s;
00339 }

Here is the call graph for this function:


Variable Documentation

string binary_name
 

Name of binary file (expected how to be the file called).

Definition at line 109 of file irc_bot.cpp.

Referenced by dcc_upgrade(), and main().

bool copy_me_to_upper_dir = false
 

Contains true if this binary of us should be copied to upper dir (after .upgrade command).

Definition at line 108 of file irc_bot.cpp.

Referenced by main().

string dcc_killing_user_eol
 

EOL string for user (DCC/telnet) who is killing the bot (.die/.restart).

Definition at line 154 of file dcc.cpp.

Referenced by dcc_loop(), dcc_upgrade(), dcc_upgrade_bot_join(), dcc_upgrade_bot_mode(), dcc_upgrade_bot_nick(), and main().

s_socket* dcc_killing_user_socket
 

Socket of DCC/telnet user who is killing the bot (.die/.restart), or NULL; (will be sent log to it).

Definition at line 153 of file dcc.cpp.

bool dcc_want_to_die
 

Set to true if .die command wants to kill the bot.

Definition at line 150 of file dcc.cpp.

bool dcc_want_to_restart
 

Set to true if .restart command wants to restart the bot.

Definition at line 149 of file dcc.cpp.

bool dcc_want_to_upgrade
 

Set to true if .upgrade command wants to upgrade the bot.

Definition at line 151 of file dcc.cpp.

Referenced by dcc_loop(), dcc_set_password(), dcc_upgrade(), filesys_flush(), log_done(), logic_exec(), logic_on_join(), logic_on_nick_change(), logic_partyline_backup(), logic_validate(), and write_kill_log().

string dcc_who_is_killing
 

Name of user (from "logic.txt") who invoked .restart/.die command.

Definition at line 152 of file dcc.cpp.

s_socket irc_socket
 

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

Definition at line 104 of file irc.cpp.

bool spawned_by_service = false
 

Contains true if the bot is spawned by service.

Definition at line 111 of file irc_bot.cpp.

Referenced by main().

s_ssl_conf ssl_conf
 

Configuration of SSL.

Definition at line 66 of file ssl.cpp.

string this_instance_binary
 

Contains name of this instance's binary file.

Definition at line 110 of file irc_bot.cpp.

Referenced by main().


Generated on Sun Jul 10 04:44:37 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo