# pgp.tcl --
#
# This file contains code which handles pgp interaction
#
#
#  TkRat software and its included text is Copyright 1996,1997,1998
#  by Martin Forssén
#
#  Postilion software and its included text and images
#  Copyright (C) 1998 Nic Bernstein
#
#  The full text of the legal notices is contained in the files called
#  COPYING and COPYRIGHT.TkRat, included with this distribution.
#
#  This program 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
#  of the License, or (at your option) any later version.
# 
#  This program 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 this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# RatGetPGPPassPhrase --
#
# Get the pgp pass phrase from the user
#
# Arguments:

proc RatGetPGPPassPhrase {} {
    global idCnt t

    # Create identifier
    set id pgpPass[incr idCnt]
    set w .$id
    upvar #0 $id hd
    set oldFocus [focus]

    # Create toplevel
    toplevel $w -class Postilion
    wm transient $w .
    wm title $w $t(pgp_pass_phrase) 

    # Populate window
    label $w.label -text "$t(pgp_pass_phrase):"
    entry $w.entry -textvariable ${id}(phrase) -width 32 -show -
    button $w.button_ok -text $t(ok) -command "set ${id}(done) ok"
    button $w.button_cancel -text $t(abort) -command "set ${id}(done) abort"
    grid $w.label $w.entry -pady 5 -padx 5
    grid $w.button_ok $w.button_cancel
    bind $w.entry <Return> "set ${id}(done) ok"

    Place $w pgpPhrase
    focus $w.entry
    grab $w

    tkwait variable ${id}(done)

    RecordPos $w pgpPhrase
    catch {focus $oldFocus}
    destroy $w
    set ret [list $hd(done) $hd(phrase)]
    unset hd
    return $ret
}

# RatPGPError --
#
# Report an PGP error to the user. It should return either "ABORT" or
# "RETRY".
#
# Arguments:
# error	-	An error message

proc RatPGPError {error} {
    global idCnt t

    # Create identifier
    set id pgpProblem[incr idCnt]
    set w .$id
    upvar #0 $id hd

    # Create toplevel
    toplevel $w -class Postilion
    wm transient $w .
    wm title $w $t(pgp_problem) 

    # Populate window
    frame $w.f
    pack $w.f -padx 5 -pady 5 -fill both -expand 1

    label $w.f.label -text "$t(pgp_problem):"
    pack $w.f.label -side top -anchor w

    frame $w.f.t -relief sunken -bd 1
    scrollbar $w.f.t.scroll \
	-relief sunken \
	-command "$w.f.t.text yview" \
	-highlightthickness 0
    text $w.f.t.text \
	-yscroll "$w.f.t.scroll set" \
	-setgrid 1 \
	-relief raised \
	-bd 0 \
	-highlightthickness 0
    # Scroll mouse support added by Stephen Ryan 14 Oct 1999
    bind $w.f.t.text <5> [list $w.f.t.text yview scroll 5 units]
    bind $w.f.t.text <4> [list $w.f.t.text yview scroll -5 units]
    bind $w.f.t.text <Shift-5> [list $w.f.t.text yview scroll 1 units]
    bind $w.f.t.text <Shift-4> [list $w.f.t.text yview scroll -1 units]
    bind $w.f.t.text <Control-5> [list $w.f.t.text yview scroll 1 pages]
    bind $w.f.t.text <Control-4> [list $w.f.t.text yview scroll -1 pages]

    Size $w.f.t.text pgpError
    pack $w.f.t.scroll -side right -fill y
    pack $w.f.t.text -side left -expand yes -fill both
    regsub -all "\a" $error {} errmsg
    $w.f.t.text insert 1.0 $errmsg
    $w.f.t.text configure -state disabled
    pack $w.f.t -expand 1 -fill both

    frame $w.f.b
    button $w.f.b.retry -text $t(retry) -command "set ${id}(done) RETRY"
    button $w.f.b.abort -text $t(abort) -command "set ${id}(done) ABORT"
    pack $w.f.b.retry $w.f.b.abort -side left -expand 1 -pady 5
    pack $w.f.b -side bottom -fill x

    Place $w pgpError

    tkwait variable ${id}(done)

    RecordSize $w.f.t.text pgpError
    RecordPos $w pgpError
    destroy $w
    set action $hd(done)
    unset hd
    return $action
}

# RatPGPGetIds --
#
# Let the user select keys from her keyrings
#
# Arguments:
# proc	- procedure to call when done
# arg	- argument to procedure (before list of ids)

proc RatPGPGetIds {proc arg} {
    global idCnt t defaultFont

    # Create identifier
    set id pgpGet[incr idCnt]
    set w .$id
    upvar #0 $id hd
    set oldFocus [focus]

    # Create toplevel
    toplevel $w -class Postilion
    wm title $w $t(select_keys) 

    # Add label
    set form "%4s %5s %8s  %10s   %s"
    set l [format $form $t(type) $t(bits) $t(keyid) $t(date) $t(user_id)]
    label $w.label -text $l -font $defaultFont
    grid $w.label -sticky w

    # Add list
    scrollbar $w.scroll \
        -relief sunken \
        -command "$w.list yview" \
	-highlightthickness 0 \
	-bd 1
    listbox $w.list \
        -yscroll "$w.scroll set" \
        -font $defaultFont \
        -exportselection false \
	-highlightthickness 0 \
	-selectmode multiple \
	-setgrid true \
	-bd 1
    # Scroll mouse support added by Stephen Ryan 14 Oct 1999
    bind $w.list <5> [list $w.list yview scroll 5 units]
    bind $w.list <4> [list $w.list yview scroll -5 units]
    bind $w.list <Shift-5> [list $w.list yview scroll 1 units]
    bind $w.list <Shift-4> [list $w.list yview scroll -1 units]
    bind $w.list <Control-5> [list $w.list yview scroll 1 pages]
    bind $w.list <Control-4> [list $w.list yview scroll -1 pages]
    Size $w.list pgpGet
    grid $w.list $w.scroll -sticky nsew

    # Buttons
    frame $w.buttons
    button $w.buttons.ok -text $t(ok) \
	    -command "RatPGPGetIdsDone $w $id 1 [list $proc $arg]"
    button $w.buttons.sel -text $t(select_all) \
	    -command "$w.list selection set 0 end"
    button $w.buttons.unsel -text $t(deselect_all) \
	    -command "$w.list selection clear 0 end"
    button $w.buttons.cancel -text $t(cancel) \
	    -command "RatPGPGetIdsDone $w $id 0 [list $proc $arg]"
    pack $w.buttons.ok \
	 $w.buttons.sel \
	 $w.buttons.unsel \
	 $w.buttons.cancel -side left -expand 1
    grid $w.buttons -columnspan 2 -sticky ew -pady 5

    grid columnconfigure $w 0 -weight 1
    grid rowconfigure $w 1 -weight 1

    foreach key [RatPGP listkeys] {
	set l [format $form [lindex $key 0] \
			    [lindex $key 1] \
			    [lindex $key 2] \
			    [lindex $key 3] \
			    [lindex $key 4]]
	$w.list insert end $l
	lappend hd(ids) [lindex $key 4]
    }

    Place $w pgpGet
}


# RatPGPGetIdsDone --
#
# Calls when the selection is done
#
# Arguments:
# w	  -	The id selection window
# handler -	The handler which identifies the session window
# done    -	The users selection (1=ok, 0=cancel)
# proc	- procedure to call when done
# arg	- argument to procedure (before list of ids)

proc RatPGPGetIdsDone {w handler done proc arg} {
    upvar #0 $handler hd
    global option

    if $done {
	foreach s [$w.list curselection] {
	    lappend ids [lindex $hd(ids) $s]
	}
	$proc $arg $ids
    }
    RecordPos $w pgpGet
    RecordSize $w.list pgpGet
    unset hd
    destroy $w
}

# RatPGPAddKeys --
#
# Add keys to keyring
#
# Arguments:
# keys	  - Keys to add
# keyring - Keyring to add them to

proc RatPGPAddKeys {keys {keyring ""}} {
    global idCnt option t

    # Create identifier
    set id pgpInt[incr idCnt]
    upvar #0 $id hd

    # Setup file
    set hd(fileName) $option(tmp)/rat.[RatGenId]
    set f [open $hd(fileName) w]
    puts $f $keys
    close $f

    # Create command and run it
    set cmd "$option(pgp_prog) $option(pgp_args) -ka $hd(fileName) $keyring"
    set cmd "$cmd; echo '$t(press_return_to_dismiss)'; read FOO"

    RatBgExec ${id}(existStatus) "$option(terminal) \"$cmd\""

    trace variable hd(existStatus) w RatPGPAddKeysDone
}

# RatPGPAddKeysDone
#
# This gets called when the add command has run and should clean
# things up.
#
# Arguments:
# name1, name2 -        Variable specifiers
# op           -        Operation

proc RatPGPAddKeysDone {name1 name2 op} {
    upvar #0 $name1 hd

    file delete -force -- $hd(fileName) &
    unset hd
}

