macssh/GUSI/include/GUSINetDB.h

267 lines
12 KiB
C++
Executable File

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSINetDB.nw - Convert between names and adresses
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.10 2000/12/23 06:11:55 neeri
// % Add SSH service
// %
// % Revision 1.9 2000/05/23 07:10:35 neeri
// % Improve formatting
// %
// % Revision 1.8 2000/03/15 07:18:43 neeri
// % Fix GUSIBuiltinServiceDB::sServices
// %
// % Revision 1.7 1999/11/15 07:23:23 neeri
// % Fix gethostname for non-TCP/IP case
// %
// % Revision 1.6 1999/08/26 05:45:05 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.5 1999/05/30 03:09:30 neeri
// % Added support for MPW compilers
// %
// % Revision 1.4 1999/03/17 09:05:10 neeri
// % Added GUSITimer, expanded docs
// %
// % Revision 1.3 1998/11/22 23:06:58 neeri
// % Releasing 2.0a4 in a hurry
// %
// % Revision 1.2 1998/10/25 11:33:38 neeri
// % Fixed disastrous bug in inet_addr, support alternative NL conventions
// %
// % Revision 1.1 1998/10/11 16:45:20 neeri
// % Ready to release 2.0a2
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Converting Between Names and IP Addresses}
//
// The [[GUSINetDB]] class coordinates access to the domain name server database.
//
// The [[GUSIServiceDB]] class is responsible for a database of TCP/IP service
// name to port number mappings.
//
// The [[hostent]] and [[servent]] classes are somewhat inconvenient to set up as
// they reference extra chunks of memory, so we define the wrapper classes
// [[GUSIhostent]] and [[GUSIservent]].
//
// <GUSINetDB.h>=
#ifndef _GUSINetDB_
#define _GUSINetDB_
#ifdef GUSI_SOURCE
#include "GUSISpecific.h"
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of [[GUSIhostent]] and [[GUSIservent]]}
//
// A [[GUSIhostent]] may need a lot of data, so we allocate the name data
// dynamically.
//
// <Definition of class [[GUSIhostent]]>=
class GUSIhostent : public hostent {
public:
GUSIhostent();
void Alloc(size_t size);
char * fAlias[16];
char * fAddressList[16];
char * fName;
size_t fAlloc;
char fAddrString[16];
};
extern "C" void GUSIKillHostEnt(void * hostent);
// A [[GUSIservent]] typically will remain more modest in its needs, so the
// data is allocated statically.
//
// <Definition of class [[GUSIservent]]>=
class GUSIservent : public servent {
public:
GUSIservent();
char * fAlias[8];
char fName[256];
};
// \section{Definition of [[GUSIServiceDB]]}
//
// [[GUSIServiceDB]] is a singleton, used as a primitive iterator. The semantics of
// these iterators conform only very superficially to real iterators:
//
// \begin{itemize}
// \item Only a single instance of the iterator is supported.
// \item Comparison operators all compare against [[end]], no matter what
// arguments are passed.
// \end{itemize}
//
// <Definition of class [[GUSIServiceDB]]>=
extern "C" void GUSIKillServiceDBData(void * entry);
class GUSIServiceDB {
public:
static GUSIServiceDB * Instance();
// Iterating is accomplished by a public interface conforming to STL iterator
// protocols.
//
// <Iterating over the [[GUSIServiceDB]]>=
class iterator {
public:
inline bool operator==(const iterator & other);
inline bool operator!=(const iterator & other);
inline iterator & operator++();
inline servent * operator*();
};
inline static iterator begin();
inline static iterator end();
protected:
static GUSIServiceDB * sInstance;
GUSIServiceDB() {}
virtual ~GUSIServiceDB() {}
friend void GUSIKillServiceDBData(void * entry);
// This interface does not access any data elements in the iterator, but directly
// calls through to a private interface in the [[GUSIServiceDB]], which explains
// the limitations in the iterator implementation.
//
// <Internal iterator protocol of [[GUSIServiceDB]]>=
friend class iterator;
class Data {
public:
Data() : fCurrent(0) {}
servent * fCurrent;
GUSIservent fServent;
};
typedef GUSISpecificData<Data, GUSIKillServiceDBData> SpecificData;
static SpecificData sData;
virtual void Reset() = 0;
virtual void Next() = 0;
};
// \section{Definition of [[GUSINetDB]]}
//
//
// <Definition of class [[GUSINetDB]]>=
class GUSINetDB {
public:
// [[GUSINetDB]] is a singleton, but usually instantiated by an instance of a
// derived class.
//
// <Constructing instances of [[GUSINetDB]]>=
static GUSINetDB * Instance();
// The public interface of [[GUSINetDB]] consists of three areas. The first set of
// calls is concerned with host names and IP numbers.
//
// <[[GUSINetDB]] host database>=
virtual hostent * gethostbyname(const char * name);
virtual hostent * gethostbyaddr(const void * addr, size_t len, int type);
virtual char * inet_ntoa(in_addr inaddr);
virtual in_addr_t inet_addr(const char *address);
virtual long gethostid();
virtual int gethostname(char *machname, int buflen);
// The next set of calls is concerned with TCP and UDP services.
//
// <[[GUSINetDB]] service database>=
virtual servent * getservbyname(const char * name, const char * proto);
virtual servent * getservbyport(int port, const char * proto);
virtual servent * getservent();
virtual void setservent(int stayopen);
virtual void endservent();
// Finally, there is a set of calls concerned with protocols.
//
// <[[GUSINetDB]] protocol database>=
virtual protoent * getprotobyname(const char * name);
virtual protoent * getprotobynumber(int proto);
virtual protoent * getprotoent();
virtual void setprotoent(int stayopen);
virtual void endprotoent();
protected:
GUSINetDB();
virtual ~GUSINetDB() {}
// \section{Implementation of [[GUSINetDB]]}
//
// [[GUSINetDB]] is a singleton, but typically implemented by an instance
// of a subclass (stored into [[fInstance]] by that subclass) rather than the
// base class.
//
// <Privatissima of [[GUSINetDB]]>=
static GUSINetDB * sInstance;
// The service database is implemented in terms of [[GUSIServiceDB]]. Only
// [[getservent]] and [[setservent]] accesse [[GUSIServiceDB]] directly, however.
//
// <Privatissima of [[GUSINetDB]]>=
bool fServiceOpen;
GUSIServiceDB::iterator fServiceIter;
// The protocol database is similar, in principle, to the service database, but it
// lends itself naturally to a much simpler implementation.
//
// <Privatissima of [[GUSINetDB]]>=
int fNextProtocol;
static protoent sProtocols[2];
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#ifdef GUSI_INTERNAL
// Iterators can be defined without regard to the implementation of the
// [[GUSIServiceDB]] currently used.
//
// <Inline member functions for class [[GUSIServiceDB]]>=
GUSIServiceDB::iterator GUSIServiceDB::begin()
{
Instance()->Reset();
Instance()->Next();
return iterator();
}
GUSIServiceDB::iterator GUSIServiceDB::end()
{
return iterator();
}
bool GUSIServiceDB::iterator::operator==(const GUSIServiceDB::iterator &)
{
return !GUSIServiceDB::sData->fCurrent;
}
bool GUSIServiceDB::iterator::operator!=(const GUSIServiceDB::iterator &)
{
return GUSIServiceDB::sData->fCurrent
== static_cast<servent *>(nil);
}
GUSIServiceDB::iterator & GUSIServiceDB::iterator::operator++()
{
GUSIServiceDB::Instance()->Next();
return *this;
}
servent * GUSIServiceDB::iterator::operator*()
{
return GUSIServiceDB::sData->fCurrent;
}
#endif /* GUSI_INTERNAL */
#endif /* GUSI_SOURCE */
#endif /* _GUSINetDB_ */