diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-06-18 12:41:32 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-06-18 12:41:32 +0300 |
commit | fb0cd0f84d0ecfba0c5a5b0045eee0ede0477a0e (patch) | |
tree | 30229f5483a036ffc3c21e429d7caa94587e1478 | |
parent | e30ddffa198dedeed50c1d9e2bbb98cabbec2eae (diff) | |
download | netsnmp-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-x | netsnmp-sendmail-setup | 213 |
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> |