mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-06-07 02:40:51 +00:00
This commit is contained in:
parent
499365e2ca
commit
30d9844f8f
|
@ -31,7 +31,7 @@ slowbash = {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
spawnShell(inlet.blanketEvent(), collect,
|
spawnShell(inlet.createBlanketEvent(), collect,
|
||||||
[[if [ "$(ls -A $1)" ]; then cp -r "$1"* "$2"; fi]],
|
[[if [ "$(ls -A $1)" ]; then cp -r "$1"* "$2"; fi]],
|
||||||
c.source, c.target)
|
c.source, c.target)
|
||||||
end,
|
end,
|
||||||
|
|
3
lsyncd.c
3
lsyncd.c
|
@ -1252,7 +1252,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/* checks if there is a "-help" or "--help" before anything more */
|
/* checks if there is a "-help" or "--help" */
|
||||||
int i;
|
int i;
|
||||||
for(i = argp; i < argc; i++) {
|
for(i = argp; i < argc; i++) {
|
||||||
if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) {
|
if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) {
|
||||||
|
@ -1292,7 +1292,6 @@ main(int argc, char *argv[])
|
||||||
lua_pop(L, 2); // TODO
|
lua_pop(L, 2); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (lsyncd_config_file) {
|
if (lsyncd_config_file) {
|
||||||
/* checks for the configuration and existence of the config file */
|
/* checks for the configuration and existence of the config file */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
154
lsyncd.lua
154
lsyncd.lua
|
@ -182,11 +182,12 @@ local Delay = (function()
|
||||||
-- Creates a new delay.
|
-- Creates a new delay.
|
||||||
--
|
--
|
||||||
-- @param TODO
|
-- @param TODO
|
||||||
local function new(etype, path, alarm)
|
local function new(etype, alarm, path, path2)
|
||||||
local o = {
|
local o = {
|
||||||
etype = etype,
|
etype = etype,
|
||||||
alarm = alarm,
|
alarm = alarm,
|
||||||
path = path,
|
path = path,
|
||||||
|
path2 = path2,
|
||||||
status = "wait",
|
status = "wait",
|
||||||
}
|
}
|
||||||
return o
|
return o
|
||||||
|
@ -349,7 +350,7 @@ local Inlet, InletControl = (function()
|
||||||
-- Creates a blanketEvent that blocks everything
|
-- Creates a blanketEvent that blocks everything
|
||||||
-- and is blocked by everything.
|
-- and is blocked by everything.
|
||||||
--
|
--
|
||||||
local function blanketEvent()
|
local function createBlanketEvent()
|
||||||
return toEvent(sync:addBlanketDelay())
|
return toEvent(sync:addBlanketDelay())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -372,7 +373,7 @@ local Inlet, InletControl = (function()
|
||||||
-- Interface for lsyncd runner to control what
|
-- Interface for lsyncd runner to control what
|
||||||
-- the inlet will present the user.
|
-- the inlet will present the user.
|
||||||
--
|
--
|
||||||
local function set(setSync)
|
local function setSync(setSync)
|
||||||
sync = setSync
|
sync = setSync
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -389,10 +390,11 @@ local Inlet, InletControl = (function()
|
||||||
return {
|
return {
|
||||||
getEvent = getEvent,
|
getEvent = getEvent,
|
||||||
getConfig = getConfig,
|
getConfig = getConfig,
|
||||||
blanketEvent = blanketEvent
|
createBlanketEvent = createBlanketEvent,
|
||||||
}, {
|
}, {
|
||||||
set = set,
|
setSync = setSync,
|
||||||
getInterior = getInterior
|
getInterior = getInterior, -- TODO <- remove
|
||||||
|
toEvent = toEvent,
|
||||||
}
|
}
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
|
@ -433,17 +435,18 @@ local Sync = (function()
|
||||||
log("Debug", "collected ",pid, ": ",delay.etype," of ",
|
log("Debug", "collected ",pid, ": ",delay.etype," of ",
|
||||||
self.source, delay.path," = ",exitcode)
|
self.source, delay.path," = ",exitcode)
|
||||||
self.processes[pid] = nil
|
self.processes[pid] = nil
|
||||||
self.delayname[delay.path] = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Puts an action on the delay stack.
|
-- Puts an action on the delay stack.
|
||||||
--
|
--
|
||||||
local function delay(self, etype, time, path, path2)
|
local function delay(self, etype, time, path, path2)
|
||||||
log("Function", "delay(", self.config.name,", ",etype,", ",path,"...)")
|
log("Function", "delay(", self.config.name,", ",etype,", ",path,")")
|
||||||
local delayname = self.delayname
|
if path2 then
|
||||||
|
log("Function", "...delay(+",path2,")")
|
||||||
|
end
|
||||||
|
|
||||||
if etype == "Move" and not self.config.move then
|
if etype == "Move" and not self.config.onMove then
|
||||||
-- if there is no move action defined, split a move as delete/create
|
-- if there is no move action defined, split a move as delete/create
|
||||||
log("Debug", "splitting Move into Delete & Create")
|
log("Debug", "splitting Move into Delete & Create")
|
||||||
delay(self, "Delete", time, path, nil)
|
delay(self, "Delete", time, path, nil)
|
||||||
|
@ -458,43 +461,53 @@ local Sync = (function()
|
||||||
else
|
else
|
||||||
alarm = lsyncd.now()
|
alarm = lsyncd.now()
|
||||||
end
|
end
|
||||||
local newd = Delay.new(etype, path, alarm)
|
-- new delay
|
||||||
|
local nd = Delay.new(etype, alarm, path, path2)
|
||||||
|
|
||||||
local oldd = delayname[path]
|
if nd.etype == "Move" then
|
||||||
if oldd then
|
log("Normal", "Stacking a move event ",path," -> ",path2)
|
||||||
-- if there is already a delay on this path.
|
table.insert(self.delays, nd)
|
||||||
-- decide what should happen with multiple delays.
|
end
|
||||||
if newd.etype == "MoveFrom" or newd.etype == "MoveTo" or
|
|
||||||
oldd.etype == "MoveFrom" or oldd.etype == "MoveTo" then
|
-----
|
||||||
-- do not collapse moves
|
-- detects blocks and collapses by working from back til
|
||||||
log("Normal", "Not collapsing events with moves on ", path)
|
-- front through the fifo
|
||||||
-- TODO stackinfo
|
InletControl.setSync(self)
|
||||||
|
local il = #self.delays -- last delay
|
||||||
|
while il > 0 do
|
||||||
|
local od = self.delays[il]
|
||||||
|
if od.etype ~= "Move" then
|
||||||
|
if nd.path == od.path then
|
||||||
|
-- tries to collapse identical paths
|
||||||
|
local oe = InletControl.toEvent(od)
|
||||||
|
local ne = InletControl.toEvent(nd)
|
||||||
|
local c = self.config.collapse(
|
||||||
|
InletControl.toEvent(od), InletControl.toEvent(nd),
|
||||||
|
self.config)
|
||||||
|
if c==0 then
|
||||||
|
-- events nullificate each ether
|
||||||
|
od.etype = "None" -- TODO better remove?
|
||||||
return
|
return
|
||||||
else
|
elseif c == 1 then
|
||||||
local col = self.config.collapseTable[oldd.etype][newd.etype]
|
log("Normal", nd.etype, " is absored by event ",
|
||||||
if col == -1 then
|
od.etype, " on ", path)
|
||||||
-- events cancel each other
|
|
||||||
log("Normal", "Nullfication: ", newd.etype, " after ",
|
|
||||||
oldd.etype, " on ", path)
|
|
||||||
oldd.etype = "None" -- TODO remove name block
|
|
||||||
return
|
return
|
||||||
elseif col == 0 then
|
elseif c == 2 then
|
||||||
-- events tack
|
log("Normal", nd.etype, " replaces event ",
|
||||||
log("Normal", "Stacking ", newd.etype, " after ",
|
od.etype, " on ", path)
|
||||||
oldd.etype, " on ", path)
|
self.delays[il] = nd
|
||||||
-- TODO Stack pointer
|
|
||||||
else
|
|
||||||
log("Normal", "Collapsing ", newd.etype, " upon ",
|
|
||||||
oldd.etype, " to ", col, " on ", path)
|
|
||||||
oldd.etype = col
|
|
||||||
return
|
return
|
||||||
|
elseif c == 3 then
|
||||||
|
log("Normal", "Stacking ", nd.etype, " upon ",
|
||||||
|
o.etype, " on ", path)
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(self.delays, newd)
|
|
||||||
else
|
|
||||||
delayname[path] = newd
|
|
||||||
table.insert(self.delays, newd)
|
|
||||||
end
|
end
|
||||||
|
il = il - 1
|
||||||
|
end
|
||||||
|
-- there was no hit on collapse or it decided to stack.
|
||||||
|
table.insert(self.delays, nd)
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
@ -543,7 +556,7 @@ local Sync = (function()
|
||||||
end
|
end
|
||||||
if d.status == "wait" then
|
if d.status == "wait" then
|
||||||
-- found a waiting delay
|
-- found a waiting delay
|
||||||
InletControl.set(self)
|
InletControl.setSync(self)
|
||||||
self.config.action(Inlet)
|
self.config.action(Inlet)
|
||||||
if self.processes:size() >= self.config.maxProcesses then
|
if self.processes:size() >= self.config.maxProcesses then
|
||||||
-- no further processes
|
-- no further processes
|
||||||
|
@ -559,8 +572,7 @@ local Sync = (function()
|
||||||
-- (used in startup)
|
-- (used in startup)
|
||||||
--
|
--
|
||||||
local function addBlanketDelay(self)
|
local function addBlanketDelay(self)
|
||||||
local newd = Delay.new("Blanket", "/", true)
|
local newd = Delay.new("Blanket", true, "/")
|
||||||
self.delayname["/"] = newd -- TODO remove delayname
|
|
||||||
table.insert(self.delays, newd)
|
table.insert(self.delays, newd)
|
||||||
return newd
|
return newd
|
||||||
end
|
end
|
||||||
|
@ -570,10 +582,9 @@ local Sync = (function()
|
||||||
--
|
--
|
||||||
local function new(config)
|
local function new(config)
|
||||||
local s = {
|
local s = {
|
||||||
-- TODO document.
|
-- fields
|
||||||
config = config,
|
config = config,
|
||||||
delays = CountArray.new(),
|
delays = CountArray.new(),
|
||||||
delayname = {},
|
|
||||||
source = config.source,
|
source = config.source,
|
||||||
processes = CountArray.new(),
|
processes = CountArray.new(),
|
||||||
|
|
||||||
|
@ -663,7 +674,7 @@ local Syncs = (function()
|
||||||
-- absolute path of source
|
-- absolute path of source
|
||||||
local real_src = lsyncd.realdir(config.source)
|
local real_src = lsyncd.realdir(config.source)
|
||||||
if not real_src then
|
if not real_src then
|
||||||
log(Error, "Cannot access source directory: ", config.source)
|
log("Error", "Cannot access source directory: ",config.source)
|
||||||
terminate(-1) -- ERRNO
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
config._source = config.source
|
config._source = config.source
|
||||||
|
@ -687,9 +698,14 @@ local Syncs = (function()
|
||||||
config[name] = settings[name] or default[name]
|
config[name] = settings[name] or default[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- TODO simplify simply go through all keys of defaults table.
|
||||||
optional("action")
|
optional("action")
|
||||||
optional("maxProcesses")
|
optional("collapse")
|
||||||
optional("collapseTable")
|
optional("collapseTable")
|
||||||
|
optional("init")
|
||||||
|
optional("maxProcesses")
|
||||||
|
optional("statusIntervall")
|
||||||
local s = Sync.new(config)
|
local s = Sync.new(config)
|
||||||
table.insert(list, s)
|
table.insert(list, s)
|
||||||
end
|
end
|
||||||
|
@ -1130,7 +1146,7 @@ function lsyncd_initialize()
|
||||||
for _, s in Syncs.iwalk() do
|
for _, s in Syncs.iwalk() do
|
||||||
Inotifies.add(s.source, "", true, s)
|
Inotifies.add(s.source, "", true, s)
|
||||||
if s.config.init then
|
if s.config.init then
|
||||||
InletControl.set(s)
|
InletControl.setSync(s)
|
||||||
s.config.init(Inlet)
|
s.config.init(Inlet)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1286,27 +1302,43 @@ default = {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Called if two events relate to the same file or directory.
|
||||||
|
-- @param event1 first event
|
||||||
|
-- @param event2 second event
|
||||||
|
-- @return 0 ... drop both events.
|
||||||
|
-- 1 ... keep first event only
|
||||||
|
-- 2 ... keep second event only
|
||||||
|
-- 3 ... keep both events.
|
||||||
|
collapse = function(event1, event2, config)
|
||||||
|
if event1.etype == "Move" or event2.etype == "Move" then
|
||||||
|
return 3
|
||||||
|
end
|
||||||
|
return(config.collapseTable[event1.etype][event2.etype])
|
||||||
|
end,
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- used by default collapse function
|
||||||
|
--
|
||||||
|
collapseTable = {
|
||||||
|
Attrib = { Attrib = 1, Modify = 2, Create = 2, Delete = 2 },
|
||||||
|
Modify = { Attrib = 1, Modify = 1, Create = 2, Delete = 2 },
|
||||||
|
Create = { Attrib = 1, Modify = 1, Create = 1, Delete = 0 },
|
||||||
|
Delete = { Attrib = 1, Modify = 1, Create = 3, Delete = 1 },
|
||||||
|
},
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- TODO
|
-- TODO
|
||||||
--
|
--
|
||||||
maxProcesses = 1,
|
maxProcesses = 1,
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- a default rsync configuration for easy usage.
|
||||||
|
rsync = defaultRsync,
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Minimum seconds between two writes of a status file.
|
-- Minimum seconds between two writes of a status file.
|
||||||
--
|
--
|
||||||
statusIntervall = 10,
|
statusIntervall = 10,
|
||||||
|
|
||||||
-----
|
|
||||||
-- TODO
|
|
||||||
--
|
|
||||||
collapseTable = {
|
|
||||||
Attrib = { Attrib = "Attrib", Modify = "Modify", Create = "Create", Delete = "Delete" },
|
|
||||||
Modify = { Attrib = "Modify", Modify = "Modify", Create = "Create", Delete = "Delete" },
|
|
||||||
Create = { Attrib = "Create", Modify = "Create", Create = "Create", Delete = -1 },
|
|
||||||
Delete = { Attrib = "Delete", Modify = "Delete", Create = "Modify", Delete = "Delete" },
|
|
||||||
},
|
|
||||||
|
|
||||||
rsync = defaultRsync
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "x3x"
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user