Back to index

lightning-sunbird  0.9+nobinonly
GUSINetDB.h
Go to the documentation of this file.
00001 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00002 // % Project  :      GUSI                        -      Grand Unified Socket Interface                    
00003 // % File            :      GUSINetDB.nw         -      Convert between names and adresses            
00004 // % Author   :      Matthias Neeracher                                           
00005 // % Language :      C++                                                        
00006 // %                                                                       
00007 // % $Log: GUSINetDB.h,v $
00008 // % Revision 1.1  2001/03/11 22:37:15  sgehani%netscape.com
00009 // % First Checked In.
00010 // %                                                
00011 // % Revision 1.10  2000/12/23 06:11:55  neeri                             
00012 // % Add SSH service                                                       
00013 // %                                                                       
00014 // % Revision 1.9  2000/05/23 07:10:35  neeri                              
00015 // % Improve formatting                                                    
00016 // %                                                                       
00017 // % Revision 1.8  2000/03/15 07:18:43  neeri                              
00018 // % Fix GUSIBuiltinServiceDB::sServices                                   
00019 // %                                                                       
00020 // % Revision 1.7  1999/11/15 07:23:23  neeri                              
00021 // % Fix gethostname for non-TCP/IP case                                   
00022 // %                                                                       
00023 // % Revision 1.6  1999/08/26 05:45:05  neeri                              
00024 // % Fixes for literate edition of source code                             
00025 // %                                                                       
00026 // % Revision 1.5  1999/05/30 03:09:30  neeri                              
00027 // % Added support for MPW compilers                                       
00028 // %                                                                       
00029 // % Revision 1.4  1999/03/17 09:05:10  neeri                              
00030 // % Added GUSITimer, expanded docs                                        
00031 // %                                                                       
00032 // % Revision 1.3  1998/11/22 23:06:58  neeri                              
00033 // % Releasing 2.0a4 in a hurry                                            
00034 // %                                                                       
00035 // % Revision 1.2  1998/10/25 11:33:38  neeri                              
00036 // % Fixed disastrous bug in inet_addr, support alternative NL conventions 
00037 // %                                                                       
00038 // % Revision 1.1  1998/10/11 16:45:20  neeri                              
00039 // % Ready to release 2.0a2                                                
00040 // %                                                                       
00041 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
00042 //                                                                         
00043 // \chapter{Converting Between Names and IP Addresses}                     
00044 //                                                                         
00045 // The [[GUSINetDB]] class coordinates access to the domain name server database.
00046 //                                                                         
00047 // The [[GUSIServiceDB]] class is responsible for a database of TCP/IP service
00048 // name to port number mappings.                                           
00049 //                                                                         
00050 // The [[hostent]] and [[servent]] classes are somewhat inconvenient to set up as
00051 // they reference extra chunks of memory, so we define the wrapper classes 
00052 // [[GUSIhostent]] and [[GUSIservent]].                                    
00053 //                                                                         
00054 // <GUSINetDB.h>=                                                          
00055 #ifndef _GUSINetDB_
00056 #define _GUSINetDB_
00057 
00058 #ifdef GUSI_SOURCE
00059 #include "GUSISpecific.h"
00060 
00061 #include <sys/types.h>
00062 #include <netdb.h>
00063 #include <arpa/inet.h>
00064 
00065 #include <ConditionalMacros.h>
00066 
00067 #if PRAGMA_STRUCT_ALIGN
00068 #pragma options align=native
00069 #endif
00070 
00071 // \section{Definition of [[GUSIhostent]] and [[GUSIservent]]}             
00072 //                                                                         
00073 // A [[GUSIhostent]] may need a lot of data, so we allocate the name data  
00074 // dynamically.                                                            
00075 //                                                                         
00076 // <Definition of class [[GUSIhostent]]>=                                  
00077 class GUSIhostent : public hostent {
00078 public:
00079        GUSIhostent();
00080        
00081        void   Alloc(size_t size);
00082 
00083        char * fAlias[16];
00084        char * fAddressList[16];
00085        char *        fName;
00086        size_t fAlloc;
00087        char   fAddrString[16];
00088 };
00089 
00090 extern "C" void GUSIKillHostEnt(void * hostent);
00091 
00092 // A [[GUSIservent]] typically will remain more modest in its needs, so the
00093 // data is allocated statically.                                           
00094 //                                                                         
00095 // <Definition of class [[GUSIservent]]>=                                  
00096 class GUSIservent : public servent {
00097 public:
00098        GUSIservent();
00099        
00100        char * fAlias[8];
00101        char   fName[256];   
00102 };
00103 // \section{Definition of [[GUSIServiceDB]]}                               
00104 //                                                                         
00105 // [[GUSIServiceDB]] is a singleton, used as a primitive iterator. The semantics of
00106 // these iterators conform only very superficially to real iterators:      
00107 //                                                                         
00108 // \begin{itemize}                                                         
00109 // \item Only a single instance of the iterator is supported.              
00110 // \item Comparison operators all compare against [[end]], no matter what  
00111 // arguments are passed.                                                   
00112 // \end{itemize}                                                           
00113 //                                                                         
00114 // <Definition of class [[GUSIServiceDB]]>=                                
00115 extern "C" void GUSIKillServiceDBData(void * entry);
00116 
00117 class GUSIServiceDB {
00118 public:
00119        static GUSIServiceDB *      Instance();
00120        // Iterating is accomplished by a public interface conforming to STL iterator
00121  // protocols.                                                              
00122  //                                                                         
00123  // <Iterating over the [[GUSIServiceDB]]>=                                 
00124  class iterator {
00125  public:
00126        inline bool                 operator==(const iterator & other);
00127        inline bool                 operator!=(const iterator & other);
00128        inline iterator &           operator++();
00129        inline servent *            operator*();
00130  };
00131  inline static iterator     begin();
00132  inline static iterator     end();
00133 protected:
00134        static GUSIServiceDB *      sInstance;
00135                                                  GUSIServiceDB()             {}
00136        virtual                            ~GUSIServiceDB()     {}
00137        
00138        friend void GUSIKillServiceDBData(void * entry);
00139        
00140        // This interface does not access any data elements in the iterator, but directly 
00141  // calls through to a private interface in the [[GUSIServiceDB]], which explains
00142  // the limitations in the iterator implementation.                         
00143  //                                                                         
00144  // <Internal iterator protocol of [[GUSIServiceDB]]>=                      
00145  friend class iterator;
00146 
00147  class Data {
00148  public:
00149        Data() : fCurrent(0) {}
00150        
00151        servent *     fCurrent;
00152        GUSIservent   fServent;
00153  };
00154  typedef GUSISpecificData<Data, GUSIKillServiceDBData> SpecificData;
00155  static       SpecificData sData;
00156 
00157  virtual void Reset() = 0;
00158  virtual void Next() = 0;
00159 }; 
00160 // \section{Definition of [[GUSINetDB]]}                                   
00161 //                                                                         
00162 //                                                                         
00163 // <Definition of class [[GUSINetDB]]>=                                    
00164 class GUSINetDB {
00165 public:
00166        // [[GUSINetDB]] is a singleton, but usually instantiated by an instance of a 
00167  // derived class.                                                          
00168  //                                                                         
00169  // <Constructing instances of [[GUSINetDB]]>=                              
00170        static GUSINetDB *   Instance();
00171        // The public interface of [[GUSINetDB]] consists of three areas. The first set of
00172  // calls is concerned with host names and IP numbers.                      
00173  //                                                                         
00174  // <[[GUSINetDB]] host database>=                                          
00175  virtual hostent *   gethostbyname(const char * name);
00176  virtual hostent *   gethostbyaddr(const void * addr, size_t len, int type);
00177  virtual char *             inet_ntoa(in_addr inaddr);
00178  virtual in_addr_t   inet_addr(const char *address);
00179  virtual long        gethostid();
00180  virtual int                gethostname(char *machname, int buflen);
00181        // The next set of calls is concerned with TCP and UDP services.           
00182  //                                                                         
00183  // <[[GUSINetDB]] service database>=                                       
00184  virtual servent *   getservbyname(const char * name, const char * proto);
00185  virtual servent *   getservbyport(int port, const char * proto);
00186  virtual servent *   getservent();
00187  virtual void        setservent(int stayopen);
00188  virtual void        endservent();
00189        // Finally, there is a set of calls concerned with protocols.              
00190  //                                                                         
00191  // <[[GUSINetDB]] protocol database>=                                      
00192  virtual protoent *  getprotobyname(const char * name);
00193  virtual protoent *  getprotobynumber(int proto);
00194  virtual protoent *  getprotoent();
00195  virtual void        setprotoent(int stayopen);
00196  virtual void        endprotoent();
00197 protected:
00198        GUSINetDB();
00199        virtual ~GUSINetDB()        {}
00200        // \section{Implementation of [[GUSINetDB]]}                               
00201  //                                                                         
00202  // [[GUSINetDB]] is a singleton, but typically implemented by an instance  
00203  // of a subclass (stored into [[fInstance]] by that subclass) rather than the
00204  // base class.                                                             
00205  //                                                                         
00206  // <Privatissima of [[GUSINetDB]]>=                                        
00207  static GUSINetDB *         sInstance;
00208  // The service database is implemented in terms of [[GUSIServiceDB]]. Only 
00209  // [[getservent]] and [[setservent]] accesse [[GUSIServiceDB]] directly, however.
00210  //                                                                         
00211  // <Privatissima of [[GUSINetDB]]>=                                        
00212  bool                              fServiceOpen;
00213  GUSIServiceDB::iterator    fServiceIter;
00214  // The protocol database is similar, in principle, to the service database, but it
00215  // lends itself naturally to a much simpler implementation.                
00216  //                                                                         
00217  // <Privatissima of [[GUSINetDB]]>=                                        
00218  int                        fNextProtocol;
00219  static protoent     sProtocols[2];
00220 }; 
00221 
00222 #if PRAGMA_STRUCT_ALIGN
00223 #pragma options align=reset
00224 #endif
00225 
00226 #ifdef GUSI_INTERNAL
00227 
00228 // Iterators can be defined without regard to the implementation of the    
00229 // [[GUSIServiceDB]] currently used.                                       
00230 //                                                                         
00231 // <Inline member functions for class [[GUSIServiceDB]]>=                  
00232 GUSIServiceDB::iterator     GUSIServiceDB::begin()
00233 {
00234        Instance()->Reset();
00235        Instance()->Next();
00236        
00237        return iterator();
00238 }
00239 GUSIServiceDB::iterator     GUSIServiceDB::end()
00240 {
00241        return iterator();
00242 }
00243 bool GUSIServiceDB::iterator::operator==(const GUSIServiceDB::iterator &)
00244 {
00245        return !GUSIServiceDB::sData->fCurrent;
00246 }
00247 bool GUSIServiceDB::iterator::operator!=(const GUSIServiceDB::iterator &)
00248 {
00249        return GUSIServiceDB::sData->fCurrent 
00250               == static_cast<servent *>(nil);
00251 }
00252 GUSIServiceDB::iterator & GUSIServiceDB::iterator::operator++()
00253 {
00254        GUSIServiceDB::Instance()->Next();
00255        return *this;
00256 }
00257 servent * GUSIServiceDB::iterator::operator*()
00258 {
00259        return GUSIServiceDB::sData->fCurrent;
00260 }
00261 
00262 #endif /* GUSI_INTERNAL */
00263 
00264 #endif /* GUSI_SOURCE */
00265 
00266 #endif /* _GUSINetDB_ */