// Copyright (c) 2003 David Muse // See the COPYING file for more information #include #include #include #include // for rpcent, functions #include #ifdef RUDIMENTS_HAVE_RPCENT_H #include #endif #ifdef RUDIMENTS_HAVE_RPC_H #include #endif // Some systems (notably cygwin 1.5.7-1) define getrpcbyname and getrpcbynumber // in their header files but then either don't implement them or don't export // the symbols. #if (defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) || \ defined(RUDIMENTS_HAVE_GETRPCBYNAME)) && \ (defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) || \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER)) \ #include #include #define MAXBUFFER (32*1024) #ifdef RUDIMENTS_NAMESPACE namespace rudiments { #endif class rpcentryprivate { friend class rpcentry; private: rpcent *_re; #if defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) rpcent _rebuffer; char *_buffer; #endif }; // LAME: not in the class #if (!defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R)) static mutex *_remutex; #endif rpcentry::rpcentry() { pvt=new rpcentryprivate; pvt->_re=NULL; #if defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) rawbuffer::zero(&pvt->_rebuffer,sizeof(pvt->_rebuffer)); pvt->_buffer=NULL; #endif } rpcentry::~rpcentry() { #if defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) delete[] pvt->_buffer; #endif delete pvt; } const char *rpcentry::getName() const { return pvt->_re->r_name; } int rpcentry::getNumber() const { return pvt->_re->r_number; } const char * const *rpcentry::getAliasList() const { return pvt->_re->r_aliases; } bool rpcentry::needsMutex() { #if !defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) return true; #else return false; #endif } void rpcentry::setMutex(mutex *mtx) { #if !defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) || \ !defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) _remutex=mtx; #endif } bool rpcentry::initialize(const char *name) { return initialize(name,0); } bool rpcentry::initialize(int number) { return initialize(NULL,number); } bool rpcentry::initialize(const char *rpcname, int number) { #if defined(RUDIMENTS_HAVE_GETRPCBYNAME_R) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R) if (pvt->_re) { pvt->_re=NULL; delete[] pvt->_buffer; pvt->_buffer=NULL; } // getrpcbyname_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_GETRPCBYNAME_R_5) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R_5) if (!((rpcname) ?(getrpcbyname_r(rpcname,&pvt->_rebuffer, pvt->_buffer,size, &pvt->_re)) :(getrpcbynumber_r(number,&pvt->_rebuffer, pvt->_buffer,size, &pvt->_re)))) { return (pvt->_re!=NULL); } #elif defined(RUDIMENTS_HAVE_GETRPCBYNAME_R_4) && \ defined(RUDIMENTS_HAVE_GETRPCBYNUMBER_R_4) if ((rpcname) ?(pvt->_re=getrpcbyname_r(rpcname, &pvt->_rebuffer, pvt->_buffer,size)) :(pvt->_re=getrpcbynumber_r(number, &pvt->_rebuffer, pvt->_buffer,size))) { return true; } #endif delete[] pvt->_buffer; pvt->_buffer=NULL; pvt->_re=NULL; if (error::getErrorNumber()!=ENOMEM) { return false; } } return false; #else pvt->_re=NULL; return (!(remutex && !remutex->lock()) && ((pvt->_re=((rpcname) ?getrpcbyname(const_cast(rpcname)) :getrpcbynumber(number)))!=NULL) && !(remutex && !remutex->unlock())); #endif } bool rpcentry::getAliasList(const char *name, char ***aliaslist) { rpcentry re; if (re.initialize(name)) { int counter; for (counter=0; re.getAliasList()[counter]; counter++); char **alias=new char *[counter+1]; alias[counter]=NULL; for (int i=0; i_re) { return; } printf("Name: %s\n",getName()); printf("Number: %d\n",getNumber()); printf("Alias list:\n"); for (int i=0; getAliasList()[i]; i++) { printf(" %s\n",getAliasList()[i]); } } #ifdef RUDIMENTS_NAMESPACE } #endif #endif