diff --git a/lsyncd-conf.lua b/lsyncd-conf.lua index a7c1f50..ca279f0 100644 --- a/lsyncd-conf.lua +++ b/lsyncd-conf.lua @@ -5,3 +5,4 @@ settings = { add("s", "d") -- add("s/s1", "t") + diff --git a/lsyncd.c b/lsyncd.c index 7feb8c9..ed70200 100644 --- a/lsyncd.c +++ b/lsyncd.c @@ -44,8 +44,34 @@ const uint32_t standard_event_mask = */ volatile sig_atomic_t reset = 0; -/* the Lua interpreter */ -lua_State* L; +/** + * "secured" calloc. + */ +void * +s_calloc(size_t nmemb, size_t size) +{ + void *r = calloc(nmemb, size); + if (r == NULL) { + printf("Out of memory!\n"); + exit(-1); // ERRNO + } + return r; +} + +/** + * "secured" malloc. the deamon shall kill itself + * in case of out of memory. + */ +void * +s_malloc(size_t size) +{ + void *r = malloc(size); + if (r == NULL) { + printf("Out of memory!\n"); + exit(-1); // ERRNO + } + return r; +} /** @@ -64,6 +90,23 @@ add_watch(lua_State *L) } +/** + * Executes a subprocess + */ +static int +exec(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + int argc = lua_gettop(L) - 1; + int i; + const char **argv = s_calloc(argc + 1, sizeof(char *)); + for(i = 0; i < argc; i++) { + argv[i] = luaL_checkstring(L, i + 2); + } + + return 0; +} + /** * Converts a relative directory path to an absolute. @@ -134,7 +177,6 @@ stackdump(lua_State* l) return 0; } - /** * Reads the directories sub directories. * @@ -155,7 +197,6 @@ sub_dirs (lua_State *L) } lua_newtable(L); - while (!reset) { struct dirent *de = readdir(d); bool isdir; @@ -165,12 +206,7 @@ sub_dirs (lua_State *L) } if (de->d_type == DT_UNKNOWN) { /* must call stat on some systems :-/ */ - char *subdir = malloc(strlen(dirname) + strlen(de->d_name) + 2); - if (subdir == NULL) { - printf("Out of memory. Cannot determine type of %s/%s\n", dirname, de->d_name); - /* otherwise not so dramatic */ - continue; - } + char *subdir = s_malloc(strlen(dirname) + strlen(de->d_name) + 2); struct stat st; strcpy(subdir, dirname); strcat(subdir, "/"); @@ -197,6 +233,7 @@ sub_dirs (lua_State *L) static const luaL_reg lsyncdlib[] = { {"add_watch", add_watch}, + {"exec", exec}, {"real_dir", real_dir}, {"stackdump", stackdump}, {"sub_dirs", sub_dirs}, @@ -206,22 +243,31 @@ static const luaL_reg lsyncdlib[] = { int main(int argc, char *argv[]) { + /* the Lua interpreter */ + lua_State* L; + /* load Lua */ L = lua_open(); luaL_openlibs(L); luaL_register(L, "lsyncd", lsyncdlib); - luaL_loadfile(L, "lsyncd.lua"); - if (lua_pcall(L, 0, LUA_MULTRET, 0)) { + if (luaL_loadfile(L, "lsyncd.lua")) { printf("error loading lsyncd.lua: %s\n", lua_tostring(L, -1)); return -1; // ERRNO } - - luaL_loadfile(L, "lsyncd-conf.lua"); if (lua_pcall(L, 0, LUA_MULTRET, 0)) { + printf("error running lsyncd.lua: %s\n", lua_tostring(L, -1)); + return -1; // ERRNO + } + + if (luaL_loadfile(L, "lsyncd-conf.lua")) { printf("error loading 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)); + return -1; // ERRNO + } /* open inotify */ inotify_fd = inotify_init(); @@ -234,6 +280,10 @@ main(int argc, char *argv[]) /* initialize */ lua_getglobal(L, "lsyncd_initialize"); lua_call(L, 0, 0); + + /* startup */ + lua_getglobal(L, "startup"); + lua_call(L, 0, 0); /* cleanup */ close(inotify_fd); diff --git a/lsyncd.lua b/lsyncd.lua index d9f34ef..53936aa 100644 --- a/lsyncd.lua +++ b/lsyncd.lua @@ -42,7 +42,7 @@ local watches = {} -- @param target -- @param ... local function attend_dir(origin, path, target) - print("attending dir", origin, "+", path, "->", target.dirname); + print("attending dir", origin, "+", path, "->", target.path); -- actual dir = origin + path local op = origin .. path -- register watch and receive watch descriptor @@ -78,9 +78,10 @@ function lsyncd_initialize() print("--- INIT ---") local i, o for i, o in ipairs(origin) do - print("Handling ", o.source, "->" , o.target) - local target = { dirname = o.target } + print("Handling ", o.source, "->" , o.targetpath) + local target = { path = o.targetpath } table.insert(targets, target) + origin[i].target = target attend_dir(lsyncd.real_dir(o.source), "", target) end end @@ -92,10 +93,30 @@ end ---- -- Add one directory to be watched. -function add(source, target) - local o = { source = source, target = target } +function add(source_dir, target_path) + local o = { source = source_dir, targetpath = target_path } table.insert(origin, o) return o end +----- +-- Called by core after initialization. +-- +-- Returns a table of integers (pid of children) the core will +-- wait for before entering normal operation. +-- +-- User can override this function by specifing his/her own +-- "startup". (and yet may still call default startup) +function default_startup() + print("--- STARTUP ---") + local pids = { } + for i, o in ipairs(origin) do + pid = lsyncd.exec("/usr/bin/rsyc", "-ltrs", o.source, o.targetpath) + print("started ", pid) + table.insert(pids, pid) + end + return pids +end +startup = default_startup +