mirror of
https://github.com/python/cpython.git
synced 2024-11-24 00:38:00 +01:00
Interface to MacTCP and the MacTCP Domain Name Resolver
This commit is contained in:
parent
114ca5c170
commit
edf585579c
301
Mac/Unsupported/mactcp/dnrglue.c
Normal file
301
Mac/Unsupported/mactcp/dnrglue.c
Normal file
@ -0,0 +1,301 @@
|
||||
/* DNR.c - DNR library for MPW
|
||||
|
||||
(c) Copyright 1988 by Apple Computer. All rights reserved
|
||||
|
||||
Modifications by Jim Matthews, Dartmouth College, 5/91
|
||||
Again modified for use with python by Jack Jansen, CWI, October 1994.
|
||||
|
||||
*/
|
||||
|
||||
#include <Traps.h>
|
||||
#include <OSUtils.h>
|
||||
#include <Errors.h>
|
||||
#include <Files.h>
|
||||
#include <Resources.h>
|
||||
#include <Memory.h>
|
||||
#include <Traps.h>
|
||||
#include <GestaltEqu.h>
|
||||
#include <Folders.h>
|
||||
#include <ToolUtils.h>
|
||||
#include <MacTCPCommonTypes.h>
|
||||
#include "AddressXlation.h"
|
||||
|
||||
TrapType GetTrapType(unsigned long theTrap);
|
||||
Boolean TrapAvailable(unsigned long trap);
|
||||
void GetSystemFolder(short *vRefNumP, long *dirIDP);
|
||||
void GetCPanelFolder(short *vRefNumP, long *dirIDP);
|
||||
short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID);
|
||||
short OpenOurRF(void);
|
||||
|
||||
#define OPENRESOLVER 1L
|
||||
#define CLOSERESOLVER 2L
|
||||
#define STRTOADDR 3L
|
||||
#define ADDRTOSTR 4L
|
||||
#define ENUMCACHE 5L
|
||||
#define ADDRTONAME 6L
|
||||
#define HINFO 7L
|
||||
#define MXINFO 8L
|
||||
|
||||
Handle codeHndl = nil;
|
||||
|
||||
OSErrProcPtr dnr = nil;
|
||||
|
||||
TrapType GetTrapType(theTrap)
|
||||
unsigned long theTrap;
|
||||
{
|
||||
if (BitAnd(theTrap, 0x0800) > 0)
|
||||
return(ToolTrap);
|
||||
else
|
||||
return(OSTrap);
|
||||
}
|
||||
|
||||
Boolean TrapAvailable(trap)
|
||||
unsigned long trap;
|
||||
{
|
||||
TrapType trapType = ToolTrap;
|
||||
unsigned long numToolBoxTraps;
|
||||
|
||||
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
|
||||
numToolBoxTraps = 0x200;
|
||||
else
|
||||
numToolBoxTraps = 0x400;
|
||||
|
||||
trapType = GetTrapType(trap);
|
||||
if (trapType == ToolTrap) {
|
||||
trap = BitAnd(trap, 0x07FF);
|
||||
if (trap >= numToolBoxTraps)
|
||||
trap = _Unimplemented;
|
||||
}
|
||||
return(NGetTrapAddress(trap, trapType) != NGetTrapAddress(_Unimplemented, ToolTrap));
|
||||
|
||||
}
|
||||
|
||||
void GetSystemFolder(short *vRefNumP, long *dirIDP)
|
||||
{
|
||||
SysEnvRec info;
|
||||
long wdProcID;
|
||||
|
||||
SysEnvirons(1, &info);
|
||||
if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) {
|
||||
*vRefNumP = 0;
|
||||
*dirIDP = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GetCPanelFolder(short *vRefNumP, long *dirIDP)
|
||||
{
|
||||
Boolean hasFolderMgr = false;
|
||||
long feature;
|
||||
|
||||
if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
|
||||
if (!hasFolderMgr) {
|
||||
GetSystemFolder(vRefNumP, dirIDP);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) {
|
||||
*vRefNumP = 0;
|
||||
*dirIDP = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SearchFolderForDNRP is called to search a folder for files that might
|
||||
contain the 'dnrp' resource */
|
||||
short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID)
|
||||
{
|
||||
HParamBlockRec fi;
|
||||
Str255 filename;
|
||||
short refnum;
|
||||
|
||||
fi.fileParam.ioCompletion = nil;
|
||||
fi.fileParam.ioNamePtr = filename;
|
||||
fi.fileParam.ioVRefNum = vRefNum;
|
||||
fi.fileParam.ioDirID = dirID;
|
||||
fi.fileParam.ioFDirIndex = 1;
|
||||
|
||||
while (PBHGetFInfo(&fi, false) == noErr) {
|
||||
/* scan system folder for driver resource files of specific type & creator */
|
||||
if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
|
||||
fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) {
|
||||
/* found the MacTCP driver file? */
|
||||
refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
|
||||
if (GetIndResource('dnrp', 1) == NULL)
|
||||
CloseResFile(refnum);
|
||||
else
|
||||
return refnum;
|
||||
}
|
||||
/* check next file in system folder */
|
||||
fi.fileParam.ioFDirIndex++;
|
||||
fi.fileParam.ioDirID = dirID; /* PBHGetFInfo() clobbers ioDirID */
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* OpenOurRF is called to open the MacTCP driver resources */
|
||||
|
||||
short OpenOurRF()
|
||||
{
|
||||
short refnum;
|
||||
short vRefNum;
|
||||
long dirID;
|
||||
|
||||
/* first search Control Panels for MacTCP 1.1 */
|
||||
GetCPanelFolder(&vRefNum, &dirID);
|
||||
refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
|
||||
if (refnum != -1) return(refnum);
|
||||
|
||||
/* next search System Folder for MacTCP 1.0.x */
|
||||
GetSystemFolder(&vRefNum, &dirID);
|
||||
refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
|
||||
if (refnum != -1) return(refnum);
|
||||
|
||||
/* finally, search Control Panels for MacTCP 1.0.x */
|
||||
GetCPanelFolder(&vRefNum, &dirID);
|
||||
refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
|
||||
if (refnum != -1) return(refnum);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
OSErr OpenResolver(fileName)
|
||||
char *fileName;
|
||||
{
|
||||
short refnum;
|
||||
OSErr rc;
|
||||
|
||||
if (dnr != nil)
|
||||
/* resolver already loaded in */
|
||||
return(noErr);
|
||||
|
||||
/* open the MacTCP driver to get DNR resources. Search for it based on
|
||||
creator & type rather than simply file name */
|
||||
refnum = OpenOurRF();
|
||||
|
||||
/* ignore failures since the resource may have been installed in the
|
||||
System file if running on a Mac 512Ke */
|
||||
|
||||
/* load in the DNR resource package */
|
||||
codeHndl = GetIndResource('dnrp', 1);
|
||||
if (codeHndl == nil) {
|
||||
/* can't open DNR */
|
||||
return(ResError());
|
||||
}
|
||||
|
||||
DetachResource(codeHndl);
|
||||
if (refnum != -1) {
|
||||
CloseWD(refnum);
|
||||
CloseResFile(refnum);
|
||||
}
|
||||
|
||||
/* lock the DNR resource since it cannot be reloated while opened */
|
||||
HLock(codeHndl);
|
||||
dnr = (OSErrProcPtr) *codeHndl;
|
||||
|
||||
/* call open resolver */
|
||||
rc = (*dnr)(OPENRESOLVER, fileName);
|
||||
if (rc != noErr) {
|
||||
/* problem with open resolver, flush it */
|
||||
HUnlock(codeHndl);
|
||||
DisposHandle(codeHndl);
|
||||
dnr = nil;
|
||||
}
|
||||
return(rc);
|
||||
}
|
||||
|
||||
|
||||
OSErr CloseResolver()
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
/* call close resolver */
|
||||
(void) (*dnr)(CLOSERESOLVER);
|
||||
|
||||
/* release the DNR resource package */
|
||||
HUnlock(codeHndl);
|
||||
DisposHandle(codeHndl);
|
||||
dnr = nil;
|
||||
return(noErr);
|
||||
}
|
||||
|
||||
OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr)
|
||||
char *hostName;
|
||||
struct hostInfo *rtnStruct;
|
||||
ResultProcPtr resultproc;
|
||||
char *userDataPtr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
return((*dnr)(STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
|
||||
}
|
||||
|
||||
OSErr AddrToStr(addr, addrStr)
|
||||
unsigned long addr;
|
||||
char *addrStr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
(*dnr)(ADDRTOSTR, addr, addrStr);
|
||||
return(noErr);
|
||||
}
|
||||
|
||||
OSErr EnumCache(resultproc, userDataPtr)
|
||||
EnumResultProcPtr resultproc;
|
||||
char *userDataPtr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
return((*dnr)(ENUMCACHE, resultproc, userDataPtr));
|
||||
}
|
||||
|
||||
|
||||
OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr)
|
||||
unsigned long addr;
|
||||
struct hostInfo *rtnStruct;
|
||||
ResultProcPtr resultproc;
|
||||
char *userDataPtr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
return((*dnr)(ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
|
||||
}
|
||||
|
||||
|
||||
extern OSErr HInfo(hostName, returnRecPtr, resultProc, userDataPtr)
|
||||
char *hostName;
|
||||
struct returnRec *returnRecPtr;
|
||||
ResultProc2Ptr resultProc;
|
||||
char *userDataPtr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
return((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
|
||||
|
||||
}
|
||||
|
||||
extern OSErr MXInfo(hostName, returnRecPtr, resultProc, userDataPtr)
|
||||
char *hostName;
|
||||
struct returnRec *returnRecPtr;
|
||||
ResultProc2Ptr resultProc;
|
||||
char *userDataPtr;
|
||||
{
|
||||
if (dnr == nil)
|
||||
/* resolver not loaded error */
|
||||
return(notOpenErr);
|
||||
|
||||
return((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
|
||||
|
||||
}
|
456
Mac/Unsupported/mactcp/macdnrmodule.c
Normal file
456
Mac/Unsupported/mactcp/macdnrmodule.c
Normal file
@ -0,0 +1,456 @@
|
||||
/***********************************************************
|
||||
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
|
||||
Amsterdam, The Netherlands.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "allobjects.h"
|
||||
#include "modsupport.h" /* For getargs() etc. */
|
||||
|
||||
#include <AddressXlation.h>
|
||||
#include <Desk.h>
|
||||
|
||||
#ifndef __MWERKS__
|
||||
#define ResultUPP ResultProcPtr
|
||||
#define NewResultProc(x) (x)
|
||||
#endif
|
||||
|
||||
static object *ErrorObject;
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Declarations for objects of type MacTCP DNR Result */
|
||||
|
||||
/* Types of records we have */
|
||||
#define DNR_ADDR 0
|
||||
#define DNR_HINFO 1
|
||||
#define DNR_MX 2
|
||||
|
||||
typedef struct {
|
||||
OB_HEAD
|
||||
int type; /* DNR_XXX */
|
||||
int waiting; /* True while completion proc not called */
|
||||
struct returnRec hinfo;
|
||||
} dnrrobject;
|
||||
|
||||
staticforward typeobject Dnrrtype;
|
||||
|
||||
#define is_dnrrobject(v) ((v)->ob_type == &Dnrrtype)
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
static pascal void
|
||||
dnrr_done(rrp, udp)
|
||||
struct hostInfo *rrp; /* Unused */
|
||||
dnrrobject *udp;
|
||||
{
|
||||
if ( !udp->waiting ) {
|
||||
printf("macdnr: dnrr_done: spurious completion call!\n");
|
||||
return;
|
||||
}
|
||||
udp->waiting = 0;
|
||||
DECREF(udp);
|
||||
}
|
||||
|
||||
static int dnrwait(self)
|
||||
dnrrobject *self;
|
||||
{
|
||||
while ( self->waiting ) {
|
||||
if ( !PyMac_Idle() )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnrr_wait(self, args)
|
||||
dnrrobject *self;
|
||||
object *args;
|
||||
{
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
if ( !dnrwait(self) ) {
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
if ( self->hinfo.rtnCode ) {
|
||||
PyErr_Mac(ErrorObject, self->hinfo.rtnCode);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnrr_isdone(self, args)
|
||||
dnrrobject *self;
|
||||
object *args;
|
||||
{
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
return newintobject(!self->waiting);
|
||||
}
|
||||
|
||||
static struct methodlist dnrr_methods[] = {
|
||||
{"wait", (method)dnrr_wait, 1},
|
||||
{"isdone", (method)dnrr_isdone, 1},
|
||||
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
/* ---------- */
|
||||
|
||||
static dnrrobject *
|
||||
newdnrrobject(tp)
|
||||
int tp;
|
||||
{
|
||||
dnrrobject *self;
|
||||
|
||||
self = NEWOBJ(dnrrobject, &Dnrrtype);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->type = tp;
|
||||
self->waiting = 0;
|
||||
memset(&self->hinfo, 0, sizeof(self->hinfo));
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
dnrr_dealloc(self)
|
||||
dnrrobject *self;
|
||||
{
|
||||
self->waiting = 0; /* Not really needed, since we incref for completion */
|
||||
DEL(self);
|
||||
}
|
||||
|
||||
/* Code to access structure members by accessing attributes */
|
||||
|
||||
#include "structmember.h"
|
||||
|
||||
#define OFF(x) offsetof(struct returnRec, x)
|
||||
|
||||
static struct memberlist dnrr_memberlist_addr[] = {
|
||||
{ "rtnCode", T_INT, OFF(rtnCode), RO},
|
||||
{ "cname", T_STRING_INPLACE, OFF(cname), RO},
|
||||
{ "ip0", T_UINT, OFF(rdata.addr[0]), RO},
|
||||
{ "ip1", T_UINT, OFF(rdata.addr[1]), RO},
|
||||
{ "ip2", T_UINT, OFF(rdata.addr[2]), RO},
|
||||
{ "ip3", T_UINT, OFF(rdata.addr[3]), RO},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct memberlist dnrr_memberlist_hinfo[] = {
|
||||
{ "rtnCode", T_INT, OFF(rtnCode), RO},
|
||||
{ "cname", T_STRING_INPLACE, OFF(cname), RO},
|
||||
{ "cpuType", T_STRING_INPLACE, OFF(rdata.hinfo.cpuType), RO},
|
||||
{ "osType", T_STRING_INPLACE, OFF(rdata.hinfo.osType), RO},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct memberlist dnrr_memberlist_mx[] = {
|
||||
{ "rtnCode", T_INT, OFF(rtnCode), RO},
|
||||
{ "cname", T_STRING_INPLACE, OFF(cname), RO},
|
||||
{ "preference", T_USHORT, OFF(rdata.mx.preference), RO},
|
||||
{ "exchange", T_STRING_INPLACE, OFF(rdata.mx.exchange), RO},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static struct memberlist *dnrr_mlists[3] = {
|
||||
dnrr_memberlist_addr,
|
||||
dnrr_memberlist_hinfo,
|
||||
dnrr_memberlist_mx
|
||||
};
|
||||
|
||||
static object *
|
||||
dnrr_getattr(self, name)
|
||||
dnrrobject *self;
|
||||
char *name;
|
||||
{
|
||||
object *rv;
|
||||
int tp;
|
||||
|
||||
rv = findmethod(dnrr_methods, (object *)self, name);
|
||||
if ( rv ) return rv;
|
||||
err_clear();
|
||||
if ( self->waiting )
|
||||
if ( !dnrwait(self) )
|
||||
return NULL;
|
||||
tp = self->type;
|
||||
return getmember((char *)&self->hinfo, dnrr_mlists[tp], name);
|
||||
}
|
||||
|
||||
|
||||
static typeobject Dnrrtype = {
|
||||
OB_HEAD_INIT(&Typetype)
|
||||
0, /*ob_size*/
|
||||
"MacTCP DNR Result", /*tp_name*/
|
||||
sizeof(dnrrobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)dnrr_dealloc, /*tp_dealloc*/
|
||||
(printfunc)0, /*tp_print*/
|
||||
(getattrfunc)dnrr_getattr, /*tp_getattr*/
|
||||
(setattrfunc)0, /*tp_setattr*/
|
||||
(cmpfunc)0, /*tp_compare*/
|
||||
(reprfunc)0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
(hashfunc)0, /*tp_hash*/
|
||||
};
|
||||
|
||||
/* End of code for MacTCP DNR Result objects */
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
int dnr_is_open;
|
||||
|
||||
static int
|
||||
opendnr(fn)
|
||||
char *fn;
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if ( dnr_is_open ) return 1;
|
||||
if ( (err=OpenResolver(fn)) ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return 0;
|
||||
}
|
||||
dnr_is_open = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_Open(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
char *fn = NULL;
|
||||
|
||||
if (!newgetargs(args, "|s", &fn))
|
||||
return NULL;
|
||||
if ( dnr_is_open ) {
|
||||
err_setstr(ErrorObject, "DNR already open");
|
||||
return NULL;
|
||||
}
|
||||
if ( !opendnr(fn) )
|
||||
return NULL;
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_Close(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
dnr_is_open = 0;
|
||||
if ( (err=CloseResolver()) ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_StrToAddr(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
char *hostname;
|
||||
dnrrobject *rv;
|
||||
ResultUPP cb_upp = NewResultProc(dnrr_done);
|
||||
|
||||
if (!newgetargs(args, "s", &hostname))
|
||||
return NULL;
|
||||
if ( !opendnr(NULL) )
|
||||
return NULL;
|
||||
if ( (rv=newdnrrobject(DNR_ADDR)) == NULL )
|
||||
return NULL;
|
||||
err = StrToAddr(hostname, (struct hostInfo *)&rv->hinfo, cb_upp, (char *)rv);
|
||||
if ( err == cacheFault ) {
|
||||
rv->waiting++;
|
||||
INCREF(rv);
|
||||
} else {
|
||||
DECREF(rv);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return (object *)rv;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_AddrToName(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
unsigned long ipaddr;
|
||||
dnrrobject *rv;
|
||||
ResultUPP cb_upp = NewResultProc(dnrr_done);
|
||||
|
||||
if (!newgetargs(args, "l", &ipaddr))
|
||||
return NULL;
|
||||
if ( !opendnr(NULL) )
|
||||
return NULL;
|
||||
if ( (rv=newdnrrobject(DNR_ADDR)) == NULL )
|
||||
return NULL;
|
||||
err = AddrToName(ipaddr, (struct hostInfo *)&rv->hinfo, cb_upp, (char *)rv);
|
||||
if ( err == cacheFault ) {
|
||||
rv->waiting++;
|
||||
INCREF(rv);
|
||||
} else {
|
||||
DECREF(rv);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return (object *)rv;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_AddrToStr(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
unsigned long ipaddr;
|
||||
char ipname[16];
|
||||
object *rv;
|
||||
|
||||
if (!newgetargs(args, "l", &ipaddr))
|
||||
return NULL;
|
||||
if ( !opendnr(NULL) )
|
||||
return NULL;
|
||||
if ( (err=AddrToStr(ipaddr, ipname)) ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return newstringobject(ipname);
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_HInfo(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
char *hostname;
|
||||
dnrrobject *rv;
|
||||
|
||||
if (!newgetargs(args, "s", &hostname))
|
||||
return NULL;
|
||||
if ( !opendnr(NULL) )
|
||||
return NULL;
|
||||
if ( (rv=newdnrrobject(DNR_HINFO)) == NULL )
|
||||
return NULL;
|
||||
err = HInfo(hostname, &rv->hinfo, (ResultProc2Ptr)dnrr_done, (char *)rv);
|
||||
if ( err == cacheFault ) {
|
||||
rv->waiting++;
|
||||
INCREF(rv);
|
||||
} else {
|
||||
DECREF(rv);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return (object *)rv;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
dnr_MXInfo(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
char *hostname;
|
||||
dnrrobject *rv;
|
||||
|
||||
if (!newgetargs(args, "s", &hostname))
|
||||
return NULL;
|
||||
if ( !opendnr(NULL) )
|
||||
return NULL;
|
||||
if ( (rv=newdnrrobject(DNR_MX)) == NULL )
|
||||
return NULL;
|
||||
err = MXInfo(hostname, &rv->hinfo, (ResultProc2Ptr)dnrr_done, (char *)rv);
|
||||
if ( err == cacheFault ) {
|
||||
rv->waiting++;
|
||||
INCREF(rv);
|
||||
} else {
|
||||
DECREF(rv);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return (object *)rv;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
/* List of methods defined in the module */
|
||||
|
||||
static struct methodlist dnr_methods[] = {
|
||||
{"Open", dnr_Open, 1},
|
||||
{"Close", dnr_Close, 1},
|
||||
{"StrToAddr", dnr_StrToAddr, 1},
|
||||
{"AddrToStr", dnr_AddrToStr, 1},
|
||||
{"AddrToName", dnr_AddrToName, 1},
|
||||
{"HInfo", dnr_HInfo, 1},
|
||||
{"MXInfo", dnr_MXInfo, 1},
|
||||
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialization function for the module (*must* be called initmacdnr) */
|
||||
|
||||
void
|
||||
initmacdnr()
|
||||
{
|
||||
object *m, *d, *o;
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = initmodule("macdnr", dnr_methods);
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
d = getmoduledict(m);
|
||||
ErrorObject = newstringobject("macdnr.error");
|
||||
dictinsert(d, "error", ErrorObject);
|
||||
#if 0
|
||||
/* Not needed, after all */
|
||||
#define CONST(name, value) o = newintobject(value); dictinsert(d, name, o);
|
||||
CONST("ADDR", DNR_ADDR);
|
||||
CONST("HINFO", DNR_HINFO);
|
||||
CONST("MX", DNR_MX);
|
||||
#endif
|
||||
/* Check for errors */
|
||||
if (err_occurred())
|
||||
fatal("can't initialize module macdnr");
|
||||
}
|
908
Mac/Unsupported/mactcp/mactcpmodule.c
Normal file
908
Mac/Unsupported/mactcp/mactcpmodule.c
Normal file
@ -0,0 +1,908 @@
|
||||
/***********************************************************
|
||||
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
|
||||
Amsterdam, The Netherlands.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "allobjects.h"
|
||||
#include "modsupport.h" /* For getargs() etc. */
|
||||
|
||||
#include "macglue.h"
|
||||
#include "tcpglue.h"
|
||||
|
||||
#include <Desk.h>
|
||||
|
||||
static object *ErrorObject;
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Declarations for objects of type MacTCP connection status */
|
||||
|
||||
typedef struct {
|
||||
OB_HEAD
|
||||
TCPStatusPB status;
|
||||
} tcpcsobject;
|
||||
|
||||
staticforward typeobject Tcpcstype;
|
||||
|
||||
#define is_tcpcsobject(v) ((v)->ob_type == &Tcpcstype)
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Declarations for objects of type MacTCP global status */
|
||||
|
||||
#ifdef TCP_GS
|
||||
typedef struct {
|
||||
OB_HEAD
|
||||
TCPParam *ptr;
|
||||
} tcpgsobject;
|
||||
|
||||
staticforward typeobject Tcpgstype;
|
||||
|
||||
#define is_tcpgsobject(v) ((v)->ob_type == &Tcpgstype)
|
||||
#endif /* TCP_GS */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Declarations for objects of type MacTCP TCP stream */
|
||||
|
||||
typedef struct {
|
||||
OB_HEAD
|
||||
TCPiopb iop;
|
||||
object *asr; /* Optional async notification routine */
|
||||
int asr_ec; /* error code parameter to asr */
|
||||
int asr_reason; /* detail for some errors */
|
||||
int async_busy; /* True when completion routine pending */
|
||||
int async_err; /* the error for the async call */
|
||||
} tcpsobject;
|
||||
|
||||
staticforward typeobject Tcpstype;
|
||||
|
||||
#define is_tcpsobject(v) ((v)->ob_type == &Tcpstype)
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Declarations for objects of type MacTCP UDP stream */
|
||||
|
||||
typedef struct {
|
||||
OB_HEAD
|
||||
UDPiopb iop;
|
||||
object *asr;
|
||||
int asr_ec; /* error code parameter to asr */
|
||||
ip_port port;
|
||||
} udpsobject;
|
||||
|
||||
staticforward typeobject Udpstype;
|
||||
|
||||
#define is_udpsobject(v) ((v)->ob_type == &Udpstype)
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
static tcpcsobject *
|
||||
newtcpcsobject(ptr)
|
||||
TCPStatusPB *ptr;
|
||||
{
|
||||
tcpcsobject *self;
|
||||
|
||||
self = NEWOBJ(tcpcsobject, &Tcpcstype);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->status = *ptr;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
tcpcs_dealloc(self)
|
||||
tcpcsobject *self;
|
||||
{
|
||||
DEL(self);
|
||||
}
|
||||
/* Code to access structure members by accessing attributes */
|
||||
|
||||
#include "structmember.h"
|
||||
|
||||
#define OFF(x) offsetof(TCPStatusPB, x)
|
||||
|
||||
static struct memberlist tcpcs_memberlist[] = {
|
||||
{"remoteHost", T_ULONG, OFF(remoteHost), RO},
|
||||
{"remotePort", T_USHORT, OFF(remotePort), RO},
|
||||
{"localHost", T_UINT, OFF(localHost), RO},
|
||||
{"localPort", T_USHORT, OFF(localPort), RO},
|
||||
{"tosFlags", T_BYTE, OFF(tosFlags), RO},
|
||||
#if 0 /* Bug in header file: cannot access precedence */
|
||||
{"precedence" T_BYTE, OFF(precedence), RO},
|
||||
#endif
|
||||
{"connectionState", T_BYTE, OFF(connectionState), RO},
|
||||
{"sendWindow", T_USHORT, OFF(sendWindow), RO},
|
||||
{"rcvWindow", T_USHORT, OFF(rcvWindow), RO},
|
||||
{"amtUnackedData", T_USHORT, OFF(amtUnackedData), RO},
|
||||
{"amtUnreadData", T_USHORT, OFF(amtUnreadData), RO},
|
||||
{"sendUnacked", T_UINT, OFF(sendUnacked), RO},
|
||||
{"sendNext", T_UINT, OFF(sendNext), RO},
|
||||
{"congestionWindow", T_UINT, OFF(congestionWindow), RO},
|
||||
{"rcvNext", T_UINT, OFF(rcvNext), RO},
|
||||
{"srtt", T_UINT, OFF(srtt), RO},
|
||||
{"lastRTT", T_UINT, OFF(lastRTT), RO},
|
||||
{"sendMaxSegSize", T_UINT, OFF(sendMaxSegSize), RO},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static object *
|
||||
tcpcs_getattr(self, name)
|
||||
tcpcsobject *self;
|
||||
char *name;
|
||||
{
|
||||
object *rv;
|
||||
|
||||
return getmember((char *)&self->status, tcpcs_memberlist, name);
|
||||
}
|
||||
|
||||
|
||||
static typeobject Tcpcstype = {
|
||||
OB_HEAD_INIT(&Typetype)
|
||||
0, /*ob_size*/
|
||||
"MacTCP connection status", /*tp_name*/
|
||||
sizeof(tcpcsobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)tcpcs_dealloc, /*tp_dealloc*/
|
||||
(printfunc)0, /*tp_print*/
|
||||
(getattrfunc)tcpcs_getattr, /*tp_getattr*/
|
||||
(setattrfunc)0, /*tp_setattr*/
|
||||
(cmpfunc)0, /*tp_compare*/
|
||||
(reprfunc)0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
(hashfunc)0, /*tp_hash*/
|
||||
};
|
||||
|
||||
/* End of code for MacTCP connection status objects */
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
#ifdef TCP_GS
|
||||
static tcpgsobject *
|
||||
newtcpgsobject(ptr)
|
||||
TCPParam *ptr;
|
||||
{
|
||||
tcpgsobject *self;
|
||||
|
||||
self = NEWOBJ(tcpgsobject, &Tcpgstype);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->ptr = ptr;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
tcpgs_dealloc(self)
|
||||
tcpgsobject *self;
|
||||
{
|
||||
DEL(self);
|
||||
}
|
||||
/* Code to access structure members by accessing attributes */
|
||||
#undef OFF
|
||||
#define OFF(x) offsetof(TCPParam, x)
|
||||
|
||||
static struct memberlist tcpgs_memberlist[] = {
|
||||
{"RtoA", T_UINT, OFF(tcpRtoA), RO},
|
||||
{"RtoMin", T_UINT, OFF(tcpRtoMin), RO},
|
||||
{"RtoMax", T_UINT, OFF(tcpRtoMax), RO},
|
||||
{"MaxSegSize", T_UINT, OFF(tcpMaxSegSize), RO},
|
||||
{"MaxConn", T_UINT, OFF(tcpMaxConn), RO},
|
||||
{"MaxWindow", T_UINT, OFF(tcpMaxWindow), RO},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static object *
|
||||
tcpgs_getattr(self, name)
|
||||
tcpgsobject *self;
|
||||
char *name;
|
||||
{
|
||||
object *rv;
|
||||
|
||||
return getmember((char *)self->ptr, tcpgs_memberlist, name);
|
||||
}
|
||||
|
||||
static typeobject Tcpgstype = {
|
||||
OB_HEAD_INIT(&Typetype)
|
||||
0, /*ob_size*/
|
||||
"MacTCP global status", /*tp_name*/
|
||||
sizeof(tcpgsobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)tcpgs_dealloc, /*tp_dealloc*/
|
||||
(printfunc)0, /*tp_print*/
|
||||
(getattrfunc)tcpgs_getattr, /*tp_getattr*/
|
||||
(setattrfunc)0, /*tp_setattr*/
|
||||
(cmpfunc)0, /*tp_compare*/
|
||||
(reprfunc)0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
(hashfunc)0, /*tp_hash*/
|
||||
};
|
||||
#endif /* TCP_GS */
|
||||
|
||||
/* End of code for MacTCP global status objects */
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
tcps_asr_safe(arg)
|
||||
void *arg;
|
||||
{
|
||||
tcpsobject *self = (tcpsobject *)arg;
|
||||
object *args, *rv;
|
||||
|
||||
if ( self->asr == None )
|
||||
return;
|
||||
args = mkvalue("(ii)", self->asr_ec, self->asr_reason);
|
||||
rv = call_object(self->asr, args);
|
||||
DECREF(args);
|
||||
if ( rv ) {
|
||||
DECREF(rv);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static pascal void
|
||||
tcps_asr(str, ec, self, reason, icmp)
|
||||
StreamPtr str;
|
||||
unsigned short ec;
|
||||
tcpsobject *self;
|
||||
unsigned short reason;
|
||||
struct ICMPReport icmp;
|
||||
{
|
||||
if ( self->asr == None )
|
||||
return;
|
||||
self->asr_ec = ec;
|
||||
self->asr_reason = reason;
|
||||
Py_AddPendingCall(tcps_asr_safe, (void *)self);
|
||||
}
|
||||
|
||||
static void
|
||||
tcps_opendone(pb)
|
||||
TCPiopb *pb;
|
||||
{
|
||||
tcpsobject *self = (tcpsobject *)pb->csParam.open.userDataPtr;
|
||||
|
||||
if ( pb != &self->iop || !self->async_busy ) {
|
||||
/* Oops... problems */
|
||||
printf("tcps_opendone: unexpected call\n");
|
||||
return;
|
||||
}
|
||||
self->async_busy = 0;
|
||||
self->async_err = pb->ioResult;
|
||||
/* Extension of mactcp semantics: also call asr on open complete */
|
||||
if ( self->asr == None )
|
||||
return;
|
||||
self->asr_ec = lastEvent-1;
|
||||
self->asr_reason = 0;
|
||||
Py_AddPendingCall(tcps_asr_safe, (void *)self);
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_isdone(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
return newintobject(!self->async_busy);
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_wait(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
while ( self->async_busy ) {
|
||||
if ( !PyMac_Idle() ) {
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
if ( self->async_err ) {
|
||||
PyErr_Mac(ErrorObject, self->async_err);
|
||||
self->async_err = 0;
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
static object *
|
||||
tcps_PassiveOpen(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
short port;
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, "h", &port))
|
||||
return NULL;
|
||||
self->async_busy = 1;
|
||||
self->async_err = 0;
|
||||
err = xTCPPassiveOpen(&self->iop, port, (TCPIOCompletionProc)tcps_opendone,
|
||||
(void *)self);
|
||||
if ( err ) {
|
||||
self->async_busy = 0;
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_ActiveOpen(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
short lport, rport;
|
||||
long rhost;
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, "hlh", &lport, &rhost, &rport))
|
||||
return NULL;
|
||||
err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_Send(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
char *buf;
|
||||
int bufsize;
|
||||
int push = 0, urgent = 0;
|
||||
OSErr err;
|
||||
miniwds wds;
|
||||
|
||||
if (!newgetargs(args, "s#|ii", &buf, &bufsize, &push, &urgent))
|
||||
return NULL;
|
||||
wds.length = bufsize;
|
||||
wds.ptr = buf;
|
||||
wds.terminus = 0;
|
||||
err = xTCPSend(&self->iop, (wdsEntry *)&wds, (Boolean)push, (Boolean)urgent,
|
||||
(TCPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_Rcv(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
int length;
|
||||
int timeout;
|
||||
rdsEntry rds[2];
|
||||
OSErr err;
|
||||
object *rv;
|
||||
int urgent, mark;
|
||||
|
||||
if (!newgetargs(args, "i", &timeout))
|
||||
return NULL;
|
||||
memset((char *)&rds, 0, sizeof(rds));
|
||||
err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
urgent = self->iop.csParam.receive.urgentFlag;
|
||||
mark = self->iop.csParam.receive.markFlag;
|
||||
rv = newsizedstringobject((char *)rds[0].ptr, rds[0].length);
|
||||
err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
/* Should not happen */printf("mactcp module: BufReturn failed?\n");
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
DECREF(rv);
|
||||
return NULL;
|
||||
}
|
||||
return mkvalue("(Oii)", rv, urgent, mark);
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_Close(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
err = xTCPClose(&self->iop, (TCPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_Abort(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
err = xTCPAbort(&self->iop);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
|
||||
static object *
|
||||
tcps_Status(self, args)
|
||||
tcpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
TCPStatusPB *pb;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
err = xTCPStatus(&self->iop, &pb);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
return (object *)newtcpcsobject(pb);
|
||||
}
|
||||
|
||||
static struct methodlist tcps_methods[] = {
|
||||
{"isdone", (method)tcps_isdone, 1},
|
||||
{"wait", (method)tcps_wait, 1},
|
||||
{"PassiveOpen", (method)tcps_PassiveOpen, 1},
|
||||
{"ActiveOpen", (method)tcps_ActiveOpen, 1},
|
||||
{"Send", (method)tcps_Send, 1},
|
||||
{"Rcv", (method)tcps_Rcv, 1},
|
||||
{"Close", (method)tcps_Close, 1},
|
||||
{"Abort", (method)tcps_Abort, 1},
|
||||
{"Status", (method)tcps_Status, 1},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
/* ---------- */
|
||||
|
||||
static object *
|
||||
tcps_getattr(self, name)
|
||||
tcpsobject *self;
|
||||
char *name;
|
||||
{
|
||||
if ( strcmp(name, "asr") == 0 ) {
|
||||
INCREF(self->asr);
|
||||
return self->asr;
|
||||
}
|
||||
return findmethod(tcps_methods, (object *)self, name);
|
||||
}
|
||||
|
||||
static int
|
||||
tcps_setattr(self, name, value)
|
||||
tcpsobject *self;
|
||||
char *name;
|
||||
object *value;
|
||||
{
|
||||
if ( strcmp(name, "asr") != 0 || value == NULL )
|
||||
return -1;
|
||||
self->asr = value; /* XXXX Assuming I don't have to incref */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static tcpsobject *
|
||||
newtcpsobject(bufsize)
|
||||
int bufsize;
|
||||
{
|
||||
tcpsobject *self;
|
||||
OSErr err;
|
||||
|
||||
self = NEWOBJ(tcpsobject, &Tcpstype);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
memset((char *)&self->iop, 0, sizeof(self->iop));
|
||||
err= xTCPCreate(bufsize, (TCPNotifyProc)tcps_asr, (void *)self, &self->iop);
|
||||
if ( err ) {
|
||||
DEL(self);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
self->asr = None;
|
||||
self->async_busy = 0;
|
||||
self->async_err = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
tcps_dealloc(self)
|
||||
tcpsobject *self;
|
||||
{
|
||||
if ( self->async_busy ) {
|
||||
printf("mactcp module: error: dealloc with async busy\n");
|
||||
return;
|
||||
}
|
||||
xTCPRelease(&self->iop);
|
||||
DEL(self);
|
||||
}
|
||||
|
||||
static typeobject Tcpstype = {
|
||||
OB_HEAD_INIT(&Typetype)
|
||||
0, /*ob_size*/
|
||||
"MacTCP TCP stream", /*tp_name*/
|
||||
sizeof(tcpsobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)tcps_dealloc, /*tp_dealloc*/
|
||||
(printfunc)0, /*tp_print*/
|
||||
(getattrfunc)tcps_getattr, /*tp_getattr*/
|
||||
(setattrfunc)tcps_setattr, /*tp_setattr*/
|
||||
(cmpfunc)0, /*tp_compare*/
|
||||
(reprfunc)0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
(hashfunc)0, /*tp_hash*/
|
||||
};
|
||||
|
||||
/* End of code for MacTCP TCP stream objects */
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
udps_asr_safe(arg)
|
||||
void *arg;
|
||||
{
|
||||
udpsobject *self = (udpsobject *)arg;
|
||||
object *args, *rv;
|
||||
|
||||
if ( self->asr == None )
|
||||
return;
|
||||
args = mkvalue("(i)", self->asr_ec);
|
||||
rv = call_object(self->asr, args);
|
||||
DECREF(args);
|
||||
if ( rv ) {
|
||||
DECREF(rv);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static pascal void
|
||||
udps_asr(str, ec, self, icmp)
|
||||
StreamPtr str;
|
||||
unsigned short ec;
|
||||
udpsobject *self;
|
||||
struct ICMPReport icmp;
|
||||
{
|
||||
if ( self->asr == None )
|
||||
return;
|
||||
self->asr_ec = ec;
|
||||
Py_AddPendingCall(udps_asr_safe, (void *)self);
|
||||
}
|
||||
|
||||
|
||||
static object *
|
||||
udps_Read(self, args)
|
||||
udpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
object *rv;
|
||||
int timeout;
|
||||
|
||||
if (!newgetargs(args, "i", &timeout))
|
||||
return NULL;
|
||||
err = xUDPRead(&self->iop, timeout, (UDPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
rv = newsizedstringobject((char *)self->iop.csParam.receive.rcvBuff,
|
||||
self->iop.csParam.receive.rcvBuffLen);
|
||||
err = xUDPBfrReturn(&self->iop, self->iop.csParam.receive.rcvBuff);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
DECREF(rv);
|
||||
return NULL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static object *
|
||||
udps_Write(self, args)
|
||||
udpsobject *self;
|
||||
object *args;
|
||||
{
|
||||
unsigned long host;
|
||||
unsigned short port;
|
||||
char *buf;
|
||||
int bufsize;
|
||||
OSErr err;
|
||||
miniwds wds;
|
||||
|
||||
if (!newgetargs(args, "lhs#", &host, &port, &buf, &bufsize))
|
||||
return NULL;
|
||||
wds.length = bufsize;
|
||||
wds.ptr = buf;
|
||||
wds.terminus = 0;
|
||||
err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionProc)0);
|
||||
if ( err ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
static struct methodlist udps_methods[] = {
|
||||
{"Read", (method)udps_Read, 1},
|
||||
{"Write", (method)udps_Write, 1},
|
||||
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
/* ---------- */
|
||||
|
||||
static object *
|
||||
udps_getattr(self, name)
|
||||
udpsobject *self;
|
||||
char *name;
|
||||
{
|
||||
if ( strcmp(name, "asr") == 0 ) {
|
||||
INCREF(self->asr);
|
||||
return self->asr;
|
||||
}
|
||||
if ( strcmp(name, "port") == 0 )
|
||||
return newintobject((int)self->port);
|
||||
return findmethod(udps_methods, (object *)self, name);
|
||||
}
|
||||
|
||||
static int
|
||||
udps_setattr(self, name, value)
|
||||
udpsobject *self;
|
||||
char *name;
|
||||
object *value;
|
||||
{
|
||||
if ( strcmp(name, "asr") != 0 || value == NULL )
|
||||
return -1;
|
||||
self->asr = value; /* XXXX Assuming I don't have to incref */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static udpsobject *
|
||||
newudpsobject(bufsize, port)
|
||||
int bufsize;
|
||||
int port;
|
||||
{
|
||||
udpsobject *self;
|
||||
OSErr err;
|
||||
|
||||
self = NEWOBJ(udpsobject, &Udpstype);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
memset((char *)&self->iop, 0, sizeof(self->iop));
|
||||
self->port = port;
|
||||
err= xUDPCreate(&self->iop, bufsize, &self->port, (UDPNotifyProc)udps_asr,
|
||||
(void *)self);
|
||||
if ( err ) {
|
||||
DEL(self);
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
INCREF(None);
|
||||
self->asr = None;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
udps_dealloc(self)
|
||||
udpsobject *self;
|
||||
{
|
||||
xUDPRelease(&self->iop);
|
||||
DEL(self);
|
||||
}
|
||||
|
||||
static typeobject Udpstype = {
|
||||
OB_HEAD_INIT(&Typetype)
|
||||
0, /*ob_size*/
|
||||
"MacTCP UDP stream", /*tp_name*/
|
||||
sizeof(udpsobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)udps_dealloc, /*tp_dealloc*/
|
||||
(printfunc)0, /*tp_print*/
|
||||
(getattrfunc)udps_getattr, /*tp_getattr*/
|
||||
(setattrfunc)udps_setattr, /*tp_setattr*/
|
||||
(cmpfunc)0, /*tp_compare*/
|
||||
(reprfunc)0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
(hashfunc)0, /*tp_hash*/
|
||||
};
|
||||
|
||||
/* End of code for MacTCP UDP stream objects */
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
static object *
|
||||
mactcp_TCPCreate(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
object *rv;
|
||||
int bufsize;
|
||||
|
||||
if (!newgetargs(args, "i", &bufsize))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
rv = (object *)newtcpsobject(bufsize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static object *
|
||||
mactcp_UDPCreate(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
object *rv;
|
||||
int bufsize, port;
|
||||
|
||||
if (!newgetargs(args, "ii", &bufsize, &port))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
rv = (object *)newudpsobject(bufsize, port);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static object *
|
||||
mactcp_MTU(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
unsigned short mtu;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
mtu = xMaxMTU();
|
||||
return newintobject((int)mtu);
|
||||
}
|
||||
|
||||
static object *
|
||||
mactcp_IPAddr(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
unsigned long rv;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
rv = xIPAddr();
|
||||
return newintobject((int)rv);
|
||||
}
|
||||
|
||||
static object *
|
||||
mactcp_NetMask(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
unsigned long rv;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
rv = xNetMask();
|
||||
return newintobject((int)rv);
|
||||
}
|
||||
|
||||
#ifdef TCP_GS
|
||||
static object *
|
||||
mactcp_GlobalInfo(self, args)
|
||||
object *self; /* Not used */
|
||||
object *args;
|
||||
{
|
||||
OSErr err;
|
||||
|
||||
if (!newgetargs(args, ""))
|
||||
return NULL;
|
||||
if ( (err = xOpenDriver()) != noErr ) {
|
||||
PyErr_Mac(ErrorObject, err);
|
||||
return NULL;
|
||||
}
|
||||
/* XXXX Allocate, fill */
|
||||
INCREF(None);
|
||||
return None;
|
||||
}
|
||||
#endif /* TCP_GS */
|
||||
|
||||
/* List of methods defined in the module */
|
||||
|
||||
static struct methodlist mactcp_methods[] = {
|
||||
{"TCPCreate", mactcp_TCPCreate, 1},
|
||||
{"UDPCreate", mactcp_UDPCreate, 1},
|
||||
{"MTU", mactcp_MTU, 1},
|
||||
{"IPAddr", mactcp_IPAddr, 1},
|
||||
{"NetMask", mactcp_NetMask, 1},
|
||||
#ifdef TCP_GS
|
||||
{"GlobalInfo", mactcp_GlobalInfo, 1},
|
||||
#endif
|
||||
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialization function for the module (*must* be called initmactcp) */
|
||||
|
||||
void
|
||||
initmactcp()
|
||||
{
|
||||
object *m, *d;
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = initmodule("mactcp", mactcp_methods);
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
d = getmoduledict(m);
|
||||
ErrorObject = newstringobject("mactcp.error");
|
||||
dictinsert(d, "error", ErrorObject);
|
||||
|
||||
/* XXXX Add constants here */
|
||||
|
||||
/* Check for errors */
|
||||
if (err_occurred())
|
||||
fatal("can't initialize module mactcp");
|
||||
}
|
490
Mac/Unsupported/mactcp/tcpglue.c
Normal file
490
Mac/Unsupported/mactcp/tcpglue.c
Normal file
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* Glue routines for mactcp module.
|
||||
* Jack Jansen, CWI, 1994.
|
||||
*
|
||||
* Adapted from mactcp socket library, which was in turn
|
||||
* adapted from ncsa telnet code.
|
||||
*
|
||||
* Original authors: Tom Milligan, Charlie Reiman
|
||||
*/
|
||||
|
||||
# include <Memory.h>
|
||||
# include <Files.h>
|
||||
# include <Errors.h>
|
||||
|
||||
#include "tcpglue.h"
|
||||
#include <Devices.h>
|
||||
|
||||
#ifndef __MWERKS__
|
||||
#define TCPIOCompletionUPP TCPIOCompletionProc
|
||||
#define NewTCPIOCompletionProc(x) (x)
|
||||
#endif /* __MWERKS__ */
|
||||
|
||||
static short driver = 0;
|
||||
|
||||
#ifndef __powerc
|
||||
/*
|
||||
* Hack fix for MacTCP 1.0.X bug
|
||||
*
|
||||
* This hack doesn't work on the PPC. But then, people with new machines
|
||||
* shouldn't run ancient buggy software. -- Jack.
|
||||
*/
|
||||
|
||||
pascal char *ReturnA5(void) = {0x2E8D};
|
||||
#endif /* !__powerc */
|
||||
|
||||
OSErr xOpenDriver()
|
||||
{
|
||||
if (driver == 0)
|
||||
{
|
||||
ParamBlockRec pb;
|
||||
OSErr io;
|
||||
|
||||
pb.ioParam.ioCompletion = 0L;
|
||||
pb.ioParam.ioNamePtr = "\p.IPP";
|
||||
pb.ioParam.ioPermssn = fsCurPerm;
|
||||
io = PBOpen(&pb,false);
|
||||
if (io != noErr)
|
||||
return(io);
|
||||
driver = pb.ioParam.ioRefNum;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
* create a TCP stream
|
||||
*/
|
||||
OSErr xTCPCreate(buflen,notify,udp, pb)
|
||||
int buflen;
|
||||
TCPNotifyProc notify;
|
||||
void *udp;
|
||||
TCPiopb *pb;
|
||||
{
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPCreate;
|
||||
pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
|
||||
pb->csParam.create.rcvBuffLen = buflen;
|
||||
pb->csParam.create.notifyProc = notify;
|
||||
pb->csParam.create.userDataPtr = udp;
|
||||
return (xPBControlSync(pb));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* start listening for a TCP connection
|
||||
*/
|
||||
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion,
|
||||
void *udp)
|
||||
{
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPPassiveOpen;
|
||||
pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
|
||||
pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
|
||||
pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
|
||||
pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
|
||||
pb->csParam.open.remoteHost = 0;
|
||||
pb->csParam.open.remotePort = 0;
|
||||
pb->csParam.open.localHost = 0;
|
||||
pb->csParam.open.localPort = port;
|
||||
pb->csParam.open.dontFrag = 0;
|
||||
pb->csParam.open.timeToLive = 0;
|
||||
pb->csParam.open.security = 0;
|
||||
pb->csParam.open.optionCnt = 0;
|
||||
pb->csParam.open.userDataPtr = udp;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
/*
|
||||
* connect to a remote TCP
|
||||
*/
|
||||
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport,
|
||||
TCPIOCompletionProc completion)
|
||||
{
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPActiveOpen;
|
||||
pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
|
||||
pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
|
||||
pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
|
||||
pb->csParam.open.commandTimeoutValue = 0;
|
||||
pb->csParam.open.remoteHost = rhost;
|
||||
pb->csParam.open.remotePort = rport;
|
||||
pb->csParam.open.localHost = 0;
|
||||
pb->csParam.open.localPort = port;
|
||||
pb->csParam.open.dontFrag = 0;
|
||||
pb->csParam.open.timeToLive = 0;
|
||||
pb->csParam.open.security = 0;
|
||||
pb->csParam.open.optionCnt = 0;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
|
||||
TCPiopb *pb;
|
||||
rdsEntry *rds;
|
||||
int rdslen;
|
||||
int timeout;
|
||||
TCPIOCompletionProc completion;
|
||||
{
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPNoCopyRcv;
|
||||
pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
|
||||
pb->csParam.receive.rdsPtr = (Ptr)rds;
|
||||
pb->csParam.receive.rdsLength = rdslen;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
|
||||
{
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPRcvBfrReturn;
|
||||
pb->csParam.receive.rdsPtr = (Ptr)rds;
|
||||
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
/*
|
||||
* send data
|
||||
*/
|
||||
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion)
|
||||
{
|
||||
if (driver == 0)
|
||||
return invalidStreamPtr;
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPSend;
|
||||
pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
|
||||
pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
|
||||
pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
|
||||
pb->csParam.send.pushFlag = push;
|
||||
pb->csParam.send.urgentFlag = urgent;
|
||||
pb->csParam.send.wdsPtr = (Ptr)wds;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* close a connection
|
||||
*/
|
||||
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion)
|
||||
{
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPClose;
|
||||
pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
|
||||
pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
|
||||
pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
/*
|
||||
* abort a connection
|
||||
*/
|
||||
OSErr xTCPAbort(TCPiopb *pb)
|
||||
{
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPAbort;
|
||||
return (xPBControlSync(pb));
|
||||
}
|
||||
|
||||
/*
|
||||
* close down a TCP stream (aborting a connection, if necessary)
|
||||
*/
|
||||
OSErr xTCPRelease(pb)
|
||||
TCPiopb *pb;
|
||||
{
|
||||
OSErr io;
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPRelease;
|
||||
io = xPBControlSync(pb);
|
||||
if (io == noErr)
|
||||
DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
|
||||
return(io);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int
|
||||
xTCPBytesUnread(sp)
|
||||
SocketPtr sp;
|
||||
{
|
||||
TCPiopb *pb;
|
||||
OSErr io;
|
||||
|
||||
if (!(pb = sock_fetch_pb(sp)))
|
||||
return -1; /* panic */
|
||||
|
||||
if (driver == 0)
|
||||
return(-1);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPStatus;
|
||||
io = xPBControlSync(pb);
|
||||
if (io != noErr)
|
||||
return(-1);
|
||||
return(pb->csParam.status.amtUnreadData);
|
||||
}
|
||||
|
||||
int
|
||||
xTCPBytesWriteable(sp)
|
||||
SocketPtr sp;
|
||||
{
|
||||
TCPiopb *pb;
|
||||
OSErr io;
|
||||
long amount;
|
||||
|
||||
if (!(pb = sock_fetch_pb(sp)))
|
||||
return -1; /* panic */
|
||||
|
||||
if (driver == 0)
|
||||
return(-1);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPStatus;
|
||||
io = xPBControlSync(pb);
|
||||
if (io != noErr)
|
||||
return(-1);
|
||||
amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
|
||||
if (amount < 0)
|
||||
amount = 0;
|
||||
return amount;
|
||||
}
|
||||
|
||||
int xTCPWriteBytesLeft(SocketPtr sp)
|
||||
{
|
||||
TCPiopb *pb;
|
||||
OSErr io;
|
||||
|
||||
if (!(pb = sock_fetch_pb(sp)))
|
||||
return -1; /* panic */
|
||||
|
||||
if (driver == 0)
|
||||
return(-1);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPStatus;
|
||||
io = xPBControlSync(pb);
|
||||
if (io != noErr)
|
||||
return(-1);
|
||||
return (pb->csParam.status.amtUnackedData);
|
||||
}
|
||||
#endif
|
||||
|
||||
OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
|
||||
{
|
||||
OSErr io;
|
||||
|
||||
if (driver == 0)
|
||||
return(-1);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPStatus;
|
||||
io = xPBControlSync(pb);
|
||||
if (io == noErr)
|
||||
*spb = &pb->csParam.status;
|
||||
return(io);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* create a UDP stream, hook it to a socket.
|
||||
*/
|
||||
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp)
|
||||
{
|
||||
OSErr io;
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = UDPCreate;
|
||||
pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
|
||||
pb->csParam.create.rcvBuffLen = buflen;
|
||||
pb->csParam.create.notifyProc = asr;
|
||||
pb->csParam.create.userDataPtr = udp;
|
||||
pb->csParam.create.localPort = *port;
|
||||
if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
|
||||
return io;
|
||||
|
||||
*port = pb->csParam.create.localPort;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
* ask for incoming data
|
||||
*/
|
||||
OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion)
|
||||
{
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = UDPRead;
|
||||
pb->csParam.receive.timeOut = timeout;
|
||||
pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
|
||||
return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion ));
|
||||
}
|
||||
|
||||
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
|
||||
{
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = UDPBfrReturn;
|
||||
pb->csParam.receive.rcvBuff = buff;
|
||||
return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* send data
|
||||
*/
|
||||
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
|
||||
UDPIOCompletionProc completion)
|
||||
{
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = UDPWrite;
|
||||
pb->csParam.send.remoteHost = host;
|
||||
pb->csParam.send.remotePort = port;
|
||||
pb->csParam.send.wdsPtr = (Ptr)wds;
|
||||
pb->csParam.send.checkSum = true;
|
||||
pb->csParam.send.sendLength = 0/* must be zero */;
|
||||
return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion));
|
||||
}
|
||||
|
||||
/*
|
||||
* close down a UDP stream (aborting a read, if necessary)
|
||||
*/
|
||||
OSErr xUDPRelease(UDPiopb *pb) {
|
||||
OSErr io;
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = UDPRelease;
|
||||
io = xPBControlSync( (TCPiopb *)pb );
|
||||
if (io == noErr) {
|
||||
DisposPtr(pb->csParam.create.rcvBuff);
|
||||
}
|
||||
return(io);
|
||||
}
|
||||
|
||||
ip_addr xIPAddr(void)
|
||||
{
|
||||
struct GetAddrParamBlock pbr;
|
||||
OSErr io;
|
||||
|
||||
pbr.ioCRefNum = driver;
|
||||
pbr.csCode = ipctlGetAddr;
|
||||
io = xPBControlSync( (TCPiopb *)&pbr );
|
||||
if (io != noErr)
|
||||
return(0);
|
||||
return(pbr.ourAddress);
|
||||
}
|
||||
|
||||
long xNetMask()
|
||||
{
|
||||
struct GetAddrParamBlock pbr;
|
||||
OSErr io;
|
||||
|
||||
pbr.ioCRefNum = driver;
|
||||
pbr.csCode = ipctlGetAddr;
|
||||
io = xPBControlSync( (TCPiopb *)&pbr);
|
||||
if (io != noErr)
|
||||
return(0);
|
||||
return(pbr.ourNetMask);
|
||||
}
|
||||
|
||||
unsigned short xMaxMTU()
|
||||
{
|
||||
struct UDPiopb pbr;
|
||||
OSErr io;
|
||||
|
||||
pbr.ioCRefNum = driver;
|
||||
pbr.csCode = UDPMaxMTUSize;
|
||||
pbr.csParam.mtu.remoteHost = xIPAddr();
|
||||
io = xPBControlSync( (TCPiopb *)&pbr );
|
||||
if (io != noErr)
|
||||
return(0);
|
||||
return(pbr.csParam.mtu.mtuSize);
|
||||
}
|
||||
|
||||
OSErr xPBControlSync(TCPiopb *pb)
|
||||
{
|
||||
(pb)->ioCompletion = 0L;
|
||||
return PBControl((ParmBlkPtr)(pb),false);
|
||||
}
|
||||
|
||||
#pragma segment SOCK_RESIDENT
|
||||
|
||||
OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
|
||||
TCPiopb *pb;
|
||||
Ptr buf;
|
||||
int buflen;
|
||||
int timeout;
|
||||
TCPIOCompletionProc completion;
|
||||
{
|
||||
|
||||
if (driver == 0)
|
||||
return(invalidStreamPtr);
|
||||
|
||||
pb->ioCRefNum = driver;
|
||||
pb->csCode = TCPRcv;
|
||||
pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
|
||||
pb->csParam.receive.rcvBuff = buf;
|
||||
pb->csParam.receive.rcvBuffLen = buflen;
|
||||
return (xPBControl(pb,completion));
|
||||
}
|
||||
|
||||
OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion)
|
||||
{
|
||||
#ifndef __MWERKS__
|
||||
pb->ioNamePtr = ReturnA5();
|
||||
#endif
|
||||
|
||||
if (completion == 0L)
|
||||
{
|
||||
(pb)->ioCompletion = 0L;
|
||||
return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
|
||||
}
|
||||
else if (completion == (TCPIOCompletionProc)-1L)
|
||||
{
|
||||
(pb)->ioCompletion = 0L;
|
||||
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
/* If I understand the PowerPC calling correctly this is the right
|
||||
** code, but the MetroWerks headers seem to disagree. We'll see... -- Jack
|
||||
*/
|
||||
TCPIOCompletionUPP comp_upp = NewTCPIOCompletionProc(completion);
|
||||
(pb)->ioCompletion = comp_upp;
|
||||
#else
|
||||
(pb)->ioCompletion = completion;
|
||||
#endif
|
||||
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
|
||||
}
|
||||
}
|
||||
|
49
Mac/Unsupported/mactcp/tcpglue.h
Normal file
49
Mac/Unsupported/mactcp/tcpglue.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Prototypes for mactcpglue routines and includes/structures needed
|
||||
* by those.
|
||||
*
|
||||
* Jack Jansen, CWI, 1994.
|
||||
*
|
||||
* Adapted from mac socket library, which has in turn adapted from ncsa telnet.
|
||||
* Original authors: Tom Milligan, Charlie Reiman
|
||||
*/
|
||||
|
||||
#include <MacTCPCommonTypes.h>
|
||||
#include <GetMyIPAddr.h>
|
||||
#include <TCPPB.h>
|
||||
#include <UDPPB.h>
|
||||
#include <AddressXlation.h>
|
||||
|
||||
typedef struct miniwds
|
||||
{
|
||||
unsigned short length;
|
||||
char * ptr;
|
||||
unsigned short terminus; /* must be zero'd for use */
|
||||
} miniwds;
|
||||
|
||||
|
||||
OSErr xOpenDriver(void);
|
||||
OSErr xPBControl(TCPiopb *pb, TCPIOCompletionProc completion);
|
||||
OSErr xPBControlSync(TCPiopb *pb);
|
||||
OSErr xTCPCreate(int buflen, TCPNotifyProc notify, void *udp, TCPiopb *pb);
|
||||
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, void *udp);
|
||||
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionProc completion);
|
||||
OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionProc completion);
|
||||
OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionProc);
|
||||
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion);
|
||||
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion);
|
||||
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion);
|
||||
OSErr xTCPAbort(TCPiopb *pb);
|
||||
OSErr xTCPRelease(TCPiopb *pb);
|
||||
|
||||
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp);
|
||||
OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionProc completion);
|
||||
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff);
|
||||
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
|
||||
UDPIOCompletionProc completion);
|
||||
OSErr xUDPRelease(UDPiopb *pb);
|
||||
|
||||
ip_addr xIPAddr(void);
|
||||
long xNetMask(void);
|
||||
unsigned short xMaxMTU(void);
|
||||
|
Loading…
Reference in New Issue
Block a user