Пример #1
0
int csync_commit(CSYNC *ctx) {
  int rc = 0;

  if (ctx == NULL) {
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  if (ctx->statedb.db != NULL
      && csync_statedb_close(ctx) < 0) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ERR: closing of statedb failed.");
    rc = -1;
  }
  ctx->statedb.db = NULL;

  _csync_clean_ctx(ctx);

  ctx->remote.read_from_db = 0;
  ctx->read_remote_from_db = true;
  ctx->db_is_empty = false;


  /* Create new trees */
  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);


  ctx->status = CSYNC_STATUS_INIT;
  SAFE_FREE(ctx->error_string);

  rc = 0;
  return rc;
}
Пример #2
0
int csync_init(CSYNC *ctx) {
  int rc;
  char *config = NULL;

  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* check for uri */
  if (csync_fnmatch("owncloud://*", ctx->remote.uri, 0) == 0 && csync_fnmatch("ownclouds://*", ctx->remote.uri, 0) == 0) {
      ctx->status_code = CSYNC_STATUS_NO_MODULE;
      rc = -1;
      goto out;
  }

  ctx->local.type = LOCAL_REPLICA;

  if ( !ctx->options.local_only_mode) {
      owncloud_init(csync_get_auth_callback(ctx), csync_get_userdata(ctx));
      ctx->remote.type = REMOTE_REPLICA;
  } else {
    ctx->remote.type = LOCAL_REPLICA;
  }

  if (ctx->options.timeout)
    csync_vio_set_property(ctx, "timeout", &ctx->options.timeout);

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  ctx->status = CSYNC_STATUS_INIT;

  csync_set_module_property(ctx, "csync_context", ctx);

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  SAFE_FREE(config);
  return rc;
}
Пример #3
0
int csync_init(CSYNC *ctx) {
  int rc;

  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* check for uri */
  if (csync_fnmatch("owncloud://*", ctx->remote.uri, 0) == 0 && csync_fnmatch("ownclouds://*", ctx->remote.uri, 0) == 0) {
      ctx->status_code = CSYNC_STATUS_NO_MODULE;
      rc = -1;
      goto out;
  }

  ctx->local.type = LOCAL_REPLICA;

#ifdef USE_NEON
  owncloud_init(ctx);
#endif
  ctx->remote.type = REMOTE_REPLICA;

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  ctx->remote.root_perms = 0;

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  return rc;
}
Пример #4
0
int csync_commit(CSYNC *ctx) {
  int rc = 0;

  if (ctx == NULL) {
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  if (ctx->statedb.db != NULL
      && csync_statedb_close(ctx) < 0) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ERR: closing of statedb failed.");
    rc = -1;
  }
  ctx->statedb.db = NULL;

  rc = csync_vio_commit(ctx);
  if (rc < 0) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "commit failed: %s",
              ctx->error_string ? ctx->error_string : "");
    goto out;
  }

  _csync_clean_ctx(ctx);

  ctx->remote.read_from_db = 0;
  ctx->read_from_db_disabled = 0;


  /* Create new trees */
  rc = c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
  if (rc < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    goto out;
  }

  rc = c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
  if (rc < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    goto out;
  }


  ctx->status = CSYNC_STATUS_INIT;
  SAFE_FREE(ctx->error_string);

  rc = 0;

out:
  return rc;
}
Пример #5
0
static void check_c_rbtree_insert_delete(void **state)
{
    c_rbtree_t *tree = NULL;
    c_rbnode_t *node = NULL;
    test_t *testdata = NULL;
    int rc;

    (void) state; /* unused */

    rc = c_rbtree_create(&tree, key_cmp, data_cmp);
    assert_int_equal(rc, 0);

    testdata = malloc(sizeof(test_t));
    testdata->key = 42;

    rc = c_rbtree_insert(tree, (void *) testdata);
    assert_int_equal(rc, 0);

    node = c_rbtree_head(tree);
    assert_non_null(node);

    testdata = c_rbtree_node_data(node);
    SAFE_FREE(testdata);
    rc = c_rbtree_node_delete(node);
    assert_int_equal(rc, 0);

    c_rbtree_free(tree);
}
Пример #6
0
static void check_c_rbtree_create_null(void **state)
{
    c_rbtree_t *tree = NULL;
    int rc;

    (void) state; /* unused */

    rc = c_rbtree_create(NULL, key_cmp, data_cmp);
    assert_int_equal(rc, -1);

    rc = c_rbtree_create(&tree, NULL, data_cmp);
    assert_int_equal(rc, -1);

    rc = c_rbtree_create(&tree, key_cmp, NULL);
    assert_int_equal(rc, -1);
}
Пример #7
0
static void setup(void **state) {
    c_rbtree_t *tree = NULL;
    int rc;

    rc = c_rbtree_create(&tree, key_cmp, data_cmp);
    assert_int_equal(rc, 0);

    *state = tree;
}
Пример #8
0
void csync_init(CSYNC *ctx) {
  assert(ctx);
  /* Do not initialize twice */

  assert(!(ctx->status & CSYNC_STATUS_INIT));
  ctx->status_code = CSYNC_STATUS_OK;

  ctx->local.type = LOCAL_REPLICA;

  ctx->remote.type = REMOTE_REPLICA;

  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);

  ctx->remote.root_perms = 0;

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));
}
Пример #9
0
static void check_c_rbtree_create_free(void **state)
{
    c_rbtree_t *tree = NULL;
    int rc;

    (void) state; /* unused */

    rc = c_rbtree_create(&tree, key_cmp, data_cmp);
    assert_int_equal(rc, 0);
    assert_int_equal(tree->size, 0);

    rc = c_rbtree_free(tree);
    assert_int_equal(rc, 0);
}
Пример #10
0
static void setup_complete_tree(void **state) {
    c_rbtree_t *tree = NULL;
    int i = 0;
    int rc;

    rc = c_rbtree_create(&tree, key_cmp, data_cmp);
    assert_int_equal(rc, 0);

    for (i = 0; i < 100; i++) {
        test_t *testdata = NULL;

        testdata = c_malloc(sizeof(test_t));
        assert_non_null(testdata);

        testdata->key = i;

        rc = c_rbtree_insert(tree, (void *) testdata);
        assert_int_equal(rc, 0);
    }

    *state = tree;
}
static void propfind_results_recursive(void *userdata,
                    const ne_uri *uri,
                    const ne_prop_result_set *set)
{
    struct resource *newres = 0;
    const char *clength, *modtime, *file_id = NULL;
    const char *resourcetype = NULL;
    const char *md5sum = NULL;
    const ne_status *status = NULL;
    char *path = ne_path_unescape( uri->path );
    char *parentPath;
    char *propfindRootUri = (char*) userdata;
    propfind_recursive_element_t *element = NULL;
    propfind_recursive_element_t *pElement = NULL;
    int depth = 0;

    (void) status;
    (void) propfindRootUri;

    if (!propfind_recursive_cache) {
        c_rbtree_create(&propfind_recursive_cache, _key_cmp, _data_cmp);
    }

    /* Fill the resource structure with the data about the file */
    newres = c_malloc(sizeof(struct resource));
    ZERO_STRUCTP(newres);

    newres->uri =  path; /* no need to strdup because ne_path_unescape already allocates */
    newres->name = c_basename( path );

    modtime      = ne_propset_value( set, &ls_props[0] );
    clength      = ne_propset_value( set, &ls_props[1] );
    resourcetype = ne_propset_value( set, &ls_props[2] );
    md5sum       = ne_propset_value( set, &ls_props[3] );
    file_id      = ne_propset_value( set, &ls_props[4] );

    newres->type = resr_normal;
    if( resourcetype && strncmp( resourcetype, "<DAV:collection>", 16 ) == 0) {
        newres->type = resr_collection;
        propfind_recursive_cache_folder_count++;
    } else {
        /* DEBUG_WEBDAV("propfind_results_recursive %s [%d]", newres->uri, newres->type); */
        propfind_recursive_cache_file_count++;
    }

    if (modtime) {
        newres->modtime = oc_httpdate_parse(modtime);
    }

    /* DEBUG_WEBDAV("Parsing Modtime: %s -> %llu", modtime, (unsigned long long) newres->modtime ); */
    newres->size = 0;
    if (clength) {
        newres->size = atoll(clength);
        /* DEBUG_WEBDAV("Parsed File size for %s from %s: %lld", newres->name, clength, (long long)newres->size ); */
    }

    if( md5sum ) {
        newres->md5 = csync_normalize_etag(md5sum);
    }

    csync_vio_set_file_id(newres->file_id, file_id);
    /*
    DEBUG_WEBDAV("propfind_results_recursive %s [%s] %s", newres->uri, newres->type == resr_collection ? "collection" : "file", newres->md5);
    */

    /* Create new item in rb tree */
    if (newres->type == resr_collection) {
        DEBUG_WEBDAV("propfind_results_recursive %s is a folder", newres->uri);
        /* Check if in rb tree */
        element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,uri->path));
        /* If not, create a new item and insert it */
        if (!element) {
            element = c_malloc(sizeof(propfind_recursive_element_t));
            element->self = resource_dup(newres);
            element->children = NULL;
            element->parent = NULL;
            c_rbtree_insert(propfind_recursive_cache, element);
            /* DEBUG_WEBDAV("results_recursive Added collection %s", newres->uri); */
        }
    }

    /* Check for parent in tree. If exists: Insert it into the children elements there */
    parentPath = ne_path_parent(uri->path);
    if (parentPath) {
        propfind_recursive_element_t *parentElement = NULL;

        parentElement = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,parentPath));
        free(parentPath);

        if (parentElement) {
            newres->next = parentElement->children;
            parentElement->children = newres;

            /* If the current result is a collection we also need to set its parent */
            if (element)
                element->parent = parentElement;

            pElement = element;
            while (pElement) {
                depth++;
                pElement = pElement->parent;
            }
            if (depth > propfind_recursive_cache_depth) {
                DEBUG_WEBDAV("propfind_results_recursive %s new maximum tree depth %d", newres->uri, depth);
                propfind_recursive_cache_depth = depth;
            }

            /* DEBUG_WEBDAV("results_recursive Added child %s to collection %s", newres->uri, element->self->uri); */
        } else {
            /* DEBUG_WEBDAV("results_recursive No parent %s found for child %s", parentPath, newres->uri); */
            resource_free(newres);
            newres = NULL;
        }
    }

}
static void propfind_results_recursive_callback(void *userdata,
                    const ne_uri *uri,
                    const ne_prop_result_set *set)
{
    struct resource *newres = 0;

    const ne_status *status = NULL;
    char *path = ne_path_unescape( uri->path );
    char *parentPath;
    propfind_recursive_element_t *element = NULL;
    propfind_recursive_element_t *pElement = NULL;
    int depth = 0;
    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;


    (void) status;

    if (!ctx->propfind_recursive_cache) {
        c_rbtree_create(&ctx->propfind_recursive_cache, _key_cmp, _data_cmp);
    }

    /* Fill the resource structure with the data about the file */
    newres = c_malloc(sizeof(struct resource));

    newres->uri =  path; /* no need to strdup because ne_path_unescape already allocates */
    newres->name = c_basename( path );
    fill_webdav_properties_into_resource(newres, set);

    if( newres->type == resr_collection) {
        ctx->propfind_recursive_cache_folder_count++;
    } else {
        ctx->propfind_recursive_cache_file_count++;
    }

    /* Create new item in rb tree */
    if (newres->type == resr_collection) {
        DEBUG_WEBDAV("propfind_results_recursive %s is a folder", newres->uri);
        /* Check if in rb tree */
        element = c_rbtree_node_data(c_rbtree_find(ctx->propfind_recursive_cache,uri->path));
        /* If not, create a new item and insert it */
        if (!element) {
            element = c_malloc(sizeof(propfind_recursive_element_t));
            element->self = resource_dup(newres);
            element->self->next = 0;
            element->children = NULL;
            element->parent = NULL;
            c_rbtree_insert(ctx->propfind_recursive_cache, element);
            /* DEBUG_WEBDAV("results_recursive Added collection %s", newres->uri); */
        }
    }

    /* Check for parent in tree. If exists: Insert it into the children elements there */
    parentPath = ne_path_parent(uri->path);
    if (parentPath) {
        propfind_recursive_element_t *parentElement = NULL;

        parentElement = c_rbtree_node_data(c_rbtree_find(ctx->propfind_recursive_cache,parentPath));
        free(parentPath);

        if (parentElement) {
            newres->next = parentElement->children;
            parentElement->children = newres;

            /* If the current result is a collection we also need to set its parent */
            if (element)
                element->parent = parentElement;

            pElement = element;
            while (pElement) {
                depth++;
                pElement = pElement->parent;
            }
            if (depth > ctx->propfind_recursive_cache_depth) {
                DEBUG_WEBDAV("propfind_results_recursive %s new maximum tree depth %d", newres->uri, depth);
                ctx->propfind_recursive_cache_depth = depth;
            }

            /* DEBUG_WEBDAV("results_recursive Added child %s to collection %s", newres->uri, element->self->uri); */
            return;
        }
    }

    resource_free(newres);
    newres = NULL;
}
Пример #13
0
int csync_init(CSYNC *ctx) {
  int rc;
  time_t timediff = -1;
  char *log = NULL;
  char *exclude = NULL;
  char *lock = NULL;
  char *config = NULL;
#ifndef _WIN32
  char errbuf[256] = {0};
#endif
  
  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }
  ctx->error_code = CSYNC_ERR_NONE;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* load log file */
  if (csync_log_init() < 0) {
    ctx->error_code = CSYNC_ERR_LOG;
    fprintf(stderr, "csync_init: logger init failed\n");
    return -1;
  }

  /* create dir if it doesn't exist */
  if (! c_isdir(ctx->options.config_dir)) {
    c_mkdirs(ctx->options.config_dir, 0700);
  }

  if (asprintf(&log, "%s/%s", ctx->options.config_dir, CSYNC_LOG_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  /* load log if it exists */
  if (c_isfile(log)) {
    csync_log_load(log);
  } else {
#ifndef _WIN32
    if (c_copy(SYSCONFDIR "/csync/" CSYNC_LOG_FILE, log, 0644) == 0) {
      csync_log_load(log);
    }
#endif
  }

  /* create lock file */
  if (asprintf(&lock, "%s/%s", ctx->options.config_dir, CSYNC_LOCK_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

#ifndef _WIN32
  if (csync_lock(lock) < 0) {
    ctx->error_code = CSYNC_ERR_LOCK;
    rc = -1;
    goto out;
  }
#endif

  /* load config file */
  if (asprintf(&config, "%s/%s", ctx->options.config_dir, CSYNC_CONF_FILE) < 0) {
    rc = -1;
    goto out;
  }

  if (csync_config_load(ctx, config) < 0) {
      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load config file %s, using defaults.", config);
  }

#ifndef _WIN32
  /* load global exclude list */
  if (asprintf(&exclude, "%s/csync/%s", SYSCONFDIR, CSYNC_EXCLUDE_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude,
              errbuf);
  }
  SAFE_FREE(exclude);

  /* load exclude list */
  if (asprintf(&exclude, "%s/%s", ctx->options.config_dir, CSYNC_EXCLUDE_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude, 
              errbuf);
  }
#endif

  /* create/load statedb */
  if (! csync_is_statedb_disabled(ctx)) {
    uint64_t h = csync_create_statedb_hash(ctx);
    if (asprintf(&ctx->statedb.file, "%s/csync_statedb_%llu.db",
          ctx->options.config_dir, (long long unsigned int) h) < 0) {
      ctx->error_code = CSYNC_ERR_UNSPEC;
      rc = -1;
      goto out;
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Remote replica: %s", ctx->remote.uri);
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Statedb: %s", ctx->statedb.file);

    if (csync_statedb_load(ctx, ctx->statedb.file) < 0) {
      ctx->error_code = CSYNC_ERR_STATEDB_LOAD;
      rc = -1;
      goto out;
    }
  }

  ctx->local.type = LOCAL_REPLICA;

  /* check for uri */
  if ( !ctx->options.local_only_mode && csync_fnmatch("*://*", ctx->remote.uri, 0) == 0) {
    size_t len;
    len = strstr(ctx->remote.uri, "://") - ctx->remote.uri;
    /* get protocol */
    if (len > 0) {
      char *module = NULL;
      /* module name */
      module = c_strndup(ctx->remote.uri, len);
      if (module == NULL) {
        ctx->error_code = CSYNC_ERR_MODULE;
        rc = -1;
        goto out;
      }
      /* load module */
retry_vio_init:
      rc = csync_vio_init(ctx, module, NULL);
      if (rc < 0) {
        len = strlen(module);

        if (len > 0 && module[len-1] == 's') {
          module[len-1] = '\0';
          goto retry_vio_init;
        }
        /* Now vio init finally failed which means a module could not be found. */
        ctx->error_code = CSYNC_ERR_MODULE;
	CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
		  "The csync module %s could not be loaded.", module);
        SAFE_FREE(module);
        goto out;
      }
      SAFE_FREE(module);
      ctx->remote.type = REMOTE_REPLCIA;
    }
  } else {
    ctx->remote.type = LOCAL_REPLICA;
  }

  if(!ctx->options.local_only_mode) {
    if(ctx->module.capabilities.time_sync_required) {
      timediff = csync_timediff(ctx);
      if (timediff > ctx->options.max_time_difference) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
                  "Clock skew detected. The time difference is greater than %d seconds!",
                  ctx->options.max_time_difference);
        ctx->error_code = CSYNC_ERR_TIMESKEW;
        rc = -1;
        goto out;
      } else if (timediff < 0) {
        /* error code was set in csync_timediff() */
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
	/* do not override error code set by timediff */
	if(ctx->error_code == CSYNC_ERR_NONE) {
	  ctx->error_code = CSYNC_ERR_TIMESKEW;
	}
        rc = -1;
        goto out;
      }
    } else {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Module does not need time synchronization.");
    }

    if(ctx->module.capabilities.unix_extensions == -1) { /* detect */
      if (csync_unix_extensions(ctx) < 0) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
        ctx->error_code = CSYNC_ERR_FILESYSTEM;
        rc = -1;
        goto out;
      }
    } else {
      /* The module specifies the value for the unix_extensions. */
      ctx->options.unix_extensions = ctx->module.capabilities.unix_extensions;
    }
  }

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->error_code = CSYNC_ERR_TREE;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->error_code = CSYNC_ERR_TREE;
    rc = -1;
    goto out;
  }

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  SAFE_FREE(log);
  SAFE_FREE(lock);
  SAFE_FREE(exclude);
  SAFE_FREE(config);
  return rc;
}
Пример #14
0
Файл: csync.c Проект: gco/csync
int csync_commit(CSYNC *ctx) {
  int rc = 0;

  if (ctx == NULL) {
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  rc = _merge_and_write_statedb(ctx);
  if (rc < 0) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Merge and Write database failed!");
    if (ctx->status_code == CSYNC_STATUS_OK) {
      ctx->status_code = CSYNC_STATUS_STATEDB_WRITE_ERROR;
    }
    rc = 1;  /* Set to soft error. */
    /* The other steps happen anyway, what else can we do? */
  }

  rc = csync_vio_commit(ctx);
  if (rc < 0) {
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "commit failed: %s",
              ctx->error_string ? ctx->error_string : "");
    goto out;
  }

  /* destroy the rbtrees */
  rc = c_rbtree_size(ctx->local.tree);
  if (rc > 0) {
    c_rbtree_destroy(ctx->local.tree, _tree_destructor);
  }

  rc = c_rbtree_size(ctx->remote.tree);
  if (rc > 0) {
    c_rbtree_destroy(ctx->remote.tree, _tree_destructor);
  }

  /* free memory */
  c_rbtree_free(ctx->local.tree);
  c_list_free(ctx->local.list);
  c_rbtree_free(ctx->remote.tree);
  c_list_free(ctx->remote.list);

  ctx->local.list = 0;
  ctx->remote.list = 0;

  /* create/load statedb */
  rc = csync_is_statedb_disabled(ctx);
  if (rc == 0) {
    if (ctx->statedb.file == NULL) {
      rc = asprintf(&ctx->statedb.file, "%s/.csync_journal.db",
                    ctx->local.uri);
      if (rc < 0) {
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Failed to assemble statedb file name.");
        goto out;
      }
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Journal: %s", ctx->statedb.file);

    rc = csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db);
    if (rc < 0) {
      ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
      goto out;
    }
  }

  /* Create new trees */
  rc = c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
  if (rc < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    goto out;
  }

  rc = c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
  if (rc < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    goto out;
  }

  /* reset the progress */
  ctx->progress.file_count = 0;
  ctx->progress.current_file_no = 0;
  ctx->progress.byte_sum = 0;
  ctx->progress.byte_current = 0;

  ctx->status = CSYNC_STATUS_INIT;
  SAFE_FREE(ctx->error_string);

  rc = 0;

out:
  return rc;
}
Пример #15
0
Файл: csync.c Проект: gco/csync
int csync_init(CSYNC *ctx) {
  int rc;
  time_t timediff = -1;
  char *exclude = NULL;
  char *lock = NULL;
  char *config = NULL;
  char errbuf[256] = {0};
  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* create dir if it doesn't exist */
  if (! c_isdir(ctx->options.config_dir)) {
    c_mkdirs(ctx->options.config_dir, 0700);
  }

  /* create lock file */
  if (asprintf(&lock, "%s/%s", ctx->options.config_dir, CSYNC_LOCK_FILE) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    goto out;
  }

#ifndef _WIN32
  if (csync_lock(lock) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_NO_LOCK;
    goto out;
  }
#endif

  /* load config file */
  if (asprintf(&config, "%s/%s", ctx->options.config_dir, CSYNC_CONF_FILE) < 0) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    rc = -1;
    goto out;
  }

  rc = csync_config_parse_file(ctx, config);
  if (rc < 0) {
      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load config file %s, using defaults.", config);
  }

#ifndef _WIN32
  /* load global exclude list */
  if (asprintf(&exclude, "%s/csync/%s", SYSCONFDIR, CSYNC_EXCLUDE_FILE) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load %s - %s", exclude,
              errbuf);
  }
  SAFE_FREE(exclude);
#endif
  /* load exclude list */
  if (asprintf(&exclude, "%s/%s", ctx->options.config_dir,
        CSYNC_EXCLUDE_FILE) < 0) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude,
              errbuf);
  }

  /* create/load statedb */
  if (! csync_is_statedb_disabled(ctx)) {
    rc = asprintf(&ctx->statedb.file, "%s/.csync_journal.db",
                  ctx->local.uri);
    if (rc < 0) {
      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
      goto out;
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Journal: %s", ctx->statedb.file);

    rc = csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db);
    if (rc < 0) {
      ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
      goto out;
    }
  }

  ctx->local.type = LOCAL_REPLICA;

  /* check for uri */
  if ( !ctx->options.local_only_mode && csync_fnmatch("*://*", ctx->remote.uri, 0) == 0) {
    size_t len;
    len = strstr(ctx->remote.uri, "://") - ctx->remote.uri;
    /* get protocol */
    if (len > 0) {
      char *module = NULL;
      /* module name */
      module = c_strndup(ctx->remote.uri, len);
      if (module == NULL) {
        rc = -1;
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        goto out;
      }
      /* load module */
retry_vio_init:
      rc = csync_vio_init(ctx, module, NULL);
      if (rc < 0) {
        len = strlen(module);

        if (module[len-1] == 's') {
          module[len-1] = '\0';
          goto retry_vio_init;
        }

        SAFE_FREE(module);
        ctx->status_code = CSYNC_STATUS_NO_MODULE;
        goto out;
      }
      SAFE_FREE(module);
      ctx->remote.type = REMOTE_REPLICA;
    }
  } else {
    ctx->remote.type = LOCAL_REPLICA;
  }

  if( !ctx->options.local_only_mode ) {
      timediff = csync_timediff(ctx);
      if (timediff > ctx->options.max_time_difference) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
                    "Clock skew detected. The time difference is greater than %d seconds!",
                    ctx->options.max_time_difference);
          ctx->status_code = CSYNC_STATUS_TIMESKEW;
          rc = -1;
          goto out;
      } else if (timediff < 0) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
          ctx->status_code = CSYNC_STATUS_TIMESKEW;
          rc = -1;
          goto out;
      }

      if (csync_unix_extensions(ctx) < 0) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
          ctx->status_code = CSYNC_STATUS_FILESYSTEM_UNKNOWN;
          rc = -1;
          goto out;
      }
  }

  /* Install progress callbacks in the module. */
  if (ctx->callbacks.file_progress_cb != NULL) {
      int prc;
      prc = csync_vio_set_property(ctx, "file_progress_callback", &ctx->callbacks.file_progress_cb);
      if (prc == -1) {
          /* The module does not support the callbacks */
          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Could not install file progress callback!");
          ctx->callbacks.file_progress_cb = NULL;
      }
  }

  if (ctx->callbacks.overall_progress_cb != NULL) {
      int prc;
      prc = csync_vio_set_property(ctx, "overall_progress_callback", &ctx->callbacks.overall_progress_cb);
      if (prc == -1) {
          /* The module does not support the callbacks */
          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Could not install overall progress callback!");
          ctx->callbacks.overall_progress_cb = NULL;
      }
  }

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  SAFE_FREE(lock);
  SAFE_FREE(exclude);
  SAFE_FREE(config);
  return rc;
}