#!/usr/ug/bin/perl5 # vim:fo=croql:cin:com=\:# # # killfiling gsubrc, mark I # jtr@ugcs.caltech.edu use strict; use POSIX qw(strftime); # gale info use vars qw($CONTENT $PING $FROM $ENC $CAT $SIGN $TIME @MESSAGE $AGENT); # misc use vars qw($GALE $HOME); # formatting use vars qw($BON $BOFF $CEOL); # killinfo use vars qw(%killpeople @killcats %polluted %gvars); $BON=`tput bold`; $BOFF=`tput sgr0`; $CEOL= `tput el`; $FROM= $ENV{'HEADER_FROM'}; $TIME= $ENV{'HEADER_TIME'}; $AGENT= $ENV{'HEADER_AGENT'}; $PING= $ENV{'HEADER_RECEIPT_TO'}; $CAT= $ENV{'GALE_CATEGORY'}; $CAT =~ s-zephyr/message-zephyr/MESSAGE-gi; $ENC= $ENV{'GALE_ENCRYPTED'}; $SIGN= $ENV{'GALE_SIGNED'}; $CONTENT= $ENV{'HEADER_CONTENT_TYPE'}; $HOME= $ENV{'HOME'}; $GALE= $HOME . "/.gale/"; @MESSAGE= <>; # # main handler # &logit; &mkKillfile; system('/bin/env > ' . $HOME . '/.galevars'); if ($CAT =~ m-^notice/-) { &printNotice(@MESSAGE); } elsif ($CAT =~ m-^receipt/-) { &printReceipt(@MESSAGE); } else { my $res= &chkkill; $gvars{'nummsg'}= 0 if !defined($gvars{'nummsg'}); $gvars{'numkilled'}= 0 if !defined($gvars{'numkilled'}); $gvars{'nummsg'}++; if (!$res) { &printMessage(@MESSAGE); } else { &printKilledHeader($res); $gvars{'numkilled'}++; } } &svKillFile; # # log information about recent messages # sub logit { if (open(LOG, "$GALE/glog")) { my @lines= ; my $FRUM= $SIGN if defined($SIGN); $FRUM= $FROM if !defined($SIGN); if ($FRUM =~ /@/) { $FRUM =~ s/^.*<(.*)@.*>.*$/$1/; } else { $FRUM= `ypcat passwd | grep "$FRUM" | head -1`; $FRUM =~ s/:.*$//; chop($FRUM); } $FRUM =~ s/\t/ /g; push @lines, "$CAT\t$FRUM\t$TIME\n"; close(LOG); open(LOG, ">$GALE/glog") || die "can't write to thingy"; my $i= $#lines - 100; $i= 0 if $i < 0; for (; $i <= $#lines; $i++) { print LOG $lines[$i]; } close(LOG); } } # # formatting # sub center { my($str, $bold)= @_; print "\r", ' ' x (40 - length($str) / 2); print $BON if ($bold); print $str; print $BOFF if ($bold); print "$CEOL\n"; } sub printKilledHeader { my ($res)= @_; if ($gvars{'showkillshit'}) { my $name= $FROM; $name =~ s/ <.*>//; print "\r$res KILLED: [$BON$CAT$BOFF] from $BON$name$BOFF$CEOL\n"; print "\r\tencrypted: $BON$ENC$BOFF$CEOL\n" if defined($ENC); print "\r"; } } sub printNotice { print $BON; print "* " if defined($SIGN); my $C= $CAT; $C =~ s-notice/[^/]*/[^/]*/([^/]*)-$1-; print "$C: "; print "$AGENT on "; print strftime("%a %T", localtime($TIME)), "$BOFF$CEOL\n\r"; } sub printReceipt { print $BON; print "* " if defined($SIGN); print "receipt: "; print "$AGENT at "; print strftime("%a %T", localtime($TIME)), "$BOFF$CEOL\n\r"; } sub printMessage { my @MESSAGE= @_; &printHeader; open(FMT, "|fmt") || die "can't fmt, meh."; my $line; foreach $line (@MESSAGE) { chop $line; $line =~ s/[^ -~\s]+//g; if ($CONTENT =~ /xml/) { $line =~ s--$BON-g; $line =~ s--$BOFF-g; } print FMT "$line\n"; #print FMT "\r$line$CEOL\n"; } close FMT; if (defined($SIGN) || defined($ENC)) { my $enc= '-- '; $enc .= "signed: $SIGN" if defined($SIGN); $enc .= " / " if (defined($SIGN) && defined($ENC)); $enc .= "encrypted: $ENC" if defined($ENC); $enc .= ' --'; ¢er($enc, 1); } print "\a" if defined($ENC); print "\r$CEOL\n$CEOL\r"; } sub printHeader { my $name= $FROM; $name =~ s/ <.*>//; print "\r"; print "+" if defined($PING); print "[$BON$CAT$BOFF] from $BON$name$BOFF"; print strftime(" %a %T", localtime($TIME)), "$CEOL\n"; } # # killfile # sub mkKillfile { if (! -f "$GALE.gkill") { system("/bin/touch", "$GALE.gkill"); } open(KILL, $GALE . "gkill") || die "can't open killfile"; while () { if (!/^\s*$/ && !/^\s*#.*$/) { my @entry= split(/\s+/, $_); if ($entry[0] eq 'dipshit') { $killpeople{$entry[1]}= $entry[2]; } elsif ($entry[0] eq 'category') { $entry[1] =~ s-\$Z-zephyr/MESSAGE/-; push @killcats, $entry[1]; } elsif ($entry[0] eq 'polluted') { $polluted{$entry[1]}= $entry[2]; } else { $gvars{$entry[0]}= $entry[1]; } } } close KILL; &expireNukes; } sub chkkill { my $addr; if (defined($SIGN)) { $addr= $SIGN; } else { $addr= $FROM; } $addr =~ s/^.*<(.*)>.*$/\1/; $addr =~ s/@.*//; my $badcat; return 0 if defined($ENC); foreach $badcat (@killcats) { return 2 if eval $CAT =~ /$badcat/i; } return 3 if defined($polluted{$CAT}); if (defined($killpeople{$addr})) { if ($killpeople{$addr} eq 'nuke') { &nukeInstance; return 4; } return 1; } return 0; } sub svKillFile { open(GK, ">$GALE/gkill") || die "can't write to killfile"; my $f; foreach $f (keys %killpeople) { print GK "dipshit $f ", $killpeople{$f}, "\n"; } foreach $f (@killcats) { print GK "category $f", "\n"; } foreach $f (keys %polluted) { print GK "polluted $f ", $polluted{$f}, "\n"; } foreach $f (keys %gvars) { print GK "$f ", $gvars{$f}, "\n"; } close GK; } sub nukeInstance { my $len= 3600; my $now= time; my $expiretime= $now + $len; $polluted{$CAT}= $expiretime; } sub expireNukes { my $key; foreach $key (keys %polluted) { delete $polluted{$key} if ($polluted{$key} < time); } }