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 / proxy < prev    next >
Text File  |  1999-03-24  |  5KB  |  196 lines

  1. #!/bin/perl -w
  2. # $Id: proxy,v 2.11 1999/01/20 15:05:30 hasegawa Exp $
  3. # copyright (c)1997-1999 Yoshinori Hasegawa <hasegawa@madoka.org>
  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'))[2];
  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(@ARGV);
  45.  
  46. sub main {
  47.   local(@args) = @_;
  48.   local($slist, $rout, $nf, $sno, $cno, $lno, $socket, $tmp);
  49.   if (@args < 3) {
  50.     &usage();
  51.     exit(1);
  52.   }
  53.   $lno = &'listen($args[2], 0) || die "cannot listen port\n";
  54.   for (;;) {
  55.     $nf = select($rout = $'rin, undef, undef, undef);
  56.     die "error in select\n" if $nf < 0;
  57.     foreach $no (&'array($slist)) {
  58.       next unless vec($rout, $no, 1);
  59.       $tmp = '';
  60.       if (sysread($'socket[$no], $tmp, $READSIZE)) {
  61.         $socket = $'socket[$peer[$no]];
  62.         print $socket $tmp if fileno($socket);
  63.       } else {
  64.         &'close($no);
  65.         &'close($peer[$no]);
  66.         $slist = &'remove($slist, $no, $peer[$no]);
  67.       }
  68.     }
  69.     if (vec($rout, $lno, 1)) {
  70.       if ($cno = &'accept($lno)) {
  71.         if ($sno = &'connect($args[0], $args[1])) {
  72.           $peer[$sno] = $cno;
  73.           $peer[$cno] = $sno;
  74.           $slist = &'add($slist, $sno, $cno);
  75.         } else {
  76.           &'close($cno);
  77.         }
  78.       }
  79.     }
  80.   }
  81. }
  82.  
  83. sub usage {
  84.   print 'usage: perl proxy <server> <port> <listen-port>', "\n";
  85. }
  86.  
  87. sub 'connect {
  88.   local($host, $port) = @_;
  89.   local($serverno, $socket, $ip, @addr, $name);
  90.   if ($host =~ /^\d+$/) {
  91.     $ip = $host;
  92.   } elsif ($host =~ /^[\d\.]+$/) {
  93.     @addr = split(/\./, $host);
  94.     $ip = unpack('N', pack('C4', @addr, 0, 0, 0));
  95.   } else {
  96.     $ip = unpack('N', (gethostbyname($host))[4] || "\0\0\0\0");
  97.   }
  98.   return 0 unless $ip;
  99.   $socket = '\'S' . ++$handle;
  100.   socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
  101.   $name = pack($SOCKADDR, $AF_INET, $port, $ip);
  102.   connect($socket, $name) || return 0;
  103.   binmode($socket);
  104.   $serverno = fileno($socket);
  105.   vec($'rin, $serverno, 1) = 1;
  106.   $'socket[$serverno] = $socket;
  107.   select((select($socket), $| = 1)[0]);
  108.   $'access[$serverno] = time();
  109.   return $serverno;
  110. }
  111.  
  112. sub 'listen {
  113.   local($port, $count) = @_;
  114.   local($listenno, $socket, $name);
  115.   $socket = '\'L' . ++$handle;
  116.   socket($socket, $PF_INET, $SOCK_STREAM, $PROTO) || return 0;
  117.   if (defined($SOL_SOCKET) && defined($SO_REUSEADDR)) {
  118.     setsockopt($socket, $SOL_SOCKET, $SO_REUSEADDR, pack('l', 1));
  119.   }
  120.   $name = pack($SOCKADDR, $AF_INET, $port, unpack('N', $INADDR_ANY));
  121.   bind($socket, $name) || return 0;
  122.   listen($socket, $count || $SOMAXCONN) || return 0;
  123.   $listenno = fileno($socket);
  124.   vec($'rin, $listenno, 1) = 1;
  125.   $'socket[$listenno] = $socket;
  126.   select((select($socket), $| = 1)[0]);
  127.   $'access[$listenno] = time();
  128.   return $listenno;
  129. }
  130.  
  131. sub 'accept {
  132.   local($listenno) = @_;
  133.   local($clientno, $socket);
  134.   $socket = '\'C' . ++$handle;
  135.   accept($socket, $'socket[$listenno]) || return 0;
  136.   binmode($socket);
  137.   $clientno = fileno($socket);
  138.   vec($'rin, $clientno, 1) = 1;
  139.   $'socket[$clientno] = $socket;
  140.   select((select($socket), $| = 1)[0]);
  141.   $'access[$clientno] = time();
  142.   return $clientno;
  143. }
  144.  
  145. sub 'close {
  146.   local($no) = @_;
  147.   close($'socket[$no]);
  148.   vec($'rin, $no, 1) = 0;
  149. }
  150.  
  151. sub 'add {
  152.   local($list, @items) = @_;
  153.   $list = '' unless $list;
  154.   foreach $item (@items) {
  155.     next if &'exist($list, $item);
  156.     $list .= $NIL . $item;
  157.   }
  158.   return $list;
  159. }
  160.  
  161. sub 'remove {
  162.   local($list, @items) = @_;
  163.   local($idx);
  164.   $list = '' unless $list;
  165.   $list .= $NIL;
  166.   foreach $item (@items) {
  167.     $idx = index("\L$list\E", $NIL . "\L$item\E" . $NIL);
  168.     next if $idx == -1;
  169.     substr($list, $idx, length($NIL . $item . $NIL)) = $NIL;
  170.   }
  171.   return substr($list, 0, length($list) - 1);
  172. }
  173.  
  174. sub 'exist {
  175.   local($list, @items) = @_;
  176.   return 0 unless $list;
  177.   $list .= $NIL;
  178.   foreach $item (@items) {
  179.     return 1 if index("\L$list\E", $NIL . "\L$item\E" . $NIL) != -1;
  180.   }
  181.   return 0;
  182. }
  183.  
  184. sub 'list {
  185.   local(@array) = @_;
  186.   return join($NIL, '', @array);
  187. }
  188.  
  189. sub 'array {
  190.   local($list) = @_;
  191.   return () unless $list;
  192.   $list = substr($list, 1);
  193.   return () unless $list;
  194.   return split(/$NIL/, $list);
  195. }
  196.