669ebd0364261ca7193445e192a6d80d3d664450
[lua-filemanager.git] / www / cgi-bin / fs
1 #!/usr/bin/lua
2
3 local os = require "os"
4 local fs = require "nixio.fs"
5 local json = require "json"
6 local uci = require("uci")
7
8 local function is_in_dir(file, dir)
9   if file == dir then
10     return true
11   else   
12     return file:sub(1, #dir) == dir
13   end  
14 end
15
16 local function rm(item)
17   local ftype = fs.stat(item,"type")
18   if ftype == "reg" then
19     return fs.remove(item)
20   elseif ftype == "dir" then
21     local dir = fs.dir(item)
22     for file in dir do
23       if not rm(item..'/'..file) then
24         return false
25       end
26     end
27     return fs.rmdir(item)  
28   end
29 end
30
31 local function chmod(item,mode,recursive)
32   local result = fs.chmod(item,mode)
33   if result and recursive then
34     local dir = fs.dir(item)
35     if dir then
36       for file in dir do
37         local ftype = fs.stat(item..'/'..file,"type")
38         if ftype == "dir" then
39           result = chmod(item..'/'..file,mode,recursive)
40         elseif ftype == "reg" then
41           result = chmod(item..'/'..file,string.gsub(mode,"x","-"),false)  
42         end
43         if not result then
44           break
45         end  
46       end
47     end
48   end
49   return result
50 end
51
52 print("Content-type: text/html; charset=utf-8")
53 print("Cache-control: no-cache")
54 print("Pragma: no-cache")
55
56 -- prepare the browser for content:
57 print("\r")
58
59 local result
60
61 local http_headers = nixio.getenv()
62 local request=io.read("*all")
63
64 local params=json.decode(request)
65 local action=params["action"]
66
67 local u_c = uci.cursor()
68 local basepath = u_c.get("filemanager","config","basedir")
69
70 local path
71 local items
72 local item
73 local newItemPath
74 local newPath
75 local singleFilename
76 local content
77 local mode
78 local destination
79 local compressedFilename
80 local recursive
81 local folderName
82
83 local files
84 local fstat
85 local ftype
86 local basename
87 local realitem
88 local command
89
90 if action == "list" then
91
92   path = fs.realpath(basepath..'/'..params["path"])
93   
94   if is_in_dir(path,basepath) then
95     files = {}
96     local rec
97     for name in fs.dir(path) do
98       fstat=fs.stat(fs.realpath(path..'/'..name))
99       if fstat["type"]=="reg" then
100         ftype="file"
101       elseif fstat["type"]=="dir" then
102         ftype="dir"
103       else
104         ftype=""
105       end      
106       if ftype then
107         rec={name=name,rights=fstat["modestr"],size=fstat["size"],type=ftype,date=os.date('%Y-%m-%d %H:%M:%S',fstat["mtime"])}
108         table.insert(files,rec)
109       end  
110     end
111     result = { result = files }
112   else
113     result = { result = {} }
114   end
115
116 elseif action == "rename" then
117
118   item = fs.realpath(basepath..'/'..params["item"])
119   newItemPath = fs.realpath(basepath..'/'..fs.dirname(params["newItemPath"]))..'/'..fs.basename(params["newItemPath"])
120
121   if is_in_dir(item,basepath) and is_in_dir(newItemPath,basepath) and item ~= basepath and newItemPath ~= basepath then
122     result = { result = { success=fs.rename(item,newItemPath), error="" } }
123   else
124     result = { result = { success=false, error="Invalid path request" } }
125   end
126
127 elseif action == "move" then
128
129   items = params["items"]
130   newPath = fs.realpath(basepath..'/'..params["newPath"])
131   
132   if is_in_dir(newPath,basepath) then
133
134     result = true
135
136     for key,item in pairs(items) do
137
138       item = fs.realpath(basepath..'/'..item)
139       basename = fs.basename(item)
140
141       if is_in_dir(item,basepath) and item ~= basepath then
142         result = fs.move(item,newPath.."/"..basename)
143         if not result then 
144           break
145         end
146       else
147         result = false
148         break
149       end
150       
151     end  
152
153     result = { result = { success=result, error="" } }
154
155   else
156
157     result = { result = { success=false, error="Invalid destination request" } }
158
159   end  
160
161 elseif action == "copy" then
162
163   items = params["items"]
164   newPath = fs.realpath(basepath..'/'..params["newPath"])
165   singleFilename = params["singleFilename"]
166   if singleFilename then
167     singleFilename = fs.basename(singleFilename)
168   end
169
170   if is_in_dir(newPath,basepath) then
171
172     result = true
173
174     for key,item in pairs(items) do
175
176       item = fs.realpath(basepath..'/'..item)
177       if singleFilename then
178         basename = singleFilename
179       else  
180         basename = fs.basename(item)
181       end
182
183       if is_in_dir(item,basepath) and item ~= basepath then
184         result = fs.copy(item,newPath.."/"..basename)
185         if not result then 
186           break
187         end
188       else
189         result = false
190         break
191       end
192
193     end  
194
195     result = { result = { success=result, error="" } }
196
197   else
198
199     result = { result = { success=false, error="Invalid destination request" } }
200
201   end  
202
203 elseif action == "remove" then
204
205   items = params["items"]
206
207   result = true
208
209   for key,item in pairs(items) do
210
211     item = fs.realpath(basepath..'/'..item)
212
213     if is_in_dir(item,basepath) and item ~= basepath then
214       result = rm(item)
215       if not result then 
216         break
217       end
218     else
219       result = false
220       break
221     end
222
223   end
224
225   result = { result = { success=result, error="" } }
226
227 elseif action == "getContent" then
228
229   item = fs.realpath(basepath..'/'..params["item"])
230   
231   if is_in_dir(item,basepath) and item ~= basepath then
232     content = fs.readfile(item)
233     result = { result = content }
234   else
235     result = { result = { success=false, error="Invalid path request" } }
236   end
237
238 elseif action == "edit" then
239
240   item = fs.realpath(basepath..'/'..params["item"])
241   content = params["content"]
242   
243   if is_in_dir(item,basepath) and item ~= basepath then
244     result = { result = { success=fs.writefile(item,content), error="" } }
245   else
246     result = { result = { success=false, error="Invalid path request" } }
247   end
248
249 elseif action == "createFolder" then
250
251   newPath = fs.realpath(basepath..'/'..fs.dirname(params["newPath"]))..'/'..fs.basename(params["newPath"])
252   
253   if is_in_dir(newPath,basepath) and newPath ~= basepath then
254     result = { result = { success=fs.mkdir(newPath), error="" } }
255   else
256     result = { result = { success=false, error="Invalid path request" } }
257   end
258
259 elseif action == "changePermissions" then
260
261   items = params["items"]
262   if params["perms"] then
263     mode = params["perms"]
264   else
265     mode = params["permsCode"]
266   end
267   
268   if mode then
269     
270     recursive = params["recursive"]
271
272     result = true
273
274     for key,item in pairs(items) do
275
276       item = fs.realpath(basepath..'/'..item)
277
278       if is_in_dir(item,basepath) and item ~= basepath then
279         result = chmod(item,mode,recursive)
280         if not result then 
281           break
282         end
283       else
284         result = false
285         break
286       end
287
288     end
289
290     result = { result = { success=result, error="" } }
291
292   else
293   
294     result = { result = { success=false, error="No permission requested" } }
295   
296   end
297
298 elseif action == "compress" then
299
300   items = params["items"]
301   destination = params["destination"]
302   compressedFilename = params["compressedFilename"]
303
304   newPath = fs.realpath(basepath..'/'..destination)..'/'..fs.basename(params["compressedFilename"])
305
306   result = true
307   files = ""
308
309   for key,item in pairs(items) do
310
311     realitem = fs.realpath(basepath..'/'..item)
312
313     if is_in_dir(realitem,basepath) and realitem ~= basepath then
314       item = item:match("/(.*)")
315       files = files.." "..item
316     else
317       result = false
318       break
319     end
320
321   end
322   
323   if files then
324
325     command = "cd "..basepath.."; zip -r "..newPath..files
326     os.execute(command)
327   
328   end
329
330   result = { result = { success=result, error="" } }
331
332 elseif action == "extract" then
333
334   item = fs.realpath(basepath..'/'..params["item"])
335   destination = params["destination"]
336   folderName = params["folderName"]
337
338   newPath = fs.realpath(basepath..'/'..destination)..'/'..fs.basename(params["folderName"])
339
340   result = true
341   files = ""
342
343   if is_in_dir(item,basepath) and is_in_dir(newPath,basepath) and item ~= basepath then
344     command = "unzip "..item.." -d "..newPath
345     os.execute(command)
346     result = { result = { success=true, error="" } }
347   else
348     result = { result = { success=false, error="Invalid path request" } }
349   end
350
351
352 else
353
354   result = { result = { success=false, error="Operation not impolemented yet" } }
355
356 end
357
358 print(json.encode(result))