summaryrefslogtreecommitdiffhomepage
path: root/libs/luci-lib-nixio/root/usr/lib/lua/nixio/fs.lua
blob: 8883835f303796ce317bf1a0f6bd367d84a1ba94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
--[[
nixio - Linux I/O library for lua

Copyright 2009 Steven Barth <steven@midlink.org>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

$Id$
]]--

local table = require "table"
local nixio = require "nixio"
local type, ipairs, setmetatable = type, ipairs, setmetatable
require "nixio.util"


module ("nixio.fs", function(m) setmetatable(m, {__index = nixio.fs}) end)


function readfile(path, limit)
	local fd, code, msg = nixio.open(path, "r")
	local data
	if not fd then
		return nil, code, msg
	end
	
	data, code, msg = fd:readall(limit)
	
	fd:close()
	return data, code, msg
end


function writefile(path, data)
	local fd, code, msg, stat = nixio.open(path, "w")
	if not fd then
		return nil, code, msg
	end
	
	stat, code, msg = fd:writeall(data)
	
	fd:close()
	return stat, code, msg
end

function datacopy(src, dest, size)
	local fdin, code, msg = nixio.open(src, "r")
	if not fdin then
		return nil, code, msg
	end
	
	local fdout, code, msg = nixio.open(dest, "w")
	if not fdout then
		return nil, code, msg
	end	
	
	local stat, code, msg, sent = fdin:copy(fdout, size)
	fdin:close()
	fdout:close()

	return stat, code, msg, sent
end

function copy(src, dest)
	local stat, code, msg, res = nixio.fs.lstat(src)
	if not stat then
		return nil, code, msg
	end
	
	if stat.type == "dir" then
		if nixio.fs.stat(dest, type) ~= "dir" then
			res, code, msg = nixio.fs.mkdir(dest)
		else
			stat = true
		end
	elseif stat.type == "lnk" then
		res, code, msg = nixio.fs.symlink(nixio.fs.readlink(src), dest)
	elseif stat.type == "reg" then
		res, code, msg = datacopy(src, dest)
	end
	
	if not res then
		return nil, code, msg
	end
	
	nixio.fs.utimes(dest, stat.atime, stat.mtime)
	
	if nixio.fs.lchown then
		nixio.fs.lchown(dest, stat.uid, stat.gid)
	end
	
	if stat.type ~= "lnk" then
		nixio.fs.chmod(dest, stat.modedec)
	end
	
	return true
end

function move(src, dest)
	local stat, code, msg = nixio.fs.rename(src, dest)
	if not stat and code == nixio.const.EXDEV then
		stat, code, msg = copy(src, dest)
		if stat then
			stat, code, msg = nixio.fs.unlink(src)
		end
	end
	return stat, code, msg
end

function mkdirr(dest, mode)
	if nixio.fs.stat(dest, "type") == "dir" then
		return true
	else
		local stat, code, msg = nixio.fs.mkdir(dest, mode)
		if not stat and code == nixio.const.ENOENT then
			stat, code, msg = mkdirr(nixio.fs.dirname(dest), mode)
			if stat then
				stat, code, msg = nixio.fs.mkdir(dest, mode)
			end
		end
		return stat, code, msg
	end
end

local function _recurse(cb, src, dest)
	local type = nixio.fs.lstat(src, "type")
	if type ~= "dir" then
		return cb(src, dest)
	else
		local stat, se, code, msg, s, c, m = true, nixio.const.sep
		if dest then
			s, c, m = cb(src, dest)
			stat, code, msg = stat and s, c or code, m or msg
		end

		for e in nixio.fs.dir(src) do
			if dest then
				s, c, m = _recurse(cb, src .. se .. e, dest .. se .. e)
			else
				s, c, m = _recurse(cb, src .. se .. e)
			end
			stat, code, msg = stat and s, c or code, m or msg
		end

		if not dest then							-- Postfix
			s, c, m = cb(src)
			stat, code, msg = stat and s, c or code, m or msg
		end

		return stat, code, msg
	end
end

function copyr(src, dest)
	return _recurse(copy, src, dest)
end

function mover(src, dest)
	local stat, code, msg = nixio.fs.rename(src, dest)
	if not stat and code == nixio.const.EXDEV then
		stat, code, msg = _recurse(copy, src, dest)
		if stat then
			stat, code, msg = _recurse(nixio.fs.remove, src)
		end
	end
	return stat, code, msg
end

function remover(src)
	return _recurse(nixio.fs.remove, src)
end