mirror of https://github.com/octoleo/lsyncd.git
new inheritance mechanics, code beautifications
This commit is contained in:
parent
2e9c103f55
commit
1bf1d13eaa
|
@ -2,7 +2,7 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
#AC_PREREQ(2.60)
|
#AC_PREREQ(2.60)
|
||||||
AC_INIT(lsyncd, 2.0.7, axkibe@gmail.com)
|
AC_INIT(lsyncd, 2.1.0-beta, axkibe@gmail.com)
|
||||||
AM_INIT_AUTOMAKE([foreign])
|
AM_INIT_AUTOMAKE([foreign])
|
||||||
|
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
|
@ -15,15 +15,19 @@
|
||||||
--
|
--
|
||||||
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
if not default then
|
if not default then
|
||||||
error('default not loaded')
|
error( 'default not loaded' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if default.rsync then
|
if default.rsync then
|
||||||
error('default-rsync already loaded')
|
error( 'default-rsync already loaded' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
default.rsync = { }
|
default.rsync = { }
|
||||||
|
local rsync = default.rsync
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Spawns rsync for a list of events
|
-- Spawns rsync for a list of events
|
||||||
|
@ -31,7 +35,7 @@ default.rsync = { }
|
||||||
-- Exlcusions are already handled by not having
|
-- Exlcusions are already handled by not having
|
||||||
-- events for them.
|
-- events for them.
|
||||||
--
|
--
|
||||||
default.rsync.action = function( inlet )
|
rsync.action = function( inlet )
|
||||||
|
|
||||||
--
|
--
|
||||||
-- gets all events ready for syncing
|
-- gets all events ready for syncing
|
||||||
|
@ -51,10 +55,10 @@ default.rsync.action = function( inlet )
|
||||||
end
|
end
|
||||||
|
|
||||||
return p:
|
return p:
|
||||||
gsub('%?', '\\?'):
|
gsub( '%?', '\\?' ):
|
||||||
gsub('%*', '\\*'):
|
gsub( '%*', '\\*' ):
|
||||||
gsub('%[', '\\['):
|
gsub( '%[', '\\[' ):
|
||||||
gsub('%]', '\\]')
|
gsub( '%]', '\\]' )
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -153,10 +157,11 @@ default.rsync.action = function( inlet )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Spawns the recursive startup sync
|
-- Spawns the recursive startup sync
|
||||||
--
|
--
|
||||||
init = function(event)
|
rsync.init = function(event)
|
||||||
|
|
||||||
local config = event.config
|
local config = event.config
|
||||||
local inlet = event.inlet
|
local inlet = event.inlet
|
||||||
|
@ -216,10 +221,11 @@ init = function(event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Prepares and checks a syncs configuration on startup.
|
-- Prepares and checks a syncs configuration on startup.
|
||||||
--
|
--
|
||||||
default.rsync.prepare = function( config )
|
rsync.prepare = function( config )
|
||||||
|
|
||||||
if not config.target then
|
if not config.target then
|
||||||
error(
|
error(
|
||||||
|
@ -317,19 +323,22 @@ default.rsync.prepare = function( config )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- rsync uses default collect
|
-- rsync uses default collect
|
||||||
--
|
--
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- By default do deletes.
|
-- By default do deletes.
|
||||||
--
|
--
|
||||||
default.rsync.delete = true
|
rsync.delete = true
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Calls rsync with this default options
|
-- Calls rsync with this default options
|
||||||
--
|
--
|
||||||
default.rsync.rsync = {
|
rsync.rsync = {
|
||||||
-- The rsync binary to be called.
|
-- The rsync binary to be called.
|
||||||
binary = '/usr/bin/rsync',
|
binary = '/usr/bin/rsync',
|
||||||
links = true,
|
links = true,
|
||||||
|
@ -337,12 +346,13 @@ default.rsync.rsync = {
|
||||||
protectArgs = true
|
protectArgs = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Exit codes for rsync.
|
-- Exit codes for rsync.
|
||||||
--
|
--
|
||||||
default.rsync.exitcodes = default.rsyncExitCodes
|
rsync.exitcodes = default.rsyncExitCodes
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Default delay
|
-- Default delay
|
||||||
--
|
--
|
||||||
default.rsync.delay = 15
|
rsync.delay = 15
|
||||||
|
|
100
default.lua
100
default.lua
|
@ -38,8 +38,10 @@ default = {
|
||||||
-- Called when collecting a finished child process
|
-- Called when collecting a finished child process
|
||||||
--
|
--
|
||||||
collect = function(agent, exitcode)
|
collect = function(agent, exitcode)
|
||||||
|
|
||||||
local config = agent.config
|
local config = agent.config
|
||||||
local rc
|
local rc
|
||||||
|
|
||||||
if config.exitcodes then
|
if config.exitcodes then
|
||||||
rc = config.exitcodes[exitcode]
|
rc = config.exitcodes[exitcode]
|
||||||
elseif exitcode == 0 then
|
elseif exitcode == 0 then
|
||||||
|
@ -71,7 +73,8 @@ default = {
|
||||||
agent.source,
|
agent.source,
|
||||||
'". Terminating since "insist" is not set.'
|
'". Terminating since "insist" is not set.'
|
||||||
)
|
)
|
||||||
terminate(-1) -- ERRNO
|
|
||||||
|
terminate( -1 )
|
||||||
end
|
end
|
||||||
elseif rc == 'die' then
|
elseif rc == 'die' then
|
||||||
log(
|
log(
|
||||||
|
@ -80,7 +83,8 @@ default = {
|
||||||
agent.source,
|
agent.source,
|
||||||
'".'
|
'".'
|
||||||
)
|
)
|
||||||
terminate(-1) -- ERRNO
|
|
||||||
|
terminate( -1 )
|
||||||
else
|
else
|
||||||
log(
|
log(
|
||||||
'Error',
|
'Error',
|
||||||
|
@ -96,13 +100,29 @@ default = {
|
||||||
|
|
||||||
if agent.isList then
|
if agent.isList then
|
||||||
if rc == 'ok' then
|
if rc == 'ok' then
|
||||||
log('Normal', 'Finished a list = ',exitcode)
|
log(
|
||||||
|
'Normal',
|
||||||
|
'Finished a list after exitcode: ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
elseif rc == 'again' then
|
elseif rc == 'again' then
|
||||||
log('Normal', 'Retrying a list on exitcode = ',exitcode)
|
log(
|
||||||
|
'Normal',
|
||||||
|
'Retrying a list after exitcode = ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
elseif rc == 'die' then
|
elseif rc == 'die' then
|
||||||
log('Error', 'Failure with a list on exitcode = ',exitcode)
|
log(
|
||||||
|
'Error',
|
||||||
|
'Failure with a list width exitcode = ',
|
||||||
|
exitcode
|
||||||
|
)
|
||||||
else
|
else
|
||||||
log('Error', 'Unknown exitcode "',exitcode,'" with a list')
|
log(
|
||||||
|
'Error',
|
||||||
|
'Unknown exitcode "',exitcode,'" with a list'
|
||||||
|
)
|
||||||
|
|
||||||
rc = 'die'
|
rc = 'die'
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -164,34 +184,58 @@ default = {
|
||||||
-- Exitcodes of rsync and what to do.
|
-- Exitcodes of rsync and what to do.
|
||||||
--
|
--
|
||||||
rsyncExitCodes = {
|
rsyncExitCodes = {
|
||||||
[ 0] = 'ok',
|
|
||||||
[ 1] = 'die',
|
--
|
||||||
[ 2] = 'die',
|
-- if another config provides the same table
|
||||||
[ 3] = 'again',
|
-- this will not be inherited (merged) into that one
|
||||||
[ 4] = 'die',
|
--
|
||||||
[ 5] = 'again',
|
-- if it does not, integer keys are to be copied
|
||||||
[ 6] = 'again',
|
-- verbatim
|
||||||
[ 10] = 'again',
|
--
|
||||||
[ 11] = 'again',
|
_merge = false,
|
||||||
[ 12] = 'again',
|
_verbatim = true,
|
||||||
[ 14] = 'again',
|
|
||||||
[ 20] = 'again',
|
[ 0 ] = 'ok',
|
||||||
[ 21] = 'again',
|
[ 1 ] = 'die',
|
||||||
[ 22] = 'again',
|
[ 2 ] = 'die',
|
||||||
[ 23] = 'ok', -- partial transfers are ok, since Lsyncd has registered the event that
|
[ 3 ] = 'again',
|
||||||
[ 24] = 'ok', -- caused the transfer to be partial and will recall rsync.
|
[ 4 ] = 'die',
|
||||||
[ 25] = 'die',
|
[ 5 ] = 'again',
|
||||||
[ 30] = 'again',
|
[ 6 ] = 'again',
|
||||||
[ 35] = 'again',
|
[ 10 ] = 'again',
|
||||||
[255] = 'again',
|
[ 11 ] = 'again',
|
||||||
|
[ 12 ] = 'again',
|
||||||
|
[ 14 ] = 'again',
|
||||||
|
[ 20 ] = 'again',
|
||||||
|
[ 21 ] = 'again',
|
||||||
|
[ 22 ] = 'again',
|
||||||
|
-- partial transfers are ok, since Lsyncd has registered the event that
|
||||||
|
-- caused the transfer to be partial and will recall rsync.
|
||||||
|
[ 23 ] = 'ok',
|
||||||
|
[ 24 ] = 'ok',
|
||||||
|
[ 25 ] = 'die',
|
||||||
|
[ 30 ] = 'again',
|
||||||
|
[ 35 ] = 'again',
|
||||||
|
[ 255 ] = 'again',
|
||||||
},
|
},
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Exitcodes of ssh and what to do.
|
-- Exitcodes of ssh and what to do.
|
||||||
--
|
--
|
||||||
sshExitCodes = {
|
sshExitCodes = {
|
||||||
[0] = 'ok',
|
|
||||||
[255] = 'again',
|
--
|
||||||
|
-- if another config provides the same table
|
||||||
|
-- this will not be inherited (merged) into that one
|
||||||
|
--
|
||||||
|
-- if it does not, integer keys are to be copied
|
||||||
|
-- verbatim
|
||||||
|
--
|
||||||
|
_merge = false,
|
||||||
|
_verbatim = true,
|
||||||
|
|
||||||
|
[ 0 ] = 'ok',
|
||||||
|
[ 255 ] = 'again',
|
||||||
},
|
},
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
565
inotify.c
565
inotify.c
|
@ -1,14 +1,14 @@
|
||||||
/**
|
/*
|
||||||
* inotify.c from Lsyncd - Live (Mirror) Syncing Demon
|
| inotify.c from Lsyncd - Live (Mirror) Syncing Demon
|
||||||
*
|
|
|
||||||
* License: GPLv2 (see COPYING) or any later version
|
| License: GPLv2 (see COPYING) or any later version
|
||||||
*
|
|
|
||||||
* Authors: Axel Kittenberger <axkibe@gmail.com>
|
| Authors: Axel Kittenberger <axkibe@gmail.com>
|
||||||
*
|
|
|
||||||
* -----------------------------------------------------------------------
|
| -----------------------------------------------------------------------
|
||||||
*
|
|
|
||||||
* Event interface for Lsyncd to Linux´ inotify.
|
| Event interface for Lsyncd to Linux´ inotify.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lsyncd.h"
|
#include "lsyncd.h"
|
||||||
|
|
||||||
|
@ -39,83 +39,130 @@
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
|
||||||
* Event types.
|
/*
|
||||||
*/
|
| Event types.
|
||||||
|
*/
|
||||||
static const char * ATTRIB = "Attrib";
|
static const char * ATTRIB = "Attrib";
|
||||||
static const char * MODIFY = "Modify";
|
static const char * MODIFY = "Modify";
|
||||||
static const char * CREATE = "Create";
|
static const char * CREATE = "Create";
|
||||||
static const char * DELETE = "Delete";
|
static const char * DELETE = "Delete";
|
||||||
static const char * MOVE = "Move";
|
static const char * MOVE = "Move";
|
||||||
|
|
||||||
/**
|
|
||||||
|
/*
|
||||||
* The inotify file descriptor.
|
* The inotify file descriptor.
|
||||||
*/
|
*/
|
||||||
static int inotify_fd = -1;
|
static int inotify_fd = -1;
|
||||||
|
|
||||||
/**
|
|
||||||
* Standard inotify events to listen to.
|
/*
|
||||||
*/
|
| Standard inotify events to listen to.
|
||||||
|
*/
|
||||||
static const uint32_t standard_event_mask =
|
static const uint32_t standard_event_mask =
|
||||||
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
IN_ATTRIB |
|
||||||
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
IN_CLOSE_WRITE |
|
||||||
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
IN_CREATE |
|
||||||
|
IN_DELETE |
|
||||||
|
IN_DELETE_SELF |
|
||||||
|
IN_MOVED_FROM |
|
||||||
|
IN_MOVED_TO |
|
||||||
|
IN_DONT_FOLLOW |
|
||||||
|
IN_ONLYDIR;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Adds an inotify watch
|
| Adds an inotify watch
|
||||||
*
|
|
|
||||||
* @param dir (Lua stack) path to directory
|
| param dir (Lua stack) path to directory
|
||||||
* @param inotifyMode (Lua stack) path to directory
|
| param inotifyMode (Lua stack) which inotify event to react upon
|
||||||
* @return (Lua stack) numeric watch descriptor
|
| "CloseWrite", "CloseWrite or Modify"
|
||||||
*/
|
|
|
||||||
|
| returns (Lua stack) numeric watch descriptor
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
l_addwatch(lua_State *L)
|
l_addwatch( lua_State *L )
|
||||||
{
|
{
|
||||||
const char *path = luaL_checkstring(L, 1);
|
const char *path = luaL_checkstring( L, 1 );
|
||||||
const char *imode = luaL_checkstring(L, 2);
|
const char *imode = luaL_checkstring( L, 2 );
|
||||||
uint32_t mask = standard_event_mask;
|
uint32_t mask = standard_event_mask;
|
||||||
if (*imode) {
|
|
||||||
if (!strcmp(imode, "Modify")) {
|
// checks the desired inotify reaction mode
|
||||||
// act on modify instead of closeWrite
|
if (*imode)
|
||||||
mask |= IN_MODIFY;
|
{
|
||||||
|
if ( !strcmp( imode, "Modify" ) )
|
||||||
|
{
|
||||||
|
// acts on modify instead of closeWrite
|
||||||
|
mask |= IN_MODIFY;
|
||||||
mask &= ~IN_CLOSE_WRITE;
|
mask &= ~IN_CLOSE_WRITE;
|
||||||
} else if (!strcmp(imode, "CloseWrite")) {
|
}
|
||||||
// default
|
else if ( !strcmp( imode, "CloseWrite" ) )
|
||||||
} else if (!strcmp(imode, "CloseWrite or Modify")) {
|
{
|
||||||
|
// thats default
|
||||||
|
}
|
||||||
|
else if ( !strcmp( imode, "CloseWrite or Modify" ) )
|
||||||
|
{
|
||||||
// acts on modify and closeWrite
|
// acts on modify and closeWrite
|
||||||
mask |= IN_MODIFY;
|
mask |= IN_MODIFY;
|
||||||
} else if (!strcmp(imode, "CloseWrite after Modify")) {
|
}
|
||||||
|
else if ( ! strcmp( imode, "CloseWrite after Modify") )
|
||||||
|
{
|
||||||
// might be done in future
|
// might be done in future
|
||||||
printlogf(L, "Error", "'CloseWrite after Modify' not implemented.");
|
printlogf(
|
||||||
exit(-1); // ERRNO
|
L, "Error",
|
||||||
} else {
|
"'CloseWrite after Modify' not implemented."
|
||||||
printlogf(L, "Error", "'%s' not a valid inotfiyMode.", imode);
|
);
|
||||||
exit(-1); // ERRNO
|
exit(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printlogf(
|
||||||
|
L, "Error",
|
||||||
|
"'%s' not a valid inotfiyMode.",
|
||||||
|
imode
|
||||||
|
);
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kernel call to create the inotify watch
|
||||||
|
int wd = inotify_add_watch( inotify_fd, path, mask );
|
||||||
|
|
||||||
int wd = inotify_add_watch(inotify_fd, path, mask);
|
if (wd < 0)
|
||||||
if (wd < 0) {
|
{
|
||||||
if (errno == ENOSPC) {
|
if (errno == ENOSPC)
|
||||||
printlogf(L, "Error", "Terminating since out of inotify watches.");
|
{
|
||||||
printlogf(L, "Error", "Consider increasing /proc/sys/fs/inotify/max_user_watches");
|
printlogf(
|
||||||
|
L, "Error",
|
||||||
|
"%s\n%s",
|
||||||
|
"Terminating since out of inotify watches.",
|
||||||
|
"Consider increasing /proc/sys/fs/inotify/max_user_watches"
|
||||||
|
);
|
||||||
exit(-1); // ERRNO.
|
exit(-1); // ERRNO.
|
||||||
}
|
}
|
||||||
printlogf(L, "Inotify", "addwatch(%s)->%d; err=%d:%s", path, wd, errno, strerror(errno));
|
|
||||||
} else {
|
printlogf(
|
||||||
printlogf(L, "Inotify", "addwatch(%s)->%d", path, wd);
|
L, "Inotify",
|
||||||
|
"addwatch( %s )-> % d; err= %d : %s",
|
||||||
|
path, wd, errno, strerror( errno )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
lua_pushinteger(L, wd);
|
else
|
||||||
|
{
|
||||||
|
printlogf(L, "Inotify", "addwatch( %s )-> %d ", path, wd );
|
||||||
|
}
|
||||||
|
lua_pushinteger( L, wd );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an inotify watch
|
/*
|
||||||
|
* Removes an inotify watch.
|
||||||
*
|
*
|
||||||
* @param dir (Lua stack) numeric watch descriptor
|
* param dir (Lua stack) numeric watch descriptor
|
||||||
* @return nil
|
*
|
||||||
|
* return nil
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
l_rmwatch(lua_State *L)
|
l_rmwatch(lua_State *L)
|
||||||
|
@ -126,147 +173,214 @@ l_rmwatch(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Cores inotify functions.
|
/*
|
||||||
*/
|
| Lsyncd's core's inotify functions.
|
||||||
|
*/
|
||||||
static const luaL_Reg linotfylib[] = {
|
static const luaL_Reg linotfylib[] = {
|
||||||
{"addwatch", l_addwatch },
|
{ "addwatch", l_addwatch },
|
||||||
{"rmwatch", l_rmwatch },
|
{ "rmwatch", l_rmwatch },
|
||||||
{NULL, NULL}
|
{ NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Buffer for MOVE_FROM events.
|
/*
|
||||||
* Lsyncd buffers MOVE_FROM events to check if
|
| Buffer for MOVE_FROM events.
|
||||||
* they are followed by MOVE_TO events with identical cookie
|
| Lsyncd buffers MOVE_FROM events to check if
|
||||||
* then they are condensed into one move event to be sent to the
|
| they are followed by MOVE_TO events with identical cookie
|
||||||
* runner
|
| then they are condensed into one move event to be sent to the
|
||||||
*/
|
| runner
|
||||||
|
*/
|
||||||
static struct inotify_event * move_event_buf = NULL;
|
static struct inotify_event * move_event_buf = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* Memory allocated for move_event_buf
|
/*
|
||||||
*/
|
| Memory allocated for move_event_buf
|
||||||
|
*/
|
||||||
static size_t move_event_buf_size = 0;
|
static size_t move_event_buf_size = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* true if the buffer is used.
|
/*
|
||||||
*/
|
| True if the buffer is used.
|
||||||
|
*/
|
||||||
static bool move_event = false;
|
static bool move_event = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles an inotify event.
|
/*
|
||||||
*/
|
| Handles an inotify event.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
handle_event(lua_State *L,
|
handle_event(
|
||||||
struct inotify_event *event)
|
lua_State *L,
|
||||||
|
struct inotify_event *event
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const char *event_type = NULL;
|
const char *event_type = NULL;
|
||||||
|
|
||||||
// used to execute two events in case of unmatched MOVE_FROM buffer
|
// used to execute two events in case of unmatched MOVE_FROM buffer
|
||||||
struct inotify_event *after_buf = NULL;
|
struct inotify_event *after_buf = NULL;
|
||||||
if (event && (IN_Q_OVERFLOW & event->mask)) {
|
if( event && ( IN_Q_OVERFLOW & event->mask ) )
|
||||||
/* and overflow happened, tells the runner */
|
{
|
||||||
load_runner_func(L, "overflow");
|
// and overflow happened, tells the runner
|
||||||
if (lua_pcall(L, 0, 0, -2)) {
|
load_runner_func( L, "overflow" );
|
||||||
exit(-1); // ERRNO
|
|
||||||
|
if( lua_pcall( L, 0, 0, -2 ) )
|
||||||
|
{
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop( L, 1 );
|
||||||
hup = 1;
|
hup = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel on ignored or resetting
|
// cancel on ignored or resetting
|
||||||
if (event && (IN_IGNORED & event->mask)) {
|
if( event && ( IN_IGNORED & event->mask ) )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event && event->len == 0) {
|
|
||||||
|
if( event && event->len == 0 )
|
||||||
|
{
|
||||||
// sometimes inotify sends such strange events,
|
// sometimes inotify sends such strange events,
|
||||||
// (e.g. when touching a dir
|
// (e.g. when touching a dir
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == NULL) {
|
if( event == NULL )
|
||||||
|
{
|
||||||
// a buffered MOVE_FROM is not followed by anything,
|
// a buffered MOVE_FROM is not followed by anything,
|
||||||
// thus it is unary
|
// thus it is unary
|
||||||
event = move_event_buf;
|
event = move_event_buf;
|
||||||
event_type = "Delete";
|
event_type = "Delete";
|
||||||
move_event = false;
|
move_event = false;
|
||||||
} else if (move_event &&
|
}
|
||||||
( !(IN_MOVED_TO & event->mask) ||
|
else if(
|
||||||
event->cookie != move_event_buf->cookie) ) {
|
move_event &&
|
||||||
|
(
|
||||||
|
!( IN_MOVED_TO & event->mask ) ||
|
||||||
|
event->cookie != move_event_buf->cookie
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
// there is a MOVE_FROM event in the buffer and this is not the match
|
// there is a MOVE_FROM event in the buffer and this is not the match
|
||||||
// continue in this function iteration to handle the buffer instead */
|
// continue in this function iteration to handle the buffer instead */
|
||||||
logstring("Inotify", "icore, changing unary MOVE_FROM into DELETE")
|
logstring(
|
||||||
|
"Inotify",
|
||||||
|
"icore, changing unary MOVE_FROM into DELETE"
|
||||||
|
)
|
||||||
after_buf = event;
|
after_buf = event;
|
||||||
event = move_event_buf;
|
event = move_event_buf;
|
||||||
event_type = "Delete";
|
event_type = "Delete";
|
||||||
move_event = false;
|
move_event = false;
|
||||||
} else if ( move_event &&
|
}
|
||||||
(IN_MOVED_TO & event->mask) &&
|
else if(
|
||||||
event->cookie == move_event_buf->cookie ) {
|
move_event &&
|
||||||
|
(
|
||||||
|
IN_MOVED_TO & event->mask ) &&
|
||||||
|
event->cookie == move_event_buf->cookie
|
||||||
|
)
|
||||||
|
{
|
||||||
// this is indeed a matched move */
|
// this is indeed a matched move */
|
||||||
event_type = "Move";
|
event_type = "Move";
|
||||||
move_event = false;
|
move_event = false;
|
||||||
} else if (IN_MOVED_FROM & event->mask) {
|
}
|
||||||
|
else if( IN_MOVED_FROM & event->mask )
|
||||||
|
{
|
||||||
// just the MOVE_FROM, buffers this event, and wait if next event is
|
// just the MOVE_FROM, buffers this event, and wait if next event is
|
||||||
// a matching MOVED_TO of this was an unary move out of the watched
|
// a matching MOVED_TO of this was an unary move out of the watched
|
||||||
// tree.
|
// tree.
|
||||||
size_t el = sizeof(struct inotify_event) + event->len;
|
size_t el = sizeof( struct inotify_event ) + event->len;
|
||||||
if (move_event_buf_size < el) {
|
|
||||||
|
if( move_event_buf_size < el )
|
||||||
|
{
|
||||||
move_event_buf_size = el;
|
move_event_buf_size = el;
|
||||||
move_event_buf = s_realloc(move_event_buf, el);
|
move_event_buf = s_realloc( move_event_buf, el );
|
||||||
}
|
}
|
||||||
memcpy(move_event_buf, event, el);
|
memcpy( move_event_buf, event, el );
|
||||||
move_event = true;
|
move_event = true;
|
||||||
return;
|
return;
|
||||||
} else if (IN_MOVED_TO & event->mask) {
|
|
||||||
|
}
|
||||||
|
else if( IN_MOVED_TO & event->mask )
|
||||||
|
{
|
||||||
// must be an unary move-to
|
// must be an unary move-to
|
||||||
event_type = CREATE;
|
event_type = CREATE;
|
||||||
} else if (IN_ATTRIB & event->mask) {
|
}
|
||||||
|
else if( IN_ATTRIB & event->mask )
|
||||||
|
{
|
||||||
// just attrib change
|
// just attrib change
|
||||||
event_type = ATTRIB;
|
event_type = ATTRIB;
|
||||||
} else if ((IN_CLOSE_WRITE | IN_MODIFY) & event->mask) {
|
}
|
||||||
|
else if( ( IN_CLOSE_WRITE | IN_MODIFY) & event->mask )
|
||||||
|
{
|
||||||
// modify, or closed after written something
|
// modify, or closed after written something
|
||||||
// the event type received depends settings.inotifyMode
|
// the event type received depends settings.inotifyMode
|
||||||
event_type = MODIFY;
|
event_type = MODIFY;
|
||||||
} else if (IN_CREATE & event->mask) {
|
}
|
||||||
|
else if( IN_CREATE & event->mask )
|
||||||
|
{
|
||||||
// a new file
|
// a new file
|
||||||
event_type = CREATE;
|
event_type = CREATE;
|
||||||
} else if (IN_DELETE & event->mask) {
|
}
|
||||||
|
else if( IN_DELETE & event->mask )
|
||||||
|
{
|
||||||
// rm'ed
|
// rm'ed
|
||||||
event_type = DELETE;
|
event_type = DELETE;
|
||||||
} else {
|
}
|
||||||
logstring("Inotify", "icore, skipped some inotify event.");
|
else
|
||||||
|
{
|
||||||
|
logstring(
|
||||||
|
"Inotify",
|
||||||
|
"skipped some inotify event."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and hands over to runner
|
// hands the event over to the runner
|
||||||
load_runner_func(L, "inotifyEvent");
|
load_runner_func( L, "inotifyEvent" );
|
||||||
if (!event_type) {
|
|
||||||
logstring("Error", "Internal: unknown event in handle_event()");
|
if( !event_type )
|
||||||
exit(-1); // ERRNO
|
{
|
||||||
|
logstring(
|
||||||
|
"Error",
|
||||||
|
"internal failure: unknown event in handle_event()"
|
||||||
|
);
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
lua_pushstring(L, event_type);
|
|
||||||
if (event_type != MOVE) {
|
lua_pushstring( L, event_type );
|
||||||
lua_pushnumber(L, event->wd);
|
if( event_type != MOVE )
|
||||||
} else {
|
{
|
||||||
lua_pushnumber(L, move_event_buf->wd);
|
lua_pushnumber( L, event->wd );
|
||||||
}
|
}
|
||||||
lua_pushboolean(L, (event->mask & IN_ISDIR) != 0);
|
else
|
||||||
l_now(L);
|
{
|
||||||
if (event_type == MOVE) {
|
lua_pushnumber( L, move_event_buf->wd );
|
||||||
lua_pushstring(L, move_event_buf->name);
|
|
||||||
lua_pushnumber(L, event->wd);
|
|
||||||
lua_pushstring(L, event->name);
|
|
||||||
} else {
|
|
||||||
lua_pushstring(L, event->name);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
}
|
}
|
||||||
if (lua_pcall(L, 7, 0, -9)) {
|
lua_pushboolean( L, ( event->mask & IN_ISDIR ) != 0 );
|
||||||
exit(-1); // ERRNO
|
|
||||||
|
l_now( L );
|
||||||
|
|
||||||
|
if( event_type == MOVE )
|
||||||
|
{
|
||||||
|
lua_pushstring( L, move_event_buf->name );
|
||||||
|
lua_pushnumber( L, event->wd );
|
||||||
|
lua_pushstring( L, event->name );
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
else
|
||||||
|
{
|
||||||
|
lua_pushstring( L, event->name );
|
||||||
|
lua_pushnil( L );
|
||||||
|
lua_pushnil( L );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lua_pcall( L, 7, 0, -9 ) )
|
||||||
|
{
|
||||||
|
exit( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop( L, 1 );
|
||||||
|
|
||||||
// if there is a buffered event, executes it
|
// if there is a buffered event, executes it
|
||||||
if (after_buf) {
|
if (after_buf) {
|
||||||
|
@ -275,31 +389,44 @@ handle_event(lua_State *L,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* buffer to read inotify events into
|
/*
|
||||||
*/
|
| buffer to read inotify events into
|
||||||
|
*/
|
||||||
static size_t readbuf_size = 2048;
|
static size_t readbuf_size = 2048;
|
||||||
static char * readbuf = NULL;
|
static char * readbuf = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by function pointer from when the inotify file descriptor
|
/*
|
||||||
* became ready. Reads it contents and forward all received events
|
| Called when the inotify file descriptor became ready.
|
||||||
* to the runner.
|
| Reads it contents and forwards all received events
|
||||||
*/
|
| to the runner.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
inotify_ready(lua_State *L, struct observance *obs)
|
inotify_ready(
|
||||||
|
lua_State *L,
|
||||||
|
struct observance *obs
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (obs->fd != inotify_fd) {
|
// sanity check
|
||||||
logstring("Error", "Internal, inotify_fd != ob->fd");
|
if( obs->fd != inotify_fd )
|
||||||
exit(-1); // ERRNO
|
{
|
||||||
|
logstring(
|
||||||
|
"Error",
|
||||||
|
"internal failure, inotify_fd != ob->fd"
|
||||||
|
);
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
while(true) {
|
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
ptrdiff_t len;
|
ptrdiff_t len;
|
||||||
int err;
|
int err;
|
||||||
do {
|
do {
|
||||||
len = read (inotify_fd, readbuf, readbuf_size);
|
len = read( inotify_fd, readbuf, readbuf_size );
|
||||||
err = errno;
|
err = errno;
|
||||||
if (len < 0 && err == EINVAL) {
|
if( len < 0 && err == EINVAL )
|
||||||
|
{
|
||||||
// kernel > 2.6.21 indicates that way that way that
|
// kernel > 2.6.21 indicates that way that way that
|
||||||
// the buffer was too small to fit a filename.
|
// the buffer was too small to fit a filename.
|
||||||
// double its size and try again. When using a lower
|
// double its size and try again. When using a lower
|
||||||
|
@ -309,90 +436,138 @@ inotify_ready(lua_State *L, struct observance *obs)
|
||||||
readbuf_size *= 2;
|
readbuf_size *= 2;
|
||||||
readbuf = s_realloc(readbuf, readbuf_size);
|
readbuf = s_realloc(readbuf, readbuf_size);
|
||||||
}
|
}
|
||||||
} while(len < 0 && err == EINVAL);
|
} while( len < 0 && err == EINVAL );
|
||||||
if (len == 0) {
|
|
||||||
// nothing more inotify
|
if( len == 0 )
|
||||||
|
{
|
||||||
|
// no more inotify events
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (len < 0) {
|
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
if (err == EAGAIN) {
|
if (err == EAGAIN) {
|
||||||
// nothing more inotify
|
// nothing more inotify
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
printlogf(L, "Error", "Read fail on inotify");
|
else
|
||||||
exit(-1); // ERRNO
|
{
|
||||||
|
printlogf(
|
||||||
|
L, "Error",
|
||||||
|
"Read fail on inotify"
|
||||||
|
);
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < len && !hup && !term) {
|
while( i < len && !hup && !term )
|
||||||
|
{
|
||||||
struct inotify_event *event =
|
struct inotify_event *event =
|
||||||
(struct inotify_event *) &readbuf[i];
|
( struct inotify_event * )
|
||||||
handle_event(L, event);
|
(readbuf + i);
|
||||||
i += sizeof(struct inotify_event) + event->len;
|
|
||||||
|
handle_event( L, event );
|
||||||
|
|
||||||
|
i += sizeof( struct inotify_event ) + event->len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!move_event) {
|
|
||||||
|
if( !move_event )
|
||||||
|
{
|
||||||
// give it a pause if not endangering splitting a move
|
// give it a pause if not endangering splitting a move
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if there is an unary MOVE_FROM left in the buffer
|
// checks if there is an unary MOVE_FROM left in the buffer
|
||||||
if (move_event) {
|
if( move_event )
|
||||||
logstring("Inotify", "icore, handling unary move from.");
|
{
|
||||||
handle_event(L, NULL);
|
logstring(
|
||||||
|
"Inotify",
|
||||||
|
"handling unary move from."
|
||||||
|
);
|
||||||
|
handle_event( L, NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* registers inotify functions.
|
/*
|
||||||
*/
|
| Registers the inotify functions.
|
||||||
|
*/
|
||||||
extern void
|
extern void
|
||||||
register_inotify(lua_State *L)
|
register_inotify( lua_State *L )
|
||||||
{
|
{
|
||||||
luaL_register(L, LSYNCD_INOTIFYLIBNAME, linotfylib);
|
luaL_register( L, LSYNCD_INOTIFYLIBNAME, linotfylib );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* closes inotify
|
/*
|
||||||
*/
|
| Cleans up the inotify handling.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
inotify_tidy(struct observance *obs)
|
inotify_tidy( struct observance *obs )
|
||||||
{
|
{
|
||||||
if (obs->fd != inotify_fd) {
|
if( obs->fd != inotify_fd )
|
||||||
logstring("Error", "Internal, inotify_fd != ob->fd");
|
{
|
||||||
exit(-1); // ERRNO
|
logstring(
|
||||||
|
"Error",
|
||||||
|
"internal failure: inotify_fd != ob->fd"
|
||||||
|
);
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
close(inotify_fd);
|
|
||||||
free(readbuf);
|
close( inotify_fd );
|
||||||
|
free( readbuf );
|
||||||
readbuf = NULL;
|
readbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* opens and initalizes inotify.
|
| Initalizes inotify handling
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
open_inotify(lua_State *L)
|
open_inotify( lua_State *L )
|
||||||
{
|
{
|
||||||
if (readbuf) {
|
if( readbuf )
|
||||||
logstring("Error",
|
{
|
||||||
"internal fail, inotify readbuf!=NULL in open_inotify()")
|
logstring(
|
||||||
exit(-1); // ERRNO
|
"Error",
|
||||||
|
"internal failure, inotify readbuf != NULL in open_inotify()"
|
||||||
|
)
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
readbuf = s_malloc(readbuf_size);
|
|
||||||
|
|
||||||
inotify_fd = inotify_init();
|
readbuf = s_malloc( readbuf_size );
|
||||||
if (inotify_fd < 0) {
|
|
||||||
printlogf(L, "Error",
|
inotify_fd = inotify_init( );
|
||||||
"Cannot access inotify monitor! (%d:%s)",
|
|
||||||
errno, strerror(errno));
|
if( inotify_fd < 0 )
|
||||||
exit(-1); // ERRNO
|
{
|
||||||
|
printlogf(
|
||||||
|
L,
|
||||||
|
"Error",
|
||||||
|
"Cannot access inotify monitor! ( %d : %s )",
|
||||||
|
errno, strerror(errno)
|
||||||
|
);
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
printlogf(L, "Inotify", "inotify fd = %d", inotify_fd);
|
|
||||||
|
|
||||||
close_exec_fd(inotify_fd);
|
printlogf(
|
||||||
non_block_fd(inotify_fd);
|
L, "Inotify",
|
||||||
observe_fd(inotify_fd, inotify_ready, NULL, inotify_tidy, NULL);
|
"inotify fd = %d",
|
||||||
|
inotify_fd
|
||||||
|
);
|
||||||
|
|
||||||
|
close_exec_fd( inotify_fd );
|
||||||
|
non_block_fd( inotify_fd );
|
||||||
|
|
||||||
|
observe_fd(
|
||||||
|
inotify_fd,
|
||||||
|
inotify_ready,
|
||||||
|
NULL,
|
||||||
|
inotify_tidy,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
181
lsyncd.lua
181
lsyncd.lua
|
@ -30,7 +30,7 @@ if lsyncd_version then
|
||||||
lsyncd.terminate( -1 )
|
lsyncd.terminate( -1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
lsyncd_version = '2.0.7'
|
lsyncd_version = '2.1.0-beta'
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Hides the core interface from user scripts.
|
-- Hides the core interface from user scripts.
|
||||||
|
@ -1630,12 +1630,12 @@ local Sync = ( function( )
|
||||||
|
|
||||||
log(
|
log(
|
||||||
'Function',
|
'Function',
|
||||||
'delay(',
|
'delay( ',
|
||||||
self.config.name, ', ',
|
self.config.name, ', ',
|
||||||
etype, ', ',
|
etype, ', ',
|
||||||
path, ', ',
|
path, ', ',
|
||||||
path2,
|
path2,
|
||||||
')'
|
' )'
|
||||||
)
|
)
|
||||||
|
|
||||||
-- TODO
|
-- TODO
|
||||||
|
@ -1777,14 +1777,24 @@ local Sync = ( function( )
|
||||||
)
|
)
|
||||||
|
|
||||||
if nd.etype == 'Init' or nd.etype == 'Blanket' then
|
if nd.etype == 'Init' or nd.etype == 'Blanket' then
|
||||||
-- always stack blanket events on the last event
|
|
||||||
log('Delay', 'Stacking ',nd.etype,' event.')
|
-- always stack init or blanket events on the last event
|
||||||
|
log(
|
||||||
|
'Delay',
|
||||||
|
'Stacking ',
|
||||||
|
nd.etype,
|
||||||
|
' event.'
|
||||||
|
)
|
||||||
|
|
||||||
if self.delays.size > 0 then
|
if self.delays.size > 0 then
|
||||||
stack( self.delays[ self.delays.last ], nd )
|
stack( self.delays[ self.delays.last ], nd )
|
||||||
end
|
end
|
||||||
|
|
||||||
nd.dpos = Queue.push( self.delays, nd )
|
nd.dpos = Queue.push( self.delays, nd )
|
||||||
recurse( )
|
recurse( )
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- detects blocks and combos by working from back until
|
-- detects blocks and combos by working from back until
|
||||||
|
@ -1896,11 +1906,10 @@ local Sync = ( function( )
|
||||||
|
|
||||||
log(
|
log(
|
||||||
'Function',
|
'Function',
|
||||||
'invokeActions("',
|
'invokeActions( "',
|
||||||
self.config.name,
|
self.config.name, '", ',
|
||||||
'",',
|
timestamp,
|
||||||
timestamp,
|
' )'
|
||||||
')'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.processes:size( ) >= self.config.maxProcesses then
|
if self.processes:size( ) >= self.config.maxProcesses then
|
||||||
|
@ -1909,6 +1918,7 @@ local Sync = ( function( )
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, d in Queue.qpairs( self.delays ) do
|
for _, d in Queue.qpairs( self.delays ) do
|
||||||
|
|
||||||
-- if reached the global limit return
|
-- if reached the global limit return
|
||||||
if settings.maxProcesses and
|
if settings.maxProcesses and
|
||||||
processCount >= settings.maxProcesses
|
processCount >= settings.maxProcesses
|
||||||
|
@ -1927,12 +1937,14 @@ local Sync = ( function( )
|
||||||
end
|
end
|
||||||
|
|
||||||
if d.status == 'wait' then
|
if d.status == 'wait' then
|
||||||
|
|
||||||
-- found a waiting delay
|
-- found a waiting delay
|
||||||
if d.etype ~= 'Init' then
|
if d.etype ~= 'Init' then
|
||||||
self.config.action( self.inlet )
|
self.config.action( self.inlet )
|
||||||
else
|
else
|
||||||
self.config.init( InletFactory.d2e( d ) )
|
self.config.init( InletFactory.d2e( d ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.processes:size( ) >= self.config.maxProcesses then
|
if self.processes:size( ) >= self.config.maxProcesses then
|
||||||
-- no further processes
|
-- no further processes
|
||||||
return
|
return
|
||||||
|
@ -1980,8 +1992,11 @@ local Sync = ( function( )
|
||||||
-- Used as startup marker to call init asap.
|
-- Used as startup marker to call init asap.
|
||||||
--
|
--
|
||||||
local function addInitDelay( self )
|
local function addInitDelay( self )
|
||||||
|
|
||||||
local newd = Delay.new( 'Init', self, true, '' )
|
local newd = Delay.new( 'Init', self, true, '' )
|
||||||
|
|
||||||
newd.dpos = Queue.push( self.delays, newd )
|
newd.dpos = Queue.push( self.delays, newd )
|
||||||
|
|
||||||
return newd
|
return newd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2113,7 +2128,7 @@ local Syncs = ( function( )
|
||||||
local round = 1
|
local round = 1
|
||||||
|
|
||||||
--
|
--
|
||||||
-- The cycle() sheduler goes into the next round of roundrobin.
|
-- The cycle( ) sheduler goes into the next round of roundrobin.
|
||||||
--
|
--
|
||||||
local function nextRound( )
|
local function nextRound( )
|
||||||
|
|
||||||
|
@ -2141,31 +2156,85 @@ local Syncs = ( function( )
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Inheritly copies all non integer keys from
|
-- Helper function for inherit
|
||||||
-- table copy source ( cs ) to
|
-- defined below
|
||||||
-- table copy destination ( cd ).
|
|
||||||
--
|
--
|
||||||
-- All entries with integer keys are treated as new sources to copy
|
local inheritKV
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Recurvely inherits a source table to a destionation table
|
||||||
|
-- copying all keys from source.
|
||||||
|
--
|
||||||
|
-- table copy source ( cs )
|
||||||
|
-- table copy destination ( cd )
|
||||||
|
--
|
||||||
|
-- All entries with integer keys are inherited as additional
|
||||||
|
-- sources for non-verbatim tables
|
||||||
--
|
--
|
||||||
local function inherit( cd, cs )
|
local function inherit( cd, cs )
|
||||||
|
|
||||||
-- first copies from source all
|
--
|
||||||
-- non-defined non-integer keyed values
|
-- First copies all entries with non-integer keys
|
||||||
|
-- tables are merged, already present keys are not
|
||||||
|
-- overwritten
|
||||||
|
--
|
||||||
|
-- For verbatim tables integer keys are treated like
|
||||||
|
-- non integer keys
|
||||||
|
--
|
||||||
for k, v in pairs( cs ) do
|
for k, v in pairs( cs ) do
|
||||||
if type( k ) ~= 'number' and cd[ k ] == nil then
|
if type( k ) ~= 'number' or cs._verbatim == true then
|
||||||
cd[ k ] = v
|
inheritKV( cd, k, v )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- first recurses into all integer keyed tables
|
--
|
||||||
for i, v in ipairs( cs ) do
|
-- recursevely inherits all integer keyed tables
|
||||||
if type( v ) == 'table' then
|
-- ( for non-verbatim tables )
|
||||||
inherit( cd, v )
|
--
|
||||||
|
if cs._verbatim ~= true then
|
||||||
|
|
||||||
|
local n = nil
|
||||||
|
for k, v in ipairs( cs ) do
|
||||||
|
n = k
|
||||||
|
if type( v ) == 'table' then
|
||||||
|
inherit( cd, v )
|
||||||
|
else
|
||||||
|
cd[ #cd + 1 ] = v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Helper to inherit. Inherits one key.
|
||||||
|
--
|
||||||
|
inheritKV = function( cd, k, v )
|
||||||
|
|
||||||
|
local dtype = type( cd [ k ] )
|
||||||
|
|
||||||
|
if type( v ) == 'table' then
|
||||||
|
|
||||||
|
if dtype == 'nil' then
|
||||||
|
|
||||||
|
cd[ k ] = { }
|
||||||
|
inherit( cd[ k ], v )
|
||||||
|
|
||||||
|
elseif dtype == 'table' and v._merge ~= false then
|
||||||
|
|
||||||
|
inherit( cd[ k ], v )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif dtype == 'nil' then
|
||||||
|
|
||||||
|
cd[ k ] = v
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Adds a new sync (directory-tree to observe).
|
-- Adds a new sync (directory-tree to observe).
|
||||||
--
|
--
|
||||||
|
@ -2175,7 +2244,7 @@ local Syncs = ( function( )
|
||||||
-- from integer keyed tables
|
-- from integer keyed tables
|
||||||
local uconfig = config
|
local uconfig = config
|
||||||
config = { }
|
config = { }
|
||||||
inherit( config, uconfig )
|
inherit( config, uconfig, false )
|
||||||
|
|
||||||
-- Lets settings or commandline override delay values.
|
-- Lets settings or commandline override delay values.
|
||||||
if settings then
|
if settings then
|
||||||
|
@ -2227,7 +2296,7 @@ local Syncs = ( function( )
|
||||||
'Error',
|
'Error',
|
||||||
info.short_src, ':',
|
info.short_src, ':',
|
||||||
info.currentline,
|
info.currentline,
|
||||||
': no actions specified, use e.g. "config = default.rsync".'
|
': no actions specified.'
|
||||||
)
|
)
|
||||||
|
|
||||||
terminate( -1 )
|
terminate( -1 )
|
||||||
|
@ -2391,14 +2460,21 @@ local Inotify = ( function( )
|
||||||
pathwds[ path ] = nil
|
pathwds[ path ] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
|
||||||
|
--
|
||||||
-- Adds watches for a directory (optionally) including all subdirectories.
|
-- Adds watches for a directory (optionally) including all subdirectories.
|
||||||
--
|
--
|
||||||
-- @param path absolute path of directory to observe
|
-- @param path absolute path of directory to observe
|
||||||
-- @param recurse true if recursing into subdirs
|
-- @param recurse true if recursing into subdirs
|
||||||
--
|
--
|
||||||
local function addWatch(path)
|
local function addWatch(path)
|
||||||
log('Function','Inotify.addWatch(',path,')')
|
|
||||||
|
log(
|
||||||
|
'Function',
|
||||||
|
'Inotify.addWatch( ',
|
||||||
|
path,
|
||||||
|
' )'
|
||||||
|
)
|
||||||
|
|
||||||
if not Syncs.concerns(path) then
|
if not Syncs.concerns(path) then
|
||||||
log('Inotify', 'not concerning "',path,'"')
|
log('Inotify', 'not concerning "',path,'"')
|
||||||
|
@ -3075,9 +3151,9 @@ local StatusFile = ( function( )
|
||||||
|
|
||||||
log(
|
log(
|
||||||
'Function',
|
'Function',
|
||||||
'write(',
|
'write( ',
|
||||||
timestamp,
|
timestamp,
|
||||||
')'
|
' )'
|
||||||
)
|
)
|
||||||
|
|
||||||
-- takes care not write too often
|
-- takes care not write too often
|
||||||
|
@ -3313,20 +3389,25 @@ function runner.cycle(
|
||||||
)
|
)
|
||||||
|
|
||||||
if lsyncdStatus == 'fade' then
|
if lsyncdStatus == 'fade' then
|
||||||
|
|
||||||
if processCount > 0 then
|
if processCount > 0 then
|
||||||
|
|
||||||
log(
|
log(
|
||||||
'Normal',
|
'Normal',
|
||||||
'waiting for ',
|
'waiting for ',
|
||||||
processCount,
|
processCount,
|
||||||
' more child processes.'
|
' more child processes.'
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if lsyncdStatus ~= 'run' then
|
if lsyncdStatus ~= 'run' then
|
||||||
|
|
||||||
error( 'runner.cycle() called while not running!' )
|
error( 'runner.cycle() called while not running!' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3340,17 +3421,19 @@ function runner.cycle(
|
||||||
processCount < settings.maxProcesses
|
processCount < settings.maxProcesses
|
||||||
then
|
then
|
||||||
local start = Syncs.getRound( )
|
local start = Syncs.getRound( )
|
||||||
|
|
||||||
local ir = start
|
local ir = start
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
|
|
||||||
local s = Syncs.get( ir )
|
local s = Syncs.get( ir )
|
||||||
s:invokeActions( timestamp )
|
s:invokeActions( timestamp )
|
||||||
ir = ir + 1
|
ir = ir + 1
|
||||||
|
|
||||||
if ir > Syncs.size( ) then
|
if ir > Syncs.size( ) then
|
||||||
|
|
||||||
ir = 1
|
ir = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
until ir == start
|
until ir == start
|
||||||
|
|
||||||
Syncs.nextRound( )
|
Syncs.nextRound( )
|
||||||
|
@ -3652,13 +3735,19 @@ end
|
||||||
--
|
--
|
||||||
function runner.initialize( firstTime )
|
function runner.initialize( firstTime )
|
||||||
|
|
||||||
|
--
|
||||||
-- creates settings if user didnt
|
-- creates settings if user didnt
|
||||||
|
--
|
||||||
settings = settings or {}
|
settings = settings or {}
|
||||||
|
|
||||||
|
--
|
||||||
-- From this point on, no globals may be created anymore
|
-- From this point on, no globals may be created anymore
|
||||||
lockGlobals()
|
--
|
||||||
|
lockGlobals( )
|
||||||
|
|
||||||
-- copies simple settings with numeric keys to 'key=true' settings.
|
--
|
||||||
|
-- copies simple settings with numeric keys to 'key = true' settings.
|
||||||
|
--
|
||||||
for k, v in ipairs( settings ) do
|
for k, v in ipairs( settings ) do
|
||||||
|
|
||||||
if settings[ v ] then
|
if settings[ v ] then
|
||||||
|
@ -3714,23 +3803,23 @@ function runner.initialize( firstTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.nodaemon then
|
if settings.nodaemon then
|
||||||
lsyncd.configure('nodaemon')
|
lsyncd.configure( 'nodaemon' )
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.logfile then
|
if settings.logfile then
|
||||||
lsyncd.configure('logfile', settings.logfile)
|
lsyncd.configure( 'logfile', settings.logfile )
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.logident then
|
if settings.logident then
|
||||||
lsyncd.configure('logident', settings.logident)
|
lsyncd.configure( 'logident', settings.logident )
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.logfacility then
|
if settings.logfacility then
|
||||||
lsyncd.configure('logfacility', settings.logfacility)
|
lsyncd.configure( 'logfacility', settings.logfacility )
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.pidfile then
|
if settings.pidfile then
|
||||||
lsyncd.configure('pidfile', settings.pidfile)
|
lsyncd.configure( 'pidfile', settings.pidfile )
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -3753,6 +3842,7 @@ function runner.initialize( firstTime )
|
||||||
|
|
||||||
-- from now on use logging as configured instead of stdout/err.
|
-- from now on use logging as configured instead of stdout/err.
|
||||||
lsyncdStatus = 'run';
|
lsyncdStatus = 'run';
|
||||||
|
|
||||||
lsyncd.configure( 'running' );
|
lsyncd.configure( 'running' );
|
||||||
|
|
||||||
local ufuncs = {
|
local ufuncs = {
|
||||||
|
@ -3766,34 +3856,49 @@ function runner.initialize( firstTime )
|
||||||
|
|
||||||
-- translates layer 3 scripts
|
-- translates layer 3 scripts
|
||||||
for _, s in Syncs.iwalk() do
|
for _, s in Syncs.iwalk() do
|
||||||
|
|
||||||
-- checks if any user functions is a layer 3 string.
|
-- checks if any user functions is a layer 3 string.
|
||||||
local config = s.config
|
local config = s.config
|
||||||
|
|
||||||
for _, fn in ipairs(ufuncs) do
|
for _, fn in ipairs(ufuncs) do
|
||||||
|
|
||||||
if type(config[fn]) == 'string' then
|
if type(config[fn]) == 'string' then
|
||||||
|
|
||||||
local ft = functionWriter.translate(config[fn])
|
local ft = functionWriter.translate(config[fn])
|
||||||
config[fn] = assert(loadstring('return '..ft))()
|
config[fn] = assert(loadstring('return '..ft))()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- runs through the Syncs created by users
|
-- runs through the Syncs created by users
|
||||||
for _, s in Syncs.iwalk( ) do
|
for _, s in Syncs.iwalk( ) do
|
||||||
|
|
||||||
if s.config.monitor == 'inotify' then
|
if s.config.monitor == 'inotify' then
|
||||||
|
|
||||||
Inotify.addSync( s, s.source )
|
Inotify.addSync( s, s.source )
|
||||||
|
|
||||||
elseif s.config.monitor == 'fsevents' then
|
elseif s.config.monitor == 'fsevents' then
|
||||||
|
|
||||||
Fsevents.addSync( s, s.source )
|
Fsevents.addSync( s, s.source )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
error(
|
error(
|
||||||
'sync ' ..
|
'sync ' ..
|
||||||
s.config.name ..
|
s.config.name ..
|
||||||
' has no known event monitor interface.'
|
' has no known event monitor interface.'
|
||||||
)
|
)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if the sync has an init function, the init delay
|
-- if the sync has an init function, the init delay
|
||||||
-- is stacked which causes the init function to be called.
|
-- is stacked which causes the init function to be called.
|
||||||
if s.config.init then
|
if s.config.init then
|
||||||
|
|
||||||
s:addInitDelay( )
|
s:addInitDelay( )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ end
|
||||||
cwriteln("testing startup excludes");
|
cwriteln("testing startup excludes");
|
||||||
writefiles();
|
writefiles();
|
||||||
cwriteln("starting Lsyncd");
|
cwriteln("starting Lsyncd");
|
||||||
local pid = spawn("./lsyncd", cfgfile);
|
local pid = spawn("./lsyncd", cfgfile, '-log', 'all');
|
||||||
cwriteln("waiting for Lsyncd to start");
|
cwriteln("waiting for Lsyncd to start");
|
||||||
posix.sleep(3)
|
posix.sleep(3)
|
||||||
cwriteln("testing excludes after startup");
|
cwriteln("testing excludes after startup");
|
||||||
|
|
Loading…
Reference in New Issue