root/gpgdir/tags/gpgdir-1.8/install.pl

Revision 268, 13.4 kB (checked in by mbr, 9 months ago)

minor addition to mention the test suite

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2 #
3 ####################################################################
4 #
5 # File: install.pl
6 #
7 # Purpose: To install gpgdir on a Linux system.
8 #
9 # Author: Michael Rash (mbr@cipherdyne.org)
10 #
11 # Copyright (C) 2002-2008 Michael Rash (mbr@cipherdyne.org)
12 #
13 # License (GNU Public License):
14 #
15 #    This program is distributed in the hope that it will be useful,
16 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 #    GNU General Public License for more details.
19 #
20 #    You should have received a copy of the GNU General Public License
21 #    along with this program; if not, write to the Free Software
22 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
23 #    USA
24 #
25 ####################################################################
26 #
27 # $Id$
28 #
29
30 use Cwd;
31 use File::Copy;
32 use Getopt::Long;
33 use strict;
34
35 #======================= config =======================
36 my $install_dir = '/usr/bin';
37 my $libdir      = '/usr/lib/gpgdir';
38 my $manpage     = 'gpgdir.1';
39
40 ### only used it $ENV{'HOME'} is not set for some reason
41 my $config_homedir = '';
42
43 ### system binaries
44 my $gzipCmd = '/usr/bin/gzip';
45 my $perlCmd = '/usr/bin/perl';
46 my $makeCmd = '/usr/bin/make';
47 #===================== end config =====================
48
49 my $print_help = 0;
50 my $uninstall  = 0;
51 my $force_mod_re  = '';
52 my $exclude_mod_re  = '';
53 my $skip_module_install   = 0;
54 my $cmdline_force_install = 0;
55 my $locale = 'C'### default LC_ALL env variable
56 my $no_locale = 0;
57
58 my %cmds = (
59     'gzip' => $gzipCmd,
60     'perl' => $perlCmd,
61     'make' => $makeCmd
62 );
63
64 ### map perl modules to versions
65 my %required_perl_modules = (
66     'Class::MethodMaker' => {
67         'force-install' => 0,
68         'mod-dir' => 'Class-MethodMaker'
69     },
70     'GnuPG::Interface' => {
71         'force-install' => 0,
72         'mod-dir' => 'GnuPG-Interface'
73     },
74     'Term::ReadKey' => {
75         'force-install' => 0,
76         'mod-dir' => 'TermReadKey'
77     }
78 );
79
80 ### make Getopts case sensitive
81 Getopt::Long::Configure('no_ignore_case');
82
83 &usage(1) unless (GetOptions(
84     'force-mod-install' => \$cmdline_force_install,  ### force install of all modules
85     'Force-mod-regex=s' => \$force_mod_re,  ### force specific mod install with regex
86     'Exclude-mod-regex=s' => \$exclude_mod_re, ### exclude a particular perl module
87     'Skip-mod-install'  => \$skip_module_install,
88     'home-dir=s'        => \$config_homedir, ### force a specific home dir
89     'LC_ALL=s'          => \$locale,
90     'no-LC_ALL'         => \$no_locale,
91     'uninstall' => \$uninstall,      # Uninstall gpgdir.
92     'help'      => \$print_help      # Display help.
93 ));
94 &usage(0) if $print_help;
95
96 ### set LC_ALL env variable
97 $ENV{'LC_ALL'} = $locale unless $no_locale;
98
99 $force_mod_re = qr|$force_mod_re| if $force_mod_re;
100 $exclude_mod_re = qr|$exclude_mod_re| if $exclude_mod_re;
101
102 ### check to see if we are installing in a Cygwin environment
103 my $non_root_user = 0;
104 if (&is_cygwin()) {
105
106     print
107 "[+] It looks like you are installing gpgdir in a Cygwin environment.\n";
108     $non_root_user = 1;
109
110 } else {
111
112     unless ($< == 0 && $> == 0) {
113         print
114 "[+] It looks like you are installing gpgdir as a non-root user, so gpgdir\n",
115 "    will be installed in your local home directory.\n\n";
116
117         $non_root_user = 1;
118     }
119 }
120
121 if ($non_root_user) {
122
123     ### we are installing as a normal user instead of root, so see
124     ### if it is ok to install within the user's home directory
125     my $homedir = '';
126     if ($config_homedir) {
127         $homedir = $config_homedir;
128     } else {
129         $homedir = $ENV{'HOME'} or die '[*] Could not get home ',
130             "directory, set the $config_homedir var.";
131     }
132
133     print
134 "    gpgdir will be installed at $homedir/bin/gpgdir, and a few\n",
135 "    perl modules needed by gpgdir will be installed in $homedir/lib/gpgdir/.\n\n",
136
137     mkdir "$homedir/lib" unless -d "$homedir/lib";
138     $libdir = "$homedir/lib/gpgdir";
139     $install_dir = "$homedir/bin";
140 }
141
142 ### make sure we can find the system binaries
143 ### in the expected locations.
144 &check_commands();
145
146 my $src_dir = getcwd() or die "[*] Could not get current working directory.";
147
148 ### create directories, make sure executables exist, etc.
149 &setup();
150
151 print "[+] Installing gpgdir in $install_dir\n";
152 &install_gpgdir();
153
154 ### install perl modules
155 unless ($skip_module_install) {
156     for my $module (keys %required_perl_modules) {
157         &install_perl_module($module);
158     }
159 }
160
161 print "[+] Installing man page.\n";
162 &install_manpage();
163
164 print "\n    It is highly recommended to run the test suite in the test/\n",
165     "    directory to ensure proper gpgdir operation.\n",
166     "\n[+] gpgdir has been installed!\n";
167
168 exit 0;
169 #===================== end main =======================
170
171 sub install_gpgdir() {
172     die "[*] gpgdir does not exist.  Download gpgdir from " .
173         "http://www.cipherdyne.org/gpgdir" unless -e 'gpgdir';
174     copy 'gpgdir', "${install_dir}/gpgdir" or die "[*] Could not copy " .
175         "gpgdir to $install_dir: $!";
176
177     if ($non_root_user) {
178         open F, "< ${install_dir}/gpgdir" or die "[*] Could not open ",
179             "${install_dir}/gpgdir: $!";
180         my @lines = <F>;
181         close F;
182         open P, "> ${install_dir}/gpgdir.tmp" or die "[*] Could not open ",
183             "${install_dir}/gpgdir.tmp: $!";
184         for my $line (@lines) {
185             ### change the lib dir to new homedir path
186             if ($line =~ m|^\s*use\s+lib\s+\'/usr/lib/gpgdir\';|) {
187                 print P "use lib '", $libdir, "';\n";
188             } else {
189                 print P $line;
190             }
191         }
192         close P;
193         move "${install_dir}/gpgdir.tmp", "${install_dir}/gpgdir" or
194             die "[*] Could not move ${install_dir}/gpgdir.tmp -> ",
195                 "${install_dir}/gpgdir: $!";
196
197         chmod 0700, "${install_dir}/gpgdir" or die "[*] Could not set " .
198             "permissions on gpgdir to 0755";
199     } else {
200         chmod 0755, "${install_dir}/gpgdir" or die "[*] Could not set " .
201             "permissions on gpgdir to 0755";
202         chown 0, 0, "${install_dir}/gpgdir" or
203             die "[*] Could not chown 0,0,${install_dir}/gpgdir: $!";
204     }
205     return;
206 }
207
208 sub install_perl_module() {
209     my $mod_name = shift;
210
211     die '[*] Missing force-install key in required_perl_modules hash.'
212         unless defined $required_perl_modules{$mod_name}{'force-install'};
213     die '[*] Missing mod-dir key in required_perl_modules hash.'
214         unless defined $required_perl_modules{$mod_name}{'mod-dir'};
215
216     if ($exclude_mod_re and $exclude_mod_re =~ /$mod_name/) {
217         print "[+] Excluding installation of $mod_name module.\n";
218         return;
219     }
220
221     my $version = '(NA)';
222
223     my $mod_dir = $required_perl_modules{$mod_name}{'mod-dir'};
224
225     if (-e "$mod_dir/VERSION") {
226         open F, "< $mod_dir/VERSION" or
227             die "[*] Could not open $mod_dir/VERSION: $!";
228         $version = <F>;
229         close F;
230         chomp $version;
231     } else {
232         print "[-] Warning: VERSION file does not exist in $mod_dir\n";
233     }
234
235     my $install_module = 0;
236
237     if ($required_perl_modules{$mod_name}{'force-install'}
238             or $cmdline_force_install) {
239         ### install regardless of whether the module may already be
240         ### installed
241         $install_module = 1;
242     } elsif ($force_mod_re and $force_mod_re =~ /$mod_name/) {
243         print "[+] Forcing installation of $mod_name module.\n";
244         $install_module = 1;
245     } else {
246         if (has_perl_module($mod_name)) {
247             print "[+] Module $mod_name is already installed in the ",
248                 "system perl tree, skipping.\n";
249         } else {
250             ### install the module in the /usr/lib/gpgdir directory because
251             ### it is not already installed.
252             $install_module = 1;
253         }
254     }
255
256     if ($install_module) {
257         unless (-d $libdir) {
258             print "[+] Creating $libdir\n";
259             mkdir $libdir, 0755 or die "[*] Could not mkdir $libdir: $!";
260         }
261         print "[+] Installing the $mod_name $version perl " .
262             "module in $libdir/\n";
263         my $mod_dir = $required_perl_modules{$mod_name}{'mod-dir'};
264         chdir $mod_dir or die "[*] Could not chdir to ",
265             "$mod_dir: $!";
266         unless (-e 'Makefile.PL') {
267             die "[*] Your $mod_name source directory appears to be incomplete!\n",
268                 "    Download the latest sources from ",
269                 "http://www.cipherdyne.org/\n";
270         }
271         system "$cmds{'make'} clean" if -e 'Makefile';
272         system "$cmds{'perl'} Makefile.PL PREFIX=$libdir LIB=$libdir";
273         system $cmds{'make'};
274 #        system "$cmds{'make'} test";
275         system "$cmds{'make'} install";
276         chdir $src_dir or die "[*] Could not chdir $src_dir: $!";
277
278         print "\n\n";
279     }
280     return;
281 }
282
283 sub has_perl_module() {
284     my $module = shift;
285
286     # 5.8.0 has a bug with require Foo::Bar alone in an eval, so an
287     # extra statement is a workaround.
288     my $file = "$module.pm";
289     $file =~ s{::}{/}g;
290     eval { require $file };
291
292     return $@ ? 0 : 1;
293 }
294
295 sub install_manpage() {
296
297     if ($non_root_user) {
298         print
299 "[+] Because this is a non-root install, the man page will not be installed\n",
300 "    but you can download it here:  http://www.cipherdyne.org/gpgdir\n\n";
301         return;
302     }
303
304     die "[*] man page: $manpage does not exist.  Download gpgdir " .
305         "from http://www.cipherdyne.org/gpgdir" unless -e $manpage;
306     ### default location to put the gpgdir man page, but check with
307     ### /etc/man.config
308     my $mpath = '/usr/share/man/man1';
309     if (-e '/etc/man.config') {
310         ### prefer to install $manpage in /usr/local/man/man1 if
311         ### this directory is configured in /etc/man.config
312         open M, '< /etc/man.config' or
313             die "[*] Could not open /etc/man.config: $!";
314         my @lines = <M>;
315         close M;
316         ### prefer the path "/usr/share/man"
317         my $found = 0;
318         for my $line (@lines) {
319             chomp $line;
320             if ($line =~ m|^MANPATH\s+/usr/share/man|) {
321                 $found = 1;
322                 last;
323             }
324         }
325         ### try to find "/usr/local/man" if we didn't find /usr/share/man
326         unless ($found) {
327             for my $line (@lines) {
328                 chomp $line;
329                 if ($line =~ m|^MANPATH\s+/usr/local/man|) {
330                     $mpath = '/usr/local/man/man1';
331                     $found = 1;
332                     last;
333                 }
334             }
335         }
336         ### if we still have not found one of the above man paths,
337         ### just select the first one out of /etc/man.config
338         unless ($found) {
339             for my $line (@lines) {
340                 chomp $line;
341                 if ($line =~ m|^MANPATH\s+(\S+)|) {
342                     $mpath = $1;
343                     last;
344                 }
345             }
346         }
347     }
348     mkdir $mpath, 0755 unless -d $mpath;
349     my $mfile = "${mpath}/${manpage}";
350     print "[+] Installing $manpage man page as: $mfile\n";
351     copy $manpage, $mfile or die "[*] Could not copy $manpage to " .
352         "$mfile: $!";
353     chmod 0644, $mfile or die "[*] Could not set permissions on ".
354         "$mfile to 0644";
355     chown 0, 0, $mfile or
356         die "[*] Could not chown 0,0,$mfile: $!";
357     print "[+] Compressing man page: $mfile\n";
358     ### remove the old one so gzip doesn't prompt us
359     unlink "${mfile}.gz" if -e "${mfile}.gz";
360     system "$cmds{'gzip'} $mfile";
361     return;
362 }
363
364 ### check paths to commands and attempt to correct if any are wrong.
365 sub check_commands() {
366     my @path = qw(
367         /bin
368         /sbin
369         /usr/bin
370         /usr/sbin
371         /usr/local/bin
372         /usr/local/sbin
373     );
374     CMD: for my $cmd (keys %cmds) {
375         unless (-x $cmds{$cmd}) {
376             my $found = 0;
377             PATH: for my $dir (@path) {
378                 if (-x "${dir}/${cmd}") {
379                     $cmds{$cmd} = "${dir}/${cmd}";
380                     $found = 1;
381                     last PATH;
382                 }
383             }
384             unless ($found) {
385                 die "[*] Could not find $cmd anywhere!!!  ",
386                     "Please edit the config section to include the path to ",
387                     "$cmd.\n";
388             }
389         }
390         unless (-x $cmds{$cmd}) {
391             die "[*] $cmd is located at ",
392                 "$cmds{$cmd} but is not executable by uid: $<\n";
393         }
394     }
395     return;
396 }
397
398 sub is_cygwin() {
399
400     my $rv = 0;
401
402     ### get OS output from uname
403     open UNAME, "uname -o |" or return $rv;
404     while (<UNAME>) {
405         $rv = 1 if /Cygwin/;
406     }
407     close UNAME;
408
409     return $rv;
410 }
411
412
413 sub setup() {
414     unless (-d $libdir) {
415         mkdir $libdir, 0755 or die "[*] Could not create $libdir: $!"
416     }
417     return;
418 }
419
420 sub usage() {
421     my $exit_status = shift;
422     print <<_HELP_;
423
424 Usage: install.pl [options]
425
426     -u,  --uninstall             - Uninstall gpgdir.
427     -f, --force-mod-install      - Force all perl modules to be installed
428                                    even if some already exist in the system
429                                    /usr/lib/perl5 tree.
430     -F, --Force-mod-regex <re>   - Specify a regex to match a module name
431                                    and force the installation of such modules.
432     -E, --Exclude-mod-regex <re> - Exclude a perl module that matches this
433                                    regular expression.
434     -S, --Skip-mod-install       - Do not install any perl modules.
435
436     -L, --LANG <locale>          - Specify LANG env variable (actually the
437                                    LC_ALL variable).
438     -h  --help                   - Prints this help message.
439
440 _HELP_
441     exit $exit_status;
442 }
Note: See TracBrowser for help on using the browser.