home *** CD-ROM | disk | FTP | other *** search
/ ftp.madoka.org / 2014.12.ftp.madoka.org.tar / ftp.madoka.org / pub / plum / 2.x / plum2_28_2.lzh / support / multiproxy < prev    next >
Text File  |  1998-10-15  |  5KB  |  211 lines

  1. #!/bin/perl -w
  2. # $Id: multiproxy,v 2.6 1998/10/06 04:21:18 hasegawa Exp $
  3. # copyright (c)1998 pupu_j <hasegawa@agusa.nuie.nagoya-u.ac.jp>
  4.  
  5. if ($] < 5) {
  6.   foreach $inc (@INC) {
  7.     if (-r "$inc/sys/socket.ph") {
  8.       eval { require 'sys/socket.ph' };
  9.       $SOCKET = "$inc/sys/socket.ph" unless $@;
  10.       last;
  11.     }
  12.     if (-r "$inc/socket.ph") {
  13.       eval { require 'socket.ph' };
  14.       $SOCKET = "$inc/socket.ph" unless $@;
  15.       last;
  16.     }
  17.   }
  18. } else {
  19.   eval 'use Socket';
  20.   $SOCKET = 'Socket.pm' unless $@;
  21. }
  22.  
  23. $NIL = $;;
  24.  
  25. $READSIZE = 1024;
  26. $SOCKADDR = 'S n N x8';
  27.  
  28. $PROTO = getprotobyname('tcp');
  29.  
  30. $AF_INET = eval { &AF_INET } || 2;
  31. $PF_INET = eval { &PF_INET } || 2;
  32. $SOCK_STREAM = eval { &SOCK_STREAM } || 1;
  33. $SOMAXCONN = eval { &SOMAXCONN } || 16;
  34. $INADDR_ANY = eval { &INADDR_ANY } || "\0\0\0\0";
  35. $SOL_SOCKET = eval { &SOL_SOCKET};
  36. $SO_REUSEADDR = eval { &SO_REUSEADDR };
  37.  
  38. $'rin = '';
  39.  
  40. $handle = 0;
  41.  
  42. $SIG{'PIPE'} = 'IGNORE' if &'exist(&'list(keys(%SIG)), 'PIPE');
  43.  
  44. &main();
  45.  
  46. sub main {
  47.   local($line, $llist, $slist, $rout, $host, $port, $lport, $nf, $tmp, $socket, $sno, $cno);
  48.   while (defined($line = <>)) {
  49.     $line =~ tr/\r\n//d;
  50.     ($host, $port, $lport) = split(/\s+/, $line);
  51.     $remotehost{$lport} = $host;
  52.     $remoteport{$lport} = $port;
  53.     $portlist = &'add($portlist, $lport);
  54.   }
  55.   foreach $port (&'array($portlist)) {
  56.     $lno = &'listen($port, 0) || die "cannot listen port\n";
  57.     $llist = &'add($llist, $lno);
  58.   }
  59.   for (;;) {
  60.     $nf = select($rout = $'rin, undef, undef, undef);
  61.     die "error in select\n" if $nf < 0;
  62.     foreach $no (&'array($slist)) {
  63.       next unless vec($rout, $no, 1);
  64.       $tmp = '';
  65.       if (sysread($'socket[$no], $tmp, $READSIZE)) {
  66.         $socket = $'socket[$peer[$no]];
  67.         print $socket $tmp;
  68.       } else {
  69.         &'close($no);
  70.         &'close($peer[$no]);
  71.         $slist = &'remove($slist, $no, $peer[$no]);
  72.       }
  73.     }
  74.     foreach $lno (&'array($llist)) {
  75.       next unless vec($rout, $lno, 1);
  76.       $port = (&'sockname($lno))[0];
  77.       if ($cno = &'accept($lno)) {
  78.         if ($sno = &'connect($remotehost{$port}, $remoteport{$port})) {
  79.           $peer[$cno] = $sno;
  80.           $peer[$sno] = $cno;
  81.           $slist = &'add($slist, $cno, $sno);
  82.         } else {
  83.           &'close($cno);
  84.         }
  85.       }
  86.     }
  87.   }
  88. }
  89.  
  90. sub 'connect {
  91.   local($host, $port) = @_;
  92.   local($serverno, $socket, $ip, @addr, $name);
  93.   if ($host =~ /^\d+$/) {
  94.     $ip = $host;
  95.   } elsif ($host =~ /^[\d\.]+$/) {
  96.     @addr = split(/\./, $host);
  97.     $ip = unpack('N', pack('C4', @addr, 0, 0, 0));
  98.   } else {
  99.     $ip = unpack('N', (gethostbyname($host))[4] || "\0\0\0\0");
  100.   }
  101.   return 0 unless $ip;
  102.   $socket = '\'S' . ++$handle;
  103.   socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
  104.   $name = pack($SOCKADDR, $AF_INET, $port, $ip);
  105.   connect($socket, $name) || return 0;
  106.   $serverno = fileno($socket);
  107.   vec($'rin, $serverno, 1) = 1;
  108.   $'socket[$serverno] = $socket;
  109.   select((select($socket), $| = 1)[0]);
  110.   $'access[$serverno] = time();
  111.   return $serverno;
  112. }
  113.  
  114. sub 'listen {
  115.   local($port, $count) = @_;
  116.   local($listenno, $socket, $name);
  117.   $socket = '\'L' . ++$handle;
  118.   socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
  119.   if (defined($SOL_SOCKET) && defined($SO_REUSEADDR)) {
  120.     setsockopt($socket, $SOL_SOCKET, $SO_REUSEADDR, pack('l', 1));
  121.   }
  122.   $name = pack($SOCKADDR, $AF_INET, $port, unpack('N', $INADDR_ANY));
  123.   bind($socket, $name) || return 0;
  124.   listen($socket, $count || $SOMAXCONN) || return 0;
  125.   $listenno = fileno($socket);
  126.   vec($'rin, $listenno, 1) = 1;
  127.   $'socket[$listenno] = $socket;
  128.   select((select($socket), $| = 1)[0]);
  129.   $'access[$listenno] = time();
  130.   return $listenno;
  131. }
  132.  
  133. sub 'accept {
  134.   local($listenno) = @_;
  135.   local($clientno, $socket);
  136.   $socket = '\'C' . ++$handle;
  137.   accept($socket, $'socket[$listenno]) || return 0;
  138.   $clientno = fileno($socket);
  139.   vec($'rin, $clientno, 1) = 1;
  140.   $'socket[$clientno] = $socket;
  141.   select((select($socket), $| = 1)[0]);
  142.   $'access[$clientno] = time();
  143.   return $clientno;
  144. }
  145.  
  146. sub 'close {
  147.   local($no) = @_;
  148.   close($'socket[$no]);
  149.   vec($'rin, $no, 1) = 0;
  150. }
  151.  
  152. sub 'sockname {
  153.   local($no) = @_;
  154.   local($port, $ip, $host);
  155.   ($port, $ip) = (unpack($SOCKADDR, getsockname($'socket[$no])))[1, 2];
  156.   $host = (gethostbyaddr(pack('N', $ip), $AF_INET))[0];
  157.   return ($port, $ip, $host);
  158. }
  159.  
  160. sub 'add {
  161.   local($list, @items) = @_;
  162.   $list = $NIL unless $list;
  163.   foreach $item (@items) {
  164.     next if &'exist($list, $item);
  165.     $list = $list . $item . $NIL;
  166.   }
  167.   $list = '' if $list eq $NIL;
  168.   return $list;
  169. }
  170.  
  171. sub 'remove {
  172.   local($list, @items) = @_;
  173.   local($idx);
  174.   $list = $NIL unless $list;
  175.   foreach $item (@items) {
  176.     $idx = index("\L$list\E", $NIL . "\L$item\E" . $NIL);
  177.     next if $idx == -1;
  178.     substr($list, $idx, length($NIL . $item . $NIL)) = $NIL;
  179.   }
  180.   $list = '' if $list eq $NIL;
  181.   return $list;
  182. }
  183.  
  184. sub 'exist {
  185.   local($list, @items) = @_;
  186.   return 0 unless $list;
  187.   foreach $item (@items) {
  188.     return 1 if index("\L$list\E", $NIL . "\L$item\E" . $NIL) != -1;
  189.   }
  190.   return 0;
  191. }
  192.  
  193. sub 'list {
  194.   local(@array) = @_;
  195.   local($list);
  196.   if (scalar(@array)) {
  197.     $list = $NIL . join($NIL, @array) . $NIL;
  198.   } else {
  199.     $list = '';
  200.   }
  201.   return $list;
  202. }
  203.  
  204. sub 'array {
  205.   local($list) = @_;
  206.   $list = $NIL unless $list;
  207.   return () if $list eq $NIL;
  208.   $list = substr($list, 1, length($list) - 2);
  209.   return split(/$NIL/, $list);
  210. }
  211.