#!/local/bin/tclsh # # tbiff - a companion to bifftk. # # usage: tbiff [ y | n | -relay ] # # tbiff - check biffing state. # tbiff n - disable biffing. # tbiff y - enable biffing (and start bifftk in bkgnd, if needed). # # tbiff -relay # - read an email message on stdin, digest it into # a biff text and relay that text to bifftk. # - primarily for use via a user's .forward file. # eg. # username, "|/usr/local/bin/tbiff -relay" # - only used if comsat is not aware of biff sockets. # # see also "man biff" # # pkern@utcc.utoronto.ca # ##### # # does comsat know about biff sockets? # # [comment/uncomment the following 2 lines as appropriate] set comsat 0 ;# no #set comsat 1 ;# yes ##### # # if comsat does NOT know about biff sockets ... # # "tbiff y" will try to (re)write $HOME/.forward so that it includes # a call to "tbiff -relay". "tbiff y" will try to start up bifftk # if it seems the user's biff socket is not "alive." # # "tbiff n" will try to rewrite $HOME/.forward to delete any calls # to "tbiff -relay". # # "tbiff" simply searches $HOME/.forward for any "tbiff -relay" calls # and if found, it then tests for the biff socket. # ##### # # if comsat knows about biff sockets ... # # # "tbiff y" will try to start up bifftk if it seems the user's biff # socket is not already "alive." # # "tbiff n" deletes the biff socket. the user has to stop the bifftk. # # "tbiff" simply tests for the biff socket. # ##### # # $Header: /local/homes/pkern/xp/RCS/tbiff,v 1.6 1998/07/23 18:12:40 pkern Exp $ # ##### set dotforward "$env(HOME)/.forward" set pattern ", \"|$argv0 -relay\"" # the path to the user's biff socket ... set sockfile "$env(HOME)/.biff_me" if {$argc == 0} { # this is a query. if {$comsat} { if {[catch {set sd [socket -local "" $sockfile ]} ]} { # no socket/socket is dead. puts "is n" } else { puts "is y" } } elseif {[ file isfile $dotforward ] == 0} { puts "is n" } elseif {[catch { set fd [ open $dotforward r ]} errmsg]} { puts "is n" } elseif {[regexp -- "$pattern" [ read -nonewline $fd ]]} { if {[catch {set sd [socket -local "" $sockfile ]} ]} { # no socket/socket is dead. puts "is n" } else { puts "is y" } } else { puts "is n" } exit 0 } elseif {$argc != 1} { puts stderr "usage: $argv0 [y | n]" exit 1 } elseif {$argv == "-relay"} { # skip. } else { switch -exact $argv { n { set add 0 } y { set add 1 } default { puts stderr "usage: $argv0 [y | n]" ; exit 1 } } if {$comsat == 0} { # # comsat is unaware of biff sockets. # so (re)write .forward based on the command line arg: # - if arg1 is y, then include self as an additional # address (if not already present). # - if arg1 is n, then delete self from the list. # if {[catch {set fd [ open $dotforward r ]} ]} { set str $env(USER) } else { set str [ read -nonewline $fd ] close $fd } if {[regexp -- "$pattern" "$str" ]} { if {$add == 0} { # escape any pipes in $pattern (sigh). regsub -all -- {\|} $pattern {\\|} pat # delete all matching patterns. regsub -all -- $pat $str "" new } } elseif {$add} { append new $str $pattern } if {[info exists new ]} { catch { exec mv $dotforward "$dotforward.bak" } set fd [ open $dotforward w 0644 ] puts $fd $new close $fd } } if {$add} { # try to start up bifftk, if it's not already running. if {[catch {set sd [socket -local "" $sockfile ]} ]} { catch { exec bifftk & } } } elseif {$comsat} { # [ugly] delete the socket. the user will need # to manually exit the corresponding bifftk. catch { exec rm -f $sockfile } } exit 0 } if {$comsat} { # if comsat is aware of biff sockets # then there's no point in continuing. # absorb the rest of the message [zmailer]. read stdin exit 0 } # # we're expecting a full mail message on stdin ... # # get the message headers and save the useful ones. while {[set n [ gets stdin line ]] > 0} { switch -glob $line { "Subject:*" { set subj $line } "From:*" { set from $line } "Date:*" { set date $line } "To:*" { set addr $line } } } # # we should now be at the first empty line (or at EOF). # # read up to 3 lines of the message body. foreach x { 1 2 3 } { set n [ gets stdin line ] if {$n < 0} { break } append mailmesg $line "\r\n" } if {$n < 0} { # ok, that was the last line. append mailmesg "---" } else { # but wait! there's more! append mailmesg "...more..." } # absorb the rest of the message [zmailer]. read stdin # build the biff blurb. set mailbiff [ format "%c\r New mail for <%s> has arrived:\r ---\r %s\r\n%s\r\n%s\r\n%s\r \r %s\r\n" 7 $env(USER) $from $addr $date $subj $mailmesg ] # connect to the user's biff socket. if {[ catch { set sd [ socket -local "" $sockfile ]} errmsg ]} { # no socket or no server; so just exit quietly. exit 0 } # send the blurb. fconfigure $sd -translation binary puts -nonewline $sd $mailbiff #x## uncomment for debugging. #x#puts [ fconfigure $sd ] #x#puts $mailbiff