Category : Modula II Source Code
Archive   : MODULA-2.ZIP
Filename : NETWORK.MOD

 
Output of file : NETWORK.MOD contained in archive : MODULA-2.ZIP
IMPLEMENTATION MODULE Network;

(* provides file support on a PC network.
can be used without a PC network if DOS 3.1 is used.

Commands here emulate/duplicate those in FileSystem.

This module is a replacement for FileSystem and cannot be
used in combination with it or DiskFiles.

Work begun: 02/12/1986
Last Edit: 03/05/1986
Author: J. Tal
Rollins Medical/Dental Systems Southfield, MI
(313) 423-7200

Added CriticalErrorISR Procedure to handle DOS int24 if
we run into invalid opens based on sharing modes already
used on a particular file. Per Logitech Fileio module
and conversations with Cris Cale and Alfred at Logitech.
(02/20/86-02/21/86)

This code may be a little verbose. If you can shrink it and
it still works, let me know.

This should be a good module to study to understand DOS.

Modifications:

03/05/1986 - Move Compiler Stack checking On directive to below
Lookup procedure. Had problems getting at files
already opened by other processes with conflicting
sharing modes. (jt)

03/31/1986 - Changed all checks for error/CriticalError.
Delete procedure Changed.
Found out delete (Dos 41H) wants full path name.
Will have to send it using DiskDirectory.CurrentDirectory().
(jt)


*)


FROM SYSTEM IMPORT AX,BX,CX,DX,DI,SETREG,CODE,SWI,WORD,BYTE,ADDRESS,DOSCALL,
ADR,GETREG;
IMPORT Strings;

FROM Terminal IMPORT WriteString, WriteLn;
FROM DOS3 IMPORT GetExtendedError;
FROM MachDep IMPORT Delay;


CONST
PushAX = 50H;
PopAX = 058H;
PopCX = 059H;
PopDX = 05AH;
PopBX = 05BH;
PopSP = 05CH;
PopBP = 05DH;
PopSI = 05EH;
PopDI = 05FH;
PopES = 007H;
PopSS = 017H;
PopDS = 01FH;
PushES = 006H;
PushCS = 00EH;
PushSS = 016H;
Iret = 0CFH;


VAR
CriticalError : CARDINAL;
CriticalErrorVector[0:90H] : PROCEDURE;
CriticalVector[0:90H] : ARRAY[1..2] OF WORD;
CriticalErrorSave : ARRAY [1..2] OF WORD;
err : CARDINAL;


(*$S-*) (*$T-*) (*$R-*)


PROCEDURE GetXerror( VAR xerror : WORD);
VAR
extendedError : WORD;
errorClass,suggestedAction,locus : BYTE;
BEGIN
CODE(55H);
GetExtendedError(WORD(0),extendedError,errorClass,suggestedAction,locus);
CODE(5DH);
xerror := extendedError;
END GetXerror;


PROCEDURE SetError ( VAR f : File; VAR err : CARDINAL );
VAR
xerror : WORD;
error : CARDINAL;
BEGIN
GetXerror(xerror);
error := CARDINAL(xerror);
CASE error OF
0 :
| 1 : WriteString('Invalid function number'); WriteLn;
| 2 : WriteString('File not found'); WriteLn;
| 3 : WriteString('Path not found'); WriteLn;
| 4 : WriteString('Too many open files (no handles left)'); WriteLn;
| 5 : WriteString('Access denied'); WriteLn;
| 6 : WriteString('Invalid handle'); WriteLn;
| 7 : WriteString('Memory control blocks destroyed'); WriteLn;
| 8 : WriteString('Insufficient memory'); WriteLn;
| 9 : WriteString('Invalid memory block address'); WriteLn;
| 10 : WriteString('Invalid environment'); WriteLn;
| 11 : WriteString('Invalid format'); WriteLn;
| 12 : WriteString('Invalid access code'); WriteLn;
| 13 : WriteString('Invalid data'); WriteLn;
| 14 : WriteString('Reserved'); WriteLn;
| 15 : WriteString('Invalid drive was specified'); WriteLn;
| 16 : WriteString('Attempt to remove the current directory'); WriteLn;
| 17 : WriteString('Not same devices'); WriteLn;
| 18 : WriteString('No more files'); WriteLn;
| 19 : WriteString('Attempt to write on write-protected diskette'); WriteLn;
| 20 : WriteString('Unknown unit'); WriteLn;
| 21 : WriteString('Drive not ready'); WriteLn;
| 22 : WriteString('Unknown command'); WriteLn;
| 23 : WriteString('Data error (CRC)'); WriteLn;
| 24 : WriteString('Bad request structure length'); WriteLn;
| 25 : WriteString('Seek error'); WriteLn;
| 26 : WriteString('Unknown media type'); WriteLn;
| 27 : WriteString('Sector not found'); WriteLn;
| 28 : WriteString('Printer out of paper'); WriteLn;
| 29 : WriteString('Write fault'); WriteLn;
| 30 : WriteString('Read fault'); WriteLn;
| 31 : WriteString('General failure'); WriteLn;
| 32 : WriteString('Sharing violation'); WriteLn;
| 33 : WriteString('Lock violation'); WriteLn;
| 34 : WriteString('Invalid disk change'); WriteLn;
| 35 : WriteString('FCB unavailable'); WriteLn;
| 36 : WriteString('Sharing buffer overflow'); WriteLn;
| 37..49 : WriteString('Reserved'); WriteLn;
| 50 : WriteString('Network request not supported'); WriteLn;
| 51 : WriteString('Remote computer not listening'); WriteLn;
| 52 : WriteString('Duplicate name on network'); WriteLn;
| 53 : WriteString('Network name not found'); WriteLn;
| 54 : WriteString('Network busy'); WriteLn;
| 55 : WriteString('Network device no longer exists'); WriteLn;
| 56 : WriteString('Net BIOS command limit exceeded'); WriteLn;
| 57 : WriteString('Network adapter hardware error'); WriteLn;
| 58 : WriteString('Incorrect response from network'); WriteLn;
| 59 : WriteString('Unexpected network error'); WriteLn;
| 60 : WriteString('Incompatible remote adapter'); WriteLn;
| 61 : WriteString('Print queue full'); WriteLn;
| 62 : WriteString('Not enough space for print file'); WriteLn;
| 63 : WriteString('Print file was deleted'); WriteLn;
| 64 : WriteString('Network name was deleted'); WriteLn;
| 65 : WriteString('Access denied'); WriteLn;
| 66 : WriteString('Network device type incorrect'); WriteLn;
| 67 : WriteString('Network name not found'); WriteLn;
| 68 : WriteString('Network name limit exceeded'); WriteLn;
| 69 : WriteString('Net BIOS session limit exceeded'); WriteLn;
| 70 : WriteString('Temporarily paused'); WriteLn;
| 71 : WriteString('Network request not accepted'); WriteLn;
| 72 : WriteString('Print or disk redirection is paused'); WriteLn;
| 73..79 : WriteString('Reserved'); WriteLn;
| 80 : WriteString('File exists'); WriteLn;
| 81 : WriteString('Reserved'); WriteLn;
| 82 : WriteString('Cannot make directory entry'); WriteLn;
| 83 : WriteString('Fail on INT 24'); WriteLn;
| 84 : WriteString('Too many redirections'); WriteLn;
| 85 : WriteString('Duplicate redirection'); WriteLn;
| 86 : WriteString('Invalid password'); WriteLn;
| 87 : WriteString('Invalid paramater'); WriteLn;
| 88 : WriteString('Network device fault'); WriteLn;
ELSE
WriteString('Unknown error'); WriteLn;
END; (* CASE *)


CASE error OF
2 : f.res := unknownfile;
|
3 : f.res := unknownmedium;
|
4 : f.res := toomanyfiles;
|
5,32 : f.res := callerror; (* Access denied *)
ELSE
f.res := notdone;
END; (* CASE *)

END SetError;

PROCEDURE CriticalErrorISR;
BEGIN
CODE(081H,0E7H,0FFH,000H);
GETREG(DI,CriticalError);
CODE(PopBP);
CODE(PopAX,PopAX,PopAX);
CODE(PopAX,PopBX,PopCX,
PopDX,PopSI,PopDI,
PopBP,PopDS,PopES);
CODE(Iret);
END CriticalErrorISR;

PROCEDURE InitCritical;
BEGIN
CriticalErrorSave[1] := CriticalVector[1];
CriticalErrorSave[2] := CriticalVector[2];
END InitCritical;


PROCEDURE SetCritical;
BEGIN
CriticalErrorSave[1] := CriticalVector[1];
CriticalErrorSave[2] := CriticalVector[2];
CriticalErrorVector := CriticalErrorISR;
CriticalError := 256;
END SetCritical;

PROCEDURE RestoreCritical;
BEGIN
CriticalVector[1] := CriticalErrorSave[1];
CriticalVector[2] := CriticalErrorSave[2];
END RestoreCritical;


(* compiler restores were here *)


PROCEDURE Close ( f : File );
VAR
error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
SetCritical;
CODE(55H);
DOSCALL(3EH,f.handle,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.inuse := FALSE;
f.read := FALSE;
f.write := FALSE;
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
RestoreCritical;
ELSE (* file not set for reading *)
f.res := callerror;
END;
END Close;


PROCEDURE DosOpen (VAR f : File; fileName : ARRAY OF CHAR;
mode,shar : ARRAY OF CHAR);

VAR
fd : CHAR;
access, inher, sharMode, reserv : CARDINAL;
smode : WORD;
fpff : BYTE;
error : WORD;
filename : ARRAY [0..64] OF CHAR;

BEGIN
Strings.Copy(fileName,0,Strings.Length(fileName),filename);

(* copy fileName to filename. If no period '.' in filename then add one at end *)

IF (Strings.Pos('.',filename) > HIGH(filename)) THEN
Strings.Concat(filename,'.',filename);
END;

inher := 0; (* or 128 if bit on *)
reserv := 0; (* or 8 if bit on *)

IF
(Strings.Pos('I',mode) > HIGH(mode)) AND
(Strings.Pos('O',mode) > HIGH(mode)) AND
(Strings.Pos('R',mode) > HIGH(mode)) AND
(Strings.Pos('A',mode) > HIGH(mode))
THEN
f.res := paramerror;
RETURN;
END;


IF
(Strings.Pos('S',shar) > HIGH(shar)) AND
(Strings.Pos('I',shar) > HIGH(shar)) AND
(Strings.Pos('N',shar) > HIGH(shar))
THEN
f.res := paramerror;
RETURN;
END;


IF mode[0] = "I" THEN access := 0
ELSIF mode[0] = "O" THEN access := 1
ELSIF mode[0] = "A" THEN access := 1
ELSIF (mode[0] = "R") AND (Strings.Length(mode) = 1) THEN
access := 2
ELSIF (mode[0] = "R") AND (mode[1] = "I" ) THEN
access := 0
END; (* IF *)


IF shar[0] = "N" THEN sharMode := 0
ELSIF shar[0] = "S" THEN sharMode := 4;
ELSIF shar[0] = "I" THEN sharMode := 2;
ELSIF shar[0] = "O" THEN sharMode := 3;
ELSIF shar[0] = "X" THEN sharMode := 1;
END;


smode := WORD((inher * 128) + (sharMode * 16) + (reserv * 8) + access);

IF mode[0] = "O" THEN
SetCritical;

CODE(55H);
DOSCALL(3CH,ADR(filename),WORD(0),f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN
Strings.Copy(filename,0,Strings.Length(filename),f.name);
f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSE
SetError(f,err);
END

ELSIF mode[0] = "A" THEN
SetCritical;

CODE(55H);
DOSCALL(3DH,ADR(filename),smode,f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN
CODE(55H); (* position R/W head at EOF *)
DOSCALL(42H,f.handle,BYTE(2),WORD(0),WORD(1),f.pointHigh,f.pointLow,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN
Strings.Copy(filename,0,Strings.Length(filename),f.name);
f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSE
f.res := notdone;
END (* IF err = 0 - inner *)
ELSE
SetError(f,err);
END (* IF err = 0 - outer *)

ELSIF ((mode[0] = "R") AND (Strings.Length(mode) = 1)) THEN
SetCritical;

CODE(55H); (* Standard open for existing file *)
DOSCALL(3DH,ADR(filename),smode,f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN
Strings.Copy(filename,0,Strings.Length(filename),f.name);

f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSIF (err = 2) THEN (* File Not Found *)
CODE(55H); (* Create it if not input *)
DOSCALL(3CH,ADR(filename),WORD(0),f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN (* level 3 - create *)
CriticalError := 256;
CODE(55H); (* Close it *)
DOSCALL(3EH,f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN (* level 2 - close created *)
CriticalError := 256;
CODE(55H); (* Standard open for existing file *)
DOSCALL(3DH,ADR(filename),smode,f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN (* level 1 - original intention *)
Strings.Copy(filename,0,Strings.Length(filename),f.name);
f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSE
SetError(f,err);
END; (* if err = 0 - level 1 *)
END; (* if err = 0 - level 2 *)
END; (* if err = 0 - level 3 *)
ELSE (* errors at original open other than 2 , i.e. 5, access denied *)
SetError(f,err);
END (* ELSIF *)

ELSIF (((mode[0] = "R") AND (mode[1] = "I")) OR (mode[0] = "I")) THEN
SetCritical;
CODE(55H); (* Standard open for existing file *)
DOSCALL(3DH,ADR(filename),smode,f.handle,error);
CODE(5DH);

err := CriticalError;
IF err = 256 THEN
err := 0
END;

IF err = 0 THEN
Strings.Copy(filename,0,Strings.Length(filename),f.name);
f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSE
WriteString('Error for Open at RI was not zero'); WriteLn;
SetError(f,err);
END; (* IF err *)

END; (* IF/ELSIF *)
END DosOpen;


PROCEDURE Lookup (VAR f : File; fileName : ARRAY OF CHAR;
mode,shar : ARRAY OF CHAR);

VAR
Waiting : BOOLEAN;
errcnt : CARDINAL;
F : File;
BEGIN
F := f;
F.res := notdone;
Waiting := TRUE;
errcnt := 0;
WHILE Waiting DO
DosOpen(F,fileName,mode,shar);
IF F.res = callerror THEN
INC(errcnt);
Delay(1000); (* wait 1000 milliseconds = 1 second *)
IF errcnt > 3 THEN
WriteString('Critical error - Cannot open - '); WriteString(fileName);
WriteLn;
Waiting := FALSE;
END;
ELSE
f := F;
Waiting := FALSE;
END;
END; (* while *)
END Lookup;

(*$S=*) (*$R=*) (*$T=*)


PROCEDURE Rename ( VAR f: File; newname : ARRAY OF CHAR );
VAR
error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
SetCritical;
CODE(55H);
DOSCALL(56H,ADR(f.name),ADR(newname),error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
Strings.Copy(newname,0,Strings.Length(newname),f.name);
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not open *)
f.res := callerror;
END; (* if not *)
END Rename;


PROCEDURE Delete ( name : ARRAY OF CHAR; VAR f : File );
VAR
error : WORD;
err : CARDINAL;
BEGIN
WriteLn; WriteString(name); WriteLn;
SetCritical;
CODE(55H);
DOSCALL(41H,ADR(name),error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
END Delete;


PROCEDURE WriteChar( VAR f: File; VAR ch : CHAR);
VAR
written,error : WORD;
err : CARDINAL;
BEGIN
IF f.write THEN
SetCritical;
CODE(55H);
DOSCALL(40H,f.handle,WORD(1),ADR(ch),written,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not set for writing *)
f.res := callerror;
END;
END WriteChar;


PROCEDURE ReadChar( VAR f: File; VAR ch : CHAR);
VAR
error : WORD;
readBytes : BYTE;
err : CARDINAL;
BEGIN
IF f.read THEN
SetCritical;
CODE(55H);
DOSCALL(3FH,f.handle,WORD(1),ADR(ch),readBytes,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
ch := CHAR(readBytes);
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not set for reading *)
f.res := callerror;
END;
END ReadChar;


PROCEDURE ReadNBytes( VAR f: File; bufPtr : ADDRESS;
requestedBytes : CARDINAL;
VAR read : CARDINAL );

VAR
nrbytes,error,readbytes : WORD;
err : CARDINAL;
BEGIN
IF f.read THEN
SetCritical;
CODE(55H);
DOSCALL(3FH,f.handle,WORD(requestedBytes),bufPtr,readbytes,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
read := CARDINAL(readbytes);
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not set for reading *)
read := 0;
f.res := callerror;
END;
END ReadNBytes;



PROCEDURE WriteNBytes( VAR f: File; bufPtr : ADDRESS;
requestedBytes : CARDINAL;
VAR written : CARDINAL );

VAR
writtenbytes,error : WORD;
err : CARDINAL;
BEGIN
IF f.write THEN
SetCritical;
CODE(55H);
DOSCALL(40H,f.handle,WORD(requestedBytes),bufPtr,writtenbytes,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
written := CARDINAL(writtenbytes);
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not set for writing *)
written := 0;
f.res := callerror;
END;
END WriteNBytes;


PROCEDURE SetRead ( VAR f: File );
BEGIN
IF f.inuse THEN
f.read := TRUE;
f.write := FALSE;
f.res := done;
ELSE (* file not opened *)
f.res := callerror;
END;
END SetRead;


PROCEDURE SetWrite ( VAR f: File );
BEGIN
IF f.inuse THEN
f.read := FALSE;
f.write := TRUE;
f.res := done;
ELSE (* file not opened *)
f.res := callerror;
END;
END SetWrite;


PROCEDURE SetModify ( VAR f: File );
BEGIN
IF f.inuse THEN
f.read := TRUE;
f.write := TRUE;
f.res := done;
ELSE
f.res := callerror;
END;
END SetModify;


PROCEDURE Reset ( VAR f: File);
VAR
outHigh,outLow,error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
SetCritical;
CODE(55H);
DOSCALL(42H,f.handle,BYTE(0),WORD(0),WORD(0),outHigh,outLow,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not open *)
f.res := callerror;
END;
END Reset;


PROCEDURE SetOpen ( VAR f: File);
VAR
outHigh,outLow,error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
f.pointHigh := 0;
f.pointLow := 0;
f.read := FALSE; (* must be set with SetRead *)
f.write := FALSE; (* must be set with SetWrite *)
f.inuse := TRUE;
f.eof := FALSE;
f.res := done;
ELSE (* file not open *)
f.res := callerror;
END;
END SetOpen;


PROCEDURE SetPos( VAR f: File; high,low: CARDINAL);
VAR
outHigh,outLow,error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
SetCritical;
CODE(55H);
DOSCALL(42H,f.handle,BYTE(0),WORD(high),WORD(low),outHigh,outLow,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.pointHigh := high;
f.pointLow := low;
f.res := done;
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not open *)
f.res := callerror;
END;
END SetPos;


PROCEDURE GetPos( VAR f: File; VAR high,low: CARDINAL);
VAR
outHigh,outLow,error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
SetCritical;
CODE(55H); (* move from the current position 0 bytes *)
DOSCALL(42H,f.handle,BYTE(1),WORD(0),WORD(0),outHigh,outLow,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.pointHigh := CARDINAL(outHigh);
f.pointLow := CARDINAL(outLow);
f.res := done;
high := CARDINAL(outHigh);
low := CARDINAL(outLow);
ELSE (* error in operation *)
SetError(f,err);
END;
ELSE (* file not open *)
f.res := callerror;
END;
END GetPos;


PROCEDURE Length( VAR f: File; VAR high,low: CARDINAL);
VAR
outHigh,outLow,error : WORD;
err : CARDINAL;
BEGIN
IF f.inuse THEN
GetPos(f,high,low);
IF f.res = done THEN
f.pointHigh := high;
f.pointLow := low;
SetCritical;
CODE(55H); (* position at EOF *)
DOSCALL(42H,f.handle,BYTE(2),WORD(0),WORD(0),high,low,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
SetCritical;
CODE(55H); (* restore original position *)
DOSCALL(42H,f.handle,BYTE(0),f.pointHigh,f.pointLow,outHigh,outLow,error);
CODE(5DH);

err := CARDINAL(error);
IF err = 0 THEN
IF CriticalError = 256 THEN
err := 0;
ELSE
err := CriticalError;
END;
END;

IF err = 0 THEN
f.res := done;
ELSE
SetError(f,err);
END
ELSE
SetError(f,err);
END; (* if err = 0 *)
ELSE (* if f.res = done *)
WriteString('Unexpected error on Length/Getpos'); WriteLn; HALT;
END;
ELSE (* file not opened *)
f.res := callerror;
END; (* IF f.inuse *)
END Length;

END Network.


  3 Responses to “Category : Modula II Source Code
Archive   : MODULA-2.ZIP
Filename : NETWORK.MOD

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/