#!/usr/bin/perl
# AQ
# 20120424

BEGIN { $ENV{LC_ALL} = "en_EN"; }
use IPC::SysV qw(IPC_STAT IPC_PRIVATE);

use utf8;
use Glib qw/TRUE FALSE/;
use Gtk2 '-init';

Gtk2::Rc->parse_string(<<__);
style "superbig" {
    font_name ="Droid Sans 14"
}

style "normal" {
    font_name = "Droid Sans 10"
}

style "error" {
    font_name ="Droid Sans 12"
    text[NORMAL] = "#FF0000"
    fg[NORMAL] = "#FF0000"
}

widget "*" style "normal"
widget "*error*" style "error"
widget "*Button*" style "superbig"
__

sub callback {
	my $widget = shift;
	my $data   = shift;
	if ($data =~ m/test/) {
	  $pchild = $portmenu->get_history;
	  $port = $Ports[$pchild];
	  open (CONF, ">/etc/ppp/peers/internet.test") || die "Can't open /etc/ppp/peers/internet.test\n";
	  print CONF "hide-password\n";
	  print CONF "$port\n";
	  $schild = $speedmenu->get_history;
	  $speed = $Speeds[$schild];
	  print CONF "$speed\n";
	  $login = $entry_login->get_text;
	  print CONF "user \"$login\"\n";
	  print CONF "connect \"/usr/sbin/chat -v -f /etc/ppp/peers/chat.test\"\n";
	  close(CONF);

	  open (CHAT, ">/etc/ppp/peers/chat.test") || die "Can't open /etc/ppp/peers/chat.test\n";
	  print CHAT "TIMEOUT 5\n";
	  print CHAT "ABORT \"NO CARRIER\"\n";
	  print CHAT "ABORT ERROR\n";
	  print CHAT "\"\" AT+CSQ\n";
	  print CHAT "OK ATE1\n";
	  $init = $entry_init->get_text;
	  print CHAT "OK AT+CGDCONT=1,\"IP\",\"$init\"\n";
	  $num = $entry_num->get_text;
	  if ($num eq "") {$num = "*99***1#";}
	  print CHAT "OK ATD$num\n";
	  print CHAT "CONNECT \\c\n";
	  close (CHAT);

	  open (PAPS, "<:utf8", "/etc/ppp/pap-secrets") || die "Can't open /etc/ppp/pap-secrets\n";
	  @PAPS = <PAPS>;
	  close (PAPS);
	  $papsize = @PAPS;

	  $have=0;
	  open (PAPS, ">/etc/ppp/pap-secrets") || die "Can't open /etc/ppp/pap-secrets\n";
	  for ($i=0;$i<$papsize;$i++) {
	    $str = @PAPS[$i];
	    chomp($str);
	    if ($str =~ m/$login/ && $str =~ m/\*/) {
	      $pass = $entry_pass->get_text;	
	      print PAPS "$login\t*\t$pass\n";
	      $have=1;
	    } else {
	      print PAPS "$str\n";
	    }
	  }
	  
	  if ($have==0) {
	      $pass = $entry_pass->get_text;	
	      print PAPS "$login\t*\t$pass\n";
	  }
	  close(PAPS);

	  system("pppd call internet.test");
	}

	if ($data =~ m/save/) {
	  $pchild = $portmenu->get_history;
	  $port = $Ports[$pchild];
	  open (CONF, ">/etc/ppp/peers/internet") || die "Can't open /etc/ppp/peers/internet\n";
	  print CONF "hide-password\n";
	  print CONF "$port\n";
	  $schild = $speedmenu->get_history;
	  $speed = $Speeds[$schild];
	  print CONF "$speed\n";
	  $login = $entry_login->get_text;
	  print CONF "user \"$login\"\n";
	  print CONF "connect \"/usr/sbin/chat -v -f /etc/ppp/peers/chat\"\n";
	  close(CONF);

	  open (CHAT, ">/etc/ppp/peers/chat") || die "Can't open /etc/ppp/peers/chat\n";
	  print CHAT "TIMEOUT 30\n";
	  print CHAT "ABORT \"NO CARRIER\"\n";
	  print CHAT "ABORT ERROR\n";
	  print CHAT "\"\" AT+CSQ\n";
	  print CHAT "OK ATE1\n";
	  $init = $entry_init->get_text;
	  print CHAT "OK AT+CGDCONT=1,\"IP\",\"$init\"\n";
	  $num = $entry_num->get_text;
	  if ($num eq "") {$num = "*99***1#";}
	  print CHAT "OK ATD$num\n";
	  print CHAT "CONNECT \\c\n";
	  close (CHAT);

	  open (PAPS, "<:utf8", "/etc/ppp/pap-secrets") || die "Can't open /etc/ppp/pap-secrets\n";
	  @PAPS = <PAPS>;
	  close (PAPS);
	  $papsize = @PAPS;

	  $have=0;
	  open (PAPS, ">/etc/ppp/pap-secrets") || die "Can't open /etc/ppp/pap-secrets\n";
	  for ($i=0;$i<$papsize;$i++) {
	    $str = @PAPS[$i];
	    chomp($str);
	    if ($str =~ m/$login/ && $str =~ m/\*/) {
	      $pass = $entry_pass->get_text;
	      print PAPS "$login\t*\t$pass\n";
	      $have=1;
	    } else {
	      print PAPS "$str\n";
	    }
	  }
	  
	  if ($have==0) {
	      $pass = $entry_pass->get_text;	
	      print PAPS "$login\t*\t$pass\n";
	  }
	  close(PAPS);
	}
  return TRUE;
}

sub on_stop {
	Gtk2->main_quit;
}

sub insert_text {
  my $buffer = shift;
  $iter2 = $buffer->get_iter_at_offset (0);
  $buffer->delete ($iter,$iter2);

  system("tail -n 50 /var/log/messages | grep -e pppd -e chat -e pptp -e pppoe | tail -n 30 > /tmp/pppd");
  open (LOG, "<:utf8", "/tmp/pppd") || die "Can't open /tmp/pppd\n";
  @LOG = <LOG>;
  close (LOG);
  $size = @LOG;

  for ($i=29;$i>0;$i--) {
    if ($i > $size) {
    $str = "";
    } else {
    $str = @LOG[$size-$i];
    }
    chomp($str);
    if ($str =~ m/erminated/ || $str =~ m/nrecognized/ || $str =~ m/alarm/ || $str =~ m/imeout/ || $str =~ m/ailed/ || $str =~ m/Invalid/ || $str =~ m/fatal/) {
      $buffer->insert_with_tags_by_name ($iter, "$str\n", "red_foreground");
    }
    elsif ($str =~ m/CHAP authentication succeeded/ || $str =~ m/IP address/ || $str =~ m/DNS address/) {
      $buffer->insert_with_tags_by_name ($iter, "$str\n", "fgreen_foreground");
    }
    elsif ($str =~ m/ifup-pp/) {
      $buffer->insert_with_tags_by_name ($iter, "$str\n", "indigo_foreground");
    }
    elsif ($str =~ m/pppd/) {
      $buffer->insert_with_tags_by_name ($iter, "$str\n", "green_foreground");
    }
    elsif ($str =~ m/chat/ || $str =~ m/pptp/ || $str =~ m/pppoe/) {
      $buffer->insert_with_tags_by_name ($iter, "$str\n", "cyan_foreground");
    }
    else {
      $buffer->insert ($iter, "$str\n");
    }
  }
  return TRUE;
}

sub port_search {
	  open(SERINFO,"/proc/tty/driver/serial");
	   while(<SERINFO>) {
	    if ($_ =~ m/16550A/ || $_ =~ m/16650V/) {
	      ($port,$raw) = split(":", $_);
	      $port_name = "/dev/ttyS$port";
	      push(@Ports, $port_name);
	      $menuitem = Gtk2::MenuItem->new_with_label ($port_name);
	      $menu->append ($menuitem);
	      $menuitem->show;
	    }
  }
  for ($i=0;$i<65;$i++) {
  if (-e "/dev/ttyUSB$i") {
    $port_name = "/dev/ttyUSB$i";
    push(@Ports, $port_name);
    $menuitem = Gtk2::MenuItem->new_with_label ($port_name);
    $menu->append ($menuitem);
    $menuitem->show;
  }
  if (-e "/dev/ttyACM$i") {
    $port_name = "/dev/ttyACM$i";
    push(@Ports, $port_name);
    $menuitem = Gtk2::MenuItem->new_with_label ($port_name);
    $menu->append ($menuitem);
    $menuitem->show;
  }
  if (-e "/dev/ttyM$i") {
    $port_name = "/dev/ttyM$i";
    push(@Ports, $port_name);
    $menuitem = Gtk2::MenuItem->new_with_label ($port_name);
    $menu->append ($menuitem);
    $menuitem->show;
  }
  if (-e "/dev/ttyD$i") {
    $port_name = "/dev/ttyD$i";
    push(@Ports, $port_name);
    $menuitem = Gtk2::MenuItem->new_with_label ($port_name);
    $menu->append ($menuitem);
    $menuitem->show;
  }
  }
  return TRUE;
}

Gtk2->init;

$window = Gtk2::Window->new;
$window->signal_connect("destroy" => \&on_stop);
$window->signal_connect("delete-event" => \&on_stop);
$window->set_default_size(800,700);
$window->set_position (GTK_WIN_POS_CENTER);
$window->set_title("Configure PPP connection");
$window->activate_focus;
$window->set_border_width(3);

$table = Gtk2::Table->new(12, 12, TRUE);
$table->set_col_spacings (2);
$table->set_row_spacings (2);
$window->add($table);

#$label_top = Gtk2::Label->new (undef);
#$table->attach_defaults($label_top, 0, 12, 0, 1);
#$label_top->set_label ("Настройка PPP подключения");
#$label_top->show;

$button_save = Gtk2::Button->new("Save");
$image_save  = Gtk2::Image->new_from_file('/usr/share/icons/Faenza/actions/22/gtk-save.png');
$button_save->set_image ($image_save);
$button_save->set_image_position ('top');
$button_save->signal_connect("clicked" => \&callback, "save");
$table->attach_defaults($button_save, 0, 4, 3, 4);
$image_save->show;
$button_save->show;
$button_exit = Gtk2::Button->new("Exit");
$image_exit  = Gtk2::Image->new_from_file('/usr/share/icons/Faenza/actions/22/application-exit.png');
$button_exit->set_image ($image_exit);
$button_exit->set_image_position ('top');
$button_exit->signal_connect("clicked" => \&on_stop);
$table->attach_defaults($button_exit, 4, 8, 3, 4);
$image_exit->show;
$button_exit->show;
$button_test = Gtk2::Button->new("Test calling");
$image_exit  = Gtk2::Image->new_from_file('/usr/share/icons/Faenza/actions/22/call-start.png');
$button_test->set_image ($image_exit);
$button_test->set_image_position ('top');
$button_test->signal_connect("clicked" => \&callback, "test");
$table->attach_defaults($button_test, 8, 12, 3, 4);
$image_exit->show;
$button_test->show;

#$button_key = Gtk2::Button->new("Экранная клавиатура");
#$image_exit  = Gtk2::Image->new_from_file('keyboard22.png');
#$button_key->set_image ($image_exit);
#$button_key->set_image_position ('top');
#$button_key->signal_connect("clicked" => \&callback, "keyboard");
#$table->attach_defaults($button_key, 0, 12, 11, 12);
#$image_exit->show;
#$button_key->show;
$label_error = Gtk2::Label->new (undef);
$label_error->set_name("error");
$table->attach_defaults($label_error, 0, 12, 11, 12);
$label_error->show;

$label_login = Gtk2::Label->new (undef);
$table->attach_defaults($label_login, 0, 2, 0, 1);
$label_login->set_label ("Login");
$label_login->show;
$label_pass = Gtk2::Label->new (undef);
$table->attach_defaults($label_pass, 6, 8, 0, 1);
$label_pass->set_label ("Password");
$label_pass->show;
$label_num = Gtk2::Label->new (undef);
$table->attach_defaults($label_num, 0, 2, 1, 2);
$label_num->set_label ("Number");
$label_num->show;
$label_cgd = Gtk2::Label->new (undef);
$table->attach_defaults($label_cgd, 6, 9, 1, 2);
$label_cgd->set_label ("Property string");
$label_cgd->show;
$label_port = Gtk2::Label->new (undef);
$table->attach_defaults($label_port, 0, 2, 2, 3);
$label_port->set_label ("Modem port");
$label_port->show;
$label_speed = Gtk2::Label->new (undef);
$table->attach_defaults($label_speed, 6, 8, 2, 3);
$label_speed->set_label ("Port speed");
$label_speed->show;


$entry_login = Gtk2::Entry->new;
$table->attach_defaults($entry_login, 2, 6, 0, 1);
$entry_login->show;
$entry_pass = Gtk2::Entry->new;
$table->attach_defaults($entry_pass, 8, 12, 0, 1);
$entry_pass->show;
$entry_num = Gtk2::Entry->new;
$table->attach_defaults($entry_num, 2, 6, 1, 2);
$entry_num->show;
$entry_init = Gtk2::Entry->new;
$table->attach_defaults($entry_init, 9, 12, 1, 2);
$entry_init->show;

$view = Gtk2::TextView->new;
$buffer = $view->get_buffer;
$iter = $buffer->get_iter_at_offset (0);
$buffer->create_tag ("red_foreground", foreground => "Firebrick");
$buffer->create_tag ("green_foreground", foreground => "Dark Olive Green");
$buffer->create_tag ("cyan_foreground", foreground => "Dark Cyan");
$buffer->create_tag ("indigo_foreground", foreground => "Dark Blue");
$buffer->create_tag ("fgreen_foreground", foreground => "Forest Green");
$sw = Gtk2::ScrolledWindow->new;
$sw->set_policy ('automatic', 'automatic');
$sw->set_shadow_type ('in');
$table->attach_defaults($sw, 0, 12, 4, 12);
$sw->add ($view);
$view->show;
$sw->show;
$timer = Glib::Timeout->add(1000, \&insert_text, $buffer);

$menu = Gtk2::Menu->new;
&port_search;
$portmenu = Gtk2::OptionMenu->new;
$portmenu->set_menu ($menu);
$portmenu->set_history (0);
$table->attach_defaults($portmenu, 2, 6, 2, 3);
$portmenu->show;

$speedmnu = Gtk2::Menu->new;
$speedmenuitem = Gtk2::MenuItem->new_with_label ("115200");
push(@Speeds, "115200");
$speedmnu->append ($speedmenuitem);
$speedmenuitem->show;
$speedmenuitem = Gtk2::MenuItem->new_with_label ("9600");
push(@Speeds, "9600");
$speedmnu->append ($speedmenuitem);
$speedmenuitem->show;

$speedmenu = Gtk2::OptionMenu->new;
$speedmenu->set_menu ($speedmnu);
$speedmenu->set_history (0);
$table->attach_defaults($speedmenu, 8, 12, 2, 3);
$speedmenu->show;

$table->show;
$window->show;

Gtk2->main;
