code beautifications

This commit is contained in:
Axel Kittenberger 2012-02-15 12:15:32 +01:00
parent 105cde4807
commit de9e404132
1 changed files with 312 additions and 409 deletions

467
lsyncd.c
View File

@ -10,6 +10,8 @@
* This is the core. It contains as minimal as possible glues * This is the core. It contains as minimal as possible glues
* to the operating system needed for lsyncd operation. All high-level * to the operating system needed for lsyncd operation. All high-level
* logic is coded (when feasable) into lsyncd.lua * logic is coded (when feasable) into lsyncd.lua
*
* This code assumes you have a 100 character wide display to view it, when tabstop is 4.
*/ */
#include "lsyncd.h" #include "lsyncd.h"
@ -90,38 +92,6 @@ struct settings settings = {
.nodaemon = false, .nodaemon = false,
}; };
/**
* configurable names for logging facility
* to be translated to integer value.
*/
//struct {
// const char * c_name;
// int c_val;
//} facilitynames[] = {
// { "auth", LOG_AUTH },
// { "authprive", LOG_AUTHPRIV },
// { "cron", LOG_CRON },
// { "daemon", LOG_DAEMON },
// { "ftp", LOG_FTP },
// { "kern", LOG_KERN },
// { "lpr", LOG_LPR },
// { "mail", LOG_MAIL },
// { "news", LOG_NEWS },
// { "syslog", LOG_SYSLOG },
// { "user", LOG_USER },
// { "uucp", LOG_UUCP },
// { "local0", LOG_LOCAL0 },
// { "local1", LOG_LOCAL1 },
// { "local2", LOG_LOCAL2 },
// { "local3", LOG_LOCAL3 },
// { "local4", LOG_LOCAL4 },
// { "local5", LOG_LOCAL5 },
// { "local6", LOG_LOCAL6 },
// { "local7", LOG_LOCAL7 },
// { NULL, -1 },
//};
/** /**
* True when lsyncd daemonized itself. * True when lsyncd daemonized itself.
*/ */
@ -203,8 +173,7 @@ struct logcat {
static struct logcat *logcats[26] = {0,}; static struct logcat *logcats[26] = {0,};
/** /**
* Returns the positive priority if category is configured to be logged. * Returns the positive priority if category is configured to be logged or -1.
* or -1
*/ */
extern int extern int
check_logcat(const char *name) check_logcat(const char *name)
@ -243,34 +212,32 @@ add_logcat(const char *name, int priority)
return true; return true;
} }
/* category must start with capital letter */ // categories must start with a capital letter.
if (name[0] < 'A' || name[0] > 'Z') { if (name[0] < 'A' || name[0] > 'Z') return false;
return false;
}
if (!logcats[name[0]-'A']) { if (!logcats[name[0]-'A']) {
/* en empty capital letter */ // an empty capital letter
lc = logcats[name[0]-'A'] = s_calloc(2, sizeof(struct logcat)); lc = logcats[name[0]-'A'] = s_calloc(2, sizeof(struct logcat));
} else { } else {
/* length of letter list */ int ll = 0; // length of letter list
int ll = 0; // counts list length
/* counts list length */
for(lc = logcats[name[0]-'A']; lc->name; lc++) { for(lc = logcats[name[0]-'A']; lc->name; lc++) {
ll++; ll++;
} }
/* enlarge list */ // enlarges list
logcats[name[0]-'A'] = logcats[name[0]-'A'] =
s_realloc(logcats[name[0]-'A'], (ll + 2) * sizeof(struct logcat)); s_realloc(logcats[name[0]-'A'], (ll + 2) * sizeof(struct logcat));
/* go to list end */ // go to list end
for(lc = logcats[name[0]-'A']; lc->name; lc++) { for(lc = logcats[name[0]-'A']; lc->name; lc++) {
if (!strcmp(name, lc->name)) { if (!strcmp(name, lc->name)) {
/* already there */ // already there
return true; return true;
} }
} }
} }
lc->name = s_strdup(name); lc->name = s_strdup(name);
lc->priority = priority; lc->priority = priority;
/* terminates the list */ // terminates the list
lc[1].name = NULL; lc[1].name = NULL;
return true; return true;
} }
@ -288,8 +255,8 @@ extern void
logstring0(int priority, const char *cat, const char *message) logstring0(int priority, const char *cat, const char *message)
{ {
if (first_time) { if (first_time) {
/* lsyncd is in intial configuration. // lsyncd is in intial configuration phase.
* thus just print to normal stdout/stderr. */ // thus just print to normal stdout/stderr.
if (priority >= LOG_ERR) { if (priority >= LOG_ERR) {
fprintf(stderr, "%s: %s\n", cat, message); fprintf(stderr, "%s: %s\n", cat, message);
} else { } else {
@ -298,10 +265,10 @@ logstring0(int priority, const char *cat, const char *message)
return; return;
} }
/* writes on console if not daemon */ // writes on console if not daemonized
if (!is_daemon) { if (!is_daemon) {
char ct[255]; char ct[255];
/* gets current timestamp hour:minute:second */ // gets current timestamp hour:minute:second
time_t mtime; time_t mtime;
time(&mtime); time(&mtime);
strftime(ct, sizeof(ct), "%T", localtime(&mtime)); strftime(ct, sizeof(ct), "%T", localtime(&mtime));
@ -309,15 +276,15 @@ logstring0(int priority, const char *cat, const char *message)
fprintf(flog, "%s %s: %s\n", ct, cat, message); fprintf(flog, "%s %s: %s\n", ct, cat, message);
} }
/* writes to file if configured so */ // writes to file if configured so
if (settings.log_file) { if (settings.log_file) {
FILE * flog = fopen(settings.log_file, "a"); FILE * flog = fopen(settings.log_file, "a");
/* gets current timestamp day-time-year */ // gets current timestamp day-time-year
char * ct; char * ct;
time_t mtime; time_t mtime;
time(&mtime); time(&mtime);
ct = ctime(&mtime); ct = ctime(&mtime);
/* cuts trailing linefeed */ // cuts trailing linefeed
ct[strlen(ct) - 1] = 0; ct[strlen(ct) - 1] = 0;
if (flog == NULL) { if (flog == NULL) {
@ -329,10 +296,8 @@ logstring0(int priority, const char *cat, const char *message)
fclose(flog); fclose(flog);
} }
/* sends to syslog if configured so */ // sends to syslog if configured so
if (settings.log_syslog) { if (settings.log_syslog) syslog(priority, "%s, %s", cat, message);
syslog(priority, "%s, %s", cat, message);
}
return; return;
} }
@ -426,13 +391,13 @@ s_strdup(const char *src)
* write() can manage. * write() can manage.
*/ */
struct pipemsg { struct pipemsg {
/* message to send */ // message to send
char *text; char *text;
/* length of text */ // length of text
int tlen; int tlen;
/* position in message */ // position in message
int pos; int pos;
}; };
@ -575,16 +540,16 @@ observe_fd(int fd,
void *extra) void *extra)
{ {
int pos; int pos;
/* looks if the fd is already there as pos or // looks if the fd is already there as pos or
* stores the position to insert the new fd in pos */ // stores the position to insert the new fd in pos
for(pos = 0; pos < observances_len; pos++) { for(pos = 0; pos < observances_len; pos++) {
if (fd <= observances[pos].fd) { if (fd <= observances[pos].fd) {
break; break;
} }
} }
if (pos < observances_len && observances[pos].fd == fd) { if (pos < observances_len && observances[pos].fd == fd) {
/* just update an existing observance */ // just updates an existing observance
logstring("Masterloop", "updating n fd observance"); logstring("Masterloop", "updating fd observance");
observances[pos].ready = ready; observances[pos].ready = ready;
observances[pos].writey = writey; observances[pos].writey = writey;
observances[pos].tidy = tidy; observances[pos].tidy = tidy;
@ -629,22 +594,20 @@ nonobserve_fd(int fd)
int pos; int pos;
if (observance_action) { if (observance_action) {
/* this function is called through a ready/writey handler // this function is called through a ready/writey handler
* while the core works through the observance list, thus // while the core works through the observance list, thus
* it does not alter the list, but stores this actions // it does not alter the list, but stores this actions
* on a stack // on a stack
*/
nonobservances_len++; nonobservances_len++;
if (nonobservances_len > nonobservances_size) { if (nonobservances_len > nonobservances_size) {
nonobservances_size = nonobservances_len; nonobservances_size = nonobservances_len;
nonobservances = s_realloc(nonobservances, nonobservances = s_realloc(nonobservances, nonobservances_size * sizeof(int));
nonobservances_size * sizeof(int));
} }
nonobservances[nonobservances_len - 1] = fd; nonobservances[nonobservances_len - 1] = fd;
return; return;
} }
/* looks for the fd */ // looks for the fd
for(pos = 0; pos < observances_len; pos++) { for(pos = 0; pos < observances_len; pos++) {
if (observances[pos].fd == fd) { if (observances[pos].fd == fd) {
break; break;
@ -656,10 +619,10 @@ nonobserve_fd(int fd)
exit(-1); //ERRNO exit(-1); //ERRNO
} }
/* tidy up the observance */ // tidies up the observance
observances[pos].tidy(observances + pos); observances[pos].tidy(observances + pos);
/* and moves the list down */ // and moves the list down
memmove(observances + pos, observances + pos + 1, memmove(observances + pos, observances + pos + 1,
(observances_len - pos) * (sizeof(struct observance))); (observances_len - pos) * (sizeof(struct observance)));
observances_len--; observances_len--;
@ -672,25 +635,23 @@ static void
user_obs_ready(lua_State *L, struct observance *obs) user_obs_ready(lua_State *L, struct observance *obs)
{ {
int fd = obs->fd; int fd = obs->fd;
/* pushes the ready table on table */ // pushes the ready table on table
lua_pushlightuserdata(L, (void *) user_obs_ready); lua_pushlightuserdata(L, (void *) user_obs_ready);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
/* pushes the error handler */ // pushes the error handler
lua_pushlightuserdata(L, (void *) &callError); lua_pushlightuserdata(L, (void *) &callError);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
/* pushed the user func */ // pushed the user func
lua_pushnumber(L, fd); lua_pushnumber(L, fd);
lua_gettable(L, -3); lua_gettable(L, -3);
/* gives the ufunc the fd */ // gives the ufunc the fd
lua_pushnumber(L, fd); lua_pushnumber(L, fd);
/* calls the user function */ // calls the user function
if (lua_pcall(L, 1, 0, -3)) { if (lua_pcall(L, 1, 0, -3)) exit(-1); // ERRNO
exit(-1); // ERRNO
}
lua_pop(L, 2); lua_pop(L, 2);
} }
@ -701,25 +662,23 @@ static void
user_obs_writey(lua_State *L, struct observance *obs) user_obs_writey(lua_State *L, struct observance *obs)
{ {
int fd = obs->fd; int fd = obs->fd;
/* pushes the writey table on table */ // pushes the writey table on table
lua_pushlightuserdata(L, (void *) user_obs_writey); lua_pushlightuserdata(L, (void *) user_obs_writey);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
/* pushes the error handler */ // pushes the error handler
lua_pushlightuserdata(L, (void *) &callError); lua_pushlightuserdata(L, (void *) &callError);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
/* pushed the user func */ // pushes the user func
lua_pushnumber(L, fd); lua_pushnumber(L, fd);
lua_gettable(L, -3); lua_gettable(L, -3);
/* gives the ufunc the fd */ // gives the user func the fd
lua_pushnumber(L, fd); lua_pushnumber(L, fd);
/* calls the user function */ // calls the user function
if (lua_pcall(L, 1, 0, -3)) { if (lua_pcall(L, 1, 0, -3)) exit(-1); // ERRNO
exit(-1); // ERRNO
}
lua_pop(L, 2); lua_pop(L, 2);
} }
@ -753,19 +712,14 @@ int l_stackdump(lua_State* L);
static int static int
l_log(lua_State *L) l_log(lua_State *L)
{ {
/* log category */ const char * cat; // log category
const char * cat; const char * message; // log message
/* log message */ int priority; // log priority
const char * message;
/* log priority */
int priority;
cat = luaL_checkstring(L, 1); cat = luaL_checkstring(L, 1);
priority = check_logcat(cat); priority = check_logcat(cat);
/* skips filtered messages */ /* skips filtered messages */
if (priority > settings.log_level) { if (priority > settings.log_level) return 0;
return 0;
}
{ {
// replace non string values // replace non string values
@ -788,8 +742,7 @@ l_log(lua_State *L)
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
{ {
clock_t *c = (clock_t *) clock_t *c = (clock_t *) luaL_checkudata(L, i, "Lsyncd.jiffies");
luaL_checkudata(L, i, "Lsyncd.jiffies");
double d = (*c); double d = (*c);
d /= clocks_per_sec; d /= clocks_per_sec;
lua_pushfstring(L, "(Timestamp: %f)", d); lua_pushfstring(L, "(Timestamp: %f)", d);
@ -804,7 +757,7 @@ l_log(lua_State *L)
} }
} }
/* concates if there is more than one string parameter */ // concates if there is more than one string parameter
lua_concat(L, lua_gettop(L) - 1); lua_concat(L, lua_gettop(L) - 1);
message = luaL_checkstring(L, 2); message = luaL_checkstring(L, 2);
@ -840,51 +793,42 @@ l_now(lua_State *L)
static int static int
l_exec(lua_State *L) l_exec(lua_State *L)
{ {
/* the binary to call */ const char *binary = luaL_checkstring(L, 1); // the binary to call
const char *binary = luaL_checkstring(L, 1); int argc = lua_gettop(L) - 1; // number of arguments
/* number of arguments */ pid_t pid; // the pid spawned
int argc = lua_gettop(L) - 1; int li = 1; // the arguments position in the lua arguments
/* the pid spawned */
pid_t pid;
/* the arguments position in the lua arguments */
int li = 1;
/* the pipe to text */ char const *pipe_text = NULL; // the pipe to text
char const *pipe_text = NULL; size_t pipe_len = 0; // the pipes length
size_t pipe_len = 0; char const **argv; // the arguments
/* the arguments */ int pipefd[2]; // pipe file descriptors
char const **argv; int i;
/* pipe file descriptors */
int pipefd[2];
/* expands tables if there are any */ // expands tables if there are any
{ for(i = 1; i <= lua_gettop(L); i++) {
int i; if (lua_istable(L, i)) {
for(i = 1; i <= lua_gettop(L); i++) { int tlen;
if (lua_istable(L, i)) { int it;
int tlen; /* table is now on top of stack */
int it; lua_checkstack(L, lua_gettop(L) + lua_objlen(L, i) + 1);
/* table is now on top of stack */ lua_pushvalue(L, i);
lua_checkstack(L, lua_gettop(L) + lua_objlen(L, i) + 1); lua_remove(L, i);
lua_pushvalue(L, i); argc--;
lua_remove(L, i); tlen = lua_objlen(L, -1);
argc--; for (it = 1; it <= tlen; it++) {
tlen = lua_objlen(L, -1); lua_pushinteger(L, it);
for (it = 1; it <= tlen; it++) { lua_gettable(L, -2);
lua_pushinteger(L, it); lua_insert(L,i);
lua_gettable(L, -2); i++;
lua_insert(L,i); argc++;
i++;
argc++;
}
i--;
lua_pop(L, 1);
} }
i--;
lua_pop(L, 1);
} }
} }
/* writes a log message, prepares the message only if actually needed. */ /* writes a log message, prepares the message only if actually needed. */
if (check_logcat("Exec") <= settings.log_level) { if (check_logcat("Exec") <= settings.log_level) {
int i;
lua_checkstack(L, lua_gettop(L) + argc * 3 + 2); lua_checkstack(L, lua_gettop(L) + argc * 3 + 2);
lua_pushvalue(L, 1); lua_pushvalue(L, 1);
for(i = 1; i <= argc; i++) { for(i = 1; i <= argc; i++) {
@ -921,55 +865,46 @@ l_exec(lua_State *L)
li += 2; li += 2;
} }
{ // prepares the arguments
/* prepares the arguments */ argv = s_calloc(argc + 2, sizeof(char *));
int i; argv[0] = binary;
argv = s_calloc(argc + 2, sizeof(char *)); for(i = 1; i <= argc; i++) {
argv[0] = binary; argv[i] = luaL_checkstring(L, i + li);
for(i = 1; i <= argc; i++) {
argv[i] = luaL_checkstring(L, i + li);
}
argv[i] = NULL;
} }
argv[i] = NULL;
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
/* replaces stdin for pipes */ // replaces stdin for pipes
if (pipe_text) { if (pipe_text) dup2(pipefd[0], STDIN_FILENO);
dup2(pipefd[0], STDIN_FILENO);
} // if lsyncd runs as a daemon and has a logfile it will redirect
// close_exec_fd(pipefd[0]); // stdout/stderr of child processes to the logfile.
/* if lsyncd runs as a daemon and has a logfile it will redirect
stdout/stderr of child processes to the logfile. */
if (is_daemon && settings.log_file) { if (is_daemon && settings.log_file) {
if (!freopen(settings.log_file, "a", stdout)) { if (!freopen(settings.log_file, "a", stdout)) {
printlogf(L, "Error", printlogf(L, "Error", "cannot redirect stdout to '%s'.", settings.log_file);
"cannot redirect stdout to '%s'.",
settings.log_file);
} }
if (!freopen(settings.log_file, "a", stderr)) { if (!freopen(settings.log_file, "a", stderr)) {
printlogf(L, "Error", printlogf(L, "Error", "cannot redirect stderr to '%s'.", settings.log_file);
"cannot redirect stderr to '%s'.",
settings.log_file);
} }
} }
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
} }
if (pipe_text) { if (pipe_text) {
int len; int len;
/* first closes read-end of pipe, this is for child process only */ // first closes read-end of pipe, this is for child process only
close(pipefd[0]); close(pipefd[0]);
/* start filling the pipe */ // starts filling the pipe
len = write(pipefd[1], pipe_text, pipe_len); len = write(pipefd[1], pipe_text, pipe_len);
if (len < 0) { if (len < 0) {
logstring("Normal", "immediatly broken pipe."); logstring("Normal", "immediatly broken pipe.");
close(pipefd[1]); close(pipefd[1]);
} else if (len == pipe_len) { } else if (len == pipe_len) {
/* usual and best case, the pipe accepted all input -> close */ // usual and best case, the pipe accepted all input -> close
close(pipefd[1]); close(pipefd[1]);
logstring("Exec", "one-sweeped pipe"); logstring("Exec", "one-sweeped pipe");
} else { } else {
@ -1001,17 +936,15 @@ l_realdir(lua_State *L)
char *cbuf; char *cbuf;
const char *rdir = luaL_checkstring(L, 1); const char *rdir = luaL_checkstring(L, 1);
/* use c-library to get absolute path */ // uses c-library to get the absolute path
#ifdef __GLIBC__ #ifdef __GLIBC__
cbuf = realpath(rdir, NULL); cbuf = realpath(rdir, NULL);
#else #else
# warning must use oldstyle realpath() # warning having to use oldstyle realpath()
{ {
char *ccbuf = s_calloc(sizeof(char), PATH_MAX); char *ccbuf = s_calloc(sizeof(char), PATH_MAX);
cbuf = realpath(rdir, ccbuf); cbuf = realpath(rdir, ccbuf);
if (!cbuf) { if (!cbuf) free(ccbuf);
free(ccbuf);
}
} }
#endif #endif
if (!cbuf) { if (!cbuf) {
@ -1019,7 +952,7 @@ l_realdir(lua_State *L)
return 0; return 0;
} }
{ {
/* makes sure its a directory */ // makes sure its a directory
struct stat st; struct stat st;
if (stat(cbuf, &st)) { if (stat(cbuf, &st)) {
printlogf(L, "Error", printlogf(L, "Error",
@ -1036,7 +969,7 @@ l_realdir(lua_State *L)
} }
} }
/* returns absolute path with a concated '/' */ // returns absolute path with a concated '/'
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
luaL_addstring(&b, cbuf); luaL_addstring(&b, cbuf);
luaL_addchar(&b, '/'); luaL_addchar(&b, '/');
@ -1058,20 +991,16 @@ l_stackdump(lua_State* L)
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'", printlogf(L, "Debug", "%d string: '%s'", i, lua_tostring(L, i));
i, lua_tostring(L, i));
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
printlogf(L, "Debug", "%d boolean %s", printlogf(L, "Debug", "%d boolean %s", i, lua_toboolean(L, i) ? "true" : "false");
i, lua_toboolean(L, i) ? "true" : "false");
break; break;
case LUA_TNUMBER: case LUA_TNUMBER:
printlogf(L, "Debug", "%d number: %g", printlogf(L, "Debug", "%d number: %g", i, lua_tonumber(L, i));
i, lua_tonumber(L, i));
break; break;
default: default:
printlogf(L, "Debug", "%d %s", printlogf(L, "Debug", "%d %s", i, lua_typename(L, t));
i, lua_typename(L, t));
break; break;
} }
} }
@ -1102,18 +1031,13 @@ l_readdir (lua_State *L)
while (!hup && !term) { while (!hup && !term) {
struct dirent *de = readdir(d); struct dirent *de = readdir(d);
bool isdir; bool isdir;
if (de == NULL) { if (de == NULL) break; // finished
/* finished */
break;
}
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { // ignores . and ..
/* ignores . and .. */ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue;
continue;
}
if (de->d_type == DT_UNKNOWN) { if (de->d_type == DT_UNKNOWN) {
/* must call stat on some systems :-/ */ // must call stat on some systems :-/
char *entry = s_malloc(strlen(dirname) + strlen(de->d_name) + 2); char *entry = s_malloc(strlen(dirname) + strlen(de->d_name) + 2);
struct stat st; struct stat st;
strcpy(entry, dirname); strcpy(entry, dirname);
@ -1123,11 +1047,11 @@ l_readdir (lua_State *L)
isdir = S_ISDIR(st.st_mode); isdir = S_ISDIR(st.st_mode);
free(entry); free(entry);
} else { } else {
/* readdir can trusted */ // readdir can trusted
isdir = de->d_type == DT_DIR; isdir = de->d_type == DT_DIR;
} }
/* adds this entry to the Lua table */ // adds this entry to the Lua table
lua_pushstring(L, de->d_name); lua_pushstring(L, de->d_name);
lua_pushboolean(L, isdir); lua_pushboolean(L, isdir);
lua_settable(L, -3); lua_settable(L, -3);
@ -1162,20 +1086,16 @@ l_configure(lua_State *L)
{ {
const char * command = luaL_checkstring(L, 1); const char * command = luaL_checkstring(L, 1);
if (!strcmp(command, "running")) { if (!strcmp(command, "running")) {
/* set by runner after first initialize // set by runner after first initialize
* from this on log to configurated log end instead of // from this on log to configurated log end instead of
* stdout/stderr */ // stdout/stderr
first_time = false; first_time = false;
if (settings.log_syslog || !settings.log_file) { if (settings.log_syslog || !settings.log_file) {
openlog(settings.log_ident ? settings.log_ident : "lsyncd", const char * log_ident = settings.log_ident ? settings.log_ident : "lsyncd";
0, openlog(log_ident, 0, settings.log_facility);
settings.log_facility
);
} }
if (!settings.nodaemon && !is_daemon) { if (!settings.nodaemon && !is_daemon) {
if (!settings.log_file) { if (!settings.log_file) settings.log_syslog = true;
settings.log_syslog = true;
}
logstring("Debug", "daemonizing now."); logstring("Debug", "daemonizing now.");
daemonize(L); daemonize(L);
} }
@ -1186,24 +1106,18 @@ l_configure(lua_State *L)
settings.nodaemon = true; settings.nodaemon = true;
} else if (!strcmp(command, "logfile")) { } else if (!strcmp(command, "logfile")) {
const char * file = luaL_checkstring(L, 2); const char * file = luaL_checkstring(L, 2);
if (settings.log_file) { if (settings.log_file) free(settings.log_file);
free(settings.log_file);
}
settings.log_file = s_strdup(file); settings.log_file = s_strdup(file);
} else if (!strcmp(command, "pidfile")) { } else if (!strcmp(command, "pidfile")) {
const char * file = luaL_checkstring(L, 2); const char * file = luaL_checkstring(L, 2);
if (settings.pidfile) { if (settings.pidfile) free(settings.pidfile);
free(settings.pidfile);
}
settings.pidfile = s_strdup(file); settings.pidfile = s_strdup(file);
} else if (!strcmp(command, "logfacility")) { } else if (!strcmp(command, "logfacility")) {
if (lua_isstring(L, 2)) { if (lua_isstring(L, 2)) {
const char * fname = luaL_checkstring(L, 2); const char * fname = luaL_checkstring(L, 2);
int i; int i;
for(i = 0; facilitynames[i].c_name; i++) { for(i = 0; facilitynames[i].c_name; i++) {
if (!strcasecmp(fname, facilitynames[i].c_name)) { if (!strcasecmp(fname, facilitynames[i].c_name)) break;
break;
}
} }
if (!facilitynames[i].c_name) { if (!facilitynames[i].c_name) {
printlogf(L, "Error", "Logging facility '%s' unknown.", fname); printlogf(L, "Error", "Logging facility '%s' unknown.", fname);
@ -1218,9 +1132,7 @@ l_configure(lua_State *L)
} }
} else if (!strcmp(command, "logident")) { } else if (!strcmp(command, "logident")) {
const char * ident = luaL_checkstring(L, 2); const char * ident = luaL_checkstring(L, 2);
if (settings.log_ident) { if (settings.log_ident) free(settings.log_ident);
free(settings.log_ident);
}
settings.log_ident = s_strdup(ident); settings.log_ident = s_strdup(ident);
} else { } else {
printlogf(L, "Error", printlogf(L, "Error",
@ -1244,9 +1156,9 @@ l_observe_fd(lua_State *L)
int fd = luaL_checknumber(L, 1); int fd = luaL_checknumber(L, 1);
bool ready = false; bool ready = false;
bool writey = false; bool writey = false;
/* Stores the user function in the lua registry. // Stores the user function in the lua registry.
* It uses the address of the cores ready/write functions // It uses the address of the cores ready/write functions
* for the user as key */ // for the user as key
if (!lua_isnoneornil(L, 2)) { if (!lua_isnoneornil(L, 2)) {
lua_pushlightuserdata(L, (void *) user_obs_ready); lua_pushlightuserdata(L, (void *) user_obs_ready);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
@ -1298,7 +1210,7 @@ l_nonobserve_fd(lua_State *L)
{ {
int fd = luaL_checknumber(L, 1); int fd = luaL_checknumber(L, 1);
/* removes read func */ // removes the read function
lua_pushlightuserdata(L, (void *) user_obs_ready); lua_pushlightuserdata(L, (void *) user_obs_ready);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
if (!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
@ -1347,7 +1259,7 @@ l_jiffies_add(lua_State *L)
clock_t *p2 = (clock_t *) lua_touserdata(L, 2); clock_t *p2 = (clock_t *) lua_touserdata(L, 2);
if (p1 && p2) { if (p1 && p2) {
logstring("Error", "Cannot add to timestamps!"); logstring("Error", "Cannot add to timestamps!");
exit(-1); /* ERRNO */ exit(-1); // ERRNO
} }
{ {
clock_t a1 = p1 ? *p1 : luaL_checknumber(L, 1) * clocks_per_sec; clock_t a1 = p1 ? *p1 : luaL_checknumber(L, 1) * clocks_per_sec;
@ -1369,13 +1281,13 @@ l_jiffies_sub(lua_State *L)
clock_t *p1 = (clock_t *) lua_touserdata(L, 1); clock_t *p1 = (clock_t *) lua_touserdata(L, 1);
clock_t *p2 = (clock_t *) lua_touserdata(L, 2); clock_t *p2 = (clock_t *) lua_touserdata(L, 2);
if (p1 && p2) { if (p1 && p2) {
/* substracting two timestamps result in a timespan in seconds */ // substracting two timestamps result in a timespan in seconds
clock_t a1 = *p1; clock_t a1 = *p1;
clock_t a2 = *p2; clock_t a2 = *p2;
lua_pushnumber(L, ((double) (a1 -a2)) / clocks_per_sec); lua_pushnumber(L, ((double) (a1 -a2)) / clocks_per_sec);
return 1; return 1;
} }
/* makes a timestamp earlier by NUMBER seconds */ // makes a timestamp earlier by NUMBER seconds
clock_t a1 = p1 ? *p1 : luaL_checknumber(L, 1) * clocks_per_sec; clock_t a1 = p1 ? *p1 : luaL_checknumber(L, 1) * clocks_per_sec;
clock_t a2 = p2 ? *p2 : luaL_checknumber(L, 2) * clocks_per_sec; clock_t a2 = p2 ? *p2 : luaL_checknumber(L, 2) * clocks_per_sec;
clock_t *r = (clock_t *) lua_newuserdata(L, sizeof(clock_t)); clock_t *r = (clock_t *) lua_newuserdata(L, sizeof(clock_t));
@ -1431,7 +1343,7 @@ register_lsyncd(lua_State *L)
luaL_register(L, "lsyncd", lsyncdlib); luaL_register(L, "lsyncd", lsyncdlib);
lua_setglobal(L, "lysncd"); lua_setglobal(L, "lysncd");
/* creates the metatable for jiffies userdata */ // creates the metatable for jiffies userdata
luaL_newmetatable(L, "Lsyncd.jiffies"); luaL_newmetatable(L, "Lsyncd.jiffies");
lua_pushstring(L, "__add"); lua_pushstring(L, "__add");
lua_pushcfunction(L, l_jiffies_add); lua_pushcfunction(L, l_jiffies_add);
@ -1456,6 +1368,7 @@ register_lsyncd(lua_State *L)
lua_getglobal(L, "lysncd"); lua_getglobal(L, "lysncd");
#ifdef LSYNCD_WITH_INOTIFY #ifdef LSYNCD_WITH_INOTIFY
// TODO what the hack?
register_inotify(L); register_inotify(L);
lua_settable(L, -3); lua_settable(L, -3);
#endif #endif
@ -1482,11 +1395,11 @@ load_runner_func(lua_State *L,
{ {
printlogf(L, "Call", "%s()", name); printlogf(L, "Call", "%s()", name);
/* pushes the error handler */ // pushes the error handler
lua_pushlightuserdata(L, (void *) &callError); lua_pushlightuserdata(L, (void *) &callError);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
/* pushes the function */ // pushes the function
lua_pushlightuserdata(L, (void *) &runner); lua_pushlightuserdata(L, (void *) &runner);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
lua_pushstring(L, name); lua_pushstring(L, name);
@ -1508,15 +1421,15 @@ daemonize(lua_State *L)
pid_t pid, sid; pid_t pid, sid;
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
printlogf(L, "Error", printlogf(L, "Error",
"Failure in daemonize at fork: %s", strerror(errno)); "Failure in daemonize at fork: %s", strerror(errno));
exit(-1); // ERRNO exit(-1); // ERRNO
} }
if (pid > 0) {
/* return parent to shell */ if (pid > 0) exit(0); // return parent to shell
exit(0);
}
sid = setsid(); sid = setsid();
if (sid < 0) { if (sid < 0) {
printlogf(L, "Error", printlogf(L, "Error",
@ -1524,28 +1437,27 @@ daemonize(lua_State *L)
exit(-1); // ERRNO exit(-1); // ERRNO
} }
/* goto root dir */ // goto root dir
if ((chdir("/")) < 0) { if ((chdir("/")) < 0) {
printlogf(L, "Error", printlogf(L, "Error",
"Failure in daemonize at chdir(\"/\"): %s", strerror(errno)); "Failure in daemonize at chdir(\"/\"): %s", strerror(errno));
exit(-1); // ERRNO exit(-1); // ERRNO
} }
/* does what clibs daemon(0, 0) cannot do, // does what clibs daemon(0, 0) cannot do,
* checks if there were no stdstreams and it might close used fds! */ // checks if there were no stdstreams and it might close used fds!
if (observances_len && observances->fd < 3) { if (observances_len && observances->fd < 3) {
printlogf(L, "Normal", printlogf(L, "Normal",
"daemonize not closing stdin/out/err, since there seem to none."); "daemonize not closing stdin/out/err, since there seem to none.");
return; return;
} }
/* disconnects stdstreams */ // disconnects stdstreams
if (!freopen("/dev/null", "r", stdin) || if (!freopen("/dev/null", "r", stdin) ||
!freopen("/dev/null", "r", stdout) || !freopen("/dev/null", "r", stdout) ||
!freopen("/dev/null", "r", stderr) !freopen("/dev/null", "r", stderr)
) { ) {
printlogf(L, "Error", printlogf(L, "Error", "Failure in daemonize at freopen(/dev/null, std[in|out|err])");
"Failure in daemonize at freopen(/dev/null, std[in|out|err])");
} }
is_daemon = true; is_daemon = true;
@ -1559,11 +1471,11 @@ masterloop(lua_State *L)
{ {
while(true) { while(true) {
bool have_alarm; bool have_alarm;
bool force_alarm; bool force_alarm = false;
clock_t now = times(dummy_tms); clock_t now = times(dummy_tms);
clock_t alarm_time; clock_t alarm_time = 0;
/* queries runner about soonest alarm */ // queries runner about soonest alarm
load_runner_func(L, "getAlarm"); load_runner_func(L, "getAlarm");
if (lua_pcall(L, 0, 1, -2)) { if (lua_pcall(L, 0, 1, -2)) {
exit(-1); // ERRNO exit(-1); // ERRNO
@ -1574,17 +1486,14 @@ masterloop(lua_State *L)
force_alarm = lua_toboolean(L, -1); force_alarm = lua_toboolean(L, -1);
} else { } else {
have_alarm = true; have_alarm = true;
alarm_time = alarm_time = *((clock_t *) luaL_checkudata(L, -1, "Lsyncd.jiffies"));
*((clock_t *) luaL_checkudata(L, -1, "Lsyncd.jiffies"));
} }
lua_pop(L, 2); lua_pop(L, 2);
if (force_alarm || if (force_alarm || (have_alarm && time_before_eq(alarm_time, now))) {
(have_alarm && time_before_eq(alarm_time, now)) // there is a delay that wants to be handled already thus instead
) { // of reading/writing from observances it jumps directly to
/* there is a delay that wants to be handled already thus instead // handling
* of reading/writing from observances it jumps directly to
* handling */
// TODO: Actually it might be smarter to handler observances // TODO: Actually it might be smarter to handler observances
// eitherway. since event queues might overflow. // eitherway. since event queues might overflow.
@ -1634,13 +1543,13 @@ masterloop(lua_State *L)
"Internal fail, no observances, no monitor!"); "Internal fail, no observances, no monitor!");
exit(-1); exit(-1);
} }
/* the great select */ // the great select, this is the very heart beat
pr = pselect( pr = pselect(
observances[observances_len - 1].fd + 1, observances[observances_len - 1].fd + 1,
&rfds, &wfds, NULL, &rfds, &wfds, NULL,
have_alarm ? &tv : NULL, &sigset); have_alarm ? &tv : NULL, &sigset);
if (pr >= 0) { if (pr >= 0) {
/* walks through the observances calling ready/writey */ // walks through the observances calling ready/writey
observance_action = true; observance_action = true;
for(pi = 0; pi < observances_len; pi++) { for(pi = 0; pi < observances_len; pi++) {
struct observance *obs = observances + pi; struct observance *obs = observances + pi;
@ -1673,7 +1582,7 @@ masterloop(lua_State *L)
} }
} }
/* collects 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);
@ -1689,7 +1598,7 @@ masterloop(lua_State *L)
lua_pop(L, 1); lua_pop(L, 1);
} }
/* reacts on signals */ // reacts on HUP signal
if (hup) { if (hup) {
load_runner_func(L, "hup"); load_runner_func(L, "hup");
if (lua_pcall(L, 0, 0, -2)) { if (lua_pcall(L, 0, 0, -2)) {
@ -1699,7 +1608,7 @@ masterloop(lua_State *L)
hup = 0; hup = 0;
} }
/* reacts on signals */ // reacts on TERM signal
if (term == 1) { if (term == 1) {
load_runner_func(L, "term"); load_runner_func(L, "term");
if (lua_pcall(L, 0, 0, -2)) { if (lua_pcall(L, 0, 0, -2)) {
@ -1709,15 +1618,13 @@ masterloop(lua_State *L)
term = 2; term = 2;
} }
/* lets the runner do stuff every cycle, // lets the runner do stuff every cycle,
* like starting new processes, writing the statusfile etc. */ // like starting new processes, writing the statusfile etc.
load_runner_func(L, "cycle"); load_runner_func(L, "cycle");
l_now(L); l_now(L);
if (lua_pcall(L, 1, 1, -3)) { if (lua_pcall(L, 1, 1, -3)) exit(-1); // ERRNO
exit(-1); // ERRNO
}
if (!lua_toboolean(L, -1)) { if (!lua_toboolean(L, -1)) {
/* cycle told core to break mainloop */ // cycle told core to break mainloop
lua_pop(L, 2); lua_pop(L, 2);
return; return;
} }
@ -1737,20 +1644,20 @@ masterloop(lua_State *L)
int int
main1(int argc, char *argv[]) main1(int argc, char *argv[])
{ {
/* the Lua interpreter */ // the Lua interpreter
lua_State* L; lua_State* L;
/* scripts */ // scripts
char * lsyncd_runner_file = NULL; char * lsyncd_runner_file = NULL;
char * lsyncd_config_file = NULL; char * lsyncd_config_file = NULL;
int argp = 1; int argp = 1;
/* load Lua */ // load Lua
L = lua_open(); L = lua_open();
luaL_openlibs(L); luaL_openlibs(L);
{ {
/* checks the lua version */ // checks the lua version
const char *version; const char *version;
int major, minor; int major, minor;
lua_getglobal(L, "_VERSION"); lua_getglobal(L, "_VERSION");
@ -1767,7 +1674,7 @@ main1(int argc, char *argv[])
} }
{ {
/* prepares logging early */ // prepares logging early
int i = 1; int i = 1;
add_logcat("Normal", LOG_NOTICE); add_logcat("Normal", LOG_NOTICE);
add_logcat("Warn", LOG_WARNING); add_logcat("Warn", LOG_WARNING);
@ -1787,7 +1694,7 @@ main1(int argc, char *argv[])
} }
} }
/* registers lsycnd core */ // registers lsycnd core
register_lsyncd(L); register_lsyncd(L);
if (check_logcat("Debug") <= settings.log_level) { if (check_logcat("Debug") <= settings.log_level) {
@ -1795,18 +1702,15 @@ main1(int argc, char *argv[])
printf("kernels clocks_per_sec=%ld\n", clocks_per_sec); printf("kernels clocks_per_sec=%ld\n", clocks_per_sec);
} }
/* checks if the user overrode default runner file */ // checks if the user overrode default runner file
if (argp < argc && !strcmp(argv[argp], "--runner")) { if (argp < argc && !strcmp(argv[argp], "--runner")) {
if (argp + 1 >= argc) { if (argp + 1 >= argc) {
logstring("Error", logstring("Error", "Lsyncd Lua-runner file missing after --runner.");
"Lsyncd Lua-runner file missing after --runner.");
#ifdef LSYNCD_DEFAULT_RUNNER_FILE #ifdef LSYNCD_DEFAULT_RUNNER_FILE
printlogf(L, "Error", printlogf(L, "Error",
"Using '%s' as default location for runner.", "Using '%s' as default location for runner.", LSYNCD_DEFAULT_RUNNER_FILE);
LSYNCD_DEFAULT_RUNNER_FILE);
#else #else
logstring("Error", logstring("Error", "Using a statically included runner as default.");
"Using a statically included runner as default.");
#endif #endif
exit(-1); //ERRNO exit(-1); //ERRNO
} }
@ -1831,8 +1735,7 @@ main1(int argc, char *argv[])
/* loads the runner file */ /* loads the runner file */
if (luaL_loadfile(L, lsyncd_runner_file)) { if (luaL_loadfile(L, lsyncd_runner_file)) {
printlogf(L, "Error", printlogf(L, "Error",
"error loading '%s': %s", "error loading '%s': %s", lsyncd_runner_file, lua_tostring(L, -1));
lsyncd_runner_file, lua_tostring(L, -1));
exit(-1); // ERRNO exit(-1); // ERRNO
} }
} else { } else {
@ -1912,10 +1815,10 @@ main1(int argc, char *argv[])
} }
{ {
/* starts the option parser in lua script */ // starts the option parser in lua script
int idx = 1; int idx = 1;
const char *s; const char *s;
/* creates a table with all remaining argv option arguments */ // creates a table with all remaining argv option arguments
load_runner_func(L, "configure"); load_runner_func(L, "configure");
lua_newtable(L); lua_newtable(L);
while(argp < argc) { while(argp < argc) {
@ -1923,7 +1826,7 @@ main1(int argc, char *argv[])
lua_pushstring(L, argv[argp++]); lua_pushstring(L, argv[argp++]);
lua_settable(L, -3); lua_settable(L, -3);
} }
/* creates a table with the cores event monitor interfaces */ // creates a table with the cores event monitor interfaces
idx = 0; idx = 0;
lua_newtable(L); lua_newtable(L);
while (monitors[idx]) { while (monitors[idx]) {
@ -1942,7 +1845,7 @@ main1(int argc, char *argv[])
} }
if (lsyncd_config_file) { if (lsyncd_config_file) {
/* checks existence of the config file */ // checks existence of the config file
struct stat st; struct stat st;
if (stat(lsyncd_config_file, &st)) { if (stat(lsyncd_config_file, &st)) {
printlogf(L, "Error", printlogf(L, "Error",
@ -1951,7 +1854,7 @@ main1(int argc, char *argv[])
exit(-1); // ERRNO exit(-1); // ERRNO
} }
/* loads and executes the config file */ // loads and executes the config file
if (luaL_loadfile(L, lsyncd_config_file)) { if (luaL_loadfile(L, lsyncd_config_file)) {
printlogf(L, "Error", printlogf(L, "Error",
"error loading %s: %s", "error loading %s: %s",
@ -2000,9 +1903,9 @@ main1(int argc, char *argv[])
masterloop(L); masterloop(L);
/* cleanup */ // cleanup
{ {
/* tidies all observances */ // tidies up all observances
int i; int i;
for(i = 0; i < observances_len; i++) { for(i = 0; i < observances_len; i++) {
struct observance *obs = observances + i; struct observance *obs = observances + i;
@ -2013,7 +1916,7 @@ main1(int argc, char *argv[])
} }
{ {
/* frees logging categories */ // frees logging categories
int ci; int ci;
struct logcat *lc; struct logcat *lc;
for(ci = 'A'; ci <= 'Z'; ci++) { for(ci = 'A'; ci <= 'Z'; ci++) {
@ -2032,7 +1935,7 @@ main1(int argc, char *argv[])
lsyncd_config_file = NULL; lsyncd_config_file = NULL;
} }
/* resets settings to default. */ // resets settings to default.
if (settings.log_file) { if (settings.log_file) {
free(settings.log_file); free(settings.log_file);
settings.log_file = NULL; settings.log_file = NULL;
@ -2055,7 +1958,7 @@ main1(int argc, char *argv[])
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
/* kernel parameters */ // gets a kernel parameter
clocks_per_sec = sysconf(_SC_CLK_TCK); clocks_per_sec = sysconf(_SC_CLK_TCK);
while(!term) { while(!term) {