3 # supported_filesystems()
4 # Returns a list of filesystem types on which dumping is supported
5 sub supported_filesystems
8 push(@rv, "ufs") if (&has_command("dump"));
12 # multiple_directory_support(fs)
13 # Returns 1 if some filesystem dump supports multiple directories
14 sub multiple_directory_support
20 $tar_command = &has_command("gtar") || &has_command("tar");
25 # Display common options
26 print &ui_table_row(&hlink($text{'dump_dest'}, "dest"),
27 &ui_radio("mode", $_[0]->{'host'} ? 1 : 0,
28 [ [ 0, $text{'dump_file'}." ".
29 &ui_textbox("file", $_[0]->{'file'}, 50).
30 " ".&file_chooser_button("file")."<br>" ],
31 [ 1, &text('dump_host',
32 &ui_textbox("host", $_[0]->{'host'}, 15),
33 &ui_textbox("huser", $_[0]->{'huser'}, 8),
34 &ui_textbox("hfile", $_[0]->{'hfile'}, 20)) ] ]), 3);
36 if ($_[0]->{'fs'} eq 'tar') {
37 # Display gnutar options
38 print &ui_table_row(&hlink($text{'dump_rsh'},"rsh"),
39 &rsh_command_input("rsh_def", "rsh", $_[0]->{'rsh'}), 3);
41 # Password option for SSH
42 print &ui_table_row(&hlink($text{'dump_pass'},"pass"),
43 &ui_password("pass", $_[0]->{'pass'}, 20), 3);
49 local ($dump, $tds) = @_;
50 if ($_[0]->{'fs'} eq 'tar') {
51 # Display gnutar options
52 print &ui_table_row(&hlink($text{'dump_label'},"label"),
53 &ui_textbox("label", $_[0]->{'label'}, 15),
56 print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
57 &ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
58 $text{'dump_auto'})." kB",
61 print &ui_table_row(&hlink($text{'dump_gzip'},"gzip"),
62 &ui_select("gzip", int($_[0]->{'gzip'}),
64 [ 1, $text{'dump_gzip1'} ] ]), 1, $tds);
66 print &ui_table_row(&hlink($text{'dump_multi'},"multi"),
67 &ui_yesno_radio("multi", int($_[0]->{'multi'})),
70 print &ui_table_row(&hlink($text{'dump_links'},"links"),
71 &ui_yesno_radio("links", int($_[0]->{'links'})),
74 print &ui_table_row(&hlink($text{'dump_xdev'},"xdev"),
75 &ui_yesno_radio("xdev", int($_[0]->{'xdev'})),
79 # Display ufs backup options
80 print &ui_table_row(&hlink($text{'dump_update'},"update"),
81 &ui_yesno_radio("update", int($_[0]->{'update'})),
84 print &ui_table_row(&hlink($text{'dump_level'},"level"),
85 &ui_select("level", int($_[0]->{'level'}),
86 [ map { [ $_, $text{'dump_level_'.$_} ] }
87 (0 .. 9) ]), 1, $tds);
89 print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
90 &ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
91 $text{'dump_auto'})." kB",
94 print &ui_table_row(&hlink($text{'dump_honour'},"honour"),
95 &ui_yesno_radio("honour", int($_[0]->{'honour'})),
103 # Parse common options
104 if ($in{'mode'} == 0) {
105 $in{'file'} =~ /\S/ || &error($text{'dump_efile'});
106 $_[0]->{'file'} = $in{'file'};
107 delete($_[0]->{'host'});
108 delete($_[0]->{'huser'});
109 delete($_[0]->{'hfile'});
112 &to_ipaddress($in{'host'}) ||
113 &to_ip6address($in{'host'}) ||
114 &error($text{'dump_ehost'});
115 $_[0]->{'host'} = $in{'host'};
116 $in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'});
117 $in{'huser'} =~ /\@/ && &error($text{'dump_ehuser2'});
118 $_[0]->{'huser'} = $in{'huser'};
119 $in{'hfile'} || &error($text{'dump_ehfile'});
120 $_[0]->{'hfile'} = $in{'hfile'};
121 delete($_[0]->{'file'});
124 if ($_[0]->{'fs'} eq 'tar') {
126 $_[0]->{'rsh'} = &rsh_command_parse("rsh_def", "rsh");
127 $_[0]->{'pass'} = $in{'pass'};
128 $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 ||
129 &error($text{'dump_elabel'});
130 $_[0]->{'label'} = $in{'label'};
131 if ($in{'blocks_def'}) {
132 delete($_[0]->{'blocks'});
135 $in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
136 $_[0]->{'blocks'} = $in{'blocks'};
137 $in{'gzip'} && &error($text{'dump_egzip'});
139 $_[0]->{'gzip'} = $in{'gzip'};
140 $_[0]->{'multi'} = $in{'multi'};
141 $_[0]->{'links'} = $in{'links'};
142 $_[0]->{'xdev'} = $in{'xdev'};
144 !-c $in{'file'} && !-b $in{'file'} ||
145 &error($text{'dump_emulti'});
146 $in{'gzip'} && &error($text{'dump_egzip2'});
152 foreach $m (&foreign_call("mount", "list_mounted")) {
153 $mp++ if ($m->[0] eq $in{'dir'});
155 $mp || &error($text{'dump_emp'});
157 $_[0]->{'update'} = $in{'update'};
158 $_[0]->{'level'} = $in{'level'};
159 $_[0]->{'honour'} = $in{'honour'};
160 if ($in{'blocks_def'}) {
161 delete($_[0]->{'blocks'});
164 $in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
165 $_[0]->{'blocks'} = $in{'blocks'};
170 # execute_dump(&dump, filehandle, escape, background-mode, [time])
171 # Executes a dump and displays the output
175 local ($cmd, $flags);
177 if ($_[0]->{'huser'}) {
178 $flags = "-f '$_[0]->{'huser'}\@$_[0]->{'host'}:".
179 &date_subs($_[0]->{'hfile'}, $_[4])."'";
181 elsif ($_[0]->{'host'}) {
182 $flags = "-f '$_[0]->{'host'}:".&date_subs($_[0]->{'hfile'}, $_[4])."'";
185 $flags = "-f '".&date_subs($_[0]->{'file'}, $_[4])."'";
187 local $tapecmd = $_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar' ? $multi_cmd :
188 $_[0]->{'multi'} ? undef :
189 $_[3] && !$config{'nonewtape'} ? $newtape_cmd : $notape_cmd;
190 if ($_[0]->{'fs'} eq 'tar') {
191 # Construct tar command
192 $cmd = "$tar_command -c $flags";
193 $cmd .= " -V '$_[0]->{'label'}'" if ($_[0]->{'label'});
194 $cmd .= " -L $_[0]->{'blocks'}" if ($_[0]->{'blocks'});
195 $cmd .= " -z" if ($_[0]->{'gzip'});
196 $cmd .= " -M" if ($_[0]->{'multi'});
197 $cmd .= " -h" if ($_[0]->{'links'});
198 $cmd .= " -l" if ($_[0]->{'xdev'});
199 $cmd .= " -F \"$tapecmd $_[0]->{'id'}\""
200 if (!$_[0]->{'gzip'});
201 $cmd .= " --rsh-command=$_[0]->{'rsh'}"
202 if ($_[0]->{'rsh'} && $_[0]->{'host'});
203 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
204 $cmd .= " '$_[0]->{'dir'}'";
207 # Construct ufs dump command
208 $cmd = "dump -$_[0]->{'level'} $flags";
209 $cmd .= " -u" if ($_[0]->{'update'});
210 if ($_[0]->{'blocks'}) {
211 $cmd .= " -B $_[0]->{'blocks'}";
216 $cmd .= " -h 0" if ($_[0]->{'honour'});
217 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
218 $cmd .= " '$_[0]->{'dir'}'";
221 &system_logged("sync");
223 $ENV{'DUMP_PASSWORD'} = $_[0]->{'pass'};
224 local $got = &run_ssh_command($cmd, $fh, $_[2], $_[0]->{'pass'});
225 if ($_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar') {
226 # Run multi-file switch command one last time
227 &execute_command("$multi_cmd $_[0]->{'id'} >/dev/null 2>&1");
235 if ($_[0]->{'file'}) {
236 return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
238 elsif ($_[0]->{'huser'}) {
239 return "<tt>".&html_escape("$_[0]->{'huser'}\@$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
242 return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
246 # missing_restore_command(filesystem)
247 sub missing_restore_command
249 return &has_command("restore") ? undef : $cmd;
252 # restore_form(filesystem, [&dump])
255 local ($fs, $dump, $tds) = @_;
258 print &ui_table_row(&hlink($text{'restore_src'}, "rsrc"),
259 &ui_radio("mode", $_[1]->{'host'} ? 1 : 0,
260 [ [ 0, $text{'dump_file'}." ".
261 &ui_textbox("file", $_[1]->{'file'}, 50).
262 " ".&file_chooser_button("file")."<br>" ],
263 [ 1, &text('dump_host',
264 &ui_textbox("host", $_[1]->{'host'}, 15),
265 &ui_textbox("huser", $_[1]->{'huser'}, 8),
266 &ui_textbox("hfile", $_[1]->{'hfile'}, 20)) ] ]), 3, $tds);
268 if ($_[0] eq 'tar') {
269 # tar restore options
270 print &ui_table_row(&hlink($text{'restore_rsh'},"rrsh"),
271 &rsh_command_input("rsh_def", "rsh", $_[1]->{'rsh'}),
274 # Password option for SSH
275 print &ui_table_row(&hlink($text{'dump_pass2'},"passs"),
276 &ui_password("pass", $_[1]->{'pass'}, 20),
280 print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
281 &ui_opt_textbox("files", undef, 40, $text{'restore_all'},
282 $text{'restore_sel'}), 3, $tds);
285 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
286 &ui_textbox("dir", undef, 50)." ".
287 &file_chooser_button("dir", 1), 3, $tds);
289 # Restore permissions?
290 print &ui_table_row(&hlink($text{'restore_perms'},"perms"),
291 &ui_yesno_radio("perms", 1), 1, $tds);
294 print &ui_table_row(&hlink($text{'restore_gzip'},"rgzip"),
295 &ui_select("gzip", $_[1]->{'gzip'},
296 [ [ 0, $text{'no'} ],
297 [ 1, $text{'dump_gzip1'} ] ]), 1, $tds);
299 print &ui_table_row(&hlink($text{'restore_keep'},"keep"),
300 &ui_yesno_radio("keep", 0), 1, $tds);
303 print &ui_table_row(&hlink($text{'restore_multi'},"rmulti"),
304 &ui_yesno_radio("multi", 0), 1, $tds);
307 print &ui_table_row(&hlink($text{'restore_test'},"rtest"),
308 &ui_yesno_radio("test", 1), 1, $tds);
311 # ufs restore options, files to restore
312 print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
313 &ui_opt_textbox("files", undef, 40, $text{'restore_all'},
314 $text{'restore_sel'}), 3, $tds);
317 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
318 &ui_textbox("dir", undef, 50)." ".
319 &file_chooser_button("dir", 1), 3, $tds);
322 print &ui_table_row(&hlink($text{'restore_nothing'},"rnothing"),
323 &ui_yesno_radio("nothing", 1), 1, $tds);
327 # parse_restore(filesystem)
328 # Parses inputs from restore_form() and returns a command to be passed to
333 if ($_[0] eq "tar") {
343 $cmd .= "restore".($in{'test'} ? " -t" : " -x");
345 if ($in{'mode'} == 0) {
346 $in{'file'} || &error($text{'restore_efile'});
347 $cmd .= " -f '$in{'file'}'";
350 &to_ipaddress($in{'host'}) ||
351 &to_ip6address($in{'host'}) ||
352 &error($text{'restore_ehost'});
353 $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
354 $in{'hfile'} || &error($text{'restore_ehfile'});
356 $cmd .= " -f '$in{'huser'}\@$in{'host'}:$in{'hfile'}'";
359 $cmd .= " -f '$in{'host'}:$in{'hfile'}'";
363 if ($_[0] eq 'tar') {
365 $cmd .= " -p" if ($in{'perms'});
366 $cmd .= " -z" if ($in{'gzip'});
367 $cmd .= " -k" if ($in{'keep'});
369 !-c $in{'file'} && !-b $in{'file'} ||
370 &error($text{'restore_emulti'});
371 $in{'mode'} == 0 || &error($text{'restore_emulti2'});
372 $cmd .= " -M -F \"$rmulti_cmd $in{'file'}\"";
374 local $rsh = &rsh_command_parse("rsh_def", "rsh");
376 $cmd .= " --rsh-command=".quotemeta($rsh);
378 $cmd .= " $in{'extra'}" if ($in{'extra'});
379 if (!$in{'files_def'}) {
380 $in{'files'} || &error($text{'restore_efiles'});
381 $cmd .= " $in{'files'}";
383 -d $in{'dir'} || &error($text{'restore_edir'});
384 $cmd = "cd '$in{'dir'}' && $cmd";
386 $cmd = "$rmulti_cmd $in{'file'} 1 && $cmd";
391 $cmd .= " -N" if ($in{'nothing'});
392 $cmd .= " $in{'extra'}" if ($in{'extra'});
393 if (!$in{'files_def'}) {
394 $in{'files'} || &error($text{'restore_efiles'});
395 $cmd .= " $in{'files'}";
397 -d $in{'dir'} || &error($text{'restore_edir'});
403 # restore_backup(filesystem, command)
404 # Restores a backup based on inputs from restore_form(), and displays the results
407 &additional_log('exec', undef, $_[1]);
408 $ENV{'DUMP_PASSWORD'} = $in{'pass'};
410 # Need to supply prompts
411 &foreign_require("proc", "proc-lib.pl");
412 local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]");
415 local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "password:", "yes\\/no", "(.*\\n)");
417 print &html_escape($matches[1]);
420 return $text{'restore_evolume'};
423 syswrite($fh, "1\n", 2);
427 syswrite($fh, "n\n", 2);
430 return &text('restore_equestion',
431 "<tt>$matches[2]</tt>");
434 syswrite($fh, "$in{'pass'}\n");
437 syswrite($fh, "yes\n");