int c_mkdirs(const char *path, mode_t mode) { int tmp; csync_stat_t sb; mbchar_t *wpath = c_utf8_to_locale(path); mbchar_t *swpath = NULL; if (path == NULL) { errno = EINVAL; return -1; } if (_tstat(wpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { errno = ENOTDIR; c_free_locale_string(wpath); return -1; } } tmp = strlen(path); while(tmp > 0 && path[tmp - 1] == '/') --tmp; while(tmp > 0 && path[tmp - 1] != '/') --tmp; while(tmp > 0 && path[tmp - 1] == '/') --tmp; if (tmp > 0) { char subpath[tmp + 1]; memcpy(subpath, path, tmp); subpath[tmp] = '\0'; swpath = c_utf8_to_locale(subpath); if (_tstat(swpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { c_free_locale_string(swpath); c_free_locale_string(wpath); errno = ENOTDIR; return -1; } } else if (errno != ENOENT) { c_free_locale_string(wpath); c_free_locale_string(swpath); return -1; } else if (c_mkdirs(subpath, mode) < 0) { c_free_locale_string(swpath); c_free_locale_string(wpath); return -1; } } tmp = _tmkdir(wpath, mode); c_free_locale_string(swpath); c_free_locale_string(wpath); if ((tmp < 0) && (errno == EEXIST)) { return 0; } return tmp; }
int c_mkdirs(const char *path, mode_t mode) { int tmp; csync_stat_t sb; const _TCHAR *wpath = c_multibyte(path); const _TCHAR *swpath = NULL; if (path == NULL) { errno = EINVAL; return -1; } if (_tstat(wpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { errno = ENOTDIR; return -1; } } tmp = strlen(path); while(tmp > 0 && path[tmp - 1] == '/') --tmp; while(tmp > 0 && path[tmp - 1] != '/') --tmp; while(tmp > 0 && path[tmp - 1] == '/') --tmp; if (tmp > 0) { char subpath[tmp + 1]; memcpy(subpath, path, tmp); subpath[tmp] = '\0'; swpath = c_multibyte(subpath); if (_tstat(swpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { errno = ENOTDIR; return -1; } } else if (errno != ENOENT) { c_free_multibyte(swpath); return -1; } else if (c_mkdirs(subpath, mode) < 0) { c_free_multibyte(swpath); return -1; } } #ifdef _WIN32 tmp = _tmkdir(wpath); #else tmp = _tmkdir(wpath, mode); #endif c_free_multibyte(swpath); c_free_multibyte(wpath); if ((tmp < 0) && (errno == EEXIST)) { return 0; } return tmp; }
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; }
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; }