#!/usr/local/bin/perl
#
$Ver = '$Id: rumor,v 1.12 1997/05/09 23:46:14 gdfast Exp gdfast $ ';
# $Log: rumor,v $
# Revision 1.12  1997/05/09 23:46:14  gdfast
# switched logging style to single line 'rid: 30-chars'
#
# Revision 1.11  1997/04/29 10:38:57  gdfast
# -V
#
# Revision 1.10  1997/04/24 19:11:02  gdfast
# rehacked the rumor picking code... switched from reading the whole
# rumor file into an array to the perl book's one-pass random line picking
# algorithm, which is slower, but won't eat all memory some day.
#
# Revision 1.8  1997/04/22 01:17:15  gdfast
#
# Revision 1.7  1997/04/22 01:11:52  gdfast
# added -s
#
# Revision 1.6  1997/04/21 23:14:00  gdfast
# print '%%' between rumors for -f/F
#
# Revision 1.3  1996/09/25 23:33:31  gdfast
# Fixed some stupidity.
# Added some more.
#
# Revision 1.2  1996/09/25 23:22:39  gdfast
# complex rumor all modes (rumor/addrumor) combined
# now determines mode to run as from command line invocation
#
# Revision 1.1  1996/09/25 22:48:34  gdfast
# Initial revision
#

require 'getopts.pl';
require 'ctime.pl';

$Rumors   = "/usr/local/libdata/rumor/usgs.rumor";
$Rumorlog = "/usr/local/libdata/rumor/rumorors.log";

($inigo = $0) =~ s%.+/%%g;

if ($inigo eq 'rumor' || $inigo eq 'fortune') {
    # run as rumor
    $Usage = <<EORUMOR;
$Ver
$0 [options]
opts: -f <regexp>  find all rumors matching <regex>
      -F <regexp>  find, case insensitive
      -v           convert control chars to readable form (^G)
      -l <n>       return only rumors of less than or equal to n lines
      -r <file>    use <file> for rumors
      -s           use stdin as rumor file (eg, for piping hot rumors)
      -c           count rumors
EORUMOR

    &Getopts('hscF:f:r:vl:V');
    die "$Ver\n" if $opt_V;
    die $Usage if $opt_h;
    $opt_r && ($Rumors = $opt_r);
    
    $/ = "%%\n";			# records separated by "%%\n";
    srand(time() ^($$ + ($$ << 15)));
    if ($opt_s) {
	open(IN, "-") || die "can't open STDIN ($!)\n";
    } else {
	open(IN, "$Rumors") || die "can't open $Rumors ($!)\n";
    }
    $count = 0;
    $bilgerat = "";
    $opt_l = 251 unless ($opt_l); # rumor of any size
    while($manna = <IN>) {
	$manna =~ s/%%\n//;
	$manna = ctrl_trans($manna) if $opt_v;
	next if (scalar(split(/\n/, $manna)) > $opt_l);
	if ($opt_F) {
	    if ($manna=~/$opt_F/i) {
		$count++;
		$bilgerat .= "$manna%%\n";
	    } 
	} elsif ($opt_f) {
	    if ($manna=~/$opt_f/) {
		$count++;
		$bilgerat .= "$manna%%\n";
	    }
	} else {		# no regex search
	    $count++;
	    $bilgerat=$manna if (rand() < (1/$count));
	}
    }
    if ($opt_c) {
	print "$count\n";
    } else {
	print $bilgerat;
    }
} elsif ($inigo eq 'addrumor') {
    # addrumor
    $Usage = <<EOADDRUMOR;
$Ver
$0 [options]
opts: -r <file>   use <file> for rumors
EOADDRUMOR

    &Getopts('hr:l:V');
    die $Usage if $opt_h;
    die "$Ver\n" if $opt_V;
    $opt_r && ($Rumors = $opt_r);

    $ferdinando .= $emilio while ($emilio = <STDIN>);
    die "no rumor?\n" unless defined($ferdinando);
    open(IN, ">>$Rumors") || die "can't open $Rumors ($!)\n";
    print IN "$ferdinando%%\n";
    close IN;
    print "Your entry has been consecrated.  You must be cool or something.\n";
    ($name,$passwd,$uid) = getpwuid($<);
    open(LG, ">>$Rumorlog") || die "argh.  no log ($!)\n";
    $host = $ENV{HOST} || `hostname`;
    $host = (gethostbyname($host))[0];
    $host = 'random.nowhere.net' unless $host;
    # there's got to be a better way...
    ($cheshire = substr($ferdinando, 0,30)) =~ s/\n/./g;
#    print LG "$name: ", &ctime($^T);
#    print LG "$name: $cheshire\n";
    print LG "$<.$$.$^T-$host: $cheshire\n";
    close LG;
} elsif ($inigo eq 'adminrumor') {
    die "adminrumor not yet implemented\n";
} elsif ($inigo eq 'rumorstat') {
    die "rurorstat not yet implemented\n";
} else {
    die <<EOSTUPID;
A hollow voice (could it be Matt?) says "Fool."
(cannot invoke as $inigo; try one of: 
  rumor addrumor adminrumor rumorstat)
EOSTUPID
}


# sub to translate control chars to readable form
sub ctrl_trans {
    my $text = shift;
    
    $text =~ s/([\x00-\x1f])/^$1/g;        # add a carat
    $text =~ tr/\x00-\x1f/@-_/;            # shift to printable range
    return $text;
}
# ctrl_trans
__END__
