22 #include "opensync_internals.h"
40 flock(
int fd,
int operation)
44 switch (operation & ~LOCK_NB) {
46 flock.l_type = F_RDLCK;
49 flock.l_type = F_WRLCK;
52 flock.l_type = F_UNLCK;
63 return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
118 char *filename = NULL;
124 filename = g_strdup_printf(
"%s/%lli", group->configdir, i);
125 }
while (g_file_test(filename, G_FILE_TEST_EXISTS));
139 return group->conv_env;
155 GError *gerror = NULL;
156 char *filename = NULL;
158 dir = g_dir_open(path, 0, &gerror);
160 osync_debug(
"OSGRP", 3,
"Unable to open group configdir %s", gerror->message);
161 osync_error_set(error, OSYNC_ERROR_IO_ERROR,
"Unable to open group configdir %s", gerror->message);
162 g_error_free (gerror);
166 const gchar *de = NULL;
167 while ((de = g_dir_read_name(dir))) {
169 if (!g_file_test(filename, G_FILE_TEST_IS_DIR) || g_file_test(filename, G_FILE_TEST_IS_SYMLINK) || g_pattern_match_simple(
".*", de) || !strcmp(
"db", de)) {
175 osync_debug(
"OSGRP", 0,
"Unable to load one of the members");
243 if (group->configdir)
244 g_free(group->configdir);
271 g_assert(group->configdir);
273 osync_bool exists = FALSE;
274 osync_bool locked = FALSE;
276 if (group->lock_fd) {
281 char *lockfile = g_strdup_printf(
"%s/lock", group->configdir);
282 osync_debug(
"GRP", 4,
"locking file %s", lockfile);
284 if (g_file_test(lockfile, G_FILE_TEST_EXISTS)) {
285 osync_debug(
"GRP", 4,
"locking group: file exists");
289 if ((group->lock_fd = open(lockfile, O_CREAT | O_WRONLY, 00700)) == -1) {
291 osync_debug(
"GRP", 1,
"error opening file: %s", strerror(errno));
294 return OSYNC_LOCK_STALE;
300 int oldflags = fcntl(group->lock_fd, F_GETFD);
301 if (oldflags == -1) {
303 return OSYNC_LOCK_STALE;
306 if (fcntl(group->lock_fd, F_SETFD, oldflags|FD_CLOEXEC) == -1) {
308 return OSYNC_LOCK_STALE;
311 if (flock(group->lock_fd, LOCK_EX | LOCK_NB) == -1) {
312 if (errno == EWOULDBLOCK) {
313 osync_debug(
"GRP", 4,
"locking group: is locked2");
315 close(group->lock_fd);
318 osync_debug(
"GRP", 1,
"error setting lock: %s", strerror(errno));
326 return OSYNC_LOCK_OK;
333 return OSYNC_LOCK_STALE;
351 g_assert(group->configdir);
352 osync_debug(
"GRP", 4,
"unlocking group %s", group->name);
354 if (!group->lock_fd) {
355 osync_debug(
"GRP", 1,
"You have to lock the group before unlocking");
359 if (flock(group->lock_fd, LOCK_UN) == -1) {
360 osync_debug(
"GRP", 1,
"error releasing lock: %s", strerror(errno));
364 fsync(group->lock_fd);
365 close(group->lock_fd);
370 char *lockfile = g_strdup_printf(
"%s/lock", group->configdir);
389 group->name = g_strdup(name);
419 osync_assert_msg(group->env,
"You must specify a Environment prior to saving the group");
421 if (!group->configdir) {
423 group->configdir = g_strdup_printf(
"%s/group%lli", group->env->groupsdir, group->id);
426 char *filename = NULL;
427 osync_debug(
"OSGRP", 3,
"Trying to open configdirectory %s to save group %s", group->configdir, group->name);
430 if (!g_file_test(group->configdir, G_FILE_TEST_IS_DIR)) {
431 osync_debug(
"OSGRP", 3,
"Creating group configdirectory %s", group->configdir);
432 if (mkdir(group->configdir, 0700)) {
433 osync_error_set(error, OSYNC_ERROR_IO_ERROR,
"Unable to create directory for group %s\n", group->name);
438 filename = g_strdup_printf (
"%s/syncgroup.conf", group->configdir);
439 osync_debug(
"OSGRP", 3,
"Saving group to file %s", filename);
443 doc = xmlNewDoc((xmlChar*)
"1.0");
444 doc->children = xmlNewDocNode(doc, NULL, (xmlChar*)
"syncgroup", NULL);
448 for (f = group->filters; f; f = f->next) {
450 xmlNodePtr child = xmlNewTextChild(doc->children, NULL, (xmlChar*)
"filter", NULL);
452 if (filter->sourcememberid) {
453 char *sourcememberid = g_strdup_printf(
"%lli", filter->sourcememberid);
454 xmlNewTextChild(child, NULL, (xmlChar*)
"sourcemember", (xmlChar*)sourcememberid);
455 g_free(sourcememberid);
457 if (filter->destmemberid) {
458 char *destmemberid = g_strdup_printf(
"%lli", filter->destmemberid);
459 xmlNewTextChild(child, NULL, (xmlChar*)
"destmember", (xmlChar*)destmemberid);
460 g_free(destmemberid);
462 if (filter->sourceobjtype)
463 xmlNewTextChild(child, NULL, (xmlChar*)
"sourceobjtype", (xmlChar*)filter->sourceobjtype);
464 if (filter->destobjtype)
465 xmlNewTextChild(child, NULL, (xmlChar*)
"destobjtype", (xmlChar*)filter->destobjtype);
466 if (filter->detectobjtype)
467 xmlNewTextChild(child, NULL, (xmlChar*)
"detectobjtype", (xmlChar*)filter->detectobjtype);
468 if (filter->action) {
469 char *action = g_strdup_printf(
"%i", filter->action);
470 xmlNewTextChild(child, NULL, (xmlChar*)
"action", (xmlChar*)action);
473 if (filter->function_name)
474 xmlNewTextChild(child, NULL, (xmlChar*)
"function_name", (xmlChar*)filter->function_name);
476 xmlNewTextChild(child, NULL, (xmlChar*)
"config", (xmlChar*)filter->config);
479 xmlNewTextChild(doc->children, NULL, (xmlChar*)
"groupname", (xmlChar*)group->name);
481 char *tmstr = g_strdup_printf(
"%i", (
int)group->last_sync);
482 xmlNewTextChild(doc->children, NULL, (xmlChar*)
"last_sync", (xmlChar*)tmstr);
485 xmlSaveFile(filename, doc);
515 char *delcmd = g_strdup_printf(
"rm -rf %s", group->configdir);
516 if (system(delcmd)) {
517 osync_error_set(error, OSYNC_ERROR_GENERIC,
"Failed to delete group. command %s failed", delcmd);
539 char *filename = NULL;
540 char *real_path = NULL;
544 osync_debug(
"OSGRP", 3,
"Trying to load group from directory %s", path);
546 if (!g_path_is_absolute(path)) {
547 real_path = g_strdup_printf(
"%s/%s", g_get_current_dir(), path);
549 real_path = g_strdup(path);
551 filename = g_strdup_printf(
"%s/syncgroup.conf", real_path);
554 group->configdir = real_path;
558 xmlNodePtr filternode;
567 while (cur != NULL) {
568 if (!xmlStrcmp(cur->name, (
const xmlChar *)
"groupname"))
569 group->name = (
char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
571 if (!xmlStrcmp(cur->name, (
const xmlChar *)
"last_sync"))
572 group->last_sync = (time_t)atoi((
char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
574 if (!xmlStrcmp(cur->name, (
const xmlChar *)
"filter")) {
575 filternode = cur->xmlChildrenNode;
577 filter->group = group;
579 while (filternode != NULL) {
580 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"sourceobjtype"))
581 filter->sourceobjtype = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
583 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"destobjtype"))
584 filter->destobjtype = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
586 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"detectobjtype"))
587 filter->detectobjtype = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
589 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"config"))
590 filter->config = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
592 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"function_name")) {
593 char *str = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
595 filternode = filternode->next;
598 osync_filter_update_hook(filter, group, str);
602 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"sourcemember")) {
603 char *str = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
605 filternode = filternode->next;
608 filter->sourcememberid = atoll(str);
612 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"destmember")) {
613 char *str = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
615 filternode = filternode->next;
618 filter->destmemberid = atoll(str);
622 if (!xmlStrcmp(filternode->name, (
const xmlChar *)
"action")) {
623 char *str = (
char*)xmlNodeListGetString(doc, filternode->xmlChildrenNode, 1);
625 filternode = filternode->next;
628 filter->action = atoi(str);
631 filternode = filternode->next;
642 osync_error_set(error, OSYNC_ERROR_MISCONFIGURATION,
"Loaded a group without a name");
643 osync_debug(
"OSGRP", 0,
"Loaded a group without a name");
670 osync_db_reset_group(group, &error);
673 for (m = group->members; m; m = m->next) {
675 osync_db_reset_member(member, &error);
690 group->members = g_list_append(group->members, member);
702 group->members = g_list_remove(group->members, member);
717 return (
OSyncMember *)g_list_nth_data(group->members, nth);
731 return g_list_length(group->members);
745 return group->configdir;
758 if (group->configdir)
759 g_free(group->configdir);
760 group->configdir = g_strdup(directory);
785 if (osync_conv_objtype_is_any(objtypestr)) {
787 for (element = conv_env->
objtypes; element; element = element->next) {
789 objtype->needs_slow_sync = slow_sync;
794 objtype->needs_slow_sync = slow_sync;
815 if (osync_conv_objtype_is_any(objtypestr)) {
817 for (element = conv_env->
objtypes; element; element = element->next) {
819 objtype->needs_slow_sync = FALSE;
824 objtype->needs_slow_sync = FALSE;
848 if (osync_objtype && osync_objtype->needs_slow_sync) {
853 g_assert(osync_objtype);
856 return osync_objtype->needs_slow_sync;
878 for (m = group->members; m; m = m->next) {
903 for (m = group->members; m; m = m->next) {
913 if (!osync_member_require_sink_info(member, NULL)) {
914 osync_debug(
"OSGRP", 0,
"%s: No sink information, can't load plugin, and I can't return error");
931 return g_list_length(group->filters);
947 return g_list_nth_data(group->filters, nth);
957 while (group->filters) {
958 OSyncFilter *f = g_list_nth_data(group->filters, 0);
962 group->filters = g_list_delete_link(group->filters, group->filters);
978 return osync_db_open_changelog(group, uids, objtype, memberids, changetypes, error);
990 return osync_db_save_changelog(group, change, error);
1002 return osync_db_remove_changelog(group, change, error);
1015 osync_assert_msg(group,
"Group missing");
1017 group->last_sync = last_sync;
1031 osync_assert_msg(group,
"Group missing");
1032 return group->last_sync;