/*******************************************************************************
* Boapns.cc Boap NAme Server
* T.Barnaby, BEAM Ltd, 4/3/04
*******************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <BString.h>
#include <BList.h>
#include <BPoll.h>
#include <BSocket.h>
#include <BoapnsD.h>
#include <BoapnsS.h>
#include <BMutex.h>
#define DEBUG 0
#define UseTimer 0
#if DEBUG
#define dprintf(fmt, a...) printf(fmt, ##a);
#else
#define dprintf(fmt, a...)
#endif
class BoapnsObject : public Boapns::BoapnsService {
public:
BoapnsObject(BoapServer& server, BString name);
BError getVersion(BString& version);
BError getEntryList(BList<Boapns::BoapEntry>& entryList);
BError getEntry(BString name, Boapns::BoapEntry& entry);
BError addEntry(Boapns::BoapEntry entry);
BError delEntry(BString name);
BError getNewName(BString& name);
void pingAll();
BError processEvent(BoapPacket& rx);
private:
void entryPrint(Boapns::BoapEntry entry);
BList<Boapns::BoapEntry> oservices;
UInt32 onextId;
BMutex olock;
};
BoapnsObject::BoapnsObject(BoapServer& server, BString name) : Boapns::BoapnsService(server, name){
onextId = 0;
#ifdef ZAP
oservices.append(Boapns::BoapEntry("test1", 0, 0, 1));
oservices.append(Boapns::BoapEntry("test2", 0, 0, 2));
oservices.append(Boapns::BoapEntry("test3", 0, 0, 3));
#endif
}
void BoapnsObject::entryPrint(Boapns::BoapEntry entry){
BIter i;
BString al;
for(entry.addressList.start(i); !entry.addressList.isEnd(i); entry.addressList.next(i)){
if(al.len())
al = al + ",";
al = al + entry.addressList[i];
}
printf("%-32.32s %s:%d %d\n", entry.name.retStr(), al.retStr(), entry.port, entry.service);
}
BError BoapnsObject::getVersion(BString& version){
BError err;
version = "1.0.0";
return err;
}
BError BoapnsObject::getEntryList(BList<Boapns::BoapEntry>& entryList){
BError err;
dprintf("%s:\n", __FUNCTION__);
olock.lock();
entryList = oservices;
olock.unlock();
dprintf("%s: End\n", __FUNCTION__);
return err;
}
BError BoapnsObject::getEntry(BString name, Boapns::BoapEntry& entry){
BError err;
BIter i;
dprintf("BoapnsObject::getEntry: %s\n", name.retStr());
olock.lock();
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
if(oservices[i].name == name){
entry = oservices[i];
olock.unlock();
return err;
}
}
olock.unlock();
err.set(1, BString("Boapns: No such service: ") + name);
return err;
}
BError BoapnsObject::addEntry(Boapns::BoapEntry entry){
BError err;
BIter i;
dprintf("BoapnsObject::addEntry: %s %s:%d %d\n", entry.name.retStr(), entry.addressList[0].retStr(), entry.port, entry.service);
olock.lock();
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
if(oservices[i].name == entry.name){
oservices.del(i);
break;
}
}
oservices.append(entry);
olock.unlock();
#if DEBUG
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
entryPrint(oservices[i]);
}
#endif
return err;
}
BError BoapnsObject::delEntry(BString name){
BError err;
BIter i;
dprintf("%s:\n", __FUNCTION__);
olock.lock();
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
if(oservices[i].name == name){
oservices.del(i);
break;
}
}
olock.unlock();
return err;
}
BError BoapnsObject::getNewName(BString& name){
BError err;
name = BString("object") + onextId++;
return err;
}
void BoapnsObject::pingAll(){
BIter i;
BError err;
BoapClientObject obj;
printf("PingAll\n");
olock.lock();
#ifdef ZAP
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
printf("Ping: %s\n", oservices[i].name.retStr());
obj.connectService(oservices[i].name);
printf("Ping: Do %s\n", oservices[i].name.retStr());
err = obj.ping();
printf("PinRes: %d\n", err.getErrorNo());
}
#endif
olock.unlock();
}
BError BoapnsObject::processEvent(BoapPacket& rx){
BError err;
BIter i;
BSocketAddressINET nadd;
uint32_t nsent;
dprintf("BoapnsObject::processEvent\n");
for(oservices.start(i); !oservices.isEnd(i); oservices.next(i)){
nadd.set(oservices[i].addressList[0], oservices[i].port);
dprintf("BoapnsObject::processEvent: Nbytes: %d SendTo: %s :%s\n", rx.nbytes(), oservices[i].name.retStr(), nadd.getString().retStr());
oserver.getEventSocket().sendTo(nadd, rx.data(), rx.nbytes(), nsent);
dprintf("BoapnsObject::processEvent: Result: %s\n", strerror(errno));
}
return err;
}
void* timer(void* data){
BoapnsObject* boapns = (BoapnsObject*)data;
while(1){
boapns->pingAll();
sleep(1);
}
}
int main(int argc, char** argv){
BoapServer server;
BoapnsObject boapns(server, "boapns");
BError err;
int a;
int foreground = 0;
#ifdef UseTimer
pthread_t timerThread;
#endif
for(a = 1; a < argc; a++){
if(argv[a][0] == '-'){
switch(argv[a][1]){
case 'f': foreground = 1; break;
}
}
}
dprintf("Initialise BoapServer\n");
if(err = server.init("", 0, 1)){
std::cerr << err.getString() << "\n";
return 1;
}
if(!foreground)
daemon(0, 0);
dprintf("Run Server\n");
#ifdef UseTimer
pthread_create(&timerThread, 0, timer, &boapns);
#endif
server.run();
return 0;
}