--- /dev/null
+#!/usr/bin/lua
+
+local uci = require "uci"
+local fs = require "nixio.fs"
+local u_c = uci.cursor()
+local basepath = u_c.get("filemanager","config","basedir")
+
+local _M = {}
+
+local bp = basepath:match("(.*)/")
+if bp and bp ~= "" then
+ basepath = bp
+end
+_M.basepath = basepath;
+
+function _M.is_in_dir(file, dir)
+ if file == dir then
+ return true
+ else
+ return file:sub(1, #dir) == dir
+ end
+end
+
+function _M.path_valid(path)
+ return _M.is_in_dir(path,_M.basepath) and fs.access(path,"r")
+end
+
+function _M.dir_path_valid(path)
+ return _M.is_in_dir(path,_M.basepath) and fs.stat(path,"type")=="dir" and fs.access(path,"w")
+end
+
+function _M.new_path_valid(path)
+ local dirpath = fs.dirname(path)
+ return _M.is_in_dir(dirpath,_M.basepath) and fs.access(dirpath,"w")
+end
+
+function _M.make_path(path)
+ local realpath = fs.realpath(_M.basepath..'/'..path)
+ if _M.path_valid(realpath) then
+ return realpath
+ else
+ return nil
+ end
+end
+
+function _M.make_new_path(path)
+ local realpath = fs.realpath(fs.dirname(_M.basepath..'/'..path))..'/'..fs.basename(path)
+ if _M.new_path_valid(realpath) then
+ return realpath
+ else
+ return nil
+ end
+end
+
+function _M.make_dir_path(path)
+ local realpath = fs.realpath(_M.basepath..'/'..path)
+ if _M.dir_path_valid(realpath) then
+ return realpath
+ else
+ return nil
+ end
+end
+
+function _M.rm(item)
+ local ftype = fs.stat(item,"type")
+ if ftype == "reg" then
+ return fs.remove(item)
+ elseif ftype == "dir" then
+ local dir = fs.dir(item)
+ for file in dir do
+ if not _M.rm(item..'/'..file) then
+ return false
+ end
+ end
+ return fs.rmdir(item)
+ else
+ return false
+ end
+end
+
+function _M.chmod(item,mode,recursive)
+ local result = fs.chmod(item,mode)
+ if result and recursive then
+ local dir = fs.dir(item)
+ if dir then
+ for file in dir do
+ local ftype = fs.stat(item..'/'..file,"type")
+ if ftype == "dir" then
+ result = _M.chmod(item..'/'..file,mode,recursive)
+ elseif ftype == "reg" then
+ result = _M.chmod(item..'/'..file,string.gsub(mode,"x","-"),false)
+ end
+ if not result then
+ break
+ end
+ end
+ end
+ end
+ return result
+end
+
+return _M
local os = require "os"
local fs = require "nixio.fs"
local json = require "json"
-local uci = require("uci")
-
-local function is_in_dir(file, dir)
- if file == dir then
- return true
- else
- return file:sub(1, #dir) == dir
- end
-end
-
-local function rm(item)
- local ftype = fs.stat(item,"type")
- if ftype == "reg" then
- return fs.remove(item)
- elseif ftype == "dir" then
- local dir = fs.dir(item)
- for file in dir do
- if not rm(item..'/'..file) then
- return false
- end
- end
- return fs.rmdir(item)
- end
-end
-
-local function chmod(item,mode,recursive)
- local result = fs.chmod(item,mode)
- if result and recursive then
- local dir = fs.dir(item)
- if dir then
- for file in dir do
- local ftype = fs.stat(item..'/'..file,"type")
- if ftype == "dir" then
- result = chmod(item..'/'..file,mode,recursive)
- elseif ftype == "reg" then
- result = chmod(item..'/'..file,string.gsub(mode,"x","-"),false)
- end
- if not result then
- break
- end
- end
- end
- end
- return result
-end
+local luafm = require("luafm")
print("Content-type: text/html; charset=utf-8")
print("Cache-control: no-cache")
local params=json.decode(request)
local action=params["action"]
-local u_c = uci.cursor()
-local basepath = u_c.get("filemanager","config","basedir")
-
local path
local items
local item
if action == "list" then
- path = fs.realpath(basepath..'/'..params["path"])
-
- if path and is_in_dir(path,basepath) and fs.access(path,"r") then
+ path = luafm.make_path(params["path"])
+
+ if path then
files = {}
local rec
for name in fs.dir(path) do
basename=fs.realpath(path..'/'..name)
if basename then
- fstat=fs.stat(fs.realpath(path..'/'..name))
+ fstat=fs.stat(basename)
if fstat["type"]=="reg" then
ftype="file"
elseif fstat["type"]=="dir" then
elseif action == "rename" then
- item = fs.realpath(basepath..'/'..params["item"])
- newItemPath = fs.realpath(basepath..'/'..fs.dirname(params["newItemPath"]))..'/'..fs.basename(params["newItemPath"])
+ item = luafm.make_path(params["item"])
+ newItemPath = luafm.make_new_path(params["newItemPath"])
- if is_in_dir(item,basepath) and is_in_dir(newItemPath,basepath) and item ~= basepath and newItemPath ~= basepath then
- result = { result = { success=fs.rename(item,newItemPath), error="" } }
+ if item and newItemPath and item ~= luafm.basepath and newItemPath ~= luafm.basepath then
+ result = fs.rename(item,newItemPath)
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot rename requested file/directory" } }
+ end
else
result = { result = { success=false, error="Invalid path request" } }
end
elseif action == "move" then
items = params["items"]
- newPath = fs.realpath(basepath..'/'..params["newPath"])
+ newPath = luafm.make_dir_path(params["newPath"])
- if is_in_dir(newPath,basepath) then
+ if newPath then
result = true
for key,item in pairs(items) do
- item = fs.realpath(basepath..'/'..item)
- basename = fs.basename(item)
+ item = luafm.make_path(item)
- if is_in_dir(item,basepath) and item ~= basepath then
+ if item and item ~= luafm.basepath then
+ basename = fs.basename(item)
result = fs.move(item,newPath.."/"..basename)
if not result then
break
end
- result = { result = { success=result, error="" } }
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot move requested file/directory" } }
+ end
else
elseif action == "copy" then
items = params["items"]
- newPath = fs.realpath(basepath..'/'..params["newPath"])
- singleFilename = params["singleFilename"]
- if singleFilename then
- singleFilename = fs.basename(singleFilename)
- end
+ newPath = luafm.make_dir_path(params["newPath"])
+
+ if newPath then
- if is_in_dir(newPath,basepath) then
+ singleFilename = params["singleFilename"]
+ if singleFilename then
+ singleFilename = fs.basename(singleFilename)
+ end
result = true
for key,item in pairs(items) do
- item = fs.realpath(basepath..'/'..item)
- if singleFilename then
- basename = singleFilename
- else
- basename = fs.basename(item)
- end
+ item = luafm.make_path(item)
- if is_in_dir(item,basepath) and item ~= basepath then
+ if item and item ~= luafm.basepath then
+ if singleFilename then
+ basename = singleFilename
+ else
+ basename = fs.basename(item)
+ end
result = fs.copy(item,newPath.."/"..basename)
if not result then
break
end
- result = { result = { success=result, error="" } }
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot copy requested file/directory" } }
+ end
else
for key,item in pairs(items) do
- item = fs.realpath(basepath..'/'..item)
+ item = luafm.make_path(item)
- if is_in_dir(item,basepath) and item ~= basepath then
- result = rm(item)
+ if item and item ~= luafm.basepath then
+ result = luafm.rm(item)
if not result then
break
end
end
- result = { result = { success=result, error="" } }
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot remove requested file/directory" } }
+ end
elseif action == "getContent" then
- item = fs.realpath(basepath..'/'..params["item"])
+ item = luafm.make_path(params["item"])
- if is_in_dir(item,basepath) and item ~= basepath then
+ if item and item ~= luafm.basepath then
content = fs.readfile(item)
result = { result = content }
else
elseif action == "edit" then
- item = fs.realpath(basepath..'/'..params["item"])
+ item = luafm.make_path(params["item"])
content = params["content"]
- if is_in_dir(item,basepath) and item ~= basepath then
- result = { result = { success=fs.writefile(item,content), error="" } }
+ if item and item ~= luafm.basepath then
+ result = fs.writefile(item,content)
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot write requested file content" } }
+ end
else
result = { result = { success=false, error="Invalid path request" } }
end
elseif action == "createFolder" then
- newPath = fs.realpath(basepath..'/'..fs.dirname(params["newPath"]))..'/'..fs.basename(params["newPath"])
+ newPath = luafm.make_new_path(params["newPath"])
- if is_in_dir(newPath,basepath) and newPath ~= basepath then
- result = { result = { success=fs.mkdir(newPath), error="" } }
+ if newPath and newPath ~= luafm.basepath then
+ result = fs.mkdir(newPath)
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot create folder" } }
+ end
else
result = { result = { success=false, error="Invalid path request" } }
end
elseif action == "changePermissions" then
items = params["items"]
+
if params["perms"] then
mode = params["perms"]
else
for key,item in pairs(items) do
- item = fs.realpath(basepath..'/'..item)
+ item = luafm.make_path(item)
- if is_in_dir(item,basepath) and item ~= basepath then
- result = chmod(item,mode,recursive)
+ if item and item ~= luafm.basepath then
+ result = luafm.chmod(item,mode,recursive)
if not result then
break
end
end
- result = { result = { success=result, error="" } }
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Cannot change permissions" } }
+ end
else
destination = params["destination"]
compressedFilename = params["compressedFilename"]
- newPath = fs.realpath(basepath..'/'..destination)..'/'..fs.basename(params["compressedFilename"])
+ newPath = luafm.make_new_path(destination..'/'..fs.basename(params["compressedFilename"]))
result = true
files = ""
for key,item in pairs(items) do
- realitem = fs.realpath(basepath..'/'..item)
+ realitem = luafm.make_path(item)
- if is_in_dir(realitem,basepath) and realitem ~= basepath then
+ if realitem and realitem ~= luafm.basepath then
item = item:match("/(.*)")
files = files.." "..item
else
if files then
- command = "cd "..basepath.."; zip -r "..newPath..files
- os.execute(command)
+ command = "cd "..luafm.basepath.."; zip -r "..newPath..files
+ result = os.execute(command)
+
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Archiver returned error" } }
+ end
+
+ else
+
+ result = { result = { success=false, error="No files selected" } }
end
- result = { result = { success=result, error="" } }
-
elseif action == "extract" then
- item = fs.realpath(basepath..'/'..params["item"])
+ item = luafm.make_path(params["item"])
destination = params["destination"]
folderName = params["folderName"]
- newPath = fs.realpath(basepath..'/'..destination)..'/'..fs.basename(params["folderName"])
+ newPath = luafm.make_new_path(destination..'/'..fs.basename(params["folderName"]))
result = true
files = ""
- if is_in_dir(item,basepath) and is_in_dir(newPath,basepath) and item ~= basepath then
+ if item and newPath and item ~= luafm.basepath then
command = "unzip "..item.." -d "..newPath
- os.execute(command)
- result = { result = { success=true, error="" } }
+ result = os.execute(command)
+ if result then
+ result = { result = { success=true, error="" } }
+ else
+ result = { result = { success=false, error="Archiver returned error" } }
+ end
else
result = { result = { success=false, error="Invalid path request" } }
end