<* M2EXTENSIONS + *>

DEFINITION MODULE ["SysCall"] NetDB;

        (********************************************************)
        (*                                                      *)
        (*             Network database library.                *)
        (*                                                      *)
        (*  Structures returned by network data base library.   *)
        (*  All addresses are supplied in host order, and       *)
        (*  returned in network order.                          *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            27 February 1998                *)
        (*  Last edited:        17 August 2000                  *)
        (*  Status:             Partly implemented              *)
        (*                                                      *)
        (*          I haven't bothered to implement the         *)
        (*          procedures I don't need.                    *)
        (*                                                      *)
        (********************************************************)

(********************************************************************************)
(*                                                                              *)
(* This module is derived in part from the netdb.h file that comes with OS/2    *)
(* Warp 4, and that file carries the following copyright notice:                *)
(*                                                                              *)
(* Copyright (c) 1980,1983,1988 Regents of the University of California.        *)
(* All rights reserved.                                                         *)
(*                                                                              *)
(* Redistribution and use in source and binary forms are permitted              *)
(* provided that this notice is preserved and that due credit is given          *)
(* to the University of California at Berkeley. The name of the University      *)
(* may not be used to endorse or promote products derived from this             *)
(* software without specific prior written permission. This software            *)
(* is provided ``as is'' without express or implied warranty.                   *)
(*                                                                              *)
(*      @(#)netdb.h     5.9 (Berkeley) 4/5/88                                   *)
(*                                                                              *)
(********************************************************************************)

FROM SYSTEM IMPORT CARD32;

FROM Sockets IMPORT AddressFamily;

CONST
    MAXALIASES = 35;
    MAXADDRS   = 35;

TYPE
    Subscript = [0..511];
    AddressPointerArrayPointer = POINTER TO ARRAY [0..MAXADDRS]
                                             OF POINTER TO CARDINAL;

    (* The fields in a HostEnt structure are defined as follows.                *)
    (*   h_name         Official name of the host                               *)
    (*   h_aliases      Zero-terminated array of alternative names for the host *)
    (*   h_addrtype     The address family of the network address being         *)
    (*                        returned, always set to AF_INET                   *)
    (*   h_length       Length of the address in bytes                          *)
    (*   h_addr_list    Pointer to array of pointers to addresses returned by   *)
    (*                  the name server.  Each address is in network byte order *)

    HostEntPtr = POINTER TO
                   RECORD
                       h_name: POINTER TO ARRAY Subscript OF CHAR;
                       h_aliases: POINTER TO ARRAY [0..MAXALIASES-1] OF
                                          POINTER TO ARRAY Subscript OF CHAR;
                       h_addrtype: CARDINAL;
                       h_length: CARDINAL;
                       h_addr_list: AddressPointerArrayPointer;
                   END (*RECORD*);

PROCEDURE ["SysCall"] gethostname (VAR (*OUT*) name: ARRAY OF CHAR;
                                                  namelength: CARDINAL): BOOLEAN;

    (* Returns our own host name in "name".  The function result is TRUE iff    *)
    (* there was an error.                                                      *)

PROCEDURE ["SysCall"] gethostbyname (name: ARRAY OF CHAR): HostEntPtr;

    (* Result: a pointer to a hostent structure maintained by the library,      *)
    (* which gives details of the host name.  The result could be NIL if there  *)
    (* was an error.                                                            *)

PROCEDURE ["SysCall"] gethostbyaddr (VAR (*IN*) addr: CARD32;  addrlength: CARDINAL;
                                               family: AddressFamily): HostEntPtr;

    (* Input: addr is a 32-bit Internet address in network-byte order.  The     *)
    (* second and third parameters should always be equal to SIZE(CARD32) and   *)
    (* AF_INET, as far as I can tell.                                           *)
    (* Result: a pointer to a hostent structure maintained by the library,      *)
    (* which gives details of the host name.  The result could be NIL if there  *)
    (* was an error.                                                            *)

PROCEDURE ["SysCall"] tcp_h_errno(): CARDINAL;

    (* Returns the error code from the last gethostbyname or gethostbyaddr call.*)
    (* The values are                                                           *)
    (*      0     no error                                                      *)
    (*      1     host not found                                                *)
    (*      2     nameserver failure, try again later                           *)
    (*      3     unrecoverable error                                           *)
    (*      4     address is valid, but does not have a nameserver entry.       *)
    (* Discovery: this is often returning an error code 1 after gethostbyname   *)
    (* or gethostbyaddr even though the host was found.  I conclude that this   *)
    (* function must be buggy, at least for some releases of tcp/ip.            *)

END NetDB.

(********************************************************************************)
(*                The following part has not yet been translated                *)
(********************************************************************************)

/*
 * Assumption here is that a network number
 * fits in 32 bits -- probably a poor one.
 */
struct  netent {
        char            *n_name;        /* official name of net */
        char            **n_aliases;    /* alias list */
        int             n_addrtype;     /* net address type */
        unsigned long   n_net;          /* network # */
};

struct  servent {
        char    *s_name;        /* official service name */
        char    **s_aliases;    /* alias list */
        int     s_port;         /* port # */
        char    *s_proto;       /* protocol to use */
};

struct  protoent {
        char    *p_name;        /* official protocol name */
        char    **p_aliases;    /* alias list */
        int     p_proto;        /* protocol # */
};

#include <stdio.h>
#include <string.h>
#include <netinet\in.h>
#define _MAXALIASES     35
#define _MAXADDRS       35
#define _MAXLINELEN     1024
#define _HOSTBUFSIZE    (BUFSIZ + 1)

/*
 * After a successful call to gethostbyname_r()/gethostbyaddr_r(), the
 * structure hostent_data will contain the data to which pointers in
 * the hostent structure will point to.
 */

struct  hostent_data {
        struct    in_addr host_addr;              /* host address pointer */
        char      *h_addr_ptrs[_MAXADDRS + 1];    /* host address         */
        char      hostaddr[_MAXADDRS];
        char      hostbuf[_HOSTBUFSIZE + 1];      /* host data            */
        char      *host_aliases[_MAXALIASES];
        char      *host_addrs[2];
        FILE      *hostf;
        int       stayopen;                       /* AIX addon            */
        unsigned  long  host_addresses[_MAXADDRS];/* As per defect 48367. */
};                                                /*    Actual Addresses. */

struct  servent_data {          /* should be considered opaque */
        FILE *serv_fp;
        char line[_MAXLINELEN];
        char *serv_aliases[_MAXALIASES];
        int _serv_stayopen;
};

int _System getservbyname_r(char *, char *, struct servent *, struct servent_data *);
struct hostent * _System _gethtbyname( char * );
struct hostent * _System _gethtbyaddr( char *, int, int );
struct netent * _System getnetbyname( char * );
struct netent * _System getnetbyaddr( unsigned long, int );
struct servent * _System getservbyname( char *, char * );
struct servent * _System getservbyport( int, char * );
struct servent * _System getservent( void );
struct protoent * _System getprotobyname( char * );
struct protoent * _System getprotobynumber( int );
void _System sethostent( int );
struct hostent * _System gethostent( void );
void _System endhostent(void);
void _System setnetent( int );
struct netent * _System getnetent( void );
void _System endnetent(void);
void _System setprotoent( int );
struct protoent * _System getprotoent( void );
void _System endprotoent(void);
void _System setservent( int );
struct servent * _System getservent( void );
void _System endservent(void);

/*
 * Error return codes from gethostbyname() and gethostbyaddr()
 * (left in extern int h_errno).
 */

#define h_errno (tcp_h_errno())   /* Thread Re-entrant */

#define HOST_NOT_FOUND  1 /* Authoritative Answer Host not found */
#define TRY_AGAIN       2 /* Non-Authoritive Host not found, or SERVERFAIL */
#define NO_RECOVERY     3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
#define NO_DATA         4 /* Valid name, no data record of requested type */
#define NO_ADDRESS      NO_DATA         /* no address, look for MX record */

#endif /* __NETDB_32H  */
