Mercurial > prosody-hg
comparison util/datamanager.lua @ 8015:ecb110f45c92
Merge 0.10->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 28 Mar 2017 20:14:35 +0200 |
| parents | ff3787033abb |
| children | 0a1c0f1107d2 |
comparison
equal
deleted
inserted
replaced
| 8009:1c311d8c1443 | 8015:ecb110f45c92 |
|---|---|
| 15 local log = require "util.logger".init("datamanager"); | 15 local log = require "util.logger".init("datamanager"); |
| 16 local io_open = io.open; | 16 local io_open = io.open; |
| 17 local os_remove = os.remove; | 17 local os_remove = os.remove; |
| 18 local os_rename = os.rename; | 18 local os_rename = os.rename; |
| 19 local tonumber = tonumber; | 19 local tonumber = tonumber; |
| 20 local tostring = tostring; | |
| 21 local next = next; | 20 local next = next; |
| 22 local type = type; | 21 local type = type; |
| 23 local t_insert = table.insert; | 22 local t_insert = table.insert; |
| 24 local t_concat = table.concat; | 23 local t_concat = table.concat; |
| 25 local envloadfile = require"util.envload".envloadfile; | 24 local envloadfile = require"util.envload".envloadfile; |
| 29 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) | 28 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) |
| 30 | 29 |
| 31 local prosody = prosody; | 30 local prosody = prosody; |
| 32 | 31 |
| 33 local raw_mkdir = lfs.mkdir; | 32 local raw_mkdir = lfs.mkdir; |
| 34 local function fallocate(f, offset, len) | 33 local atomic_append; |
| 35 -- This assumes that current position == offset | |
| 36 local fake_data = (" "):rep(len); | |
| 37 local ok, msg = f:write(fake_data); | |
| 38 if not ok then | |
| 39 return ok, msg; | |
| 40 end | |
| 41 f:seek("set", offset); | |
| 42 return true; | |
| 43 end; | |
| 44 local ENOENT = 2; | 34 local ENOENT = 2; |
| 45 pcall(function() | 35 pcall(function() |
| 46 local pposix = require "util.pposix"; | 36 local pposix = require "util.pposix"; |
| 47 raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask | 37 raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask |
| 48 fallocate = pposix.fallocate or fallocate; | 38 atomic_append = pposix.atomic_append; |
| 49 ENOENT = pposix.ENOENT or ENOENT; | 39 ENOENT = pposix.ENOENT or ENOENT; |
| 50 end); | 40 end); |
| 51 | 41 |
| 52 local _ENV = nil; | 42 local _ENV = nil; |
| 53 | 43 |
| 60 return s and (s:gsub("%%(%x%x)", urlcodes)); | 50 return s and (s:gsub("%%(%x%x)", urlcodes)); |
| 61 end | 51 end |
| 62 | 52 |
| 63 encode = function (s) | 53 encode = function (s) |
| 64 return s and (s:gsub("%W", function (c) return format("%%%02x", c:byte()); end)); | 54 return s and (s:gsub("%W", function (c) return format("%%%02x", c:byte()); end)); |
| 55 end | |
| 56 end | |
| 57 | |
| 58 if not atomic_append then | |
| 59 function atomic_append(f, data) | |
| 60 local pos = f:seek(); | |
| 61 if not f:write(data) or not f:flush() then | |
| 62 f:seek("set", pos); | |
| 63 f:write((" "):rep(#data)); | |
| 64 f:flush(); | |
| 65 return nil, "write-failed"; | |
| 66 end | |
| 67 return true; | |
| 65 end | 68 end |
| 66 end | 69 end |
| 67 | 70 |
| 68 local _mkdir = {}; | 71 local _mkdir = {}; |
| 69 local function mkdir(path) | 72 local function mkdir(path) |
| 218 -- Append a blob of data to a file | 221 -- Append a blob of data to a file |
| 219 local function append(username, host, datastore, ext, data) | 222 local function append(username, host, datastore, ext, data) |
| 220 if type(data) ~= "string" then return; end | 223 if type(data) ~= "string" then return; end |
| 221 local filename = getpath(username, host, datastore, ext, true); | 224 local filename = getpath(username, host, datastore, ext, true); |
| 222 | 225 |
| 223 local ok; | 226 local f = io_open(filename, "r+"); |
| 224 local f, msg = io_open(filename, "r+"); | |
| 225 if not f then | 227 if not f then |
| 226 return atomic_store(filename, data); | 228 return atomic_store(filename, data); |
| 227 -- File did probably not exist, let's create it | 229 -- File did probably not exist, let's create it |
| 228 end | 230 end |
| 229 | 231 |
| 230 local pos = f:seek("end"); | 232 local pos = f:seek("end"); |
| 231 ok, msg = fallocate(f, pos, #data); | 233 |
| 232 if not ok then | 234 local ok, msg = atomic_append(f, data); |
| 233 log("warn", "fallocate() failed: %s", tostring(msg)); | 235 |
| 234 -- This doesn't work on every file system | |
| 235 end | |
| 236 | |
| 237 if f:seek() ~= pos then | |
| 238 log("debug", "fallocate() changed file position"); | |
| 239 f:seek("set", pos); | |
| 240 end | |
| 241 | |
| 242 ok, msg = f:write(data); | |
| 243 if not ok then | 236 if not ok then |
| 244 f:close(); | 237 f:close(); |
| 245 return ok, msg, "write"; | 238 return ok, msg, "write"; |
| 246 end | 239 end |
| 247 | 240 |
| 248 ok, msg = f:close(); | 241 ok, msg = f:close(); |
| 249 if not ok then | 242 if not ok then |
| 250 return ok, msg; | 243 return ok, msg, "close"; |
| 251 end | 244 end |
| 252 | 245 |
| 253 return true, pos; | 246 return true, pos; |
| 254 end | 247 end |
| 255 | 248 |
| 257 if not data then return; end | 250 if not data then return; end |
| 258 if callback(username, host, datastore) == false then return true; end | 251 if callback(username, host, datastore) == false then return true; end |
| 259 -- save the datastore | 252 -- save the datastore |
| 260 | 253 |
| 261 data = "item(" .. serialize(data) .. ");\n"; | 254 data = "item(" .. serialize(data) .. ");\n"; |
| 262 local ok, msg = append(username, host, datastore, "list", data); | 255 local ok, msg, where = append(username, host, datastore, "list", data); |
| 263 if not ok then | 256 if not ok then |
| 264 log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil"); | 257 log("error", "Unable to write to %s storage ('%s' in %s) for user: %s@%s", |
| 258 datastore, msg, where, username or "nil", host or "nil"); | |
| 265 return ok, msg; | 259 return ok, msg; |
| 266 end | 260 end |
| 267 return true; | 261 return true; |
| 268 end | 262 end |
| 269 | 263 |
