#!/usr/bin/perl # # new installer in the making # see also http://about.psyc.eu/psyced use strict; # all of the full screen editing stuff could move into # its appropriate own .pm file ...? there even seems # to be overlap with PSYCion.. nevermind.. :) # use Prompt; use Term::Cap; use Term::ANSIColor qw(colored :constants); use Data::Dumper; use Storable; use Getopt::Std; my $term; my $prompt; my $t; #misc stuff my %v; my %opts; if (-f '.ser.data') { %v = %{retrieve('.ser.data')}; } getopt('w', \%opts); my %key2name; my %name2key = ( 'left' => "\e[D", 'right' => "\e[C", 'down' => "\e[B", 'up' => "\e[A", 'a-left' => "\e\e[D", 'a-right' => "\e\e[C", 'a-down' => "\e\e[B", 'a-up' => "\e\e[A", 'ret' => "\x0d", 'C-m' => "\x0d", 'esc' => "\x1b", 'c-c' => "\x03", 'tab' => "\x09", 'bs' => "\x7f", 'pu' => "\e[5~", 'pd' => "\e[6~", 'home' => ["\e[H", "\eO", "\e[1~"], 'end' => ["\eOw","\eOe", "\e[4~"], 'ins' => "\e[2~", 'del' => "\e[3~", 'f1' => "\e[11~", 'f2' => "\e[12~", 'f3' => "\e[13~", 'f4' => "\e[14~", 'f5' => "\e[15~", 'f6' => "\e[17~", 'f7' => "\e[18~", 'f8' => "\e[19~", 'f9' => "\e[20~", 'f10' => "\e[21~", 'f11' => "\e[23~", 'f12' => "\e[24~", 'c-a' => "\x01", 'c-b' => "\x02", #'c-c' => "\x03", 'c-d' => "\x04", 'c-e' => "\x05", 'c-f' => "\x06", 'c-g' => "\x07", 'c-h' => "\x08", 'c-i' => "\x09", 'c-j' => "\x0a", 'c-k' => "\x0b", 'c-l' => "\x0c", 'c-m' => "\x0d", 'c-n' => "\x0e", 'c-o' => "\x0f", 'c-p' => "\x10", 'c-q' => "\x11", 'c-r' => "\x12", 'c-s' => "\x13", 'c-t' => "\x14", 'c-u' => "\x15", 'c-v' => "\x16", 'c-w' => "\x17", 'c-x' => "\x18", 'c-y' => "\x19", 'c-z' => "\x1a", 'a-1' => "\e1", 'a-2' => "\e2", 'a-3' => "\e3", 'a-4' => "\e4", 'a-5' => "\e5", 'a-6' => "\e6", 'a-7' => "\e7", 'a-8' => "\e8", 'a-9' => "\e9", 'a-0' => "\e0", ); sub YESNO { +{ 'y' => 1, 'n' => 1 } } sub NUMFT { my $from = shift; my $to = shift; die unless (defined $from && defined $to); my $href = {}; foreach ($from..$to) { $href->{$_} = 1; } return $href; } sub bind { my $key = shift; my $cmd = shift; $key2name{$name2key{$key}} = $cmd; #print "$key, $cmd, " . unpack("H*", $name2key{$key}) . "\r\n"; } $name2key{'pos1'} = $name2key{'home'}; $name2key{'alt-left'} = $name2key{'a-left'}; $name2key{'alt-right'} = $name2key{'a-right'}; my %action = ( 'exit' => sub { print "\r\n"; exit; } ); sub del_line { "\r".$term->Tputs('dl', 1) } sub init { select(STDIN); $| = 1; select(STDOUT); $| = 1; system "stty raw -echo"; $term = Tgetent Term::Cap { TERM => undef, OSPEED => 9600 }; *Prompt::del_line = \&del_line; if ($opts{'w'} && int($opts{'w'}) == $opts{'w'}) { print "true!\r\n"; $prompt = new Prompt({ 'width' => $opts{'w'} }); } else { $prompt = new Prompt; } $Term::ANSIColor::AUTORESET = 1; main::bind('left', 'backward-char'); main::bind('right', 'forward-char'); main::bind('c-c', 'exit'); main::bind('bs', 'backward-delete-char'); main::bind('home', 'beginning-of-line'); main::bind('c-a', 'beginning-of-line'); main::bind('end', 'end-of-line'); main::bind('c-e', 'end-of-line'); main::bind('c-u', 'kill-whole-line'); main::bind('c-k', 'kill-line'); } sub type { my $stdin = shift; my $raw; sysread(*$stdin, $raw, 5); if ($raw =~ /^[\r\n]$/) { return 1; } if (exists $key2name{$raw}) { if (exists($action{$key2name{$raw}})) { return $action{$key2name{$raw}}->(); } print $prompt->type($key2name{$raw}, $raw); return; } $prompt->put($raw); print del_line() . $prompt->prompt(); return; } sub get { my $p = shift; my $default = shift; my $enforce = shift; do { $prompt->Ret(); $prompt->setPrompt($p); $prompt->data($default) if $default; $prompt->type('end-of-line'); print del_line() . $prompt->prompt(); while (!type(\*STDIN)) { } print "\r\n"; } while ($enforce && (!$prompt->data() || ref $enforce && !$enforce->{$prompt->data()}) && print "Invalid input. Try again!\r\n"); return $prompt->data(); } sub find_driver { opendir(DIR, "."); my @driver = grep { /^(psyclpc|ldmud)-.+\.tar\.(gz|bz2)$/ } readdir(DIR); closedir(DIR); if (scalar(@driver) != 1) { return \@driver; } return $driver[0]; } sub investigate_protocol { my $setting = shift || die; my $what = shift || die; my $duse = shift || die; my $dport = shift || die; my $prange = shift; my $psome = shift; my $pport = shift; $v{'use_' . $setting} = get('Enable ' . $what . ': ', $v{'use_' . $setting} || $duse, YESNO); if ($v{'use_' . $setting} eq 'y') { my $trange; my $enf; if ($prange) { $trange = " between $prange->[0] and $prange->[1]"; $enf = NUMFT(@$prange); } elsif ($psome) { $trange = " ("; $enf = {}; for (my $i = 0; $i < scalar(@$psome); $i++) { $trange .= ' or ' if $i; $trange .= $psome->[$i]; $enf->{$psome->[$i]} = 1; } $trange .= ')'; } else { $enf = 1; } $v{'port_' . $setting} = get('Port number' . $trange . ': ', $dport, $enf); if ($pport) { print '[official port for ' . uc($setting) . " is $pport]\r\n\n"; } } } init(); #print Dumper(\%key2name); print BOLD "psyced.ini configuration generator wizard\r\n\n"; ## let's leave ldmud installation in install.sh for those who still want or ## need to do it manually. the majority should use distribution packages! ## #unless (!ref($t = find_driver())) { # print BOLD "ATTENTION: "; # print "You have "; # # if (scalar(@$t) == 0) { # print "no psyclpc-*.tar.gz in this directory\r\n"; # print "Please obtain one from http://lpc.psyc.eu\r\n"; # } else { # print "several driver tars in this directory\r\n"; # print "Please delete some of them until you have only one left.\r\n"; # print "If you continue now, this script won't compile a driver for you. \r\n\n"; # } # # unless (get("Continue? ", "n", YESNO) eq 'y') { exit; } # print "\r\n"; #} else { # print "I can see you have a driver tar here. That's good.\r\n\n"; #} print BOLD "INSTALLATION SPECIFIC QUESTIONS\r\n\n"; if ($>) { print "Since you started this installation not as root, you will see non-root defaults.\r\n\n"; } $v{'prefix'} = get("Install psyced to: ", $v{'prefix'} || $ENV{'HOME'} . "/psyced", 1); $v{'prefix_sbin'} = get("Install binaries to: ", $v{'prefix_sbin'} || $v{'prefix'}.'/sbin'); $v{'hostname'} = get("Server host name: ", $v{'hostname'} || $ENV{'HOSTNAME'}); print "\r\n"; print BOLD "HINT:"; print " Your domain name. If your server is funny.bunny.com, that'll be bunny.com\r\n"; $v{'domainname'} = get("Domain name: ", $v{'domainname'}); print "\r\nIf you have a static IP, please tell me. Otherwise leave this field blank.\r\n"; $v{'ip'} = get("Server IP address: ", $v{'ip'}); print "\r\n"; unless ($>) { $v{'user'} = get("Install and run psyced as user: ", $v{'user'} || $ENV{'USER'}); v{'group'} = get("Install and run psyced as group: ", $v{'group'} || $ENV{'GROUP'}); print "\r\n"; } print "Where do you want psyced runtime output? For manually started development\r\n"; print "servers choose 'console', for background daemon service use 'files'.\r\n"; $v{'log'} = get("Send server runtime output to: ", $v{'log'} || 'console', { 'files' => 1, 'console' => 1 }); $v{'debug'} = get("Debug level (0..4): ", '1', NUMFT(0, 4)); unless ($>) { $v{'init'} = get("Install a System V style init script? ", "n", YESNO); } print BOLD "\r\nPSYC SPECIFIC OPTIONS\r\n\n"; print<