blob: f15fd87719ab3ea6d86f7ef5d4fb01f2bbd5221d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#!/bin/sh
#
# Receive a data stream describing a sparse file, and reproduce it,
# either to a named file or stdout.
#
# The data stream is simple: it's a sequence of DATA or HOLE records:
#
# DATA
# 123
# <123 bytes of binary data, NOT including newline at the end>
#
# HOLE
# 123
#
# This shell script can be executed over ssh (given to ssh as an arguemnt,
# with suitable escaping) on a different computer. This allows a large
# sparse file (e.g., disk image) be transferred quickly.
set -eu
die()
{
echo "$@" 1>&2
exit 1
}
recv_hole_to_file()
{
local n
read n
truncate --size "+$n" "$1"
}
recv_data_to_file()
{
local n
read n
local blocksize=1048576
local blocks="$(echo "$n" / "$blocksize" | bc)"
local extra="$(echo "$n" % "$blocksize" | bc)"
xfer_data_to_stdout "$blocksize" "$blocks" >> "$1"
xfer_data_to_stdout 1 "$extra" >> "$1"
}
recv_hole_to_stdout()
{
local n
read n
(echo "$n"; cat /dev/zero) | recv_data_to_stdout
}
recv_data_to_stdout()
{
local n
read n
local blocksize=1048576
local blocks="$(echo "$n" / "$blocksize" | bc)"
local extra="$(echo "$n" % "$blocksize" | bc)"
xfer_data_to_stdout "$blocksize" "$blocks"
xfer_data_to_stdout 1 "$extra"
}
xfer_data_to_stdout()
{
local log="$(mktemp)"
if ! dd "bs=$1" count="$2" iflag=fullblock status=noxfer 2> "$log"
then
cat "$log" 1>&2
rm -f "$log"
exit 1
else
rm -f "$log"
fi
}
type="$1"
case "$type" in
file)
output="$2"
truncate --size=0 "$output"
while read what
do
case "$what" in
DATA) recv_data_to_file "$output" ;;
HOLE) recv_hole_to_file "$output" ;;
*) die "Unknown instruction: $what" ;;
esac
done
;;
vbox)
output="$2"
disk_size="$3"
while read what
do
case "$what" in
DATA) recv_data_to_stdout ;;
HOLE) recv_hole_to_stdout ;;
*) die "Unknown instruction: $what" ;;
esac
done |
VBoxManage convertfromraw stdin "$output" "$disk_size"
;;
esac
|