e089d55dd04bfa1a508dd5b6cbfffdf0b6c2a1a6
[project/luci.git] / libs / core / luasrc / fs.lua
1 --[[
2 LuCI - Filesystem tools
3
4 Description:
5 A module offering often needed filesystem manipulation functions
6
7 FileId:
8 $Id$
9
10 License:
11 Copyright 2008 Steven Barth <steven@midlink.org>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
16
17         http://www.apache.org/licenses/LICENSE-2.0
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 ]]--
26
27 --- LuCI filesystem library.
28 module("luci.fs", package.seeall)
29
30 require("posix")
31
32 --- Test for file access permission on given path.
33 -- @class               function
34 -- @name                access
35 -- @param str   String value containing the path
36 -- @return              Number containing the return code, 0 on sucess or nil on error
37 -- @return              String containing the error description (if any)
38 -- @return              Number containing the os specific errno (if any)
39 access = posix.access
40
41 --- Evaluate given shell glob pattern and return a table containing all matching
42 -- file and directory entries.
43 -- @class                       function
44 -- @name                        glob
45 -- @param filename      String containing the path of the file to read
46 -- @return                      Table containing file and directory entries or nil if no matches
47 -- @return                      String containing the error description (if no matches)
48 -- @return                      Number containing the os specific errno (if no matches)
49 glob = posix.glob
50
51 --- Checks wheather the given path exists and points to a regular file.
52 -- @param filename      String containing the path of the file to read
53 -- @return                      Boolean indicating wheather given path points to regular file
54 function isfile(filename)
55         return posix.stat(filename, "type") == "regular"
56 end
57
58 --- Read the whole content of the given file into memory.
59 -- @param filename      String containing the path of the file to read
60 -- @return                      String containing the file contents or nil on error
61 -- @return                      String containing the error message on error
62 function readfile(filename)
63         local fp, err = io.open(filename)
64
65         if fp == nil then
66                 return nil, err
67         end
68
69         local data = fp:read("*a")
70         fp:close()
71         return data
72 end
73
74 --- Write the contents of given string to given file.
75 -- @param filename      String containing the path of the file to read
76 -- @param data          String containing the data to write
77 -- @return                      Boolean containing true on success or nil on error
78 -- @return                      String containing the error message on error
79 function writefile(filename, data)
80         local fp, err = io.open(filename, "w")
81
82         if fp == nil then
83                 return nil, err
84         end
85
86         fp:write(data)
87         fp:close()
88
89         return true
90 end
91
92 --- Get the last modification time of given file path in Unix epoch format.
93 -- @param path  String containing the path of the file or directory to read
94 -- @return              Number containing the epoch time or nil on error
95 -- @return              String containing the error description (if any)
96 -- @return              Number containing the os specific errno (if any)
97 function mtime(path)
98         return posix.stat(path, "mtime")
99 end
100
101 --- Return the last element - usually the filename - from the given path with
102 -- the directory component stripped.
103 -- @class               function
104 -- @name                basename
105 -- @param path  String containing the path to strip
106 -- @return              String containing the base name of given path
107 -- @see                 dirname
108 basename = posix.basename
109
110 --- Return the directory component of the given path with the last element
111 -- stripped of.
112 -- @class               function
113 -- @name                dirname
114 -- @param path  String containing the path to strip
115 -- @return              String containing the directory component of given path
116 -- @see                 basename
117 dirname = posix.dirname
118
119 --- Return a table containing all entries of the specified directory.
120 -- @class               function
121 -- @name                dir
122 -- @param path  String containing the path of the directory to scan
123 -- @return              Table containing file and directory entries or nil on error
124 -- @return              String containing the error description on error
125 -- @return              Number containing the os specific errno on error
126 dir = posix.dir
127
128 --- Create a new directory, recursively on demand.
129 -- @param path          String with the name or path of the directory to create
130 -- @param recursive     Create multiple directory levels (optional, default is true)
131 -- @return                      Number with the return code, 0 on sucess or nil on error
132 -- @return                      String containing the error description on error
133 -- @return                      Number containing the os specific errno on error
134 function mkdir(path, recursive)
135         if recursive then
136                 local base = "."
137
138                 if path:sub(1,1) == "/" then
139                         base = ""
140                         path = path:gsub("^/+","")
141                 end
142
143                 for elem in path:gmatch("([^/]+)/*") do
144                         base = base .. "/" .. elem
145
146                         local stat = posix.stat( base )
147
148                         if not stat then
149                                 local stat, errmsg, errno = posix.mkdir( base )
150
151                                 if type(stat) ~= "number" or stat ~= 0 then
152                                         return stat, errmsg, errno
153                                 end
154                         else
155                                 if stat.type ~= "directory" then
156                                         return nil, base .. ": File exists", 17
157                                 end
158                         end
159                 end
160
161                 return 0
162         else
163                 return posix.mkdir( path )
164         end
165 end
166
167 --- Remove the given empty directory.
168 -- @class               function
169 -- @name                rmdir
170 -- @param path  String containing the path of the directory to remove
171 -- @return              Number with the return code, 0 on sucess or nil on error
172 -- @return              String containing the error description on error
173 -- @return              Number containing the os specific errno on error
174 rmdir = posix.rmdir
175
176 --- Get information about given file or directory.
177 -- @class               function
178 -- @name                stat
179 -- @param path  String containing the path of the directory to query
180 -- @return              Table containing file or directory properties or nil on error
181 -- @return              String containing the error description on error
182 -- @return              Number containing the os specific errno on error
183 stat = posix.stat
184
185 --- Set permissions on given file or directory.
186 -- @class               function
187 -- @name                chmod
188 -- @param path  String containing the path of the directory
189 -- @param perm  String containing the permissions to set ([ugoa][+-][rwx])
190 -- @return              Number with the return code, 0 on sucess or nil on error
191 -- @return              String containing the error description on error
192 -- @return              Number containing the os specific errno on error
193 chmod = posix.chmod
194
195 --- Create a hard- or symlink from given file (or directory) to specified target
196 -- file (or directory) path.
197 -- @class                       function
198 -- @name                        link
199 -- @param path1         String containing the source path to link
200 -- @param path2         String containing the destination path for the link
201 -- @param symlink       Boolean indicating wheather to create a symlink (optional)
202 -- @return                      Number with the return code, 0 on sucess or nil on error
203 -- @return                      String containing the error description on error
204 -- @return                      Number containing the os specific errno on error
205 link = posix.link
206
207 --- Remove the given file.
208 -- @class               function
209 -- @name                unlink
210 -- @param path  String containing the path of the file to remove
211 -- @return              Number with the return code, 0 on sucess or nil on error
212 -- @return              String containing the error description on error
213 -- @return              Number containing the os specific errno on error
214 unlink = posix.unlink
215
216 --- Retrieve target of given symlink.
217 -- @class               function
218 -- @name                readlink
219 -- @param path  String containing the path of the symlink to read
220 -- @return              String containing the link target or nil on error
221 -- @return              String containing the error description on error
222 -- @return              Number containing the os specific errno on error
223 readlink = posix.readlink