#!/usr/bin/perl # (c)2003 Marc Alexander Lehmann # # This file is released under the General Public License, version 2 or later. require v5.8; use strict 'subs'; use Socket; use IO::Socket::INET; $VERSION = 0.1; ############################################################################# $DEV = "/dev/nd0"; umask 077; for (0..7) { -e "/dev/nd$_" || qx; } print < "127.0.0.1", Listen => 1 or die "unable to create listen socket: $!"; my $cli = new IO::Socket::INET PeerHost => $srv->sockhost, PeerPort => $srv->sockport or die "unable to connect to listen socket: $!"; $srv = $srv->accept or die "accept: $!"; # TODO: should exchange secure token, but I don't care for races now ioctl ND, NBD_SET_SOCK, 0 + fileno $cli or die "NBD_SET_SOCK: $!"; sub REQ_MAGIC () { 0x25609513 } sub REQ($) { unpack "N N a8 NN N", $_[0] } sub REQ_SIZE (){ 4+4+4 + 8 + 8 } sub REP_MAGIC () { 0x67446698 } sub REP($$$;$) { pack "N N a8 a*", @_ } if (!($srv_pid = fork)) { ioctl ND, NBD_DO_IT, my $x or die "unable do _do_ _it_: $!"; exit; } $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { exit }; sub END { if ($srv_pid) { print "killing server...\n"; kill 9, $srv_pid; } print "bye.\n"; } #if (fork == 0) { # system "isoinfo", "-l", "-i", $DEV; # _exit(1); #} print <> 11); if ($type == 0) { printf "READ %08x \@%08x (block $from_h+$from_l)\n", $len, $from; syswrite $srv, REP REP_MAGIC, 0, $handle; while ($len) { sysseek BIN, ($from_h * 2352) + $from_l + 0x18, 0 or die; $from_l = 2048 - $from_l; $from_l < $len or $from_l = $len; sysread BIN, my $buf, $from_l; $from_l == length $buf or $buf = "\x0" x $from_l; syswrite $srv, $buf; $len -= $from_l; $from_l = 0; $from_h++; } } elsif ($type == 1) { die "write not supported\n"; } elsif ($type == 2) { print "disconnect requested, exiting...\n"; last; } else { die "unsupported operation ($type)\n"; } }