3 local $out = &backquote_command("dump -v 2>&1", 1);
4 if ($out =~ /dump\s+([0-9\.]+)b(\d+)/) {
5 $dump_version = "$1$2";
8 $out = &backquote_command("dump --version 2>&1", 1);
9 if ($out =~ /dump\s+([0-9\.]+)b(\d+)/) {
10 $dump_version = "$1$2";
16 # supported_filesystems()
17 # Returns a list of filesystem types on which dumping is supported
18 sub supported_filesystems
21 push(@rv, "ext2", "ext3", "ext4") if (&has_command("dump"));
22 push(@rv, "xfs") if (&has_command("xfsdump"));
26 # multiple_directory_support(fs)
27 # Returns 1 if some filesystem dump supports multiple directories
28 sub multiple_directory_support
30 return $_[0] eq "tar";
36 # Display destination options
37 print &ui_table_row(&hlink($text{'dump_dest'}, "dest"),
38 &ui_radio("mode", $_[0]->{'host'} ? 1 : 0,
39 [ [ 0, $text{'dump_file'}." ".
40 &ui_textbox("file", $_[0]->{'file'}, 50).
41 " ".&file_chooser_button("file")."<br>" ],
42 [ 1, &text('dump_host',
43 &ui_textbox("host", $_[0]->{'host'}, 15),
44 &ui_textbox("huser", $_[0]->{'huser'}, 8),
45 &ui_textbox("hfile", $_[0]->{'hfile'}, 20)) ] ]), 3);
47 if ($_[0]->{'fs'} ne 'xfs') {
48 # Display remote target options
49 print &ui_table_row(&hlink($text{'dump_rsh'},"rsh"),
50 &rsh_command_input("rsh_def", "rsh", $_[0]->{'rsh'}), 3);
52 # Password option for SSH
53 print &ui_table_row(&hlink($text{'dump_pass2'},"pass2"),
54 &ui_password("pass", $_[0]->{'pass'}, 20), 3);
60 local ($dump, $tds) = @_;
61 if ($_[0]->{'fs'} eq 'tar') {
62 # Display gnutar options
63 print &ui_table_row(&hlink($text{'dump_label'},"label"),
64 &ui_textbox("label", $_[0]->{'label'}, 15),
67 print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
68 &ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
69 $text{'dump_auto'})." kB",
72 print &ui_table_row(&hlink($text{'dump_exclude'}, "exclude"),
73 &ui_textbox("exclude", $_[0]->{'exclude'}, 50),
76 print &ui_table_row(&hlink($text{'dump_gzip'},"gzip"),
77 &ui_select("gzip", int($_[0]->{'gzip'}),
79 [ 1, $text{'dump_gzip1'} ],
80 [ 2, $text{'dump_gzip2'} ] ]), 1, $tds);
82 print &ui_table_row(&hlink($text{'dump_multi'},"multi"),
83 &ui_yesno_radio("multi", int($_[0]->{'multi'})),
86 print &ui_table_row(&hlink($text{'dump_links'},"links"),
87 &ui_yesno_radio("links", int($_[0]->{'links'})),
90 print &ui_table_row(&hlink($text{'dump_xdev'},"xdev"),
91 &ui_yesno_radio("xdev", int($_[0]->{'xdev'})),
94 print &ui_table_row(&hlink($text{'dump_notape'},"notape"),
95 &ui_radio("notape", int($_[0]->{'notape'}),
96 [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]),
99 print &ui_table_row(&hlink($text{'dump_update2'},"tarupdate"),
100 &ui_yesno_radio("update", int($_[0]->{'update'})),
103 print &ui_table_row(&hlink($text{'dump_ignoreread'},"ignoreread"),
104 &ui_yesno_radio("ignoreread",
105 int($_[0]->{'ignoreread'})),
108 elsif ($_[0]->{'fs'} eq 'xfs') {
109 # Display xfs dump options
110 print &ui_table_row(&hlink($text{'dump_level'},"level"),
111 &ui_select("level", int($_[0]->{'level'}),
112 [ map { [ $_, $text{'dump_level_'.$_} ] }
113 (0 .. 9) ]), 1, $tds);
115 print &ui_table_row(&hlink($text{'dump_label'},"label"),
116 &ui_textbox("label", $_[0]->{'label'}, 15),
119 print &ui_table_row(&hlink($text{'dump_max'},"max"),
120 &ui_opt_textbox("max", $_[0]->{'max'}, 8,
121 $text{'dump_unlimited'})." kB", 1, $tds);
123 print &ui_table_row(&hlink($text{'dump_attribs'},"attribs"),
124 &ui_yesno_radio("attribs", int($_[0]->{'attribs'})),
127 print &ui_table_row(&hlink($text{'dump_over'},"over"),
128 &ui_yesno_radio("over", int($_[0]->{'over'})),
131 print &ui_table_row(&hlink($text{'dump_invent'},"invent"),
132 &ui_radio("noinvent", int($_[0]->{'noinvent'}),
133 [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]),
136 print &ui_table_row(&hlink($text{'dump_overwrite'},"overwrite"),
137 &ui_yesno_radio("overwrite", int($_[0]->{'overwrite'})),
140 print &ui_table_row(&hlink($text{'dump_erase'},"erase"),
141 &ui_yesno_radio("erase", int($_[0]->{'erase'})),
144 print &ui_table_row(&hlink($text{'dump_bsize'},"bsize"),
145 &ui_opt_textbox("bsize", $_[0]->{'bsize'}, 8,
146 $text{'default'})." kB", 1, $tds);
149 # Display ext2/3 filesystem dump options
150 print &ui_table_row(&hlink($text{'dump_update'},"update"),
151 &ui_yesno_radio("update", int($_[0]->{'update'})),
154 print &ui_table_row(&hlink($text{'dump_multi'},"multi"),
155 &ui_yesno_radio("multi", int($_[0]->{'multi'})),
158 print &ui_table_row(&hlink($text{'dump_level'},"level"),
159 &ui_select("level", int($_[0]->{'level'}),
160 [ map { [ $_, $text{'dump_level_'.$_} ] }
161 (0 .. 9) ]), 1, $tds);
163 print &ui_table_row(&hlink($text{'dump_label'},"label"),
164 &ui_textbox("label", $_[0]->{'label'}, 15),
167 print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
168 &ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
169 $text{'dump_auto'})." kB",
172 print &ui_table_row(&hlink($text{'dump_bsize'},"bsize"),
173 &ui_opt_textbox("bsize", $_[0]->{'bsize'}, 8,
174 $text{'default'})." kB", 1, $tds);
176 print &ui_table_row(&hlink($text{'dump_honour'},"honour"),
177 &ui_yesno_radio("honour", int($_[0]->{'honour'})),
180 if ($dump_version >= 0.424) {
181 print &ui_table_row(&hlink($text{'dump_comp'},"comp"),
182 &ui_opt_textbox("comp", $_[0]->{'comp'}, 4,
183 $text{'no'}, $text{'dump_complvl'}),
189 print &ui_table_row(&hlink($text{'dump_remount'},"remount"),
190 &ui_yesno_radio("remount", int($_[0]->{'remount'})), 1, $tds);
192 if ($_[0]->{'fs'} eq 'tar') {
194 print &ui_table_row(&hlink($text{'dump_rmt'},"rmt"),
195 &ui_opt_textbox("rmt", $_[0]->{'rmt'}, 30, $text{'default'}),
203 # Parse destination options
204 if ($in{'mode'} == 0) {
205 $in{'file'} =~ /\S/ || &error($text{'dump_efile'});
206 $_[0]->{'file'} = $in{'file'};
207 delete($_[0]->{'host'});
208 delete($_[0]->{'huser'});
209 delete($_[0]->{'hfile'});
212 &to_ipaddress($in{'host'}) ||
213 &to_ip6address($in{'host'}) ||
214 &error($text{'dump_ehost'});
215 $_[0]->{'host'} = $in{'host'};
216 $in{'huser'} =~ /^\S*$/ || &error($text{'dump_ehuser'});
217 $in{'huser'} =~ /\@/ && &error($text{'dump_ehuser2'});
218 $_[0]->{'huser'} = $in{'huser'};
219 $in{'hfile'} || &error($text{'dump_ehfile'});
220 $_[0]->{'hfile'} = $in{'hfile'};
221 delete($_[0]->{'file'});
224 if ($_[0]->{'fs'} eq 'tar') {
226 $_[0]->{'rsh'} = &rsh_command_parse("rsh_def", "rsh");
227 $_[0]->{'pass'} = $in{'pass'};
228 $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 ||
229 &error($text{'dump_elabel'});
230 $_[0]->{'label'} = $in{'label'};
231 if ($in{'blocks_def'}) {
232 delete($_[0]->{'blocks'});
235 $in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
236 $_[0]->{'blocks'} = $in{'blocks'};
237 $in{'gzip'} && &error($text{'dump_egzip'});
239 $_[0]->{'exclude'} = $in{'exclude'};
240 $_[0]->{'gzip'} = $in{'gzip'};
241 $_[0]->{'multi'} = $in{'multi'};
242 $_[0]->{'links'} = $in{'links'};
243 $_[0]->{'xdev'} = $in{'xdev'};
244 if ($in{'update'} && $in{'rsh_def'} == 3) {
245 # Cannot append via FTP
246 &error($text{'dump_eftpupdate'});
248 $_[0]->{'update'} = $in{'update'};
249 $_[0]->{'ignoreread'} = $in{'ignoreread'};
250 if ($in{'gzip'} && $in{'update'}) {
251 &error($text{'dump_egzip3'});
254 !-c $in{'file'} && !-b $in{'file'} ||
255 &error($text{'dump_emulti'});
256 $in{'gzip'} && &error($text{'dump_egzip2'});
257 $in{'mode'} == 0 || &error($text{'dump_emulti2'});
259 $_[0]->{'notape'} = $in{'notape'};
260 if ($in{'rmt_def'}) {
261 delete($_[0]->{'rmt'});
264 $in{'rmt'} =~ /^\S+$/ || &error($text{'dump_ermt'});
265 $_[0]->{'rmt'} = $in{'rmt'};
268 elsif ($_[0]->{'fs'} eq 'xfs') {
270 &is_mount_point($in{'dir'}) || &error($text{'dump_emp'});
271 $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 256 ||
272 &error($text{'dump_elabel2'});
273 $_[0]->{'label'} = $in{'label'};
274 $_[0]->{'level'} = $in{'level'};
275 if ($in{'max_def'}) {
276 delete($_[0]->{'max'});
279 $in{'max'} =~ /^\d+$/ || &error($text{'dump_emax'});
280 $_[0]->{'max'} = $in{'max'};
282 $_[0]->{'noattribs'} = $in{'noattribs'};
283 $_[0]->{'over'} = $in{'over'};
284 $_[0]->{'noinvent'} = $in{'noinvent'};
285 $_[0]->{'overwrite'} = $in{'overwrite'};
286 $_[0]->{'erase'} = $in{'erase'};
287 if ($in{'bsize_def'}) {
288 delete($_[0]->{'bsize'});
291 $in{'bsize'} =~ /^\d+$/ || &error($text{'dump_ebsize'});
292 $_[0]->{'bsize'} = $in{'bsize'};
296 # Parse ext2/3 dump options
297 $_[0]->{'rsh'} = &rsh_command_parse("rsh_def", "rsh");
298 $_[0]->{'pass'} = $in{'pass'};
300 &is_mount_point($in{'dir'}) || &error($text{'dump_eupdatedir'});
302 $_[0]->{'update'} = $in{'update'};
303 $_[0]->{'multi'} = $in{'multi'};
304 if ($in{'level'} > 0) {
305 &is_mount_point($in{'dir'}) || &error($text{'dump_eleveldir'});
307 $_[0]->{'level'} = $in{'level'};
308 $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 ||
309 &error($text{'dump_elabel'});
310 $_[0]->{'label'} = $in{'label'};
311 if ($in{'blocks_def'}) {
312 delete($_[0]->{'blocks'});
315 $in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
316 $_[0]->{'blocks'} = $in{'blocks'};
318 if ($in{'bsize_def'}) {
319 delete($_[0]->{'bsize'});
322 $in{'bsize'} =~ /^\d+$/ || &error($text{'dump_ebsize'});
323 $_[0]->{'bsize'} = $in{'bsize'};
325 $_[0]->{'honour'} = $in{'honour'};
326 if ($in{'comp_def'} || !defined($in{'comp'})) {
327 delete($_[0]->{'comp'});
330 $in{'comp'} =~ /^[1-9]\d*$/ || &error($text{'dump_ecomp'});
331 $_[0]->{'comp'} = $in{'comp'};
334 $_[0]->{'remount'} = $in{'remount'};
337 # execute_dump(&dump, filehandle, escape, background-mode, [time])
338 # Executes a dump and displays the output
343 local ($flag, $hfile) = &dump_flag($_[0], $_[4]);
344 local $tapecmd = $_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar' ? $multi_cmd :
345 $_[0]->{'notape'} ? undef :
346 $_[0]->{'multi'} ? undef :
347 $_[3] && !$config{'nonewtape'} ? $newtape_cmd : $notape_cmd;
348 local @dirs = $_[0]->{'tabs'} ? split(/\t+/, $_[0]->{'dir'})
349 : split(/\s+/, $_[0]->{'dir'});
350 if ($_[0]->{'fs'} eq 'tar') {
352 $cmd = "tar ".($_[0]->{'update'} ? "-u" : "-c")." ".$flag;
353 $cmd .= " -V '$_[0]->{'label'}'" if ($_[0]->{'label'});
354 $cmd .= " -L $_[0]->{'blocks'}" if ($_[0]->{'blocks'});
355 $cmd .= " -z" if ($_[0]->{'gzip'} == 1);
356 $cmd .= " --bzip" if ($_[0]->{'gzip'} == 2);
357 $cmd .= " -M" if ($_[0]->{'multi'});
358 $cmd .= " -h" if ($_[0]->{'links'});
359 $cmd .= " --one-file-system" if ($_[0]->{'xdev'});
360 $cmd .= " -F \"$tapecmd $_[0]->{'id'}\""
361 if (!$_[0]->{'gzip'} && $tapecmd);
362 $cmd .= " --rsh-command=".quotemeta($_[0]->{'rsh'})
363 if ($_[0]->{'rsh'} && $_[0]->{'host'});
364 $cmd .= " --rmt-command=".quotemeta($_[0]->{'rmt'})
366 $cmd .= " --ignore-failed-read" if ($_[0]->{'ignoreread'});
367 if ($_[0]->{'exclude'}) {
368 foreach my $e (&split_quoted_string($_[0]->{'exclude'})) {
369 $cmd .= " --exclude ".quotemeta($e);
372 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
373 $cmd .= " ".join(" ", map { "'$_'" } @dirs);
375 elsif ($_[0]->{'fs'} eq 'xfs') {
377 $cmd = "xfsdump -l $_[0]->{'level'}";
379 $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'});
380 $cmd .= " -M '$_[0]->{'label'}'" if ($_[0]->{'label'});
381 $cmd .= " -z '$_[0]->{'max'}'" if ($_[0]->{'max'});
382 $cmd .= " -A" if ($_[0]->{'noattribs'});
383 $cmd .= " -F" if ($_[0]->{'over'});
384 $cmd .= " -J" if ($_[0]->{'noinvent'});
385 $cmd .= " -o" if ($_[0]->{'overwrite'});
386 $cmd .= " -E -F" if ($_[0]->{'erase'});
387 $cmd .= " -b $_[0]->{'bsize'}" if ($_[0]->{'bsize'});
388 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
389 $cmd .= " ".join(" ", map { "'$_'" } @dirs);
393 $cmd = "dump -$_[0]->{'level'}";
395 $cmd .= " -u" if ($_[0]->{'update'});
396 $cmd .= " -M" if ($_[0]->{'multi'});
397 $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'});
398 $cmd .= " -B $_[0]->{'blocks'}" if ($_[0]->{'blocks'});
399 $cmd .= " -b $_[0]->{'bsize'}" if ($_[0]->{'bsize'});
400 $cmd .= " -h0" if ($_[0]->{'honour'});
401 $cmd .= " -j$_[0]->{'comp'}" if ($_[0]->{'comp'});
402 $cmd .= " -F \"$tapecmd $_[0]->{'id'}\"" if ($tapecmd);
403 $cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
404 $cmd .= " '$_[0]->{'dir'}'";
405 if ($_[0]->{'rsh'}) {
406 $cmd = "RSH=\"$_[0]->{'rsh'}\" RMT=\"touch '$hfile'; /etc/rmt\" $cmd";
409 $cmd = "RMT=\"touch '$hfile'; /etc/rmt\" $cmd";
413 &system_logged("sync");
416 # Remount with noatime, if needed
417 if ($_[0]->{'remount'}) {
418 local @fs = &directory_filesystem($dirs[0]);
419 &mount::parse_options($fs[2], $fs[3]);
420 $mount::options{'noatime'} = '';
421 $fs[3] = &mount::join_options($fs[2]);
422 local $err = &mount::remount_dir(@fs);
424 $err =~ s/<[^>]*>//g;
425 print $fh "Failed to re-mount with noatime option : $err\n";
430 # Run the command, which may call SSH to do a remote login
431 $ENV{'DUMP_PASSWORD'} = $_[0]->{'pass'};
432 local $got = &run_ssh_command($cmd, $fh, $_[2], $_[0]->{'pass'});
433 if ($_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar') {
434 # Run multi-file switch command one last time
435 &execute_command("$multi_cmd $_[0]->{'id'} >/dev/null 2>&1");
438 # Remount with atime option
439 if ($_[0]->{'remount'}) {
440 local @fs = &directory_filesystem($dirs[0]);
441 &mount::parse_options($fs[2], $fs[3]);
442 delete($mount::options{'noatime'});
443 $mount::options{'atime'} = '';
444 $fs[3] = &mount::join_options($fs[2]);
445 local $err = &mount::remount_dir(@fs);
451 # dump_flag(&dump, at-time)
452 # Given a dump, returns the -f flag and server-side file
455 local ($flag, $hfile);
456 if ($_[0]->{'huser'}) {
457 $hfile = &date_subs($_[0]->{'hfile'}, $_[1]);
458 $flag = " -f '$_[0]->{'huser'}\@$_[0]->{'host'}:$hfile'";
460 elsif ($_[0]->{'host'}) {
461 $hfile = &date_subs($_[0]->{'hfile'}, $_[1]);
462 $flag = " -f '$_[0]->{'host'}:$hfile'";
465 $flag = " -f '".&date_subs($_[0]->{'file'}, $_[1])."'";
467 return ($flag, $hfile);
470 # verify_dump(&dump, filehandle, escape, background-mode, [time])
471 # Verifies a dump, returning 1 if OK and 0 if not
474 # Build verify command
477 local ($flag, $hfile) = &dump_flag($_[0], $_[4]);
478 if ($_[0]->{'fs'} eq "tar") {
480 $vcmd .= " -z" if ($_[0]->{'gzip'} == 1);
481 $vcmd .= " --bzip" if ($_[0]->{'gzip'} == 2);
482 $vcmd .= " -M" if ($_[0]->{'multi'});
484 elsif ($_[0]->{'fs'} eq "xfs") {
485 $vcmd = "xfsrestore -t";
488 $vcmd = "restore -t";
489 $vcmd .= " -M" if ($_[0]->{'multi'});
492 if ($_[0]->{'fs'} eq "tar") {
493 $vcmd .= " --rsh-command=$_[0]->{'rsh'}"
494 if ($_[0]->{'rsh'} && $_[0]->{'host'});
496 elsif ($_[0]->{'fs'} ne "xfs") {
497 if ($_[0]->{'rsh'}) {
498 $vcmd = "RSH=\"$_[0]->{'rsh'}\" RMT=\"touch '$hfile'; /etc/rmt\" $vcmd";
501 $vcmd = "RMT=\"touch '$hfile'; /etc/rmt\" $vcmd";
506 $vcmd .= " >/dev/null";
507 local $vgot = &run_ssh_command($vcmd, $fh, $_[2], $_[0]->{'pass'});
508 return $vgot ? 0 : 1;
514 if ($_[0]->{'file'}) {
515 return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
518 return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
522 # missing_restore_command(filesystem)
523 sub missing_restore_command
525 local $cmd = $_[0] eq 'xfs' ? 'xfsrestore' : 'restore';
526 return &has_command($cmd) ? undef : $cmd;
529 # restore_form(filesystem, [&dump], &tds)
532 local ($fs, $dump, $tds) = @_;
535 print &ui_table_row(&hlink($text{'restore_src'}, "rsrc"),
536 &ui_radio("mode", $_[1]->{'host'} ? 1 : 0,
537 [ [ 0, $text{'dump_file'}." ".
538 &ui_textbox("file", $_[1]->{'file'}, 50).
539 " ".&file_chooser_button("file")."<br>" ],
540 [ 1, &text('dump_host',
541 &ui_textbox("host", $_[1]->{'host'}, 15),
542 &ui_textbox("huser", $_[1]->{'huser'}, 8),
543 &ui_textbox("hfile", $_[1]->{'hfile'}, 20)) ] ]), 3, $tds);
545 if ($_[0] eq 'tar') {
546 # tar restore options
547 print &ui_table_row(&hlink($text{'restore_rsh'},"rrsh"),
548 &rsh_command_input("rsh_def", "rsh", $_[1]->{'rsh'}),
551 # Password option for SSH
552 print &ui_table_row(&hlink($text{'dump_pass2'},"passs"),
553 &ui_password("pass", $_[1]->{'pass'}, 20),
557 print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
558 &ui_opt_textbox("files", undef, 40, $text{'restore_all'},
559 $text{'restore_sel'}), 3, $tds);
562 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
563 &ui_textbox("dir", undef, 50)." ".
564 &file_chooser_button("dir", 1), 3, $tds);
566 # Restore permissions?
567 print &ui_table_row(&hlink($text{'restore_perms'},"perms"),
568 &ui_yesno_radio("perms", 1), 1, $tds);
571 print &ui_table_row(&hlink($text{'restore_gzip'},"rgzip"),
572 &ui_select("gzip", $_[1]->{'gzip'},
573 [ [ 0, $text{'no'} ],
574 [ 1, $text{'dump_gzip1'} ],
575 [ 2, $text{'dump_gzip2'} ] ]), 1, $tds);
577 print &ui_table_row(&hlink($text{'restore_keep'},"keep"),
578 &ui_yesno_radio("keep", 0), 1, $tds);
581 print &ui_table_row(&hlink($text{'restore_multi'},"rmulti"),
582 &ui_yesno_radio("multi", 0), 1, $tds);
584 elsif ($_[0] eq 'xfs') {
585 # xfs restore options
588 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
589 &ui_textbox("dir", undef, 50)." ".
590 &file_chooser_button("dir", 1), 3, $tds);
593 print &ui_table_row(&hlink($text{'restore_over'},"rover"),
594 &ui_radio("over", 0, [ [ 0, $text{'restore_over0'} ],
595 [ 1, $text{'restore_over1'} ],
596 [ 2, $text{'restore_over2'} ] ]),
600 print &ui_table_row(&hlink($text{'restore_noattribs'},"rnoattribs"),
601 &ui_radio("noattribs", 0, [ [ 0, $text{'yes'} ],
602 [ 1, $text{'no'} ] ]), 1, $tds);
604 # Label to restore from
605 print &ui_table_row(&hlink($text{'restore_label'},"rlabel"),
606 &ui_textbox("label", undef, 20), 1, $tds);
609 # ext2/3 restore options
610 print &ui_table_row(&hlink($text{'restore_rsh'},"rrsh"),
611 &rsh_command_input("rsh_def", "rsh", $_[1]->{'rsh'}),
614 # Password option for SSH
615 print &ui_table_row(&hlink($text{'dump_pass2'},"passs"),
616 &ui_password("pass", $_[1]->{'pass'}, 20),
620 print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
621 &ui_opt_textbox("files", undef, 40, $text{'restore_all'},
622 $text{'restore_sel'}), 3, $tds);
625 print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
626 &ui_textbox("dir", undef, 50)." ".
627 &file_chooser_button("dir", 1), 3, $tds);
630 print &ui_table_row(&hlink($text{'restore_multi'},"rmulti"),
631 &ui_yesno_radio("multi", 0), 1, $tds);
635 print &ui_table_row(&hlink($text{'restore_test'},"rtest"),
636 &ui_yesno_radio("test", 1), 1, $tds);
639 # parse_restore(filesystem)
640 # Parses inputs from restore_form() and returns a command to be passed to
645 if ($_[0] eq 'tar') {
654 elsif ($_[0] eq 'xfs') {
656 $cmd .= " -t" if ($in{'test'});
660 $cmd .= ($in{'test'} ? " -t" : " -x");
662 if ($in{'mode'} == 0) {
663 $in{'file'} || &error($text{'restore_efile'});
664 $cmd .= " -f '$in{'file'}'";
667 &to_ipaddress($in{'host'}) ||
668 &to_ip6address($in{'host'}) ||
669 &error($text{'restore_ehost'});
670 $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
671 $in{'hfile'} || &error($text{'restore_ehfile'});
673 $cmd .= " -f '$in{'huser'}\@$in{'host'}:$in{'hfile'}'";
676 $cmd .= " -f '$in{'host'}:$in{'hfile'}'";
679 if ($_[0] eq 'tar') {
681 $cmd .= " -p" if ($in{'perms'});
682 $cmd .= " -z" if ($in{'gzip'} == 1);
683 $cmd .= " --bzip" if ($in{'gzip'} == 2);
684 $cmd .= " -k" if ($in{'keep'});
686 !-c $in{'file'} && !-b $in{'file'} ||
687 &error($text{'restore_emulti'});
688 $in{'mode'} == 0 || &error($text{'restore_emulti2'});
689 $cmd .= " -M -F \"$rmulti_cmd $in{'file'}\"";
691 local $rsh = &rsh_command_parse("rsh_def", "rsh");
693 $cmd .= " --rsh-command=".quotemeta($rsh);
695 $cmd .= " $in{'extra'}" if ($in{'extra'});
696 if (!$in{'files_def'}) {
697 $in{'files'} || &error($text{'restore_efiles'});
698 $cmd .= " $in{'files'}";
700 -d $in{'dir'} || &error($text{'restore_edir'});
701 $cmd = "cd '$in{'dir'}' && $cmd";
703 $cmd = "$rmulti_cmd $in{'file'} 1 && $cmd";
706 elsif ($_[0] eq 'xfs') {
708 $cmd .= " -E" if ($in{'over'} == 1);
709 $cmd .= " -e" if ($in{'over'} == 2);
710 $cmd .= " -A" if ($in{'noattribs'});
711 $cmd .= " -L '$in{'label'}'" if ($in{'label'});
713 $cmd .= " $in{'extra'}" if ($in{'extra'});
715 -d $in{'dir'} || &error($text{'restore_edir'});
716 $cmd .= " '$in{'dir'}'";
720 # parse ext2/3 options
721 local $rsh = &rsh_command_parse("rsh_def", "rsh");
723 $cmd = "RSH=\"$rsh\" $cmd";
728 if ($dump_version >= 0.428 && $in{'extra'} !~ /-a/) {
732 $cmd .= " -u"; # force overwrite
733 $cmd .= " $in{'extra'}" if ($in{'extra'});
734 if (!$in{'files_def'}) {
735 $in{'files'} || &error($text{'restore_efiles'});
736 $cmd .= " $in{'files'}";
738 -d $in{'dir'} || &error($text{'restore_edir'});
743 # restore_backup(filesystem, command)
744 # Restores a backup based on inputs from restore_form(), and displays the results
747 &additional_log('exec', undef, $_[1]);
748 $ENV{'DUMP_PASSWORD'} = $in{'pass'};
749 if ($_[0] eq 'xfs') {
750 # Just run the xfsrestore command
751 &open_execute_command(CMD, "$_[1] 2>&1 </dev/null", 1);
753 print &html_escape($_);
759 # Need to supply prompts
760 &foreign_require("proc", "proc-lib.pl");
761 local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]");
764 local $rv = &wait_for($fh, "(.*next volume #)", "(.*set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "(.*enter volume name)", "password:", "yes\\/no", "(.*\\n)");
766 print &html_escape($matches[1]);
769 return $text{'restore_evolume'};
772 syswrite($fh, "1\n", 2);
776 syswrite($fh, "n\n", 2);
779 syswrite($fh, "\n", 1);
782 return &text('restore_equestion',
783 "<tt>$matches[2]</tt>");
786 syswrite($fh, "$in{'pass'}\n");
789 syswrite($fh, "yes\n");