#!/usr/bin/perl
#
# Slrn configurator program. By Joey Hess, <joeyh@master.debian.org>

# Get a yes or no response from the user.
sub AskYN { my ($prompt,$default)=@_;
	$default=lc($default);
	print $prompt;
	my $yn="[y/n] ";
	$yn=~s/$default/uc($default)/e;
	print $yn;

	my $resp=lc(substr(<>,0,1));

	while (($resp ne 'y' && $resp ne 'n' && $resp ne "\n") ||
	       ($resp eq "\n" && !$default)) {

		print "Please answer 'y' or 'n'.\n";
		print $prompt.$yn;

		$resp=lc(substr(<>,0,1));
	}

	print "\n";

	if ($resp eq "\n") {
		return lc($default);
	}
	else {
		return $resp;
	}
}

# Get a numeric response from the user.
sub AskNumeric { my ($prompt,$max)=@_;
	print $prompt."[".(join '/',(1..$max))."] ";
	my $resp=int(substr(<>,0,1));

	while (!$resp || $resp > $max) {
		print "Please answer with a number from 1 to $max\n";
		print $prompt."[".(join '/',(1..$max))."] ";
		$resp=int(substr(<>,0,1));
	}

	print "\n";

	return $resp;
}

# Remove slrn modified sections from /etc/ppp/ip-up.
# This is left in (forever) for backwards compatability with old versions
# of this script that modified /etc/ppp/ip-up. Now we use the ip-ip.d
# directory, instead.
sub FixIpUp {
	return if ! -f "/etc/ppp/ip-up";

	open (IPUP,"</etc/ppp/ip-up") || exit print "Unable to read /etc/ppp/ip-up:$!\n";
	my @lines=<IPUP>;
	close IPUP;

	open (IPUP,">/etc/ppp/ip-up") || exit print "Unable to write /etc/ppp/ip-up:$!\n";
	my $ignore=undef;
	foreach (@lines) {
		if ((/# begin: GETDESC_WITH_PPP/ ne undef) ||
		    (/# begin: SLRNPULL_WITH_PPP/ ne undef)) {
			$ignore=1;
		}
		elsif ((/# end: GETDESC_WITH_PPP/ ne undef) ||
		       (/# end: SLRNPULL_WITH_PPP/ ne undef)) {
			$ignore=undef;
		}
		elsif (!$ignore) {
			print IPUP $_;
		}
	}
	close IPUP;
}

# Output current configuration.
sub ShowConfig {
	print "Current configuration: \n";
	print "\tUse cron job to refresh newsgroup descriptions.\n" 
		if $GETDESC_WITH_CRONJOB eq 'y';
	print "\tRefresh newsgroup descriptions via /etc/ppp/ip-up.d/slrn.\n" 
		if $GETDESC_WITH_PPP eq 'y';
	print "\tRefresh newsgroup descriptions by hand.\n" 
		if $GETDESC_WITH_PPP ne 'y' && $GETDESC_WITH_CRONJOB ne 'y';
	print "\n";
}

# Rather than parse the conf file, which is a shell script, I have
# sh source it and then echo out the variables it sets.
sub ReadConfig {
	open (READCONF,'sh -c \'source /etc/news/slrn.debian.conf;
		echo $GETDESC_WITH_CRONJOB;
		echo $GETDESC_WITH_PPP;
		\' |') || die "Error processing /etc/news/slrn.debian.conf: $!";
	$GETDESC_WITH_CRONJOB=lc(substr(<READCONF>,0,1));
	$GETDESC_WITH_PPP=lc(substr(<READCONF>,0,1));
	close READCONF;
}

# This file needs to be set up right.
sub CheckNewsServerFile {
	if (! -f "/etc/nntpserver") {
		print <<eof;
	What news server (NNTP server) should I use for reading and
	posting news?
eof
		my $guesserver=`hostname -f 2>/dev/null`;
		chomp $guesserver;
		if ($guesserver=~m/(?:.*?\.)?(.*\.\w+)/) {
			$guesserver="news.$1";
		}
		print "Enter its full name: [$guesserver] ";
		$server=<>;
		chomp $server;
		if ($server eq undef) {
			$server=$guesserver;
		}
		open (NNTPSERVER,">/etc/nntpserver") 
			|| die "Unable to write to /etc/nntpserver: $!";
		print NNTPSERVER $server."\n";
		close NNTPSERVER;
	}
}

# Save their configuration.
sub SaveConfig {
	open (CONFIG,">/etc/news/slrn.debian.conf") || 
		die "Unable to write to /etc/news/slrn.debian.conf: $!\nConfiguration was not saved.\n";
	print CONFIG 
qq{# This file configures how slrn is called to refresh newsgroups
# descriptions.
#
# This file can be edited by hand, or you can run /usr/sbin/slrnconfig for
# interactive setup. Each option should be answered 'y' or 'n'.

# Should slrn download newsgroup descriptions via a cron job?
GETDESC_WITH_CRONJOB=$GETDESC_WITH_CRONJOB

# Should /etc/ppp/ip-up.d/slrn be used to run slrn when the network comes up
# to refresh newsgroup descriptions?
GETDESC_WITH_PPP=$GETDESC_WITH_PPP

};
	close CONFIG;
	print "Configuration saved to /etc/news/slrn.debian.conf.\n\n";

	# Fix old ip-up files that were modified. This should
	# *never* be removed.
	FixIpUp();
}

if (shift eq '--quiet' and -f "/etc/news/slrn.debian.conf") {
	# Don't do anything but refresh the config.
	&ReadConfig;
	&SaveConfig;
	exit;
}

print "Slrn Configuration\n";
print "------------------\n";

CheckNewsServerFile();

if ( -f "/etc/news/slrn.debian.conf") {
	&ReadConfig;
	&ShowConfig;

	if (AskYN("Do you want to change the current configuration? ",'y') eq 'n') {
		print "Configuration was not changed.\n";
		# Refresh config anyway.
		&SaveConfig;
		exit;
	}
}

TOP: 

print <<eof;
Slrn needs to periodically connect to the network to download
new descriptions of newsgroups. Please select how you want this
to be handled:

  1. By a cron script that is run weekly.
     This works well if you have a perminant network connection, or
     if you are using diald or a similar program that connects to the
     network on demand.
  
  2. By the /etc/ppp/ip-up.d/slrn script.
     This will have slrn get the new newsgroup descriptions when you connect
     to the network via ppp. The new descriptions will still only be retrieved
     once a week if you choose this method, no matter how often you connect to
     the network.
  
  3. By hand.
     You want to run a command manually every now and then when you are
     connected to the network to tell slrn to update the newsgroup 
     descriptions. Or you want to roll your own solution.

eof

$resp=AskNumeric("Which do you choose? ",3);

$GETDESC_WITH_CRONJOB='n';
$GETDESC_WITH_PPP='n';

if ($resp eq 1) {
	$GETDESC_WITH_CRONJOB='y';
}
elsif ($resp eq 2) {
	$GETDESC_WITH_PPP='y';
}
else {
	print "The command to run (as root) to update the newsgroup descriptions is:\n/usr/sbin/slrn_getdescs\n\n";
}

print "Configuration complete.\n\n";
&ShowConfig;
if (AskYN("Are you happy with this configuration? ",'y') ne 'y') { goto TOP }

&SaveConfig;

if (! -f "/var/lib/slrn/newsgroups.dsc") {
	if (AskYN("Are you online now? If so, I'd like to refresh the\nnewsgroup descriptions. May I? ",$SLRNPULL_WITH_CRONJOB) eq 'y') {
		print "Refreshing...\n";
		system "/usr/sbin/slrn_getdescs";
	}
}
