not logged at a high enough logging level to be
useful in diagnosing this situation. [RT #275]
+ 435. [bug] dns_zone_dump() overwrote existing zone files
+ rather than writing to a temporary file and
+ renaming. This could lead to empty or partial
+ zone files being left around in certain error
+ conditions involving the initial transfer of a
+ slave zone, interfering with subsequent server
+ startup. [RT #282]
+
429. [bug] The space reserved for a TSIG record in a response
was 2 bytes too short, leading to message
generation failures.
* SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.27.2.1 2000/08/15 00:29:48 gson Exp $ */
+/* $Id: masterdump.c,v 1.27.2.2 2000/09/11 19:27:47 explorer Exp $ */
#include <config.h>
{
FILE *f = NULL;
isc_result_t result;
+ char *tempname;
+ int tempnamelen;
- result = isc_stdio_open(filename, "w", &f);
+ tempnamelen = strlen(filename) + 20;
+ tempname = isc_mem_get(mctx, tempnamelen);
+ if (tempname == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_file_mktemplate(filename, tempname, tempnamelen);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = isc_file_openunique(tempname, &f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: open: %s", filename,
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
+ "dumping master file: %s: open: %s",
+ tempname, isc_result_totext(result));
+ goto cleanup;
}
result = dns_master_dumptostream(mctx, db, version, style, f);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
+ "dumping master file: %s: %s",
+ tempname, isc_result_totext(result));
+ (void)isc_stdio_close(f);
+ (void)isc_file_remove(tempname);
+ goto cleanup;
+ }
result = isc_stdio_close(f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: close: %s", filename,
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
+ "dumping master file: %s: close: %s",
+ tempname, isc_result_totext(result));
+ (void)isc_file_remove(tempname);
+ goto cleanup;
+
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
+ "dumping master file: %s: close: %s",
+ tempname, isc_result_totext(result));
+ goto cleanup;
+ }
+
+ result = isc_file_rename(tempname, filename);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
+ "dumping master file: rename: %s: %s",
+ filename, isc_result_totext(result));
+ goto cleanup;
}
+ cleanup:
+ isc_mem_put(mctx, tempname, tempnamelen);
return (result);
}
* SOFTWARE.
*/
-/* $Id: zone.c,v 1.152.2.10 2000/09/07 16:55:33 gson Exp $ */
+/* $Id: zone.c,v 1.152.2.11 2000/09/11 19:27:49 explorer Exp $ */
#include <config.h>
zone_dump(dns_zone_t *zone) {
isc_result_t result;
dns_dbversion_t *version = NULL;
- dns_db_t *db = NULL;
- char *buf;
- int buflen;
- FILE *f = NULL;
- int n;
/*
* 'zone' locked by caller.
*/
REQUIRE(DNS_ZONE_VALID(zone));
- buflen = strlen(zone->dbname) + 20;
- buf = isc_mem_get(zone->mctx, buflen);
- if (buf == NULL)
- return (ISC_R_NOMEMORY);
+ dns_db_currentversion(zone->db, &version);
- result = isc_file_mktemplate(zone->dbname, buf, buflen);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
+ result = dns_master_dump(zone->mctx, zone->db, version,
+ &dns_master_style_default,
+ zone->dbname);
+
+ dns_db_closeversion(zone->db, &version, ISC_FALSE);
- result = isc_file_openunique(buf, &f);
if (result != ISC_R_SUCCESS)
- goto cleanup;
+ return (result);
- dns_db_attach(zone->db, &db);
- dns_db_currentversion(db, &version);
- result = dns_master_dumptostream(zone->mctx, db, version,
- &dns_master_style_default, f);
- dns_db_closeversion(db, &version, ISC_FALSE);
- dns_db_detach(&db);
- n = fflush(f);
- if (n != 0 && result == ISC_R_SUCCESS)
- result = ISC_R_UNEXPECTED;
- n = ferror(f);
- if (n != 0 && result == ISC_R_SUCCESS)
- result = ISC_R_UNEXPECTED;
- n = fclose(f);
- if (n != 0 && result == ISC_R_SUCCESS)
- result = ISC_R_UNEXPECTED;
- if (result == ISC_R_SUCCESS) {
- n = rename(buf, zone->dbname);
- if (n == -1) {
- (void)remove(buf);
- result = ISC_R_UNEXPECTED;
- } else {
- zone->flags &= ~DNS_ZONEFLG_NEEDDUMP;
- }
- } else
- (void)remove(buf);
- cleanup:
- isc_mem_put(zone->mctx, buf, buflen);
- return (result);
+ zone->flags &= ~DNS_ZONEFLG_NEEDDUMP;
+ return (ISC_R_SUCCESS);
}
isc_result_t
* SOFTWARE.
*/
-/* $Id: file.h,v 1.7 2000/06/22 21:57:32 tale Exp $ */
+/* $Id: file.h,v 1.7.2.1 2000/09/11 19:27:50 explorer Exp $ */
#ifndef ISC_FILE_H
#define ISC_FILE_H 1
* Remove the file named by 'filename'.
*/
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname);
+/*
+ * Rename the file 'oldname' to 'newname'.
+ */
+
/*
* XXX We should also have a isc_file_writeeopen() function
* for safely open a file in a publicly writable directory
* SOFTWARE.
*/
-/* $Id: file.c,v 1.17 2000/06/22 21:58:35 tale Exp $ */
+/* $Id: file.c,v 1.17.2.1 2000/09/11 19:27:52 explorer Exp $ */
#include <config.h>
else
return (isc__errno2result(errno));
}
+
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname) {
+ int r;
+
+ r = rename(oldname, newname);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}