1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
@Override
public void write(Map<String, String> hostnamesIp) throws ZoneFileSystemException, ArgumentInvalidException, BadAddressIPException, SerialOutOfBoundException {
CheckerArguments.checkObject(hostnamesIp);
if(hostnamesIp.isEmpty()){
log.debug("Writing a DB zone file: the map hostnames-IPs is empty");
return;
}
this.hostnamesIP = hostnamesIp;
log.info("Writing a DB zone file: zone " + this.zone.getZoneName() + " - " + this.file.getAbsolutePath()
+ " - number of hostnames " + this.hostnamesIP.size());
// get the lock to be the only one for editing the file
lock();
if (!this.locked) {
log.warn("Writing a DB zone file: " + this.file.getAbsolutePath() + " is not locked");
throw new ZoneFileSystemException(this.file.getAbsolutePath() + " is not locked");
}
BufferedReader in = null;
BufferedWriter out = null;
try {
in = new BufferedReader(new FileReader(this.file.getAbsolutePath()));
out = new BufferedWriter(new FileWriter(this.file.getAbsolutePath() + NEWER_FILE));
String currentLine, previousLine = "-", lineComment = "", strTab1[], nSerial;
// hostname -> comment
//Map<String, String> hostnameComment = new HashMap<String, String>();
// write the master comment
log.debug("Writing a DB zone file: write the master comment");
out.write(MASTER_COMMENT_ZONE_FILE);
log.debug("Writing a DB zone file: reading the file");
while ((currentLine = in.readLine()) != null) {
log.debug("Writing a DB zone file: read line: " + currentLine);
// skip the line if it's the master/hostname comment block
if (currentLine.matches(REGEXP_DB_ZONE_SYSTEM_COMMENT)) {
log.debug("Writing a DB zone file: skip system comments");
previousLine = currentLine;
continue;
}
// skip comment lines
if (currentLine.matches("^(\\s)*("+REGEXP_DB_ZONE_START_COMMENT+ ")(.)*$")) {
log.debug("Writing a DB zone file: skip comment line");
previousLine = currentLine;
continue;
}
// skip hostnames lines
if (currentLine.matches(REGEXP_DB_LINE_HOSTNAME)) {
log.debug("Writing a DB zone file: skip all hostnames line");
previousLine = currentLine;
continue;
}
/*
* skip blank/comment/hostname line when the previous line is a
* blank/comment/hostname line
*/
if( (currentLine.trim().equals("") || currentLine.matches(REGEXP_DB_LINE_HOSTNAME)
|| currentLine.matches("^(\\s)*("+REGEXP_DB_ZONE_START_COMMENT+ ")(.)*$"))
&& (previousLine.trim().equals("") || previousLine.matches(REGEXP_DB_LINE_HOSTNAME)
|| previousLine.matches("^(\\s)*("+REGEXP_DB_ZONE_START_COMMENT+ ")(.)*$"))
){
previousLine = currentLine.trim();
continue;
}
// get the current TTL and replace by the zone TTL field
if (currentLine.matches(REGEXP_DB_TTL)) {
log.debug("Writing a DB zone file: write TTL " + zone.getTtl());
out.write(TTL_DONT_MODIFY_COMMENT);
out.write("$TTL " + zone.getTtl() + "\n\n");
}
// get the current serial
else if (currentLine.matches(REGEXP_DB_SERIAL)) {
strTab1 = currentLine.split(REGEXP_DB_ZONE_START_COMMENT, 2);
this.fileSerial = strTab1[0].trim();
nSerial = getNewSerial();
if(nSerial == null){
log.warn("Writing a DB zone file: getting a new serial number: the serial number has exceeded the limit");
throw new SerialOutOfBoundException("The serial number has exceeded the limit of zone " + this.zone.getZoneName());
}
log.debug("Writing a DB zone file: write serial " + nSerial);
// there is a comment
if (strTab1.length == 2) {
lineComment = "\t" + BIND_COMMENT + " " + strTab1[1].trim() + "\n";
out.write("\t\t\t" + nSerial + lineComment);
} else
out.write("\t\t\t" + nSerial + "\n");
nSerial = null; // gc
}
// write others lines
else {
log.debug("Writing a DB zone file: write line: " + currentLine);
out.write(currentLine + "\n");
}
strTab1 = null; // gc
lineComment = null; // gc
previousLine = currentLine.trim();
}
// END WHILE read-write
// write hostname comment
log.debug("Writing a DB zone file: write the hostnames comment");
out.write("\n\n\n");
out.write(HOSTNAME_COMMENT_ZONE_FILE);
// write all backup hostnames (hostname -> ip)
Iterator<String> it = this.hostnamesIP.keySet().iterator();
String hostn, ip, toWrite = null;
log.debug("Writing a DB zone file: write all hostnames with their IP");
while (it.hasNext()) {
hostn = it.next();
ip = this.hostnamesIP.get(hostn);
CheckerArguments.checkIsAnIp(ip);
// IP v4 or v6?
if (CheckerArguments.isAnIpV4(ip)) {
toWrite = hostn + "\t\t" + BIND_RECORD_IPV4 + "\t" + ip + "\n";
} else if (CheckerArguments.isAnIpV6(ip)) {
toWrite = hostn + "\t" + BIND_RECORD_IPV6 + "\t" + ip + "\n";
} else {
// IPv4 dotted quad at the end
log.debug("Writing a DB zone file: IPv4 dotted quad at the end " + ip);
//toWrite = hostn + "\t" + BIND_RECORD_IPV6 + "\t" + ip + "\n";
}
out.write(toWrite);
log.debug("Writing a DB zone file: write -> " + toWrite);
toWrite = "";
}
// END WHILE write
// closing the files --> see finally block
/*
* switch this.filePath.new to this.filePath
*
* if an exception occurs, renameFilesTo() function will be skipped
* and the newer file (BufferedWriter out) will be removed in the
* finally block
*/
renameFilesTo();
// remove the lock file --> see finally block
} catch (PatternSyntaxException e) {
log.fatal("Writing a DB zone file: PatternSyntaxException", e);
throw new RuntimeException(e);
} catch (IOException e) {
log.warn("Writing a DB zone file: IOException", e);
throw new ZoneFileSystemException(e);
} finally {
try {
unlock();
// closing the files
if (in != null)
in.close();
if (out != null)
out.close();
/*
* removing the file "this.file.getAbsolutePath() + NEWER_FILE"
* if it exist due to an error
*/
(new File(this.file.getAbsolutePath() + NEWER_FILE)).delete();
log.info("Writing a DB zone file: done");
} catch (IOException e) {
log.warn("Writing a DB zone file: IOException: can't close files", e);
throw new ZoneFileSystemException("can't close files");
}
}
} |
Partager