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.