#!/usr/bin/env perl
#
# my_convert_usr_local.pl
#
# A script automate the replacement of old fermi login code
# with the latest version.  Probably needs perl version 5.
#
# Key variables:
#
#   $TEST                       Set to TRUE for a test run,
#                                 about which, more below
#   $SYSTEM                     Set to the name of the cluster,
#                                 which controls the following:
#   $_new_u_l_e                 The directory to be used as the
#                                 standard location for setups.*
#                                 typically '/usr/local/etc',
#

use File::Copy;
use FastGlob qw(glob);

#
# Decide whether this is a test run or not
#

$TEST = 1;
$TEST = 0;

#
# Give us a hint about where we're running
#

$SYSTEM = "my_fnalu";

#
# We can now establish the main variables
#

for ($SYSTEM)
{
  /ossbuild/  and do
              {   
                $_new_u_l_e = '/fnal/ups/etc';
                @list = `ypcat passwd | cut -d: -f6 | sort -u`;
                last;
              };
  /my_fnalu/  and do
              {   
                $_new_u_l_e = '/afs/fnal.gov/ups/etc';
                @list = &glob ('~');
                last;
              };
  /d0/  and do
              {   
                $_new_u_l_e = '/usr/local/etc';
                @list = `ypcat passwd | cut -d: -f6 | sort -u`;
                last;
              };
  /cdf/  and do
              {   
                $_new_u_l_e = '/usr/local/etc';
                @list = `cat /etc/passwd | cut -d: -f6 | sort -u`;
                last;
              };
  /ktev/  and do
              {   
                $_new_u_l_e = '/usr/local/etc';
                @list = `ypcat passwd | cut -d: -f6 | sort -u`;
                last;
              };
  /special/  and do
              {   
                $_new_u_l_e = '/afs/fnal.gov/ups/etc';
                @list = &glob (
                  '/afs/fnal.gov/files/home/room1/buckley',
                  '/afs/fnal.gov/files/home/room1/compsec',
                  '/afs/fnal.gov/files/home/room1/csieh',
                  '/afs/fnal.gov/files/home/room1/dane',
                  '/afs/fnal.gov/files/home/room1/fagan',
                  '/afs/fnal.gov/files/home/room1/foster',
                  '/afs/fnal.gov/files/home/room1/gberanek',
                  '/afs/fnal.gov/files/home/room1/gelfand',
                  '/afs/fnal.gov/files/home/room1/genser',
                  '/afs/fnal.gov/files/home/room1/joyk',
                  '/afs/fnal.gov/files/home/room1/kipp',
                  '/afs/fnal.gov/files/home/room1/lisa',
                  '/afs/fnal.gov/files/home/room1/mengel',
                  '/afs/fnal.gov/files/home/room1/mgreaney',
                  '/afs/fnal.gov/files/home/room1/nicholls',
                  '/afs/fnal.gov/files/home/room1/rayp',
                  '/afs/fnal.gov/files/home/room2/dawson',
                  '/afs/fnal.gov/files/home/room2/donnar',
                  '/afs/fnal.gov/files/home/room2/patrol',
                  '/afs/fnal.gov/files/home/room2/rasmus',
                  '/afs/fnal.gov/files/home/room2/slimmer',
                  '/afs/fnal.gov/files/home/room2/stan',
                  '/afs/fnal.gov/files/home/room3/baisley',
                  '/afs/fnal.gov/files/home/room3/kastner',
                  '/afs/fnal.gov/files/home/room3/kovich',
                  '/afs/fnal.gov/files/home/room3/lauri',
                  '/afs/fnal.gov/files/home/room3/roediger',
                  '/afs/fnal.gov/files/home/room3/shepelak',
                  '/afs/fnal.gov/products/UNIX/lsf');
                last;
              };
}

chomp @list;

#
# Initialize various counters
#

$_pattern_count [0] = 0;                     #Preset the unused entry#
$file_count = 0;
$copyright_count = 0;

#
# Make a home for our output to live in
#

($myhome = $ENV{HOME}) =~ s#/$##;
$log_dir = &make_dir ("$myhome/my_convert_usr_local");
$_ups_comment = ": #_UPS_# ";

#
# Do some test-mode initialization
#

if ($TEST)
{
  $file_count_offset = 24;
  $results_dir = &make_dir ("$myhome/my_convert_usr_local/test");
  ($x, $x, $x, $x, $uid, $gid) = stat ($results_dir);
  if (@list <= 75)
    { $file_count_mod = 1; }
  else
    { $file_count_mod = 50; }
}

#
# Call the initializing routines
#

&initialize_log;
&setup_boilerplates;
&setup_strings;

#
# Get busy time ...
#

while (defined ($next_dir = shift @list))
{

#
# Skip afs space except on the fnalu cluster, and emptiness 
#

  $out_dir = $next_dir;
  if ((($SYSTEM ne "my_fnalu") && ($SYSTEM ne "special") && ($next_dir =~ /^\/afs/)) ||
      ($next_dir =~ /^\s*$/))
  {
    undef $out_dir;
    next;
  }

#
# For test runs, make a subdirectory for each user's files
#

  if ($TEST)
  {
    $out_dir = &make_dir ($results_dir . $next_dir);
  }

#
# Change to the user's (or the user's test output) directory
#

  if (-d $next_dir)
  {
    if (-w $out_dir)
    {
      if (!chdir ($next_dir))
      {
        print ERR "Could not cd to $next_dir\n";
        next;
      }
      print LOG "$next_dir";

#
# Work through the list of candidate files for this user's directory
#

      @chklist = (".bash_profile", ".bash_login", ".bashrc", ".cshrc", ".login", ".profile", ".shrc", ".tcshrc", ".zshrc");
      while ($old_file = shift @chklist)
      {
        if (-s "$old_file")
        {
          ++$file_count;
          if ($TEST)
            { ($x, $x, $mode, $x, $x, $x, $x, $x, $atime, $mtime) = stat ("$old_file"); }
          else
            { ($x, $x, $mode, $x, $uid, $gid, $x, $x, $atime, $mtime) = stat ("$old_file"); }

          $sav_file = "$old_file.UPS_SAVE";
          $new_file = "$old_file.UPS_NEW";
          print LOG " $old_file";
          if (-l "$old_file")
          {
            print LOG "@";
            next;
          }

#
# Open the candidate file, and the replacement file
#

          if (!open (OLD_FILE, "$old_file"))
          {
            print ERR "Could not open $next_dir/$old_file\n";
            print LOG "<";
            next;
          }
          if (!open (NEW_FILE, ">$out_dir/$new_file"))
          {
            print ERR "Could not open $out_dir/$new_file\n";
            print LOG ">";
            close (OLD_FILE);
            next;
          }

#
# Glom the candidate file into $_, with extra newlines, fore and aft
#

          $change_count = 0;
          $saved_line = "\n";                  #Nota Bene!#
          while (<OLD_FILE>)
          {
            $saved_line .= $_;
          }
          $saved_line .= "\n";                 #Nota Bene!#
          close (OLD_FILE);
          $_ = $saved_line ;

          $tag_char = "";

#
# Make sure the file hasn't already been doctored
#

          if (m#\n[^\#\n]*(source|\.)[ \t]+"(/usr/local/etc/|/fnal/ups/etc/|/afs/\.?fnal\.gov/ups/etc/)setups.c?sh"#s)
            {$tag_char .= "&";}
          else
          {

#
# Work through the list of patterns
#

            $tag_count = 0;
            @_tmp_pattern_list = @_pattern_list;  $pattern_number = 0;
            while ($pattern = shift @_tmp_pattern_list)
            {
              ++$pattern_number;
              while (m#$pattern#gs)
              {

#
# We found a match, so comment it out
#

                my ($_a, $_b, $_c) = ($`, $&, $');
                $_b =~ s#^#$_ups_comment#gm;
                $_b =~ s#^$_ups_comment##;
                $_ = $_a . $_b . $_c;
                ++($_pattern_count [$pattern_number]);
                print LOG "$pattern_number+";
                ++$tag_count;
                if (($pattern eq $_dot_minimal_source_shrc_old_style) or
                    ($pattern eq $_dot_minimal_tilde_shrc_old_style)) {$tag_char .= "#";}
              }
            }

#
# If we made changes, finish up the job
#

            if ($tag_count gt 0)
            {

#
# Undo excesses in $_dot_export_source_shrc_old_style pattern handling
#

              s#$_ups_comment(\s*export HOST)#$1#gm;
              s#$_ups_comment(\s*HOST=\$\{MACH_ID})#$1#gm;

#
# Prefix the proper boilerplate code to the file, after the
# shell-specification line, if any
#

              ($bp = $old_file . "_boilerplate") =~ s#\.#\_dot_#;
              if (! s#^\n(\#!/[^\n]*\n)?#$&$$bp#s) {print ERR "Can't find boilerplate $bp\n";}
              $tag_char .= "$tag_count";
              if (s#$_old_copyright##gs) {++$copyright_count;}
              if (m#Copyright [^\s]* [0-9]* Universities Research Association#gs) {$tag_char .= "©";}
            }

          }


#
# Check for any old stuff which may have been missed
#

          if (m{\n[^#\n]*((source|\.)[ \t]+((.HOME|~\w?)/\.shrc|(/usr/local/etc/|/fnal/ups/etc/|/afs/\.?fnal\.gov/ups/etc/)(fermi|setpath|setups)\.))}s) 
            {$tag_char .= "?";}

          if ($saved_line ne $_)
          {
            $change_count++;             # Only count substantive changes
          }

#
# Remove the extra newlines we added, and write the new file
#

          s/^\n//;                             #Nota Bene!#
          s/\n$//;                             #Nota Bene!#
          print NEW_FILE;
          close (NEW_FILE);
          if ($change_count == 0)
          {
            print LOG "$tag_char-";
            if (!unlink ("$out_dir/$new_file"))
            {
              print ERR "Could not removed new file $out_dir/$new_file\n";
              print LOG "%";
            }
          }
          else
          {

#
# Make a backup of the original file
#

            if (!copy ("$old_file", "$out_dir/$sav_file") ||
                !chmod ($mode, "$out_dir/$sav_file") ||
                !chown ($uid, $gid, "$out_dir/$sav_file") ||
                !utime ($atime, $mtime, "$out_dir/$sav_file"))
            {
              print ERR "Could not back up $next_dir/$old_file\n";
              print LOG "*";
              if (!unlink ("$out_dir/$new_file"))
              {
                print ERR "Could not removed new file $out_dir/$new_file\n";
                print LOG "%";
              }
              next;
            }

#
# Move the new file into place
#

            if (!chmod ($mode, "$out_dir/$new_file") ||
                !chown ($uid, $gid, "$out_dir/$new_file") ||
                !rename ("$out_dir/$new_file", "$out_dir/$old_file"))
            {
              print ERR "Could not rewrite $out_dir/$old_file\n";
              print LOG "!";
              next;
            }
          }

#
# If this is a test run, keep a sampling of our handiwork
#

          if ($TEST)
          {
            if (($tag_char !~ /\?/) and ((($file_count + $file_count_offset) % $file_count_mod) != 0))
              { unlink ("$out_dir/$old_file"); }
            unlink ("$out_dir/$sav_file");
          }
        }
      }
      print LOG "\n";
    }
    else
    {
      print ERR "Unwritable directory $next_dir\n";
    }
  }
} continue {
  if ($TEST)
  {
    if (defined $out_dir) {rmdir ("$out_dir");}
  }
}

#
# Print the final statistics
#

print LOG "\n";
$pattern_number = 0;
$count = shift @_pattern_count;                 #Toss the unused entry#
while (defined ($count = shift @_pattern_count))
{
++$pattern_number;
print LOG "Pattern $pattern_number was used $count time", ($count == 1 ? "" : "s"), "\n";
}
print LOG "Copyright notices were removed from $copyright_count of $file_count files\n";

close (ERR);
close (LOG);
close (OLD_FILE);
close (NEW_FILE);


#
# Create the log file and print the introductory material
#

sub initialize_log

{

$log = "$log_dir/my_convert_usr_local.log";
open (LOG, ">$log") || die "Failed to open $log";
if ($TEST) {print LOG "Test mode results are in $results_dir/\n";}
print LOG "Legend of symbols:\n";
print LOG "n+ = This file had boilerplate added and section(s) matching pattern n commented out\n";
print LOG "&  = This file had already been modified\n";
print LOG "-  = This file wasn't changed\n";
print LOG "@  = The file pointed to by this link wasn't changed\n";
print LOG "#  = This file had a '. \$HOME/.shrc' line commented out\n";
print LOG "*  = Could not make a backup copy of this file\n";
print LOG "<  = Could not open this file for reading\n";
print LOG ">  = Could not open this file for writing\n";
print LOG "!  = Could not rename this file\n";
print LOG "%  = Could not delete the temporary new version\n";
print LOG "If the changes were made, the original is renamed with a .UPS_SAVE extension.\n";
print LOG "\n";
print LOG "Pattern strings:\n";

$err = "$log_dir/my_convert_usr_local.err";
open (ERR, ">$err") || die "Failed to open $err";

}

# setup_strings creates the patterns for matching text
# we wish to modify.
#
# When setting up a new pattern, copy the prototype string
# into the following template, double any apostrophes and
# backslashes, remove the comment characters, and replace
# the 'newtemplate' name with something appropriate.
#
# ($_dot_newtemplate_old_style = '
# <your multiline prototype string goes here ...>
# ');
# $_dot_newtemplate_old_style = patternize ($_dot_newtemplate_old_style);
# push @_pattern_list, $_dot_newtemplate_old_style;
# push @_pattern_count, 0;
#


sub setup_strings

{

@_pattern_list = ();

#   Pattern Number 1

($_dot_bashrcII_extreme_old_style = '
if [ -e /usr/local/etc/fermi.upsII.shrc ]
then
  if [ -r /usr/local/etc/fermi.upsII.shrc ]
  then
    . /usr/local/etc/fermi.upsII.shrc
  fi
else
  if [ -e /usr/local/etc/fermi.shrc ]
  then
    if [ -r /usr/local/etc/fermi.shrc ]
    then
      . /usr/local/etc/fermi.shrc
    fi
  fi
fi
');
$_dot_bashrcII_extreme_old_style = patternize ($_dot_bashrcII_extreme_old_style);
push @_pattern_list, $_dot_bashrcII_extreme_old_style;
push @_pattern_count, 0;


#   Pattern Number 2

($_dot_cshrcII_extreme_old_style = '
if ( -r /usr/local/etc/fermi.upsII.cshrc )
then
  source /usr/local/etc/fermi.upsII.cshrc
  if ( -r /usr/local/etc/setupsII.csh )
  then
    source /usr/local/etc/setupsII.csh
  endif
else
  if ( -r /usr/local/etc/fermi.cshrc )
  then
    source /usr/local/etc/fermi.cshrc
  endif
endif
');
$_dot_cshrcII_extreme_old_style = patternize ($_dot_cshrcII_extreme_old_style);
push @_pattern_list, $_dot_cshrcII_extreme_old_style;
push @_pattern_count, 0;


#   Pattern Number 3

($_dot_cshrcII_old_style = '
if ( -r /usr/local/etc/fermi.upsII.cshrc )
then
  source /usr/local/etc/fermi.upsII.cshrc
else
  if ( -r /usr/local/etc/fermi.cshrc )
  then
    source /usr/local/etc/fermi.cshrc
  endif
endif
');
$_dot_cshrcII_old_style = patternize ($_dot_cshrcII_old_style);
push @_pattern_list, $_dot_cshrcII_old_style;
push @_pattern_count, 0;


#   Pattern Number 4

($_dot_shrcII_old_style = '
if [ -r /usr/local/etc/fermi.upsII.shrc ]
then
  . /usr/local/etc/fermi.upsII.shrc
else
  if [ -r /usr/local/etc/fermi.shrc ]
  then
    . /usr/local/etc/fermi.shrc
  fi
fi
');
$_dot_shrcII_old_style = patternize ($_dot_shrcII_old_style);
push @_pattern_list, $_dot_shrcII_old_style;
push @_pattern_count, 0;


#   Pattern Number 5

($_dot_profile_semi_new_old_style = '
if [ -r /usr/local/etc/setups.sh ]
then
  . /usr/local/etc/setups.sh
elif [ -r /usr/local/etc/fermi.profile ]
then
  . /usr/local/etc/fermi.profile
  . /usr/local/etc/fermi.shrc
fi
');
$_dot_profile_semi_new_old_style = patternize ($_dot_profile_semi_new_old_style);
push @_pattern_list, $_dot_profile_semi_new_old_style;
push @_pattern_count, 0;


#   Pattern Number 6

($_dot_export_source_shrc_old_style = '
shellname=`basename $SHELL|sed \'s/[0-9]//\'`
if [ "$shellname" = "sh" ] || [ "$shellname" = "bash" ]
then
  export HOST
  HOST=${MACH_ID}
  if [ -r $HOME/.shrc ]
  then
    . $HOME/.shrc
  fi
fi
');
$_dot_export_source_shrc_old_style = patternize ($_dot_export_source_shrc_old_style);
push @_pattern_list, $_dot_export_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 7

($_dot_profile_shrc_old_style = '
if [ -r /usr/local/etc/fermi.profile ]
then
  . /usr/local/etc/fermi.profile
  if [ -r /usr/local/etc/fermi.shrc ]
  then
    . /usr/local/etc/fermi.shrc
  fi
fi
');
$_dot_profile_shrc_old_style = patternize ($_dot_profile_shrc_old_style);
push @_pattern_list, $_dot_profile_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 8

($_dot_bashrc_set_u_old_style = '
file=/usr/local/etc/fermi.profile
if [ -r $file ]
then
  set +u
  source $file
  set -u
else
fi
unset file
');
$_dot_bashrc_set_u_old_style = patternize ($_dot_bashrc_set_u_old_style);
push @_pattern_list, $_dot_bashrc_set_u_old_style;
push @_pattern_count, 0;


#   Pattern Number 9

($_dot_bash_profile_old_style = '
if [ -e /usr/local/etc/fermi.profile ]
then
  if [ -r /usr/local/etc/fermi.profile ]
  then
    . /usr/local/etc/fermi.profile
  fi
fi
');
$_dot_bash_profile_old_style = patternize ($_dot_bash_profile_old_style);
push @_pattern_list, $_dot_bash_profile_old_style;
push @_pattern_count, 0;


#   Pattern Number 10

($_dot_bashrc_old_style = '
if [ -e /usr/local/etc/fermi.shrc ]
then
    if [ -r /usr/local/etc/fermi.shrc ]
    then
        . /usr/local/etc/fermi.shrc
    fi
fi
');
$_dot_bashrc_old_style = patternize ($_dot_bashrc_old_style);
push @_pattern_list, $_dot_bashrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 11

($_dot_fancy_source_shrc_old_style = '
shellname=`basename $SHELL|sed \'s/[0-9]//\'`
if [ "$shellname" = "sh" ] || [ "$shellname" = "bash" ]
then
  if [ -r $HOME/.shrc ]
  then
    . $HOME/.shrc
  fi
fi
');
$_dot_fancy_source_shrc_old_style = patternize ($_dot_fancy_source_shrc_old_style);
push @_pattern_list, $_dot_fancy_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 12

($_dot_profile_set_u_old_style = '
if [ -r /usr/local/etc/fermi.profile ]
then
  set +u
  source /usr/local/etc/fermi.profile
  set -u
fi
');
$_dot_profile_set_u_old_style = patternize ($_dot_profile_set_u_old_style);
push @_pattern_list, $_dot_profile_set_u_old_style;
push @_pattern_count, 0;


#   Pattern Number 13

($_dot_bashrc_setpath_style = '
if [ -r /usr/local/etc/fermi.shrc ]
then
  . /usr/local/etc/fermi.shrc
  . /usr/local/etc/setpath.sh
fi
');
$_dot_bashrc_setpath_style = patternize ($_dot_bashrc_setpath_style);
push @_pattern_list, $_dot_bashrc_setpath_style;
push @_pattern_count, 0;


#   Pattern Number 14

($_dot_source_shrc_env_old_style = '
if [ "`basename $SHELL|sed \'s/[0-9]//\'`" = "bash" -a -r $HOME/.shrc ]
then
  . $HOME/.shrc
  export ENV
  ENV=~/.shrc
fi
');
$_dot_source_shrc_env_old_style = patternize ($_dot_source_shrc_env_old_style);
push @_pattern_list, $_dot_source_shrc_env_old_style;
push @_pattern_count, 0;


#   Pattern Number 15

($_dot_env_source_shrc_old_style = '
if [ "`basename $SHELL|sed \'s/[0-9]//\'`" = "bash" -a -r $HOME/.shrc ]
then
  export ENV
  ENV=~/.shrc
  . $HOME/.shrc
fi
');
$_dot_env_source_shrc_old_style = patternize ($_dot_env_source_shrc_old_style);
push @_pattern_list, $_dot_env_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 16

($_dot_bash_profile_return_old_style = '
if [ -r /usr/local/etc/fermi.profile ]
then
  . /usr/local/etc/fermi.profile
  return
fi
');
$_dot_bash_profile_return_old_style = patternize ($_dot_bash_profile_return_old_style);
push @_pattern_list, $_dot_bash_profile_return_old_style;
push @_pattern_count, 0;


#   Pattern Number 17

($_dot_login_etc_old_style = '
if ( -f /usr/local/etc/fermi.login )
then
  source /usr/local/etc/fermi.login
else
  if ( -f /etc/fermi.login )
then
    source /etc/fermi.login
  endif
endif
');
$_dot_login_etc_old_style = patternize ($_dot_login_etc_old_style);
push @_pattern_list, $_dot_login_etc_old_style;
push @_pattern_count, 0;


#   Pattern Number 18

($_dot_login_else_old_style = '
if ( -e /usr/local/etc/fermi.login )
then
  source /usr/local/etc/fermi.login
else
endif
');
$_dot_login_else_old_style = patternize ($_dot_login_else_old_style);
push @_pattern_list, $_dot_login_else_old_style;
push @_pattern_count, 0;


#   Pattern Number 19

($_dot_elif_source_shrc_old_style = '
elif [ "`basename $SHELL|sed \'s/[0-9]//\'`" = "bash" -a -r $HOME/.shrc ]
then
  export ENV
  ENV=~/.shrc
  . $HOME/.shrc
');
$_dot_elif_source_shrc_old_style = patternize ($_dot_elif_source_shrc_old_style);
push @_pattern_list, $_dot_elif_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 20

($_dot_source_bash_redundant_style = '
if [ "`basename $SHELL|sed \'s/[0-9]//\'`" = "bash" -a -r $HOME/.shrc ]
then
  . $HOME/.shrc
fi
. $HOME/.shrc
');
$_dot_source_bash_redundant_style = patternize ($_dot_source_bash_redundant_style);
push @_pattern_list, $_dot_source_bash_redundant_style;
push @_pattern_count, 0;


#   Pattern Number 21

($_dot_fancy_source_shrc_old_style = '
shellname=`basename $SHELL|sed \'s/[0-9]//\'`
if [ "$shellname" = "sh" ] || [ "$shellname" = "bash" ]
then
  . $HOME/.shrc
fi
');
$_dot_fancy_source_shrc_old_style = patternize ($_dot_fancy_source_shrc_old_style);
push @_pattern_list, $_dot_fancy_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 22

($_dot_profile_bracket_old_style = '
if [ -r /usr/local/etc/fermi.profile ]
then
  . /usr/local/etc/fermi.profile ]
fi
');
$_dot_profile_bracket_old_style = patternize ($_dot_profile_bracket_old_style);
push @_pattern_list, $_dot_profile_bracket_old_style;
push @_pattern_count, 0;


#   Pattern Number 23

($_dot_profile_old_style = '
if [ -r /usr/local/etc/fermi.profile ]
then
  . /usr/local/etc/fermi.profile
fi
');
$_dot_profile_old_style = patternize ($_dot_profile_old_style);
push @_pattern_list, $_dot_profile_old_style;
push @_pattern_count, 0;


#   Pattern Number 24

($_dot_cshrc_old_style = '
if ( -r /usr/local/etc/fermi.cshrc )
then
        source /usr/local/etc/fermi.cshrc
endif
');
$_dot_cshrc_old_style = patternize ($_dot_cshrc_old_style);
push @_pattern_list, $_dot_cshrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 25

($_dot_login_old_style = '
if ( -r /usr/local/etc/fermi.login )
then
  source /usr/local/etc/fermi.login
endif
');
$_dot_login_old_style = patternize ($_dot_login_old_style);
push @_pattern_list, $_dot_login_old_style;
push @_pattern_count, 0;


#   Pattern Number 26

($_dot_bashrc_huh_old_style = '
if [ -r /usr/local/etc/fermi.bashrc ]
then
  . /usr/local/etc/fermi.bashrc
fi
');
$_dot_bashrc_huh_old_style = patternize ($_dot_bashrc_huh_old_style);
push @_pattern_list, $_dot_bashrc_huh_old_style;
push @_pattern_count, 0;


#   Pattern Number 27

($_dot_bashrc_huh_old_style = '
if [ -r /usr/local/etc/fermi.bashr ]
then
  . /usr/local/etc/fermi.bashrc
fi
');
$_dot_bashrc_huh_old_style = patternize ($_dot_bashrc_huh_old_style);
push @_pattern_list, $_dot_bashrc_huh_old_style;
push @_pattern_count, 0;


#   Pattern Number 28

($_dot_shrc_old_style = '
if [ -r /usr/local/etc/fermi.shrc ]
then
  . /usr/local/etc/fermi.shrc
fi
');
$_dot_shrc_old_style = patternize ($_dot_shrc_old_style);
push @_pattern_list, $_dot_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 29

($_dot_shrc_wrong_old_style = '
if [ -r /usr/local/etc/fermi.csh ]
then
  . /usr/local/etc/fermi.shrc
fi
');
$_dot_shrc_wrong_old_style = patternize ($_dot_shrc_wrong_old_style);
push @_pattern_list, $_dot_shrc_wrong_old_style;
push @_pattern_count, 0;


#   Pattern Number 30

($_dot_profile_new_old_style = '
if [ -r /usr/local/etc/setups.sh ]
then
  . /usr/local/etc/setups.sh
fi
');
$_dot_profile_new_old_style = patternize ($_dot_profile_new_old_style);
push @_pattern_list, $_dot_profile_new_old_style;
push @_pattern_count, 0;


#   Pattern Number 31

($_dot_shrc_setpath_old_style = '
if [ -r /usr/local/etc/setpath.sh ]
then
    . /usr/local/etc/setpath.sh
fi
');
$_dot_shrc_setpath_old_style = patternize ($_dot_shrc_setpath_old_style);
push @_pattern_list, $_dot_shrc_setpath_old_style;
push @_pattern_count, 0;


#   Pattern Number 32

($_dot_source_bash_style = '
if [ "`basename $SHELL|sed \'s/[0-9]//\'`" = "bash" -a -r $HOME/.shrc ]
then
  . $HOME/.shrc
fi
');
$_dot_source_bash_style = patternize ($_dot_source_bash_style);
push @_pattern_list, $_dot_source_bash_style;
push @_pattern_count, 0;


#   Pattern Number 33

($_dot_foreach_login_style = '
foreach login ( /usr/local/etc/fermi.login /etc/fermi.login )
    if ( -f $login ) break
end
source $login
');
$_dot_foreach_login_style = patternize ($_dot_foreach_login_style);
push @_pattern_list, $_dot_foreach_login_style;
push @_pattern_count, 0;


#   Pattern Number 34

($_dot_shrc_setpath_old_style = '
if [ -f $SETUPS_DIR/setups.sh ]
then
  . $SETUPS_DIR/setups.sh
fi
');
$_dot_shrc_setpath_old_style = patternize ($_dot_shrc_setpath_old_style);
push @_pattern_list, $_dot_shrc_setpath_old_style;
push @_pattern_count, 0;


#   Pattern Number 35

($_dot_home_shrc_old_style = '
if [ -r $HOME/.shrc ]
then
  . $HOME/.shrc
fi
');
$_dot_home_shrc_old_style = patternize ($_dot_home_shrc_old_style);
push @_pattern_list, $_dot_home_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 36

($_dot_tiny_shrc_old_style = '
if [ -r ~/.shrc ]
then
  . ~/.shrc
fi
');
$_dot_tiny_shrc_old_style = patternize ($_dot_tiny_shrc_old_style);
push @_pattern_list, $_dot_tiny_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 37

($_dot_minimal_profile_old_style = '
. /usr/local/etc/fermi.profile
. $HOME/.shrc
');
$_dot_minimal_profile_old_style = patternize ($_dot_minimal_profile_old_style);
push @_pattern_list, $_dot_minimal_profile_old_style;
push @_pattern_count, 0;


#   Pattern Number 38

($_dot_no_then_login_old_style = '
if ( -f /usr/local/etc/fermi.login ) source /usr/local/etc/fermi.login
');
$_dot_no_then_login_old_style = patternize ($_dot_no_then_login_old_style);
push @_pattern_list, $_dot_no_then_login_old_style;
push @_pattern_count, 0;


#   Pattern Number 39

($_dot_minimal_term_cshrc_old_style = '
if( $?term )source /usr/local/etc/fermi.cshrc
');
$_dot_minimal_term_cshrc_old_style = patternize ($_dot_minimal_term_cshrc_old_style);
push @_pattern_list, $_dot_minimal_term_cshrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 40

($_dot_minimal_term_login_old_style = '
if( $?term )source /usr/local/etc/fermi.login
');
$_dot_minimal_term_login_old_style = patternize ($_dot_minimal_term_login_old_style);
push @_pattern_list, $_dot_minimal_term_login_old_style;
push @_pattern_count, 0;


#   Pattern Number 41

($_dot_minimal_profile_old_style = '
. /usr/local/etc/fermi.profile
');
$_dot_minimal_profile_old_style = patternize ($_dot_minimal_profile_old_style);
push @_pattern_list, $_dot_minimal_profile_old_style;
push @_pattern_count, 0;


#   Pattern Number 42

($_dot_minimal_bashrc_old_style = '
. /usr/local/etc/fermi.bashrc
');
$_dot_minimal_bashrc_old_style = patternize ($_dot_minimal_bashrc_old_style);
push @_pattern_list, $_dot_minimal_bashrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 43

($_dot_minimal_cshrc_old_style = '
source /usr/local/etc/fermi.cshrc
');
$_dot_minimal_cshrc_old_style = patternize ($_dot_minimal_cshrc_old_style);
push @_pattern_list, $_dot_minimal_cshrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 44

($_dot_minimal_login_old_style = '
source /usr/local/etc/fermi.login
');
$_dot_minimal_login_old_style = patternize ($_dot_minimal_login_old_style);
push @_pattern_list, $_dot_minimal_login_old_style;
push @_pattern_count, 0;


#   Pattern Number 45

($_dot_minimal_shrc_old_style = '
. /usr/local/etc/fermi.shrc
');
$_dot_minimal_shrc_old_style = patternize ($_dot_minimal_shrc_old_style);
push @_pattern_list, $_dot_minimal_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 46

($_dot_minimal_setups_old_style = '
. /usr/local/etc/setups.sh
');
$_dot_minimal_setups_old_style = patternize ($_dot_minimal_setups_old_style);
push @_pattern_list, $_dot_minimal_setups_old_style;
push @_pattern_count, 0;


#   Pattern Number 47

($_dot_minimal_shrc_setpath_old_style = '
. /usr/local/etc/setpath.sh
');
$_dot_minimal_shrc_setpath_old_style = patternize ($_dot_minimal_shrc_setpath_old_style);
push @_pattern_list, $_dot_minimal_shrc_setpath_old_style;
push @_pattern_count, 0;


#   Pattern Number 48

($_dot_shrc_setpath_old_style = '
. $SETUPS_DIR/setups.sh
');
$_dot_shrc_setpath_old_style = patternize ($_dot_shrc_setpath_old_style);
push @_pattern_list, $_dot_shrc_setpath_old_style;
push @_pattern_count, 0;


#   Pattern Number 49

($_dot_minimal_source_shrc_old_style = '
. $HOME/.shrc
');
$_dot_minimal_source_shrc_old_style = patternize ($_dot_minimal_source_shrc_old_style);
push @_pattern_list, $_dot_minimal_source_shrc_old_style;
push @_pattern_count, 0;


#   Pattern Number 50

($_dot_minimal_tilde_shrc_old_style = '
. ~/.shrc
');
$_dot_minimal_tilde_shrc_old_style = patternize ($_dot_minimal_tilde_shrc_old_style);
push @_pattern_list, $_dot_minimal_tilde_shrc_old_style;
push @_pattern_count, 0;


# Print the pattern list

my @_tmp_pattern_list = @_pattern_list;
my $pattern_number = 0;
my $pattern;
while ($pattern = shift @_tmp_pattern_list)
{
  ++$pattern_number;
  print LOG "Pattern $pattern_number: (", length ($pattern), ") $pattern\n";
  my @_tmp_pattern_list_2 = @_tmp_pattern_list;
  my $pattern_number_2 = $pattern_number;
  my $pattern_2;
  while ($pattern_2 = shift @_tmp_pattern_list_2)
  {
    ++$pattern_number_2;
    if ($pattern eq $pattern_2) {
      print LOG "Pattern $pattern_number is duplicated by Pattern $pattern_number_2\n";
    }
  }
}


#   Copyright pattern

($_old_copyright = '
(#)*
# Copyright \(c\) [0-9]+ Universities Research Association, Inc.
#       All Rights Reserved
#
(#)*
(# This material resulted from work developed under a Government Contract and)*
(# is subject to the following license:  The Government retains a paid-up,)*
(# nonexclusive, irrevocable worldwide license to reproduce, prepare)*
(#)*
(derivative)*
(# works, perform publicly and display publicly by or for the Government,)*
(# including the right to distribute to other Government contractors.  Neither)*
(# the United States nor the United States Department of Energy, nor any of)*
(# their employees, makes any warrenty, express or implied, or assumes any)*
(# legal liability or responsibility for the accuracy, completeness, or)*
(# usefulness of any information, apparatus, product, or process disclosed, or)*
(# represents that its use would not infringe privately owned rights.)*
');
$_old_copyright =~ s/^\s*//s;
$_old_copyright =~ s/[\t ][\t ]+/\\s*/gs;
$_old_copyright =~ s/\n/\\s*/gs;
$_old_copyright =~ s/\\s\*$/\\n/s;
$_old_copyright =~ s/^\(\#\)\*\\s\*/(#\\s*)?/s;

print LOG "Copyright pattern: (", length ($_old_copyright), ") $_old_copyright\n";

print LOG "\n";

}


# patternize does the heavy lifting in doctoring the
# pattern-matching strings.
#
# This routine does two different things to the input string:
# 1) It quotes all of the metacharacters (and trims the string).
# 2) It generalizes certain known character sequences.
#
# In several places, we generalize things like parentheses and brackets, or
# single and double quotes, in such a way that they won't necessarily balance
# or match.  This is perfectly fine, because the shell will have been enforcing
# those rules.  We can afford to match impossible supersets.  In the "worst"
# case, we'll end up overriding a chunk of code that wasn't working.
#
# The generalizations are quite involved in places, and can be
# fragile, since they can easily interfere with each other.
#

sub patternize

{

# Grab the input pattern string.

$_ = $_[0];

# Trim all leading and trailing newlines.

s/^\n*//s;
s/\n*$//s;

# Quote all of the regular expression metacharacters.

s/\./\\./gm;
s/\(/\\(/gm;
s/\)/\\)/gm;
s/\[/\\[/gm;
s/\|/\\|/gm;
s/\{/\\{/gm;
s/\^/\\^/gm;
s/\*/\\*/gm;
s/\?/\\?/gm;
s/\$/\\\$/gm;
s/\+/\\+/gm;

# Allow for an optional trailing semicolon.  Another pattern mangling
# step below will allow for embedded semicolons, but that won't cover
# single-line patterns.

s/$/;?/gm;

# Allow for intervening echo commands.  This consist of the command
# itself, plus a string we'll call ECHOJUNK for now, possibly surrounded
# by single or double quote marks (we're not overly picky about their
# matching or being balanced), possibly followed by a semicolon.

s/\n/\n(echo(\\s+-n)*\\s+('|")?ECHOJUNK('|")?;?)*\n/gm;

# Turn new-lines into a pattern to match arbitrary whitespace.

s/\n/\\s*/gm;

# Turn arbitrary whitespace into a pattern to match mandatory whitespace.

s/\s+/\\s+/gm;

# Collapse the results of the previous steps into appropriate patterns.

s/\\s\*\\s\+/\\s+/gm;
s/\\s\+\\s\*/\\s+/gm;
s/\\s\*\\s\*/\\s*/gm;

# Finish our handling of intervening echo commands.  Move the optional leading
# whitespace inside the parentheses for the whole optional echo string.
# Expand the ECHOJUNK placeholder to match anything but control characters
# which terminate lines, various quote marks, and the semicolon.

s/\\s\*\(echo\(\\s\+/\(\\s*echo\(\\s+/gm;
s/ECHOJUNK/[^\\n\\r\\f\\e`'";]*/gm;

# Generalize the file test options to match all of the usual cases:
# if -a, if -e, if -f, if -r, if -s, and if -x.

s/if\\s\+\\\[\\s\+-[aefrsx]\\s\+/if\\s\+\\\[\\s\+-[aefrsx]\\s\+/gm;
s/if\\s\+\\\(\\s\+-[aefrsx]\\s\+/if\\s\+\\\(\\s\+-[aefrsx]\\s\+/gm;

# Make sure comment lines in patterns don't bleed to the following line(s).

s/#(\\s\+)*/#[ \\t]*/gm;

# Generalize the sourcing of certain files (/usr/local/etc/fermi.*, 
# /usr/local/etc/setpath.*, /usr/local/etc/setups.*, and $SETUPS_DIR/setups.*)
# to allow either the . or source command.  Besides reducing the number of 
# patterns needed, this also catches bash variants.

s/(source|\\\.)(\\s\+\/usr\/local\/etc\/fermi\\\.\w+)/(\\.|source)$2/gm;
s/(source|\\\.)(\\s\+\/usr\/local\/etc\/setpath\\\.\w+)/(\\.|source)$2/gm;
s/(source|\\\.)(\\s\+\/usr\/local\/etc\/setups\\\.\w+)/(\\.|source)$2/gm;
s/(source|\\\.)(\\s\+\\\$SETUPS_DIR\/setups\\\.\w+)/(\\.|source)$2/gm;

# Generalize the sourcing of the users' .shrc files, similar to the previous.

s/(source|\\\.)(\\s\+(\\\$HOME|~\w*)\/\\\.shrc)/(\\.|source)$2/gm;

# Make the spacing optional in "if (", "( -", and " )" strings, and generalize
# to match either parentheses or brackets (we don't care if they don't match).

s/if\\s\+\\/if\\s\*\\/gs;
s/\\(\[|\()\\s\+-/(\\[|\\()\\s*-/gs;
s/\\s\+(]|\\\))/\\s*(]|\\))/gs;

# Generalize certain strings to match bash, ksh or sh.

s/=\\s\+"bash"\\s\+/!?=\\s+"(ba|k)?sh"\\s+/gm;

# Generalize anded tests to match "-a" or "] && ["

s/\\s\+-a\\s\+/(\\s+-a\\s+|\\s*(]|\\))\\s+&&\\s+(\\[|\\()\\s*)/gs;

# Allow intervening comments, but disallow a trailing comment.

s/;\?/;\?(\\s*#[^\\n]*\\n)*/gs;
s/\(\\s\*#\[\^\\n]\*\\n\)\*$//s;

# Generalize to match fermi(.upsII) and setups(II).  Also match either shell
# extension in the setups(II).(c)sh and setpath.(c)sh files.

s/(\/fermi)(\\\.upsII)?(\\\.)/$1(\\.upsII)?$3/gs;
s/(\/setups)(II)?(\\\.)(c?sh)/$1(II)?$3c?sh/gs;
s/(\/setpath)(\\\.)(c?sh)/$1$2c?sh/gs;

# Match either fi or endif to end an if block

s/\\s\*(fi|endif);\?/\\s*(fi|endif);?/gs;

# Generalize /usr/local/etc to match /usr/local/etc, /fnal/ups/etc, and
# /afs/(.)fnal.gov/ups/etc

s#/usr/local/etc/#(/usr/local/etc/|/fnal/ups/etc/|/afs/\.?fnal\.gov/ups/etc/)#gs;

# Allow for ~/.shrc and ~username/.shrc forms.

s#~\w?/\\\.shrc#~\\w?/\\.shrc#gs;

# Let semicolons be followed by optional blanks and tabs

s/;\?/[ \\t]*;?/gm;

# Put the leading newline back on the pattern, with optional blanks and tabs.

s/^/\\n[ \\t]*/s;

# Match any trailing blanks and tabs.

s/$/[\\t ]\*/s;

# All done.

$_;

}

#
# setup_boilerplates creates the replacement text strings.
#

sub setup_boilerplates

{

($x, $x, $x, $day, $mon, $year, $wday) = localtime (time);
$year += 1900;
@mmm = ("January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December");
@ddd = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
$_date = "$ddd[$wday], $mmm[$mon] $day, $year";

# Frontmatter Boilerplate

($_frontmatter = "
#
# The following code was added on $_date
# by the UAS group to bring this file up to date.
#
# Add any personal extra databases here:
#
") =~ s/\s*$//;
# ');


# Replacement Boilerplate Number 1

($_dot_cshrc_boilerplate = $_frontmatter . '
#setenv UPS_EXTRA_DIR $HOME/p/upsdb
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Get ups environment, and then setup the shrc product
#
if ( -f "$_new_u_l_e/setups.csh" ) then
    source "$_new_u_l_e/setups.csh"
endif

if ( { ups exist shrc } ) then
    setup shrc
endif
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
') =~ s/^\s*//;
# ');
$_dot_cshrc_boilerplate =~ s/\$_new_u_l_e/$_new_u_l_e/g;


# Replacement Boilerplate Number 2

($_dot_login_boilerplate = $_frontmatter . '
#setenv UPS_EXTRA_DIR $HOME/p/upsdb
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# get ups environment, and then setup the login product
#
if ( -f "$_new_u_l_e/setups.csh" ) then
    source "$_new_u_l_e/setups.csh"
    if ( { ups exist login } ) then
        setup login
    endif
endif
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
') =~ s/^\s*//;
# ');
$_dot_login_boilerplate =~ s/\$_new_u_l_e/$_new_u_l_e/g;


# Replacement Boilerplate Number 3

($_dot_profile_boilerplate = $_frontmatter . '
#UPS_EXTRA_DIR=$HOME/p/upsdb; export UPS_EXTRA_DIR
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# get ups environment, and then setup the login product
#
if [  -f "$_new_u_l_e/setups.sh" ]
then
    . "$_new_u_l_e/setups.sh"
    if ups exist login
    then
        setup login
    fi
fi
#
# make sure our .shrc gets run...
#
ENV=$HOME/.shrc
export ENV
if [ "`basename $SHELL`" != ksh -a -r $ENV ]
then
    . $ENV
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
') =~ s/^\s*//;
# ');
$_dot_profile_boilerplate =~ s/\$_new_u_l_e/$_new_u_l_e/g;


# Replacement Boilerplate Number 4

($_dot_shrc_boilerplate = $_frontmatter . '
#UPS_EXTRA_DIR=$HOME/p/upsdb; export UPS_EXTRA_DIR
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# get ups environment, and then setup the shrc product
#
if [ -f "$_new_u_l_e/setups.sh" ]
then
    . "$_new_u_l_e/setups.sh"
fi

if ups exist shrc
then
    setup shrc
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
') =~ s/^\s*//;
# ');
$_dot_shrc_boilerplate =~ s/\$_new_u_l_e/$_new_u_l_e/g;


$_dot_bash_profile_boilerplate = $_dot_profile_boilerplate;
$_dot_bash_login_boilerplate = $_dot_profile_boilerplate;
$_dot_bashrc_boilerplate = $_dot_shrc_boilerplate;
$_dot_tcshrc_boilerplate = $_dot_cshrc_boilerplate;
$_dot_zshrc_boilerplate = $_dot_shrc_boilerplate;

}


#
# Create a directory (and its higher levels) and return its name
#

sub make_dir

{

  (my $_dir = "$_[0]") =~ s#/$##;
  if (! -d $_dir)
  {
    if (((my $_prev_dir = $_dir) =~ s#/[^/]*$##) ne "")
      {&make_dir ("$_prev_dir")}
    mkdir ($_dir, 0755) or die "Couldn't make $_dir\n";
  }
  $_dir;

}

