// Copyright (c) 2002 David Muse // See the COPYING file for more information #include #include #include #include // for protoent, functions #include #include #include #define MAXBUFFER (32*1024) #ifdef RUDIMENTS_NAMESPACE namespace rudiments { #endif class protocolentryprivate { friend class protocolentry; private: protoent *_pe; #if defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) || \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) protoent _pebuffer; char *_buffer; #endif }; // LAME: not in the class #if (!defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R)) static mutex *_pemutex; #endif protocolentry::protocolentry() { pvt=new protocolentryprivate; pvt->_pe=NULL; #if defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) rawbuffer::zero(&pvt->_pebuffer,sizeof(pvt->_pebuffer)); pvt->_buffer=NULL; #endif } protocolentry::protocolentry(const protocolentry &p) { pvt=new protocolentryprivate; initialize(p.getName()); } protocolentry &protocolentry::operator=(const protocolentry &p) { if (this!=&p) { initialize(p.getName()); } return *this; } protocolentry::~protocolentry() { #if defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) delete[] pvt->_buffer; #endif delete pvt; } const char *protocolentry::getName() const { return pvt->_pe->p_name; } const char * const *protocolentry::getAliasList() const { return pvt->_pe->p_aliases; } int protocolentry::getNumber() const { return pvt->_pe->p_proto; } bool protocolentry::needsMutex() { #if !defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) return true; #else return false; #endif } void protocolentry::setMutex(mutex *mtx) { #if !defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) _pemutex=mtx; #endif } bool protocolentry::initialize(const char *protocolname) { return initialize(protocolname,0); } bool protocolentry::initialize(int number) { return initialize(NULL,number); } bool protocolentry::initialize(const char *protocolname, int number) { #if defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R) if (pvt->_pe) { pvt->_pe=NULL; delete[] pvt->_buffer; pvt->_buffer=NULL; } // getprotobyname_r is goofy. // It will retrieve an arbitrarily large amount of data, but // requires that you pass it a pre-allocated buffer. If the // buffer is too small, it returns an ENOMEM and you have to // just make the buffer bigger and try again. for (int size=1024; size_buffer=new char[size]; #if defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R_5) && \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R_5) if (!((protocolname) ?(getprotobyname_r(protocolname, &pvt->_pebuffer, pvt->_buffer,size, &pvt->_pe)) :(getprotobynumber_r(number, &pvt->_pebuffer, pvt->_buffer,size, &pvt->_pe)))) { return (pvt->_pe!=NULL); } #elif defined(RUDIMENTS_HAVE_GETPROTOBYNAME_R_4) && \ defined(RUDIMENTS_HAVE_GETPROTOBYNUMBER_R_4) if ((protocolname) ?(pvt->_pe=getprotobyname_r(protocolname, &pvt->_pebuffer, pvt->_buffer,size)) :(pvt->_pe=getprotobynumber_r(number, &pvt->_pebuffer, pvt->_buffer,size))) { return true; } #endif delete[] pvt->_buffer; pvt->_buffer=NULL; pvt->_pe=NULL; if (error::getErrorNumber()!=ENOMEM) { return false; } } return false; #else pvt->_pe=NULL; return (!(_pemutex && !_pemutex->lock())) && ((pvt->_pe=((protocolname) ?getprotobyname(protocolname) :getprotobynumber(number)))!=NULL) && !(_pemutex && !_pemutex->unlock()); #endif } bool protocolentry::getAliasList(const char *protocolname, char ***aliaslist) { protocolentry pe; if (pe.initialize(protocolname)) { int counter; for (counter=0; pe.getAliasList()[counter]; counter++); char **alias=new char *[counter+1]; alias[counter]=NULL; for (int i=0; i_pe) { return; } printf("Name: %s\n",getName()); printf("Alias list:\n"); for (int i=0; getAliasList()[i]; i++) { printf(" %s\n",getAliasList()[i]); } printf("Number: %d\n",getNumber()); } #ifdef RUDIMENTS_NAMESPACE } #endif