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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#!/usr/bin/ruby
# encoding: UTF-8
#
# Program to receive backups and run rsync in receive mode. Must check that
# user as authorised by SSH is allowed to access particular directory.
$LOAD_PATH << '/usr/lib/byteback'
require 'trollop'
require 'byteback'
require 'byteback/restore'
include Byteback::Log
if ENV['SSH_ORIGINAL_COMMAND']
ARGV.concat(ENV['SSH_ORIGINAL_COMMAND'].split(' '))
end
byteback_host = ENV['BYTEBACK_HOST']
fatal('BYTEBACK_HOST environment not set') unless byteback_host
byteback_root = ENV['HOME'] + '/' + ENV['BYTEBACK_HOST']
fatal("#{byteback_root} does not exist") unless File.directory?(byteback_root)
#
# Calling byteback-restore really needs rsync to restore the files.
#
if (ARGV[0] == 'byteback-restore')
#
# Ignore the first arg
#
ARGV.shift
args = ["rsync"]
snapshot = nil
verbose = false
all = false
#
# Mangle the arguments, and pull out any that are not-rsync compatible.
#
while(arg = ARGV.shift)
case arg
when "."
break
when /^-([^-]*v[^-]*|-verbose)$/
verbose = true
args << arg
when "--snapshot"
snapshot = ARGV.shift
when "--all"
all = true
else
args << arg
end
end
# Always exclude the current directory, because it can change the
# ownership at the restorers end.
args << "--exclude=."
#
# Search for certain files
# DANGER the args might be too long if lots of files are returned.
#
paths = Byteback::Restore.decode_args(ARGV)
restore = Byteback::Restore.new(byteback_root)
restore.snapshot = snapshot if snapshot
restore.find(paths, :all => all)
Dir.chdir(byteback_host)
restore.results.each do |r|
args << File.join(".", r.snapshot, r.path)
end
if restore.results.empty?
STDERR.puts "** Sorry. There were no files matching:"
STDERR.puts "--> "+paths.join("\n--> ")
exit 1
end
STDERR.puts "Restoring:"
STDERR.puts restore.list
STDERR.puts(args.join(" ")) if verbose
exec(*args)
elsif ARGV[0] == 'rsync'
ARGV[-1] = "#{byteback_root}/current"
exec(*ARGV)
elsif ARGV[0] == 'byteback-snapshot'
ARGV.concat(['--root', "#{byteback_root}"])
exec(*ARGV)
elsif ARGV[0] == "restore"
puts "** Your byteback package needs to be updated. Please update and try again."
exit(1)
end
opts = Trollop.options do
opt :ping, 'Check connection parameters and exit'
opt :complete, 'Mark current backup as complete'
opt :list, 'Show backed up files matching the given pattern'
opt :all, 'Show all stored versions of a file'
opt :snapshot, 'Show backed up files in a certain snapshot.', :default => '*'
opt :verbose, 'Print diagnostics'
end
#
# Make sure we don't get crazy option combinations.
#
n_modes = opts.keys.inject(0) do |s,m|
s += 1 if [:ping, :complete, :list].include?(m)
end
error('Please only choose one mode') unless n_modes == 1
if opts[:complete]
system('byteback-snapshot', '--root', byteback_root)
elsif opts[:list]
args = Byteback::Restore.decode_args(ARGV[1..-1])
restore = Byteback::Restore.new(byteback_root)
restore.snapshot = opts[:snapshot]
restore.find(args, :all => opts[:all], :verbose => opts[:verbose])
if restore.results.empty?
puts "** Sorry. There were no files matching:"
puts "--> "+args.join("\n--> ")
else
puts restore.list
end
exit(0)
elsif opts[:ping]
exit 0
else
STDERR.print "byteback-receive failed\n"
exit 9
end
|