{**********************************************} { } { UCSD PASCAL FILEHANDLER } { } { RELEASE LEVEL: F.5 SEPTEMBER, 1978 } { } { } { WRITTEN BY ROGER T. SUMNER } { WINTER, 1977 } { MODIFIED AND UPDATED BY STEVEN S THOMSON } { SEPTEMBER, 1978 } { } { INSTITUTE FOR INFORMATION SYSTEMS } { UC SAN DIEGO, LA JOLLA, CA } { } { KENNETH L. BOWLES, DIRECTOR } { } { } {**********************************************} { Copyright (C) 1978 Regents of the University of California. } { Permission to copy or distribute this software or documen- } { tation in hard or soft copy granted only by written license } { obtained from the Institute for Information Systems. } SEGMENT PROCEDURE FILEHANDLER(ZZZZZ,ZZZZZZ : INTEGER CONST SHSTRLENG = 25; MAXTITLE = 40; TYPE ERRANGE = 0..100; { Range of error messages } ERRORS = SET OF ERRANGE; { Set of error message numbers. Used in scaninput } CHECKS = (BADTITLE, NOVOL, BADDIR, BADFILE, UNBLKDVOL, OKDIR, OKFILE); { Possible states of a file or volume name } CHCKS = SET OF CHECKS; { Set of states that a file can be in. } { Used in scaninput } LONGSTRING = STRING[255]; { Longest string available } SHORTSTRING = STRING[SHSTRLENG]; { For handling volume & file names } STRNG = STRING[MAXTITLE]; { For handling concatted volume & filenames } VAR GS : STRING; { General purpose string. Used primarily for prompt lines } CH : CHAR; { General purpose character } GDIR : DIRP; { Global pointer to the directory } GINX : DIRRANGE; { 0..77 } GKIND : FILEKIND; { UNTYPEDFILE, XDSKFILE, CODEFILE, TEXTFILE } { INFOFILE,DATAFILE, GRAFFILE, FOTOFILE } SAVEUNIT, GUNIT : UNITNUM; { 0..12 } GBUF: WINDOWP; { Pointer to buffer window } FOUND, QUESTION, WILDCARD, { For wildcard information only! } OK, DONE, { General purpose booleans } BADCOMMAND, { Check for incorrect input to general prompt line } SYMSAVED, CODESAVED : BOOLEAN; { Workfile information } VOLNAME1, VOLNAME2, { Volume names for source and dest. respectively } SAVEGVID, SAVEVID, { Used in searchdir and savework to save VID's } GVID, { General purpose VID } GVID2 : VID; { Unmodified VID. Used in savework } GBUFBLKS, { Keeps track of number of blocks available in buffer } X, I : INTEGER; { General purpose integers } STRING1, STRING2, { Wildcard scan strings source file } STRING3, STRING4, { Wildcard replacement strings destination } NEWSTRING, { String left after removing scan strings from filename } SAVEGTID, { Used in savework to save GTID } GTID : TID; { General purpose TID } FROMWHERE, TOWHERE : STRNG; { Source $ destination strings respectively } FILENAM1, FILENAM2 : SHORTSTRING; { Source & dest. filenames respectively. } { None wildcard only } INSTRING : LONGSTRING; { For input off of main prompt line } GFIB : FIB; { General purpose FIB } MONTHS : ARRAY [0..15] OF STRING[3]; { Holds abbreviations for valid months } PROCEDURE FILERINIT; TYPE ABLOCK = PACKED ARRAY [1..FBLKSIZE] OF CHAR; VAR ONEBLOCK: ^ABLOCK; BEGIN { FILERINIT } { Initializes the months } MONTHS[ 0] := '???'; MONTHS[ 1] := 'Jan'; MONTHS[ 2] := 'Feb'; MONTHS[ 3] := 'Mar'; MONTHS[ 4] := 'Apr'; MONTHS[ 5] := 'May'; MONTHS[ 6] := 'Jun'; MONTHS[ 7] := 'Jul'; MONTHS[ 8] := 'Aug'; MONTHS[ 9] := 'Sep'; MONTHS[10] := 'Oct'; MONTHS[11] := 'Nov'; MONTHS[12] := 'Dec'; MONTHS[13] := '???'; MONTHS[14] := '???'; MONTHS[15] := '???'; { If an updated file exists in the workfile and it hasn't been saved } { yet, then set symsaved and codesaved to false if their respective files } { have not been saved. Otherwise, set symsaved and codesaved to false } WITH USERINFO DO BEGIN IF GOTSYM THEN SYMSAVED := SYMTID <> 'SYSTEM.WRK.TEXT' ELSE SYMSAVED := TRUE; IF GOTCODE THEN CODESAVED := CODETID <> 'SYSTEM.WRK.CODE' ELSE CODESAVED := TRUE END; FINIT(GFIB,NIL,-1); MARK(GBUF); { Set GBUFBLKS equal to the number of blocks available in the buffer } GBUFBLKS := 0; I := SIZEOF(DIRECTORY)+SIZEOF(FIB)+2048; { QUITSIZE } REPEAT NEW(ONEBLOCK); GBUFBLKS := GBUFBLKS+1; X := ORD(SYSCOM^.LASTMP)-ORD(ONEBLOCK)-FBLKSIZE { GAPSIZE } UNTIL ((X > 0) AND (X < I)) OR (GBUFBLKS = 63) {PREVENT INTEGER OFLOW} END {FILERINIT} ; PROCEDURE CLEAR; BEGIN { CLEAR } GVID := ''; GVID2 := ''; GTID := ''; STRING1 := ''; STRING2 := ''; STRING3 := ''; STRING4 := ''; { Used to clear selected global strings & booleans } VOLNAME1 := ''; { between commands in the outer block of the filer } VOLNAME2 := ''; { and under error conditions } FILENAM1 := ''; FILENAM2 := ''; TOWHERE := ''; FROMWHERE := ''; WILDCARD := FALSE; QUESTION := FALSE; END { CLEAR }; PROCEDURE CLWRITELN(STR : STRING); { Commonly used format for output } BEGIN { CLWRITELNO } WRITE(OUTPUT,STR); CLEARLINE; WRITELN(OUTPUT) END { CLWRITELNO }; PROCEDURE MESSAGES(NUMBER : ERRANGE); PROCEDURE FILERERRORS; BEGIN { FILERERRORS } CASE NUMBER OF 1: GS := 'Parity (CRC) error'; { IBADBLOCK } 2: GS := 'Bad unit number'; { IBADUNIT } 3: GS := 'Bad IO operation'; { IBADMODE } 4: GS := 'Timeout error'; { ITIMEOUT } 5: GS := 'Vol went off-line'; { ILOSTUNIT } 6: GS := 'File lost in dir'; { ILOSTFILE } { I/O error messages } 7: GS := 'Bad file name'; { IBADTITLE } 8: GS := 'No room on vol'; { INOROOM } 9: GS := 'No such vol on-line'; { INOUNIT } 10: GS := 'File not found'; { INOFILE } 11: GS := 'Dup dir entry'; { IDUPFILE } 12: GS := 'Filer error!!' { INOTCLOSED } END END; { FILERERRORS } PROCEDURE EXPECTED; BEGIN { EXPECTED } { Messages giving information as to the type } { of file that was expected on input } CASE NUMBER OF 79,80 : GS := 'Blkd volume'; 78,81 : GS := 'Unblkd volume'; 82,83,84 : BEGIN IF NUMBER <> 82 THEN BEGIN GS := ' or '; IF NUMBER = 83 THEN GS := CONCAT(GS,'un'); GS := CONCAT(GS,'blkd vol') END; GS := CONCAT('File name',GS) END; 85 : GS := 'File or vol name'; 86 : GS := 'Volume name' END; IF NOT (NUMBER IN [78,79]) THEN GS := CONCAT(GS,' expected') END; { EXPECTED } BEGIN { MESSAGES } { General messages & error messages } GS := ''; IF NUMBER <> 0 THEN CASE NUMBER OF 1,2,3,4,5,6,7,8,9,10,11,12 : FILERERRORS; 40 : GS := 'Wildcard not allowed'; 41,42 : BEGIN IF NUMBER = 42 THEN GS := 'not '; GS := CONCAT('First vol/file name was ',GS,'a wildcard') END; 50,51 : BEGIN GS := 'file loaded'; IF NUMBER = 51 THEN GS := CONCAT('No ',GS) END; 52,53,54 : BEGIN CASE NUMBER OF 52 : GS := 'file'; 53,54 : GS := 'volume' END; GS := CONCAT('Illegal ',GS,' name'); IF NUMBER <> 54 THEN GS := CONCAT(GS,' ') END; 60,61 : BEGIN CASE NUMBER OF 60 : GS := 'Vol to file name'; 61 : GS := 'File to vol name' END; GS := CONCAT('Illegal change <',GS,'>') END; 64 : GS := ' file name '; 65 : GS := ' scan string '; 66 : GS := ' volume name '; 67 : GS := '- Illegal format'; 68 : GS := ' - char. max >'; 69 : GS := 'No directory on volume'; 70 : GS := 'File found'; 72 : GS := 'Volume already on line'; 73 : GS := 'Output file full'; 75 : GS := 'Workfile already saved'; 76 : GS := 'No workfile to save'; 78,79,80,81,82,83,84,85,86 : EXPECTED; 90,91 : BEGIN IF NUMBER = 90 THEN GS := 'Text' ELSE GS := 'Code'; GS := CONCAT(GS,' file lost ') END; 100 : CLWRITELN( 'Dangerous! Suggest using ? on wildcards to same vol') END; WRITE(OUTPUT,GS); CLEARLINE END; { MESSAGES } FUNCTION CHECKRSLT(RSLT : ERRANGE) : BOOLEAN; { Returns as true if the result of the I/O operation passed to it was } { equal to zero. Otherwise, prints error message and returns as false } BEGIN CHECKRSLT := RSLT = 0; IF RSLT <> 0 THEN MESSAGES(RSLT) END; PROCEDURE TOUPPER(VAR STRG : LONGSTRING; START,STOP : INTEGER); VAR I : INTEGER; { Changes STRG [START] through STRG [STOP] into uppercase letters } BEGIN { TOUPPER } FOR I := START TO STOP DO IF ( STRG[I] >= 'a' ) AND ( STRG[I] <= 'z' ) THEN STRG[I] := CHR( ORD( STRG[I] ) - ORD( 'a' ) + ORD ('A' )) END { TOUPPER }; PROCEDURE EATSPACES(VAR STRG : LONGSTRING); VAR I : INTEGER; { Removes unprintable characters & blanks from STRG } BEGIN {EATSPACES} I := 1; WHILE I <= LENGTH(STRG) DO IF STRG[I] > ' ' THEN I := I + 1 ELSE DELETE(STRG,I,1) END {EATSPACES} ; FUNCTION NGETCHAR(TEMP : BOOLEAN) : CHAR; { Very frequent structure for calling getchar } BEGIN CLEARLINE; NGETCHAR := GETCHAR(TEMP); IF NOT EOLN(INPUT) THEN WRITELN(OUTPUT); END;