+ }
+
+ 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) {
+ if(!mesh->confbase) {
+ return true;
+ }
+
+ 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;
+ }
+
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s" SLASH "meshlink.lock", mesh->confbase);
+
+ mesh->lockfile = fopen(path, "w+");
+
+ if(!mesh->lockfile) {
+ logger(NULL, MESHLINK_ERROR, "Cannot not open %s: %s\n", path, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+#ifdef FD_CLOEXEC
+ fcntl(fileno(mesh->lockfile), F_SETFD, FD_CLOEXEC);
+#endif