mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-06-01 16:00:52 +00:00
This commit is contained in:
parent
844ae1b65e
commit
9976269bfb
|
@ -6,7 +6,7 @@
|
||||||
settings = {
|
settings = {
|
||||||
-- logfile = "/tmp/lsyncd",
|
-- logfile = "/tmp/lsyncd",
|
||||||
nodaemon,
|
nodaemon,
|
||||||
status = "/tmp/lsyncd.stat",
|
statuspipe = "/tmp/lsyncd.stat",
|
||||||
loglevel = DEBUG,
|
loglevel = DEBUG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,23 +55,6 @@ slowbash = {
|
||||||
-- end,
|
-- end,
|
||||||
}
|
}
|
||||||
|
|
||||||
-----
|
|
||||||
-- lsyncd classic - sync with rsync
|
|
||||||
--
|
|
||||||
-- All functions return the pid of a spawned process
|
|
||||||
-- or 0 if they didn't exec something.
|
|
||||||
rsync = {
|
|
||||||
----
|
|
||||||
-- Called for every sync/target pair on startup
|
|
||||||
startup = function(source, target)
|
|
||||||
log(NORMAL, "startup recursive rsync: " .. source .. " -> " .. target)
|
|
||||||
return exec("/usr/bin/rsync", "-ltrs", source, target)
|
|
||||||
end,
|
|
||||||
|
|
||||||
default = function(source, target, path)
|
|
||||||
return exec("/usr/bin/rsync", "--delete", "-ltds", source .. "/" .. path, target .. "/" .. path)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
sync("s", "d/", slowbash)
|
sync("s", "d/", slowbash)
|
||||||
|
|
||||||
|
|
314
lsyncd.c
314
lsyncd.c
|
@ -15,7 +15,7 @@
|
||||||
#ifdef HAVE_SYS_INOTIFY_H
|
#ifdef HAVE_SYS_INOTIFY_H
|
||||||
# include <sys/inotify.h>
|
# include <sys/inotify.h>
|
||||||
#else
|
#else
|
||||||
# error Missing <sys/inotify.h> please supply kernel-headers and rerun configure
|
# error Missing <sys/inotify.h>; supply kernel-headers and rerun configure.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -42,12 +42,14 @@
|
||||||
* Extended debugging, undefine these to enable respective parts.
|
* Extended debugging, undefine these to enable respective parts.
|
||||||
*/
|
*/
|
||||||
#define DBG_MASTERLOOP(x)
|
#define DBG_MASTERLOOP(x)
|
||||||
|
#define DBG_STARTUP(x)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debugging definitions
|
* Debugging definitions
|
||||||
*/
|
*/
|
||||||
#ifndef DBG_MASTERLOOP
|
#ifndef DBG_MASTERLOOP
|
||||||
#define DBG_MASTERLOOP(x) { logstring(DEBUG, x); }
|
#define DBG_MASTERLOOP(x) { logstring(DEBUG, x); }
|
||||||
|
#define DBG_STARTUP(x) { logstring(DEBUG, x); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,18 +119,43 @@ bool logsyslog = false;
|
||||||
/**
|
/**
|
||||||
* lsyncd log level
|
* lsyncd log level
|
||||||
*/
|
*/
|
||||||
static enum loglevel {
|
enum loglevel {
|
||||||
DEBUG = 1, /* Log debug messages */
|
DEBUG = 1, /* Log debug messages */
|
||||||
VERBOSE = 2, /* Log more */
|
VERBOSE = 2, /* Log more */
|
||||||
NORMAL = 3, /* Log short summeries */
|
NORMAL = 3, /* Log short summeries */
|
||||||
ERROR = 4, /* Log severe errors only */
|
ERROR = 4, /* Log severe errors only */
|
||||||
CORE = 0x80 /* Indicates a core message */
|
CORE = 0x80 /* Indicates a core message */
|
||||||
} loglevel = DEBUG; // TODO
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameters
|
||||||
|
*/
|
||||||
|
static struct settings {
|
||||||
|
enum loglevel loglevel;
|
||||||
|
char * statuspipe;
|
||||||
|
} settings = {
|
||||||
|
.loglevel = DEBUG,
|
||||||
|
.statuspipe = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True when lsyncd daemonized itself.
|
* True when lsyncd daemonized itself.
|
||||||
*/
|
*/
|
||||||
static bool is_daemon;
|
static bool is_daemon = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True after first configuration phase. This is to write configuration error
|
||||||
|
* messages to stdout/stderr after being first started. Then it uses whatever
|
||||||
|
* it has been configured to. This survives a reset by HUP signal or
|
||||||
|
* inotify OVERFLOW!
|
||||||
|
*/
|
||||||
|
static bool running = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loglevel before user configuration took place
|
||||||
|
* set to DEBUG for upstart debugging, Normally its NORMAL.
|
||||||
|
*/
|
||||||
|
static const enum loglevel startup_loglevel = DEBUG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to TERM or HUP in signal handler, when lsyncd should end or reset ASAP.
|
* Set to TERM or HUP in signal handler, when lsyncd should end or reset ASAP.
|
||||||
|
@ -238,8 +265,19 @@ logstring0(enum loglevel level,
|
||||||
/* strip flags from level */
|
/* strip flags from level */
|
||||||
level &= 0x0F;
|
level &= 0x0F;
|
||||||
|
|
||||||
|
if (!running) {
|
||||||
|
/* lsyncd is in intial configuration.
|
||||||
|
* thus just print to normal stdout/stderr. */
|
||||||
|
if (level == ERROR) {
|
||||||
|
fprintf(stderr, "%s\n", message);
|
||||||
|
} else if (level >= startup_loglevel) {
|
||||||
|
printf("%s\n", message);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* skips filtered messagaes */
|
/* skips filtered messagaes */
|
||||||
if (level < loglevel) {
|
if (level < settings.loglevel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +285,7 @@ logstring0(enum loglevel level,
|
||||||
(coremsg ? "CORE ERROR: " : "ERROR: ") :
|
(coremsg ? "CORE ERROR: " : "ERROR: ") :
|
||||||
(coremsg ? "core: " : "");
|
(coremsg ? "core: " : "");
|
||||||
|
|
||||||
/* writes on console */
|
/* writes on console if not daemon */
|
||||||
if (!is_daemon) {
|
if (!is_daemon) {
|
||||||
char ct[255];
|
char ct[255];
|
||||||
/* gets current timestamp hour:minute:second */
|
/* gets current timestamp hour:minute:second */
|
||||||
|
@ -258,7 +296,7 @@ logstring0(enum loglevel level,
|
||||||
fprintf(flog, "%s %s%s\n", ct, prefix, message);
|
fprintf(flog, "%s %s%s\n", ct, prefix, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes on file */
|
/* writes to file if configured so */
|
||||||
if (logfile) {
|
if (logfile) {
|
||||||
FILE * flog = fopen(logfile, "a");
|
FILE * flog = fopen(logfile, "a");
|
||||||
/* gets current timestamp day-time-year */
|
/* gets current timestamp day-time-year */
|
||||||
|
@ -277,7 +315,7 @@ logstring0(enum loglevel level,
|
||||||
fclose(flog);
|
fclose(flog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sends to syslog */
|
/* sends to syslog if configured so */
|
||||||
if (logsyslog) {
|
if (logsyslog) {
|
||||||
int sysp;
|
int sysp;
|
||||||
switch (level) {
|
switch (level) {
|
||||||
|
@ -339,7 +377,7 @@ l_log(lua_State *L)
|
||||||
/* log level */
|
/* log level */
|
||||||
int level = luaL_checkinteger(L, 1);
|
int level = luaL_checkinteger(L, 1);
|
||||||
/* skips filtered messages early */
|
/* skips filtered messages early */
|
||||||
if ((level & 0x0F) < loglevel) {
|
if ((level & 0x0F) < settings.loglevel) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
message = luaL_checkstring(L, 2);
|
message = luaL_checkstring(L, 2);
|
||||||
|
@ -379,7 +417,8 @@ l_earlier(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns (on Lua stack) the current kernels clock state (jiffies, times() call)
|
* Returns (on Lua stack) the current kernels
|
||||||
|
* clock state (jiffies)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
l_now(lua_State *L)
|
l_now(lua_State *L)
|
||||||
|
@ -429,6 +468,7 @@ l_exec(lua_State *L)
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
// TODO
|
||||||
//if (!log->flag_nodaemon && log->logfile) {
|
//if (!log->flag_nodaemon && log->logfile) {
|
||||||
// if (!freopen(log->logfile, "a", stdout)) {
|
// if (!freopen(log->logfile, "a", stdout)) {
|
||||||
// printlogf(log, ERROR, "cannot redirect stdout to [%s].", log->logfile);
|
// printlogf(log, ERROR, "cannot redirect stdout to [%s].", log->logfile);
|
||||||
|
@ -473,7 +513,8 @@ l_real_dir(lua_State *L)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(cbuf, &st);
|
stat(cbuf, &st);
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
printlogf(L, ERROR, "failure in real_dir [%s] is not a directory", rdir);
|
printlogf(L, ERROR,
|
||||||
|
"failure in real_dir '%s' is not a directory", rdir);
|
||||||
free(cbuf);
|
free(cbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -496,21 +537,25 @@ l_stackdump(lua_State* L)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
printlogf(L, DEBUG, "total in stack %d\n",top);
|
printlogf(L, DEBUG, "total in stack %d",top);
|
||||||
for (i = 1; i <= top; i++) {
|
for (i = 1; i <= top; i++) {
|
||||||
int t = lua_type(L, i);
|
int t = lua_type(L, i);
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case LUA_TSTRING:
|
case LUA_TSTRING:
|
||||||
printlogf(L, DEBUG, "%d string: '%s'\n", i, lua_tostring(L, i));
|
printlogf(L, DEBUG, "%d string: '%s'",
|
||||||
|
i, lua_tostring(L, i));
|
||||||
break;
|
break;
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
printlogf(L, DEBUG, "%d boolean %s\n", i, lua_toboolean(L, i) ? "true" : "false");
|
printlogf(L, DEBUG, "%d boolean %s",
|
||||||
|
i, lua_toboolean(L, i) ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
printlogf(L, DEBUG, "%d number: %g\n", i, lua_tonumber(L, i));
|
printlogf(L, DEBUG, "%d number: %g",
|
||||||
|
i, lua_tonumber(L, i));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printlogf(L, DEBUG, "%d %s\n", i, lua_typename(L, t));
|
printlogf(L, DEBUG, "%d %s",
|
||||||
|
i, lua_typename(L, t));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -558,8 +603,9 @@ l_sub_dirs (lua_State *L)
|
||||||
/* readdir can trusted */
|
/* readdir can trusted */
|
||||||
isdir = de->d_type == DT_DIR;
|
isdir = de->d_type == DT_DIR;
|
||||||
}
|
}
|
||||||
if (!isdir || !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
|
if (!isdir || !strcmp(de->d_name, ".") ||
|
||||||
/* ignore non directories and . and .. */
|
!strcmp(de->d_name, ".."))
|
||||||
|
{ /* ignore non directories and . and .. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,7 +721,8 @@ l_wait_pids(lua_State *L)
|
||||||
if (newp == 0) {
|
if (newp == 0) {
|
||||||
remaining--;
|
remaining--;
|
||||||
}
|
}
|
||||||
/* does not break, in case there are duplicate pids (whyever) */
|
/* does not break!
|
||||||
|
* in case there are duplicate pids (why-ever) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -683,11 +730,45 @@ l_wait_pids(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures core parameters.
|
||||||
|
*
|
||||||
|
* @param (Lua stack) a string for a core configuratoin
|
||||||
|
* @param (Lua stack) --differes depending on string.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_configure(lua_State *L)
|
||||||
|
{
|
||||||
|
const char * command = luaL_checkstring(L, 1);
|
||||||
|
if (!strcmp(command, "statuspipe")) {
|
||||||
|
/* configures the status pipe lsyncd will dump
|
||||||
|
* its status to if opened*/
|
||||||
|
if (settings.statuspipe) {
|
||||||
|
free(settings.statuspipe);
|
||||||
|
}
|
||||||
|
settings.statuspipe = s_strdup(luaL_checkstring(L, 2));
|
||||||
|
} else if (!strcmp(command, "loglevel")) {
|
||||||
|
settings.loglevel = luaL_checkinteger(L, 2);
|
||||||
|
} else if (!strcmp(command, "running")) {
|
||||||
|
/* set by runner after first initialize
|
||||||
|
* from this on log to configurated log end instead of
|
||||||
|
* stdout/stderr */
|
||||||
|
running = true;
|
||||||
|
} else {
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"Internal error, unknown parameter in l_configure(%s)",
|
||||||
|
command);
|
||||||
|
exit(-1); //ERRNO
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const luaL_reg lsyncdlib[] = {
|
static const luaL_reg lsyncdlib[] = {
|
||||||
{"add_watch", l_add_watch },
|
{"add_watch", l_add_watch },
|
||||||
{"addto_clock", l_addto_clock },
|
{"addto_clock", l_addto_clock },
|
||||||
{"before_eq", l_before_eq },
|
{"before_eq", l_before_eq },
|
||||||
|
{"configure", l_configure },
|
||||||
{"earlier", l_earlier },
|
{"earlier", l_earlier },
|
||||||
{"exec", l_exec },
|
{"exec", l_exec },
|
||||||
{"log", l_log },
|
{"log", l_log },
|
||||||
|
@ -715,7 +796,7 @@ printlogf(lua_State *L,
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
/* skips filtered messages early */
|
/* skips filtered messages early */
|
||||||
if (level < loglevel) {
|
if (level < settings.loglevel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lua_pushcfunction(L, l_log);
|
lua_pushcfunction(L, l_log);
|
||||||
|
@ -727,38 +808,6 @@ printlogf(lua_State *L,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
if (settings.logfile) {
|
|
||||||
free(settings.logfile);
|
|
||||||
settings.logfile = NULL;
|
|
||||||
}
|
|
||||||
lua_getglobal(L, "settings");
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffer for MOVE_FROM events.
|
* Buffer for MOVE_FROM events.
|
||||||
* Lsyncd buffers MOVE_FROM events to check if
|
* Lsyncd buffers MOVE_FROM events to check if
|
||||||
|
@ -814,8 +863,9 @@ void handle_event(lua_State *L, struct inotify_event *event) {
|
||||||
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 a matching
|
/* just the MOVE_FROM, buffers this event, and wait if next event is
|
||||||
* MOVED_TO of this was an unary move out of the watched tree. */
|
* a matching MOVED_TO of this was an unary move out of the watched
|
||||||
|
* 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;
|
||||||
|
@ -891,8 +941,8 @@ masterloop(lua_State *L)
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
|
||||||
if (have_alarm && time_before(alarm_time, now)) {
|
if (have_alarm && time_before(alarm_time, now)) {
|
||||||
/* there is a delay that wants to be handled already
|
/* there is a delay that wants to be handled already thus do not
|
||||||
* thus do not read from inotify_fd and jump directly to its handling */
|
* read from inotify_fd and jump directly to its handling */
|
||||||
DBG_MASTERLOOP("immediately handling delays.");
|
DBG_MASTERLOOP("immediately handling delays.");
|
||||||
do_read = 0;
|
do_read = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -908,7 +958,8 @@ masterloop(lua_State *L)
|
||||||
if (have_alarm) {
|
if (have_alarm) {
|
||||||
DBG_MASTERLOOP("going into timed select.");
|
DBG_MASTERLOOP("going into timed select.");
|
||||||
tv.tv_sec = (alarm_time - now) / clocks_per_sec;
|
tv.tv_sec = (alarm_time - now) / clocks_per_sec;
|
||||||
tv.tv_nsec = (alarm_time - now) * 1000000000 / clocks_per_sec % 1000000000;
|
tv.tv_nsec = (alarm_time - now) *
|
||||||
|
1000000000 / clocks_per_sec % 1000000000;
|
||||||
} else {
|
} else {
|
||||||
DBG_MASTERLOOP("going into blocking select.");
|
DBG_MASTERLOOP("going into blocking select.");
|
||||||
}
|
}
|
||||||
|
@ -916,14 +967,12 @@ masterloop(lua_State *L)
|
||||||
* on zero the timemout occured. */
|
* on zero the timemout occured. */
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(inotify_fd, &readfds);
|
FD_SET(inotify_fd, &readfds);
|
||||||
do_read = pselect(inotify_fd + 1, &readfds, NULL, NULL, have_alarm ? &tv : NULL,
|
do_read = pselect(inotify_fd + 1, &readfds, NULL, NULL,
|
||||||
&sigset);
|
have_alarm ? &tv : NULL, &sigset);
|
||||||
|
|
||||||
if (do_read > 0) {
|
DBG_MASTERLOOP(do_read > 0 ?
|
||||||
DBG_MASTERLOOP("theres data on inotify.");
|
"theres data on inotify." :
|
||||||
} else {
|
"core: select() timeout or signal.");
|
||||||
DBG_MASTERLOOP("core: select() timeout or signal.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reads possible events from inotify stream */
|
/* reads possible events from inotify stream */
|
||||||
|
@ -943,7 +992,8 @@ masterloop(lua_State *L)
|
||||||
}
|
}
|
||||||
} while(0);
|
} while(0);
|
||||||
while (i < len && !reset) {
|
while (i < len && !reset) {
|
||||||
struct inotify_event *event = (struct inotify_event *) &readbuf[i];
|
struct inotify_event *event =
|
||||||
|
(struct inotify_event *) &readbuf[i];
|
||||||
handle_event(L, event);
|
handle_event(L, event);
|
||||||
i += sizeof(struct inotify_event) + event->len;
|
i += sizeof(struct inotify_event) + event->len;
|
||||||
}
|
}
|
||||||
|
@ -953,7 +1003,8 @@ masterloop(lua_State *L)
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(inotify_fd, &readfds);
|
FD_SET(inotify_fd, &readfds);
|
||||||
do_read = pselect(inotify_fd + 1, &readfds, NULL, NULL, &tv, NULL);
|
do_read = pselect(inotify_fd + 1, &readfds,
|
||||||
|
NULL, NULL, &tv, NULL);
|
||||||
if (do_read > 0) {
|
if (do_read > 0) {
|
||||||
DBG_MASTERLOOP("there is more data on inotify.");
|
DBG_MASTERLOOP("there is more data on inotify.");
|
||||||
}
|
}
|
||||||
|
@ -987,7 +1038,7 @@ masterloop(lua_State *L)
|
||||||
/**
|
/**
|
||||||
* Prints a minimal help if e.g. config_file is missing
|
* Prints a minimal help if e.g. config_file is missing
|
||||||
*/
|
*/
|
||||||
void mini_help(char *arg0)
|
void minihelp(char *arg0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Missing config file\n");
|
fprintf(stderr, "Missing config file\n");
|
||||||
fprintf(stderr, "Minimal Usage: %s CONFIG_FILE\n", arg0);
|
fprintf(stderr, "Minimal Usage: %s CONFIG_FILE\n", arg0);
|
||||||
|
@ -1001,24 +1052,23 @@ void mini_help(char *arg0)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
/* the Lua interpreter */
|
||||||
|
lua_State* L;
|
||||||
|
|
||||||
/* position at cores (minimal) argument parsing *
|
/* position at cores (minimal) argument parsing *
|
||||||
* most arguments are parsed in the lua runner */
|
* most arguments are parsed in the lua runner */
|
||||||
int argp = 1;
|
int argp = 1;
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
mini_help(argv[0]);
|
minihelp(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kernel parameters */
|
/* kernel parameters */
|
||||||
clocks_per_sec = sysconf(_SC_CLK_TCK);
|
clocks_per_sec = sysconf(_SC_CLK_TCK);
|
||||||
|
|
||||||
/* the Lua interpreter */
|
|
||||||
lua_State* L;
|
|
||||||
|
|
||||||
/* TODO check lua version */
|
|
||||||
|
|
||||||
/* load Lua */
|
/* load Lua */
|
||||||
L = lua_open();
|
L = lua_open();
|
||||||
|
/* TODO check lua version */
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
luaL_register(L, "lsyncd", lsyncdlib);
|
luaL_register(L, "lsyncd", lsyncdlib);
|
||||||
lua_setglobal(L, "lysncd");
|
lua_setglobal(L, "lysncd");
|
||||||
|
@ -1038,52 +1088,73 @@ main(int argc, char *argv[])
|
||||||
lua_pushinteger(L, NORMAL); lua_setglobal(L, "NORMAL");
|
lua_pushinteger(L, NORMAL); lua_setglobal(L, "NORMAL");
|
||||||
lua_pushinteger(L, ERROR); lua_setglobal(L, "ERROR");
|
lua_pushinteger(L, ERROR); lua_setglobal(L, "ERROR");
|
||||||
|
|
||||||
#ifdef LSYNCD_DEFAULT_RUNNER_FILE
|
|
||||||
/* checks if the user overrode default runner file */
|
/* checks if the user overrode default runner file */
|
||||||
if (!strcmp(argv[argp], "--runner")) {
|
if (!strcmp(argv[argp], "--runner")) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Lsyncd Lua-runner file missing after --runner.\n");
|
logstring(ERROR, "Lsyncd Lua-runner file missing after --runner.");
|
||||||
|
#ifdef LSYNCD_DEFAULT_RUNNER_FILE
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"Using '%s' as default location for runner.",
|
||||||
|
LSYNCD_DEFAULT_RUNNER_FILE);
|
||||||
|
#else
|
||||||
|
logstring(ERROR,
|
||||||
|
"Using a staticly included runner as default.");
|
||||||
|
#endif
|
||||||
return -1; //ERRNO
|
return -1; //ERRNO
|
||||||
}
|
}
|
||||||
lsyncd_runner_file = argv[argp + 1];
|
lsyncd_runner_file = argv[argp + 1];
|
||||||
argp += 2;
|
argp += 2;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef LSYNCD_DEFAULT_RUNNER_FILE
|
||||||
lsyncd_runner_file = LSYNCD_DEFAULT_RUNNER_FILE;
|
lsyncd_runner_file = LSYNCD_DEFAULT_RUNNER_FILE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
{
|
if (lsyncd_runner_file) {
|
||||||
/* checks if the runne file exists */
|
/* checks if the runner file exists */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(lsyncd_runner_file, &st)) {
|
if (stat(lsyncd_runner_file, &st)) {
|
||||||
fprintf(stderr, "Cannot find Lsyncd Lua-runner at '%s'.\n", lsyncd_runner_file);
|
printlogf(L, ERROR,
|
||||||
fprintf(stderr, "Maybe specify another place? %s --runner RUNNER_FILE CONFIG_FILE\n", argv[0]);
|
"Cannot find Lsyncd Lua-runner at '%s'.", lsyncd_runner_file);
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"Maybe specify another place?");
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"%s --runner RUNNER_FILE CONFIG_FILE", argv[0]);
|
||||||
|
return -1; // ERRNO
|
||||||
|
}
|
||||||
|
/* loads the runner file */
|
||||||
|
if (luaL_loadfile(L, lsyncd_runner_file)) {
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"error loading '%s': %s",
|
||||||
|
lsyncd_runner_file, lua_tostring(L, -1));
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* loads the runner file */
|
#ifndef LSYNCD_DEFAULT_RUNNER_FILE
|
||||||
if (luaL_loadfile(L, lsyncd_runner_file)) {
|
else {
|
||||||
fprintf(stderr, "error loading '%s': %s\n",
|
/* loads the runner from binary */
|
||||||
lsyncd_runner_file, lua_tostring(L, -1));
|
if (luaL_loadbuffer(L, &_binary_luac_out_start,
|
||||||
return -1; // ERRNO
|
&_binary_luac_out_end - &_binary_luac_out_start, "lsyncd.lua"))
|
||||||
|
{
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"error loading precompiled lsyncd.lua runner: %s",
|
||||||
|
lua_tostring(L, -1));
|
||||||
|
return -1; // ERRNO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* User cannot override runner file in a static compile */
|
else {
|
||||||
if (!strcmp(argv[argp], "--runner")) {
|
/* this should never be possible, security code nevertheless */
|
||||||
fprintf(stderr, "This lsyncd binary has its lua runner staticly compiled.\n");
|
logstring(ERROR,
|
||||||
fprintf(stderr, "Configure and compile with --with-runner=FILE to use the lsyncd.lua file.\n");
|
"Internal fail: lsyncd_runner is NULL with non-static runner");
|
||||||
return -1; // ERRNO
|
|
||||||
}
|
|
||||||
/* loads the runner from binary */
|
|
||||||
if (luaL_loadbuffer(L, &_binary_luac_out_start,
|
|
||||||
&_binary_luac_out_end - &_binary_luac_out_start, "lsyncd.lua")) {
|
|
||||||
fprintf(stderr, "error loading precompiled lsyncd.lua runner: %s\n",
|
|
||||||
lua_tostring(L, -1));
|
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* execute the runner defining all its functions */
|
/* execute the runner defining all its functions */
|
||||||
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||||
fprintf(stderr, "error preparing '%s': %s\n",
|
printlogf(L, ERROR,
|
||||||
lsyncd_runner_file, lua_tostring(L, -1));
|
"error preparing '%s': %s",
|
||||||
|
lsyncd_runner_file ? lsyncd_runner_file : "internal runner",
|
||||||
|
lua_tostring(L, -1));
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1094,14 +1165,16 @@ main(int argc, char *argv[])
|
||||||
lversion = luaL_checkstring(L, -1);
|
lversion = luaL_checkstring(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (strcmp(lversion, PACKAGE_VERSION)) {
|
if (strcmp(lversion, PACKAGE_VERSION)) {
|
||||||
fprintf(stderr, "Version mismatch '%s' is '%s', but core is '%s'\n",
|
printlogf(L, ERROR,
|
||||||
lsyncd_runner_file, lversion, PACKAGE_VERSION);
|
"Version mismatch '%s' is '%s', but core is '%s'",
|
||||||
|
lsyncd_runner_file ? lsyncd_runner_file : "internal runner",
|
||||||
|
lversion, PACKAGE_VERSION);
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/* checks if there is a "-help" or "--help" in the args before anything else */
|
/* checks if there is a "-help" or "--help" before anything else */
|
||||||
int i;
|
int i;
|
||||||
for(i = argp; i < argc; i++) {
|
for(i = argp; i < argc; i++) {
|
||||||
if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) {
|
if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) {
|
||||||
|
@ -1111,39 +1184,50 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argp + 1 < argc) {
|
|
||||||
mini_help(argv[0]);
|
|
||||||
return -1; // ERRNO
|
|
||||||
}
|
|
||||||
|
|
||||||
lsyncd_config_file = argv[argp++];
|
|
||||||
{
|
{
|
||||||
/* checks for the existence of the config file */
|
/* checks for the configuration and existence of the config file */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
if (argp + 1 > argc) {
|
||||||
|
minihelp(argv[0]);
|
||||||
|
return -1; // ERRNO
|
||||||
|
}
|
||||||
|
lsyncd_config_file = argv[argp++];
|
||||||
if (stat(lsyncd_config_file, &st)) {
|
if (stat(lsyncd_config_file, &st)) {
|
||||||
fprintf(stderr, "Cannot find config file at '%s'.\n", lsyncd_config_file);
|
printlogf(L, ERROR,
|
||||||
|
"Cannot find config file at '%s'.",
|
||||||
|
lsyncd_config_file);
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* loads and executes the config file */
|
||||||
if (luaL_loadfile(L, lsyncd_config_file)) {
|
if (luaL_loadfile(L, lsyncd_config_file)) {
|
||||||
fprintf(stderr, "error loading %s: %s\n", lsyncd_config_file, lua_tostring(L, -1));
|
printlogf(L, ERROR,
|
||||||
|
"error loading %s: %s",
|
||||||
|
lsyncd_config_file, lua_tostring(L, -1));
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||||
fprintf(stderr, "error preparing %s: %s\n", lsyncd_config_file, lua_tostring(L, -1));
|
printlogf(L, ERROR,
|
||||||
|
"error preparing %s: %s",
|
||||||
|
lsyncd_config_file, lua_tostring(L, -1));
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open inotify */
|
/* opens inotify */
|
||||||
inotify_fd = inotify_init();
|
inotify_fd = inotify_init();
|
||||||
if (inotify_fd == -1) {
|
if (inotify_fd == -1) {
|
||||||
fprintf(stderr, "Cannot create inotify instance! (%d:%s)\n", errno, strerror(errno));
|
printlogf(L, ERROR,
|
||||||
|
"Cannot create inotify instance! (%d:%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
return -1; // ERRNO
|
return -1; // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add signal handlers */
|
|
||||||
{
|
{
|
||||||
|
/* adds signal handlers *
|
||||||
|
* listens to SIGCHLD, but blocks it until pselect()
|
||||||
|
* opens up*/
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigaddset(&set, SIGCHLD);
|
sigaddset(&set, SIGCHLD);
|
||||||
|
@ -1151,11 +1235,11 @@ main(int argc, char *argv[])
|
||||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize */
|
|
||||||
/* lua code will set configuration and add watches */
|
|
||||||
{
|
{
|
||||||
|
/* runs initialitions from runner *
|
||||||
|
* lua code will set configuration and add watches */
|
||||||
int idx = 1;
|
int idx = 1;
|
||||||
/* creates a table with all option arguments */
|
/* creates a table with all remaining argv option arguments */
|
||||||
lua_getglobal(L, "lsyncd_initialize");
|
lua_getglobal(L, "lsyncd_initialize");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
while(argp < argc) {
|
while(argp < argc) {
|
||||||
|
|
121
lsyncd.lua
121
lsyncd.lua
|
@ -16,7 +16,8 @@
|
||||||
--
|
--
|
||||||
if lsyncd_version then
|
if lsyncd_version then
|
||||||
-- checks if the runner is being loaded twice
|
-- checks if the runner is being loaded twice
|
||||||
io.stderr:write("You cannot use the lsyncd runner as configuration file!\n")
|
io.stderr:write(
|
||||||
|
"You cannot use the lsyncd runner as configuration file!\n")
|
||||||
os.exit(-1)
|
os.exit(-1)
|
||||||
end
|
end
|
||||||
lsyncd_version = "2.0beta1"
|
lsyncd_version = "2.0beta1"
|
||||||
|
@ -26,6 +27,7 @@ lsyncd_version = "2.0beta1"
|
||||||
--
|
--
|
||||||
log = lsyncd.log
|
log = lsyncd.log
|
||||||
exec = lsyncd.exec
|
exec = lsyncd.exec
|
||||||
|
terminate = lsyncd.terminate
|
||||||
|
|
||||||
--============================================================================
|
--============================================================================
|
||||||
-- Coding checks, ensure termination on some easy to do coding errors.
|
-- Coding checks, ensure termination on some easy to do coding errors.
|
||||||
|
@ -87,13 +89,13 @@ local meta_check_count_array = {
|
||||||
local meta_check_prototype = {
|
local meta_check_prototype = {
|
||||||
__index = function(t, k)
|
__index = function(t, k)
|
||||||
if not t.prototype[k] then
|
if not t.prototype[k] then
|
||||||
error("This table does not have key '"..k.."' in its prototype.", 2)
|
error("tables prototype doesn't have key '"..k.."'.", 2)
|
||||||
end
|
end
|
||||||
return rawget(t, k)
|
return rawget(t, k)
|
||||||
end,
|
end,
|
||||||
__newindex = function(t, k, v)
|
__newindex = function(t, k, v)
|
||||||
if not t.prototype[k] then
|
if not t.prototype[k] then
|
||||||
error("This table does not have key '"..k.."' in its prototype.", 2)
|
error("tables prototype doesn't have key '"..k.."'.", 2)
|
||||||
end
|
end
|
||||||
rawset(t, k, v)
|
rawset(t, k, v)
|
||||||
end
|
end
|
||||||
|
@ -105,7 +107,7 @@ local meta_check_prototype = {
|
||||||
local function set_array(t)
|
local function set_array(t)
|
||||||
for k, _ in pairs(t) do
|
for k, _ in pairs(t) do
|
||||||
if type(k) ~= "number" then
|
if type(k) ~= "number" then
|
||||||
error("This table cannot be set as array, it has non-numberic key '"..k.."'", 2)
|
error("table can't become an array, since it has key '"..k.."'", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
setmetatable(t, meta_check_array)
|
setmetatable(t, meta_check_array)
|
||||||
|
@ -138,7 +140,7 @@ local function set_prototype(t, prototype)
|
||||||
t.prototype = prototype
|
t.prototype = prototype
|
||||||
for k, _ in pairs(t) do
|
for k, _ in pairs(t) do
|
||||||
if not t.prototype[k] and k ~= "prototype" then
|
if not t.prototype[k] and k ~= "prototype" then
|
||||||
error("Cannot set prototype of table, conflicting key: '"..k.."'.", 2)
|
error("Cannot set prototype, conflicting key: '"..k.."'.", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
setmetatable(t, proto_check_table)
|
setmetatable(t, proto_check_table)
|
||||||
|
@ -205,7 +207,8 @@ end
|
||||||
-- .filename .. filename or nil (=dir itself)
|
-- .filename .. filename or nil (=dir itself)
|
||||||
-- (.movepeer) .. for MOVEFROM/MOVETO link to other delay
|
-- (.movepeer) .. for MOVEFROM/MOVETO link to other delay
|
||||||
-- }
|
-- }
|
||||||
-- .delaywd [wd] = [#] .. a list of lists of all delays from a watch descriptor.
|
-- .delaywd [wd] = [#] .. a list of lists of all delays from a
|
||||||
|
-- watch descriptor.
|
||||||
-- }
|
-- }
|
||||||
--
|
--
|
||||||
local origins = new_array()
|
local origins = new_array()
|
||||||
|
@ -387,7 +390,9 @@ function lsyncd_collect_process(pid, exitcode)
|
||||||
end
|
end
|
||||||
local sync = process.sync
|
local sync = process.sync
|
||||||
local o = sync.origin
|
local o = sync.origin
|
||||||
print("collected ", pid, ": ", event_names[process.atype], o.source, "/", sync.path , process.filename, " = ", exitcode)
|
-- TODO
|
||||||
|
print("collected ", pid, ": ", event_names[process.atype], o.source,
|
||||||
|
"/", sync.path , process.filename, " = ", exitcode)
|
||||||
processes[pid] = nil
|
processes[pid] = nil
|
||||||
o.processes[pid] = nil
|
o.processes[pid] = nil
|
||||||
end
|
end
|
||||||
|
@ -398,10 +403,10 @@ end
|
||||||
--
|
--
|
||||||
local function invoke_action(delay)
|
local function invoke_action(delay)
|
||||||
local sync = delay.sync
|
local sync = delay.sync
|
||||||
local origin = sync.origin
|
local o = sync.origin
|
||||||
local actions = origin.actions
|
local actions = o.actions
|
||||||
local func = nil
|
local func = nil
|
||||||
local atype = delay.atype
|
local atype = delay.atype
|
||||||
if atype == NONE then
|
if atype == NONE then
|
||||||
-- a removed action
|
-- a removed action
|
||||||
return
|
return
|
||||||
|
@ -418,7 +423,7 @@ local function invoke_action(delay)
|
||||||
end
|
end
|
||||||
|
|
||||||
if func then
|
if func then
|
||||||
local pid = func(origin.source, sync.path, delay.filename, origin.targetident)
|
local pid = func(o.source, sync.path, delay.filename, o.targetident)
|
||||||
if pid and pid > 0 then
|
if pid and pid > 0 then
|
||||||
local process = {pid = pid,
|
local process = {pid = pid,
|
||||||
atype = delay.atype,
|
atype = delay.atype,
|
||||||
|
@ -428,7 +433,7 @@ local function invoke_action(delay)
|
||||||
}
|
}
|
||||||
set_prototype(process, proto_process)
|
set_prototype(process, proto_process)
|
||||||
processes[pid] = process
|
processes[pid] = process
|
||||||
origin.processes[pid] = process
|
o.processes[pid] = process
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -462,7 +467,7 @@ end
|
||||||
-- the arguments.
|
-- the arguments.
|
||||||
--
|
--
|
||||||
function lsyncd_help()
|
function lsyncd_help()
|
||||||
io.stderr:write(
|
io.stdout:write(
|
||||||
[[TODO this is a multiline
|
[[TODO this is a multiline
|
||||||
help
|
help
|
||||||
]])
|
]])
|
||||||
|
@ -474,13 +479,18 @@ end
|
||||||
-- Called from core on init or restart after user configuration.
|
-- Called from core on init or restart after user configuration.
|
||||||
--
|
--
|
||||||
function lsyncd_initialize(args)
|
function lsyncd_initialize(args)
|
||||||
|
-- creates settings if user didnt
|
||||||
|
settings = settings or {}
|
||||||
|
|
||||||
-- From this point on, no globals may be created anymore
|
-- From this point on, no globals may be created anymore
|
||||||
GLOBAL_lock(_G)
|
GLOBAL_lock(_G)
|
||||||
|
|
||||||
|
-- parses all arguments
|
||||||
for i = 1, #args do
|
for i = 1, #args do
|
||||||
local a = args[i]
|
local a = args[i]
|
||||||
if a:sub(1, 1) ~= "-" then
|
if a:sub(1, 1) ~= "-" then
|
||||||
io.stderr:write("Unknown option "..a..". Options must start with '-' or '--'.\n")
|
log(ERROR, "Unknown option "..a..
|
||||||
|
". Options must start with '-' or '--'.")
|
||||||
os.exit(-1) -- ERRNO
|
os.exit(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
if a:sub(1, 2) == "--" then
|
if a:sub(1, 2) == "--" then
|
||||||
|
@ -488,15 +498,49 @@ function lsyncd_initialize(args)
|
||||||
else
|
else
|
||||||
a = a:sub(2)
|
a = a:sub(2)
|
||||||
end
|
end
|
||||||
print(i, a)
|
--TOTO
|
||||||
|
end
|
||||||
|
|
||||||
|
-- all valid settings, first value is 1 if it needs a parameter
|
||||||
|
local configure_settings = {
|
||||||
|
loglevel = {1,
|
||||||
|
function(param)
|
||||||
|
if not (param == DEBUG or param == NORMAL or
|
||||||
|
param == VERBOSE or param == ERROR) then
|
||||||
|
log(ERROR, "unknown settings.loglevel '"..param.."'")
|
||||||
|
terminate(-1); -- ERRNO
|
||||||
|
end
|
||||||
|
end},
|
||||||
|
statuspipe = {1, nil},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- check all entries in the settings table
|
||||||
|
for c, p in pairs(settings) do
|
||||||
|
local cs = configure_settings[c]
|
||||||
|
if not cs then
|
||||||
|
log(ERROR, "unknown setting '"..c.."'")
|
||||||
|
terminate(-1) -- ERRNO
|
||||||
|
end
|
||||||
|
if cs[1] == 1 and not p then
|
||||||
|
log(ERROR, "setting '"..c.."' needs a parameter")
|
||||||
|
end
|
||||||
|
-- calls the check function if its not nil
|
||||||
|
if cs[2] then
|
||||||
|
cs[2](p)
|
||||||
|
end
|
||||||
|
lsyncd.configure(c, p)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- makes sure the user gave lsyncd anything to do
|
-- makes sure the user gave lsyncd anything to do
|
||||||
if #origins == 0 then
|
if #origins == 0 then
|
||||||
log(ERROR, "nothing to watch. Use directory(SOURCEDIR, TARGET) in your config file.");
|
log(ERROR, "Nothing to watch!")
|
||||||
lsyncd.terminate(-1) -- ERRNO
|
log(ERROR, "Use sync(SOURCE, TARGET, BEHAVIOR) in your config file.");
|
||||||
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- from this point on use logging facilities as configured.
|
||||||
|
lsyncd.configure("running");
|
||||||
|
|
||||||
-- set to true if at least one origin has a startup function
|
-- set to true if at least one origin has a startup function
|
||||||
local have_startup = false
|
local have_startup = false
|
||||||
-- runs through the origins table filled by user calling directory()
|
-- runs through the origins table filled by user calling directory()
|
||||||
|
@ -506,7 +550,7 @@ function lsyncd_initialize(args)
|
||||||
local actions = o.actions
|
local actions = o.actions
|
||||||
if not asrc then
|
if not asrc then
|
||||||
print("Cannot resolve source path: ", o.source)
|
print("Cannot resolve source path: ", o.source)
|
||||||
lsyncd.terminate(-1) -- ERRNO
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
o.source = asrc
|
o.source = asrc
|
||||||
o.delays = new_count_array()
|
o.delays = new_count_array()
|
||||||
|
@ -526,7 +570,7 @@ function lsyncd_initialize(args)
|
||||||
if actions.startup then
|
if actions.startup then
|
||||||
have_startup = true
|
have_startup = true
|
||||||
end
|
end
|
||||||
|
-- TODO move above to be before "running"
|
||||||
-- and add the dir watch inclusively all subdirs
|
-- and add the dir watch inclusively all subdirs
|
||||||
attend_dir(o, "", nil)
|
attend_dir(o, "", nil)
|
||||||
end
|
end
|
||||||
|
@ -542,9 +586,11 @@ function lsyncd_initialize(args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
lsyncd.wait_pids(pids, "startup_collector")
|
lsyncd.wait_pids(pids, "startup_collector")
|
||||||
log(NORMAL, "--- Entering normal operation with "..watches.size.." monitored directories ---")
|
log(NORMAL, "--- Entering normal operation with "..watches.size..
|
||||||
|
" monitored directories ---")
|
||||||
else
|
else
|
||||||
log(NORMAL, "--- Warmstart into normal operation with "..watches.size.." monitored directories ---")
|
log(NORMAL, "--- Warmstart into normal operation with "..watches.size..
|
||||||
|
" monitored directories ---")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -626,7 +672,7 @@ end
|
||||||
function startup_collector(pid, exitcode)
|
function startup_collector(pid, exitcode)
|
||||||
if exitcode ~= 0 then
|
if exitcode ~= 0 then
|
||||||
log(ERROR, "Startup process", pid, " failed")
|
log(ERROR, "Startup process", pid, " failed")
|
||||||
lsyncd.terminate(-1) -- ERRNO
|
terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
@ -661,8 +707,7 @@ end
|
||||||
--
|
--
|
||||||
function default_overflow()
|
function default_overflow()
|
||||||
log(ERROR, "--- OVERFLOW on inotify event queue ---")
|
log(ERROR, "--- OVERFLOW on inotify event queue ---")
|
||||||
lsyncd.terminate(-1) -- TODO reset instead.
|
terminate(-1) -- TODO reset instead.
|
||||||
|
|
||||||
end
|
end
|
||||||
overflow = default_overflow
|
overflow = default_overflow
|
||||||
|
|
||||||
|
@ -677,11 +722,33 @@ end
|
||||||
-- lsyncd default settings
|
-- lsyncd default settings
|
||||||
--============================================================================
|
--============================================================================
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- lsyncd classic - sync with rsync
|
||||||
|
--
|
||||||
|
local default_rsync = {
|
||||||
|
----
|
||||||
|
-- Called for every sync/target pair on startup
|
||||||
|
startup = function(source, target)
|
||||||
|
log(NORMAL, "startup recursive rsync: "..source.." -> "..target)
|
||||||
|
return exec("/usr/bin/rsync", "-ltrs",
|
||||||
|
source, target)
|
||||||
|
end,
|
||||||
|
|
||||||
|
default = function(source, target, path)
|
||||||
|
return exec("/usr/bin/rsync", "--delete", "-ltds",
|
||||||
|
source.."/".. path, target .. "/" .. path)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- The defaults table for the user to access
|
||||||
|
--
|
||||||
defaults = {
|
defaults = {
|
||||||
-----
|
-----
|
||||||
-- TODO
|
-- TODO
|
||||||
--
|
--
|
||||||
max_processes = 1,
|
max_processes = 1,
|
||||||
|
|
||||||
------
|
------
|
||||||
-- TODO
|
-- TODO
|
||||||
--
|
--
|
||||||
|
@ -690,7 +757,9 @@ defaults = {
|
||||||
[MODIFY] = { [ATTRIB] = MODIFY, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
[MODIFY] = { [ATTRIB] = MODIFY, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
||||||
[CREATE] = { [ATTRIB] = CREATE, [MODIFY] = CREATE, [CREATE] = CREATE, [DELETE] = -1 },
|
[CREATE] = { [ATTRIB] = CREATE, [MODIFY] = CREATE, [CREATE] = CREATE, [DELETE] = -1 },
|
||||||
[DELETE] = { [ATTRIB] = DELETE, [MODIFY] = DELETE, [CREATE] = MODIFY, [DELETE] = DELETE },
|
[DELETE] = { [ATTRIB] = DELETE, [MODIFY] = DELETE, [CREATE] = MODIFY, [DELETE] = DELETE },
|
||||||
}
|
},
|
||||||
|
|
||||||
|
rsync = default_rsync
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user