#!/bin/sh

resolvepath(){
  oldpath="$1"

  newpath="$oldpath"_
  while [ _"$newpath" != _"$oldpath" ] ; do
    newpath="$oldpath"

    oldpath=`echo "$oldpath"|sed 's#/\./#/#g;s#/\.$##g;s#//*#/#g;s#^\./##g;s#^/\.\./#/#g'`

    if [ "$oldpath" != '/' ] ; then
      set oldpath=`echo "$oldpath"|sed 's#/*$##g'`
    fi
  done

  if [ _`echo "$oldpath"|cut -c1` = _"/" ] ; then
    oldhead="/"`echo "$oldpath"|cut -c2-|sed 's#/.*$##g'`
    oldtail=`echo "$oldpath"|cut -c2-|sed 's#^[^/]*/##'`
  else
    oldhead=`echo "$oldpath"|sed 's#/.*$##g'`
    oldtail=`echo "$oldpath"|sed 's#^[^/]*/##'`
  fi
  if [ _"$oldpath" = _"$oldhead" ] ; then
    oldtail=""
  fi

  while true ; do
    if [ _"$oldhead" = _ ] ; then
      oldhead="."
    fi
    if [ ! -f "$oldhead" -a ! -d "$oldhead" ] ; then
      echo ""
      return 0
    fi

    linkchar=`ls -ld "$oldhead"|cut -c1`
    if [ $linkchar = 'l' ] ; then
      points_to=`ls -ld "$oldhead"|sed 's#^.*->[ 	]*##g'`

      if [ `echo "$points_to"|cut -c1` = '/' ] ; then
        newpath="$points_to"/"$oldtail"
      else
        newpath=`dirname "$oldhead"`/"$points_to"/"$oldtail"
      fi

      echo `resolvepath "$newpath"`
      return $?
    fi

    if [ _"$oldtail" = _ ] ; then
      oldpath="$oldhead"
      break
    fi

    oldhead="$oldhead"/`echo "$oldtail"|sed 's#/.*$##g'`
    if [ `echo "$oldtail"|grep /|wc -l` -lt 1 ] ; then
      oldtail=''
    else
      oldtail=`echo "$oldtail"|sed 's#^[^/]*/##g'`
    fi
  done

  newpath="$oldpath"_
  while [ _"$newpath" != _"$oldpath" ] ; do
    newpath="$oldpath"

    oldpath=`echo $oldpath|sed 's#[^/][^/]*/\.\./##g;s#[^/][^/]*/\.\.$##g;s#/\./#/#g;s#/\.$##g;s#//*#/#g;s#^\./##g;s#^/\.\./#/#g'`

    if [ "$oldpath" != '/' ] ; then
      oldpath=`echo "$oldpath"|sed 's#/*$##g'`
    fi
  done

  echo "$newpath"
  return 0
}

if [ _"$BACKUP_HOME" = _ ] ; then
  p="$0"
  pnam=$p
  pnam=`basename $pnam`
  if [ "$pnam" = "$0" ] ; then
    for dir in `echo $PATH | tr : " "` ; do
      if [ -x $dir/$pnam ] ; then
	p="$dir/$pnam"
	break
      fi
    done
  fi
  if [ `echo "$p"|cut -c1` != "/" ] ; then
    p="`pwd`/$p"
  fi

  BACKUP_HOME_DEFAULT=`resolvepath "$p"`
  BACKUP_HOME_DEFAULT=`dirname "$BACKUP_HOME_DEFAULT"`
  if [ `basename "$BACKUP_HOME_DEFAULT"` = bin -o `basename "$BACKUP_HOME_DEFAULT"` = sbin ] ; then
    BACKUP_HOME_DEFAULT=`dirname "$BACKUP_HOME_DEFAULT"`
  fi
else
  BACKUP_HOME_DEFAULT="$BACKUP_HOME"
fi
export BACKUP_HOME_DEFAULT


WISH=""
for dir in `echo $PATH | tr : ' '` ; do
  if [ ! -d $dir ] ; then
    continue
  fi

  progs=`/bin/ls -1 $dir | sort -r | egrep '^wish([0-9]+[.]?)*$'`
  for prog in $progs ; do
    if [ -x $dir/$prog ] ; then
      WISH=$dir/$prog
      break
    fi
  done

  if [ _"$WISH" != _ ] ; then
    break
  fi
done

if [ _"$WISH" = _ ] ; then
  echo "Error: window shell wish not found. Exiting." >&2
  exit 1
fi

args=""
sep=""
for arg in "$@" ; do
  narg=`echo "$arg" | sed 's/"/\\\\"/g'`
  args="$args$sep"'"'"$narg"'"'
  sep=" "
done

$WISH << END_OF_INPUT
set argv [ list $args ]
set argv0 "$0"
set INTL_gettext_program "/usr/local/bin/gettext"
if { ! [ file executable \$INTL_gettext_program ] } {
  unset INTL_gettext_program
}
#! /opt/bin/wish

set prefix "/usr/local"
set TEXTDOMAIN "afbackup"
set TEXTDOMAINDIR "/usr/local/share/afbackup/locale"

proc T_ { text } {
  global TEXTDOMAIN TEXTDOMAINDIR

  return [ INTL_gettext \$text \$TEXTDOMAIN \$TEXTDOMAINDIR ]
}

proc TN_ { text } {
  return \$text
}

source "/usr/local/share/afbackup/lib/aftcllib.tcl"

if { [ llength \$argv ] > 1 } {
  set usagestr [ T_ "Usage" ]
  append usagestr [ TN_ ": " ] [ file tail \$argv0 ] { [ <config-file> ]}
  puts stderr \$usagestr
  exit 2
}

# user settable section

set BACKUP_HOME_DEFAULT \$env(BACKUP_HOME_DEFAULT)

if { [ info exists env(BACKUP_HOME) ] } {
  set BACKUP_HOME \$env(BACKUP_HOME)
}

if { [ llength \$argv ] == 1 } {
  set configfile [ lindex \$argv 0 ]
} else {
  set found 0
  set configfiles "\$BACKUP_HOME_DEFAULT/lib/backup.conf /etc/buserver.conf /etc/afbuserver.conf /etc/afserver.conf /etc/afbackup/server.conf"
  lappend configfiles "/usr/local/etc/afbackup/server.conf"
  foreach configfile "\$configfiles" {
    if { [ file readable \$configfile ] } {
      set found 1
      break
    }
  }

  if { ! \$found } {
    puts stderr [ T_ "Error: Cannot read configuration file. Exiting." ]
    exit 2
  }
}

proc getparam { pat } {
  global configfile

  set pattern {^[ \t]*}
  append pattern \$pat
  append pattern {[ \t]*}


  set errfl [ catch { set fp [ open \$configfile r ] } ]
  if { \$errfl } {
    puts stderr [ format [ T_ "Error: Cannot open file \`%s'.\n" ] \$configfile ]
    exit 0
  }

  while { [ gets \$fp line ] >= 0 } {
    if { [ regexp -indices \$pattern \$line i1 ] } {
      close \$fp
      set idx [ expr [ lindex \$i1 1 ] + 1 ]
      return [ string trim [ string range \$line \$idx end ] ]
    }
  }

  close \$fp
  return ""
}

set replacements {
  { "%V" "vardir" "var" "/var/spool/afbackup" }
  { "%L" "libdir" "lib" "/usr/local/etc/afbackup" }
  { "%I" "logdir" "var" "/var/spool/afbackup" }
  { "%B" "bindir" "bin" "/usr/local/sbin" }
  { "%E" "libexecdir" "libexec" "/usr/local/sbin" }
  { "%C" "confdir" "lib" "/usr/local/etc/afbackup" }
}

proc repl_dirs { args } {
  global replacements

  foreach uvar \$args {
    upvar \$uvar var

    foreach repl \$replacements {
	set key [ lindex \$repl 0 ]
	set varname [ lindex \$repl 1 ]

	global \$varname

	set var [ GStr_replSubstring \$var \$key [ set \$varname ] ]
	break
    }
  }
}

set vardir [ getparam {[Vv][Aa][Rr][-_ \t]*[Dd]ire?c?t?o?r?y?:?} ]
if { \$vardir == "" } {
  unset vardir
}

foreach repl \$replacements {
  set varname [ lindex \$repl 1 ]
  set subdir [ lindex \$repl 2 ]

  if { ! [ info exists \$varname ] } {
    if { [ info exists BACKUP_HOME ] } {
      set \$varname "\$BACKUP_HOME/\$subdir"
    } else {
      set \$varname [ lindex \$repl 3 ]
    }
  }
}

set statusfile [ getparam {[Ss]tatus[-_ \t]*[Ff]ile:?} ]
if { \$statusfile == "" } {
  set statusfile "\$vardir/status"
}

set logfile [ getparam {[Ll]ogg?i?n?g?[-_ \t]*[Ff]ile:?} ]
if { [ string range \$logfile 0 0 ] == "@" } {
  set logfile [ lindex \$logfile 1 ]
  if { [ string trim \$logfile ] == "" } {
    unset logfile
  }
}

repl_dirs statusfile logfile

proc update_statusdisplay { } {
  global	statusfile logfile num_log_lines_str prev_log_display

  set success [ catch { set line [ exec tail -1 \$statusfile ] } ]
  if { ! \$success } {
    .top.stat.stat.label configure -text \$line
  }

  if { [ info exists logfile ] } {
    if { ! [ info exists prev_log_display ] } {
      set prev_log_display ""
    }

    set numlines 1
    scan \$num_log_lines_str "%d" numlines
    set success [ catch { set lines [ exec tail -\$numlines \$logfile ] } ]
    if { ! \$success } {
      if { \$lines != \$prev_log_display } {
	.top.log.log.text configure -state normal
	.top.log.log.text delete 0.0 end
	.top.log.log.text insert 0.0 \$lines
	.top.log.log.text configure -state disabled
	.top.log.log.text yview end

	set prev_log_display \$lines
      }
    }
  }
  
  after 2000 update_statusdisplay
}

set num_log_lines_str 10

frame .top -borderwidth 5
frame .top.stat -borderwidth 5 -relief sunken
label .top.stat.label -text [ T_ "Current server status:" ]
frame .top.stat.stat -borderwidth 2 -relief sunken
label .top.stat.stat.label -width 80
pack .top.stat.label -side top -anchor w
pack .top.stat.stat.label -fill x -side top -expand 1
pack .top.stat.stat -fill x -side top -expand 1
pack .top.stat -fill x
pack .top -fill x
if { [ info exists logfile ] } {
  frame .top.log -borderwidth 5 -relief sunken
  label .top.log.label -text [ T_ "Most recent lines in server's log:" ]
  frame .top.log.log -borderwidth 0
  text .top.log.log.text -width 80 -height \$num_log_lines_str -state disabled -xscrollcommand ".top.log.xscroll set" -yscrollcommand ".top.log.log.yscroll set" -wrap none
  scrollbar .top.log.log.yscroll -command ".top.log.log.text yview"
  scrollbar .top.log.xscroll -command ".top.log.log.text xview" -orient horizontal
  frame .top.log.num -borderwidth 0
  label .top.log.num.label -text [ T_ "Number of displayed log lines:" ]
  entry .top.log.num.entry -textvariable num_log_lines_str
  pack .top.log.label -side top -anchor w
  pack .top.log.log.text -side left -expand 1 -fill both
  pack .top.log.log.yscroll -side left -fill y
  pack .top.log.log -fill both -expand 1 -side top
  pack .top.log.xscroll -fill x -side top
  pack .top.log.num.label -side left
  pack .top.log.num.entry -side left -expand 1 -fill x
  pack .top.log.num -side top
  pack .top.log -fill both -expand 1 -side top
  pack .top -fill both -expand 1
}
wm title . [ T_ "AF Backup server status" ]

update_statusdisplay

END_OF_INPUT
