On 10/21/2017 5:40 AM, Rob Jarratt via cctech wrote:
I have a couple of hard disks I want to make dd copies
of. I have Ultrix
running on my DECstation 5000/240 with the disk I want to clone attached to
it. The trouble is that I don't have enough disk space on the machine to
clone the disk and then grab the image using FTP. I have been trying to find
a way to pipe the dd output over the network to a SIMH Ultrix machine that
has plenty of disk space. I tried piping dd into rcp, but rcp doesn't seem
to take input from standard input. I have looked at cpio, but that too
appears not to accept input from standard input.
Unix is not my strong point. Are there any other ways I could pipe the dd
output across the network to a machine that has enough disk space?
Thanks
Rob
One way would be to attach the drive to an x86 machine that supports the
disk drives, and use clonezilla.
Another way, which I have used, is to use perl or Python to do the job.
They are relatively small, so I just included mine here.
I had trouble with the perl version under Linux at some point, so now on
the Linux side, I use a Python version. NOTE: I am not very fluent in
Python. Also, I don't use the Python server version.
#!/usr/bin/perl
#
# Simple program for piping output (such as tar) from one system to another.
# Contains client and server in the same script.
#
# Usage: tcppipe [ -c server [-i file] ] | [ -s [-o file] ] [-p port]
#
# The client reads standard input by default and sends it to "server" on
"port".
# The server writes standard output by default.
#
# Port defaults to 1025
#
# JRJ 12/95
#
use Getopt::Std;
use Socket;
$debug=1;
$PROGRAM='tcppipe';
$VERSION='V1.0';
$PORT = 4097;
$MTU=65536;
$AF_INET=2;
$SOCK_STREAM=1;
$PF_INET=2;
$sockaddr='S n a4 x8';
#
# Get and validate options.
#
getopts('c:si:o:p:') || usage();
if(($opt_c && $opt_s) || (!$opt_c && !$opt_s) ||
($opt_c && $opt_o) || ($opt_s && $opt_i)) {
usage();
}
if(!$opt_p) {
$opt_p = $PORT;
}
#
# Call the client or server piece, as appropriate.
#
if($opt_c) {
return(pipe_client($opt_c,$opt_p,$opt_i));
}
else {
return(pipe_server($opt_p,$opt_o));
}
#
# Client piece
#
sub pipe_client {
local($server,$client_port,$infile) = @_;
if($infile && ! -f $infile) {
die "$0: $infile is not a valid file.\n";
}
#
# Open the file. In binary, if you please...
#
if($infile) {
open(INFILE,$infile) || die "$0: Can't open file $infile: $!";
$fd = INFILE;
}
else {
$fd = STDIN;
}
binmode $fd;
if($debug) {
print "Server: $server \n";
}
#
# Do some work to prepare the socket data structures
#
($pname, $paliases, $proto) = getprotobyname('tcp');
($hname, $haliases, $htype, $hlen, $hip) = gethostbyname($server);
if(!defined($hip)) {
die "$0: Unknown host: $server : $! ";
}
if($debug) {
@nip = unpack('C4',$hip);
print "Host address for $server: @nip \n";
}
$netaddr = pack($sockaddr, $AF_INET, $client_port, $hip);
socket(SERVER,$PF_INET,$SOCK_STREAM,$proto) ||
die "Can't create socket: $!";
#
# Open the connection to the server.
#
connect(SERVER,$netaddr) || die "Can't connect to server: $!";
select(SERVER); $|=1; select(stdout);
if($debug) {
print "Connected to $server\n";
}
#
# Server indicates it's name and version
#
$_=<SERVER>;
if($debug) {
print "Server: $_";
}
/^220 $PROGRAM $VERSION\n$/ ||
die "$0: Unexpected server response: $_";
#
# Send the file.
#
while(read($fd,$buf,$MTU)) {
if($debug) {
print "Read in " . length($buf) . " bytes.\n";
}
print SERVER $buf ||
die "Can't send data to server: $!";
if($debug) {
print "Sent...\n";
}
}
#
# All done
#
close(SERVER);
close($fd);
print "Transfer completed.\n";
exit 0;
}
#
# Server piece
#
sub pipe_server {
local($server_port,$outfile) = @_;
#
# Open the file. In binary, if you please...
#
if($outfile) {
open(OUTFILE,">$outfile") || die "$0: Can't open file $infile:
$!";
$fd = OUTFILE;
}
else {
$fd = STDOUT;
}
binmode $fd;
#
# Do some work to prepare the socket data structures
#
($pname, $paliases, $proto) = getprotobyname('tcp');
socket(SERVER,$PF_INET,$SOCK_STREAM,$proto) ||
die "Can't create socket: $!";
setsockopt(SERVER,SOL_SOCKET,SO_REUSEADDR,pack("l",1)) ||
die "Can't setsockopt: $!";
bind(SERVER,sockaddr_in($server_port,INADDR_ANY)) ||
die "Can't bind: $!";
listen(SERVER,SOMAXCONN) ||
die "Can't listen: $!";
if($debug) {
print "Server started on port $server_port\n";
}
#
# Wait for a connection.
#
accept(CLIENT,SERVER);
select(CLIENT); $| =1; select(STDOUT);
#
# Send our banner
#
if ($debug) {
print "Received connection request...\n";
}
print CLIENT "220 $PROGRAM $VERSION\n";
#
# Send the file.
#
while(read(CLIENT,$buf,$MTU)) {
if($debug) {
print "Read in " . length($buf) . " bytes.\n";
}
print $fd $buf ||
die "Can't write data: $!";
}
#
# All done
#
close(CLIENT);
close(SERVER);
close($fd);
if($debug) {
print "Transfer completed.\n";
}
exit 0;
}
sub usage {
printf STDERR "Usage $0: -c server [-i infile] | -s [-o outfile] [-p
[port]]\n";
exit(2);
}
##################################################################################
#!/usr/bin/python
#
# Client program in python corresponding to tcppipe.pl
#
# WARNING: If running this program under Cygwin under
# Windows, set your file output style to binary (rather
# than ASCII) or it adds carriage returns before every
# newline (or just use the perl version, instead)
# This simplistic code takes ONE MANDATORY argument - the
# host address
import socket
import sys
PORT = 4097
PROGRAM = 'tcppipe'
VERSION = 'V1.0'
MTU = 16384
HOST = sys.argv[1]
debug = 0
if debug:
sys.stderr.write('Server: ' + HOST)
#
# Prepare the socket
#
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
buf = s.recv(1024)
if debug:
sys.stderr.write('Connected: ' + buf)
#
# Send the data
#
while 1:
buf = sys.stdin.read(MTU)
if not buf: break
s.send(buf)
if debug:
sys.stderr.write('Sent ' + str(len(buf)) + ' bytes' + '\n')
#
# Close down
#
s.close()
if debug:
sys.stderr.write('Done...\n')
##################################################################################
#
# Server program in Python corresponding to tcppipe.pl
#
#
# WARNING: If running this program under Cygwin under
# Windows, set your file output style to binary (rather
# than ASCII) or it adds carriage returns before every
# newline (or just use the perl version, instead)
#
import socket
import sys
PORT = 4097 # port to listen on
PROGRAM = 'tcppipe'
VERSION = 'V1.0' # Version
MTU = 16384 # max block to receive
debug = 1 # Print debugging messages
#
# Prepare the socket
#
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('',PORT))
if debug:
sys.stderr.write('Server started on port' + str(PORT) + '\n')
#
# Wait for a connection
#
s.listen(1)
connection, client_address = s.accept()
if debug:
sys.stderr.write('Received connection request from ' +
str(client_address) + '\n')
#
# Send out the banner to the client
#
connection.send('220 ' + PROGRAM + ' ' + VERSION + '\n')
#
# Receive the data
#
while 1:
buf = connection.recv(MTU)
if not buf: break
if debug:
sys.stderr.write('Read in ' + str(len(buf)) + ' bytes' +
'\n')
sys.stdout.write(buf)
#
# Close down
#
connection.close()
if debug:
sys.stderr.write('Done...\n')