#!/usr/local/bin/perl ;# ;# tcpreceive: read input from tcp port and output to stdout ;# ;# Copyright (c) 1991-1994 Kazumasa Utashiro ;# Software Research Associates, Inc., Japan ;# 1-1-1 Hirakawa-cho, Chiyoda-ku, Tokyo 102, Japan ;# ;; $_=<<";#."; ;# Usage: tcpreceive [-p port] [-i userid] [client] ;# ;# Options: ;# -p port local port number (taken from system if not specified) ;# -i userid restrict remote user using ident protocol ;# -d debug option ;# -h show this message ;# ;# client specify remote host if necessary ;#. ;; ($usage = $_) =~ s/(^|\n);# ?/\1/g; ;; $rcsid = '$Id: tcpreceive,v 1.2 1994/04/27 07:47:00 utashiro Exp $' ;# ;# ;# DESCRIPTION ;# ;# Tcpreceive opens port, wait for connection from remote host ;# and prints incoming data to the standard output. It works ;# like a pipe across the network and useful when used with ;# tcpconnect command. ;# ;# ;# Example: ;# ;# On one machine: ;# % tcpreceive | tar xf - ;# Please connect to port=xxxx ;# ;# On the other machine: ;# % tar cf - . | tcpconnect client:xxxx ;# ;# require 'sys/socket.ph'; unless (do 'sys/socket.ph') { print STDERR "File sys/socket.ph is not found. Using default...\n"; eval 'sub SOCK_STREAM {1;} sub AF_INET {2;} sub PF_INET { &AF_INET;}'; } ;# ;# &usage2opts: Generate getopts string from usage ;# sub usage2opts { local($_, $opts) = shift; while (/(^|\n)\t-(\w)(\t|\s\s)?/g) { $opts .= $2 . ($3 ? '' : ':'); } $opts; } require 'getopts.pl'; sub usage { print $usage, "\n$rcsid\n"; exit 1; } &Getopts(&usage2opts($usage)) || &usage; &usage if $opt_h; $debug = $opt_d; $silent = $opt_s; $localport = $opt_p; $userid = $opt_i; $clientname = shift; if ($userid) { require 'ident.pl'; $ident'debug = $debug; } $sockaddr='S n a4 x8'; ($name, $aliases, $TCP) = getprotobyname('tcp'); select(STDERR); chop($localname = `hostname`); ($name, $aliases, $type, $len, $localaddr) = gethostbyname($localname); if ($clientname) { $clientaddr = &getaddr($clientname) || die "Unknown client $clientname.\n"; } $serverport = (getservbyname($serverport, 'tcp'))[2] unless $serverport =~ /^\d+$/; $this = pack($sockaddr, &AF_INET, $localport, pack('N', 0)); socket(S, &PF_INET, &SOCK_STREAM, $TCP) || die "socket: $!\n"; bind(S, $this) || die "bind: $!\n"; listen(S, 1) || die "listen: $!\n"; $newport = (unpack($sockaddr, getsockname(S)))[1]; printf STDERR "Please connect to port=%d\n", $newport; ($addr = accept(NS, S)) || die "accept: $!\n"; ($af, $peerport, $peeraddr) = unpack($sockaddr, $addr); if ($clientaddr && $peeraddr ne $clientaddr) { printf STDERR "Host \"%s\" is not allowed!\n", &dotted($peeraddr); exit 1; } printf STDERR "Connection established with %s(%d)\n", &dotted($peeraddr), $peerport if $debug; if ($userid) { $remoteuser = &ident(NS); if ($userid ne $remoteuser) { if ($remoteuser) { printf STDERR "User \"%s\" is not allowed!\n", $remoteuser; } else { printf STDERR "Can't ident remote user.\n"; } exit 1; } printf STDERR "Remote user is \"%s\".\n", $remoteuser if $debug; } &forward(NS, STDOUT); print STDERR "$0($$): exiting\n" if $debug; exit 0; sub forward { local($from, $to) = @_; eval "print $to \$_ while(read($from, \$_, 4096));"; shutdown($from, 1); shutdown($to, 0); } sub getaddr { local($_) = @_; /^[0-9\.]+$/ ? pack("C4", split(/\./)) : (gethostbyname($_))[4]; } sub dotted { join('.', unpack('C4', shift)); }