📄 tcp_mac.c
字号:
stc->text.size = n; stc = stc->next = mail_newstringlist (); ret = tcp_getline_work (stream,&n,&contd); } while (ret && contd); if (ret) { /* stash final part of line on list */ stc->text.data = (unsigned char *) ret; stc->text.size = n; /* determine how large a buffer we need */ for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size; ret = fs_get (n + 1); /* copy parts into buffer */ for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next) memcpy (ret + n,stc->text.data,stc->text.size); ret[n] = '\0'; } mail_free_stringlist (&stl);/* either way, done with list */ } return ret;}/* TCP receive line or partial line * Accepts: TCP stream * pointer to return size * pointer to return continuation flag * Returns: text line string, size and continuation flag, or NIL if failure */static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, long *contd){ unsigned long n; char *s,*ret,c,d; *contd = NIL; /* assume no continuation */ /* make sure have data */ if (!tcp_getdata (stream)) return NIL; for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) { d = *stream->iptr++; /* slurp another character */ if ((c == '\015') && (d == '\012')) { ret = (char *) fs_get (n--); memcpy (ret,s,*size = n); /* copy into a free storage string */ ret[n] = '\0'; /* tie off string with null */ return ret; } } /* copy partial string from buffer */ memcpy ((ret = (char *) fs_get (n)),s,*size = n); /* get more data from the net */ if (!tcp_getdata (stream)) fs_give ((void **) &ret); /* special case of newline broken by buffer */ else if ((c == '\015') && (*stream->iptr == '\012')) { stream->iptr++; /* eat the line feed */ stream->ictr--; ret[*size = --n] = '\0'; /* tie off string with null */ } else *contd = LONGT; /* continuation needed */ return ret;}/* TCP/IP receive buffer * Accepts: TCP/IP stream * size in bytes * buffer to read into * Returns: T if success, NIL otherwise */long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer){ unsigned long n; char *bufptr = buffer; while (size > 0) { /* until request satisfied */ if (!tcp_getdata (stream)) return NIL; n = min (size,stream->ictr);/* number of bytes to transfer */ /* do the copy */ memcpy (bufptr,stream->iptr,n); bufptr += n; /* update pointer */ stream->iptr +=n; size -= n; /* update # of bytes to do */ stream->ictr -=n; } bufptr[0] = '\0'; /* tie off string */ return T;}/* TCP/IP receive data * Accepts: TCP/IP stream * Returns: T if success, NIL otherwise */long tcp_getdata (TCPSTREAM *stream){ time_t t = time (0); struct TCPReceivePB *receivepb = &stream->pb.csParam.receive; struct TCPAbortPB *abortpb = &stream->pb.csParam.abort; while (stream->ictr < 1) { /* if nothing in the buffer */ time_t tl = time (0); stream->pb.csCode = TCPRcv; /* receive TCP data */ receivepb->commandTimeoutValue = (int) ttmo_read; receivepb->rcvBuff = stream->ibuf; receivepb->rcvBuffLen = BUFLEN; receivepb->secondTimeStamp = 0; receivepb->userDataPtr = NIL; PBControlAsync ((ParmBlkPtr) &stream->pb); while (stream->pb.ioResult == inProgress && wait ()); if (stream->pb.ioResult) { /* punt if got an error */ time_t tc = time (0); if ((stream->pb.ioResult == commandTimeout) && tmoh && ((*tmoh) (tc - t,tc - tl))) continue; /* nuke connection */ stream->pb.csCode = TCPAbort; abortpb->userDataPtr = NIL; PBControlSync ((ParmBlkPtr) &stream->pb); return NIL; } stream->iptr = stream->ibuf;/* point at TCP buffer */ stream->ictr = receivepb->rcvBuffLen; } return T;}/* TCP/IP send string as record * Accepts: TCP/IP stream * string pointer * Returns: T if success else NIL */long tcp_soutr (TCPSTREAM *stream,char *string){ return tcp_sout (stream,string,(unsigned long) strlen (string));}/* TCP/IP send string * Accepts: TCP/IP stream * string pointer * byte count * Returns: T if success else NIL */long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size){ struct TCPSendPB *sendpb = &stream->pb.csParam.send; struct TCPAbortPB *abortpb = &stream->pb.csParam.abort; struct { unsigned short length; Ptr buffer; unsigned short trailer; } wds; while (wds.length = (size > (unsigned long) 32768) ? 32768 : size) { wds.buffer = string; /* buffer */ wds.trailer = 0; /* tie off buffer */ size -= wds.length; /* this many words will be output */ string += wds.length; stream->pb.csCode = TCPSend;/* send TCP data */ sendpb->ulpTimeoutValue = (int) ttmo_write; sendpb->ulpTimeoutAction = 0; sendpb->validityFlags = timeoutValue|timeoutAction; sendpb->pushFlag = T; /* send the data now */ sendpb->urgentFlag = NIL; /* non-urgent data */ sendpb->wdsPtr = (Ptr) &wds; sendpb->userDataPtr = NIL; PBControlAsync ((ParmBlkPtr) &stream->pb); while (stream->pb.ioResult == inProgress && wait ()); if (stream->pb.ioResult) { /* punt if got an error */ /* nuke connection */ stream->pb.csCode =TCPAbort; abortpb->userDataPtr = NIL; PBControlSync ((ParmBlkPtr) &stream->pb); return NIL; } } return T; /* success */}/* TCP/IP close * Accepts: TCP/IP stream */void tcp_close (TCPSTREAM *stream){ struct TCPClosePB *closepb = &stream->pb.csParam.close; struct TCPCreatePB *createpb = &stream->pb.csParam.create; stream->pb.csCode = TCPClose; /* close TCP stream */ closepb->ulpTimeoutValue = (int) ttmo_close; closepb->ulpTimeoutAction = 0; closepb->validityFlags = timeoutValue|timeoutAction; closepb->userDataPtr = NIL; PBControlAsync ((ParmBlkPtr) &stream->pb); while (stream->pb.ioResult == inProgress && wait ()); stream->pb.csCode =TCPRelease;/* flush the buffers */ createpb->userDataPtr = NIL; if (PBControlSync ((ParmBlkPtr) &stream->pb)) fatal ("TCPRelease lossage"); /* free its buffer */ fs_give ((void **) &createpb->rcvBuff); /* flush host names */ fs_give ((void **) &stream->host); fs_give ((void **) &stream->localhost); fs_give ((void **) &stream); /* flush the stream */}/* TCP/IP return host for this stream * Accepts: TCP/IP stream * Returns: host name for this stream */char *tcp_host (TCPSTREAM *stream){ return stream->host; /* return host name */}/* TCP/IP return remote host for this stream * Accepts: TCP/IP stream * Returns: host name for this stream */char *tcp_remotehost (TCPSTREAM *stream){ return stream->host; /* return host name */}/* TCP/IP return port for this stream * Accepts: TCP/IP stream * Returns: port number for this stream */unsigned long tcp_port (TCPSTREAM *stream){ return stream->port; /* return port number */}/* TCP/IP return local host for this stream * Accepts: TCP/IP stream * Returns: local host name for this stream */char *tcp_localhost (TCPSTREAM *stream){ return stream->localhost; /* return local host name */}/* TCP/IP return canonical form of host name * Accepts: host name * Returns: canonical form of host name */char *tcp_canonical (char *name){ int i; struct hostInfo hst; /* look like domain literal? */ if (name[0] == '[' && name[i = (strlen (name))-1] == ']') return name; if (StrToAddr (name,&hst,tcp_dns_upp,NIL)) { while (hst.rtnCode == cacheFault && wait ()); /* kludge around MacTCP bug */ if (hst.rtnCode == outOfMemory) { mm_log ("Re-initializing domain resolver",WARN); CloseResolver (); /* bop it on the head and try again */ OpenResolver (NIL); /* note this will leak 12K */ StrToAddr (name,&hst,tcp_dns_upp,NIL); while (hst.rtnCode == cacheFault && wait ()); } /* still have error status? */ if (hst.rtnCode) return name; } return hst.cname; /* success */}/* TCP/IP get client host name (server calls only) * Returns: client host name */char *tcp_clienthost (){ return "UNKNOWN";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -