# linux-lib.pl # supported_filesystems() # Returns a list of filesystem types on which dumping is supported sub supported_filesystems { local @rv; push(@rv, "ext2", "ext3") if (&has_command("dump")); push(@rv, "xfs") if (&has_command("xfsdump")); return @rv; } # dump_form(&dump) sub dump_form { # Display common options print " ",&hlink($text{'dump_dest'}, "dest"), " \n"; printf " %s\n", $_[0]->{'host'} ? '' : 'checked', $text{'dump_file'}; printf " %s
\n", $_[0]->{'host'} ? '' : $_[0]->{'file'}, &file_chooser_button("file"); printf "\n", $_[0]->{'host'} ? 'checked' : ''; print &text('dump_host', "", "", ""), " \n"; if ($_[0]->{'fs'} eq 'xfs') { # Display xfs dump options print " ",&hlink($text{'dump_level'},"level"),"\n"; print "\n"; print "",&hlink($text{'dump_label'},"label"),"\n"; printf " \n", $_[0]->{'label'}; print " ",&hlink($text{'dump_max'},"max"),"\n"; printf " %s\n", $_[0]->{'max'} ? '' : 'checked', $text{'dump_unlimited'}; printf "\n", $_[0]->{'max'} ? 'checked' : ''; printf " kB\n", $_[0]->{'max'}; print "",&hlink($text{'dump_attribs'},"attribs"),"\n"; printf " %s\n", $_[0]->{'noattribs'} ? '' : 'checked', $text{'yes'}; printf " %s \n", $_[0]->{'noattribs'} ? 'checked' : '', $text{'no'}; print " ",&hlink($text{'dump_over'},"over"),"\n"; printf " %s\n", $_[0]->{'over'} ? '' : 'checked', $text{'yes'}; printf " %s\n", $_[0]->{'over'} ? 'checked' : '', $text{'no'}; print "",&hlink($text{'dump_invent'},"invent"),"\n"; printf " %s\n", $_[0]->{'noinvent'} ? '' : 'checked', $text{'yes'}; printf " %s \n", $_[0]->{'noinvent'} ? 'checked' : '', $text{'no'}; print " ",&hlink($text{'dump_overwrite'},"overwrite"), "\n"; printf " %s\n", $_[0]->{'overwrite'} ? 'checked' : '', $text{'yes'}; printf " %s\n", $_[0]->{'overwrite'} ? '' : 'checked', $text{'no'}; print "",&hlink($text{'dump_erase'},"erase"),"\n"; printf " %s\n", $_[0]->{'erase'} ? 'checked' : '', $text{'yes'}; printf " %s \n", $_[0]->{'erase'} ? '' : 'checked', $text{'no'}; } else { # Display ext2/3 filesystem dump options print " ",&hlink($text{'dump_update'},"update"), "\n"; printf " %s\n", $_[0]->{'update'} ? 'checked' : '', $text{'yes'}; printf " %s\n", $_[0]->{'update'} ? '' : 'checked', $text{'no'}; print "",&hlink($text{'dump_multi'},"multi"),"\n"; printf " %s\n", $_[0]->{'multi'} ? 'checked' : '', $text{'yes'}; printf " %s \n", $_[0]->{'multi'} ? '' : 'checked', $text{'no'}; print " ",&hlink($text{'dump_level'},"level"),"\n"; print "\n"; print "",&hlink($text{'dump_label'},"label"),"\n"; printf " \n", $_[0]->{'label'}; } } # parse_dump(&dump) sub parse_dump { # Parse common options if ($in{'mode'} == 0) { $in{'file'} =~ /\S/ || &error($text{'dump_efile'}); $_[0]->{'file'} = $in{'file'}; delete($_[0]->{'host'}); delete($_[0]->{'huser'}); delete($_[0]->{'hfile'}); } else { gethostbyname($in{'host'}) || &check_ipaddress($in{'host'}) || &error($text{'dump_ehost'}); $_[0]->{'host'} = $in{'host'}; $in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'}); $_[0]->{'huser'} = $in{'huser'}; $in{'hfile'} || &error($text{'dump_ehfile'}); $_[0]->{'hfile'} = $in{'hfile'}; delete($_[0]->{'file'}); } if ($_[0]->{'fs'} eq 'xfs') { # Parse xfs options local $mp; foreach $m (&foreign_call("mount", "list_mounted")) { $mp++ if ($m->[0] eq $in{'dir'}); } $mp || &error($text{'dump_emp'}); $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 256 || &error($text{'dump_elabel2'}); $_[0]->{'label'} = $in{'label'}; $_[0]->{'level'} = $in{'level'}; if ($in{'max_def'}) { delete($_[0]->{'max'}); } else { $in{'max'} =~ /^\d+$/ || &error($text{'dump_emax'}); $_[0]->{'max'} = $in{'max'}; } $_[0]->{'noattribs'} = $in{'noattribs'}; $_[0]->{'over'} = $in{'over'}; $_[0]->{'noinvent'} = $in{'noinvent'}; $_[0]->{'overwrite'} = $in{'overwrite'}; $_[0]->{'erase'} = $in{'erase'}; } else { # Parse ext2/3 options $_[0]->{'update'} = $in{'update'}; $_[0]->{'multi'} = $in{'multi'}; $_[0]->{'level'} = $in{'level'}; $in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 || &error($text{'dump_elabel'}); $_[0]->{'label'} = $in{'label'}; } } # execute_dump(&dump, filehandle, escape) # Executes a dump and displays the output sub execute_dump { local $fh = $_[1]; local ($cmd, $flag); if ($_[0]->{'huser'}) { $flag = " -f '$_[0]->{'huser'}@$_[0]->{'host'}:$_[0]->{'hfile'}'"; } elsif ($_[0]->{'host'}) { $flag = " -f '$_[0]->{'host'}:$_[0]->{'hfile'}'"; } else { $flag = " -f '$_[0]->{'file'}'"; } if ($_[0]->{'fs'} eq 'xfs') { # xfs backup $cmd = "xfsdump -l $_[0]->{'level'}"; $cmd .= $flag; $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'}); $cmd .= " -M '$_[0]->{'label'}'" if ($_[0]->{'label'}); $cmd .= " -z '$_[0]->{'max'}'" if ($_[0]->{'max'}); $cmd .= " -A" if ($_[0]->{'noattribs'}); $cmd .= " -F" if ($_[0]->{'over'}); $cmd .= " -J" if ($_[0]->{'noinvent'}); $cmd .= " -o" if ($_[0]->{'overwrite'}); $cmd .= " -E -F" if ($_[0]->{'erase'}); $cmd .= " '$_[0]->{'dir'}'"; } else { # ext2/3 backup $cmd = "dump -$_[0]->{'level'}"; $cmd .= $flag; $cmd .= " -u" if ($_[0]->{'update'}); $cmd .= " -M" if ($_[0]->{'multi'}); $cmd .= " -L '$_[0]->{'label'}'" if ($_[0]->{'label'}); $cmd .= " '$_[0]->{'dir'}'"; } &system_logged("sync"); sleep(1); &additional_log('exec', undef, $cmd); open(CMD, "$cmd 2>&1 ) { if ($_[2]) { print $fh &html_escape($_); } else { print $fh $_; } } close(CMD); } # dump_dest(&dump) sub dump_dest { if ($_[0]->{'file'}) { return "".&html_escape($_[0]->{'file'}).""; } elsif ($_[0]->{'huser'}) { return "".&html_escape("$_[0]->{'huser'}@$_[0]->{'host'}:$_[0]->{'hfile'}").""; } else { return "".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}").""; } } # missing_restore_command(filesystem) sub missing_restore_command { local $cmd = $_[0] eq 'xfs' ? 'xfsrestore' : 'restore'; return &has_command($cmd) ? undef : $cmd; } # restore_form(filesystem) sub restore_form { # common options print " ",&hlink($text{'restore_src'}, "rsrc"), "\n"; printf " %s\n", $text{'dump_file'}; printf " %s
\n", &file_chooser_button("file"); printf "\n"; print &text('dump_host', "", "", ""), " \n"; if ($_[0] eq 'xfs') { # xfs restore options print " ",&hlink($text{'restore_dir'},"rdir"), " \n"; print " ",&file_chooser_button("dir", 1), " \n"; print " ",&hlink($text{'restore_over'},"rover"), "\n"; print " ", "$text{'restore_over0'}\n"; print " $text{'restore_over1'}\n"; print " ", "$text{'restore_over2'} \n"; print " ",&hlink($text{'restore_noattribs'},"rnoattribs"), " \n"; print " $text{'yes'}\n"; print " $text{'no'}\n"; print "",&hlink($text{'restore_label'},"rlabel"),"\n"; print " \n"; print " ",&hlink($text{'restore_test'},"rtest"),"\n"; print " $text{'yes'}\n"; print " $text{'no'} \n"; } else { # ext2/3 restore options print " ",&hlink($text{'restore_files'},"rfiles"), "\n"; print " ", "$text{'restore_all'}\n"; print " $text{'restore_sel'}\n"; print " \n"; print " ",&hlink($text{'restore_dir'},"rdir"),"\n"; print " ", &file_chooser_button("dir", 1)," \n"; print " ",&hlink($text{'restore_multi'},"rmulti"), "\n"; print " $text{'yes'}\n"; print " $text{'no'}\n"; print "",&hlink($text{'restore_test'},"rtest"),"\n"; print " $text{'yes'}\n"; print " $text{'no'} \n"; } } # parse_restore(filesystem) # Parses inputs from restore_form() and returns a command to be passed to # restore_backup() sub parse_restore { local $cmd; if ($_[0] eq 'xfs') { $cmd = "xfsrestore"; $cmd .= " -t" if ($in{'test'}); } else { $cmd = "restore"; $cmd .= ($in{'test'} ? " -t" : " -x"); } if ($in{'mode'} == 0) { $in{'file'} || &error($text{'restore_efile'}); $cmd .= " -f '$in{'file'}'"; } else { gethostbyname($in{'host'}) || &check_ipaddress($in{'host'}) || &error($text{'restore_ehost'}); $in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'}); $in{'hfile'} || &error($text{'restore_ehfile'}); if ($in{'huser'}) { $cmd .= " -f '$in{'huser'}@$in{'host'}:$in{'hfile'}'"; } else { $cmd .= " -f '$in{'host'}:$in{'hfile'}'"; } } if ($_[0] eq 'xfs') { # parse xfs options $cmd .= " -E" if ($in{'over'} == 1); $cmd .= " -e" if ($in{'over'} == 2); $cmd .= " -A" if ($in{'noattribs'}); $cmd .= " -L '$in{'label'}'" if ($in{'label'}); $cmd .= " -F"; if (!$in{'test'}) { -d $in{'dir'} || &error($text{'restore_edir'}); $cmd .= " '$in{'dir'}'"; } } else { # parse ext2/3 options $cmd .= " -M" if ($in{'multi'}); if (!$in{'files_def'}) { $in{'files'} || &error($text{'restore_efiles'}); $cmd .= " $in{'files'}"; } -d $in{'dir'} || &error($text{'restore_edir'}); } return $cmd; } # restore_backup(filesystem, command) # Restores a backup based on inputs from restore_form(), and displays the results sub restore_backup { &additional_log('exec', undef, $_[1]); if ($_[0] eq 'xfs') { # Just run the backup command open(CMD, "$_[1] 2>&1 ) { print &html_escape($_); } close(CMD); } else { # Need to supply prompts &foreign_require("proc", "proc-lib.pl"); local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec", "cd '$in{'dir'}' ; $_[1]"); local $donevolume; while(1) { local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "(.*\\n)"); last if ($rv < 0); print &html_escape($matches[1]); if ($rv == 0) { if ($donevolume++) { return $text{'restore_evolume'}; } else { syswrite($fh, "1\n"); } } elsif ($rv == 1) { syswrite($fh, "n\n"); } elsif ($rv == 2) { return &text('restore_equestion', "$matches[2]"); } } close($fh); } return undef; } 1;