Files
Asuro/src/app/app.volcmd.pas
T

242 lines
5.4 KiB
ObjectPascal

{
Prog->VolCmd - Command-line tools for viewing volumes.
Shell command: VOL [subcommand]
Subcommands:
list - List all volumes (device, size, FS)
info <index> - Show volume details
@author(Aaron Hance <[email protected]>)
}
unit app.volcmd;
interface
procedure init();
implementation
uses
core.ds.lists,
memory.heap,
driver.storage.mgr,
driver.storage.types,
core.strings,
io.stdio,
debug.tracer,
driver.storage.vol.mgr;
var
g_out : POutBuf;
{ ---------- helpers ---------- }
function wnd : uint32;
begin
wnd := 0;
end;
function str2int(s : pchar) : uint32;
begin
str2int := stringToInt(s);
end;
{ Check whether a string contains only digit characters }
function isNumeric(s : pchar) : boolean;
var
i : uint32;
len : uint32;
begin
isNumeric := false;
len := stringSize(s);
if len = 0 then exit;
for i := 0 to len - 1 do begin
if (s[i] < '0') or (s[i] > '9') then exit;
end;
isNumeric := true;
end;
procedure print(s : pchar);
begin
io.stdio.bufWriteStr(g_out, s);
end;
procedure println(s : pchar);
begin
io.stdio.bufWriteStrLn(g_out, s);
end;
procedure printint(v : uint32);
begin
io.stdio.bufWriteInt(g_out, integer(v));
end;
procedure printhex(v : uint32);
begin
io.stdio.bufWriteHex(g_out, v);
end;
{ Print a byte count in human-readable form: B, KB, MB or GB }
procedure printsize(bytes : uint32);
begin
if bytes >= 1073741824 then begin
printint(bytes div 1073741824);
print(' GB');
end else if bytes >= 1048576 then begin
printint(bytes div 1048576);
print(' MB');
end else if bytes >= 1024 then begin
printint(bytes div 1024);
print(' KB');
end else begin
printint(bytes);
print(' B');
end;
end;
{ ---------- VOL LIST ---------- }
procedure cmd_list();
var
i : uint32;
count : uint32;
vol : PStorage_Volume;
begin
count := driver.storage.vol.mgr.get_volume_count();
if count = 0 then begin
println('No volumes registered.');
exit;
end;
println('IDX DEVICE SIZE FS');
println('--- ------ ---- --');
for i := 0 to count - 1 do begin
vol := driver.storage.vol.mgr.get_volume(i);
if vol = nil then continue;
print(' ');
printint(i);
print(' ');
{ Device info }
if vol^.device <> nil then begin
printint(vol^.device^.id);
print(' (');
print(driver.storage.mgr.controller_type_2_string(vol^.device^.controller));
print(')');
end else
print('?');
print(' ');
{ Size }
printsize(vol^.sectorCount * vol^.sectorSize);
print(' ');
{ Filesystem }
if vol^.filesystem <> nil then
print(vol^.filesystem^.sName)
else
print('none');
println('');
end;
end;
{ ---------- VOL INFO ---------- }
procedure cmd_info(params : PParamList);
var
idx : uint32;
vol : PStorage_Volume;
begin
if paramCount(params) < 2 then begin
println('Usage: VOL info <index>');
exit;
end;
if not isNumeric(getParam(1, params)) then begin
println('Error: volume index must be a number.');
exit;
end;
idx := str2int(getParam(1, params));
vol := driver.storage.vol.mgr.get_volume(idx);
if vol = nil then begin
print('Error: volume ');
printint(idx);
print(' not found (');
printint(driver.storage.vol.mgr.get_volume_count());
println(' volumes registered).');
exit;
end;
print('Sector Start: '); printint(vol^.sectorStart); println('');
print('Sector Count: '); printint(vol^.sectorCount); println('');
print('Sector Size: '); printint(vol^.sectorSize); println(' bytes');
print('Size: '); printsize(vol^.sectorCount * vol^.sectorSize); println('');
print('Free: ');
if (vol^.lifecycleFlags and STORAGE_VOLUME_FLAG_FREE_UNKNOWN) <> 0 then println('Unknown')
else begin printsize(vol^.freeSectors * vol^.sectorSize); println(''); end;
print('Boot Drive: ');
if vol^.isBootDrive then println('yes') else println('no');
print('Filesystem: ');
if vol^.filesystem <> nil then
println(vol^.filesystem^.sName)
else
println('none');
print('Device: ');
if vol^.device <> nil then begin
printint(vol^.device^.id);
print(' (');
print(driver.storage.mgr.controller_type_2_string(vol^.device^.controller));
println(')');
end else
println('none');
end;
{ ---------- Main dispatcher ---------- }
procedure command_vol(params : PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf);
var
subcmd : pchar;
begin
g_out := stdout_buf;
push_trace('VolCmd.command_vol');
if paramCount(params) = 0 then begin
println('Usage: VOL <list|info>');
exit;
end;
subcmd := getParam(0, params);
if stringEquals(subcmd, 'list') then begin
cmd_list();
exit;
end;
if stringEquals(subcmd, 'info') then begin
cmd_info(params);
exit;
end;
print('Unknown subcommand: ');
println(subcmd);
end;
{ ---------- Init ---------- }
procedure init();
begin
io.stdio.registerCommand('VOL', @command_vol, 'Volume information & management.');
end;
end.