if(fd < 0) {
logger(NULL, MESHLINK_ERROR, "Failed to open %s: %s\n", pathname, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
if(fsync(fd)) {
logger(NULL, MESHLINK_ERROR, "Failed to sync %s: %s\n", pathname, strerror(errno));
close(fd);
+ meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
if(close(fd)) {
logger(NULL, MESHLINK_ERROR, "Failed to close %s: %s\n", pathname, strerror(errno));
close(fd);
+ meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
return rename(old_path, new_path) == 0;
}
+bool config_sync(meshlink_handle_t *mesh, const char *conf_subdir) {
+ if(!mesh->confbase) {
+ return true;
+ }
+
+ if(!conf_subdir) {
+ return false;
+ }
+
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s" SLASH "%s" SLASH "hosts", mesh->confbase, conf_subdir);
+
+ if(!sync_path(path)) {
+ return false;
+ }
+
+ snprintf(path, sizeof(path), "%s" SLASH "%s", mesh->confbase, conf_subdir);
+
+ if(!sync_path(path)) {
+ return false;
+ }
+
+ return true;
+}
+
bool meshlink_confbase_exists(meshlink_handle_t *mesh) {
if(!mesh->confbase) {
return false;
}
char path[PATH_MAX];
+ char tmp_path[PATH_MAX + 4];
make_host_path(mesh, conf_subdir, name, path, sizeof(path));
+ snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", path);
- FILE *f = fopen(path, "w");
+ FILE *f = fopen(tmp_path, "w");
if(!f) {
- logger(mesh, MESHLINK_ERROR, "Failed to open `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to open `%s': %s", tmp_path, strerror(errno));
return false;
}
if(!config_write_file(mesh, f, config, key)) {
- logger(mesh, MESHLINK_ERROR, "Failed to write `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to write `%s': %s", tmp_path, strerror(errno));
+ fclose(f);
+ return false;
+ }
+
+ if(fsync(fileno(f))) {
+ logger(mesh, MESHLINK_ERROR, "Failed to sync `%s': %s", tmp_path, strerror(errno));
fclose(f);
return false;
}
if(fclose(f)) {
- logger(mesh, MESHLINK_ERROR, "Failed to close `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to close `%s': %s", tmp_path, strerror(errno));
+ return false;
+ }
+
+ if(rename(tmp_path, path)) {
+ logger(mesh, MESHLINK_ERROR, "Failed to rename `%s' to `%s': %s", tmp_path, path, strerror(errno));
return false;
}
}
char path[PATH_MAX];
+ char tmp_path[PATH_MAX + 4];
make_main_path(mesh, conf_subdir, path, sizeof(path));
+ snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", path);
- FILE *f = fopen(path, "w");
+ FILE *f = fopen(tmp_path, "w");
if(!f) {
- logger(mesh, MESHLINK_ERROR, "Failed to open `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to open `%s': %s", tmp_path, strerror(errno));
return false;
}
if(!config_write_file(mesh, f, config, key)) {
- logger(mesh, MESHLINK_ERROR, "Failed to write `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to write `%s': %s", tmp_path, strerror(errno));
fclose(f);
return false;
}
+ if(fsync(fileno(f))) {
+ logger(mesh, MESHLINK_ERROR, "Failed to sync `%s': %s", tmp_path, strerror(errno));
+ fclose(f);
+ return false;
+ }
+
+ if(rename(tmp_path, path)) {
+ logger(mesh, MESHLINK_ERROR, "Failed to rename `%s' to `%s': %s", tmp_path, path, strerror(errno));
+ return false;
+ }
+
if(fclose(f)) {
- logger(mesh, MESHLINK_ERROR, "Failed to close `%s': %s", path, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to close `%s': %s", tmp_path, strerror(errno));
return false;
}
return false;
}
- if(time(NULL) > st.st_mtime + mesh->invitation_timeout) {
+ if(mesh->loop.now.tv_sec > st.st_mtime + mesh->invitation_timeout) {
logger(mesh, MESHLINK_ERROR, "Peer tried to use an outdated invitation file %s\n", name);
fclose(f);
unlink(used_path);
return false;
}
+ if(fsync(fileno(f))) {
+ logger(mesh, MESHLINK_ERROR, "Failed to sync `%s': %s", path, strerror(errno));
+ return false;
+ }
+
if(fclose(f)) {
logger(mesh, MESHLINK_ERROR, "Failed to close `%s': %s", path, strerror(errno));
return false;