00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #include "botkernel.h"
00032 void * threadFunc (void *);
00033
00041 BotKernel::BotKernel(string confFile)
00042 {
00043 this->author = "eponyme (Nicoleau Fabien)";
00044 this->version = VERSION;
00045 this->description = "trustyRC kernel";
00046 this->in_loop_plugins.clear();
00047 this->in_command_handler_plugins.clear();
00048 this->in_free_command_handler_plugins.clear();
00049 this->in_type_handler_plugins.clear();
00050 this->in_before_treatment_plugins.clear();
00051 this->in_all_msgs_plugins.clear();
00052 this->countDowns.clear();
00053 this->sendQueue.clear();
00054
00055 this->conff=new ConfigurationFile(confFile);
00056 if(!this->conff->load()) {
00057 cerr << "Error loading configuration file (" + confFile+ "). Exiting..." <<endl;
00058 exit(0);
00059 }
00060 if (this->conff->getValue("kernel.verbose")=="1") {
00061 this->displayLicenceHeader() ;
00062 this->verbose=true;
00063 }
00064 else {
00065 this->verbose=false;
00066 }
00067 this->initDirs();
00068 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"));
00069 if ( ! this->myLog->open() ) {
00070 cerr<< "Error opening log file. Nothing will be logged" << endl;
00071 }
00072 this->conff->addProtectedKey("remotecontrol.port");
00073 this->conff->addProtectedKey("remotecontrol.accounts");
00074 this->conff->addProtectedKey("remotecontrol.maxclients");
00075 this->conff->addProtectedKey("admin.sapass");
00076 this->sock=new Socket();
00077 time(&this->startTime);
00078 this->connected=false;
00079 this->turn=true;
00080 this->loadPlugins(true);
00081 this->AEX.penality = 0;
00082 time(&this->AEX.last_decrease);
00083 }
00084
00089 BotKernel::~BotKernel()
00090 {
00091 this->myLog->log("Going to delete kernel objects ...",INFO);
00092 this->unloadMyPlugins(false);
00093 delete(this->sock);
00094 delete(this->conff);
00095 delete(this->myLog);
00096 }
00097
00102 void BotKernel::connect()
00103 {
00104 this->turn=true;
00105 this->myLog->log("Trying to connect to " + this->conff->getValue("kernel.server"),INFO);
00106 while(!this->sock->connectSock(Tools::strToInt(this->conff->getValue("kernel.port")),this->conff->getValue("kernel.server"),this->conff->getValue("kernel.dedicatedIP")))
00107 {
00108 this->myLog->log("Unable to connect, waiting "+this->conff->getValue("kernel.reco_wait")+" seconds ...",ERROR);
00109 sleep(Tools::strToInt(this->conff->getValue("kernel.reco_wait")));
00110 }
00111 this->send(IRCProtocol::identify(this->conff->getValue("kernel.password"),this->conff->getValue("kernel.ident"),this->conff->getValue("kernel.name"),this->conff->getValue("kernel.nick")));
00112 this->setConnected(true);
00113 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);
00114 this->setNick(this->conff->getValue("kernel.nick"));
00115 time(&this->startOnline);
00116 }
00117
00122 void BotKernel::reconnect()
00123 {
00124 this->myLog->log("Bot going to reconnect",INFO);
00125 this->sock->closeSock();
00126 delete(this->sock);
00127 this->sock=new Socket();
00128 this->setConnected(false);
00129 this->connect();
00130 }
00131
00136 void BotKernel::run()
00137 {
00138 time_t now;
00139 vector<CountDownFunction>::iterator it;
00140 list<string> queue;
00141 bool treatMsg = true;
00142 bool complete;
00143 unsigned int startIndex;
00144 Message m;
00145 string buffer;
00146 vector<string> messages;
00147 Tools::log(this->getDatasDir()+"trustyrc.pid",Tools::intToStr(getpid()),false,true) ;
00148 this->connect();
00149 queue.clear();
00150 while(this->turn)
00151 {
00152 if ((!queue.empty())&&(queue.front()[queue.front().length()-1]=='\n')){
00153 buffer = queue.front();
00154 queue.pop_front();
00155 }
00156 else {
00157 buffer = this->sock->receive();
00158 if (!this->sock->getState()) {
00159 this->myLog->log("Disconnected (read error)",WARNING);
00160 this->setConnected(false);
00161 }
00162 else {
00163 if (buffer.length() > 2 )
00164 {
00165 messages = Tools::stringToVector(buffer,"\n",0);
00166 if ( buffer[buffer.length()-1] == '\n') {
00167 complete = true;
00168 }
00169 else {
00170 complete = false;
00171 }
00172 if((!queue.empty())&&(queue.back()[queue.back().length()-1]!='\n')) {
00173 queue.back() += messages[0]+'\n';
00174 startIndex = 1;
00175 }
00176 else {
00177 startIndex = 0 ;
00178 }
00179 for(unsigned int i = startIndex; i < messages.size() ; i ++ ) {
00180 queue.push_back(messages[i]+'\n');
00181 }
00182 if (!complete) {
00183 queue.back() = queue.back().substr(0,queue.back().length()-1);
00184 }
00185 buffer = queue.front();
00186 queue.pop_front();
00187 }
00188 }
00189 }
00190 if (buffer.length() > 2 )
00191 {
00192
00193 if ( buffer[buffer.length()-2] == '\r' ) {
00194 buffer.erase(buffer.length()-2);
00195 }
00196 else {
00197 buffer.erase(buffer.length()-1);
00198 }
00199 if(this->verbose) {
00200 cout << buffer << endl;
00201 }
00202 m.setMessage(buffer);
00203 treatMsg = true;
00204
00205 for ( unsigned int i = 0 ; i < this->in_before_treatment_plugins.size() ; i ++ )
00206 {
00207 if(!this->executeFunction(&m,this->in_before_treatment_plugins[i])) {
00208 treatMsg = false;
00209 break;
00210 }
00211 }
00212 if(treatMsg) {
00213 this->msgTreatment(&m);
00214 }
00215 }
00216
00217 time(&now);
00218 it = this->countDowns.begin();
00219 while ( it != this->countDowns.end() ) {
00220 if ( now >= (*it).timestamp ) {
00221 if(this->executeFunction(&((*it).msg),(*it).function)) {
00222 this->countDowns.erase(it);
00223 }
00224 else {
00225 (*it).timestamp = now + (*it).count;
00226 it ++ ;
00227 }
00228 }
00229 else {
00230 it ++ ;
00231 }
00232 }
00233 for ( unsigned int i = 0 ; i < this->in_loop_plugins.size() ; i ++ )
00234 {
00235 if ( this->in_loop_plugins[i].highlightedWord == "") {
00236 this->executeFunction(NULL,this->in_loop_plugins[i]);
00237 }
00238 else {
00239 if ((now-this->in_loop_plugins[i].lastExec)>= Tools::strToInt(this->in_loop_plugins[i].highlightedWord) ) {
00240 this->executeFunction(NULL,this->in_loop_plugins[i]);
00241 time(&this->in_loop_plugins[i].lastExec);
00242 }
00243 }
00244 }
00245 if (!this->connected && this->turn)
00246 {
00247 this->myLog->log("Disconnected, waiting 10 seconds ...",INFO);
00248 sleep(10);
00249 this->reconnect();
00250 }
00251 }
00252 this->sock->closeSock();
00253 }
00254
00258 void BotKernel::stop()
00259 {
00260 this->myLog->log("stopped !",INFO);
00261 this->turn = false;
00262 }
00263
00268 void BotKernel::loadPlugins(bool checkDependancy)
00269 {
00270 int plugOK=0,plugNOK=0;
00271 vector<string> plugins = Tools::stringToVector(this->conff->getValue("kernel.plugins"),",",0);
00272 for(unsigned int i =0;i < plugins.size() ; i ++ )
00273 {
00274 if(this->loadPlugin(plugins[i],checkDependancy)) {
00275 plugOK++;
00276 }
00277 else {
00278 plugNOK++;
00279 }
00280 }
00281 this->myLog->log(Tools::intToStr(plugOK)+" plugin(s) successfully loaded. "+Tools::intToStr(plugNOK)+" plugin(s) unsuccessfully loaded.",INFO);
00282 }
00283
00291 bool BotKernel::loadPlugin(string fileName,bool checkDependancy)
00292 {
00293 void*handle;
00294 char * error;
00295 Plugin* obj;
00296 const unsigned int NBPATHS = 3;
00297 vector<string> requirements;
00298 plugin_constructor constructor;
00299 plugin_destructor destructor;
00300 StructFunctionStorage func;
00301 vector<StructFunctionStorage> funcs;
00302 pPlugin plug;
00303 string paths[NBPATHS] = {this->datasDir+"../plugins",PLUGINSDIR,"plugins"};
00304
00305 for(unsigned int i = 0 ; i < NBPATHS ; i ++ ) {
00306 handle = dlopen((paths[i]+"/"+fileName).c_str(), RTLD_NOW);
00307 if (handle==NULL) {
00308 continue;
00309 }
00310 constructor = (plugin_constructor)(intptr_t) dlsym(handle,("contruct_"+fileName.substr(0,fileName.find("."))).c_str());
00311 if (constructor==NULL) {
00312 this->myLog->log("Cannot load symbol create("+fileName+"): " + dlerror(),ERROR);
00313 return false;
00314 }
00315 destructor = (plugin_destructor)(intptr_t) dlsym(handle, ("destroy_"+fileName.substr(0,fileName.find("."))).c_str());
00316 if (destructor==NULL) {
00317 this->myLog->log("Cannot load symbol destroy("+fileName+"): " + dlerror(),ERROR);
00318 return false;
00319 }
00320 obj = constructor(this);
00321
00322 plug.name = obj->getName();
00323 plug.handle = handle;
00324 plug.object = obj ;
00325 plug.creator = constructor;
00326 plug.destructor = destructor;
00327
00328 if ( !obj->checkMembers() ) {
00329 this->myLog->log("Attributs error("+fileName+")",ERROR);
00330 plug.destructor(plug.object);
00331 dlclose(plug.handle);
00332 return false;
00333 }
00334 if ( this->pluginLoaded(plug.name) ) {
00335 this->myLog->log("Plugin \"" + plug.name + "\" already loaded",WARNING);
00336 plug.destructor(plug.object);
00337 dlclose(plug.handle);
00338 return false;
00339 }
00340 if(checkDependancy) {
00341 requirements = plug.object->getRequirements() ;
00342 for(unsigned int i = 0 ; i < requirements.size() ; i ++ ) {
00343 if(!this->pluginLoaded(requirements[i]) ) {
00344 this->myLog->log("Cannot load "+plug.name+". "+requirements[i]+" is required and not loaded",ERROR);
00345 plug.destructor(plug.object);
00346 dlclose(plug.handle);
00347 return false;
00348 }
00349 }
00350 }
00351 plug.object->setHandle(plug.handle);
00352 this->myPlugins.push_back(plug);
00353 funcs = obj->getFunctions();
00354 for (unsigned int i = 0 ; i < funcs.size() ; i ++ ) {
00355 func = funcs[i];
00356 func.handle = handle;
00357 func.function = (plugin_function)(intptr_t) dlsym(handle, func.symbole.c_str());
00358 if (func.function==NULL) {
00359 this->myLog->log("Cannot load symbol "+func.symbole+" ("+fileName+"): " + dlerror(),WARNING);
00360 }
00361 else {
00362 this->storeFunction(&func);
00363 }
00364 }
00365 this->myLog->log("Plugin "+fileName+" successfully loaded",INFO);
00366 return true;
00367 }
00368 error = dlerror();
00369 if ( error != NULL) {
00370 this->myLog->log("Cannot load library " +fileName+":" + error,ERROR);
00371 }
00372 return false;
00373 }
00374
00382 bool BotKernel::unloadPlugin(string name,bool checkDependancy)
00383 {
00384 void * handle;
00385 vector<pPlugin>::iterator it = this->myPlugins.begin();
00386 vector<StructFunctionStorage>::iterator it2 ;
00387 if (checkDependancy) {
00388 for(unsigned int i = 0 ; i < this->myPlugins.size() ; i++ ) {
00389 if ( this->myPlugins[i].object->requires(name) ) {
00390 this->myLog->log("Cannot unload "+name+". "+myPlugins[i].name+" requires this plugin and is loaded",ERROR);
00391 return false;
00392 }
00393 }
00394 }
00395 while ( it != this->myPlugins.end() )
00396 {
00397 if ( (*it).name == name )
00398 {
00399 handle = (*it).handle;
00400 (*it).destructor((*it).object);
00401 this->myPlugins.erase(it);
00402 it2 = this->in_loop_plugins.begin();
00403 while ( it2 != this->in_loop_plugins.end() ) {
00404 if ( (*it2).handle == handle )
00405 this->in_loop_plugins.erase(it2);
00406 else
00407 it2 ++;
00408 }
00409 it2 = this->in_command_handler_plugins.begin();
00410 while ( it2 != this->in_command_handler_plugins.end() ) {
00411 if ( (*it2).handle == handle )
00412 this->in_command_handler_plugins.erase(it2);
00413 else
00414 it2 ++;
00415 }
00416 it2 = this->in_free_command_handler_plugins.begin();
00417 while ( it2 != this->in_free_command_handler_plugins.end() ) {
00418 if ( (*it2).handle == handle )
00419 this->in_free_command_handler_plugins.erase(it2);
00420 else
00421 it2 ++;
00422 }
00423 it2 = this->in_type_handler_plugins.begin();
00424 while ( it2 != this->in_type_handler_plugins.end() ) {
00425 if ( (*it2).handle == handle )
00426 this->in_type_handler_plugins.erase(it2);
00427 else
00428 it2 ++;
00429 }
00430 it2 = this->in_before_treatment_plugins.begin();
00431 while ( it2 != this->in_before_treatment_plugins.end() ) {
00432 if ( (*it2).handle == handle )
00433 this->in_before_treatment_plugins.erase(it2);
00434 else
00435 it2 ++;
00436 }
00437 it2 = this->in_all_msgs_plugins.begin();
00438 while ( it2 != this->in_all_msgs_plugins.end() ) {
00439 if ( (*it2).handle == handle )
00440 this->in_all_msgs_plugins.erase(it2);
00441 else
00442 it2 ++;
00443 }
00444 it2 = this->in_first_word_plugins.begin();
00445 while ( it2 != this->in_first_word_plugins.end() ) {
00446 if ( (*it2).handle == handle )
00447 this->in_first_word_plugins.erase(it2);
00448 else
00449 it2 ++;
00450 }
00451 it2 = this->out_all_msgs_plugins.begin();
00452 while ( it2 != this->out_all_msgs_plugins.end() ) {
00453 if ( (*it2).handle == handle )
00454 this->out_all_msgs_plugins.erase(it2);
00455 else
00456 it2 ++;
00457 }
00458 this->myLog->log("Plugin "+name + " unloaded",INFO);
00459 dlclose(handle);
00460 return true;
00461 }
00462 else
00463 it ++ ;
00464 }
00465 return false;
00466 }
00467
00473 void BotKernel::unloadMyPlugins(bool checkDependancy)
00474 {
00475 while(this->myPlugins.size()>0)
00476 {
00477 this->unloadPlugin(this->myPlugins[0].name,checkDependancy);
00478 }
00479 }
00480
00488 bool BotKernel::pluginLoaded(string name)
00489 {
00490 for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00491 {
00492 if (this->myPlugins[i].name == name )
00493 return true;
00494 }
00495 return false;
00496 }
00497
00504 bool BotKernel::pluginLoaded(void*handle)
00505 {
00506 for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00507 {
00508 if (this->myPlugins[i].handle == handle )
00509 return true;
00510 }
00511 return false;
00512 }
00513
00519 plugin_function BotKernel::storeFunction(StructFunctionStorage*func)
00520 {
00521 switch (func->type) {
00522 case IN_LOOP : this->in_loop_plugins.push_back(*func);
00523 break;
00524 case IN_COMMAND_HANDLER : this->in_command_handler_plugins.push_back(*func);
00525 break;
00526 case IN_FREE_COMMAND_HANDLER : this->in_free_command_handler_plugins.push_back(*func);
00527 break;
00528 case IN_TYPE_HANDLER : this->in_type_handler_plugins.push_back(*func);
00529 break;
00530 case IN_BEFORE_TREATMENT : this->in_before_treatment_plugins.push_back(*func);
00531 break;
00532 case IN_ALL_MSGS : this->in_all_msgs_plugins.push_back(*func);
00533 break;
00534 case IN_FIRST_WORD : this->in_first_word_plugins.push_back(*func) ;
00535 break;
00536 case OUT_ALL_MSGS : this->out_all_msgs_plugins.push_back(*func) ;
00537 break;
00538 default : this->myLog->log("Undefined func type for "+func->symbole,WARNING);
00539 return NULL;
00540 }
00541 return func->function ;
00542 }
00543
00556 plugin_function BotKernel::registerFunction(string hlword,Plugin*object,func_type type,string symbole,plugin_function function,time_t lastExec,unsigned int timeout)
00557 {
00558 if (!this->pluginLoaded(object->getHandle())) {
00559 return NULL;
00560 }
00561 StructFunctionStorage store;
00562 store.handle = object->getHandle();
00563 store.highlightedWord = hlword;
00564 store.object = object;
00565 store.type = type;
00566 store.symbole = symbole;
00567 store.function = function;
00568 store.lastExec = lastExec;
00569 store.timeout = timeout;
00570 return this->storeFunction(&store);
00571 }
00572
00577 void BotKernel::unregisterFunction(plugin_function func)
00578 {
00579 vector<StructFunctionStorage>::iterator it ;
00580 vector<CountDownFunction>::iterator itCount;
00581 it = this->in_loop_plugins.begin();
00582 while ( it != this->in_loop_plugins.end() ) {
00583 if ( (*it).function == func ) { this->in_loop_plugins.erase(it); return; }
00584 it++;
00585 }
00586 it = this->in_command_handler_plugins.begin();
00587 while ( it != this->in_command_handler_plugins.end() ) {
00588 if ( (*it).function == func ) { this->in_command_handler_plugins.erase(it); return; }
00589 it++;
00590 }
00591 it = this->in_free_command_handler_plugins.begin();
00592 while ( it != this->in_free_command_handler_plugins.end() ) {
00593 if ( (*it).function == func ) { this->in_free_command_handler_plugins.erase(it); return; }
00594 it++;
00595 }
00596 it = this->in_type_handler_plugins.begin();
00597 while ( it != this->in_type_handler_plugins.end() ) {
00598 if ( (*it).function == func ) { this->in_type_handler_plugins.erase(it); return; }
00599 it++;
00600 }
00601 it = this->in_before_treatment_plugins.begin();
00602 while ( it != this->in_before_treatment_plugins.end() ) {
00603 if ( (*it).function == func ) { this->in_before_treatment_plugins.erase(it); return; }
00604 it++;
00605 }
00606 it = this->in_all_msgs_plugins.begin();
00607 while ( it != this->in_all_msgs_plugins.end() ) {
00608 if ( (*it).function == func ) { this->in_all_msgs_plugins.erase(it); return; }
00609 it++;
00610 }
00611 it = this->in_first_word_plugins.begin();
00612 while ( it != this->in_first_word_plugins.end() ) {
00613 if ( (*it).function == func ) { this->in_first_word_plugins.erase(it); return; }
00614 it++;
00615 }
00616 it = this->out_all_msgs_plugins.begin();
00617 while ( it != this->out_all_msgs_plugins.end() ) {
00618 if ( (*it).function == func ) { this->out_all_msgs_plugins.erase(it); return; }
00619 it++;
00620 }
00621 itCount = this->countDowns.begin();
00622 while ( itCount != this->countDowns.end() ) {
00623 if ( (*itCount).function.function == func ) { this->countDowns.erase(itCount); return; }
00624 itCount++;
00625 }
00626 }
00627
00639 plugin_function BotKernel::addCountDown(Plugin*p,plugin_function f,Message* m,unsigned int count,unsigned int timeout)
00640 {
00641 string max = this->conff->getValue("kernel.maxcountdowns") ;
00642 if ( (max=="") || (max=="0") || (Tools::strToUnsignedInt(max)>=this->countDowns.size()) ) {
00643 time_t now;
00644 time(&now);
00645 StructFunctionStorage sfs ;
00646 CountDownFunction cdf;
00647 Message msg(m->getMessage());
00648 sfs.handle = p->getHandle();
00649 sfs.highlightedWord = "";
00650 sfs.object = p;
00651 sfs.type = COUNTDOWN;
00652 sfs.symbole = "countDown";
00653 sfs.function = f;
00654 sfs.lastExec = 0;
00655 sfs.timeout = timeout;
00656 cdf.function = sfs;
00657 cdf.msg = msg;
00658 cdf.count = count;
00659 cdf.timestamp=now+count;
00660 this->countDowns.push_back(cdf);
00661 return f;
00662 }
00663 else {
00664 this->myLog->log("Max count downs reached : "+Tools::intToStr(this->countDowns.size()),WARNING);
00665 return NULL;
00666 }
00667 }
00668
00674 void BotKernel::msgTreatment(Message* msg)
00675 {
00676
00677 for ( unsigned int i = 0 ; i < this->in_first_word_plugins.size() ; i ++ ) {
00678 if ( msg->getPart(0) == this->in_first_word_plugins[i].highlightedWord ) {
00679 this->executeFunction(msg,this->in_first_word_plugins[i]);
00680 }
00681 }
00682
00683 if ( msg->getSplit().size() >= 2 ) {
00684 for ( unsigned int i = 0 ; i < this->in_type_handler_plugins.size() ; i ++ ) {
00685 if ( msg->getPart(1) == this->in_type_handler_plugins[i].highlightedWord ) {
00686 this->executeFunction(msg,this->in_type_handler_plugins[i]);
00687 }
00688 }
00689 }
00690
00691 if ( msg->nbParts() >= 4 ) {
00692 for ( unsigned int i = 0 ; i < this->in_command_handler_plugins.size() ; i ++ ) {
00693 if ( Tools::to_lower(msg->getPart(3)) == ":"+this->conff->getValue("kernel.command_prefix")+Tools::to_lower(this->in_command_handler_plugins[i].highlightedWord) ) {
00694 if(!this->executeFunction(msg,this->in_command_handler_plugins[i])) {
00695 return ;
00696 }
00697 }
00698 }
00699 for ( unsigned int i = 0 ; i < this->in_free_command_handler_plugins.size() ; i ++ ) {
00700 if ( msg->getPart(3) == ":"+this->in_free_command_handler_plugins[i].highlightedWord ) {
00701 if(!this->executeFunction(msg,this->in_free_command_handler_plugins[i])) {
00702 return;
00703 }
00704 }
00705 }
00706 }
00707
00708 for ( unsigned int i = 0 ; i < this->in_all_msgs_plugins.size() ; i ++ ) {
00709 this->executeFunction(msg,this->in_all_msgs_plugins[i]);
00710 }
00711 }
00712
00719 bool BotKernel::executeFunction(Message*m,StructFunctionStorage pfs)
00720 {
00721
00722 sem_t my_sem;
00723 sem_init (&my_sem, 0, 0);
00724 CPPThread th;
00725 ThreadParams tp;
00726 tp.function = &pfs;
00727 tp.b = this;
00728 tp.msg = m;
00729 tp.sem = &my_sem;
00730 struct timespec my_timeout;
00731 struct timeval now;
00732 gettimeofday(&now,NULL);
00733 my_timeout.tv_sec = now.tv_sec + pfs.timeout;
00734 my_timeout.tv_nsec = now.tv_usec * 1000;
00735 th.exec(threadFunc,&tp);
00736 int back = sem_timedwait(&my_sem,&my_timeout);
00737 if ((back == -1)&&(errno == ETIMEDOUT)) {
00738 this->myLog->log(pfs.symbole +" timed out",WARNING);
00739 th.terminate();
00740 if ((m!=NULL) && (pfs.type!=OUT_ALL_MSGS)) {
00741 this->send(IRCProtocol::sendNotice(m->getNickSender(),pfs.symbole +" timed out")) ;
00742 }
00743 return true;
00744 }
00745 else {
00746 th.join();
00747 return pfs.back;
00748 }
00749 return true;
00750 }
00751
00756 void BotKernel::send(string str)
00757 {
00758 unsigned int diff=0;
00759 time_t now;
00760 Message msg;
00761 const unsigned int MAXCHARS = 450;
00762 string command;
00763 vector<string> messages;
00764 bool sended;
00765 messages.clear();
00766 if ( (str.length() > MAXCHARS) && (str.find("PRIVMSG ")!=string::npos) ){
00767 command = str.substr(0,str.find(":")+1);
00768 for ( unsigned int i = command.length(); i < str.length() ; i += MAXCHARS-command.length() ) {
00769 messages.push_back(command+str.substr(i,MAXCHARS-command.length()));
00770 }
00771 }
00772 else {
00773 messages.push_back(str);
00774 }
00775 for(unsigned int i = 0 ; i < messages.size();i ++ ) {
00776
00777 msg.setMessage(messages[i]);
00778 for ( unsigned int j = 0 ; j < this->out_all_msgs_plugins.size() ; j ++ ) {
00779 if (!this->executeFunction(&msg,this->out_all_msgs_plugins[j]) ) {
00780 return;
00781 }
00782 }
00783 sended = false;
00784 if ( this->conff->getValue("kernel.antief") == "1" ) {
00785 while (!sended)
00786 {
00787 time(&now);
00788 diff = now - this->AEX.last_decrease;
00789 if ( diff > 0 ) {
00790 this->AEX.penality -= diff;
00791 if (this->AEX.penality < 0 )
00792 this->AEX.penality = 0 ;
00793 time(&this->AEX.last_decrease);
00794 }
00795 if (( this->AEX.penality + 2 ) < 10 ) {
00796 if ( !this->sock->sendStr(msg.getMessage()+"\n") ) {
00797 this->myLog->log("Disconnected (write error)",WARNING);
00798 this->setConnected(false);
00799 }
00800 sended = true;
00801 this->AEX.penality += 2 ;
00802 }
00803 }
00804 }
00805 else {
00806 if ( !this->sock->sendStr(msg.getMessage()+"\n") ) {
00807 this->myLog->log("Disconnected (write error)",WARNING);
00808 this->setConnected(false);
00809 }
00810 }
00811 }
00812 }
00813
00818 void BotKernel::send(vector<string> vec)
00819 {
00820 for ( unsigned int i = 0 ; i < vec.size() ; i ++ ) {
00821 this->send(vec[i]);
00822 }
00823 }
00824
00828 void BotKernel::displayLicenceHeader() {
00829 cout << "You are running trustyRC "<<this->version<<" by "+this->author+". A C++ IRC robot" << endl;
00830 cout << "trustyRC Copyright (C) 2006-2009 Nicoleau Fabien" << endl;
00831 cout << "This program comes with ABSOLUTELY NO WARRANTY." << endl;
00832 cout << "This is free software, and you are welcome to redistribute it under certain conditions." << endl;
00833 cout << "Read COPYING file for details." << endl << endl;
00834 }
00835
00839 void BotKernel::initDirs() {
00840 char * pHOME = NULL;
00841 DIR*directory = NULL;
00842 pHOME = getenv("HOME");
00843 string confName = this->conff->getFilePath().substr(this->conff->getFilePath().rfind("/")+1,this->conff->getFilePath().rfind(".")-this->conff->getFilePath().rfind("/")-1);
00844 if ( pHOME != NULL ) {
00845 this->datasDir = (string)pHOME+"/.trustyrc/";
00846 }
00847 else {
00848 this->datasDir = "/tmp/trustyrc/";
00849 cerr<< "Wrong datasdir value. Using "+this->datasDir << endl;
00850 }
00851 directory = opendir(this->datasDir.c_str()) ;
00852 if (directory==NULL) {
00853 if (mkdir(this->datasDir.c_str(),0755) == -1 ) {
00854 cerr << "Unable to create datas dir (check write access?). Can't continue ..." << endl;
00855 exit(-1);
00856 }
00857 }
00858 closedir(directory);
00859 directory = opendir((this->datasDir+"plugins").c_str());
00860 if (directory==NULL) {
00861 if (mkdir((this->datasDir+"plugins").c_str(),0755) == -1 ) {
00862 cerr << "Unable to create alias dir (check write access.). Can't continue ..." << endl;
00863 exit(-1);
00864 }
00865 }
00866 closedir(directory);
00867 directory = opendir((this->datasDir+confName).c_str());
00868 if (directory==NULL) {
00869 if (mkdir((this->datasDir+confName).c_str(),0755) == -1 ) {
00870 cerr << "Unable to create alias dir (check write access.). Can't continue ..." << endl;
00871 exit(-1);
00872 }
00873 }
00874 closedir(directory);
00875 this->datasDir += (confName+"/") ;
00876 directory = opendir((this->datasDir+"syslog").c_str());
00877 if (directory==NULL) {
00878 if (mkdir((this->datasDir+"syslog").c_str(),0755) == -1 ) {
00879 cerr << "Unable to create syslog dir (check write access). Nothing will be logged ..." << endl;
00880 }
00881 }
00882 closedir(directory);
00883 }
00884
00889 ConfigurationFile* BotKernel::getCONFF()
00890 {
00891 return this->conff;
00892 }
00893
00898 string BotKernel::getAuthor()
00899 {
00900 return this->author;
00901 }
00902
00907 string BotKernel::getVersion()
00908 {
00909 return this->version;
00910 }
00911
00916 string BotKernel::getDescription()
00917 {
00918 return this->description;
00919 }
00920
00925 LogFile* BotKernel::getSysLog()
00926 {
00927 return this->myLog;
00928 }
00929
00934 string BotKernel::getNick()
00935 {
00936 return this->nick;
00937 }
00938
00943 void BotKernel::setNick(string nick)
00944 {
00945
00946 this->nick = nick;
00947 }
00948
00953 bool BotKernel::getConnected()
00954 {
00955 return this->connected;
00956 }
00957
00963 void BotKernel::setConnected(bool state)
00964 {
00965 this->connected = state;
00966 }
00967
00975 pPlugin* BotKernel::getPlugin(string name)
00976 {
00977 if ( !this->pluginLoaded(name) )
00978 {
00979 return NULL;
00980 }
00981 else
00982 {
00983 for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
00984 {
00985 if ( this->myPlugins[i].name == name)
00986 {
00987 return &this->myPlugins[i] ;
00988 }
00989 }
00990 return NULL;
00991 }
00992 return NULL;
00993 }
00994
00999 vector<string> BotKernel::getPluginsList()
01000 {
01001 vector<string> back;
01002 for ( unsigned int i = 0 ; i < this->myPlugins.size() ; i ++ )
01003 {
01004 back.push_back(this->myPlugins[i].name);
01005 }
01006 return back;
01007 }
01008
01013 time_t BotKernel::getStartTime()
01014 {
01015 return this->startTime;
01016 }
01017
01022 time_t BotKernel::getStartOnline()
01023 {
01024 return this->startOnline;
01025 }
01026
01031 vector<CountDownFunction>* BotKernel::getCountDowns()
01032 {
01033 return &this->countDowns ;
01034 }
01035
01040 string BotKernel::getDatasDir()
01041 {
01042 return this->datasDir;
01043 }
01044
01045 void* threadFunc (void*args)
01046 {
01047 ThreadParams* tp = (ThreadParams*) args;
01048 StructFunctionStorage* pfs = tp->function;
01049 pfs->back = pfs->function(tp->msg,pfs->object,tp->b);
01050 sem_post (tp->sem);
01051 return NULL;
01052 }
01053