mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 09:18:05 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
This commit is contained in:
commit
6b80b75fd3
@ -7,6 +7,8 @@ if #args < 2 then
|
||||
io.write(" -i: prompt before overwrite (overrides -n option).\n")
|
||||
io.write(" -n: do not overwrite an existing file.\n")
|
||||
io.write(" -r: copy directories recursively.\n")
|
||||
io.write(" -u: copy only when the SOURCE file differs from the destination\n")
|
||||
io.write(" file or when the destination file is missing.\n")
|
||||
io.write(" -v: verbose output.")
|
||||
return
|
||||
end
|
||||
@ -19,7 +21,7 @@ local to = shell.resolve(args[#args])
|
||||
|
||||
local function status(from, to)
|
||||
if options.v then
|
||||
print(from .. " -> " .. to)
|
||||
io.write(from .. " -> " .. to .. "\n")
|
||||
end
|
||||
os.sleep(0) -- allow interrupting
|
||||
end
|
||||
@ -27,9 +29,33 @@ end
|
||||
local result, reason
|
||||
|
||||
local function prompt(message)
|
||||
io.write(message .. " ")
|
||||
io.write(message .. " [Y/n]\n")
|
||||
local result = io.read()
|
||||
return result and result:sub(1, 1):lower() == "y"
|
||||
return result and (result == "" or result:sub(1, 1):lower() == "y")
|
||||
end
|
||||
|
||||
local function areEqual(path1, path2)
|
||||
local f1 = io.open(path1, "rb")
|
||||
if not f1 then
|
||||
return nil, "could not open `" .. path1 .. "' for update test"
|
||||
end
|
||||
local f2 = io.open(path2, "rb")
|
||||
if not f2 then
|
||||
f1:close()
|
||||
return nil, "could not open `" .. path2 .. "' for update test"
|
||||
end
|
||||
local result = true
|
||||
local chunkSize = 4 * 1024
|
||||
repeat
|
||||
local s1, s2 = f1:read(chunkSize), f2:read(chunkSize)
|
||||
if s1 ~= s2 then
|
||||
result = false
|
||||
break
|
||||
end
|
||||
until not s1 or not s2
|
||||
f1:close()
|
||||
f2:close()
|
||||
return result
|
||||
end
|
||||
|
||||
local function recurse(fromPath, toPath)
|
||||
@ -70,6 +96,11 @@ local function recurse(fromPath, toPath)
|
||||
return nil, "cannot overwrite directory `" .. toPath .. "' with non-directory"
|
||||
end
|
||||
else
|
||||
if options.u then
|
||||
if areEqual(fromPath, toPath) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if options.i then
|
||||
if not prompt("overwrite `" .. toPath .. "'?") then
|
||||
return true
|
||||
|
@ -1,22 +1,24 @@
|
||||
local component = require("component")
|
||||
local computer = require("computer")
|
||||
local event = require("event")
|
||||
local filesystem = require("filesystem")
|
||||
local unicode = require("unicode")
|
||||
local shell = require("shell")
|
||||
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local fromAddress = options.from and component.get(options.from) or filesystem.get(os.getenv("_")).address
|
||||
local candidates = {}
|
||||
for address in component.list("filesystem") do
|
||||
local dev = component.proxy(address)
|
||||
if not dev.isReadOnly() and dev.address ~= computer.tmpAddress() then
|
||||
if not dev.isReadOnly() and dev.address ~= computer.tmpAddress() and dev.address ~= fromAddress then
|
||||
table.insert(candidates, dev)
|
||||
end
|
||||
end
|
||||
|
||||
if #candidates == 0 then
|
||||
print("No writable disks found, aborting.")
|
||||
return
|
||||
io.write("No writable disks found, aborting.\n")
|
||||
os.exit()
|
||||
end
|
||||
|
||||
for i = 1, #candidates do
|
||||
@ -26,45 +28,53 @@ for i = 1, #candidates do
|
||||
else
|
||||
label = candidates[i].address
|
||||
end
|
||||
print(i .. ") " .. label)
|
||||
io.write(i .. ") " .. label .. "\n")
|
||||
end
|
||||
|
||||
print("To select the device to install to, please enter a number between 1 and " .. #candidates .. ".")
|
||||
print("Press 'q' to cancel the installation.")
|
||||
io.write("To select the device to install to, please enter a number between 1 and " .. #candidates .. ".\n")
|
||||
io.write("Press 'q' to cancel the installation.\n")
|
||||
local choice
|
||||
while not choice do
|
||||
result = io.read()
|
||||
if result:sub(1, 1):lower() == "q" then
|
||||
return
|
||||
os.exit()
|
||||
end
|
||||
local number = tonumber(result)
|
||||
if number and number > 0 and number <= #candidates then
|
||||
choice = candidates[number]
|
||||
else
|
||||
print("Invalid input, please try again.")
|
||||
io.write("Invalid input, please try again.\n")
|
||||
end
|
||||
end
|
||||
|
||||
local function findMount(address)
|
||||
for fs, path in filesystem.mounts() do
|
||||
if fs.address == component.get(address) then
|
||||
return path
|
||||
end
|
||||
end
|
||||
end
|
||||
candidates = nil
|
||||
|
||||
local name = options.name or "OpenOS"
|
||||
print("Installing " .. name .." to device " .. (choice.getLabel() or choice.address))
|
||||
io.write("Installing " .. name .." to device " .. (choice.getLabel() or choice.address) .. "\n")
|
||||
os.sleep(0.25)
|
||||
local origin = options.from and options.from:sub(1,3) or computer.getBootAddress():sub(1, 3)
|
||||
local fromDir = options.fromDir or "/"
|
||||
local mnt = choice.address:sub(1, 3)
|
||||
local result, reason = os.execute("/bin/cp -vr /mnt/" .. origin .. fromDir .. "* /mnt/" .. mnt .. "/")
|
||||
local cpPath = filesystem.concat(findMount(filesystem.get(os.getenv("_")).address), "bin/cp")
|
||||
local cpOptions = "-vr" .. (options.u and "ui " or "")
|
||||
local cpSource = filesystem.concat(findMount(fromAddress), options.fromDir or "/", "*")
|
||||
local cpDest = findMount(choice.address) .. "/"
|
||||
local result, reason = os.execute(cpPath .. " " .. cpOptions .. " " .. cpSource .. " " .. cpDest)
|
||||
if not result then
|
||||
error(reason, 0)
|
||||
end
|
||||
if not options.nolabelset then pcall(choice.setLabel, name) end
|
||||
|
||||
if not options.noreboot then
|
||||
print("All done! " .. ((not options.noboot) and "Set as boot device and r" or "R") .. "eboot now? [Y/n]")
|
||||
io.write("All done! " .. ((not options.noboot) and "Set as boot device and r" or "R") .. "eboot now? [Y/n]\n")
|
||||
local result = io.read()
|
||||
if not result or result == "" or result:sub(1, 1):lower() == "y" then
|
||||
if not options.noboot then computer.setBootAddress(choice.address)end
|
||||
print("\nRebooting now!")
|
||||
io.write("\nRebooting now!\n")
|
||||
computer.shutdown(true)
|
||||
end
|
||||
end
|
||||
print("Returning to shell.")
|
||||
io.write("Returning to shell.\n")
|
||||
|
@ -17,6 +17,9 @@ function memoryStream:close()
|
||||
end
|
||||
|
||||
function memoryStream:seek()
|
||||
if self.closed then
|
||||
error("attempt to use a closed stream")
|
||||
end
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
|
||||
@ -24,8 +27,9 @@ function memoryStream:read(n)
|
||||
if self.closed then
|
||||
if self.buffer == "" and self.redirect.read then
|
||||
return self.redirect.read:read(n)
|
||||
else
|
||||
error("attempt to use a closed stream")
|
||||
end
|
||||
return nil -- eof
|
||||
end
|
||||
if self.buffer == "" then
|
||||
self.args = table.pack(coroutine.yield(table.unpack(self.result)))
|
||||
@ -36,19 +40,24 @@ function memoryStream:read(n)
|
||||
end
|
||||
|
||||
function memoryStream:write(value)
|
||||
local ok
|
||||
if not self.redirect.write and self.closed then
|
||||
error("attempt to use a closed stream")
|
||||
end
|
||||
if self.redirect.write then
|
||||
ok = self.redirect.write:write(value)
|
||||
self.redirect.write:write(value)
|
||||
end
|
||||
if not self.closed then
|
||||
self.buffer = self.buffer .. value
|
||||
self.result = table.pack(coroutine.resume(self.next, table.unpack(self.args)))
|
||||
ok = true
|
||||
if coroutine.status(self.next) == "dead" then
|
||||
self:close()
|
||||
end
|
||||
if not self.result[1] then
|
||||
error(self.result[2], 0)
|
||||
end
|
||||
table.remove(self.result, 1)
|
||||
end
|
||||
if ok then
|
||||
return true
|
||||
end
|
||||
return nil, "stream is closed"
|
||||
end
|
||||
|
||||
function memoryStream.new()
|
||||
@ -328,16 +337,15 @@ local function execute(env, command, ...)
|
||||
result = table.pack(coroutine.resume(threads[i], table.unpack(args, 2, args.n)))
|
||||
if coroutine.status(threads[i]) ~= "dead" then
|
||||
args = table.pack(pcall(event.pull, table.unpack(result, 2, result.n)))
|
||||
elseif not args[1] then
|
||||
args[2] = debug.traceback(threads[i], args[2])
|
||||
end
|
||||
end
|
||||
if pipes[i] then
|
||||
pipes[i]:close()
|
||||
pcall(pipes[i].close, pipes[i])
|
||||
end
|
||||
if not result[1] then
|
||||
if type(result[2]) == "table" and result[2].reason == "terminated" then
|
||||
if result[2].code then
|
||||
result[1] = true
|
||||
result.n = 1
|
||||
else
|
||||
result[2] = "terminated"
|
||||
@ -473,7 +481,7 @@ if #args == 0 and (io.input() == io.stdin or options.i) and not options.c then
|
||||
term.write("\n")
|
||||
end
|
||||
if not result then
|
||||
io.stderr:write((tostring(reason) or "unknown error").. "\n")
|
||||
io.stderr:write((reason and tostring(reason) or "unknown error") .. "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -491,7 +499,7 @@ elseif #args == 0 and (io.input() ~= io.stdin) then
|
||||
elseif command ~= "" then
|
||||
local result, reason = os.execute(command)
|
||||
if not result then
|
||||
io.stderr:write((tostring(reason) or "unknown error").. "\n")
|
||||
io.stderr:write((reason and tostring(reason) or "unknown error") .. "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,7 +1,7 @@
|
||||
local args = {...}
|
||||
|
||||
if #args < 1 then
|
||||
print("Usage: unset <varname>[ <varname2> [...]]")
|
||||
io.write("Usage: unset <varname>[ <varname2> [...]]\n")
|
||||
else
|
||||
for _, k in ipairs(args) do
|
||||
os.setenv(k, nil)
|
||||
|
@ -175,7 +175,7 @@ local function motd()
|
||||
os.execute("/etc/motd")
|
||||
else
|
||||
f:seek("set", 0)
|
||||
print(f:read("*a"))
|
||||
io.write(f:read("*a") .. "\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
@ -185,7 +185,7 @@ while true do
|
||||
local result, reason = os.execute(os.getenv("SHELL"))
|
||||
if not result then
|
||||
io.stderr:write((tostring(reason) or "unknown error") .. "\n")
|
||||
print("Press any key to continue.")
|
||||
io.write("Press any key to continue.\n")
|
||||
os.sleep(0.5)
|
||||
require("event").pull("key")
|
||||
end
|
||||
|
@ -25,7 +25,7 @@ function buffer.new(mode, stream)
|
||||
end
|
||||
|
||||
function buffer:close()
|
||||
if self.mode.w or self.mode.a then
|
||||
if not self.closed and (self.mode.w or self.mode.a) then
|
||||
self:flush()
|
||||
end
|
||||
self.closed = true
|
||||
|
@ -210,7 +210,6 @@ function event.pullFiltered(...)
|
||||
if not (seconds or filter) or filter == nil or filter(table.unpack(signal, 1, signal.n)) then
|
||||
return table.unpack(signal, 1, signal.n)
|
||||
end
|
||||
|
||||
until computer.uptime() >= deadline
|
||||
end
|
||||
|
||||
|
@ -383,7 +383,7 @@ function term.read(history, dobreak, hint, pwchar, filter)
|
||||
end
|
||||
term.setCursorBlink(false)
|
||||
if term.getCursor() > 1 and dobreak ~= false then
|
||||
print()
|
||||
term.write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user