mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Interface to MacTCP and the MacTCP Domain Name Resolver
This commit is contained in:
parent
114ca5c170
commit
edf585579c
5 changed files with 2204 additions and 0 deletions
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…
Add table
Add a link
Reference in a new issue