#!/usr/bin/perl # Promise has installed Perl 5.004 which is 12 years old, and I have # version 5.10 on my development machine. Imagine my suprise. $old_perl = 1; $chmod_cmd = "/bin/chmod"; $df_cmd = "/bin/df"; $ln_cmd = "/bin/ln"; $mv_cmd = "/bin/mv"; $mkdir_cmd = "/bin/mkdir"; $rm_cmd = "/bin/rm"; $rmdir_cmd = "/bin/rmdir"; $root_dir = "/"; $profile = $root_dir . "etc/profile"; $profile_tmp = $profile . "tmp"; $terminfo = "/data/usr/share/terminfo"; $terminfo_env = "export TERMINFO=$terminfo\n"; $bak_dir_name = ".tools.BAK"; @dir_list = ( "bin", "lib", "etc", "data/usr" ); $action = $ARGV[0]; $app_path = $ENV{'APP_PATH'}; # search installed path if ( $app_path eq "" ) { open(IN, "$df_cmd |"); while(){ if (/(VOLUME\d+)/) { if ( -d "/$1/PLUGINAPP/TOOLS" ) { $app_path = "/$1/PLUGINAPP/TOOLS"; last; } } } close(IN); } if ( $app_path eq "" ) { die "Can't find the installation path!"; } # This code "installs" the contents of directories in the array @dir_list # from the $app_path to the $root_dir, by directory. No files are coppied # from $app_path, only symlinks are created within the $root_dir directories # to the $app_path directories. When there is a name collision, i.e., there # is an element $app_path/ABC/XYZ and $root_dir/ABC/XYZ, then a directory # named $bak_dir_name is created in $root_dir/ABC, and the original file is # safely stored there: eg. as $root_dir/ABC/$bak_dir_name/XYZ. Then the # symlink is created as normal. # # When run with the parameter "stop," the process is reversed, the symlinks # are removed from $root_dir, any files stored in any $bak_dir_name are # restored and the $bak_dir_name directories are removed. The removal of # symlinks checks to make sure that they still point to the $app_dir; if # they do not or they are not a symlink, then they are left as is. if ( $action eq "start") { # print "Starting up\n"; foreach $dir_name ( @dir_list ) { # make symbolic links from /$dir_name to our $app_path/$dir_name $app_dir = "$app_path/" . $dir_name; $dest_dir = $root_dir . $dir_name; opendir( DIR_HANDLE, $app_dir ); @file_list = readdir( DIR_HANDLE ); closedir( DIR_HANDLE ); foreach $file_name ( @file_list ) { # print " Working on file $file_name\n"; $full_pathname = "$app_dir" . "/" . "$file_name"; $link_pathname = "$dest_dir" . "/" . "$file_name"; next if (($file_name eq ".") || ($file_name eq "..")) ; if (( -f $link_pathname ) || ( -l $link_pathname )) { # print " Found existing $link_pathname - "; # Check for existing link - eg. we were started 2X if ( -l $link_pathname ) { $temp = readlink $link_pathname; if (( readlink $link_pathname ) =~ m/$app_dir/ ) { # print " Hey, it's our link!\n"; next; } } # Else, it is not ours, save it into a back up dir $back_dir = "$dest_dir" . "/" . $bak_dir_name; if (! -d $back_dir ) { # Create it if need be make_dir( $back_dir, 0755 ); } $back_pathname = $back_dir . "/" . $file_name; # print " Moving it to $back_pathname\n"; move_file( $link_pathname, $back_pathname); } # print " Linking $link_pathname to $full_pathname\n"; link_file( $full_pathname, $link_pathname ); } } # Now we fix the TERMINFO environment variable. It should have been # compiled into ncurses when I built it, but that doesn't seem to be # working. $missing = 1; open PROFILE, "+<$profile"; while() { if ( $_ eq $terminfo_env ) { $missing = 0; last; } } if ( $missing ) { print PROFILE $terminfo_env; } close PROFILE; exit 0; } elsif ($action eq "stop") { # print "Stopping\n"; # Remove symbolic links from our /$dir_name to $app_path/$dir_name foreach $dir_name ( @dir_list ) { $app_dir = "$app_path/" . $dir_name; $dest_dir = $root_dir . $dir_name; opendir( DIR_HANDLE, $app_dir ); @file_list = readdir( DIR_HANDLE ); closedir( DIR_HANDLE ); foreach $file_name ( @file_list ) { $link_pathname = "$dest_dir" . "/" . "$file_name"; if ( -l $link_pathname ) { $full_pathname = readlink $link_pathname; if ( $full_pathname =~ m/$app_dir/ ) { # print " Unlinking $link_pathname to $full_pathname\n"; del_file( $link_pathname ); } else { # print " Not unlinking $link_pathname\n"; } } } $back_dir = "$dest_dir" . "/" . $bak_dir_name; if ( -d $back_dir ) { opendir( DIR_HANDLE, $back_dir ); @file_list = readdir( DIR_HANDLE ); closedir( DIR_HANDLE ); foreach $file_name ( @file_list ) { next if (($file_name eq ".") || ($file_name eq "..")) ; $back_pathname = "$back_dir" . "/" . "$file_name"; $link_pathname = "$dest_dir" . "/" . "$file_name"; # print " Restoring $back_pathname to $link_pathname\n"; move_file( $back_pathname, $link_pathname ); } # It had better be empty at this point del_dir( $back_dir ); } } # Now we unfix the TERMINFO environment variable. $missing = 1; open IN, "<$profile"; open OUT, ">$profile_tmp"; while() { next if ( $_ eq $terminfo_env ); print OUT; } del_file( $profile ); move_file( $profile_tmp, $profile ); exit 0; } sub move_file { my $from_file = $_[0]; my $to_file = $_[1]; if ( $old_perl ) { system("$mv_cmd $from_file $to_file > /dev/null 2> /dev/null "); } else { ( link $from_file, $to_file ) || die "Move couldn't hard link $from_file to $to_file\n"; ( unlink $from_file ) || die "Move couldn't unlink $from_file\n"; } } sub make_dir { my $dir_name = $_[0]; my $dir_mode = $_[1]; if ( $old_perl ) { system("$mkdir_cmd $dir_name > /dev/null 2> /dev/null "); system("$chmod_cmd $dir_mode $dir_name > /dev/null 2> /dev/null ") } else { mkdir $back_dir, $dir_mode; } } sub link_file { my $file_name = $_[0]; my $link_name = $_[1]; if ( $old_perl ) { system("$ln_cmd -s $file_name $link_name > /dev/null 2> /dev/null "); } else { (symlink $file_name, $link_name) || die "Couldn't symlink\n"; } } sub del_file { my $file_name = $_[0]; if ( $old_perl ) { system("$rm_cmd $file_name > /dev/null 2> /dev/null "); } else { unlink( $file_name ); } } sub del_dir { my $dir_name = $_[0]; if ( $old_perl ) { system("$rmdir_cmd $dir_name > /dev/null 2> /dev/null "); } else { rmdir( $dir_name ); } }