Teach Windows build and installer about new _symtable module/DLL.
[python/dscho.git] / Mac / Unsupported / GUSI1-mods / GUSINetDB.cp
blob8b2140e5c4e5e129fe209765006a2c00924af94e
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  2000/09/12 20:24:49  jack
15 Moved to Unsupported.
17 Revision 1.1  1998/08/18 14:52:38  jack
18 Putting Python-specific GUSI modifications under CVS.
20 Revision 1.3  1994/08/10  00:07:30  neeri
21 Sanitized for universal headers.
23 Revision 1.2  1994/05/01  23:43:31  neeri
24 getservbyname() without /etc/services would fail.
26 Revision 1.1  1994/02/25  02:29:36  neeri
27 Initial revision
29 Revision 0.5  1993/10/31  00:00:00  neeri
30 Deferred opening of resolver
32 Revision 0.4  1993/07/29  00:00:00  neeri
33 Real getservent code (adapted from Sak Wathanasin)
35 Revision 0.3  1993/01/19  00:00:00  neeri
36 Can't set aliases to NULL.
38 Revision 0.2  1992/11/21  00:00:00  neeri
39 Remove force_active
41 Revision 0.1  1992/09/14  00:00:00  neeri
42 Maybe it works, maybe it doesn't
44 *********************************************************************/
46 #include "GUSIINET_P.h"
48 #include "TFileSpec.h"
49 #include "Folders.h"
50 #include "PLStringFuncs.h"
52 #ifdef __MWERKS__
54 // I disapprove of the way dnr.c is written
55 // This disapproval gets stronger with every version
57 #include "dnr.c"
58 #pragma require_prototypes reset
59 #pragma cplusplus reset
60 #endif
62 #if GENERATING68K
63 #pragma segment GUSIINET
64 #endif
66 static pascal void DNRDone(struct hostInfo *, Boolean * done)
68         *done = true;
71 #if GENERATINGCFM
72 RoutineDescriptor       uDNRDone = 
73                 BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRDone);
74 #else
75 #define uDNRDone DNRDone
76 #endif
78 int h_errno;
81  *   Gethostbyname and gethostbyaddr each return a pointer to an
82  *   object with the following structure describing an Internet
83  *   host referenced by name or by address, respectively. This
84  *   structure contains the information obtained from the MacTCP
85  *   name server.
86  *
87  *   struct    hostent
88  *   {
89  *        char *h_name;
90  *        char **h_aliases;
91  *        int  h_addrtype;
92  *        int  h_length;
93  *        char **h_addr_list;
94  *   };
95  *   #define   h_addr  h_addr_list[0]
96  *
97  *   The members of this structure are:
98  *
99  *   h_name       Official name of the host.
101  *   h_aliases    A zero terminated array of alternate names for the host.
103  *   h_addrtype   The type of address being  returned; always AF_INET.
105  *   h_length     The length, in bytes, of the address.
107  *   h_addr_list  A zero terminated array of network addresses for the host.
109  *   Error return status from gethostbyname and gethostbyaddr  is
110  *   indicated by return of a null pointer.  The external integer
111  *   h_errno may then  be checked  to  see  whether  this  is  a
112  *   temporary  failure  or  an  invalid  or  unknown  host.  The
113  *   routine herror  can  be  used  to  print  an error  message
114  *   describing the failure.  If its argument string is non-NULL,
115  *   it is printed, followed by a colon and a space.   The  error
116  *   message is printed with a trailing newline.
118  *   h_errno can have the following values:
120  *     HOST_NOT_FOUND  No such host is known.
122  *     TRY_AGAIN        This is usually a temporary error and
123  *                                      means   that  the  local  server  did  not
124  *                                      receive a response from  an  authoritative
125  *                                      server.   A  retry at some later time may
126  *                                      succeed.
128  *     NO_RECOVERY      Some unexpected server failure was encountered.
129  *                                      This is a non-recoverable error.
131  *     NO_DATA          The requested name is valid but  does  not
132  *                                      have   an IP  address;  this  is not  a
133  *                                      temporary error. This means that the  name
134  *                                      is known  to the name server but there is
135  *                                      no address  associated  with  this  name.
136  *                                      Another type of request to the name server
137  *                                      using this domain name will result in  an
138  *                                      answer;  for example, a mail-forwarder may
139  *                                      be registered for this domain.
140  *                                      (NOT GENERATED BY THIS IMPLEMENTATION)
141  */
143 static struct hostInfo macHost;
145 #define MAXALIASES 0
146 static char *aliasPtrs[MAXALIASES+1] = {NULL};
147 static ip_addr *addrPtrs[NUM_ALT_ADDRS+1];
149 static struct hostent  unixHost =
151         macHost.cname,
152         aliasPtrs,
153         AF_INET,
154         sizeof(ip_addr),
155         (char **) addrPtrs
158 inline struct in_addr make_in_addr(ip_addr addr)
160         struct in_addr  res;
162         res.s_addr      =       addr;
164         return res;
167 struct hostent * gethostbyname(char *name)
169         Boolean done;
170         int i;
172         if (!strcmp(name, "localhost")) {
173                 in_addr ipaddr;
175                 ipaddr  =       make_in_addr(ip_addr(gethostid()));
177                 if (ipaddr.s_addr)
178                         return gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
180                 h_errno = HOST_NOT_FOUND;
181                         
182                 return NULL;
183         }
184         
185         if (INETSockets.Resolver()) {
186                 h_errno = NO_RECOVERY;  
187                 return NULL;
188         }
189         
190         for (i=0; i<NUM_ALT_ADDRS; i++)
191                 macHost.addr[i] = 0;
193         done = false;
195         if (StrToAddr(name, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
196                 SPINP(!done,SP_NAME,0L);
198         switch (macHost.rtnCode) {
199         case noErr: break;
201         case nameSyntaxErr:     h_errno = HOST_NOT_FOUND;       return(NULL);
202         case cacheFault:                h_errno = NO_RECOVERY;          return(NULL);
203         case noResultProc:      h_errno = NO_RECOVERY;          return(NULL);
204         case noNameServer:      h_errno = HOST_NOT_FOUND;       return(NULL);
205         case authNameErr:               h_errno = HOST_NOT_FOUND;       return(NULL);
206         case noAnsErr:                  h_errno = TRY_AGAIN;                    return(NULL);
207         case dnrErr:                    h_errno = NO_RECOVERY;          return(NULL);
208         case outOfMemory:               h_errno = TRY_AGAIN;                    return(NULL);
209         default:                                        h_errno = NO_RECOVERY;          return(NULL);
210         }
212         /* was the 'name' an IP address? */
213         if (macHost.cname[0] == 0) {
214                 h_errno = HOST_NOT_FOUND;
215                 return(NULL);
216         }
218         /* for some reason there is a dot at the end of the name */
219         i = int(strlen(macHost.cname)) - 1;
220         if (macHost.cname[i] == '.')
221                 macHost.cname[i] = 0;
223         for (i=0; i<NUM_ALT_ADDRS && macHost.addr[i]!=0; i++)
224                 addrPtrs[i] =   (ip_addr *) &macHost.addr[i];
226         addrPtrs[i] = NULL;
228         return &unixHost;
231 struct hostent * gethostbyaddr(const char *addrP, int, int)
233         Boolean done;
234         int             i;
236         if (INETSockets.Resolver()) {
237                 h_errno = NO_RECOVERY;  
238                 return NULL;
239         }
241         for (i=0; i<NUM_ALT_ADDRS; i++)
242                 macHost.addr[i] = 0;
244         done = false;
246         ip_addr addr = FIX_LOOPBACK(*(ip_addr *)addrP);
247         
248         if (AddrToName(addr, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
249                 SPINP(!done,SP_ADDR,0L);
251         switch (macHost.rtnCode) {
252         case noErr:                     break;
254         case cacheFault:                h_errno = NO_RECOVERY;          return(NULL);
255         case noNameServer:      h_errno = HOST_NOT_FOUND;       return(NULL);
256         case authNameErr:               h_errno = HOST_NOT_FOUND;       return(NULL);
257         case noAnsErr:                  h_errno = TRY_AGAIN;                    return(NULL);
258         case dnrErr:                    h_errno = NO_RECOVERY;          return(NULL);
259         case outOfMemory:               h_errno = TRY_AGAIN;                    return(NULL);
260         default:                                        h_errno = NO_RECOVERY;          return(NULL);
261         }
263         /* for some reason there is a dot at the end of the name */
264         i = int(strlen(macHost.cname)) - 1;
265         if (macHost.cname[i] == '.')
266                 macHost.cname[i] = 0;
268         /* For some reason, the IP address usually seems to be set to 0 */
269         if (!macHost.addr[0])
270                 macHost.addr[0] = addr;
271                 
272         for (i=0; i<NUM_ALT_ADDRS; i++)
273                 addrPtrs[i] = (ip_addr *) &macHost.addr[i];
275         addrPtrs[NUM_ALT_ADDRS] = NULL;
277         return &unixHost;
280 char * inet_ntoa(struct in_addr inaddr)
282         if (INETSockets.Resolver()) {
283                 h_errno = NO_RECOVERY;  
284                 return NULL;
285         }
286         
287         (void) AddrToStr(inaddr.s_addr, macHost.cname);
289         return macHost.cname;
292 struct in_addr inet_addr(char *address)
294         if (INETSockets.Resolver()) {
295                 h_errno = NO_RECOVERY;  
296                 return make_in_addr(0xFFFFFFFF);
297         }
298         
299         if (StrToAddr(address,&macHost,NULL,NULL) != noErr)
300                 return make_in_addr(0xFFFFFFFF);
302         /* was the 'address' really a name? */
303         if (macHost.cname[0] != 0)
304                 return make_in_addr(0xFFFFFFFF);
306         return make_in_addr(macHost.addr[0]);
310  * gethostid()
312  * Get internet address of current host
313  */
315 long gethostid()
317         static long sHostID = 0;
318         if (sHostID)
319                 return sHostID;
320         
321         struct GetAddrParamBlock pbr;
322                 
323         pbr.ioCRefNum   = INETSockets.Driver();
324         pbr.csCode              = ipctlGetAddr;
326         if (PBControlSync(ParmBlkPtr(&pbr)))
327                 return 0;
328         else
329                 return sHostID = (long)pbr.ourAddress;
333  * gethostname()
335  * Try to get my host name from DNR. If it fails, just return my
336  * IP address as ASCII. This is non-standard, but it's a mac,
337  * what do you want me to do?
338  */
340 int gethostname(char *machname, int buflen)
342         static char * sHostName = nil;
343         
344         if (!sHostName) {
345                 in_addr ipaddr;
346                 struct  hostent *hp;
348                 ipaddr  =       make_in_addr(ip_addr(gethostid()));
350                 if (!ipaddr.s_addr)                                     // TCP/IP not up at all
351                         return GUSI_error(ENETDOWN);
352                 
353                 hp = gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
355                 if (!hp) {
356                         // No good name
357                         if (buflen < 16)                                                // Not enough space
358                                 return GUSI_error(EINVAL);      
359                         sprintf(machname, "%d.%d.%d.%d",
360                                                         ipaddr.s_addr>>24,
361                                                         ipaddr.s_addr>>16 & 0xff,
362                                                         ipaddr.s_addr>>8 & 0xff,
363                                                         ipaddr.s_addr & 0xff);
364                         return 0;
365                 } else {
366                         // We only cache satisfactory replies in sHostName
367                         sHostName = new char[strlen(hp->h_name)+1];
368                         strcpy(sHostName, hp->h_name);
369                 }
370         }
371         strncpy(machname, sHostName, unsigned(buflen));
372         machname[buflen-1] = 0;  /* extra safeguard */
374         return 0;
379  *      getservbybname()
381  */
383 static char * servlist[] =
385         "echo                     7/udp",
386         "discard          9/udp",
387         "time                    37/udp",
388         "domain          53/udp",
389         "sunrpc         111/udp",
390         "tftp            69/udp",
391         "biff                   512/udp",
392         "who            513/udp",
393         "talk                   517/udp",
394         "ftp-data        20/tcp",
395         "ftp             21/tcp",
396         "telnet          23/tcp",
397         "smtp            25/tcp",
398         "time            37/tcp",
399         "whois                   43/tcp",
400         "domain                  53/tcp",
401         "hostnames  101/tcp",
402         "nntp                   119/tcp",
403         "finger          79/tcp",
404         "ntp            123/tcp",
405         "uucp                   540/tcp",
406         NULL
409 static char                             servline[128];
410 static struct servent   serv;
411 static FILE *                           servfil;
412 static int                                      servptr;
413 static char *                           servalias[8];
414 static int                                      servstay = 0;
416 void setservent(int stayopen)
418         if (servfil && servfil != (FILE *) -1) {
419                 rewind(servfil);
420         }
421         servptr = 0;
422         servstay = servstay || stayopen;
425 void endservent()
427         if (servfil && servfil != (FILE *) -1) {
428                 fclose(servfil);
429                 servfil = NULL;
430         }
431         
432         servstay = 0;
435 struct servent *  getservent()
437         char *  p;
438         int             aliascount;
439         
440         if (!servfil) {
441                 TFileSpec serv;
442                 
443                 if (!FindFolder(
444                                 kOnSystemDisk, 
445                                 kPreferencesFolderType, 
446                                 kDontCreateFolder, 
447                                 &serv.vRefNum,
448                                 &serv.parID)
449                 ) {
450                         PLstrcpy(serv.name, (StringPtr) "\p/etc/services");
451                 
452                         if (servfil = fopen(serv.FullPath(), "r"))
453                                 goto retry;
454                 }       
455                 servfil         = (FILE *) -1;
456                 servptr = 0;
457         }
458         
459 retry:
460         if (servfil == (FILE *) -1)
461                 if (!servlist[servptr])
462                         return (struct servent *) NULL;
463                 else
464                         strcpy(servline, servlist[servptr++]);
465         else if (!(fgets(servline, 128, servfil)))
466                 return (struct servent *) NULL;
467                 
468         if (p = strpbrk(servline, "#\n\r"))
469                 *p = 0;
470         if (!servline[0])
471                 goto retry;
472         
473         if (!(serv.s_name = strtok(servline, " \t")))
474                 goto retry;
475                 
476         if (!(p = strtok(NULL, " \t")))
477                 goto retry;
478         
479         if (!(serv.s_proto = strpbrk(p, "/,")))
480                 goto retry;
481                 
482         *serv.s_proto++         = 0;
483         serv.s_port             = htons(atoi(p));
484         serv.s_aliases  = servalias;
485         
486         for (aliascount = 0; aliascount < 7; ) 
487                 if (!(servalias[aliascount++] = strtok(NULL, " \t")))
488                         break;
489         
490         servalias[aliascount] = NULL;
491         
492         return &serv;
495 struct servent * getservbyname(const char * name, const char * proto)
497         struct servent *        ent;
498         char **                                 al;
499         setservent(0);
500         
501         while (ent = getservent()) {
502                 if (!strcmp(name, ent->s_name))
503                         goto haveName;
504                 
505                 for (al = ent->s_aliases; *al; ++al)
506                         if (!strcmp(name, *al))
507                                 goto haveName;
508                 
509                 continue;
510 haveName:
511                 if (!proto || !strcmp(proto, ent->s_proto))
512                         break;
513         }
514         
515         if (!servstay)
516                 endservent();
517         
518         return ent;
521 struct servent * getservbyport(int port, const char * proto)
523         struct servent * ent;
524         
525         setservent(0);
526         
527         while (ent = getservent())
528                 if (port == ent->s_port && (!proto || !strcmp(proto, ent->s_proto)))
529                         break;
530         
531         if (!servstay)
532                 endservent();
533         
534         return ent;
537 static  char    tcp[] = "tcp";
538 static  char    udp[] = "udp";
539 #define MAX_PROTOENT                    10
540 static  struct protoent         protoents[MAX_PROTOENT];
541 static  int                                             protoent_count=0;
543 struct protoent * getprotobyname(const char * name)
545         struct protoent *pe;
547         pe = &protoents[protoent_count];
548         if (strcmp(name, "udp") == 0) {
549                 pe->p_name = udp;
550                 pe->p_proto = IPPROTO_UDP;
551         } else if (strcmp (name, "tcp") == 0)  {
552                 pe->p_name = tcp;
553                 pe->p_proto = IPPROTO_TCP;
554         } else {
555                 errno = EPROTONOSUPPORT;
556                 return NULL;
557         }
558         pe->p_aliases = aliasPtrs;
559         protoent_count = (protoent_count +1) % MAX_PROTOENT;
560         return pe;
563 struct protoent * getprotobynumber(int proto)
565         struct protoent *pe;
567         pe = &protoents[protoent_count];
568         if (proto == IPPROTO_UDP) {
569                 pe->p_name = udp;
570                 pe->p_proto = IPPROTO_UDP;
571         } else if (proto == IPPROTO_TCP)  {
572                 pe->p_name = tcp;
573                 pe->p_proto = IPPROTO_TCP;
574         } else {
575                 errno = EPROTONOSUPPORT;
576                 return NULL;
577         }
578         pe->p_aliases = aliasPtrs;
579         protoent_count = (protoent_count +1) % MAX_PROTOENT;
580         return pe;