--- /dev/null
+#!/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 = <F>;
+ 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 = <F>;
+ 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 = <M>;
+ 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 (<UNAME>) {
+ $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 <re> - Specify a regex to match a module name
+ and force the installation of such modules.
+ -E, --Exclude-mod-regex <re> - Exclude a perl module that matches this
+ regular expression.
+ -S, --Skip-mod-install - Do not install any perl modules.
+
+ -L, --LANG <locale> - Specify LANG env variable (actually the
+ LC_ALL variable).
+ -h --help - Prints this help message.
+
+_HELP_
+ exit $exit_status;
+}