#! /bin/sh

#    Dec 03/08 - F.Majaess (Revised for sa/saiph, ib/dorval-ib, af/alef)
#    Oct 16/06 - F.Majaess (Revised for ma/maia, ns/naos)
#    Mar 01/06 - F.Majaess (Revised for rg/rigel)
#    Feb 15/05 - F.Majaess (Revised for AIX/Linux setup in Victoria)
#    Jun 20/03 - F.Majaess (Revised for az/azur)
#    Feb 25/02 - F.Majaess (Revised for ya/yata)
#    Dec 01/00 - F.Majaess (Revised to support matching the ownership of 
#                           a link, when pollux is targeted, to that of 
#                           the actual file.)
#    Sep 14/00 - F.Majaess (Revised for tu/tsunami)
#    Jan 05/00 - F.Majaess (Added kz/kaze)
#    Jan 21/99 - F.Majaess (Added yo/yonaka)
#    Jul 14/97 - F.Majaess (Added sx/hiru)
#    Mar 14/96 - F.Majaess (Added sx4)
#    Oct 16/95 - F.Majaess (Added orion, gandalf & aragorn)
#    Sep 25/95 - F. Majaess (Add '-h' to 'file' on SGI)
#    Nov 08/94 - F.Majaess (Modify for sx3r and new destination identifiers)
#    JUL 21/94 - F. Majaess (exclude checking for metacod/prntjbs)
#    Dec 01/92 - E. Chan   
 
#id  lncheck - generates a list of symbolic links on a file system on the 
#id            front-end or one of the back-ends that no longer point to 
#id            a file.
 
#    AUTHOR - E. Chan  
 
#hd  PURPOSE - "lncheck" submits a job to the front-end or one of the 
#hd            back-ends and generates a listing of all symbolic links on
#hd            an official CCRD/N file system that no longer point to a 
#hd            file. This situation may arise if a file was removed without 
#hd            deleting the corresponding link on the official CCRD/N data 
#hd            directory. The problem may also result from a crash of one 
#hd            of the official CCRD/N file systems. 
 
#pr  PARAMETERS:
#pr  
#pr    POSITIONAL/PRIMARY
#pr   
#pr      path = path of data directory (='$DATAPATH') 
#pr  
#pr    PRIMARY
#pr   
#pr      Note: One of 'ha/sp/po/ca/mz'  in Dorval.
#pr
#pr        ha = to target job to IBM (hadar).
#pr
#pr        sp = to target job to IBM (spica).
#pr
#pr        po = to target job to Linux (pollux).
#pr
#pr        ca = to target job to Linux (castor).
#pr
#pr        mz = to target job to Linux (mez).
#pr
#pr
#pr      time = time limit for job in seconds (=600)
#pr  
#pr       mem = memory limit for job in megabytes (=25)
#pr  
#pr    SECONDARY
#pr  
#pr       rmv = switch to remove "bad" links in addition to listing
#pr             them out
#pr 
#pr     valown= switch valid only at CMC site to force matched link 
#pr             ownership to that of the dataset pointed to by the link.
 
#ex  EXAMPLE: 
#ex  
#ex  lncheck ha
#ex 
#ex  The above example obtains a list of all symbolic links in the official
#ex  data directory ('$DATAPATH') on MAIA that do not point to a file. 

#  * Obtain any specified option. 

for arg in $@
do
  case $arg in
        -x) set $arg                    ;;
       *=*) eval $arg                   ;;
        ha) mdest=${mdest:='hadar'}       ;;
        sp) mdest=${mdest:='spica'}       ;;
        po) mdest=${mdest:='pollux'}    ;;
        ca) mdest=${mdest:='castor'}    ;;
        mz) mdest=${mdest:='mez'}    ;;
       rmv) rmv=yes                     ;;
    valown) valown=yes                  ;;
         *) path=${path:=$arg}
  esac
done

#  * Set the defaults.

time=${time:=600}
mem=${mem:=100}
nonqs=${nonqs:=$NONQS}
nonqs=${nonqs:='no'}
valown=${valown='no'}
path=${path:='$DATAPATH'}

#  * Prompt for a destination if none was specified.

while [ -z "$mdest" ]
do
 if [ "$SITE_ID" = 'Victoria' ] ; then
  if [ "$OS" = 'Linux' ] ; then
   mdest="$HOSTID"
  else
   mdest='vicsmall'
  fi
 elif [ "$SITE_ID" = 'Dorval' ] ; then
  echo "please enter a destination; ha/sp/po/ca/mz: > \\c"
  read tmdest
  case $tmdest in
      ha) mdest='hadar'                 ;;
      sp) mdest='spica'                 ;;
      po) mdest='pollux'                ;;
      ca) mdest='castor'                ;;
      mz) mdest='mez'                ;;
       *) echo "illegal destination ! " ;;
  esac
 else
  echo "please enter a destination: > \\c"
  read mdest
 fi
done

#  * Construct and submit the job.

if [ "$mdest" = 'hadar' ] ; then
  outdest=$OUTPUTQ/lncheck.ha.$$
  if [ "$time" -lt 1799 ] ; then
   time=1799
  fi
elif [ "$mdest" = 'spica' ] ; then
  outdest=$OUTPUTQ/lncheck.sp.$$
  if [ "$time" -lt 1799 ] ; then
   time=1799
  fi
elif [ "$mdest" = 'pollux' ] ; then
  outdest=$OUTPUTQ/lncheck.po.$$
elif [ "$mdest" = 'castor' ] ; then
  outdest=$OUTPUTQ/lncheck.ca.$$
elif [ "$mdest" = 'mez' ] ; then
  outdest=$OUTPUTQ/lncheck.mz.$$
else
  outdest=$OUTPUTQ/lncheck.$$
fi

#  * Define variable to contain command to remove bad link if requested.
#  * This variable is expanded in the job below before it is sent to NQS.

if [ -n "$rmv" ] ; then
# if [ "$SITE_ID" = 'Victoria' ] ; then
        remove_link='\ls -ld $file ; \rm -f $file ; echo "link $file has been removed"'
   #!!! remove_link='\ls -ld $file ; echo "link $file needs to be removed"'
# else
#  remove_link='\rm -f $file ; echo "link $file has been removed"'
# fi
fi
## if [ "$mdest" = 'sx' ] ; then
##  queue=${DEFBEQ:='hiru'}
## else
    queue=$mdest
## fi
# qsub -q $queue -lT $time -lM ${mem}mb -r lncheck \
#                -eo -o $outdest <<endjob
if [ "$nonqs" = 'yes' ] ; then
 if [ "$queue" = "$HOSTID" ] ; then
  if [ "$OS" = 'Linux' ] ; then
   Batch_job="/tmp/tmp_lncheck_job$$"
   RM_Batch_job="rm -f $Batch_job"
   line="cat > $Batch_job ; chmod u+x $Batch_job ; nohup $Batch_job 1>>$outdest 2>>$outdest & " 
  else
   RM_Batch_job=':'
   line="nohup sh -s - 1>>$outdest 2>>$outdest & "
  fi
 else
  echo "LNCHECK: Sorry, nohup is limited to the same platform"
  echo "         queue=$queue; HOSTID=$HOSTID !"
  exit 1
 fi
else
 line="qsub -q $queue -lT $time -lM ${mem}mb -r lncheck -eo -o $outdest"
fi
#
cd $HOME/tmp
(cat <<endjob) | eval "$line"
#!/bin/sh
# set -xv
#
chkme () { 
#set -x
 unset file 
 eval "\$@" 
 if [ -n "\$file" ] ; then
  #echo "Checking \$file :"
   nfiles=\`expr \$nfiles + 1\`
   if [ "\$file" != "metacod" -a "\$file" != "prntjbs" -a "\$file" != "utmp" -a "\$file" != '.hold_dir' ] ; then
  # set -x
  # if [ -n "\$link" -a "\$file" != "metacod" -a "\$file" != "prntjbs" ] ; then
  ##  if [ -n "\$link" ] ; then
    if [ -L "\$file" ] ; then
     if [ ! -f "\$file" ] ; then
      echo "symbolic link \$file does not point to a file"
      $remove_link
     else
  #   if [ "$valown" = 'yes' -a "\$SITE_ID" = 'Dorval' -a "\$file" = 'ufmtest2.002' ] ; then
      if [ "$valown" = 'yes' -a "\$SITE_ID" = 'Dorval' ] ; then
       Link_line=\`ls -l \$file \`
       Olink=\`echo "\$Link_line" | \$AWK '{ print \$3 ; }'\`
       Ofile=\`ls -Ldo \$file | \$AWK '{ print \$3 ; }'\`
       if [ "\$Olink" != "\$Ofile" ] ; then
         if [ "\$Olink" = "\$Self" ] ; then
          if [ "\$OS" = 'Linux' -o "\$OS" = 'AIX' ] ; then
           ActualFile=\`echo "\$Link_line" | sed -e 's/^.* -> //' | sed -e 's/\*//g'\`
#          echo "Link_line=\$Link_line"
#          echo "ActualFile=\$ActualFile"
           hold_file=".hold_dir/""\$file"
           if [ "\$OS" = 'Linux' ] ; then
            if [ "$mdest" = 'pollux' ] ; then
              ssh \$Ofile@pollux "cd $path; mv \$file .hold_dir ; ln -s -f \$ActualFile \$file"
             echo "Adjusted \$file -> \$ActualFile ownership to \$Ofile"
           #else
           ## echo "\$Ofile@alef cd $path; mv \$file \$hold_file ; ln -s -f \$ActualFile \$file"
           ## ssh \$Ofile@alef "cd $path; ln -s -f \$ActualFile \$file"
           ## ssh \$Ofile@alef "cd $path; mv \$file \$hold_file ; ln -s -f \$ActualFile \$file"
           #  ssh \$Ofile@alef "cd $path; mv \$file .hold_dir ; ln -s -f \$ActualFile \$file"
            elif [ "$mdest" = 'castor' -o "$mdest" = 'mez' ] ; then
             ssh \$Ofile@${mdest} "cd $path; mv \$file .hold_dir ; ln -s -f \$ActualFile \$file"
             echo "Adjusted \$file -> \$ActualFile ownership to \$Ofile"
            fi
           elif [ "\$OS" = 'AIX' ] ; then
            if [ "$mdest" = 'hadar' ] ; then
             ssh \$Ofile@hadar "cd $path; mv \$file .hold_dir ; ln -s -f \$ActualFile \$file"
             echo "Adjusted \$file -> \$ActualFile ownership to \$Ofile"
            elif [ "$mdest" = 'spica' ] ; then
             ssh \$Ofile@spica "cd $path; mv \$file .hold_dir ; ln -s -f \$ActualFile \$file"
             echo "Adjusted \$file -> \$ActualFile ownership to \$Ofile"
            fi
           fi
          else
           echo "not able to adjust \$file link ownership to \$Ofile!"
          fi
         else
           echo "Link and target file ownership mismatch, not able to reset:"
           echo "\$Link_line"
         fi
       fi
      fi
     fi
    fi
   fi
  fi
 }
#
  echo "            Check done from - \$HOSTID - as of \`date\`" 
if [ "$SITE_ID" = 'Victoria' ] ; then
 cd $path ; sleep 2 ; cd $path 
else
 cd $path
fi
if samefs "$path" \`pwd\` ; then
#
echo
echo "            List of bad links in directory: $path"
echo
# if [ \`hostname\` = 'cidsv08' ] ; then
#   echo "                       \`/usr/bsd43/bin/date\`" 
# else
# echo "                       \`date\`" 
# echo "            Check done from - \$HOSTID - as of \`date\`" 
# fi
echo
Self=\`whoami\`
valown="$valown"
#
#  * Loop through all files/links in target directory and list out 
#  * all links which do not point to a file. Also delete link if 
#  * variable "remove_link" is defined. 
#
# file_list=\`ls -C\`
# set -x
Scrpt_File="\$HOME/tmp/tmp_lncheck_\${HOSTID}_scrpt\$\$"
# if [ "$mdest" = 'yata' ] ; then
#  # file_list=\`rsh yata "cd $path ; ls -C"\`
#  rsh yata "cd $path ; ls -C" | sed -e 's/^/chkme file=/' > \${Scrpt_File}
# else
#  # file_list=\`ls -C\`
#  ls -C | sed -e 's/^/chkme file=/' > \${Scrpt_File}
   ls -C | sed -n -e '/^.*\.[0-9][0-9][0-9]$/p' | sed -e 's/^/chkme file=/' > \${Scrpt_File}
# #file_list=\`rsh \$HOSTID "cd $path ; ls -C"\`
# fi
nfiles=0
if [ -s "\${Scrpt_File}" ] ; then
 if [ "$valown" = 'yes' -a "\$SITE_ID" = 'Dorval' ] ; then
  (mkdir -m 755 ${path}/.hold_dir || : )
  chmod 775 ${path}/.hold_dir
  chmod -t ${path}/.
 fi
 echo "rm \${Scrpt_File}" >> \${Scrpt_File}
 # echo "\${Scrpt_File} file contents:"
 # cat \${Scrpt_File}
 . \${Scrpt_File}
 if [ "$valown" = 'yes' -a "\$SITE_ID" = 'Dorval' ] ; then
  chmod +t ${path}/.
 fi
fi
echo " CHECKED \$nfiles ENTRIES"
echo " FINISHED:             \`date\`" 
else
  echo "Problem switching to $path; cwd=\`pwd\`"
fi
# sleep 10
#
( rmllfls || : )
$RM_Batch_job
exit
endjob

exit
