Cloning A Hard Disk Over The Network Using Ultrix

Jay Jaeger cube1 at charter.net
Mon Oct 23 14:34:56 CDT 2017


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')
	






More information about the cctech mailing list