From 6dfa6f9cfdf8334f54273fe33d15911cd555ee63 Mon Sep 17 00:00:00 2001 From: Stephane Sezer Date: Mon, 29 Aug 2011 17:10:41 +0200 Subject: [PATCH] Implemented exists() methods for both file and dpl backends. --- src/storage/backends/dpl.c | 35 ++++++++++++++++++++---------- src/storage/backends/file.c | 43 +++++++++++++++++++++---------------- src/storage/storage.h | 13 +++++++++-- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/storage/backends/dpl.c b/src/storage/backends/dpl.c index 0e3e45f..9f8012c 100644 --- a/src/storage/backends/dpl.c +++ b/src/storage/backends/dpl.c @@ -251,13 +251,28 @@ static void sto_dpl_delete(void *state) free(s); } +static bool sto_dpl_exists(void *state, const char *path) +{ + struct dpl_storage_state *s = state; + char full_path[strlen(s->remote_root) + strlen(path) + 2]; + dpl_status_t ret; + dpl_dict_t *dict; + + snprintf(full_path, sizeof (full_path), "%s/%s", s->remote_root, path); + + ret = dpl_head(s->ctx, s->ctx->cur_bucket, full_path, NULL, NULL, &dict); + free(dict); + + return ret == DPL_SUCCESS; +} + storage_t sto_dpl_new(const char *uri, bool create_dirs) { struct storage *res = NULL; struct dpl_storage_state *state = NULL; dpl_ctx_t *ctx = NULL; - /* strlen("/backups") == strlen("/objects") == strlen("/.dplbck") */ - char path[strlen(uri) + strlen("/backups") + 1]; + /* strlen("backups") == strlen("objects") == strlen(".dplbck") */ + char path[strlen(uri) + strlen("backups") + 2]; dpl_status_t ret; dpl_dict_t *dict; @@ -281,13 +296,14 @@ storage_t sto_dpl_new(const char *uri, bool create_dirs) if (state->remote_root == NULL) state->remote_root = "/"; + res->delete = sto_dpl_delete; res->store_file = sto_dpl_store_file; res->store_buffer = sto_dpl_store_buffer; res->retrieve_file = sto_dpl_retrieve_file; res->retrieve_buffer = sto_dpl_retrieve_buffer; res->list = sto_dpl_list; res->unlink = sto_dpl_unlink; - res->delete = sto_dpl_delete; + res->exists = sto_dpl_exists; state->ctx = ctx; res->state = state; @@ -298,32 +314,29 @@ storage_t sto_dpl_new(const char *uri, bool create_dirs) */ if (create_dirs) { - strcpy(path, state->remote_root); + snprintf(path, sizeof (path), "%s", state->remote_root); ret = dpl_mkdir(ctx, path); if (ret != DPL_SUCCESS && ret != DPL_EEXIST) goto err; - strcat(path, "/backups"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, "backups"); ret = dpl_mkdir(ctx, path); if (ret != DPL_SUCCESS && ret != DPL_EEXIST) goto err; - strcpy(path, state->remote_root); - strcat(path, "/objects"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, "objects"); ret = dpl_mkdir(ctx, path); if (ret != DPL_SUCCESS && ret != DPL_EEXIST) goto err; - strcpy(path, state->remote_root); - strcat(path, "/.dplbck"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, ".dplbck"); ret = dpl_mknod(ctx, path); if (ret != DPL_SUCCESS && ret != DPL_EEXIST) goto err; } else { - strcpy(path, state->remote_root); - strcat(path, "/.dplbck"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, ".dplbck"); ret = dpl_head(ctx, ctx->cur_bucket, path, NULL, NULL, &dict); if (ret != DPL_SUCCESS) goto err; diff --git a/src/storage/backends/file.c b/src/storage/backends/file.c index 90b0ebb..ab98d1f 100644 --- a/src/storage/backends/file.c +++ b/src/storage/backends/file.c @@ -262,6 +262,16 @@ static bool sto_file_unlink(void *state, const char *path) return unlink(full_path) == 0; } +static bool sto_file_exists(void *state, const char *path) +{ + struct file_storage_state *s = state; + char full_path[strlen(s->remote_root) + strlen(path) + 2]; + + snprintf(full_path, sizeof (full_path), "%s/%s", s->remote_root, path); + + return access(full_path, F_OK) == 0; +} + static void sto_file_delete(void *state) { struct file_storage_state *s = state; @@ -275,20 +285,21 @@ struct storage *sto_file_new(const char *uri, bool create_dirs) { struct storage *res = NULL; struct file_storage_state *state = NULL; - /* strlen("/backups") == strlen("/objects") == strlen("/.dplbck") */ - char path[strlen(uri) + strlen("/backups") + 1]; + /* strlen("backups") == strlen("objects") == strlen(".dplbck") */ + char path[strlen(uri) + strlen("backups") + 2]; int fd; res = emalloc(sizeof (struct storage)); state = emalloc(sizeof (struct file_storage_state)); + res->delete = sto_file_delete; res->store_file = sto_file_store_file; res->store_buffer = sto_file_store_buffer; res->retrieve_file = sto_file_retrieve_file; res->retrieve_buffer = sto_file_retrieve_buffer; res->list = sto_file_list; res->unlink = sto_file_unlink; - res->delete = sto_file_delete; + res->exists = sto_file_exists; state->remote_root = uri; state->last_list = NULL; res->state = state; @@ -297,41 +308,35 @@ struct storage *sto_file_new(const char *uri, bool create_dirs) ** Ensure we have access to the directory where we want to backup, and create ** required subdirectories (e.g.: `backups`, `objects`) if they do not exist ** yet. - ** XXX: Some parts of this code are a little stupid. */ if (create_dirs) { - strcpy(path, state->remote_root); + snprintf(path, sizeof (path), "%s", state->remote_root); if (mkdir(path, 0777) == -1 && errno != EEXIST) goto err; - strcat(path, "/backups"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, "backups"); if (mkdir(path, 0777) == -1 && errno != EEXIST) goto err; - strcpy(path, state->remote_root); - strcat(path, "/objects"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, "objects"); if (mkdir(path, 0777) == -1 && errno != EEXIST) goto err; - strcpy(path, state->remote_root); - strcat(path, "/.dplbck"); + snprintf(path, sizeof (path), "%s/%s", state->remote_root, ".dplbck"); + /* + ** We could replace this with an mknod(), but the manpage states that "The + ** only portable use of mknod() is to create a FIFO-special file". + */ if ((fd = open(path, O_CREAT | O_RDONLY, 0666)) == -1) goto err; close(fd); } else { - strcpy(path, state->remote_root); - strcat(path, "/.dplbck"); - /* - ** XXX: Maybe we should replace this with a call to mknod(), but the manpage - ** states that "The only portable use of mknod() is to create a FIFO-special - ** file". - */ - if ((fd = open(path, O_RDONLY)) == -1) + snprintf(path, sizeof (path), "%s/%s", state->remote_root, ".dplbck"); + if (access(path, F_OK) == -1) goto err; - close(fd); } return res; diff --git a/src/storage/storage.h b/src/storage/storage.h index 7214bc2..7a4d28d 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -51,13 +51,18 @@ enum store_res struct storage { + void (*delete)(void *state); + enum store_res (*store_file)(void *state, const char *path, FILE *file); enum store_res (*store_buffer)(void *state, const char *path, struct buffer *buffer); + FILE *(*retrieve_file)(void *state, const char *path); struct buffer *(*retrieve_buffer)(void *state, const char *path); + const char *(*list)(void *state, const char *path); bool (*unlink)(void *state, const char *path); - void (*delete)(void *state); + bool (*exists)(void *state, const char *path); + void *state; }; # endif /* STORAGE_INTERNAL */ @@ -65,12 +70,16 @@ struct storage typedef struct storage *storage_t; storage_t storage_new(const char *uri, bool create_dirs, bool lock); +void storage_delete(storage_t storage); + bool storage_store_file(storage_t storage, const char *path, FILE *file); bool storage_store_buffer(storage_t storage, const char *path, struct buffer *buffer); + FILE *storage_retrieve_file(storage_t storage, const char *path); struct buffer *storage_retrieve_buffer(storage_t storage, const char *path); + const char *storage_list(storage_t storage, const char *path); bool storage_unlink(storage_t storage, const char *path); -void storage_delete(storage_t storage); +bool storage_exists(storage_t storage, const char *path); #endif /* !STORAGE_H_ */