home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.madoka.org
/
2014.12.ftp.madoka.org.tar
/
ftp.madoka.org
/
pub
/
plum
/
plum2_33_1.lzh
/
support
/
multiproxy
< prev
next >
Wrap
Text File
|
1999-03-24
|
5KB
|
207 lines
#!/bin/perl -w
# $Id: multiproxy,v 2.9 1999/01/20 15:04:08 hasegawa Exp $
# copyright (c)1998-1999 Yoshinori Hasegawa <hasegawa@madoka.org>
if ($] < 5) {
foreach $inc (@INC) {
if (-r "$inc/sys/socket.ph") {
eval 'require "sys/socket.ph"';
$SOCKET = "$inc/sys/socket.ph" unless $@;
last;
}
if (-r "$inc/socket.ph") {
eval 'require "socket.ph"';
$SOCKET = "$inc/socket.ph" unless $@;
last;
}
}
} else {
eval 'use Socket';
$SOCKET = 'Socket.pm' unless $@;
}
$NIL = $;;
$READSIZE = 1024;
$SOCKADDR = 'S n N x8';
$PROTO = (getprotobyname('tcp'))[2];
$AF_INET = eval '&AF_INET' || 2;
$PF_INET = eval '&PF_INET' || 2;
$SOCK_STREAM = eval '&SOCK_STREAM' || 1;
$SOMAXCONN = eval '&SOMAXCONN' || 16;
$INADDR_ANY = eval '&INADDR_ANY' || "\0\0\0\0";
$SOL_SOCKET = eval '&SOL_SOCKET';
$SO_REUSEADDR = eval '&SO_REUSEADDR';
$'rin = '';
$handle = 0;
$SIG{'PIPE'} = 'IGNORE' if &'exist(&'list(keys(%SIG)), 'PIPE');
&main();
sub main {
local($line, $llist, $slist, $rout, $host, $port, $lport, $nf, $tmp, $socket, $sno, $cno);
while (defined($line = <>)) {
$line =~ tr/\r\n//d;
($host, $port, $lport) = split(/\s+/, $line);
$remotehost{$lport} = $host;
$remoteport{$lport} = $port;
$portlist = &'add($portlist, $lport);
}
foreach $port (&'array($portlist)) {
$lno = &'listen($port, 0) || die "cannot listen port\n";
$llist = &'add($llist, $lno);
}
for (;;) {
$nf = select($rout = $'rin, undef, undef, undef);
die "error in select\n" if $nf < 0;
foreach $no (&'array($slist)) {
next unless vec($rout, $no, 1);
$tmp = '';
if (sysread($'socket[$no], $tmp, $READSIZE)) {
$socket = $'socket[$peer[$no]];
print $socket $tmp;
} else {
&'close($no);
&'close($peer[$no]);
$slist = &'remove($slist, $no, $peer[$no]);
}
}
foreach $lno (&'array($llist)) {
next unless vec($rout, $lno, 1);
$port = (&'sockname($lno))[0];
if ($cno = &'accept($lno)) {
if ($sno = &'connect($remotehost{$port}, $remoteport{$port})) {
$peer[$cno] = $sno;
$peer[$sno] = $cno;
$slist = &'add($slist, $cno, $sno);
} else {
&'close($cno);
}
}
}
}
}
sub 'connect {
local($host, $port) = @_;
local($serverno, $socket, $ip, @addr, $name);
if ($host =~ /^\d+$/) {
$ip = $host;
} elsif ($host =~ /^[\d\.]+$/) {
@addr = split(/\./, $host);
$ip = unpack('N', pack('C4', @addr, 0, 0, 0));
} else {
$ip = unpack('N', (gethostbyname($host))[4] || "\0\0\0\0");
}
return 0 unless $ip;
$socket = '\'S' . ++$handle;
socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
$name = pack($SOCKADDR, $AF_INET, $port, $ip);
connect($socket, $name) || return 0;
binmode($socket);
$serverno = fileno($socket);
vec($'rin, $serverno, 1) = 1;
$'socket[$serverno] = $socket;
select((select($socket), $| = 1)[0]);
$'access[$serverno] = time();
return $serverno;
}
sub 'listen {
local($port, $count) = @_;
local($listenno, $socket, $name);
$socket = '\'L' . ++$handle;
socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
if (defined($SOL_SOCKET) && defined($SO_REUSEADDR)) {
setsockopt($socket, $SOL_SOCKET, $SO_REUSEADDR, pack('l', 1));
}
$name = pack($SOCKADDR, $AF_INET, $port, unpack('N', $INADDR_ANY));
bind($socket, $name) || return 0;
listen($socket, $count || $SOMAXCONN) || return 0;
$listenno = fileno($socket);
vec($'rin, $listenno, 1) = 1;
$'socket[$listenno] = $socket;
select((select($socket), $| = 1)[0]);
$'access[$listenno] = time();
return $listenno;
}
sub 'accept {
local($listenno) = @_;
local($clientno, $socket);
$socket = '\'C' . ++$handle;
accept($socket, $'socket[$listenno]) || return 0;
binmode($socket);
$clientno = fileno($socket);
vec($'rin, $clientno, 1) = 1;
$'socket[$clientno] = $socket;
select((select($socket), $| = 1)[0]);
$'access[$clientno] = time();
return $clientno;
}
sub 'close {
local($no) = @_;
close($'socket[$no]);
vec($'rin, $no, 1) = 0;
}
sub 'sockname {
local($no) = @_;
local($port, $ip, $host);
($port, $ip) = (unpack($SOCKADDR, getsockname($'socket[$no])))[1, 2];
$host = (gethostbyaddr(pack('N', $ip), $AF_INET))[0];
return ($port, $ip, $host);
}
sub 'add {
local($list, @items) = @_;
$list = '' unless $list;
foreach $item (@items) {
next if &'exist($list, $item);
$list .= $NIL . $item;
}
return $list;
}
sub 'remove {
local($list, @items) = @_;
local($idx);
$list = '' unless $list;
$list .= $NIL;
foreach $item (@items) {
$idx = index("\L$list\E", $NIL . "\L$item\E" . $NIL);
next if $idx == -1;
substr($list, $idx, length($NIL . $item . $NIL)) = $NIL;
}
return substr($list, 0, length($list) - 1);
}
sub 'exist {
local($list, @items) = @_;
return 0 unless $list;
$list .= $NIL;
foreach $item (@items) {
return 1 if index("\L$list\E", $NIL . "\L$item\E" . $NIL) != -1;
}
return 0;
}
sub 'list {
local(@array) = @_;
return join($NIL, '', @array);
}
sub 'array {
local($list) = @_;
return () unless $list;
$list = substr($list, 1);
return () unless $list;
return split(/$NIL/, $list);
}