IonutParau 687cfebd00 testing version of LuaBIOS and OpenOS
people were having issues getting them to work so now we promote consistency
2025-06-28 20:41:49 +02:00

129 lines
2.8 KiB
Lua

local shell = require("shell")
local fs = require("filesystem")
local args, options, reason = shell.parse(...)
if #args == 0 then
args[1] = '.'
end
local TRY=[[
Try 'du --help' for more information.]]
local VERSION=[[
du (OpenOS bin) 1.0
Written by payonel, patterned after GNU coreutils du]]
local HELP=[[
Usage: du [OPTION]... [FILE]...
Summarize disk usage of each FILE, recursively for directories.
-h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize display only a total for each argument
--help display this help and exit
--version output version information and exit]]
if options.help then
print(HELP)
return true
end
if options.version then
print(VERSION)
return true
end
local function addTrailingSlash(path)
if path:sub(-1) ~= '/' then
return path .. '/'
else
return path
end
end
local function opCheck(shortName, longName)
local enabled = options[shortName] or options[longName]
options[shortName] = nil
options[longName] = nil
return enabled
end
local bHuman = opCheck('h', 'human-readable')
local bSummary = opCheck('s', 'summarize')
if next(options) then
for op,v in pairs(options) do
io.stderr:write(string.format("du: invalid option -- '%s'\n", op))
end
io.stderr:write(TRY..'\n')
return 1
end
local function formatSize(size)
if not bHuman then
return tostring(size)
end
local sizes = {"", "K", "M", "G"}
local unit = 1
local power = options.si and 1000 or 1024
while size > power and unit < #sizes do
unit = unit + 1
size = size / power
end
return math.floor(size * 10) / 10 .. sizes[unit]
end
local function printSize(size, rpath)
local displaySize = formatSize(size)
io.write(string.format("%s%s\n", string.format("%-12s", displaySize), rpath))
end
local function visitor(rpath)
local subtotal = 0
local dirs = 0
local spath = shell.resolve(rpath)
if fs.isDirectory(spath) then
local list_result = fs.list(spath)
for list_item in list_result do
local vtotal, vdirs = visitor(addTrailingSlash(rpath) .. list_item)
subtotal = subtotal + vtotal
dirs = dirs + vdirs
end
if dirs == 0 then -- no child dirs
if not bSummary then
printSize(subtotal, rpath)
end
end
elseif not fs.isLink(spath) then
subtotal = fs.size(spath)
end
return subtotal, dirs
end
for i,arg in ipairs(args) do
local path = shell.resolve(arg)
if not fs.exists(path) then
io.stderr:write(string.format("du: cannot access '%s': no such file or directory\n", arg))
return 1
else
if fs.isDirectory(path) then
local total = visitor(arg)
if bSummary then
printSize(total, arg)
end
elseif fs.isLink(path) then
printSize(0, arg)
else
printSize(fs.size(path), arg)
end
end
end
return true