Newer
Older
ubixfs-2 / uformat.pas
@flameshadow flameshadow on 10 Jun 2005 4 KB UbixFS
program uFormat;

uses device, ubixfs, diskDrv, dos, crt, debug;

procedure usage;
begin
  writeln('Format a disk or file for use with UbixOS');
  writeln;
  writeln('uFormat drive: [-Q] [-B] [-A:BlockSize]');
  writeln('uFormat file   [-Q] [-B] [-A:BlockSize] [-S:Size]');
  writeln;
  writeln;
  writeln('  -Q          Performs a quick format.');
  writeln('  -S          Specifies the size in blocks');
  writeln('  -B          Allocates space on the formatted disk for system files.');
  writeln('  -A          Overrides the default allocation unit size. Default is 1024');
  writeln('              UbixFS supports 1024, 2048, 4096, and 8192 block sizes');
  halt;
end;

function upcasestr(ins:string):string;
var
  s:string;
  i:integer;
begin
  s[0] := ins[0];
  for i:=1 to length(ins) do
    s[i] := upcase(ins[i]);
  result := s;
end;

function getBlockSize:uInt32;
var
  s:string;
  i:integer;
  code:integer;
  size:integer;
begin

  result := 1024;  {default}
  for i:=1 to paramCount do
    if (pos('-A:', upcasestr(paramstr(i))) <> 0) then
      begin
        s := copy(paramstr(i), 4, length(paramstr(i)) - 3);
        val(s, size, code);
        if (code<>0) then
          begin
            writeln('Error parsing allocation unit size: ', paramstr(i));
            halt;
          end;
        result := size;
        break;
      end; {if}
end; {getBlockSize}

function getSize:uInt32;
var
  s:string;
  i:integer;
  code:integer;
  size:integer;
begin
  result := 0;
  for i:=1 to paramCount do
    if (pos('-S:', upcasestr(paramstr(i))) <> 0) then
      begin
        s := copy(paramstr(i), 4, length(paramstr(i)) - 3);
        val(s, size, code);
        if (code<>0) then
          begin
            writeln('Error parsing size: ', paramstr(i));
            halt;
          end;
        result := size;
        break;
      end; {if}
end; {getSize}

function getQuick:boolean;
var i:integer;
begin
  result := FALSE;
  for i := 1 to paramcount do
    if (upcasestr(paramstr(i)) = '-Q') then
      begin
        result := TRUE;
        exit;
      end; {if}
end; {getQuick}

procedure verifyBlockSize(size:uInt32);
begin
  if ((size = 1024) or (size = 2048) or (size = 4096) or (size = 8192)) then exit;
  writeln('Allocation unit must be one of the following: 1024, 2048, 4096, 8192');
  halt;
end; {verifyBlockSize}

var
  quick:boolean;
  i:integer;
  drivefile:string;
  dev:PDevice;
  f:file;
  key:char;
  size:uInt32;
  fsBlockSize:uInt32;
  p:pointer;
  ufs:PUbixFS;
begin

  if (paramcount = 0) then usage;
  drivefile := paramstr(1);

  fsBlockSize := getBlockSize;
  verifyBlockSize(fsBlockSize);
  quick := getQuick;

  if ((length(drivefile) = 2) and (drivefile[2] = ':')) then
    begin
      // physical drive
      writeln('Physical drive: ', drivefile);
    end
  else
    begin
      // file
      size := getSize;
      if (fsearch(drivefile, '')<>'') then
        begin
          writeln('Warning! ', drivefile, ' already exists. Overwrite? [Y/n]');
          repeat key := upcase(readkey) until key in [#27, #13, 'Y', 'N'];
          if (key in ['N', #27]) then halt;
          assign(f, drivefile);
          reset(f, 1);

          if (size = 0) then
            begin
              size := filesize(f);
              if (size mod fsBlockSize <> 0) then
                begin
                  writeln('File size of ', drivefile, ' isn''t evenly divisible by ', fsBlockSize);
                  writeln('Use the -S: option to override the file block count');
                  close(f);
                  halt;
                end;
              size := size div fsBlockSize;
            end;

          if (size = 0) then
            begin
              writeln('Block count is 0! Aborting!');
              close(f);
              halt;
            end;

          if (size <> filesize(f)) then
            begin
              getmem(p, fsBlockSize);
              fillchar(p^, fsBlockSize, 0);

              rewrite(f, fsBlockSize);
              for i:=0 to size-1 do
                blockwrite(f, p^, 1);

              freemem(p, fsBlockSize);
            end;
          close(f);
          dev := dev_diskDrive(drivefile);
        end
      else    // file didn't exist, create one
        begin
          if (size = 0) then
            begin
              writeln('Block count is 0.  Use the -S: option to specify the size in blocks');
              halt
            end;
          assign(f, driveFile);
          rewrite(f, fsBlockSize);
          getmem(p, fsBlockSize);
          fillchar(p^, fsBlockSize, 0);
          for i := 0 to size - 1 do
            blockwrite(f, p^, 1);
          freemem(p, fsBlockSize);
          close(f);
          dev := dev_diskDrive(driveFile);
        end;

    end; {else}
  new(ufs, init(NIL));
  ufs^.vfs_format(dev, fsBlockSize, quick);
  dispose(ufs, done);
end.