56108db953194c958c7edc4bc02e6f7d22c9b8d5
[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 local posix = require "posix"
28 local io = require "io"
29 local type = type
30
31 --- LuCI filesystem library.
32 module "luci.fs"
33
34 --- Test for file access permission on given path.
35 -- @class function
36 -- @name access
37 -- @param str String value containing the path
38 -- @return Number containing the return code, 0 on sucess or nil on error
39 -- @return String containing the error description (if any)
40 -- @return Number containing the os specific errno (if any)
41 access = posix.access
42
43 --- Evaluate given shell glob pattern and return a table containing all matching
44 -- file and directory entries.
45 -- @class function
46 -- @name glob
47 -- @param filename String containing the path of the file to read
48 -- @return Table containing file and directory entries or nil if no matches
49 -- @return String containing the error description (if no matches)
50 -- @return Number containing the os specific errno (if no matches)
51 glob = posix.glob
52
53 --- Checks wheather the given path exists and points to a regular file.
54 -- @param filename String containing the path of the file to read
55 -- @return Boolean indicating wheather given path points to regular file
56 function isfile(filename)
57 return posix.stat(filename, "type") == "regular"
58 end
59
60 --- Read the whole content of the given file into memory.
61 -- @param filename String containing the path of the file to read
62 -- @return String containing the file contents or nil on error
63 -- @return String containing the error message on error
64 function readfile(filename)
65 local fp, err = io.open(filename)
66
67 if fp == nil then
68 return nil, err
69 end
70
71 local data = fp:read("*a")
72 fp:close()
73 return data
74 end
75
76 --- Write the contents of given string to given file.
77 -- @param filename String containing the path of the file to read
78 -- @param data String containing the data to write
79 -- @return Boolean containing true on success or nil on error
80 -- @return String containing the error message on error
81 function writefile(filename, data)
82 local fp, err = io.open(filename, "w")
83
84 if fp == nil then
85 return nil, err
86 end
87
88 fp:write(data)
89 fp:close()
90
91 return true
92 end
93
94 --- Get the last modification time of given file path in Unix epoch format.
95 -- @param path String containing the path of the file or directory to read
96 -- @return Number containing the epoch time or nil on error
97 -- @return String containing the error description (if any)
98 -- @return Number containing the os specific errno (if any)
99 function mtime(path)
100 return posix.stat(path, "mtime")
101 end
102
103 --- Return the last element - usually the filename - from the given path with
104 -- the directory component stripped.
105 -- @class function
106 -- @name basename
107 -- @param path String containing the path to strip
108 -- @return String containing the base name of given path
109 -- @see dirname
110 basename = posix.basename
111
112 --- Return the directory component of the given path with the last element
113 -- stripped of.
114 -- @class function
115 -- @name dirname
116 -- @param path String containing the path to strip
117 -- @return String containing the directory component of given path
118 -- @see basename
119 dirname = posix.dirname
120
121 --- Return a table containing all entries of the specified directory.
122 -- @class function
123 -- @name dir
124 -- @param path String containing the path of the directory to scan
125 -- @return Table containing file and directory entries or nil on error
126 -- @return String containing the error description on error
127 -- @return Number containing the os specific errno on error
128 dir = posix.dir
129
130 --- Create a new directory, recursively on demand.
131 -- @param path String with the name or path of the directory to create
132 -- @param recursive Create multiple directory levels (optional, default is true)
133 -- @return Number with the return code, 0 on sucess or nil on error
134 -- @return String containing the error description on error
135 -- @return Number containing the os specific errno on error
136 function mkdir(path, recursive)
137 if recursive then
138 local base = "."
139
140 if path:sub(1,1) == "/" then
141 base = ""
142 path = path:gsub("^/+","")
143 end
144
145 for elem in path:gmatch("([^/]+)/*") do
146 base = base .. "/" .. elem
147
148 local stat = posix.stat( base )
149
150 if not stat then
151 local stat, errmsg, errno = posix.mkdir( base )
152
153 if type(stat) ~= "number" or stat ~= 0 then
154 return stat, errmsg, errno
155 end
156 else
157 if stat.type ~= "directory" then
158 return nil, base .. ": File exists", 17
159 end
160 end
161 end
162
163 return 0
164 else
165 return posix.mkdir( path )
166 end
167 end
168
169 --- Remove the given empty directory.
170 -- @class function
171 -- @name rmdir
172 -- @param path String containing the path of the directory to remove
173 -- @return Number with the return code, 0 on sucess or nil on error
174 -- @return String containing the error description on error
175 -- @return Number containing the os specific errno on error
176 rmdir = posix.rmdir
177
178 --- Get information about given file or directory.
179 -- @class function
180 -- @name stat
181 -- @param path String containing the path of the directory to query
182 -- @return Table containing file or directory properties or nil on error
183 -- @return String containing the error description on error
184 -- @return Number containing the os specific errno on error
185 stat = posix.stat
186
187 --- Set permissions on given file or directory.
188 -- @class function
189 -- @name chmod
190 -- @param path String containing the path of the directory
191 -- @param perm String containing the permissions to set ([ugoa][+-][rwx])
192 -- @return Number with the return code, 0 on sucess or nil on error
193 -- @return String containing the error description on error
194 -- @return Number containing the os specific errno on error
195 chmod = posix.chmod
196
197 --- Create a hard- or symlink from given file (or directory) to specified target
198 -- file (or directory) path.
199 -- @class function
200 -- @name link
201 -- @param path1 String containing the source path to link
202 -- @param path2 String containing the destination path for the link
203 -- @param symlink Boolean indicating wheather to create a symlink (optional)
204 -- @return Number with the return code, 0 on sucess or nil on error
205 -- @return String containing the error description on error
206 -- @return Number containing the os specific errno on error
207 link = posix.link
208
209 --- Remove the given file.
210 -- @class function
211 -- @name unlink
212 -- @param path String containing the path of the file to remove
213 -- @return Number with the return code, 0 on sucess or nil on error
214 -- @return String containing the error description on error
215 -- @return Number containing the os specific errno on error
216 unlink = posix.unlink
217
218 --- Retrieve target of given symlink.
219 -- @class function
220 -- @name readlink
221 -- @param path String containing the path of the symlink to read
222 -- @return String containing the link target or nil on error
223 -- @return String containing the error description on error
224 -- @return Number containing the os specific errno on error
225 readlink = posix.readlink