mirror of
https://github.com/octoleo/lsyncd.git
synced 2025-01-07 17:14:03 +00:00
added memory tracking
This commit is contained in:
parent
8aa0cba99e
commit
4efa89d951
307
lsyncd.c
307
lsyncd.c
@ -39,6 +39,11 @@
|
|||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define for debug memchecking.
|
||||||
|
*/
|
||||||
|
//#define MEMCHECK
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of inotifies to read max. at once from the kernel.
|
* Number of inotifies to read max. at once from the kernel.
|
||||||
*/
|
*/
|
||||||
@ -384,31 +389,45 @@ struct delay_vector {
|
|||||||
char * exclude_dirs[MAX_EXCLUDES] = {NULL, };
|
char * exclude_dirs[MAX_EXCLUDES] = {NULL, };
|
||||||
int exclude_dir_n = 0;
|
int exclude_dir_n = 0;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*
|
||||||
|
* MEMCHECK
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* (Re)sets global options to default values.
|
* This routines keep track which memory allocs
|
||||||
*
|
* have not been freed. Debugging purposes.
|
||||||
* TODO memfree's
|
|
||||||
*/
|
*/
|
||||||
void
|
#ifdef MEMCHECK
|
||||||
reset_options(struct global_options *opts) {
|
#include <search.h>
|
||||||
opts->log.loglevel = NORMAL;
|
int memc = 0;
|
||||||
opts->log.flag_nodaemon = 0;
|
void * mroot = NULL;
|
||||||
opts->log.logfile = NULL;
|
struct mentry {
|
||||||
|
const void *data;
|
||||||
opts->flag_dryrun = 0;
|
const char *desc;
|
||||||
opts->flag_stubborn = 0;
|
|
||||||
opts->flag_nostartup = 0;
|
|
||||||
opts->pidfile = NULL;
|
|
||||||
#ifdef XML_CONFIG
|
|
||||||
opts->conf_filename = DEFAULT_CONF_FILENAME;
|
|
||||||
#endif
|
|
||||||
opts->default_binary = DEFAULT_BINARY;
|
|
||||||
opts->default_exclude_file = NULL;
|
|
||||||
opts->default_callopts = standard_callopts;
|
|
||||||
opts->delay = 5;
|
|
||||||
opts->dir_confs = NULL;
|
|
||||||
opts->dir_conf_n = 0;
|
|
||||||
};
|
};
|
||||||
|
int mcompare(const void *pa, const void *pb) {
|
||||||
|
const struct mentry *ma = (const struct mentry *) pa;
|
||||||
|
const struct mentry *mb = (const struct mentry *) pb;
|
||||||
|
if (ma->data < mb->data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ma->data > mb->data) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void maction(const void *nodep, const VISIT which, const int depth) {
|
||||||
|
if (which == leaf || which == postorder) {
|
||||||
|
struct mentry * r = *((struct mentry **) nodep);
|
||||||
|
memc--;
|
||||||
|
fprintf(stderr, "<*> unfreed data %p:%s\n", r->data, r->desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MEMCHECK
|
||||||
|
#define s_free(x) free(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* Small generic helper routines.
|
* Small generic helper routines.
|
||||||
@ -562,7 +581,7 @@ printlogf(const struct log *log, int level, const char *fmt, ...)
|
|||||||
* available.
|
* available.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
s_malloc(const struct log *log, size_t size)
|
s_malloc(const struct log *log, size_t size, const char *desc)
|
||||||
{
|
{
|
||||||
void *r = malloc(size);
|
void *r = malloc(size);
|
||||||
|
|
||||||
@ -571,6 +590,20 @@ s_malloc(const struct log *log, size_t size)
|
|||||||
terminate(log, LSYNCD_OUTOFMEMORY);
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
{
|
||||||
|
struct mentry * mentry;
|
||||||
|
memc++;
|
||||||
|
mentry = malloc(sizeof(struct mentry));
|
||||||
|
mentry->data = r;
|
||||||
|
mentry->desc = desc;
|
||||||
|
if (!mentry) {
|
||||||
|
printlogf(log, ERROR, "Out of memory in memcheck!");
|
||||||
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
tsearch(mentry, &mroot, mcompare);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +611,7 @@ s_malloc(const struct log *log, size_t size)
|
|||||||
* "secured" calloc.
|
* "secured" calloc.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
s_calloc(const struct log *log, size_t nmemb, size_t size)
|
s_calloc(const struct log *log, size_t nmemb, size_t size, const char *desc)
|
||||||
{
|
{
|
||||||
void *r = calloc(nmemb, size);
|
void *r = calloc(nmemb, size);
|
||||||
|
|
||||||
@ -587,6 +620,21 @@ s_calloc(const struct log *log, size_t nmemb, size_t size)
|
|||||||
terminate(log, LSYNCD_OUTOFMEMORY);
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
{
|
||||||
|
struct mentry * mentry;
|
||||||
|
memc++;
|
||||||
|
mentry = malloc(sizeof(struct mentry));
|
||||||
|
mentry->data = r;
|
||||||
|
mentry->desc = desc;
|
||||||
|
if (!mentry) {
|
||||||
|
printlogf(log, ERROR, "Out of memory in memcheck!");
|
||||||
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
tsearch(mentry, &mroot, mcompare);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,6 +651,33 @@ s_realloc(const struct log *log, void *ptr, size_t size)
|
|||||||
terminate(log, LSYNCD_OUTOFMEMORY);
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
{
|
||||||
|
struct mentry * mentry = malloc(sizeof(struct mentry));
|
||||||
|
struct mentry **ret;
|
||||||
|
if (!mentry) {
|
||||||
|
printlogf(log, ERROR, "Out of memory in memcheck!");
|
||||||
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
if (ptr == NULL) {
|
||||||
|
fprintf(stderr, "<*> Reallocating NULL!?\n");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
// first delete the old entry
|
||||||
|
mentry->data = ptr;
|
||||||
|
ret = tfind(mentry, &mroot, mcompare);
|
||||||
|
if (ret == NULL) {
|
||||||
|
fprintf(stderr, "<*> Memcheck error, reallocating unknown pointer %p!\n", ptr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
mentry->desc = (*ret)->desc;
|
||||||
|
tdelete(mentry, &mroot, mcompare);
|
||||||
|
// and reenter the reallocated entry
|
||||||
|
mentry->data = r;
|
||||||
|
tsearch(mentry, &mroot, mcompare);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +685,7 @@ s_realloc(const struct log *log, void *ptr, size_t size)
|
|||||||
* "secured" strdup.
|
* "secured" strdup.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
s_strdup(const struct log *log, const char *src)
|
s_strdup(const struct log *log, const char *src, const char *desc)
|
||||||
{
|
{
|
||||||
char *s = strdup(src);
|
char *s = strdup(src);
|
||||||
|
|
||||||
@ -619,9 +694,44 @@ s_strdup(const struct log *log, const char *src)
|
|||||||
terminate(log, LSYNCD_OUTOFMEMORY);
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
{
|
||||||
|
struct mentry * mentry;
|
||||||
|
memc++;
|
||||||
|
mentry = malloc(sizeof(struct mentry));
|
||||||
|
mentry->data = s;
|
||||||
|
mentry->desc = desc;
|
||||||
|
if (!mentry) {
|
||||||
|
printlogf(log, ERROR, "Out of memory in memcheck!");
|
||||||
|
terminate(log, LSYNCD_OUTOFMEMORY);
|
||||||
|
}
|
||||||
|
tsearch(mentry, &mroot, mcompare);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
void
|
||||||
|
s_free(void *p) {
|
||||||
|
struct mentry mentry = {0,};
|
||||||
|
struct mentry **r;
|
||||||
|
memc--;
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "<*> Memcheck freeing NULL!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mentry.data = p;
|
||||||
|
r = tdelete(&mentry, &mroot, mcompare);
|
||||||
|
if (r == NULL) {
|
||||||
|
fprintf(stderr, "<*> Memcheck error, freeing unknown pointer %p!\n", p);
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the canonicalized path of a directory with a final '/'.
|
* Returns the canonicalized path of a directory with a final '/'.
|
||||||
* Makes sure it is a directory.
|
* Makes sure it is a directory.
|
||||||
@ -629,7 +739,7 @@ s_strdup(const struct log *log, const char *src)
|
|||||||
char *
|
char *
|
||||||
realdir(const struct log *log, const char *dir)
|
realdir(const struct log *log, const char *dir)
|
||||||
{
|
{
|
||||||
char* cs = s_malloc(log, PATH_MAX+1);
|
char* cs = s_malloc(log, PATH_MAX+1, "realdir/cs");
|
||||||
cs = realpath(dir, cs);
|
cs = realpath(dir, cs);
|
||||||
|
|
||||||
if (cs == NULL) {
|
if (cs == NULL) {
|
||||||
@ -644,7 +754,7 @@ realdir(const struct log *log, const char *dir)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
stat(cs, &st);
|
stat(cs, &st);
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
free(cs);
|
s_free(cs);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,6 +762,58 @@ realdir(const struct log *log, const char *dir)
|
|||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*
|
||||||
|
* Options.
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Re)sets global options to default values.
|
||||||
|
*
|
||||||
|
* TODO memfree's
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
reset_options(struct global_options *opts) {
|
||||||
|
opts->log.loglevel = NORMAL;
|
||||||
|
opts->log.flag_nodaemon = 0;
|
||||||
|
|
||||||
|
if (opts->log.logfile) {
|
||||||
|
s_free(opts->log.logfile);
|
||||||
|
opts->log.logfile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts->flag_dryrun = 0;
|
||||||
|
opts->flag_stubborn = 0;
|
||||||
|
opts->flag_nostartup = 0;
|
||||||
|
|
||||||
|
if (opts->pidfile) {
|
||||||
|
s_free(opts->pidfile);
|
||||||
|
opts->pidfile = NULL;
|
||||||
|
}
|
||||||
|
#ifdef XML_CONFIG
|
||||||
|
if (opts->conf_filename && opts->conf_filename != DEFAULT_CONF_FILENAME) {
|
||||||
|
s_free(opts->conf_filename);
|
||||||
|
}
|
||||||
|
opts->conf_filename = DEFAULT_CONF_FILENAME;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (opts->default_binary && opts->default_binary != DEFAULT_BINARY) {
|
||||||
|
s_free(opts->default_binary);
|
||||||
|
}
|
||||||
|
opts->default_binary = DEFAULT_BINARY;
|
||||||
|
|
||||||
|
if (opts->default_exclude_file) {
|
||||||
|
s_free(opts->default_exclude_file);
|
||||||
|
opts->default_exclude_file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO free callopts
|
||||||
|
opts->default_callopts = standard_callopts;
|
||||||
|
opts->delay = 5;
|
||||||
|
opts->dir_confs = NULL;
|
||||||
|
opts->dir_conf_n = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* Per directory configuration handling.
|
* Per directory configuration handling.
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
@ -675,14 +837,14 @@ new_dir_conf(struct global_options *opts) {
|
|||||||
opts->dir_confs = s_realloc(log, opts->dir_confs, opts->dir_conf_n * sizeof(struct dir_conf));
|
opts->dir_confs = s_realloc(log, opts->dir_confs, opts->dir_conf_n * sizeof(struct dir_conf));
|
||||||
memset(opts->dir_confs + opts->dir_conf_n - 1, 0, sizeof(struct dir_conf));
|
memset(opts->dir_confs + opts->dir_conf_n - 1, 0, sizeof(struct dir_conf));
|
||||||
// creates targets NULL terminator (no targets yet)
|
// creates targets NULL terminator (no targets yet)
|
||||||
opts->dir_confs[opts->dir_conf_n - 1].targets = s_calloc(log, 1, sizeof(char *));
|
opts->dir_confs[opts->dir_conf_n - 1].targets = s_calloc(log, 1, sizeof(char *), "dir_conf");
|
||||||
return opts->dir_confs + opts->dir_conf_n - 1;
|
return opts->dir_confs + opts->dir_conf_n - 1;
|
||||||
} else {
|
} else {
|
||||||
// create the memory.
|
// create the memory.
|
||||||
opts->dir_conf_n = 1;
|
opts->dir_conf_n = 1;
|
||||||
opts->dir_confs = s_calloc(log, opts->dir_conf_n, sizeof(struct dir_conf));
|
opts->dir_confs = s_calloc(log, opts->dir_conf_n, sizeof(struct dir_conf), "dir_conf");
|
||||||
// creates targets NULL terminator (no targets yet)
|
// creates targets NULL terminator (no targets yet)
|
||||||
opts->dir_confs[0].targets = s_calloc(log, 1, sizeof(char *));
|
opts->dir_confs[0].targets = s_calloc(log, 1, sizeof(char *), "dir_conf-target");
|
||||||
return opts->dir_confs;
|
return opts->dir_confs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -706,7 +868,7 @@ dir_conf_add_target(const struct log *log, struct dir_conf *dir_conf, char *targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
dir_conf->targets = s_realloc(log, dir_conf->targets, (target_n + 2) * sizeof(char *));
|
dir_conf->targets = s_realloc(log, dir_conf->targets, (target_n + 2) * sizeof(char *));
|
||||||
dir_conf->targets[target_n] = s_strdup(log, target);
|
dir_conf->targets[target_n] = s_strdup(log, target, "dupped target");
|
||||||
dir_conf->targets[target_n + 1] = NULL;
|
dir_conf->targets[target_n + 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,7 +938,7 @@ remove_first_delay(struct delay_vector *delays)
|
|||||||
char *
|
char *
|
||||||
parse_option_text(const struct log *log, char *text, bool recursive)
|
parse_option_text(const struct log *log, char *text, bool recursive)
|
||||||
{
|
{
|
||||||
char * str = s_strdup(log, text);
|
char * str = s_strdup(log, text, "dupped option text");
|
||||||
char * chr; // search result for %.
|
char * chr; // search result for %.
|
||||||
|
|
||||||
// replace all '%' specifiers with there special meanings
|
// replace all '%' specifiers with there special meanings
|
||||||
@ -818,7 +980,7 @@ get_arg_str(const struct log *log, char **argv, int argc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// alloc
|
// alloc
|
||||||
str = s_malloc(log, len + 2 * argc + 1);
|
str = s_malloc(log, len + 2 * argc + 1, "argument string");
|
||||||
|
|
||||||
str[0] = 0;
|
str[0] = 0;
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
@ -861,7 +1023,7 @@ action(const struct global_options *opts,
|
|||||||
|
|
||||||
// makes a copy of all call parameters
|
// makes a copy of all call parameters
|
||||||
// step 1 binary itself
|
// step 1 binary itself
|
||||||
argv[argc++] = s_strdup(log, dir_conf->binary ? dir_conf->binary : opts->default_binary);
|
argv[argc++] = s_strdup(log, dir_conf->binary ? dir_conf->binary : opts->default_binary, "argv");
|
||||||
// now all other parameters
|
// now all other parameters
|
||||||
for(; optp->kind != CO_EOL; optp++) {
|
for(; optp->kind != CO_EOL; optp++) {
|
||||||
switch (optp->kind) {
|
switch (optp->kind) {
|
||||||
@ -874,14 +1036,14 @@ action(const struct global_options *opts,
|
|||||||
if (dir_conf->exclude_file == NULL && opts->default_exclude_file == NULL) {
|
if (dir_conf->exclude_file == NULL && opts->default_exclude_file == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
argv[argc++] = s_strdup(log, "--exclude-from");
|
argv[argc++] = s_strdup(log, "--exclude-from", "argv exclude-from");
|
||||||
argv[argc++] = s_strdup(log, dir_conf->exclude_file ? dir_conf->exclude_file : opts->default_exclude_file);
|
argv[argc++] = s_strdup(log, dir_conf->exclude_file ? dir_conf->exclude_file : opts->default_exclude_file, "argv exclude-file");
|
||||||
continue;
|
continue;
|
||||||
case CO_SOURCE :
|
case CO_SOURCE :
|
||||||
argv[argc++] = s_strdup(log, src);
|
argv[argc++] = s_strdup(log, src, "argv source");
|
||||||
continue;
|
continue;
|
||||||
case CO_DEST :
|
case CO_DEST :
|
||||||
argv[argc++] = s_strdup(log, dest);
|
argv[argc++] = s_strdup(log, dest, "argv dest");
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
printlogf(log, ERROR, "Internal error: unknown kind of option.");
|
printlogf(log, ERROR, "Internal error: unknown kind of option.");
|
||||||
@ -901,10 +1063,10 @@ action(const struct global_options *opts,
|
|||||||
char * binary = dir_conf->binary ? dir_conf->binary : opts->default_binary;
|
char * binary = dir_conf->binary ? dir_conf->binary : opts->default_binary;
|
||||||
char * argall = get_arg_str(log, argv, argc);
|
char * argall = get_arg_str(log, argv, argc);
|
||||||
printlogf(log, NORMAL, "dry run: would call %s(%s)", binary, argall);
|
printlogf(log, NORMAL, "dry run: would call %s(%s)", binary, argall);
|
||||||
free(argall);
|
s_free(argall);
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
if (argv[i]) {
|
if (argv[i]) {
|
||||||
free(argv[i]);
|
s_free(argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -932,7 +1094,7 @@ action(const struct global_options *opts,
|
|||||||
// free the memory from the arguments.
|
// free the memory from the arguments.
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
if (argv[i]) {
|
if (argv[i]) {
|
||||||
free(argv[i]);
|
s_free(argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,13 +1172,13 @@ add_watch(const struct log *log,
|
|||||||
watches->size * sizeof(struct watch *));
|
watches->size * sizeof(struct watch *));
|
||||||
}
|
}
|
||||||
// allocate memory for a new watch
|
// allocate memory for a new watch
|
||||||
watches->data[watches->len++] = s_calloc(log, 1, sizeof(struct watch));
|
watches->data[watches->len++] = s_calloc(log, 1, sizeof(struct watch), "watch");
|
||||||
}
|
}
|
||||||
|
|
||||||
w = watches->data[wi];
|
w = watches->data[wi];
|
||||||
w->wd = wd;
|
w->wd = wd;
|
||||||
w->parent = parent;
|
w->parent = parent;
|
||||||
w->dirname = s_strdup(log, dirname);
|
w->dirname = s_strdup(log, dirname, "dirname");
|
||||||
w->dir_conf = dir_conf;
|
w->dir_conf = dir_conf;
|
||||||
w->alarm = 0; // not needed, just to be save
|
w->alarm = 0; // not needed, just to be save
|
||||||
w->delayed = false;
|
w->delayed = false;
|
||||||
@ -1346,7 +1508,7 @@ remove_dirwatch(const struct global_options *opts,
|
|||||||
// mark this entry invalid
|
// mark this entry invalid
|
||||||
w->wd = -1;
|
w->wd = -1;
|
||||||
|
|
||||||
free(w->dirname);
|
s_free(w->dirname);
|
||||||
w->dirname = NULL;
|
w->dirname = NULL;
|
||||||
|
|
||||||
// remove a possible delay
|
// remove a possible delay
|
||||||
@ -1451,8 +1613,6 @@ handle_event(const struct global_options *opts,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO AXK ORDER?
|
|
||||||
|
|
||||||
// put the watch on the delay or act if delay == 0
|
// put the watch on the delay or act if delay == 0
|
||||||
if ((IN_ATTRIB | IN_CREATE | IN_CLOSE_WRITE | IN_DELETE |
|
if ((IN_ATTRIB | IN_CREATE | IN_CLOSE_WRITE | IN_DELETE |
|
||||||
IN_MOVED_TO | IN_MOVED_FROM) & event->mask
|
IN_MOVED_TO | IN_MOVED_FROM) & event->mask
|
||||||
@ -1711,7 +1871,7 @@ parse_callopts(struct global_options *opts, xmlNodePtr node) {
|
|||||||
opt_n++;
|
opt_n++;
|
||||||
}
|
}
|
||||||
opt_n++;
|
opt_n++;
|
||||||
asw = (struct call_option *) s_calloc(NULL, opt_n, sizeof(struct call_option));
|
asw = (struct call_option *) s_calloc(NULL, opt_n, sizeof(struct call_option), "call options");
|
||||||
|
|
||||||
// fill in the answer
|
// fill in the answer
|
||||||
opt_n = 0;
|
opt_n = 0;
|
||||||
@ -1727,7 +1887,7 @@ parse_callopts(struct global_options *opts, xmlNodePtr node) {
|
|||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
asw[opt_n].kind = CO_TEXT;
|
asw[opt_n].kind = CO_TEXT;
|
||||||
asw[opt_n].text = s_strdup(NULL, (char *) xc);
|
asw[opt_n].text = s_strdup(NULL, (char *) xc, "asw text");
|
||||||
} else if (!xmlStrcmp(cnode->name, BAD_CAST "exclude-file")) {
|
} else if (!xmlStrcmp(cnode->name, BAD_CAST "exclude-file")) {
|
||||||
asw[opt_n].kind = CO_EXCLUDE;
|
asw[opt_n].kind = CO_EXCLUDE;
|
||||||
} else if (!xmlStrcmp(cnode->name, BAD_CAST "source")) {
|
} else if (!xmlStrcmp(cnode->name, BAD_CAST "source")) {
|
||||||
@ -1767,7 +1927,7 @@ parse_directory(struct global_options *opts, xmlNodePtr node) {
|
|||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
// TODO: use realdir() on xc
|
// TODO: use realdir() on xc
|
||||||
dc->source = s_strdup(NULL, (char *) xc);
|
dc->source = s_strdup(NULL, (char *) xc, "xml source");
|
||||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "target")) {
|
} else if (!xmlStrcmp(dnode->name, BAD_CAST "target")) {
|
||||||
xc = xmlGetProp(dnode, BAD_CAST "path");
|
xc = xmlGetProp(dnode, BAD_CAST "path");
|
||||||
if (xc == NULL) {
|
if (xc == NULL) {
|
||||||
@ -1781,14 +1941,14 @@ parse_directory(struct global_options *opts, xmlNodePtr node) {
|
|||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <binary>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <binary>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
dc->binary = s_strdup(NULL, (char *) xc);
|
dc->binary = s_strdup(NULL, (char *) xc, "xml binary");
|
||||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "exclude-from")) {
|
} else if (!xmlStrcmp(dnode->name, BAD_CAST "exclude-from")) {
|
||||||
xc = xmlGetProp(dnode, BAD_CAST "filename");
|
xc = xmlGetProp(dnode, BAD_CAST "filename");
|
||||||
if (xc == NULL) {
|
if (xc == NULL) {
|
||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <exclude-from>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <exclude-from>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
dc->exclude_file = s_strdup(NULL, (char *) xc);
|
dc->exclude_file = s_strdup(NULL, (char *) xc, "xml exclude");
|
||||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "callopts")) {
|
} else if (!xmlStrcmp(dnode->name, BAD_CAST "callopts")) {
|
||||||
if (dc->callopts) {
|
if (dc->callopts) {
|
||||||
printlogf(NULL, ERROR, "error in config file: there is more than one <callopts> in a <directory>\n");
|
printlogf(NULL, ERROR, "error in config file: there is more than one <callopts> in a <directory>\n");
|
||||||
@ -1850,28 +2010,28 @@ parse_settings(struct global_options *opts, xmlNodePtr node) {
|
|||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <exclude-from/>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <exclude-from/>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
opts->default_exclude_file = s_strdup(NULL, (char *) xc);
|
opts->default_exclude_file = s_strdup(NULL, (char *) xc, "xml default-exclude-file");
|
||||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "logfile")) {
|
} else if (!xmlStrcmp(snode->name, BAD_CAST "logfile")) {
|
||||||
xc = xmlGetProp(snode, BAD_CAST "filename");
|
xc = xmlGetProp(snode, BAD_CAST "filename");
|
||||||
if (xc == NULL) {
|
if (xc == NULL) {
|
||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <logfile/>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <logfile/>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
opts->log.logfile = s_strdup(NULL, (char *) xc);
|
opts->log.logfile = s_strdup(NULL, (char *) xc, "xml logfile");
|
||||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "binary")) {
|
} else if (!xmlStrcmp(snode->name, BAD_CAST "binary")) {
|
||||||
xc = xmlGetProp(snode, BAD_CAST "filename");
|
xc = xmlGetProp(snode, BAD_CAST "filename");
|
||||||
if (xc == NULL) {
|
if (xc == NULL) {
|
||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <binary/>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <binary/>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
opts->default_binary = s_strdup(NULL, (char *) xc);
|
opts->default_binary = s_strdup(NULL, (char *) xc, "xml default-binary");
|
||||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "pidfile")) {
|
} else if (!xmlStrcmp(snode->name, BAD_CAST "pidfile")) {
|
||||||
xc = xmlGetProp(snode, BAD_CAST "filename");
|
xc = xmlGetProp(snode, BAD_CAST "filename");
|
||||||
if (xc == NULL) {
|
if (xc == NULL) {
|
||||||
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <pidfile/>\n");
|
printlogf(NULL, ERROR, "error in config file: attribute filename missing from <pidfile/>\n");
|
||||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||||
}
|
}
|
||||||
opts->pidfile = s_strdup(NULL, (char *) xc);
|
opts->pidfile = s_strdup(NULL, (char *) xc, "xml pidfile");
|
||||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "callopts")) {
|
} else if (!xmlStrcmp(snode->name, BAD_CAST "callopts")) {
|
||||||
opts->default_callopts = parse_callopts(opts, snode);
|
opts->default_callopts = parse_callopts(opts, snode);
|
||||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "scarce")) {
|
} else if (!xmlStrcmp(snode->name, BAD_CAST "scarce")) {
|
||||||
@ -2018,7 +2178,7 @@ parse_options(struct global_options *opts, int argc, char **argv)
|
|||||||
if (c == 0) { // longoption
|
if (c == 0) { // longoption
|
||||||
if (!strcmp("conf", long_options[oi].name)) {
|
if (!strcmp("conf", long_options[oi].name)) {
|
||||||
read_conf = true;
|
read_conf = true;
|
||||||
opts->conf_filename = s_strdup(NULL, optarg);
|
opts->conf_filename = s_strdup(NULL, optarg, "opt conf-filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("help", long_options[oi].name)) {
|
if (!strcmp("help", long_options[oi].name)) {
|
||||||
@ -2063,7 +2223,7 @@ parse_options(struct global_options *opts, int argc, char **argv)
|
|||||||
|
|
||||||
if (c == 0) { // longoption
|
if (c == 0) { // longoption
|
||||||
if (!strcmp("binary", long_options[oi].name)) {
|
if (!strcmp("binary", long_options[oi].name)) {
|
||||||
opts->default_binary = s_strdup(NULL, optarg);
|
opts->default_binary = s_strdup(NULL, optarg, "opt default-binary");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("delay", long_options[oi].name)) {
|
if (!strcmp("delay", long_options[oi].name)) {
|
||||||
@ -2080,7 +2240,7 @@ parse_options(struct global_options *opts, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("exclude-from", long_options[oi].name)) {
|
if (!strcmp("exclude-from", long_options[oi].name)) {
|
||||||
opts->default_exclude_file = s_strdup(NULL, optarg);
|
opts->default_exclude_file = s_strdup(NULL, optarg, "opt default-exclude-file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("help", long_options[oi].name)) {
|
if (!strcmp("help", long_options[oi].name)) {
|
||||||
@ -2088,11 +2248,11 @@ parse_options(struct global_options *opts, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("logfile", long_options[oi].name)) {
|
if (!strcmp("logfile", long_options[oi].name)) {
|
||||||
opts->log.logfile = s_strdup(NULL, optarg);
|
opts->log.logfile = s_strdup(NULL, optarg, "opt logfile");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("pidfile", long_options[oi].name)) {
|
if (!strcmp("pidfile", long_options[oi].name)) {
|
||||||
opts->pidfile = s_strdup(NULL, optarg);
|
opts->pidfile = s_strdup(NULL, optarg, "opt pidfile");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("version", long_options[oi].name)) {
|
if (!strcmp("version", long_options[oi].name)) {
|
||||||
@ -2208,7 +2368,7 @@ parse_exclude_file(struct log *log, char *filename) {
|
|||||||
|
|
||||||
printlogf(log, NORMAL, "Excluding directories of the name '%s'", line);
|
printlogf(log, NORMAL, "Excluding directories of the name '%s'", line);
|
||||||
|
|
||||||
exclude_dirs[exclude_dir_n] = s_malloc(log, strlen(line) + 1);
|
exclude_dirs[exclude_dir_n] = s_malloc(log, strlen(line) + 1, "exclude_dir");
|
||||||
strcpy(exclude_dirs[exclude_dir_n], line);
|
strcpy(exclude_dirs[exclude_dir_n], line);
|
||||||
exclude_dir_n++;
|
exclude_dir_n++;
|
||||||
}
|
}
|
||||||
@ -2278,10 +2438,10 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
watches.size = VECT_INIT_SIZE;
|
watches.size = VECT_INIT_SIZE;
|
||||||
watches.data = s_calloc(log, watches.size, sizeof(struct watch *));
|
watches.data = s_calloc(log, watches.size, sizeof(struct watch *), "watches vector");
|
||||||
|
|
||||||
delays.size = VECT_INIT_SIZE;
|
delays.size = VECT_INIT_SIZE;
|
||||||
delays.data = s_calloc(log, delays.size, sizeof(struct watch *));
|
delays.data = s_calloc(log, delays.size, sizeof(struct watch *), "delays vector");
|
||||||
|
|
||||||
{
|
{
|
||||||
// add all watches
|
// add all watches
|
||||||
@ -2334,5 +2494,26 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
master_loop(&opts, &watches, &delays, inotify_fd);
|
master_loop(&opts, &watches, &delays, inotify_fd);
|
||||||
|
|
||||||
|
{
|
||||||
|
// memory clean up
|
||||||
|
int i;
|
||||||
|
reset_options(&opts);
|
||||||
|
for(i = 0; i < watches.len; i++) {
|
||||||
|
if (watches.data[i]->dirname) {
|
||||||
|
s_free(watches.data[i]->dirname);
|
||||||
|
}
|
||||||
|
s_free(watches.data[i]);
|
||||||
|
}
|
||||||
|
s_free(watches.data);
|
||||||
|
s_free(delays.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MEMCHECK
|
||||||
|
fprintf(stderr, "Memcheck count: %d\n", memc);
|
||||||
|
twalk(mroot, maction);
|
||||||
|
fprintf(stderr, "Memcheck count: %d\n", memc);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ for A in 1 2 3 4 5 6 7 8 9 10; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo -e "$CON* waiting for lsyncd to do the job.$COFF"
|
echo -e "$CON* waiting for lsyncd to do the job.$COFF"
|
||||||
sleep 20s
|
sleep 10s
|
||||||
|
|
||||||
echo -e "$CON* killing lsyncd$COFF"
|
echo -e "$CON* killing lsyncd$COFF"
|
||||||
LSYNCPID=$(cat "${PIDFILE}")
|
LSYNCPID=$(cat "${PIDFILE}")
|
||||||
|
Loading…
Reference in New Issue
Block a user