mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-04 19:03:17 +00:00
This commit is contained in:
parent
a3424ed034
commit
a5a0b04ae0
@ -36,5 +36,5 @@ bash = {
|
||||
onMove = prefix..[[mv ^o.targetPathname ^d.targetPathname]],
|
||||
}
|
||||
|
||||
sync{bash, source="src", target="trg/"}
|
||||
sync{bash, source="src", target="/path/to/trg/"}
|
||||
|
||||
|
@ -11,6 +11,6 @@ settings = {
|
||||
sync{
|
||||
default.rsync,
|
||||
source="src",
|
||||
target="/home/user/dst/",
|
||||
target="trg",
|
||||
}
|
||||
|
||||
|
38
lsyncd.c
38
lsyncd.c
@ -900,17 +900,18 @@ l_stackdump(lua_State* L)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the directories sub directories.
|
||||
*
|
||||
* Reads the directories entries.
|
||||
* XXX
|
||||
* @param (Lua stack) absolute path to directory.
|
||||
* @return (Lua stack) a table of directory names.
|
||||
* names are keys, values are boolean
|
||||
* true on dirs.
|
||||
*/
|
||||
static int
|
||||
l_subdirs (lua_State *L)
|
||||
l_readdir (lua_State *L)
|
||||
{
|
||||
const char * dirname = luaL_checkstring(L, 1);
|
||||
DIR *d;
|
||||
int idx = 1;
|
||||
|
||||
d = opendir(dirname);
|
||||
if (d == NULL) {
|
||||
@ -926,29 +927,30 @@ l_subdirs (lua_State *L)
|
||||
/* finished */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
|
||||
/* ignores . and .. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (de->d_type == DT_UNKNOWN) {
|
||||
/* must call stat on some systems :-/ */
|
||||
char *subdir = s_malloc(strlen(dirname) + strlen(de->d_name) + 2);
|
||||
char *entry = s_malloc(strlen(dirname) + strlen(de->d_name) + 2);
|
||||
struct stat st;
|
||||
strcpy(subdir, dirname);
|
||||
strcat(subdir, "/");
|
||||
strcat(subdir, de->d_name);
|
||||
stat(subdir, &st);
|
||||
strcpy(entry, dirname);
|
||||
strcat(entry, "/");
|
||||
strcat(entry, de->d_name);
|
||||
stat(entry, &st);
|
||||
isdir = S_ISDIR(st.st_mode);
|
||||
free(subdir);
|
||||
free(entry);
|
||||
} else {
|
||||
/* readdir can trusted */
|
||||
isdir = de->d_type == DT_DIR;
|
||||
}
|
||||
if (!isdir || !strcmp(de->d_name, ".") ||
|
||||
!strcmp(de->d_name, ".."))
|
||||
{ /* ignore non directories and . and .. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* add this to the Lua table */
|
||||
lua_pushnumber(L, idx++);
|
||||
/* adds this entry to the Lua table */
|
||||
lua_pushstring(L, de->d_name);
|
||||
lua_pushboolean(L, isdir);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
return 1;
|
||||
@ -1032,9 +1034,9 @@ static const luaL_reg lsyncdlib[] = {
|
||||
{"inotifyrm", l_inotifyrm },
|
||||
{"log", l_log },
|
||||
{"now", l_now },
|
||||
{"readdir", l_readdir },
|
||||
{"realdir", l_realdir },
|
||||
{"stackdump", l_stackdump },
|
||||
{"subdirs", l_subdirs },
|
||||
{"terminate", l_terminate },
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
111
lsyncd.lua
111
lsyncd.lua
@ -348,6 +348,14 @@ local Inlet, InletControl = (function()
|
||||
return getPath(event)
|
||||
end,
|
||||
|
||||
-----
|
||||
-- Returns the directory of the file/dir relative to watch root
|
||||
-- Always includes a trailing slash.
|
||||
--
|
||||
pathdir = function(event)
|
||||
return string.match(getPath(event), "^(.*/)[^/]*/?") or ""
|
||||
end,
|
||||
|
||||
-----
|
||||
-- Returns the file/dir relativ to watch root
|
||||
-- Excludes a trailing slash for dirs.
|
||||
@ -1421,26 +1429,34 @@ local Inotifies = (function()
|
||||
-- the relative path to root for recursed inotifies
|
||||
-- @param sync link to the observer to be notified.
|
||||
-- Note: Inotifies should handle this opaquely
|
||||
local function add(root, path, recurse, sync)
|
||||
-- @param raise if not nil creates Create events for all files/dirs
|
||||
-- in this directory. Value is time for event.
|
||||
local function addSync(root, path, recurse, sync, raise)
|
||||
log("Function",
|
||||
"Inotifies.add(",root,", ",path,", ",recurse,", ",sync,")")
|
||||
-- registers watch
|
||||
"Inotifies.addSync(",root,", ",path,", ",recurse,", ",sync,")")
|
||||
|
||||
-- lets the core registers watch with the kernel
|
||||
local wd = lsyncd.inotifyadd(root .. path);
|
||||
if wd < 0 then
|
||||
log("Error","Failure adding watch ",dir," -> ignored ")
|
||||
return
|
||||
end
|
||||
|
||||
-- creates a sublist in wdlist
|
||||
if not wdlist[wd] then
|
||||
wdlist[wd] = Array.new()
|
||||
end
|
||||
|
||||
-- and adds this sync to wdlist.
|
||||
table.insert(wdlist[wd], {
|
||||
root = root,
|
||||
path = path,
|
||||
recurse = recurse,
|
||||
sync = sync
|
||||
})
|
||||
-- create an entry for receival of with sync/path keys
|
||||
|
||||
-- creates an entry in syncpaths to quickly retrieve
|
||||
-- all entries of this sync for a path.
|
||||
local sp = syncpaths[sync]
|
||||
if not sp then
|
||||
sp = {}
|
||||
@ -1449,10 +1465,23 @@ local Inotifies = (function()
|
||||
sp[path] = wd
|
||||
|
||||
-- registers and adds watches for all subdirectories
|
||||
if recurse then
|
||||
local subdirs = lsyncd.subdirs(root .. path)
|
||||
for _, dirname in ipairs(subdirs) do
|
||||
add(root, path..dirname.."/", true, sync)
|
||||
-- and/or raises create events for all entries
|
||||
if recurse or raise then
|
||||
local entries = lsyncd.readdir(root .. path)
|
||||
for dirname, isdir in pairs(entries) do
|
||||
local pd = path .. dirname
|
||||
if isdir then
|
||||
pd = pd .. "/"
|
||||
end
|
||||
|
||||
-- creates a Create event for entry.
|
||||
if raise then
|
||||
sync:delay("Create", raise, pd, nil)
|
||||
end
|
||||
-- adds syncs for subdirs
|
||||
if isdir and recurse then
|
||||
addSync(root, pd, true, sync, raise)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1534,15 +1563,16 @@ local Inotifies = (function()
|
||||
path2 = inotify.path .. filename2
|
||||
end
|
||||
inotify.sync:delay(etype, time, path, path2)
|
||||
|
||||
-- adds subdirs for new directories
|
||||
if isdir and inotify.recurse then
|
||||
if etype == "Create" then
|
||||
add(inotify.root, path, true, inotify.sync)
|
||||
addSync(inotify.root, path, true, inotify.sync, time)
|
||||
elseif etype == "Delete" then
|
||||
removeSync(inotify.sync, path)
|
||||
elseif etype == "Move" then
|
||||
removeSync(inotify.sync, path)
|
||||
add(inotify.root, path2, true, inotify.sync)
|
||||
addSync(inotify.root, path2, true, inotify.sync, time)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1572,7 +1602,7 @@ local Inotifies = (function()
|
||||
|
||||
-- public interface
|
||||
return {
|
||||
add = add,
|
||||
addSync = addSync,
|
||||
size = size,
|
||||
event = event,
|
||||
statusReport = statusReport
|
||||
@ -1588,6 +1618,7 @@ local functionWriter = (function()
|
||||
-- all variables for layer 3
|
||||
transVars = {
|
||||
{ "%^pathname", "event.pathname" , 1, },
|
||||
{ "%^pathdir", "event.pathdir" , 1, },
|
||||
{ "%^path", "event.path" , 1, },
|
||||
{ "%^sourcePathname", "event.sourcePathname" , 1, },
|
||||
{ "%^sourcePath", "event.sourcePath" , 1, },
|
||||
@ -2156,9 +2187,9 @@ function runner.initialize()
|
||||
end
|
||||
end
|
||||
|
||||
-- runs through the syncs table filled by user calling directory()
|
||||
-- runs through the Syncs created by users
|
||||
for _, s in Syncs.iwalk() do
|
||||
Inotifies.add(s.source, "", true, s)
|
||||
Inotifies.addSync(s.source, "", true, s, nil, nil)
|
||||
if s.config.init then
|
||||
InletControl.setSync(s)
|
||||
s.config.init(Inlet)
|
||||
@ -2365,6 +2396,7 @@ local rsync_ssh = {
|
||||
[255] = "again",
|
||||
}
|
||||
|
||||
|
||||
-----
|
||||
-- Lsyncd classic - sync with rsync
|
||||
--
|
||||
@ -2373,17 +2405,44 @@ local default_rsync = {
|
||||
-- Spawns rsync for a list of events
|
||||
--
|
||||
action = function(inlet)
|
||||
local elist = inlet.getEvents()
|
||||
local config = inlet.getConfig()
|
||||
local paths = elist.getPaths()
|
||||
log("Normal", "rsyncing list\n", paths)
|
||||
spawn(elist, "/usr/bin/rsync",
|
||||
"<", paths,
|
||||
"--delete",
|
||||
config.rsyncOps .. "r",
|
||||
"--include-from=-",
|
||||
"--exclude=*",
|
||||
config.source, config.target)
|
||||
local event = inlet.getEvent()
|
||||
-- if the next element is a Delete does a delete operation
|
||||
-- over its directory
|
||||
if event.etype == "Delete" then
|
||||
local evDir = event.pathdir
|
||||
-- gets all deletes in the same directory
|
||||
local elist = inlet.getEvents(function(e2)
|
||||
return e2.etype == "Delete" and evDir == e2.pathdir
|
||||
end)
|
||||
local paths = elist.getPaths()
|
||||
log("Normal", "rsyncing deletes in ",evDir,":\n",paths)
|
||||
local config = inlet.getConfig()
|
||||
spawn(elist, "/usr/bin/rsync",
|
||||
"<", paths,
|
||||
"--delete",
|
||||
config.rsyncOps .. "d",
|
||||
"--include-from=-",
|
||||
"--exclude=*",
|
||||
config.source .. evDir, config.target .. evDir)
|
||||
else
|
||||
-- if it isn't it does a normal transfer of everything
|
||||
-- new or altered.
|
||||
|
||||
-- gets all non-deletes.
|
||||
local elist = inlet.getEvents(function(e2)
|
||||
return e2.etype ~= "Delete"
|
||||
end)
|
||||
local paths = elist.getPaths()
|
||||
log("Normal", "rsyncing a list of new/modified files/dirs\n",
|
||||
paths)
|
||||
local config = inlet.getConfig()
|
||||
spawn(elist, "/usr/bin/rsync",
|
||||
"<", paths,
|
||||
config.rsyncOps,
|
||||
"--files-from=-",
|
||||
config.source, config.target)
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
-----
|
||||
@ -2415,9 +2474,9 @@ local default_rsync = {
|
||||
exitcodes = rsync_exitcodes,
|
||||
|
||||
-----
|
||||
-- Default delay 3 seconds
|
||||
-- Default delay
|
||||
--
|
||||
delay = 20,
|
||||
delay = 10,
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ P=$R/pid
|
||||
|
||||
echo -e "$C1* using root dir for test $R$C0"
|
||||
echo -e "$C1* populating the source$C0"
|
||||
echo -e "$C1* ceating d[x]/e/f1 $C0"
|
||||
mkdir -p "$S"/d/e
|
||||
echo 'test' > "$S"/d/e/f1
|
||||
echo -e "$C1* starting lsyncd$C0"
|
||||
@ -35,10 +36,11 @@ echo -e "$C1* waiting for lsyncd to start$C0"
|
||||
sleep 4s
|
||||
|
||||
# cp -r the directory
|
||||
echo -e "$C1* making some data$CO"
|
||||
echo -e "$C1* making some data$C0"
|
||||
echo -e "$C1* ceating d[x]/e/f2 $C0"
|
||||
for i in $RANGE; do
|
||||
cp -r "$S"/d "$S"/d${i}
|
||||
echo 'test2' > "$S"/d${i}/e/f2
|
||||
# echo 'test2' > "$S"/d${i}/e/f2
|
||||
done
|
||||
|
||||
#mkdir -p "$S"/m/n
|
||||
@ -49,7 +51,7 @@ done
|
||||
#done
|
||||
|
||||
echo -e "$C1* waiting for Lsyncd to do its job.$C0"
|
||||
sleep 30s
|
||||
sleep 20s
|
||||
|
||||
echo -e "$C1* killing Lsyncd$C0"
|
||||
PID=$(cat "$P")
|
||||
|
Loading…
Reference in New Issue
Block a user