This commit is contained in:
Axel Kittenberger 2010-10-18 17:09:59 +00:00
parent cba4cc680c
commit b7a51969bb
4 changed files with 121 additions and 23 deletions

View File

@ -1,7 +1,7 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
#AC_PREREQ(2.60)
AC_INIT(lsyncd, 2.0, axkibe@gmail.com)
AC_INIT(lsyncd, 2.0b1, axkibe@gmail.com)
AC_CONFIG_SRCDIR([lsyncd.c])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE(lsyncd, main)

View File

@ -1,4 +1,5 @@
settings = {
logfile = "/tmp/lsyncd",
nodaemon,
}

109
lsyncd.c
View File

@ -26,6 +26,11 @@
#include <lualib.h>
#include <lauxlib.h>
/**
* The Lua part of lsyncd.
*/
#define LSYNCD_RUNNER_FILE "lsyncd.lua"
/**
* The inotify file descriptor.
*/
@ -39,6 +44,13 @@ const uint32_t standard_event_mask =
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
/**
* Configuration settings relevant for core.
*/
struct settings {
char * logfile;
};
struct settings settings = {0,};
/**
* Set to TERM or HUP in signal handler, when lsyncd should end or reset ASAP.
@ -74,6 +86,22 @@ s_malloc(size_t size)
return r;
}
/**
* "secured" strdup.
*/
char *
s_strdup(const char *src)
{
char *s = strdup(src);
if (s == NULL) {
printf("Out of memory!\n");
exit(-1); // ERRNO
}
return s;
}
/*****************************************************************************
* Library calls for lsyncd.lua
*
@ -250,7 +278,7 @@ l_sub_dirs (lua_State *L)
isdir = S_ISDIR(st.st_mode);
free(subdir);
} else {
/* we can trust readdir */
/* readdir can trusted */
isdir = de->d_type == DT_DIR;
}
if (!isdir || !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
@ -281,10 +309,6 @@ l_terminate(lua_State *L)
return 0;
}
/*****************************************************************************
* Lsyncd Core
****************************************************************************/
static const luaL_reg lsyncdlib[] = {
{"add_watch", l_add_watch},
{"exec", l_exec},
@ -295,6 +319,44 @@ static const luaL_reg lsyncdlib[] = {
{NULL, NULL}
};
/*****************************************************************************
* Lsyncd Core
****************************************************************************/
/**
* Transfers the core relevant settings from lua's global "settings" into core.
* This saves time in normal operation instead of bothering lua all the time.
*/
void
get_settings(lua_State *L)
{
/* frees old settings */
if (settings.logfile) {
free(settings.logfile);
settings.logfile = NULL;
}
/* gets settings table */
lua_getglobal(L, "settings");
if (!lua_istable(L, -1)) {
/* user has not specified any settings */
return;
}
/* logfile */
lua_pushstring(L, "logfile");
lua_gettable(L, -2);
if (settings.logfile) {
free(settings.logfile);
settings.logfile = NULL;
}
if (lua_isstring(L, -1)) {
settings.logfile = s_strdup(luaL_checkstring(L, -1));
}
lua_pop(L, 1);
}
/**
* Waits after startup for all children.
*
@ -377,11 +439,9 @@ wait_startup(lua_State *L)
}
}
}
free(pids);
}
/**
* Main
*/
@ -398,20 +458,37 @@ main(int argc, char *argv[])
lua_setglobal(L, "lysncd");
if (luaL_loadfile(L, "lsyncd.lua")) {
printf("error loading lsyncd.lua: %s\n", lua_tostring(L, -1));
printf("error loading '%s': %s\n",
LSYNCD_RUNNER_FILE, lua_tostring(L, -1));
return -1; // ERRNO
}
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
printf("error running lsyncd.lua: %s\n", lua_tostring(L, -1));
printf("error preparing '%s': %s\n",
LSYNCD_RUNNER_FILE, lua_tostring(L, -1));
return -1; // ERRNO
}
{
/* checks version match between runner/core */
const char *lversion;
lua_getglobal(L, "lsyncd_version");
lversion = luaL_checkstring(L, -1);
lua_pop(L, 1);
if (strcmp(lversion, PACKAGE_VERSION)) {
printf("Version mismatch '%s' is '%s', but core is '%s'\n",
LSYNCD_RUNNER_FILE,
lversion,
PACKAGE_VERSION);
return -1; // ERRNO
}
}
if (luaL_loadfile(L, "lsyncd-conf.lua")) {
printf("error loading lsyncd-conf.lua: %s\n", lua_tostring(L, -1));
printf("error load lsyncd-conf.lua: %s\n", lua_tostring(L, -1));
return -1; // ERRNO
}
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
printf("error running lsyncd-conf.lua: %s\n", lua_tostring(L, -1));
printf("error prep lsyncd-conf.lua: %s\n", lua_tostring(L, -1));
return -1; // ERRNO
}
@ -426,13 +503,21 @@ main(int argc, char *argv[])
/* lua code will set configuration and add watches */
lua_getglobal(L, "lsyncd_initialize");
lua_call(L, 0, 0);
/* load core settings into core */
get_settings(L);
/* startup */
/* lua code will perform startup calls like recursive rsync */
lua_getglobal(L, "startup");
lua_call(L, 0, 1);
/* wait for children spawned at startup */
wait_startup(L);
/* enter normal operation */
lua_getglobal(L, "normalop");
lua_call(L, 0, 1);
/* cleanup */
close(inotify_fd);
lua_close(L);

View File

@ -2,17 +2,21 @@
-- lsyncd runner implemented in LUA
------------------------------------------------------------------------------
----
-- Core will exit if version ids mismatch.
lsyncd_version = "2.0b1"
----
-- Table of all directories to watch.
local origins = {}
origins = {}
----
-- all targets
local targets = {}
targets = {}
-----
-- all watches
local watches = {}
watches = {}
----
-- Adds watches for a directory including all subdirectories.
@ -21,7 +25,6 @@ local watches = {}
-- @param target
--
local function attend_dir(origin, path, target)
print("attending dir", origin, "+", path, "->", target.path);
-- actual dir = origin + path
local op = origin .. path
-- register watch and receive watch descriptor
@ -54,10 +57,8 @@ end
-- Called from core on init or restart after user configuration.
--
function lsyncd_initialize()
print("--- INIT ---")
local i, o
for i, o in ipairs(origins) do
print("Handling ", o.source, "->" , o.targetpath)
-- resolves source to be an absolute path
local src = lsyncd.real_dir(o.source)
if src == nil then
@ -100,12 +101,11 @@ end
-- "startup". (and yet may still call default startup)
--
function default_startup()
print("--- STARTUP ---")
print("--- startup ---")
local pids = { }
for i, o in ipairs(origins) do
print("/usr/bin/rsync", "-ltrs", o.source, o.targetpath)
print("initialize recursive rsync: " .. o.source .. " -> " .. o.targetpath)
pid = lsyncd.exec("/usr/bin/rsync", "-ltrs", o.source, o.targetpath)
print("started ", pid)
table.insert(pids, pid)
end
return pids
@ -123,7 +123,6 @@ startup = default_startup
-- finished/ok.
--
function default_startup_returned(pid, exitcode)
print("startup_returned ", pid, exitcode);
if exitcode ~= 0 then
print("Startup process", pid, " failed")
lsyncd.terminate(-1) -- ERRNO
@ -132,3 +131,16 @@ function default_startup_returned(pid, exitcode)
end
startup_returned = default_startup_returned
-----
-- Called by core after startup phase when finished waiting for
-- children spawned at startup.
--
function default_normalop()
print("--- Entering normal operation with " .. #watches .. " monitored directories ---")
end
normalop = default_normalop
----
-- other functions the user might want to use
exec = lsyncd.exec