mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-12 14:17:47 +00:00
This commit is contained in:
parent
9976269bfb
commit
d823e8b580
@ -5,8 +5,8 @@
|
|||||||
--
|
--
|
||||||
settings = {
|
settings = {
|
||||||
-- logfile = "/tmp/lsyncd",
|
-- logfile = "/tmp/lsyncd",
|
||||||
nodaemon,
|
-- nodaemon,
|
||||||
statuspipe = "/tmp/lsyncd.stat",
|
statusfile = "/tmp/lsyncd.stat",
|
||||||
loglevel = DEBUG,
|
loglevel = DEBUG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
115
lsyncd.c
115
lsyncd.c
@ -24,6 +24,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -100,7 +101,7 @@ static int inotify_fd;
|
|||||||
/**
|
/**
|
||||||
* TODO allow configure.
|
* TODO allow configure.
|
||||||
*/
|
*/
|
||||||
static const uint32_t standard_event_mask =
|
static const uint32_t standard_event_mask =
|
||||||
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
||||||
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
||||||
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
||||||
@ -131,11 +132,19 @@ enum loglevel {
|
|||||||
* configuration parameters
|
* configuration parameters
|
||||||
*/
|
*/
|
||||||
static struct settings {
|
static struct settings {
|
||||||
|
/**
|
||||||
|
* threshold for log messages
|
||||||
|
*/
|
||||||
enum loglevel loglevel;
|
enum loglevel loglevel;
|
||||||
char * statuspipe;
|
|
||||||
|
/**
|
||||||
|
* lsyncd will periodically write its status in this
|
||||||
|
* file if configured so. (for special observing only)
|
||||||
|
*/
|
||||||
|
char * statusfile;
|
||||||
} settings = {
|
} settings = {
|
||||||
.loglevel = DEBUG,
|
.loglevel = DEBUG,
|
||||||
.statuspipe = NULL,
|
.statusfile = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -443,6 +452,7 @@ l_addto_clock(lua_State *L)
|
|||||||
lua_pushinteger(L, c1 + c2 * clocks_per_sec);
|
lua_pushinteger(L, c1 + c2 * clocks_per_sec);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a subprocess. Does not wait for it to return.
|
* Executes a subprocess. Does not wait for it to return.
|
||||||
*
|
*
|
||||||
@ -468,17 +478,20 @@ l_exec(lua_State *L)
|
|||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
// TODO
|
/* if lsyncd runs as a daemon and has a logfile it will redirect
|
||||||
//if (!log->flag_nodaemon && log->logfile) {
|
stdout/stderr of child processes to the logfile. */
|
||||||
// if (!freopen(log->logfile, "a", stdout)) {
|
if (is_daemon && logfile) {
|
||||||
// printlogf(log, ERROR, "cannot redirect stdout to [%s].", log->logfile);
|
if (!freopen(logfile, "a", stdout)) {
|
||||||
// }
|
printlogf(L, ERROR,
|
||||||
// if (!freopen(log->logfile, "a", stderr)) {
|
"cannot redirect stdout to '%s'.", logfile);
|
||||||
// printlogf(log, ERROR, "cannot redirect stderr to [%s].", log->logfile);
|
}
|
||||||
// }
|
if (!freopen(logfile, "a", stderr)) {
|
||||||
//}
|
printlogf(L, ERROR,
|
||||||
|
"cannot redirect stderr to '%s'.", logfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
execv(binary, (char **)argv);
|
execv(binary, (char **)argv);
|
||||||
// in a sane world execv does not return!
|
/* in a sane world execv does not return! */
|
||||||
printlogf(L, ERROR, "Failed executing [%s]!", binary);
|
printlogf(L, ERROR, "Failed executing [%s]!", binary);
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
@ -511,10 +524,16 @@ l_real_dir(lua_State *L)
|
|||||||
{
|
{
|
||||||
/* makes sure its a directory */
|
/* makes sure its a directory */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(cbuf, &st);
|
if (stat(cbuf, &st)) {
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"cannot get absolute path of dir '%s': %s",
|
||||||
|
rdir, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
printlogf(L, ERROR,
|
printlogf(L, ERROR,
|
||||||
"failure in real_dir '%s' is not a directory", rdir);
|
"cannot get absolute path of dir '%s': is not a directory",
|
||||||
|
rdir);
|
||||||
free(cbuf);
|
free(cbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -617,6 +636,21 @@ l_sub_dirs (lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a string to a file descriptor
|
||||||
|
*
|
||||||
|
* @param (Lua Stack) file descriptor
|
||||||
|
* @param (Lua Stack) string.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
l_writefd(lua_State *L)
|
||||||
|
{
|
||||||
|
int fd = luaL_checkinteger(L, 1);
|
||||||
|
const char *s = luaL_checkstring(L, 2);
|
||||||
|
write(fd, s, strlen(s));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates lsyncd daemon.
|
* Terminates lsyncd daemon.
|
||||||
*
|
*
|
||||||
@ -740,13 +774,12 @@ static int
|
|||||||
l_configure(lua_State *L)
|
l_configure(lua_State *L)
|
||||||
{
|
{
|
||||||
const char * command = luaL_checkstring(L, 1);
|
const char * command = luaL_checkstring(L, 1);
|
||||||
if (!strcmp(command, "statuspipe")) {
|
if (!strcmp(command, "statusfile")) {
|
||||||
/* configures the status pipe lsyncd will dump
|
/* configures the status file lsyncd will dump its status to */
|
||||||
* its status to if opened*/
|
if (settings.statusfile) {
|
||||||
if (settings.statuspipe) {
|
free(settings.statusfile);
|
||||||
free(settings.statuspipe);
|
|
||||||
}
|
}
|
||||||
settings.statuspipe = s_strdup(luaL_checkstring(L, 2));
|
settings.statusfile = s_strdup(luaL_checkstring(L, 2));
|
||||||
} else if (!strcmp(command, "loglevel")) {
|
} else if (!strcmp(command, "loglevel")) {
|
||||||
settings.loglevel = luaL_checkinteger(L, 2);
|
settings.loglevel = luaL_checkinteger(L, 2);
|
||||||
} else if (!strcmp(command, "running")) {
|
} else if (!strcmp(command, "running")) {
|
||||||
@ -773,6 +806,7 @@ static const luaL_reg lsyncdlib[] = {
|
|||||||
{"exec", l_exec },
|
{"exec", l_exec },
|
||||||
{"log", l_log },
|
{"log", l_log },
|
||||||
{"now", l_now },
|
{"now", l_now },
|
||||||
|
{"writefd", l_writefd },
|
||||||
{"real_dir", l_real_dir },
|
{"real_dir", l_real_dir },
|
||||||
{"stackdump", l_stackdump },
|
{"stackdump", l_stackdump },
|
||||||
{"sub_dirs", l_sub_dirs },
|
{"sub_dirs", l_sub_dirs },
|
||||||
@ -813,8 +847,15 @@ printlogf(lua_State *L,
|
|||||||
* Lsyncd buffers MOVE_FROM events to check if
|
* Lsyncd buffers MOVE_FROM events to check if
|
||||||
*/
|
*/
|
||||||
struct inotify_event * move_event_buf = NULL;
|
struct inotify_event * move_event_buf = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory allocated for move_event_buf
|
||||||
|
*/
|
||||||
size_t move_event_buf_size = 0;
|
size_t move_event_buf_size = 0;
|
||||||
/* true if the buffer is used.*/
|
|
||||||
|
/**
|
||||||
|
* true if the buffer is used.
|
||||||
|
*/
|
||||||
bool move_event = false;
|
bool move_event = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -826,6 +867,7 @@ void handle_event(lua_State *L, struct inotify_event *event) {
|
|||||||
|
|
||||||
/* 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;
|
||||||
|
logstring(DEBUG, "got an event");
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
return;
|
return;
|
||||||
@ -1015,7 +1057,7 @@ masterloop(lua_State *L)
|
|||||||
handle_event(L, NULL);
|
handle_event(L, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* collect zombified child processes */
|
/* collects zombified child processes */
|
||||||
while(1) {
|
while(1) {
|
||||||
int status;
|
int status;
|
||||||
pid_t pid = waitpid(0, &status, WNOHANG);
|
pid_t pid = waitpid(0, &status, WNOHANG);
|
||||||
@ -1028,7 +1070,29 @@ masterloop(lua_State *L)
|
|||||||
lua_call(L, 2, 0);
|
lua_call(L, 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let the runner spawn new processes */
|
/* writes status of lsyncd in a file */
|
||||||
|
/* this is not a real loop, it will only be runned once max.
|
||||||
|
* this is just using break as comfortable jump down. */
|
||||||
|
while (settings.statusfile) {
|
||||||
|
int fd = open(settings.statusfile, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
if (fd < 0) {
|
||||||
|
printlogf(L, ERROR,
|
||||||
|
"Cannot open statusfile '%s' for writing.",
|
||||||
|
settings.statusfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* calls the lua runner to write the status. */
|
||||||
|
lua_getglobal(L, "lsyncd_status_report");
|
||||||
|
lua_pushinteger(L, fd);
|
||||||
|
lua_call(L, 1, 0);
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
fsync(fd);
|
||||||
|
close(fd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lets the runner spawn new processes */
|
||||||
lua_getglobal(L, "lsyncd_alarm");
|
lua_getglobal(L, "lsyncd_alarm");
|
||||||
lua_pushinteger(L, times(NULL));
|
lua_pushinteger(L, times(NULL));
|
||||||
lua_call(L, 1, 0);
|
lua_call(L, 1, 0);
|
||||||
@ -1036,7 +1100,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 minihelp(char *arg0)
|
void minihelp(char *arg0)
|
||||||
{
|
{
|
||||||
@ -1045,7 +1109,6 @@ void minihelp(char *arg0)
|
|||||||
fprintf(stderr, " Specify -help for more help.\n");
|
fprintf(stderr, " Specify -help for more help.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main
|
* Main
|
||||||
*/
|
*/
|
||||||
|
39
lsyncd.lua
39
lsyncd.lua
@ -188,7 +188,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
-- Table of all root directories to sync,
|
-- origins
|
||||||
|
--
|
||||||
|
-- table of all root directories to sync.
|
||||||
-- filled during initialization.
|
-- filled during initialization.
|
||||||
--
|
--
|
||||||
-- [#] {
|
-- [#] {
|
||||||
@ -212,11 +214,19 @@ end
|
|||||||
-- }
|
-- }
|
||||||
--
|
--
|
||||||
local origins = new_array()
|
local origins = new_array()
|
||||||
local proto_origin = {actions=true, source=true, targetident=true, processes=true, delays=true, delaywd=true}
|
local proto_origin = {
|
||||||
local proto_delay = {atype =true, alarm=true, wd=true, sync=true, filename=true, movepeer=true}
|
actions=true, source=true, targetident=true,
|
||||||
|
processes=true, delays=true, delaywd=true
|
||||||
|
}
|
||||||
|
local proto_delay = {
|
||||||
|
atype =true, alarm=true, wd=true,
|
||||||
|
sync=true, filename=true, movepeer=true
|
||||||
|
}
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- all watches
|
-- watches
|
||||||
|
--
|
||||||
|
-- contains all inotify watches.
|
||||||
--
|
--
|
||||||
-- structure:
|
-- structure:
|
||||||
-- [wd] = {
|
-- [wd] = {
|
||||||
@ -439,6 +449,25 @@ local function invoke_action(delay)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
-- Called from core to get a status report written into a file descriptor
|
||||||
|
--
|
||||||
|
function lsyncd_status_report(fd)
|
||||||
|
local w = lsyncd.writefd
|
||||||
|
w(fd, "Lsyncd status report at "..os.date().."\n\n")
|
||||||
|
w(fd, "Watching "..watches.size.." directories\n")
|
||||||
|
for i, v in pairs(watches) do
|
||||||
|
w(fd, " "..i..": ")
|
||||||
|
if i ~= v.wd then
|
||||||
|
w(fd, "[Error: wd/v.wd "..i.."~="..v.wd.."]")
|
||||||
|
end
|
||||||
|
for _, s in pairs(v.syncs) do
|
||||||
|
w(fd, "("..s.origin.source.."//"..s.origin.path..")")
|
||||||
|
end
|
||||||
|
w(fd, "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
----
|
----
|
||||||
-- Called from core everytime at the latest of an
|
-- Called from core everytime at the latest of an
|
||||||
-- expired alarm (or more often)
|
-- expired alarm (or more often)
|
||||||
@ -511,7 +540,7 @@ function lsyncd_initialize(args)
|
|||||||
terminate(-1); -- ERRNO
|
terminate(-1); -- ERRNO
|
||||||
end
|
end
|
||||||
end},
|
end},
|
||||||
statuspipe = {1, nil},
|
statusfile = {1, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- check all entries in the settings table
|
-- check all entries in the settings table
|
||||||
|
Loading…
Reference in New Issue
Block a user