static int _csync_propagation_cleanup(CSYNC *ctx) { c_list_t *list = NULL; c_list_t *walk = NULL; char *uri = NULL; char *dir = NULL; switch (ctx->current) { case LOCAL_REPLICA: list = ctx->local.list; uri = ctx->local.uri; break; case REMOTE_REPLICA: list = ctx->remote.list; uri = ctx->remote.uri; break; default: break; } if (list == NULL) { ctx->status_code = CSYNC_STATUS_MEMORY_ERROR; return 0; } list = c_list_sort(list, _csync_cleanup_cmp); if (list == NULL) { ctx->status_code = CSYNC_STATUS_MEMORY_ERROR; return -1; } for (walk = c_list_last(list); walk != NULL; walk = c_list_prev(walk)) { csync_file_stat_t *st = NULL; st = (csync_file_stat_t *) walk->data; if (asprintf(&dir, "%s/%s", uri, st->path) < 0) { ctx->status_code = CSYNC_STATUS_MEMORY_ERROR; return -1; } if (csync_vio_rmdir(ctx, dir) < 0) { /* Write it back to statedb, that we try to delete it next time. */ st->instruction = CSYNC_INSTRUCTION_NONE; } else { st->instruction = CSYNC_INSTRUCTION_DELETED; } CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "CLEANUP dir: %s", dir); SAFE_FREE(dir); } return 0; }
static void check_csync_vio_rmdir(void **state) { CSYNC *csync = *state; csync_stat_t sb; int rc; rc = csync_vio_mkdir(csync, CSYNC_TEST_DIR, MKDIR_MASK); assert_int_equal(rc, 0); rc = lstat(CSYNC_TEST_DIR, &sb); assert_int_equal(rc, 0); rc = csync_vio_rmdir(csync, CSYNC_TEST_DIR); assert_int_equal(rc, 0); rc = lstat(CSYNC_TEST_DIR, &sb); assert_int_equal(rc, -1); }
static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) { c_list_t *list = NULL; char errbuf[256] = {0}; char *uri = NULL; int rc = -1; switch (ctx->current) { case LOCAL_REPLICA: if (asprintf(&uri, "%s/%s", ctx->local.uri, st->path) < 0) { return -1; } break; case REMOTE_REPLCIA: if (asprintf(&uri, "%s/%s", ctx->remote.uri, st->path) < 0) { return -1; } break; default: break; } if (csync_vio_rmdir(ctx, uri) < 0) { switch (errno) { case ENOMEM: CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "dir: %s, command: rmdir, error: %s", uri, strerror_r(errno, errbuf, sizeof(errbuf))); rc = -1; break; case ENOTEMPTY: switch (ctx->current) { case LOCAL_REPLICA: list = c_list_prepend(ctx->local.list, (void *) st); if (list == NULL) { return -1; } ctx->local.list = list; break; case REMOTE_REPLCIA: list = c_list_prepend(ctx->remote.list, (void *) st); if (list == NULL) { return -1; } ctx->remote.list = list; break; default: break; } rc = 0; break; default: CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "dir: %s, command: rmdir, error: %s", uri, strerror_r(errno, errbuf, sizeof(errbuf))); rc = 1; break; } goto out; } /* set instruction for the statedb merger */ st->instruction = CSYNC_INSTRUCTION_DELETED; CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "REMOVED dir: %s", uri); rc = 0; out: SAFE_FREE(uri); /* set instruction for the statedb merger */ if (rc != 0) { st->instruction = CSYNC_INSTRUCTION_NONE; } return rc; }