Commit 4612e926 authored by mr-ti's avatar mr-ti
Browse files

No commit message

No commit message
parent c9cc29eb
...@@ -51,7 +51,7 @@ CRegex::State CRegex::getState(){ ...@@ -51,7 +51,7 @@ CRegex::State CRegex::getState(){
bool CRegex::exec(int flags){ bool CRegex::exec(int flags){
int match = regexec (&regex, buffer->c_str()+offset, nmatch, pmatch, flags); int match = regexec (&regex, buffer->c_str()+offset, nmatch, pmatch, flags);
if (match == REG_NOMATCH || pmatch[0].rm_eo == pmatch[0].rm_so){ if (match == REG_NOMATCH || /*pmatch[0].rm_eo == */pmatch[0].rm_so+offset >= buffer->length()){
state=NOMATCH; state=NOMATCH;
return false; return false;
}else if(match==0){ }else if(match==0){
...@@ -71,20 +71,51 @@ unsigned int CRegex::end(){ ...@@ -71,20 +71,51 @@ unsigned int CRegex::end(){
return (state==MATCH?pmatch[0].rm_eo:0); return (state==MATCH?pmatch[0].rm_eo:0);
} }
string CRegex::getFirstMatch(){ string CRegex::getFirstMatch(CRegex *subRegex){
string match; string match;
if(exec() && pmatch[0].rm_so!=-1){ if(exec() && pmatch[0].rm_so!=-1){
match=buffer->substr(pmatch[0].rm_so,pmatch[0].rm_eo - pmatch[0].rm_so); match=buffer->substr(pmatch[0].rm_so,pmatch[0].rm_eo - pmatch[0].rm_so);
if(subRegex){
subRegex->setBuffer(&match);
match=subRegex->getFirstMatch();
}
} }
return match; return match;
} }
list<string> CRegex::getMatchs(){ list<string> CRegex::getMatchs(CRegex *subRegex){
list<string> lst; list<string> lst;
string match;
if(state!=ERROR){
while(exec()){
if(pmatch[0].rm_so!=-1){
match=buffer->substr(pmatch[0].rm_so+offset,pmatch[0].rm_eo - pmatch[0].rm_so);
if(subRegex){
subRegex->setBuffer(&match);
match=subRegex->getFirstMatch();
}
lst.push_back(match);
}
offset+=pmatch[0].rm_eo+1;
}
offset=0;
}
return lst;
}
vector<string> CRegex::getMatchsToVect(CRegex *subRegex){
vector<string> lst;
string match;
if(state!=ERROR){ if(state!=ERROR){
while(exec()){ while(exec()){
if(pmatch[0].rm_so!=-1) if(pmatch[0].rm_so!=-1){
lst.push_back(buffer->substr(pmatch[0].rm_so+offset,pmatch[0].rm_eo - pmatch[0].rm_so)); match=buffer->substr(pmatch[0].rm_so+offset,pmatch[0].rm_eo - pmatch[0].rm_so);
if(subRegex){
subRegex->setBuffer(&match);
match=subRegex->getFirstMatch();
}
lst.push_back(match);
}
offset+=pmatch[0].rm_eo+1; offset+=pmatch[0].rm_eo+1;
} }
offset=0; offset=0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define CREGEX_H #define CREGEX_H
#include <string> #include <string>
#include <list> #include <list>
#include <vector>
#include <regex.h> #include <regex.h>
#include <unicomctrl/cuniobj.h> #include <unicomctrl/cuniobj.h>
...@@ -34,8 +35,9 @@ public: ...@@ -34,8 +35,9 @@ public:
unsigned int begin(); unsigned int begin();
unsigned int end(); unsigned int end();
State getState(); State getState();
list<string> getMatchs(); list<string> getMatchs(CRegex *subRegex=NULL);
string getFirstMatch(); vector<string> getMatchsToVect(CRegex *subRegex=NULL);
string getFirstMatch(CRegex *subRegex=NULL);
int getErrorNb(); int getErrorNb();
string getErrorMsg(); string getErrorMsg();
virtual string className(); virtual string className();
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include "ddnsshttpcl.h" #include "ddnsshttpcl.h"
#include "cregex.h" #include "cregex.h"
string DdnssHttpCl::curPubIp;
DdnssHttpCl::DdnssHttpCl() DdnssHttpCl::DdnssHttpCl()
: CUniObj() { : CUniObj() {
publicIpGetAdress="http://checkip.dyndns.org/"; publicIpGetAdress="http://checkip.dyndns.org/";
...@@ -30,7 +32,7 @@ DdnssHttpCl::~DdnssHttpCl() { ...@@ -30,7 +32,7 @@ DdnssHttpCl::~DdnssHttpCl() {
curl_easy_cleanup(handle); //Détrut le handle cURL curl_easy_cleanup(handle); //Détrut le handle cURL
} }
string DdnssHttpCl::getPublicIp(){ string DdnssHttpCl::getPubIp(){
string res; string res;
if(!get(res,publicIpGetAdress)){ if(!get(res,publicIpGetAdress)){
return ""; return "";
...@@ -40,6 +42,14 @@ string DdnssHttpCl::getPublicIp(){ ...@@ -40,6 +42,14 @@ string DdnssHttpCl::getPublicIp(){
return reg.getFirstMatch(); return reg.getFirstMatch();
} }
string DdnssHttpCl::getCurPubIp(){
return curPubIp;
}
void DdnssHttpCl::setCurPubIp(const string &ip){
curPubIp=ip;
}
void DdnssHttpCl::setHttpUserPwd(const string &login, const string &passwd){ void DdnssHttpCl::setHttpUserPwd(const string &login, const string &passwd){
string tmp=login+":"+passwd; string tmp=login+":"+passwd;
curl_easy_setopt(handle,CURLOPT_USERPWD,tmp.c_str()); curl_easy_setopt(handle,CURLOPT_USERPWD,tmp.c_str());
......
...@@ -22,7 +22,9 @@ class DdnssHttpCl : public CUniObj{ ...@@ -22,7 +22,9 @@ class DdnssHttpCl : public CUniObj{
public: public:
DdnssHttpCl(); DdnssHttpCl();
~DdnssHttpCl(); ~DdnssHttpCl();
string getPublicIp(); string getPubIp();
static string getCurPubIp();
static void setCurPubIp(const string &ip);
void setHttpUserPwd(const string &login, const string &passwd); void setHttpUserPwd(const string &login, const string &passwd);
bool get(string &result, const string &url); bool get(string &result, const string &url);
bool post(string &result, const string &url); bool post(string &result, const string &url);
...@@ -30,6 +32,7 @@ public: ...@@ -30,6 +32,7 @@ public:
private: private:
string publicIpGetAdress; string publicIpGetAdress;
CURL *handle; CURL *handle;
static string curPubIp;
static size_t writeInRepBuf(void *ptr, size_t size, size_t nmemb, FILE *out); static size_t writeInRepBuf(void *ptr, size_t size, size_t nmemb, FILE *out);
}; };
......
#include "../../ddnssbase/ddnsshttpcl.h" #include "../../ddnssbase/ddnsshttpcl.h"
#include "../../ddnssbase/cregex.h" #include "../../ddnssbase/cregex.h"
#include <unicomctrl/unilib.h>
extern "C" extern "C"
{ {
void exec(const string& request){ void exec(const string& request){
CRegex regex("('([^']+)')|(([^[:space:]]+))"); CRegex regex("('[^']+')|([^[:space:]]+)");
CRegex subRegex("([^']+)");
regex.setBuffer(&request); regex.setBuffer(&request);
list<string> elts=regex.getMatchs(); if(equ(request,"HELP"))
for(list<string>::iterator it=elts.begin();it!=elts.end();it++){ throw string("dyndns <domaine name> <IP> <login> <password>");
CUniObj::printd("",*it+"\n"); vector<string> elts=regex.getMatchsToVect(&subRegex);
if(elts.size()!=4){
string err="Wrong dyndns plugin use !\nUse : dyndns <domaine name> <IP> <login> <password>";
CUniObj::printc("DynDNS plugin",err+"\n");
throw string(err);
}
CUniObj::printd("DynDNS plugin","Request >> \""+request+"\"\n");
DdnssHttpCl httpcl;
string newIp=(elts.at(1)=="<IP>"?httpcl.getCurPubIp():elts.at(1));
httpcl.setHttpUserPwd(elts.at(2),elts.at(3));
string res;
httpcl.post(res,"https://members.dyndns.org/nic/update?system=dyndns&hostname="+elts.at(0)+"&myip="+newIp);
if(res=="good "+newIp){
}else if(res=="nochg "+newIp){
string err="Warning >> Duplicate updates for the same host/ip, you should verify client settings...";
CUniObj::prints("DynDNS plugin",err+"\n");
throw string(err);
}else{
string err="FATAL ERROR >> See logs for more details, you must verify client settings...";
CUniObj::prints("DynDNS plugin",err+"\nRequest result : \n"+res+"\n");
throw string(err);
} }
} }
} }
#include "../../ddnssbase/ddnsshttpcl.h" #include "../../ddnssbase/ddnsshttpcl.h"
#include "../../ddnssbase/cregex.h" #include "../../ddnssbase/cregex.h"
#include <unicomctrl/unilib.h>
extern "C" extern "C"
{ {
void exec(const string& request){ void exec(const string& request){
CRegex regex("('[^']+')|([^[:space:]]+)");
CRegex subRegex("([^']+)");
regex.setBuffer(&request);
if(equ(request,"HELP"))
throw string("zoneedit <domaine name> <IP> <login> <password>");
vector<string> elts=regex.getMatchsToVect(&subRegex);
if(elts.size()!=4){
string err="Wrong zoneedit plugin use !\nUse : zoneedit <domaine name> <IP> <login> <password>";
CUniObj::printc("ZoneEdit plugin",err+"\n");
throw string(err);
}
CUniObj::printd("ZoneEdit plugin","Request >> \""+request+"\"\n");
DdnssHttpCl httpcl;
string newIp=(elts.at(1)=="<IP>"?httpcl.getCurPubIp():elts.at(1));
httpcl.setHttpUserPwd(elts.at(2),elts.at(3));
string res;
httpcl.post(res,"http://dynamic.zoneedit.com/auth/dynamic.html?zones="+elts.at(0));
if(res=="<SUCCESS CODE=\"200\" TEXT=\"Update succeeded.\" ZONE=\""+elts.at(0)+"\" IP=\""+newIp+"\">"){
}else if(res=="<ERROR CODE=\"707\" TEXT=\"Duplicate updates for the same host/ip, adjust client settings\" ZONE=\""+elts.at(0)+"\">"){
string err="Warning >> Duplicate updates for the same host/ip, you should verify client settings...";
CUniObj::prints("DynDNS plugin",err+"\n");
throw string(err);
}else{
string err="FATAL ERROR >> See logs for more details, you must verify client settings...";
CUniObj::prints("DynDNS plugin",err+"\nRequest result : \n"+res+"\n");
throw string(err);
}
} }
} }
...@@ -38,3 +38,6 @@ TARGET_LINK_LIBRARIES(ddnssync ${ddnssync_LIBS}) ...@@ -38,3 +38,6 @@ TARGET_LINK_LIBRARIES(ddnssync ${ddnssync_LIBS})
# ### INSTALL ### # ### INSTALL ###
INSTALL(TARGETS ddnssync DESTINATION bin PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE) INSTALL(TARGETS ddnssync DESTINATION bin PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
ADD_EXECUTABLE(test test.cpp)
TARGET_LINK_LIBRARIES(test ddnssbase)
...@@ -42,6 +42,7 @@ DDnsSPlList::DDnsSPlList(CUniConf &config):CUniObj() { ...@@ -42,6 +42,7 @@ DDnsSPlList::DDnsSPlList(CUniConf &config):CUniObj() {
plugin->handle=handle; plugin->handle=handle;
plugin->exec=exec; plugin->exec=exec;
plugList[*it]=plugin; plugList[*it]=plugin;
printd("DDnsSPlList() >> plugin \""+*it+"\" loaded.\n");
} }
} }
} }
...@@ -57,7 +58,7 @@ DDnsSPlList::~DDnsSPlList() { ...@@ -57,7 +58,7 @@ DDnsSPlList::~DDnsSPlList() {
for(map<string,Plugin *>::iterator it=plugList.begin();it!=plugList.end();it++){ for(map<string,Plugin *>::iterator it=plugList.begin();it!=plugList.end();it++){
dlclose(it->second->handle); dlclose(it->second->handle);
delete it->second; delete it->second;
printd("~() >> plugin \""+it->first+"\" unloaded.\n"); printd("~DDnsSPlList() >> plugin \""+it->first+"\" unloaded.\n");
} }
} }
...@@ -77,6 +78,18 @@ void DDnsSPlList::exec(const string &request){ ...@@ -77,6 +78,18 @@ void DDnsSPlList::exec(const string &request){
} }
} }
string DDnsSPlList::getHelps(){
string uses;
for(map<string,Plugin *>::iterator it=plugList.begin();it!=plugList.end();it++){
try{
it->second->exec("help");
}catch(string err){
uses+=" * "+err+"\n";
}
}
return uses;
}
/** /**
* @brief The name of the class. * @brief The name of the class.
* @return "DDnsSPlList" * @return "DDnsSPlList"
......
...@@ -36,6 +36,7 @@ public: ...@@ -36,6 +36,7 @@ public:
DDnsSPlList(CUniConf &config); DDnsSPlList(CUniConf &config);
~DDnsSPlList(); ~DDnsSPlList();
void exec(const string &request); void exec(const string &request);
string getHelps();
virtual string className(); virtual string className();
static DDnsSPlList *pList; static DDnsSPlList *pList;
private: private:
......
...@@ -45,7 +45,7 @@ void DDnsSReqAnalyzer::exec(const string& request){ ...@@ -45,7 +45,7 @@ void DDnsSReqAnalyzer::exec(const string& request){
returnMessage("Command list :\n" returnMessage("Command list :\n"
" * VERSION; Get the version.\n" " * VERSION; Get the version.\n"
" * REVISION; Get the revision (SVN).\n" " * REVISION; Get the revision (SVN).\n"
" * BUILD; Get the build date.\n" " * BUILD; Get the build date.\nPlugins :\n"+DDnsSPlList::pList->getHelps()+
" NB:\n{choice|other choice} => choice or other choice.\n[Option] => this is an option.\n"); " NB:\n{choice|other choice} => choice or other choice.\n[Option] => this is an option.\n");
}else{ }else{
returnError("HELP request error."); returnError("HELP request error.");
...@@ -65,6 +65,7 @@ void DDnsSReqAnalyzer::exec(const string& request){ ...@@ -65,6 +65,7 @@ void DDnsSReqAnalyzer::exec(const string& request){
}else{ }else{
try{ try{
DDnsSPlList::pList->exec(request); DDnsSPlList::pList->exec(request);
returnMessage("Success.");
}catch(string err){ }catch(string err){
returnError(err); returnError(err);
} }
......
...@@ -10,14 +10,19 @@ ...@@ -10,14 +10,19 @@
// //
// //
#include "ddnssslist.h" #include "ddnssslist.h"
#include "ddnsspluginlist.h"
#include "../ddnssbase/ddnsshttpcl.h"
#include <queue>
DDnsSSList::DDnsSSList(CUniConf &cf) DDnsSSList::DDnsSSList(CUniConf &cf)
: CUniObj() : CUniThread()
{ {
StringList cmdList=cf.getListValue("dn_list"); StringList cmdList=cf.getListValue("dn_list");
for(StringList::iterator it=cmdList.begin();it!=cmdList.begin();it++){ for(StringList::iterator it=cmdList.begin();it!=cmdList.begin();it++){
dnList.push_back(new DName(cf,*it)); dnList.push_back(new DName(cf,*it));
} }
time=cf.getValueToInt("time");
doStop=false;
} }
...@@ -29,6 +34,31 @@ DDnsSSList::~DDnsSSList() ...@@ -29,6 +34,31 @@ DDnsSSList::~DDnsSSList()
dnList.clear(); dnList.clear();
} }
int DDnsSSList::run(){
DdnssHttpCl httpcl;
string ip;
do{
ip=httpcl.getPubIp();
if(ip!=httpcl.getCurPubIp()){
DdnssHttpCl::setCurPubIp(ip);
for(list<DName*>::iterator it=dnList.begin();it!=dnList.begin();it++){
(*it)->doSync();
}
}
for(int i=0;i<time;i++){
if(doStop)
return 0;
}
}while(true);
return 0;
}
void DDnsSSList::onExit(){
doStop=true;
}
/** /**
* @brief The ame of the class. * @brief The ame of the class.
* @return "DDnsSSList" * @return "DDnsSSList"
...@@ -43,6 +73,7 @@ DDnsSSList::DName::DName(CUniConf &cf, const string &dname) ...@@ -43,6 +73,7 @@ DDnsSSList::DName::DName(CUniConf &cf, const string &dname)
{ {
this->dname=dname; this->dname=dname;
cmdList=cf.getListValue(dname+"_req"); cmdList=cf.getListValue(dname+"_req");
sync=false;
} }
...@@ -50,14 +81,56 @@ DDnsSSList::DName::~DName() ...@@ -50,14 +81,56 @@ DDnsSSList::DName::~DName()
{ {
} }
void DDnsSSList::DName::doSync(){
condSync.lock();
sync=true;
condSync.signal();
condSync.unlock();
}
int DDnsSSList::DName::run(){ int DDnsSSList::DName::run(){
queue<string> q1,q2,*orig=&q1,*dest=&q2,*tmp;
do{
if(!condSync.lock())
return 0;
while(!sync)
if(!condSync.wait()) //Attente
return 0;
sync=false;
condSync.unlock();
// Mise en file de la liste des commande
for(StringList::iterator it=cmdList.begin();it!=cmdList.end();it++){
orig->push(*it);
}
// Traitement de la file
while(!orig->empty() && !dest->empty()){
try{
DDnsSPlList::pList->exec(orig->front());
}catch(string err){
// Ajoute à la file des commandes à réexécuter
dest->push(orig->front());
}
orig->pop();
if(orig->empty() && !dest->empty()){
// Inverse les files et attend 3 minutes avant de réexécuter les commande qui ont échoué
tmp=orig;
orig=dest;
dest=tmp;
for(unsigned int i=0;i<300;i++){
if(!condSync.isEnabled())
return 0;
}
}
if(!condSync.isEnabled())
return 0;
}
}while(true);
return 0; return 0;
} }
void DDnsSSList::DName::onExit(){ void DDnsSSList::DName::onExit(){
condSync.enable(false);
} }
/** /**
......
...@@ -22,13 +22,14 @@ using namespace std; ...@@ -22,13 +22,14 @@ using namespace std;
/** /**
@author Emeric VERSCHUUR <contact@mr-ti.com> @author Emeric VERSCHUUR <contact@mr-ti.com>
*/ */
class DDnsSSList : public CUniObj class DDnsSSList : public CUniThread
{ {
public: public:
class DName : public CUniThread{ class DName : public CUniThread{
public: public:
DName(CUniConf &cf, const string &dname); DName(CUniConf &cf, const string &dname);
~DName(); ~DName();
void doSync();
virtual string className(); virtual string className();
protected: protected:
virtual int run(); virtual int run();
...@@ -36,12 +37,19 @@ public: ...@@ -36,12 +37,19 @@ public:
private: private:
string dname; string dname;
StringList cmdList; StringList cmdList;
bool sync;
CUniCondition condSync;
}; };
DDnsSSList(CUniConf &cf); DDnsSSList(CUniConf &cf);
~DDnsSSList(); ~DDnsSSList();
virtual string className(); virtual string className();
protected:
virtual int run();
virtual void onExit();
private: private:
list<DName*> dnList; list<DName*> dnList;
int time;
bool doStop;
}; };
#endif #endif
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <unicomctrl/cuniconfreg.h> #include <unicomctrl/cuniconfreg.h>
#include <unicomctrl/cunicomcl.h> #include <unicomctrl/cunicomcl.h>
#include <unicomctrl/cunithreadmanager.h> #include <unicomctrl/cunithreadmanager.h>
#include "../ddnssbase/ddnsshttpcl.h"
#include "ddnssreqanalyzer.h" #include "ddnssreqanalyzer.h"
#include "ddnsspluginlist.h" #include "ddnsspluginlist.h"
#include <string> #include <string>
...@@ -21,7 +22,7 @@ public: ...@@ -21,7 +22,7 @@ public:
switch(type){ switch(type){
case CUniData::REQUEST: case CUniData::REQUEST:
analyzer.lock(); analyzer.lock();
analyzer.init(this,"URA"); analyzer.init(this,"DDnsSync");
analyzer.exec(getMessage()); analyzer.exec(getMessage());
analyzer.unlock(); analyzer.unlock();
break; break;
...@@ -60,6 +61,7 @@ int main(int argc, char **argv) { ...@@ -60,6 +61,7 @@ int main(int argc, char **argv) {
"You must correct this error in the configuration file.\n"); "You must correct this error in the configuration file.\n");