]> andersk Git - gssapi-openssh.git/blob - setup/setup-openssh.pl
o Add mention of official GSI-OpenSSH site.
[gssapi-openssh.git] / setup / setup-openssh.pl
1 #!/usr/bin/perl
2 #
3 # setup-openssh.pl
4 #
5 # Adapts the installed gsi-openssh environment to the current machine,
6 # performing actions that originally occurred during the package's
7 # 'make install' phase.
8 #
9 # Send comments/fixes/suggestions to:
10 # Chase Phillips <cphillip@ncsa.uiuc.edu>
11 #
12
13 #
14 # Get user's GPT_LOCATION since we may be installing this using a new(er)
15 # version of GPT.
16 #
17
18 $gptpath = $ENV{GPT_LOCATION};
19
20 #
21 # And the old standby..
22 #
23
24 $gpath = $ENV{GLOBUS_LOCATION};
25 if (!defined($gpath))
26 {
27     die "GLOBUS_LOCATION needs to be set before running this script"
28 }
29
30 #
31 # Include standard modules
32 #
33
34 use Getopt::Long;
35 use Cwd;
36 use Cwd 'abs_path';
37
38 #
39 # modify the ld library path for when we call ssh executables
40 #
41
42 $oldldpath = $ENV{LD_LIBRARY_PATH};
43 $newldpath = "$gpath/lib";
44 if (length($oldldpath) > 0)
45 {
46     $newldpath .= ":$oldldpath";
47 }
48 $ENV{LD_LIBRARY_PATH} = "$newldpath";
49
50 #
51 # i'm including this because other perl scripts in the gpt setup directories
52 # do so
53 #
54
55 if (defined($gptpath))
56 {
57     @INC = (@INC, "$gptpath/lib/perl", "$gpath/lib/perl");
58 }
59 else
60 {
61     @INC = (@INC, "$gpath/lib/perl");
62 }
63
64 require Grid::GPT::Setup;
65
66 #
67 # script-centred variable initialization
68 #
69
70 my $globusdir = $gpath;
71 my $myname = "setup-openssh.pl";
72
73 #
74 # Set up path prefixes for use in the path translations
75 #
76
77 $prefix = ${globusdir};
78 $exec_prefix = "${prefix}";
79 $bindir = "${exec_prefix}/bin";
80 $sbindir = "${exec_prefix}/sbin";
81 $sysconfdir = "$prefix/etc/ssh";
82 $localsshdir = "/etc/ssh";
83 $setupdir = "$prefix/setup/gsi_openssh_setup";
84
85 #
86 # standard key types and their root file name mappings
87 #
88
89 my $keyfiles = {
90                  "dsa" => "ssh_host_dsa_key",
91                  "rsa" => "ssh_host_rsa_key",
92                  "rsa1" => "ssh_host_key",
93                };
94
95 #
96 # argument specification.  we offload some processing work from later functions
97 # to verify correct args by using anon subs in various places.
98 #
99
100 my($interactive, $force, $verbose);
101
102 GetOptions(
103             'interactive!' => \$interactive,
104             'force' => \$force,
105             'verbose' => \$verbose,
106           ) or pod2usage(2);
107
108 #
109 # main execution.  This should find its way into a subroutine at some future
110 # point.
111 #
112
113 print "$myname: Configuring package 'gsi_openssh'...\n";
114 print "---------------------------------------------------------------------\n";
115 print "Hi, I'm the setup script for the gsi_openssh package!  I will create\n";
116 print "a number of configuration files based on your local system setup.  I\n";
117 print "will also attempt to copy or create a number of SSH key pairs for\n";
118 print "this machine.  (Loosely, if I find a pair of host keys in /etc/ssh,\n";
119 print "I will copy them into \$GLOBUS_LOCATION/etc/ssh.  Otherwise, I will\n";
120 print "generate them for you.)\n";
121 print "\n";
122 print "    Jacobim Mugatu says,\n";
123 print "    \t\"Utopian Prime Minister Bad!  GSI-OpenSSH Good!\"\n";
124 print "\n";
125
126 if ( isForced() )
127 {
128     print "WARNING:\n";
129     print "\n";
130     print "    Using the '-force' flag will cause all gsi_openssh_setup files to\n";
131     print "    be removed and replaced by new versions!  Backup any critical\n";
132     print "    SSH configuration files before you choose to continue!\n";
133     print "\n";
134 }
135
136 $response = query_boolean("Do you wish to continue with the setup package?","y");
137 if ($response eq "n")
138 {
139     print "\n";
140     print "Exiting gsi_openssh setup.\n";
141
142     exit 0;
143 }
144
145 print "\n";
146
147 makeConfDir();
148 copyPRNGFile();
149 $keyhash = determineKeys();
150 runKeyGen($keyhash->{gen});
151 copyKeyFiles($keyhash->{copy});
152 copyConfigFiles();
153
154 my $metadata = new Grid::GPT::Setup(package_name => "gsi_openssh_setup");
155
156 $metadata->finish();
157
158 print "\n";
159 print "Additional Notes:\n";
160 print "\n";
161 print "  o I see that you have your GLOBUS_LOCATION environmental variable\n";
162 print "    set to:\n";
163 print "\n";
164 print "    \t\"$gpath\"\n";
165 print "\n";
166 print "    Remember to keep this variable set (correctly) when you want to\n";
167 print "    use the executables that came with this package.\n";
168 print "\n";
169 print "    After that you may execute, for example:\n";
170 print "\n";
171 print "    \t\$ . \$GLOBUS_LOCATION/etc/globus-user-env.sh\n";
172 print "\n";
173 print "    to prepare your environment for running the gsi_openssh\n";
174 print "    executables.\n";
175
176 if ( !getPrivilegeSeparation() )
177 {
178     print "\n";
179     print "  o For System Administrators:\n";
180     print "\n";
181     print "    If you are going to run the GSI-OpenSSH server, we recommend\n";
182     print "    enabling privilege separation.  Although this package supports\n";
183     print "    this feature, your system appears to require some additional\n";
184     print "    configuration.\n";
185     print "\n";
186     print "    To enable privilege separation:\n";
187     print "\n";
188     print "    \tIf the system user 'sshd' does not already exist,\n";
189     print "    \tadd a user with that username.\n";
190     print "\n";
191     print "    \tVerify that /var/empty exists, is owned by root,\n";
192     print "    \tand has a mode of 0700.\n";
193     print "\n";
194     print "    \tEnable the feature UsePrivilegeSeparation in\n";
195     print "    \t\$GLOBUS_LOCATION/etc/ssh/sshd_config.\n";
196 }
197
198 print "\n";
199 print "For more information about GSI-Enabled OpenSSH, visit:\n";
200 print "<http://www.ncsa.uiuc.edu/Divisions/ACES/GSI/openssh/>\n";
201
202 #
203 # give the user a chance to read all of this output
204 #
205
206 print "\n";
207 print "Press <return> to continue... ";
208 $trash = <STDIN>;
209
210 print "\n";
211 print "---------------------------------------------------------------------\n";
212 print "$myname: Finished configuring package 'gsi_openssh'.\n";
213
214 exit;
215
216 #
217 # subroutines
218 #
219
220 ### initPRNGHash( )
221 #
222 # initialize the PRNG pathname hash
223 #
224
225 sub initPRNGHash( )
226 {
227     #
228     # standard prng to executable conversion names
229     #
230
231     addPRNGCommand("\@PROG_LS\@", "ls");
232     addPRNGCommand("\@PROG_NETSTAT\@", "netstat");
233     addPRNGCommand("\@PROG_ARP\@", "arp");
234     addPRNGCommand("\@PROG_IFCONFIG\@", "ifconfig");
235     addPRNGCommand("\@PROG_PS\@", "ps");
236     addPRNGCommand("\@PROG_JSTAT\@", "jstat");
237     addPRNGCommand("\@PROG_W\@", "w");
238     addPRNGCommand("\@PROG_WHO\@", "who");
239     addPRNGCommand("\@PROG_LAST\@", "last");
240     addPRNGCommand("\@PROG_LASTLOG\@", "lastlog");
241     addPRNGCommand("\@PROG_DF\@", "df");
242     addPRNGCommand("\@PROG_SAR\@", "sar");
243     addPRNGCommand("\@PROG_VMSTAT\@", "vmstat");
244     addPRNGCommand("\@PROG_UPTIME\@", "uptime");
245     addPRNGCommand("\@PROG_IPCS\@", "ipcs");
246     addPRNGCommand("\@PROG_TAIL\@", "tail");
247
248     print "Determining paths for PRNG commands...\n";
249
250     $paths = determinePRNGPaths();
251
252     return;
253 }
254
255 ### getDirectoryPaths( )
256 #
257 # return an array ref containing all of the directories in which we should search
258 # for our listing of executable names.
259 #
260
261 sub getDirectoryPaths( )
262 {
263     #
264     # read in the PATH environmental variable and prepend a set of 'safe'
265     # directories from which to test PRNG commands.
266     #
267
268     $path = $ENV{PATH};
269     $path = "/bin:/usr/bin:/sbin:/usr/sbin:/etc:" . $path;
270     @dirs = split(/:/, $path);
271
272     #
273     # sanitize each directory listed in the array.
274     #
275
276     @dirs = map {
277                   $tmp = $_;
278                   $tmp =~ s:/+:/:g;
279                   $tmp =~ s:^\s+|\s+$::g;
280                   $tmp;
281                 } @dirs;
282
283     return \@dirs;
284 }
285
286 ### addPRNGCommand( $prng_name, $exec_name )
287 #
288 # given a PRNG name and a corresponding executable name, add it to our list of
289 # PRNG commands for which to find on the system.
290 #
291
292 sub addPRNGCommand
293 {
294     my($prng_name, $exec_name) = @_;
295
296     prngAddNode($prng_name, $exec_name);
297 }
298
299 ### copyPRNGFile( )
300 #
301 # read in ssh_prng_cmds.in, translate the program listings to the paths we have
302 # found on the local system, and then write the output to ssh_prng_cmds.
303 #
304
305 sub copyPRNGFile
306 {
307     my($fileInput, $fileOutput);
308     my($mode, $uid, $gid);
309     my($data);
310
311     if ( isPresent("/dev/random") && !isForced() )
312     {
313         printf("/dev/random found and not forced.  Not installing ssh_prng_cmds...\n");
314         return;
315     }
316
317     initPRNGHash();
318
319     print "Fixing paths in ssh_prng_cmds...\n";
320
321     $fileInput = "$setupdir/ssh_prng_cmds.in";
322     $fileOutput = "$sysconfdir/ssh_prng_cmds";
323
324     #
325     # verify that we are prepared to work with $fileInput
326     #
327
328     if ( !isReadable($fileInput) )
329     {
330         printf("Cannot read $fileInput... skipping.\n");
331         return;
332     }
333
334     #
335     # verify that we are prepared to work with $fileOuput
336     #
337
338     if ( !prepareFileWrite($fileOutput) )
339     {
340         return;
341     }
342
343     #
344     # Grab the current mode/uid/gid for use later
345     #
346
347     $mode = (stat($fileInput))[2];
348     $uid = (stat($fileInput))[4];
349     $gid = (stat($fileInput))[5];
350
351     #
352     # Open the files for reading and writing, and loop over the input's contents
353     #
354
355     $data = readFile($fileInput);
356     for my $k (keys %$prngcmds)
357     {
358         $sub = prngGetExecPath($k);
359         $data =~ s:$k:$sub:g;
360     }
361     writeFile($fileOutput, $data);
362
363     #
364     # An attempt to revert the new file back to the original file's
365     # mode/uid/gid
366     #
367
368     chmod($mode, $fileOutput);
369     chown($uid, $gid, $fileOutput);
370
371     return 0;
372 }
373
374 ### determinePRNGPaths( )
375 #
376 # for every entry in the PRNG hash, seek out and find the path for the
377 # corresponding executable name.
378 #
379
380 sub determinePRNGPaths
381 {
382     my(@paths, @dirs);
383     my($exec_name, $exec_path);
384
385     $dirs = getDirectoryPaths();
386
387     for my $k (keys %$prngcmds)
388     {
389         $exec_name = prngGetExecName($k);
390         $exec_path = findExecutable($exec_name, $dirs);
391         prngSetExecPath($k, $exec_path);
392     }
393
394     return;
395 }
396
397 ### prngAddNode( $prng_name, $exec_name )
398 #
399 # add a new node to the PRNG hash
400 #
401
402 sub prngAddNode
403 {
404     my($prng_name, $exec_name) = @_;
405     my($node);
406
407     if (!defined($prngcmds))
408     {
409         $prngcmds = {};
410     }
411
412     $node = {};
413     $node->{prng} = $prng_name;
414     $node->{exec} = $exec_name;
415
416     $prngcmds->{$prng_name} = $node;
417 }
418
419 ### prngGetExecName( $key )
420 #
421 # get the executable name from the prng commands hash named by $key
422 #
423
424 sub prngGetExecName
425 {
426     my($key) = @_;
427
428     return $prngcmds->{$key}->{exec};
429 }
430
431 ### prngGetExecPath( $key )
432 #
433 # get the executable path from the prng commands hash named by $key
434 #
435
436 sub prngGetExecPath
437 {
438     my($key) = @_;
439
440     return $prngcmds->{$key}->{exec_path};
441 }
442
443 ### prngGetNode( $key )
444 #
445 # return a reference to the node named by $key
446 #
447
448 sub prngGetNode
449 {
450     my($key) = @_;
451
452     return ${$prngcmds}{$key};
453 }
454
455 ### prngSetExecPath( $key, $path )
456 #
457 # given a key, set the executable path in that node to $path
458 #
459
460 sub prngSetExecPath
461 {
462     my($key, $path) = @_;
463
464     $prngcmds->{$key}->{exec_path} = $path;
465 }
466
467 ### findExecutable( $exec_name, $dirs )
468 #
469 # given an executable name, test each possible path in $dirs to see if such
470 # an executable exists.
471 #
472
473 sub findExecutable
474 {
475     my($exec_name, $dirs) = @_;
476
477     for my $d (@$dirs)
478     {
479         $test = "$d/$exec_name";
480
481         if ( isExecutable($test) )
482         {
483             return $test;
484         }
485     }
486
487     return "undef";
488 }
489
490 ### copyKeyFiles( $copylist )
491 #
492 # given an array of keys to copy, copy both the key and its public variant into
493 # the gsi-openssh configuration directory.
494 #
495
496 sub copyKeyFiles
497 {
498     my($copylist) = @_;
499     my($regex, $basename);
500
501     if (@$copylist)
502     {
503         print "Copying ssh host keys...\n";
504
505         for my $f (@$copylist)
506         {
507             $f =~ s:/+:/:g;
508
509             if (length($f) > 0)
510             {
511                 $keyfile = "$f";
512                 $pubkeyfile = "$f.pub";
513
514                 copyFile("$localsshdir/$keyfile", "$sysconfdir/$keyfile");
515                 copyFile("$localsshdir/$pubkeyfile", "$sysconfdir/$pubkeyfile");
516             }
517         }
518     }
519 }
520
521 ### isForced( )
522 #
523 # return true if the user passed in the force flag.  return false otherwise.
524 #
525
526 sub isForced
527 {
528     if ( defined($force) && $force )
529     {
530         return 1;
531     }
532     else
533     {
534         return 0;
535     }
536 }
537
538 ### isReadable( $file )
539 #
540 # given a file, return true if that file both exists and is readable by the
541 # effective user id.  return false otherwise.
542 #
543
544 sub isReadable
545 {
546     my($file) = @_;
547
548     if ( ( -e $file ) && ( -r $file ) )
549     {
550         return 1;
551     }
552     else
553     {
554         return 0;
555     }
556 }
557
558 ### isExecutable( $file )
559 #
560 # return true if $file is executable.  return false otherwise.
561 #
562
563 sub isExecutable
564 {
565     my($file) = @_;
566
567     if ( -x $file )
568     {
569         return 1;
570     }
571     else
572     {
573         return 0;
574     }
575 }
576
577 ### isWritable( $file )
578 #
579 # given a file, return true if that file does not exist or is writable by the
580 # effective user id.  return false otherwise.
581 #
582
583 sub isWritable
584 {
585     my($file) = @_;
586
587     if ( ( ! -e $file ) || ( -w $file ) )
588     {
589         return 1;
590     }
591     else
592     {
593         return 0;
594     }
595 }
596
597 ### isPresent( $file )
598 #
599 # given a file, return true if that file exists.  return false otherwise.
600 #
601
602 sub isPresent
603 {
604     my($file) = @_;
605
606     if ( -e $file )
607     {
608         return 1;
609     }
610     else
611     {
612         return 0;
613     }
614 }
615
616 ### makeConfDir( )
617 #
618 # make the gsi-openssh configuration directory if it doesn't already exist.
619 #
620
621 sub makeConfDir
622 {
623     if ( isPresent($sysconfdir) )
624     {
625         if ( -d $sysconfdir )
626         {
627             return;
628         }
629
630         die("${sysconfdir} already exists and is not a directory!\n");
631     }
632
633     print "Could not find ${sysconfdir} directory... creating.\n";
634     action("mkdir -p $sysconfdir");
635
636     return;
637 }
638
639 ### determineKeys( )
640 #
641 # based on a set of key types, triage them to determine if for each key type, that
642 # key type should be copied from the main ssh configuration directory, or if it
643 # should be generated using ssh-keygen.
644 #
645
646 sub determineKeys
647 {
648     my($keyhash, $keylist);
649     my($count);
650
651     #
652     # initialize our variables
653     #
654
655     $count = 0;
656
657     $keyhash = {};
658     $keyhash->{gen} = [];   # a list of keytypes to generate
659     $keyhash->{copy} = [];  # a list of files to copy from the 
660
661     $genlist = $keyhash->{gen};
662     $copylist = $keyhash->{copy};
663
664     #
665     # loop over our keytypes and determine what we need to do for each of them
666     #
667
668     for my $keytype (keys %$keyfiles)
669     {
670         $basekeyfile = $keyfiles->{$keytype};
671
672         #
673         # if the key's are already present, we don't need to bother with this rigamarole
674         #
675
676         $gkeyfile = "$sysconfdir/$basekeyfile";
677         $gpubkeyfile = "$sysconfdir/$basekeyfile.pub";
678
679         if ( isPresent($gkeyfile) && isPresent($gpubkeyfile) )
680         {
681             if ( isForced() )
682             {
683                 if ( isWritable("$sysconfdir/$basekeyfile") && isWritable("$sysconfdir/$basekeyfile.pub") )
684                 {
685                      action("rm $sysconfdir/$basekeyfile");
686                      action("rm $sysconfdir/$basekeyfile.pub");
687                 }
688                 else
689                 {
690                      next;
691                 }
692             }
693         }
694
695         #
696         # if we can find a copy of the keys in /etc/ssh, we'll copy them to the user's
697         # globus location
698         #
699
700         $mainkeyfile = "$localsshdir/$basekeyfile";
701         $mainpubkeyfile = "$localsshdir/$basekeyfile.pub";
702
703         if ( isReadable($mainkeyfile) && isReadable($mainpubkeyfile) )
704         {
705             push(@$copylist, $basekeyfile);
706             $count++;
707             next;
708         }
709
710         #
711         # otherwise, we need to generate the key
712         #
713
714         push(@$genlist, $keytype);
715         $count++;
716     }
717
718     return $keyhash;
719 }
720
721 ### runKeyGen( $gen_keys )
722 #
723 # given a set of key types, generate private and public keys for that key type and
724 # place them in the gsi-openssh configuration directory.
725 #
726
727 sub runKeyGen
728 {
729     my($gen_keys) = @_;
730     my $keygen = "$bindir/ssh-keygen";
731
732     if (@$gen_keys && -x $keygen)
733     {
734         print "Generating ssh host keys...\n";
735
736         for my $k (@$gen_keys)
737         {
738             $keyfile = $keyfiles->{$k};
739
740             if ( !isPresent("$sysconfdir/$keyfile") )
741             {
742                 action("$bindir/ssh-keygen -t $k -f $sysconfdir/$keyfile -N \"\"");
743             }
744         }
745     }
746
747     return 0;
748 }
749
750 ### copySSHDConfigFile( )
751 #
752 # this subroutine 'edits' the paths in sshd_config to suit them to the current environment
753 # in which the setup script is being run.
754 #
755
756 sub copySSHDConfigFile
757 {
758     my($fileInput, $fileOutput);
759     my($mode, $uid, $gid);
760     my($line, $newline);
761     my($privsep_enabled);
762
763     print "Fixing paths in sshd_config...\n";
764
765     $fileInput = "$setupdir/sshd_config.in";
766     $fileOutput = "$sysconfdir/sshd_config";
767
768     #
769     # verify that we are prepared to work with $fileInput
770     #
771
772     if ( !isReadable($fileInput) )
773     {
774         printf("Cannot read $fileInput... skipping.\n");
775         return;
776     }
777
778     #
779     # verify that we are prepared to work with $fileOuput
780     #
781
782     if ( !prepareFileWrite($fileOutput) )
783     {
784         return;
785     }
786
787     #
788     # check to see whether we should enable privilege separation
789     #
790
791     if ( userExists("sshd") && ( -d "/var/empty" ) && ( getMode("/var/empty") eq "0700" ) )
792     {
793         setPrivilegeSeparation(1);
794     }
795     else
796     {
797         setPrivilegeSeparation(0);
798     }
799
800     if ( getPrivilegeSeparation() )
801     {
802         $privsep_enabled = "yes";
803     }
804     else
805     {
806         $privsep_enabled = "no";
807     }
808
809     #
810     # Grab the current mode/uid/gid for use later
811     #
812
813     $mode = (stat($fileInput))[2];
814     $uid = (stat($fileInput))[4];
815     $gid = (stat($fileInput))[5];
816
817     #
818     # Open the files for reading and writing, and loop over the input's contents
819     #
820
821     $data = readFile($fileInput);
822
823     #
824     # alter the PidFile config
825     #
826
827     $text = "PidFile\t$gpath/var/sshd.pid";
828     $data =~ s:^[\s|#]*PidFile.*$:$text:gm;
829
830     #
831     # set the sftp directive
832     #
833
834     $text = "Subsystem\tsftp\t$gpath/libxec/sftp-server";
835     $data =~ s:^[\s|#]*Subsystem\s+sftp\s+.*$:$text:gm;
836
837     #
838     # set the privilege separation directive
839     #
840
841     $text = "UsePrivilegeSeparation\t${privsep_enabled}";
842     $data =~ s:^[\s|#]*UsePrivilegeSeparation.*$:$text:gm;
843
844     #
845     # dump the modified output to the config file
846     #
847
848     writeFile($fileOutput, $data);
849
850     #
851     # An attempt to revert the new file back to the original file's
852     # mode/uid/gid
853     #
854
855     chmod($mode, $fileOutput);
856     chown($uid, $gid, $fileOutput);
857
858     return 0;
859 }
860
861 ### setPrivilegeSeparation( $value )
862 #
863 # set the privilege separation variable to $value
864 #
865
866 sub setPrivilegeSeparation
867 {
868     my($value) = @_;
869
870     $privsep = $value;
871 }
872
873 ### getPrivilegeSeparation( )
874 #
875 # return the value of the privilege separation variable
876 #
877
878 sub getPrivilegeSeparation
879 {
880     return $privsep;
881 }
882
883 ### prepareFileWrite( $file )
884 #
885 # test $file to prepare for writing to it.
886 #
887
888 sub prepareFileWrite
889 {
890     my($file) = @_;
891
892     if ( isPresent($file) )
893     {
894         printf("$file already exists... ");
895
896         if ( isForced() )
897         {
898             if ( isWritable($file) )
899             {
900                 printf("removing.\n");
901                 action("rm $file");
902                 return 1;
903             }
904             else
905             {
906                 printf("not writable -- skipping.\n");
907                 return 0;
908             }
909         }
910         else
911         {
912             printf("skipping.\n");
913             return 0;
914         }
915     }
916
917     return 1;
918 }
919
920 ### copyConfigFiles( )
921 #
922 # subroutine that copies some extra config files to their proper location in
923 # $GLOBUS_LOCATION/etc/ssh.
924 #
925
926 sub copyConfigFiles
927 {
928     #
929     # copy the sshd_config file into the ssh configuration directory and alter
930     # the paths in the file.
931     #
932
933     copySSHDConfigFile();
934
935     #
936     # do straight copies of the ssh_config and moduli files.
937     #
938
939     printf("Copying ssh_config and moduli to their proper location...\n");
940
941     copyFile("$setupdir/ssh_config", "$sysconfdir/ssh_config");
942     copyFile("$setupdir/moduli", "$sysconfdir/moduli");
943
944     #
945     # copy and alter the SXXsshd script.
946     #
947
948     copySXXScript("$setupdir/SXXsshd.in", "$sbindir/SXXsshd");
949 }
950
951 ### copyFile( $src, $dest )
952 #
953 # copy the file pointed to by $src to the location specified by $dest.  in the
954 # process observe the rules regarding when the '-force' flag was passed to us.
955 #
956
957 sub copyFile
958 {
959     my($src, $dest) = @_;
960
961     if ( !isReadable($src) )
962     {
963         printf("$src is not readable... not creating $dest.\n");
964         return;
965     }
966
967     if ( !prepareFileWrite($dest) )
968     {
969         return;
970     }
971
972     action("cp $src $dest");
973 }
974
975 ### copySXXScript( $in, $out )
976 #
977 # parse the input file, substituting in place the value of GLOBUS_LOCATION, and
978 # write the result to the output file.
979 #
980
981 sub copySXXScript
982 {
983     my($in, $out) = @_;
984
985     if ( !isReadable($in) )
986     {
987         printf("$in is not readable... not creating $out.\n");
988         return;
989     }
990
991     if ( !prepareFileWrite($out) )
992     {
993         return;
994     }
995
996     $data = readFile($in);
997     $data =~ s|\@GLOBUS_LOCATION\@|$gpath|g;
998     writeFile($out, $data);
999     action("chmod 755 $out");
1000 }
1001
1002 ### readFile( $filename )
1003 #
1004 # reads and returns $filename's contents
1005 #
1006
1007 sub readFile
1008 {
1009     my($filename) = @_;
1010     my($data);
1011
1012     open(IN, "$filename") || die "Can't open '$filename': $!";
1013     $/ = undef;
1014     $data = <IN>;
1015     $/ = "\n";
1016     close(IN);
1017
1018     return $data;
1019 }
1020
1021 ### writeFile( $filename, $fileinput )
1022 #
1023 # create the inputs to the ssl program at $filename, appending the common name to the
1024 # stream in the process
1025 #
1026
1027 sub writeFile
1028 {
1029     my($filename, $fileinput) = @_;
1030
1031     #
1032     # test for a valid $filename
1033     #
1034
1035     if ( !defined($filename) || (length($filename) lt 1) )
1036     {
1037         die "Filename is undefined";
1038     }
1039
1040     #
1041     # verify that we are prepared to work with $filename
1042     #
1043
1044     if ( !prepareFileWrite($filename) )
1045     {
1046         return;
1047     }
1048
1049     #
1050     # write the output to $filename
1051     #
1052
1053     open(OUT, ">$filename");
1054     print OUT "$fileinput";
1055     close(OUT);
1056 }
1057
1058 ### action( $command )
1059 #
1060 # run $command within a proper system() command.
1061 #
1062
1063 sub action
1064 {
1065     my($command) = @_;
1066
1067     printf "$command\n";
1068
1069     my $result = system("LD_LIBRARY_PATH=\"$gpath/lib:\$LD_LIBRARY_PATH\"; $command 2>&1");
1070
1071     if (($result or $?) and $command !~ m!patch!)
1072     {
1073         die "ERROR: Unable to execute command: $!\n";
1074     }
1075 }
1076
1077 ### query_boolean( $query_text, $default )
1078 #
1079 # query the user with a string, and expect a response.  If the user hits
1080 # 'enter' instead of entering an input, then accept the default response.
1081 #
1082
1083 sub query_boolean
1084 {
1085     my($query_text, $default) = @_;
1086     my($nondefault, $foo, $bar);
1087
1088     #
1089     # Set $nondefault to the boolean opposite of $default.
1090     #
1091
1092     if ($default eq "n")
1093     {
1094         $nondefault = "y";
1095     }
1096     else
1097     {
1098         $nondefault = "n";
1099     }
1100
1101     print "${query_text} ";
1102     print "[$default] ";
1103
1104     $foo = <STDIN>;
1105     ($bar) = split //, $foo;
1106
1107     if ( grep(/\s/, $bar) )
1108     {
1109         # this is debatable.  all whitespace means 'default'
1110
1111         $bar = $default;
1112     }
1113     elsif ($bar ne $default)
1114     {
1115         # everything else means 'nondefault'.
1116
1117         $bar = $nondefault;
1118     }
1119     else
1120     {
1121         # extraneous step.  to get here, $bar should be eq to $default anyway.
1122
1123         $bar = $default;
1124     }
1125
1126     return $bar;
1127 }
1128
1129 ### absolutePath( $file )
1130 #
1131 # converts a given pathname into a canonical path using the abs_path function.
1132 #
1133
1134 sub absolutePath
1135 {
1136     my($file) = @_;
1137     my $home = $ENV{'HOME'};
1138     $file =~ s!~!$home!;
1139     my $startd = cwd();
1140     $file =~ s!^\./!$startd/!;
1141     $file = "$startd/$file" if $file !~ m!^\s*/!;
1142     $file = abs_path($file);
1143     return $file;
1144 }
1145
1146 ### getMode( $file )
1147 #
1148 # return a string containing the mode of the given file.
1149 #
1150
1151 sub getMode
1152 {
1153     my($file) = @_;
1154     my($tempmode, $mode);
1155
1156     #
1157     # call stat() to get the mode of the file
1158     #
1159
1160     $tempmode = (stat($file))[2];
1161     if (length($tempmode) < 1)
1162     {
1163         return "";
1164     }
1165
1166     #
1167     # call sprintf to format the mode into a UNIX-like string
1168     #
1169
1170     $mode = sprintf("%04o", $tempmode & 07777);
1171
1172     return $mode;
1173 }
1174
1175 ### userExists( $username )
1176 #
1177 # given a username, return true if the user exists on the system.  return false
1178 # otherwise.
1179 #
1180
1181 sub userExists
1182 {
1183     my($username) = @_;
1184     my($uid);
1185
1186     #
1187     # retrieve the userid of the user with the given username
1188     #
1189
1190     $uid = getpwnam($username);
1191
1192     #
1193     # return true if $uid is defined and has a length greater than 0
1194     #
1195
1196     if ( defined($uid) and (length($uid) > 0) )
1197     {
1198         return 1;
1199     }
1200     else
1201     {
1202         return 0;
1203     }
1204 }
This page took 0.14139 seconds and 5 git commands to generate.