-#ifdef HAVE_MINGW
- // We cannot atomically replace files on Windows.
- char bakname[PATH_MAX];
- snprintf(bakname, PATH_MAX, "%s.bak", filename);
- if(rename(tmpname, bakfile) || rename(bakfile, filename)) {
- rename(bakfile, filename);
-#else
- if(rename(tmpname, filename)) {
-#endif
- logger(mesh, MESHLINK_ERROR, "Failed to update `%s': %s", filename, strerror(errno));
+ fclose(f);
+
+ unlink(used_path);
+ return true;
+}
+
+/// Write an invitation file.
+bool invitation_write(meshlink_handle_t *mesh, const char *conf_subdir, const char *name, const config_t *config, void *key) {
+ if(!mesh->confbase && !conf_subdir) {
+ return false;
+ }
+
+ char path[PATH_MAX];
+ make_invitation_path(mesh, conf_subdir, name, path, sizeof(path));
+
+ FILE *f = fopen(path, "w");
+
+ if(!f) {
+ logger(mesh, MESHLINK_ERROR, "Failed to open `%s': %s", 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));
+ fclose(f);
+ 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));