+ snprintf(dst_filename, sizeof(dst_filename), "%s" SLASH "%s", dst_dir_name, ent->d_name);
+ snprintf(src_filename, sizeof(src_filename), "%s" SLASH "%s", src_dir_name, ent->d_name);
+
+ if(ent->d_type == DT_DIR) {
+ if(!copytree(src_filename, src_key, dst_filename, dst_key)) {
+ logger(NULL, MESHLINK_ERROR, "Copying %s to %s failed\n", src_filename, dst_filename);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ if(!sync_path(dst_filename)) {
+ return false;
+ }
+ } else if(ent->d_type == DT_REG) {
+ struct stat st;
+ config_t config;
+
+ if(stat(src_filename, &st)) {
+ logger(NULL, MESHLINK_ERROR, "Could not stat file `%s': %s\n", src_filename, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ FILE *f = fopen(src_filename, "r");
+
+ if(!f) {
+ logger(NULL, MESHLINK_ERROR, "Failed to open `%s': %s\n", src_filename, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ 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;