+bool meshlink_confbase_exists(meshlink_handle_t *mesh) {
+ if(!mesh->confbase) {
+ return false;
+ }
+
+ bool confbase_exists = false;
+ bool confbase_decryptable = false;
+
+ if(main_config_exists(mesh, "current")) {
+ confbase_exists = true;
+
+ if(mesh->config_key && main_config_decrypt(mesh, "current")) {
+ confbase_decryptable = true;
+ }
+ }
+
+ if(mesh->config_key && !confbase_decryptable && main_config_exists(mesh, "new")) {
+ confbase_exists = true;
+
+ if(main_config_decrypt(mesh, "new")) {
+ if(!config_destroy(mesh->confbase, "current")) {
+ return false;
+ }
+
+ if(!config_rename(mesh, "new", "current")) {
+ return false;
+ }
+
+ confbase_decryptable = true;
+ }
+ }
+
+ if(mesh->config_key && !confbase_decryptable && main_config_exists(mesh, "old")) {
+ confbase_exists = true;
+
+ if(main_config_decrypt(mesh, "old")) {
+ if(!config_destroy(mesh->confbase, "current")) {
+ return false;
+ }
+
+ if(!config_rename(mesh, "old", "current")) {
+ return false;
+ }
+
+ confbase_decryptable = true;
+ }
+ }
+
+ // Cleanup if current is existing with old and new
+ if(confbase_exists && confbase_decryptable) {
+ if(!config_destroy(mesh->confbase, "old") || !config_destroy(mesh->confbase, "new")) {
+ return false;
+ }
+ }
+
+ return confbase_exists;
+}
+
+/// Lock the main configuration file. Creates confbase if necessary.
+bool main_config_lock(meshlink_handle_t *mesh, const char *lock_filename) {
+ if(!mesh->confbase) {
+ return true;
+ }
+
+ assert(lock_filename);
+
+ if(mkdir(mesh->confbase, 0700) && errno != EEXIST) {
+ logger(NULL, MESHLINK_ERROR, "Cannot create configuration directory %s: %s", mesh->confbase, strerror(errno));
+ meshlink_close(mesh);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return NULL;
+ }
+
+ mesh->lockfile = fopen(lock_filename, "w+");
+
+ if(!mesh->lockfile) {
+ logger(NULL, MESHLINK_ERROR, "Cannot not open %s: %s\n", lock_filename, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;