Skip to content

Commit d5408ec

Browse files
committed
miniOS 0.5.9.7
Added file management commands. Will not work between drives. Signed-off-by: Skye M. <[email protected]>
1 parent 334de1c commit d5408ec

File tree

6 files changed

+194
-43
lines changed

6 files changed

+194
-43
lines changed

miniOS/command.lua

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@ local tArgs={...}
88
local continue
99
if tArgs[1] == "-c" then continue = true table.remove(tArgs, 1) end
1010

11-
local function intro() print(_OSVERSION .. " [".. math.floor(computer.totalMemory()/1024).."k RAM, at least "..math.floor(miniOS.freeMem/1024).."k Free]" .."\nCommand Interpreter By Skye M.\n") end
11+
local function intro() print(_OSVERSION .. " [".. math.floor(computer.totalMemory()/1024).."k RAM, around "..math.floor(miniOS.freeMem/1024).."k Free]" .."\nCommand Interpreter By Skye M.\n") end
1212
if not continue then intro() end
1313

1414
local history = {}
1515
if miniOS.cmdHistory then history = miniOS.cmdHistory end
1616
if miniOS.cmdDrive then fs.drive.setcurrent(miniOS.cmdDrive) end
1717

18+
local function fixPath(path)
19+
checkArg(1, path, "string")
20+
if path:sub(1,1) == '"' and path:sub(-1,-1) == '"' then path = path:sub(2, -2) end
21+
return path
22+
end
23+
1824
local function runprog(file, parts)
1925
miniOS.cmdHistory = history
2026
miniOS.cmdDrive = fs.drive.getcurrent()
@@ -34,7 +40,7 @@ end
3440

3541
local function lables()
3642
for letter, address in fs.drive.list() do
37-
print(letter, component.invoke(address, "getLabel"))
43+
print(letter, component.invoke(address, "getLabel") or "")
3844
end
3945
end
4046

@@ -85,6 +91,57 @@ local function dir(folder)
8591
printPaged(output)
8692
end
8793

94+
local function moveFile(from, to, force)
95+
checkArg(1, from, "string")
96+
checkArg(2, to, "string")
97+
if fs.isDirectory(to) then
98+
to = to .. "/" .. fs.name(from)
99+
end
100+
if fs.exists(to) then
101+
if not force then
102+
printErr("target file exists")
103+
return
104+
end
105+
fs.remove(to)
106+
end
107+
local result, reason = fs.rename(from, to)
108+
if not result then
109+
error(reason or "unknown error", 0)
110+
end
111+
end
112+
113+
local function copyFile(from, to, force)
114+
checkArg(1, from, "string")
115+
checkArg(2, to, "string")
116+
if fs.isDirectory(to) then
117+
to = to .. "/" .. fs.name(from)
118+
end
119+
if fs.exists(to) then
120+
if not force then
121+
printErr("target file exists")
122+
return
123+
end
124+
fs.remove(to)
125+
end
126+
local result, reason = fs.copy(from, to)
127+
if not result then
128+
error(reason or "unknown error", 0)
129+
end
130+
end
131+
132+
local function twoFileCommandHelper(run, parts)
133+
if #parts >= 3 then
134+
if parts[2] == "-f" then
135+
table.remove(parts, 2)
136+
run(fixPath(parts[2]), fixPath(parts[3]), true)
137+
return true
138+
else
139+
run(fixPath(parts[2]), fixPath(parts[3]))
140+
return true
141+
end
142+
else printErr("Bad Parameters!") return true end
143+
end
144+
88145
local function runline(line)
89146
line = text.trim(line)
90147
if line == "" then return true end
@@ -121,16 +178,23 @@ local function runline(line)
121178
if command == "cls" then term.clear() return true end
122179
if command == "ver" then print(_OSVERSION) return true end
123180
if command == "mem" then print(math.floor(computer.totalMemory()/1024).."k RAM, "..math.floor(computer.freeMemory()/1024).."k Free") return true end
124-
if command == "dir" then dir() return true end
181+
if command == "dir" then if parts[2] then dir(fixPath(parts[2])) else dir() end return true end
125182
if command == "intro" then intro() return true end
126183
if command == "disks" then listdrives() return true end
127184
if command == "discs" then listdrives() return true end
128185
if command == "drives" then listdrives() return true end
129186
if command == "labels" then lables() return true end
130-
if command == "label" then if parts[2] then label(parts) return true else print("Invalid Parameters") return false end end
131-
if command == "type" then outputFile(parts[2]) return true end
132-
if command == "more" then outputFile(parts[2], true) return true end
187+
if command == "label" then if parts[2] then label(parts) return true else printErr("Invalid Parameters") return false end end
188+
if command == "type" then outputFile(fixPath(parts[2])) return true end
189+
if command == "more" then outputFile(fixPath(parts[2]), true) return true end
133190
if command == "echo" then print(table.concat(parts, " ", 2)) return true end
191+
if command == "print" then print(table.concat(parts, "\t", 2)) return true end
192+
if command == "touch" then filesystem.close(filesystem.open(fixPath(parts[2]), 'w')) return true end
193+
if command == "del" then filesystem.remove(fixPath(parts[2])) return true end
194+
if command == "copy" then return twoFileCommandHelper(copyFile, parts) end
195+
if command == "rename" then return twoFileCommandHelper(moveFile, parts) end
196+
if command == "ren" then return twoFileCommandHelper(moveFile, parts) end
197+
if command == "move" then return twoFileCommandHelper(moveFile, parts) end
134198
if command == "cmds" then printPaged([[
135199
Internal Commands:
136200
exit --- Exit the command interpreter, Usually restarts it.
@@ -146,8 +210,11 @@ label -- Sets the label of a drive.
146210
echo --- Outputs its arguments.
147211
type --- Like echo, but outputs a file.
148212
more --- Like type, but the output is paged.
213+
touch -- Creates a file.
214+
del ---- Deletes a file.
149215
copy --- Copies a file.
150-
move --- Moves a file.]]) print() return true end
216+
move --- Moves a file.
217+
ren ---- Renames a file.]]) print() return true end
151218
print("'" .. parts[1] .. "' is not an internal or external command, program or batch file.")
152219
return false
153220
end

miniOS/minios.lua

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
_G._OSNAME = "MiniOS"
2-
_G._OSVER = "0.5.9.5"
1+
_G._OSNAME = "miniOS"
2+
_G._OSVER = "0.5.9.7"
33
_G._OSVERSION = _OSNAME .. " " .. _OSVER
44

55
--component code
@@ -228,6 +228,10 @@ function text_code()
228228

229229
-------------------------------------------------------------------------------
230230

231+
function text.endswith(s, send)
232+
return #s >= #send and s:find(send, #s-#send+1, true) and true or false
233+
end
234+
231235
return text
232236
end
233237
--event code
@@ -419,24 +423,44 @@ function event_code()
419423

420424
return event
421425
end
422-
--Simple filesystem code
426+
--filesystem code
423427
function fs_code()
424428
local fs = {}
425429
fs.drive = {}
426-
fs.drive._map = { ["A"]=computer.getBootAddress(), ["X"]=computer.tmpAddress() } --Z: will be the unix style root
430+
--drive mapping table, initilized later
431+
fs.drive._map = {}
432+
--converts a drive letter into a proxy
433+
function fs.drive.letterToProxy(letter)
434+
return fs.drive._map[letter]
435+
end
436+
--finds the proxy associated with the letter
437+
function fs.drive.proxyToLetter(proxy)
438+
for l,p in pairs(fs.drive._map) do
439+
if p == proxy then return l end
440+
end
441+
return nil
442+
end
443+
--maps a proxy to a letter
444+
function fs.drive.mapProxy(letter, proxy)
445+
fs.drive._map[letter] = proxy
446+
end
447+
--finds the address of a drive letter.
427448
function fs.drive.toAddress(letter)
428-
return fs.drive._map[letter]
449+
return fs.drive._map[letter].address
429450
end
451+
--finds the drive letter mapped to an address
430452
function fs.drive.toLetter(address)
431-
for l,a in pairs(fs.drive._map) do
432-
if a == address then return l end
453+
for l,p in pairs(fs.drive._map) do
454+
if p.address == address then return l end
433455
end
434456
return nil
435457
end
436458
function fs.drive.mapAddress(letter, address)
437-
fs.drive._map[letter] = address
459+
--print("mapAddress")
460+
fs.drive._map[letter] = fs.proxy(address)
438461
end
439462
function fs.drive.autoMap(address) --returns the letter if mapped OR already mapped, false if not.
463+
--print("autoMap")
440464
--we get the address and see if it already is mapped...
441465
local l = fs.drive.toLetter(address)
442466
if l then return l end
@@ -450,28 +474,38 @@ function fs_code()
450474
if l == "_" then return false end
451475
end
452476
end
453-
function fs.drive.list()
477+
function fs.drive.listProxy()
454478
local t = fs.drive._map
455-
local a = {}
456-
for n in pairs(t) do table.insert(a, n) end
457-
table.sort(a, f)
479+
local p = {}
480+
for n in pairs(t) do table.insert(p, n) end
481+
table.sort(p, f)
458482
local i = 0 -- iterator variable
459483
local iter = function () -- iterator function
460484
i = i + 1
461-
if a[i] == nil then return nil
462-
else return a[i], t[a[i]]
485+
if p[i] == nil then return nil
486+
else return p[i], t[p[i]]
463487
end
464488
end
465489
return iter
466490
end
491+
function fs.drive.list()
492+
local i = 0 -- iterator variable
493+
local proxyIter = fs.drive.listProxy()
494+
local iter = function () -- iterator function
495+
l, p = proxyIter()
496+
if not l then return nil end
497+
return l, p.address
498+
end
499+
return iter
500+
end
467501
fs.drive._current = "A" --as the boot drive is A:
468502
function fs.drive.setcurrent(letter)
469503
letter = letter:upper()
470504
if not fs.drive._map[letter] then error("Invalid Drive", 2) end
471505
fs.drive._current = letter
472506
end
473507
function fs.drive.getcurrent() return fs.drive._current end
474-
function fs.invoke(method, ...) return component.invoke(fs.drive.toAddress(fs.drive._current), method, ...) end
508+
function fs.invoke(method, ...) return fs.drive._map[fs.drive._current][method](...) end
475509
function fs.proxy(filter)
476510
checkArg(1, filter, "string")
477511
local address
@@ -499,6 +533,39 @@ function fs_code()
499533
function fs.close(handle) return fs.invoke("close", handle) end
500534
function fs.isDirectory(path) return fs.invoke("isDirectory", path) end
501535
function fs.exists(path) return fs.invoke("exists", path) end
536+
function fs.remove(path) return fs.invoke("remove", path) end
537+
function fs.copy(fromPath, toPath)
538+
if fs.isDirectory(fromPath) then
539+
return nil, "cannot copy folders"
540+
end
541+
local input, reason = fs.open(fromPath, "rb")
542+
if not input then
543+
return nil, reason
544+
end
545+
local output, reason = fs.open(toPath, "wb")
546+
if not output then
547+
fs.close(input)
548+
return nil, reason
549+
end
550+
repeat
551+
local buffer, reason = filesystem.read(input)
552+
if not buffer and reason then
553+
return nil, reason
554+
elseif buffer then
555+
local result, reason = filesystem.write(output, buffer)
556+
if not result then
557+
filesystem.close(input)
558+
filesystem.close(output)
559+
return nil, reason
560+
end
561+
end
562+
until not buffer
563+
filesystem.close(input)
564+
filesystem.close(output)
565+
return true
566+
end
567+
function fs.rename(path1, path2) return fs.invoke("rename", path1, path2) end
568+
function fs.makeDirectory(path) return fs.invoke("makeDirectory", path) end
502569
function fs.list(path)
503570
local i = 0
504571
local t = fs.invoke("list", path)
@@ -517,12 +584,18 @@ function fs_code()
517584
end
518585
end
519586
local function onComponentRemoved(_, address, componentType)
520-
if componentType == "filesystem" then
521-
fs.drive.mapAddress(fs.drive.toLetter(address), nil)
587+
if componentType == "filesystem" then
588+
fs.drive.mapAddress(fs.drive.toLetter(address), nil)
589+
end
522590
end
523-
end
524591
event.listen("component_added", onComponentAdded)
525592
event.listen("component_removed", onComponentRemoved)
593+
local function driveInit()
594+
local boot = fs.proxy(computer.getBootAddress())
595+
local temp = fs.proxy(computer.tmpAddress())
596+
fs.drive._map = { ["A"]=boot, ["X"]=temp }
597+
end
598+
driveInit()
526599
--return the API
527600
return fs
528601
end
@@ -1043,15 +1116,14 @@ end
10431116

10441117
print("Starting " .. _OSNAME .. "...\n")
10451118

1119+
--clean up libs
1120+
event_code, component_code, text_code, fs_code, terminal_code = nil, nil, nil, nil, nil
1121+
10461122
--map the drives
10471123
for address, componentType in component.list() do
10481124
if componentType == "filesystem" then filesystem.drive.autoMap(address) end
10491125
end
10501126

1051-
function text.endswith(s, send)
1052-
return #s >= #send and s:find(send, #s-#send+1, true) and true or false
1053-
end
1054-
10551127
miniOS = {}
10561128
local function interrupt(data)
10571129
if data[2] == "RUN" then miniOS.runfile(data[3], table.unpack(data[4])) end

miniOS/power.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local targs = {...}
22
local computer = require("computer")
33
print(...)
44
if not targs[1] then computer.shutdown()
5-
elseif targs[1] == "s" then computer.shutdown()
6-
elseif targs[1] == "r" then computer.shutdown(true) end
7-
error("Could not shutdown!")
5+
elseif targs[1]:sub(1,1) == "s" then computer.shutdown()
6+
elseif targs[1]:sub(1,1) == "r" then computer.shutdown(true)
7+
elseif targs[1] then print("Bad Argument: " .. targs[1] .. "\nTry 'r' or 's' or no argument") return end
8+
error("Could not Shutdown!")

miniOS/sked.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
local b={}
2+
local l=1
3+
local function ctr() s=term.read() s=s:sub(1,s:len()-1) return s end
4+
local function p(d) term.write(d,true) end
5+
while true do
6+
local c=ctr()
7+
if c=="l" then for k,v in pairs(b) do p(v.."\n") end
8+
elseif c=="lc" then p(tostring(b[l]).."\n")
9+
elseif c=="s" then p">" l=tonumber(ctr())
10+
elseif c=="so" then p(l)
11+
elseif c=="a" then p":" table.insert(b,l,ctr()) l=l+1
12+
elseif c=="r" then p":" b[l]=ctr()
13+
elseif c=="d" then p(table.remove(b,l))
14+
elseif c=="o" then p">" local rF=ctr() local f=filesystem.open(rF) local a=filesystem.read(f) filesystem.close(f) for L in a:gmatch("[^\r\n]+") do table.insert(b,l,L) l=l+1 end
15+
elseif c=="w" then p">" local wT=ctr() local f=filesystem.open(wT,"w") for k,v in pairs(b) do filesystem.write(f,v.."\n") end filesystem.close(f)
16+
elseif c=="e" then break else p"?" end end

miniOS/todo.txt

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
use startswith() in shutdown
2-
use fs proxies in fs
1+
pastebin port
32
basic directory support
4-
improve dir command
5-
file management commands
6-
resolution command
7-
handle bad programs in the kernel
3+
resolution+other screen control command
84
fix readkey echo
5+
advanced directory&path support. (paths like MS-DOS. with "/" and "\") (with unix option!)
96
disk cloner + images (miniOS + openOS)
10-
move program starting function to kernel. Improve with command / args to run when done.
7+
move program starting function to kernel. Program Stack? (With arguments)
118
os libary
129
tape drive?
13-
directory support. (paths like MS-DOS. with "/" and "\") (with unix option!)
1410
io implementation
1511
batch files
1612
check for bad drives in command
@@ -19,5 +15,4 @@ very basic require. (libaryies already stored)
1915
automatic clean up of unused drives
2016
run miniOS programs on openOS
2117
use coroutienes for interrupts
22-
make things look nicer
23-
swap internal / external commands?
18+
make things look nicer

miniOS/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
miniOS
2-
0.5.9.5
2+
0.5.9.7
33
Alpha

0 commit comments

Comments
 (0)