diff options
Diffstat (limited to 'usr.sbin/unbound/smallapp/unbound-anchor.c')
-rw-r--r-- | usr.sbin/unbound/smallapp/unbound-anchor.c | 70 |
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); } /** |