// file.sr get "BFS.DEF"; get "BRAVO1.DF"; get "CHAR.DF"; get "ALTOFILESYS.D"; get "VM.DF"; get "ST.DF"; get "DIR.DF"; get "COM.DF"; get "RN1.DF"; // Incoming Procedures external [ InitNmd move stappend FindFptr SetVab VerNext SetRegionW stcopy ReName stsize hpalloca AppendVer RealDA movec setmacfp readformattedfile ActOnPages errhlta sbwsize CreateFile gets puts flushfn trims inheap hpfree doDc ReadCalendar ckdoc remakevmtb stcompare ]; // Incoming Statics external [ diskKd cfaSysDirEnd mpfnof vrlwsys fillInDA macfda DCread dnbp vfloppy rgmpbifc rgmpbifb vkcb DCwrite macbp rgvpa rglastused fpSysLog vfIniting ]; // Outgoing Procedures external [ FtyOpen; opens; fnalloc; closes; deallocfn; fCkFilePtr; LeaderPage; // BrMakeLogEntry updateofs; BravoCreateFile; TryOpenLog; ]; // Outgoing Statics external [ mpfnsb; vpos; vdeltafp; vformattedfile; rgcfn; macfn; vnewfile vFNoLog defaultVersionsKept ]; // Local Statics static [ mpfnsb; vpos; vdeltafp; vformattedfile; rgcfn; macfn; vnewfile vFNoLog defaultVersionsKept ]; structure KLABEL: [ next word previous word blank word numchars word pgn word version word sn word 2 ] manifest [ lnklabel = (size KLABEL)/16 DcCkHeaderCkLabelRdData = #44120; ] manifest [ cvmneeded = 2; ] // O P E N // catalogue no. = 124 let FtyOpen(fn, sb, wf, wmode, vc, fptrHint, fOflowOk, vecNmd, vecNmdDollar; numargs na) = valof [ switchon na into [ case 3: wmode = false case 4: vc = vcNewest; case 5: fptrHint = 0; case 6: fOflowOk = false; ] let fty = ftyOld; let tstream = nil; let tchar = nil; let fCreatedFile = false let nverKept = defaultVersionsKept let nmd = vec lnmdMax; if (na gr 7) then nmd = vecNmd let nmdDollar = vec lnmdMax; if (na gr 8) then nmdDollar = vecNmdDollar let nmdNeed = nmd InitNmd(nmd,lnmdMax,sb,vc) updateofs() unless mpfnof ! fndir eq ofNil then deallocfn(fndir); if vc eq vcNew then [ if (nverKept eq 0) then [ move(nmd,nmdDollar,lnmdMax) let tsbFile = lv nmdDollar >> NMD.asbFile tsbFile >> SB.cch = tsbFile >> SB.cch-1 stappend(tsbFile,"$.") nmd >> NMD.next = nmdDollar unless FnInBravo(nmdDollar) ne fnnil then nmdNeed = nmdDollar ] ] test (fptrHint ne 0) & fCkFilePtr(fptrHint) ifso move(fptrHint,lv nmdNeed >> NMD.afptr,lFP) ifnot [ let mpPgnDa = vec #100; FindFptr(cfaSysDirEnd,lv nmd,mpPgnDa,#100) let fCreateFile = valof [ if vc eq vcNewestOrNew then resultis (nmdNeed >> NMD.cver eq 0) unless vc eq vcNew then resultis false if nmd >> NMD.cver eq 0 then nmdNeed = nmd; if FnInBravo(nmdNeed) ne fnnil then [ test (nverKept eq 0) % (nmdNeed >> NMD.vc eq vcExact) ifso [ // "Can't write on that file - Command terminated" SetVab(abmsg, false, 43, 50) // I want to return from open, not valof - so I kludge nmdNeed >> NMD.cver = 0 resultis false ] ifnot resultis true ] if nmdNeed >> NMD.cver eq 0 then resultis true // for either old or new system if nmdNeed >> NMD.vc eq vcExact then [ fty = ftyOverwrite resultis false ] if nmdNeed >> NMD.cver ls nverKept then resultis true unless nmdNeed eq nmdDollar then fty = ftyNewOnOld resultis false ] test fCreateFile ifnot if nmdNeed >> NMD.cver eq 0 then [ // "File foo not found - Command terminated" unless vfIniting then [ SetRegionW(vrlwsys, 0, sb) let rid = nil rid<> CFA.fa.pageNumber opens(fndir,lv cfaSysDirEnd >> CFA.fp,true,true,false,false,pgnMac+2) let ofDir = mpfnof ! fndir; move(mpPgnDa,lv ofDir >> OF.rgda,pgnMac+1) ofDir >> OF.macpos = ((pgnMac-1) lshift 9)+cfaSysDirEnd >> CFA.fa.charPos ] unless nmdNeed >> NMD.vc eq vcExact then nmdNeed >> NMD.ver = VerNext(nmdNeed) BravoCreateFile(nmdNeed,true) fCreatedFile = true; fty = (nverKept eq 0) ? ftyNewFile,ftyNewVer ] // BrMakeLogEntry(lv nmdNeed>>NMD.afptr,fCreatedFile ? typLogCreateFile,typLogOpenFile) if vc eq vcNew then test nmdNeed eq nmdDollar ifso [ fty = ftyNewOnDollar let tsbFile = vec 30; stcopy(tsbFile,lv nmdDollar >> NMD.asbFile) ReName(nmdDollar,lv nmd >> NMD.asbFile,0) ReName(nmd,tsbFile,0) ] ifnot if fty eq ftyNewOnOld then ReName(nmd,lv nmd >> NMD.asbFile,VerNext(nmd)) ] unless opens(fn, lv nmdNeed>>NMD.afptr, wf, wmode, fCreatedFile, fOflowOk) do [ // "File too long - Command terminated" SetVab(abmsg, false, 44, 50) resultis ftyNil; ] let siz = (stsize(sb)+8) rshift 1; mpfnsb ! fn = hpalloca(siz); (mpfnsb ! fn) ! 0 = 0; stcopy(mpfnsb ! fn,lv nmdNeed >> NMD.asbFile); AppendVer(mpfnsb ! fn,nmdNeed >> NMD.ver) resultis fty; ] and opens(fn,fptr,wf,wmode,fCreatedFile,fOflowOk,macfp; numargs na) = valof [ switchon na into [ case 4: fCreatedFile = false case 5: fOflowOk = false; case 6: macfp = 40 ] let tof = hpalloca(ofsiz+400); tof >> OF.version = fptr >> FP.version; move(lv fptr >> FP.serialNumber,lv tof >> OF.sn1,lSN) tof >> OF.wf = wf; tof >> OF.wmode = wmode; tof >> OF.rgda = RealDA(fptr >> FP.leaderVirtualDa); tof >> OF.pos = 0; tof >> OF.macfp = 400; tof >> OF.bphint = 1; tof >> OF.fFullPages = false; let rgda = lv (tof >> OF.rgda); let lastpage = nil; let numcharslast = nil; let numcharsfullpages = nil; movec(rgda+1,rgda+400,fillInDA); tof >> OF.formatted = (vformattedfile & not wmode); tof >> OF.macbi = 0; tof >> OF.fda = macfda mpfnof ! fn = tof; test wf ifnot [ test tof >> OF.formatted ifnot lastpage = ActOnPages(0,rgda,lv(tof >> OF.fileid),0,400,DCread,lv numcharslast,0,dnbp ! bpbuff,0) ifso lastpage = readformattedfile(fn,lv numcharslast); if (lastpage gr #200) & (fOflowOk eq false) then [ deallocfn(fn) resultis false; ] test lastpage ifso numcharsfullpages = (lastpage-1) lshift 9 ifnot numcharsfullpages = 0; (mpfnof ! fn) >> OF.macpos = numcharsfullpages+numcharslast; setmacfp(fn,lastpage+1); ] ifso [ tof >> OF.macpos = 0; setmacfp(fn,macfp); ] LeaderPage(fptr, 0, wf eq 0) macfda = macfda+(mpfnof ! fn) >> OF.macfp if vfloppy & (macfda << FDA.track gr 77) then errhlta(185) resultis true; ] // C R E A T E // // and Create(fn,sb,wf,wmode, fptrHint; numargs n) = valof // [ if n ls 5 then fptrHint = 0 // vnewfile = false; // // whats the deal on these 2 results? // unless open(fn,sb,wf,wmode,vcNew,fptrHint) then resultis false // resultis vnewfile; // ] // B R A V O C R E A T E F I L E // and BravoCreateFile(nmd,fcreateOnDisk) be [ let tsbFile = vec 30; movec(tsbFile,tsbFile+29,0) stcopy(tsbFile,lv nmd >> NMD.asbFile) AppendVer(tsbFile,nmd >>NMD.ver) if mpfnof ! fndir eq ofNil then errhlta(186) let posMac = (mpfnof ! fndir) >> OF.macpos let cwDe = (offset DE.asbFile)/16+sbwsize(tsbFile); // let cwDe = nmd >> NMD.ldeFree; let t = nmd >> NMD.waDeFree let posHole = (t eq -1) ? posMac,t lshift 1 let b = dnbp!0 test fcreateOnDisk ifso CreateFile(tsbFile,lv nmd >> NMD.afptr,b) ifnot [ let posOld = nmd >> NMD.waDe lshift 1 (mpfnof ! fndir) >> OF.pos = posOld; let t = gets(fndir); t << DE.ty = tyDeFree (mpfnof ! fndir) >> OF.pos = posOld; puts(fndir,t); ] let cwHole = 0; if posHole ne posMac then [ let tpos = posHole [ (mpfnof ! fndir) >> OF.pos = tpos; let t = gets(fndir); if t << DE.ty ne tyDeFree then errhlta(187) cwHole = cwHole+t << DE.l; tpos = tpos+((t << DE.l) lshift 1); ] repeatwhile (cwHole ls cwDe) ] nmd >> NMD.waDeFree = posHole rshift 1; (mpfnof ! fndir) >> OF.pos = posHole; let t = nil; t << DE.l = cwDe; t << DE.ty = tyDeFile puts(fndir,t) let tp = lv nmd >> NMD.afptr for i = 0 to lFP-1 do puts(fndir,tp ! i); for i = lFP to cwDe-2 do puts(fndir,tsbFile ! (i-lFP)); if cwDe ls cwHole then [ // (mpfnof ! fndir) >> OF.pos = posHole; puts(fndir,cwHole-cwDe); // posHole = posHole+((cwHole-cwDe) lshift 1); ] nmd >> NMD.waDe = nmd >> NMD.waDeFree flushfn(fndir); ] // F N A L L O C // catalogue no. = 128 and fnalloc( ) = valof [ for fn = minuserfn to maxfn-1 do if mpfnof ! fn eq -1 then resultis fn; resultis -1; ] // C L O S E S // and closes(fn) be [ if (mpfnof ! fn) >> OF.wf then [ flushfn(fn); trims(fn); (mpfnof ! fn) >> OF.wf = false; ] ] // D E A L L O C F N // and deallocfn(fn) be [ if inheap(mpfnof ! fn) then hpfree(mpfnof ! fn); if inheap(mpfnsb ! fn) then hpfree(mpfnsb ! fn); mpfnsb ! fn = 0; mpfnof ! fn = -1; unless rgmpbifc ! fn eq 0 then [ hpfree(rgmpbifc ! fn); rgmpbifc ! fn = 0; ] unless rgmpbifb ! fn eq 0 then [ hpfree(rgmpbifb ! fn); rgmpbifb ! fn = 0; ] ] // F C K F I L E P T R // and fCkFilePtr(filePtr) = valof [ let klabel = vec lnklabel; for i = 1 to 5 do [ movec(klabel,klabel+lnklabel-1,0); move((lv (filePtr>>FP.serialNumber)),(lv (klabel>>KLABEL.sn)),2) // klabel>>KLABEL.pgn = 0; ** done by movec ! klabel>>KLABEL.version = filePtr>>FP.version doDc(RealDA(filePtr>>FP.leaderVirtualDa), DcCkHeaderCkLabelRdData, klabel); while (rv nextDiskCommand) ne 0 do loop if (vkcb>>KCB.status & DSgoodStatusMask) eq DSgoodStatus then resultis true ] resultis false; ] // L E A D E R P A G E // and LeaderPage(fptr, nmd, fRead; numargs n) be // ** [ switchon n into [ case 1: nmd = 0; case 2: fRead = false ] let b = vec (chperpage/2); let mpPgnDa = vec 2; mpPgnDa ! 0 = RealDA(fptr >> FP.leaderVirtualDa) let fileid = vec 3; fileid ! 0 = fptr >> FP.version move(lv fptr >> FP.serialNumber,fileid+1,lSN) ActOnPages(0, mpPgnDa, fileid, 0, 0, DCread, 0, 0, b, 0) unless nmd eq 0 then [ let sbFile = lv nmd >> NMD.asbFile move(sbFile, lv b>>LD.name, sbwsize(sbFile)) AppendVer(lv b>>LD.name,nmd >> NMD.ver) ] let todCur = vec lntod ReadCalendar(todCur) test fRead ifso move(todCur,lv b>>LD.read,lntod) ifnot [ move(todCur,lv b>>LD.written,lntod) move(todCur,lv b>>LD.created,lntod) ] ActOnPages(0, mpPgnDa, fileid, 0, 0, DCwrite, 0, 0, b, 0) ] // Make log entries -- but not references to system files. // and BrMakeLogEntry(fptr,logType,fptrNew; numargs na) be // [ // TryOpenLog() // if vFNoLog then return // let sn = lv fptr >> FP.serialNumber // unless (sn>>SN.nolog eq 0) then return // // let ofLog = mpfnof ! fnLog // ofLog>>OF.pos = ofLog>>OF.macpos // let a=vec lLOGV+lFP // movec(a,a+lLOGV-1,0) // let fp = lv a>>LOGV.fp // move(fptr,fp,lFP) // ReadCalendar(lv a>>LOGV.time) // a>>LOGV.type=logType // let ln = lLOGV // if logType eq typLogRenameFile then // [ unless na eq 3 then errhlta(188); // move(fptrNew,a+lLOGV,lFP) // ln = ln+lFP // ] // a>>LOGV.length=ln // for i = 0 to a>>LOGV.length-1 do // puts(fnLog,a ! i) // flushfn(fnLog) // ] // U P D A T E O F S // and updateofs( ) be [ ckdoc( ); for fn = minuserfn to maxfn-1 do [ if fnscr eq fn then errhlta(189); if (rgcfn ! fn eq 0) & (mpfnof ! fn ne -1) & not (mpfnof ! fn) >> OF.wf & not (mpfnof ! fn) >> OF.wmode do deallocfn(fn); ] for bp = 0 to macbp-1 do if mpfnof ! ((rgvpa+bp) >> VPA.fn) eq -1 then [ rgvpa ! bp = -1; rglastused ! bp = 1; ] remakevmtb( ); ] // F I N B R A VO // and FnInBravo(nmd) = valof [ let sbFile = vec 30 stcopy(sbFile,lv nmd >> NMD.asbFile) AppendVer(sbFile,nmd >> NMD.ver) for fn = minuserfn to maxfn-1 do if mpfnof ! fn ne -1 do if stcompare(sbFile,mpfnsb ! fn) eq 0 then resultis fn resultis fnnil ] // T R Y O P E N L O G // // and TryOpenLog() be // [ if vFNoLog then return // if mpfnof ! fnLog eq ofNil then // [ vFNoLog = true // (mpfnof ! fndir) >> OF.wf = true; // if FtyOpen(fnLog,"SYS.LOG",false,true,vcNewest,fpSysLog) eq ftyNil then // return // (mpfnof ! fnLog) >> OF.wf = true; // vFNoLog = false // ] // ]