botkernel.cpp

Go to the documentation of this file.
00001 /*
00002 #########################################################################
00003 #
00004 #  This file is part of trustyRC.
00005 #
00006 #  trustyRC, fully modular IRC robot 
00007 #  Copyright (C) 2006-2008 Nicoleau Fabien 
00008 #
00009 #  trustyRC is free software: you can redistribute it and/or modify
00010 #  it under the terms of the GNU General Public License as published by
00011 #  the Free Software Foundation, either version 3 of the License, or
00012 #  (at your option) any later version.
00013 #
00014 #  trustyRC is distributed in the hope that it will be useful,
00015 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 #  GNU General Public License for more details.
00018 #
00019 #  You should have received a copy of the GNU General Public License
00020 #  along with trustyRC.  If not, see <http://www.gnu.org/licenses/>.
00021 #
00022 #########################################################################
00023 */
00024 
00030 #include "botkernel.h"
00031 
00033 sigjmp_buf jmp_buffer;
00035 static void signalHandler(int);
00036 
00044 BotKernel::BotKernel(string confFile)
00045 {
00046    signal(SIGALRM,signalHandler);
00047         this->author = "eponyme (Nicoleau Fabien)";
00048         this->version = VERSION;
00049         this->description = "trustyRC kernel";
00050         this->in_loop_plugins.clear();
00051         this->in_command_handler_plugins.clear();
00052    this->in_free_command_handler_plugins.clear();
00053         this->in_type_handler_plugins.clear();
00054         this->in_before_treatment_plugins.clear();
00055         this->in_all_msgs_plugins.clear();
00056    this->countDowns.clear();
00057         this->sendQueue.clear();
00058 
00059         this->conff=new ConfigurationFile(confFile);
00060         if(!this->conff->load()) {
00061                 cerr << "Error loading configuration file (" + confFile+ "). Exiting..." <<endl;
00062                 exit(0);
00063         }
00064         if (this->conff->getValue("kernel.verbose")=="1") {
00065       this->displayLicenceHeader() ;
00066                 this->verbose=true;
00067    }
00068         else {
00069                 this->verbose=false;
00070    }
00071    this->initDirs();
00072         this->myLog = new LogFile(this->datasDir+"syslog/"+"trustyrc-",this->verbose,(this->conff->getValue("kernel.logkeepfiles")=="1")?true:false,this->conff->getValue("kernel.logminlevel"),this->conff->getValue("kernel.logperiod"));
00073    if ( ! this->myLog->open() ) {
00074       cerr<< "Error opening log file. Nothing will be logged" << endl;
00075    }
00076    this->conff->addProtectedKey("remotecontrol.port");
00077    this->conff->addProtectedKey("remotecontrol.accounts");
00078    this->conff->addProtectedKey("remotecontrol.maxclients");
00079    this->conff->addProtectedKey("admin.sapass");
00080         this->sock=new Socket();
00081    time(&this->startTime);
00082         this->connected=false;
00083         this->turn=true;        
00084         this->loadPlugins(true);
00085    this->AEX.penality = 0;
00086    time(&this->AEX.last_decrease);
00087 }
00088 
00093 BotKernel::~BotKernel()
00094 {
00095         this->myLog->log("Going to delete kernel objects ...",INFO);
00096         this->unloadMyPlugins(false);
00097         delete(this->sock);
00098         delete(this->conff);
00099         delete(this->myLog);
00100 }
00101 
00106 void BotKernel::connect()
00107 {
00108         this->turn=true;
00109         this->myLog->log("Trying to connect to " + this->conff->getValue("kernel.server"),INFO);
00110    while(!this->sock->connectSock(Tools::strToInt(this->conff->getValue("kernel.port")),this->conff->getValue("kernel.server"),this->conff->getValue("kernel.dedicatedIP")))
00111    {    
00112       this->myLog->log("Unable to connect, waiting "+this->conff->getValue("kernel.reco_wait")+" seconds ...",ERROR);
00113       sleep(Tools::strToInt(this->conff->getValue("kernel.reco_wait"))); 
00114    }
00115         this->send(IRCProtocol::identify(this->conff->getValue("kernel.password"),this->conff->getValue("kernel.ident"),this->conff->getValue("kernel.name"),this->conff->getValue("kernel.nick")));
00116         this->setConnected(true);
00117         this->myLog->log("Bot connected : " + this->conff->getValue("kernel.server")+":"+this->conff->getValue("kernel.port")+" (password:"+this->conff->getValue("kernel.password")+") "+this->conff->getValue("kernel.nick")+" "+this->conff->getValue("kernel.ident")+((this->conff->getValue("kernel.dedicatedIP")=="")?"":" through "+this->conff->getValue("kernel.dedicatedIP")),INFO);
00118         this->setNick(this->conff->getValue("kernel.nick"));
00119    time(&this->startOnline);
00120 }
00121 
00126 void BotKernel::reconnect()
00127 {
00128         this->myLog->log("Bot going to reconnect",INFO);
00129    this->sock->closeSock();
00130         delete(this->sock);
00131         this->sock=new Socket();
00132         this->setConnected(false);
00133         this->connect();
00134 }
00135 
00140 void BotKernel::run()
00141 {
00142         time_t now;
00143    vector<CountDownFunction>::iterator it;
00144         bool treatMsg = true;
00145         Message m;
00146    string buffer ;
00147    Tools::log(this->getDatasDir()+"trustyrc.pid",Tools::intToStr(getpid()),false,true) ;
00148    this->connect();
00149    while(this->turn)
00150    {
00151       buffer = this->sock->getOldestMessage();
00152       if (!this->sock->getState()) {
00153          this->myLog->log("Disconnected (read error)",WARNING);
00154          this->setConnected(false);
00155       }
00156       else {
00157          if (buffer.length() > 2 )
00158          {
00159             // \r\n 
00160             if ( buffer[buffer.length()-2] == '\r' ) {
00161                buffer.erase(buffer.length()-2); 
00162             }
00163             else { 
00164                buffer.erase(buffer.length()-1); 
00165             }
00166             if(this->verbose) {
00167                cout << buffer << endl;
00168             }
00169             m.setMessage(buffer);
00170                            treatMsg = true;
00171                            // IN_BEFORE_TREATMENT
00172                            for ( unsigned int i = 0 ; i < this->in_before_treatment_plugins.size() ; i ++ )
00173                            {
00174                                    if(!this->executeFunction(&m,this->in_before_treatment_plugins[i])) {
00175                                            treatMsg = false;
00176                                            break;
00177                                    }
00178                            }
00179                            if(treatMsg) {
00180                     this->msgTreatment(&m);
00181             }
00182          }
00183       }
00184                 // IN_LOOP & COUNTDOWN
00185                 time(&now);
00186       it = this->countDowns.begin();
00187       while ( it != this->countDowns.end() ) {
00188          if ( now >= (*it).timestamp ) {
00189             if(this->executeFunction(&((*it).msg),(*it).function)) {
00190                this->countDowns.erase(it);
00191             }
00192             else {
00193                (*it).timestamp = now + (*it).count;
00194                it ++ ;
00195             }
00196          }
00197          else {
00198             it ++ ;
00199          }
00200       }
00201                 for ( unsigned int i = 0 ; i < this->in_loop_plugins.size() ; i ++ )
00202                 {
00203                         if ( this->in_loop_plugins[i].highlightedWord == "") {
00204                                 this->executeFunction(NULL,this->in_loop_plugins[i]);
00205                         }
00206                         else {
00207                                 if ((now-this->in_loop_plugins[i].lastExec)>= Tools::strToInt(this->in_loop_plugins[i].highlightedWord) ) {
00208                                         this->executeFunction(NULL,this->in_loop_plugins[i]);
00209                                         time(&this->in_loop_plugins[i].lastExec);
00210                                 }
00211                         }
00212                 }
00213                 if (!this->connected && this->turn)
00214                 {
00215                         this->myLog->log("Disconnected, waiting 10 seconds ...",INFO);
00216                         sleep(10);
00217                         this->reconnect();
00218                 }
00219    }
00220    this->sock->closeSock();
00221 }
00222 
00226 void BotKernel::stop()
00227 {
00228         this->myLog->log("stopped !",INFO);
00229         this->turn = false;
00230 }
00231 
00236 void BotKernel::loadPlugins(bool checkDependancy)
00237 {
00238         int plugOK=0,plugNOK=0;
00239         vector<string> plugins = Tools::stringToVector(this->conff->getValue("kernel.plugins"),",",0);
00240         for(unsigned int i =0;i < plugins.size() ; i ++ )
00241         {
00242                 if(this->loadPlugin(plugins[i],checkDependancy)) {
00243                         plugOK++;
00244                 }
00245                 else {
00246                         plugNOK++;
00247                 }
00248         }
00249         this->myLog->log(Tools::intToStr(plugOK)+" plugin(s) successfully loaded. "+Tools::intToStr(plugNOK)+" plugin(s) unsuccessfully loaded.",INFO);
00250 }
00251 
00259 bool BotKernel::loadPlugin(string fileName,bool checkDependancy)
00260 {
00261         void*handle;
00262    char * error;
00263         Plugin* obj;
00264    const unsigned int NBPATHS = 3;
00265    vector<string> requirements;
00266         plugin_constructor constructor;
00267         plugin_destructor destructor;
00268         StructFunctionStorage func;
00269         vector<StructFunctionStorage> funcs;
00270         pPlugin plug;
00271    string paths[NBPATHS] = {this->datasDir+"../plugins",LIBDIR,"plugins"};
00272 
00273    for(unsigned int i = 0 ; i < NBPATHS ; i ++ ) {
00274         handle = dlopen((paths[i]+"/"+fileName).c_str(), RTLD_NOW);
00275         if (handle==NULL) {
00276          continue;
00277       }
00278       constructor = (plugin_constructor)(intptr_t) dlsym(handle,("contruct_"+fileName.substr(0,fileName.find("."))).c_str()); //*(void **)(&constructor) = dlsym(handle,("contruct_"+fileName.substr(0,fileName.find("."))).c_str()); //constructor = (plugin_constructor) dlsym(handle,("contruct_"+fileName.substr(0,fileName.find("."))).c_str());
00279       if (constructor==NULL) {
00280                    this->myLog->log("Cannot load symbol create("+fileName+"): " + dlerror(),ERROR);
00281          return false;
00282       }
00283            destructor = (plugin_destructor)(intptr_t) dlsym(handle, ("destroy_"+fileName.substr(0,fileName.find("."))).c_str()); //*(void **)(&destructor) = dlsym(handle, ("destroy_"+fileName.substr(0,fileName.find("."))).c_str()); // destructor = (plugin_destructor) dlsym(handle, ("destroy_"+fileName.substr(0,fileName.find("."))).c_str());
00284       if (destructor==NULL) {
00285                    this->myLog->log("Cannot load symbol destroy("+fileName+"): " + dlerror(),ERROR);
00286          return false;
00287       } 
00288            obj = constructor(this);
00289 
00290         plug.name = obj->getName();
00291         plug.handle = handle;
00292         plug.object = obj ;
00293         plug.creator = constructor;
00294         plug.destructor = destructor;
00295 
00296            if ( !obj->checkMembers() ) {
00297                 this->myLog->log("Attributs error("+fileName+")",ERROR);
00298                    plug.destructor(plug.object);
00299                 dlclose(plug.handle);
00300                 return false;
00301         }
00302         if ( this->pluginLoaded(plug.name) ) {
00303                 this->myLog->log("Plugin \"" + plug.name + "\" already loaded",WARNING);
00304                 plug.destructor(plug.object);
00305                 dlclose(plug.handle);
00306                 return false;
00307         }
00308       if(checkDependancy) {
00309          requirements = plug.object->getRequirements() ;
00310          for(unsigned int i = 0 ; i < requirements.size() ; i ++ ) {
00311             if(!this->pluginLoaded(requirements[i]) ) {
00312                this->myLog->log("Cannot load "+plug.name+". "+requirements[i]+" is required and not loaded",ERROR);
00313                          plug.destructor(plug.object);
00314                          dlclose(plug.handle);
00315                          return false;
00316             }
00317          }
00318       }
00319       plug.object->setHandle(plug.handle);
00320            this->myPlugins.push_back(plug);
00321            funcs = obj->getFunctions();
00322            for (unsigned int i = 0 ; i < funcs.size() ; i ++ ) {
00323                    func = funcs[i];
00324                    func.handle = handle;        
00325          func.function = (plugin_function)(intptr_t) dlsym(handle, func.symbole.c_str()); //*(void **)(&func.function) = dlsym(handle, func.symbole.c_str()); // func.function = (plugin_function) dlsym(handle, func.symbole.c_str());
00326                    if (func.function==NULL) {
00327                            this->myLog->log("Cannot load symbol "+func.symbole+" ("+fileName+"): " + dlerror(),WARNING);
00328                    }    
00329                    else {
00330             this->storeFunction(&func);
00331                    }
00332            }
00333            this->myLog->log("Plugin "+fileName+" successfully loaded",INFO);
00334            return true;
00335    }
00336    error = dlerror();
00337    if ( error != NULL) {
00338       this->myLog->log("Cannot load library " +fileName+":" + error,ERROR);
00339    }
00340    return false;
00341 }
00342 
00350 bool BotKernel::unloadPlugin(string name,bool checkDependancy)
00351 {
00352         void * handle;
00353    vector<pPlugin>::iterator it = this->myPlugins.begin();
00354         vector<StructFunctionStorage>::iterator it2 ;
00355    if (checkDependancy) {
00356       for(unsigned int i = 0 ; i < this->myPlugins.size() ; i++ ) {
00357          if ( this->myPlugins[i].object->requires(name) ) {
00358             this->myLog->log("Cannot unload "+name+". "+myPlugins[i].name+" requires this plugin and is loaded",ERROR);
00359             return false;
00360          }
00361       }
00362    }
00363    while ( it != this->myPlugins.end() )
00364    {
00365       if ( (*it).name == name )
00366       {
00367                         handle = (*it).handle;
00368                         (*it).destructor((*it).object);
00369          this->myPlugins.erase(it);
00370                         it2 = this->in_loop_plugins.begin();
00371                         while ( it2 != this->in_loop_plugins.end() ) {
00372                                 if ( (*it2).handle == handle )
00373                                         this->in_loop_plugins.erase(it2);
00374                                 else 
00375                                         it2 ++;
00376                         }
00377                         it2 = this->in_command_handler_plugins.begin();
00378                         while ( it2 != this->in_command_handler_plugins.end() ) {
00379                                 if ( (*it2).handle == handle )
00380                                         this->in_command_handler_plugins.erase(it2);
00381                                 else 
00382                                         it2 ++;
00383                         }
00384                         it2 = this->in_free_command_handler_plugins.begin();
00385                         while ( it2 != this->in_free_command_handler_plugins.end() ) {
00386                                 if ( (*it2).handle == handle )
00387                                         this->in_free_command_handler_plugins.erase(it2);
00388                                 else 
00389                                         it2 ++;
00390                         }
00391                         it2 = this->in_type_handler_plugins.begin();
00392                         while ( it2 != this->in_type_handler_plugins.end() ) {
00393                                 if ( (*it2).handle == handle )
00394                                         this->in_type_handler_plugins.erase(it2);
00395                                 else 
00396                                         it2 ++;
00397                         }
00398                         it2 = this->in_before_treatment_plugins.begin();
00399                         while ( it2 != this->in_before_treatment_plugins.end() ) {
00400                                 if ( (*it2).handle == handle )
00401                                         this->in_before_treatment_plugins.erase(it2);
00402                                 else 
00403                                         it2 ++;
00404                         }
00405                         it2 = this->in_all_msgs_plugins.begin();
00406                         while ( it2 != this->in_all_msgs_plugins.end() ) {
00407                                 if ( (*it2).handle == handle )
00408                                         this->in_all_msgs_plugins.erase(it2);
00409                                 else 
00410                                         it2 ++;
00411                         }
00412                         it2 = this->in_first_word_plugins.begin();
00413                         while ( it2 != this->in_first_word_plugins.end() ) {
00414                                 if ( (*it2).handle == handle )
00415                                         this->in_first_word_plugins.erase(it2);
00416                                 else 
00417                                         it2 ++;
00418                         }
00419                         it2 = this->out_all_msgs_plugins.begin();
00420                         while ( it2 != this->out_all_msgs_plugins.end() ) {
00421                                 if ( (*it2).handle == handle )
00422                                         this->out_all_msgs_plugins.erase(it2);
00423                                 else 
00424                                         it2 ++;
00425                         }
00426                         this->myLog->log("Plugin "+name + " unloaded",INFO);
00427                         dlclose(handle);
00428          return true;
00429       }
00430       else
00431          it ++ ;
00432    }
00433    return false;
00434 }
00435 
00441 void BotKernel::unloadMyPlugins(bool checkDependancy)
00442 {
00443         while(this->myPlugins.size()>0)
00444         {
00445                 this->unloadPlugin(this->myPlugins[0].name,checkDependancy);
00446         }
00447 }
00448 
00456 bool BotKernel::pluginLoaded(string name)
00457 {
00458         for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00459         {
00460                 if (this->myPlugins[i].name == name )
00461                         return true;
00462         }
00463         return false;
00464 }
00465 
00472 bool BotKernel::pluginLoaded(void*handle)
00473 {
00474         for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00475         {
00476                 if (this->myPlugins[i].handle == handle )
00477                         return true;
00478         }
00479         return false;
00480 }
00481 
00487 plugin_function BotKernel::storeFunction(StructFunctionStorage*func)
00488 {
00489    switch (func->type) {
00490            case IN_LOOP : this->in_loop_plugins.push_back(*func);    
00491                 break;
00492                 case IN_COMMAND_HANDLER : this->in_command_handler_plugins.push_back(*func);
00493                 break;
00494       case IN_FREE_COMMAND_HANDLER : this->in_free_command_handler_plugins.push_back(*func);
00495       break;
00496                 case IN_TYPE_HANDLER : this->in_type_handler_plugins.push_back(*func);
00497                 break;
00498                 case IN_BEFORE_TREATMENT : this->in_before_treatment_plugins.push_back(*func);
00499                 break;
00500                 case IN_ALL_MSGS : this->in_all_msgs_plugins.push_back(*func);
00501                 break;
00502       case IN_FIRST_WORD : this->in_first_word_plugins.push_back(*func) ;
00503       break;
00504       case OUT_ALL_MSGS : this->out_all_msgs_plugins.push_back(*func) ;
00505       break;
00506            default : this->myLog->log("Undefined func type for "+func->symbole,WARNING);
00507                 return NULL;
00508         }
00509    return func->function ;
00510 }
00511 
00524 plugin_function BotKernel::registerFunction(string hlword,Plugin*object,func_type type,string symbole,plugin_function function,time_t lastExec,unsigned int timeout)
00525 {
00526    if (!this->pluginLoaded(object->getHandle())) {
00527       return NULL;
00528    }
00529    StructFunctionStorage store;
00530    store.handle = object->getHandle();
00531    store.highlightedWord = hlword;
00532    store.object = object;
00533    store.type = type;
00534    store.symbole = symbole;
00535    store.function = function;
00536    store.lastExec = lastExec;
00537    store.timeout = timeout;
00538    return this->storeFunction(&store);
00539 }
00540 
00545 void BotKernel::unregisterFunction(plugin_function func)
00546 {
00547    vector<StructFunctionStorage>::iterator it ;
00548    vector<CountDownFunction>::iterator itCount;
00549    it = this->in_loop_plugins.begin();
00550    while ( it != this->in_loop_plugins.end() ) {
00551       if ( (*it).function == func ) { this->in_loop_plugins.erase(it); return; }
00552       it++;
00553         }
00554         it = this->in_command_handler_plugins.begin();
00555    while ( it != this->in_command_handler_plugins.end() ) {
00556       if ( (*it).function == func ) { this->in_command_handler_plugins.erase(it); return; }
00557       it++;
00558         }
00559         it = this->in_free_command_handler_plugins.begin();
00560    while ( it != this->in_free_command_handler_plugins.end() ) {
00561       if ( (*it).function == func ) { this->in_free_command_handler_plugins.erase(it); return; }
00562       it++;
00563         }
00564         it = this->in_type_handler_plugins.begin();
00565    while ( it != this->in_type_handler_plugins.end() ) {
00566       if ( (*it).function == func ) { this->in_type_handler_plugins.erase(it); return; }
00567       it++;
00568         }
00569         it = this->in_before_treatment_plugins.begin();
00570    while ( it != this->in_before_treatment_plugins.end() ) {
00571       if ( (*it).function == func ) { this->in_before_treatment_plugins.erase(it); return; }
00572       it++;
00573         }
00574         it = this->in_all_msgs_plugins.begin();
00575    while ( it != this->in_all_msgs_plugins.end() ) {
00576       if ( (*it).function == func ) { this->in_all_msgs_plugins.erase(it); return; }
00577       it++;
00578         }
00579         it = this->in_first_word_plugins.begin();
00580    while ( it != this->in_first_word_plugins.end() ) {
00581       if ( (*it).function == func ) { this->in_first_word_plugins.erase(it); return; }
00582       it++;
00583         }
00584         it = this->out_all_msgs_plugins.begin();
00585    while ( it != this->out_all_msgs_plugins.end() ) {
00586       if ( (*it).function == func ) { this->out_all_msgs_plugins.erase(it); return; }
00587       it++;
00588         }
00589    itCount = this->countDowns.begin();
00590    while ( itCount != this->countDowns.end() ) {
00591       if ( (*itCount).function.function == func ) { this->countDowns.erase(itCount); return; }
00592       itCount++;
00593         }
00594 }
00595 
00607 plugin_function BotKernel::addCountDown(Plugin*p,plugin_function f,Message* m,unsigned int count,unsigned int timeout)
00608 {  
00609    string max = this->conff->getValue("kernel.maxcountdowns") ;
00610    if ( (max=="") || (max=="0") || (Tools::strToUnsignedInt(max)>=this->countDowns.size()) ) {
00611       time_t now;
00612       time(&now);
00613       StructFunctionStorage sfs ;
00614       CountDownFunction cdf;
00615       Message msg(m->getMessage());
00616       sfs.handle = p->getHandle();
00617       sfs.highlightedWord = "";
00618       sfs.object = p;
00619       sfs.type = COUNTDOWN;
00620       sfs.symbole = "countDown";
00621       sfs.function = f;
00622       sfs.lastExec = 0;
00623       sfs.timeout = timeout;
00624       cdf.function = sfs;
00625       cdf.msg = msg;
00626       cdf.count = count;
00627       cdf.timestamp=now+count;
00628       this->countDowns.push_back(cdf);
00629       return f;
00630    }
00631    else {
00632       this->myLog->log("Max count downs reached : "+Tools::intToStr(this->countDowns.size()),WARNING);
00633       return NULL;
00634    }
00635 }
00636 
00642 void BotKernel::msgTreatment(Message* msg)
00643 {
00644    // IN_FIRST_WORD
00645    for ( unsigned int i = 0 ; i < this->in_first_word_plugins.size() ; i ++ ) {
00646       if ( msg->getPart(0) == this->in_first_word_plugins[i].highlightedWord ) {
00647          this->executeFunction(msg,this->in_first_word_plugins[i]);      
00648       }
00649    }
00650         // IN_TYPE_HANDLER
00651         if ( msg->getSplit().size() >= 2 ) {
00652                 for ( unsigned int i = 0 ; i < this->in_type_handler_plugins.size() ; i ++ ) {
00653                         if ( msg->getPart(1) == this->in_type_handler_plugins[i].highlightedWord ) {
00654                                 this->executeFunction(msg,this->in_type_handler_plugins[i]);
00655          }
00656                 }
00657         }
00658         // IN_COMMAND_HANDLER & // IN_FREE_COMMAND_HANDLER
00659         if ( msg->nbParts() >= 4 ) {
00660                 for ( unsigned int i = 0 ; i < this->in_command_handler_plugins.size() ; i ++ ) {
00661                         if ( Tools::to_lower(msg->getPart(3)) == ":"+this->conff->getValue("kernel.command_prefix")+Tools::to_lower(this->in_command_handler_plugins[i].highlightedWord) ) {
00662                                 if(!this->executeFunction(msg,this->in_command_handler_plugins[i])) {
00663                return ;
00664             }
00665          }
00666                 }
00667                 for ( unsigned int i = 0 ; i < this->in_free_command_handler_plugins.size() ; i ++ ) {
00668                         if ( msg->getPart(3) == ":"+this->in_free_command_handler_plugins[i].highlightedWord ) {
00669                                 if(!this->executeFunction(msg,this->in_free_command_handler_plugins[i])) {
00670                return;
00671             }
00672          }
00673                 }  
00674         }
00675         // IN_ALL_MSGS
00676         for ( unsigned int i = 0 ; i < this->in_all_msgs_plugins.size() ; i ++ ) {
00677       this->executeFunction(msg,this->in_all_msgs_plugins[i]);
00678         }
00679 }
00680 
00687 bool BotKernel::executeFunction(Message*m,StructFunctionStorage pfs)
00688 {
00689    //cout << "Execution de : " << pfs.symbole << endl;
00690    bool back = true;
00691    alarm(pfs.timeout);
00692    if (!sigsetjmp(jmp_buffer, 1)) {
00693       back = pfs.function(m,pfs.object,this);
00694       alarm(0);
00695       return back;
00696    }
00697    else {
00698       this->myLog->log(pfs.symbole +" timed out",WARNING);
00699       if ((m!=NULL) && (pfs.type!=OUT_ALL_MSGS)) {
00700          this->send(IRCProtocol::sendNotice(m->getNickSender(),pfs.symbole +" timed out")) ;
00701       }
00702       alarm(0);
00703       return true;
00704    }
00705 }
00706 
00711 void BotKernel::send(string str)
00712 {
00713    unsigned int diff=0;
00714    time_t now;
00715    Message msg;
00716    const unsigned int MAXCHARS = Tools::strToUnsignedInt(this->conff->getValue("kernel.maxchars"));
00717    string command;
00718    vector<string> messages;
00719    bool sended;
00720    messages.clear();
00721    if ( (str.length() > MAXCHARS) && (str.find("PRIVMSG ")!=string::npos) ){
00722       command = str.substr(0,str.find(":")+1);
00723       for ( unsigned int i = command.length(); i < str.length() ; i += MAXCHARS-command.length() ) {
00724          messages.push_back(command+str.substr(i,MAXCHARS-command.length()));
00725       }
00726    }
00727    else {
00728       messages.push_back(str);
00729    }
00730    for(unsigned int i = 0 ; i < messages.size();i ++ ) {
00731       // OUT_ALL_MSGS
00732       msg.setMessage(messages[i]);
00733         for ( unsigned int j = 0 ; j < this->out_all_msgs_plugins.size() ; j ++ ) {
00734          if (!this->executeFunction(&msg,this->out_all_msgs_plugins[j]) ) {
00735             return;
00736          }
00737         }
00738       sended = false;
00739       if ( this->conff->getValue("kernel.antief") == "1" ) {
00740          while (!sended)
00741          {
00742             time(&now);
00743             diff = now - this->AEX.last_decrease;
00744             if ( diff > 0 ) {
00745                this->AEX.penality -= diff;
00746                if (this->AEX.penality < 0 )
00747                   this->AEX.penality = 0 ;
00748                time(&this->AEX.last_decrease);
00749             }
00750             if (( this->AEX.penality + 2 ) < 10 ) {
00751                if ( !this->sock->sendStr(msg.getMessage()+"\n") ) {
00752                   this->myLog->log("Disconnected (write error)",WARNING);
00753                   this->setConnected(false);
00754                }
00755                sended = true;
00756                this->AEX.penality += 2 ;
00757             } 
00758          }
00759       }
00760       else {
00761          if ( !this->sock->sendStr(msg.getMessage()+"\n") ) {
00762             this->myLog->log("Disconnected (write error)",WARNING);
00763             this->setConnected(false);
00764          }   
00765       }
00766    }
00767 }
00768 
00773 void BotKernel::send(vector<string> vec)
00774 {
00775         for ( unsigned int i = 0 ; i < vec.size() ; i ++ ) {
00776                 this->send(vec[i]);
00777         }
00778 }
00779 
00783 void BotKernel::displayLicenceHeader() {
00784    cout << "You are running trustyRC "<<this->version<<" by "+this->author+". A C++ IRC robot" << endl;
00785    cout << "trustyRC Copyright (C) 2006-2009  Nicoleau Fabien" << endl;
00786    cout << "This program comes with ABSOLUTELY NO WARRANTY." << endl;
00787    cout << "This is free software, and you are welcome to redistribute it under certain conditions." << endl;
00788    cout << "Read COPYING file for details." << endl << endl;
00789 }
00790 
00794 void BotKernel::initDirs() {
00795    char * pHOME = NULL;
00796    DIR*directory = NULL;
00797    pHOME = getenv("HOME");
00798    string confName = this->conff->getFilePath().substr(this->conff->getFilePath().rfind("/")+1,this->conff->getFilePath().rfind(".")-this->conff->getFilePath().rfind("/")-1);
00799    if ( pHOME != NULL ) {
00800       this->datasDir = (string)pHOME+"/.trustyrc/";
00801    }
00802    else {
00803       this->datasDir = "/tmp/trustyrc/";
00804       cerr<< "Wrong datasdir value. Using "+this->datasDir << endl;
00805    }
00806    directory = opendir(this->datasDir.c_str()) ;
00807    if (directory==NULL) {
00808       if (mkdir(this->datasDir.c_str(),0755) == -1 ) {
00809          cerr << "Unable to create datas dir (check write access?). Can't continue ..." << endl;
00810          exit(-1);
00811       }
00812    }
00813    closedir(directory);
00814    directory = opendir((this->datasDir+"plugins").c_str());
00815    if (directory==NULL) {
00816       if (mkdir((this->datasDir+"plugins").c_str(),0755) == -1 ) {
00817          cerr << "Unable to create alias dir (check write access.). Can't continue ..." << endl;
00818          exit(-1);
00819       }
00820    }
00821    closedir(directory);
00822    directory = opendir((this->datasDir+confName).c_str());
00823    if (directory==NULL) {
00824       if (mkdir((this->datasDir+confName).c_str(),0755) == -1 ) {
00825          cerr << "Unable to create alias dir (check write access.). Can't continue ..." << endl;
00826          exit(-1);
00827       }
00828    }
00829    closedir(directory);
00830    this->datasDir += (confName+"/") ;
00831    directory = opendir((this->datasDir+"syslog").c_str());
00832    if (directory==NULL) {
00833       if (mkdir((this->datasDir+"syslog").c_str(),0755) == -1 ) {
00834          cerr << "Unable to create syslog dir (check write access). Nothing will be logged ..." << endl;
00835       }
00836    }
00837    closedir(directory);
00838 }
00839 
00844 ConfigurationFile* BotKernel::getCONFF()
00845 {
00846         return this->conff;
00847 }
00848 
00853 string BotKernel::getAuthor()
00854 {
00855         return this->author;
00856 }
00857 
00862 string BotKernel::getVersion()
00863 {
00864         return this->version;
00865 }
00866 
00871 string BotKernel::getDescription()
00872 {
00873         return this->description;
00874 }
00875 
00880 LogFile* BotKernel::getSysLog()
00881 {
00882         return this->myLog;
00883 }
00884 
00889 string BotKernel::getNick()
00890 {
00891         return this->nick;
00892 }
00893 
00898 void BotKernel::setNick(string nick)
00899 {
00900    //this->conff->setValue("kernel.nick",nick);
00901         this->nick = nick;
00902 }
00903 
00908 bool BotKernel::getConnected()
00909 {
00910    return this->connected;
00911 }
00912 
00918 void BotKernel::setConnected(bool state)
00919 {
00920         this->connected = state;
00921 }
00922 
00930 pPlugin* BotKernel::getPlugin(string name)
00931 {
00932         if ( !this->pluginLoaded(name) )
00933         {
00934                 return NULL;
00935         }
00936         else
00937         {
00938                 for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00939                 {
00940                         if ( this->myPlugins[i].name == name)
00941                         {
00942                                 return &this->myPlugins[i] ;
00943                         }
00944                 }
00945                 return NULL;
00946         }
00947         return NULL;
00948 }
00949 
00954 vector<string> BotKernel::getPluginsList()
00955 {
00956    vector<string> back;
00957         for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00958         {
00959       back.push_back(this->myPlugins[i].name);
00960         }
00961    return back; 
00962 }
00963 
00968 time_t BotKernel::getStartTime()
00969 {
00970    return this->startTime;
00971 }
00972 
00977 time_t BotKernel::getStartOnline()
00978 {
00979    return this->startOnline;
00980 }
00981 
00986 vector<CountDownFunction>* BotKernel::getCountDowns()
00987 {
00988    return &this->countDowns ;
00989 }
00990 
00995 string BotKernel::getDatasDir() 
00996 {
00997    return this->datasDir;
00998 }
00999 
01004 void signalHandler(int sig)
01005 {
01006    if ( sig == SIGALRM ) {
01007       siglongjmp(jmp_buffer,1);
01008    }
01009 }

Generated on Sun Apr 19 02:47:15 2009 for trustyRC by  doxygen 1.5.7.1