$CONTROL USLINIT,CODE,MAP,PRIVILEGED                                    00015000
<< LOGSEG0 - MODULE 90 >>                                               00020000
$COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980. ",            & 00025000
$     "THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A ",      & 00030000
$     "TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR ",    & 00035000
$     "STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION ",& 00040000
$     "OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED ",  & 00045000
$     "WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY."   00050000
$TITLE "LOGGING PROCESS"                                                00055000
$CONTROL ADR                                                   <<01869>>00060000
<<-------------------------------------------------------->>   <<01874>>00065000
<< USE X1 = ON TO COMPILE IN DEBUGGING/BUG CATCHER CODE.  >>   <<01874>>00070000
<<-------------------------------------------------------->>   <<01874>>00075000
$SET X1=OFF                                                    <<01874>>00080000
<< Store fully qualified filename correctly in the tables. >>  <<01869>>00085000
<<Check for early release of LOGBUFF DST.                   >> <<01869>>00090000
<< Adds extra error checking and makes use of equated values.>><<01869>>00095000
<< Correct recover from powerfail routine.                  >> <<01869>>00100000
<< Changes equates to user new error msg -> ULOGERR 28.    >>  <<01869>>00105000
<< Fix non-recovery of logfile on warmstart >>                 <<01869>>00110000
<< Enhancement - Logging to labeled serial disc, LINUS  >>     <<01869>>00115000
<< Post GAP table after every write to serial disc. Also>>     <<01869>>00120000
<< cleanup recovery routine to work for all logfiles    >>     <<01869>>00125000
<< Make sure HDR labels posted to tape file right after FOPEN>><<01869>>00130000
<<  Also perform abortio to tape upon a powerfail.           >><<01869>>00135000
<< Preserve locking hierarchy - get logsir before resource. >> <<01869>>00140000
<< Remove declarations of unused items. General clean up.    >><<01869>>00145000
<< New procedure to stop all log processes upon =SHUTDOWN.   >><<01869>>00150000
<< Make DB at stack when call FWRITEDIR for restart.         >><<01869>>00155000
<< One last "fix" to powerfail recovery stuff.               >><<01869>>00160000
<< Problem with log process calling FLUSH and losing STOPs.  >><<01869>>00165000
<< Make use of include file for table definitions, etc.      >><<01869>>00170000
<< Remove all dependencies to the DST table.                 >><<01869>>00175000
<< Print out File System errors along with U.L. errors.      >><<01869>>00180000
<< Check for I/O channel timeout after powerfails in RECPFAIL>><<01869>>00185000
<< Solve problem of regular records in between CONT records. >><<01869>>00190000
<< Make sure DST field of LOGTAB is NULL when initializing.  >><<01869>>00195000
<< Enhancement -- CHANGELOG.                                 >><<01869>>00200000
                                                               <<01869>>00205000
BEGIN                                                                   00210000
$CONTROL SEGMENT=LOGSEG0,MAIN=LOGSEG0                                   00215000
$INCLUDE INCLPCB5                                              <<01869>>00220000
$INCLUDE INCLLOG                                               <<01869>>00225000
$IF X1=ON                                                      <<01874>>00230000
$PAGE "*** BUG CATCHER DEFINES, EQUATES, AND VARIABLES ***"    <<01874>>00231000
                                                               <<01874>>00232000
EQUATE                                                         <<01874>>00297000
   <<---------------------------------------------------->>    <<01874>>00298000
   << EQUATES FOR VARIOUS BUG CATCHER EVENT NUMBERS.     >>    <<01874>>00299000
   <<---------------------------------------------------->>    <<01874>>00300000
                                                               <<01874>>00301000
   BC'RELEASE             = 1,                                 <<01874>>00302000
   BC'OBTAIN              = BC'RELEASE+1,                      <<01874>>00303000
   BC'AWAKE               = BC'OBTAIN+1,                       <<01874>>00304000
   BC'WAIT                = BC'AWAKE+1,                        <<01874>>00305000
   BC'ATTACHIO            = BC'WAIT+1,                         <<01874>>00306000
   BC'VALUES              = BC'ATTACHIO+1,                     <<01874>>00307000
   BC'RELDATASEG          = BC'VALUES+1,                       <<01874>>00308000
   BC'RELSIR              = BC'RELDATASEG+1,                   <<01874>>00309000
   BC'GETSIR              = BC'RELSIR+1;                       <<01874>>00310000
                                                               <<01874>>00311000
$PAGE                                                          <<01874>>00311100
$IF                                                            <<01874>>00312000
                                                                        00460000
<<FILE LABEL EQUATES>>                                                  00465000
                                                                        00470000
EQUATE                                                                  00475000
EOF               =       21,                                           00480000
FCODE             =       26,                    <<FILE CODE>>          00485000
FLIMIT            =       15,   << File limit >>               <<01869>>00490000
FBLKSIZE          =       38,   << Blocksize >>                <<01869>>00495000
FEXTSIZE          =       41,   << Size of extent >>           <<01869>>00500000
F'CKSUM           =       34,   << File label checksum       >><<01869>>00505000
CREATOR'ID        =       24,                                  <<01869>>00510000
LASTEXT           =       40;             <<LAST EXTENT SIZE>>          00515000
                                                                        00520000
DEFINE                                                         <<01869>>00525000
OFFSET'TO'DATA  = 39).(0:8#;                                   <<01869>>00530000
                                                               <<01869>>00535000
                                                                        00540000
                                                                        00545000
EQUATE                                                                  00550000
ZERO'LENGTH    =  0,                                                    00555000
PRI            =   140,            <<PRIORITY OF REC PROCESS>>          00560000
ABSYS          =   %1000,                                               00565000
SYSEXTPTR      =   ABSYS+%377,                                          00570000
LOCSIZE      =   1000,   <<Q TO Z>>                            <<01869>>00575000
                                                                        00580000
                                                                        00585000
GLOBSIZE       =   4620          <<BLOCKSIZE>>+128<<REC SIZE>>          00590000
+ 100                             <<MISC>>+256<<PRIMARY DB>> ,          00595000
INITSTACK      =   GLOBSIZE+LOCSIZE+512 ,          <<PCBX>>             00600000
maxstack    = initstack+4096;                                  <<01869>>00605000
                                                                        00610000
DEFINE                                                                  00615000
RECLOGPLABEL   =    ABSYS+ABSOLUTE(SYSEXTPTR)+%62#,                     00620000
RECLOGDELTAP   =    ABSYS+ABSOLUTE(SYSEXTPTR)+%63#,                     00625000
A'             =    ABSOLUTE#;                                          00630000
                                                                        00635000
                                                                        00640000
                                                                        00645000
DEFINE                                                                  00650000
                                                                        00655000
ULOGPLABEL   =   ABSYS+ABSOLUTE(SYSEXTPTR)+%60#,                        00660000
ULOGDELTAP   =   ABSYS+ABSOLUTE(SYSEXTPTR)+%61#,                        00665000
ULOGRSTARTPLABEL  =  ABSYS+ABSOLUTE(SYSEXTPTR)+%65#,                    00670000
ULOGRSTARTDELTAP  =  ABSYS+ABSOLUTE(SYSEXTPTR)+%64#;                    00675000
                                                                        00680000
                                                                        00685000
                                                                        00690000
INTEGER POINTER PDB  = DB;                                     <<01869>>00695000
                                                               <<01869>>00700000
INTEGER X = X;                                                          00705000
                                                                        00710000
<< Any changes to the following DB-relative declarations will>><<01869>>00715000
<< require changes to INITLOG & INITRECLOG. Those routines   >><<01869>>00720000
<< are responsible for initializing the logging process and  >><<01869>>00725000
<< the warmstart recovery process. That initialization       >><<01869>>00730000
<< involves setting up the addresses for these DB variables. >><<01869>>00735000
                                                               <<01869>>00740000
                                                                        00745000
BYTE ARRAY ZEROS(0:3);                                         <<01869>>00750000
BYTE ARRAY FORMS(0:9);                                                  00755000
BYTE ARRAY FNAME(0:36);                                        <<01869>>00760000
BYTE ARRAY BFNAME(0:36);                                       <<01869>>00765000
BYTE ARRAY PROCNAME(0:8);                                               00770000
LOGICAL ARRAY BUFFAREA(0:BLKSIZE-1);                           <<01869>>00775000
DOUBLE ARRAY DBUFFAREA(*) = BUFFAREA;                                   00780000
LOGICAL ARRAY DISCREC(0:RECSIZEM1);                            <<01869>>00785000
DOUBLE ARRAY DDISCREC(*) = DISCREC;                                     00790000
                                                                        00795000
                                                                        00800000
$PAGE                                                          <<01869>>00805000
PROCEDURE DELAY(MSEC);                                         <<01869>>00810000
   VALUE MSEC;                                                 <<01869>>00815000
   DOUBLE MSEC;                                                <<01869>>00820000
   OPTION EXTERNAL;                                            <<01869>>00825000
                                                               <<01869>>00830000
                                                               <<01869>>00835000
                                                               <<01869>>00840000
INTEGER PROCEDURE GETDATASEG(MEMSIZE,VDSIZE);                           00845000
VALUE MEMSIZE,VDSIZE;                                                   00850000
INTEGER MEMSIZE,VDSIZE;                                                 00855000
OPTION EXTERNAL;                                                        00860000
                                                                        00865000
                                                                        00870000
INTEGER PROCEDURE FLABIO(D,S,F,A);                                      00875000
VALUE D,S,F;                                                            00880000
INTEGER D,F;                                                            00885000
DOUBLE S;                                                               00890000
INTEGER ARRAY A;                                                        00895000
OPTION EXTERNAL;                                                        00900000
                                                                        00905000
                                                                        00910000
LOGICAL PROCEDURE EXCHANGEDB(DSTX);                                     00915000
VALUE DSTX;                                                             00920000
LOGICAL DSTX;                                                           00925000
OPTION EXTERNAL;                                                        00930000
                                                                        00935000
                                                                        00940000
PROCEDURE AWAKE(PCBPT,N,WAITF);                                         00945000
VALUE PCBPT,N,WAITF;                                                    00950000
INTEGER PCBPT,N,WAITF;                                                  00955000
OPTION PRIVILEGED UNCALLABLE,EXTERNAL;                                  00960000
                                                                        00965000
PROCEDURE WAIT(WAITC,JPCOUNTX);                                         00970000
VALUE WAITC,JPCOUNTX;                                                   00975000
INTEGER WAITC,JPCOUNTX;                                                 00980000
OPTION PRIVILEGED,UNCALLABLE,EXTERNAL;                                  00985000
                                                                        00990000
                                                                        00995000
LOGICAL PROCEDURE GETSIR(SIRN);                                         01000000
VALUE SIRN;                                                             01005000
INTEGER SIRN;                                                           01010000
OPTION PRIVILEGED,UNCALLABLE,EXTERNAL;                                  01015000
                                                                        01020000
PROCEDURE RELSIR(SIRN,A);                                               01025000
VALUE SIRN,A;                                                           01030000
INTEGER SIRN;                                                           01035000
LOGICAL A;                                                              01040000
OPTION PRIVILEGED,UNCALLABLE,EXTERNAL;                                  01045000
                                                                        01050000
DOUBLE PROCEDURE ATTACHIO(LDEV,QMISC,DSTX,ADDR,FUNC,CNT,P1,P2,FLAGS);   01055000
VALUE LDEV,QMISC,DSTX,ADDR,FUNC,CNT,P1,P2,FLAGS;                        01060000
INTEGER LDEV,QMISC,DSTX,ADDR,FUNC,CNT,P1,P2,FLAGS;                      01065000
OPTION EXTERNAL;                                                        01070000
PROCEDURE LOGCLOSE(A,B,C);                                     <<01869>>01075000
VALUE A,B,C;                                                   <<01869>>01080000
INTEGER A,B,C;                                                 <<01869>>01085000
OPTION EXTERNAL;                                               <<01869>>01090000
                                                               <<01869>>01095000
                                                                        01100000
INTRINSIC DEBUG;                                               <<01869>>01105000
INTRINSIC FFILEINFO;                                           <<01869>>01110000
INTRINSIC FCONTROL,FSPACE;                                     <<01869>>01115000
INTRINSIC FOPEN,FCLOSE,FREADDIR,FWRITEDIR,FGETINFO,FWRITE;     <<01869>>01120000
INTRINSIC FPOINT,FCHECK,ASCII,DASCII,CLOCK,CALENDAR,FREAD;     <<01869>>01125000
INTRINSIC FSETMODE;                                            <<01869>>01130000
                                                                        01135000
                                                                        01140000
                                                                        01145000
                                                                        01150000
LOGICAL PROCEDURE FINDLOG(LOGNAME,INDEX);                               01155000
INTEGER INDEX;                                                          01160000
BYTE ARRAY LOGNAME;                                                     01165000
OPTION FORWARD;                                                         01170000
                                                                        01175000
LOGICAL PROCEDURE RECPFAIL(BUFFILENO,RECNUM,TAPELDEV,FIRST);   <<01869>>01180000
VALUE BUFFILENO,RECNUM,TAPELDEV,FIRST;                         <<01869>>01185000
INTEGER BUFFILENO,TAPELDEV;                                    <<01869>>01190000
LOGICAL FIRST;                                                 <<01869>>01195000
DOUBLE RECNUM;                                                          01200000
OPTION FORWARD;                                                         01205000
                                                               <<01869>>01210000
                                                               <<01869>>01215000
LOGICAL PROCEDURE GENTRY(INDEX,TYPE);                                   01220000
VALUE TYPE;                                                             01225000
INTEGER INDEX,TYPE;                                                     01230000
OPTION FORWARD;                                                         01235000
                                                                        01240000
                                                                        01245000
INTEGER PROCEDURE GENMSG(SETNO,MSGNO,MASK,PARM1,PARM2,PARM3,            01250000
PARM4,PARM5,DEST,REPLY,OFFSET,DST',CONTROL);                            01255000
VALUE SETNO,MSGNO,MASK,PARM1,PARM2,PARM3,PARM4,PARM5,DEST,              01260000
REPLY,OFFSET,DST',CONTROL;                                              01265000
INTEGER SETNO,MSGNO,DEST,DST';                                          01270000
LOGICAL MASK,PARM1,PARM2,PARM3,PARM4,PARM5,REPLY,OFFSET,                01275000
CONTROL;                                                                01280000
OPTION VARIABLE,EXTERNAL;                                               01285000
                                                                        01290000
                                                                        01295000
PROCEDURE RELDATASEG(IX);                                               01300000
VALUE IX;                                                               01305000
INTEGER IX;                                                             01310000
OPTION EXTERNAL;                                                        01315000
                                                                        01320000
                                                                        01325000
PROCEDURE RELENTRY(INDEX,TYPE);                                <<01869>>01330000
VALUE INDEX,TYPE;                                                       01335000
INTEGER INDEX,TYPE;                                                     01340000
OPTION FORWARD;                                                         01345000
PROCEDURE FENTRY'SWITCH(LOGID',PASS',FNAME',UNAME',            <<01869>>01350000
UACCT',TYPE');                                                 <<01869>>01355000
BYTE ARRAY LOGID',PASS',FNAME',UNAME',UACCT';                  <<01869>>01360000
LOGICAL TYPE';                                                 <<01869>>01365000
OPTION EXTERNAL,PRIVILEGED,VARIABLE;                           <<01869>>01370000
PROCEDURE FENTRY(LOGID',PASS',FNAME',UNAME',                            01375000
UACCT',TYPE');                                                          01380000
BYTE ARRAY LOGID',PASS',FNAME',UNAME',UACCT';                           01385000
LOGICAL TYPE';                                                          01390000
OPTION EXTERNAL,PRIVILEGED,VARIABLE;                                    01395000
                                                                        01400000
PROCEDURE DEPOSIT'FILENAME(STRING,FN,LW',GN,AN);               <<01869>>01405000
   BYTE ARRAY STRING,FN,LW',GN,AN;                             <<01869>>01410000
   OPTION EXTERNAL;                                            <<01869>>01415000
                                                               <<01869>>01420000
                                                               <<01869>>01425000
PROCEDURE EXTRACT'FILENAME(STRING,FN,LW',GN,AN);               <<01869>>01430000
   BYTE ARRAY STRING,FN,LW',GN,AN;                             <<01869>>01435000
   OPTION EXTERNAL;                                            <<01869>>01440000
                                                               <<01869>>01445000
                                                                        01450000
PROCEDURE RELEASE(RES,ALTRES,WAKEUP);                                   01455000
VALUE RES,ALTRES,WAKEUP;                                                01460000
LOGICAL WAKEUP;                                                         01465000
LOGICAL POINTER RES,ALTRES;                                             01470000
OPTION EXTERNAL;                                                        01475000
                                                                        01480000
INTEGER PROCEDURE OBTAIN(RES,ALTRES);                                   01485000
VALUE RES,ALTRES;                                                       01490000
LOGICAL POINTER RES,ALTRES;                                             01495000
OPTION EXTERNAL;                                                        01500000
                                                                        01505000
INTEGER PROCEDURE LUN(VTABINDX,MVTABX);                                 01510000
VALUE VTABINDX,MVTABX;                                                  01515000
INTEGER VTABINDX,MVTABX;                                                01520000
OPTION EXTERNAL;                                                        01525000
                                                                        01530000
                                                                        01535000
                                                                        01540000
PROCEDURE PROCREATE (PINN, PLABEL, DELTAP, STACKDST, GLOBSIZE, <<01869>>01545000
                     DLSIZE, LOCSIZE, PRI, STRING, STRINGLNTH, <<01869>>01550000
                     PARM, FLAGS, MAXSTACK, STDIN, STDLIST);   <<01869>>01555000
  VALUE PLABEL, DELTAP, STACKDST, GLOBSIZE, DLSIZE, LOCSIZE,   <<01869>>01560000
        PRI, STRING, STRINGLNTH, PARM, FLAGS, MAXSTACK;        <<01869>>01565000
  INTEGER PLABEL, DELTAP, STACKDST, GLOBSIZE, DLSIZE, LOCSIZE, <<01869>>01570000
          PRI, STRING, STRINGLNTH, PARM, PINN, MAXSTACK;       <<01869>>01575000
  LOGICAL FLAGS;                                               <<01869>>01580000
  LOGICAL ARRAY STDIN, STDLIST;                                <<01869>>01585000
  OPTION EXTERNAL;                                             <<01869>>01590000
                                                                        01595000
LOGICAL PROCEDURE ALTER'LID'ENTRY(LID,PASS,FNAME,TYPE);        <<01869>>01600000
VALUE TYPE;                                                    <<01869>>01605000
BYTE ARRAY LID,PASS,FNAME;                                     <<01869>>01610000
INTEGER TYPE;                                                  <<01869>>01615000
OPTION VARIABLE,UNCALLABLE,EXTERNAL;                           <<01869>>01620000
                                                                        01625000
LOGICAL PROCEDURE GETSTACK(N,MP);                                       01630000
VALUE N,MP;                                                             01635000
LOGICAL N,MP;                                                           01640000
OPTION EXTERNAL;                                                        01645000
                                                                        01650000
                                                                        01655000
PROCEDURE WRITEDSEG(EN);                                                01660000
VALUE EN;                                                               01665000
INTEGER EN;                                                             01670000
OPTION EXTERNAL;                                                        01675000
                                                                        01680000
INTEGER PROCEDURE ADOPT(A,B);                                  <<01869>>01685000
VALUE A,B; INTEGER A,B;                                        <<01869>>01690000
OPTION EXTERNAL, PRIVILEGED;                                   <<01869>>01695000
                                                               <<01869>>01700000
INTEGER PROCEDURE FGETPVINFO(FILENUM);                         <<01869>>01705000
VALUE FILENUM;                                                 <<01869>>01710000
INTEGER FILENUM;                                               <<01869>>01715000
OPTION EXTERNAL;                                               <<01869>>01720000
                                                               <<01869>>01725000
                                                                        01730000
PROCEDURE FLUSH(INDEX,FLAG);                                   <<01869>>01735000
VALUE INDEX,FLAG;                                              <<01869>>01740000
INTEGER INDEX;                                                 <<01869>>01745000
LOGICAL FLAG;                                                  <<01869>>01750000
OPTION EXTERNAL;                                               <<01869>>01755000
                                                                        01760000
PROCEDURE MOVE'FROM'DSEG(TARGET,SEGMENT,OFFSET,COUNT);         <<01869>>01765000
   VALUE TARGET,SEGMENT,OFFSET,COUNT;                          <<01869>>01770000
   INTEGER TARGET,SEGMENT,OFFSET,COUNT;                        <<01869>>01775000
   OPTION FORWARD,INTERNAL;                                    <<01869>>01780000
                                                               <<01869>>01785000
                                                               <<01869>>01790000
PROCEDURE MOVE'TO'DSEG(SEGMENT,OFFSET,SOURCE,COUNT);           <<01869>>01795000
   VALUE SEGMENT,OFFSET,SOURCE,COUNT;                          <<01869>>01800000
   INTEGER SEGMENT,OFFSET,SOURCE,COUNT;                        <<01869>>01805000
   OPTION FORWARD,INTERNAL;                                    <<01869>>01810000
                                                               <<01869>>01815000
                                                               <<01869>>01820000
                                                               <<01869>>01825000
INTEGER PROCEDURE IOSTAT(STAT);                                <<01869>>01830000
   VALUE STAT;                                                 <<01869>>01835000
   INTEGER STAT;                                               <<01869>>01840000
   OPTION EXTERNAL;                                            <<01869>>01845000
                                                               <<01869>>01850000
                                                               <<01869>>01855000
PROCEDURE DEL'LOCKWORD(FILENAME);                              <<01869>>01860000
   BYTE ARRAY FILENAME;                                        <<01869>>01865000
   OPTION FORWARD;                                             <<01869>>01870000
INTEGER PROCEDURE ULR'OPEN(FORMDESIGNATOR,FOPTIONS,AOPTIONS,   <<01871>>01871000
                           RECSIZE,DEVICE,FORMMSG,USERLABELS,  <<01871>>01871100
                           BLOCKFACTOR,PRICOPBUFS,FILESIZE,    <<01871>>01871200
                           NUMEXTENTS,INITALLOC,FILECODE);     <<01871>>01871300
   VALUE FOPTIONS,AOPTIONS,RECSIZE,USERLABELS,BLOCKFACTOR,     <<01871>>01871400
         PRICOPBUFS,FILESIZE,NUMEXTENTS,INITALLOC,FILECODE;    <<01871>>01871500
   BYTE ARRAY FORMDESIGNATOR,DEVICE,FORMMSG;                   <<01871>>01871600
   LOGICAL FOPTIONS,AOPTIONS;                                  <<01871>>01871700
   INTEGER RECSIZE,USERLABELS,BLOCKFACTOR,PRICOPBUFS,          <<01871>>01871800
           NUMEXTENTS,INITALLOC,FILECODE;                      <<01871>>01871900
   DOUBLE FILESIZE;                                            <<01871>>01872000
   OPTION VARIABLE,PRIVILEGED,EXTERNAL;                        <<01871>>01872100
                                                               <<01871>>01872200
INTEGER PROCEDURE REELSWITCH(LDEV,RDWR);                       <<01871>>01872300
   VALUE LDEV,RDWR;                                            <<01871>>01872400
   LOGICAL LDEV;                                               <<01871>>01872500
   INTEGER RDWR;                                               <<01871>>01872600
   OPTION EXTERNAL;                                            <<01871>>01872700
                                                               <<01869>>01875000
                                                               <<01869>>01880000
$IF X1=ON                                                      <<01874>>01885000
                                                               <<01874>>01900000
   PROCEDURE WHAT'S'UP (EVENT, P1, P2, P3, P4);                <<01874>>01905000
      VALUE   EVENT, P1, P2, P3, P4;                           <<01874>>01910000
      INTEGER EVENT, P1, P2, P3, P4;                           <<01874>>01915000
      OPTION  EXTERNAL, UNCALLABLE, PRIVILEGED, VARIABLE;      <<01874>>01920000
                                                               <<01874>>01925000
$IF                                                            <<01874>>01930000
$PAGE  "Logging Process Declarations"                          <<01869>>01935000
LOGICAL PROCEDURE ULOGPROC;                                    <<01869>>01940000
                                                               <<01869>>01945000
OPTION PRIVILEGED,UNCALLABLE;                                           01950000
BEGIN                                                                   01955000
                                                                        01960000
COMMENT                                                        <<01869>>01965000
                                                               <<01869>>01970000
User Logging Process. Has responsibility for creating          <<01869>>01975000
and initializing the Logging Buffer Table. It will open the    <<01869>>01980000
User Logging files - the disc logging file (disc logging) or   <<01869>>01985000
the tape logging file and the disc buffer file (tape logging). <<01869>>01990000
                                                               <<01869>>01995000
If a Restart was requested (via the LOG command), then will    <<01869>>02000000
re-read the logging file to find where it left off, output a   <<01869>>02005000
Log restart record to the buffer area of the Logging Buffer and<<01869>>02010000
continue as if a Start was requested. If a Start was requested,<<01869>>02015000
then will output a Log header (start) record to the buffer area<<01869>>02020000
                                                               <<01869>>02025000
After this initialization, will wait (at label WAIT1) for a    <<01869>>02030000
request from a user (via the intrinsics). The type of action   <<01869>>02035000
desired by the user will be communicated here via the Global   <<01869>>02040000
Area of the Logging Buffer. This process will then perform the <<01869>>02045000
function, clear the request word, and return any error conditio<<01869>>02050000
to the user process, and then wait for another request.        <<01869>>02055000
                                                               <<01869>>02060000
When the request is to stop, will set the internal message word<<01869>>02065000
of the global area, and wait for the number of active users to <<01869>>02070000
become zero. At this point the buffer area will be flushed to  <<01869>>02075000
the logging file, the files closed, and the Logging Buffer Tabl<<01869>>02080000
will be released.                                              <<01869>>02085000
NOTE:                                                          <<01869>>02090000
  Cartridge tape and serial disc logfiles are treated the same <<01869>>02095000
  as tape logfiles.                                            <<01869>>02100000
                                                               <<01869>>02105000
;                                                              <<01869>>02110000
                                                                        02115000
                                                                        02120000
ENTRY RESTART;                                                          02125000
                                                                        02130000
                                                               <<01869>>02135000
EQUATE                                                         <<01869>>02140000
   PRINT'NOTHING    = 0,                                       <<01869>>02145000
   PRINT'PROCNAME   = 1,                                       <<01869>>02150000
   PRINT'FNAME      = 2,                                       <<01869>>02155000
   PRINT'BFNAME     = 3,                                       <<01869>>02160000
   PRINT'PREV       = 4;                                       <<01869>>02165000
                                                               <<01869>>02170000
DOUBLE                                                                  02175000
   ADDR,         << Disc address of current extent of the    >>         02180000
                 << buffer file or disc log file.            >>         02185000
   ATT'STAT,     << Return from ATTACHIO.                    >>         02190000
   BLOCKNUM,     << Last blk # of current extent (disc log). >>         02195000
   CURRREC,      << Current record number + 1 (next rec #)   >>         02200000
   DTEMP,        <<                                          >>         02205000
   FLABADDR,     << Address of file label                    >><<01869>>02210000
   LASTREC,      << Last good record found by CHECKRECORD.   >>         02215000
   LIMIT,        << File limit of disc log file.             >>         02220000
   OUTBUFREC,    << Next blk # ot move from disc buffer file.>><<01869>>02225000
   Q'OLD'LIMIT;  << File limit of previous disc log file.    >><<01869>>02230000
                                                                        02235000
INTEGER                                                                 02240000
   A,            << Used for GETSIR/RELSIR of LOGSIR.        >>         02245000
   ADDR1 = ADDR,                                                        02250000
   ADDR2 = ADDR + 1,                                                    02255000
   ATT'STAT0 = ATT'STAT,                                                02260000
   BUFDST,       << DST # of the LOGBUFF.                    >>         02265000
   BUFFILENO,    << File number of the disc buffer file.     >>         02270000
   COUNT,        << Used to determine how many reads are need>>         02275000
                 <<   to empty the disc buffer file.         >>         02280000
   DISCLDEV,     << Ldev for current extent.                 >><<01869>>02285000
   ERRCODE,      << File system error number (from FCHECK).  >>         02290000
   EXTNUM,       << Current extent number.                   >>         02295000
   FILE'NAME'LEN,<< Length of file name.                     >><<01869>>02300000
   FILENO,       << File number of the log file.             >>         02305000
   FLABADDR1 = FLABADDR,                                       <<01869>>02310000
   FLAGADDR2 = FLABADDR + 1,                                   <<01869>>02315000
   FLABLDEV,     << Ldev for file label of disc (buf) file   >><<01869>>02320000
   I,            << # good records in the block - CHECKBLOCK >>         02325000
                 <<   Loop counter when intializing LOGBUFF. >>         02330000
   INDEX,        << Word offset to user entry in LOGBUFF.    >>         02335000
   J,            << # fill records needed by FORMAT'TRAILER. >>         02340000
   LAST'REC'CODE,<< Code of last record - CONTINUE'LOGGING.  >>         02345000
   LEN,          << Minimum length of DST for the LOGBUFF.   >>         02350000
   MAXUSERS,     << Max # users per log process.             >>         02355000
   MSGNO,        << Message # for GENMSG.                    >>         02360000
   NUMEXT,       << Max # extents allowed for disc log file. >>         02365000
   Q'NEWTYPE,    << Type for the next log file in the set.   >><<01869>>02370000
   Q'OLD'NUMEXT, << Number of extents in previous log file.  >><<01869>>02375000
   Q'OLDTYPE,    << Type for the previous log file in the set>><<01869>>02380000
   Q'VSETNO,     << Current file sequence.                   >><<01869>>02385000
   SAVEFILENO,   << File number of previous log file in set. >><<01869>>02390000
   TAPEDEV,      << If tape logging - ldev # of tape drive.  >>         02395000
   TABINDEX,     << Word offset to entry in the LOGTAB.      >>         02400000
   TABINDEX' = Q-4,<< Same as above. Passed here by PCREATE. >>         02405000
   TEMP,         << # for the buffer file name.              >>         02410000
   TEMPCNT,      << Used when need more than one write to    >><<01869>>02415000
                 <<  empty the disc buffer file.             >>         02420000
   ULERRCODE;    << User logging error number                >><<01869>>02425000
                                                                        02430000
LOGICAL                                                                 02435000
   ALLOW'CHANGELOG,<< TRUE if allow :CHANGELOG               >><<01869>>02440000
   ABNORMAL'EXIT,<< TRUE of error and disc logging.          >>         02445000
   DUMMY,        << Dummy parm for FCONTROL calls.           >>         02450000
   EOFORERR,     << Loop terminator for CONTINUE'LOGGING.    >>         02455000
   EXTSIZE,      << Size of current disc log file extent.    >>         02460000
   FIRST'TAPE'BLOCK,   << TRUE if writing 1st tape block     >><<01869>>02465000
   FREE'LAST'EXTENT,  << TRUE if last record of last extent  >>         02470000
                  <<   has been released when stop disc log. >>         02475000
   FORMATTED'TRAILER,  << TRUE if trailer record done.       >>         02480000
   GOT'LOGBUFF,  << TRUE if created LOGBUFF                  >><<01869>>02485000
   LID'TYP,      << Type field from LIDTAB                   >><<01869>>02490000
   NOTIFIED,     << TRUE is message printed to console.      >>         02495000
   RESFLAG1,     <<TRUE if locked disc info                >>  <<01875>>02500000
   RESFLAG2,     <<TRUE if locked buffer info              >>  <<01875>>02501000
   RESFLAG3,     <<TRUE if locked user entry info          >>  <<01875>>02502000
   RESTART',     << TRUE if restart entry point was used.    >>         02505000
   SWITCH'FLAG,  << TRUE if processing a changelog.          >>         02510000
   TAPE',        << TRUE if tape log file.                   >>         02515000
   USER'REQUESTED'CHANGE,  << TRUE if requested changelog.   >><<01869>>02520000
   VALID;        << TRUE if good block from CHECKBLOCK.      >>         02525000
                                                                        02530000
LOGICAL POINTER                                                         02535000
   BUF,          << Ptr to buffer area of LOGBUFF.           >>         02540000
   RECPTR;       << Ptr within buffer area to put next rec.  >>         02545000
                                                                        02550000
DOUBLE POINTER                                                          02555000
   DBUF,         << Same as BUF.                             >>         02560000
   DRECPTR;      << Same as RECPTR.                          >>         02565000
                                                                        02570000
BYTE POINTER                                                            02575000
   BBUF,         << Same as BUF.                             >>         02580000
   BRECPTR;      << Same as RECPTR.                          >>         02585000
                                                                        02590000
BYTE ARRAY DEV(0:8);                                           <<01872>>02595000
                                                               <<01869>>02600000
<< Local copy of LOGTAB entry. >>                              <<01869>>02605000
                                                               <<01869>>02610000
LOGICAL ARRAY ENTRY'(0:TENTRYSIZE-1) = Q;                      <<01869>>02615000
BYTE ARRAY BENTRY'(*) = ENTRY';                                         02620000
DOUBLE ARRAY DENTRY'(*) = ENTRY';                                       02625000
BYTE ARRAY TEMP'FILE'NAME'(0:8);                               <<01869>>02630000
BYTE ARRAY OLD'FILE'NAME(0:36);                                <<01869>>02635000
LOGICAL ARRAY FLAB(0:127)=Q;                                            02640000
BYTE ARRAY BFLAB(*) = FLAB;                                    <<01869>>02645000
DOUBLE ARRAY DFLAB(*) = FLAB;                                           02650000
$PAGE "Logging Process -- CheckMsg"                            <<01869>>02655000
SUBROUTINE CHECKMSG;                                           <<01869>>02660000
BEGIN                                                          <<01869>>02665000
                                                               <<01869>>02670000
<< This subroutine is used to check for special conditions >>  <<01869>>02675000
<< after calling FLUSH.                                    >>  <<01869>>02680000
<< DB is at LOGBUFF. If MSG word is STOP and got an error  >>  <<01869>>02685000
<< then will go to close the log file and terminate.       >>           02690000
                                                                        02695000
                                                               <<01869>>02700000
                                                               <<01869>>02705000
IF LOGBUFF(USERMSG) <> CONTINUE  OR                            <<01869>>02710000
   LOGBUFF(LOGMSG) <> CONTINUE  THEN                           <<01869>>02715000
   BEGIN                                                       <<01869>>02720000
                                                               <<01869>>02725000
   IF LOGBUFF(STATE) = INITIALIZING THEN GO INIT'FAIL;         <<01869>>02730000
                                                               <<01869>>02735000
   IF SWITCH'FLAG THEN                                         <<01869>>02740000
      BEGIN                                                    <<01869>>02745000
      IF LOGBUFF(LOGMSG) = WRITEERR THEN                       <<01869>>02750000
         BEGIN                                                 <<01869>>02755000
         ULERRCODE := FWRITEERROR;                             <<01869>>02760000
         GO CHANGELOG'ERROR'RECOVERY;                          <<01869>>02765000
         END;                                                  <<01869>>02770000
      END;                                                     <<01869>>02775000
                                                               <<01869>>02780000
   IF LOGBUFF(USERMSG) = DISCSPACE THEN GO GETIT;              <<01869>>02785000
                                                               <<01869>>02790000
   IF LOGBUFF(MSG) = STOP AND LOGBUFF(NUMUSER) = 0  THEN       <<01869>>02795000
      BEGIN                                                    <<01869>>02800000
      << We have an error during the STOP, just quit >>        <<01869>>02805000
                                                               <<01869>>02810000
      IF LOGBUFF(LOGMSG) = WRITEERR THEN                       <<01869>>02815000
         BEGIN                                                 <<01869>>02820000
         IF LOGBUFF(LOGTYPE) = DISC  THEN                      <<01869>>02825000
            BEGIN                                              <<01869>>02830000
            LOGBUFF(MSG) := STOP;                              <<01869>>02835000
            ABNORMAL'EXIT := TRUE;                             <<01869>>02840000
            END                                                <<01869>>02845000
         ELSE LOGBUFF(MSG) := SUSPEND;                         <<01869>>02850000
                                                               <<01869>>02855000
         GO WAIT1;                                             <<01869>>02860000
         END;        << Write error >>                         <<01869>>02865000
                                                               <<01869>>02870000
      IF LOGBUFF(LOGMSG) = EOFONLOGFILE THEN                   <<01869>>02875000
         BEGIN                                                 <<01869>>02880000
         IF DLOGBUFF(FSPACE') = 0D AND FORMATTED'TRAILER THEN  <<01869>>02885000
            BEGIN                                              <<01869>>02890000
            LOGBUFF(LOGMSG) := CONTINUE;                       <<01869>>02895000
            LOGBUFF(USERMSG) := CONTINUE;                      <<01869>>02900000
            END                                                <<01869>>02905000
         ELSE                                                  <<01869>>02910000
            BEGIN                                              <<01869>>02915000
            IF LOGBUFF(LOGTYPE) = DISC THEN                    <<01869>>02920000
               BEGIN                                           <<01869>>02925000
               ABNORMAL'EXIT := TRUE;                          <<01869>>02930000
               GO CLOSE'DISC'FILE;                             <<01869>>02935000
               END                                             <<01869>>02940000
            ELSE GO CLOSE'SERIAL'FILE;                         <<01869>>02945000
            END;                                               <<01869>>02950000
         END;       << EOF on the log file >>                  <<01869>>02955000
      END;         << Error while stopping >>                  <<01869>>02960000
   END;                                                        <<01869>>02965000
                                                               <<01869>>02970000
END;       << Subroutine CHECKMSG >>                           <<01869>>02975000
$PAGE "Logging Process -- Format'Trailer"                      <<01869>>02980000
SUBROUTINE FORMAT'TRAILER;                                     <<01869>>02985000
BEGIN                                                                   02990000
                                                                        02995000
<< Outputs a trailer record padded by null records to fill out <<01869>>03000000
<< the block. DB at LOGBUFF.                                >> <<01869>>03005000
<<                                                          >>          03010000
<< Variables used:                                          >>          03015000
<<   BUF    - ptr to where record will reside in LOGBUFF.   >>          03020000
<<   DTEMP  -                                               >>          03025000
<<   J      - # available records in the LOGBUFF.           >>          03030000
                                                                        03035000
                                                               <<01869>>03040000
                                                               <<01869>>03045000
DTEMP := (DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))/             <<01869>>03050000
         DOUBLE(BLKFACTOR);                                    <<01869>>03055000
DTEMP := DTEMP * DOUBLE(BLKFACTOR);                            <<01869>>03060000
J := INTEGER((DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))-DTEMP);  <<01869>>03065000
J := BLKFACTOR - J;                                            <<01869>>03070000
IF ILOGBUFF(BSPACE) < J  THEN                                  <<01869>>03075000
   BEGIN                                                       <<01869>>03080000
                                                               <<01869>>03085000
   << Not enough room in the buffer for the trailer   >>       <<01869>>03090000
   << record. We need to flush it and then add the    >>       <<01869>>03095000
   << trailer record.                                       >> <<01869>>03100000
                                                               <<01869>>03105000
   FLUSH(NULL,FALSE);<< Tell it we are the log process   >>    <<01869>>03110000
   CHECKMSG;                                                   <<01869>>03115000
   END;                                                        <<01869>>03120000
                                                               <<01869>>03125000
@BUF := BUFBASE + LOGBUFF(BUFUSED) * RECSIZE;                  <<01869>>03130000
@DBUF := @BUF;                                                 <<01869>>03135000
@BBUF := 2 * @BUF;                                             <<01869>>03140000
                                                                        03145000
<< Clear out available space in buffer area >>                          03150000
                                                                        03155000
BUF := "  ";                                                   <<01869>>03160000
MOVE BUF(1) := BUF, (LOGBUFF(BSPACE)*RECSIZE-1);               <<01869>>03165000
                                                                        03170000
BUF(CODE) := TRAILER;                                          <<01869>>03175000
MOVE BBUF(LID') := BLOGBUFF(LOGID), (8);                       <<01869>>03180000
LOGBUFF(BSPACE) := LOGBUFF(BSPACE) - LOGICAL(J);               <<01869>>03185000
LOGBUFF(BUFUSED) := LOGBUFF(BUFUSED) + LOGICAL(J);             <<01869>>03190000
                                                                        03195000
DO                                                             <<01869>>03200000
   BEGIN                                                       <<01869>>03205000
   DBUF(RNUM) := DLOGBUFF(TRECS) := DLOGBUFF(TRECS) + 1D;      <<01869>>03210000
   BUF(DATE) := CALENDAR;                                      <<01869>>03215000
   DBUF(TIME) := CLOCK;                                        <<01869>>03220000
   X := RECSIZEM1;                                             <<01869>>03225000
   TOS := -1;                                                  <<01869>>03230000
   DO                                                          <<01869>>03235000
      BEGIN                                                    <<01869>>03240000
      IF X <> CKSUM THEN                                       <<01869>>03245000
      TOS := TOS XOR BUF(X);                                   <<01869>>03250000
      END                                                               03255000
   UNTIL (X := X-1) < 0;                                                03260000
   BUF(CKSUM) := TOS;                                          <<01869>>03265000
   @BUF := @DBUF := @BUF + RECSIZE;                            <<01869>>03270000
   END                                                                  03275000
UNTIL (J := J-1) <= 0;                                                  03280000
                                                               <<01869>>03285000
END;   << Subroutine FORMAT'TRAILER >>                         <<01869>>03290000
$PAGE "Logging Process -- FormatRestart"                       <<01869>>03295000
SUBROUTINE FORMATRESTART;                                               03300000
BEGIN                                                                   03305000
                                                                        03310000
                                                                        03315000
<< Formats a RESTART record, places it in the buffer area of>>          03320000
<< the buffer area, and clears the remainder of the buffer  >>          03325000
<< area. DB at LOGBUFF.                                     >>          03330000
<<                                                          >>          03335000
<<   ENTRY:                                                 >>          03340000
<<     CURRREC - Current record number + 1.                 >>          03345000
<<     RECPTR  - ptr to where this record will be placed in >>          03350000
<<                  the LOGBUFF.                            >>          03355000
<<     I       - # records already in the LOGBUFF buffer.   >>          03360000
                                                                        03365000
                                                                        03370000
                                                               <<01869>>03375000
   @BRECPTR := @RECPTR * 2;                                    <<01869>>03380000
                                                                        03385000
   << Clear out remainder of the LOGBUFF buffer area. >>                03390000
                                                                        03395000
   RECPTR := "  ";                                             <<01869>>03400000
   MOVE RECPTR(1) := RECPTR, ((BLKFACTOR-I)*RECSIZE-1);        <<01869>>03405000
                                                                        03410000
   DRECPTR(RNUM):=CURRREC;                                              03415000
   RECPTR(CODE):=RSTART;                                                03420000
   MOVE BRECPTR(LID') := BLOGBUFF(LOGID), (8);                 <<01869>>03425000
   RECPTR(DATE):=CALENDAR;                                              03430000
   DRECPTR(TIME):=CLOCK;                                                03435000
   X:=RECSIZEM1;                                               <<01869>>03440000
   TOS:=-1;                                                             03445000
   DO                                                                   03450000
      BEGIN                                                             03455000
      IF X <> CKSUM THEN                                                03460000
      TOS:=TOS XOR RECPTR(X);                                           03465000
      END                                                               03470000
   UNTIL (X:=X-1) < 0;                                                  03475000
   RECPTR(CKSUM):=TOS;                                                  03480000
                                                               <<01869>>03485000
   FLUSH(NULL,FALSE);                                          <<01869>>03490000
   CHECKMSG;                                                   <<01869>>03495000
END;   << Subroutine FORMATRESTART >>                                   03500000
$PAGE  "Logging Process -- Format'First'File"                  <<01869>>03505000
SUBROUTINE FORMAT'FIRST'FILE;                                  <<01869>>03510000
   BEGIN                                                       <<01869>>03515000
   << Formats the first log record to the new log file upon  >><<01869>>03520000
   << changelog. This record will provide linkage to the     >><<01869>>03525000
   << previous log file in the set.                          >><<01869>>03530000
                                                               <<01869>>03535000
   @BUF := BUFBASE + LOGBUFF(BUFUSED)*RECSIZE;                 <<01869>>03540000
   @DBUF:=@BUF;                                                <<01869>>03545000
   @BBUF:=2*@BUF;                                              <<01869>>03550000
   BUF := "  ";                                                <<01869>>03555000
   MOVE BUF(1) := BUF, (LOGBUFF(BSPACE)*RECSIZE-1);            <<01869>>03560000
   DBUF(RNUM):=DLOGBUFF(TRECS):=DLOGBUFF(TRECS)+1D;            <<01869>>03565000
   BUF(CODE):=FIRST'CODE;                                      <<01869>>03570000
   MOVE BBUF(LID') := BLOGBUFF(LOGID), (8);                    <<01869>>03575000
   BUF(DATE):=CALENDAR;                                        <<01869>>03580000
   DBUF(TIME):=CLOCK;                                          <<01869>>03585000
   BUF(SEQ):=LOGBUFF(VSETNO);                                  <<01869>>03590000
   MOVE BBUF(F'FILE'NAME):=BLOGBUFF(FIRST'FILE),(35);          <<01869>>03595000
   MOVE BBUF(P'FILE'NAME):=BLOGBUFF(PREVIOUS'FILE),(35);       <<01869>>03600000
   MOVE BBUF(C'FILE'NAME):=BLOGBUFF(CURRENT'FILE),(35);        <<01869>>03605000
   BUF(F'FILE'TYPE):=LOGBUFF(F'TYPE);                          <<01869>>03610000
   BUF(P'FILE'TYPE):=LOGBUFF(P'TYPE);                          <<01869>>03615000
   BUF(C'FILE'TYPE):=LOGBUFF(C'TYPE);                          <<01869>>03620000
   DBUF(C'TIME):=DLOGBUFF(FIRST'C'TIME);                       <<01869>>03625000
   BUF(C'DATE):=LOGBUFF(FIRST'C'DATE);                         <<01869>>03630000
   LOGBUFF(BSPACE):=LOGBUFF(BSPACE)-1;                         <<01869>>03635000
   LOGBUFF(BUFUSED):=LOGBUFF(BUFUSED)+1;                       <<01869>>03640000
   X:=RECSIZEM1;                                               <<01869>>03645000
   TOS:=-1;                                                    <<01869>>03650000
   DO                                                          <<01869>>03655000
      BEGIN                                                    <<01869>>03660000
      IF X <> CKSUM THEN                                       <<01869>>03665000
      TOS:=TOS XOR BUF(X);                                     <<01869>>03670000
      END                                                      <<01869>>03675000
   UNTIL (X:=X-1) < 0;                                         <<01869>>03680000
   BUF(CKSUM):=TOS;                                            <<01869>>03685000
                                                               <<01869>>03690000
   << Need to make sure this record gets out to the new file >><<01869>>03695000
   << as soon as possible - in case of system crash, etc.    >><<01869>>03700000
                                                               <<01869>>03705000
   FLUSH(NULL,FALSE);                                          <<01869>>03710000
   CHECKMSG;                                                   <<01869>>03715000
   END;      << Subroutine FORMAT'FIRST'FILE >>                <<01869>>03720000
$PAGE  "Logging Process -- Format'Next'File"                   <<01869>>03725000
SUBROUTINE FORMAT'NEXT'FILE;                                   <<01869>>03730000
BEGIN                                                          <<01869>>03735000
<< Formats the last record in the current log file upon a    >><<01869>>03740000
<< a changelog. This record will provide linkage to the next >><<01869>>03745000
<< log file in the set.                                      >><<01869>>03750000
                                                               <<01869>>03755000
   << If this is the last extent in the disc log file, make  >><<01869>>03760000
   << the last record free now.                              >><<01869>>03765000
                                                               <<01869>>03770000
                                                               <<01869>>03775000
  IF NOT FREE'LAST'EXTENT THEN                                 <<01869>>03780000
  BEGIN                                                        <<01869>>03785000
   IF LOGBUFF(EXTENT) = LOGBUFF(LASTEXT') AND Q'OLDTYPE = DISC <<01869>>03790000
      AND DLOGBUFF(FSPACE') < DOUBLE(BLKFACTOR) THEN                    03795000
      BEGIN                                                    <<01869>>03800000
      DLOGBUFF(FSIZE):=DLOGBUFF(FSIZE)+1D;                     <<01869>>03805000
      DLOGBUFF(FSPACE'):=DLOGBUFF(FSPACE')+1D;                 <<01869>>03810000
      LOGBUFF(BSPACE):=LOGBUFF(BSPACE)+1;                               03815000
      FREE'LAST'EXTENT:=TRUE;                                           03820000
      END;                                                     <<01869>>03825000
  END;                                                         <<01869>>03830000
                                                               <<01869>>03835000
<< Correct buffer for partial writes caused by FLUSHes. Want >><<01869>>03840000
<< to always make sure that we have complete blocks in the   >><<01869>>03845000
<< log file when it gets closed.                             >><<01869>>03850000
                                                               <<01869>>03855000
                                                               <<01869>>03860000
   DTEMP := (DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))/          <<01869>>03865000
          DOUBLE(BLKFACTOR);                                   <<01869>>03870000
   DTEMP:=DTEMP*DOUBLE(BLKFACTOR);                             <<01869>>03875000
   J:=INTEGER((DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))-DTEMP); <<01869>>03880000
   J:=BLKFACTOR-J;                                             <<01869>>03885000
   IF LOGBUFF(BSPACE) < LOGICAL(J)  THEN                       <<01869>>03890000
      BEGIN                                                    <<01869>>03895000
      FLUSH(NULL,FALSE);  << Tell it we are the log process >> <<01869>>03900000
      CHECKMSG;                                                <<01869>>03905000
      END;                                                     <<01869>>03910000
                                                               <<01869>>03915000
   @BUF := BUFBASE + LOGBUFF(BUFUSED)*RECSIZE;                 <<01869>>03920000
   @DBUF:=@BUF;                                                <<01869>>03925000
   @BBUF:=2*@BUF;                                              <<01869>>03930000
   BUF := "  ";                                                <<01869>>03935000
   MOVE BUF(1) := BUF, (LOGBUFF(BSPACE)*RECSIZE-1);            <<01869>>03940000
   LOGBUFF(BSPACE):=LOGBUFF(BSPACE)-LOGICAL(J);                <<01869>>03945000
   LOGBUFF(BUFUSED) := LOGBUFF(BUFUSED) + LOGICAL(J);          <<01869>>03950000
                                                               <<01869>>03955000
   << Will fill the buffer with NULL records. The last record>><<01869>>03960000
   << will be the changelog record.                          >><<01869>>03965000
                                                               <<01869>>03970000
   DO                                                          <<01869>>03975000
      BEGIN                                                    <<01869>>03980000
      DBUF(RNUM):=DLOGBUFF(TRECS):=DLOGBUFF(TRECS)+1D;         <<01869>>03985000
      BUF(DATE):=CALENDAR;                                     <<01869>>03990000
      DBUF(TIME):=CLOCK;                                       <<01869>>03995000
      IF J = 1 THEN                                            <<01869>>04000000
         BEGIN                                                 <<01869>>04005000
         BUF(CODE):=NEXT'CODE;                                 <<01869>>04010000
         MOVE BBUF(LID') := BLOGBUFF(LOGID), (8);              <<01869>>04015000
         BUF(DATE):=CALENDAR;                                  <<01869>>04020000
         DBUF(TIME):=CLOCK;                                    <<01869>>04025000
         BUF(SEQ):=LOGBUFF(VSETNO);                            <<01869>>04030000
         MOVE BBUF(C'FILE'NAME):=BLOGBUFF(CURRENT'FILE),(35);  <<01869>>04035000
         MOVE BBUF(F'FILE'NAME):=BLOGBUFF(FIRST'FILE),(35);    <<01869>>04040000
         MOVE BBUF(P'FILE'NAME):=BLOGBUFF(NEXT'FILE),(35);     <<01869>>04045000
         BUF(F'FILE'TYPE):=LOGBUFF(F'TYPE);                    <<01869>>04050000
         BUF(P'FILE'TYPE):=LOGBUFF(N'TYPE);                    <<01869>>04055000
         BUF(C'FILE'TYPE):=LOGBUFF(C'TYPE);                    <<01869>>04060000
         DBUF(C'TIME):=DLOGBUFF(FIRST'C'TIME);                 <<01869>>04065000
         BUF(C'DATE):=LOGBUFF(FIRST'C'DATE);                   <<01869>>04070000
         END;                                                  <<01869>>04075000
      X := RECSIZEM1;                                          <<01869>>04080000
      TOS:=-1;                                                 <<01869>>04085000
      DO                                                       <<01869>>04090000
         BEGIN                                                 <<01869>>04095000
         IF X <> CKSUM THEN                                    <<01869>>04100000
         TOS:=TOS XOR BUF(X);                                  <<01869>>04105000
         END UNTIL (X:=X-1) < 0;                               <<01869>>04110000
      BUF(CKSUM):=TOS;                                         <<01869>>04115000
      @BUF := @DBUF := @BUF + RECSIZE;                         <<01869>>04120000
      @BBUF:=2*@BUF;                                           <<01869>>04125000
      END UNTIL (J:=J-1) <= 0;                                 <<01869>>04130000
                                                               <<01869>>04135000
   FLUSH(NULL,FALSE);                                          <<01869>>04140000
   CHECKMSG;                                                   <<01869>>04145000
   END;  << Subroutine FORMAT'NEXT'FILE >>                     <<01869>>04150000
$PAGE "Logging Process -- CheckRecord"                         <<01869>>04155000
SUBROUTINE CHECKRECORD;                                                 04160000
BEGIN                                                                   04165000
                                                                        04170000
<< Validates the individual record format (passed by       >>  <<01869>>04175000
<< CHECKBLOCK) to see if it's in the format of a User      >>  <<01869>>04180000
<< Logging record. DB at LOGBUFF. Used when re-reading the >>  <<01869>>04185000
<< log file to find out where it left off before it was last>>          04190000
<< closed.                                                  >>          04195000
<<                                                          >>          04200000
<<   ENTRY:                                                 >>          04205000
<<     RECPTR - ptr to the current record in the block.     >>          04210000
<<                                                          >>          04215000
<<   EXIT:                                                  >>          04220000
<<     VALID  - TRUE if record is O.K.                      >>          04225000
<<     CURRREC- Total number of good records found so far.  >>          04230000
<<     LAST'REC'FOUND - code field from the last good rec.  >>          04235000
                                                                        04240000
                                                                        04245000
                                                                        04250000
VALID:=TRUE;                                                            04255000
TOS := -1;                                                              04260000
X := RECSIZEM1;                                                <<01869>>04265000
DO                                                                      04270000
   BEGIN                                                                04275000
   IF X <> CKSUM THEN                                                   04280000
   TOS := TOS XOR RECPTR(X);                                            04285000
   END                                                                  04290000
UNTIL (X := X-1) < 0;                                                   04295000
                                                                        04300000
CURRREC := CURRREC + 1D;                                                04305000
                                                                        04310000
IF TOS <> RECPTR(CKSUM) THEN                                            04315000
   BEGIN                                                                04320000
   VALID := FALSE;                                             <<01869>>04325000
   END                                                                  04330000
ELSE                                                                    04335000
   BEGIN <<CKSUM OK>>                                                   04340000
   IF CURRREC = 1D AND RECPTR(CODE) = FIRST'CODE THEN          <<01869>>04345000
      BEGIN                                                    <<01869>>04350000
      CURRREC:=DRECPTR(RNUM);                                  <<01869>>04355000
      DLOGBUFF(RECS'IN'PREV):=CURRREC-1D;                      <<01869>>04360000
      <<SET UP FILE ENTRIES IN LOG COM AREA>>                  <<01869>>04365000
      MOVE BLOGBUFF(PREVIOUS'FILE):=BRECPTR(P'FILE'NAME),(35); <<01869>>04370000
      LOGBUFF(P'TYPE):=RECPTR(P'FILE'TYPE);                    <<01869>>04375000
      MOVE BLOGBUFF(CURRENT'FILE):=BRECPTR(C'FILE'NAME),(35);  <<01869>>04380000
      LOGBUFF(C'TYPE):=RECPTR(C'FILE'TYPE);                    <<01869>>04385000
      MOVE BLOGBUFF(FIRST'FILE):=BRECPTR(F'FILE'NAME),(35);    <<01869>>04390000
      LOGBUFF(F'TYPE):=RECPTR(F'FILE'TYPE);                    <<01869>>04395000
      DLOGBUFF(FIRST'C'TIME):=DRECPTR(C'TIME);                 <<01869>>04400000
      LOGBUFF(FIRST'C'DATE):=RECPTR(C'DATE);                   <<01869>>04405000
      LOGBUFF(VSETNO) := Q'VSETNO := RECPTR(SEQ);              <<01869>>04410000
      END                                                      <<01869>>04415000
   ELSE                                                        <<01869>>04420000
      IF CURRREC <> DRECPTR(RNUM) THEN VALID:=FALSE;                    04425000
   END;                                                        <<01869>>04430000
                                                                        04435000
                                                                        04440000
                                                               <<01869>>04445000
   IF RECPTR(CODE).(8:8) = OPEN  THEN                          <<01869>>04450000
   IF LOGBUFF(USERNO) <= RECPTR(LNUM)                          <<01869>>04455000
      THEN LOGBUFF(USERNO) := RECPTR(LNUM) + 1;                <<01869>>04460000
   LAST'REC'CODE := RECPTR(CODE).(8:8);                        <<01869>>04465000
                                                               <<01869>>04470000
                                                                        04475000
END;   << Subroutine CHECKRECORD >>                                     04480000
$PAGE "Logging Process -- CheckBlock"                          <<01869>>04485000
SUBROUTINE CHECKBLOCK;                                                  04490000
BEGIN                                                                   04495000
                                                                        04500000
                                                                        04505000
<< Validates the block of Log records read while Restarting. >><<01869>>04510000
<< DB at LOGBUFF.                                            >>         04515000
<<                                                           >>         04520000
<<  ENTRY:                                                   >>         04525000
<<    RECPTR - ptr to first record of the block.             >>         04530000
<<                                                           >>         04535000
<<  EXIT:                                                    >>         04540000
<<    I      - # good records found in the block.            >>         04545000
<<    RECPTR - ptr to last good record + 1.                  >>         04550000
<<    VALID  - TRUE if all records O.K. in the block.        >>         04555000
                                                                        04560000
                                                                        04565000
VALID := TRUE;                                                          04570000
I := 0;                                                                 04575000
DO                                                                      04580000
   BEGIN                                                                04585000
   CHECKRECORD;                                                         04590000
   IF VALID THEN                                                        04595000
      BEGIN                                                             04600000
      @RECPTR := @RECPTR + RECSIZE;                            <<01869>>04605000
      @DRECPTR := @RECPTR;                                              04610000
      @BRECPTR:=2*@RECPTR;                                     <<01869>>04615000
      END;                                                              04620000
   END                                                                  04625000
UNTIL NOT VALID OR (I:=I+1) >= BLKFACTOR;                               04630000
                                                                        04635000
END;   << Subroutine CHECKBLOCK >>                                      04640000
$PAGE "Logging Process -- WakeUp'"                             <<01869>>04645000
SUBROUTINE WAKEUP';                                                     04650000
                                                                        04655000
                                                                        04660000
<< Wakes up any sleeping user processes after a request >>              04665000
<< for service has been completed. DB at LOGBUFF. Will  >>              04670000
<< loop thru the user entries of the LOGBUFF and  wake  >>              04675000
<< up any sleeping user processes until the SLPCNT is   >>              04680000
<< zero. These users were put to sleep by FLUSH which   >>     <<01869>>04685000
<< in turn is called from the user logging intrinsics.  >>     <<01869>>04690000
<< DB at LOGBUFF.                                       >>     <<01869>>04695000
                                                                        04700000
                                                                        04705000
BEGIN                                                                   04710000
                                                                        04715000
<< Any user processes waiting ?? >>                                     04720000
                                                                        04725000
INDEX:=LOGBUFF(UHEAD);                                                  04730000
WHILE LOGBUFF(SLPCT) > 0 DO                                             04735000
   BEGIN                                                                04740000
   IF LOGBUFF(WSTATE)=INACT THEN                                        04745000
      BEGIN                                                             04750000
      AWAKE(LOGBUFF(UPIN),%20,0);                                       04755000
$IF X1=ON                                                      <<01874>>04760000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>04770000
$IF                                                            <<01874>>04775000
      LOGBUFF(WSTATE):=ACT;                                             04780000
      LOGBUFF(SLPCT):=LOGBUFF(SLPCT)-1;                                 04785000
      END;                                                              04790000
   INDEX:=LOGBUFF(NENTRY);                                              04795000
   IF INDEX = NULL THEN INDEX:=LOGBUFF(UHEAD);                          04800000
   END;                                                                 04805000
                                                                        04810000
END;   << Subroutine WAKEUP' >>                                         04815000
$PAGE "Logging Process -- GetFname"                            <<01869>>04820000
SUBROUTINE GETFNAME;                                           <<01869>>04825000
                                                               <<01869>>04830000
<< Gets logging file name from the LIDTAB. DB at stack.      >><<01869>>04835000
<< Used only for starting/restarting log files - not during  >><<01869>>04840000
<< a changelog.                                              >><<01869>>04845000
<<                                                           >>         04850000
<< EXIT:                                                     >>         04855000
<<   FNAME - log file name.                                  >>         04860000
<<   ALLOW'CHANGELOG - TRUE if :CHANGELOG is allowed.          <<01869>>04865000
                                                               <<01869>>04870000
BEGIN                                                          <<01869>>04875000
                                                               <<01869>>04880000
FNAME := 0;                                                    <<01869>>04885000
MOVE FNAME(1) := FNAME, (35);                                  <<01869>>04890000
FENTRY(BENTRY'(LGNAME),,FNAME,,,I);                            <<01869>>04895000
IF ENTRY'(LGTYPE)<>DISC THEN FNAME(8):=0;                      <<01869>>04900000
                                                               <<01869>>04905000
ALLOW'CHANGELOG := I.TYP'ALLOW'CHANGE;                         <<01869>>04910000
                                                               <<01869>>04915000
END;   << Subroutine GETFNAME >>                               <<01869>>04920000
$PAGE  "Logging Process -- AbEnd"                              <<01869>>04925000
SUBROUTINE ABEND(MSG',LOGGING'TYPE,TYPE);                      <<01869>>04930000
   VALUE MSG',LOGGING'TYPE,TYPE;                               <<01869>>04935000
   INTEGER MSG',LOGGING'TYPE,TYPE;                             <<01869>>04940000
BEGIN                                                          <<01869>>04945000
                                                               <<01869>>04950000
<< Called when an error occurs when starting/restarting or  >> <<01869>>04955000
<< changing log files. DB at stack.                         >> <<01869>>04960000
                                                               <<01869>>04965000
DEL'LOCKWORD(FNAME);  << No lockword for messages >>           <<01869>>04970000
                                                               <<01869>>04975000
                                                               <<01869>>04980000
ULERRCODE := MSG';                                             <<01869>>04985000
CASE TYPE OF                                                   <<01869>>04990000
   BEGIN                                                       <<01869>>04995000
   << 0 >> GENMSG(SETNO,MSG',,,,,,,0);                         <<01869>>05000000
   << 1 >> GENMSG(SETNO,MSG',0,@PROCNAME,,,,,0);               <<01869>>05005000
   << 2 >> GENMSG(SETNO,MSG',0,@FNAME,@PROCNAME,,,,0);         <<01869>>05010000
   << 3 >> GENMSG(SETNO,MSG',0,@BFNAME,@PROCNAME,,,,0);        <<01869>>05015000
   << 4 >> GENMSG(SETNO,MSG',0,@PROCNAME,@OLD'FILE'NAME,,,,0); <<01869>>05020000
   END;                                                        <<01869>>05025000
                                                               <<01869>>05030000
IF SWITCH'FLAG THEN                                            <<01869>>05035000
   BEGIN                                                       <<01869>>05040000
   DEL;         << Remove return address >>                    <<01869>>05045000
   GO CHANGELOG'ERROR'RECOVERY;                                <<01869>>05050000
   END;                                                        <<01869>>05055000
                                                               <<01869>>05060000
RELENTRY(TABINDEX',0);     << Get rid of LOGTAB entry >>       <<01869>>05065000
RELSIR(LOGSIR,A);                                              <<01869>>05070000
                                                               <<01869>>05075000
FCLOSE(FILENO,0,0);                                            <<01869>>05080000
IF LOGGING'TYPE <> DISC THEN                                   <<01869>>05085000
   FCLOSE(BUFFILENO,4,0);    << Delete buffer file >>          <<01869>>05090000
                                                               <<01869>>05095000
IF RESTART' THEN                                               <<01869>>05100000
   MSGNO := CANTRESTART                                        <<01869>>05105000
ELSE                                                           <<01869>>05110000
   MSGNO := CANTSTART;                                         <<01869>>05115000
                                                               <<01869>>05120000
DEL;            << Get rid of return address >>                <<01869>>05125000
GO OUT;                                                        <<01869>>05130000
                                                               <<01869>>05135000
END;     << Subroutine ABEND >>                                <<01869>>05140000
                                                               <<01869>>05145000
$PAGE "Logging Process -- AbEnd'"                              <<01869>>05150000
SUBROUTINE ABEND'(MSG',FNUM,LOGGING'TYPE,TYPE);                <<01869>>05155000
   VALUE MSG',FNUM,LOGGING'TYPE,TYPE;                          <<01869>>05160000
   INTEGER MSG',FNUM,LOGGING'TYPE,TYPE;                        <<01869>>05165000
BEGIN                                                          <<01869>>05170000
                                                               <<01869>>05175000
<< Same as ABEND, but also prints the file system error.     >><<01869>>05180000
                                                               <<01869>>05185000
FCHECK(FNUM,ERRCODE);                                          <<01869>>05190000
GENMSG(FSSETNO,ERRCODE,,,,,,,0);                               <<01869>>05195000
ABEND(MSG',LOGGING'TYPE,TYPE);                                 <<01869>>05200000
                                                               <<01869>>05205000
END;    << Subroutine ABEND' >>                                <<01869>>05210000
                                                               <<01869>>05215000
$PAGE  "Logging Process -- Open'Serial'Logfile"                <<01869>>05220000
SUBROUTINE OPEN'SERIAL'LOGFILE;                                         05225000
BEGIN                                                                   05230000
                                                                        05235000
<< Will open a serial log file. If any errors are detected,  >>         05240000
<< will print message to the console and go to OUT. DB at    >>         05245000
<< stack.                                                    >>         05250000
<<                                                           >>         05255000
<<   ENTRY:                                                  >>         05260000
<<     Has the LOGSIR.                                       >>         05265000
<<     ENTRY'    - copy of the LOGTAB entry.                 >>         05270000
<<     TABINDEX' - entry offset within the LOGTAB for ENTRY'.>>         05275000
<<     RESTART'  - TRUE if currently restarting a log process>>         05280000
<<     SWITCH'FLAG-TRUE if currently processing a changelog. >>         05285000
<<                                                           >>         05290000
<<   EXIT:                                                   >>         05295000
<<     DEV     - device name where log file resides.         >>         05300000
<<     ERRCODE - if error, file system error number.         >>         05305000
<<     FNAME   - log file name.                              >>         05310000
<<     FILENO  - file number of serial log file.             >>         05315000
<<     TAPE'   - TRUE if log file on tape device.            >>         05320000
<<     TAPEDEV - ldev # for log file if it's on a tape device>>         05325000
<<     ULERRCODE- if error, the user logging error number    >><<01869>>05330000
                                                                        05335000
TAPE' := FALSE;                                                <<01869>>05340000
NOTIFIED:=FALSE;                                               <<01869>>05345000
ABNORMAL'EXIT:=FALSE;                                          <<01869>>05350000
FORMATTED'TRAILER := FALSE;                                    <<01869>>05355000
FREE'LAST'EXTENT := FALSE;                                     <<01869>>05360000
FIRST'TAPE'BLOCK := TRUE;                                      <<01869>>05365000
                                                               <<01869>>05370000
DEV := " ";                                                    <<01869>>05375000
MOVE DEV(1) := DEV, (7);                                       <<01869>>05380000
DEV(8) := 0;                                                   <<01869>>05385000
                                                                        05390000
                                                                        05395000
ERRCODE := 0;                                                           05400000
ULERRCODE := 0;                                                <<01869>>05405000
   CASE ENTRY'(LGTYPE) OF                                      <<01869>>05410000
   BEGIN                                                       <<01869>>05415000
   <<0>>  ;         << Disc - never get here >>                <<01869>>05420000
                                                                        05425000
   <<1>>  BEGIN    << Tape log file >>                         <<01869>>05430000
          MOVE DEV := "TAPE ";                                 <<01869>>05435000
          TAPE' := TRUE;                                       <<01869>>05440000
          END;     << Tape log file >>                         <<01869>>05445000
                                                                        05450000
   <<2>>  MOVE DEV := "SDISC ";                                <<01869>>05455000
   <<3>>  MOVE DEV := "CTAPE ";                                <<01869>>05460000
   END;                                                        <<01869>>05465000
                                                               <<01869>>05470000
IF NOT SWITCH'FLAG THEN                                        <<01869>>05475000
   GETFNAME;                                                   <<01869>>05480000
MOVE FORMS:=".,,,,; ";                                                  05485000
                                                               <<01869>>05490000
IF SWITCH'FLAG THEN                                            <<01869>>05495000
   GENMSG(SETNO,MOUNT'NEXT,0,@DEV,@PROCNAME,,,,0);             <<01869>>05500000
                                                               <<01869>>05505000
<< Log file is ascii,fixed labeled tape (no :FILE),default>>   <<01869>>05510000
<< access, read/write, no multi-rec, no buf.                 >><<01869>>05515000
                                                               <<01869>>05520000
FILENO := FOPEN(FNAME,%3004,%404,RECSIZE,DEV,FORMS,,BLKFACTOR);<<01869>>05525000
IF <> THEN             << Open failure >>                               05530000
   BEGIN                                                                05535000
   DEL'LOCKWORD(FNAME);                                        <<01869>>05540000
   IF SWITCH'FLAG THEN                                         <<01869>>05545000
      ABEND'(NLOGOPENFAIL,FILENO,TAPE,PRINT'FNAME)             <<01869>>05550000
   ELSE                                                        <<01869>>05555000
      ABEND'(TOPENFAILED,FILENO,TAPE,PRINT'FNAME);             <<01869>>05560000
   END;                                                                 05565000
                                                                        05570000
DEL'LOCKWORD(FNAME);                                           <<01869>>05575000
FFILEINFO(FILENO, GET'LDEV,TAPEDEV);                           <<01869>>05580000
IF < THEN                                                      <<01869>>05585000
   BEGIN                                                       <<01869>>05590000
   IF SWITCH'FLAG THEN                                         <<01869>>05595000
      ABEND'(NLOGOPENFAIL,FILENO,TAPE,PRINT'FNAME)             <<01869>>05600000
   ELSE                                                        <<01869>>05605000
      ABEND'(TOPENFAILED,FILENO,TAPE,PRINT'FNAME);             <<01869>>05610000
   END;                                                        <<01869>>05615000
                                                               <<01869>>05620000
<< If we're doing a log start to tape, then we want to do >>   <<01869>>05625000
<< a dummy write to force the HDR labels to be written    >>   <<01869>>05630000
<< now. This must be done to protect ourselves from a     >>   <<01869>>05635000
<< powerfail before the HDRs get to tape. The labeled tape>>   <<01869>>05640000
<< interface will never tell the F.S. if it got powerfail,>>   <<01869>>05645000
<< therefore if we wait until we start flushing buffers to>>   <<01869>>05650000
<< tape we will never know if there was a powerfail, and  >>   <<01869>>05655000
<< would never be able to recover. By performing an FWRITE>>   <<01869>>05660000
<< now, if we get any error at all, we will not let the   >>   <<01869>>05665000
<< process start.                                         >>   <<01869>>05670000
                                                               <<01869>>05675000
IF ENTRY'(LGTYPE)=TAPE AND ((NOT RESTART') LOR SWITCH'FLAG)    <<01869>>05680000
   THEN                                                        <<01869>>05685000
   BEGIN                                                       <<01869>>05690000
   FWRITE(FILENO,BUFFAREA,ZERO'LENGTH,NORMAL'WRITE);           <<01869>>05695000
   IF <> THEN                                                  <<01869>>05700000
      BEGIN                                                    <<01869>>05705000
      IF SWITCH'FLAG THEN                                      <<01869>>05710000
         ABEND'(NEWFWRITEERROR,FILENO,TAPE,PRINT'FNAME)        <<01869>>05715000
      ELSE                                                     <<01869>>05720000
         ABEND'(FWRITEERROR,FILENO,TAPE,PRINT'FNAME);          <<01869>>05725000
      END;                                                     <<01869>>05730000
   END;                                                        <<01869>>05735000
                                                                        05740000
IF NOT RESTART' AND                                            <<01869>>05745000
   (ENTRY'(LGTYPE) = SDISC LOR ENTRY'(LGTYPE) = CTAPE) OR      <<01869>>05750000
   (Q'NEWTYPE = SDISC LOR Q'NEWTYPE = CTAPE) AND SWITCH'FLAG   <<01869>>05755000
   THEN                                                        <<01869>>05760000
   BEGIN                                                       <<01869>>05765000
   << Need to issue a special write request for the first    >><<01869>>05770000
   << write. This will cause the Serial Disc interface to    >><<01869>>05775000
   << post an EOD marker to the gap table so that recovery   >><<01869>>05780000
   << will be possible in the event of a system crash.       >><<01869>>05785000
                                                               <<01869>>05790000
   FWRITE(FILENO,BUFFAREA,ZERO'LENGTH,SPECIAL'WRITE);          <<01869>>05795000
   IF <> THEN                                                  <<01869>>05800000
      BEGIN                                                    <<01869>>05805000
      IF SWITCH'FLAG THEN                                      <<01869>>05810000
         ABEND'(NEWFWRITEERROR,FILENO,TAPE,PRINT'FNAME)        <<01869>>05815000
      ELSE                                                     <<01869>>05820000
         ABEND'(FWRITEERROR,FILENO,TAPE,PRINT'FNAME);          <<01869>>05825000
      END;                                                     <<01869>>05830000
   END;                                                        <<01869>>05835000
                                                               <<01869>>05840000
END;       << Subroutine OPEN'SERIAL'LOGFILE >>                         05845000
$PAGE "Logging Process -- Open'Buffer'File"                    <<01869>>05850000
SUBROUTINE OPEN'BUFFER'FILE;                                            05855000
BEGIN                                                                   05860000
                                                               <<01869>>05865000
<< Will open a disc buffer file - ULOGxxxx.PUB.SYS to be used>>         05870000
<< with a serial log file. After successfully opening, will  >>         05875000
<< close it to make it a permanent file (need this file for  >>         05880000
<< system crashes in order to perform warmstart recovery).   >>         05885000
<< Will then re-open the file, set EOF to the file limit (to >>         05890000
<< order to recover the data during recovery). This file will>>         05895000
<< be treated internally as a circular queue. If any errors  >>         05900000
<< are detected, will print message on console and go OUT.   >>         05905000
<< DB at stack.                                              >>         05910000
<<                                                           >>         05915000
<< ENTRY:                                                    >>         05920000
<<   Has the LOGSIR.                                         >>         05925000
<<   ENTRY'    - entry from the LOGTAB for this process.     >>         05930000
<<   SWITCH'FLAG- TRUE if currently processing a changelog.  >>         05935000
<<                                                           >>         05940000
<< EXIT:                                                     >>         05945000
<<   ADDR      - sector address of disc buffer file.         >>         05950000
<<   BFNAME    - disc buffer file name.                      >>         05955000
<<   BUFFILENO - file number of disc buffer file.            >>         05960000
<<   DEV       - device name ("DISC").                       >>         05965000
<<   DISCLDEV  - ldev for the disc buffer file.              >><<01869>>05970000
<<   DTEMP     - # records in disc buffer file.              >>         05975000
<<   ENTRY'    - global values updated.                      >>         05980000
<<   ERRCODE   - if error, file system error number.         >>         05985000
<<   FLAB      - file label of the disc buffer file.         >>         05990000
<<   FLABADDR  - address of file label.                      >><<01869>>05995000
<<   FLABLDEV  - ldev of file label.                         >><<01869>>06000000
<<   LIMIT     - # records in the buffer file.               >>         06005000
<<   NUMEXT    - max # extents in disc buffer file (always 1)>>         06010000
<<   TEMP      - current buffer number.                      >>         06015000
<<   ULERRCODE - if error, user logging error number         >><<01869>>06020000
                                                                        06025000
                                                                        06030000
                                                                        06035000
                                                               <<01869>>06040000
   MOVE BFNAME:="  ";                                                   06045000
   MOVE BFNAME(1):=BFNAME,(14);                                         06050000
   MOVE DEV:="DISC ";                                          <<01869>>06055000
                                                               <<01869>>06060000
   << Format the disc buffer name -- ULOGxxxx.PUB.SYS >>       <<01869>>06065000
                                                               <<01869>>06070000
   MOVE BFNAME:=BENTRY'(BNAME),(8);            <<BUFFER NAME>>          06075000
                                                                        06080000
NEXT'BUFNUM:                                                            06085000
   ERRCODE:=0;                                                 <<01869>>06090000
   ULERRCODE := 0;                                             <<01869>>06095000
   MOVE'FROM'DSEG(@TEMP,LOGDST,BUFNUM,1);                      <<01869>>06100000
   TEMP:=TEMP+1;                                               <<01869>>06105000
   IF TEMP > 9999 THEN TEMP := 0;   << Max of 4 chars >>       <<01869>>06110000
   MOVE'TO'DSEG(LOGDST,BUFNUM,@TEMP,1);                        <<01869>>06115000
                                                               <<01869>>06120000
   << Format the buffer file name >>                                    06125000
                                                                        06130000
   MOVE BFNAME(4):=ZEROS,(4);                                  <<01869>>06135000
   ASCII(TEMP,-10,BFNAME(7));                                  <<01869>>06140000
                                                               <<01869>>06145000
   MOVE BFNAME(8):=".PUB.SYS ";                                         06150000
   MOVE BENTRY'(BNAME):=BFNAME,(8);                                     06155000
                                                                        06160000
   << Open a new buffer file >>                                         06165000
                                                                        06170000
                                                               <<01869>>06175000
   << Buffer file: ascii, new, fixed, no :FILE, read/write, >> <<01869>>06180000
   << multi-rec, no buf, exc.                               >> <<01869>>06185000
                                                               <<01869>>06190000
   BUFFILENO := FOPEN(BFNAME,%2004,%524,RECSIZE,DEV,,,,,       <<01869>>06195000
                      640D,1,1);                               <<01869>>06200000
   IF <> THEN                                                  <<01869>>06205000
      BEGIN                                                             06210000
      FCHECK(BUFFILENO,ERRCODE);                                        06215000
      IF ERRCODE = DUP'FILENAME THEN                                    06220000
         GO NEXT'BUFNUM                                                 06225000
      ELSE                                                              06230000
         BEGIN                                                          06235000
         IF SWITCH'FLAG THEN                                   <<01869>>06240000
            ABEND'(NEWBOPENFAIL,BUFFILENO,TAPE,PRINT'BFNAME)   <<01869>>06245000
         ELSE                                                  <<01869>>06250000
            ABEND'(BOPENFAILED,BUFFILENO,TAPE,PRINT'BFNAME);   <<01869>>06255000
         END;                                                           06260000
      END;                                                              06265000
                                                                        06270000
   FCLOSE(BUFFILENO,1,0);   << Save as a permanent file >>              06275000
   IF <> THEN                                                           06280000
      BEGIN                                                             06285000
      FCHECK(BUFFILENO,ERRCODE);                                        06290000
      IF ERRCODE = DUP'FILENAME                                         06295000
         THEN GO NEXT'BUFNUM                                            06300000
      ELSE                                                              06305000
         BEGIN                                                          06310000
         IF SWITCH'FLAG THEN                                   <<01869>>06315000
            ABEND'(NEWBOPENFAIL,BUFFILENO,TAPE,PRINT'BFNAME)   <<01869>>06320000
         ELSE                                                  <<01869>>06325000
            ABEND'(BOPENFAILED,BUFFILENO,TAPE,PRINT'BFNAME);   <<01869>>06330000
         END;                                                           06335000
      END;                                                              06340000
                                                               <<01869>>06345000
   BUFFILENO := FOPEN(BFNAME,%2005,%524,RECSIZE,DEV);          <<01869>>06350000
   IF <> THEN                                                  <<01869>>06355000
      BEGIN                                                             06360000
      IF SWITCH'FLAG THEN                                      <<01869>>06365000
         ABEND'(NEWBOPENFAIL,BUFFILENO,TAPE,PRINT'BFNAME)      <<01869>>06370000
      ELSE                                                     <<01869>>06375000
         ABEND'(BOPENFAILED,BUFFILENO,TAPE,PRINT'BFNAME);      <<01869>>06380000
      END;                                                              06385000
                                                               <<01869>>06390000
   << Move file record ptr to last record of the file. >>               06395000
                                                                        06400000
   FWRITEDIR(BUFFILENO,BUFFAREA,RECSIZE,639D);                 <<01869>>06405000
   IF <> THEN                                                  <<01869>>06410000
      BEGIN                                                             06415000
      IF SWITCH'FLAG THEN                                      <<01869>>06420000
         ABEND'(NEWBWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME)    <<01869>>06425000
      ELSE                                                     <<01869>>06430000
         ABEND'(BWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME);      <<01869>>06435000
      END;                                                              06440000
                                                               <<01869>>06445000
   << Now set EOF to protect any data from system crashes. >>           06450000
                                                                        06455000
   FCONTROL(BUFFILENO,SET'EOF,DUMMY);                          <<01869>>06460000
   IF <> THEN                                                  <<01869>>06465000
      BEGIN                                                             06470000
      IF SWITCH'FLAG THEN                                      <<01869>>06475000
         ABEND'(NEWBWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME)    <<01869>>06480000
      ELSE                                                     <<01869>>06485000
         ABEND'(BWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME);      <<01869>>06490000
      END;                                                              06495000
                                                               <<01869>>06500000
   FGETINFO(BUFFILENO,,,,,,FLABLDEV,,,,,LIMIT,,,,,,,,FLABADDR);<<01869>>06505000
   IF <> THEN                                                  <<01869>>06510000
      BEGIN                                                             06515000
      IF SWITCH'FLAG THEN                                      <<01869>>06520000
         ABEND'(NEWBWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME)    <<01869>>06525000
      ELSE                                                     <<01869>>06530000
         ABEND'(BWRITEERROR,BUFFILENO,TAPE,PRINT'BFNAME);      <<01869>>06535000
      END;                                                              06540000
                                                               <<01869>>06545000
   DTEMP:=LIMIT;                                               <<01869>>06550000
                                                                        06555000
   << Get sector offset to begining of data of the file. >>             06560000
                                                                        06565000
   IF FLABIO(FLABLDEV,FLABADDR,READ,FLAB) <> 0  THEN           <<01869>>06570000
      BEGIN                                                             06575000
      IF SWITCH'FLAG THEN                                      <<01869>>06580000
         ABEND(NEWBWRITEERROR,TAPE,PRINT'BFNAME)               <<01869>>06585000
      ELSE                                                     <<01869>>06590000
         ABEND(BWRITEERROR,TAPE,PRINT'BFNAME);                 <<01869>>06595000
      END;                                                              06600000
                                                               <<01869>>06605000
                                                               <<01869>>06610000
   NUMEXT := 1;                                                <<01869>>06615000
   EXTNUM := 1;                                                <<01869>>06620000
   ADDR := DFLAB(21+EXTNUM);                                   <<01869>>06625000
   DISCLDEV := FLABLDEV;                                       <<01869>>06630000
   ADDR1.(0:8) := 0;         << Get rid of ldev >>             <<01869>>06635000
   ADDR := ADDR + DOUBLE(FLAB(OFFSET'TO'DATA));                <<01869>>06640000
   ENTRY'(LGDEV) := DISCLDEV;                                  <<01869>>06645000
   DENTRY'(LGADDR):=ADDR;                                               06650000
   MOVE BENTRY'(BNAME) := BFNAME, (8);                         <<01869>>06655000
END;       << Subroutine OPEN'BUFFER'FILE >>                            06660000
$PAGE  "Logging Process -- Open'Disc'Logfile"                  <<01869>>06665000
SUBROUTINE OPEN'DISC'LOGFILE;                                           06670000
BEGIN                                                                   06675000
                                                                        06680000
<< Will open the specified disc log file. This file must have>>         06685000
<< been built by the user prior to (re)starting this log     >>         06690000
<< process. Will extract various info - # extents, extent    >>         06695000
<< size, disc address, etc. - that will be used by this log  >>         06700000
<< process to manage the file. DB is at stack.               >>         06705000
<<                                                           >>         06710000
<<                                                           >>         06715000
<< ENTRY:                                                    >>         06720000
<<   Has LOGSIR.                                             >>         06725000
<<   ENTRY'   - entry from the LOGTAB for this log process.  >>         06730000
<<   RESTART' - TRUE if currently restarting the log process.>>         06735000
<<   TABINDEX'- entry offset within the LOGTAB for this entry>>         06740000
<<                                                           >>         06745000
<< EXIT:                                                     >>         06750000
<<   ADDR     - disc address of current extent.              >>         06755000
<<   BLOCKNUM - last block of the current extent.            >>         06760000
<<   DISCLDEV - Ldev for current extent.                     >><<01869>>06765000
<<   DTEMP    - # records in extent.                         >>         06770000
<<   EXTNUM   - current extent number.                       >>         06775000
<<   FNAME    - name of this log file.                       >>         06780000
<<   FLAB     - file label of disc log file.                 >>         06785000
<<   FLABADDR - address of file label.                       >><<01869>>06790000
<<   FLABLDEV - ldev of file label.                          >><<01869>>06795000
<<   FILENO   - file number of the disc log file.            >>         06800000
<<   NUMEXT   - max # of extents.                            >>         06805000
<<   ULERRCODE- if error, user logging error number          >><<01869>>06810000
                                                               <<01869>>06815000
                                                                        06820000
TAPE' := FALSE;                                                <<01869>>06825000
NOTIFIED:=FALSE;                                               <<01869>>06830000
ABNORMAL'EXIT:=FALSE;                                          <<01869>>06835000
FORMATTED'TRAILER := FALSE;                                    <<01869>>06840000
FREE'LAST'EXTENT := FALSE;                                     <<01869>>06845000
                                                                        06850000
DEV := " ";                                                    <<01869>>06855000
MOVE DEV(1) := DEV, (7);                                       <<01869>>06860000
DEV(8) := 0;                                                   <<01869>>06865000
                                                                        06870000
ERRCODE := 0;                                                           06875000
ULERRCODE := 0;                                                <<01869>>06880000
                                                               <<01869>>06885000
   MOVE DEV:="DISC ";                                                   06890000
   IF NOT SWITCH'FLAG THEN GETFNAME;                           <<01869>>06895000
                                                                        06900000
   << Disc log file: ascii, old, no :FILE, read/write, ear,  >>         06905000
   <<                mr, nobuf.                              >>         06910000
                                                                        06915000
   IF NOT SWITCH'FLAG THEN                                     <<01869>>06920000
   BEGIN                                                       <<01869>>06925000
   FILENO := FOPEN(FNAME,%2005,%624,RECSIZE,DEV,,,BLKFACTOR);  <<01869>>06930000
   IF <> THEN                                                           06935000
      BEGIN                                                             06940000
      DEL'LOCKWORD(FNAME);                                     <<01869>>06945000
      IF SWITCH'FLAG THEN                                      <<01869>>06950000
        ABEND'(NLOGOPENFAIL,FILENO,DISC,PRINT'FNAME)           <<01869>>06955000
      ELSE                                                     <<01869>>06960000
         ABEND'(UOPENFAILED,FILENO,DISC,PRINT'FNAME);          <<01869>>06965000
      END;                                                              06970000
      END                                                      <<01869>>06975000
   ELSE                                                        <<01869>>06980000
      BEGIN                                                    <<01869>>06985000
                                                               <<01869>>06990000
      << Performing a changelog >>                             <<01869>>06995000
                                                               <<01869>>07000000
      EXCHANGEDB(BUFDST);                                      <<01869>>07005000
      IF Q'OLDTYPE <> DISC THEN                                <<01869>>07010000
         LIMIT := DEFAULT'LIMIT D                              <<01869>>07015000
      ELSE                                                     <<01869>>07020000
         LIMIT := DLOGBUFF(OLD'LIMIT);                         <<01869>>07025000
                                                               <<01869>>07030000
      IF Q'OLDTYPE <> DISC THEN                                <<01869>>07035000
         NUMEXT := DEFAULT'NUMEXT                              <<01869>>07040000
      ELSE                                                     <<01869>>07045000
         NUMEXT := LOGBUFF(OLD'NUMEXT);                        <<01869>>07050000
      EXCHANGEDB(0);                                           <<01869>>07055000
                                                               <<01869>>07060000
TRY'SMALLER'SIZE'ON'CHANGELOG:                                 <<01869>>07065000
                                                               <<01869>>07070000
      FILENO:=FOPEN(FNAME, %2004,%624,RECSIZE,                 <<01869>>07075000
              DEV,,,BLKFACTOR,NO'BUF,LIMIT,NUMEXT,,LOG);       <<01869>>07080000
      IF <> THEN                                               <<01869>>07085000
         BEGIN                                                 <<01869>>07090000
         FCHECK(FILENO,ERRCODE);                               <<01869>>07095000
         IF ERRCODE = OUT'OF'ACCOUNT'SPACE OR                  <<01869>>07100000
            ERRCODE = OUT'OF'GROUP'SPACE THEN                  <<01869>>07105000
            BEGIN                                              <<01869>>07110000
            LIMIT := LIMIT/2D;                                 <<01869>>07115000
            IF LIMIT >= LOWEST'LIMIT D THEN                    <<01869>>07120000
               GO TRY'SMALLER'SIZE'ON'CHANGELOG;               <<01869>>07125000
            ABEND'(NEWDISCSPACE,FILENO,DISC,PRINT'FNAME);      <<01869>>07130000
            END;                                               <<01869>>07135000
         ABEND'(NLOGOPENFAIL,FILENO,DISC,PRINT'FNAME);         <<01869>>07140000
         END;                                                  <<01869>>07145000
                                                               <<01869>>07150000
         << Make the new log file permenate >>                 <<01869>>07155000
                                                               <<01869>>07160000
         LOGCLOSE(FILENO,1,0);                                 <<01869>>07165000
         IF <> THEN                                            <<01869>>07170000
            BEGIN                                              <<01869>>07175000
            ABEND'(NEWLOGCLOSEFAIL,FILENO,DISC,PRINT'FNAME);   <<01869>>07180000
            END;                                               <<01869>>07185000
                                                               <<01869>>07190000
         << Now reopen the file to see what we got.          >><<01869>>07195000
                                                               <<01869>>07200000
         FILENO:=FOPEN(FNAME,%2005,%624,RECSIZE,DEV,,,BLKFACTOR);       07205000
         IF <> THEN                                            <<01869>>07210000
            BEGIN                                              <<01869>>07215000
            ABEND'(NLOGOPENFAIL,FILENO,DISC,PRINT'FNAME);      <<01869>>07220000
            END;                                               <<01869>>07225000
      END;                                                     <<01869>>07230000
                                                               <<01869>>07235000
DEL'LOCKWORD(FNAME);                                           <<01869>>07240000
   IF SWITCH'FLAG THEN                                         <<01869>>07245000
      BEGIN                                                    <<01869>>07250000
      EXCHANGEDB(BUFDST);                                      <<01869>>07255000
      DLOGBUFF(OLD'LIMIT):=LIMIT;                              <<01869>>07260000
      LOGBUFF(OLD'NUMEXT):=NUMEXT;                             <<01869>>07265000
      LOGBUFF(LASTEXT'):=NUMEXT;                               <<01869>>07270000
      EXCHANGEDB(0);                                           <<01869>>07275000
      END;                                                     <<01869>>07280000
   FGETINFO(FILENO,,,,,,FLABLDEV,,,,,                          <<01869>>07285000
            LIMIT,,,,EXTSIZE,NUMEXT,,,FLABADDR);               <<01869>>07290000
   IF <> THEN                                                  <<01869>>07295000
      BEGIN                                                             07300000
      IF SWITCH'FLAG THEN                                      <<01869>>07305000
         ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)        <<01869>>07310000
      ELSE                                                     <<01869>>07315000
         ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);          <<01869>>07320000
      END;                                                     <<01869>>07325000
                                                               <<01869>>07330000
                                                               <<01869>>07335000
   FLABADDR1.(0:8) := 0;       << Get rid of ldev >>           <<01869>>07340000
   IF FLABIO(FLABLDEV,FLABADDR,READ,FLAB) <> 0 THEN            <<01869>>07345000
      BEGIN                                                             07350000
      IF SWITCH'FLAG THEN                                      <<01869>>07355000
         ABEND(NEWFLABERROR,DISC,PRINT'FNAME)                  <<01869>>07360000
      ELSE                                                     <<01869>>07365000
         ABEND(FLABELERR,DISC,PRINT'FNAME);                    <<01869>>07370000
      END;                                                              07375000
                                                               <<01869>>07380000
   IF (DFLAB(EOF) <> 0D) AND (NOT RESTART') THEN               <<01869>>07385000
     BEGIN                 << Can't start >>                   <<01869>>07390000
     ABEND(NOTEMPTY,DISC,PRINT'FNAME);                         <<01869>>07395000
     RETURN;                                                            07400000
     END;                                                               07405000
                                                               <<01869>>07410000
   IF RESTART' AND (DFLAB(EOF) >= DFLAB(FLIMIT) - 1D) THEN     <<01869>>07415000
     BEGIN                                                     <<01869>>07420000
     IF SWITCH'FLAG THEN                                       <<01869>>07425000
        ABEND(NEWLOGEOF,DISC,PRINT'FNAME)                      <<01869>>07430000
     ELSE                                                      <<01869>>07435000
        ABEND(LOGFILEEOF,DISC,PRINT'FNAME);                    <<01869>>07440000
     END;                                                               07445000
                                                               <<01869>>07450000
   IF FLAB(FCODE) <> LOG THEN                                  <<01869>>07455000
      BEGIN                                                             07460000
      ABEND(INVALIDFILE,DISC,PRINT'FNAME);                     <<01869>>07465000
      RETURN;                                                           07470000
      END;                                                              07475000
                                                               <<01869>>07480000
   IF FLAB(FBLKSIZE) <> BLKSIZE THEN                           <<01869>>07485000
      BEGIN                                                    <<01869>>07490000
      ABEND(INVALIDFILE,DISC,PRINT'FNAME);                     <<01869>>07495000
      RETURN;                                                           07500000
      END;                                                              07505000
                                                               <<01869>>07510000
   IF DFLAB(FLIMIT) <= DOUBLE(BLKFACTOR) THEN                  <<01869>>07515000
     BEGIN                <<File too small>>                   <<01869>>07520000
     IF SWITCH'FLAG THEN                                       <<01869>>07525000
        ABEND(NEW'TOO'SMALL,DISC,PRINT'FNAME)                  <<01869>>07530000
     ELSE                                                      <<01869>>07535000
        ABEND(TOOSMALL,DISC,PRINT'FNAME);                      <<01869>>07540000
     END;                                                               07545000
                                                               <<01869>>07550000
   << Make sure that the creator of the previous file is also>><<01869>>07555000
   << the creator of this file.                              >><<01869>>07560000
                                                               <<01869>>07565000
   IF SWITCH'FLAG THEN                                         <<01869>>07570000
      BEGIN                                                    <<01869>>07575000
      MOVE BFLAB(CREATOR'ID):=" ";                             <<01869>>07580000
      MOVE BFLAB(CREATOR'ID):=BFLAB(CREATOR'ID),(7);           <<01869>>07585000
   FENTRY'SWITCH(BENTRY'(LGNAME),,,BFLAB(CREATOR'ID));         <<01869>>07590000
      FLAB(F'CKSUM):=0;                                        <<01869>>07595000
      IF FLABIO(FLABLDEV,FLABADDR,WRITE,FLAB) <> 0 THEN        <<01869>>07600000
         BEGIN                                                 <<01869>>07605000
         ABEND(NEWFLABERROR,DISC,PRINT'FNAME);                 <<01869>>07610000
                                                               <<01869>>07615000
         END;                                                  <<01869>>07620000
      END;                                                     <<01869>>07625000
                                                               <<01869>>07630000
   << The first block will be used up by the file label.    >> <<01869>>07635000
                                                               <<01869>>07640000
   DTEMP := DOUBLE(EXTSIZE) - DOUBLE(BLKFACTOR);               <<01869>>07645000
                                                               <<01869>>07650000
   << Want to leave the last record of the last extent free,>> <<01869>>07655000
   << for now, to insure there will be room in the file so  >> <<01869>>07660000
   << proper close information can get posted.              >> <<01869>>07665000
                                                               <<01869>>07670000
   IF NUMEXT = 1 THEN                                          <<01869>>07675000
      BEGIN           << Last extent >>                        <<01869>>07680000
      DTEMP := DTEMP - 1D;                                     <<01869>>07685000
                                                               <<01869>>07690000
      << Check to see if there's room to do this.           >> <<01869>>07695000
      IF DTEMP <= 0D THEN                                      <<01869>>07700000
         BEGIN                                                 <<01869>>07705000
         IF SWITCH'FLAG THEN                                   <<01869>>07710000
            ABEND(NEW'TOO'SMALL,DISC,PRINT'FNAME)              <<01869>>07715000
         ELSE                                                  <<01869>>07720000
            ABEND(TOOSMALL,DISC,PRINT'FNAME);                  <<01869>>07725000
         END;                                                  <<01869>>07730000
                                                               <<01869>>07735000
      END;                                                     <<01869>>07740000
                                                               <<01869>>07745000
                                                               <<01869>>07750000
   IF NOT RESTART' THEN                                                 07755000
      BEGIN                                                             07760000
      << Allocate the first extent to be used for data.      >><<01869>>07765000
      << Calculate the last block number in the extent -     >><<01869>>07770000
      << move the EOF ptr. here.  (FWRITEDIR, FCONTROL)      >><<01869>>07775000
                                                               <<01869>>07780000
      BLOCKNUM := DOUBLE((EXTSIZE-BLKFACTOR)/BLKFACTOR) -1D;   <<01869>>07785000
      IF BLOCKNUM < 0D  THEN BLOCKNUM := 0D;                   <<01869>>07790000
                                                               <<01869>>07795000
      FWRITEDIR(FILENO,BUFFAREA,RECSIZE,BLOCKNUM);             <<01869>>07800000
      IF <> THEN                                               <<01869>>07805000
         BEGIN                                                          07810000
         IF SWITCH'FLAG THEN                                   <<01869>>07815000
            ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)     <<01869>>07820000
         ELSE                                                  <<01869>>07825000
            ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);       <<01869>>07830000
         END;                                                           07835000
                                                                        07840000
      FCONTROL(FILENO,SET'EOF,DUMMY);                          <<01869>>07845000
      IF <> THEN                                               <<01869>>07850000
         BEGIN                                                          07855000
         IF SWITCH'FLAG THEN                                   <<01869>>07860000
            ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)     <<01869>>07865000
         ELSE                                                  <<01869>>07870000
            ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);       <<01869>>07875000
         END;                                                           07880000
                                                               <<01869>>07885000
      << If the first extent is the same size as the         >><<01869>>07890000
      << blocksize, then the above FWRITEDIR will actually   >><<01869>>07895000
      << force the file system to allocate the 2nd extent.   >><<01869>>07900000
      << (The first block would have been used up by the file>><<01869>>07905000
      << label). If this has happened, need to re-read the   >><<01869>>07910000
      << the file label to get the disc address of the 2nd   >><<01869>>07915000
      << extent (and it's ldev).                             >><<01869>>07920000
                                                               <<01869>>07925000
      IF EXTSIZE <= BLKFACTOR THEN                             <<01869>>07930000
         BEGIN                                                 <<01869>>07935000
         IF FLABIO(FLABLDEV,FLABADDR,READ,FLAB) <> 0 THEN      <<01869>>07940000
            BEGIN                                              <<01869>>07945000
            IF SWITCH'FLAG THEN                                <<01869>>07950000
               ABEND(NEWFLABERROR,DISC,PRINT'FNAME)            <<01869>>07955000
            ELSE                                               <<01869>>07960000
               ABEND(FLABELERR,DISC,PRINT'FNAME);              <<01869>>07965000
            END;                                               <<01869>>07970000
                                                               <<01869>>07975000
         EXTNUM := 2;                                          <<01869>>07980000
         IF EXTNUM = NUMEXT THEN                               <<01869>>07985000
            DTEMP := DOUBLE(FLAB(LASTEXT)) - 1D                <<01869>>07990000
         ELSE                                                  <<01869>>07995000
            DTEMP := DOUBLE(FLAB(FEXTSIZE));                   <<01869>>08000000
                                                               <<01869>>08005000
         ADDR := DFLAB(21+EXTNUM);                             <<01869>>08010000
         DISCLDEV := LUN(ADDR1.(0:8),FGETPVINFO(FILENO).(4:4));<<01869>>08015000
         ADDR1.(0:8) := 0;      << Get rid of ldev >>          <<01869>>08020000
         END                                                   <<01869>>08025000
      ELSE                                                     <<01869>>08030000
         BEGIN                                                 <<01869>>08035000
         << This is the normal case, where the extent size is ><<01869>>08040000
         << bigger than the block size.                       ><<01869>>08045000
                                                               <<01869>>08050000
         EXTNUM := 1;                                          <<01869>>08055000
         ADDR := DFLAB(21+EXTNUM);                             <<01869>>08060000
         DISCLDEV := FLABLDEV;                                 <<01869>>08065000
         ADDR1.(0:8) := 0;     << Get rid of ldev >>           <<01869>>08070000
         ADDR := ADDR + DOUBLE(FLAB(OFFSET'TO'DATA));          <<01869>>08075000
                                                               <<01869>>08080000
         IF EXTNUM = NUMEXT THEN                               <<01869>>08085000
            BEGIN                                              <<01869>>08090000
            << FILE HASE ONLY 1 EXTENT,SAVE THE LAST EXTENT>>  <<01869>>08095000
            <<FOR EITHER TRAILER RECORD OR CHANGELOG RECORD>>  <<01869>>08100000
            DTEMP := DOUBLE(FLAB(LASTEXT))-1D;                 <<01869>>08105000
            END                                                <<01869>>08110000
         ELSE                                                  <<01869>>08115000
            DTEMP := DOUBLE(FLAB(FEXTSIZE));                   <<01869>>08120000
            << IF WERE ON THE FIRST EXTENT, THE FIRST BLOCK>>  <<01869>>08125000
            << OF THE FIRST EXTENT WILL BE USED FOR THE    >>  <<01869>>08130000
            << FILE LABEL.                                 >>  <<01869>>08135000
            IF EXTNUM = 1 THEN                                 <<01869>>08140000
               DTEMP := DTEMP - DOUBLE(BLKFACTOR);             <<01869>>08145000
                                                               <<01869>>08150000
         END;                                                  <<01869>>08155000
      END;   << Not restarting the log process >>                       08160000
                                                               <<01869>>08165000
   << If the log process is being restarted, then when the   >><<01869>>08170000
   << log file is re-read, the information about the current >><<01869>>08175000
   << extent, address, etc will be calculated.               >><<01869>>08180000
                                                               <<01869>>08185000
                                                               <<01869>>08190000
END;         << Subroutine OPEN'DISC'LOGFILE >>                         08195000
$PAGE "Logging Process -- Open'Logfile"                        <<01869>>08200000
SUBROUTINE OPEN'LOGFILE;                                                08205000
BEGIN                                                                   08210000
                                                                        08215000
<< Will clear important global variables, get the entry from >>         08220000
<< the LOGTAB for this process, and call the proper subrout. >>         08225000
<< to open the specified log file. DB at stack.              >>         08230000
<<                                                           >>         08235000
<< ENTRY:                                                    >>         08240000
<<   TABINDEX' - entry offset within LOGTAB for this entry.  >>         08245000
<<                                                           >>         08250000
<< EXIT:                                                     >>         08255000
<<   Has the LOGSIR.                                         >>         08260000
<<   A         - return form GETSIR.                         >>         08265000
<<   ENTRY'    - entry from the LOGTAB for this process.     >>         08270000
<<   PROCNAME  - logid for this process.                     >>         08275000
                                                                        08280000
                                                                        08285000
INDEX:=0;                                                               08290000
TABINDEX:=0;         <<SET TABINDEX FOR TEMP ENTRY JUST READ>>          08295000
IF NOT SWITCH'FLAG THEN Q'VSETNO := 1;                         <<01869>>08300000
                                                                        08305000
A:=GETSIR(LOGSIR);                                                      08310000
MOVE'FROM'DSEG(@ENTRY',LOGDST,TABINDEX',TENTRYSIZE);           <<01869>>08315000
MOVE PROCNAME:=BENTRY'(LGNAME),(8);                            <<01869>>08320000
PROCNAME(8):=0;                                                         08325000
                                                               <<01869>>08330000
IF ENTRY'(LGTYPE) <> DISC  THEN                                <<01869>>08335000
   BEGIN                     << Serial log file - file opens >><<01869>>08340000
   OPEN'SERIAL'LOGFILE;                                                 08345000
   OPEN'BUFFER'FILE;                                                    08350000
   END                                                                  08355000
ELSE                                                                    08360000
  OPEN'DISC'LOGFILE;                                                    08365000
                                                                        08370000
END;           << Subroutine OPEN'NEW'LOG'FILE >>                       08375000
$PAGE "Logging Process -- Find'Last'Record"                    <<01869>>08380000
SUBROUTINE FIND'LAST'RECORD;                                            08385000
BEGIN                                                                   08390000
                                                                        08395000
<< Will re-read the log file to find the last valid record   >>         08400000
<< from the last time the log file was opened. DB at LOGBUFF.>>         08405000
<<                                                           >>         08410000
<< ENTRY:                                                    >>         08415000
<<   BUF       - ptr to buffer area of LOGBUFF.              >>         08420000
<<                                                           >>         08425000
<< EXIT:                                                     >>         08430000
<<   CURRREC   - current record number.                      >>         08435000
<<   EOFORERROR- TRUE to terminate read loop.                >>         08440000
<<   LASTREC   - last good record found.                     >>         08445000
<<   LAST'REC'CODE - set by CHECKBLOCK.                      >>         08450000
<<   VALID     - set by CHECKBLOCK (TRUE if block was good). >>         08455000
                                                                        08460000
                                                                        08465000
                                                                        08470000
   EOFORERR:=FALSE;                                                     08475000
   CURRREC:=0D;                                                         08480000
   LASTREC:=0D;                                                         08485000
                                                                        08490000
   DO                                                                   08495000
      BEGIN                                                             08500000
                                                                        08505000
   << Read and check old info in the file. Will read until an>>         08510000
   << I/O error, bad block, or EOF is detected.              >>         08515000
                                                                        08520000
      @RECPTR:=@BUF;                                                    08525000
      @DRECPTR:=@BUF;                                                   08530000
      @BRECPTR:=2*@BUF;                                        <<01869>>08535000
      COUNT:=FREAD(FILENO,BUF,BLKSIZE);                                 08540000
      IF <> THEN                                                        08545000
         BEGIN                                                          08550000
         IF < THEN     << Error ? >>                                    08555000
            BEGIN                                                       08560000
            FCHECK(FILENO,ERRCODE);                                     08565000
            FSPACE(FILENO,-1);                                          08570000
            EXCHANGEDB(0);   << Back to stack >>                        08575000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>08580000
            GENMSG(SETNO,READERR,0,@PROCNAME,,,,,0);           <<01869>>08585000
            EXCHANGEDB(BUFDST);    << To LOGBUFF >>                     08590000
            END;                                                        08595000
         EOFORERR:=TRUE;                                                08600000
         END;             << Error detected >>                          08605000
                                                                        08610000
      IF COUNT <> BLKSIZE THEN EOFORERR := TRUE;                        08615000
                                                                        08620000
      CHECKBLOCK;                                                       08625000
      IF VALID THEN                                                     08630000
         BEGIN                                                          08635000
         @RECPTR:=@RECPTR-RECSIZE;                             <<01869>>08640000
         @DRECPTR:=@RECPTR;                                             08645000
         @BRECPTR:=2*@RECPTR;                                  <<01869>>08650000
         LASTREC:=DRECPTR(RNUM);                                        08655000
         FIRST'TAPE'BLOCK := FALSE;                            <<01869>>08660000
         END                                                            08665000
                                                               <<01869>>08670000
      ELSE                                                              08675000
                                                                        08680000
      << We've found the last good block. If the last record >>         08685000
      << was not a trailer record, then the log file was     >>         08690000
      << never properly closed. Tell operator that no EOF was>>         08695000
      << found in the log file.                              >>         08700000
                                                                        08705000
      IF NOT EOFORERR AND LAST'REC'CODE <> TRAILER             <<01869>>08710000
         AND CURRREC > 1D THEN                                 <<01869>>08715000
         BEGIN                                                          08720000
         EXCHANGEDB(0);    << Back to stack >>                          08725000
         FSPACE(FILENO,-1);                                    <<01869>>08730000
         GENMSG(SETNO,READERR,0,@FNAME,@PROCNAME,,,,0);        <<01869>>08735000
         EXCHANGEDB(BUFDST);      << To LOGBUFF >>                      08740000
         END;                                                           08745000
      END                                                               08750000
   UNTIL EOFORERR OR NOT VALID;                                         08755000
                                                                        08760000
END;      << Subroutine FIND'LAST'RECORD >>                             08765000
$PAGE "Logging Process -- Continue'Disc'Logging"               <<01869>>08770000
SUBROUTINE CONTINUE'DISC'LOGGING;                                       08775000
BEGIN                                                                   08780000
                                                               <<01869>>08785000
<< Called when want to continue disc logging after a RESTART >><<01869>>08790000
<< to find the last good record previously written to the log>><<01869>>08795000
<< file. Will allocate the next extent, calculate the record >>         08800000
<< offset within the current extent, etc. needed to manage   >>         08805000
<< the disc log file. If any errors are encountered, will    >>         08810000
<< print message to console and go OUT. DB at LOGBUFF.       >>         08815000
<<                                                           >>         08820000
<< ENTRY:                                                    >>         08825000
<<   CURRREC   - Current record number (last good rec + 1).  >>         08830000
<<   NUMEXT    - max # extents.                              >>         08835000
<<                                                           >>         08840000
<< EXIT:                                                     >>         08845000
<<   ADDR      - disc address of current extent.             >>         08850000
<<   BLOCKNUM  - block number of last block in current ext.  >>         08855000
<<   DISCLDEV  - ldev of current extent.                     >><<01869>>08860000
<<   DTEMP     - # records in current extent.                >>         08865000
<<   EXTNUM    - current extent number.                      >>         08870000
<<   FLAB      - file label of disc log file.                >>         08875000
<<   LOGBUFF   - globals updated to reflect state of the file>>         08880000
                                                                        08885000
                                                               <<01869>>08890000
                                                                        08895000
                                                                        08900000
      EXTNUM:=INTEGER(((((LASTREC-DLOGBUFF(RECS'IN'PREV))      <<01869>>08905000
       /DOUBLE(BLKFACTOR)+1D)                                  <<01869>>08910000
       /DOUBLE(EXTSIZE/BLKFACTOR))))+1;                        <<01869>>08915000
                                                               <<01869>>08920000
      << Remember when calculating INBUFREC (offset into the >><<01869>>08925000
      << current extent for the next writes), to add 1 extra >><<01869>>08930000
      << block (for the FLAB).                               >><<01869>>08935000
                                                               <<01869>>08940000
      DLOGBUFF(INBUFREC):=((LASTREC-DLOGBUFF(RECS'IN'PREV))    <<01869>>08945000
        +DOUBLE(EXTSIZE+BLKFACTOR))-DOUBLE(EXTNUM)             <<01869>>08950000
        *DOUBLE(EXTSIZE);                                      <<01869>>08955000
      DLOGBUFF(FSPACE') := DOUBLE(EXTNUM)*DOUBLE(EXTSIZE)      <<01869>>08960000
        -DOUBLE(BLKFACTOR)-LASTREC+DLOGBUFF(RECS'IN'PREV);     <<01869>>08965000
      IF EXTNUM = NUMEXT THEN                                  <<01869>>08970000
         BEGIN                                                 <<01869>>08975000
         << We must reserve the last record of this extent so>><<01869>>08980000
         << the proper close info can be posted to the file. >><<01869>>08985000
                                                               <<01869>>08990000
         DLOGBUFF(FSPACE') := DLOGBUFF(FSPACE') - 1D;          <<01869>>08995000
         DLOGBUFF(FSIZE) := DOUBLE(FLAB(LASTEXT)) - 1D;        <<01869>>09000000
         END                                                   <<01869>>09005000
      ELSE DLOGBUFF(FSIZE) := DOUBLE(EXTSIZE);                 <<01869>>09010000
                                                               <<01869>>09015000
      DTEMP:=(CURRREC-DLOGBUFF(RECS'IN'PREV))/                 <<01869>>09020000
        DOUBLE(BLKFACTOR);                                     <<01869>>09025000
      LOGBUFF(BUFUSED):=INTEGER((CURRREC-DLOGBUFF(RECS'IN'PREV))        09030000
        -(DTEMP*DOUBLE(BLKFACTOR)));                           <<01869>>09035000
      LOGBUFF(BSPACE) := BLKFACTOR - LOGBUFF(BUFUSED);         <<01869>>09040000
                                                               <<01869>>09045000
      << If this is the last block of the last extent, then  >><<01869>>09050000
      << save the last record for proper close information.  >><<01869>>09055000
                                                               <<01869>>09060000
      IF EXTNUM = NUMEXT AND                                   <<01869>>09065000
         DLOGBUFF(FSPACE') <= DOUBLE(BLKFACTOR)                <<01869>>09070000
        THEN LOGBUFF(BSPACE) := LOGBUFF(BSPACE) - 1;           <<01869>>09075000
                                                               <<01869>>09080000
                                                               <<01869>>09085000
      << Allocate the extent, and set EOF to end of extent. >> <<01869>>09090000
                                                               <<01869>>09095000
      BLOCKNUM := DOUBLE(EXTNUM * INTEGER(EXTSIZE/BLKFACTOR))  <<01869>>09100000
                  - 2D;                                                 09105000
      IF EXTNUM = NUMEXT    << Last extent may be different >> <<01869>>09110000
         THEN BLOCKNUM := BLOCKNUM + DOUBLE(FLAB(LASTEXT)/     <<01869>>09115000
                          BLKFACTOR)-DOUBLE(EXTSIZE/BLKFACTOR);<<01869>>09120000
                                                               <<01869>>09125000
      DLOGBUFF(TRECS):=CURRREC;                                <<01869>>09130000
      EXCHANGEDB(0);   << Back to stack >>                              09135000
                                                               <<01869>>09140000
      FWRITEDIR(FILENO,BUFFAREA,BLKSIZE,BLOCKNUM);             <<01869>>09145000
      IF <> THEN                                               <<01869>>09150000
         BEGIN        <<Error writing to disc>>                <<01869>>09155000
         IF SWITCH'FLAG THEN                                   <<01869>>09160000
            ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)     <<01869>>09165000
         ELSE                                                  <<01869>>09170000
            ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);       <<01869>>09175000
         END;       <<Error writing to disc>>                  <<01869>>09180000
                                                               <<01869>>09185000
      FCONTROL(FILENO,SET'EOF,DUMMY);   << Write EOF >>        <<01869>>09190000
      IF < THEN         <<Failed to write EOF>>                <<01869>>09195000
         BEGIN                                                 <<01869>>09200000
         IF SWITCH'FLAG THEN                                   <<01869>>09205000
            ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)     <<01869>>09210000
         ELSE                                                  <<01869>>09215000
            ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);       <<01869>>09220000
         END;                                                  <<01869>>09225000
                                                               <<01869>>09230000
      IF FLABIO(FLABLDEV,FLABADDR,READ,FLAB) <> 0 THEN         <<01869>>09235000
         BEGIN                                                 <<01869>>09240000
         IF SWITCH'FLAG THEN                                   <<01869>>09245000
            ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)     <<01869>>09250000
         ELSE                                                  <<01869>>09255000
            ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);       <<01869>>09260000
         END;                                                  <<01869>>09265000
      EXCHANGEDB(BUFDST);     << Back to LOGBUFF >>                     09270000
      <<Get ldev #, and sector # for this extent>>             <<01869>>09275000
      ADDR:=DFLAB(21+EXTNUM);                                           09280000
      DISCLDEV := LUN(ADDR1.(0:8),FGETPVINFO(FILENO).(4:4));   <<01869>>09285000
      LOGBUFF(LOGDEV) := ENTRY'(LGDEV) := DISCLDEV;            <<01869>>09290000
      ADDR1.(0:8):=0;    << Get rid of ldev # >>                        09295000
      DLOGBUFF(LOGADDR) := DENTRY'(LGADDR) := ADDR;            <<01869>>09300000
      LOGBUFF(EXTENT):=EXTNUM;                                 <<01869>>09305000
                                                               <<01869>>09310000
END;      << Subroutine CONTINUE'LOGGING >>                             09315000
$PAGE "Logging Process -- Continue'Serial'Logging"             <<01869>>09320000
SUBROUTINE CONTINUE'SERIAL'LOGGING;                                     09325000
BEGIN                                                                   09330000
                                                                        09335000
<< Called when want to continue serial logging after a       >><<01869>>09340000
<< restart to set up the LOGBUFF to reflect the last good    >><<01869>>09345000
<< record written to the log file.                           >><<01869>>09350000
<<                                                           >>         09355000
<< ENTRY:                                                    >>         09360000
<<   ADDR    - sector address of disc buffer file.           >>         09365000
<<   CURRREC - current record (last good rec + 1).           >>         09370000
<<   DTEMP   - max # records in the disc buffer file.        >>         09375000
<<                                                           >>         09380000
<< EXIT:                                                     >>         09385000
<<   LOGBUFF updated and ready to continue logging.          >>         09390000
                                                                        09395000
                                                                        09400000
                                                                        09405000
                                                                        09410000
                                                                        09415000
DLOGBUFF(INBUFREC):=0D;                                                 09420000
DLOGBUFF(TRECS):=CURRREC;                                               09425000
DLOGBUFF(LOGADDR):=ADDR;                                                09430000
DTEMP:=(CURRREC-DLOGBUFF(RECS'IN'PREV))/DOUBLE(BLKFACTOR);     <<01869>>09435000
LOGBUFF(BUFUSED):=INTEGER(CURRREC-DLOGBUFF(RECS'IN'PREV)       <<01869>>09440000
  -(DTEMP*DOUBLE(BLKFACTOR)));                                 <<01869>>09445000
LOGBUFF(BSPACE) := BLKFACTOR - LOGBUFF(BUFUSED);               <<01869>>09450000
                                                                        09455000
   IF ENTRY'(LGTYPE) = SDISC OR ENTRY'(LGTYPE) = CTAPE THEN    <<01869>>09460000
    BEGIN                                                      <<01869>>09465000
      << We need to issue a special write request for the   >> <<01869>>09470000
      << first write to a SDISC or CTAPE log file. This will>> <<01869>>09475000
      << post an eod marker to the gap table of the serial  >> <<01869>>09480000
      << disc interface so that recovery will be possible   >> <<01869>>09485000
      << in the event that the system goes down.            >> <<01869>>09490000
                                                               <<01869>>09495000
      EXCHANGEDB(0);                                           <<01869>>09500000
      FWRITE(FILENO,BUFFAREA,ZERO'LENGTH,SPECIAL'WRITE);       <<01869>>09505000
      IF <> THEN                                               <<01869>>09510000
      BEGIN                                                    <<01869>>09515000
      IF SWITCH'FLAG THEN                                      <<01869>>09520000
         ABEND'(NEWFWRITEERROR,FILENO,DISC,PRINT'FNAME)        <<01869>>09525000
      ELSE                                                     <<01869>>09530000
         ABEND'(FWRITEERROR,FILENO,DISC,PRINT'FNAME);          <<01869>>09535000
      END;                                                     <<01869>>09540000
    END;                                                       <<01869>>09545000
END;    << Subroutine CONTINUE'SERIAL'LOGGING >>                        09550000
$PAGE "Logging Process -- Continue'Logging"                    <<01869>>09555000
SUBROUTINE CONTINUE'LOGGING;                                            09560000
BEGIN                                                                   09565000
                                                                        09570000
<< Called when want to continue logging to a log file that   >>         09575000
<< just been re-opened. Will call the appropriate routine to >>         09580000
<< read and verify the current contents of the log file.     >>         09585000
<< DB is at LOGBUFF.                                         >>         09590000
                                                                        09595000
IF ENTRY'(LGTYPE) = DISC                                       <<01869>>09600000
    THEN  CONTINUE'DISC'LOGGING                                         09605000
ELSE CONTINUE'SERIAL'LOGGING;                                           09610000
                                                                        09615000
END;    << Subroutine CONTINUE'LOGGING >>                               09620000
$PAGE "Logging Process -- Allocate'Next'Extent"                <<01869>>09625000
LOGICAL SUBROUTINE ALLOCATE'NEXT'EXTENT;                                09630000
BEGIN                                                                   09635000
                                                                        09640000
<< Called when user needs the next extent allocated for disc >>         09645000
<< log file. Will allocate the extent, set EOF to end of the >>         09650000
<< extent and update the LOGBUFF to reflect the size of this >>         09655000
<< extent.  DB at LOGBUF on entry and exit.                  >>         09660000
<<                                                           >>         09665000
<< RETURNS:                                                  >>         09670000
<<   TRUE - Extent allocated and everything O.K.             >>         09675000
<<   FALSE- Error - extent not allocated.                    >>         09680000
<<                                                           >>         09685000
<< ENTRY:                                                    >>         09690000
<<   EXTNUM   - current extent number.                       >>         09695000
<<   NUMEXT   - maximum number of extents for the log file.  >>         09700000
<<                                                           >>         09705000
<< EXIT:                                                     >>         09710000
<<   ADDR     - disc address of the new extent.              >>         09715000
<<   BLOCKNUM - block number of last block of new extent.    >>         09720000
<<   DISCLDEV - Ldev of current extent                       >><<01869>>09725000
<<   ERRCODE  - if error, file system error number.          >>         09730000
<<   EXTNUM   - new extent number.                           >>         09735000
<<   FLAB     - file label of disc log file.                 >>         09740000
<<   LOGBUFF  - updated with info about this new extent.     >>         09745000
                                                                        09750000
                                                                        09755000
ERRCODE := 0;                                                           09760000
ALLOCATE'NEXT'EXTENT := FALSE;                                          09765000
EXCHANGEDB(0);       << Make sure at stack >>                           09770000
                                                                        09775000
EXTNUM := EXTNUM + 1;                                                   09780000
BLOCKNUM := DOUBLE(EXTNUM*INTEGER(EXTSIZE/BLKFACTOR)) - 2D;             09785000
IF EXTNUM = NUMEXT                                                      09790000
   THEN BLOCKNUM := BLOCKNUM + DOUBLE(FLAB(LASTEXT)/BLKFACTOR)          09795000
                    - DOUBLE(EXTSIZE/BLKFACTOR);                        09800000
                                                                        09805000
BUFFAREA := "  ";                                                       09810000
MOVE BUFFAREA(1) := BUFFAREA, (BLKSIZE-1);                              09815000
                                                                        09820000
<< Now move the record ptr to the end of this extent.        >>         09825000
<< File System will clear the entire extent.                 >>         09830000
                                                                        09835000
FWRITEDIR(FILENO,BUFFAREA,BLKSIZE,BLOCKNUM);                            09840000
IF <> THEN                                                              09845000
   BEGIN      << Error - may be out of disc space >>                    09850000
   FCHECK(FILENO,ERRCODE);                                              09855000
   GENMSG(FSSETNO,ERRCODE,,,,,,,0);                                     09860000
   IF ERRCODE = OUT'OF'GROUP'SPACE OR                                   09865000
      ERRCODE = OUT'OF'ACCOUNT'SPACE  THEN                     <<01869>>09870000
      BEGIN                                                    <<01869>>09875000
      IF SWITCH'FLAG THEN                                      <<01869>>09880000
         ULERRCODE := NEWDISCSPACE                             <<01869>>09885000
      ELSE                                                     <<01869>>09890000
         ULERRCODE := OUTOFDISCSPACE;                          <<01869>>09895000
      END                                                      <<01869>>09900000
   ELSE                                                        <<01869>>09905000
      BEGIN                                                    <<01869>>09910000
      IF SWITCH'FLAG THEN                                      <<01869>>09915000
         ULERRCODE := NEWFWRITEERROR                           <<01869>>09920000
      ELSE                                                     <<01869>>09925000
         ULERRCODE := FWRITEERROR;                             <<01869>>09930000
      END;                                                     <<01869>>09935000
                                                               <<01869>>09940000
   GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);            <<01869>>09945000
                                                               <<01869>>09950000
                                                                        09955000
   IF SWITCH'FLAG THEN                                                  09960000
      BEGIN                                                             09965000
      DEL;       << Get rid of return address >>               <<01869>>09970000
      GO CHANGELOG'ERROR'RECOVERY;                             <<01869>>09975000
      END;                                                              09980000
                                                                        09985000
   EXCHANGEDB(BUFDST);                                                  09990000
   LOGBUFF(MSG) := STOP;                                                09995000
   IF ERRCODE = OUT'OF'GROUP'SPACE OR                                   10000000
      ERRCODE = OUT'OF'ACCOUNT'SPACE                                    10005000
      THEN LOGBUFF(LOGMSG) := DISCSPACE                                 10010000
   ELSE LOGBUFF(LOGMSG) := WRITEERR;                                    10015000
   RETURN                                                               10020000
   END;                                                                 10025000
                                                                        10030000
<< Update the EOF ptr in the file system tables. >>                     10035000
                                                                        10040000
FCONTROL(FILENO,SET'EOF,DUMMY);                                <<01869>>10045000
IF <> THEN                                                              10050000
   BEGIN                                                                10055000
   FCHECK(FILENO,ERRCODE);                                              10060000
   GENMSG(FSSETNO,ERRCODE,,,,,,,0);                                     10065000
   IF SWITCH'FLAG THEN                                         <<01869>>10070000
      ULERRCODE := NEWFWRITEERROR                              <<01869>>10075000
   ELSE                                                        <<01869>>10080000
      ULERRCODE := FWRITEERROR;                                <<01869>>10085000
                                                               <<01869>>10090000
   GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);            <<01869>>10095000
                                                                        10100000
   IF SWITCH'FLAG THEN                                                  10105000
      BEGIN                                                             10110000
      DEL;    << Get rid of return address >>                  <<01869>>10115000
      GO CHANGELOG'ERROR'RECOVERY;                             <<01869>>10120000
      END;                                                              10125000
                                                                        10130000
   EXCHANGEDB(BUFDST);                                                  10135000
   LOGBUFF(LOGMSG) := WRITEERR;                                         10140000
   RETURN;                                                              10145000
   END;                                                                 10150000
                                                                        10155000
<< Now need to find the disc address of this extent.      >>            10160000
                                                                        10165000
                                                                        10170000
<< Now get the extent sizes, etc. from the file label.    >>            10175000
                                                                        10180000
IF FLABIO(FLABLDEV,FLABADDR,READ,FLAB) <> 0 THEN               <<01869>>10185000
   BEGIN                                                                10190000
                                                                        10195000
   IF SWITCH'FLAG THEN                                                  10200000
      BEGIN                                                             10205000
      DEL;    << Get rid of return address >>                  <<01869>>10210000
      ULERRCODE := NEWFLABERROR;                               <<01869>>10215000
      GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);         <<01869>>10220000
      GO CHANGELOG'ERROR'RECOVERY;                             <<01869>>10225000
      END;                                                              10230000
                                                                        10235000
   ULERRCODE := FLABELERR;                                     <<01869>>10240000
   GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);            <<01869>>10245000
   EXCHANGEDB(BUFDST);                                                  10250000
   LOGBUFF(LOGMSG) := WRITEERR;                                         10255000
   RETURN;                                                              10260000
   END;                                                                 10265000
                                                                        10270000
<< Now reset the disc address and ldev #. >>                            10275000
                                                                        10280000
ADDR := DFLAB(21+EXTNUM);                                               10285000
DISCLDEV := LUN(ADDR1.(0:8),FGETPVINFO(FILENO).(4:4));         <<01869>>10290000
ADDR1.(0:8) := 0;    << Get rid of ldev >>                     <<01869>>10295000
                                                                        10300000
<< If this is the last extent, need to leave one record free >>         10305000
<< for now so there will be enough room for the trailer      >>         10310000
<< or changelog record.                                      >>         10315000
                                                                        10320000
IF EXTNUM = NUMEXT                                                      10325000
   THEN TOS := DOUBLE(FLAB(LASTEXT)) - 1D                               10330000
ELSE TOS := DOUBLE(FLAB(FEXTSIZE));                                     10335000
                                                                        10340000
EXCHANGEDB(BUFDST);                                                     10345000
                                                                        10350000
<< Now update the global info in the LOGBUFF. >>                        10355000
                                                                        10360000
DLOGBUFF(FSPACE') := DLOGBUFF(FSIZE) := TOS;                            10365000
LOGBUFF(EXTENT) := EXTNUM;                                              10370000
LOGBUFF(LOGDEV) := DISCLDEV;                                   <<01869>>10375000
DLOGBUFF(LOGADDR) := ADDR;                                              10380000
DLOGBUFF(INBUFREC) := 0D;                                               10385000
LOGBUFF(LOGMSG) := CONTINUE;                                            10390000
                                                                        10395000
ALLOCATE'NEXT'EXTENT := TRUE;                                           10400000
                                                                        10405000
END;   << Subroutine ALLOCATE'NEXT'EXTENT >>                            10410000
$PAGE "Logging Process -- Empty'Disc'Buffer"                   <<01869>>10415000
LOGICAL SUBROUTINE EMPTY'DISC'BUFFER(LENGTH);                           10420000
   VALUE LENGTH;                                                        10425000
   INTEGER LENGTH;                                                      10430000
BEGIN                                                                   10435000
                                                                        10440000
<< Called when need to move stuff from the disc buffer file to >>       10445000
<< the serial log file. DB at LOGBUFF on entry and exit.       >>       10450000
<<                                                             >>       10455000
<< ENTRY:                                                      >>       10460000
<<   LENGTH    - # words to xfer from disc to serial log file. >>       10465000
<<   OUTBUFREC - block # to start the read from disc.          >>       10470000
<<                                                             >>       10475000
<< EXIT:                                                       >>       10480000
<<   ERRCODE   - if error, file system error number.           >>       10485000
<<   ULERRCODE - if error, user logging error number.          <<01869>>10490000
                                                                        10495000
                                                                        10500000
ERRCODE := 0;                                                           10505000
                                                                        10510000
EMPTY'DISC'BUFFER := FALSE;                                             10515000
EXCHANGEDB(0);                                                          10520000
                                                                        10525000
FREADDIR(BUFFILENO,BUFFAREA,LENGTH,OUTBUFREC);                          10530000
IF <> THEN                                                              10535000
   BEGIN                                                                10540000
   FREADDIR(BUFFILENO,BUFFAREA,LENGTH,OUTBUFREC);                       10545000
   IF <> THEN                                                           10550000
      BEGIN                                                             10555000
      FCHECK(BUFFILENO,ERRCODE);                                        10560000
      GENMSG(FSSETNO,ERRCODE,,,,,,,0);                                  10565000
                                                                        10570000
      IF SWITCH'FLAG THEN                                               10575000
         BEGIN                                                          10580000
         DEL;    << Get rid of return address >>               <<01869>>10585000
         ULERRCODE := NEWBWRITEERROR;                          <<01869>>10590000
         GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);     <<01869>>10595000
         GO CHANGELOG'ERROR'RECOVERY;                          <<01869>>10600000
         END;                                                           10605000
                                                                        10610000
      ULERRCODE := BWRITEERROR;                                <<01869>>10615000
      GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);        <<01869>>10620000
      EXCHANGEDB(BUFDST);                                               10625000
      RETURN;                                                           10630000
      END;                                                              10635000
   END;                                                                 10640000
                                                                        10645000
FWRITE(FILENO,BUFFAREA,LENGTH,NORMAL'WRITE);                            10650000
IF <> THEN                                                              10655000
   BEGIN                                                                10660000
   FCHECK(FILENO,ERRCODE);                                              10665000
   IF ERRCODE = SYSPOWERFAIL OR ERRCODE = TAPEPOWERFAIL THEN            10670000
      BEGIN                                                             10675000
      IF TAPE' THEN                                                     10680000
         BEGIN                                                          10685000
         IF RECPFAIL(FILENO,DBUFFAREA,TAPEDEV,FIRST'TAPE'BLOCK)<<01869>>10690000
            THEN GO OKAY;                                      <<01869>>10695000
         GENMSG(SETNO,PFAILERROR,0,@FNAME,@PROCNAME,,,,0);     <<01869>>10700000
         END;                                                           10705000
      END                                                               10710000
   ELSE                                                        <<01869>>10715000
      BEGIN                                                    <<01869>>10720000
      IF SWITCH'FLAG THEN                                      <<01869>>10725000
         ULERRCODE := NEWFWRITEERROR                           <<01869>>10730000
      ELSE ULERRCODE := FWRITEERROR;                           <<01869>>10735000
      GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);         <<01869>>10740000
      END;                                                     <<01869>>10745000
                                                                        10750000
                                                                        10755000
   IF SWITCH'FLAG THEN                                                  10760000
      BEGIN                                                             10765000
      DEL;     << Get rid of return address >>                 <<01869>>10770000
      GO CHANGELOG'ERROR'RECOVERY;                             <<01869>>10775000
      END;                                                              10780000
                                                                        10785000
   EXCHANGEDB(BUFDST);                                                  10790000
   LOGBUFF(LOGMSG) := WRITEERR;                                         10795000
   LOGBUFF(MSG) := SUSPEND;                                             10800000
   RETURN;                                                              10805000
   END;                                                                 10810000
                                                                        10815000
OKAY:                                                                   10820000
                                                                        10825000
FIRST'TAPE'BLOCK := FALSE;                                     <<01869>>10830000
EXCHANGEDB(BUFDST);                                                     10835000
EMPTY'DISC'BUFFER := TRUE;                                              10840000
                                                                        10845000
END;   << Subroutine EMPTY'DISC'BUFFER >>                               10850000
$PAGE "Logging Process -- Set'Up'Logbuff"                      <<01869>>10855000
SUBROUTINE SET'UP'LOGBUFF;                                     <<01869>>10860000
   BEGIN                                                       <<01869>>10865000
                                                               <<01869>>10870000
   << Called during a changelog to update the global info in >><<01869>>10875000
   << the LOGBUFF to reflect the new characteristics of the  >><<01869>>10880000
   << log file.                                              >><<01869>>10885000
                                                               <<01869>>10890000
   LOGBUFF(LOGMSG):=CONTINUE;                                  <<01869>>10895000
   LOGBUFF(LOGTYPE):=Q'NEWTYPE;                                <<01869>>10900000
   LOGBUFF(VSETNO):=Q'VSETNO;                                  <<01869>>10905000
   LOGBUFF(USERMSG):=CONTINUE;                                 <<01869>>10910000
   LOGBUFF(LOGERR):=0;                                         <<01869>>10915000
   DLOGBUFF(RECS'IN'PREV):=DLOGBUFF(TRECS);                    <<01869>>10920000
   LOGBUFF(BSPACE):=BLKFACTOR;                                          10925000
   LOGBUFF(BUFUSED):=0;                                                 10930000
   LOGBUFF(EXTENT) := EXTNUM;                                  <<01869>>10935000
   DLOGBUFF(FSPACE') := DENTRY'(BSIZE) := DTEMP;               <<01869>>10940000
   DLOGBUFF(MAXFSPACE) := LIMIT - 1D;                          <<01869>>10945000
   DLOGBUFF(LOGADDR) := DENTRY'(LGADDR) := ADDR;               <<01869>>10950000
   LOGBUFF(VSETNO) := Q'VSETNO;                                <<01869>>10955000
   DLOGBUFF(FSIZE) := DTEMP;                                   <<01869>>10960000
   DLOGBUFF(INBUFREC) := 0D;                                   <<01869>>10965000
   LOGBUFF(LOGTYPE)  := LOGBUFF(NEWTYPE);                      <<01869>>10970000
   ENTRY'(LGTYPE) := LOGBUFF(NEWTYPE);                         <<01869>>10975000
   LOGBUFF(LOGDEV) := ENTRY'(LGDEV) := DISCLDEV;               <<01869>>10980000
      IF Q'NEWTYPE <> DISC THEN DLOGBUFF(INBUFREC):=0D;        <<01869>>10985000
      LOGBUFF(LOGERR):=0;                                      <<01869>>10990000
      LOGBUFF(USERMSG):=CONTINUE;                              <<01869>>10995000
      LOGBUFF(BUFUSED):=0;                                     <<01869>>11000000
      FREE'LAST'EXTENT:=FALSE;                                          11005000
   LOGBUFF(LASTEXT') := NUMEXT;                                <<01869>>11010000
   IF LOGBUFF(LOGTYPE) <> DISC THEN                            <<01869>>11015000
      BEGIN                                                    <<01869>>11020000
      DLOGBUFF(OLD'LIMIT) := 0D;                               <<01869>>11025000
      LOGBUFF(OLD'NUMEXT) := 0;                                <<01869>>11030000
      END;                                                     <<01869>>11035000
                                                               <<01869>>11040000
   OUTBUFREC := 0D;                                            <<01869>>11045000
   END;      << Subroutine SET'UP'LOGBUFF >>                   <<01869>>11050000
$PAGE "Logging Process -- Get'New'File"                        <<01869>>11055000
SUBROUTINE GET'NEW'FILE;                                       <<01869>>11060000
   BEGIN                                                       <<01869>>11065000
                                                               <<01869>>11070000
   << Obtains the new file name for the next log file in the >><<01869>>11075000
   << set. If the old and new file is serial, then closes the>><<01869>>11080000
   << old log file so that is can open the new serial file on>><<01869>>11085000
   << the same device if wanted.                             >><<01869>>11090000
   <<                                                        >><<01869>>11095000
   <<                                                        >><<01869>>11100000
   <<                                                        >><<01869>>11105000
   <<                                                        >><<01869>>11110000
   <<                                                        >><<01869>>11115000
                                                               <<01869>>11120000
   Q'OLD'LIMIT := DLOGBUFF(MAXFSPACE) + 1D;                    <<01869>>11125000
   Q'OLD'NUMEXT := LOGBUFF(NUMEXT);                            <<01869>>11130000
   Q'VSETNO:=LOGBUFF(VSETNO);                                  <<01869>>11135000
   Q'NEWTYPE:=LOGBUFF(NEWTYPE);                                <<01869>>11140000
   Q'OLDTYPE:=LOGBUFF(LOGTYPE);                                <<01869>>11145000
   EXCHANGEDB(0);                                              <<01869>>11150000
                                                               <<01869>>11155000
   << Make sure get latest copy of LOGTAB entry >>             <<01869>>11160000
                                                               <<01869>>11165000
   MOVE'FROM'DSEG(@ENTRY',LOGDST,TABINDEX',TENTRYSIZE);        <<01869>>11170000
                                                               <<01869>>11175000
   ENTRY'(LGTYPE):=Q'NEWTYPE;                                  <<01869>>11180000
   MOVE TEMP'FILE'NAME':= " ";                                 <<01869>>11185000
   MOVE TEMP'FILE'NAME'(1):=TEMP'FILE'NAME',(7);               <<01869>>11190000
   MOVE TEMP'FILE'NAME' := BENTRY'(LFNAME),(8);                <<01869>>11195000
   TEMP'FILE'NAME'(8) := 0;                                    <<01869>>11200000
   MOVE TEMP'FILE'NAME' := TEMP'FILE'NAME' WHILE ANS,1;        <<01869>>11205000
   FILE'NAME'LEN:=TOS-@TEMP'FILE'NAME';                        <<01869>>11210000
   IF (Q'VSETNO:=Q'VSETNO+1) > 999 THEN                        <<01869>>11215000
      Q'VSETNO:=1;                                             <<01869>>11220000
                                                               <<01869>>11225000
   << Get old file name from the LIDTAB. Do this to make sure>><<01869>>11230000
   << get the lockword if it had one. (The lockwords get     >><<01869>>11235000
   << deleted so that they will not appear in any messages.  >><<01869>>11240000
                                                               <<01869>>11245000
   FENTRY'SWITCH(BENTRY'(LGNAME),,OLD'FILE'NAME,,,LID'TYP);    <<01869>>11250000
                                                               <<01869>>11255000
   << if we are switching to serial, clear out the GRP and >>  <<01872>>11256000
   << ACCT fields of the filename. >>                          <<01872>>11257000
   IF Q'NEWTYPE = DISC THEN                                    <<01872>>11258000
      MOVE FNAME:= OLD'FILE'NAME,(36)                          <<01872>>11259000
   ELSE BEGIN                                                  <<01872>>11260000
      MOVE FNAME:= OLD'FILE'NAME,(FILE'NAME'LEN);              <<01872>>11260500
      FNAME(FILE'NAME'LEN):= 32; <<blanks instead of nulls!>>  <<01923>>11260600
      MOVE FNAME(FILE'NAME'LEN+1):=                            <<01872>>11260700
         FNAME(FILE'NAME'LEN),(35-FILE'NAME'LEN);              <<01872>>11260800
      FNAME(8):=0;  <<imitate getfname>>                       <<01923>>11260850
      END; << else serial >>                                   <<01872>>11260900
                                                               <<01872>>11261000
   << if the old file was serial, we need to get rid of >>     <<01872>>11261500
   << GRP and ACCT returned in OLD'FILE'NAME from FENTRY >>    <<01872>>11262000
   IF Q'OLDTYPE <> DISC THEN BEGIN                             <<01872>>11262500
      OLD'FILE'NAME(FILE'NAME'LEN):= 32; <<blanks, not nulls>> <<01923>>11263000
      MOVE OLD'FILE'NAME(FILE'NAME'LEN+1):=                    <<01872>>11263500
         OLD'FILE'NAME(FILE'NAME'LEN),(35-FILE'NAME'LEN);      <<01872>>11264000
      OLD'FILE'NAME(8):=0;  <<imitate getfname>>               <<01923>>11264100
      END;  << if serial >>                                    <<01872>>11264500
   FNAME(36) := 0;                                             <<01869>>11265000
   IF Q'VSETNO = 1 THEN                                        <<01869>>11270000
      MOVE FNAME(FILE'NAME'LEN-3):="000";                      <<01869>>11275000
   ASCII(Q'VSETNO,-10,FNAME(FILE'NAME'LEN-1));                 <<01869>>11280000
   MOVE'TO'DSEG(BUFDST,NEXT'FILE/2,@FNAME/2,18);               <<01869>>11285000
                                                               <<01869>>11290000
   DEPOSIT'FILENAME(FNAME,BENTRY'(LFNAME),BENTRY'(LFLOCKW),    <<01869>>11295000
                    BENTRY'(LFGROUP),BENTRY'(LFACCT));         <<01869>>11300000
                                                               <<01869>>11305000
   << Make sure LOGDST is updated on disc for warmstart      >><<01869>>11310000
   << recovery.                                              >><<01869>>11315000
                                                               <<01869>>11320000
   MOVE'TO'DSEG(LOGDST,TABINDEX',@ENTRY',TENTRYSIZE-2);        <<01869>>11325000
   WRITEDSEG(LOGDST);                                          <<01869>>11330000
                                                               <<01869>>11335000
   EXCHANGEDB(BUFDST);                                         <<01869>>11340000
   LOGBUFF(N'TYPE):=Q'NEWTYPE;                                 <<01869>>11345000
   FORMAT'NEXT'FILE;                                           <<01869>>11350000
   FLUSH(NULL,FALSE);     << Tell it we are the log process >> <<01869>>11355000
   CHECKMSG;                                                   <<01869>>11360000
                                                               <<01869>>11365000
   EXCHANGEDB(0);                                              <<01869>>11370000
   ERRCODE:=0;                                                 <<01869>>11375000
   SAVEFILENO:=FILENO;                                         <<01869>>11380000
                                                               <<01869>>11385000
   IF Q'NEWTYPE = DISC THEN                                    <<01869>>11390000
      BEGIN                                                    <<01869>>11395000
      IF Q'OLDTYPE <> DISC THEN                                <<01869>>11400000
         BEGIN                                                 <<01869>>11405000
         << Old log file was serial, new log file is disc >>   <<01869>>11410000
         << Therefore, must close (and purge) the disc buffer>><<01869>>11415000
         << file. But first make sure it gets posted to the  >><<01869>>11420000
         << serial log file.                                 >><<01869>>11425000
                                                               <<01869>>11430000
         EXCHANGEDB(BUFDST);                                   <<01869>>11435000
         COUNT:=INTEGER(DLOGBUFF(FSIZE)-DLOGBUFF(FSPACE'))*RECSIZE;     11440000
         DO                                                    <<01869>>11445000
            BEGIN                                              <<01869>>11450000
            << May require more that 1 write to empty buffer >><<01869>>11455000
                                                               <<01869>>11460000
            IF COUNT > BLKSIZE THEN                            <<01869>>11465000
               BEGIN                                           <<01869>>11470000
               TEMPCNT:=COUNT-BLKSIZE;                         <<01869>>11475000
               COUNT:=BLKSIZE;                                 <<01869>>11480000
               END                                             <<01869>>11485000
            ELSE TEMPCNT:=0;                                   <<01869>>11490000
            IF NOT EMPTY'DISC'BUFFER(COUNT) THEN               <<01869>>11495000
               BEGIN                                           <<01869>>11500000
               EXCHANGEDB(0);                                  <<01869>>11505000
               ULERRCODE := BWRITEERROR;                       <<01869>>11510000
              GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);<<01869>>11515000
               DEL;    << Get rid of return address >>         <<01869>>11520000
               GO CHANGELOG'ERROR'RECOVERY;                    <<01869>>11525000
               END;                                            <<01869>>11530000
                                                               <<01869>>11535000
            COUNT:=TEMPCNT;  <<WORDS LEFT>>                    <<01869>>11540000
            OUTBUFREC:=OUTBUFREC+DOUBLE(BLKFACTOR);            <<01869>>11545000
            IF OUTBUFREC >= DLOGBUFF(FSIZE) THEN               <<01869>>11550000
            OUTBUFREC:=0D;                                     <<01869>>11555000
            DLOGBUFF(FSPACE'):=DLOGBUFF(FSPACE') +             <<01869>>11560000
                               DOUBLE(COUNT/RECSIZE);          <<01869>>11565000
            END                                                <<01869>>11570000
         UNTIL COUNT <= 0;                                     <<01869>>11575000
         EXCHANGEDB(0);                                        <<01869>>11580000
         END;                                                  <<01869>>11585000
                                                               <<01869>>11590000
      << O.K. disc buffer file now posted to tape. There is >> <<01869>>11595000
      << a possiblity of having more info in the buffer file>> <<01869>>11600000
      << if it is less than one block. Will need to force   >> <<01869>>11605000
      OPEN'DISC'LOGFILE;                                       <<01869>>11610000
      IF ERRCODE <> 0 THEN                                     <<01869>>11615000
         BEGIN                                                 <<01869>>11620000
         FILENO:=SAVEFILENO;                                   <<01869>>11625000
         DEL;     << Get rid of return address >>              <<01869>>11630000
         GO CHANGELOG'ERROR'RECOVERY;                          <<01869>>11635000
         END;   << Error opening new disc log file >>          <<01869>>11640000
      END <<NEWTYPE=DISC>>                                     <<01869>>11645000
   ELSE                                                        <<01869>>11650000
      BEGIN                                                    <<01869>>11655000
      <<NEWTYPE=SERIAL>>                                       <<01869>>11660000
      IF Q'OLDTYPE <> DISC THEN                                <<01869>>11665000
         BEGIN                                                 <<01869>>11670000
         << For this case, we can use the "old" buffer file  >><<01869>>11675000
         << for the new serial log file.                     >><<01869>>11680000
                                                               <<01869>>11685000
         <<MUST CLOSE OLD FILE>>                               <<01869>>11690000
         EXCHANGEDB(BUFDST);                                   <<01869>>11695000
         COUNT:=INTEGER(DLOGBUFF(FSIZE)-DLOGBUFF(FSPACE'))*RECSIZE;     11700000
                                                               <<01869>>11705000
         << Still must flush out the disc buffer file to the>> <<01869>>11710000
         << "old" serial log file.                          >> <<01869>>11715000
                                                               <<01869>>11720000
         DO                                                    <<01869>>11725000
            BEGIN                                              <<01869>>11730000
            << May require more than 1 write to empty buffer>> <<01869>>11735000
                                                               <<01869>>11740000
            IF COUNT > BLKSIZE THEN                            <<01869>>11745000
               BEGIN                                           <<01869>>11750000
               TEMPCNT:=COUNT-BLKSIZE;                         <<01869>>11755000
               COUNT:=BLKSIZE;                                 <<01869>>11760000
               END                                             <<01869>>11765000
            ELSE TEMPCNT:=0;                                   <<01869>>11770000
            IF NOT EMPTY'DISC'BUFFER(COUNT) THEN               <<01869>>11775000
               BEGIN                                           <<01869>>11780000
               EXCHANGEDB(0);                                  <<01869>>11785000
               ULERRCODE := BWRITEERROR;                       <<01869>>11790000
              GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);<<01869>>11795000
               DEL;     << Get rid of return address >>        <<01869>>11800000
               GO CHANGELOG'ERROR'RECOVERY;                    <<01869>>11805000
               END;                                            <<01869>>11810000
                                                               <<01869>>11815000
            OUTBUFREC:=OUTBUFREC+DOUBLE(BLKFACTOR);            <<01869>>11820000
            IF OUTBUFREC >= DLOGBUFF(FSIZE) THEN               <<01869>>11825000
            OUTBUFREC:=0D;                                     <<01869>>11830000
            DLOGBUFF(FSPACE'):=DLOGBUFF(FSPACE') +             <<01869>>11835000
                               DOUBLE(COUNT/RECSIZE);          <<01869>>11840000
            COUNT:=TEMPCNT;  <<WORDS LEFT>>                    <<01869>>11845000
            END                                                <<01869>>11850000
         UNTIL COUNT <= 0;                                     <<01869>>11855000
         EXCHANGEDB(0);                                        <<01869>>11860000
         FCLOSE(FILENO,0,0);                                   <<01869>>11865000
         IF <> THEN                                            <<01869>>11870000
            BEGIN                                              <<01869>>11875000
            << Error closing "old" serial log file >>          <<01869>>11880000
                                                               <<01869>>11885000
            FCHECK(FILENO,ERRCODE);                            <<01869>>11890000
             GENMSG(FSSETNO,ERRCODE,,,,,,,0);                  <<01869>>11895000
            ULERRCODE := BWRITEERROR;                          <<01869>>11900000
            GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);  <<01869>>11905000
            DEL;      << Get rid of return address >>          <<01869>>11910000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>11915000
            END;                                               <<01869>>11920000
         END;                                                  <<01869>>11925000
                                                               <<01869>>11930000
      << Will try to open the new serial log file. In case>>   <<01869>>11935000
      << of error, will only attempt the open 3 times.    >>   <<01869>>11940000
                                                               <<01869>>11945000
      I:=0;                                                    <<01869>>11950000
      DO                                                       <<01869>>11955000
         BEGIN                                                 <<01869>>11960000
         ERRCODE:=0;                                           <<01869>>11965000
         OPEN'SERIAL'LOGFILE;                                  <<01869>>11970000
         END UNTIL (I:=I+1) >= 3 OR (ERRCODE = 0);             <<01869>>11975000
                                                               <<01869>>11980000
      IF ERRCODE <> 0 THEN                                     <<01869>>11985000
         BEGIN                                                 <<01869>>11990000
         DEL;     << Get rid of return address >>              <<01869>>11995000
         GO CHANGELOG'ERROR'RECOVERY;                          <<01869>>12000000
         END;                                                  <<01869>>12005000
      END;<<NEWTYPE=SERIAL>>                                   <<01869>>12010000
                                                               <<01869>>12015000
   END;            << Subroutine GET'NEW'FILE >>               <<01869>>12020000
$PAGE "Logging Process -- Finish'Changelog"                    <<01869>>12025000
SUBROUTINE FINISH'CHANGELOG;                                   <<01869>>12030000
   BEGIN                                                       <<01869>>12035000
   << Completes the changelog. If the "old" log file is disc,>><<01869>>12040000
   << will close it. If the "old" log file is tape and the   >><<01869>>12045000
   << new is disc, closes the old tape and disc buffer file. >><<01869>>12050000
   << Also, formats current and previous file entries in the >><<01869>>12055000
   << Comm. area of the LOGBUFF.                             >><<01869>>12060000
                                                               <<01869>>12065000
   IF Q'NEWTYPE = DISC THEN                                    <<01869>>12070000
      BEGIN                                                    <<01869>>12075000
      EXCHANGEDB(BUFDST);                                      <<01869>>12080000
      FLUSH(NULL,FALSE);   << Tell it we are the log process >><<01869>>12085000
      CHECKMSG;                                                <<01869>>12090000
                                                               <<01869>>12095000
      IF Q'OLDTYPE<>DISC THEN                                  <<01869>>12100000
         BEGIN                                                 <<01869>>12105000
         <<MUST MAKE LOG PROCESS POST TO TAPE>>                <<01869>>12110000
                                                               <<01869>>12115000
         << May want to make sure the disc buffer file gets  >><<01869>>12120000
         << posted to tape BEFORE close and purge it.        >><<01869>>12125000
                                                               <<01869>>12130000
         EXCHANGEDB(0);                                        <<01869>>12135000
         FCLOSE(BUFFILENO,0,0);                                <<01869>>12140000
         IF <> THEN                                            <<01869>>12145000
            BEGIN                                              <<01869>>12150000
            FCHECK(BUFFILENO,ERRCODE);                         <<01869>>12155000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12160000
            ULERRCODE := OLDBCLOSEFAIL;                        <<01869>>12165000
            GENMSG(SETNO,ULERRCODE,0,@BFNAME,@PROCNAME,,,,0);  <<01869>>12170000
            DEL;     << Get rid of return address >>           <<01869>>12175000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12180000
            END;                                               <<01869>>12185000
         FCLOSE(SAVEFILENO,0,0);                               <<01869>>12190000
         IF <> THEN                                            <<01869>>12195000
            BEGIN                                              <<01869>>12200000
            FCHECK(SAVEFILENO,ERRCODE);                        <<01869>>12205000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12210000
            ULERRCODE := OLDLOGCLOSEFAIL;                      <<01869>>12215000
            GENMSG(SETNO,ULERRCODE,0,@OLD'FILE'NAME,@PROCNAME, <<01869>>12220000
                   ,,,0);                                      <<01869>>12225000
            DEL;     << Get rid of return address >>           <<01869>>12230000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12235000
            END;                                               <<01869>>12240000
         END      << Old type was serial >>                    <<01869>>12245000
      ELSE                                                     <<01869>>12250000
         BEGIN                                                 <<01869>>12255000
         << Old log type was disc >>                           <<01869>>12260000
                                                               <<01869>>12265000
         FPOINT(SAVEFILENO,(DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))     12270000
                /DOUBLE(BLKFACTOR));                           <<01869>>12275000
         EXCHANGEDB(0);                                        <<01869>>12280000
         FCONTROL(SAVEFILENO,SET'EOF,DUMMY);                   <<01869>>12285000
         IF <> THEN                                            <<01869>>12290000
            BEGIN                                              <<01869>>12295000
            FCHECK(SAVEFILENO,ERRCODE);                        <<01869>>12300000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12305000
            ULERRCODE := FWRITEERROR;                          <<01869>>12310000
            GENMSG(SETNO,ULERRCODE,0,@OLD'FILE'NAME,@PROCNAME, <<01869>>12315000
                   ,,,0);                                      <<01869>>12320000
            DEL;     << Get rid of return address >>           <<01869>>12325000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12330000
            END;                                               <<01869>>12335000
         FCLOSE(SAVEFILENO,0,0);                               <<01869>>12340000
         IF <> THEN                                            <<01869>>12345000
            BEGIN                                              <<01869>>12350000
            FCHECK(SAVEFILENO,ERRCODE);                        <<01869>>12355000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12360000
            ULERRCODE := OLDLOGCLOSEFAIL;                      <<01869>>12365000
            GENMSG(SETNO,ULERRCODE,0,@OLD'FILE'NAME,@PROCNAME, <<01869>>12370000
                   ,,,0);                                      <<01869>>12375000
            DEL;    << Get rid of return address >>            <<01869>>12380000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12385000
            END;                                               <<01869>>12390000
         END;                                                  <<01869>>12395000
      END <<NEWTYPE=DISC>>                                     <<01869>>12400000
   ELSE                                                        <<01869>>12405000
      BEGIN                                                    <<01869>>12410000
      <<NEW FILE IS SERIAL>>                                   <<01869>>12415000
      IF Q'OLDTYPE=DISC THEN                                   <<01869>>12420000
         BEGIN                                                 <<01869>>12425000
         <<MUST OPEN NEW BUFFER>>                              <<01869>>12430000
         EXCHANGEDB(0);                                        <<01869>>12435000
         OPEN'BUFFER'FILE;                                     <<01869>>12440000
         IF ERRCODE<>0 THEN                                    <<01869>>12445000
            BEGIN                                              <<01869>>12450000
            DEL;   << Get rid of return address >>             <<01869>>12455000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12460000
            END;                                               <<01869>>12465000
         <<CLOSE OLD FILE>>                                    <<01869>>12470000
         EXCHANGEDB(BUFDST);                                   <<01869>>12475000
         FPOINT(SAVEFILENO,(DLOGBUFF(TRECS)-DLOGBUFF(RECS'IN'PREV))     12480000
                /DOUBLE(BLKFACTOR));                           <<01872>>12485000
$EDIT VOID=12545000                                            <<01872>>12490000
         EXCHANGEDB(0);                                        <<01869>>12550000
         FCONTROL(SAVEFILENO,SET'EOF,DUMMY);                   <<01869>>12555000
         IF <> THEN                                            <<01869>>12560000
            BEGIN                                              <<01869>>12565000
            FCHECK(SAVEFILENO,ERRCODE);                        <<01869>>12570000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12575000
            ULERRCODE := FWRITEERROR;                          <<01869>>12580000
            GENMSG(SETNO,ULERRCODE,0,@OLD'FILE'NAME,@PROCNAME, <<01869>>12585000
                   ,,,0);                                      <<01869>>12590000
            DEL;    << Get rid of return address >>            <<01869>>12595000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12600000
            END;                                               <<01869>>12605000
         FCLOSE(SAVEFILENO,0,0);                               <<01869>>12610000
         IF <> THEN                                            <<01869>>12615000
            BEGIN                                              <<01869>>12620000
            FCHECK(SAVEFILENO,ERRCODE);                        <<01869>>12625000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>12630000
            ULERRCODE := OLDLOGCLOSEFAIL;                      <<01869>>12635000
            GENMSG(SETNO,ULERRCODE,0,@OLD'FILE'NAME,@PROCNAME, <<01869>>12640000
                   ,,,0);                                      <<01869>>12645000
            DEL;     << Get rid of return address >>           <<01869>>12650000
            GO CHANGELOG'ERROR'RECOVERY;                       <<01869>>12655000
            END;                                               <<01869>>12660000
         END;  <<OLDTYPE=DISC>>                                <<01869>>12665000
      END;<<NEWFILE IS SERIAL>>                                <<01869>>12670000
      EXCHANGEDB(0);                                           <<01869>>12675000
      MOVE'TO'DSEG(BUFDST,PREVIOUS'FILE/2,@OLD'FILE'NAME/2,18);<<01869>>12680000
      MOVE'TO'DSEG(BUFDST,CURRENT'FILE/2,@FNAME/2,18);         <<01869>>12685000
      EXCHANGEDB(BUFDST);                                      <<01869>>12690000
      LOGBUFF(P'TYPE):=LOGBUFF(LOGTYPE);                       <<01869>>12695000
      LOGBUFF(C'TYPE):=LOGBUFF(NEWTYPE);                       <<01869>>12700000
      <<#recs in disc buffer file remains same.we reuse>>      <<01869>>12705000
      <<the old disc buffer file                       >>      <<01869>>12710000
      IF Q'OLDTYPE <> DISC AND                                 <<01869>>12715000
         Q'NEWTYPE <> DISC THEN                                <<01869>>12720000
         DTEMP := LIMIT;                                       <<01869>>12725000
   END;                                                        <<01869>>12730000
$PAGE "Logging Process -- Main Body"                           <<01869>>12735000
IF (RESTART' := FALSE) THEN                                             12740000
   BEGIN                                                                12745000
RESTART:                                                                12750000
   RESTART':=TRUE;                                                      12755000
   END;                                                                 12760000
                                                               <<01869>>12765000
                                                               <<01869>>12770000
<< Turn traps off  >>                                          <<01869>>12775000
                                                               <<01869>>12780000
ASSEMBLE(PSHR %10);                                                     12785000
TOS.(2:1):=0;                                                           12790000
ASSEMBLE(SETR %10);                                                     12795000
                                                               <<01869>>12800000
SWITCH'FLAG := FALSE;                                          <<01869>>12805000
GOT'LOGBUFF := FALSE;                                          <<01869>>12810000
                                                                        12815000
<< When return from OPEN'LOGFILE will have the LOGSIR.  >>              12820000
                                                                        12825000
OPEN'LOGFILE;                                             <<04962>>     12830000
                                                                        12835000
<<CREATE LOGGING DATA SEGMENT>>                                         12840000
                                                                        12845000
MOVE'FROM'DSEG(@MAXUSERS,LOGDST,MAX'USR'PROC,1);               <<01869>>12850000
<< If max users is zero, then can't let anyone start the Proc>><<01869>>12855000
                                                               <<01869>>12860000
IF MAXUSERS <= 0 THEN                                          <<01869>>12865000
   ABEND(BAD'USER'COUNT,ENTRY'(LGTYPE),PRINT'PROCNAME);        <<01869>>12870000
                                                               <<01869>>12875000
LEN:=BLKSIZE+MAXUSERS*BENTRYSIZE+BENTRYBASE;                            12880000
ENTRY'(DST):=BUFDST:=GETDATASEG(LEN,LEN);                               12885000
IF ENTRY'(DST) = 0                                             <<01869>>12890000
      THEN ABEND(NODSEG,ENTRY'(LGTYPE),PRINT'PROCNAME);        <<01869>>12895000
                                                                        12900000
GOT'LOGBUFF := TRUE;                                           <<01869>>12905000
ENTRY'(PIN) := MYPIN;       << Pin number of logging process >><<01869>>12910000
                                                                        12915000
<<NOW WRITE ENTRY BACK TO MASTER LOGGING DATA SEGMENT>>                 12920000
                                                                        12925000
MOVE'TO'DSEG(LOGDST,TABINDEX',@ENTRY',TENTRYSIZE-2);           <<01869>>12930000
  WRITEDSEG(LOGDST);                                           <<01910>>12931000
                                                                        12935000
<<INITIALIZE LOGGING DATA SEGMENT>>                                     12940000
                                                                        12945000
<<SET UP GLOBAL AND COMMUNICATIONS AREA>>                               12950000
                                                               <<01869>>12955000
EXCHANGEDB(BUFDST);   << DB to LOGBUFF >>                               12960000
                                                               <<01869>>12965000
<< Clear global communications area of LOGBUFF. >>                      12970000
                                                                        12975000
LOGBUFF := 0;                                                  <<01869>>12980000
MOVE LOGBUFF(1):=LOGBUFF, (BENTRYBASE-1);                      <<01869>>12985000
                                                               <<01869>>12990000
<< First get the logid >>                                      <<01869>>12995000
                                                               <<01869>>13000000
TOS := BUFDST;        << Dst of LOGBUFF >>                     <<01869>>13005000
TOS := LOGID/2;       << Word offset into LOGBUFF >>           <<01869>>13010000
TOS := LOGDST;        << Source DST - LOGTAB >>                <<01869>>13015000
TOS := LGNAME/2 + TABINDEX';    << Word offset in LOGTAB >>    <<01869>>13020000
TOS := 4;             << Count >>                              <<01869>>13025000
ASSEMBLE (MDS 5);                                              <<01869>>13030000
                                                               <<01869>>13035000
                                                               <<01869>>13040000
LOGBUFF(RESOURCE1) := 0;                                       <<01875>>13045000
LOGBUFF(RESOURCE2) := 0;                                       <<01875>>13046000
LOGBUFF(RESOURCE3) := 0;                                       <<01875>>13047000
DLOGBUFF(INBUFREC):=0D;                                                 13050000
DLOGBUFF(LOGADDR):=ADDR;                                                13055000
LOGBUFF(AUTO) := ENTRY'(LGAUTO);                               <<01869>>13060000
LOGBUFF(CHANGE) := ALLOW'CHANGELOG;                            <<01869>>13065000
LOGBUFF(LOGTYPE) := ENTRY'(LGTYPE);                            <<01869>>13070000
                                                               <<01869>>13075000
LOGBUFF(NEWTYPE) := NULL;                                      <<01869>>13080000
LOGBUFF(SWITCH') := ENTRY'(LGSWITCH);                          <<01869>>13085000
LOGBUFF(STATE) := INITIALIZING;                                <<01869>>13090000
LOGBUFF(NUMUSER):=0;                                                    13095000
LOGBUFF(LOGDEV) := ENTRY'(LGDEV) := DISCLDEV;                  <<01869>>13100000
DLOGBUFF(FSIZE):=DTEMP;                                        <<01869>>13105000
DLOGBUFF(MAXFSPACE) := LIMIT - 1D;                             <<01869>>13110000
DLOGBUFF(FSPACE'):=DENTRY'(BSIZE):=DTEMP;                      <<01869>>13115000
LOGBUFF(BSPACE):=BLKFACTOR;                                             13120000
LOGBUFF(SLPCT):=0;                                                      13125000
LOGBUFF(USERNO):=0;                                                     13130000
LOGBUFF(LOGPIN) := ENTRY'(PIN) := MYPIN;                       <<01869>>13135000
DLOGBUFF(TRECS):=0D;                                                    13140000
LOGBUFF(UHEAD):=NULL;                                                   13145000
LOGBUFF(FHEAD):=BENTRYBASE;                                             13150000
LOGBUFF(LOGERR) := FALSE;                                      <<01869>>13155000
LOGBUFF(FSERR'CODE) := 0;                                      <<01869>>13160000
LOGBUFF(ULERR'CODE) := 0;                                      <<01869>>13165000
LOGBUFF(HEAD'CHANGE'PIN) := 0;                                 <<01869>>13170000
LOGBUFF(MSG) := CONTINUE;                                      <<01869>>13175000
LOGBUFF(USERMSG):=CONTINUE;                                    <<01869>>13180000
LOGBUFF(LOGMSG):=CONTINUE;                                     <<01869>>13185000
LOGBUFF(MAXUSER') := MAXUSERS;                                 <<01869>>13190000
LOGBUFF(LASTEXT'):=NUMEXT;                                     <<01869>>13195000
LOGBUFF(BDST):=ENTRY'(DST);                                    <<01869>>13200000
OUTBUFREC:=0D;                                                          13205000
LOGBUFF(EXTENT) := EXTNUM;                                     <<01869>>13210000
LOGBUFF(BUFUSED) := 0;                                         <<01869>>13215000
LOGBUFF(VSETNO) := Q'VSETNO;                                   <<01869>>13220000
IF ENTRY'(LGTYPE) <> DISC THEN                                 <<01869>>13225000
   BEGIN                                                       <<01869>>13230000
   DLOGBUFF(OLD'LIMIT):=0D;                                    <<01869>>13235000
   LOGBUFF(OLD'NUMEXT):=0;                                     <<01869>>13240000
   END                                                         <<01869>>13245000
ELSE                                                           <<01869>>13250000
   BEGIN                                                       <<01869>>13255000
   LOGBUFF(OLD'NUMEXT):=NUMEXT;                                <<01869>>13260000
   DLOGBUFF(OLD'LIMIT) := LIMIT;                               <<01869>>13265000
   END;                                                        <<01869>>13270000
                                                               <<01877>>13271000
LOGBUFF(NOT'SAFE'TO'STOP) := FALSE;                            <<01877>>13272000
                                                                        13275000
<< Now set up the user entries of the LOGBUFF >>                        13280000
                                                               <<01869>>13285000
LOGBUFF(BENTRYBASE) := "  ";                                   <<01869>>13290000
MOVE LOGBUFF(BENTRYBASE+1) := LOGBUFF(BENTRYBASE),             <<01869>>13295000
                              (MAXUSERS*BENTRYSIZE-1);         <<01869>>13300000
                                                               <<01869>>13305000
TEMP:=NULL;                                                             13310000
                                                                        13315000
I:=0;                                                                   13320000
DO                                                                      13325000
BEGIN                                                                   13330000
   INDEX:=BENTRYBASE+I*BENTRYSIZE;                                      13335000
   LOGBUFF(PENTRY):=TEMP;                                               13340000
   LOGBUFF(NENTRY):=INDEX+BENTRYSIZE;                                   13345000
   TEMP:=INDEX;                                                         13350000
END UNTIL (I:=I+1) = MAXUSERS;                                          13355000
                                                               <<01869>>13360000
LOGBUFF(NENTRY):=NULL;                                                  13365000
INDEX:=0;                                                               13370000
$EDIT                                                          <<01875>>13375000
$EDIT                                                          <<01875>>13380000
                                                                        13385000
RELSIR(LOGSIR,A);                                                       13390000
@BUF:=BUFBASE;                                                          13395000
                                                               <<01869>>13400000
<< Clear the buffer area of the LOGBUFF. >>                    <<01869>>13405000
                                                               <<01869>>13410000
BUF := "  ";                                                   <<01869>>13415000
MOVE BUF(1):=BUF,(BLKSIZE-1);                                           13420000
                                                               <<01869>>13425000
<< Now set up pointer to area to format the header record >>   <<01869>>13430000
                                                               <<01869>>13435000
@BUF:=BUFBASE+(BLKFACTOR-LOGBUFF(BSPACE))*RECSIZE;             <<01869>>13440000
@DBUF:=@BUF;                                                            13445000
@BBUF := 2 * @BUF;                                             <<01869>>13450000
                                                               <<01869>>13455000
IF NOT RESTART' THEN                                                    13460000
BEGIN                                                                   13465000
   << Format a log start (header) record.          >>          <<01869>>13470000
                                                               <<01869>>13475000
   DLOGBUFF(FIRST'C'TIME) := CLOCK;                            <<01869>>13480000
   LOGBUFF(FIRST'C'DATE) := CALENDAR;                          <<01869>>13485000
   LOGBUFF(F'TYPE) := ENTRY'(LGTYPE);                          <<01869>>13490000
   LOGBUFF(C'TYPE) := ENTRY'(LGTYPE);                          <<01869>>13495000
   LOGBUFF(VSETNO) := Q'VSETNO := 1;                           <<01869>>13500000
   BUF(CODE):=HEADER;                                                   13505000
   DBUF(RNUM):=DLOGBUFF(TRECS):=DLOGBUFF(TRECS)+1D;                     13510000
   BUF(DATE):=CALENDAR;                                                 13515000
   DBUF(TIME):=CLOCK;                                                   13520000
   MOVE BBUF(LID') := BLOGBUFF(LOGID), (8);                    <<01869>>13525000
                                                               <<01869>>13530000
   X:=RECSIZEM1;                                               <<01869>>13535000
   TOS:=-1;                                                             13540000
   DO                                                                   13545000
   BEGIN                                                                13550000
      IF X <> CKSUM THEN                                                13555000
      TOS:=TOS XOR BUF(X);                                              13560000
   END UNTIL (X:=X-1) < 0;                                              13565000
   BUF(CKSUM):=TOS;                                                     13570000
   LOGBUFF(BSPACE):=LOGBUFF(BSPACE)-1;                                  13575000
   LOGBUFF(BUFUSED) := LOGBUFF(BUFUSED) + 1;                   <<01869>>13580000
   FLUSH(NULL,FALSE);                                          <<01869>>13585000
   CHECKMSG;                                                   <<01869>>13590000
END;                                                                    13595000
                                                               <<01869>>13600000
IF RESTART' THEN                                                        13605000
BEGIN                                                                   13610000
   << Re-read file to see where we left off, format a log    >><<01869>>13615000
   << restart record, and then we're ready to go again.      >><<01869>>13620000
                                                               <<01869>>13625000
   FIND'LAST'RECORD;                                                    13630000
                                                               <<01869>>13635000
<< Set up LOGBUFF to continue logging >>                       <<01869>>13640000
                                                               <<01869>>13645000
CONTINUE'LOGGING;                                              <<01869>>13650000
                                                               <<01869>>13655000
   FORMATRESTART;                                                       13660000
                                                                        13665000
END;                                            <<IF RESTART>>          13670000
                                                                        13675000
LOGBUFF(C'TYPE):=ENTRY'(LGTYPE);                               <<01869>>13680000
EXCHANGEDB(0);         << Back to stack >>                              13685000
                                                               <<01869>>13690000
   MOVE'TO'DSEG(BUFDST,CURRENT'FILE/2,@FNAME/2,18);            <<01869>>13695000
   IF NOT RESTART' THEN                                        <<01869>>13700000
      MOVE'TO'DSEG(BUFDST,FIRST'FILE/2,@FNAME/2,18);           <<01869>>13705000
                                                               <<01869>>13710000
<< At this point we've finished the initialization for the   >><<01869>>13715000
<< process. Now need to set the status field in the LOGTAB to>><<01869>>13720000
<< INACT so users can use the process.                       >><<01869>>13725000
                                                               <<01869>>13730000
EXCHANGEDB(BUFDST);       << to LOGBUFF  >>                             13735000
$EDIT                                                          <<01875>>13740000
$EDIT                                                          <<01875>>13765000
                                                               <<01869>>13770000
<< Now we can get the LOGSIR (preserving the locking order). >><<01869>>13775000
                                                               <<01869>>13780000
EXCHANGEDB(LOGDST);       << to LOGTAB   >>                    <<01869>>13785000
A := GETSIR(LOGSIR);                                           <<01869>>13790000
LOGTAB(TABINDEX' + STATUS) := INACT;                           <<01869>>13795000
RELSIR(LOGSIR,A);                                              <<01869>>13800000
                                                               <<01869>>13805000
EXCHANGEDB(BUFDST);       << Return to LOGBUFF >>              <<01869>>13810000
OBTAIN(LOGBUFF(RESOURCE2),NULL);                               <<01875>>13815000
$IF X1=ON                                                      <<01874>>13816000
      WHAT'S'UP ( BC'OBTAIN,2 );                               <<01874>>13818000
$IF                                                            <<01874>>13819000
RESFLAG2 := TRUE;                                              <<01875>>13820000
                                                               <<01869>>13825000
EXCHANGEDB(0);      << Back to stack >>                                 13830000
MSGNO:=LOGPROCRUNS;                                                     13835000
GENMSG(SETNO,MSGNO,0,@PROCNAME,,,,,0);                         <<01869>>13840000
                                                                        13845000
EXCHANGEDB(BUFDST);    << Back to LOGBUFF >>                            13850000
GO GETIT;                                                      <<01869>>13855000
                                                               <<01869>>13860000
$PAGE "Logging Process -- GetIt"                               <<01869>>13865000
GETIT:                                                                  13870000
                                                                        13875000
<< This is the main work loop. Get here to see what there is >>         13880000
<< to do. For serial log files, transfer info from the disc  >>         13885000
<< buffer file to the serial log file. For disc log files,   >>         13890000
<< allocate the next extent.  DB at LOGBUFF.                 >>         13895000
                                                                        13900000
                                                                        13905000
IF ABNORMAL'EXIT THEN GO WAIT1;                                <<01869>>13910000
                                                               <<01869>>13915000
LOGBUFF(STATE) := ACT;                                                  13920000
                                                                        13925000
IF LOGBUFF(LOGTYPE) <> DISC THEN                                        13930000
   BEGIN             << Serial logging >>                               13935000
   WHILE DLOGBUFF(FSIZE) - DLOGBUFF(FSPACE') >=                         13940000
         DOUBLE(BLKFACTOR)   DO                                         13945000
      BEGIN                                                             13950000
      << There's something in the disc buffer file >>                   13955000
                                                                        13960000
      IF RESFLAG2 THEN                                         <<01875>>13965000
         BEGIN       << Don't hold resource when blocked I/O >>         13970000
         RELEASE(LOGBUFF(RESOURCE2),NULL,1);                   <<01875>>13975000
$IF X1=ON                                                      <<01874>>13980000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>13990000
$IF                                                            <<01874>>13995000
         RESFLAG2 := FALSE;                                    <<01875>>14000000
         END;                                                           14005000
      IF RESFLAG1 THEN                                         <<01875>>14010000
         BEGIN                                                 <<01875>>14011000
         RELEASE(LOGBUFF(RESOURCE1),NULL,1);                   <<01875>>14012000
$IF X1=ON                                                               14012100
         WHAT'S'UP ( BC'RELEASE,1 );                           <<01874>>14012200
$IF                                                                     14012300
         RESFLAG2 := FALSE;                                    <<01875>>14013000
         END;                                                  <<01875>>14014000
     << Move a block from the disc buffer file to the serial >>         14015000
     << log file.                                            >>         14020000
                                                                        14025000
      IF NOT EMPTY'DISC'BUFFER(BLKSIZE) THEN                            14030000
         BEGIN                                                          14035000
         IF LOGBUFF(LOGMSG) = WRITEERR THEN                             14040000
            BEGIN                                                       14045000
            << If auto change for tape write error is ever   >><<01869>>14050000
            << implemented. Should check LOGBUFF(AUTO) to see>><<01869>>14055000
            << if AUTO change has been enabled. If it is,    >><<01869>>14060000
            << then goto AUTO'CHANGE'LOGFILE. Will have to   >><<01869>>14065000
            << decide how to put the changelog record into   >><<01869>>14070000
            << the file that just got a write error.         >><<01869>>14075000
                                                               <<01869>>14080000
            LOGBUFF(MSG) := SUSPEND;                                    14085000
            END;                                                        14090000
         GO WAIT1;                                                      14095000
         END;                                                           14100000
                                                                        14105000
      << If the user msg is DISCSPACE, then there was no room>>         14110000
      << in the buffer file to flush the memory buffer. The  >>         14115000
      << user process (doing the FLUSH) owns the resource.   >>         14120000
                                                                        14125000
      IF LOGBUFF(USERMSG) <> DISCSPACE AND NOT RESFLAG2 THEN   <<01875>>14130000
         BEGIN                                                          14135000
         OBTAIN(LOGBUFF(RESOURCE2),NULL);                      <<01875>>14140000
$IF X1=ON                                                      <<01874>>14141000
      WHAT'S'UP ( BC'OBTAIN,2 );                               <<01874>>14143000
$IF                                                            <<01874>>14144000
         RESFLAG2 := TRUE;                                     <<01875>>14145000
         END;                                                           14150000
                                                                        14155000
      << Update global info to reflect the successful write. >>         14160000
                                                                        14165000
      OUTBUFREC := OUTBUFREC + DOUBLE(BLKFACTOR);                       14170000
      IF OUTBUFREC >= DLOGBUFF(FSIZE) THEN OUTBUFREC := 0D;             14175000
      DLOGBUFF(FSPACE') := DLOGBUFF(FSPACE')+DOUBLE(BLKFACTOR);         14180000
                                                                        14185000
      LOGBUFF(LOGMSG) := CONTINUE;                                      14190000
      WAKEUP';                                                          14195000
                                                                        14200000
      << If the message was DISCSPACE, user needed one block >>         14205000
      << cleared from the buffer file before FLUSH could     >>         14210000
      << complete. Since the user owns the resource, must go >>         14215000
      << to WAIT1 (and not loop thru here again) to avoid a  >>         14220000
      << possible deadlock over the resource.                >>         14225000
                                                                        14230000
      IF LOGBUFF(USERMSG) = DISCSPACE THEN                              14235000
         BEGIN                                                          14240000
         LOGBUFF(USERMSG) := CONTINUE;                                  14245000
         GO WAIT1;                                                      14250000
         END;                                                           14255000
                                                               <<01869>>14260000
      GO GETIT;                                                <<01869>>14265000
      END;                                                              14270000
                                                                        14275000
   GO WAIT1;                                                            14280000
   END                                                                  14285000
ELSE                                                                    14290000
   IF LOGBUFF(LOGTYPE) = DISC THEN                                      14295000
      BEGIN                                                             14300000
      IF LOGBUFF(USERMSG) = DISCSPACE THEN                              14305000
         BEGIN                                                          14310000
         << User needs another extent allocated >>                      14315000
                                                                        14320000
         LOGBUFF(USERMSG) := CONTINUE;                                  14325000
         IF EXTNUM + 1 > NUMEXT THEN                                    14330000
            BEGIN                                                       14335000
            << Opps...no more extents - EOF >>                          14340000
                                                                        14345000
            IF LOGBUFF(AUTO) THEN                                       14350000
               BEGIN                                                    14355000
               << O.K. change to new log file >>                        14360000
                                                               <<01869>>14365000
               LOGBUFF(USERMSG) := DISCSPACE;                  <<01869>>14370000
               GO AUTO'CHANGE'LOGFILE;                         <<01869>>14375000
               END;                                                     14380000
                                                                        14385000
            << EOF and user did not want to automatically    >>         14390000
            << change to a new log file - too bad.           >>         14395000
                                                                        14400000
            IF NOT NOTIFIED THEN                                        14405000
               BEGIN                                                    14410000
               ULERRCODE := LOGFILEEOF;                        <<01869>>14415000
               EXCHANGEDB(0);                                  <<01869>>14420000
               GENMSG(SETNO,ULERRCODE,0,@FNAME,@PROCNAME,,,,0);<<01869>>14425000
               EXCHANGEDB(BUFDST);                                      14430000
               NOTIFIED := TRUE;                                        14435000
               END;                                                     14440000
                                                                        14445000
            << Not much to do but wait for all users to quit>>          14450000
                                                                        14455000
            LOGBUFF(MSG) := STOP;                                       14460000
            LOGBUFF(LOGMSG) := EOFONLOGFILE;                            14465000
            DLOGBUFF(INBUFREC) := DLOGBUFF(FSIZE);                      14470000
            WAKEUP';                                                    14475000
            GO WAIT1;                                                   14480000
            END                                                         14485000
         ELSE                                                           14490000
            BEGIN                                                       14495000
            << There are more extents available to us >>                14500000
                                                                        14505000
            IF NOT ALLOCATE'NEXT'EXTENT THEN                            14510000
               BEGIN                                                    14515000
               << Oh no...can't allocate the extent! >>                 14520000
                                                                        14525000
               ABNORMAL'EXIT := TRUE;                                   14530000
               GO WAIT1;                                                14535000
               END;                                                     14540000
            END;                                                        14545000
         END;       << Need another extent >>                  <<01869>>14550000
                                                                        14555000
      GO WAIT1;                                                         14560000
      END;            << Disc logging >>                                14565000
$PAGE "Logging Process -- Requested'Changelog"                 <<01869>>14570000
                                                               <<01869>>14575000
                                                               <<01869>>14580000
REQUESTED'CHANGELOG:                                           <<01869>>14585000
                                                               <<01869>>14590000
IF RESFLAG2 THEN                                               <<01875>>14595000
   BEGIN                                                       <<01874>>14595100
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>14595200
$IF X1=ON                                                      <<01874>>14596000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>14598000
$IF                                                            <<01874>>14599000
   RESFLAG2 := FALSE;                                          <<01875>>14599050
   END;                                                        <<01874>>14599100
                                                               <<01869>>14600000
<< Get here if :CHANGELOG was issued. All info already updated <<01869>>14605000
<< in the LOGTAB. Need to release all resources to aquire them <<01869>>14610000
<< in the prober order to avoid a deadlock. DB at Logbuff.    ><<01869>>14615000
                                                               <<01869>>14620000
IF NOT RESFLAG1 THEN                                           <<01875>>14621000
   OBTAIN(LOGBUFF(RESOURCE1),NULL);                            <<01875>>14622000
$IF X1=ON                                                               14623000
   WHAT'S'UP ( BC'OBTAIN,1 );                                  <<01874>>14624000
$IF                                                                     14625000
A := GETSIR(LOGSIR);                                           <<01869>>14630000
OBTAIN(LOGBUFF(RESOURCE2),NULL);                               <<01875>>14635000
$IF X1=ON                                                      <<01874>>14636000
      WHAT'S'UP ( BC'OBTAIN,2 );                               <<01874>>14638000
$IF                                                            <<01874>>14639000
USER'REQUESTED'CHANGE := TRUE;                                 <<01869>>14640000
RESFLAG1 := TRUE;                                              <<01875>>14645000
RESFLAG2 := TRUE;                                              <<01875>>14646000
                                                               <<01869>>14650000
IF ABNORMAL'EXIT THEN                                          <<01869>>14655000
   BEGIN                                                       <<01869>>14660000
   EXCHANGEDB(LOGDST);                                         <<01869>>14665000
   LOGTAB(TABINDEX'+LGSWITCH) := FALSE;                        <<01869>>14670000
   LOGTAB(TABINDEX'+LGNEWTYPE) := NULL;                        <<01869>>14675000
   WRITEDSEG(LOGDST);                                          <<01869>>14680000
   EXCHANGEDB(BUFDST);                                         <<01869>>14685000
   LOGBUFF(SWITCH') := FALSE;                                  <<01869>>14690000
   LOGBUFF(NEWTYPE) := NULL;                                   <<01869>>14695000
   LOGBUFF(LOGMSG) := WRITEERR;                                <<01869>>14700000
   LOGBUFF(ULERR'CODE) := PREVIOUS'ERROR;                      <<01869>>14705000
   LOGBUFF(LOGERR) := TRUE;                                    <<01869>>14710000
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>14710200
$IF X1=ON                                                               14710220
   WHAT'S'UP ( BC'RELEASE,2 );                                 <<01874>>14710230
$IF                                                                     14710240
   RESFLAG2 := FALSE;                                          <<01875>>14710300
   RELSIR(LOGSIR,A);                                           <<01869>>14715000
   GO WAIT1;                                                   <<01869>>14720000
   END;                                                        <<01869>>14725000
                                                               <<01869>>14730000
GO CHANGE'LOGFILE;                                             <<01869>>14735000
$PAGE "Logging Process -- Auto'Changelog"                      <<01869>>14740000
AUTO'CHANGE'LOGFILE:                                           <<01869>>14745000
                                                               <<01869>>14750000
<< Get here if need to perform an auto changelog because the  ><<01869>>14755000
<< disc log file is full. (May also want to use this to do an ><<01869>>14760000
<< auto changelog if get a write error to the current log file><<01869>>14765000
<<                                                            ><<01869>>14770000
<< The resource is already owned by the process doing a FLUSH ><<01869>>14775000
<< if the message is DISCSPACE.  DB at Logbuff.               ><<01869>>14780000
                                                               <<01869>>14785000
IF RESFLAG2 THEN                                               <<01875>>14785100
   BEGIN                                                       <<01875>>14785200
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>14785300
$IF X1=ON                                                               14785320
   WHAT'S'UP ( BC'RELEASE,2 );                                 <<01874>>14785330
$IF                                                                     14785340
   RESFLAG2 := FALSE;                                          <<01875>>14785400
   END;                                                        <<01875>>14785500
                                                               <<01875>>14785600
A := GETSIR(LOGSIR);                                           <<01869>>14790000
OBTAIN(LOGBUFF(RESOURCE2),NULL);                               <<01875>>14795000
$IF X1=ON                                                               14796000
WHAT'S'UP ( BC'OBTAIN,2 );                                     <<01874>>14797000
$IF                                                                     14797500
IF ABNORMAL'EXIT THEN                                          <<01869>>14800000
   BEGIN                                                       <<01869>>14805000
   LOGBUFF(LOGMSG) := EOFONLOGFILE;                            <<01869>>14810000
   LOGBUFF(ULERR'CODE) := PREVIOUS'ERROR;                      <<01869>>14815000
   LOGBUFF(LOGERR) := TRUE;                                    <<01869>>14820000
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>14821000
$IF X1=ON                                                               14821200
   WHAT'S'UP ( BC'RELEASE,2 );                                          14821300
$IF                                                                     14821400
   RESFLAG2 := FALSE;                                          <<01875>>14822000
   RELSIR(LOGSIR,A);                                           <<01869>>14825000
   GO WAIT1;                                                   <<01869>>14830000
   END;                                                        <<01869>>14835000
                                                               <<01869>>14840000
EXCHANGEDB(LOGDST);                                            <<01869>>14845000
LOGTAB(TABINDEX'+LGSWITCH) := TRUE;                            <<01869>>14850000
LOGTAB(TABINDEX'+LGNEWTYPE) := LOGTAB(TABINDEX'+LGTYPE);       <<01869>>14855000
                                                               <<01869>>14860000
EXCHANGEDB(BUFDST);                                            <<01869>>14865000
LOGBUFF(SWITCH') := TRUE;                                      <<01869>>14870000
LOGBUFF(NEWTYPE) := ENTRY'(LGTYPE);                            <<01869>>14875000
                                                               <<01869>>14880000
                                                               <<01869>>14885000
GO CHANGE'LOGFILE;                                             <<01869>>14890000
$PAGE "Logging Process -- Change'Logfile"                      <<01869>>14895000
CHANGE'LOGFILE:                                                         14900000
                                                               <<01869>>14905000
SWITCH'FLAG := TRUE;                                           <<01869>>14910000
LOGBUFF(STATE) := ACT;                                         <<01869>>14915000
RESTART' := FALSE;                                             <<01869>>14920000
                                                               <<01869>>14925000
<< First get the new log file name and open new log file.    >><<01869>>14930000
                                                               <<01869>>14935000
GET'NEW'FILE;                                                  <<01869>>14940000
                                                               <<01869>>14945000
<< Now close the old log file. >>                              <<01869>>14950000
                                                               <<01869>>14955000
FINISH'CHANGELOG;                                              <<01869>>14960000
                                                               <<01869>>14965000
<< Now set up the logbuff to reflect the characteristics of  >><<01869>>14970000
<< the new log file.                                         >><<01869>>14975000
                                                               <<01869>>14980000
SET'UP'LOGBUFF;                                                <<01869>>14985000
                                                               <<01869>>14990000
<< Now format the first record of the new log file. >>         <<01869>>14995000
                                                               <<01869>>15000000
FORMAT'FIRST'FILE;                                             <<01869>>15005000
                                                               <<01869>>15010000
IF ERRCODE = 0 AND ULERRCODE =  0 THEN                         <<01869>>15015000
   BEGIN     << No error -- success >>                         <<01869>>15020000
   LOGBUFF(LOGERR) := FALSE;                                   <<01869>>15025000
   LOGBUFF(ULERR'CODE) := 0;                                   <<01869>>15030000
   LOGBUFF(FSERR'CODE) := 0;                                   <<01869>>15035000
   LOGBUFF(USERMSG) := CONTINUE;                               <<01869>>15040000
   LOGBUFF(LOGMSG) := CONTINUE;                                <<01869>>15045000
   LOGBUFF(SWITCH') := FALSE;                                  <<01869>>15050000
   LOGBUFF(NEWTYPE) := NULL;                                   <<01869>>15055000
   END                                                         <<01869>>15060000
ELSE                                                           <<01869>>15065000
   GO CHANGELOG'ERROR'RECOVERY;                                <<01869>>15070000
                                                               <<01869>>15075000
SWITCH'FLAG := FALSE;                                          <<01869>>15080000
                                                               <<01869>>15085000
EXCHANGEDB(0);                                                 <<01869>>15090000
ENTRY'(LGNEWTYPE) := NULL;                                     <<01869>>15095000
ENTRY'(LGSWITCH) := FALSE;                                     <<01869>>15100000
MOVE'TO'DSEG(LOGDST,TABINDEX',@ENTRY',TENTRYSIZE-2);           <<01869>>15105000
WRITEDSEG(LOGDST);                                             <<01869>>15110000
                                                               <<01869>>15115000
<< Now want to update the LIDTAB to reflect the new current >> <<01869>>15120000
<< log file in the set.                                     >> <<01869>>15125000
                                                               <<01869>>15130000
$EDIT VOID=15135000                                                     15135000
LID'TYP.TYP'CURRENT := ENTRY'(LGTYPE);                         <<01869>>15140000
ALTER'LID'ENTRY(ENTRY'(LGNAME),,FNAME,LID'TYP);                <<01869>>15145000
                                                               <<01869>>15150000
GENMSG(SETNO,CHANGELOG'OK,0,@PROCNAME,@OLD'FILE'NAME,@FNAME,   <<01869>>15155000
        ,,0);                                                  <<01869> 15160000
                                                               <<01869>>15165000
EXCHANGEDB(BUFDST);                                            <<01869>>15170000
IF LOGBUFF(HEAD'CHANGE'PIN) <> 0 THEN                          <<01869>>15175000
   BEGIN                                                       <<01869>>15180000
   AWAKE(LOGBUFF(HEAD'CHANGE'PIN),%20,0);                      <<01869>>15185000
$IF X1=ON                                                      <<01874>>15190000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>15200000
$IF                                                            <<01874>>15205000
   LOGBUFF(HEAD'CHANGE'PIN) := 0;                              <<01869>>15210000
   END;                                                        <<01869>>15215000
                                                               <<01869>>15220000
RELEASE(LOGBUFF(RESOURCE2),NULL,1);                            <<01875>>15221000
$IF X1=ON                                                               15221200
WHAT'S'UP (BC'RELEASE,2 );                                              15221300
$IF                                                                     15221400
RESFLAG2 := FALSE;                                             <<01875>>15222000
RELSIR(LOGSIR,A);                                              <<01869>>15225000
GO WAIT1;                                                      <<01869>>15230000
$PAGE "Logging Process -- Changelog'Error'Recovery"            <<01869>>15235000
CHANGELOG'ERROR'RECOVERY:                                      <<01869>>15240000
                                                               <<01869>>15245000
<< At this point this is very wishful thinking. Maybe someday>><<01869>>15250000
<< we will be able to recover from an error.....             >><<01869>>15255000
                                                               <<01869>>15260000
EXCHANGEDB(0);                                                 <<01869>>15265000
GO CHANGELOG'FAIL;                                             <<01869>>15270000
$PAGE "Logging Process -- Changelog'Fail"                      <<01869>>15275000
CHANGELOG'FAIL:                                                <<01869>>15280000
                                                               <<01869>>15285000
<< Get here if found a fatal error during a changelog. DB is >><<01869>>15290000
<< at stack.                                                 >><<01869>>15295000
                                                               <<01869>>15300000
GENMSG(SETNO,CHANGELOG'ABORT,0,@PROCNAME,,,,,0);               <<01869>>15305000
                                                               <<01869>>15310000
<< Put old info back into LOGTAB. >>                           <<01869>>15315000
                                                               <<01869>>15320000
DEPOSIT'FILENAME(OLD'FILE'NAME,BENTRY'(LFNAME),               <<<01869>>15325000
       BENTRY'(LFLOCKW),BENTRY'(LFGROUP),BENTRY'(LFACCT));     <<01869>>15330000
                                                               <<01869>>15335000
ENTRY'(LGNEWTYPE) := NULL;                                     <<01869>>15340000
ENTRY'(LGSWITCH) := FALSE;                                     <<01869>>15345000
                                                               <<01869>>15350000
MOVE'TO'DSEG(LOGDST,TABINDEX',@ENTRY',TENTRYSIZE-2);           <<01869>>15355000
WRITEDSEG(LOGDST);                                             <<01869>>15360000
EXCHANGEDB(BUFDST);                                            <<01869>>15365000
                                                               <<01869>>15370000
IF ERRCODE = OUT'OF'GROUP'SPACE OR                             <<01869>>15375000
   ERRCODE = OUT'OF'ACCOUNT'SPACE THEN                         <<01869>>15380000
   LOGBUFF(LOGMSG) := DISCSPACE                                <<01869>>15385000
ELSE                                                           <<01869>>15390000
   LOGBUFF(LOGMSG) := WRITEERR;                                <<01869>>15395000
                                                               <<01869>>15400000
IF LOGBUFF(USERMSG) = DISCSPACE THEN   << Auto change on EOF>> <<01869>>15405000
   LOGBUFF(LOGMSG) := EOFONLOGFILE;                            <<01869>>15410000
                                                               <<01869>>15415000
                                                               <<01869>>15420000
LOGBUFF(LOGERR) := TRUE;                                       <<01869>>15425000
LOGBUFF(FSERR'CODE) := ERRCODE;                                <<01869>>15430000
LOGBUFF(ULERR'CODE) := ULERRCODE;                              <<01869>>15435000
                                                               <<01869>>15440000
LOGBUFF(MSG) := STOP;                                          <<01869>>15445000
LOGBUFF(SWITCH') := FALSE;                                     <<01869>>15450000
LOGBUFF(LOGTYPE) := Q'OLDTYPE;                                 <<01869>>15455000
ABNORMAL'EXIT := TRUE;                                         <<01869>>15460000
SWITCH'FLAG := FALSE;                                          <<01869>>15465000
                                                               <<01869>>15470000
IF LOGBUFF(HEAD'CHANGE'PIN) <> 0 THEN                          <<01869>>15475000
   BEGIN                                                       <<01869>>15480000
   AWAKE(LOGBUFF(HEAD'CHANGE'PIN),%20,0);                      <<01869>>15485000
$IF X1=ON                                                      <<01874>>15486000
      WHAT'S'UP ( BC'AWAKE );                                 <<1SWAT>> 15488000
$IF                                                            <<01874>>15489000
   LOGBUFF(HEAD'CHANGE'PIN) := 0;                              <<01869>>15490000
   END;                                                        <<01869>>15495000
                                                               <<01869>>15500000
RELEASE (LOGBUFF(RESOURCE2),NULL,1);                           <<01875>>15501000
$IF X1=ON                                                               15501200
WHAT'S'UP ( BC'RELEASE,2 );                                             15501300
$IF                                                                     15501400
RESFLAG2 := FALSE;                                             <<01875>>15502000
RELSIR(LOGSIR,A);                                              <<01869>>15505000
GO WAIT1;                                                      <<01869>>15510000
                                                               <<01869>>15515000
$PAGE "Logging Process -- Wait1"                               <<01869>>15520000
WAIT1:                                                                  15525000
                                                                        15530000
<< Want to release any resources, wake up any sleeping users,>>         15535000
<< and then wait for another user to tell us to do something.>>         15540000
<< DB at LOGBUFF.                                            >>         15545000
                                                                        15550000
IF NOT RESFLAG2 THEN                                           <<01875>>15551000
   BEGIN                                                       <<01875>>15551100
   OBTAIN(LOGBUFF(RESOURCE2),NULL);                            <<01875>>15551200
$IF X1=ON                                                               15551220
   WHAT'S'UP ( BC'OBTAIN,2 );                                           15551230
$IF                                                                     15551240
   RESFLAG2 := TRUE;                                           <<01875>>15551300
                                                               <<01875>>15551400
   END;                                                        <<01875>>15551500
LOGBUFF(STATE) := INACT;                                                15555000
WAKEUP';                                                                15560000
                                                                        15565000
IF RESFLAG2 THEN                                               <<01875>>15570000
   BEGIN                                                                15575000
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>15580000
$IF X1=ON                                                      <<01874>>15585000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>15595000
$IF                                                            <<01874>>15600000
   RESFLAG2 := FALSE;                                          <<01875>>15605000
   END;                                                                 15610000
                                                                        15615000
IF RESFLAG1 THEN                                               <<01875>>15615100
   BEGIN                                                       <<01875>>15615200
   RELEASE(LOGBUFF(RESOURCE1),NULL,1);                         <<01875>>15615300
$IF X1=ON                                                               15615320
   WHAT'S'UP ( BC'RELEASE,1 );                                 <<01874>>15615330
$IF                                                                     15615340
   RESFLAG1 := FALSE;                                          <<01875>>15615400
   END;                                                        <<01875>>15615500
IF LOGBUFF(MSG) = STOP AND LOGBUFF(NUMUSER) = 0                         15620000
   AND NOT USER'REQUESTED'CHANGE                               <<01869>>15625000
   AND NOT LOGBUFF(SWITCH')                                    <<01877>>15630000
   AND NOT LOGBUFF(NOT'SAFE'TO'STOP) THEN GO STOP1;            <<01877>>15631000
                                                                        15635000
IF LOGBUFF(SWITCH') THEN GO REQUESTED'CHANGELOG;               <<01869>>15640000
                                                                        15645000
$IF X1=ON                                                      <<01874>>15646000
      WHAT'S'UP ( BC'WAIT );                                   <<01874>>15648000
$IF                                                            <<01874>>15649000
WAIT(%20,0);                                                   <<01869>>15650000
                                                               <<01869>>15655000
IF LOGBUFF(SWITCH') THEN GO REQUESTED'CHANGELOG;               <<01869>>15660000
USER'REQUESTED'CHANGE := FALSE;                                <<01869>>15665000
                                                                        15670000
$EDIT VOID=15680000                                            <<01875>>15675000
OBTAIN(LOGBUFF(RESOURCE2),NULL);                               <<01875>>15685000
$IF X1=ON                                                      <<01874>>15686000
      WHAT'S'UP ( BC'OBTAIN,2 );                               <<01874>>15688000
$IF                                                            <<01874>>15689000
RESFLAG2 := TRUE;                                              <<01875>>15690000
$EDIT                                                          <<01875>>15695000
                                                                        15700000
IF LOGBUFF(MSG) = STOP THEN                                             15705000
   BEGIN                                                                15710000
   IF LOGBUFF(NUMUSER) = 0 AND NOT LOGBUFF(SWITCH')  THEN      <<01877>>15715000
      IF LOGBUFF(NOT'SAFE'TO'STOP) THEN                        <<01877>>15716000
         GO WAIT1                                              <<01877>>15717000
      ELSE                                                     <<01877>>15718000
         GO STOP1;                                             <<01877>>15720000
                                                                        15725000
   << Tell operator we will stop soon. >>                               15730000
                                                                        15735000
   IF NOT NOTIFIED THEN                                                 15740000
      BEGIN                                                             15745000
      EXCHANGEDB(0);                                                    15750000
      GENMSG(SETNO,LOGINUSE,0,@PROCNAME,,,,,0);                         15755000
      EXCHANGEDB(BUFDST);                                               15760000
      NOTIFIED := TRUE;                                                 15765000
      END;                                                              15770000
   END;                                                                 15775000
                                                                        15780000
                                                                        15785000
GO GETIT;                                                               15790000
$PAGE "Logging Process -- Stop1"                               <<01869>>15795000
STOP1:                                                                  15800000
                                                               <<01869>>15805000
<< Time to stop the user logging process. DB at LOGBUFF.     >>         15810000
                                                                        15815000
IF NOT RESFLAG1 THEN                                           <<01875>>15820000
   BEGIN                                                       <<01869>>15825000
   OBTAIN(LOGBUFF(RESOURCE1),NULL);                            <<01875>>15830000
   RESFLAG1 := TRUE;                                           <<01875>>15835000
$IF X1=ON                                                      <<01874>>15836000
      WHAT'S'UP ( BC'OBTAIN,1 );                               <<01874>>15838000
$IF                                                            <<01874>>15839000
   END;                                                        <<01869>>15840000
                                                               <<01869>>15845000
IF NOT RESFLAG2 THEN                                           <<01875>>15845100
   BEGIN                                                       <<01875>>15845200
   OBTAIN(LOGBUFF(RESOURCE2),NULL);                            <<01875>>15845300
$IF X1=ON                                                               15845320
   WHAT'S'UP ( BC'OBTAIN,2 );                                           15845330
$IF                                                                     15845340
   RESFLAG2 := TRUE;                                           <<01875>>15845400
   END;                                                        <<01875>>15845500
MSGNO:=LOGPROCSTOP;                                                     15850000
                                                               <<01869>>15855000
<< If there was an error during a changelog, better not do   >><<01869>>15860000
<< anything - don't know what was updated and what was not.  >><<01869>>15865000
                                                               <<01869>>15870000
IF ABNORMAL'EXIT AND LOGBUFF(LOGERR) THEN                      <<01869>>15875000
   BEGIN                                                       <<01869>>15880000
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>15885000
$IF X1=ON                                                               15885200
   WHAT'S'UP ( BC'RELEASE,2 );                                          15885300
$IF                                                                     15885400
   RELEASE(LOGBUFF(RESOURCE1),NULL,1);                         <<01875>>15885500
$IF X1=ON                                                      <<01874>>15886000
      WHAT'S'UP ( BC'RELEASE,1 );                              <<01874>>15888000
$IF                                                            <<01874>>15889000
   EXCHANGEDB (0);                                             <<01869>>15890000
   RELENTRY (TABINDEX',0);                                     <<01869>>15895000
   GO OUT;                                                     <<01869>>15900000
   END;                                                        <<01869>>15905000
                                                               <<01869>>15910000
                                                                        15915000
IF LOGBUFF(LOGTYPE) <> DISC  THEN                              <<01869>>15920000
   BEGIN    << Stop the serial log file >>                     <<01869>>15925000
   <<FORMAT THE LAST BLOCK>>                                            15930000
                                                               <<01869>>15935000
   IF NOT FORMATTED'TRAILER THEN                               <<01869>>15940000
      BEGIN                                                    <<01869>>15945000
      FORMAT'TRAILER;                                          <<01869>>15950000
      FORMATTED'TRAILER := TRUE;                               <<01869>>15955000
      END;                                                     <<01869>>15960000
                                                               <<01869>>15965000
   FLUSH(NULL,FALSE);      << Tell it we are the log process >><<01869>>15970000
   CHECKMSG;       << Make sure all okay >>                    <<01869>>15975000
                                                               <<01869>>15980000
   COUNT:=INTEGER(DLOGBUFF(FSIZE)-DLOGBUFF(FSPACE'))*RECSIZE;  <<01869>>15985000
                                                                        15990000
   EXCHANGEDB(0);    << Back to stack >>                                15995000
                                                                        16000000
   DO                                                          <<01869>>16005000
      BEGIN                                                    <<01869>>16010000
     << May need more than one read/write to empty the disc>>  <<01869>>16015000
     << buffer file.                                       >>  <<01869>>16020000
                                                               <<01869>>16025000
      IF COUNT > BLKSIZE  THEN                                 <<01869>>16030000
         BEGIN                                                 <<01869>>16035000
            TEMPCNT := COUNT - BLKSIZE;                        <<01869>>16040000
            COUNT := BLKSIZE;                                  <<01869>>16045000
         END                                                   <<01869>>16050000
      ELSE  TEMPCNT := 0;                                      <<01869>>16055000
                                                               <<01869>>16060000
      IF NOT EMPTY'DISC'BUFFER(COUNT)                                   16065000
         THEN GO CLOSE'SERIAL'FILE;                                     16070000
                                                                        16075000
      COUNT := TEMPCNT;     << # words left in disc buffer >>  <<01869>>16080000
      OUTBUFREC := OUTBUFREC + DOUBLE(BLKFACTOR);              <<01869>>16085000
      IF OUTBUFREC >= DLOGBUFF(FSIZE)  THEN OUTBUFREC := 0D;   <<01869>>16090000
                                                               <<01869>>16095000
      END                                                      <<01869>>16100000
   UNTIL  COUNT <= 0;                                          <<01869>>16105000
                                                               <<01869>>16110000
                                                               <<01869>>16115000
$PAGE "Logging Process -- Change'Serial'Logfile"               <<01869>>16120000
CLOSE'SERIAL'FILE:                                             <<01869>>16125000
                                                                        16130000
<< Close files for tape logging - DB is at stack >>            <<01869>>16135000
                                                                        16140000
FCLOSE(BUFFILENO,4,0);    << Delete >>                                  16145000
FCLOSE(FILENO,0,0);                                                     16150000
IF <> THEN                                                     <<01869>>16155000
   BEGIN                                                       <<01869>>16160000
   FCHECK(FILENO,ERRCODE);                                     <<01869>>16165000
   GENMSG(FSSETNO,ERRCODE,,,,,,,0);                            <<01869>>16170000
   GENMSG(SETNO,FCLOSEERROR,0,@PROCNAME);                      <<01869>>16175000
   END;                                                        <<01869>>16180000
   EXCHANGEDB(BUFDST);    << To LOGBUFF >>                              16185000
   RELEASE(LOGBUFF(RESOURCE2),NULL,1);                         <<01875>>16190000
$IF X1=ON                                                      <<01874>>16195000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>16205000
$IF                                                            <<01874>>16210000
   RELEASE(LOGBUFF(RESOURCE1),NULL,1);                         <<01875>>16215000
$IF X1=ON                                                               16215100
     WHAT'S'UP ( BC'RELEASE,1 );                                        16215130
$IF                                                            <<*1918>>16215140
   RESFLAG2 := FALSE;                                          <<01875>>16215200
   RESFLAG1 := FALSE;                                          <<01875>>16215300
   EXCHANGEDB(0);     << Back to stack >>                               16220000
   RELENTRY(TABINDEX',0);                                      <<01869>>16225000
   RELDATASEG(BUFDST);                                         <<01869>>16230000
$IF X1=ON                                                      <<01874>>16231000
      WHAT'S'UP ( BC'RELDATASEG );                             <<01874>>16233000
$IF                                                            <<01874>>16234000
   GOT'LOGBUFF := FALSE;                                       <<01869>>16235000
   GO OUT;                                                     <<01869>>16240000
   END                                                                  16245000
ELSE                                                                    16250000
BEGIN                                                                   16255000
                                                               <<01869>>16260000
   << Stop the disc logging process. >>                        <<01869>>16265000
                                                               <<01869>>16270000
   IF LOGBUFF(LOGTYPE) = DISC  THEN                            <<01869>>16275000
   BEGIN                                                                16280000
      IF ABNORMAL'EXIT AND (EXTNUM<=NUMEXT)                    <<01869>>16285000
         THEN GO CLOSE'DISC'FILE;                                       16290000
                                                               <<01869>>16295000
      << If we're on the last extent, then we can free up the>><<01869>>16300000
      << file space we've been saving.                       >><<01869>>16305000
                                                               <<01869>>16310000
      IF NOT FREE'LAST'EXTENT THEN                             <<01869>>16315000
      BEGIN                                                    <<01869>>16320000
         IF LOGBUFF(EXTENT) = LOGBUFF(LASTEXT')  AND           <<01869>>16325000
            DLOGBUFF(FSPACE') < DOUBLE(BLKFACTOR)  THEN        <<01869>>16330000
         BEGIN                                                 <<01869>>16335000
            << If this is the last block of the last extent, >><<01869>>16340000
            << then it's time to make the last record        >><<01869>>16345000
            << available.                                    >><<01869>>16350000
                                                               <<01869>>16355000
            DLOGBUFF(FSIZE) := DLOGBUFF(FSIZE) + 1D;           <<01869>>16360000
            DLOGBUFF(FSPACE') := DLOGBUFF(FSPACE') + 1D;       <<01869>>16365000
            LOGBUFF(BSPACE) := LOGBUFF(BSPACE) + 1;            <<01869>>16370000
                                                               <<01869>>16375000
            FREE'LAST'EXTENT := TRUE;                          <<01869>>16380000
         END;                                                  <<01869>>16385000
      END;                                                     <<01869>>16390000
                                                               <<01869>>16395000
      << Now we can format the trailer record. >>              <<01869>>16400000
                                                               <<01869>>16405000
      IF NOT FORMATTED'TRAILER THEN                            <<01869>>16410000
      BEGIN                                                    <<01869>>16415000
         FORMAT'TRAILER;                                       <<01869>>16420000
         FORMATTED'TRAILER := TRUE;                            <<01869>>16425000
      END;                                                     <<01869>>16430000
                                                               <<01869>>16435000
      << Now flush the buffer (with the trailer record). >>    <<01869>>16440000
                                                               <<01869>>16445000
      FLUSH(NULL,FALSE);   << Tell it we are the log process >><<01869>>16450000
      CHECKMSG;                                                <<01869>>16455000
                                                               <<01869>>16460000
      FPOINT(FILENO,(DLOGBUFF(TRECS)-                          <<01869>>16465000
        DLOGBUFF(RECS'IN'PREV))/DOUBLE(BLKFACTOR));            <<01869>>16470000
      IF < THEN                                                <<01869>>16475000
      BEGIN                                                    <<01869>>16480000
         EXCHANGEDB(0);       << Back to stack >>                       16485000
         FCHECK(FILENO,ERRCODE);                               <<01869>>16490000
         GENMSG(FSSETNO,ERRCODE,,,,,,,0);                      <<01869>>16495000
         GENMSG(SETNO,FWRITEERROR,0,@PROCNAME,,,,,0);          <<01869>>16500000
         EXCHANGEDB(BUFDST);       << Back to LOGBUFF >>                16505000
      END;                                                     <<01869>>16510000
                                                               <<01869>>16515000
$PAGE "Logging Process -- Close'Disc'Logfile"                  <<01869>>16520000
CLOSE'DISC'FILE:                                               <<01869>>16525000
            << DB at LOGBUFF >>                                         16530000
                                                                        16535000
   IF RESFLAG2 THEN                                            <<01875>>16540000
      BEGIN                                                             16545000
      RELEASE(LOGBUFF(RESOURCE2),NULL,1);                      <<01875>>16550000
$IF X1=ON                                                      <<01874>>16555000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>16565000
$IF                                                            <<01874>>16570000
      RESFLAG2 := FALSE;                                       <<01875>>16575000
      END;                                                              16580000
                                                                        16585000
   IF RESFLAG1 THEN                                            <<01875>>16586000
      BEGIN                                                    <<01875>>16586200
      RELEASE(LOGBUFF(RESOURCE1),NULL,1);                      <<01875>>16586300
$IF X1=ON                                                               16586320
      WHAT'S'UP ( BC'RELEASE,1 );                              <<01874>>16586330
$IF                                                                     16586340
      RESFLAG1 := FALSE;                                       <<01875>>16586400
      END;                                                     <<01875>>16586500
                                                                        16590000
      EXCHANGEDB(0);     << Back to stack >>                            16595000
         FCONTROL(FILENO,SET'EOF,DUMMY);  << Write EOF >>      <<01869>>16600000
         IF <> THEN                                            <<01869>>16605000
         BEGIN                                                 <<01869>>16610000
            FCHECK(FILENO,ERRCODE);                            <<01869>>16615000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>16620000
            GENMSG(SETNO,FWRITEERROR,0,@PROCNAME,,,,,0);       <<01869>>16625000
         END;                                                  <<01869>>16630000
                                                               <<01869>>16635000
      FCLOSE(FILENO,0,0);                                               16640000
      IF <> THEN                                               <<01869>>16645000
      BEGIN                                                    <<01869>>16650000
         FCHECK(FILENO,ERRCODE);                               <<01869>>16655000
         GENMSG(FSSETNO,ERRCODE,,,,,,,0);                      <<01869>>16660000
         GENMSG(SETNO,FWRITEERROR,0,@PROCNAME,,,,,0);          <<01869>>16665000
      END;                                                     <<01869>>16670000
                                                               <<01869>>16675000
      RELENTRY(TABINDEX',0);                                            16680000
      RELDATASEG(BUFDST);                                      <<01869>>16685000
$IF X1=ON                                                      <<01874>>16686000
      WHAT'S'UP ( BC'RELDATASEG );                             <<01874>>16688000
$IF                                                            <<01874>>16689000
      GOT'LOGBUFF := FALSE;                                    <<01869>>16690000
   END;     <<Disc logging - stop>>                            <<01869>>16695000
END;                                                                    16700000
                                                               <<01869>>16705000
GO OUT;                                                        <<01869>>16710000
$PAGE "Logging Process -- Init'Fail"                           <<01869>>16715000
INIT'FAIL:                                                     <<01869>>16720000
                                                               <<01869>>16725000
<< DB at LOGBUFF >>                                            <<01869>>16730000
RELEASE(LOGBUFF(RESOURCE2),NULL,1);                            <<01875>>16735000
$IF X1=ON                                                               16735200
WHAT'S'UP ( BC'RELEASE,2 );                                             16735300
$IF                                                                     16735400
RELEASE(LOGBUFF(RESOURCE1),NULL,1);                            <<01875>>16736000
$IF X1=ON                                                      <<01874>>16740000
      WHAT'S'UP ( BC'RELEASE,1 );                              <<01874>>16750000
$IF                                                            <<01874>>16755000
EXCHANGEDB(0);                                                 <<01869>>16760000
RELENTRY(TABINDEX',0);                                         <<01869>>16765000
IF RESTART' THEN                                               <<01869>>16770000
   MSGNO := CANTRESTART                                        <<01869>>16775000
ELSE                                                           <<01869>>16780000
   MSGNO := CANTSTART;                                         <<01869>>16785000
                                                               <<01869>>16790000
GO OUT;                                                        <<01869>>16795000
                                                               <<01869>>16800000
                                                               <<01869>>16805000
                                                               <<01869>>16810000
                                                                        16815000
                                                                        16820000
OUT:                                                                    16825000
                                                               <<01869>>16830000
EXCHANGEDB(0);    << Make sure at stack >>                              16835000
                                                               <<01869>>16840000
IF GOT'LOGBUFF THEN                                            <<01869>>16845000
   RELDATASEG(BUFDST);                                         <<01869>>16850000
$IF X1=ON                                                      <<01874>>16851000
      WHAT'S'UP ( BC'RELDATASEG );                             <<01874>>16853000
$IF                                                            <<01874>>16854000
                                                               <<01869>>16855000
$edit void=16880000                                            <<01870>>16856000
GENMSG(SETNO,MSGNO,%0,@PROCNAME,,,,,0); <<TELL OPERATOR FINI>>          16885000
END; <<ULOGPROC>>                                                       16890000
$PAGE "Power Fail Recovery"                                    <<01869>>16895000
LOGICAL PROCEDURE RECPFAIL(FILENO,RECNUM,TLDEV,FIRST'BLOCK);   <<01869>>16900000
   VALUE FILENO,RECNUM,TLDEV,FIRST'BLOCK;                      <<01869>>16905000
   INTEGER FILENO,TLDEV;                                       <<01869>>16910000
   LOGICAL FIRST'BLOCK;                                        <<01869>>16915000
   DOUBLE RECNUM;                                              <<01869>>16920000
   OPTION INTERNAL;                                            <<01869>>16925000
                                                               <<01869>>16930000
BEGIN                                                          <<01869>>16935000
                                                               <<01869>>16940000
<< Called from ULOGPROC when writting to the tape logging    >><<01869>>16945000
<< file and a powerfail error occurred. We want to rewind to >><<01869>>16950000
<< Load Point (LP) and then read each block until we find the>><<01869>>16955000
<< last good block before the power failed.  At that point   >><<01869>>16960000
<< we can try to re-write the block.                         >><<01869>>16965000
<<                                                           >><<01869>>16970000
<< Since the Logging file is a Labeled Tape and contains only>><<01869>>16975000
<< one file (the Log file) we must rewind the tape back to   >><<01869>>16980000
<< LP, then forward space over the label stuff to the        >><<01869>>16985000
<< Tape Mark (TM).                                           >><<01869>>16990000
<<                                                           >><<01869>>16995000
<< Format of a Labeled Tape:                                 >><<01869>>17000000
<<    [LP] [vol1] [hdr1] [hd2]  [TM] [...data......]         >><<01869>>17005000
<<                                                           >><<01869>>17010000
<<  DB is at the stack.                                      >><<01869>>17015000
<<                                                           >><<01869>>17020000
<< ENTRY:                                                    >><<01869>>17025000
<<   RECNUM  - Record number for block trying to write when  >><<01869>>17030000
<<             power fail occurred.                          >><<01869>>17035000
<<   TLDEV   - Ldev for the tape device.                     >><<01869>>17040000
<<   FIRST'BLOCK - TRUE if were writing the first block to   >><<01869>>17045000
<<                 tape when the power fail occurred.        >><<01869>>17050000
                                                               <<01869>>17055000
<< RETURNS:                                                  >><<01869>>17060000
<<    TRUE - Block successfully rewritten to log file.       >><<01869>>17065000
<<    FALSE- Some other error occurred. Log file may not     >><<01869>>17070000
<<           completely be recovered.                        >><<01869>>17075000
                                                               <<01869>>17080000
                                                               <<01869>>17085000
                                                               <<01869>>17090000
DOUBLE                                                         <<01869>>17095000
   STAT,           << Status return from ATTACHIO >>           <<01869>>17100000
   RECORD;         << Rec # before the one to write >>         <<01869>>17105000
                                                               <<01869>>17110000
INTEGER                                                        <<01869>>17115000
   STAT0 = STAT + 0,                                           <<01869>>17120000
   ERRCODE;        << Return from FCHECK >>                    <<01869>>17125000
                                                               <<01869>>17130000
LOGICAL ARRAY TAPEREC(0:RECSIZEM1) = Q;                        <<01869>>17135000
DOUBLE ARRAY DTAPEREC(*) = TAPEREC;                            <<01869>>17140000
                                                               <<01869>>17145000
EQUATE                                                         <<01869>>17150000
   SYSPFAIL = %63,   << Sys powerfail code - from ATTACHIO >>  <<01869>>17155000
   TAPEPFAIL= %213,  << Device powerfail   - from ATTACHIO >>  <<01869>>17160000
   CHANEL'TIMEOUT=%144,<< Channel timed out after the PF   >>  <<01869>>17165000
   SUCCESS  = 1,      << General status  -  from Attachio >>   <<01869>>17170000
   BLOCKEDIO= 1;                                               <<01869>>17175000
                                                               <<01869>>17180000
                                                               <<01869>>17185000
                                                               <<01869>>17190000
                                                               <<01869>>17195000
RECPFAIL := FALSE;                                             <<01869>>17200000
                                                               <<01869>>17205000
<< If this was the 2nd write (RECNUM=32D), then need to stop>> <<01869>>17210000
<< re-reading the file when we've found the 1st block.      >> <<01869>>17215000
                                                               <<01869>>17220000
IF NOT FIRST'BLOCK THEN                                        <<01869>>17225000
   RECORD := RECNUM - DOUBLE(BLKFACTOR);                       <<01869>>17230000
                                                               <<01869>>17235000
                                                               <<01869>>17240000
                                                               <<01869>>17245000
POWERFAIL:                                                     <<01869>>17250000
                                                               <<01869>>17255000
   << Make sure we'll still be posting device buffer on each>> <<01869>>17260000
   << write to tape.                                        >> <<01869>>17265000
                                                               <<01869>>17270000
   FSETMODE(FILENO,POST'TAPE'BUFFER);                          <<01869>>17275000
                                                               <<01869>>17280000
   << Tell the operator to reset the tape drive and place    >><<01869>>17285000
   << it back on-line.                                       >><<01869>>17290000
                                                               <<01869>>17295000
   GENMSG(SETNO,TPOWERFAIL,%10000,TLDEV,,,,,0);                <<01869>>17300000
                                                               <<01869>>17305000
   << Rewind to LP. (FCONTROL won't do this o labeled tape). >><<01869>>17310000
                                                               <<01869>>17315000
RETRY:                                                         <<01869>>17320000
                                                               <<01869>>17325000
    STAT:=ATTACHIO(TLDEV,0,0,0,REWIND,0,0,0,FLAGS);            <<01869>>17330000
    IF STAT0.(13:3) <> SUCCESS THEN                            <<01869>>17335000
    BEGIN                                                      <<01869>>17340000
       IF STAT0.(8:8) = CHANEL'TIMEOUT THEN GO RETRY;          <<01869>>17345000
       IF STAT0.(8:8) = SYSPFAIL OR STAT0.(8:8) = TAPEPFAIL    <<01869>>17350000
           THEN GO POWERFAIL                                   <<01869>>17355000
       ELSE                                                    <<01869>>17360000
       BEGIN                                                   <<01869>>17365000
          ERRCODE := IOSTAT(STAT0);                            <<01869>>17370000
          GENMSG(FSSETNO,ERRCODE,,,,,,,0);                     <<01869>>17375000
          RETURN;                                              <<01869>>17380000
       END;                                                    <<01869>>17385000
                                                               <<01869>>17390000
    END;                                                       <<01869>>17395000
                                                               <<01869>>17400000
    << Skip over Label stuff to TM >>                          <<01869>>17405000
                                                               <<01869>>17410000
    STAT:=ATTACHIO(TLDEV,0,0,0,FORWARDSPACE,0,0,0,FLAGS);      <<01869>>17415000
    IF STAT0.(13:3) <> SUCCESS THEN                            <<01869>>17420000
    BEGIN                                                      <<01869>>17425000
       IF STAT0.(8:8) = CHANEL'TIMEOUT THEN GO RETRY;          <<01869>>17430000
       IF STAT0.(8:8) = SYSPFAIL OR STAT0.(8:8) = TAPEPFAIL    <<01869>>17435000
           THEN GO POWERFAIL                                   <<01869>>17440000
       ELSE                                                    <<01869>>17445000
       BEGIN                                                   <<01869>>17450000
          ERRCODE := IOSTAT(STAT0);                            <<01869>>17455000
          GENMSG(FSSETNO,ERRCODE,,,,,,,0);                     <<01869>>17460000
          RETURN;                                              <<01869>>17465000
       END;                                                    <<01869>>17470000
                                                               <<01869>>17475000
    END;                                                       <<01869>>17480000
                                                               <<01869>>17485000
                                                               <<01869>>17490000
    << If we power failed on the first write to tape then    >><<01869>>17495000
    << we need to skip over the re-reading of the file.      >><<01869>>17500000
                                                               <<01869>>17505000
    << May be a problem if not the first file in the set. >>   <<01869>>17510000
                                                               <<01869>>17515000
    IF NOT FIRST'BLOCK THEN                                    <<01869>>17520000
    BEGIN                                                      <<01869>>17525000
                                                               <<01869>>17530000
    << Now we're positioned to start reading the data from  >> <<01869>>17535000
    << the file to find the last good block.  Will read the >> <<01869>>17540000
    << first record of each block to find the record number >> <<01869>>17545000
    << of that block.  (The 1st double word of the record   >> <<01869>>17550000
    << contains the record number).                         >> <<01869>>17555000
    << We must use ATTACHIO to perform the read since the   >> <<01869>>17560000
    << File System will not allow an FREAD after an FWRITE  >> <<01869>>17565000
    << (FS does not know about the rewind/forward space).   >> <<01869>>17570000
                                                               <<01869>>17575000
       DO                                                      <<01869>>17580000
       BEGIN                                                   <<01869>>17585000
          STAT:=ATTACHIO(TLDEV,0,0,@TAPEREC,READ,RECSIZE,0,0,  <<01869>>17590000
                         FLAGS);                               <<01869>>17595000
          IF STAT0.(13:3) <> SUCCESS THEN                      <<01869>>17600000
          BEGIN                                                <<01869>>17605000
             IF STAT0.(8:8) = CHANEL'TIMEOUT THEN GO RETRY;    <<01869>>17610000
             IF STAT0.(8:8) = SYSPFAIL OR                      <<01869>>17615000
                STAT0.(8:8) = TAPEPFAIL  THEN GO POWERFAIL     <<01869>>17620000
             ELSE                                              <<01869>>17625000
             BEGIN                                             <<01869>>17630000
                ERRCODE := IOSTAT(STAT0);                      <<01869>>17635000
                GENMSG(FSSETNO,ERRCODE,,,,,,,0);               <<01869>>17640000
                RETURN;                                        <<01869>>17645000
             END;                                              <<01869>>17650000
          END;                                                 <<01869>>17655000
       END                                                     <<01869>>17660000
       UNTIL DTAPEREC = RECORD;                                <<01869>>17665000
    END;                                                       <<01869>>17670000
                                                               <<01869>>17675000
    << At this point we've found the last complete block    >> <<01869>>17680000
    << before the Power fail. Try to write the block again. >> <<01869>>17685000
                                                               <<01869>>17690000
    FWRITE(FILENO,BUFFAREA,BLKSIZE,0);                         <<01869>>17695000
    IF <> THEN                                                 <<01869>>17700000
    BEGIN                                                      <<01869>>17705000
       FCHECK(FILENO,ERRCODE);                                 <<01869>>17710000
       IF ERRCODE = SYSPOWERFAIL  OR  ERRCODE = TAPEPOWERFAIL  <<01869>>17715000
           THEN GO POWERFAIL                                   <<01869>>17720000
       ELSE                                                    <<01869>>17725000
       BEGIN                                                   <<01869>>17730000
          GENMSG(FSSETNO,ERRCODE,,,,,,,0);                     <<01869>>17735000
          RETURN;                                              <<01869>>17740000
       END;                                                    <<01869>>17745000
                                                               <<01869>>17750000
    END;                                                       <<01869>>17755000
                                                               <<01869>>17760000
    << If we finally make it here, recovery is successful.  >> <<01869>>17765000
                                                               <<01869>>17770000
    RECPFAIL := TRUE;                                          <<01869>>17775000
                                                               <<01869>>17780000
END;                                                           <<01869>>17785000
$PAGE "Warmstart Recovery declarations"                                 17790000
PROCEDURE RECLOG;                                                       17795000
OPTION PRIVILEGED,UNCALLABLE;                                           17800000
BEGIN                                                                   17805000
                                                                        17810000
COMMENT                                                        <<01869>>17815000
                                                               <<01869>>17820000
Called during a Warmstart to recover any active User Loggging  <<01869>>17825000
files. Will search the LOGTAB for an entry, open the file      <<01869>>17830000
associated with this entry, re-read the file until the last    <<01869>>17835000
good record is found, then will write a log crash record to the<<01869>>17840000
file, print a message to the console telling how many records  <<01869>>17845000
were recovered, update the EOF marker in the file label to     <<01869>>17850000
the corrert setting, and close the file.                       <<01869>>17855000
This will be repeated until all active files are recovered.    <<01869>>17860000
                                                               <<01869>>17865000
It is important to realize that any information in the Buffer  <<01869>>17870000
area of the Logging Buffer will be lost if the system crashes. <<01869>>17875000
                                                               <<01910>>17875010
Warm Start Recovery for serial log files was changed entirely  <<01910>>17875020
in Jan 1986 (UMIT patch). According to the new algorithm,      <<01910>>17875030
RECLOG will search LOGTAB for an entry, open the disc buffer   <<01910>>17875040
file and User Logging destination file associated with this    <<01910>>17875050
entry. Read the disc buffer file to find a valid record with   <<01910>>17875060
the smallest record number. This record number minus one block <<01910>>17875070
is assumed to be the last record flushed to the destination    <<01910>>17875080
file.  Will re-read the destination file until the record that <<01910>>17875090
matches with the record found from disc buffer file. Then all  <<01910>>17875100
the data beyond this point from disc buffer file is flushed to <<01910>>17875110
to serial destination file, write a crash record to the file,  <<01910>>17875120
print a message to the console telling how many records were   <<01910>>17875130
recovered, update the EOF marker in the file label to the      <<01910>>17875140
correct setting and close the file. This will be repeated      <<01910>>17875150
until all active files are recovered.                          <<01910>>17875160
;                                                              <<01869>>17880000
                                                                        17885000
   <<RECOVERS USER LOGGING FILE DURING WARMSTART>>                      17890000
                                                                        17895000
EQUATE                                                         <<01869>>17900000
  FEOF      =  %12,        << ATTACHIO found EOF >>            <<01869>>17905000
  FORWRD    =  FORWARDSPACE;  << Forward space file >>         <<01869>>17910000
   DOUBLE                                                      <<01869>>17915000
      STAT;          << Status return from ATTACHIO >>         <<01869>>17920000
                                                               <<01869>>17925000
   INTEGER                                                     <<01869>>17930000
      I,                                                       <<01869>>17935000
      ERRCODE,                                                 <<01869>>17940000
      STAT0  =  STAT + 0;                                      <<01869>>17945000
                                                               <<01869>>17950000
   INTEGER                                                     <<01869>>17955000
     LOGGING'TYPE,                                             <<01869>>17960000
     SAVE'TABINDEX,                                            <<01869>>17965000
     TABINDEX;                                                 <<01869>>17970000
                                                               <<01869>>17975000
   LOGICAL                                                     <<01869>>17980000
      FIRST,                                                   <<01869>>17985000
      NAMES'MATCH,                                             <<01869>>17990000
      SWITCH'FLAG;                                             <<01869>>17995000
                                                               <<01869>>18000000
                                                                        18005000
<< CURRREC is the record number expected next >>               <<01869>>18010000
                                                               <<01869>>18015000
   DOUBLE CURRREC,LASTREC,RECNUM,EOF;                                   18020000
DOUBLE STOPPER;                                                <<01869>>18025000
   INTEGER BUFFILENO,LOGFILENO;                                         18030000
   LOGICAL VALID,PARM,EOFORERR;                                         18035000
DOUBLE NUMRECOVERED;                                           <<01869>>18040000
   LOGICAL B;                                                           18045000
   INTEGER NUMOPEN,NUMCLOSE,LEN,NEXT'TABINDEX;                 <<01869>>18050000
   BYTE POINTER BINREC;                                        <<01869>>18055000
   LOGICAL POINTER INREC,OUTREC;                                        18060000
   DOUBLE POINTER DINREC;                                      <<01869>>18065000
   INTEGER TAPEDEV;                                            <<01869>>18070000
   LOGICAL NOTIFIED;                                           <<01869>>18075000
   BYTE ARRAY RECOV'FNAME(0:36);                               <<01869>>18080000
   BYTE ARRAY SAVE'FNAME(0:36);                                <<01869>>18085000
   BYTE ARRAY LOST'FNAME(0:36);                                <<01869>>18090000
                                                               <<01869>>18095000
                                                               <<01869>>18100000
   BYTE ARRAY BUFNAME(0:16) = Q;                               <<01869>>18105000
   BYTE ARRAY DEV(0:8);                                        <<01869>>18110000
   BYTE ARRAY FORMS(0:8);                                      <<01869>>18115000
   BYTE ARRAY PROCNAME(0:8) = Q;                               <<01869>>18120000
   BYTE ARRAY OUTPUT1(0:12);                                   <<01869>>18125000
   BYTE ARRAY OUTPUT2(0:6);                                    <<01869>>18130000
   BYTE ARRAY OUTPUT3(0:6);                                    <<01869>>18135000
                                                               <<01869>>18140000
   ARRAY ENTRY'(0:TENTRYSIZE-1) = Q;                           <<01869>>18145000
   BYTE ARRAY BENTRY'(*) = ENTRY';                             <<01869>>18150000
$EDIT VOID=18160000                                            <<01910>>18155000
   DOUBLE LASTBUFREC;                                          <<01910>>18157100
   DOUBLE CURTAPEREC;                                          <<01910>>18157200
   DOUBLE RECNUM1;                                             <<01910>>18157400
   INTEGER FILE'LENGTH;                                        <<01910>>18162000
$PAGE "Warmstart Recovery Subroutines"                                  18165000
SUBROUTINE CHECKRECORD;                                        <<01869>>18170000
BEGIN                                                          <<01869>>18175000
                                                               <<01869>>18180000
<< Checks each record for CHECKBLOCK. >>                       <<01869>>18185000
                                                               <<01869>>18190000
VALID := FALSE;                                                <<01869>>18195000
IF LOGGING'TYPE <> DISC THEN                                   <<01910>>18196000
   GO TO CHECKTAPE;                                            <<01910>>18197000
IF FIRST THEN                                                  <<01869>>18200000
   BEGIN                                                       <<01869>>18205000
   IF INREC(CODE).(8:8) <> HEADER AND                          <<01869>>18210000
      INREC(CODE).(8:8) <> RSTART AND                          <<01869>>18215000
      INREC(CODE).(8:8) <> FIRST'CODE THEN                     <<01869>>18220000
      RETURN;                                                  <<01869>>18225000
                                                               <<01869>>18230000
   IF INREC(CODE).(8:8) = FIRST'CODE THEN                      <<01869>>18235000
      CURRREC := DINREC(RNUM);                                 <<01869>>18240000
$EDIT VOID=18242000                                            <<01910>>18241000
   END;                                                        <<01869>>18245000
                                                               <<01869>>18250000
IF INREC(CODE).(8:8) <> FIRST'CODE THEN                        <<01869>>18255000
CHECKTAPE:                                                     <<01910>>18257000
   CURRREC := CURRREC + 1D;                                    <<01869>>18260000
                                                               <<01869>>18265000
IF DINREC(RNUM) <> CURRREC THEN RETURN;                        <<01869>>18270000
                                                               <<01869>>18275000
<< If we find a changelog record, we will consider it an error <<01869>>18280000
<< I.e. a changelog was in progress when the system crashed.   <<01869>>18285000
<< Maybe in the future will be able to finish the changelog    <<01869>>18290000
<< during the warmstart recovery.                              <<01869>>18295000
                                                               <<01869>>18300000
IF INREC(CODE).(8:8) = NEXT'CODE THEN RETURN;                  <<01869>>18305000
                                                                        18306000
$EDIT VOID=18311000                                            <<01910>>18307000
<< Now calculate the checksums >>                              <<01869>>18315000
                                                               <<01869>>18320000
TOS := -1;                                                     <<01869>>18325000
X := RECSIZEM1;                                                <<01869>>18330000
DO                                                             <<01869>>18335000
   BEGIN                                                       <<01869>>18340000
   IF X <> CKSUM THEN                                          <<01869>>18345000
      TOS := TOS XOR INREC(X);                                 <<01869>>18350000
   END                                                         <<01869>>18355000
UNTIL (X := X-1) < 0;                                          <<01869>>18360000
                                                               <<01869>>18365000
IF TOS <> INREC(CKSUM) THEN RETURN;                            <<01869>>18370000
                                                               <<01869>>18375000
IF INREC(CODE).(8:8) = OPEN THEN NUMOPEN := NUMOPEN + 1;       <<01869>>18380000
IF INREC(CODE).(8:8) = CLOSE THEN NUMCLOSE := NUMCLOSE + 1;    <<01869>>18385000
                                                               <<01869>>18390000
NUMRECOVERED := NUMRECOVERED + 1D;                             <<01869>>18395000
VALID := TRUE;                                                 <<01869>>18400000
                                                               <<01869>>18405000
END;       << Subroutine CHECKRECORD >>                        <<01869>>18410000
                                                                        18415000
                                                                        18420000
                                                                        18425000
                                                                        18430000
SUBROUTINE CHECKBLOCK;                                                  18435000
BEGIN                                                                   18440000
                                                                        18445000
                                                                        18450000
<<CHECKS A BLOCK READ FROM THE LOGFILE OR BUFFER>>                      18455000
                                                                        18460000
                                                                        18465000
   VALID:=TRUE;                                                         18470000
   I:=0;                                                                18475000
   DO                                                                   18480000
   BEGIN                                                                18485000
      CHECKRECORD;                                                      18490000
      IF VALID THEN                                                     18495000
      BEGIN                                                             18500000
         @INREC:=@INREC+RECSIZE;                               <<01869>>18505000
         @DINREC:=@INREC;                                               18510000
         FIRST := FALSE;                                       <<01869>>18515000
      END;                                                              18520000
   END UNTIL NOT VALID OR (I:=I+1)>=BLKFACTOR;                          18525000
END;                                                                    18530000
                                                                        18535000
                                                                        18540000
                                                                        18545000
                                                                        18550000
                                                                        18555000
SUBROUTINE FORMATCRASH;                                                 18560000
BEGIN                                                                   18565000
                                                                        18570000
<<FORMATS A CRASH RECORD>>                                              18575000
                                                                        18580000
<< Output one crach record, then fill remainder of the     >>  <<01869>>18585000
<< block with null records.                                >>  <<01869>>18590000
<< I = last valid record # found by CHECKBLOCK >>              <<01869>>18595000
                                                                        18600000
   @INREC:=@BUFFAREA+I*RECSIZE;                                <<01869>>18605000
   @DINREC:=@INREC;                                                     18610000
   INREC:="  ";                                                <<01869>>18615000
   MOVE INREC(1):=INREC, ((BLKFACTOR-I)*RECSIZE-1);            <<01869>>18620000
   INREC(CODE):=CRASH;                                                  18625000
   DO                                                                   18630000
   BEGIN                                                                18635000
   INREC(DATE) := CALENDAR;                                    <<01869>>18640000
   DINREC(TIME):=CLOCK;                                                 18645000
   DINREC(RNUM):=CURRREC:=CURRREC+1D;                                   18650000
      X:=RECSIZEM1;                                            <<01869>>18655000
      TOS:=-1;                                                          18660000
      DO                                                                18665000
      BEGIN                                                             18670000
         IF X<>CKSUM THEN                                               18675000
         TOS:=TOS XOR INREC(X);                                         18680000
      END UNTIL (X:=X-1) < 0;                                           18685000
      INREC(CKSUM):=TOS;                                                18690000
      @INREC:=@INREC+RECSIZE;                                  <<01869>>18695000
      @DINREC:=@INREC;                                                  18700000
                                                                        18705000
   END UNTIL(I:=I+1) >= BLKFACTOR;                                      18710000
END;                                                                    18715000
$PAGE "Warmstart Recovery -- Get'File'Names"                   <<01869>>18720000
SUBROUTINE GET'FILE'NAMES;                                     <<01869>>18725000
BEGIN                                                          <<01869>>18730000
                                                               <<01869>>18735000
<< Called to get the file name to recover - from the LIDTAB. >><<01869>>18740000
<< Will also determine if a changelog was in progress when   >><<01869>>18745000
<< the system went down and print an appropriate message on  >><<01869>>18750000
<< the console explaining that the changelog was lost.       >><<01869>>18755000
                                                               <<01869>>18760000
FENTRY(PROCNAME,,RECOV'FNAME,,,LOGGING'TYPE);                  <<01869>>18765000
LOGGING'TYPE := LOGGING'TYPE.TYP'CURRENT;                      <<01869>>18770000
RECOV'FNAME(36) := 0;                                          <<01869>>18775000
                                                               <<01869>>18780000
SAVE'TABINDEX := TABINDEX;                                     <<01869>>18785000
TABINDEX := 0;                                                 <<01869>>18790000
   FILE'LENGTH := 36;                                          <<01910>>18793000
                                                               <<01869>>18795000
<< Now get info from the LOGTAB. This will tell us if there  >><<01869>>18800000
<< was a changelog in progress and perhaps what the new log  >><<01869>>18805000
<< file name would have been.                                >><<01869>>18810000
                                                               <<01869>>18815000
MOVE'FROM'DSEG(@ENTRY',LOGDST,SAVE'TABINDEX,TENTRYSIZE);       <<01869>>18820000
EXTRACT'FILENAME(LOST'FNAME,BENTRY'(LFNAME),BENTRY'(LFLOCKW),  <<01869>>18825000
        BENTRY'(LFGROUP),BENTRY'(LFACCT));                     <<01869>>18830000
LOST'FNAME(36) := 0;                                           <<01869>>18835000
                                                               <<01869>>18840000
   IF LOGGING'TYPE <> DISC THEN                                <<01910>>18840100
     BEGIN                                                     <<01910>>18840200
       MOVE RECOV'FNAME := RECOV'FNAME WHILE AN,1;             <<01910>>18840300
       FILE'LENGTH := TOS - @RECOV'FNAME;                      <<01910>>18840400
       RECOV'FNAME(8) := 0;                                    <<01910>>18840500
     END;                                                      <<01910>>18840600
<< If the filenames are not the same or the SWITCH' flag is  >><<01869>>18845000
<< set, then there was a changelog in progress.              >><<01869>>18850000
                                                               <<01869>>18855000
   IF RECOV'FNAME <> LOST'FNAME,(FILE'LENGTH) THEN             <<01910>>18860000
   BEGIN                                                       <<01869>>18865000
   SWITCH'FLAG := TRUE;                                        <<01869>>18870000
   NAMES'MATCH := FALSE;                                       <<01869>>18875000
   END                                                         <<01869>>18880000
ELSE                                                           <<01869>>18885000
   BEGIN                                                       <<01869>>18890000
   NAMES'MATCH := TRUE;                                        <<01869>>18895000
   IF ENTRY'(LGSWITCH) THEN                                    <<01869>>18900000
      SWITCH'FLAG := TRUE                                      <<01869>>18905000
   ELSE                                                        <<01869>>18910000
      SWITCH'FLAG := FALSE;                                    <<01869>>18915000
   END;                                                        <<01869>>18920000
                                                               <<01869>>18925000
$EDIT VOID = 18950000                                          <<01910>>18930000
                                                               <<01869>>18955000
IF ENTRY'(LGSWITCH) AND ENTRY'(LGNEWTYPE) <> DISC OR           <<01869>>18960000
   NOT ENTRY'(LGSWITCH) AND ENTRY'(LGTYPE) <> DISC THEN        <<01869>>18965000
   BEGIN                                                       <<01869>>18970000
   MOVE LOST'FNAME := LOST'FNAME WHILE AN, 1;                  <<01869>>18975000
   MOVE * := 0;                                                <<01869>>18980000
   END;                                                        <<01869>>18985000
                                                               <<01869>>18990000
   MOVE SAVE'FNAME := RECOV'FNAME, (36);                       <<01869>>18995000
   DEL'LOCKWORD(SAVE'FNAME);                                   <<01869>>19000000
   SAVE'FNAME (26) := 0;                                       <<01869>>19005000
                                                               <<01869>>19010000
<< If there was a changelog in progress, now want to print   >><<01869>>19015000
<< message on the console explaning that it was lost.        >><<01869>>19020000
                                                               <<01869>>19025000
IF SWITCH'FLAG THEN                                            <<01869>>19030000
   BEGIN                                                       <<01869>>19035000
   IF ENTRY'(LGSWITCH) AND ENTRY'(LGNEWTYPE) = DISC OR         <<01869>>19040000
      NOT ENTRY'(LGSWITCH) AND ENTRY'(LGTYPE) = DISC THEN      <<01869>>19045000
      BEGIN                                                    <<01869>>19050000
      << Will purge the "new" log file that is lost. If the  >><<01869>>19055000
      << new log file would have been serial, then there is  >><<01869>>19060000
      << nothing to purge.                                   >><<01869>>19065000
                                                               <<01869>>19070000
      IF NOT NAMES'MATCH THEN                                  <<01869>>19075000
         BEGIN                                                 <<01869>>19080000
         MOVE DEV := "DISC ";                                  <<01869>>19085000
         LOGFILENO := FOPEN(LOST'FNAME,%2005,%524,DEV);        <<01869>>19090000
         FCLOSE(LOGFILENO,4,0);     << Delete >>               <<01869>>19095000
         END;                                                  <<01869>>19100000
      END;                                                     <<01869>>19105000
                                                               <<01869>>19110000
   DEL'LOCKWORD(LOST'FNAME);                                   <<01869>>19115000
   LOST'FNAME (26) := 0;                                       <<01869>>19120000
   IF NOT NAMES'MATCH THEN                                     <<01869>>19125000
      GENMSG(SETNO,CHANGELOG'LOST1,0,@SAVE'FNAME,@LOST'FNAME,  <<01869>>19130000
             @PROCNAME,,,0)                                    <<01869>>19135000
   ELSE                                                        <<01869>>19140000
      GENMSG(SETNO,CHANGELOG'LOST2,0,@PROCNAME,,,,,0);         <<01869>>19145000
   END;                                                        <<01869>>19150000
                                                               <<01869>>19155000
TABINDEX := SAVE'TABINDEX;                                     <<01869>>19160000
                                                               <<01869>>19165000
END;       << Subroutine GET'FILE'NAMES >>                     <<01869>>19170000
$PAGE "Warmstart Recovery"                                     <<01869>>19175000
   << Turn traps off >>                                        <<01869>>19180000
                                                               <<01869>>19185000
   ASSEMBLE(PSHR %10);                                                  19190000
   TOS.(2:1):=0;                                                        19195000
   ASSEMBLE(SETR %10);                                                  19200000
                                                               <<01869>>19205000
   MOVE OUTPUT1:="  ";                                                  19210000
   MOVE OUTPUT1(1):=OUTPUT1,(18);                                       19215000
   NOTIFIED := FALSE;                                          <<01869>>19220000
   EXCHANGEDB(LOGDST);    << To LOGTAB >>                               19225000
   B:=GETSIR(LOGSIR);                                                   19230000
   IF LOGTAB(NUMENTRIES) = 0 THEN                                       19235000
   BEGIN                                                                19240000
      <<LOGGING NOT IN USE, GO EXIT>>                                   19245000
      RELSIR(LOGSIR,B);                                                 19250000
      GO OUT;                                                           19255000
   END;                                                                 19260000
                                                                        19265000
   IF (TABINDEX:=LOGTAB(INUSE)) = NULL  THEN                   <<01869>>19270000
   BEGIN                                                                19275000
      RELSIR(LOGSIR,B);                                                 19280000
      GO OUT;                                                           19285000
   END;                                                                 19290000
   DO LOGTAB(STATUS):=RECOVERING                               <<01869>>19295000
    UNTIL (TABINDEX:=LOGTAB(NEXT)) = NULL;                     <<01869>>19300000
                                                               <<01869>>19305000
   TABINDEX:=LOGTAB(INUSE);                                             19310000
   RELSIR(LOGSIR,B);                                                    19315000
                                                               <<01869>>19320000
   DO                                                                   19325000
      BEGIN           <<Recover loop>>                         <<01869>>19330000
      I := 0;                                                  <<01869>>19335000
      DO PROCNAME(I) := BLOGTAB(LGNAME+I) UNTIL (I:=I+1) >= 8; <<01869>>19340000
      PROCNAME(8) := 0;                                        <<01869>>19345000
                                                               <<01869>>19350000
      I := 0;                                                  <<01869>>19355000
      DO BUFNAME(I) := BLOGTAB(BNAME+I) UNTIL (I:=I+1) >= 8;   <<01869>>19360000
                                                               <<01869>>19365000
      SWITCH'FLAG := FALSE;                                    <<01869>>19370000
      NEXT'TABINDEX := LOGTAB(NEXT);                           <<01869>>19375000
      EXCHANGEDB(0);                                           <<01869>>19380000
                                                               <<01869>>19385000
      GET'FILE'NAMES;                                          <<01869>>19390000
      GENMSG(SETNO,LOGRECOV,0,@SAVE'FNAME,@PROCNAME,,,,0);     <<01869>>19395000
                                                               <<01869>>19400000
      I := 0;                                                  <<01869>>19405000
      FIRST := TRUE;                                           <<01869>>19410000
      NOTIFIED := FALSE;                                       <<01869>>19415000
      NUMOPEN := 0;                                            <<01869>>19420000
      NUMCLOSE := 0;                                           <<01869>>19425000
      CURRREC := 0D;                                           <<01869>>19430000
      LASTREC := 0D;                                           <<01869>>19435000
      RECNUM := 0D;                                            <<01869>>19440000
      NUMRECOVERED := 0D;                                      <<01869>>19445000
                                                               <<01869>>19450000
      @INREC := @BUFFAREA;                                     <<01869>>19455000
      @DINREC := @INREC;                                       <<01869>>19460000
      @BINREC := @INREC * 2;                                   <<01869>>19465000
                                                               <<01869>>19470000
      IF LOGGING'TYPE = DISC THEN                              <<01869>>19475000
      BEGIN                                   <<DISC LOGGING>>          19480000
         MOVE DEV:="DISC ";                                             19485000
                                                               <<01869>>19490000
         << Log file: old perm, fixed, ascii, read/write,    >><<01869>>19495000
         << multi-rec, no buf, exc, no :FILE.                >><<01869>>19500000
                                                               <<01869>>19505000
         LOGFILENO:=FOPEN(RECOV'FNAME,%2005,%524,DEV);         <<01869>>19510000
         IF <> THEN                                                     19515000
         BEGIN                                                          19520000
            <<UNABLE TO OPEN LOGGING FILE>>                             19525000
            FCHECK(LOGFILENO,ERRCODE);                         <<01869>>19530000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>19535000
            GENMSG(SETNO,UOPENFAILED,0,@SAVE'FNAME,@PROCNAME,  <<01869>>19540000
                   ,,,0);                                      <<01869>>19545000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>19550000
                   ,,,0);                                      <<01869>>19555000
            NOTIFIED := TRUE;                                  <<01869>>19560000
            GO NEXTONE;                                        <<01869>>19565000
         END;                                                           19570000
         FGETINFO(LOGFILENO,,,,,,,,,,EOF);                              19575000
         IF <> THEN                                            <<01869>>19580000
         BEGIN                                                 <<01869>>19585000
            FCHECK(LOGFILENO,ERRCODE);                         <<01869>>19590000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>19595000
            GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,@PROCNAME,    <<01869>>19600000
                   ,,,0);                                      <<01869>>19605000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>19610000
                   ,,,0);                                      <<01869>>19615000
            NOTIFIED := TRUE;                                  <<01869>>19620000
            GO NEXTONE;                                        <<01869>>19625000
         END;                                                  <<01869>>19630000
         DO                                                             19635000
         BEGIN                                                          19640000
            FREAD(LOGFILENO,BUFFAREA,BLKSIZE);                          19645000
            IF <> THEN EOFORERR:=TRUE;                                  19650000
            @INREC:=@BUFFAREA;                                          19655000
            @DINREC:=@BUFFAREA;                                         19660000
            CHECKBLOCK;                                                 19665000
            IF NOT VALID THEN                                           19670000
            BEGIN                                                       19675000
               IF FIRST THEN                                   <<01869>>19680000
               BEGIN                                           <<01869>>19685000
                  GENMSG(SETNO,LOGEMPTY,0,@SAVE'FNAME,         <<01869>>19690000
                         @PROCNAME,,,,0);                      <<01869>>19695000
                  NOTIFIED := TRUE;                            <<01869>>19700000
                  GO NEXTONE;                                  <<01869>>19705000
               END;                                            <<01869>>19710000
                                                               <<01869>>19715000
               IF NOT EOFORERR THEN FSPACE(LOGFILENO,-1);               19720000
               CURRREC:=CURRREC-1D;                                     19725000
               FORMATCRASH;                                             19730000
               FWRITE(LOGFILENO,BUFFAREA,BLKSIZE,0);                    19735000
               IF < THEN                                       <<01869>>19740000
               BEGIN                                           <<01869>>19745000
                  FCHECK(LOGFILENO,ERRCODE);                   <<01869>>19750000
                  GENMSG(FSSETNO,ERRCODE,,,,,,,0);             <<01869>>19755000
                  GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,      <<01869>>19760000
                         @PROCNAME,,,,0);                      <<01869>>19765000
                  GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,         <<01869>>19770000
                         @PROCNAME,,,,0);                      <<01869>>19775000
                  NOTIFIED := TRUE;                            <<01869>>19780000
                  GO NEXTONE;                                  <<01869>>19785000
               END;                                            <<01869>>19790000
               IF > THEN                                       <<01869>>19795000
               BEGIN                                           <<01869>>19800000
                  FCHECK(LOGFILENO,ERRCODE);                   <<01869>>19805000
                  GENMSG(FSSETNO,ERRCODE,,,,,,,0);             <<01869>>19810000
                  GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,      <<01869>>19815000
                         @PROCNAME,,,0);                       <<01869>>19820000
                  GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,         <<01869>>19825000
                         @PROCNAME,,,,0);                      <<01869>>19830000
                  NOTIFIED := TRUE;                            <<01869>>19835000
                  GO NEXTONE;                                  <<01869>>19840000
               END;                                            <<01869>>19845000
            END;                                                        19850000
         END UNTIL EOFORERR OR NOT VALID;                               19855000
                                                               <<01869>>19860000
         FCONTROL(LOGFILENO,SET'EOF,PARM);                     <<01869>>19865000
         IF <> THEN                                            <<01869>>19870000
         BEGIN                                                 <<01869>>19875000
            FCHECK(LOGFILENO,ERRCODE);                         <<01869>>19880000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>19885000
            GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,@PROCNAME,  <<01869>>19890000
                   ,,,0);                                      <<01869>>19895000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>19900000
                   ,,,0);                                      <<01869>>19905000
            NOTIFIED := TRUE;                                  <<01869>>19910000
            GO NEXTONE;                                        <<01869>>19915000
         END;                                                  <<01869>>19920000
                                                               <<01869>>19925000
         LEN:=DASCII(NUMRECOVERED,10,OUTPUT1);                          19930000
         OUTPUT1(LEN):=0;                                               19935000
         LEN:=ASCII(NUMOPEN,10,OUTPUT2);                                19940000
         OUTPUT2(LEN):=0;                                               19945000
         LEN:=ASCII(NUMCLOSE,10,OUTPUT3);                               19950000
         OUTPUT3(LEN):=0;                                               19955000
         GENMSG(SETNO,LOGREC,0,@OUTPUT1,@PROCNAME,@OUTPUT2,    <<01869>>19960000
                @OUTPUT3);                                     <<01869>>19965000
         END          << Disc logging recovery >>              <<01869>>19970000
      ELSE                                                              19975000
      BEGIN                                                             19980000
         <<TAPE LOGGING>>                                               19985000
                                                               <<01910>>19986100
       <<Recovery of User Logging file from tape during >>     <<01910>>19986200
       <<warmstart was rewritten entirely in Jan.86>>          <<01910>>19986300
                                                               <<01910>>19986400
         CASE LOGGING'TYPE OF                                  <<01869>>19990000
         BEGIN                                                 <<01869>>19995000
            <<0>>  ;         << Disc - never get here >>       <<01869>>20000000
            <<1>>  MOVE DEV := "TAPE ";                        <<01869>>20005000
            <<2>>  MOVE DEV := "SDISC ";                       <<01869>>20010000
            <<3>>  MOVE DEV := "CTAPE ";                       <<01869>>20015000
         END;                                                  <<01869>>20020000
                                                               <<01869>>20025000
         MOVE FORMS:=".,,,,; ";                                         20030000
                                                               <<01869>>20035000
         << Log file: old perm or temp, fixed, ascii, exc,  >> <<01869>>20040000
         << read/write, multi-rec, no buf, labeled tape.    >> <<01869>>20045000
                                                               <<01869>>20050000
   LOGFILENO := ULR'OPEN(RECOV'FNAME,%3007,%524,RECSIZE,                20055000
                          DEV,FORMS,,BLKFACTOR );              <<01871>>20060000
         IF <> THEN                                                     20065000
         BEGIN                                                          20070000
            FCHECK(LOGFILENO,ERRCODE);                         <<01869>>20075000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>20080000
            GENMSG(SETNO,TOPENFAILED,0,@SAVE'FNAME,@PROCNAME,  <<01869>>20085000
                   ,,,0);                                      <<01869>>20090000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>20095000
                   ,,,0);                                      <<01869>>20100000
            NOTIFIED := TRUE;                                  <<01869>>20105000
            GO NEXTONE;                                        <<01869>>20110000
         END;                                                           20115000
                                                               <<01869>>20120000
         MOVE DEV:="DISC ";                                             20125000
                                                               <<01869>>20130000
         << Buffer file: old perm, fixed, ascii, no :FILE,   >><<01869>>20135000
         << read/write, multi-rec, no buf, exc.              >><<01869>>20140000
                                                               <<01869>>20145000
         MOVE BUFNAME(8) := ".PUB.SYS ";                       <<01869>>20150000
         BUFNAME (16) := 0;                                    <<01869>>20155000
         BUFFILENO:=FOPEN(BUFNAME,%2005,%524,RECSIZE,DEV);     <<01869>>20160000
         IF <> THEN                                                     20165000
         BEGIN                                                          20170000
            FCHECK(BUFFILENO,ERRCODE);                         <<01869>>20175000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>20180000
            GENMSG(SETNO,BOPENFAILED,0,@BUFNAME,@PROCNAME,     <<01869>>20185000
                   ,,,0);                                      <<01869>>20190000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>20195000
                   ,,,0);                                      <<01869>>20200000
                                                                        20205000
            <<ERROR OPENING BUFFER>>                                    20210000
                                                                        20215000
            NOTIFIED := TRUE;                                  <<01869>>20220000
            GO NEXTONE;                                        <<01869>>20225000
         END;                                                           20230000
         FGETINFO(BUFFILENO,,,,,,,,,,EOF);                              20235000
         IF <> THEN                                            <<01869>>20240000
         BEGIN                                                 <<01869>>20245000
            FCHECK(BUFFILENO,ERRCODE);                         <<01869>>20250000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>20255000
            GENMSG(SETNO,LOGRECERR,0,@BUFNAME,@PROCNAME,,,,0); <<01869>>20260000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>20265000
                   ,,,0);                                      <<01869>>20270000
            NOTIFIED := TRUE;                                  <<01869>>20275000
            GO NEXTONE;                                        <<01869>>20280000
         END;                                                  <<01869>>20285000
         FGETINFO(LOGFILENO,,,,,,TAPEDEV);                     <<01869>>20290000
         IF <> THEN                                            <<01869>>20295000
         BEGIN                                                 <<01869>>20300000
            FCHECK(LOGFILENO,ERRCODE);                         <<01869>>20305000
            GENMSG(FSSETNO,ERRCODE,,,,,,,0);                   <<01869>>20310000
            GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,@PROCNAME,    <<01869>>20315000
                   ,,,0);                                      <<01869>>20320000
            GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,     <<01869>>20325000
                   ,,,0);                                      <<01869>>20330000
            NOTIFIED := TRUE;                                  <<01869>>20335000
            GO NEXTONE;                                        <<01869>>20340000
         END;                                                  <<01869>>20345000
                                                               <<01869>>20350000
$EDIT VOID=21090000                                            <<01910>>20355000
EOFORERR := FALSE;                                             <<01910>>20356000
RECNUM := 0D;                                                  <<01910>>20357000
VALID := TRUE;                                                 <<01910>>20358000
RECNUM1 := 0D;                                                 <<01910>>20359000
LASTBUFREC := 0D;                                              <<01910>>20360000
@INREC := @DISCREC;                                            <<01910>>20361000
@DINREC := @INREC;                                             <<01910>>20362000
                                                               <<01910>>20363000
<<Read the first record from the disc buffer file.>>           <<01910>>20364000
<<If empty close the file else find the record    >>           <<01910>>20365000
<<number of the first record and assign to        >>           <<01910>>20366000
<<the LASTBUFFILE for comparison.                 >>           <<01910>>20367000
                                                               <<01910>>20368000
FREADDIR(BUFFILENO,DISCREC,RECSIZE,RECNUM);                    <<01910>>20369000
IF <> THEN EOFORERR := TRUE;                                   <<01910>>20370000
                                                               <<01910>>20371000
IF EOFORERR THEN                                               <<01910>>20372000
BEGIN                                                          <<01910>>20373000
  IF RECNUM = 0D THEN                                          <<01910>>20374000
                                                               <<01910>>20375000
  <<since discbuffer empty, logfile must be empty,>>           <<01910>>20376000
  <<nothing to recover. >>                                     <<01910>>20377000
                                                               <<01910>>20378000
  begin                                                        <<01910>>20379000
    GENMSG(SETNO,LOGEMPTY,0,@SAVE'FNAME,@PROCNAME,,,,0);       <<01910>>20380000
    NOTIFIED := TRUE;                                          <<01910>>20381000
    GO NEXTONE;                                                <<01910>>20382000
  END                                                          <<01910>>20383000
END                                                            <<01910>>20384000
ELSE                                                           <<01910>>20385000
                                                               <<01910>>20386000
<<The first record was read successfully >>                    <<01910>>20387000
<<from the disc buffer file.>>                                 <<01910>>20388000
                                                               <<01910>>20389000
  <<If the record number of the first record read from the >>  <<01910>>20390000
  <<buffer file is one, assume nothing is posted to the    >>  <<01910>>20391000
  <<tape yet,so flush the entire buffer to the tape.>>         <<01910>>20392000
                                                               <<01910>>20393000
  BEGIN                                                        <<01910>>20394000
    IF DDISCREC(RNUM) = 1D THEN                                <<01910>>20395000
      BEGIN                                                    <<01910>>20396000
        LASTREC := 1D;                                         <<01910>>20397000
        GO FLUSHREST;                                          <<01910>>20398000
      END                                                      <<01910>>20399000
    ELSE                                                       <<01910>>20400000
      IF INREC(CODE).(8:8) = FIRST'CODE THEN                   <<01910>>20401000
        BEGIN                                                  <<01910>>20402000
          LASTREC := DDISCREC(RNUM);                           <<01910>>20403000
          GO FLUSHREST;                                        <<01910>>20404000
        END                                                    <<01910>>20405000
    ELSE                                                       <<01910>>20406000
      BEGIN                                                    <<01910>>20407000
        LASTBUFREC := DDISCREC(RNUM);                          <<01910>>20408000
        CURRREC := DDISCREC(RNUM) - 1D;                        <<01910>>20409000
      END;                                                     <<01910>>20410000
    DO                                                         <<01910>>20411000
    BEGIN                                                      <<01910>>20412000
                                                               <<01910>>20413000
     <<read the disc buffer to find the lowest record number>> <<01910>>20414000
      <<which is also a valid record>>                         <<01910>>20415000
                                                               <<01910>>20416000
      FREADDIR(BUFFILENO,BUFFAREA,BLKSIZE,RECNUM);             <<01910>>20417000
      IF <> THEN                                               <<01910>>20418000
      BEGIN                                                    <<01910>>20419000
        FCHECK(BUFFILENO,ERRCODE);                             <<01910>>20420000
        GENMSG(FSSETNO,ERRCODE,,,,,,,);                        <<01910>>20421000
        GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,@PROCNAME,,,,0);  <<01910>>20422000
        GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);   <<01910>>20423000
        NOTIFIED := TRUE;                                      <<01910>>20424000
        GO NEXTONE;                                            <<01910>>20425000
      END;                                                     <<01910>>20426000
                                                               <<01910>>20427000
      @INREC := @BUFFAREA;                                     <<01910>>20428000
      @DINREC := @BUFFAREA;                                    <<01910>>20429000
      IF DINREC(RNUM) < LASTBUFREC THEN                        <<01910>>20430000
      BEGIN                                                    <<01910>>20431000
        RECNUM1 := RECNUM;                                     <<01910>>20432000
        CURRREC := DINREC(RNUM) - 1D;                          <<01910>>20433000
        LASTBUFREC := DINREC(RNUM);                            <<01910>>20434000
      END;                                                     <<01910>>20435000
      CHECKBLOCK;                                              <<01910>>20436000
      IF VALID THEN                                            <<01910>>20437000
      BEGIN                                                    <<01910>>20438000
        RECNUM := RECNUM + DOUBLE(BLKFACTOR);                  <<01910>>20439000
        IF RECNUM >= EOF THEN EOFORERR := TRUE;                <<01910>>20440000
      END                                                      <<01910>>20441000
      ELSE                                                     <<01910>>20442000
       IF RECNUM = 0D THEN                                     <<01910>>20443000
                                                               <<01910>>20444000
     <<Disc buffer file is empty, so backspace the tape file>> <<01910>>20445000
     <<and write crashmarker in the tape file and close it.>>  <<01910>>20446000
                                                               <<01910>>20447000
       BEGIN                                                   <<01910>>20448000
         STAT := ATTACHIO(TAPEDEV,QMISC,0,@BUFFAREA,BKSPACE,   <<01910>>20449000
                 0,0,0,FLAGS);                                 <<01910>>20450000
         IF STAT0.(13:3) <> SUCCESS AND                        <<01910>>20451000
            STAT0.(8:8) <> FEOF THEN                           <<01910>>20452000
         BEGIN                                                 <<01910>>20453000
           ERRCODE := IOSTAT(STAT0);                           <<01910>>20454000
           GENMSG(FSSETNO,ERRCODE,,,,,,,0);                    <<01910>>20455000
           GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,             <<01910>>20456000
                  @PROCNAME,,,,0);                             <<01910>>20456500
           GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);<<01910>>20457000
           NOTIFIED := TRUE;                                   <<01910>>20458000
           GO NEXTONE;                                         <<01910>>20459000
         END;                                                  <<01910>>20460000
         LASTREC := 0D;                                        <<01910>>20461000
         NUMRECOVERED := LASTREC;                              <<01910>>20462000
         FORMATCRASH;                                          <<01910>>20463000
         FWRITE(LOGFILENO,BUFFAREA,BLKSIZE,0);                 <<01910>>20464000
         IF <> THEN                                            <<01910>>20465000
         BEGIN                                                 <<01910>>20466000
           FCHECK(LOGFILENO,ERRCODE);                          <<01910>>20467000
           GENMSG(FSSETNO,ERRCODE,,,,,,,0);                    <<01910>>20468000
           GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,             <<01910>>20469000
                  @PROCNAME,,,,0);                             <<01910>>20469500
           GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);<<01910>>20470000
           NOTIFIED := TRUE;                                   <<01910>>20471000
           GO NEXTONE;                                         <<01910>>20472000
         END;                                                  <<01910>>20473000
         GO EMPTYFILE;                                         <<01910>>20474000
       END;                                                    <<01910>>20475000
                                                               <<01910>>20476000
    END UNTIL NOT VALID OR EOFORERR;                           <<01910>>20477000
                                                               <<01910>>20478000
      <<Invalid block or end of file encountered>>             <<01910>>20479000
      <<in disc buffer file. To be on the safe side>>          <<01910>>20480000
      <<determine the last block flushed to tape as>>          <<01910>>20481000
      <<follows: Lowest record number found in the  >>         <<01910>>20482000
      <<disc buffer file minus a block and assign   >>         <<01910>>20483000
      << the variable STOPPER to it.            >>             <<01910>>20484000
                                                               <<01910>>20485000
        STOPPER := LASTBUFREC - DOUBLE(BLKFACTOR);             <<01910>>20486000
  END;                                                         <<01910>>20487000
                                                               <<01910>>20488000
<<now match up the disc buffer record with the tape record>>   <<01910>>20489000
                                                               <<01910>>20490000
                                                               <<01910>>20491000
    NUMRECOVERED := 0D;                                        <<01910>>20492000
    LASTREC := 1D;                                             <<01910>>20493000
    EOFORERR := FALSE;                                         <<01910>>20494000
    VALID := FALSE;                                            <<01910>>20495000
    FIRST := TRUE;                                             <<01910>>20496000
                                                               <<01910>>20497000
DO                                                             <<01910>>20498000
BEGIN                                                          <<01910>>20499000
  FREAD(LOGFILENO,BUFFAREA,BLKSIZE);                           <<01910>>20500000
  IF < THEN                                                    <<01910>>20501000
  BEGIN                                                        <<01910>>20502000
    FCHECK(LOGFILENO,ERRCODE);                                 <<01910>>20503000
    GENMSG(FSSETNO,ERRCODE,,,,,,,0);                           <<01910>>20504000
    GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,@PROCNAME,,,,0);      <<01910>>20505000
    GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);       <<01910>>20506000
    NOTIFIED := TRUE;                                          <<01910>>20507000
    GO NEXTONE;                                                <<01910>>20508000
  END                                                          <<01910>>20509000
  ELSE                                                         <<01910>>20510000
  IF > THEN                                                    <<01910>>20511000
  BEGIN                                                        <<01910>>20512000
   EOFORERR := TRUE;                                           <<01910>>20513000
   LASTREC := CURTAPEREC;                                      <<01910>>20514000
  END                                                          <<01910>>20515000
 ELSE                                                          <<01910>>20516000
  BEGIN                                                        <<01910>>20517000
    @INREC := @BUFFAREA;                                       <<01910>>20518000
    @DINREC := @BUFFAREA;                                      <<01910>>20519000
                                                               <<01910>>20520000
<<Verify that the first record read from tape is either >>     <<01910>>20521000
<<the header,restart or changelog record.               >>     <<01910>>20522000
                                                               <<01910>>20523000
    IF FIRST THEN                                              <<01910>>20524000
    BEGIN                                                      <<01910>>20525000
      IF INREC(CODE).(8:8) <> HEADER AND                       <<01910>>20526000
         INREC(CODE).(8:8) <> RSTART AND                       <<01910>>20527000
         INREC(CODE).(8:8) <> FIRST'CODE THEN                  <<01910>>20528000
         RETURN;                                               <<01910>>20529000
      IF INREC(CODE).(8:8) = FIRST'CODE THEN                   <<01910>>20530000
         CURTAPEREC := DINREC(RNUM)                            <<01910>>20531000
      ELSE                                                     <<01910>>20532000
         CURTAPEREC := 1D;                                     <<01910>>20533000
    END;                                                       <<01910>>20534000
                                                               <<01910>>20535000
    IF DINREC(RNUM) >= STOPPER THEN                            <<01910>>20536000
    BEGIN                                                      <<01910>>20537000
      VALID := TRUE;                                           <<01910>>20538000
      LASTREC := LASTBUFREC;                                   <<01910>>20539000
      NUMRECOVERED := NUMRECOVERED + DOUBLE(BLKFACTOR);        <<01910>>20540000
    END                                                        <<01910>>20541000
    ELSE                                                       <<01910>>20542000
      IF DINREC(RNUM) < STOPPER THEN                           <<01910>>20543000
      BEGIN                                                    <<01910>>20544000
        IF CURTAPEREC <> DINREC(RNUM) THEN                     <<01910>>20545000
        BEGIN                                                  <<01910>>20546000
          EOFORERR := TRUE;                                    <<01910>>20547000
          LASTREC := CURTAPEREC;                               <<01910>>20548000
        END                                                    <<01910>>20549000
        ELSE                                                   <<01910>>20550000
        BEGIN                                                  <<01910>>20551000
          CURTAPEREC := CURTAPEREC + DOUBLE(BLKFACTOR);        <<01910>>20552000
          NUMRECOVERED := NUMRECOVERED + DOUBLE(BLKFACTOR);    <<01910>>20553000
          FIRST := FALSE                                       <<01910>>20554000
        END                                                    <<01910>>20555000
      END                                                      <<01910>>20556000
    END                                                        <<01910>>20557000
  END UNTIL VALID OR EOFORERR;                                 <<01910>>20558000
                                                               <<01910>>20559000
<<if we could'nt find the record in the tape file >>           <<01910>>20560000
<<for any reason then format crashrecord and close>>           <<01910>>20561000
<<the tape log file.                              >>           <<01910>>20562000
                                                               <<01910>>20563000
  IF EOFORERR THEN                                             <<01910>>20564000
    BEGIN                                                      <<01910>>20565000
      NUMRECOVERED :=  LASTREC;                                <<01910>>20566000
      FORMATCRASH;                                             <<01910>>20567000
      FWRITE(LOGFILENO,BUFFAREA,BLKSIZE,0);                    <<01910>>20568000
      IF <> THEN                                               <<01910>>20569000
        BEGIN                                                  <<01910>>20570000
           FCHECK(LOGFILENO,ERRCODE);                          <<01910>>20571000
           GENMSG(FSSETNO,ERRCODE,,,,,,,0);                    <<01910>>20572000
           GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,             <<01910>>20573000
                  @PROCNAME,,,,0);                             <<01910>>20573500
           GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);<<01910>>20574000
           NOTIFIED := TRUE;                                   <<01910>>20575000
           GO NEXTONE;                                         <<01910>>20576000
        END;                                                   <<01910>>20577000
    END;                                                       <<01910>>20578000
                                                               <<01910>>20579000
                                                               <<01910>>20580000
@INREC := @DISCREC;                                            <<01910>>20581000
@DINREC := @INREC;                                             <<01910>>20582000
EOFORERR := FALSE;                                             <<01910>>20583000
VALID := TRUE;                                                 <<01910>>20584000
                                                               <<01910>>20585000
            << When we get here, we have found the last good >><<01869>>21095000
            << block from the logfile and the first block    >><<01869>>21100000
            << needed from the buffer file. We need to update>><<01869>>21105000
            << CURRREC so that when we get ready to output   >><<01869>>21110000
            << where we left off, the log records will be in >><<01869>>21115000
            << sequence.                                     >><<01869>>21120000
FLUSHREST:                                                     <<01910>>21121000
                                                               <<01910>>21122000
             LASTREC := LASTREC - 1D;                          <<01910>>21123000
                                                               <<01869>>21125000
             CURRREC := LASTREC;                               <<01910>>21130000
             RECNUM := RECNUM1;                                <<01910>>21133000
                                                               <<01869>>21135000
            DO                                                          21140000
            BEGIN                                                       21145000
                                                               <<01869>>21150000
               FREADDIR(BUFFILENO,BUFFAREA,BLKSIZE,RECNUM);             21155000
               IF <> THEN                                      <<01869>>21160000
               BEGIN                                           <<01869>>21165000
                  FCHECK(BUFFILENO,ERRCODE);                   <<01869>>21170000
                  GENMSG(FSSETNO,ERRCODE,,,,,,,0);             <<01869>>21175000
                  GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,        <<01869>>21180000
                         @PROCNAME,,,,0);                      <<01869>>21185000
                  GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,         <<01869>>21190000
                         @PROCNAME,,,,0);                      <<01869>>21195000
                  NOTIFIED := TRUE;                            <<01869>>21200000
                  GO NEXTONE;                                  <<01869>>21205000
               END;                                            <<01869>>21210000
                                                               <<01869>>21215000
               @INREC:=@BUFFAREA;                                       21220000
               @DINREC:=@BUFFAREA;                                      21225000
               CHECKBLOCK;                                              21230000
               IF VALID THEN                                            21235000
               BEGIN                                                    21240000
                  FWRITE(LOGFILENO,BUFFAREA,BLKSIZE,0);                 21245000
                  IF <> THEN                                   <<01869>>21250000
                  BEGIN                                        <<01869>>21255000
                   FCHECK(LOGFILENO,ERRCODE);                  <<01869>>21260000
                   GENMSG(FSSETNO,ERRCODE,,,,,,,0);            <<01869>>21265000
                   GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,     <<01869>>21270000
                          @PROCNAME,,,,0);                     <<01869>>21275000
                   GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,        <<01869>>21280000
                          @PROCNAME,,,,0);                     <<01869>>21285000
                   NOTIFIED := TRUE;                           <<01869>>21290000
                   GO NEXTONE;                                 <<01869>>21295000
                  END;                                         <<01869>>21300000
                  RECNUM:=RECNUM+DOUBLE(BLKFACTOR);                     21305000
                  IF RECNUM >= EOF THEN RECNUM:=0D;                     21310000
                                                               <<01869>>21315000
                  << Bump LASTREC to remember the last     >>  <<01869>>21320000
                  << record successfully recovered.        >>  <<01869>>21325000
                                                               <<01869>>21330000
                  LASTREC := LASTREC + DOUBLE(BLKFACTOR);      <<01869>>21335000
               END                                                      21340000
               ELSE                                                     21345000
               BEGIN                                                    21350000
                  << Need to bump CURRREC to reflect the     >><<01869>>21355000
                  << current # of good records found. LASTREC>><<01869>>21360000
                  << is the # actuallly written to the       >><<01869>>21365000
                  << logfile, I is the number of good records>><<01869>>21370000
                  << found in the last block from the buffer >><<01869>>21375000
                  << file.                                   >><<01869>>21380000
                                                               <<01869>>21385000
                  CURRREC := LASTREC + DOUBLE(I);              <<01869>>21390000
                  FORMATCRASH;                                          21395000
                                                               <<01869>>21400000
                  FWRITE(LOGFILENO,BUFFAREA,BLKSIZE,0);                 21405000
                  IF <> THEN                                   <<01869>>21410000
                  BEGIN                                        <<01869>>21415000
                   FCHECK(LOGFILENO,ERRCODE);                  <<01869>>21420000
                   GENMSG(FSSETNO,ERRCODE,,,,,,,0);            <<01869>>21425000
                   GENMSG(SETNO,FWRITEERROR,0,@SAVE'FNAME,     <<01869>>21430000
                          @PROCNAME,,,,0);                     <<01869>>21435000
                   GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,        <<01869>>21440000
                          @PROCNAME,,,,0);                     <<01869>>21445000
                   NOTIFIED := TRUE;                           <<01869>>21450000
                   GO NEXTONE;                                 <<01869>>21455000
                  END;                                         <<01869>>21460000
               END;                                                     21465000
            END UNTIL NOT VALID OR EOFORERR;                            21470000
                                                               <<01869>>21475000
$EDIT VOID=21480000                                            <<01910>>21480000
EMPTYFILE:                                                     <<01910>>21482000
         LEN:=DASCII(NUMRECOVERED,10,OUTPUT1);                          21485000
         OUTPUT1(LEN):=0;                                               21490000
         LEN:=ASCII(NUMOPEN,10,OUTPUT2);                                21495000
         OUTPUT2(LEN):=0;                                               21500000
         LEN:=ASCII(NUMCLOSE,10,OUTPUT3);                               21505000
         OUTPUT3(LEN):=0;                                               21510000
         GENMSG(SETNO,TAPELOGREC,0,@OUTPUT1,@PROCNAME);        <<01910>>21515000
$EDIT VOID=21520000                                            <<01910>>21520000
      END;         <<Tape logging>>                            <<01869>>21525000
                                                               <<01869>>21530000
      NEXTONE:                                                          21535000
                                                               <<01869>>21540000
      RELENTRY(TABINDEX,0);                                             21545000
      FCLOSE(LOGFILENO,0,0);                                            21550000
      IF <> AND (NOT NOTIFIED) THEN                            <<01869>>21555000
      BEGIN                                                    <<01869>>21560000
         FCHECK(LOGFILENO,ERRCODE);                            <<01869>>21565000
         GENMSG(FSSETNO,ERRCODE,,,,,,,0);                      <<01869>>21570000
         GENMSG(SETNO,LOGRECERR,0,@SAVE'FNAME,@PROCNAME,,,,0); <<01869>>21575000
         GENMSG(SETNO,NOLOGREC,0,@SAVE'FNAME,@PROCNAME,,,,0);  <<01869>>21580000
      END;                                                     <<01869>>21585000
DONE:                                                          <<01910>>21588000
      FCLOSE(BUFFILENO,4,0);                                            21590000
      EXCHANGEDB(LOGDST);                                               21595000
   END             <<Recover loop>>                            <<01869>>21600000
  UNTIL (TABINDEX:=NEXT'TABINDEX) = NULL;                      <<01869>>21605000
   OUT:                                                                 21610000
                                                               <<01869>>21615000
   EXCHANGEDB(0);    << Back to stack >>                                21620000
   <<LOGGING PROCESS RECOVERED>>                                        21625000
END;                                                                    21630000
$PAGE "INITRECLOG -- Set up warmstart recovery"                         21635000
PROCEDURE INITRECLOG;                                                   21640000
OPTION PRIVILEGED,UNCALLABLE;                                           21645000
BEGIN                                                                   21650000
                                                                        21655000
COMMENT                                                        <<01869>>21660000
  Called from Progen to initiate RECLOG (to recover open       <<01869>>21665000
  logging files). The logging files will only be recovered     <<01869>>21670000
  during a WARMSTART since any other start will re-initialize  <<01869>>21675000
  the LOGTAB (DST %33) such that there are no current logging  <<01869>>21680000
  processes.                                                   <<01869>>21685000
;                                                              <<01869>>21690000
                                                               <<01869>>21695000
                                                               <<01869>>21700000
   INTEGER CLEANUPIN:=0,STACK,DB;                                       21705000
   LOGICAL NOSTDIN:=0, NOSTDLIST:=0;     << FOR PROCREATE >>   <<01869>>21710000
   EQUATE NOSTRING=0, NOSTLEN=0;                               <<01869>>21715000
                                                               <<01869>>21720000
   STACK:=GETSTACK(INITSTACK,MAXSTACK);                                 21725000
   TOS:=@CLEANUPIN;                                                     21730000
   IF STACK <> 0 THEN                                                   21735000
   BEGIN                                                                21740000
      TOS:=A'(RECLOGPLABEL);                                            21745000
                                                               <<01869>>21750000
      << The external P-label is in the form:                >><<01869>>21755000
      << STT entry, code segment number. PROCREATE only needs>><<01869>>21760000
      << the code segment number.                            >><<01869>>21765000
                                                               <<01869>>21770000
      TOS.(0:8):=0;                                                     21775000
      TOS.(0:1):=1;                                                     21780000
                                                               <<01869>>21785000
      << Also need the Delta P-label - starting offset within>><<01869>>21790000
      << the code segment for the procedure.                 >><<01869>>21795000
                                                               <<01869>>21800000
      TOS:=A'(RECLOGDELTAP);                                            21805000
      PROCREATE(*,*,*,STACK,GLOBSIZE,0,LOCSIZE,PRI,NOSTRING,   <<01869>>21810000
                NOSTLEN,0,%713,MAXSTACK,NOSTDIN,NOSTDLIST);    <<01869>>21815000
      IF = THEN                                                         21820000
      BEGIN            << Procreate was successfull >>         <<01869>>21825000
      DB:=EXCHANGEDB(STACK);                                            21830000
                                                               <<01869>>21835000
      << Set up the primary DB area of the stack. The only   >><<01869>>21840000
      << global variables used by RECLOG are BUFFAREA and    >><<01869>>21845000
      << DISCREC - need to set up their pointers.            >><<01869>>21850000
                                                               <<01869>>21855000
      PDB(5) := %71;           << Word addr for BUFFAREA     >><<01869>>21860000
      PDB(6) := %10071;        << Word addr for DISCREC      >><<01869>>21865000
                                                               <<01869>>21870000
      TOS:=EXCHANGEDB(DB);                                              21875000
      AWAKE(CLEANUPIN*PCBSIZE,%1,0);                                    21880000
$IF X1=ON                                                      <<01874>>21885000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>21895000
$IF                                                            <<01874>>21900000
      END;                                                     <<01869>>21905000
                                                               <<01869>>21910000
   END;                                                                 21915000
END;                                                                    21920000
$PAGE "CLEANUP -- release user entries from LOGBUFF"                    21925000
PROCEDURE CLEANUPLOG;                                                   21930000
OPTION PRIVILEGED,UNCALLABLE;                                           21935000
BEGIN                                                                   21940000
                                                                        21945000
                                                                        21950000
<<USER LOGGING PROCESS TERMINATION CLEANUP>>                            21955000
                                                                        21960000
                                                                        21965000
   LOGICAL POINTER PXFIXED;                                             21970000
   LOGICAL POINTER S0 = S-0;                                            21975000
   INTEGER DB,DB2;                                                      21980000
   INTEGER SAVEINDEX;                                          <<01869>>21985000
   INTEGER INDEX,TABINDEX;                                              21990000
   LOGICAL A;                                                           21995000
                                                               <<01869>>22000000
                                                               <<01869>>22005000
   DB:=EXCHANGEDB(0);                                                   22010000
   PUSH(DL);                                                            22015000
   ASSEMBLE(DUP);                                                       22020000
   TOS:=TOS-2;                                                          22025000
   TOS:=S0;                                                             22030000
   ASSEMBLE(XCH,DEL,SUB);                                               22035000
   @PXFIXED:=TOS;                                                       22040000
   IF PXFXLOGGING = 1 THEN                                     <<01869>>22045000
   BEGIN                                                                22050000
      PXFXLOGGING:=0;                                          <<01869>>22055000
      EXCHANGEDB(LOGDST);                                      <<01869>>22060000
      A:=GETSIR(LOGSIR);                                       <<01869>>22065000
      TABINDEX:=LOGTAB(INUSE);                                          22070000
      IF TABINDEX = NULL THEN                                           22075000
      BEGIN                                                             22080000
         RELSIR(LOGSIR,A);                                     <<01869>>22085000
         EXCHANGEDB(DB);                                       <<01869>>22090000
         RETURN;                                                        22095000
      END;                                                              22100000
                                                               <<01869>>22105000
      DO                                                                22110000
      BEGIN                                                             22115000
                                                                        22120000
         DB2 := LOGTAB(DST);                                   <<01869>>22125000
         IF LOGTAB(STATUS) = INITIALIZING  OR                  <<01869>>22130000
            LOGTAB(STATUS) = RECOVERING THEN GO AROUND;        <<01869>>22135000
         IF DB2 = NULL THEN GO AROUND;                         <<01869>>22140000
         EXCHANGEDB(LOGTAB(DST));                              <<01869>>22145000
         OBTAIN(LOGBUFF(RESOURCE3),NULL);                      <<01875>>22150000
$IF X1=ON                                                      <<01874>>22151000
      WHAT'S'UP ( BC'OBTAIN,3 );                               <<01874>>22153000
$IF                                                            <<01874>>22154000
         INDEX:=LOGBUFF(UHEAD);                                         22155000
                                                               <<01869>>22160000
         IF INDEX <> NULL THEN                                          22165000
         DO                                                             22170000
         BEGIN                                                          22175000
            IF LOGBUFF(UPIN) = MYPIN  THEN                     <<01869>>22180000
            BEGIN                                              <<01869>>22185000
               SAVEINDEX:=LOGBUFF(NENTRY);                     <<01869>>22190000
               RELENTRY(INDEX,DB2);                            <<01869>>22195000
               INDEX:=SAVEINDEX;                               <<01869>>22200000
            END                                                <<01869>>22205000
            ELSE INDEX:=LOGBUFF(NENTRY);                       <<01869>>22210000
                                                                        22215000
         END UNTIL INDEX = NULL;                               <<01869>>22220000
         RELEASE(LOGBUFF(RESOURCE3),NULL,1);                   <<01875>>22225000
$IF X1=ON                                                      <<01874>>22226000
      WHAT'S'UP ( BC'RELEASE,3 );                              <<01874>>22228000
$IF                                                            <<01874>>22229000
         IF LOGBUFF(NUMUSER) = 0 THEN                                   22230000
         BEGIN                                                 <<01874>>22231000
         AWAKE(LOGBUFF(LOGPIN),%20,0);                                  22235000
$IF X1=ON                                                      <<01874>>22240000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>22250000
$IF                                                            <<01874>>22255000
         END;                                                  <<01874>>22256000
AROUND:                                                        <<01869>>22260000
                                                                        22265000
                                                               <<01869>>22270000
         EXCHANGEDB(LOGDST);                                   <<01869>>22275000
      END UNTIL (TABINDEX:=LOGTAB(NEXT)) = NULL;                        22280000
      RELSIR(LOGSIR,A);                                                 22285000
      EXCHANGEDB(DB);                                          <<01869>>22290000
   END;                                                                 22295000
END;                                                                    22300000
$PAGE "Table Access Utilities -- RELENTRY"                              22305000
PROCEDURE RELENTRY(INDEX',TYPE);                               <<01869>>22310000
VALUE INDEX',TYPE;                                                      22315000
INTEGER INDEX',TYPE;                                                    22320000
OPTION PRIVILEGED,UNCALLABLE;                                           22325000
BEGIN                                                                   22330000
                                                                        22335000
                                                                        22340000
   <<THIS PROCEDURE RELEASES LOGGING ENTRIES IN THE GLOBAL       >>     22345000
   <<LOGGING TABLE LOGTAB AND IN THE COMMUNICATION AREA OF LOGBUF>>     22350000
   <<TO SPECIFY THE GLOBAL TABLE, TYPE MUST BE ZERO.  TO SPECIFY >>     22355000
   <<AN ENTRY IN LOGBUFF, TYPE MUST BE SET TO THE DST NUMBER OF  >>     22360000
   <<LOGBUFF                                                     >>     22365000
   <<                                                            >>     22370000
   <<THE ADDRESS FOR THE  ENTRY TO BE DELETED SHOULD BE IN THE   >>     22375000
   <<INDEX PARAMETER.                                            >>     22380000
   <<                                                            >>     22385000
   << SPLIT STACK CALLS ARE NOT PERMITTED BY THIS PROCEDURE      >>     22390000
                                                                        22395000
                                                                        22400000
                                                                        22405000
   INTEGER X = X;                                                       22410000
   LOGICAL S0 = S-0;                                           <<01869>>22415000
   LOGICAL ALREADY'LOCKED;                                     <<01869>>22420000
   INTEGER PREV',                                                       22425000
   NEXT',                                                               22430000
   FREEENTRY;                                                           22435000
                                                                        22440000
   LOGICAL A;                                                           22445000
   INTEGER TABINDEX,INDEX,DB;                                           22450000
   LOGICAL COND;                                                        22455000
                                                               <<01869>>22460000
                                                               <<01869>>22465000
   IF TYPE = 0 THEN                                                     22470000
   BEGIN                                                                22475000
      TABINDEX:=INDEX';                                                 22480000
      A:=GETSIR(LOGSIR);                                                22485000
      DB:=EXCHANGEDB(LOGDST);                                           22490000
      <<GLOBL LOGTAB>>                                                  22495000
      PREV':=LOGTAB(PREV);                                              22500000
      NEXT':=LOGTAB(NEXT);                                              22505000
      FREEENTRY:=TABINDEX;                                              22510000
      X:=FREEENTRY;                                            <<01869>>22515000
      DO                                                       <<01869>>22520000
      LOGTAB(X) := "  "                                        <<01869>>22525000
      UNTIL (X:=X+1) >= (FREEENTRY+TENTRYSIZE-2);              <<01869>>22530000
      LOGTAB(NEXT):=LOGTAB(FREE);                                       22535000
      LOGTAB(PREV):=NULL;                                               22540000
      LOGTAB(LGSWITCH) := FALSE;                               <<01869>>22545000
      LOGTAB(DST) := NULL;                                     <<01869>>22550000
                                                               <<01869>>22555000
      TABINDEX:=LOGTAB(FREE);                                           22560000
      LOGTAB(PREV):=FREEENTRY;                                          22565000
      LOGTAB(FREE):=FREEENTRY;                                          22570000
                                                                        22575000
      <<NOW REMOVE FROM IN USE>>                                        22580000
                                                                        22585000
      IF PREV' <> NULL THEN                                             22590000
      BEGIN                                                             22595000
         TABINDEX:=PREV';                                               22600000
         LOGTAB(NEXT):=NEXT';                                           22605000
      END;                                                              22610000
      IF NEXT' <> NULL THEN                                             22615000
      BEGIN                                                             22620000
         TABINDEX:=NEXT';                                               22625000
         LOGTAB(PREV):=PREV';                                           22630000
      END;                                                              22635000
      IF PREV' = NULL THEN LOGTAB(INUSE):=NEXT';                        22640000
      RELSIR(LOGSIR,A);                                                 22645000
      DB:=EXCHANGEDB(DB);                                               22650000
   END                                                                  22655000
   ELSE                                                                 22660000
   BEGIN                                                                22665000
      INDEX:=INDEX';                                                    22670000
      COND:=TRUE;                                                       22675000
      DB:=EXCHANGEDB(TYPE);                                             22680000
      IF LOGBUFF(RES3'OWNER) = MYPIN THEN                      <<01875>>22685000
               ALREADY'LOCKED := TRUE                          <<01875>>22690000
            ELSE                                               <<01875>>22695000
            BEGIN                                              <<01875>>22700000
               ALREADY'LOCKED := FALSE;                        <<01875>>22705000
               OBTAIN(LOGBUFF(RESOURCE3),NULL);                <<01875>>22710000
$IF X1=ON                                                      <<01874>>22711000
      WHAT'S'UP ( BC'OBTAIN,3 );                               <<01874>>22713000
$IF                                                            <<01874>>22714000
            END;                                               <<01875>>22715000
      PREV':=LOGBUFF(PENTRY);                                           22720000
      NEXT':=LOGBUFF(NENTRY);                                           22725000
      FREEENTRY:=INDEX;                                                 22730000
      X:=FREEENTRY;                                                     22735000
      DO                                                                22740000
      LOGBUFF(X) := "  "                                       <<01869>>22745000
      UNTIL (X:=X+1) >= (FREEENTRY+BENTRYSIZE-2);              <<01869>>22750000
      LOGBUFF(NENTRY):=LOGBUFF(FHEAD);                                  22755000
      LOGBUFF(PENTRY):=NULL;                                            22760000
      INDEX:=LOGBUFF(FHEAD);                                            22765000
      IF INDEX <> NULL THEN LOGBUFF(PENTRY):=FREEENTRY;                 22770000
      LOGBUFF(FHEAD):=FREEENTRY;                                        22775000
                                                                        22780000
      <<NOW REMOVE FROM IN USE>>                                        22785000
                                                                        22790000
      IF PREV' <> NULL THEN                                             22795000
      BEGIN                                                             22800000
         INDEX:=PREV';                                                  22805000
         LOGBUFF(NENTRY):=NEXT';                                        22810000
      END;                                                              22815000
      IF NEXT' <> NULL THEN                                             22820000
      BEGIN                                                             22825000
         INDEX:=NEXT';                                                  22830000
         LOGBUFF(PENTRY):=PREV';                                        22835000
      END;                                                              22840000
      IF PREV' = NULL THEN LOGBUFF(UHEAD):=NEXT';                       22845000
      LOGBUFF(NUMUSER):=LOGBUFF(NUMUSER)-1;                             22850000
      IF NOT ALREADY'LOCKED THEN                               <<01869>>22855000
         BEGIN                                                 <<01874>>22856000
            RELEASE(LOGBUFF(RESOURCE3),NULL,1);                <<01875>>22860000
$IF X1=ON                                                      <<01874>>22865000
      WHAT'S'UP ( BC'RELEASE,3 );                              <<01874>>22875000
$IF                                                            <<01874>>22880000
         END;                                                  <<01874>>22881000
      DB:=EXCHANGEDB(DB);                                               22885000
   END;                                                                 22890000
   WRITEDSEG(LOGDST);                                                   22895000
END;                                                                    22900000
$PAGE "Table Access Utilities -- GENTRY"                       <<01869>>22905000
LOGICAL PROCEDURE GENTRY(INDEX',TYPE);                                  22910000
VALUE TYPE;                                                             22915000
INTEGER INDEX',TYPE;                                                    22920000
OPTION PRIVILEGED,UNCALLABLE;                                           22925000
BEGIN                                                                   22930000
                                                                        22935000
                                                                        22940000
   <<THIS PROCEDURE GETS A LOGGING ENTRY IN THE SYSTEM GLOBAL LOGGIN>>  22945000
   <<DATASEGMENT LOGTAB OR IN THE LOGGING PROCESS COMM AREA OF LOGBU>>  22950000
   <<IF AN ENTRY IS DESIRED IN THE LOGTAB, TYPE MUST BE SET TO ZERO >>  22955000
   <<IF AN ENTRY IS DESIRED IN LOGBUFF, TYPE MUST BE SET TO THE DST >>  22960000
   <<NUMBER OF LOGBUFF.                                             >>  22965000
   <<                                                               >>  22970000
   <<SPLIT STACK CALLS ARE NOT PERMITTED BY THIS PROCEDURE          >>  22975000
   <<                                                               >>  22980000
   <<THE RELATIVE ADDRESS WHERE THE AQUIRED ENTRY RESIDES IS RETURNE>>  22985000
   <<IN THE INDEX PARAMETER.                                        >>  22990000
   <<                                                        >><<01869>>22995000
   << RETURNS:                                           >>    <<01869>>23000000
   <<     TRUE - Entry obtained from table.              >>    <<01869>>23005000
   <<     FALSE- No more entries available.              >>    <<01869>>23010000
                                                                        23015000
                                                                        23020000
   LOGICAL A;                                                           23025000
   INTEGER DB;                                                          23030000
   LOGICAL ALREADY'LOCKED;                                     <<01869>>23035000
   INTEGER                                                              23040000
   NEWENTRY,                                                            23045000
   QINDEX;                                                              23050000
   INTEGER TABINDEX,INDEX;                                              23055000
   LOGICAL S0 = S-0;                                                    23060000
                                                                        23065000
   IF TYPE = 0  THEN   <<Entry in LOGTAB>>                     <<01869>>23070000
   BEGIN                                                                23075000
      << GLOBL LOGGING TABLE >>                                         23080000
      A:=GETSIR(LOGSIR);                                                23085000
      DB:=EXCHANGEDB(LOGDST);                                           23090000
      TABINDEX:=LOGTAB(FREE);                                           23095000
      IF TABINDEX = NULL THEN                                           23100000
      BEGIN                                <<NO MORE ENTRIES>>          23105000
         GENTRY:=FALSE;                                                 23110000
         RELSIR(LOGSIR,A);                                              23115000
         EXCHANGEDB(DB);                                       <<01869>>23120000
         RETURN;                                                        23125000
      END;                                                              23130000
      NEWENTRY:=LOGTAB(FREE);                                           23135000
      <<REMOVE FROM FREE LIST>>                                         23140000
                                                                        23145000
      LOGTAB(FREE):=LOGTAB(NEXT);                                       23150000
      TABINDEX:=LOGTAB(FREE);                                  <<01869>>23155000
      LOGTAB(PREV):=NULL;                                               23160000
                                                               <<01869>>23165000
      <<ADD TO INUSE LIST>>                                             23170000
                                                               <<01869>>23175000
      TABINDEX:= IF LOGTAB(INUSE) = NULL THEN                           23180000
      NEWENTRY ELSE LOGTAB(INUSE);                                      23185000
      LOGTAB(PREV):= IF LOGTAB(INUSE) =NULL THEN                        23190000
      NULL ELSE NEWENTRY;                                               23195000
                                                               <<01869>>23200000
      TABINDEX:=NEWENTRY;                                               23205000
                                                               <<01869>>23210000
      << Clear the entry -- except the prev and next ptrs >>   <<01869>>23215000
                                                               <<01869>>23220000
      LOGTAB(TABINDEX) := "  ";                                <<01869>>23225000
      MOVE LOGTAB(TABINDEX+1) := LOGTAB(TABINDEX),             <<01869>>23230000
           (TENTRYSIZE-3);                                     <<01869>>23235000
                                                               <<01869>>23240000
      LOGTAB(LGSWITCH) := FALSE;                               <<01869>>23245000
      LOGTAB(DST) := NULL;                                     <<01869>>23250000
      LOGTAB(NEXT):=LOGTAB(INUSE);                                      23255000
      LOGTAB(INUSE):=NEWENTRY;                                          23260000
                                                               <<01869>>23265000
      <<UPDATE GLOBL ENTRIES>>                                          23270000
      LOGTAB(NUMENTRIES):=LOGTAB(NUMENTRIES)+1;                         23275000
      RELSIR(LOGSIR,A);                                                 23280000
      GENTRY:=TRUE;                                                     23285000
      DB:=EXCHANGEDB(DB);                                               23290000
      INDEX':=NEWENTRY;                                                 23295000
   END                                                                  23300000
   ELSE                                                                 23305000
   BEGIN                                                                23310000
      <<Entry in LOGBUFF; TYPE = buffer dst>>                  <<01869>>23315000
      DB:=EXCHANGEDB(TYPE);                                             23320000
      IF LOGBUFF(RES3'OWNER) = MYPIN THEN                      <<01875>>23325000
               ALREADY'LOCKED := TRUE                          <<01875>>23330000
            ELSE                                               <<01875>>23335000
            BEGIN                                                       23340000
               ALREADY'LOCKED := FALSE;                        <<01875>>23345000
               OBTAIN(LOGBUFF(RESOURCE3),NULL);                <<01875>>23350000
$IF X1=ON                                                      <<01874>>23351000
      WHAT'S'UP ( BC'OBTAIN,3 );                               <<01874>>23353000
$IF                                                            <<01874>>23354000
            END;                                               <<01875>>23355000
      INDEX:=LOGBUFF(FHEAD);                                            23360000
      IF INDEX = NULL THEN                                              23365000
      BEGIN                                <<NO MORE ENTRIES>>          23370000
         IF NOT ALREADY'LOCKED THEN                            <<01869>>23375000
            BEGIN                                              <<01874>>23376000
            RELEASE(LOGBUFF(RESOURCE3),NULL,1);                <<01875>>23380000
$IF X1=ON                                                      <<01874>>23385000
      WHAT'S'UP ( BC'RELEASE,3 );                              <<01874>>23395000
$IF                                                            <<01874>>23400000
            END;                                               <<01874>>23401000
         DB:=EXCHANGEDB(DB);                                            23405000
         GENTRY:=FALSE;                                                 23410000
         RETURN;                                                        23415000
      END;                                                              23420000
      LOGBUFF(WSTATE):=ACT;  <<TO PREVENT WAKEUP>>                      23425000
$EDIT                                                          <<01876>>23430000
      NEWENTRY:=LOGBUFF(FHEAD);                                         23435000
                                                               <<01869>>23440000
      <<REMOVE FROM FREE LIST>>                                         23445000
      LOGBUFF(FHEAD):=LOGBUFF(NENTRY);                                  23450000
      INDEX:=LOGBUFF(FHEAD);                                   <<01876>>23455000
      IF INDEX <> NULL THEN                                    <<01876>>23456000
      LOGBUFF(PENTRY):=NULL;                                            23460000
                                                               <<01869>>23465000
      <<ADD TO INUSE LIST>>                                             23470000
      INDEX:= IF LOGBUFF(UHEAD) = NULL THEN                             23475000
      NEWENTRY ELSE LOGBUFF(UHEAD);                                     23480000
      LOGBUFF(PENTRY):= IF LOGBUFF(UHEAD)=NULL THEN                     23485000
      NULL ELSE NEWENTRY;                                               23490000
      INDEX:=NEWENTRY;                                                  23495000
      LOGBUFF(NENTRY):=LOGBUFF(UHEAD);                                  23500000
      LOGBUFF(UHEAD):=NEWENTRY;                                         23505000
      <<UPDATE GLOBL ENTRIES>>                                          23510000
                                                                        23515000
      LOGBUFF(NUMUSER):=LOGBUFF(NUMUSER)+1;                             23520000
      IF NOT ALREADY'LOCKED THEN                               <<01869>>23525000
         BEGIN                                                 <<01874>>23526000
         RELEASE(LOGBUFF(RESOURCE3),NULL,1);                   <<01875>>23530000
$IF X1=ON                                                      <<01874>>23535000
      WHAT'S'UP ( BC'RELEASE,3 );                              <<01874>>23545000
$IF                                                            <<01874>>23550000
         END;                                                  <<01874>>23551000
      DB:=EXCHANGEDB(DB);                                               23555000
      GENTRY:=TRUE;                                                     23560000
      INDEX':=NEWENTRY;                                                 23565000
   END;                                                                 23570000
   WRITEDSEG(LOGDST);                                                   23575000
END;                                                                    23580000
$PAGE "Table Access Utilities -- FINDLOG"                      <<01869>>23585000
LOGICAL PROCEDURE FINDLOG(LOGNAME,INDEX');                              23590000
INTEGER INDEX';                                                         23595000
BYTE ARRAY LOGNAME;                                                     23600000
OPTION PRIVILEGED,UNCALLABLE;                                           23605000
BEGIN                                                                   23610000
                                                                        23615000
                                                                        23620000
   <<THIS PROCEDURE FINDS THE ENTRY SPECIFIED BY LOGNAME IN THE  >>     23625000
   <<MASTER LOGGING DST.   THE INDEX INTO THE DST WHERE THE ENTRY>>     23630000
   <<RESIDES IS RETURNED IN THE INDEX PARAMETER.                 >>     23635000
   <<                                                            >>     23640000
   <<                                                            >>     23645000
   <<SPLIT STACK CALLS ARE NOT PERMITTED BY THIS PROCEDURE       >>     23650000
                                                                        23655000
                                                                        23660000
   LOGICAL A;                                                           23665000
   LOGICAL ARRAY ENTRY'(0:TENTRYSIZE-1) = Q;                   <<01869>>23670000
   BYTE ARRAY BENTRY'(*)=ENTRY';                                        23675000
   INTEGER TABINDEX,J,K;                                       <<01869>>23680000
                                                               <<01869>>23685000
                                                               <<01869>>23690000
   TABINDEX:=0;                                                         23695000
   FINDLOG:=TRUE;                                                       23700000
   A:=GETSIR(LOGSIR);                                                   23705000
   MOVE'FROM'DSEG(@ENTRY',LOGDST,INUSE,1);                     <<01869>>23710000
   IF ENTRY' = NULL THEN                                                23715000
   BEGIN                                                                23720000
      <<EMPTY DST>>                                                     23725000
      RELSIR(LOGSIR,A);                                                 23730000
      FINDLOG:=FALSE;                                                   23735000
      RETURN;                                                           23740000
   END;                                                                 23745000
   ENTRY'(NEXT):=ENTRY';                                                23750000
   MOVE LOGNAME:=LOGNAME WHILE AN,0;                                    23755000
   K:=TOS-@LOGNAME;                                                     23760000
   DO                                                                   23765000
   BEGIN                                                                23770000
      IF ENTRY'(NEXT) = NULL THEN                                       23775000
      BEGIN                                                             23780000
         FINDLOG:=FALSE;                                                23785000
         RELSIR(LOGSIR,A);                                              23790000
         RETURN;                                                        23795000
      END;                                                              23800000
      INDEX' := ENTRY'(NEXT);                                  <<01869>>23805000
      MOVE'FROM'DSEG(@ENTRY',LOGDST,ENTRY'(NEXT),TENTRYSIZE);  <<01869>>23810000
      IF BENTRY'(7) <> " " THEN J:=8                                    23815000
      ELSE                                                              23820000
      BEGIN                                                             23825000
         MOVE BENTRY':=BENTRY' WHILE AN,0;                              23830000
         J:=TOS-@BENTRY';                                               23835000
      END;                                                              23840000
   END                                                         <<01869>>23845000
  UNTIL  (BENTRY'=LOGNAME, (J)) AND (J=K);                     <<01869>>23850000
                                                               <<01869>>23855000
  IF ENTRY'(DST) = NULL AND (ENTRY'(STATUS) = ACT  LOR         <<01869>>23860000
                             ENTRY'(STATUS) = INACT)           <<01869>>23865000
    THEN FINDLOG := FALSE;                                     <<01869>>23870000
                                                               <<01869>>23875000
   RELSIR(LOGSIR,A);                                                    23880000
END;                                                                    23885000
$PAGE "INITLOG -- Log Process Initialization"                           23890000
LOGICAL PROCEDURE INITLOG(LOGNAME,TARGET);                              23895000
VALUE TARGET;                                                           23900000
INTEGER TARGET;                                                         23905000
BYTE ARRAY LOGNAME;                                                     23910000
OPTION PRIVILEGED,UNCALLABLE;                                           23915000
BEGIN                                                                   23920000
                                                                        23925000
COMMENT                                                        <<01869>>23930000
                                                               <<01869>>23935000
  Called from CXLOG (mod. 85) when need to start or restart a  <<01869>>23940000
  logging process. Will create the logging process (named      <<01869>>23945000
  LOGNAME) and have it adopted by PROGEN (this system process  <<01869>>23950000
  will run in the linear queue). TARGET is used to specify     <<01869>>23955000
  whether a start or restart was specified.                    <<01869>>23960000
  TARGET.(0:8) = 5  for Resstart                               <<01869>>23965000
  TARGET.(0:8) = 0  for Start                                  <<01869>>23970000
                                                               <<01869>>23975000
  NOTE:                                                        <<01869>>23980000
    DB must be at stack.                                       <<01869>>23985000
;                                                              <<01869>>23990000
                                                                        23995000
                                                                        24000000
                                                                        24005000
   INTEGER ULOGPIN:= 0,LOGPROC'STACK;                                   24010000
   LOGICAL A;                                                  <<01869>>24015000
   INTEGER I;                                                           24020000
   LOGICAL LID'TYPE;                                           <<01869>>24025000
   LOGICAL PRI;                                                         24030000
   BYTE ARRAY FNAME(0:36) = Q;                                 <<01869>>24035000
   BYTE POINTER BPS0 = S-0;                                    <<01869>>24040000
   LOGICAL ARRAY ENTRY'(0:TENTRYSIZE-1) = Q;                   <<01869>>24045000
   BYTE ARRAY BENTRY'(*)=ENTRY';                                        24050000
   INTEGER TABINDEX,INDEX;                                              24055000
   LOGICAL NOSTDIN:=0, NOSTDLIST:=0;     << FOR PROCREATE >>   <<01869>>24060000
   EQUATE NOSTRING=0, NOSTLEN=0;                               <<01869>>24065000
                                                               <<01869>>24070000
                                                               <<01869>>24075000
   TABINDEX:=0;                                                         24080000
   A := GETSIR(LOGSIR);                                        <<01869>>24085000
   IF NOT GENTRY(INDEX,0) THEN                                 <<01869>>24090000
      BEGIN  << couldn't get an entry in the log dst >>        <<01869>>24095000
      RELSIR(LOGSIR,A);                                        <<01869>>24100000
      INITLOG := FALSE;                                        <<01869>>24105000
      RETURN;                                                  <<01869>>24110000
      END    << couldn't get entry >>                          <<01869>>24115000
   ELSE                                                        <<01869>>24120000
   BEGIN                                       <<GOT A SPACE>>          24125000
      FNAME := " ";                                            <<01869>>24130000
      MOVE FNAME(1) := FNAME, (36);                            <<01869>>24135000
                                                               <<01869>>24140000
      MOVE'FROM'DSEG(@ENTRY',LOGDST,INDEX,TENTRYSIZE);         <<01869>>24145000
      MOVE BENTRY':=LOGNAME,(8);                                        24150000
      ENTRY'(NUMUSERS) := 0;                                   <<01869>>24155000
      FENTRY(BENTRY'(LGNAME),,FNAME,,,LID'TYPE);               <<01869>>24160000
      IF > THEN                                                         24165000
      BEGIN                                                             24170000
         RELENTRY(INDEX,0);                                             24175000
         RELSIR(LOGSIR,A);                                     <<01869>>24180000
         INITLOG:=FALSE;                                                24185000
         RETURN;                                                        24190000
      END;                                                              24195000
      ENTRY'(LGTYPE) := LID'TYPE.TYP'CURRENT;                  <<01869>>24200000
      ENTRY'(LGAUTO) := LID'TYPE.TYP'ALLOW'AUTO;               <<01869>>24205000
      MOVE BENTRY'(LFNAME) := FNAME WHILE AN, 0;               <<01869>>24210000
      IF BPS0 = "/" THEN                                       <<01869>>24215000
      BEGIN                                                    <<01869>>24220000
         @BPS0 := @BPS0 + 1;                                   <<01869>>24225000
         MOVE BENTRY'(LFLOCKW) := BPS0 WHILE AN, 0;            <<01869>>24230000
      END;                                                     <<01869>>24235000
      IF BPS0 = "." THEN                                       <<01869>>24240000
      BEGIN                                                    <<01869>>24245000
         @BPS0 := @BPS0 + 1;                                   <<01869>>24250000
         MOVE BENTRY'(LFGROUP) := BPS0 WHILE AN, 0;            <<01869>>24255000
         IF BPS0 = "."  THEN                                   <<01869>>24260000
         BEGIN                                                 <<01869>>24265000
            @BPS0 := @BPS0 + 1;                                <<01869>>24270000
            MOVE BENTRY'(LFACCT) := BPS0 WHILE AN;             <<01869>>24275000
         END;                                                  <<01869>>24280000
      END;                                                     <<01869>>24285000
                                                               <<01869>>24290000
      PRI:=[5/4,3/0,8/149];                                             24295000
      LOGPROC'STACK:=GETSTACK(INITSTACK,MAXSTACK);                      24300000
      TOS:=@ULOGPIN;                                                    24305000
      IF LOGPROC'STACK <> 0 THEN                                        24310000
      BEGIN                                                             24315000
         IF TARGET.(0:8) = RESTRT THEN                                  24320000
         TOS := A'(ULOGRSTARTPLABEL)                           <<01869>>24325000
         ELSE TOS:=A'(ULOGPLABEL);                                      24330000
         << Zero out the STT entry of the external P-label >>  <<01869>>24335000
         << Procreate only needs the code segment number.  >>  <<01869>>24340000
                                                               <<01869>>24345000
         TOS.(0:8):=0;                                                  24350000
         TOS.(0:1):=1;                                                  24355000
                                                               <<01869>>24360000
         << Also need the Delta P-label  -  offset within the>><<01869>>24365000
         << code segment where the procedure begins.         >><<01869>>24370000
                                                               <<01869>>24375000
         IF TARGET.(0:8) = RESTRT                              <<01869>>24380000
          THEN TOS:=A'(ULOGRSTARTDELTAP)                       <<01869>>24385000
         ELSE TOS:=A'(ULOGDELTAP);                                      24390000
         PROCREATE(*,*,*,LOGPROC'STACK,GLOBSIZE,0,LOCSIZE,PRI, <<01869>>24395000
                   NOSTRING,NOSTLEN,INDEX,%13,MAXSTACK,        <<01869>>24400000
                   NOSTDIN,NOSTDLIST);                         <<01869>>24405000
         IF = THEN                                                      24410000
         BEGIN                                                          24415000
            <<Make process a system process (son of PROGEN)>>  <<01869>>24420000
            ADOPT(ULOGPIN,3);                        <<00601>> <<01869>>24425000
            EXCHANGEDB(LOGPROC'STACK);                                  24430000
            PDB(0):=0;                                                  24435000
            I:=0;                                                       24440000
            DO BEGIN PDB(I+1):=PDB(I) END UNTIL (I:=I+1) >=255;         24445000
                                                               <<01869>>24450000
            << Set up the stack.  >>                           <<01869>>24455000
                                                               <<01869>>24460000
            << First primary DB >>                             <<01869>>24465000
                                                               <<01869>>24470000
            PDB(0) := %16;      << Byte addr for ZEROS       >><<01869>>24475000
            PDB(1) := %22;      << Byte addr for FORMS       >><<01869>>24480000
            PDB(2) := %34;      << Byte addr for FNAME       >><<01869>>24485000
            PDB(3) := %102;    << Byte addr for BFNAME       >><<01869>>24490000
            PDB(4) := %150;    << Byte addr for PRCNAME      >><<01869>>24495000
            PDB(5) := %71;     << Word addr for BUFFAREA     >><<01869>>24500000
            PDB(6) := %10071;  << Word addr for DISCREC      >><<01869>>24505000
                                                               <<01869>>24510000
            << Now set up secondary DB >>                      <<01869>>24515000
                                                               <<01869>>24520000
            PDB(7) := "00";     << Initialize the ZEROS      >><<01869>>24525000
            PDB(8) := "00";     <<     array for later use   >><<01869>>24530000
            EXCHANGEDB(0);                                              24535000
         END                                                            24540000
         ELSE                                                           24545000
         BEGIN                                                          24550000
            RELENTRY(INDEX,0);                                          24555000
            RELSIR(LOGSIR,A);                                  <<01869>>24560000
            INITLOG:=FALSE;                                             24565000
            RETURN;                                                     24570000
         END;                                                           24575000
         <<NOW ADD ENTRY TO LOGGING TABLE>>                             24580000
                                                               <<01869>>24585000
                                                               <<01869>>24590000
         MOVE BENTRY'(BNAME):="ULOG    ";                      <<01869>>24595000
                                                               <<01869>>24600000
         ENTRY'(PIN) := ULOGPIN * PCBSIZE;                     <<01869>>24605000
         ENTRY'(STATUS) := INITIALIZING;                       <<01869>>24610000
         ENTRY'(LGSWITCH) := FALSE;                            <<01869>>24615000
         ENTRY'(LGNEWTYPE) := NULL;                            <<01869>>24620000
                                                               <<01869>>24625000
         ENTRY'(LGNEWAUTO) := FALSE;                           <<01869>>24630000
         MOVE'TO'DSEG(LOGDST,INDEX,@ENTRY',TENTRYSIZE-2);      <<01869>>24635000
         WRITEDSEG(LOGDST);                                             24640000
         AWAKE(ULOGPIN*PCBSIZE,%1,0);                                   24645000
$IF X1=ON                                                      <<01874>>24650000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>24660000
$IF                                                            <<01874>>24665000
         RELSIR(LOGSIR,A);                                     <<01869>>24670000
         INITLOG:=TRUE;                                                 24675000
         RETURN;                                               <<01869>>24680000
      END                                                               24685000
      ELSE                                                              24690000
      BEGIN                                                             24695000
         RELSIR(LOGSIR,A);                                     <<01869>>24700000
         INITLOG:=FALSE;                                                24705000
         RETURN;                                                        24710000
      END;                                                              24715000
   END;                                                                 24720000
END;                                                                    24725000
$PAGE "Stop all logging processes on =SHUTDOWN, =LOGOFF"       <<01869>>24730000
PROCEDURE STOP'ALL'USERLOGS;                                   <<01869>>24735000
   OPTION PRIVILEGED,UNCALLABLE;                               <<01869>>24740000
                                                               <<01869>>24745000
BEGIN                                                          <<01869>>24750000
                                                               <<01869>>24755000
<< Called by PROGEN when performing a =SHUTDOWN or =LOGOFF.  >><<01869>>24760000
<< At this time we need to make sure all user logging        >><<01869>>24765000
<< processes will end gracefully.                            >><<01869>>24770000
<<                                                           >><<01869>>24775000
                                                               <<01869>>24780000
INTEGER                                                        <<01869>>24785000
   STACK,           << Stack upon entry/exit       >>          <<01869>>24790000
   TABINDEX;        << Pointer to LOGTAB entries   >>          <<01869>>24795000
                                                               <<01869>>24800000
                                                               <<01869>>24805000
                                                               <<01869>>24810000
STACK := EXCHANGEDB(LOGDST);                                   <<01869>>24815000
TABINDEX := LOGTAB(INUSE);   << First entry in table.        >><<01869>>24820000
                                                               <<01869>>24825000
<< Now cycle thru the table stopping the processes.          >><<01869>>24830000
                                                               <<01869>>24835000
WHILE (TABINDEX <> NULL)  AND  (TABINDEX <> "  ")  DO          <<01869>>24840000
BEGIN        << Found an active one >>                         <<01869>>24845000
                                                               <<01869>>24850000
   << If the process is recovering or initializing, we do not>><<01869>>24855000
   << want to disturb it. Instead we'll wait.                >><<01869>>24860000
                                                               <<01869>>24865000
   IF LOGTAB(STATUS) = ACT  OR  LOGTAB(STATUS) = INACT  THEN   <<01869>>24870000
   BEGIN                                                       <<01869>>24875000
      IF LOGTAB(DST) <> NULL THEN                              <<01869>>24880000
      BEGIN                                                    <<01869>>24885000
         << Found a live process to stop. >>                   <<01869>>24890000
                                                               <<01869>>24895000
         EXCHANGEDB(LOGTAB(DST));                              <<01869>>24900000
         LOGBUFF(NUMUSER) := 0;                                <<01869>>24905000
         LOGBUFF(MSG) := STOP;                                 <<01869>>24910000
         AWAKE(LOGBUFF(LOGPIN),%20,0);                         <<01869>>24915000
$IF X1=ON                                                               24915500
         WHAT'S'UP ( BC'AWAKE );                                        24915600
$IF                                                                     24915700
         EXCHANGEDB(LOGDST);                                   <<01869>>24920000
      END;                                                     <<01869>>24925000
   END;                                                        <<01869>>24930000
                                                               <<01869>>24935000
   DELAY(2000D);                                               <<01869>>24940000
   TABINDEX := LOGTAB(INUSE);   << Back to the top          >> <<01869>>24945000
END;         << Found an active process  >>                    <<01869>>24950000
                                                               <<01869>>24955000
EXCHANGEDB(STACK);                                             <<01869>>24960000
                                                               <<01869>>24965000
END;         << Stop'all'userlogs >>                           <<01869>>24970000
$PAGE  "STOPLOG -- stops individual log processes"             <<01869>>24975000
LOGICAL PROCEDURE STOPLOG(LOGNAME);                                     24980000
BYTE ARRAY LOGNAME;                                                     24985000
                                                                        24990000
OPTION PRIVILEGED,UNCALLABLE;                                           24995000
                                                                        25000000
                                                                        25005000
   <<THIS PROCEDURE STOPS USER LOGGING PROCESSES>>                      25010000
                                                                        25015000
                                                                        25020000
                                                                        25025000
BEGIN                                                                   25030000
   LOGICAL ARRAY ENTRY'(0:TENTRYSIZE-1) = Q;                   <<01869>>25035000
   INTEGER TABINDEX,ORIG'DB;                                   <<01869>>25040000
   LOGICAL A;                                                  <<01869>>25045000
                                                               <<01869>>25050000
                                                               <<01869>>25055000
   A := GETSIR(LOGSIR);                                        <<01869>>25060000
   IF FINDLOG(LOGNAME,TABINDEX) THEN                                    25065000
   BEGIN                                                                25070000
      MOVE'FROM'DSEG(@ENTRY',LOGDST,TABINDEX,TENTRYSIZE);      <<01869>>25075000
                                                               <<01869>>25080000
      TABINDEX:=0;                                                      25085000
      IF (ENTRY'(STATUS)=RECOVERING) OR (ENTRY'(STATUS)=STOP)  <<01869>>25090000
         OR (ENTRY'(STATUS)=INITIALIZING)  THEN                <<01869>>25095000
      BEGIN                                                    <<01869>>25100000
         STOPLOG:=FALSE;                                       <<01869>>25105000
         RELSIR(LOGSIR,A);                                     <<01869>>25110000
         RETURN;                                               <<01869>>25115000
      END;                                                     <<01869>>25120000
      ORIG'DB:=EXCHANGEDB(ENTRY'(DST));    << to LOGBUFF >>    <<01869>>25125000
                                                               <<01869>>25130000
      << Need to tell the process to stop. The process will  >><<01869>>25135000
      << stop as soon as the user count goes to zero.        >><<01869>>25140000
                                                               <<01869>>25145000
      OBTAIN(LOGBUFF(RESOURCE2),NULL);                         <<01875>>25150000
$IF X1=ON                                                      <<01874>>25151000
      WHAT'S'UP ( BC'OBTAIN,2 );                               <<01874>>25153000
$IF                                                            <<01874>>25154000
      LOGBUFF(MSG):= STOP;                                              25155000
      RELEASE(LOGBUFF(RESOURCE2),NULL,1);                      <<01875>>25160000
$IF X1=ON                                                      <<01874>>25165000
      WHAT'S'UP ( BC'RELEASE,2 );                              <<01874>>25175000
$IF                                                            <<01874>>25180000
                                                               <<01869>>25185000
      AWAKE(LOGBUFF(LOGPIN),%20,0);                                     25190000
$IF X1=ON                                                      <<01874>>25195000
      WHAT'S'UP ( BC'AWAKE );                                  <<01874>>25205000
$IF                                                            <<01874>>25210000
      STOPLOG:=TRUE;                                                    25215000
      EXCHANGEDB(ORIG'DB);                                              25220000
      RELSIR(LOGSIR,A);                                        <<01869>>25225000
      RETURN;                                                           25230000
   END                                                                  25235000
   ELSE                                                                 25240000
   BEGIN                                                                25245000
      RELSIR(LOGSIR,A);                                        <<01869>>25250000
      STOPLOG:=FALSE;                                                   25255000
      RETURN;                                                           25260000
   END;                                                                 25265000
END;                                                                    25270000
$PAGE  "DEL'LOCKWORRD"                                         <<01869>>25275000
PROCEDURE DEL'LOCKWORD(FILENAME);                              <<01869>>25280000
   BYTE ARRAY FILENAME;                                        <<01869>>25285000
   OPTION UNCALLABLE,PRIVILEGED;                               <<01869>>25290000
                                                               <<01869>>25295000
BEGIN                                                          <<01869>>25300000
                                                               <<01869>>25305000
<< DB must be at stack. >>                                              25310000
BYTE POINTER                                                   <<01869>>25315000
   BPS0   = S-0,                                               <<01869>>25320000
   PT,                 <<                                >>    <<01869>>25325000
   PT1,                << Ptr to "/lockword"             >>    <<01869>>25330000
   PT2;                << Ptr to ".group"                >>    <<01869>>25335000
                                                               <<01869>>25340000
INTEGER                                                        <<01869>>25345000
   LOCK'LEN;                                                   <<01869>>25350000
                                                               <<01869>>25355000
MOVE FILENAME := FILENAME WHILE AN, 1;                         <<01869>>25360000
IF BPS0 = "/" THEN                                             <<01869>>25365000
   BEGIN         << Found a lockword to delete >>              <<01869>>25370000
   @PT1 := @BPS0;      << Save address of "/"  >>              <<01869>>25375000
   @PT := @BPS0 + 1;                                           <<01869>>25380000
   MOVE PT := PT WHILE AN, 1;                                  <<01869>>25385000
   @PT2 := TOS;        << Save address of "."  >>              <<01869>>25390000
   LOCK'LEN := @PT2 - @PT1;   << Length of lockword >>         <<01869>>25395000
   MOVE PT1 := PT2, (36 - (@PT2 - @FILENAME)), 2;              <<01869>>25400000
   @PT := TOS;                                                 <<01869>>25405000
   PT := " ";                                                  <<01869>>25410000
   MOVE PT(1) := PT, (LOCK'LEN-1), 2;                          <<01869>>25415000
   MOVE * := 0;      << Terminator for GENMSG >>               <<01869>>25420000
   END;                                                        <<01869>>25425000
                                                               <<01869>>25430000
DEL;                                                           <<01869>>25435000
END;      << Procedure DEL'LOCKWORD >>                         <<01869>>25440000
$PAGE  "Utilities"                                             <<01869>>25445000
PROCEDURE MOVE'FROM'DSEG(TARGET,SEGMENT,OFFSET,COUNT);         <<01869>>25450000
   VALUE TARGET,SEGMENT,OFFSET,COUNT;                          <<01869>>25455000
   INTEGER TARGET,SEGMENT,OFFSET,COUNT;                        <<01869>>25460000
   OPTION PRIVILEGED,UNCALLABLE,INTERNAL;                      <<01869>>25465000
                                                               <<01869>>25470000
                                                               <<01869>>25475000
                                                               <<01869>>25480000
                                                               <<01869>>25485000
BEGIN                                                          <<01869>>25490000
                                                               <<01869>>25495000
   TOS := TARGET;                                              <<01869>>25500000
   TOS := SEGMENT;                                             <<01869>>25505000
   TOS := OFFSET;                                              <<01869>>25510000
   TOS := COUNT;                                               <<01869>>25515000
   ASSEMBLE (MFDS 4);                                          <<01869>>25520000
                                                               <<01869>>25525000
                                                               <<01869>>25530000
                                                               <<01869>>25535000
END;                                                           <<01869>>25540000
                                                               <<01869>>25545000
                                                               <<01869>>25550000
                                                               <<01869>>25555000
PROCEDURE MOVE'TO'DSEG(SEGMENT,OFFSET,SOURCE,COUNT);           <<01869>>25560000
   VALUE SEGMENT,OFFSET,SOURCE,COUNT;                          <<01869>>25565000
   INTEGER SEGMENT,OFFSET,SOURCE,COUNT;                        <<01869>>25570000
   OPTION PRIVILEGED,UNCALLABLE,INTERNAL;                      <<01869>>25575000
                                                               <<01869>>25580000
                                                               <<01869>>25585000
                                                               <<01869>>25590000
BEGIN                                                          <<01869>>25595000
                                                               <<01869>>25600000
   TOS := SEGMENT;                                             <<01869>>25605000
   TOS := OFFSET;                                              <<01869>>25610000
   TOS := SOURCE;                                              <<01869>>25615000
   TOS := COUNT;                                               <<01869>>25620000
   ASSEMBLE (MTDS 4);                                          <<01869>>25625000
                                                               <<01869>>25630000
                                                               <<01869>>25635000
END;                                                           <<01869>>25640000
                                                               <<01869>>25645000
                                                               <<01869>>25650000
                                                               <<01869>>25655000
$CONTROL SEGMENT=MAIN                                          <<01869>>25660000
END.                                                           <<01869>>25665000
