From 1a9732f40afec1e6687e6a98f30f29346bfc7ade Mon Sep 17 00:00:00 2001 From: Axel Kittenberger Date: Wed, 20 Oct 2010 18:33:17 +0000 Subject: [PATCH] --- lsyncd-conf.lua | 2 +- lsyncd.c | 270 +++++++++++++++++++++++++++--------------------- lsyncd.lua | 26 ++--- 3 files changed, 165 insertions(+), 133 deletions(-) diff --git a/lsyncd-conf.lua b/lsyncd-conf.lua index ef075f8..b1d9d78 100644 --- a/lsyncd-conf.lua +++ b/lsyncd-conf.lua @@ -16,7 +16,7 @@ add("s", "d") -- Returns the pid of a spawned process -- Return 0 if you dont exec something. function startup_action(source, target) - print("startup recursive rsync: " .. source .. " -> " .. target) + log(NORMAL, "startup recursive rsync: " .. source .. " -> " .. target) return exec("/usr/bin/rsync", "-ltrs", source, target) end diff --git a/lsyncd.c b/lsyncd.c index 35b632d..8240849 100644 --- a/lsyncd.c +++ b/lsyncd.c @@ -119,6 +119,22 @@ static volatile sig_atomic_t reset = 0; */ static long clocks_per_sec; +/** + * predeclerations -- see belorw. + */ +static void +logstring0(enum loglevel level, + const char *message); +/* core logs with CORE flag */ +#define logstring(loglevel, message) logstring0(loglevel | CORE, message) + +static void +printlogf(lua_State *L, + enum loglevel level, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + + /** * "secured" calloc. */ @@ -127,7 +143,7 @@ s_calloc(size_t nmemb, size_t size) { void *r = calloc(nmemb, size); if (r == NULL) { - printf("Out of memory!\n"); + logstring(ERROR, "Out of memory!"); exit(-1); // ERRNO } return r; @@ -142,7 +158,7 @@ s_malloc(size_t size) { void *r = malloc(size); if (r == NULL) { - printf("Out of memory!\n"); + logstring(ERROR, "Out of memory!"); exit(-1); // ERRNO } return r; @@ -156,7 +172,7 @@ s_realloc(void *ptr, size_t size) { void *r = realloc(ptr, size); if (r == NULL) { - printf("Out of memory!\n"); + logstring(ERROR, "Out of memory!"); exit(-1); } return r; @@ -170,12 +186,91 @@ s_strdup(const char *src) { char *s = strdup(src); if (s == NULL) { - printf("Out of memory!\n"); + logstring(ERROR, "Out of memory!"); exit(-1); // ERRNO } return s; } +/** + * Logs a string + * + * @param level the level of the log message + * @param message the log message + */ +static void +logstring0(enum loglevel level, + const char *message) +{ + const char *prefix; + /* true if logmessages comes from core */ + bool coremsg = (level & CORE) != 0; + /* strip flags from level */ + level &= 0x0F; + + /* skips filtered messagaes */ + if (level < loglevel) { + return; + } + + prefix = level == ERROR ? + (coremsg ? "CORE ERROR " : "ERROR ") : + (coremsg ? "core " : ""); + + /* writes on console */ + if (!is_daemon) { + char ct[255]; + /* gets current timestamp hour:minute:second */ + time_t mtime; + time(&mtime); + strftime(ct, sizeof(ct), "%T", localtime(&mtime)); + FILE * flog = level == ERROR ? stderr : stdout; + fprintf(flog, "%s %s%s\n", ct, prefix, message); + } + + /* writes on file */ + if (logfile) { + FILE * flog = fopen(logfile, "a"); + /* gets current timestamp day-time-year */ + char * ct; + time_t mtime; + time(&mtime); + ct = ctime(&mtime); + /* cuts trailing linefeed */ + ct[strlen(ct) - 1] = 0; + + if (flog == NULL) { + fprintf(stderr, "core: cannot open logfile [%s]!\n", logfile); + exit(-1); // ERRNO + } + fprintf(flog, "%s: %s%s", ct, prefix, message); + fclose(flog); + } + + /* sends to syslog */ + if (logsyslog) { + int sysp; + switch (level) { + case DEBUG : + sysp = LOG_DEBUG; + break; + case VERBOSE : + case NORMAL : + sysp = LOG_NOTICE; + break; + case ERROR : + sysp = LOG_ERR; + break; + default : + /* should never happen */ + sysp = 0; + break; + } + syslog(sysp, "%s%s", prefix, message); + } + return; +} + /***************************************************************************** * Library calls for lsyncd.lua @@ -201,7 +296,7 @@ l_add_watch(lua_State *L) } /** - * Logs a log level + * Logs a message. * * @param loglevel (Lua stack) loglevel of massage * @param string (Lua stack) the string to log @@ -211,63 +306,14 @@ l_log(lua_State *L) { /* log message */ const char * message; - /* current time */ - char * ct; - time_t mtime; /* log level */ int level = luaL_checkinteger(L, 1); - /* true if logmessages comes from core */ - bool core = (level & CORE) != 0; - /* strip flags from level */ - level &= 0x0F; - - /* skips filtered messagaes */ - if (level < loglevel) { + /* skips filtered messages early */ + if ((level & 0x0F) < loglevel) { return 0; } message = luaL_checkstring(L, 2); - - /* gets current time */ - time(&mtime); - ct = ctime(&mtime); - /* cuts trailing linefeed */ - ct[strlen(ct) - 1] = 0; - - /* writes on console */ - if (!is_daemon) { - if (level == ERROR) { - fprintf(stderr, "%s: %sERROR: %s", ct, core ? "CORE " : "", message); - } else { - fprintf(stdout, "%s: %s%s", ct, core ? "core: " : "", message); - } - } - - /* writes on file */ - if (logfile) { - FILE * flog = fopen(logfile, "a"); - if (flog == NULL) { - fprintf(stderr, "core: cannot open logfile [%s]!\n", logfile); - exit(-1); // ERRNO - } - if (level == ERROR) { - fprintf(flog, "%s: %sERROR: %s", ct, core ? "CORE " : "", message); - } else { - fprintf(flog, "%s: %s%s", ct, core ? "core: " : "", message); - } - fclose(flog); - } - - /* sends to syslog */ - /* TODO - if (logsyslog) { - if (!core) { - // TODO - syslog(sysp, message); - } else { - syslog(sysp, message); - } - } - */ + logstring0(level, message); return 0; } @@ -317,7 +363,7 @@ l_exec(lua_State *L) //} execv(binary, (char **)argv); // in a sane world execv does not return! - printf("Failed executing [%s]!\n", binary); + printlogf(L, ERROR, "Failed executing [%s]!", binary); exit(-1); // ERRNO } @@ -343,7 +389,7 @@ l_real_dir(lua_State *L) /* use c-library to get absolute path */ cbuf = realpath(rdir, NULL); if (cbuf == NULL) { - printf("failure getting absolute path of \"%s\"\n", rdir); + printlogf(L, ERROR, "failure getting absolute path of [%s]", rdir); return 0; } { @@ -351,7 +397,7 @@ l_real_dir(lua_State *L) struct stat st; stat(cbuf, &st); if (!S_ISDIR(st.st_mode)) { - printf("failure in real_dir \"%s\" is not a directory\n", rdir); + printlogf(L, ERROR, "failure in real_dir [%s] is not a directory", rdir); free(cbuf); return 0; } @@ -374,26 +420,24 @@ l_stackdump(lua_State* L) { int i; int top = lua_gettop(L); - printf("total in stack %d\n",top); + printlogf(L, DEBUG, "total in stack %d\n",top); for (i = 1; i <= top; i++) { int t = lua_type(L, i); switch (t) { case LUA_TSTRING: - printf("%d string: '%s'\n", i, lua_tostring(L, i)); + printlogf(L, DEBUG, "%d string: '%s'\n", i, lua_tostring(L, i)); break; case LUA_TBOOLEAN: - printf("%d boolean %s\n", i, lua_toboolean(L, i) ? "true" : "false"); + printlogf(L, DEBUG, "%d boolean %s\n", i, lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: - printf("%d number: %g\n", i, lua_tonumber(L, i)); + printlogf(L, DEBUG, "%d number: %g\n", i, lua_tonumber(L, i)); break; default: - printf("%d %s\n", i, lua_typename(L, t)); + printlogf(L, DEBUG, "%d %s\n", i, lua_typename(L, t)); break; } } - - printf("\n"); return 0; } @@ -412,7 +456,7 @@ l_sub_dirs (lua_State *L) d = opendir(dirname); if (d == NULL) { - printf("cannot open dir %s.\n", dirname); + printlogf(L, ERROR, "cannot open dir [%s].", dirname); return 0; } @@ -583,21 +627,20 @@ static const luaL_reg lsyncdlib[] = { ****************************************************************************/ /** - * TODO + * Let the core print logmessage comfortably. */ static void printlogf(lua_State *L, enum loglevel level, - const char *fmt, ...) - __attribute__((format(printf, 3, 4))); -static void -printlogf(lua_State *L, - enum loglevel level, - const char *fmt, ...) + const char *fmt, ...) { va_list ap; + /* skips filtered messages early */ + if (level < loglevel) { + return; + } lua_pushcfunction(L, l_log); - lua_pushinteger(L, level); + lua_pushinteger(L, level | CORE); va_start(ap, fmt); lua_pushvfstring(L, fmt, ap); va_end(ap); @@ -656,17 +699,18 @@ void handle_event(lua_State *L, struct inotify_event *event) { /* used to execute two events in case of unmatched MOVE_FROM buffer */ struct inotify_event *after_buf = NULL; - - if (event) { - if (IN_Q_OVERFLOW & event->mask) { - /* and overflow happened, lets runner/user decide what to do. */ - lua_getglobal(L, "overflow"); - lua_call(L, 0, 0); - return; - } - if (IN_IGNORED & event->mask || reset) { - return; - } + if (reset) { + return; + } + if (event && (IN_Q_OVERFLOW & event->mask)) { + /* and overflow happened, lets runner/user decide what to do. */ + lua_getglobal(L, "overflow"); + lua_call(L, 0, 0); + return; + } + /* cancel on ignored or resetting */ + if (event && (IN_IGNORED & event->mask)) { + return; } if (event == NULL) { @@ -694,7 +738,6 @@ void handle_event(lua_State *L, struct inotify_event *event) { } memcpy(move_event_buf, event, sizeof(struct inotify_event) + event->len); move_event = true; - printf("buffered\n"); return; } else if (IN_MOVED_TO & event->mask) { /* must be an unary moveto */ @@ -715,7 +758,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { /* rm'ed */ event_type = DELETE; } else { - printf("skipped an event\n"); + logstring(DEBUG, "skipped some inotify event."); return; } @@ -762,7 +805,7 @@ masterloop(lua_State *L) if (alarm_state < 0) { /* there is a delay that wants to be handled already * thus do not read from inotify_fd and jump directly to its handling */ - printf("core: immediately handling delayed entries\n"); + logstring(DEBUG, "immediately handling delayed entries."); do_read = 0; } else if (alarm_state > 0) { /* use select() to determine what happens next @@ -774,7 +817,7 @@ masterloop(lua_State *L) if (time_after(now, alarm_time)) { /* should never happen */ - printf("Internal failure, alarm_time is in past!\n"); + logstring(ERROR, "critical failure, alarm_time is in past!\n"); exit(-1); //ERRNO } @@ -787,13 +830,13 @@ masterloop(lua_State *L) do_read = select(inotify_fd + 1, &readfds, NULL, NULL, &tv); if (do_read) { - printf("core: theres data on inotify.\n"); + logstring(DEBUG, "theres data on inotify."); } else { - printf("core: select() timeout or signal, doing delays.\n"); + logstring(DEBUG, "core: select() timeout or signal."); } } else { // if nothing to wait for, enter a blocking read - printf("core: gone blocking\n"); + logstring(DEBUG, "gone blocking."); do_read = 1; } @@ -826,12 +869,11 @@ masterloop(lua_State *L) if (do_read) { struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; fd_set readfds; - FD_ZERO(&readfds); FD_SET(inotify_fd, &readfds); do_read = select(inotify_fd + 1, &readfds, NULL, NULL, &tv); if (do_read) { - printf("core: there is more data on inotify\n"); + logstring(DEBUG, "there is more data on inotify."); } } } while (do_read); @@ -855,9 +897,9 @@ main(int argc, char *argv[]) int argp = 1; if (argc < 2) { - printf("Missing config file\n"); - printf("Minimal Usage: %s CONFIG_FILE\n", argv[0]); - printf(" Specify --help for more help.\n"); + fprintf(stderr, "Missing config file\n"); + fprintf(stderr, "Minimal Usage: %s CONFIG_FILE\n", argv[0]); + fprintf(stderr, " Specify --help for more help.\n"); return -1; // ERRNO } @@ -891,13 +933,13 @@ main(int argc, char *argv[]) /* TODO parse runner */ if (!strcmp(argv[argp], "--runner")) { if (argc < 3) { - printf("Lsyncd Lua-runner file missing after --runner.\n"); + fprintf(stderr, "Lsyncd Lua-runner file missing after --runner.\n"); return -1; //ERRNO } if (argc < 4) { - printf("Missing config file\n"); - printf(" Usage: %s --runner %s CONFIG_FILE\n", argv[0], argv[2]); - printf(" Specify --help for more help.\n"); + fprintf(stderr, "Missing config file\n"); + fprintf(stderr, " Usage: %s --runner %s CONFIG_FILE\n", argv[0], argv[2]); + fprintf(stderr, " Specify --help for more help.\n"); return -1; // ERRNO } lsyncd_runner_file = argv[argp + 1]; @@ -909,23 +951,23 @@ main(int argc, char *argv[]) { struct stat st; if (stat(lsyncd_runner_file, &st)) { - printf("Cannot find Lsyncd Lua-runner at %s.\n", lsyncd_runner_file); - printf("Maybe specify another place? %s --runner RUNNER_FILE CONFIG_FILE\n", argv[0]); + fprintf(stderr, "Cannot find Lsyncd Lua-runner at %s.\n", lsyncd_runner_file); + fprintf(stderr, "Maybe specify another place? %s --runner RUNNER_FILE CONFIG_FILE\n", argv[0]); return -1; // ERRNO } if (stat(lsyncd_config_file, &st)) { - printf("Cannot find config file at %s.\n", lsyncd_config_file); + fprintf(stderr, "Cannot find config file at %s.\n", lsyncd_config_file); return -1; // ERRNO } } if (luaL_loadfile(L, lsyncd_runner_file)) { - printf("error loading '%s': %s\n", + fprintf(stderr, "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 preparing '%s': %s\n", + fprintf(stderr, "error preparing '%s': %s\n", lsyncd_runner_file, lua_tostring(L, -1)); return -1; // ERRNO } @@ -937,27 +979,25 @@ main(int argc, char *argv[]) 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); + fprintf(stderr, "Version mismatch '%s' is '%s', but core is '%s'\n", + lsyncd_runner_file, lversion, PACKAGE_VERSION); return -1; // ERRNO } } if (luaL_loadfile(L, lsyncd_config_file)) { - printf("error loading %s: %s\n", lsyncd_config_file, lua_tostring(L, -1)); + fprintf(stderr, "error loading %s: %s\n", lsyncd_config_file, lua_tostring(L, -1)); return -1; // ERRNO } if (lua_pcall(L, 0, LUA_MULTRET, 0)) { - printf("error preparing %s: %s\n", lsyncd_config_file, lua_tostring(L, -1)); + fprintf(stderr, "error preparing %s: %s\n", lsyncd_config_file, lua_tostring(L, -1)); return -1; // ERRNO } /* open inotify */ inotify_fd = inotify_init(); if (inotify_fd == -1) { - printf("Cannot create inotify instance! (%d:%s)\n", errno, strerror(errno)); + fprintf(stderr, "Cannot create inotify instance! (%d:%s)\n", errno, strerror(errno)); return -1; // ERRNO } diff --git a/lsyncd.lua b/lsyncd.lua index 4a0619c..9814a59 100644 --- a/lsyncd.lua +++ b/lsyncd.lua @@ -14,11 +14,13 @@ -- A security measurement. -- Core will exit if version ids mismatch. if lsyncd_version ~= nil then - print "You cannot use the lsyncd runner as configuration file!" + print("You cannot use the lsyncd runner as configuration file!") os.exit(-1) end lsyncd_version = "2.0b1" +log = lsyncd.log + ---- -- Table of all directories to watch. origins = {} @@ -125,9 +127,9 @@ local event_names = { -- function lsyncd_event(etype, wd, filename, filename2) if filename2 == nil then - print("got event " .. event_names[etype] .. " of " .. filename) + log(NORMAL, "got event " .. event_names[etype] .. " of " .. filename) else - print("got event " .. event_names[etype] .. " of " .. filename .. " to " .. filename2) + log(NORMAL, "got event " .. event_names[etype] .. " of " .. filename .. " to " .. filename2) end end @@ -147,22 +149,12 @@ end ---- -- Called by core when an overflow happened. function default_overflow() - print("--- OVERFLOW on inotify event queue ---") + log(ERROR, "--- OVERFLOW on inotify event queue ---") lsyncd.terminate(-1) -- TODO reset instead. end overflow = default_overflow ------ --- Called by core on event --- --- --- @return the pid of a spawned child process or 0 if no spawn. -function default_event() - print("got an event") - return 0 -end - ----- -- Called by core after initialization. -- @@ -173,14 +165,14 @@ end -- "startup". (and yet may still call default startup) -- function default_startup() - print("--- startup ---") + log(NORMAL, "--- startup ---") local pids = { } for i, o in ipairs(origins) do startup_action(o.source, o.targetpath) table.insert(pids, pid) end lsyncd.wait_pids(pids, "startup_collector") - print("--- Entering normal operation with " .. #watches .. " monitored directories ---") + log(NORMAL, "--- Entering normal operation with " .. #watches .. " monitored directories ---") end startup = default_startup @@ -197,7 +189,7 @@ startup = default_startup -- function default_startup_collector(pid, exitcode) if exitcode ~= 0 then - print("Startup process", pid, " failed") + log(ERROR, "Startup process", pid, " failed") lsyncd.terminate(-1) -- ERRNO end return 0