Ditched '_find_SET()', since it was a no-value-added wrapper around
[python/dscho.git] / Mac / GUSI-mods / into-src / GUSINetDB.cp
blobbc435b6c7fc6b0db4c80ba68d108ccbaaeebc226
1 /*********************************************************************
2 Project :       GUSI                            -       Grand Unified Socket Interface
3 File            :       GUSINetDB.cp    -       Convert internet names to adresses
4 Author  :       Matthias Neeracher
6         This file was derived from the socket library by
8                 Charlie Reiman  <creiman@ncsa.uiuc.edu> and
9                 Tom Milligan    <milligan@madhaus.utcs.utoronto.ca>
11 Language        :       MPW C++
13 $Log$
14 Revision 1.1  1998/08/18 14:52:38  jack
15 Putting Python-specific GUSI modifications under CVS.
17 Revision 1.3  1994/08/10  00:07:30  neeri
18 Sanitized for universal headers.
20 Revision 1.2  1994/05/01  23:43:31  neeri
21 getservbyname() without /etc/services would fail.
23 Revision 1.1  1994/02/25  02:29:36  neeri
24 Initial revision
26 Revision 0.5  1993/10/31  00:00:00  neeri
27 Deferred opening of resolver
29 Revision 0.4  1993/07/29  00:00:00  neeri
30 Real getservent code (adapted from Sak Wathanasin)
32 Revision 0.3  1993/01/19  00:00:00  neeri
33 Can't set aliases to NULL.
35 Revision 0.2  1992/11/21  00:00:00  neeri
36 Remove force_active
38 Revision 0.1  1992/09/14  00:00:00  neeri
39 Maybe it works, maybe it doesn't
41 *********************************************************************/
43 #include "GUSIINET_P.h"
45 #include "TFileSpec.h"
46 #include "Folders.h"
47 #include "PLStringFuncs.h"
49 #ifdef __MWERKS__
51 // I disapprove of the way dnr.c is written
52 // This disapproval gets stronger with every version
54 #include "dnr.c"
55 #pragma require_prototypes reset
56 #pragma cplusplus reset
57 #endif
59 #if GENERATING68K
60 #pragma segment GUSIINET
61 #endif
63 static pascal void DNRDone(struct hostInfo *, Boolean * done)
65         *done = true;
68 #if GENERATINGCFM
69 RoutineDescriptor       uDNRDone = 
70                 BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRDone);
71 #else
72 #define uDNRDone DNRDone
73 #endif
75 int h_errno;
78  *   Gethostbyname and gethostbyaddr each return a pointer to an
79  *   object with the following structure describing an Internet
80  *   host referenced by name or by address, respectively. This
81  *   structure contains the information obtained from the MacTCP
82  *   name server.
83  *
84  *   struct    hostent
85  *   {
86  *        char *h_name;
87  *        char **h_aliases;
88  *        int  h_addrtype;
89  *        int  h_length;
90  *        char **h_addr_list;
91  *   };
92  *   #define   h_addr  h_addr_list[0]
93  *
94  *   The members of this structure are:
95  *
96  *   h_name       Official name of the host.
97  *
98  *   h_aliases    A zero terminated array of alternate names for the host.
99  *
100  *   h_addrtype   The type of address being  returned; always AF_INET.
102  *   h_length     The length, in bytes, of the address.
104  *   h_addr_list  A zero terminated array of network addresses for the host.
106  *   Error return status from gethostbyname and gethostbyaddr  is
107  *   indicated by return of a null pointer.  The external integer
108  *   h_errno may then  be checked  to  see  whether  this  is  a
109  *   temporary  failure  or  an  invalid  or  unknown  host.  The
110  *   routine herror  can  be  used  to  print  an error  message
111  *   describing the failure.  If its argument string is non-NULL,
112  *   it is printed, followed by a colon and a space.   The  error
113  *   message is printed with a trailing newline.
115  *   h_errno can have the following values:
117  *     HOST_NOT_FOUND  No such host is known.
119  *     TRY_AGAIN        This is usually a temporary error and
120  *                                      means   that  the  local  server  did  not
121  *                                      receive a response from  an  authoritative
122  *                                      server.   A  retry at some later time may
123  *                                      succeed.
125  *     NO_RECOVERY      Some unexpected server failure was encountered.
126  *                                      This is a non-recoverable error.
128  *     NO_DATA          The requested name is valid but  does  not
129  *                                      have   an IP  address;  this  is not  a
130  *                                      temporary error. This means that the  name
131  *                                      is known  to the name server but there is
132  *                                      no address  associated  with  this  name.
133  *                                      Another type of request to the name server
134  *                                      using this domain name will result in  an
135  *                                      answer;  for example, a mail-forwarder may
136  *                                      be registered for this domain.
137  *                                      (NOT GENERATED BY THIS IMPLEMENTATION)
138  */
140 static struct hostInfo macHost;
142 #define MAXALIASES 0
143 static char *aliasPtrs[MAXALIASES+1] = {NULL};
144 static ip_addr *addrPtrs[NUM_ALT_ADDRS+1];
146 static struct hostent  unixHost =
148         macHost.cname,
149         aliasPtrs,
150         AF_INET,
151         sizeof(ip_addr),
152         (char **) addrPtrs
155 inline struct in_addr make_in_addr(ip_addr addr)
157         struct in_addr  res;
159         res.s_addr      =       addr;
161         return res;
164 struct hostent * gethostbyname(char *name)
166         Boolean done;
167         int i;
169         if (!strcmp(name, "localhost")) {
170                 in_addr ipaddr;
172                 ipaddr  =       make_in_addr(ip_addr(gethostid()));
174                 if (ipaddr.s_addr)
175                         return gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
177                 h_errno = HOST_NOT_FOUND;
178                         
179                 return NULL;
180         }
181         
182         if (INETSockets.Resolver()) {
183                 h_errno = NO_RECOVERY;  
184                 return NULL;
185         }
186         
187         for (i=0; i<NUM_ALT_ADDRS; i++)
188                 macHost.addr[i] = 0;
190         done = false;
192         if (StrToAddr(name, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
193                 SPINP(!done,SP_NAME,0L);
195         switch (macHost.rtnCode) {
196         case noErr: break;
198         case nameSyntaxErr:     h_errno = HOST_NOT_FOUND;       return(NULL);
199         case cacheFault:                h_errno = NO_RECOVERY;          return(NULL);
200         case noResultProc:      h_errno = NO_RECOVERY;          return(NULL);
201         case noNameServer:      h_errno = HOST_NOT_FOUND;       return(NULL);
202         case authNameErr:               h_errno = HOST_NOT_FOUND;       return(NULL);
203         case noAnsErr:                  h_errno = TRY_AGAIN;                    return(NULL);
204         case dnrErr:                    h_errno = NO_RECOVERY;          return(NULL);
205         case outOfMemory:               h_errno = TRY_AGAIN;                    return(NULL);
206         default:                                        h_errno = NO_RECOVERY;          return(NULL);
207         }
209         /* was the 'name' an IP address? */
210         if (macHost.cname[0] == 0) {
211                 h_errno = HOST_NOT_FOUND;
212                 return(NULL);
213         }
215         /* for some reason there is a dot at the end of the name */
216         i = int(strlen(macHost.cname)) - 1;
217         if (macHost.cname[i] == '.')
218                 macHost.cname[i] = 0;
220         for (i=0; i<NUM_ALT_ADDRS && macHost.addr[i]!=0; i++)
221                 addrPtrs[i] =   (ip_addr *) &macHost.addr[i];
223         addrPtrs[i] = NULL;
225         return &unixHost;
228 struct hostent * gethostbyaddr(const char *addrP, int, int)
230         Boolean done;
231         int             i;
233         if (INETSockets.Resolver()) {
234                 h_errno = NO_RECOVERY;  
235                 return NULL;
236         }
238         for (i=0; i<NUM_ALT_ADDRS; i++)
239                 macHost.addr[i] = 0;
241         done = false;
243         ip_addr addr = FIX_LOOPBACK(*(ip_addr *)addrP);
244         
245         if (AddrToName(addr, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
246                 SPINP(!done,SP_ADDR,0L);
248         switch (macHost.rtnCode) {
249         case noErr:                     break;
251         case cacheFault:                h_errno = NO_RECOVERY;          return(NULL);
252         case noNameServer:      h_errno = HOST_NOT_FOUND;       return(NULL);
253         case authNameErr:               h_errno = HOST_NOT_FOUND;       return(NULL);
254         case noAnsErr:                  h_errno = TRY_AGAIN;                    return(NULL);
255         case dnrErr:                    h_errno = NO_RECOVERY;          return(NULL);
256         case outOfMemory:               h_errno = TRY_AGAIN;                    return(NULL);
257         default:                                        h_errno = NO_RECOVERY;          return(NULL);
258         }
260         /* for some reason there is a dot at the end of the name */
261         i = int(strlen(macHost.cname)) - 1;
262         if (macHost.cname[i] == '.')
263                 macHost.cname[i] = 0;
265         /* For some reason, the IP address usually seems to be set to 0 */
266         if (!macHost.addr[0])
267                 macHost.addr[0] = addr;
268                 
269         for (i=0; i<NUM_ALT_ADDRS; i++)
270                 addrPtrs[i] = (ip_addr *) &macHost.addr[i];
272         addrPtrs[NUM_ALT_ADDRS] = NULL;
274         return &unixHost;
277 char * inet_ntoa(struct in_addr inaddr)
279         if (INETSockets.Resolver()) {
280                 h_errno = NO_RECOVERY;  
281                 return NULL;
282         }
283         
284         (void) AddrToStr(inaddr.s_addr, macHost.cname);
286         return macHost.cname;
289 struct in_addr inet_addr(char *address)
291         if (INETSockets.Resolver()) {
292                 h_errno = NO_RECOVERY;  
293                 return make_in_addr(0xFFFFFFFF);
294         }
295         
296         if (StrToAddr(address,&macHost,NULL,NULL) != noErr)
297                 return make_in_addr(0xFFFFFFFF);
299         /* was the 'address' really a name? */
300         if (macHost.cname[0] != 0)
301                 return make_in_addr(0xFFFFFFFF);
303         return make_in_addr(macHost.addr[0]);
307  * gethostid()
309  * Get internet address of current host
310  */
312 long gethostid()
314         static long sHostID = 0;
315         if (sHostID)
316                 return sHostID;
317         
318         struct GetAddrParamBlock pbr;
319                 
320         pbr.ioCRefNum   = INETSockets.Driver();
321         pbr.csCode              = ipctlGetAddr;
323         if (PBControlSync(ParmBlkPtr(&pbr)))
324                 return 0;
325         else
326                 return sHostID = (long)pbr.ourAddress;
330  * gethostname()
332  * Try to get my host name from DNR. If it fails, just return my
333  * IP address as ASCII. This is non-standard, but it's a mac,
334  * what do you want me to do?
335  */
337 int gethostname(char *machname, int buflen)
339         static char * sHostName = nil;
340         
341         if (!sHostName) {
342                 in_addr ipaddr;
343                 struct  hostent *hp;
345                 ipaddr  =       make_in_addr(ip_addr(gethostid()));
347                 if (!ipaddr.s_addr)                                     // TCP/IP not up at all
348                         return GUSI_error(ENETDOWN);
349                 
350                 hp = gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
352                 if (!hp) {
353                         // No good name
354                         if (buflen < 16)                                                // Not enough space
355                                 return GUSI_error(EINVAL);      
356                         sprintf(machname, "%d.%d.%d.%d",
357                                                         ipaddr.s_addr>>24,
358                                                         ipaddr.s_addr>>16 & 0xff,
359                                                         ipaddr.s_addr>>8 & 0xff,
360                                                         ipaddr.s_addr & 0xff);
361                         return 0;
362                 } else {
363                         // We only cache satisfactory replies in sHostName
364                         sHostName = new char[strlen(hp->h_name)+1];
365                         strcpy(sHostName, hp->h_name);
366                 }
367         }
368         strncpy(machname, sHostName, unsigned(buflen));
369         machname[buflen-1] = 0;  /* extra safeguard */
371         return 0;
376  *      getservbybname()
378  */
380 static char * servlist[] =
382         "echo                     7/udp",
383         "discard          9/udp",
384         "time                    37/udp",
385         "domain          53/udp",
386         "sunrpc         111/udp",
387         "tftp            69/udp",
388         "biff                   512/udp",
389         "who            513/udp",
390         "talk                   517/udp",
391         "ftp-data        20/tcp",
392         "ftp             21/tcp",
393         "telnet          23/tcp",
394         "smtp            25/tcp",
395         "time            37/tcp",
396         "whois                   43/tcp",
397         "domain                  53/tcp",
398         "hostnames  101/tcp",
399         "nntp                   119/tcp",
400         "finger          79/tcp",
401         "ntp            123/tcp",
402         "uucp                   540/tcp",
403         NULL
406 static char                             servline[128];
407 static struct servent   serv;
408 static FILE *                           servfil;
409 static int                                      servptr;
410 static char *                           servalias[8];
411 static int                                      servstay = 0;
413 void setservent(int stayopen)
415         if (servfil && servfil != (FILE *) -1) {
416                 rewind(servfil);
417         }
418         servptr = 0;
419         servstay = servstay || stayopen;
422 void endservent()
424         if (servfil && servfil != (FILE *) -1) {
425                 fclose(servfil);
426                 servfil = NULL;
427         }
428         
429         servstay = 0;
432 struct servent *  getservent()
434         char *  p;
435         int             aliascount;
436         
437         if (!servfil) {
438                 TFileSpec serv;
439                 
440                 if (!FindFolder(
441                                 kOnSystemDisk, 
442                                 kPreferencesFolderType, 
443                                 kDontCreateFolder, 
444                                 &serv.vRefNum,
445                                 &serv.parID)
446                 ) {
447                         PLstrcpy(serv.name, (StringPtr) "\p/etc/services");
448                 
449                         if (servfil = fopen(serv.FullPath(), "r"))
450                                 goto retry;
451                 }       
452                 servfil         = (FILE *) -1;
453                 servptr = 0;
454         }
455         
456 retry:
457         if (servfil == (FILE *) -1)
458                 if (!servlist[servptr])
459                         return (struct servent *) NULL;
460                 else
461                         strcpy(servline, servlist[servptr++]);
462         else if (!(fgets(servline, 128, servfil)))
463                 return (struct servent *) NULL;
464                 
465         if (p = strpbrk(servline, "#\n\r"))
466                 *p = 0;
467         if (!servline[0])
468                 goto retry;
469         
470         if (!(serv.s_name = strtok(servline, " \t")))
471                 goto retry;
472                 
473         if (!(p = strtok(NULL, " \t")))
474                 goto retry;
475         
476         if (!(serv.s_proto = strpbrk(p, "/,")))
477                 goto retry;
478                 
479         *serv.s_proto++         = 0;
480         serv.s_port             = htons(atoi(p));
481         serv.s_aliases  = servalias;
482         
483         for (aliascount = 0; aliascount < 7; ) 
484                 if (!(servalias[aliascount++] = strtok(NULL, " \t")))
485                         break;
486         
487         servalias[aliascount] = NULL;
488         
489         return &serv;
492 struct servent * getservbyname(const char * name, const char * proto)
494         struct servent *        ent;
495         char **                                 al;
496         setservent(0);
497         
498         while (ent = getservent()) {
499                 if (!strcmp(name, ent->s_name))
500                         goto haveName;
501                 
502                 for (al = ent->s_aliases; *al; ++al)
503                         if (!strcmp(name, *al))
504                                 goto haveName;
505                 
506                 continue;
507 haveName:
508                 if (!proto || !strcmp(proto, ent->s_proto))
509                         break;
510         }
511         
512         if (!servstay)
513                 endservent();
514         
515         return ent;
518 struct servent * getservbyport(int port, const char * proto)
520         struct servent * ent;
521         
522         setservent(0);
523         
524         while (ent = getservent())
525                 if (port == ent->s_port && (!proto || !strcmp(proto, ent->s_proto)))
526                         break;
527         
528         if (!servstay)
529                 endservent();
530         
531         return ent;
534 static  char    tcp[] = "tcp";
535 static  char    udp[] = "udp";
536 #define MAX_PROTOENT                    10
537 static  struct protoent         protoents[MAX_PROTOENT];
538 static  int                                             protoent_count=0;
540 struct protoent * getprotobyname(const char * name)
542         struct protoent *pe;
544         pe = &protoents[protoent_count];
545         if (strcmp(name, "udp") == 0) {
546                 pe->p_name = udp;
547                 pe->p_proto = IPPROTO_UDP;
548         } else if (strcmp (name, "tcp") == 0)  {
549                 pe->p_name = tcp;
550                 pe->p_proto = IPPROTO_TCP;
551         } else {
552                 errno = EPROTONOSUPPORT;
553                 return NULL;
554         }
555         pe->p_aliases = aliasPtrs;
556         protoent_count = (protoent_count +1) % MAX_PROTOENT;
557         return pe;
560 struct protoent * getprotobynumber(int proto)
562         struct protoent *pe;
564         pe = &protoents[protoent_count];
565         if (proto == IPPROTO_UDP) {
566                 pe->p_name = udp;
567                 pe->p_proto = IPPROTO_UDP;
568         } else if (proto == IPPROTO_TCP)  {
569                 pe->p_name = tcp;
570                 pe->p_proto = IPPROTO_TCP;
571         } else {
572                 errno = EPROTONOSUPPORT;
573                 return NULL;
574         }
575         pe->p_aliases = aliasPtrs;
576         protoent_count = (protoent_count +1) % MAX_PROTOENT;
577         return pe;