home *** CD-ROM | disk | FTP | other *** search
- {/////////////////////////////////////////////////////////////////////////////
- // NETCHAT (tm) Version 1.00A December 1, 1988 //
- // Copyright 1988 by L. Brett Glass, Systems Consultant //
- // //
- // This source code is copyrighted and may NOT be published in any medium //
- // without the express permission of the author. //
- // //
- // Please address correspondence to: //
- // L. Brett Glass, P.O Box 817, Palo Alto, CA 94302-0817 //
- //////////////////////////////////////////////////////////////////////////////}
-
- program NetChat; {Network Conference Program}
-
- uses CRT,Network;
-
- const {Manifest constants}
- RCVNCBS = 4; {Number of NCBs for receive operations}
- RCVBUFS = 5; {Number of receive buffers available. There is one
- more receive buffer than there are NCBs. This allows
- a new receive to be started with a fresh buffer while
- text from a previous receive is being displayed.}
-
- type
- RcvNCBNumber = 1..RCVNCBS; {Type for receive NCB numbers}
- RcvBufNumber = 1..RCVBUFS; {Type for receive buffer numbers}
- StringPtr = ^String; {Pointer to a generic string}
-
- const {Typed constants}
- chatError : Byte = GOOD_RTN; {If program ended with an error, code goes here}
- NetChatName : NetName = 'NETCHAT'#0#0#0#0#0#0#0#0#0; {Group name for chat}
- rcvY : Byte = 1; {Line for next received message}
- sendX : Byte = 1; {Character position for send message}
-
-
- var
- receiveNCBs : array [RcvNCBNumber] of NCB; {NCBs for receieve commands}
- receiveBuffers : array [RcvBufNumber] of String; {Buffers for received text}
- freeBuffer, tempBufferPtr : StringPtr; {Pointers to receive buffers}
- sendNCB : NCB; {NCB for send commands}
- sendBuffer : String; {Buffer for sends}
- netChatNameNum : Byte; {Number of the name NETCHAT in our name table}
- userName : String[40]; {Name of user}
- editString : String[79]; {Buffer for the line editor}
- ch : Char; {Character buffer for the line editor}
- i : RcvNCBNumber; {Loop counter}
- oldExitProc : Pointer; {Original value of exitProc}
-
- function AddGroupName(groupName : NetName; var nameNum : Byte) : Byte;
- {Add the given group name. Return the number of the name and
- the result code.}
- var
- addNCB : NCB;
- begin {AddGroupName}
- InitNCB(addNCB);
- with addNCB do
- begin
- command := ADD_GROUP_NAME;
- name := groupName;
- end;
- AddGroupName := NetBIOS(addNCB);
- nameNum := addNCB.num
- end; {AddGroupName}
-
- procedure DeleteName(delName : NetName);
- {Delete the given name.}
- var
- delNCB: NCB;
- begin {DeleteName}
- InitNCB(delNCB);
- with delNCB do
- begin
- command := DELETE_NAME;
- name := delName
- end;
- CallNetBIOS(delNCB)
- end; {DeleteName}
-
- {$F+}
- procedure ExitChat;
- {This Turbo Pascal exit procedure "cleans up" when the program exits.}
- begin {ExitChat}
- repeat until sendNCB.cmd_cplt <> COMMAND_PENDING; {Wait for send}
- DeleteName(netChatName); {This kills all receive commands}
- Window(1,1,80,25);
- GotoXY(1,25);
- Writeln;
- if Length(editString) > 0 then
- Writeln;
- if chatError <> GOOD_RTN then
- Writeln(^G'NetBIOS error ',chatError)
- else
- begin
- Writeln('Thank you for using NetChat. This program is ShareWare. You may freely');
- Writeln('redistribute the executable version of this program, provided that it');
- Writeln('is not altered in any way. The license fee is $10 per network station');
- Writeln('that runs the program.');
- Writeln;
- Writeln('Please address correspondence to:');
- Writeln('L. Brett Glass, P.O Box 817, Palo Alto, CA 94302-0817')
- end;
- exitProc := oldExitProc
- end; {ExitChat}
- {$F-}
-
- begin {NetChat}
- checkBreak := FALSE; {Disable CRT unit break checking}
- Writeln('NETCHAT (tm) V1.00A, Copyright L. Brett Glass 1988');
- Write('Please enter your name: '); {Ask for name for attribution purposes}
- Readln(userName);
- if Length(userName) = 0 then {Let user back out by typing null string}
- Halt;
- if Length(userName) > 38 then {If name too long, truncate it}
- userName[0] := #38;
- userName := userName + ': '; {Add a colon and a space, just to be neat}
- {Clear the string that holds the user's message as it's being edited}
- editString := '';
- {Check for presence of a network}
- if not NetPresent then
- begin
- Writeln('Network or NetBIOS not installed.');
- Halt
- end;
- {Try to add the group name 'NETCHAT'}
- chatError := AddGroupName(netChatName,netChatNameNum);
- if chatError <> GOOD_RTN then
- begin
- Writeln('NetBIOS error ', chatError, ' adding group name; program aborting.');
- Halt
- end;
- {Set up a procedure to clean up when program exits}
- oldExitProc := exitProc;
- exitProc := @ExitChat;
- {Prepare the screen}
- ClrScr;
- GoToXY(1,24);
- Write('╠═ NETCHAT (tm) ══ Copyright 1988 L. Brett Glass'+
- ' ══ Enter to send, ^C to Exit ═╣');
- Window(1,25,80,25);
- {Initialize all the receive NCBs we'll use}
- for i := 1 to RCVNCBS do
- begin
- InitNCB(receiveNCBs[i]);
- with receiveNCBs[i] do
- begin
- command := RECEIVE_DATAGRAM_NO_WAIT;
- bufPtr := @receiveBuffers[i];
- len := SizeOf(String);
- num := netChatNameNum
- end
- end;
- freeBuffer := @receiveBuffers[RCVBUFS]; {Extra buffer is free at the start}
- {Prepare the send NCB}
- InitNCB (sendNCB);
- with sendNCB do
- begin
- command := SEND_DATAGRAM_NO_WAIT;
- bufPtr := @sendBuffer;
- callName.name := netChatName;
- num := netChatNameNum
- end;
- {Start a receive command for each receive NCB}
- for i := 1 to RCVNCBS do
- begin
- case NetBIOS(receiveNCBs[i]) of
- GOOD_RTN, COMMAND_PENDING: ; {These codes are OK}
- else
- chatError := receiveNCBs[i].retCode;
- Halt
- end
- end;
- {Main loop}
- repeat
- if KeyPressed then
- begin
- ch := ReadKey;
- case ch of
- ^C : Halt; {Exit program}
- ^H : {Backspace}
- if Length(editString) > 0 then
- begin
- Write(^H' '^H);
- Dec(editString[0])
- end;
- ^M : {Send the string}
- with sendNCB do
- begin
- repeat until cmd_cplt <> COMMAND_PENDING; {Wait for prev send}
- if cmd_cplt <> GOOD_RTN then
- begin
- chatError := cmd_cplt;
- Halt
- end;
- sendBuffer := userName + editString; {Add attribution}
- len := Succ(Length(sendBuffer)); {Size the datagram}
- case NetBIOS(sendNCB) of
- GOOD_RTN, COMMAND_PENDING:; {These codes OK}
- else
- chatError := retCode;
- Halt
- end;
- editString := '';
- ClrScr {Clear the bottom one-line window}
- end;
- #0: ch := ReadKey; {Ignore function keys}
- #1..#31,#127,#255:; {and non-printing characters}
- else
- {Check for full line. Add character if there is room}
- if Length(editString) < Pred(SizeOf(editString)) then
- begin
- editString := editString + ch;
- Write(ch)
- end
- end
- end;
- for i := 1 to RCVNCBS do
- with receiveNCBs[i] do
- case cmd_cplt of
- COMMAND_PENDING:; {Do nothing; no message came in for this NCB}
- GOOD_RTN: {Display a message from the network}
- begin
- tempBufferPtr := bufPtr; {Get msg address}
- bufPtr := freeBuffer; {Find the free buffer}
- len := SizeOf(String); {Set buffer length field back to max length}
- case NetBIOS(receiveNCBs[i]) of {Immediately start another receive}
- GOOD_RTN, COMMAND_PENDING:; {These codes OK}
- else
- chatError := retCode;
- Halt
- end;
- sendX := WhereX; {Save location on bottom line}
- Window(1,1,80,23); {Move to the upper window and position cursor}
- GoToXY(1,rcvY);
- Write(^M^J,tempBufferPtr^); {Write the message}
- rcvY := WhereY; {Go back to the botton line}
- Window(1,25,80,25);
- GoToXY(sendX,1);
- freeBuffer := tempBufferPtr;
- end
- else
- chatError := cmd_cplt;
- Halt
- end
- until FALSE
- end. {NetChat}