diff options
Diffstat (limited to 'convert-etc-shells')
-rwxr-xr-x | convert-etc-shells | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/convert-etc-shells b/convert-etc-shells new file mode 100755 index 0000000..824de4a --- /dev/null +++ b/convert-etc-shells @@ -0,0 +1,64 @@ +#!/usr/bin/perl +# vim: shiftwidth=4 tabstop=4 +# +# Copyright 2016-2022 by Marco d'Itri <md@Linux.IT> +# +# 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. + +use warnings; +use strict; +use autodie; +use v5.16; + +convert($ARGV[0] || '/etc/shells'); +exit; + +sub convert { + my ($file) = @_; + + my (@shells, @nonusr_shells, %seen_in_usr); + + open(my $in, '<', $file); + while (<$in>) { + chomp; + push(@shells, $_); + $seen_in_usr{$1} = 1 if m#^/usr(/s?bin/.+)#; + push(@nonusr_shells, $_) if m#^/s?bin/#; + } + close $in; + + my @new_shells = # and add them to the list + map { "/usr$_" } # add /usr to their path + grep { not $seen_in_usr{$_} } # if they do not already exist in /usr + @nonusr_shells; # for each shell not in /usr + + return unless @new_shells; + + umask(0022); + open(my $out, '>', "$file.tmp"); + say $out $_ foreach @shells, @new_shells; + close $out; + + rename("$file.tmp", $file); + restore_context($file); +} + +sub safe_system { + my (@cmd) = @_; + + my $rc = system(@cmd); + die "Failed to execute @cmd: $!\n" if $rc == -1; + die "@cmd: rc=" . ($? >> 8) . "\n" if $rc; +} + +sub restore_context { + my ($file) = @_; + + return if not -x '/sbin/restorecon'; + + safe_system('restorecon', $file); +} + |