]> granicus.if.org Git - pdns/commitdiff
ixfrdist: handle zone write errors
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Thu, 17 Oct 2019 13:24:34 +0000 (15:24 +0200)
committerPeter van Dijk <peter.van.dijk@powerdns.com>
Thu, 17 Oct 2019 13:24:34 +0000 (15:24 +0200)
pdns/ixfrutils.cc

index d96c6398045a2fc36b654df889d60a6c5934a227..59e514c1f9ae3f133f6b142f20421255876ccddd 100644 (file)
@@ -110,11 +110,13 @@ uint32_t getSerialFromRecords(const records_t& records, DNSRecord& soaret)
 static void writeRecords(FILE* fp, const records_t& records)
 {
   for(const auto& r: records) {
-    fprintf(fp, "%s\t%" PRIu32 "\tIN\t%s\t%s\n",
+    if(fprintf(fp, "%s\t%" PRIu32 "\tIN\t%s\t%s\n",
             r.d_name.isRoot() ? "@" :  r.d_name.toStringNoDot().c_str(),
             r.d_ttl,
             DNSRecordContent::NumberToType(r.d_type).c_str(),
-            r.d_content->getZoneRepresentation().c_str());
+            r.d_content->getZoneRepresentation().c_str()) < 0) {
+      throw runtime_error(stringerror());
+    }
   }
 }
 
@@ -129,13 +131,29 @@ void writeZoneToDisk(const records_t& records, const DNSName& zone, const std::s
 
   records_t soarecord;
   soarecord.insert(soa);
-  fprintf(fp, "$ORIGIN %s\n", zone.toString().c_str());
+  if(fprintf(fp, "$ORIGIN %s\n", zone.toString().c_str()) < 0) {
+    string error = "Error writing to zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + stringerror();
+    fclose(fp);
+    unlink((fname+".partial").c_str());
+    throw std::runtime_error(error);
+  }
 
-  writeRecords(fp, soarecord);
-  writeRecords(fp, records);
-  writeRecords(fp, soarecord);
+  try {
+    writeRecords(fp, soarecord);
+    writeRecords(fp, records);
+    writeRecords(fp, soarecord);
+  } catch (runtime_error &e) {
+    fclose(fp);
+    unlink((fname+".partial").c_str());
+    throw runtime_error("Error closing zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + e.what());
+  }
+
+  if(fclose(fp) != 0) {
+    string error = "Error closing zone file for " + zone.toLogString() + " in file " + fname + ".partial" + ": " + stringerror();
+    unlink((fname+".partial").c_str());
+    throw std::runtime_error(error);
+  }
 
-  fclose(fp);
   if (rename( (fname+".partial").c_str(), fname.c_str()) != 0) {
     throw std::runtime_error("Unable to move the zone file for " + zone.toLogString() + " from " + fname + ".partial to " + fname + ": " + stringerror());
   }