mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-12 22:27:50 +00:00
Merge branch 'tunnel' into periodic-full
This commit is contained in:
commit
e2a4dc0e87
8
.editorconfig
Normal file
8
.editorconfig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 4 tab indentation
|
||||||
|
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.nix]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
@ -1,7 +1,7 @@
|
|||||||
# preamble
|
# preamble
|
||||||
project( Lsyncd )
|
project( Lsyncd )
|
||||||
cmake_minimum_required( VERSION 3.10 )
|
cmake_minimum_required( VERSION 3.10 )
|
||||||
set( LSYNCD_VERSION 2.2.3 )
|
set( LSYNCD_VERSION 2.3.0-beta1 )
|
||||||
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/" )
|
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/" )
|
||||||
|
|
||||||
|
|
||||||
@ -118,6 +118,6 @@ add_executable( lsyncd ${LSYNCD_SRC} )
|
|||||||
target_link_libraries( lsyncd ${LUA_LIBRARIES} )
|
target_link_libraries( lsyncd ${LUA_LIBRARIES} )
|
||||||
|
|
||||||
install( TARGETS lsyncd RUNTIME DESTINATION bin )
|
install( TARGETS lsyncd RUNTIME DESTINATION bin )
|
||||||
install( FILES doc/manpage/lsyncd.1 DESTINATION man )
|
install( FILES doc/manpage/lsyncd.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT man )
|
||||||
install( DIRECTORY examples DESTINATION doc )
|
install( DIRECTORY examples DESTINATION doc )
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ Lsyncd watches a local directory trees event monitor interface (inotify or fseve
|
|||||||
|
|
||||||
Rsync+ssh is an advanced action configuration that uses a SSH to act file and directory moves directly on the target instead of re-transmitting the move destination over the wire.
|
Rsync+ssh is an advanced action configuration that uses a SSH to act file and directory moves directly on the target instead of re-transmitting the move destination over the wire.
|
||||||
|
|
||||||
Fine-grained customization can be achieved through the config file. Custom action configs can even be written from scratch in cascading layers ranging from shell scripts to code written in the [Lua language](http://www.lua.org/). This way simple, powerful and flexible configurations can be acheived. See [the manual](https://axkibe.github.io/lsyncd/) for details.
|
Fine-grained customization can be achieved through the config file. Custom action configs can even be written from scratch in cascading layers ranging from shell scripts to code written in the [Lua language](http://www.lua.org/). This way simple, powerful and flexible configurations can be achieved. See [the manual](https://axkibe.github.io/lsyncd/) for details.
|
||||||
|
|
||||||
Lsyncd 2.2.1 requires rsync >= 3.1 on all source and target machines.
|
Lsyncd 2.2.1 requires rsync >= 3.1 on all source and target machines.
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#=============================================================================
|
#=============================================================================
|
||||||
# Copyright 2007-2009 Kitware, Inc.
|
# Copyright 2007-2009 Kitware, Inc.
|
||||||
# Modified to support Lua 5.2 by LuaDist 2012
|
# Modified to support Lua 5.2 by LuaDist 2012
|
||||||
|
# Modified to support Lua 5.4 by LuaDist 2022
|
||||||
#
|
#
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
# see accompanying file Copyright.txt for details.
|
# see accompanying file Copyright.txt for details.
|
||||||
@ -27,7 +28,7 @@
|
|||||||
# (To distribute this file outside of CMake, substitute the full
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
# License text for the above reference.)
|
# License text for the above reference.)
|
||||||
#
|
#
|
||||||
# This module will try to find the newest Lua version down to 5.2
|
# This module will try to find the newest Lua version down to 5.4
|
||||||
|
|
||||||
# Always search for non-versioned lua first (recommended)
|
# Always search for non-versioned lua first (recommended)
|
||||||
SET(_POSSIBLE_LUA_INCLUDE include include/lua)
|
SET(_POSSIBLE_LUA_INCLUDE include include/lua)
|
||||||
@ -36,7 +37,7 @@ SET(_POSSIBLE_LUA_INCLUDE include include/lua)
|
|||||||
#SET(_POSSIBLE_LUA_LIBRARY lua)
|
#SET(_POSSIBLE_LUA_LIBRARY lua)
|
||||||
|
|
||||||
# Determine possible naming suffixes (there is no standard for this)
|
# Determine possible naming suffixes (there is no standard for this)
|
||||||
SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "53" "5.3" "-5.3" "")
|
SET(_POSSIBLE_SUFFIXES "54" "5.4" "-5.4" "53" "5.3" "-5.3" "52" "5.2" "-5.2" "")
|
||||||
|
|
||||||
# Set up possible search names and locations
|
# Set up possible search names and locations
|
||||||
FOREACH(_SUFFIX IN LISTS _POSSIBLE_SUFFIXES)
|
FOREACH(_SUFFIX IN LISTS _POSSIBLE_SUFFIXES)
|
||||||
|
@ -63,6 +63,7 @@ rsync.checkgauge = {
|
|||||||
copy_links = true,
|
copy_links = true,
|
||||||
copy_unsafe_links = true,
|
copy_unsafe_links = true,
|
||||||
cvs_exclude = true,
|
cvs_exclude = true,
|
||||||
|
delete_excluded = true,
|
||||||
dry_run = true,
|
dry_run = true,
|
||||||
executability = true,
|
executability = true,
|
||||||
existing = true,
|
existing = true,
|
||||||
@ -128,6 +129,9 @@ rsync.action = function
|
|||||||
-- gets all events ready for syncing
|
-- gets all events ready for syncing
|
||||||
local elist = inlet.getEvents( eventNotInitBlank )
|
local elist = inlet.getEvents( eventNotInitBlank )
|
||||||
|
|
||||||
|
local substitudes = inlet.getSubstitutionData(elist, {})
|
||||||
|
local target = substitudeCommands(config.target, substitudes)
|
||||||
|
|
||||||
-- gets the list of paths for the event list
|
-- gets the list of paths for the event list
|
||||||
-- deletes create multi match patterns
|
-- deletes create multi match patterns
|
||||||
local paths = elist.getPaths( )
|
local paths = elist.getPaths( )
|
||||||
@ -236,7 +240,7 @@ rsync.action = function
|
|||||||
'--include-from=-',
|
'--include-from=-',
|
||||||
'--exclude=*',
|
'--exclude=*',
|
||||||
config.source,
|
config.source,
|
||||||
config.target
|
target
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -317,7 +321,7 @@ rsync.init = function
|
|||||||
|
|
||||||
local filters = inlet.hasFilters( ) and inlet.getFilters( )
|
local filters = inlet.hasFilters( ) and inlet.getFilters( )
|
||||||
|
|
||||||
local delete = nil
|
local delete = {}
|
||||||
|
|
||||||
local target = config.target
|
local target = config.target
|
||||||
|
|
||||||
@ -331,12 +335,20 @@ rsync.init = function
|
|||||||
target = config.host .. ':' .. config.targetdir
|
target = config.host .. ':' .. config.targetdir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local substitudes = inlet.getSubstitutionData(event, {})
|
||||||
|
target = substitudeCommands(target, substitudes)
|
||||||
|
|
||||||
if config.delete == true
|
if config.delete == true
|
||||||
or config.delete == 'startup'
|
or config.delete == 'startup'
|
||||||
then
|
then
|
||||||
delete = { '--delete', '--ignore-errors' }
|
delete = { '--delete', '--ignore-errors' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if config.rsync.delete_excluded == true
|
||||||
|
then
|
||||||
|
table.insert( delete, '--delete-excluded' )
|
||||||
|
end
|
||||||
|
|
||||||
if not filters and #excludes == 0
|
if not filters and #excludes == 0
|
||||||
then
|
then
|
||||||
-- starts rsync without any filters or excludes
|
-- starts rsync without any filters or excludes
|
||||||
|
10
default.lua
10
default.lua
@ -52,6 +52,7 @@ default.checkgauge = {
|
|||||||
prepare = true,
|
prepare = true,
|
||||||
source = true,
|
source = true,
|
||||||
target = true,
|
target = true,
|
||||||
|
tunnel = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -120,7 +121,14 @@ default.collect = function
|
|||||||
agent.target,
|
agent.target,
|
||||||
' finished.'
|
' finished.'
|
||||||
)
|
)
|
||||||
|
if settings('onepass')
|
||||||
|
then
|
||||||
|
log(
|
||||||
|
'Normal',
|
||||||
|
'onepass config set, exiting'
|
||||||
|
)
|
||||||
|
terminate( 0 )
|
||||||
|
end
|
||||||
return 'ok'
|
return 'ok'
|
||||||
elseif rc == 'again'
|
elseif rc == 'again'
|
||||||
then
|
then
|
||||||
|
@ -17,16 +17,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1637709854,
|
"lastModified": 1639488789,
|
||||||
"narHash": "sha256-y98gkOBUEiPAmwRhZPzTQ0YayZKPS2loNgA0GcNewMM=",
|
"narHash": "sha256-Ey12CBni1jlEGoW4eH4X0hugWs25MxHMcNH4N8VVX0U=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9c43581935a23d56734bd02da0ba8e7fda21e747",
|
"rev": "ce635e9dca8f7e2bfab19a3667d7e697c019c68b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "release-21.05",
|
"ref": "release-21.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
63
flake.nix
63
flake.nix
@ -1,27 +1,37 @@
|
|||||||
{
|
{
|
||||||
description = "Lsyncd (Live Syncing Daemon)";
|
description = "Lsyncd (Live Syncing Daemon)";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/release-21.05";
|
inputs.nixpkgs.url = "github:nixos/nixpkgs/release-21.11";
|
||||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }:
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
flake-utils.lib.eachDefaultSystem
|
flake-utils.lib.eachDefaultSystem
|
||||||
(system:
|
(system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = (import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
# Makes the config pure as well. See <nixpkgs>/top-level/impure.nix:
|
||||||
|
config = {
|
||||||
|
allowBroken = true;
|
||||||
|
};}); #.legacyPackages.${system};
|
||||||
defaultDeps = with pkgs; [
|
defaultDeps = with pkgs; [
|
||||||
gcc
|
gcc
|
||||||
cmake
|
cmake
|
||||||
|
gnumake
|
||||||
glib
|
glib
|
||||||
rsync
|
rsync
|
||||||
openssh
|
openssh
|
||||||
|
curl
|
||||||
];
|
];
|
||||||
version = builtins.elemAt
|
version = builtins.elemAt
|
||||||
(builtins.match ''.*set\(.LSYNCD_VERSION ([0-9\.]*).*''
|
(builtins.match ''.*set\(.LSYNCD_VERSION ([0-9\.]*).*''
|
||||||
(builtins.substring 0 500
|
(builtins.substring 0 500
|
||||||
(builtins.readFile ./CMakeLists.txt))) 0;
|
(builtins.readFile ./CMakeLists.txt))) 0;
|
||||||
|
mylua5_4 = pkgs.lua5_4.override({
|
||||||
|
packageOverrides = luaself: luaprev: {
|
||||||
|
luarocks = luaprev.luarocks-3_7;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
buildExtensions = luapkgs: (
|
buildExtensions = luapkgs: (
|
||||||
let
|
let
|
||||||
@ -82,11 +92,34 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
luaposix35 = mylua: mylua.pkgs.buildLuarocksPackage {
|
||||||
|
pname = "luaposix";
|
||||||
|
lua = mylua;
|
||||||
|
version = "35.1-1";
|
||||||
|
knownRockspec = (pkgs.fetchurl {
|
||||||
|
url = "https://luarocks.org/luaposix-35.1-1.rockspec";
|
||||||
|
sha256 = "1n6c7qyabj2y95jmbhf8fxbrp9i73kphmwalsam07f9w9h995xh1";
|
||||||
|
}).outPath;
|
||||||
|
src = pkgs.fetchurl {
|
||||||
|
url = "http://github.com/luaposix/luaposix/archive/v35.1.zip";
|
||||||
|
sha256 = "1c03chkzwr2p1wd0hs1bafl2890fqbrfc3qk0wxbd202gc6128zi";
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
propagatedBuildInputs = [ mylua ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
homepage = "http://github.com/luaposix/luaposix/";
|
||||||
|
description = "Lua bindings for POSIX";
|
||||||
|
license.fullName = "MIT/X11";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
buildTypes = {
|
buildTypes = {
|
||||||
lua5_1 = [(pkgs.lua5_1.withPackages (ps: [ps.luaposix ps.penlight (buildExtensions pkgs.lua51Packages)]))];
|
lua5_1 = [pkgs.lua5_1 pkgs.lua51Packages.luaposix (buildExtensions pkgs.lua51Packages)];
|
||||||
lua5_2 = [(pkgs.lua5_2.withPackages (ps: [ps.luaposix ps.penlight (buildExtensions pkgs.lua52Packages)]))];
|
lua5_2 = [pkgs.lua5_2 pkgs.lua52Packages.luaposix (buildExtensions pkgs.lua51Packages)];
|
||||||
lua5_3 = [(pkgs.lua5_3.withPackages (ps: [ps.luaposix ps.penlight (buildExtensions pkgs.lua53Packages)]))];
|
lua5_3 = [pkgs.lua5_3 pkgs.lua53Packages.luaposix (buildExtensions pkgs.lua51Packages)];
|
||||||
lua5_4 = [(pkgs.lua5_4.withPackages (ps: [ps.luaposix ps.penlight (buildExtensions pkgs.lua54Packages)]))];
|
lua5_4 = [pkgs.lua5_3 (luaposix35 mylua5_4) (buildExtensions mylua5_4)];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
let
|
let
|
||||||
@ -98,6 +131,9 @@
|
|||||||
|
|
||||||
buildInputs = defaultDeps ++ luaPackages;
|
buildInputs = defaultDeps ++ luaPackages;
|
||||||
});
|
});
|
||||||
|
mkDev = packages: pkgs.mkShell {
|
||||||
|
propagatedBuildInputs = defaultDeps ++ packages;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages = {
|
packages = {
|
||||||
@ -108,10 +144,15 @@
|
|||||||
lsyncd_lua5_4 = mkLsync buildTypes.lua5_4;
|
lsyncd_lua5_4 = mkLsync buildTypes.lua5_4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
devShells = {
|
||||||
|
lsyncd = mkDev buildTypes.lua5_3;
|
||||||
|
lsyncd_lua5_1 = mkDev buildTypes.lua5_1;
|
||||||
|
lsyncd_lua5_2 = mkDev buildTypes.lua5_2;
|
||||||
|
lsyncd_lua5_3 = mkDev buildTypes.lua5_3;
|
||||||
|
lsyncd_lua5_4 = mkDev buildTypes.lua5_4;
|
||||||
|
};
|
||||||
|
|
||||||
defaultPackage = self.packages.${system}.lsyncd;
|
defaultPackage = self.packages.${system}.lsyncd;
|
||||||
# devShell = pkgs.mkShell {
|
|
||||||
# buildInputs = defaultDeps ++ buildTypes.lua5_3;
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
213
lsyncd.c
213
lsyncd.c
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#define SYSLOG_NAMES 1
|
#define SYSLOG_NAMES 1
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
@ -46,6 +48,11 @@
|
|||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
|
||||||
|
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
|
||||||
|
#define lua_objlen lua_rawlen
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| The Lua part of Lsyncd
|
| The Lua part of Lsyncd
|
||||||
*/
|
*/
|
||||||
@ -135,6 +142,22 @@ int pidfile_fd = 0;
|
|||||||
static long clocks_per_sec;
|
static long clocks_per_sec;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Dummy variable of which it's address is used as
|
||||||
|
| the cores index in the lua registry to
|
||||||
|
| the lua runners function table in the lua registry.
|
||||||
|
*/
|
||||||
|
static int runner;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Dummy variable of which it's address is used as
|
||||||
|
| the cores index n the lua registry to
|
||||||
|
| the lua runners error handler.
|
||||||
|
*/
|
||||||
|
static int callError;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* signal handler
|
* signal handler
|
||||||
*/
|
*/
|
||||||
@ -438,6 +461,40 @@ printlogf0(lua_State *L,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Print a traceback of the error
|
||||||
|
*/
|
||||||
|
static int l_traceback (lua_State *L) {
|
||||||
|
// runner.callError
|
||||||
|
lua_getglobal(L, "debug");
|
||||||
|
lua_getfield(L, -1, "traceback");
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_pushinteger(L, 2);
|
||||||
|
lua_call(L, 2, 1);
|
||||||
|
printlogf( L, "traceback", "%s", lua_tostring(L, -1) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Call runners terminate function and exit with given exit code
|
||||||
|
*/
|
||||||
|
static void safeexit (lua_State *L, int exitcode) {
|
||||||
|
// load_runner_func(L, "teardown");
|
||||||
|
// pushes the function
|
||||||
|
lua_pushlightuserdata( L, (void *) &runner );
|
||||||
|
lua_gettable( L, LUA_REGISTRYINDEX );
|
||||||
|
lua_pushstring( L, "teardown" );
|
||||||
|
lua_gettable( L, -2 );
|
||||||
|
lua_remove( L, -2 );
|
||||||
|
lua_pushinteger(L, exitcode);
|
||||||
|
lua_call(L, 2, 1);
|
||||||
|
if (lua_isinteger(L, -1)) {
|
||||||
|
exitcode = luaL_checkinteger(L, -1);
|
||||||
|
}
|
||||||
|
exit(exitcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
|
||||||
( Simple memory management )
|
( Simple memory management )
|
||||||
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||||
@ -605,23 +662,6 @@ pipe_tidy( struct observance * observance )
|
|||||||
( Helper Routines )
|
( Helper Routines )
|
||||||
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
| Dummy variable of which it's address is used as
|
|
||||||
| the cores index in the lua registry to
|
|
||||||
| the lua runners function table in the lua registry.
|
|
||||||
*/
|
|
||||||
static int runner;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
| Dummy variable of which it's address is used as
|
|
||||||
| the cores index n the lua registry to
|
|
||||||
| the lua runners error handler.
|
|
||||||
*/
|
|
||||||
static int callError;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| Sets the close-on-exit flag of a file descriptor.
|
| Sets the close-on-exit flag of a file descriptor.
|
||||||
*/
|
*/
|
||||||
@ -697,7 +737,7 @@ write_pidfile
|
|||||||
pidfile
|
pidfile
|
||||||
);
|
);
|
||||||
|
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = lockf( pidfile_fd, F_TLOCK, 0 );
|
int rc = lockf( pidfile_fd, F_TLOCK, 0 );
|
||||||
@ -710,7 +750,7 @@ write_pidfile
|
|||||||
pidfile
|
pidfile
|
||||||
);
|
);
|
||||||
|
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( buf, sizeof( buf ), "%i\n", getpid( ) );
|
snprintf( buf, sizeof( buf ), "%i\n", getpid( ) );
|
||||||
@ -918,7 +958,7 @@ user_obs_ready(
|
|||||||
// calls the user function
|
// calls the user function
|
||||||
if( lua_pcall( L, 1, 0, -3 ) )
|
if( lua_pcall( L, 1, 0, -3 ) )
|
||||||
{
|
{
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop( L, 2 );
|
lua_pop( L, 2 );
|
||||||
@ -954,7 +994,7 @@ user_obs_writey(
|
|||||||
// calls the user function
|
// calls the user function
|
||||||
if( lua_pcall( L, 1, 0, -3 ) )
|
if( lua_pcall( L, 1, 0, -3 ) )
|
||||||
{
|
{
|
||||||
exit(-1);
|
safeexit(L, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop( L, 2 );
|
lua_pop( L, 2 );
|
||||||
@ -1078,6 +1118,82 @@ l_now(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Sends a signal to proceess pid
|
||||||
|
|
|
||||||
|
| Params on Lua stack:
|
||||||
|
| 1: pid
|
||||||
|
| 2: signal
|
||||||
|
|
|
||||||
|
| Returns on Lua stack:
|
||||||
|
| return value of kill
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_kill( lua_State *L )
|
||||||
|
{
|
||||||
|
pid_t pid = luaL_checkinteger( L, 1 );
|
||||||
|
int sig = luaL_checkinteger( L, 2 );
|
||||||
|
|
||||||
|
int rv = kill(pid, sig );
|
||||||
|
|
||||||
|
lua_pushinteger( L, rv );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Returns a free port of host
|
||||||
|
|
|
||||||
|
| Params on Lua stack:
|
||||||
|
| (not yet) 1: hostname or ip for bind
|
||||||
|
|
|
||||||
|
| Returns on Lua stack:
|
||||||
|
| return integer of free port
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_free_port(lua_State *L) {
|
||||||
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(sock < 0) {
|
||||||
|
printf("error opening socket\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
serv_addr.sin_port = 0;
|
||||||
|
if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||||
|
if(errno == EADDRINUSE) {
|
||||||
|
printf("the port is not available. already to other process\n");
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
printf("could not bind to process (%d) %s\n", errno, strerror(errno));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socklen_t len = sizeof(serv_addr);
|
||||||
|
if (getsockname(sock, (struct sockaddr *)&serv_addr, &len) == -1) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushinteger(L, ntohs(serv_addr.sin_port));
|
||||||
|
|
||||||
|
if (close (sock) < 0 ) {
|
||||||
|
printf("did not close: %s\n", strerror(errno));
|
||||||
|
lua_pop ( L, 1 );
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
error:
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| Executes a subprocess. Does not wait for it to return.
|
| Executes a subprocess. Does not wait for it to return.
|
||||||
@ -1203,7 +1319,7 @@ l_exec( lua_State *L )
|
|||||||
"in spawn(), expected a string after pipe '<'"
|
"in spawn(), expected a string after pipe '<'"
|
||||||
);
|
);
|
||||||
|
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_text = lua_tolstring( L, 3, &pipe_len );
|
pipe_text = lua_tolstring( L, 3, &pipe_len );
|
||||||
@ -1215,7 +1331,7 @@ l_exec( lua_State *L )
|
|||||||
{
|
{
|
||||||
logstring( "Error", "cannot create a pipe!" );
|
logstring( "Error", "cannot create a pipe!" );
|
||||||
|
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// always closes the write end for child processes
|
// always closes the write end for child processes
|
||||||
@ -1839,6 +1955,8 @@ static const luaL_Reg lsyncdlib[] =
|
|||||||
{ "exec", l_exec },
|
{ "exec", l_exec },
|
||||||
{ "log", l_log },
|
{ "log", l_log },
|
||||||
{ "now", l_now },
|
{ "now", l_now },
|
||||||
|
{ "kill", l_kill },
|
||||||
|
{ "get_free_port", l_free_port },
|
||||||
{ "nonobserve_fd", l_nonobserve_fd },
|
{ "nonobserve_fd", l_nonobserve_fd },
|
||||||
{ "observe_fd", l_observe_fd },
|
{ "observe_fd", l_observe_fd },
|
||||||
{ "readdir", l_readdir },
|
{ "readdir", l_readdir },
|
||||||
@ -1861,7 +1979,7 @@ l_jiffies_add( lua_State *L )
|
|||||||
if( p1 && p2 )
|
if( p1 && p2 )
|
||||||
{
|
{
|
||||||
logstring( "Error", "Cannot add two timestamps!" );
|
logstring( "Error", "Cannot add two timestamps!" );
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1881,6 +1999,33 @@ l_jiffies_add( lua_State *L )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
| Adds a number in seconds to a jiffy timestamp.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_jiffies_concat( lua_State *L )
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
clock_t *p1 = ( clock_t * ) lua_touserdata( L, 1 );
|
||||||
|
clock_t *p2 = ( clock_t * ) lua_touserdata( L, 2 );
|
||||||
|
|
||||||
|
if( p1 && p2 )
|
||||||
|
{
|
||||||
|
logstring( "Error", "Cannot add two timestamps!" );
|
||||||
|
safeexit(L, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (p1) {
|
||||||
|
snprintf( buf, sizeof(buf), "%Lf", (long double)(*p1));
|
||||||
|
lua_pushfstring(L, "%s%s", &buf, luaL_checkstring( L, 2));
|
||||||
|
} else {
|
||||||
|
snprintf( buf, sizeof(buf), "%Lf", (long double)(*p2));
|
||||||
|
lua_pushfstring(L, "%s%s", luaL_checkstring( L, 1), &buf);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| Subracts two jiffy timestamps resulting in a number in seconds
|
| Subracts two jiffy timestamps resulting in a number in seconds
|
||||||
@ -1987,6 +2132,9 @@ register_lsyncd( lua_State *L )
|
|||||||
lua_pushcfunction( L, l_jiffies_eq );
|
lua_pushcfunction( L, l_jiffies_eq );
|
||||||
lua_setfield( L, mt, "__eq" );
|
lua_setfield( L, mt, "__eq" );
|
||||||
|
|
||||||
|
lua_pushcfunction( L, l_jiffies_concat );
|
||||||
|
lua_setfield( L, mt, "__concat" );
|
||||||
|
|
||||||
lua_pop( L, 1 ); // pop(mt)
|
lua_pop( L, 1 ); // pop(mt)
|
||||||
|
|
||||||
#ifdef WITH_INOTIFY
|
#ifdef WITH_INOTIFY
|
||||||
@ -2162,7 +2310,7 @@ masterloop(lua_State *L)
|
|||||||
|
|
||||||
if( lua_pcall( L, 0, 1, -2 ) )
|
if( lua_pcall( L, 0, 1, -2 ) )
|
||||||
{
|
{
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lua_type( L, -1 ) == LUA_TBOOLEAN)
|
if( lua_type( L, -1 ) == LUA_TBOOLEAN)
|
||||||
@ -2348,7 +2496,9 @@ masterloop(lua_State *L)
|
|||||||
lua_pushinteger( L, WEXITSTATUS( status ) );
|
lua_pushinteger( L, WEXITSTATUS( status ) );
|
||||||
|
|
||||||
if ( lua_pcall( L, 2, 0, -4 ) )
|
if ( lua_pcall( L, 2, 0, -4 ) )
|
||||||
{ exit(-1); }
|
{
|
||||||
|
safeexit(L, -1);
|
||||||
|
}
|
||||||
|
|
||||||
lua_pop( L, 1 );
|
lua_pop( L, 1 );
|
||||||
}
|
}
|
||||||
@ -2360,7 +2510,7 @@ masterloop(lua_State *L)
|
|||||||
|
|
||||||
if( lua_pcall( L, 0, 0, -2 ) )
|
if( lua_pcall( L, 0, 0, -2 ) )
|
||||||
{
|
{
|
||||||
exit( -1 );
|
safeexit( L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop( L, 1 );
|
lua_pop( L, 1 );
|
||||||
@ -2377,7 +2527,7 @@ masterloop(lua_State *L)
|
|||||||
|
|
||||||
if( lua_pcall( L, 1, 0, -3 ) )
|
if( lua_pcall( L, 1, 0, -3 ) )
|
||||||
{
|
{
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop( L, 1 );
|
lua_pop( L, 1 );
|
||||||
@ -2393,7 +2543,7 @@ masterloop(lua_State *L)
|
|||||||
|
|
||||||
if( lua_pcall( L, 1, 1, -3 ) )
|
if( lua_pcall( L, 1, 1, -3 ) )
|
||||||
{
|
{
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !lua_toboolean( L, -1 ) )
|
if( !lua_toboolean( L, -1 ) )
|
||||||
@ -2411,7 +2561,7 @@ masterloop(lua_State *L)
|
|||||||
"internal, stack is dirty."
|
"internal, stack is dirty."
|
||||||
);
|
);
|
||||||
l_stackdump( L );
|
l_stackdump( L );
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2791,8 +2941,9 @@ main1( int argc, char *argv[] )
|
|||||||
lsyncd_config_file,
|
lsyncd_config_file,
|
||||||
lua_tostring( L, -1 )
|
lua_tostring( L, -1 )
|
||||||
);
|
);
|
||||||
|
l_traceback(L);
|
||||||
|
|
||||||
exit( -1 );
|
safeexit(L, -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
lsyncd.h
1
lsyncd.h
@ -57,6 +57,7 @@ extern struct settings {
|
|||||||
int log_facility; // The syslog facility
|
int log_facility; // The syslog facility
|
||||||
int log_level; // -1 logs everything, 0 normal mode, LOG_ERROR errors only.
|
int log_level; // -1 logs everything, 0 normal mode, LOG_ERROR errors only.
|
||||||
bool nodaemon; // True if Lsyncd shall not daemonize.
|
bool nodaemon; // True if Lsyncd shall not daemonize.
|
||||||
|
bool onepass; // True if Lsyncd should exit after first sync pass
|
||||||
char * pidfile; // If not NULL Lsyncd writes its pid into this file.
|
char * pidfile; // If not NULL Lsyncd writes its pid into this file.
|
||||||
|
|
||||||
} settings;
|
} settings;
|
||||||
|
1004
lsyncd.lua
1004
lsyncd.lua
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,7 @@
|
|||||||
-- common testing environment
|
-- common testing environment
|
||||||
posix = require( 'posix' )
|
posix = require( 'posix' )
|
||||||
string = require( 'string' )
|
string = require( 'string' )
|
||||||
path = require( 'pl.path' )
|
|
||||||
stringx = require( 'pl.stringx' )
|
|
||||||
local sys_stat = require "posix.sys.stat"
|
local sys_stat = require "posix.sys.stat"
|
||||||
|
|
||||||
-- escape codes to colorize output on terminal
|
-- escape codes to colorize output on terminal
|
||||||
@ -94,10 +93,39 @@ function writefile
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function splitpath(P)
|
||||||
|
local i = #P
|
||||||
|
local ch = P:sub(i,i)
|
||||||
|
while i > 0 and ch ~= "/" do
|
||||||
|
i = i - 1
|
||||||
|
ch = P:sub(i,i)
|
||||||
|
end
|
||||||
|
if i == 0 then
|
||||||
|
return '',P
|
||||||
|
else
|
||||||
|
return P:sub(1,i-1), P:sub(i+1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function isabs(p)
|
||||||
|
return string.sub(p, 1, 2) == "/"
|
||||||
|
end
|
||||||
|
|
||||||
|
function abspath(P,pwd)
|
||||||
|
P = P:gsub('[\\/]$','')
|
||||||
|
if not isabs(P) then
|
||||||
|
local rv = posix.unistd.getcwd() .. "/" .. P
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
return P
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function script_path()
|
function script_path()
|
||||||
-- local str = debug.getinfo(2, "S").source:sub(2)
|
-- local str = debug.getinfo(2, "S").source:sub(2)
|
||||||
-- return str:match("(.*/)")
|
-- return str:match("(.*/)")
|
||||||
return path.dirname(path.abspath(debug.getinfo(1).short_src))
|
local dir, file = splitpath(abspath(debug.getinfo(1).short_src))
|
||||||
|
return dir
|
||||||
end
|
end
|
||||||
|
|
||||||
function which(exec)
|
function which(exec)
|
||||||
@ -159,6 +187,11 @@ function startSshd()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function strip(s)
|
||||||
|
return s:match "^%s*(.-)%s*$"
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Stop test ssh server
|
-- Stop test ssh server
|
||||||
--
|
--
|
||||||
@ -169,7 +202,7 @@ function stopSshd()
|
|||||||
then
|
then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
pid = stringx.strip(f:read("*a"))
|
pid = strip(f:read("*a"))
|
||||||
posix.kill(tonumber(pid))
|
posix.kill(tonumber(pid))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,4 +9,19 @@ assert(isTableEqual(
|
|||||||
{"-p", "22", "-i", "/home/test/bla blu/id_rsa"}
|
{"-p", "22", "-i", "/home/test/bla blu/id_rsa"}
|
||||||
))
|
))
|
||||||
|
|
||||||
|
-- test string replacement
|
||||||
|
local testData = {
|
||||||
|
localPort = 1234,
|
||||||
|
localHost = "localhorst"
|
||||||
|
}
|
||||||
|
assert(substitudeCommands("echo ssh ${localHost}:${localPort}", testData) ==
|
||||||
|
"echo ssh localhorst:1234")
|
||||||
|
|
||||||
|
assert(isTableEqual(
|
||||||
|
substitudeCommands({"-p${doesNotExist}", "2${localHost}2", "-i '${localPort}'"}, testData),
|
||||||
|
{"-p", "2localhorst2", "-i '1234'"}
|
||||||
|
))
|
||||||
|
|
||||||
|
assert(type(lsyncd.get_free_port()) == "number")
|
||||||
|
|
||||||
os.exit(0)
|
os.exit(0)
|
Loading…
Reference in New Issue
Block a user