+ if(!config_read_file(NULL, f, &config, src_key)) {
+ logger(NULL, MESHLINK_ERROR, "Failed to read `%s': %s\n", src_filename, strerror(errno));
+ fclose(f);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ if(fclose(f)) {
+ logger(NULL, MESHLINK_ERROR, "Failed to close `%s': %s\n", src_filename, strerror(errno));
+ config_free(&config);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ f = fopen(dst_filename, "w");
+
+ if(!f) {
+ logger(NULL, MESHLINK_ERROR, "Failed to open `%s': %s", dst_filename, strerror(errno));
+ config_free(&config);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ if(!config_write_file(NULL, f, &config, dst_key)) {
+ logger(NULL, MESHLINK_ERROR, "Failed to write `%s': %s", dst_filename, strerror(errno));
+ config_free(&config);
+ fclose(f);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ if(fclose(f)) {
+ logger(NULL, MESHLINK_ERROR, "Failed to close `%s': %s", dst_filename, strerror(errno));
+ config_free(&config);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ config_free(&config);
+
+ struct utimbuf times;
+ times.modtime = st.st_mtime;
+ times.actime = st.st_atime;
+
+ if(utime(dst_filename, ×)) {
+ logger(NULL, MESHLINK_ERROR, "Failed to utime `%s': %s", dst_filename, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+ }
+ }
+
+ closedir(src_dir);
+ return true;