aboutsummaryrefslogtreecommitdiff
path: root/netsnmp-sendmail-setup
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 /netsnmp-sendmail-setup
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.
Diffstat (limited to 'netsnmp-sendmail-setup')
-rwxr-xr-xnetsnmp-sendmail-setup171
1 files changed, 132 insertions, 39 deletions
diff --git a/netsnmp-sendmail-setup b/netsnmp-sendmail-setup
index 86e8002..5e49ad6 100755
--- a/netsnmp-sendmail-setup
+++ b/netsnmp-sendmail-setup
@@ -1,7 +1,7 @@
#!/bin/sh
#! -*-perl-*-
# This file is part of NetSNMP::Sendmail
-# Copyright (C) 2019 Sergey Poznyakoff <gray@gnu.org>
+# Copyright (C) 2019-2020 Sergey Poznyakoff <gray@gnu.org>
#
# 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
@@ -35,6 +35,8 @@ sub addts {
. "\n";
}
+my $my_ts_rx = qr{^# Line added by $0 at };
+
use constant {
EX_OK => 0, # Success
EX_UNCHANGED => 1, # Files not changed
@@ -42,9 +44,13 @@ use constant {
EX_USAGE => 64 # Usage error
};
+use constant {
+ CMD_SETUP => 0,
+ CMD_REMOVE => 1
+};
+
my $suppress_level = 0;
my $dry_run;
-my $changed = 0;
my @updated_services;
use constant {
@@ -54,7 +60,7 @@ use constant {
L_ERR => 3
};
-use constant MAX_SUPPRESS_LEVEL => L_NOTICE;
+use constant MAX_SUPPRESS_LEVEL => L_WARN;
sub printlog {
my $level = shift;
@@ -96,6 +102,41 @@ 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 {
my ($file, $fd) = @_;
@@ -107,15 +148,25 @@ sub scan_snmpd_conf {
++$line;
chomp;
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/) {
$insert_line = $line;
}
}
- return $insert_line || $line + 1;
+ return (0, $insert_line || $line + 1);
}
sub update_snmpd_conf {
@@ -140,29 +191,24 @@ sub update_snmpd_conf {
addts $ofd;
print $ofd "$stmt\n";
}
- $changed++;
- return $ofd;
+ close $ofd;
+ file_replace($ifile, $ofd->filename) unless ($dry_run);
}
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';
}
+ } elsif ($found) {
+ file_remline($name, $fd, $line, $endline);
push @updated_services, 'snmpd';
}
close $fd;
@@ -210,25 +256,39 @@ sub scan_sendmail_mc {
my $fd = shift;
my $name;
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));
}
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);
+ my ($statfile, $last_nl, $line, $endline) = scan_sendmail_mc($fd);
+ if ($command == CMD_SETUP) {
if ($statfile) {
- printlog(L_INFO, "status file $statfile");
+ printlog(L_INFO,
+ "$file:".($endline ? $endline : $line).
+ ": status file $statfile already enabled");
} else {
- $statfile = shift;
+ $statfile = $default_statfile;
printlog(L_NOTICE, "editing $file");
unless ($dry_run) {
seek($fd, 0, SEEK_END) or die "seek: $!";
@@ -237,10 +297,8 @@ sub edit_sendmail_mc {
print $fd "define(`STATUS_FILE', `$statfile')\n";
}
push @updated_services, 'sendmail';
- $need_make = 1;
- $changed++;
+ $need_make = !$dry_run;
}
- close $fd;
if (-f $statfile) {
printlog(L_INFO, "$statfile exists");
@@ -254,6 +312,17 @@ sub edit_sendmail_mc {
}
}
}
+ } 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;
if ($need_make) {
my $sendmail_dir = dirname($file);
@@ -274,14 +343,18 @@ my $sendmail_mc = '/etc/mail/sendmail.mc';
my $sendmail_statfile = '/etc/mail/sendmail.st';
my $sendmail_bindir;
+my $command = CMD_SETUP;
+
GetOptions('quiet|q+' => \$suppress_level,
'dry-run|n' => \$dry_run,
'status-file=s' => \$sendmail_statfile,
'bindir=s' => \$sendmail_bindir,
'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 {
pod2usage(-exitstatus => EX_OK, -verbose => 2);
},
@@ -298,9 +371,9 @@ 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');
unless ($sendmail_bindir) {
if (-d "/usr/lib/sm.bin") {
@@ -314,12 +387,12 @@ if ($sendmail_bindir) {
}
$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);
map { restart_service($_) } @updated_services;
-exit($changed ? EX_OK : EX_UNCHANGED);
+exit(@updated_services ? EX_OK : EX_UNCHANGED);
__END__
=head1 NAME
@@ -331,6 +404,8 @@ netsnmp-sendmail-setup - sets up Sendmail monitoring via SNMP
B<netsnmp-sendmail-setup>
[B<-nq>]
[B<--bindir=I<DIR>>]
+[B<--configure>]
+[B<--deconfigure>]
[B<--dry-run>]
[B<--status-file=I<FILE>>]
[B<--quiet>]
@@ -346,6 +421,15 @@ F</etc/mail/sendmail.mc> contains the B<STATUS_FILE> clause and adds it
if not. Then, it creates the status file and runs B<make> in the F</etc/mail>
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.
=head1 OPTIONS
@@ -360,6 +444,15 @@ inform B<NetSNMP::Sendmail> about this.
Notice for the users of Debian-based systems: the F</usr/lib/sm.bin>
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>
Dry run mode. Don't modify any files, just print what would have been done

Return to:

Send suggestions and report system problems to the System administrator.