|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Stas Vlasov 2:5080/172 02 Jun 2002 18:52:10 To : All Subject : modem to telnet --------------------------------------------------------------------------------
Понадобилось мне перебросить модемное соединение на телнет. Сделать "телнет по
модему" под виндами. Hатуральный телнет, а не то извращение, что именуется bbs
doors. (на всякий случай напоминаю, что под виндами нет mgetty)
Конечно, удобнее было бы запустить службу удаленного доступа и потом уже
коннектиться по ppp, но тут несколько не тот случай (RAS мой брат уже сломал,
причем непонятно как умудрился). К тому же, порт постоянно занят фидошным
софтом, впрочем, позволяющим запустить другой софт, работающий с модемом.
Соответственно, был написан скрипт:
=== Cut ===
#!perl
use IPC::Open2;
use IO::Handle;
use strict;
my ($modem_device, $modem_command, $modem_pid, $telnet_pid,
$pid, $in, $out, $line);
$modem_device = '/dev/com2';
$modem_command = 'AT&D2O';
autoflush STDOUT, 1;
sub open_modem {
my $line;
my $stty = `/bin/stty -g`;
my $pid = open2( \*MODEM_IN, \*MODEM_OUT, "cu -l $modem_device -s 57600
--parity=none --nostop 2>&1");
# starting cu hoses /dev/tty's stty settings, even when it has
# been opened on a pipe...
system("/bin/stty $stty");
if ($pid == 0) {
die "Can't start cu !\n";
}
printf MODEM_OUT "$modem_command\r\n";
$line = <MODEM_IN>;
printf "$line";
while (!($line =~ /^[Cc][Oo][Nn][Nn][Ee][Cc][Tt]/)) {
$line = <MODEM_IN>;
printf "$line";
}
return $pid;
}
sub open_telnet {
my $pid = open2( \*TELNET_IN, \*TELNET_OUT, "c:/cygwin/bin/telnet localhost
2>&1");
if ($pid == 0) {
die "Can't start telnet !\n";
}
return $pid;
}
$modem_pid = open_modem();
$telnet_pid = open_telnet();
if ($pid = fork()) {
printf "#>$pid\n";
while (!(eof TELNET_IN)) {
read TELNET_IN, $in, 1;
print MODEM_OUT $in;
print $in;
};
} else {
printf "*>$pid\n";
while (!(eof MODEM_IN)) {
read MODEM_IN, $out, 1;
print TELNET_OUT $out;
};
exit;
}
`kill -9 $pid`;
close MODEM_IN;
close MODEM_OUT;
open CU, "ps -l|grep /usr/bin/cu|grep $modem_pid|";
while ($line = <CU>) {
chomp $line;
$pid = substr $line, 1, 8;
$pid =~ s/(^\s+|\s+$)//g;
printf "$pid\n";
`kill -9 $pid`;
}
close CU;
close TELNET_IN;
close TELNET_OUT;
`kill -9 $telnet_pid`;
=== Cut ===
Он работает. Даже смею сказать, что неплохо работает. Hо имеет единственный
недостаток - не умеет завершаться при обрыве соединения, что грозит тем, что
модем будет заблокирован до прихода админа, то есть минимум на несколько часов.
Потому вопрос: что можно сделать в данном случае?
В принципе, достаточно будет таймаута на пару минут. Hо как именно это лучше
сделать - я, к сожалению, не знаю. Могу сделать плохо. Хочется лучше.
Можете предложить скрипт, если уверены, что ваш вариант будет работать под
cygwin/NT
Good luck.
Stas
--- Еще одно "золото" 1.1.5-20020105
* Origin: gui is good, but console better (2:5080/172)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/22873cfa17be.html, оценка из 5, голосов 10
|