home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-04 | 25.8 KB | 863 lines | [TEXT/PJMM] |
- {This document is formated in monaco 9 pt }
- { }
- {LEGAL STUFF }
- { }
- {Copyright © 1994 by University of Melbourne. All Rights Reserved. This work is }
- {provided "as is" and without any express or implied warranties, including, }
- {without limitation, the implied warranties of merchantability and fitness }
- {for a particular purpose. }
- { }
- {University of Melbourne is not responsible for the consequences of the use of this}
- {work, regardless of the cause. You may use this work in a public domain, }
- {freeware, or shareware product with no restrictions, as long as you include }
- {the following notice in your product's about box or splash screen: }
- { "Portions Copyright © 1994 by University of Melbourne". }
- {If you use more than 50 lines of this work, please credit the author also: }
- { "Portions by Michael Cutter" }
- {Public domain is defined as something that you release to the public, without }
- {copyright and without restrictions on use. Freeware is a copyrighted work, }
- {for which you charge no money. Shareware is a copyrighted work for which you }
- {charge a fee if the user decides to keep it. If you intend to use this work }
- {in a commercial product, please contact us. }
- { }
- { }
- {OTHER STUFF }
- { }
- {AUTHOR: }
- { Michael Trevor Cutter }
- { }
- {CONTACT: }
- { Internet: }
- { mtc@arbld.unimelb.edu.au (Preferred) }
- { Snail Mail: }
- { Dept of Architecture & Building }
- { University of Melbourne }
- { Parkville VIC 3052 }
- { AUSTRALIA }
- { }
- {PERSONAL STUFF }
- { I'd really appreciate it if you'd let me know what you're using my code }
- { in, (send me email or a postcard). Please report any bugs or errors to me. }
- { }
- {MODULE DESCRIPTION }
- {These functions provide a very simple interface to Peter N Lewis' fantastic TCP }
- {libraries, which I hope are somewhere else on this disc. It's best used for }
- {local - server transaction type connections, where you don't expect the connection}
- {to close suddenly on you or anything. Peter, I know you hate exit(), but I like }
- {the way it neatens my code. I think it does, anyway :-) }
-
- unit MCTCPComms;
- interface
- uses
- AppleTalk, Processes, PPCToolBox, EPPC, Notification, AppleEvents,{}
- TCPTypes, TCPStuff, TCPConnections, MCHandlesAndStrs, MCCursor, MCConversions;
-
- {check for MacTCP}
- function MCIsMacTCPThere: boolean;
-
- {initialize all globals used in the following procedures}
- procedure MCTCPInitGlobals;
-
- {returns a user readable error message as a str}
- function MCTCPErrToString (err: OSErr;
- var fatalerror: boolean): Str255; {sets fatal error to true if fatal}
-
- {returns first 3 characters of string as a number - standard for codes for TCP communications}
- function MCTCPCodeOfStr (str: str255): integer;
-
- {Call this function before opening _any_ TCP connections, cause it will probably kill them}
- function MCTCPGetMyIP: Str255;
-
- {Call this function to get MacTCP going and ready to create connections}
- function MCTCPStart: OSErr;
-
- {Call this procedure to finish up using MacTCP}
- procedure MCTCPStop;
-
- {Call this function to check an address exists}
- function MCTCPCheckAddress (ipaddress: Str255): OSErr;
-
- {all timeouts are in seconds}
-
- {Call this function to open a connection to a port - ip number should be of form:}
- {'xxx.xxx.xxx.xxx'}
- {timeout is in seconds. Use timeout = 0 to use default maximum, and use timeout < 0}
- {to wait forever}
- function MCTCPOpenConnection (ipnumber: Str255;
- portNo: integer;
- var connIndx: connectionIndex;
- timeout: longint;
- dowaitnextevent: Boolean): OSErr;
-
- {call this function to wait for a connection on the given port number, from the given ipnumber}
- function MCTCPOpenPassiveConxn (ipnumber: Str255;
- portNo: integer;
- var connIndx: connectionIndex;
- timeout: longint;
- dowaitnextevent: Boolean): OSErr;
-
- {Call this procedure to close a connection }
- procedure MCTCPCloseConnection (var connIndx: connectionIndex);
-
- {Call this function to send a line stored as a hndl}
- function MCTCPSendHndlLine (connIndx: connectionIndex;
- hmsg: Handle;
- dontaddlinefeed: Boolean): OSErr;
-
- {Call this function to send a line as a string}
- function MCTCPSendStrLine (connectionID: connectionIndex;
- msg: Str255;
- dontaddlinefeed: Boolean): OSErr;
-
- {not normally called by outside proc, but I put it in the interface because I was lazy :-)}
- procedure CallProgBarProc (dlog: DialogPtr;
- value: longint;
- p: ProcPtr);
- inline
- $205F, $4E90;
-
- {Call this function to receive a line as a handle}
- {timeout is in seconds. Use timeout = 0 to use default maximum, and use timeout < 0}
- { to wait forever}
- function MCTCPRcvHndlLine (connIndx: connectionIndex;
- var hmsg: Handle;
- timeout: longint;
- dowaitnextevent: Boolean;
- handleaeevents: Boolean;
- callbackproc: ProcPtr;
- progdlog: DialogPtr): OSErr;
-
- {Call this function to receive a line as a string}
- {timeout is in seconds. Use timeout = 0 to use default maximum, and use timeout < 0}
- { to wait forever}
- function MCTCPRcvStrLine (connectionID: connectionIndex;
- var msg: Str255;
- timeout: longint;
- dowaitnextevent: Boolean;
- handleaeevents: Boolean;
- callbackproc: ProcPtr;
- progdlog: DialogPtr): OSErr;
-
- implementation
- const
- MAX_WAIT_FOR_SERVER = 60; {maximum number of seconds to wait for server if timedout = 0}
- MAX_PASSIVE_WAIT = 60 * 60 * 24 * 365;{a year should be enough}
-
- LineFeedCode = $0A;
- ReturnCode = $0D;
-
- const
- ipfailedtoopen = 2;
- iptimedoutonopen = -23900; {defined by mtc, not apple}
- ipOpenProtErr = -23030;
- ipCloseProtErr = -23031;
- ipBadWDSErr = -23034;
- icmpEchoTimeoutErr = -23035;
-
- var
- gMCTCPStarted: Boolean;
- gMCTCPStopped: Boolean;
-
- function MCIsMacTCPThere: boolean;
- var
- myerr: OSErr;
- myfeature: longint;
- myBit: integer;
- begin
- myerr := Gestalt('mtcp', myFeature);
- if myErr = noErr then {because it can't be a valid selector unless MacTCP is actually }
- {installed anyway}
- begin
- MCIsMacTCPThere := true
- end
- else
- MCIsMacTCPThere := false;
- end;
-
- procedure MCTCPInitGlobals;
- begin
- gMCTCPStarted := false;
- gMCTCPStopped := false;
- end;
-
- function MCTCPErrToString;
- begin
- fatalerror := false;
- case err of
- noErr:
- MCTCPErrToString := '';
-
-
- {specially defined errors}
-
- {2}
- ipfailedtoopen:
- begin
- MCTCPErrToString := 'The server is not available.';
- fatalerror := true;
- end;
-
- {-23900}
- iptimedoutonopen:
- begin
- MCTCPErrToString := 'The server does not respond to connection request.';
- fatalerror := true;
- end;
-
-
- {standard errors}
-
- {-23000}
- ipBadLapErr:
- begin
- MCTCPErrToString := 'TCP Bad network configuration.';
- fatalerror := true;
- end;
- {-23001}
- ipBadCnfgErr:
- begin
- MCTCPErrToString := 'TCP Bad IP configuration error.';
- fatalerror := true;
- end;
- {-23002}
- ipNoCnfgErr:
- begin
- MCTCPErrToString := 'TCP Missing IP or LAP configuration error.';
- fatalerror := true;
- end;
- {-23003}
- ipLoadErr:
- begin
- MCTCPErrToString := 'MacTCP is not, or could not be loaded.';
- fatalerror := true;
- end;
- {-23004}
- ipBadAddr:
- begin
- MCTCPErrToString := 'TCP Could not find the requested server.';
- fatalerror := true;
- end;
- {-23005}
- connectionClosing:
- MCTCPErrToString := 'TCP Connection is closing.';
- {-23006}
- invalidLength:
- MCTCPErrToString := 'TCP Invalid length.';
- {-23007}
- connectionExists:
- MCTCPErrToString := 'TCP Request conflicts with existing connection.';
- {-23008}
- connectionDoesntExist:
- MCTCPErrToString := 'TCP Connection does not exist. ';
- {-23009}
- insufficientResources:
- MCTCPErrToString := 'TCP Insufficient resources to perform request . ';
- {-23010}
- invalidStreamPtr:
- MCTCPErrToString := 'TCP Invalid stream.';
- {-23011}
- streamAlreadyOpen:
- MCTCPErrToString := 'TCP Stream already open.';
- {-23012}
- connectionTerminated:
- MCTCPErrToString := 'TCP Connection terminated unexpectedly.';
- {-23013}
- invalidBufPtr:
- MCTCPErrToString := 'TCP Invalid BuffPtr.';
- {-23014}
- invalidRDS:
- MCTCPErrToString := 'TCP Invalid RDS.';
- {-23015}
- openFailed:
- MCTCPErrToString := 'TCP Open connection failed.';
- {-23016}
- commandTimeout:
- MCTCPErrToString := 'TCP Server failed to respond to command.';
- {-23017}
- duplicateSocket:
- MCTCPErrToString := 'TCP duplicate socket.';
- {-23030}
- ipOpenProtErr:
- MCTCPErrToString := 'TCP Can’t open new protocol , table full.';
- {-23031}
- ipCloseProtErr:
- MCTCPErrToString := 'TCP Can’t find protocol to close . ';
- {-23032}
- ipDontFragErr:
- MCTCPErrToString := 'TCP Packet too large to send w/o fragmenting.';
- {-23033}
- ipDestDeadErr:
- MCTCPErrToString := 'TCP Destination not responding.';
- {-23034}
- ipBadWDSErr:
- MCTCPErrToString := 'TCP Error in WDS format.';
- {-23035}
- icmpEchoTimeoutErr:
- MCTCPErrToString := 'TCP ICMP echo timed-out.';
- {-23036}
- ipNoFragMemErr:
- MCTCPErrToString := 'TCP No memory to send fragmented pkt.';
- {-23037}
- ipRouteErr:
- MCTCPErrToString := 'TCP Can’t route packet off - net.';
- {-23041}
- nameSyntaxErr:
- MCTCPErrToString := 'TCP Name syntax error.';
- {-23042}
- cacheFault:
- MCTCPErrToString := 'TCP Cache fault.';
- {-23043}
- noResultProc:
- MCTCPErrToString := 'TCP No result procedure.';
- {-23044}
- noNameServer:
- MCTCPErrToString := 'TCP No name server.';
- {-23045}
- authNameErr:
- MCTCPErrToString := 'TCP Name authorisation error.';
- {-23046}
- noAnsErr:
- MCTCPErrToString := 'TCP No answer error.';
- {-23047}
- dnrErr:
- MCTCPErrToString := 'TCP dnr error.';
- {-23048}
- outOfMemory:
- begin
- MCTCPErrToString := 'TCP Out of memory.';
- fatalerror := true;
- end;
-
- otherwise
- MCTCPErrToString := concat('unknown error:', MCNumToString(err));
- end;
- end;
-
- {returns first 3 characters of string as a number - standard for codes for TCP communications}
- function MCTCPCodeOfStr;
- var
- total: longint;
- begin
- delete(str, 4, length(str) - 3);
- StringToNum(str, total);
- MCTCPCodeOfStr := total;
- end;
-
- function MCTCPGetMyIP;
- var
- myipstr: str255;
- myip: longint;
- procedure CatchOSErr (err: OSErr);
- begin
- if err <> noErr then
- begin
- MCTCPGetMyIP := '';
- exit(MCTCPGetMyIP);
- end;
- end;
- begin
- {make sure that MacTCP is awake}
- CatchOSErr(MCTCPStart);
-
- {get our IP address}
- CatchOSErr(TCPGetMyIPAddr(myip));
-
- {find the string version of the ip number}
- FindString(myip, myipstr);
-
- {close all connections}
- MCTCPStop;
-
- MCTCPGetMyIP := myipstr;
- end;
-
- function MCTCPStart;
- var
- err: OSErr;
- begin
- {should modify to use Gestalt to check for MacTCP}
- MCTCPStart := noErr;
- if not MCIsMacTCPThere then
- begin
- MCTCPStart := ipLoadErr;
- gMCTCPStarted := false;
- end
- else if not gMCTCPStarted then {don't start them again!}
- begin
- err := InitConnections;
- if err <> noErr then
- MCTCPStart := err
- else
- begin
- gMCTCPStarted := true;
- gMCTCPStopped := false;
- end;
- end; {otherwise is already started, so don't worry about it}
- end;
-
- procedure MCTCPStop;
- begin
- if (not gMCTCPStopped) and (gMCTCPStarted) then {don't stop them again!}
- begin
- FinishEverything;
- gMCTCPStopped := true;
- gMCTCPStarted := false;
- end;
- end;
-
- {Call this function to check an address}
- {MCTCPStart should have already been called.}
- function MCTCPCheckAddress (ipaddress: Str255): OSErr;
- var
- myconnIndx: connectionIndex;
- conEvtRec: connectionEventRecord; { Event record for TCP events, similar to EventRecord }
- myErr: OSErr;
- gotResponse: Boolean;
- begin
- MCTCPCheckAddress := noErr;
- if not gMCTCPStarted then
- MCTCPCheckAddress := ipLoadErr
- else
- begin{-23003?}
- myconnIndx := 0;
- myErr := FindAddress(myconnIndx, ipaddress, nil);
- if myErr <> noErr then
- MCTCPCheckAddress := myErr
- else
- begin
- gotResponse := false;
- while not gotResponse do
- if GetConnectionEvent(any_connection, conEvtRec) then {look for an event on the connection, no mask}
- begin { Get the next TCP event }
-
- case conEvtRec.event of {case the event of}
- C_Found:
- begin
- MCTCPCheckAddress := noErr;
- gotResponse := true;
- end;
-
- C_SearchFailed: {couldn't find the address!}
- begin
- MCTCPCheckAddress := -23004;{bad address}
- gotResponse := true;
- end;
- otherwise
- ;
- end;
- end;
- end;
- end;
- end;
-
- function MCTCPOpenConnection;
- {MCTCPStart should have already been called}
- var
- myip: longint; {just to make sure MacTCP is awake, and has allocated us an IP number}
- conEvtRec: connectionEventRecord; { Event record for TCP events, similar to EventRecord }
- connectionOpened: Boolean;
- starttime, endtime: longint;
- ignoreResult: Boolean;
- event: EventRecord;
-
- procedure CatchOSErr (err: OSErr);
- begin
- if err <> noerr then
- begin
- MCTCPOpenConnection := err;
- if connectionOpened then
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- exit(MCTCPOpenConnection);
- end;
- end;
-
- begin
- connectionOpened := false;
- MCTCPOpenConnection := noErr;
- if not gMCTCPStarted then
- CatchOSErr(ipLoadErr);{-23003?}
-
- connIndx := 0;
-
- CatchOSErr(FindAddress(connIndx, ipnumber, nil));
-
- {get our IP address}
- CatchOSerr(TCPGetMyIPAddr(myip));
-
- {enter loop to wait for the found event, and for the connection response from the server}
- {use negative time out if wait forever}
- if timeout = 0 then
- timeout := MAX_WAIT_FOR_SERVER;
- if timeout > 0 then
- begin
- starttime := TickCount;
- endtime := starttime + timeout * 60;
- end;
- while not connectionOpened do
- begin
- MCNextAnimCursor;
- if dowaitnextevent then
- ignoreResult := WaitNextEvent(everyEvent, event, 60, nil);
- if timeout > 0 then
- if (TickCount > endtime) then
- CatchOSErr(iptimedoutonopen);
- if GetConnectionEvent(any_connection, conEvtRec) then {look for an event on the connection, no mask}
- begin { Get the next TCP event }
-
- case conEvtRec.event of {case the event of}
- C_Found:
- begin
- CatchOSErr(NewActiveConnection(connIndx, Default_TCPBUFFERSIZE, conEvtRec.value, portNo, nil));
- end;
-
- C_SearchFailed: {couldn't find the address!}
- begin
- CatchOSErr(-23004);{bad address}
- end;
-
- C_Established: { Happens once per succesful connection establishment }
- begin
- connectionOpened := true;
- end;
-
- C_FailedToOpen:
- begin
- CatchOSErr(conEvtRec.value);
- end;
-
- C_Closing:
- begin
- { Gets called when the connection starts closing down - shouldn't happen in this loop}
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- end;
-
- C_Closed:
- begin
- CatchOSErr(-23012); {connection terminated unexpectedly}
- end;
- otherwise
- ;
- end;
- end;{iff}
- end;{while}
- end;
-
- {this function exits as soon as it finds the server and tries to connect to it. You should immediately go into}
- {a wait if the function succeeds, checking for open connection events. Don't forget to make sure there is a }
- {WaitNextEvent in the waiting loop. Also, don't forget to allow for quit events.}
- function MCTCPOpenPassiveConxn (ipnumber: Str255;
- portNo: integer;
- var connIndx: connectionIndex;
- timeout: longint;
- dowaitnextevent: Boolean): OSErr;
- {MCTCPStart must have already been called}
- var
- myip: longint; {just to make sure MacTCP is awake, and has allocated us an IP number}
- conEvtRec: connectionEventRecord; { Event record for TCP events, similar to EventRecord }
- connectionOpened: Boolean;
- starttime, endtime: longint;
- ignoreResult: Boolean;
- event: EventRecord;
-
- procedure CatchOSErr (err: OSErr);
- begin
- if err <> noerr then
- begin
- MCTCPOpenPassiveConxn := err;
- if connectionOpened then
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- exit(MCTCPOpenPassiveConxn);
- end;
- end;
-
- begin
- connectionOpened := false;
- MCTCPOpenPassiveConxn := noErr;
- if not gMCTCPStarted then
- CatchOSErr(ipLoadErr);{-23003?}
-
- connIndx := 0;
-
- {get our IP address}
- CatchOSerr(TCPGetMyIPAddr(myip));
-
- if ipnumber <> '' then
- CatchOSErr(FindAddress(connIndx, ipnumber, nil)) {find the server address}
- else
- begin {just open one, and do it. Don't have to worry about finding the address}
- CatchOSErr(NewPassiveConnection(connIndx, Default_TCPBUFFERSIZE, portNo, 0, 0, nil));
- exit(MCTCPOpenPassiveConxn);
- end;
- {enter loop to wait for the found event, and for the connection response from the server}
- {use negative time out if wait forever}
- if timeout = 0 then
- timeout := MAX_PASSIVE_WAIT;
- if timeout > 0 then
- begin
- starttime := TickCount;
- endtime := starttime + timeout * 60;
- end;
- while not connectionOpened do
- begin
- MCNextAnimCursor;
- if dowaitnextevent then
- ignoreResult := WaitNextEvent(everyEvent, event, 60, nil);
- if timeout > 0 then
- if (TickCount > endtime) then
- CatchOSErr(iptimedoutonopen);
- if GetConnectionEvent(any_connection, conEvtRec) then {look for an event on the connection, no mask}
- begin { Get the next TCP event }
- case conEvtRec.event of {case the event of}
- C_Found:
- begin
- CatchOSErr(NewPassiveConnection(connIndx, Default_TCPBUFFERSIZE, portNo, conEvtRec.value, 0, nil));
- connectionOpened := true;
- end;
-
- C_SearchFailed: {couldn't find the address!}
- begin
- CatchOSErr(-23004);{bad address}
- end;
-
- C_Closing:
- begin
- { Gets called when the connection starts closing down - shouldn't happen in this loop}
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- end;
-
- C_Closed:
- begin
- CatchOSErr(-23012); {connection terminated unexpectedly}
- end;
- otherwise
- ;
- end;
- end;{iff}
- end;{while}
- end;
-
-
- {close the connection specified}
-
- procedure MCTCPCloseConnection;
- var
- myip: longint; {just to make sure MacTCP is awake, and has allocated us an IP number}
- closedConnection: Boolean;
- conEvtRec: connectionEventRecord; { Event record for TCP events, similar to EventRecord }
- begin
- closedConnection := false;
- CloseConnection(connIndx); { Close our side of the connection }
- while not closedConnection do
- begin
- MCNextAnimCursor;
- if GetConnectionEvent(connIndx, conEvtRec) then {look for an event on the connection, no mask}
- begin { Get the next TCP event }
-
- case conEvtRec.event of {case the event of}
- C_Closing:
- begin
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- closedConnection := true;
- end;
-
- C_Closed:
- begin
- closedConnection := true;
- end;
- otherwise
- ;
- end;
- end;{iff}
- end;{while}
- end;
-
- {does not dispose handle of message}
- function MCTCPSendHndlLine;
- var
- tcpc: TCPConnectionPtr;
- hlen: longint;
- p: Ptr;
- procedure CatchOSErr (err: OsErr);
- begin
- if err <> noErr then
- begin
- MCTCPSendHndlLine := err;
- exit(MCTCPSendHndlLine);
- end;
- end;
- begin
- MCTCPSendHndlLine := noErr;
- if hmsg = nil then
- CatchOSErr(nilHandleErr);
-
- {append line feed to handle if not already there}
- hlock(hmsg);
- hlen := GetHandleSize(hmsg);
- if not dontaddlinefeed then
- begin
- p := Pointer(ord4(hmsg^) + hlen - 1);
- if p^ <> LineFeedCode then
- begin
- CatchOSErr(MCAppendStrToHndl(chr(LineFeedCode), hmsg)); { add linefeed just in case }
- hlen := hlen + 1;
- end;
- end;
- {get connection pointer and send it}
- GetConnectionTCPC(connIndx, tcpc);
- if tcpc <> nil then
- CatchOSErr(TCPSend(tcpc, hmsg^, hlen, true))
- else
- SysBeep(1);
- hunlock(hmsg);
- end;
-
- function MCTCPSendStrLine;
- var
- myh: Handle;
- err: OSErr;
- begin
- MCTCPSendStrLine := noErr;
- myh := nil;
- if msg = '' then
- msg := chr($0D);
- err := MCAppendStrToHndl(msg, myh);
- if (err = noErr) and (myh <> nil) then
- begin
- MCTCPSendStrLine := MCTCPSendHndlLine(connectionID, myh, dontaddlinefeed);
- DisposeHandle(myh);
- end
- else
- MCTCPSendStrLine := err;
- end;
-
- function MCTCPRcvHndlLine;
- var
- gotlinefeed: boolean;
- feed: boolean;
- str: Str255;
- count: longint;
- conEvtRec: connectionEventRecord; { Event record for TCP events, similar to EventRecord }
- starttime, endtime, lasttime: longint; {last time is last time the call back was called - every second}
- ignoreResult: Boolean;
- event: EventRecord;
- myErr: OSErr;
- procedure CatchOSErr (err: OSErr);
- begin
- if err <> noErr then
- begin
- MCTCPRcvHndlLine := err;
- hmsg := nil;
- exit(MCTCPRcvHndlLine);
- end;
- end;
- begin
- MCTCPRcvHndlLine := noErr;
- gotlinefeed := false;
- hmsg := nil;
- if timeout = 0 then
- timeout := MAX_WAIT_FOR_SERVER;
- if timeout > 0 then
- begin
- starttime := TickCount;
- endtime := starttime + timeout * 60;
- end;
- if callbackproc <> nil then
- lasttime := TickCount;
- while not gotlinefeed do
- begin
- MCNextAnimCursor;
- if timeout > 0 then
- begin
- if (TickCount > endtime) then
- begin
- if (callbackproc <> nil) and (progdlog <> nil) then
- CallProgBarProc(progdlog, timeout, callbackproc); {finish the bar}
- CatchOSErr(commandTimeout);
- end
- else if (((TickCount - lasttime) div 60) > 1) then
- begin
- if (callbackproc <> nil) and (progdlog <> nil) then
- CallProgBarProc(progdlog, ((lasttime - starttime) div 60 + 1), callbackproc);
- lasttime := TickCount;
- end;
- end;
- if dowaitnextevent then
- begin
- ignoreResult := WaitNextEvent(everyEvent, event, 60, nil);
- if handleaeevents then
- if event.what = kHighLevelEvent then
- begin
- myErr := AEProcessAppleEvent(event);
- if (myErr <> noErr) and (myErr <> -1708) then {allow for undefined received apple events}
- begin
- CatchOsErr(myErr);
- end;
- end;
- end;
-
- if GetConnectionEvent(connIndx, conEvtRec) then {look for an event on the connection, no mask}
- begin { Get the next TCP event }
- case conEvtRec.event of {case the event of}
- C_Closing:
- begin
- { Gets called when the connection starts closing down - shouldn't happen in this loop}
- CloseConnection(conEvtRec.connection); { Close our side of the connection }
- end;
-
- C_Closed:
- begin
- CatchOSErr(-23012); {connection terminated unexpectedly}
- end;
-
- C_CharsAvailable: {something waiting to be read! All right :-)}
- begin
- count := 0;
- str := '';
- CatchOSErr(TCPReceiveUpTo(conEvtRec.tcpc, LineFeedCode, 60, @str[1], 255, count, gotlinefeed));
-
- { Recieve characters up to a line feed }
- if (count > 0) & (str[count] = chr(LineFeedCode)) then { strip off linefeed }
- count := count - 1;
- if (count > 0) & (str[count] = chr(ReturnCode)) then { strip off cr }
- count := count - 1;
- MCSetStrLen(str, count);
-
- {append the string to the handle}
- if str <> '' then
- CatchOSErr(MCAppendStrToHndl(str, hmsg));
-
- { if we got a linefeed, return the handle, otherwise go round again and wait for more characters }
- end;
- otherwise
- ;
- end; {case}
- end;{iff}
- end;{while}
- if (callbackproc <> nil) and (progdlog <> nil) then
- CallProgBarProc(progdlog, timeout, callbackproc); {finish the bar}
- end;
-
- function MCTCPRcvStrLine;
- var
- myh: Handle;
- hlen: longint;
- err: OSErr;
- begin
- MCTCPRcvStrLine := noErr;
- err := MCTCPRcvHndlLine(connectionID, myh, timeout, dowaitnextevent, handleaeevents, callbackproc, progdlog);
- if err = noErr then
- begin
- hlen := GetHandleSize(myh);
- if hlen > 255 then
- hlen := 255;
- MCSetStrLen(msg, hlen);
- hlock(myh);
- BlockMove(myh^, @msg[1], hlen);
- hunlock(myh);
- DisposeHandle(myh);{toss the handle}
- end
- else
- MCTCPRcvStrLine := err;
- end;
-
- end.