Added additional tcp-ip stuff for mac project

This commit is contained in:
cboatwri 1998-05-29 23:08:33 +00:00
Родитель b33d67da1e
Коммит 93bf370e96
2 изменённых файлов: 1077 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,992 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Copyright (c) 1990-92 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* tcp.c -- TCP communication related routines
*/
#include "lber.h"
#include "ldap.h"
#include "tcp.h"
#include <Devices.h>
#include <Events.h> /* to get SystemTask() */
#include <Memory.h>
#include <Errors.h>
#include <Gestalt.h>
/*
* local prototypes
*/
#ifdef NEEDPROTOS
void bzero( char *buf, unsigned long count );
pascal void setdoneflag( struct hostInfo *hip, char *donep );
pascal void tcp_asynchnotify( StreamPtr tstream, unsigned short event, Ptr userdatap,
unsigned short term_reason, struct ICMPReport *icmpmsg );
OSErr kick_mactcp( short *drefnump );
#ifdef SUPPORT_OPENTRANSPORT
pascal void EventHandler(tcpstream *tsp, OTEventCode event, OTResult result, void * /* cookie */);
#endif /* SUPPORT_OPENTRANSPORT */
#else /* NEEDPROTOS */
void bzero();
pascal void setdoneflag();
pascal void tcp_asynchnotify();
OSErr kick_mactcp();
#ifdef SUPPORT_OPENTRANSPORT
pascal void EventHandler();
#endif /* SUPPORT_OPENTRANSPORT */
#endif /* NEEDPROTOS */
#ifdef SUPPORT_OPENTRANSPORT
static Boolean gHaveOT = false;
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
/*
* Initialize the tcp module. This mainly consists of seeing if we have
* Open Transport and initializing it and setting our global saying so.
*/
OSStatus
tcp_init( void )
{
static Boolean sInitialized = false;
Boolean hasOT;
long gestaltResult;
OSStatus otErr = kOTNoError;
OSErr err;
if ( sInitialized ) {
return otErr;
}
err = Gestalt(gestaltOpenTpt, &gestaltResult);
hasOT = (err == noErr) && ((gestaltResult & gestaltOpenTptPresentMask) != 0);
hasOT = hasOT && ((gestaltResult & gestaltOpenTptTCPPresentMask) != 0);
sInitialized = true;
if ( hasOT ) {
gHaveOT = ( InitOpenTransport() == noErr );
}
return otErr;
}
Boolean
tcp_have_opentransport( void )
{
return( gHaveOT );
}
#endif /* SUPPORT_OPENTRANSPORT */
/*
* open and return an pointer to a TCP stream (return NULL if error)
* "buf" is a buffer for receives of length "buflen."
*/
tcpstream *
tcpopen( unsigned char * buf, long buflen ) {
TCPiopb pb;
OSStatus err;
tcpstream * tsp;
short drefnum;
#ifdef SUPPORT_OPENTRANSPORT
TEndpointInfo info;
#endif /* SUPPORT_OPENTRANSPORT */
if (nil == (tsp = (tcpstream *)NewPtrClear(sizeof(tcpstream)))) {
return( nil );
}
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
//
// Now create a TCP
//
tsp->tcps_ep = OTOpenEndpoint( OTCreateConfiguration( kTCPName ), 0, &info, &err );
if ( !tsp->tcps_ep ) {
if ( err == kOTNoError ) {
err = -1;
}
}
if ( !err ) {
err = OTSetSynchronous( tsp->tcps_ep );
}
tsp->tcps_data = 0;
tsp->tcps_terminated = tsp->tcps_connected = false;
//
// Install notifier we're going to use
//
if ( !err ) {
err = OTInstallNotifier( tsp->tcps_ep, (OTNotifyProcPtr) EventHandler, 0 );
}
if ( err != kOTNoError ) {
if ( tsp->tcps_ep ) {
OTCloseProvider( tsp->tcps_ep );
}
DisposePtr( (Ptr)tsp );
tsp = nil;
}
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( kick_mactcp( &drefnum ) != noErr ) {
return ( nil );
}
if (( tsp->tcps_notifyupp = NewTCPNotifyProc( tcp_asynchnotify )) == NULL ) {
DisposePtr( (Ptr)tsp );
return( nil );
}
tsp->drefnum = drefnum;
if ( buflen == 0 ) {
buflen = TCP_BUFSIZ;
}
if ( buf == NULL &&
(nil == ( buf = tsp->tcps_buffer = (unsigned char *)NewPtr( buflen )))) {
DisposeRoutineDescriptor( (UniversalProcPtr)tsp->tcps_notifyupp );
DisposePtr( (Ptr)tsp );
return( nil );
}
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPCreate;
pb.ioCRefNum = tsp->drefnum;
pb.csParam.create.rcvBuff = (Ptr) buf;
pb.csParam.create.rcvBuffLen = buflen;
pb.csParam.create.notifyProc = tsp->tcps_notifyupp;
pb.csParam.create.userDataPtr = (Ptr)tsp;
if (( err = PBControl( (ParmBlkPtr)&pb, 0 )) != noErr || pb.ioResult != noErr ) {
DisposeRoutineDescriptor( (UniversalProcPtr)tsp->tcps_notifyupp );
DisposePtr( (Ptr)tsp->tcps_buffer );
DisposePtr( (Ptr)tsp );
return( nil );
}
tsp->tcps_data = 0;
tsp->tcps_terminated = tsp->tcps_connected = false;
tsp->tcps_sptr = pb.tcpStream;
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
return( tsp );
}
/*
* connect to remote host at IP address "addr", TCP port "port"
* return local port assigned, 0 if error
*/
#ifdef SUPPORT_OPENTRANSPORT
InetPort
tcpconnect( tcpstream * tsp, InetHost addr, InetPort port ) {
#else /* SUPPORT_OPENTRANSPORT */
ip_port
tcpconnect( tcpstream * tsp, ip_addr addr, ip_port port ) {
#endif /* SUPPORT_OPENTRANSPORT */
TCPiopb pb;
OSStatus err;
#ifdef SUPPORT_OPENTRANSPORT
struct InetAddress sndsin, rcvsin, retsin;
TCall sndcall, rcvcall;
TBind ret;
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
if ( tsp->tcps_ep == NULL ) {
return( 0 );
}
bzero( (char *)&sndsin, sizeof( struct InetAddress ));
bzero( (char *)&rcvsin, sizeof( struct InetAddress ));
bzero( (char *)&retsin, sizeof( struct InetAddress ));
bzero( (char *)&sndcall, sizeof( TCall ));
bzero( (char *)&rcvcall, sizeof( TCall));
bzero( (char *)&ret, sizeof( TBind ));
// Bind TCP to an address and port. We don't care which one, so we pass null for
// the requested address.
ret.addr.maxlen = sizeof( struct InetAddress );
ret.addr.buf = (unsigned char *)&retsin;
err = OTBind( tsp->tcps_ep, NULL, &ret );
if ( err != kOTNoError ) {
return( 0 );
}
OTInitInetAddress( &sndsin, port, addr );
sndcall.addr.len = sizeof( struct InetAddress );
sndcall.addr.buf = (UInt8 *)&sndsin;
rcvcall.addr.maxlen = sizeof( struct InetAddress );
rcvcall.addr.buf = (unsigned char *)&rcvsin;
err = OTConnect( tsp->tcps_ep, &sndcall, &rcvcall );
if ( err != kOTNoError ) {
return 0;
}
tsp->tcps_connected = true;
tsp->tcps_remoteport = rcvsin.fPort;
tsp->tcps_remoteaddr = rcvsin.fHost;
return( retsin.fPort );
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( 0 );
}
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPActiveOpen;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = tsp->tcps_sptr;
pb.csParam.open.remoteHost = addr;
pb.csParam.open.remotePort = port;
pb.csParam.open.ulpTimeoutValue = 15;
pb.csParam.open.validityFlags = timeoutValue;
if (( err = PBControl( (ParmBlkPtr)&pb, 0 )) != noErr || pb.ioResult != noErr ) {
return( 0 );
}
tsp->tcps_connected = true;
return( pb.csParam.open.localPort );
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
}
/*
* close and release a TCP stream
* returns 0 if no error, -1 if any error occurs
*/
short
tcpclose( tcpstream * tsp ) {
TCPiopb pb;
OSStatus rc;
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
if ( tsp->tcps_ep == NULL ) {
return( -1 );
}
#ifdef notdef
/*
* if connected execute a close
*/
if ( tcp->tcps_connected ) {
Call OTSndOrderlyDisconnect and wait for the other end to respond. This requires
waiting for and reading any data that comes in in the meantime. This code was ifdefed
out in the MacTCP so it is here too.
}
#endif /* notdef */
rc = OTSndDisconnect( tsp->tcps_ep, NULL );
OTCloseProvider( tsp->tcps_ep );
DisposePtr( (Ptr)tsp );
if ( rc != 0 ) {
rc = -1;
}
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( -1 );
}
#ifdef notdef
/*
* if connected execute a close
*/
if ( tcp->tcps_connected ) {
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPClose;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = sp;
pb.csParam.close.validityFlags = 0;
PBControl( (ParmBlkPtr)&pb, 0 );
}
#endif /* notdef */
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPRelease;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = tsp->tcps_sptr;
pb.csParam.close.validityFlags = 0;
rc = 0;
if ( PBControl( (ParmBlkPtr)&pb, 0 ) != noErr || pb.ioResult != noErr ) {
rc = -1;
}
DisposeRoutineDescriptor( (UniversalProcPtr)tsp->tcps_notifyupp );
DisposePtr( (Ptr)tsp->tcps_buffer );
DisposePtr( (Ptr)tsp );
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
return( rc );
}
/*
* wait for new data to arrive
*
* if "timeout" is NULL, wait until data arrives or connection goes away
* if "timeout" is a pointer to a zero'ed struct, poll
* else wait for "timeout->tv_sec + timeout->tv_usec" seconds
*/
short
tcpselect( tcpstream * tsp, struct timeval * timeout )
{
unsigned long ticks, endticks;
short rc;
if ( timeout != NULL ) {
endticks = 60 * timeout->tv_sec + ( 60 * timeout->tv_usec ) / 1000000 + TickCount();
}
ticks = 0;
while (( rc = tcpreadready( tsp )) == 0 && ( timeout == NULL || ticks < endticks )) {
Delay( 2L, &ticks );
SystemTask();
}
return ( rc );
}
short
tcpreadready( tcpstream *tsp )
{
#ifdef SUPPORT_OPENTRANSPORT
size_t dataAvail;
if (gHaveOT) {
if ( tsp->tcps_ep == NULL ) {
return( -1 );
}
OTCountDataBytes( tsp->tcps_ep, &dataAvail );
tsp->tcps_data = ( dataAvail != 0 );
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( -1 );
}
/* tsp->tcps_data is set in async. notify proc, so nothing for us to do here */
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
return ( tsp->tcps_terminated ? -1 : ( tsp->tcps_data < 1 ) ? 0 : 1 );
}
/*
* read up to "rbuflen" bytes into "rbuf" from a connected TCP stream
* wait up to "timeout" seconds for data (if timeout == 0, wait "forever")
*/
long
tcpread( tcpstream * tsp, UInt8 timeout, unsigned char * rbuf,
unsigned short rbuflen, DialogPtr dlp ) {
#pragma unused (dlp)
TCPiopb pb;
unsigned long time, end_time;
#ifdef SUPPORT_OPENTRANSPORT
OTFlags flags;
OTResult result;
size_t dataAvail;
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
if ( tsp->tcps_ep == NULL ) {
return( -1 );
}
// Try to read data. Since we're in non-blocking mode, this will fail with kOTNoDataErr
// if no data is available.
result = OTRcv( tsp->tcps_ep, rbuf, rbuflen, &flags );
if ( result == kOTNoDataErr ) {
// Nothing available, wait for some. The ugly spin loop below is the way the old
// MacTCP code worked. I should fix it, but I don't have time right now.
tsp->tcps_data = 0;
GetDateTime( &time );
end_time = time + timeout;
while (( timeout <= 0 || end_time > time ) && tsp->tcps_data < 1 && !tsp->tcps_terminated ) {
OTCountDataBytes( tsp->tcps_ep, &dataAvail );
if ( dataAvail > 0 ) {
tsp->tcps_data = 1;
}
GetDateTime( &time );
SystemTask();
}
if ( tsp->tcps_data < 1 ) {
return( tsp->tcps_terminated ? -3 : -1 );
}
// Should have data available now, try again.
result = OTRcv( tsp->tcps_ep, rbuf, rbuflen, &flags );
}
if ( result < 0 ) {
return( -1 );
}
OTCountDataBytes( tsp->tcps_ep, &dataAvail );
if ( dataAvail == 0 ) {
tsp->tcps_data = 0;
}
return( result );
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( -1 );
}
GetDateTime( &time );
end_time = time + timeout;
while(( timeout <= 0 || end_time > time ) && tsp->tcps_data < 1 &&
!tsp->tcps_terminated ) {
GetDateTime( &time );
SystemTask();
}
if ( tsp->tcps_data < 1 ) {
return( tsp->tcps_terminated ? -3 : -1 );
}
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPRcv;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = tsp->tcps_sptr;
pb.csParam.receive.commandTimeoutValue = timeout;
pb.csParam.receive.rcvBuff = (char *)rbuf;
pb.csParam.receive.rcvBuffLen = rbuflen;
if ( PBControl( (ParmBlkPtr)&pb, 0 ) != noErr || pb.ioResult != noErr ) {
return( -1 );
}
if ( --(tsp->tcps_data) < 0 ) {
tsp->tcps_data = 0;
}
return( pb.csParam.receive.rcvBuffLen );
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
}
/*
* send TCP data
* "sp" is the stream to write to
* "wbuf" is "wbuflen" bytes of data to send
* returns < 0 if error, number of bytes written if no error
*/
long
tcpwrite( tcpstream * tsp, unsigned char * wbuf, unsigned short wbuflen ) {
TCPiopb pb;
wdsEntry wds[ 2 ];
OSErr err;
#ifdef SUPPORT_OPENTRANSPORT
OTResult result;
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
if ( tsp->tcps_ep == NULL ) {
return( -1 );
}
OTSetBlocking( tsp->tcps_ep );
result = OTSnd( tsp->tcps_ep, wbuf, wbuflen, 0 );
OTSetNonBlocking( tsp->tcps_ep );
return( result );
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( -1 );
}
wds[ 0 ].length = wbuflen;
wds[ 0 ].ptr = (char *)wbuf;
wds[ 1 ].length = 0;
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPSend;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = tsp->tcps_sptr;
pb.csParam.send.wdsPtr = (Ptr)wds;
pb.csParam.send.validityFlags = 0;
if (( err = PBControl( (ParmBlkPtr)&pb, 0 )) != noErr || pb.ioResult != noErr ) {
return( -1 );
}
return( (long) wbuflen );
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
}
static pascal void
tcp_asynchnotify(
StreamPtr tstream,
unsigned short event,
Ptr userdatap,
unsigned short term_reason,
struct ICMPReport *icmpmsg
)
{
#pragma unused (tstream, term_reason, icmpmsg)
tcpstream *tsp;
tsp = (tcpstream *)userdatap;
switch( event ) {
case TCPDataArrival:
++(tsp->tcps_data);
break;
case TCPClosing:
case TCPTerminate:
case TCPULPTimeout:
tsp->tcps_terminated = true;
break;
default:
break;
}
}
short
tcpgetpeername( tcpstream *tsp, ip_addr *addrp, tcp_port *portp ) {
TCPiopb pb;
OSErr err;
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
if ( tsp->tcps_ep == NULL ) {
return( -1 );
}
if ( addrp != NULL ) {
*addrp = tsp->tcps_remoteaddr;
}
if ( portp != NULL ) {
*portp = tsp->tcps_remoteport;
}
} else {
#endif /* SUPPORT_OPENTRANSPORT */
if ( tsp->tcps_sptr == (StreamPtr)NULL ) {
return( -1 );
}
bzero( (char *)&pb, sizeof( pb ));
pb.csCode = TCPStatus;
pb.ioCRefNum = tsp->drefnum;
pb.tcpStream = tsp->tcps_sptr;
if (( err = PBControl( (ParmBlkPtr)&pb, 0 )) != noErr || pb.ioResult != noErr ) {
return( err );
}
if ( addrp != NULL ) {
*addrp = pb.csParam.status.remoteHost;
}
if ( portp != NULL ) {
*portp = pb.csParam.status.remotePort;
}
#ifdef SUPPORT_OPENTRANSPORT
}
return( kOTNoError );
#else /* SUPPORT_OPENTRANSPORT */
return( noErr );
#endif /* SUPPORT_OPENTRANSPORT */
}
/*
* bzero -- set "len" bytes starting at "p" to zero
*/
static void
bzero( char *p, unsigned long len )
{
unsigned long i;
for ( i = 0; i < len; ++i ) {
*p++ = '\0';
}
}
pascal void
setdoneflag( struct hostInfo *hip, char *donep )
{
++(*donep);
#pragma unused (hip)
}
/*
* return a hostInfo structure for "host" (return != noErr if error)
*/
short
#ifdef SUPPORT_OPENTRANSPORT
gethostinfobyname( char *host, InetHostInfo *hip ) {
#else /* SUPPORT_OPENTRANSPORT */
gethostinfobyname( char *host, struct hostInfo *hip ) {
#endif /* SUPPORT_OPENTRANSPORT */
char done = 0;
OSStatus err;
unsigned long time;
ResultUPP rupp;
#ifdef notdef
struct dnr_struct dnr_global = {nil, 0};
#endif /* notdef */
#ifdef SUPPORT_OPENTRANSPORT
hostInfo hi; /* Old MacTCP version of hostinfo */
InetSvcRef inetsvc; /* Internet services reference */
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
// Get an Internet Services reference
inetsvc = OTOpenInternetServices( kDefaultInternetServicesPath, 0, &err );
if ( !inetsvc || err != kOTNoError ) {
if ( err == kOTNoError ) {
err = -1;
}
inetsvc = nil;
}
if ( !err ) {
err = OTInetStringToAddress( inetsvc, host, hip );
}
if ( inetsvc ) {
OTCloseProvider(inetsvc);
}
} else {
#endif /* SUPPORT_OPENTRANSPORT */
kick_mactcp( NULL );
if (( err = OpenResolver( /* &dnr_global, */ NULL )) != noErr )
return( err );
if (( rupp = NewResultProc( setdoneflag )) == NULL ) {
err = memFullErr;
} else {
#ifdef SUPPORT_OPENTRANSPORT
bzero( (char *)&hi, sizeof( hostInfo ));
if (( err = StrToAddr( /* &dnr_global, */ host, &hi, rupp, &done )) == cacheFault ) {
#else /* SUPPORT_OPENTRANSPORT */
bzero((char *) hip, sizeof( hostInfo ));
if (( err = StrToAddr( /* &dnr_global, */ host, hip, rupp, &done )) == cacheFault ) {
#endif /* SUPPORT_OPENTRANSPORT */
while( !done ) {
Delay( 2L, &time ); // querying DN servers; wait for reply
SystemTask();
}
#ifdef SUPPORT_OPENTRANSPORT
err = hi.rtnCode;
#else /* SUPPORT_OPENTRANSPORT */
err = hip->rtnCode;
#endif /* SUPPORT_OPENTRANSPORT */
}
DisposeRoutineDescriptor( (UniversalProcPtr)rupp );
}
#if !defined(MOZILLA_CLIENT)
CloseResolver( /* &dnr_global */ );
#endif
#ifdef SUPPORT_OPENTRANSPORT
/* Copy the results to the InetHostInfo area passed in by caller */
BlockMove(hi.cname, hip->name, kMaxHostNameLen);
BlockMove(hi.addr, hip->addrs, 4*NUM_ALT_ADDRS);
hip->addrs[NUM_ALT_ADDRS] = 0;
/* Convert the return code to an OT style return code */
if ( err == nameSyntaxErr ) {
err = kOTBadNameErr;
} else if ( err == noNameServer || err == authNameErr || err == noAnsErr ) {
err = kOTBadNameErr;
} else if (err != noErr) {
err = kOTSysErrorErr;
}
}
if (( err == kOTNoError ) && ( hip->addrs[ 0 ] == 0 )) {
err = kOTBadNameErr;
}
return( err );
#else /* SUPPORT_OPENTRANSPORT */
if ( err != noErr || (( err == noErr ) && ( hip->addr[ 0 ] == 0 ))) {
return( err == noErr ? noAnsErr : err );
}
return( noErr );
#endif /* SUPPORT_OPENTRANSPORT */
}
/*
* return a hostInfo structure for "addr" (return != noErr if error)
*/
short
#ifdef SUPPORT_OPENTRANSPORT
gethostinfobyaddr( InetHost addr, InetHostInfo *hip )
#else /* SUPPORT_OPENTRANSPORT */
gethostinfobyaddr( ip_addr addr, struct hostInfo *hip )
#endif /* SUPPORT_OPENTRANSPORT */
{
char done = 0;
OSStatus err;
unsigned long time;
ResultUPP rupp;
#ifdef notdef
struct dnr_struct dnr_global = {nil, 0};
#endif /* notdef */
#ifdef SUPPORT_OPENTRANSPORT
hostInfo hi; /* Old MacTCP version of hostinfo */
InetSvcRef inetsvc; /* Internet services reference */
#endif /* SUPPORT_OPENTRANSPORT */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
// Get an Internet Services reference
inetsvc = OTOpenInternetServices( kDefaultInternetServicesPath, 0, &err );
if ( !inetsvc || err != kOTNoError ) {
if ( err == kOTNoError ) {
err = -1;
}
inetsvc = nil;
}
if ( !err ) {
err = OTInetAddressToName( inetsvc, addr, hip->name );
}
if ( inetsvc ) {
OTCloseProvider( inetsvc );
}
} else {
#endif /* SUPPORT_OPENTRANSPORT */
kick_mactcp( NULL );
if (( err = OpenResolver( /* &dnr_global, */ NULL )) != noErr )
return( err );
if (( rupp = NewResultProc( setdoneflag )) == NULL ) {
err = memFullErr;
} else {
#ifdef SUPPORT_OPENTRANSPORT
bzero( (char *) &hi, sizeof( hostInfo ));
if (( err = AddrToName( /* &dnr_global, */ addr, &hi, rupp, &done )) == cacheFault ) {
#else /* SUPPORT_OPENTRANSPORT */
bzero( (char *)hip, sizeof( hostInfo ));
if (( err = AddrToName( /* &dnr_global, */ addr, hip, rupp, &done )) == cacheFault ) {
#endif /* SUPPORT_OPENTRANSPORT */
while( !done ) {
Delay( 2L, &time ); // querying DN servers; wait for reply
SystemTask();
}
#ifdef SUPPORT_OPENTRANSPORT
err = hi.rtnCode;
#else /* SUPPORT_OPENTRANSPORT */
err = hip->rtnCode;
#endif /* SUPPORT_OPENTRANSPORT */
}
DisposeRoutineDescriptor( (UniversalProcPtr)rupp );
}
#if !defined(MOZILLA_CLIENT)
CloseResolver( /* &dnr_global */ );
#endif
#ifdef SUPPORT_OPENTRANSPORT
/* Copy the results to the InetHostInfo area passed in by caller */
BlockMove(hi.cname, hip->name, kMaxHostNameLen);
BlockMove(hi.addr, hip->addrs, 4*NUM_ALT_ADDRS);
hip->addrs[NUM_ALT_ADDRS] = 0;
/* Convert the return code to an OT style return code */
if (err == nameSyntaxErr) {
err = kOTBadNameErr;
} else if (err == noNameServer || err == authNameErr || err == noAnsErr) {
err = kOTBadNameErr;
} else if (err != noErr) {
err = kOTSysErrorErr;
}
}
#endif /* SUPPORT_OPENTRANSPORT */
return( err );
}
/*
* return a ASCII equivalent of ipaddr. addrstr must be at large enough to hold the
* result which is of the form "AAA.BBB.CCC.DDD" and can be a maximum of 16 bytes in size
*/
short
#ifdef SUPPORT_OPENTRANSPORT
ipaddr2str( InetHost ipaddr, char *addrstr )
#else /* SUPPORT_OPENTRANSPORT */
ipaddr2str( ip_addr ipaddr, char *addrstr )
#endif /* SUPPORT_OPENTRANSPORT */
{
OSStatus err;
#ifdef notdef
struct dnr_struct dnr_global = {nil, 0};
#endif /* notdef */
#ifdef SUPPORT_OPENTRANSPORT
if ( gHaveOT ) {
OTInetHostToString( ipaddr, addrstr );
err = kOTNoError;
} else {
#endif /* SUPPORT_OPENTRANSPORT */
kick_mactcp( NULL );
if (( err = OpenResolver( /* &dnr_global, */ NULL )) != noErr )
return( err );
err = AddrToStr( ipaddr, addrstr );
#if !defined(MOZILLA_CLIENT)
CloseResolver( /* &dnr_global */ );
#endif
#ifdef SUPPORT_OPENTRANSPORT
}
#endif /* SUPPORT_OPENTRANSPORT */
return( err );
}
#ifdef SUPPORT_OPENTRANSPORT
/*******************************************************************************
** EventHandler
********************************************************************************/
pascal void EventHandler(tcpstream *tsp, OTEventCode event, OTResult result, void * /* cookie */)
{
switch(event)
{
case T_ORDREL:
case T_DISCONNECT:
tsp->tcps_terminated = true;
break;
case T_DATA:
case T_EXDATA:
tsp->tcps_data += 1;
break;
default:
break;
}
return;
}
#endif /* SUPPORT_OPENTRANSPORT */
static OSErr
kick_mactcp( short *drefnump )
{
short dref;
OSErr err;
struct GetAddrParamBlock gapb;
/*
* we make sure the MacTCP driver is open and issue a "Get My Address" call
* so that adevs link MacPPP are initialized (MacTCP is dumb)
*/
if (( err = OpenDriver( "\p.IPP", &dref )) != noErr ) {
return( err );
}
if ( drefnump != NULL ) {
*drefnump = dref;
}
bzero( (char *)&gapb, sizeof( gapb ));
gapb.csCode = ipctlGetAddr;
gapb.ioCRefNum = dref;
err = PBControl( (ParmBlkPtr)&gapb, 0 );
return( noErr );
}

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* tcp.h interface to MCS's TCP routines
*/
#include <Dialogs.h>
#ifdef SUPPORT_OPENTRANSPORT
#include <OpenTransport.h>
#include <OpenTptInternet.h>
#endif /* SUPPORT_OPENTRANSPORT */
//#include "MacTCPCommonTypes.h"
#include "AddressXlation.h"
#include "TCPPB.h"
#include "GetMyIPAddr.h"
#include <utime.h> /* for the UNIX-y struct timeval */
#include <MacTCP.h>
#ifndef TCP_BUFSIZ
#define TCP_BUFSIZ 8192
#endif /* TCP_BUFSIZ */
typedef struct tcpstream {
StreamPtr tcps_sptr; /* stream pointer for MacTCP TCP PB calls */
#ifdef SUPPORT_OPENTRANSPORT
EndpointRef tcps_ep; /* OpenTransport end point */
#endif /* SUPPORT_OPENTRANSPORT */
short tcps_data; /* count of packets on read queue */
short drefnum; /* driver ref num, for convenience */
Boolean tcps_connected; /* true if connection was made */
Boolean tcps_terminated; /* true if connection no longer exists */
#ifdef SUPPORT_OPENTRANSPORT
InetHost tcps_remoteaddr; /* Address of our peer */
InetPort tcps_remoteport; /* Port number of our peer */
#endif /* SUPPORT_OPENTRANSPORT */
unsigned char *tcps_buffer; /* buffer given over to system to use */
struct tcpstream *tcps_next; /* next one in chain */
TCPNotifyUPP tcps_notifyupp; /* universal proc pointer for notify routine */
} tcpstream, *tcpstreamptr;
#define TCP_IS_TERMINATED( tsp ) (tsp)->tcps_terminated
/*
* function prototypes
*/
#ifdef SUPPORT_OPENTRANSPORT
OSStatus tcp_init(void);
Boolean tcp_have_opentransport( void );
#endif /* SUPPORT_OPENTRANSPORT */
tcpstream *tcpopen( unsigned char * buf, long buflen );
tcp_port tcpconnect( tcpstream *s, ip_addr addr, tcp_port port );
short tcpclose( tcpstream *s );
long tcpread( tcpstream *s, UInt8 timeout, unsigned char * rbuf,
unsigned short rbuflen, DialogPtr dlp );
long tcpwrite( tcpstream *s, unsigned char * wbuf, unsigned short wbuflen );
short tcpselect( tcpstream *s, struct timeval * timeout );
short tcpreadready( tcpstream *tsp );
short tcpgetpeername( tcpstream * tsp, ip_addr *addrp, tcp_port *portp );
#ifdef SUPPORT_OPENTRANSPORT
short gethostinfobyname( char *host, InetHostInfo *hip );
short gethostinfobyaddr(InetHost addr, InetHostInfo *hip );
short ipaddr2str( InetHost ipaddr, char *addrstr );
#else /* SUPPORT_OPENTRANSPORT */
short gethostinfobyname( char *host, struct hostInfo *hip );
short gethostinfobyaddr( ip_addr addr, struct hostInfo *hip );
short ipaddr2str( ip_addr ipaddr, char *addrstr );
#endif /* SUPPORT_OPENTRANSPORT */