summaryrefslogtreecommitdiff
path: root/usr.sbin/unbound/smallapp/unbound-anchor.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/unbound/smallapp/unbound-anchor.c')
-rw-r--r--usr.sbin/unbound/smallapp/unbound-anchor.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/usr.sbin/unbound/smallapp/unbound-anchor.c b/usr.sbin/unbound/smallapp/unbound-anchor.c
index f8bce83082b..ac9fe63599d 100644
--- a/usr.sbin/unbound/smallapp/unbound-anchor.c
+++ b/usr.sbin/unbound/smallapp/unbound-anchor.c
@@ -1839,15 +1839,49 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust, const char* p7signer)
return secure;
}
+/** open a temp file */
+static FILE*
+tempfile_open(char* tempf, size_t tempflen, const char* fname, const char* mode)
+{
+ snprintf(tempf, tempflen, "%s~", fname);
+ return fopen(tempf, mode);
+}
+
+/** close an open temp file and replace the original with it */
+static void
+tempfile_close(FILE* fd, const char* tempf, const char* fname)
+{
+ fflush(fd);
+#ifdef HAVE_FSYNC
+ fsync(fileno(fd));
+#else
+ FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(fd)));
+#endif
+ if(fclose(fd) != 0) {
+ printf("could not complete write: %s: %s\n",
+ tempf, strerror(errno));
+ unlink(tempf);
+ return;
+ }
+ /* success; overwrite actual file */
+#ifdef USE_WINSOCK
+ (void)unlink(fname); /* windows does not replace file with rename() */
+#endif
+ if(rename(tempf, fname) < 0) {
+ printf("rename(%s to %s): %s", tempf, fname, strerror(errno));
+ }
+}
+
/** write unsigned root anchor file, a 5011 revoked tp */
static void
write_unsigned_root(const char* root_anchor_file)
{
FILE* out;
time_t now = time(NULL);
- out = fopen(root_anchor_file, "w");
+ char tempf[2048];
+ out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
if(!out) {
- if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
+ if(verb) printf("%s: %s\n", tempf, strerror(errno));
return;
}
if(fprintf(out, "; autotrust trust anchor file\n"
@@ -1862,13 +1896,7 @@ write_unsigned_root(const char* root_anchor_file)
root_anchor_file);
if(verb && errno != 0) printf("%s\n", strerror(errno));
}
- fflush(out);
-#ifdef HAVE_FSYNC
- fsync(fileno(out));
-#else
- FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out)));
-#endif
- fclose(out);
+ tempfile_close(out, tempf, root_anchor_file);
}
/** write root anchor file */
@@ -1878,29 +1906,24 @@ write_root_anchor(const char* root_anchor_file, BIO* ds)
char* pp = NULL;
int len;
FILE* out;
+ char tempf[2048];
(void)BIO_seek(ds, 0);
len = BIO_get_mem_data(ds, &pp);
if(!len || !pp) {
if(verb) printf("out of memory\n");
return;
}
- out = fopen(root_anchor_file, "w");
+ out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
if(!out) {
- if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
+ if(verb) printf("%s: %s\n", tempf, strerror(errno));
return;
}
if(fwrite(pp, (size_t)len, 1, out) != 1) {
if(verb) printf("failed to write all data to %s\n",
- root_anchor_file);
+ tempf);
if(verb && errno != 0) printf("%s\n", strerror(errno));
}
- fflush(out);
-#ifdef HAVE_FSYNC
- fsync(fileno(out));
-#else
- FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out)));
-#endif
- fclose(out);
+ tempfile_close(out, tempf, root_anchor_file);
}
/** Perform the verification and update of the trustanchor file */
@@ -2044,18 +2067,19 @@ try_read_anchor(const char* file)
static void
write_builtin_anchor(const char* file)
{
+ char tempf[2048];
const char* builtin_root_anchor = get_builtin_ds();
- FILE* out = fopen(file, "w");
+ FILE* out = tempfile_open(tempf, sizeof(tempf), file, "w");
if(!out) {
printf("could not write builtin anchor, to file %s: %s\n",
- file, strerror(errno));
+ tempf, strerror(errno));
return;
}
if(!fwrite(builtin_root_anchor, strlen(builtin_root_anchor), 1, out)) {
printf("could not complete write builtin anchor, to file %s: %s\n",
- file, strerror(errno));
+ tempf, strerror(errno));
}
- fclose(out);
+ tempfile_close(out, tempf, file);
}
/**