This commit is contained in:
Axel Kittenberger 2010-10-20 15:34:01 +00:00
parent fe669ed7f7
commit 76c92ba0a1
1 changed files with 152 additions and 35 deletions

187
lsyncd.c
View File

@ -30,6 +30,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include <lua.h> #include <lua.h>
@ -48,7 +50,10 @@
#define time_before_eq(a,b) time_after_eq(b,a) #define time_before_eq(a,b) time_after_eq(b,a)
enum event { /**
* Event types core sends to runner.
*/
enum event_type {
NONE = 0, NONE = 0,
ATTRIB = 1, ATTRIB = 1,
MODIFY = 2, MODIFY = 2,
@ -61,8 +66,8 @@ enum event {
* The Lua part of lsyncd. * The Lua part of lsyncd.
*/ */
#define LSYNCD_DEFAULT_RUNNER_FILE "lsyncd.lua" #define LSYNCD_DEFAULT_RUNNER_FILE "lsyncd.lua"
char * lsyncd_runner_file = NULL; static char * lsyncd_runner_file = NULL;
char * lsyncd_config_file = NULL; static char * lsyncd_config_file = NULL;
/** /**
* The inotify file descriptor. * The inotify file descriptor.
@ -72,28 +77,47 @@ static int inotify_fd;
/** /**
* TODO allow configure. * TODO allow configure.
*/ */
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;
/**
* Configuration settings relevant for core. /**
* If not null lsyncd logs in this file.
*/ */
struct settings { static char * logfile = NULL;
char * logfile;
}; /**
struct settings settings = {0,}; * If true lsyncd sends log messages to syslog
*/
bool logsyslog = false;
/**
* lsyncd log level
*/
static enum loglevel {
DEBUG = 1, /* Log debug messages */
VERBOSE = 2, /* Log more */
NORMAL = 3, /* Log short summeries */
ERROR = 4, /* Log severe errors only */
CORE = 0x80 /* Indicates a core message */
} loglevel = NORMAL;
/**
* True when lsyncd daemonized itself.
*/
static bool is_daemon;
/** /**
* 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.
*/ */
volatile sig_atomic_t reset = 0; static volatile sig_atomic_t reset = 0;
/** /**
* The kernels clock ticks per second. * The kernels clock ticks per second.
*/ */
long clocks_per_sec; static long clocks_per_sec;
/** /**
* "secured" calloc. * "secured" calloc.
@ -176,6 +200,77 @@ l_add_watch(lua_State *L)
return 1; return 1;
} }
/**
* Logs a log level
*
* @param loglevel (Lua stack) loglevel of massage
* @param string (Lua stack) the string to log
*/
static int
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) {
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);
}
}
*/
return 0;
}
/** /**
* Returns (on Lua stack) the current kernels clock state (jiffies, times() call) * Returns (on Lua stack) the current kernels clock state (jiffies, times() call)
*/ */
@ -283,18 +378,18 @@ l_stackdump(lua_State* L)
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:
printf("%d string: '%s'\n", i, lua_tostring(L, i)); printf("%d string: '%s'\n", i, lua_tostring(L, i));
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
printf("%d boolean %s\n", i, lua_toboolean(L, i) ? "true" : "false"); printf("%d boolean %s\n", i, lua_toboolean(L, i) ? "true" : "false");
break; break;
case LUA_TNUMBER: case LUA_TNUMBER:
printf("%d number: %g\n", i, lua_tonumber(L, i)); printf("%d number: %g\n", i, lua_tonumber(L, i));
break; break;
default: /* other values */ default:
printf("%d %s\n", i, lua_typename(L, t)); printf("%d %s\n", i, lua_typename(L, t));
break; break;
} }
} }
@ -471,6 +566,7 @@ l_wait_pids(lua_State *L)
static const luaL_reg lsyncdlib[] = { static const luaL_reg lsyncdlib[] = {
{"add_watch", l_add_watch }, {"add_watch", l_add_watch },
{"log", l_log },
{"now", l_now }, {"now", l_now },
{"exec", l_exec }, {"exec", l_exec },
{"real_dir", l_real_dir }, {"real_dir", l_real_dir },
@ -486,27 +582,46 @@ static const luaL_reg lsyncdlib[] = {
* Lsyncd Core * Lsyncd Core
****************************************************************************/ ****************************************************************************/
/**
* TODO
*/
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, ...)
{
va_list ap;
lua_pushcfunction(L, l_log);
lua_pushinteger(L, level);
va_start(ap, fmt);
lua_pushvfstring(L, fmt, ap);
va_end(ap);
lua_call(L, 2, 0);
return;
}
/** /**
* Transfers the core relevant settings from lua's global "settings" into 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. * This saves time in normal operation instead of bothering lua all the time.
*/ */
/*
void void
get_settings(lua_State *L) get_settings(lua_State *L)
{ {
/* frees old settings */
if (settings.logfile) { if (settings.logfile) {
free(settings.logfile); free(settings.logfile);
settings.logfile = NULL; settings.logfile = NULL;
} }
/* gets settings table */
lua_getglobal(L, "settings"); lua_getglobal(L, "settings");
if (!lua_istable(L, -1)) { if (!lua_istable(L, -1)) {
/* user has not specified any settings */
return; return;
} }
/* get logfile */
lua_pushstring(L, "logfile"); lua_pushstring(L, "logfile");
lua_gettable(L, -2); lua_gettable(L, -2);
if (settings.logfile) { if (settings.logfile) {
@ -518,9 +633,8 @@ get_settings(lua_State *L)
} }
lua_pop(L, 1); lua_pop(L, 1);
/* pop the settings table */
lua_pop(L, 1); lua_pop(L, 1);
} }*/
/** /**
@ -761,12 +875,18 @@ main(int argc, char *argv[])
luaL_register(L, "lsyncd", lsyncdlib); luaL_register(L, "lsyncd", lsyncdlib);
lua_setglobal(L, "lysncd"); lua_setglobal(L, "lysncd");
/* register inotify identifiers */ /* register event types */
lua_pushinteger(L, ATTRIB); lua_setglobal(L, "ATTRIB"); lua_pushinteger(L, ATTRIB); lua_setglobal(L, "ATTRIB");
lua_pushinteger(L, MODIFY); lua_setglobal(L, "MODIFY"); lua_pushinteger(L, MODIFY); lua_setglobal(L, "MODIFY");
lua_pushinteger(L, CREATE); lua_setglobal(L, "CREATE"); lua_pushinteger(L, CREATE); lua_setglobal(L, "CREATE");
lua_pushinteger(L, DELETE); lua_setglobal(L, "DELETE"); lua_pushinteger(L, DELETE); lua_setglobal(L, "DELETE");
lua_pushinteger(L, MOVE); lua_setglobal(L, "MOVE"); lua_pushinteger(L, MOVE); lua_setglobal(L, "MOVE");
/* register log levels */
lua_pushinteger(L, DEBUG); lua_setglobal(L, "DEBUG");
lua_pushinteger(L, VERBOSE); lua_setglobal(L, "VERBOSE");
lua_pushinteger(L, NORMAL); lua_setglobal(L, "NORMAL");
lua_pushinteger(L, ERROR); lua_setglobal(L, "ERROR");
/* TODO parse runner */ /* TODO parse runner */
if (!strcmp(argv[argp], "--runner")) { if (!strcmp(argv[argp], "--runner")) {
@ -846,9 +966,6 @@ main(int argc, char *argv[])
lua_getglobal(L, "lsyncd_initialize"); lua_getglobal(L, "lsyncd_initialize");
lua_call(L, 0, 0); lua_call(L, 0, 0);
/* load core settings into core */
get_settings(L);
/* let lua code will perform startup calls like recursive rsync */ /* let lua code will perform startup calls like recursive rsync */
lua_getglobal(L, "startup"); lua_getglobal(L, "startup");
lua_call(L, 0, 0); lua_call(L, 0, 0);