aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-06-18 12:41:32 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-06-18 12:41:32 +0300
commitfb0cd0f84d0ecfba0c5a5b0045eee0ede0477a0e (patch)
tree30229f5483a036ffc3c21e429d7caa94587e1478
parente30ddffa198dedeed50c1d9e2bbb98cabbec2eae (diff)
downloadnetsnmp-sendmail-fb0cd0f84d0ecfba0c5a5b0045eee0ede0477a0e.tar.gz
netsnmp-sendmail-fb0cd0f84d0ecfba0c5a5b0045eee0ede0477a0e.tar.bz2
Update netsnmp-sendmail-setup
* netsnmp-sendmail-setup: Add --deconfigure option: remove previosly added configuration statements.
-rwxr-xr-xnetsnmp-sendmail-setup213
1 files changed, 153 insertions, 60 deletions
diff --git a/netsnmp-sendmail-setup b/netsnmp-sendmail-setup
index 86e8002..5e49ad6 100755
--- a/netsnmp-sendmail-setup
+++ b/netsnmp-sendmail-setup
@@ -3,3 +3,3 @@
# This file is part of NetSNMP::Sendmail
-# Copyright (C) 2019 Sergey Poznyakoff <gray@gnu.org>
+# Copyright (C) 2019-2020 Sergey Poznyakoff <gray@gnu.org>
#
@@ -37,2 +37,4 @@ sub addts {
+my $my_ts_rx = qr{^# Line added by $0 at };
+
use constant {
@@ -44,5 +46,9 @@ use constant {
+use constant {
+ CMD_SETUP => 0,
+ CMD_REMOVE => 1
+};
+
my $suppress_level = 0;
my $dry_run;
-my $changed = 0;
my @updated_services;
@@ -56,3 +62,3 @@ use constant {
-use constant MAX_SUPPRESS_LEVEL => L_NOTICE;
+use constant MAX_SUPPRESS_LEVEL => L_WARN;
@@ -98,2 +104,37 @@ sub restart_service {
+sub file_replace {
+ my ($file, $newfile) = @_;
+ my $bk = "$file~";
+ unlink $bk if -e $bk;
+ rename $file, $bk or die "can't rename $file to $bk: $!";
+ unless (rename $newfile, $file) {
+ printlog(L_WARN,
+ "can't rename $newfile to $file: $!; restoring from backup");
+ unless (rename $bk, $file) {
+ printlog(L_ERR, "failed to rename $bk to $file: $!");
+ exit(EX_FATAL);
+ }
+ }
+}
+
+sub file_remline {
+ my ($file, $fd, $line, $endline) = @_;
+ $endline //= $line;
+ printlog(L_NOTICE,
+ ($endline == $line) ? "editing $file: removing line $line"
+ : "editing $file: removing lines $line-$endline");
+ return if $dry_run;
+ my $ofd = File::Temp->new(DIR => dirname($file), UNLINK => $dry_run);
+ seek($fd, 0, SEEK_SET) or die "seek $file: $!";
+ my $ln = 0;
+ while (<$fd>) {
+ $ln++;
+ next if ($line <= $ln && $ln <= $endline);
+ print $ofd $_;
+ }
+ close $ofd;
+ close $fd;
+ file_replace($file, $ofd->filename);
+}
+
sub scan_snmpd_conf {
@@ -109,6 +150,16 @@ sub scan_snmpd_conf {
s/^\s+//;
+
+ if (/$my_ts_rx/) {
+ $comline = $line;
+ next;
+ }
+
if (/^perl\s+use\s+NetSNMP::Sendmail/) {
- printlog(L_INFO, "$file:$line: NetSNMP::Sendmail already enabled");
- return;
+ if ($comline && $comline + 1 == $line) {
+ return (1, $comline, $line);
+ } else {
+ return (1, $line);
+ }
}
+
if (/^perl\s+use/) {
@@ -117,3 +168,3 @@ sub scan_snmpd_conf {
}
- return $insert_line || $line + 1;
+ return (0, $insert_line || $line + 1);
}
@@ -142,4 +193,4 @@ sub update_snmpd_conf {
}
- $changed++;
- return $ofd;
+ close $ofd;
+ file_replace($ifile, $ofd->filename) unless ($dry_run);
}
@@ -147,21 +198,16 @@ sub update_snmpd_conf {
sub edit_snmpd_conf {
- my ($name, $stmt) = @_;
+ my ($command, $name, $stmt) = @_;
my $u = umask(077);
if (open(my $fd, '<', $name)) {
- if (defined(my $insert_line = scan_snmpd_conf($name, $fd))) {
- my $fh = update_snmpd_conf($name, $fd, $insert_line, $stmt);
- unless ($dry_run) {
- my $bk = "$name~";
- unlink $bk if -e $bk;
- rename $name, $bk or die "can't rename $name to $bk: $!";
- unless (rename $fh->filename, $name) {
- printlog(L_WARN,
- "can't rename ".$fh->filename." to $name: $!; restoring from backup");
- unless (rename $bk, $name) {
- printlog(L_ERR, "failed to rename $bk to $name: $!");
- exit(EX_FATAL);
- }
- }
+ my ($found, $line, $endline) = scan_snmpd_conf($name, $fd);
+ if ($command == CMD_SETUP) {
+ if ($found) {
+ printlog(L_INFO, "$name:".($endline ? $endline : $line).": NetSNMP::Sendmail already enabled");
+ } else {
+ update_snmpd_conf($name, $fd, $line, $stmt);
+ push @updated_services, 'snmpd';
}
- push @updated_services, 'snmpd';
+ } elsif ($found) {
+ file_remline($name, $fd, $line, $endline);
+ push @updated_services, 'snmpd';
}
@@ -212,10 +258,21 @@ sub scan_sendmail_mc {
my $last_nl;
+ my $comline;
+ my $line = 0;
while (<$fd>) {
+ $line++;
$last_nl = chomp;
s/^\s+//;
+
+ if (/$my_ts_rx/) {
+ $comline = $line;
+ next;
+ }
if (/^define\(\s*`?STATUS_FILE'?\s*,\s*`?(.+?)'?\s*\)/) {
$name = $1;
+ last
}
}
- return ($name, $last_nl);
+
+ return ($name, $last_nl,
+ ($comline && $comline + 1 == $line) ? ($comline, $line) : ($line));
}
@@ -223,35 +280,47 @@ sub scan_sendmail_mc {
sub edit_sendmail_mc {
- my $file = shift;
+ my ($command, $file, $default_statfile) = @_;
if (open(my $fd, '+<', $file)) {
my $need_make;
- my ($statfile, $last_nl) = scan_sendmail_mc($fd);
- if ($statfile) {
- printlog(L_INFO, "status file $statfile");
- } else {
- $statfile = shift;
- printlog(L_NOTICE, "editing $file");
- unless ($dry_run) {
- seek($fd, 0, SEEK_END) or die "seek: $!";
- print $fd "\n" unless $last_nl;
- addts $fd;
- print $fd "define(`STATUS_FILE', `$statfile')\n";
+ my ($statfile, $last_nl, $line, $endline) = scan_sendmail_mc($fd);
+ if ($command == CMD_SETUP) {
+ if ($statfile) {
+ printlog(L_INFO,
+ "$file:".($endline ? $endline : $line).
+ ": status file $statfile already enabled");
+ } else {
+ $statfile = $default_statfile;
+ printlog(L_NOTICE, "editing $file");
+ unless ($dry_run) {
+ seek($fd, 0, SEEK_END) or die "seek: $!";
+ print $fd "\n" unless $last_nl;
+ addts $fd;
+ print $fd "define(`STATUS_FILE', `$statfile')\n";
+ }
+ push @updated_services, 'sendmail';
+ $need_make = !$dry_run;
}
- push @updated_services, 'sendmail';
- $need_make = 1;
- $changed++;
- }
- close $fd;
- if (-f $statfile) {
- printlog(L_INFO, "$statfile exists");
- } else {
- printlog(L_NOTICE, "creating $statfile");
- unless ($dry_run) {
- if (open($fd, '>', $statfile)) {
- close($fd);
- } else {
- warn "failed to create $statfile: $!";
+ if (-f $statfile) {
+ printlog(L_INFO, "$statfile exists");
+ } else {
+ printlog(L_NOTICE, "creating $statfile");
+ unless ($dry_run) {
+ if (open($fd, '>', $statfile)) {
+ close($fd);
+ } else {
+ warn "failed to create $statfile: $!";
+ }
}
}
+ } elsif ($statfile) {
+ if ($endline) {
+ file_remline($file, $fd, $line, $endline);
+ push @updated_services, 'sendmail';
+ $need_make = !$dry_run;
+ } else {
+ printlog(L_INFO,
+ "$file:$line: retaining status file setup: not configured by $0");
+ }
}
+ close $fd;
@@ -276,2 +345,4 @@ my $sendmail_bindir;
+my $command = CMD_SETUP;
+
GetOptions('quiet|q+' => \$suppress_level,
@@ -281,5 +352,7 @@ GetOptions('quiet|q+' => \$suppress_level,
'restart=s' => sub {
- my ($name,$command) = split /=/, $_[1], 2;
- $restart_override{$name} = $command;
+ my ($name,$cmd) = split /=/, $_[1], 2;
+ $restart_override{$name} = $cmd;
},
+ 'configure' => sub { $command = CMD_SETUP },
+ 'deconfigure' => sub { $command = CMD_REMOVE },
'help' => sub {
@@ -300,5 +373,5 @@ if ($suppress_level > MAX_SUPPRESS_LEVEL) {
check_module;
-check_file $snmpd_conf;
-check_file $sendmail_mc;
-check_file '/etc/mail/Makefile';
+check_file($snmpd_conf);
+check_file($sendmail_mc);
+check_file('/etc/mail/Makefile');
@@ -316,4 +389,4 @@ $stmt .= ';';
-edit_sendmail_mc($sendmail_mc, $sendmail_statfile);
-edit_snmpd_conf($snmpd_conf, $stmt);
+edit_sendmail_mc($command, $sendmail_mc, $sendmail_statfile);
+edit_snmpd_conf($command, $snmpd_conf, $stmt);
@@ -321,3 +394,3 @@ map { restart_service($_) } @updated_services;
-exit($changed ? EX_OK : EX_UNCHANGED);
+exit(@updated_services ? EX_OK : EX_UNCHANGED);
@@ -333,2 +406,4 @@ B<netsnmp-sendmail-setup>
[B<--bindir=I<DIR>>]
+[B<--configure>]
+[B<--deconfigure>]
[B<--dry-run>]
@@ -337,3 +412,3 @@ B<netsnmp-sendmail-setup>
[B<--restart=I<service>=I<command>>]
-
+
B<netsnmp-sendmail-setup> B<--help> | B<--usage>
@@ -348,2 +423,11 @@ directory. Finally, the file F</etc/snmp/snmpd.conf> is scanned for the
B<perl use NetSNMP::Sendmail> statement. It is added if not already present.
+Each added configuration line is preceded by a comment stating that it
+was added by the script.
+
+When run with the B<--deconfigure> option, the reverse operation is
+performed. The B<NetSNMP::Sendmail> configuration statement is removed
+from the snmpd configuration unconditionally. The B<STATUS_FILE> clause
+is removed from F</etc/mail/sendmail.mc> only if it is preceded by the
+B<netsnmp-sendmail-setup> comment marker. The status file itself is
+never removed.
@@ -362,2 +446,11 @@ directory is picked up automatically.
+=item B<--configure>
+
+A no-op option included for symmetry with B<--deconfigure>.
+
+=item B<--deconfigure>
+
+Remove the configuration statements previously added to the snmdp and
+sendmail configuration files.
+
=item B<-n>, B<--dry-run>

Return to:

Send suggestions and report system problems to the System administrator.