⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtcpnet.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	mactcp_set_frozen,	mactcp_socket_error    };    TCPiopb pb;    UDPiopb upb;    Actual_Socket ret;    ip_addr dstaddr;    size_t buflen;    /*     * Create Socket structure.     */    ret = snew(struct Socket_tag);    ret->s = 0;    ret->fn = &fn_table;    ret->err = noErr;    ret->plug = plug;    bufchain_init(&ret->output_data);    ret->connected = 0;		       /* to start with */    ret->writable = 0;		       /* to start with */    ret->sending_oob = 0;    ret->frozen = 0;    ret->frozen_readable = 0;    ret->localhost_only = 0;	       /* unused, but best init anyway */    ret->pending_error = 0;    ret->oobinline = oobinline;    ret->oobpending = FALSE;    ret->listener = 0;    dstaddr = addr->hostinfo.addr[0]; /* XXX should try all of them */    /*     * Create a TCP stream.     *      * MacTCP requires us to provide it with some buffer memory.  Page     * 31 of the Programmer's Guide says it should be a minimum of     * 4*MTU+1024.  Page 36 says a minimum of 4096 bytes.  Assume     * they're both correct.     */    assert(addr->resolved);    upb.ioCRefNum = mactcp.refnum;    upb.csCode = UDPMaxMTUSize;    upb.csParam.mtu.remoteHost = dstaddr;    upb.csParam.mtu.userDataPtr = NULL;    ret->err = PBControlSync((ParmBlkPtr)&upb);    if (ret->err != noErr) return (Socket)ret;    buflen = upb.csParam.mtu.mtuSize * 4 + 1024;    if (buflen < 4096) buflen = 4096;    if (mactcp_asr_upp == NULL)	mactcp_asr_upp = NewTCPNotifyUPP(&mactcp_asr);    GetCurrentProcess(&mactcp.self);    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPCreate;    pb.csParam.create.rcvBuff = snewn(buflen, char);    pb.csParam.create.rcvBuffLen = buflen;    pb.csParam.create.notifyProc = mactcp_asr_upp;    pb.csParam.create.userDataPtr = (Ptr)ret;    ret->err = PBControlSync((ParmBlkPtr)&pb);    if (ret->err != noErr) return (Socket)ret;    ret->s = pb.tcpStream;    /*     * Open the connection.     */    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPActiveOpen;    pb.tcpStream = ret->s;    pb.csParam.open.validityFlags = 0;    pb.csParam.open.remoteHost = dstaddr;    pb.csParam.open.remotePort = port;    pb.csParam.open.localPort = privport ? 1023 : 0;    pb.csParam.open.dontFrag = FALSE;    pb.csParam.open.timeToLive = 0;    pb.csParam.open.security = 0;    pb.csParam.open.optionCnt = 0;    pb.csParam.open.userDataPtr = (Ptr)ret;    while (1) {	ret->err = PBControlSync((ParmBlkPtr)&pb);	if (!privport || ret->err != duplicateSocket)	    break;	pb.csParam.open.localPort--;	if (pb.csParam.open.localPort == 0)	    break;    }    if (ret->err != noErr) return (Socket)ret;    ret->connected = TRUE;    ret->writable = TRUE;    /* Add this to the list of all sockets */    ret->next = mactcp.socklist;    ret->prev = &mactcp.socklist;    if (ret->next != NULL)	ret->next->prev = &ret->next;    mactcp.socklist = ret;    sk_addr_free(addr); /* don't need this anymore */    return (Socket)ret;}Socket mactcp_newlistener(char *srcaddr, int port, Plug plug,			  int local_host_only){    fatalbox("mactcp_newlistener");}static void mactcp_close(Socket sock){    Actual_Socket s = (Actual_Socket)sock;    TCPiopb pb;    /*     * TCPClose is equivalent to shutdown(fd, SHUT_WR), and hence     * leaves the Rx side open, while TCPAbort seems rather vicious,     * throwing away Tx data that haven't been ACKed yet.  We do both     * in succession.     */    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPClose;    pb.tcpStream = s->s;    pb.csParam.close.validityFlags = 0;    pb.csParam.close.userDataPtr = (Ptr)s;    s->err = PBControlSync((ParmBlkPtr)&pb);    /* Not much we can do about an error anyway. */    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPAbort;    pb.tcpStream = s->s;    pb.csParam.abort.userDataPtr = (Ptr)s;    s->err = PBControlSync((ParmBlkPtr)&pb);    /* Even less we can do about an error here. */    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPRelease;    pb.tcpStream = s->s;    pb.csParam.create.userDataPtr = (Ptr)s;    s->err = PBControlSync((ParmBlkPtr)&pb);    if (s->err == noErr)	sfree(pb.csParam.create.rcvBuff);    /* Unhitch from list of sockets */    *s->prev = s->next;    if (s->next != NULL)	s->next->prev = s->prev;    sfree(s);}static int mactcp_write(Socket sock, char const *buf, int len){    Actual_Socket s = (Actual_Socket) sock;    wdsEntry wds[2];    TCPiopb pb;    /*      * Casting away const from buf should be safe -- MacTCP won't     * write to it.     */    wds[0].length = len;    wds[0].ptr = (char *)buf;    wds[1].length = 0;    pb.ioCRefNum = mactcp.refnum;    pb.csCode = TCPSend;    pb.tcpStream = s->s;    pb.csParam.send.validityFlags = 0;    pb.csParam.send.pushFlag = TRUE; /* XXX we want it to return. */    pb.csParam.send.urgentFlag = 0;    pb.csParam.send.wdsPtr = (Ptr)wds;    pb.csParam.send.userDataPtr = (Ptr)s;    s->err = PBControlSync((ParmBlkPtr)&pb);    return 0;}static int mactcp_write_oob(Socket sock, char const *buf, int len){    fatalbox("mactcp_write_oob");}static pascal void mactcp_asr(StreamPtr str, unsigned short event, Ptr cookie, 			      unsigned short termin_reason,			      struct ICMPReport *icmp){    WakeUpProcess(&mactcp.self);}			      /* * Called from our event loop if there's work to do. */void mactcp_poll(void){    Actual_Socket s, next;    TCPiopb pb;    for (s = mactcp.socklist; s != NULL; s = next) {	next = s->next;	do {	    pb.ioCRefNum = mactcp.refnum;	    pb.csCode = TCPStatus;	    pb.tcpStream = s->s;	    pb.csParam.status.userDataPtr = (Ptr)s;	    s->err = PBControlSync((ParmBlkPtr)&pb);	    if (s->err != noErr)		goto next_socket;	    if (pb.csParam.status.amtUnreadData == 0)		break;	    mactcp_recv(s, pb.csParam.status.amtUnreadData);	} while (TRUE);	switch (pb.csParam.status.connectionState) {	  case TCPS_CLOSE_WAIT:	    /* Remote end has sent us a FIN */	    plug_closing(s->plug, NULL, 0, 0);	}      next_socket:	;    }}static void mactcp_recv(Actual_Socket s, size_t len){    rdsEntry rds[2];    TCPiopb pb;    if (s->frozen) return;    while (len > 0) {	pb.ioCRefNum = mactcp.refnum;	pb.csCode = TCPNoCopyRcv;	pb.tcpStream = s->s;	pb.csParam.receive.commandTimeoutValue = 0;	pb.csParam.receive.rdsPtr = (Ptr)rds;	pb.csParam.receive.rdsLength = lenof(rds) - 1;	pb.csParam.receive.userDataPtr = (Ptr)s;	s->err = PBControlSync((ParmBlkPtr)&pb);	if (s->err != noErr)	    return;	plug_receive(s->plug, 0, rds[0].ptr, rds[0].length);	len -= rds[0].length;	pb.csCode = TCPRcvBfrReturn;	s->err = PBControlSync((ParmBlkPtr)&pb);	if (s->err != noErr)	    return;    }	}/* * Each socket abstraction contains a `void *' private field in * which the client can keep state. */static void mactcp_set_private_ptr(Socket sock, void *ptr){    Actual_Socket s = (Actual_Socket) sock;    s->private_ptr = ptr;}static void *mactcp_get_private_ptr(Socket sock){    Actual_Socket s = (Actual_Socket) sock;    return s->private_ptr;}/* * Special error values are returned from mactcp_namelookup and * mactcp_new if there's a problem. These functions extract an error * message, or return NULL if there's no problem. */char *mactcp_addr_error(SockAddr addr){    static char buf[64];    switch (addr->hostinfo.rtnCode) {      case noErr:	return NULL;      case nameSyntaxErr:	return "Name syntax error";      case noNameServer:	return "No name server found";      case authNameErr:	return "Domain name does not exist";      case noAnsErr:	return "No answer from domain name server";      case dnrErr:	return "Domain name server returned an error";      case outOfMemory:	return "Out of memory";      default:	sprintf(buf, "Unknown DNR error %d", addr->hostinfo.rtnCode);	return buf;    }}static const char *mactcp_socket_error(Socket sock){    static char buf[64];    Actual_Socket s = (Actual_Socket) sock;    switch (s->err) {      case noErr:	return NULL;      case insufficientResources:	return "Insufficient resources to open TCP stream";      case duplicateSocket:	return "Duplicate socket";      case openFailed:	return "Connection failed while opening";      default:	sprintf(buf, "Unknown MacTCP error %d", s->err);	return buf;    }}static void mactcp_set_frozen(Socket sock, int is_frozen){    Actual_Socket s = (Actual_Socket) sock;    if (s->frozen == is_frozen)	return;    s->frozen = is_frozen;}/* * Bits below here would usually be in dnr.c, shipped with the MacTCP * SDK, but its convenient not to require that, and since we assume * System 7 we can actually simplify things a lot. */static OSErr OpenResolver(char *hosts_file){    short vrefnum;    long dirid;    HParamBlockRec pb;    Str255 filename;    OSErr err;    int fd;    Handle dnr_handle;    if (mactcp.dnr_handle != NULL)	return noErr;    err = FindFolder(kOnSystemDisk, kControlPanelFolderType, FALSE, &vrefnum,		     &dirid);    if (err != noErr) return err;    /*     * Might be better to use PBCatSearch here, but it's not always     * available.     */    pb.fileParam.ioCompletion = NULL;    pb.fileParam.ioNamePtr = filename;    pb.fileParam.ioVRefNum = vrefnum;    pb.fileParam.ioFDirIndex = 1;    pb.fileParam.ioDirID = dirid;    fd = -1;    while (PBHGetFInfoSync(&pb) == noErr) {	if (pb.fileParam.ioFlFndrInfo.fdType == 'cdev' &&	    pb.fileParam.ioFlFndrInfo.fdCreator == 'ztcp') {	    fd = HOpenResFile(vrefnum, dirid, filename, fsRdPerm);	    if (fd == -1) continue;	    dnr_handle = Get1IndResource('dnrp', 1);	    if (dnr_handle != NULL)		break;	    CloseResFile(fd);	    fd = -1;	}	pb.fileParam.ioDirID = dirid;	pb.fileParam.ioFDirIndex++;    }    if (fd == -1)	return fnfErr;        DetachResource(dnr_handle);    CloseResFile(fd);    MoveHHi(dnr_handle);    HLock(dnr_handle);    err = InvokeOpenResolverUPP(OPENRESOLVER, hosts_file,				(OpenResolverUPP)*dnr_handle);    if (err != noErr) {	HUnlock(dnr_handle);	DisposeHandle(dnr_handle);	return err;    }    mactcp.dnr_handle = dnr_handle;    return noErr;}OSErr CloseResolver(void){    Handle dnr_handle = mactcp.dnr_handle;    OSErr err;    if (mactcp.dnr_handle == NULL)	return notOpenErr;    err = InvokeCloseResolverUPP(CLOSERESOLVER,				 (CloseResolverUPP)*mactcp.dnr_handle);    if (err != noErr)	return err;    mactcp.dnr_handle = NULL;    HUnlock(dnr_handle);    DisposeHandle(dnr_handle);    return noErr;}#endif/* * Local Variables: * c-file-style: "simon" * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -