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.