diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-02 12:54:52 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-02 12:54:52 +0200 |
commit | db032057eb89e07b79eefb8617e326e2cd037300 (patch) | |
tree | 6b2c80bb44ef91afda06eca064347a6b42c3813a /vhostcname/vhostcname | |
parent | e3ea08d43ccf0a117b10e9d52c91612281a4193f (diff) | |
download | dnstools-db032057eb89e07b79eefb8617e326e2cd037300.tar.gz dnstools-db032057eb89e07b79eefb8617e326e2cd037300.tar.bz2 |
vhostcname: allow for different per-zone servers/keys/ttls
* vhostcname/vhostcname: Rewrite configuration handling. Store
zone settings in individual hash cells.
Redefine exit codes.
Implement status command.
Clean up the semantics of start/forced-restart vs. reload.
Accept abbreviated command names.
Diffstat (limited to 'vhostcname/vhostcname')
-rwxr-xr-x | vhostcname/vhostcname | 774 |
1 files changed, 572 insertions, 202 deletions
diff --git a/vhostcname/vhostcname b/vhostcname/vhostcname index 359101c..fc6dd2d 100755 --- a/vhostcname/vhostcname +++ b/vhostcname/vhostcname | |||
@@ -1,3 +1,3 @@ | |||
1 | #!/usr/bin/perl | 1 | #!/usr/bin/perl |
2 | # Copyright (C) 2014 Sergey Poznyakoff <gray@gnu.org> | 2 | # Copyright (C) 2014-2016 Sergey Poznyakoff <gray@gnu.org> |
3 | # | 3 | # |
@@ -24,26 +24,31 @@ use Net::DNS; | |||
24 | 24 | ||
25 | my $script; # This script name; | 25 | my $progname; # This script name; |
26 | 26 | my $progdescr = "update DNS from Apache virtual host configuration"; | |
27 | my $config_file = "/etc/vhostcname.conf"; | 27 | my $config_file = "/etc/vhostcname.conf"; |
28 | my %config = ( | ||
29 | core => { | ||
30 | 'cache' => "/var/run/vhostcname.cache", | ||
31 | # Default TTL. | ||
32 | 'ttl' => 3600, | ||
33 | # A globbing pattern for Apache configuration files. | ||
34 | 'apache-config-pattern' => "*", | ||
35 | } | ||
36 | ); | ||
37 | |||
38 | use constant EX_OK => 0; | ||
39 | use constant EX_NOTUPDATED => 1; | ||
40 | use constant EX_USAGE => 64; | ||
41 | use constant EX_NOINPUT => 66; | ||
42 | use constant EX_CANTCREAT => 73; | ||
43 | use constant EX_CONFIG => 78; | ||
28 | 44 | ||
29 | my $cnamelist = "/var/run/vhostcname.cache"; | ||
30 | my $host; # This host name. | 45 | my $host; # This host name. |
31 | my @zone; # List of acceptable DNS zones. | ||
32 | my $nameserver; # Nameserver to use for updates. | 46 | my $nameserver; # Nameserver to use for updates. |
33 | my @tsig_args; # Arguments to sing_tsig (path to the DNSSEC key file, or | ||
34 | # the key name and hash. | ||
35 | my $ttl = 3600; # Default TTL. | ||
36 | my $confdir; # Apache configuration directory. | ||
37 | my $confpat = "*"; # A globbing pattern for Apache configuration files. | ||
38 | my $dry_run; # Dry-run mode. | 47 | my $dry_run; # Dry-run mode. |
39 | my $debug; # Debug level. | 48 | my $debug; # Debug level. |
40 | my $allow_wildcard_domains; | ||
41 | 49 | ||
42 | my $help; # Display help summary. | 50 | my $status = EX_OK;# Default exit status. |
43 | my $man; # Ditto in manpage format. | ||
44 | |||
45 | my $status = 0; # Default exit status. | ||
46 | 51 | ||
47 | sub err { | 52 | sub err { |
48 | print STDERR "$script: "; | 53 | print STDERR "$progname: "; |
49 | print STDERR $_ for (@_); | 54 | print STDERR $_ for (@_); |
@@ -58,21 +63,189 @@ sub abend { | |||
58 | 63 | ||
59 | sub read_config_file($) { | 64 | sub parse_section { |
60 | my $file = shift; | 65 | my ($conf, $input) = @_; |
61 | unless (-f $file) { | 66 | my $ref = $conf; |
62 | print STDERR "$script: configuration file $file does not exist\n" | 67 | my $quote; |
63 | if ($debug); | 68 | my $rootname; |
64 | return; | 69 | while ($input ne '') { |
70 | my $name; | ||
71 | if (!defined($quote)) { | ||
72 | if ($input =~ /^"(.*)/) { | ||
73 | $quote = ''; | ||
74 | $input = $1; | ||
75 | } elsif ($input =~ /^(.+?)(?:\s+|")(.*)/) { | ||
76 | $name = $1; | ||
77 | $input = $2; | ||
78 | } else { | ||
79 | $name = $input; | ||
80 | $input = ''; | ||
81 | } | ||
82 | } else { | ||
83 | if ($input =~ /^([^\\"]*)\\(.)(.*)/) { | ||
84 | $quote .= $1 . $2; | ||
85 | $input = $3; | ||
86 | } elsif ($input =~ /^([^\\"]*)"\s*(.*)/) { | ||
87 | $name = $quote . $1; | ||
88 | $input = $2; | ||
89 | $quote = undef; | ||
90 | } else { | ||
91 | die "unparsable input $input"; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | if (defined($name)) { | ||
96 | $rootname = $name unless defined $rootname; | ||
97 | $ref->{$name} = {} unless ref($ref->{$name}) eq 'HASH'; | ||
98 | $ref = $ref->{$name}; | ||
99 | $name = undef; | ||
100 | } | ||
65 | } | 101 | } |
66 | print STDERR "$script: reading $file\n" if ($debug); | 102 | return ($ref, $rootname); |
67 | open(my $fd, "<", $file) or abend(1, "cannot open $file: $!"); | 103 | } |
104 | |||
105 | sub check_mandatory { | ||
106 | my ($section, $kw, $loc, $s) = @_; | ||
107 | my $err = 0; | ||
108 | while (my ($k, $d) = each %{$kw}) { | ||
109 | if (ref($d) eq 'HASH' | ||
110 | and $d->{mandatory} | ||
111 | and !exists($section->{$k})) { | ||
112 | if (exists($d->{section})) { | ||
113 | if ($s) { | ||
114 | err("$loc: mandatory section [$k] not present"); | ||
115 | ++$err; | ||
116 | } | ||
117 | } else { | ||
118 | err("$loc: mandatory variable \"$k\" not set"); | ||
119 | ++$err; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | return $err; | ||
124 | } | ||
125 | |||
126 | sub readconfig { | ||
127 | my $file = shift; | ||
128 | my $conf = shift; | ||
129 | my %param = @_; | ||
130 | |||
131 | # debug(2, "reading $file"); | ||
132 | open(my $fd, "<", $file) | ||
133 | or do { | ||
134 | err("can't open configuration file $file: $!"); | ||
135 | return 1 if $param{include}; | ||
136 | exit(EX_NOINPUT); | ||
137 | }; | ||
138 | |||
139 | my $line; | ||
140 | my $err; | ||
141 | my $section = $conf; | ||
142 | my $kw = $param{kw}; | ||
143 | my $include = 0; | ||
144 | my $rootname; | ||
145 | |||
68 | while (<$fd>) { | 146 | while (<$fd>) { |
69 | chomp; | 147 | ++$line; |
70 | s/^\s+//; | 148 | chomp; |
71 | s/\s+$//; | 149 | if (/\\$/) { |
72 | s/\s+=\s+/=/; | 150 | chop; |
73 | s/#.*//; | 151 | $_ .= <$fd>; |
74 | next if ($_ eq ""); | 152 | redo; |
75 | unshift(@ARGV, "--$_"); | 153 | } |
154 | |||
155 | s/^\s+//; | ||
156 | s/\s+$//; | ||
157 | s/#.*//; | ||
158 | next if ($_ eq ""); | ||
159 | |||
160 | if (/^\[(.+?)\]$/) { | ||
161 | $include = 0; | ||
162 | my $arg = $1; | ||
163 | $arg =~ s/^\s+//; | ||
164 | $arg =~ s/\s+$//; | ||
165 | if ($arg eq 'include') { | ||
166 | $include = 1; | ||
167 | } else { | ||
168 | ($section, $rootname) = parse_section($conf, $1); | ||
169 | if (ref($param{kw}) eq 'HASH') { | ||
170 | if (defined($rootname)) { | ||
171 | if (ref($param{kw}{$rootname}) eq 'HASH' | ||
172 | and exists($param{kw}{$rootname}{section})) { | ||
173 | $kw = $param{kw}{$rootname}{section}; | ||
174 | } else { | ||
175 | err("$file:$line: unknown section"); | ||
176 | $kw = undef; | ||
177 | } | ||
178 | } else { | ||
179 | $kw = $param{kw}; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | } elsif (/([\w_-]+)\s*=\s*(.*)/) { | ||
184 | my ($k, $v) = ($1, $2); | ||
185 | $k = lc($k) if $param{ci}; | ||
186 | |||
187 | if ($include) { | ||
188 | if ($k eq 'path') { | ||
189 | $err += readconfig($v, $conf, include => 1, @_); | ||
190 | } elsif ($k eq 'pathopt') { | ||
191 | $err += readconfig($v, $conf, include => 1, @_) | ||
192 | if -f $v; | ||
193 | } elsif ($k eq 'glob') { | ||
194 | foreach my $file (bsd_glob($v, 0)) { | ||
195 | $err += readconfig($file, $conf, include => 1, @_); | ||
196 | } | ||
197 | } else { | ||
198 | err("$file:$line: unknown keyword"); | ||
199 | ++$err; | ||
200 | } | ||
201 | next; | ||
202 | } | ||
203 | |||
204 | if (defined($kw)) { | ||
205 | my $x = $kw->{$k}; | ||
206 | if (!defined($x)) { | ||
207 | err("$file:$line: unknown keyword $k"); | ||
208 | ++$err; | ||
209 | next; | ||
210 | } elsif (ref($x) eq 'HASH') { | ||
211 | if (exists($x->{re})) { | ||
212 | if ($v !~ /$x->{re}/) { | ||
213 | err("$file:$line: invalid value for $k"); | ||
214 | ++$err; | ||
215 | next; | ||
216 | } | ||
217 | if (exists($x->{check}) | ||
218 | and !&{$x->{check}}($k, $v, "$file:$line")) { | ||
219 | ++$err; | ||
220 | next; | ||
221 |