X-Git-Url: https://git.sthu.org/?a=blobdiff_plain;f=gpgdir%2Finstall.pl;fp=gpgdir%2Finstall.pl;h=95def39c3a88892f92258d051f566610c7ba774a;hb=957ed3e08d73f53b2df43e5c20c03c78f54c08f1;hp=0000000000000000000000000000000000000000;hpb=8b16f5d3cdfc8dd2886d86fabd7467c65b687c86;p=pgp-tools.git diff --git a/gpgdir/install.pl b/gpgdir/install.pl new file mode 100755 index 0000000..95def39 --- /dev/null +++ b/gpgdir/install.pl @@ -0,0 +1,450 @@ +#!/usr/bin/perl -w +# +#################################################################### +# +# File: install.pl +# +# Purpose: To install gpgdir on a Linux system. +# +# Author: Michael Rash (mbr@cipherdyne.org) +# +# Copyright (C) 2002-2008 Michael Rash (mbr@cipherdyne.org) +# +# License (GNU Public License): +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +#################################################################### +# +# $Id: install.pl 311 2008-08-31 23:11:12Z mbr $ +# + +use Cwd; +use File::Copy; +use Getopt::Long; +use strict; + +#======================= config ======================= +my $install_dir = '/usr/bin'; +my $libdir = '/usr/lib/gpgdir'; +my $manpage = 'gpgdir.1'; + +### only used it $ENV{'HOME'} is not set for some reason +my $config_homedir = ''; + +### system binaries +my $gzipCmd = '/usr/bin/gzip'; +my $perlCmd = '/usr/bin/perl'; +my $makeCmd = '/usr/bin/make'; +#===================== end config ===================== + +my $print_help = 0; +my $uninstall = 0; +my $force_mod_re = ''; +my $exclude_mod_re = ''; +my $skip_module_install = 0; +my $cmdline_force_install = 0; +my $locale = 'C'; ### default LC_ALL env variable +my $no_locale = 0; +my $deps_dir = 'deps'; + +my %cmds = ( + 'gzip' => $gzipCmd, + 'perl' => $perlCmd, + 'make' => $makeCmd +); + +### map perl modules to versions +my %required_perl_modules = ( + 'Class::MethodMaker' => { + 'force-install' => 0, + 'mod-dir' => 'Class-MethodMaker' + }, + 'GnuPG::Interface' => { + 'force-install' => 0, + 'mod-dir' => 'GnuPG-Interface' + }, + 'Term::ReadKey' => { + 'force-install' => 0, + 'mod-dir' => 'TermReadKey' + } +); + +### make Getopts case sensitive +Getopt::Long::Configure('no_ignore_case'); + +&usage(1) unless (GetOptions( + 'force-mod-install' => \$cmdline_force_install, ### force install of all modules + 'Force-mod-regex=s' => \$force_mod_re, ### force specific mod install with regex + 'Exclude-mod-regex=s' => \$exclude_mod_re, ### exclude a particular perl module + 'Skip-mod-install' => \$skip_module_install, + 'home-dir=s' => \$config_homedir, ### force a specific home dir + 'LC_ALL=s' => \$locale, + 'locale=s' => \$locale, + 'no-LC_ALL' => \$no_locale, + 'no-locale' => \$no_locale, ### synonym + 'uninstall' => \$uninstall, # Uninstall gpgdir. + 'help' => \$print_help # Display help. +)); +&usage(0) if $print_help; + +### set LC_ALL env variable +$ENV{'LC_ALL'} = $locale unless $no_locale; + +$force_mod_re = qr|$force_mod_re| if $force_mod_re; +$exclude_mod_re = qr|$exclude_mod_re| if $exclude_mod_re; + +### check to see if we are installing in a Cygwin environment +my $non_root_user = 0; +if (&is_cygwin()) { + + print +"[+] It looks like you are installing gpgdir in a Cygwin environment.\n"; + $non_root_user = 1; + +} else { + + unless ($< == 0 && $> == 0) { + print +"[+] It looks like you are installing gpgdir as a non-root user, so gpgdir\n", +" will be installed in your local home directory.\n\n"; + + $non_root_user = 1; + } +} + +if ($non_root_user) { + + ### we are installing as a normal user instead of root, so see + ### if it is ok to install within the user's home directory + my $homedir = ''; + if ($config_homedir) { + $homedir = $config_homedir; + } else { + $homedir = $ENV{'HOME'} or die '[*] Could not get home ', + "directory, set the $config_homedir var."; + } + + print +" gpgdir will be installed at $homedir/bin/gpgdir, and a few\n", +" perl modules needed by gpgdir will be installed in $homedir/lib/gpgdir/.\n\n", + + mkdir "$homedir/lib" unless -d "$homedir/lib"; + $libdir = "$homedir/lib/gpgdir"; + $install_dir = "$homedir/bin"; +} + +### make sure we can find the system binaries +### in the expected locations. +&check_commands(); + +my $src_dir = getcwd() or die "[*] Could not get current working directory."; + +### create directories, make sure executables exist, etc. +&setup(); + +print "[+] Installing gpgdir in $install_dir\n"; +&install_gpgdir(); + +### install perl modules +unless ($skip_module_install) { + for my $module (keys %required_perl_modules) { + &install_perl_module($module); + } +} +chdir $src_dir or die "[*] Could not chdir $src_dir: $!"; + +print "[+] Installing man page.\n"; +&install_manpage(); + +print "\n It is highly recommended to run the test suite in the test/\n", + " directory to ensure proper gpgdir operation.\n", + "\n[+] gpgdir has been installed!\n"; + +exit 0; +#===================== end main ======================= + +sub install_gpgdir() { + die "[*] gpgdir does not exist. Download gpgdir from " . + "http://www.cipherdyne.org/gpgdir" unless -e 'gpgdir'; + copy 'gpgdir', "${install_dir}/gpgdir" or die "[*] Could not copy " . + "gpgdir to $install_dir: $!"; + + if ($non_root_user) { + open F, "< ${install_dir}/gpgdir" or die "[*] Could not open ", + "${install_dir}/gpgdir: $!"; + my @lines = ; + close F; + open P, "> ${install_dir}/gpgdir.tmp" or die "[*] Could not open ", + "${install_dir}/gpgdir.tmp: $!"; + for my $line (@lines) { + ### change the lib dir to new homedir path + if ($line =~ m|^\s*use\s+lib\s+\'/usr/lib/gpgdir\';|) { + print P "use lib '", $libdir, "';\n"; + } else { + print P $line; + } + } + close P; + move "${install_dir}/gpgdir.tmp", "${install_dir}/gpgdir" or + die "[*] Could not move ${install_dir}/gpgdir.tmp -> ", + "${install_dir}/gpgdir: $!"; + + chmod 0700, "${install_dir}/gpgdir" or die "[*] Could not set " . + "permissions on gpgdir to 0755"; + } else { + chmod 0755, "${install_dir}/gpgdir" or die "[*] Could not set " . + "permissions on gpgdir to 0755"; + chown 0, 0, "${install_dir}/gpgdir" or + die "[*] Could not chown 0,0,${install_dir}/gpgdir: $!"; + } + return; +} + +sub install_perl_module() { + my $mod_name = shift; + + chdir $src_dir or die "[*] Could not chdir $src_dir: $!"; + chdir $deps_dir or die "[*] Could not chdir($deps_dir): $!"; + + die '[*] Missing force-install key in required_perl_modules hash.' + unless defined $required_perl_modules{$mod_name}{'force-install'}; + die '[*] Missing mod-dir key in required_perl_modules hash.' + unless defined $required_perl_modules{$mod_name}{'mod-dir'}; + + if ($exclude_mod_re and $exclude_mod_re =~ /$mod_name/) { + print "[+] Excluding installation of $mod_name module.\n"; + return; + } + + my $version = '(NA)'; + + my $mod_dir = $required_perl_modules{$mod_name}{'mod-dir'}; + + if (-e "$mod_dir/VERSION") { + open F, "< $mod_dir/VERSION" or + die "[*] Could not open $mod_dir/VERSION: $!"; + $version = ; + close F; + chomp $version; + } else { + print "[-] Warning: VERSION file does not exist in $mod_dir\n"; + } + + my $install_module = 0; + + if ($required_perl_modules{$mod_name}{'force-install'} + or $cmdline_force_install) { + ### install regardless of whether the module may already be + ### installed + $install_module = 1; + } elsif ($force_mod_re and $force_mod_re =~ /$mod_name/) { + print "[+] Forcing installation of $mod_name module.\n"; + $install_module = 1; + } else { + if (has_perl_module($mod_name)) { + print "[+] Module $mod_name is already installed in the ", + "system perl tree, skipping.\n"; + } else { + ### install the module in the /usr/lib/gpgdir directory because + ### it is not already installed. + $install_module = 1; + } + } + + if ($install_module) { + unless (-d $libdir) { + print "[+] Creating $libdir\n"; + mkdir $libdir, 0755 or die "[*] Could not mkdir $libdir: $!"; + } + print "[+] Installing the $mod_name $version perl " . + "module in $libdir/\n"; + my $mod_dir = $required_perl_modules{$mod_name}{'mod-dir'}; + chdir $mod_dir or die "[*] Could not chdir to ", + "$mod_dir: $!"; + unless (-e 'Makefile.PL') { + die "[*] Your $mod_name source directory appears to be incomplete!\n", + " Download the latest sources from ", + "http://www.cipherdyne.org/\n"; + } + system "$cmds{'make'} clean" if -e 'Makefile'; + system "$cmds{'perl'} Makefile.PL PREFIX=$libdir LIB=$libdir"; + system $cmds{'make'}; +# system "$cmds{'make'} test"; + system "$cmds{'make'} install"; + chdir $src_dir or die "[*] Could not chdir $src_dir: $!"; + + print "\n\n"; + } + chdir $src_dir or die "[*] Could not chdir $src_dir: $!"; + return; +} + +sub has_perl_module() { + my $module = shift; + + # 5.8.0 has a bug with require Foo::Bar alone in an eval, so an + # extra statement is a workaround. + my $file = "$module.pm"; + $file =~ s{::}{/}g; + eval { require $file }; + + return $@ ? 0 : 1; +} + +sub install_manpage() { + + if ($non_root_user) { + print +"[+] Because this is a non-root install, the man page will not be installed\n", +" but you can download it here: http://www.cipherdyne.org/gpgdir\n\n"; + return; + } + + die "[*] man page: $manpage does not exist. Download gpgdir " . + "from http://www.cipherdyne.org/gpgdir" unless -e $manpage; + ### default location to put the gpgdir man page, but check with + ### /etc/man.config + my $mpath = '/usr/share/man/man1'; + if (-e '/etc/man.config') { + ### prefer to install $manpage in /usr/local/man/man1 if + ### this directory is configured in /etc/man.config + open M, '< /etc/man.config' or + die "[*] Could not open /etc/man.config: $!"; + my @lines = ; + close M; + ### prefer the path "/usr/share/man" + my $found = 0; + for my $line (@lines) { + chomp $line; + if ($line =~ m|^MANPATH\s+/usr/share/man|) { + $found = 1; + last; + } + } + ### try to find "/usr/local/man" if we didn't find /usr/share/man + unless ($found) { + for my $line (@lines) { + chomp $line; + if ($line =~ m|^MANPATH\s+/usr/local/man|) { + $mpath = '/usr/local/man/man1'; + $found = 1; + last; + } + } + } + ### if we still have not found one of the above man paths, + ### just select the first one out of /etc/man.config + unless ($found) { + for my $line (@lines) { + chomp $line; + if ($line =~ m|^MANPATH\s+(\S+)|) { + $mpath = $1; + last; + } + } + } + } + mkdir $mpath, 0755 unless -d $mpath; + my $mfile = "${mpath}/${manpage}"; + print "[+] Installing $manpage man page as: $mfile\n"; + copy $manpage, $mfile or die "[*] Could not copy $manpage to " . + "$mfile: $!"; + chmod 0644, $mfile or die "[*] Could not set permissions on ". + "$mfile to 0644"; + chown 0, 0, $mfile or + die "[*] Could not chown 0,0,$mfile: $!"; + print "[+] Compressing man page: $mfile\n"; + ### remove the old one so gzip doesn't prompt us + unlink "${mfile}.gz" if -e "${mfile}.gz"; + system "$cmds{'gzip'} $mfile"; + return; +} + +### check paths to commands and attempt to correct if any are wrong. +sub check_commands() { + my @path = qw( + /bin + /sbin + /usr/bin + /usr/sbin + /usr/local/bin + /usr/local/sbin + ); + CMD: for my $cmd (keys %cmds) { + unless (-x $cmds{$cmd}) { + my $found = 0; + PATH: for my $dir (@path) { + if (-x "${dir}/${cmd}") { + $cmds{$cmd} = "${dir}/${cmd}"; + $found = 1; + last PATH; + } + } + unless ($found) { + die "[*] Could not find $cmd anywhere!!! ", + "Please edit the config section to include the path to ", + "$cmd.\n"; + } + } + unless (-x $cmds{$cmd}) { + die "[*] $cmd is located at ", + "$cmds{$cmd} but is not executable by uid: $<\n"; + } + } + return; +} + +sub is_cygwin() { + + my $rv = 0; + + ### get OS output from uname + open UNAME, "uname -o |" or return $rv; + while () { + $rv = 1 if /Cygwin/; + } + close UNAME; + + return $rv; +} + + +sub setup() { + unless (-d $libdir) { + mkdir $libdir, 0755 or die "[*] Could not create $libdir: $!" + } + return; +} + +sub usage() { + my $exit_status = shift; + print <<_HELP_; + +Usage: install.pl [options] + + -u, --uninstall - Uninstall gpgdir. + -f, --force-mod-install - Force all perl modules to be installed + even if some already exist in the system + /usr/lib/perl5 tree. + -F, --Force-mod-regex - Specify a regex to match a module name + and force the installation of such modules. + -E, --Exclude-mod-regex - Exclude a perl module that matches this + regular expression. + -S, --Skip-mod-install - Do not install any perl modules. + + -L, --LANG - Specify LANG env variable (actually the + LC_ALL variable). + -h --help - Prints this help message. + +_HELP_ + exit $exit_status; +}