#!/bin/sh
# Program to edit problem reports for GNATS.
# Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
# Contributed by Jeffrey Osier (jeffrey@cygnus.com).
#
# This file is part of GNU GNATS.
#
# GNU GNATS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU GNATS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU GNATS; see the file COPYING.  If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

debug_print=false # or echo to get output.
DATE=`date`
GNATS_ROOT=/var/lib/gnats/gnats-db
LIBDIR=/usr/lib
PATH=$PATH:$GNATS_ROOT/gnats-bin
PR_EDIT=$LIBDIR/gnats/pr-edit
PR_ADDR=$LIBDIR/gnats/pr-addr
locked=
version=3.101

usage="Usage: $0 [-hV] [--version] [--help] PR"

# Newer config information?
[ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config

# Host-specific; must come after config file.
MAIL_AGENT="/usr/lib/sendmail -oi -t"

# check to see if there is a $EDITOR; if not, use vi
[ -z "$VISUAL" ] &&
  if [ -z "$EDITOR" ]; then
    VISUAL=vi
  else
    VISUAL="$EDITOR"
  fi

# parse command line.
# for the non-flag argument, assume it's correct.  if it's a full
# id number, use that; if not, find the full id.
# only continue if $full_id is an actual file.

if [ $# -eq 0 ]; then
  echo "$usage" ; exit 1
fi
case "$1" in
  -V|-v|--version|--ve*)
    echo "$version"; exit 0
    ;;
  -h|--help*)
    echo "$usage"; exit 0
    ;;
  -*)
    echo "$usage"; exit 1
    ;;
  *)
    if [ "`echo $1 | grep /`" != "" ]; then
      full_id=$1
    else
      full_id=`grep "/$1:" $GNATS_ROOT/gnats-adm/index | awk -F: '{print $1}' -`
    fi
    ;;
esac

trap 'rm -f /tmp/u$$ $new ; exit 0' 0
trap 'if [ "$locked" != "" ]; then \
        $PR_EDIT --unlock $full_id ; \
	locked= ; \
      fi ; \
      rm -f /tmp/u$$ $new ; exit 1' 1 2 3 13 15

# check $full_id
pr=$GNATS_ROOT/$full_id    # pr = full path of editee

if [ "$full_id" = "" ]; then
  echo "edit-pr: PR $pr_arg not in index" ; echo "$usage" ; exit 1
else
  if [ ! -f $pr -o ! -r $pr ]; then
    echo "edit-pr: cannot read PR $full_id"
    echo "$usage" ; exit 1
  fi
fi

# find a user name
if [ "$USER" != "" ]; then
  me=$USER
else
  if [ "$LOGNAME" != "" ]; then
    me=$LOGNAME
  else
    echo "edit-pr: no user name found---set LOGNAME." ; exit 1
  fi
fi

if [ -z "$HOSTNAME" ]; then
  if [ -f /bin/hostname ] ; then HOSTNAME=`/bin/hostname`
  elif [ -f /usr/bin/hostname ] ; then HOSTNAME=`/usr/bin/hostname`
  # Solaris et al.
  elif [ -f /usr/ucb/hostname ] ; then HOSTNAME=`/usr/ucb/hostname`
  # Irix
  elif [ -f /usr/bsd/hostname ] ; then HOSTNAME=`/usr/bsd/hostname`
  fi
fi

if [ -n "$HOSTNAME" ]; then
  full_me="$me@$HOSTNAME"
else
  full_me="$me"
fi

# now we have a valid $full_id.. use its full path
# idea is to have $pr=original pr (unchanged), $new=temp version of $pr

# new = temp file to use for editing
new="/tmp/ep$$"
# make a copy of pr in new
cp $pr $new

# lock the pr
$debug_print "Locking $full_id."
$PR_EDIT --lock $full_me --process "edit-pr script pid $$" $full_id 2> /tmp/u$$
locked=t

if [ -s /tmp/u$$ ]; then
  if [ "`grep exists /tmp/u$$`" = "" ]; then
    echo "edit-pr: PR $full_id is locked by `sed 's/.*by //g' /tmp/u$$`"
  else
    echo "edit-pr: GNATS is presently locked, try again in a moment"
  fi
  rm -f /tmp/u$$
  exit 1
fi

# here's where we actually call the editor.
cp $new $new.old
$VISUAL $new
if cmp -s $new.old $new ; then
  echo "edit-pr: PR not changed"
  $PR_EDIT --unlock $full_id
  exit 0
fi
rm -f $new.old

# error-check output by calling pr-edit --check; if mistakes exist,
# call $VISUAL or exit
checking=t
while [ "$checking" != "" ]; do
  errors="`$PR_EDIT --check < $new`"
  if [ "$errors" != "" ]; then
    echo "Hit \`return\` to fix the following errors, or type \'quit\' to quit:"
    echo "$errors"
    read fixme
    case "$fixme" in
      q* | Q*) 
        echo "PR $full_id not updated: changed file is in $new"
	$PR_EDIT --unlock $full_id
        exit 0
        ;;
    esac
    $VISUAL $new
  else
    checking=
  fi
done

# now that we have a clean new PR
# check for changes in Responsible or State
# add audit trail
# mail changes to relevant parties

old_state="`sed -n '/^>State:/{s,^>[-a-zA-Z]*: *,,;p;q;}' $pr`"
new_state="`sed -n '/^>State:/{s,^>[-a-zA-Z]*: *,,;p;q;}' $new`"
old_resp="`sed -n '/^>Responsible:/{s,^>[-a-zA-Z]*: *,,;s, *(.*,,g;p;q;}' $pr`"
new_resp="`sed -n '/^>Responsible:/{s,^>[-a-zA-Z]*: *,,;s, *(.*,,g;p;q;}' $new`"
old_synopsis="`sed -n '/^>Synopsis:/{s,^>[-a-zA-Z]*: *,,;p;q;}' $pr`"
new_synopsis="`sed -n '/^>Synopsis:/{s,^>[-a-zA-Z]*: *,,;p;q;}' $new`"

# If you can read this, you may have a future in sed(1) programming.
reply_to="`sed -n \
-e '/^$/{g;s/	/ /g;s/\n/ /g;s/^.*: *//;s/ *(.*) *//;s/.*<//;s/>.*//;p;q;}' \
-e '/^Reply-To:/h' \
-e '/^Reply-To:/,/^[^ 	]/{s/^[^ 	].*//;H;}' \
-e '/^Reply-To:/,$b' \
-e '/^From:/h' \
-e '/^From:/,/^[^ 	]/{s/^[^ 	].*//;H;}' \
$pr`"

change_msg=/tmp/ed_pr_ch$$

# the following could stand to be cleaned up...
if [ "$old_state" != "$new_state" ]; then
  state_change=yes
fi
if [ "$old_resp" != "$new_resp" ]; then
  resp_change=yes
fi

if [ ! -z "$state_change" ] || [ ! -z "$resp_change" ]; then
  # we've got a change
  mail_to="$me"
  if [ ! -z "$state_change" ]; then
    $debug_print "Doing state change."
    echo State-Changed-From-To: "$old_state"-"$new_state" >> $change_msg
    echo State-Changed-By: $me >> $change_msg
    echo State-Changed-When: $DATE >> $change_msg
    echo "State-Changed-Why: " >> $change_msg
    echo 'Why did the state change? (Ctrl-D to end)'
    cat >> $change_msg
    to_old=1
    to_subm=1
  fi
  if [ ! -z "$state_change" ] && [ ! -z "$resp_change" ]; then
    echo "" >> $change_msg
    echo "" >> $change_msg
  fi
  if [ ! -z "$resp_change" ]; then
    $debug_print "Doing responsible change."
    echo Responsible-Changed-From-To: "$old_resp"'->'"$new_resp" >> $change_msg
    echo Responsible-Changed-By: $me >> $change_msg
    echo Responsible-Changed-When: $DATE >> $change_msg
    echo "Responsible-Changed-Why: " >> $change_msg
    echo 'Why did the responsible person change? (Ctrl-D to end)'
    cat >> $change_msg
    to_old=1
    to_new=1
  fi

  if [ -n "$to_subm" ]; then mail_to="${reply_to}, ${mail_to}" ; fi
  if [ -n "$to_old" ] ; then mail_to="${mail_to}, `$PR_ADDR ${old_resp}`" ; fi
  if [ -n "$to_new" ] ; then mail_to="${mail_to}, `$PR_ADDR ${new_resp}`" ; fi

  # We have to quote the end of each line in the change_msg, so that sed
  # won't try to use it as a new command.
  $debug_print "Quoting lines in $change_msg."
  sed -e "/^>Unformatted:/i\\
`sed -e 's/$/ \\\\/g' $change_msg`
" $new > $new.tmp
  mv -f $new.tmp $new

  $MAIL_AGENT << __EOF__
To: $mail_to
From: $me
Subject: Re: $full_id

`if [ "$old_synopsis" != "$new_synopsis" ]; then
	echo Old Synopsis: "$old_synopsis"
	echo New Synopsis: "$new_synopsis"
else
	echo Synopsis: "$old_synopsis"
fi`

`cat $change_msg`
__EOF__
fi

echo "edit-pr: filing $full_id back into the database"

# call PR_EDIT on the new file and clean up
$PR_EDIT < $new
$PR_EDIT --unlock $full_id

[ -f "$new" ] && rm -f $new
[ -f "$change_msg" ] && rm -f $change_msg

exit 0
