/******************************************************************************* * 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; }