$SYSPROG$

module filepack;

import sysglobals, misc, fs, asm;

export
 
 type 
     volumearray = array[1..50] of string[25];

 procedure volumes  (var v: volumearray);
 procedure filecopy (filename1, filename2: fid; format, writeover: boolean);
 procedure duplicate(filename1, filename2: fid; purgeold: boolean);
 procedure change   (filename1, filename2: fid);
 procedure repack   (filename: fid);
 procedure createdir(filename: fid; newname: vid; entries, bytes: integer);
 procedure makefile (filename: fid);
 procedure makedir  (filename: fid);
 procedure remove   (filename: fid);
 procedure prefix   (filename: fid; unitonly, sysvol: boolean);
 procedure startcat (filename: fid;
        var dirname: vid;
        var typeinfo : string;
        var createdate, changedate: daterec;
        var createtime, changetime: timerec;
        var blocksize, phy_size, start_byte, free_bytes, max_files: integer);
 procedure cat(filenumber: integer;
        var filename: tid;
        var typeinfo: string;
        var createdate, changedate: daterec;
        var createtime, changetime: timerec;
        var kind: filekind;
        var eft: shortint;
        var blocksize, logical_size, phy_size, start_byte,
            extension1, extension2: integer);
 procedure endcat;
 procedure startlistpass(filename: fid);
 procedure listattribute(wordnumber: integer; var outstring: string);
 procedure listpassword (wordnumber: integer; var outstring: string);
 procedure changepassword(word: passtype; attrlist: string255);
 procedure endpass;
 function  ioerrmsg(var msg: string):boolean;
 
implement
 
 const
     catlimit  = 200;
 
 type
     buftype   = packed array[0..maxint] of char;
     bigptr    = ^buftype;
     closecode = (keepit, purgeit);
     catarray  = array[0..catlimit] of catentry;
     passarray = array[0..catlimit] of passentry;
     passarayptr = ^passarray;
     
 var
     catfib, passfib: ^fib;
     catentptr      : ^catarray;
     wordlist, optionlist: passarayptr;
     
 {function memavail $alias 'asm_memavail'$ : integer; external;}
 
 function min(a, b: integer): integer;
 begin
  if a<b then
   min := a
  else
   min := b
 end; { min }
 
 function ioerrmsg(var msg: string): boolean;
 begin
  if ioresult=ord(inoerror) then
   ioerrmsg := false
  else
   begin
    ioerrmsg := true;
    getioerrmsg(msg, ioresult);
   end;
 end; { ioerrmsg }
  
 procedure iocheck;
 begin
  if ioresult <> ord(inoerror) then
   escape(-10);
 end; { iocheck }
 
 procedure badio(iocode: iorsltwd);
 begin
  ioresult := ord(iocode);
  escape(-10);
 end; { badio }
 
 function unitnumber(var fvid: vid): boolean;
 var scanning: boolean;
     i: shortint;
 begin
  unitnumber := false;
  zapspaces(fvid);
  if strlen(fvid) > 1 then
   if fvid[1] = '#' then
    begin
     scanning := true;
     i := 2;
     repeat
      if (fvid[i]>='0') and (fvid[i]<='9') then
       i := i + 1
      else
       scanning := false;
     until (i>strlen(fvid)) or not scanning;
     unitnumber := scanning;
    end;
 end; { unitnumber }
 
 function samedevice(unit1, unit2: unitnum): boolean;
 var u: ^unitentry;
 begin
  u := addr(unitable^[unit1]);
  with unitable^[unit2] do
   samedevice := (u^.sc = sc) and (u^.ba = ba) and
                 (u^.du = du) and (u^.dv = dv) and
                 (u^.letter = letter) and
                 (u^.byteoffset = byteoffset);
 end; { samedevice }
 
 procedure anytomem(ffib: fibp; anyvar buffer: bigptr; maxbuf: integer);
 var bufrec   : ^string255;
     bufptr   : ^char;
     leftinbuf: integer;
 begin { anytomem }
  bufptr    := addr(buffer^);
  bufptr^   := chr(0);   { data coming }
  bufrec    := addr(bufptr^,1);
  setstrlen(bufrec^, 0);  { zero length record }
  bufptr    := addr(bufrec^, 1);
  leftinbuf := maxbuf;
  
  with ffib^, unitable^[funit] do
   begin
    call(am, ffib, readtoeol, bufrec^, 255, fpos);
    repeat
     iocheck;  { check result form last readtoeol }
     bufptr    := addr(bufptr^, strlen(bufrec^));
     leftinbuf := leftinbuf - strlen(bufrec^) - 2;
     if strlen(bufrec^) = 255 then
      bufptr := addr(bufptr^, -1)
     else
      begin
       if strlen(bufrec^) = 0 then
        begin  { discard the length byte }
         bufptr    := addr(bufrec^, -1);
         leftinbuf := leftinbuf + 1;
        end;
         
       { check end of line/file }
       call(am, ffib, readbytes, bufptr^, 1, fpos);
       if feoln then
        begin  { end of line }
         bufptr^ := chr(1);
         feoln   := false;
         if ioresult = ord(ieof) then
          bufptr := addr(bufptr^, 1);
        end;  { end of line }
       if ioresult = ord(ieof) then
        begin  { end of file }
         bufptr^  := chr(2);
         ioresult := ord(inoerror);
         feof     := true;
        end;  { end of file }
       iocheck;  { check ioresult from readbytes }
      end;
      if not((leftinbuf < 259) or feof) then
       begin  { set up for then read the next line }
        bufptr  := addr(bufptr^, 1);
        bufptr^ := chr(0);  { data record }
        bufrec  := addr(bufptr^, 1);
        setstrlen(bufrec^, 0);  { zero length record }
        bufptr  := addr(bufrec^, 1);
        call(am, ffib, readtoeol, bufrec^, 255, fpos);
       end;
     until (leftinbuf < 259) or feof;
     bufptr  := addr(bufptr^, 1);
     bufptr^ := chr(3);  { end buffer }
   end;
 end;  { anytomem }
 
 procedure memtoany(anyvar buffer: bigptr;
                           ffib  : fibp);
 var bytes : integer;
     bufptr: ^char;
 begin
  bufptr := addr(buffer^);
  with ffib^, unitable^[funit] do
   begin
    bytes := 0;
    repeat
     bufptr := addr(bufptr^, bytes);
     bytes  := ord(bufptr^);
     bufptr := addr(bufptr^, 1);
     case bytes of
      0: begin  { data bytes }
          bytes  := ord(bufptr^);  { record length }
          bufptr := addr(bufptr^, 1);
          call(am, ffib, writebytes, bufptr^, bytes, fpos);
         end;
      1: begin  { end record }
          call(am, ffib, writeeol, bufptr^, bytes, fpos);
          bytes := 0;
         end;
      2: begin  { end file }
          call(am, ffib, flush, bufptr^, bytes, fpos);
          bytes := -1;
         end;
      3: bytes := -1;  { end of buffer }
      otherwise ioresult := ord(ibadrequest);
     end;  { case }
     iocheck;
    until bytes < 0;
   end;
 end;  { memtoany }
 
 procedure setupfibforfile(var filename      : fid;
                           var lfib          : fib;
                           requireddirectory : boolean);
 var lkind: filekind;
     segs : integer;
 begin
  ioresult := ord(inoerror);
  with lfib do
   if scantitle(filename, fvid, ftitle, segs, lkind) then
    begin
     funit := findvolume(fvid, true);
     if funit = 0 then
      badio(inounit);
     if not ((ioresult = ord(inodirectory))
     and (strlen(ftitle) = 0)
     and (not requireddirectory)) then
      begin
       iocheck;
       if unitnumber(fvid) then
        badio(znodevice);
      end;
     fkind        := lkind;
     feft         := efttable^[lkind];
     fpos         := segs * 512;
     freptcnt     := 0;
     flastpos     := -1;
     fanonymous   := false;
     fmodified    := false;
     fbufchanged  := false;
     fstartaddress:= 0;
     pathid       := -1;
     foptstring   := nil;
     fnosrmtemp   := true;
     flocked      := true;
     feof         := false;
     feoln        := false;
    end
   else
    badio(ibadtitle);
 end;  { setupfibforfile }
 
 procedure closeinfile(var infib: fib);
 begin
  with infib do
   if freadable then
    begin
     fmodified := false;
     call(unitable^[funit].dam, infib, funit, closefile);
     freadable := false;
    end;
 end;  { closeinfile }
 
 procedure closeoutfile(var outfib: fib; option: closecode);
 var coption: damrequesttype;
 begin
  with outfib do
   if fwriteable then
    begin
     case option of
      keepit:  begin
                fmodified := true;
                coption := closefile;
               end;
      purgeit: coption := purgefile;
     end;
     call(unitable^[funit].dam, outfib, funit, coption);
     fwriteable := false;
    end;
  end;  { closeoutfile }
  
 procedure filecopy(filename1, filename2: fid; format, writeover: boolean);
 type fullname = string[vidleng + tidleng + 1];
      ipointer = ^integer;
 var infib, outfib : fib;
     outsize       : integer;
     outfkind      : filekind;
     outeft        : shortint;
     outfstarta    : integer;
     overcreate    : damrequesttype;
     typecode      : integer;
     lheap         : anyptr;
     saveio        : integer;
     saveesc       : integer;
     buf           : bigptr;
     bufsize       : integer;
     movesize      : integer;
 begin  { filecopy }
  mark(lheap);
  if format then
   typecode := -3  { TEXT file }
  else
   typecode := 1;  { DATA file }
  newwords(infib.fwindow, 1);  { buffer variable }
  finitb(infib, infib.fwindow, typecode);
  
  newwords(outfib.fwindow, 1);  { buffer variable }
  finitb(outfib, outfib.fwindow, typecode);
  
  try
   with infib do
    begin
     setupfibforfile(filename1, infib, false);
     if strlen(ftitle) = 0 then
      begin  { volume -> x }
       call(unitable^[funit].dam, infib, funit, openvolume);
       fkind := datafile;
       feft  := efttable^[datafile];
      end
     else
      begin  { file -> x }
       call(unitable^[funit].dam, infib, funit, openfile);
      end;
     iocheck;
     fpos      := 0;
     freadable := true;
     outfkind  := fkind;
     outeft    := feft;
     outsize   := fleof;
     outfstarta:= fstartaddress;
    end;  { with infib }
    
    with outfib do
     begin
      setupfibforfile(filename2, outfib, false);
      if format then
       begin
        fkind   := suffix(ftitle);  { set destination fkind }
        feft    := efttable^[fkind];
        outsize := 0;
       end
      else
       begin
        fkind   := outfkind;
        feft    := outeft;
        if fpos = 0 then  { no size was specified }
         fpos   := outsize;
       end;
      fstartaddress := outfstarta;
      
      if strlen(ftitle) = 0 then
       begin  { x -> volume }
        call(unitable^[funit].dam, outfib, funit, openvolume);
        iocheck;
        if fpeof < outsize then
         badio(inoroom);
       end  { x -> volume }
      else
       begin  { x -> file }
        if writeover then
         overcreate := overwritefile
        else
         overcreate := createfile;
        call(unitable^[funit].dam, outfib, funit, overcreate);
        iocheck;
        if fpeof < outsize then
         begin  { try to stretch file }
          fpos := outsize;
          call(unitable^[funit].dam, outfib, funit, stretchit);
          iocheck;
          if outsize > fpeof then
           badio(inoroom);
         end;
       end;  { x -> file }
      fpos      := 0;
      fwriteable:= true;
     end;  { with outfib }
     
     bufsize := ((memavail - 5000) div 256) * 256;  { save 5k for slop }
     if bufsize < 512 then escape(-2);              { not enough room }
     newwords(buf, bufsize div 2);                  { allocate buffer space }
     if format then
      outsize := -1;
     
     repeat  { move the file }
      with infib do
       if format then
        begin  { formatted filecopy }
         anytomem(addr(infib), buf, bufsize);
         if feof then
          outsize := 0;
        end
       else
        begin  { unformatted filecopy }
         if bufsize > outsize then
          movesize := outsize
         else
          movesize := bufsize;
         call(unitable^[funit].tm, addr(infib), readbytes, buf^, movesize,
              fpos);
         fpos := fpos + movesize;
        end;
      iocheck;
      
      with outfib do
       if format then
        memtoany(buf, addr(outfib))
       else
        begin  {unformatted filecopy }
         call(unitable^[funit].tm, addr(outfib), writebytes,
              buf^, movesize, fpos);
         fpos    := fpos + movesize;
         fleof   := fpos;
         outsize := outsize - movesize;
        end;
     until outsize  = 0;
     
     release(lheap);
     closeinfile(infib);
     closeoutfile(outfib, keepit);
   
  recover
   begin
    release(lheap);
    saveio   := ioresult;
    saveesc  := escapecode;
    closeinfile(infib);
    closeoutfile(outfib, purgeit);
    escape(saveesc);
   end;
 end;  { filecopy }
 
 procedure volumes(var v: volumearray);
 var un : unitnum;
     i  : integer;
     sym: string[3];
 begin
  for un := 1 to maxunit do
   with unitable^[un] do
    begin
     call(dam, uvid, un, getvolumename);
     v[un] := '';
     if (ioresult = ord(inoerror)) and (strlen(uvid) > 0) then
      begin
       if uvid = syvid then
        sym := ' * '
       else
        if uisblkd then
         sym := ' # '
        else
         sym := '   ';
       strwrite(v[un], 1, i, sym, uvid, ':');
      end;
    end;
 end;  { volumes }
 
 procedure repack(filename : fid);
 var infib : fib;
 begin
  with infib do
   begin
    setupfibforfile(filename, infib, true);
    call(unitable^[funit].dam, infib, funit, crunch);
    iocheck;
   end;
 end;  { repack }
 
 procedure opendir(var filename    : fid;
                   var infib       : fib;
                   var dircatentry : catentry);
 begin  { opendir }
  with infib do
   begin
    freadable := false;
    fwindow   := addr(dircatentry);
    setupfibforfile(filename, infib, false);
    if ioresult = ord(inoerror) then
     begin
      call(unitable^[funit].dam, infib, funit, opendirectory);
      iocheck;
      freadable := true;
     end;
   end;
 end;  { opendir }
 
 procedure closedir(var infib : fib);
 begin
  with infib do
   begin
    if freadable then
     begin
      call(unitable^[funit].dam, infib, funit, closedirectory);
      freadable := false;
     end;
   end;
 end;  { closedir }
 
 procedure createdir(filename : fid; newname : vid; entries, bytes : integer);
 var infib          : fib;
     dircatentry    : catentry;
     saveio, saveesc: integer;
 begin  { createdir }
  with infib, dircatentry do
   try
    opendir(filename, infib, dircatentry);
    if ioresult = ord(inodirectory) then
     begin  { no directory, so set up default values }
      setstrlen(cname, 0);      { volume name }
      cpsize  := maxint;        { size in bytes }
      cextra1 := 0;             { number of entries }
     end
    else
     if (strlen(ftitle) > 0) or (cpsize <= 0) then
      badio(ibadrequest);
    closedir(infib);
    cpsize := min(cpsize, ueovbytes(funit));
    if entries >= 0 then        { -1 retains old values }
     cextra1 := entries;        {  0 selects default 
    if bytes > 0 then
     cpsize := bytes;           { -1 retains old value }
    if cpsize = 0 then
     badio(ibadvalue);
    zapspaces(newname);
    if strlen(newname) > 0 then
     cname := newname;          { null retains old name }
    call(unitable^[funit].dam, infib, funit, makedirectory);
    iocheck;
   recover
    begin
     saveio    := ioresult;
     saveesc   := escapecode;
     closedir(infib);
     ioresult  := saveio;
     escape(saveesc);
    end;
 end;  { createdir }
 
 procedure makedir(filename: fid);
 var infib          : fib;
     dircatentry    : catentry;
     saveio, saveesc:integer;
 begin
  with infib, dircatentry do
   try
    opendir(filename, infib, dircatentry);
    iocheck;
    if strlen(ftitle) = 0 then
     badio(idupfile);
    cname := ftitle;
    call(unitable^[funit].dam, infib, funit, makedirectory);
    iocheck;
    closedir(infib);
   recover 
    begin
     saveio  := ioresult;
     saveesc := escapecode;
     closedir(infib);
     ioresult:= saveio;
     escape(saveesc);
    end;
  closedir(infib);
 end;  { makedir }
 
 procedure makefile(filename : fid);
 var outfib : fib;
 begin
  with outfib do
   begin
    setupfibforfile(filename, outfib, true);
    call(unitable^[funit].dam, outfib, funit, createfile);
    iocheck;
    fwriteable := true;
    fleof      := fpeof;  { cause file size to be retained }
    closeoutfile(outfib, keepit);
    iocheck;
   end;  { with }
 end;  { makefile }
 
 procedure endcat;
 begin
  if catfib <> nil then
   begin
    closedir(catfib^);
    release(catfib);
    catfib := nil;
   end;
 end;  { endcat }
 
 procedure startcat(filename : fid;
                    var dirname               : vid;
                    var typeinfo              : string;
                    var createdate, changedate: daterec;
                    var createtime, changetime: timerec;
                    var blocksize, phy_size, start_byte, free_bytes,
                        max_files             : integer);
 var dircatentry : catentry;
     saveio      : integer;
     saveesc     : integer;
 begin  { startcat }
  endcat;
  new(catfib);
  new(catentptr);
  try
   opendir(filename, catfib^, dircatentry);
   iocheck;
   with dircatentry do
    begin
     dirname   := cname;
     typeinfo  := cinfo;
     createdate:= ccreatedate;
     changedate:= clastdate;
     createtime:= ccreatetime;
     changetime:= clasttime;
     blocksize := cblocksize;
     phy_size  := cpsize;
     start_byte:= cstart;
     free_bytes:= cextra2;
     max_files := cextra1;
    end;
   with catfib^, unitable^[funit] do
    begin
     fwindow := addr(catentptr^);
     fpos    := 0;
     fpeof   := catlimit;
     call(dam, catfib^, funit, catalog);
     iocheck;
    end;
  recover
   begin
    saveio   := ioresult;
    saveesc  := escapecode;
    endcat;
    ioresult := saveio;
    escape(saveesc);
   end;
 end;  { startcat }
 
 procedure cat(filenumber :integer;
               var filename               : tid;
               var typeinfo               : string;
               var createdate, changedate : daterec;
               var createtime, changetime : timerec;
               var kind                   : filekind;
               var eft                    : shortint;
               var blocksize, logical_size, phy_size, start_byte,
                   extension1, extension2 : integer);
 begin
  if catfib = nil then escape(-3);
  with catfib^, unitable^[funit] do
   begin
    if not freadable then
     badio(inotopen);
    if (filenumber >= 0) and
     ((filenumber < fpos) or
     ((filenumber >= fpos + catlimit) and (fpeof = catlimit))) then
      begin
       fpos  := filenumber;
       fpeof := catlimit;
       call(dam, catfib^, funit, catalog);
       iocheck;
      end;
    if (filenumber < fpos) or (filenumber >= fpos + fpeof) then
     filename := ''
    else
     with catentptr^[filenumber - fpos] do
      begin
       filename    := cname;
       typeinfo    := cinfo;
       createdate  := ccreatedate;
       changedate  := clastdate;
       createtime  := ccreatetime;
       changetime  := clasttime;
       kind        := ckind;
       eft         := ceft;
       blocksize   := cblocksize;
       logical_size:=clsize;
       phy_size    := cpsize;
       start_byte  := cstart;
       extension1  := cextra1;
       extension2  := cextra2;
      end;
   end;
 end;  { cat }
 
 procedure duplicate(filename1, filename2: fid; purgeold: boolean);
 var infib, outfib   : fib;
     dircatentry     : catentry;
     saveio, saveesc : integer;
 begin
  with infib do
   try
    opendir(filename1, infib, dircatentry);
    iocheck;
    opendir(filename2, outfib, dircatentry);
    iocheck;
    if not samedevice(funit, outfib.funit) then
     badio(ibadrequest);
    fwindow := addr(outfib);
    fpurgeoldlink := purgeold;
    call(unitable^[funit].dam, infib, funit, duplicatelink);
    iocheck;
    closedir(infib);
    closedir(outfib);
   recover
    begin
     saveio  := ioresult;
     saveesc := escapecode;
     closedir(infib);
     closedir(outfib);
     ioresult := saveio;
     if saveesc <> 0 then
      escape(saveesc);
    end;
 end;  { duplicate }
 
 procedure remove(filename: fid);
 var infib : fib;
 begin
  setupfibforfile(filename, infib, true);
  with infib do
   call(unitable^[funit].dam, infib, funit, purgename);
  iocheck;
 end;  { remove }
 
 procedure change(filename1, filename2: fid);
 var infib, outfib : fib;
     lsegs         : integer;
     lkind         : filekind;
 begin
  setupfibforfile(filename1, infib, true);
  with outfib do
   if not scantitle(filename2, fvid, ftitle, lsegs, lkind) then
    badio(ibadtitle);
  with infib do
   if ftitle = '' then
    call(unitable^[funit].dam, outfib.fvid, funit, setvolumename)
   else
    begin
     fwindow := addr(outfib.ftitle);
     call(unitable^[funit].dam, infib, funit, changename);
    end;
  iocheck;
 end;  { change }
 
 procedure endpass;
 begin
  if passfib <> nil then
   release(passfib);
 end;  { endpass }
 
 procedure startlistpass(filename : fid);
 begin
  endpass;
  new(passfib);
  new(wordlist);
  try
   setupfibforfile(filename, passfib^, true);
   with passfib^ do
    begin
     fwindow := addr(wordlist^);
     fpos    := 0;
     fpeof   := catlimit;
     call(unitable^[funit].dam, passfib^, funit, catpasswords);
     iocheck;
     optionlist := addr(foptstring^);
    end;
  recover
   begin
    endpass;
    escape(escapecode);
   end;
 end;  { startlistpass }
 
 procedure listattribute(wordnumber : integer; var outstring : string);
 var i    : integer;
     done : boolean;
 begin
  outstring := '';
  if passfib = nil then
   escape(-3);
  with passfib^ do
   begin
    i    := 0;
    done := false;
    repeat
     with optionlist^[i] do
      begin
       if pbits = 0 then
        done := true
       else
        if i = wordnumber then
         begin
          outstring := pword;
          done      := true;
         end;
       end;
      i := i + 1;
    until done;
    end;
 end;  { listattribute }
 
 procedure listpassword(wordnumber : integer; var outstring : string);
 var i, j, p     : integer;
     first, last : boolean;
 begin
  outstring := '';
  if passfib = nil then
   escape(-3);
  with passfib^ do
   begin
    if (wordnumber >= 0) and
     ((fwindow <> addr(wordlist^)) or
     (wordnumber < fpos) or ((wordnumber >= fpos + catlimit) and 
     (fpeof = catlimit))) then
      begin
       fwindow := addr(wordlist^);
       fpos    := wordnumber;
       fpeof   := catlimit;
       call(unitable^[funit].dam, passfib^, funit, catpasswords);
       iocheck;
      end;
    if (wordnumber >= fpos) and (wordnumber < fpos + fpeof) then
     with wordlist^[wordnumber-fpos] do
      if pbits <> 0 then
       begin
        strwrite(outstring, 1, j, pword, ':');
        first := true;
        last  := false;
        i     := 0;
        p     := pbits;
        repeat
         with optionlist^[i] do
          begin
           last := pbits = 0;
           if not last then
            if iand(pbits, p) = p then
             begin
              if not first then
               strwrite(outstring, strlen(outstring) + 1, j, ',');
              first := false;
              strwrite(outstring, strlen(outstring) + 1, j, pword);
             end;
          end;
         i := i + 1;
        until last;
       end;
   end;
 end;  { listpassword }
 
 procedure changepassword(word: passtype; attrlist: string255);
 var entry  : passentry;
     name   : passtype;
     bits, i: integer;
     found  : boolean;
 begin
  if passfib = nil then
   escape(-3);
  bits := 0;
  zapspaces(attrlist);  { remove blanks and control characters }
  while strlen(attrlist) > 0 do
   begin
    i := strpos(',', attrlist);
    if i = 0 then
     i := strlen(attrlist) + 1;
    name := str(attrlist, 1, i - 1);
    upc(name);  { uppercase the attribute }
    if i > strlen(attrlist) then
     setstrlen(attrlist, 0)
    else
     attrlist := str(attrlist, i + 1, strlen(attrlist) - i);
    i     := 0;
    found := false;
    repeat
     with optionlist^[i] do
      begin
       if pbits = 0 then
        badio(ibadformat);
       if name = pword then
        begin
         found := true;
         bits  := ior(bits, pbits);
        end;
      end;
     i := i + 1;
    until found;
  end;  { get attributes }
  zapspaces(word);
  with entry do
   begin
    pword := word;
    pbits := bits;
   end;
  with passfib^ do
   begin
    fwindow := addr(entry);
    fpos    := 0;
    fpeof   := 1;
    call(unitable^[funit].dam, passfib^, funit, setpasswords);
    iocheck;
   end;
 end;  { changepassword }
 
 procedure prefix(filename: fid; unitonly, sysvol : boolean);
 var i : integer;
     s : vid;
 begin
  zapspaces(filename);
  if unitonly then
   doprefix(filename, s, i, true)
  else
   if sysvol then
    doprefix(filename, syvid, sysunit, true)
   else
    doprefix(filename, dkvid, i, false);
  iocheck;
 end;  { prefix }
 
end.  { module filepack }
   
     
