diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/du.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/du.lua new file mode 100644 index 000000000..9e8017307 --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/du.lua @@ -0,0 +1,133 @@ +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]] + +local function writeline(value, pipe) + pipe = pipe or io.stdout + pipe:write(value) + pipe:write('\n') +end + +if options.help then + writeline(HELP) + return true +end + +if options.version then + writeline(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 + writeline(TRY, io.stderr) + return false +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) + writeline(string.format("%s%s", 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 + writeline(string.format("%s does not exist", arg), io.stderr) + 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