Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
2.9KB

  1. fs = {}
  2. fs.mounts = {}
  3. -- basics
  4. function fs.segments(path) -- splits *path* on each /
  5. local segments = {}
  6. for segment in path:gmatch("[^/]+") do
  7. segments[#segments+1] = segment
  8. end
  9. return segments
  10. end
  11. function fs.resolve(path) -- resolves *path* to a specific filesystem mount and path
  12. if not path or path == "." then path = os.getenv("PWD") end
  13. if path:sub(1,1) ~= "/" then path=(os.getenv("PWD") or "").."/"..path end
  14. local segments, rpath = fs.segments(path), "/"
  15. for i = 2, #segments do
  16. rpath = rpath .. segments[i] .. "/"
  17. end
  18. rpath = rpath:match("(.+)/") or rpath
  19. return segments[1] or "root",rpath
  20. end
  21. -- generate some simple functions
  22. for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","remove","size","spaceUsed","isReadOnly","getLabel"}) do
  23. fs[v] = function(path)
  24. local fsi,path = fs.resolve(path)
  25. return fs.mounts[fsi][v](path)
  26. end
  27. end
  28. local function fread(self,length)
  29. if length == "*a" then
  30. length = math.huge
  31. end
  32. if type(length) == "number" then
  33. local rstr, lstr = "", ""
  34. repeat
  35. lstr = fs.mounts[self.fs].read(self.fid,math.min(2^16,length-rstr:len())) or ""
  36. rstr = rstr .. lstr
  37. until rstr:len() == length or lstr == ""
  38. return rstr
  39. end
  40. return fs.mounts[self.fs].read(self.fid,length)
  41. end
  42. local function fwrite(self,data)
  43. fs.mounts[self.fs].write(self.fid,data)
  44. end
  45. local function fseek(self,dist)
  46. fs.mounts[self.fs].seek(self.fid,dist)
  47. end
  48. local function fclose(self)
  49. fs.mounts[self.fs].close(self.fid)
  50. end
  51. function fs.open(path,mode) -- opens file *path* with mode *mode*
  52. mode = mode or "rb"
  53. local fsi,path = fs.resolve(path)
  54. if not fs.mounts[fsi] then return false end
  55. local fid = fs.mounts[fsi].open(path,mode)
  56. if fid then
  57. local fobj = {["fs"]=fsi,["fid"]=fid,["seek"]=fseek,["close"]=fclose}
  58. if mode:find("r") then
  59. fobj.read = fread
  60. end
  61. if mode:find("w") then
  62. fobj.write = fwrite
  63. end
  64. return fobj
  65. end
  66. return false
  67. end
  68. function fs.copy(from,to) -- copies a file from *from* to *to*
  69. local of = fs.open(from,"rb")
  70. local df = fs.open(to,"wb")
  71. if not of or not df then
  72. return false
  73. end
  74. df:write(of:read("*a"))
  75. df:close()
  76. of:close()
  77. end
  78. function fs.rename(from,to) -- moves file *from* to *to*
  79. local ofsi, opath = fs.resolve(from)
  80. local dfsi, dpath = fs.resolve(to)
  81. if ofsi == dfsi then
  82. fs.mounts[ofsi].rename(opath,dpath)
  83. return true
  84. end
  85. fs.copy(from,to)
  86. fs.remove(from)
  87. return true
  88. end
  89. fs.mounts.temp = component.proxy(computer.tmpAddress())
  90. if computer.getBootAddress then
  91. fs.mounts.boot = component.proxy(computer.getBootAddress())
  92. end
  93. for addr, _ in component.list("filesystem") do
  94. fs.mounts[addr:sub(1,3)] = component.proxy(addr)
  95. end
  96. local function rf()
  97. return false
  98. end
  99. fs.mounts.root = {}
  100. for k,v in pairs(fs.mounts.temp) do
  101. fs.mounts.root[k] = rf
  102. end
  103. function fs.mounts.root.list()
  104. local t = {}
  105. for k,v in pairs(fs.mounts) do
  106. t[#t+1] = k
  107. end
  108. t.n = #t
  109. return t
  110. end
  111. function fs.mounts.root.isReadOnly()
  112. return true
  113. end