PROC FSEFILE;
BEGIN
#
*** FSEFILE -- SUBROUTINES FOR FILE ACCESS.
*
* COPYRIGHT CONTROL DATA SYSTEMS INC. 1992.
*
* FSEFILE HAS THE ROUTINES TO TEST THE ATTRIBUTES OF
* VARIOUS LOCAL FILES. THIS IS THEREFORE USED ONLY FOR
* THE SINGLE-USER VERSION OF FSE AND IS NOT PROGRAMMED
* REENTRANTLY. THIS MODULE IS A CANDIDATE FOR FUTURE
* OVERLAY STRUCTURING. IT MAY BE USED BY THE FSEMAIN MODULE
* AND THE FILCMD MODULE ONLY.
#
DEF LISTCON #0#;
CONTROL EJECT; # UNIVERSAL DECLARES #
*IFCALL SINGLE,COMFSGL
*IFCALL ONLY,COMFONL
*IFCALL MULTI,COMFMLT
*CALL COMFFSE
# EXTERNALS #
XDEF
BEGIN
*CALL COMFXFL
END
XREF ARRAY MAXADDR;; # KEY ADDRESSES IN BUFFER SEGMENT #
XREF ARRAY WORKBUF;;
XREF PROC FASTRLC;
XREF
BEGIN
PROC PF;
PROC FILINFO;
PROC READ;
PROC READC;
PROC REWIND;
PROC FLDLEN;
PROC RTIME;
PROC TTLIN;
PROC TTSTR;
PROC VDTCLO;
PROC VDTOPN;
PROC VDTPRT$; # PROMPT ON/OFF #
END
XREF
BEGIN
*CALL COMFXSB
*CALL COMFXSC
*CALL COMFXED
*CALL COMFXWK
END
# COMMON DATA #
*CALL COMFDS1
*CALL COMFVD2
*CALL COMFDS2
*CALL COMSPFM
PAGE # HERE WE GO #
FUNC MSEQUIP(NAME) B;
BEGIN
#
** MSEQUIP - TEST FILE ATTRIBUTES FOR MASS STORAGE.
*
* ENTRY NAME - NAME OF FILE TO INSPECT.
*
* EXIT MSEQUIP - TRUE IF ALREADY ON MASS STORAGE OR IF
* ANTICIPATED TO BE ON MASS STORAGE BY DEFAULT.
* OTHERWISE FALSE.
*
* CALLS GETINFO, TRIMNAME.
*
* NOTE ASSUMES CORRECT DEFINITION OF DEFAULT NAMES
* FOR INPUT AND OUTPUT FILES.
#
ITEM NAME C(7);
FILINFSTAT = 0;
IF B<0,42>NAME EQ 0 THEN
BEGIN
MSEQUIP=FALSE;
RETURN;
END
MSEQUIP=TRUE;
GETINFO(NAME);
IF FILINFSTAT EQ 0 THEN
BEGIN
IF TRIMNAME(NAME) EQ DEFINPNAM THEN MSEQUIP=FALSE;
IF TRIMNAME(NAME) EQ DEFOUTNAM THEN MSEQUIP=FALSE;
END
ELSE
BEGIN
IF NOT (FILINFRMS AND FILINFREAD) THEN MSEQUIP=FALSE;
END
END # OF MSEQUIP #
FUNC TTEQUIP(NAME) B;
BEGIN
#
** TTEQUIP - TEST FILE ATTRIBUTES FOR TERMINAL.
*
* ENTRY NAME - FILE TO TEST.
*
* EXIT TTEQUIP - TRUE IF FILE ALREADY ASSIGNED TO TERMINAL
* EQUIPMENT, OR IF ANTICIPATED TO BE SO ASSIGNED
* BY DEFAULT. OTHERWISE FALSE.
*
* CALLS GETINFO, TRIMNAME.
*
* NOTE ASSUMES CORRECT DEFINITION OF DEFAULT NAMES FOR
* INPUT AND OUTPUT FILES.
#
ITEM NAME C(7);
TTEQUIP=FALSE;
IF B<0,42>NAME EQ 0 THEN RETURN;
GETINFO(NAME);
IF FILINFSTAT EQ 0 THEN # NOT EXIST #
BEGIN
IF TRIMNAME(NAME) EQ DEFINPNAM THEN TTEQUIP=TRUE;
IF TRIMNAME(NAME) EQ DEFOUTNAM THEN TTEQUIP=TRUE;
END
ELSE # FILE ALREADY EXIST #
BEGIN
IF FILINFTTY THEN TTEQUIP=TRUE;
END
END # OF TTEQUIP #
FUNC WRITEABLE(NAME) B;
BEGIN
#
** WRITEABLE - TEST FILE FOR NON-READ-ONLY DISK.
*
* ENTRY NAME - FILE TO INSPECT.
*
* EXIT - WRITEABLE - TRUE IF AND ONLY IF FILE IS ON
* MASS STORAGE AND HAS NO ACCESS RESTRICTIONS.
*
* CALLS MSEQUIP.
*
* NOTE CODING ASSUMES GETINFO WILL BE CALLED FOR THIS
* FILE NO LATER THAN COMPLETION OF MSEQUIP.
#
ITEM NAME C(7);
WRITEABLE=FALSE;
IF MSEQUIP(NAME) THEN
BEGIN
WRITEABLE=FILINFWRIT;
IF FILINFSTAT EQ 0 THEN WRITEABLE=TRUE;
END
END # OF WRITEABLE #
FUNC LOCALFILE(NAME) B;
BEGIN
#
** LOCALFILE - TEST FILE ATTRIBUTES FOR LOFT.
*
* ENTRY NAME - FILE TO INSPECT.
*
* EXIT LOCALFILE - TRUE IF AND ONLY IF FILE IS ON
* MASS STORAGE, HAS WRITE PERMISSION, AND IS OF
* LOCAL FILE TYPE.
*
* CALLS WRITEABLE.
*
* NOTE ASSUMES GETINFO IS CALLED BY WRITEABLE.
#
ITEM NAME C(7);
LOCALFILE=FALSE;
IF WRITEABLE(NAME) THEN
BEGIN
IF FILINFFT EQ 0
OR FILINFFT EQ 6 THEN LOCALFILE=TRUE;
END
END # OF LOCALFILE #
PROC GETINFO(NAME);
BEGIN
#
** GETINFO - INTERFACE TO FILINFO MACRO.
*
* ENTRY NAME - FILE TO PROCESS.
*
* EXIT FILINFPARMS ARRAY IS FILLED IN.
*
* CALLS TRIMNAME, FILINFO.
#
ITEM NAME C(7), NEWNAME C(7);
NEWNAME=TRIMNAME(NAME);
FILINFNAME=NEWNAME;
FILINFO(FILINFPARMS);
END # OF GETINFO #
FUNC ASSGNFILE(NAME) B;
BEGIN
#
** ASSGNFILE - TEST FILE FOR FNT ASSIGNMENT.
*
* ENTRY NAME - FILE TO INSPECT.
*
* EXIT ASSGNFILE - TRUE IF AND ONLY IF THIS JOB HAS
* AN FNT FOR THE FILE.
*
* CALLS GETINFO.
#
ITEM NAME C(7);
ASSGNFILE=FALSE;
IF B<0,42>NAME EQ 0 THEN RETURN;
GETINFO(NAME);
IF FILINFSTAT NQ 0 THEN ASSGNFILE=TRUE;
END # OF ASSGNFILE #
PROC VFYFILE(NAME,MODE);
BEGIN
#
** VFYFILE - VERIFY FILE AS LEGAL TO BE EDITED.
*
* ENTRY NAME - FILE TO INSPECT.
* MODE - POSITIVE IMPLIES USE ERRJUMP FOR FAILURES,
* NEGATIVE IMPLIES ABORT THE JOB STEP VIA MORTAL.
*
* EXIT TO CALLER IF FILE IS LEGAL, OTHERWISE TO
* SPECIFIED ERROR ROUTINE WITHOUT RETURN.
*
* CALLS ERRJUMP, MORTAL, ERROR(INTERNAL), COMPARE(INTERNAL).
#
ITEM NAME C(7), MODE I;
PROC ERROR(STR);
BEGIN
ITEM STR C(40);
IF MODE GQ 0 THEN ERRJUMP(STR);
MORTAL(STR);
END
PROC COMPARE(PARM);
BEGIN
ITEM PARM C(7), NAME1 C(7), NAME2 C(7);
NAME1=TRIMNAME(NAME);
NAME2=TRIMNAME(PARM);
IF NAME1 EQ NAME2 THEN ERROR("RESERVED FILE$");
END
COMPARE(INPTNAM);
COMPARE(OUTPNAM);
COMPARE(WORKNAM);
COMPARE("ZZZMOVE");
IF NOT MSEQUIP(NAME) THEN
BEGIN
IF FILINFSTAT NQ 0 AND FILINFRMS THEN
BEGIN # IF FILE HAS NO READ PERMISSION #
ERROR("FILE DOES NOT HAVE READ PERMISSION$");
END
ELSE
BEGIN # IF FILE IS NOT ON DISK #
ERROR("FILE MUST BE ON DISK$");
END
END
END # OF VFYFILE #
PAGE # FILE READ SUBROUTINE #
PROC FILEREAD;
BEGIN
#
** FILEREAD - READ A LOCAL FILE INTO FILE IMAGE BRACKET.
*
* NOTE THAT TO SAVE THE CPU OVERHEAD OF RELOCATING THE
* POINTER STACKS FOR EVERY INSERTION, WE CALL WORKIO
* DIRECTLY, THEN WE CALL RELOCATE TO CORRECT FOR BYPASSING
* THE "INSY" INTERFACE.
*
* NOTE THAT THE "USRBRK" FLAG IS CONTINUALLY CHECKED
* TO DETECT AN EXTERNAL INTERRUPT.
*
* ENTRY FILNUM - WHICH BRACKET.
* FILEFET - ALREADY INITIALIZED.
* ASCII[FILNUM] - CHARACTER SET.
*
* EXIT NUMBERED[FILNUM] - WHETHER FILE REALLY NUMBERED.
* FILEFET - AT EOI, OR INDETERINATE IF USER BREAK.
*
* CALLS READ, READC, CONVIN, GETLNUM, TRIMPAD, INS, FASTRLC.
*
* USES WIDTHFOUND.
#
DEF AVERAGE #500#; # AVERAGE FILE SIZE #
DEF TWOANAHALF #2500#; # TWO AND A HALF SECONDS #
ITEM LOOPCTL, RESULT, LASTNUM, ASCIITYPE, MAXL, RECYCLE, FIRSTPOS;
ITEM ZERO=0;
ITEM COUNTER I; # LINE COUNTER #
ITEM SAMPLE I; # LINE SAMPLE RATE #
ITEM STARTTIME I; # REAL TIME CLOCK (START) #
ITEM CHECKTIME I; # REAL TIME CLOCK (CHECK) #
IF SCREENMODE OR DONTPRINT OR NOT INTERACT
OR READNAM EQ "FSEPROC" THEN
BEGIN # IF NO MESSAGE SHOULD BE SENT #
COUNTER = 0;
END
ELSE
BEGIN # MESSAGE MAY BE SENT #
COUNTER = 1;
SAMPLE = AVERAGE;
RTIME(STARTTIME);
STARTTIME = B<24,36>STARTTIME;
END
REWIND(FILEFET,1);
READ(FILEFET,0);
FIRSTPOS=CURRENT;
RESULT=0;
MAXL=0;
RECYCLE=0;
LASTNUM=0;
FOR LOOPCTL=LOOPCTL WHILE RESULT EQ 0 AND USRBRK EQ 0 DO
BEGIN
ASCIITYPE=ASCII[FILNUM]; # CHARACTER SET FOR FILE #
LINE[0]=0;
READC(FILEFET,TMPLIN,BUFWID2P1,RESULT);
IF COUNTER NQ 0 THEN
BEGIN # IF MESSAGE STILL TO ISSUE #
COUNTER = COUNTER + 1;
IF COUNTER GR SAMPLE THEN
BEGIN # IF SAMPLE SIZE REACHED #
RTIME(CHECKTIME);
CHECKTIME = B<24,36>CHECKTIME - STARTTIME;
IF CHECKTIME GR TWOANAHALF THEN
BEGIN # IF ENOUGH TIME HAS PASSED #
TTSTR("BUILDING: $");
TTLFN(READNAM);
TTLIN(" ONE MOMENT PLEASE$");
COUNTER = 0; # ONE MESSAGE IS ENOUGH #
VDTCLO(COUNTER); # FLUSH OUTPUT,NO RECALL #
END
ELSE
BEGIN # COMPUTE PROBABLE SAMPLE COUNT #
SAMPLE = (SAMPLE*TWOANAHALF)/CHECKTIME;
END
END
END
IF RESULT GR 0 THEN
BEGIN
ASCIITYPE=1; # CHARACTER SET FOR EORCON #
TMPLINE[0]=EORCON;
FILECODE=1;
READ(FILEFET,1);
IF FILECODE EQ O"31" THEN RESULT=-1;
ELSE IF FILECODE NQ O"1031" OR FILEIN NQ FILEOUT THEN
BEGIN
RESULT=0;
END
END
IF RESULT EQ -1 THEN
BEGIN
ASCIITYPE=1; # CHARACTER SET FOR EOFCON #
RESULT=0;
TMPLINE[0]=EOFCON;
FILECODE=1;
READ(FILEFET,0);
END
IF RESULT EQ 0 THEN # PREPARE LINE OF TEXT #
BEGIN
MAXL=MAXL+1; # COUNT RELOCATION FACTOR #
CONVIN(LIN,ASCIITYPE);
IF NUMBERED[FILNUM] NQ 0 THEN # VERIFY/ADJUST SEQUENCE NUMBERS #
BEGIN
GETLNUM;
IF LINENO LQ LASTNUM THEN # FILE IS NOT REALLY SEQUENCED #
BEGIN
NUMBERED[FILNUM]=0;
CHANGED[FILNUM]=0; # TAKE BACK FLAG FOR ADJUSTMENTS #
IF MAXL GR 1 THEN
BEGIN
REWIND(FILEFET,1);
READ(FILEFET,0);
POSZ(FIRSTPOS);
RECYCLE=MAXL-1;
MAXL=0;
TEST LOOPCTL;
END
END
ELSE # ADJUST SEQUENCING DIGITS #
BEGIN
IF WIDTHFOUND EQ NUMWIDTH THEN
BEGIN # FIX INTERVENING BLANK #
GETCHAR(LINE,NUMWIDTH,LINCTR);
IF BLANKS NQ 0 AND LINCTR NQ CBLANK THEN
BEGIN
RSHIFT(LIN,NUMWIDTH,1);
SETCHAR(LINE,NUMWIDTH,CBLANK);
CHANGED[FILNUM]=1; # FLAG THAT WE ADJUSTED TEXT #
END
END
IF WIDTHFOUND GR 0 AND WIDTHFOUND LS NUMWIDTH
AND NUMMODE EQ NUMST"PREFER" THEN
BEGIN # ADJUST DIGITS #
CHANGED[FILNUM]=1; # FLAG THAT WE ADJUSTED TEXT #
SETLNUM;
GETLNUM;
END
END
END
LASTNUM=LINENO;
TRIMPAD;
IF RECYCLE NQ 0 THEN
BEGIN
ZERO = = P<LINEBUF>; # POSITION INVISIBLY #
FWDZ; # POSITION INVISIBLY #
ZERO = = P<LINEBUF>; # POSITION INVISIBLY #
REP;
RECYCLE=RECYCLE-1;
END
ELSE INS;
END
END
FASTRLC(REGSTACK,MAXREG+1,CURRENT-MAXL+1,MAXL);
END # OF FILEREAD #
PAGE # ADDFILE CONTROLS FILEBUILD #
PROC ADDFILE;
BEGIN
#
** ADDFILE - ADD AN EXTERNAL FILE TO INTERNAL FILES.
*
* ENTRY FILNUM - WHICH BRACKET.
* READNAM - FILE NAME.
* CHARPARM - CHARACTER SET PREFERENCE OR DEFAULT.
* GETPARM - PERMANENT/LOCAL PREFERENCE OR DEFAULT.
* ALLASCII - DEFAULT CHARACTER SET.
* SMALLFIELD - WHETHER FIELD LENGTH NOW SMALL OR LARGE.
* BOTC(FILECTL) - BRACKETS FILE DIRECTORY AREA.
* TOPA(AUDITCTL) - BRACKETS AUDIT TRAIL.
* NUMMMODE - WHAT TO DO WITH EMPTY FILE.
* SCNFDINIT - 1 IF FILE IS INITIAL EDIT FILE,
* 0 OTHERWISE.
*
* EXIT GETPARM - INDICATES WHETHER GET REALLY DONE.
* LOCKED[FILNUM] - SET BY FILE ATTRIBUTES.
* ASCII[FILNUM] - SET BY PARAMETER.
* CHANGED[FILUM] - FALSE.
* NUMBERED[FILNUM] - SET BY NUMMODE AND FILE CONTENT.
* BOTC, TOPA - RELOCATED, ALSO VARIOUS OTHERS.
* CURRENT, CURF(FILNUM) - TOP OF FILE.
* FDLF(FILNUM) - UPDATED.
* TOPF(FILNUM), BOTF(FILNUM) - BRACKET THE FILE.
*
* USES FILEFET, DSKSIZ, UTILFET.
*
* CALLS VFYFILE, FLDLEN, PAUSEIO, TRIMNAME, ASSGNFILE,
* MAKEFET, GET, WRITEABLE, POSZ, FORMFDL, INSY,
* FILEREAD, REWIND.
#
ITEM NEWNAME C(7);
VFYFILE(READNAM,0);
IF SMALLFIELD THEN
BEGIN
FLDLEN(LOC(MAXADDR)+4);
PAUSEIO; # DRAIN BUFFERS SO WE CAN ... #
DSKSIZ=INIDSKSIZ; # ... ENLARGE BUFFERS #
END
NEWNAME=TRIMNAME(READNAM);
IF GETPARM EQ 1 AND NOT ASSGNFILE(READNAM) THEN GETPARM=2;
IF GETPARM EQ 2 THEN
BEGIN
PF("GET",READNAM,READNAM,"RC",PFMERROR,"EM",PFMMSG,"EL","40",0);
IF PFMERROR EQ 0 THEN
BEGIN # IF POSSIBLE CALL TO *CPUPFM* #
IF SCREENMODE AND TABTYPHEAD[0] THEN
BEGIN # IF RUNNING WITH TYPE AHEAD #
VDTPRT$(0); # ASSURE PROMPT IS OFF #
END
END
IF PFMERROR EQ FNF THEN
BEGIN
PF("ATTACH",READNAM,READNAM,"RC",PFMERROR,"M","W","NA","YES",
"SR","NF","EM",PFMMSG,"EL","40",0);
END
IF PFMERROR NQ 0 THEN
BEGIN
C<0,18>ERRSTRING="USING LOCAL FILE -";
C<18,40>ERRSTRING=C<0,40>PFMMSG;
C<58,1>ERRSTRING="$";
END
END
IF GETPARM GQ 2 THEN GETPARM=0;
FILENAM[FILNUM]=NEWNAME;
CHANGED[FILNUM]=0;
LOCKED[FILNUM]=0;
INITFILE[FILNUM]=SCNFDINIT;
ASCII[FILNUM]=CHARPARM;
IF CHARPARM EQ 0 AND ALLASCII THEN ASCII[FILNUM]=2;
IF NOT WRITEABLE(READNAM) THEN LOCKED[FILNUM]=1;
POSZ(BOTC(FILECTL)-1);
FORMFDL(FILNUM);
INSY;
FDLF(FILNUM)=CURRENT;
# NEW FILE BRACKET GOES BEFORE AUDIT TRAIL BRACKET #
POSZ(TOPA(AUDITCTL)-1);
TOPF(FILNUM)=CURRENT;
MAKEFET(FILEFET,READNAM,FILEBUF,DSKSIZ);
IF ASSGNFILE(READNAM) THEN
BEGIN
FILEREAD;
REWIND(FILEFET,0);
END
LINE[0]=NULLIN;
INSY;
BOTF(FILNUM)=CURRENT;
IF BOTF(FILNUM) EQ TOPF(FILNUM)+1 THEN
BEGIN
POSZ(TOPF(FILNUM));
IF NUMMODE EQ NUMST"INTERPRET" THEN NUMBERED[FILNUM]=0;
END
ELSE POSZ(TOPF(FILNUM)+1);
CURF(FILNUM)=CURRENT;
IF SMALLFIELD THEN
BEGIN
PAUSEIO; # DRAIN BUFFERS SO WE CAN ... #
DSKSIZ=DISKSIZE; # ... SHRINK BUFFERS BACK #
FLDLEN(LOC(WORKBUF)+DSKSIZ+4);
END
END # OF ADDFILE #
END TERM