/*************************************************************************** zonefile.cpp - support for zone files ------------------- begin : su oct 5 2003 copyright : (C) 2003 by Meilof email : meilof@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "zonefile.h" #include "zones.h" #include "lib.h" #include "posadisrc.h" #include "configuration.h" #include void load_zone_file(domainname &znroot, const char *fname, bool finalize) { struct stat statstr; char buff[1024], *ptr; stl_string item; int linenum = 1, linenum2 = 1; FILE *f = try_fopen_r(fname); if (!f) throw PException(true, "Cannot read from %s", fname); /* ignore empty zone files */ int c; c = fgetc(f); if (c == EOF) { fclose(f); return; } ungetc(c, f); do { read_line(buff, f, &linenum, &linenum2); if (is_whitespace(buff[0])) { skip_whitespace(buff, ptr); if (ptr[0] != 0) { fclose(f); throw PException("No whitespace expected before \"zone\" line in zonefile"); } } else ptr = buff; if (*ptr == '\0') continue; else break; } while (!feof(f)); if (feof(f) || strcmpi(read_entry(ptr).c_str(), "zone") != 0) { pos_log(context_zonedata, log_warning, "Ignoring empty zone file %s", fname); fclose(f); return; } Zone *z = create_zone(read_entry(ptr).c_str()); if (z->type == Z_PRIMARY) { delete z; fclose(f); throw PException("You cannot create primary zones using zone files: use master files instead!"); } add_authoritative_zone(znroot, z); z->zonefile = fname; if (stat(fname, &statstr) == 0 && S_ISREG(statstr.st_mode)) z->last_ftime = statstr.st_mtime; try { while (!feof(f)) { read_line(buff, f, &linenum, &linenum2); if (is_whitespace(buff[0])) { skip_whitespace(buff, ptr); } else ptr = buff; if (*ptr == '\0') continue; item = read_entry(ptr); /* setting name */ try { set_setting((setting_fn)zone_set, z, (void *)item.c_str(), ptr); } catch (PException p) { throw PException(true, "Error in setting \"%s\": %s", item.c_str(), p.message); } } if (finalize) z->end_setting(); } catch (PException p) { throw PException(true, "line %d: %s", linenum2, p.message); } fclose(f); } bool is_zonefile(const char *name, domainname &dom) { char c; if ( (c = name[strlen(name) - 1]) == '~' || c == '/' || c == '\\') return false; if (strncmpi(name, "zn.", 3) == 0) { dom = domainname(name + 3); return true; } if (strlen(name) >= 4 && strcmp(name + strlen(name) - 4, ".znf") == 0) { char *tmp = strdup(name); try { tmp[strlen(tmp) - 4] = '\0'; dom = domainname(tmp); free(tmp); return true; } catch (PException p) { free(tmp); return false; } return true; } return false; } bool is_masterfile(const char *name, domainname &dom) { char c; if ( (c = name[strlen(name) - 1]) == '~' || c == '/' || c == '\\') return false; if (strncmpi(name, "db.", 3) == 0) { dom = domainname(name + 3); return true; } if (strlen(name) >= 4 && strcmp(name + strlen(name) - 4, ".prm") == 0) { char *tmp = strdup(name); try { tmp[strlen(tmp) - 4] = '\0'; dom = domainname(tmp); free(tmp); return true; } catch (PException p) { free(tmp); return false; } return true; } return false; }