Done some TODOs

This commit is contained in:
Axel Kittenberger 2010-08-04 11:22:32 +00:00
parent 6f32b6a2f5
commit 00d8894e97

181
lsyncd.c
View File

@ -836,19 +836,18 @@ get_arg_str(const struct log *log, char **argv, int argc) {
* Calls the specified action (most likely rsync) to sync from src to dest. * Calls the specified action (most likely rsync) to sync from src to dest.
* Returns after the forked process has finished. * Returns after the forked process has finished.
* *
* @param dir_conf The config the is applicatable for this dir. * @param dir_conf the config applicatable for this dir.
* @param src Source string. * @param src source string.
* @param dest Destination string, * @param dest destination string,
* @param recursive If true -r will be handled on, -d (single directory) otherwise * @param recursive if true -r will be handled on, -d (single directory) otherwise
* @return true if successful, false if not.
* *
* TODO change dir_conf and src pointer simply to index offset. * @return true if successful, false if not.
*/ */
bool bool
action(const struct global_options *opts, action(const struct global_options *opts,
struct dir_conf * dir_conf, struct dir_conf *dir_conf,
char const * src, const char *src,
const char * dest, const char *dest,
bool recursive) bool recursive)
{ {
pid_t pid; pid_t pid;
@ -887,12 +886,13 @@ action(const struct global_options *opts,
argv[argc++] = s_strdup(log, dest); argv[argc++] = s_strdup(log, dest);
continue; continue;
default: default:
assert(false); printlogf(log, ERROR, "Internal error: unknown kind of option.");
terminate(log, LSYNCD_INTERNALFAIL);
} }
if (argc >= MAX_ARGS) { if (argc >= MAX_ARGS) {
/* check for error condition */ // check for error condition
printlogf(log, ERROR, printlogf(log, ERROR,
"Internal error: too many (>%i) options passed", argc); "Error: too many (>%i) options passed", argc);
return false; return false;
} }
} }
@ -978,8 +978,9 @@ add_watch(const struct log *log,
struct watch *parent, struct watch *parent,
struct dir_conf *dir_conf) struct dir_conf *dir_conf)
{ {
int wd; // kernels inotify descriptor int wd; // kernels inotify descriptor
int newdw; // position to insert this watch into the watch vector int wi; // index to insert this watch into the watch vector
struct watch *w; // the new watch
wd = inotify_add_watch(inotify_fd, pathname, wd = inotify_add_watch(inotify_fd, pathname,
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE | IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
@ -996,14 +997,14 @@ add_watch(const struct log *log,
// //
// lsyncd currently does not free unused slots, but marks // lsyncd currently does not free unused slots, but marks
// them as unused with wd < 0. // them as unused with wd < 0.
for (newdw = 0; newdw < watches->len; newdw++) { for (wi = 0; wi < watches->len; wi++) {
if (watches->data[newdw]->wd < 0) { if (watches->data[wi]->wd < 0) {
break; break;
} }
} }
// there is no unused entry // there is no unused entry
if (newdw == watches->len) { if (wi == watches->len) {
// extend the vector if necessary // extend the vector if necessary
if (watches->len + 1 >= watches->size) { if (watches->len + 1 >= watches->size) {
watches->size *= 2; watches->size *= 2;
@ -1014,14 +1015,14 @@ add_watch(const struct log *log,
watches->data[watches->len++] = s_calloc(log, 1, sizeof(struct watch)); watches->data[watches->len++] = s_calloc(log, 1, sizeof(struct watch));
} }
// TODO simplify using pointer w = watches->data[wi];
watches->data[newdw]->wd = wd; w->wd = wd;
watches->data[newdw]->parent = parent; w->parent = parent;
watches->data[newdw]->dirname = s_strdup(log, dirname); w->dirname = s_strdup(log, dirname);
watches->data[newdw]->dir_conf = dir_conf; w->dir_conf = dir_conf;
watches->data[newdw]->alarm = 0; // not needed, just to be save w->alarm = 0; // not needed, just to be save
watches->data[newdw]->delayed = false; w->delayed = false;
return watches->data[newdw]; return w;
} }
/** /**
@ -1152,30 +1153,31 @@ rsync_dir(const struct global_options *opts,
* Puts a directory on the delay list OR * Puts a directory on the delay list OR
* directly calls rsync_dir if delay == 0; * directly calls rsync_dir if delay == 0;
* *
* @param delay if true will put it on the delay, if false act immediately
* @param watch the watches of the delayed directory. * @param watch the watches of the delayed directory.
* @param alarm times() when the directory handling should be fired. * @param alarm times() when the directory handling should be fired.
*/ */
void void
delay_dir(const struct global_options *opts, delay_or_act_dir(const struct global_options *opts,
struct watch *watch, bool delay,
clock_t alarm) struct watch *watch,
clock_t alarm)
{ {
char pathname[PATH_MAX+1];
const struct log *log = &opts->log; const struct log *log = &opts->log;
char pathname[PATH_MAX+1];
if (opts->delay == 0) { if (!delay) {
rsync_dir(opts, watch); rsync_dir(opts, watch);
return;
}
if (!buildpath(log, pathname, sizeof(pathname), watch, NULL, NULL)) {
return;
}
if (append_delay(log, watch, alarm)) {
printlogf(log, NORMAL, "Putted %s on a delay", pathname);
} else { } else {
printlogf(log, NORMAL, "Not acted on %s already on delay", pathname); if (!buildpath(log, pathname, sizeof(pathname), watch, NULL, NULL)) {
return;
}
if (append_delay(log, watch, alarm)) {
printlogf(log, NORMAL, "Putted %s on a delay", pathname);
} else {
printlogf(log, NORMAL, "Not acted on %s already on delay", pathname);
}
} }
} }
@ -1189,7 +1191,7 @@ delay_dir(const struct global_options *opts,
* @param dirname The name or absolute path of the directory to watch. * @param dirname The name or absolute path of the directory to watch.
* @param parent If not -1, the index in watches to the parent directory already watched. * @param parent If not -1, the index in watches to the parent directory already watched.
* Must have absolute path if parent == -1. * Must have absolute path if parent == -1.
* @param dir_conf ??? TODO * @param dir_conf applicateable configuration
* *
* @returns the watches of the directory or NULL on fail. * @returns the watches of the directory or NULL on fail.
*/ */
@ -1203,7 +1205,7 @@ add_dirwatch(const struct global_options *opts,
{ {
const struct log *log = &opts->log; const struct log *log = &opts->log;
DIR *d; DIR *d;
struct watch *dw; // TODO rename struct watch *w;
char pathname[PATH_MAX+1]; char pathname[PATH_MAX+1];
printlogf(log, DEBUG, "add_dirwatch(%s, p->dirname:%s, ...)", printlogf(log, DEBUG, "add_dirwatch(%s, p->dirname:%s, ...)",
@ -1226,13 +1228,13 @@ add_dirwatch(const struct global_options *opts,
} }
// watch this directory // watch this directory
dw = add_watch(log, watches, inotify_fd, pathname, dirname, parent, dir_conf); w = add_watch(log, watches, inotify_fd, pathname, dirname, parent, dir_conf);
if (!dw) { if (!w) {
return NULL; return NULL;
} }
// put this directory on list to be synced ASAP. // put this directory on list to be synced ASAP.
delay_dir(opts, dw, times(NULL)); delay_or_act_dir(opts, true, w, times(NULL));
if (strlen(pathname) + strlen(dirname) + 2 > sizeof(pathname)) { if (strlen(pathname) + strlen(dirname) + 2 > sizeof(pathname)) {
printlogf(log, ERROR, "pathname too long %s//%s", pathname, dirname); printlogf(log, ERROR, "pathname too long %s//%s", pathname, dirname);
@ -1261,7 +1263,7 @@ add_dirwatch(const struct global_options *opts,
// use traditional means to determine if its a directory. // use traditional means to determine if its a directory.
char subdir[PATH_MAX+1]; char subdir[PATH_MAX+1];
struct stat st; struct stat st;
isdir = buildpath(log, subdir, sizeof(subdir), dw, de->d_name, NULL) && isdir = buildpath(log, subdir, sizeof(subdir), w, de->d_name, NULL) &&
!stat(subdir, &st) && !stat(subdir, &st) &&
S_ISDIR(st.st_mode); S_ISDIR(st.st_mode);
} else { } else {
@ -1271,16 +1273,15 @@ add_dirwatch(const struct global_options *opts,
// add watches if its a directory and not . or .. // add watches if its a directory and not . or ..
if (isdir && strcmp(de->d_name, "..") && strcmp(de->d_name, ".")) { if (isdir && strcmp(de->d_name, "..") && strcmp(de->d_name, ".")) {
// recurse into subdirectories // recurse into subdirectories
// TODO rename struct watch *nw = add_dirwatch(opts, watches, inotify_fd, de->d_name, w, dir_conf);
struct watch *ndw = add_dirwatch(opts, watches, inotify_fd, de->d_name, dw, dir_conf);
printlogf(log, NORMAL, printlogf(log, NORMAL,
"found new directory: %s in %s -- %s", "found new directory: %s in %s -- %s",
de->d_name, dirname, ndw ? "will be synced" : "ignored it"); de->d_name, dirname, nw ? "will be synced" : "ignored it");
} }
} }
closedir(d); closedir(d);
return dw; return w;
} }
/** /**
@ -1303,15 +1304,14 @@ remove_dirwatch(const struct global_options *opts,
struct watch *parent) struct watch *parent)
{ {
const struct log *log = &opts->log; const struct log *log = &opts->log;
struct watch *dw; // the directory to remove -> TODO rename struct watch *w; // the watch to remove
if (name) { if (name) {
int i; int i;
// look for the child with the name // look for the child with the name
// TODO optimize by using subdir lists // TODO optimize by using subdir lists
for (i = 0; i < watches->len; i++) { for (i = 0; i < watches->len; i++) {
struct watch *p = watches->data[i]; w = watches->data[i];
if (p->wd >= 0 && p->parent == parent && !strcmp(name, p->dirname)) { if (w->wd >= 0 && w->parent == parent && !strcmp(name, w->dirname)) {
dw = p;
break; break;
} }
} }
@ -1322,7 +1322,7 @@ remove_dirwatch(const struct global_options *opts,
return false; return false;
} }
} else { } else {
dw = parent; w = parent;
} }
{ {
@ -1330,26 +1330,27 @@ remove_dirwatch(const struct global_options *opts,
// TODO possible optimization by keeping a list of subdirs // TODO possible optimization by keeping a list of subdirs
int i; int i;
for (i = 0; i < watches->len; i++) { for (i = 0; i < watches->len; i++) {
// TODO shortcut pointer struct watch * iw = watches->data[i];
if (watches->data[i]->wd >= 0 && watches->data[i]->parent == dw) { if (iw->wd >= 0 && iw->parent == w) {
remove_dirwatch(opts, watches, inotify_fd, NULL, watches->data[i]); // recurse into the subdirectory
remove_dirwatch(opts, watches, inotify_fd, NULL, iw);
} }
} }
} }
inotify_rm_watch(inotify_fd, dw->wd); inotify_rm_watch(inotify_fd, w->wd);
// mark this entry invalid // mark this entry invalid
dw->wd = -1; w->wd = -1;
free(dw->dirname); free(w->dirname);
dw->dirname = NULL; w->dirname = NULL;
// remove a possible delay // remove a possible delay
// (this dir is on the to do/delay list) // (this dir is on the to do/delay list)
if (delays->len > 0 && dw->delayed) { if (delays->len > 0 && w->delayed) {
int i; int i;
for(i = 0; i < delays->len; i++) { for(i = 0; i < delays->len; i++) {
if (delays->data[i] == dw) { if (delays->data[i] == w) {
// move the list up. // move the list up.
memmove(delays->data + i, delays->data + i + 1, (delays->len - i - 1) * sizeof(int)); memmove(delays->data + i, delays->data + i + 1, (delays->len - i - 1) * sizeof(int));
delays->len--; delays->len--;
@ -1398,39 +1399,41 @@ handle_event(const struct global_options *opts,
struct inotify_event *event, struct inotify_event *event,
clock_t alarm) clock_t alarm)
{ {
char masktext[255] = {0,};
int mask = event->mask;
int i; //TODO
struct inotify_mask_text *p; //TODO
struct watch *watch;
const struct log *log = &opts->log; const struct log *log = &opts->log;
char masktext[255] = {0,};
struct watch *watch;
// creates a string for logging that shows which flags {
// were raised in the event // creates a string for logging that shows which flags
for (p = mask_texts; p->mask; p++) { // were raised in the event
if (mask & p->mask) { struct inotify_mask_text *p;
if (strlen(masktext) + strlen(p->text) + 3 >= sizeof(masktext)) { int mask = event->mask;
printlogf(log, ERROR, "bufferoverflow in handle_event"); for (p = mask_texts; p->mask; p++) {
return false; if (mask & p->mask) {
if (strlen(masktext) + strlen(p->text) + 3 >= sizeof(masktext)) {
printlogf(log, ERROR, "bufferoverflow in handle_event");
return false;
}
if (*masktext) {
strcat(masktext, ", ");
}
strcat(masktext, p->text);
} }
if (*masktext) {
strcat(masktext, ", ");
}
strcat(masktext, p->text);
} }
printlogf(log, DEBUG, "inotfy event: %s:%s", masktext, event->name);
} }
printlogf(log, DEBUG, "inotfy event: %s:%s", masktext, event->name);
if (IN_IGNORED & event->mask) { if (IN_IGNORED & event->mask) {
return true; return true;
} }
// TODO, is this needed? {
for (i = 0; i < exclude_dir_n; i++) { // TODO, is this needed? or will it be excluded already?
if (!strcmp(event->name, exclude_dirs[i])) { int i;
return true; for (i = 0; i < exclude_dir_n; i++) {
if (!strcmp(event->name, exclude_dirs[i])) {
return true;
}
} }
} }
@ -1452,12 +1455,12 @@ handle_event(const struct global_options *opts,
remove_dirwatch(opts, watches, inotify_fd, event->name, watch); remove_dirwatch(opts, watches, inotify_fd, event->name, watch);
} }
// call the binary if something changed // 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
) { ) {
printlogf(log, NORMAL, "received event %s:%s.", masktext, event->name); printlogf(log, NORMAL, "received event %s:%s.", masktext, event->name);
delay_dir(opts, watch, alarm); delay_or_act_dir(opts, opts->delay > 0, watch, alarm);
} else { } else {
printlogf(log, DEBUG, "... ignored this event."); printlogf(log, DEBUG, "... ignored this event.");
} }