From 89d675c474a6717d9daa8b5d9ff2c0f2c03666f9 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 28 Oct 2015 22:06:21 +0100 Subject: [PATCH] Add a function to destroy a MeshLink instance. This will remove all configuration files related to a MeshLink instance. --- src/meshlink++.h | 13 +++++++++++++ src/meshlink.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/meshlink.h | 12 ++++++++++++ test/basic.c | 14 ++++++++++++++ test/basicpp.cpp | 12 ++++++++++++ 5 files changed, 94 insertions(+) diff --git a/src/meshlink++.h b/src/meshlink++.h index f1a3b962..8e0745e4 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -540,6 +540,19 @@ namespace meshlink { return meshlink_strerror(err); } + /// Destroy a MeshLink instance. + /** This function remove all configuration files of a MeshLink instance. It should only be called when the application + * does not have an open handle to this instance. Afterwards, a call to meshlink_open() will create a completely + * new instance. + * + * @param confbase The directory in which MeshLink stores its configuration files. + * After the function returns, the application is free to overwrite or free @a confbase @a. + * + * @return This function will return true if the MeshLink instance was succesfully destroyed, false otherwise. + */ + static bool destroy(const char *confbase) { + return meshlink_destroy(confbase); + } } #endif // MESHLINKPP_H diff --git a/src/meshlink.c b/src/meshlink.c index cbbb64d3..e9250e25 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1049,6 +1049,49 @@ void meshlink_close(meshlink_handle_t *mesh) { free(mesh); } +static void deltree(const char *dirname) { + DIR *d = opendir(dirname); + if(d) { + struct dirent *ent; + while((ent = readdir(d))) { + if(ent->d_name[0] == '.') + continue; + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "%s", dirname, ent->d_name); + if(unlink(filename)) + deltree(filename); + } + closedir(d); + } + rmdir(dirname); + return; +} + +bool meshlink_destroy(const char *confbase) { + if(!confbase) { + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "%s" SLASH "meshlink.conf", confbase); + + if(unlink(filename)) { + if(errno == ENOENT) { + meshlink_errno = MESHLINK_ENOENT; + return false; + } else { + logger(NULL, MESHLINK_ERROR, "Cannot delete %s: %s\n", filename, strerror(errno)); + meshlink_errno = MESHLINK_ESTORAGE; + return false; + } + } + + deltree(confbase); + + return true; +} + void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) { if(!mesh) { meshlink_errno = MESHLINK_EINVAL; diff --git a/src/meshlink.h b/src/meshlink.h index 1f4bb726..cca5db1a 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -196,6 +196,18 @@ extern void meshlink_stop(meshlink_handle_t *mesh); */ extern void meshlink_close(meshlink_handle_t *mesh); +/// Destroy a MeshLink instance. +/** This function remove all configuration files of a MeshLink instance. It should only be called when the application + * does not have an open handle to this instance. Afterwards, a call to meshlink_open() will create a completely + * new instance. + * + * @param confbase The directory in which MeshLink stores its configuration files. + * After the function returns, the application is free to overwrite or free @a confbase @a. + * + * @return This function will return true if the MeshLink instance was succesfully destroyed, false otherwise. + */ +extern bool meshlink_destroy(const char *confbase); + /// A callback for receiving data from the mesh. /** @param mesh A handle which represents an instance of MeshLink. * @param source A pointer to a meshlink_node_t describing the source of the data. diff --git a/test/basic.c b/test/basic.c index 626d06f6..93b7f5e9 100644 --- a/test/basic.c +++ b/test/basic.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "meshlink.h" @@ -79,5 +81,17 @@ int main(int argc, char *argv[]) { meshlink_close(mesh); + // Destroy the mesh. + + if(!meshlink_destroy("basic_conf")) { + fprintf(stderr, "Could not destroy configuration\n"); + return 1; + } + + if(!access("basic_conf", F_OK) || errno != ENOENT) { + fprintf(stderr, "Configuration not fully destroyed\n"); + return 1; + } + return 0; } diff --git a/test/basicpp.cpp b/test/basicpp.cpp index 34c0bacb..3a0c75ac 100644 --- a/test/basicpp.cpp +++ b/test/basicpp.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "meshlink++.h" @@ -71,5 +73,15 @@ int main(int argc, char *argv[]) { mesh.stop(); + if(!meshlink::destroy("basicpp_conf")) { + cerr << "Could not destroy configuration\n"; + return 1; + } + + if(!access("basic.conf", F_OK) || errno != ENOENT) { + cerr << "Configuration not fully destroyed\n"; + return 1; + } + return 0; } -- 2.39.2