chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:12:17 +08:00
commit cf8edb9f21
44281 changed files with 1655134 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
---- Changes since 1.130 ----
Backup emails are now send using the Read User Mail module, removing any dependency on the Sendmail module.
---- Changes since 1.140 ----
Added support for backups that span multiple tapes. The user will be notified by email when a tape change is needed, after which is link on the module's main apge can be clicked to signal that the backup should continue.
Added access control options to restrict a user to only performing backups or restores, or limit the directories he is allowed to backup. Thanks for Martin Mewese for sponsoring these two features.
Added the ability to use tar for backups instead of dump commands, on Linux and FreeBSD. Tar will be used automatically for filesystems that do not have a dump command (like reiserfs), and can be enabled for all filesystems on the Module Config page.
---- Changes since 1.150 ----
Improved layout of dump form.
---- Changes since 1.160 ----
Added module configuration option to prevent prompting for a new tape if the curent one runs out of space.
---- Changes since 1.170 ----
When scheduling a dump, it can be specified to run after the completion of another backup dump. This makes it easy to backup multiple directories to a single tape.
When creating a TAR format backup, multiple directories can be entered.
---- Changes since 1.180 ----
A password can now be specified for remote backups and restores via SSH, on Linux and BSD systems.
---- Changes since 1.210 ----
Added options on Linux systems to verify a backup once it is complete, and to re-mount with the noatime option when backing up.
---- Changes since 1.260 ----
If the before-backup command fails, the entire backup is halted.
Added support for bzipping TAR archives on Linux systems.
---- Changes since 1.270 ----
Added checkboxes and a button for deleting multiple backups at once.
The backup message subject can include variables like ${HOSTNAME}, which will be substituted when the email is sent.
---- Changes since 1.290 ----
Made the backup and new tape email contents translatable.
Added an option for setting the path to the remote rmt command for tar format backups on Linux.
On Linux and BSD systems, backups and restores in TAR or EXT formats can be done via FTP as well as SSH, RSH and to local files.
---- Changes since 1.320 ----
Added a warning if % is used in filenames but strftime substition is not enabled.
---- Changes since 1.390 ----
When making tar format backups on Linux, an option to just append new files to the archive instead of over-writing it is available.
---- Changes since 1.400 ----
Fixed remote tar backups via FTP on OSX.
Files and directories to exclude can be specified for TAR format backups on Linux.
---- Changes since 1.410 ----
Added checkboxes to control if failure of the pre and post-backup commands cause the whole job to be regarded as a failure.
Prevent non-level-0 backups and updating of the /etc/dumpdates file for backups of directories that are not filesystem mount points, as this isn't supported by the <tt>dump</tt> command.
---- Changes since 1.440 ----
Fixed a bug that prevented backups of directories with spaces in their names from working properly on Linux.
---- Changes since 1.470 ----
When terminating a running backup, all sub-processes such as tar and dump commands are killed too.
Converted the UI on Solaris, OSX and FreeBSD to use the new Webmin UI library.
---- Changes since 1.510 ----
Fixed verification when a dump is to a date-based destination and takes more than one day.
+41
View File
@@ -0,0 +1,41 @@
do 'fsdump-lib.pl';
# acl_security_form(&options)
# Output HTML for editing security options for the acl module
sub acl_security_form
{
print &ui_table_row($text{'acl_edit'},
&ui_yesno_radio('edit', $_[0]->{'edit'}));
print &ui_table_row($text{'acl_restore'},
&ui_yesno_radio('restore', $_[0]->{'restore'}));
print &ui_table_row($text{'acl_cmds'},
&ui_yesno_radio('cmds', $_[0]->{'cmds'}));
print &ui_table_row($text{'acl_extra'},
&ui_yesno_radio('extra', $_[0]->{'extra'}));
print &ui_table_row($text{'acl_dirs'},
&ui_radio("dirs_def", $_[0]->{'dirs'} eq "*" ? 1 : 0,
[ [ 1, $text{'acl_all'} ],
[ 0, $text{'acl_list'} ] ])."<br>\n".
&ui_textarea("dirs", $_[0]->{'dirs'} eq "*" ? "" :
join("\n", split(/\t/, $_[0]->{'dirs'})),
5, 50), 3);
}
# acl_security_save(&options)
# Parse the form for security options for the acl module
sub acl_security_save
{
$_[0]->{'edit'} = $in{'edit'};
$_[0]->{'restore'} = $in{'restore'};
$_[0]->{'cmds'} = $in{'cmds'};
$_[0]->{'extra'} = $in{'extra'};
$in{'dirs'} =~ s/\r//g;
$_[0]->{'dirs'} = $in{'dirs_def'} ? "*" :
join("\t", split(/\n/, $in{'dirs'}));
}
+90
View File
@@ -0,0 +1,90 @@
#!/usr/local/bin/perl
# backup.cgi
# Run a filesystem backup, either in the background or foreground (and show
# the results)
require './fsdump-lib.pl';
&ReadParse();
$dump = &get_dump($in{'id'});
$dump->{'id'} || &error($text{'backup_egone'});
&can_edit_dir($dump) || &error($text{'backup_ecannot'});
if ($config{'run_mode'}) {
# Background
&ui_print_header(undef, $text{'backup_title'}, "");
print "<p>$text{'backup_bg'}<p>\n";
&clean_environment();
&system_logged("$cron_cmd ".quotemeta($dump->{'id'}).
" >/dev/null 2>&1 </dev/null &");
&reset_environment();
&webmin_log("bgbackup", undef, undef, $dump);
}
else {
# Foreground
&ui_print_unbuffered_header(undef, $text{'backup_title'}, "");
# Setup command to be called upon tape change (which is not
# supported in this mode)
$nfile = "$module_config_directory/$dump->{'id'}.notape";
unlink($nfile);
&create_wrappers();
print "<b>",&text('backup_desc',
"<tt>".&html_escape($dump->{'dir'})."</tt>",
&dump_dest($dump)),"</b><p>\n";
print "<pre>";
$bok = &execute_before($dump, STDOUT, 1);
if (!$bok && !$dump->{'beforefok'}) {
# Before command failed
print "</pre>\n";
print "<b>$text{'backup_beforefailed'}</b><p>\n";
}
else {
# Do the dump
$now = time();
$ok = &execute_dump($dump, STDOUT, 1, 0, $now);
print "</pre>\n";
if (!$bok) {
print "<b>$text{'backup_afterfailed'}</b><p>\n";
}
elsif ($ok) {
# Worked .. but verify if asked
if ($dump->{'reverify'}) {
print "<b>$text{'backup_reverify'}</b><p>\n";
print "<pre>";
$ok = &verify_dump($dump, STDOUT, 1, 0, $now);
print "</pre>";
}
if ($ok) {
print "<b>$text{'backup_done'}</b><br>\n";
}
else {
print "<b>$text{'backup_noverify'}</b><br>\n";
}
}
else {
if (-r $nfile) {
print "<b>$text{'backup_notape'}</b><br>\n";
}
else {
print "<b>$text{'backup_failed'}</b><br>\n";
}
}
# Execute the post-backup command, if any
if ($ok || $dump->{'afteraok'}) {
print "<pre>";
$bok = &execute_after($dump, STDOUT, 1);
print "</pre>\n";
}
}
unlink($nfile);
delete($dump->{'pass'});
&webmin_log("backup", undef, undef, $dump);
}
&ui_print_footer($access{'edit'} ? ( "edit_dump.cgi?id=$in{'id'}",
$text{'edit_return'} ) : ( ),
"", $text{'index_return'});
+137
View File
@@ -0,0 +1,137 @@
#!/usr/local/bin/perl
# backup.pl
# Perform a backup and send the results to someone
$no_acl_check++;
require './fsdump-lib.pl';
$dump = &get_dump($ARGV[0]);
$dump->{'id'} || die "Dump $ARGV[0] does not exist!";
# Check if this backup is already running
&foreign_require("proc", "proc-lib.pl");
@procs = &proc::list_processes();
@running = &running_dumps(\@procs);
($running) = grep { $_->{'id'} eq $dump->{'id'} &&
$_->{'pid'} != $$ } @running;
$sfile = "$module_config_directory/$dump->{'id'}.$$.status";
if ($running) {
# Already running! Do nothing ..
$ok = 0;
$out = &text('email_already', $running->{'pid'})."\n";
}
else {
# Update status file
%status = ( 'status' => 'running',
'pid' => $$,
'start' => time() );
&write_file($sfile, \%status);
if ($dump->{'email'}) {
# Save output for mailing
$temp = &transname();
open(OUT, ">$temp");
}
else {
# Throw output away
open(OUT, ">/dev/null");
}
# Create tape change wrapper
&create_wrappers();
$bok = &execute_before($dump, OUT, 0);
if (!$bok && !$dump->{'beforefok'}) {
# Before command failed!
print OUT "\n$text{'email_ebefore'}\n";
$status{'status'} = 'failed';
}
else {
# Do the backup
$now = time();
$ok = &execute_dump($dump, OUT, 0, 1, $now);
# Re-update the status file
if ($ok) {
# Worked .. but verify if asked
if ($dump->{'reverify'}) {
print OUT "\n$text{'email_verify'}\n";
$ok = &verify_dump($dump, OUT, 0, 1, $now);
}
if ($ok) {
$status{'status'} = 'complete';
}
else {
$status{'status'} = 'verifyfailed';
}
}
else {
$status{'status'} = 'failed';
}
}
$status{'end'} = time();
&write_file($sfile, \%status);
if ($status{'status'} eq 'complete' || $dump->{'afteraok'}) {
# Execute the post-backup script
$dump{'status'} = $status{'status'};
$bok = &execute_after($dump, OUT, 0);
if (!$bok && !$dump->{'afterfok'}) {
print OUT "\n$text{'email_eafter'}\n";
$status{'status'} = 'failed';
$ok = 0;
}
}
close(OUT);
if ($temp) {
# Read output
open(OUT, "<".$temp);
while(<OUT>) {
s/\r//g;
$out .= $_;
}
close(OUT);
unlink($temp);
}
}
if ($out && $dump->{'email'} && &foreign_check("mailboxes")) {
# Construct the email
&foreign_require("mailboxes", "mailboxes-lib.pl");
$host = &get_system_hostname();
@dirs = &dump_directories($dump);
$dirs = join(", ", @dirs);
%hash = ( %$dirs, 'dirs' => $dirs );
local $subject = &substitute_template($dump->{'subject'}, \%hash) ||
&text('email_subject', $dirs, $host);
local $data = &text('email_subject', $dirs, $host)."\n\n";
$data .= $out;
$data .= "\n";
if ($ok) {
$data .= $text{'email_ok'}."\n";
}
else {
$data .= $text{'email_failed'}."\n";
}
# Send the email
if (!$ok || !$config{'error_email'}) {
# Only send email upon failure, or it requested always
&mailboxes::send_text_mail(
&mailboxes::get_from_address(),
$dump->{'email'} eq '*' ? $gconfig{'webmin_email_to'}
: $dump->{'email'},
undef,
$subject,
$data,
$config{'smtp_server'});
}
}
# Check for any dumps scheduled to run after this one
foreach $follow (&list_dumps()) {
if ($follow->{'follow'} eq $dump->{'id'} && $follow->{'enabled'} == 2) {
system("$cron_cmd ".quotemeta($follow->{'id'}));
}
}
+17
View File
@@ -0,0 +1,17 @@
do 'fsdump-lib.pl';
sub cgi_args
{
my ($cgi) = @_;
my @dumps = grep { &can_edit_dir($_) } &list_dumps();
if ($cgi eq 'edit_dump.cgi') {
return @dumps ? 'id='.&urlize($dumps[0]->{'id'}) : 'dir=/etc';
}
elsif ($cgi eq 'restore_form.cgi') {
return @dumps ? 'id='.&urlize($dumps[0]->{'id'}).
'&fs='.$dumps[0]->{'fs'}
: 'fs=tar';
}
return undef;
}
+7
View File
@@ -0,0 +1,7 @@
date_subs=1
webmin_subs=0
run_mode=1
always_tar=0
nonewtape=0
error_email=0
simple_sched=0
+8
View File
@@ -0,0 +1,8 @@
date_subs=Do <tt>strftime</tt> substitution of backup destinations?,1,1-Yes,0-No
webmin_subs=Do Webmin variable substitution on backup destinations?,1,1-Yes,0-No
smtp_server=Send mail via SMTP server,3,Read User Mail module
run_mode=Run backups in,1,0-Foreground,1-Background
nonewtape=Action if tape is full,1,1-Fail immediately,0-Prompt for new tape
always_tar=Always use TAR format for backups?,1,1-Yes,0-No
error_email=Send backup email,1,0-Always,1-Only if error occurs
simple_sched=Schedule selector format,1,1-Simple,0-Complex
+6
View File
@@ -0,0 +1,6 @@
date_subs=هل استبدل <tt>strftime</tt> من وجهات النسخ الاحتياطية؟,1,1-نعم,0-لا
webmin_subs=هل استبدل متغير Webmin على وجهات النسخ الاحتياطية؟,1,1-نعم,0-لا
smtp_server=إرسال البريد عبر خادم SMTP,3,قراءة وحدة بريد المستخدم
run_mode=تشغيل النسخ الاحتياطية في,1,0-المقدمة,1-الخلفية
nonewtape=الإجراء إذا كان الشريط ممتلئ,1,1-Fail immediately,0-Prompt for new tape
always_tar=استخدم دائمًا تنسيق TAR للنسخ الاحتياطية؟,1,1-نعم,0-لا
+8
View File
@@ -0,0 +1,8 @@
date_subs=Fes la substitució <tt>strftime</tt> de les destinacions de la còpia,1,1-Sí,0-No
webmin_subs=Fes la substitució de les variables Webmin a les destinacions de còpia,1,1-Sí,0-No
smtp_server=Envia el correu via servidor SMTP,3,Mòdul de Lectura del Correu d'Usuaris
run_mode=Executa les còpies,1,0-En primer pla,1-En segon pla
nonewtape=Acció quan la cinta queda plena,1,1-Falla immediatament,0-Demana una altra cinta
always_tar=Utilitza sempre el format TAR per a les còpies,1,1-Sí,0-No
error_email=Envia correu de la còpia,1,0-Sempre,1-Només si es produeix un error
simple_sched=Format del selector de planificació,1,1-Simple,0-Complex
+6
View File
@@ -0,0 +1,6 @@
date_subs=Vytvořit <tt>strftime</tt> substituce cílů pro zálohování?,1,1-ano,0-ne
smtp_server=Odesílat mail přes SMTP server,3,Lokální spouštěč Sendmailu
run_mode=Spouštět zálohování v,1,0-Popředí,1-Pozadí
always_tar=Při zálohování vždy používat formát TAR?,1,1-Ano,0-Ne
error_email=Poslat zálohovací mail,1,0-Vždy,1-Jen v případě chyby
simple_sched=Formát pro plánovač,1,1-Jednoduchý,0-Komplexní
+8
View File
@@ -0,0 +1,8 @@
date_subs=<tt>strftime</tt>&#45;Substitution der Backup&#45;Ziele?,1,1-Ja,0-Nein
webmin_subs=Webmin Variablesubstitution auf Backup&#45;Zielen?,1,1-Ja,0-Nein
smtp_server=Sende E&#45;Mail über SMTP&#45;Server,3,Lese Benutzer&#45;E&#45;Mail&#45;Modul
run_mode=Starte Backups im,1,0-Vordergrund,1-Hintergrund
nonewtape=Aktion&#44; wenn Band voll ist,1,1-Sofort fehlschlagen,0-Aufforderung für ein neues Band
always_tar=Benutze immer TAR&#45;Format für Backups?,1,1-Ja,0-Nein
error_email=Sende Benachrichtigungs&#45;E&#45;Mail,1,0-Immer,1-Nur wenn Fehler auftreten
simple_sched=Schedule&#45;Selektor&#45;Format,1,1-Einfach,0-Komplex
+5
View File
@@ -0,0 +1,5 @@
date_subs=¿Hacer sustitución <tt>strftime</tt> de los destinos de copia de seguridad?,1,1-,0-No
smtp_server=Enviar correo via servidor SMTP,3,Módulo de Lectura de Correo de Usuarios
run_mode=Crear copias de seguridad en,1,0-Primer plano,1-Segundo plano
always_tar=¿Utilizar siempre formato TAR para las copias de seguridad?,1,1-,0-No
error_email=Mandar email de copia de seguridad,1,0-Siempre,1-Sólo si ocurre un error
View File
+6
View File
@@ -0,0 +1,6 @@
date_subs=백업 결과물의 <tt>strftime</tt> 을 대체 하겠습니까?,1,1-예,0-아니오
smtp_server=SMTP 서버로 메일 발송,3,유저 메일 일기 모듈
run_mode=백업 실행,1,0-포그라운드,1-백그라운드
always_tar=백업시 항상 TAR 형식을 사용할까요?1,1-예,0-아니오
error_email=백업 결과를 메일로 발송,1,0-항상,1-에러 발생시에만
simple_sched=스케쥴 선택 형식,1,1-간단히,0-자세히
+8
View File
@@ -0,0 +1,8 @@
date_subs=Doe <tt>strftime</tt> substitutie van de backup bestemmingen?,1,1-Ja,0-Nee
webmin_subs=Webmin variabele substitutie uitvoeren op backup bestemmingen?,1,1-Ja,0-Nee
smtp_server=Verstuur email via SMTP server,3,Lees Gebruikers Email module
run_mode=Backups uitvoeren op de,1,0-Voorgrond,1-Achtergrond
nonewtape=Welke actie als de tape vol is?,1,1-Mislukt onmiddellijk,0-Waarschuwen voor een nieuwe tape
always_tar=Altijd TAR formaat gebruiken voor backups?,1,1-Ja,0-Nee
error_email=Verstuur backup email,1,0-Altijd,1-Alleen als er fouten zijn
simple_sched=Schema selectie formaat,1,1-Simpel,0-Complex
+8
View File
@@ -0,0 +1,8 @@
date_subs=Utfør <tt>strftime</tt> erstatninger på mål for sikkerhetskopier?,1,1-Ja,0-Nei
webmin_subs=Utfør Webmin variabel-erstatning på mål for sikkerhetskopier?,1,1-Ja,0-Nei
smtp_server=Send e-post via SMTP tjener,3,Modulen Les brukers e-post
run_mode=Kjør sikkerhetskopiering i,1,0-Forgrunnen,1-Bakgrunnen
nonewtape=Be om ny tape dersom tape er full?,1,1-Ja,0-Nei
always_tar=Bruk alltid TAR format for sikkerhetskopier,1,1-Ja,0-Nei
error_email=Send e-post om sikkerhetskopiering,1,0-Alltid,1-Bare dersom feil oppstår
simple_sched=Format på tidsplanvelger,1,1-Enkel,0-Kompleks
+8
View File
@@ -0,0 +1,8 @@
date_subs=Podstawić <tt>strftime</tt> jako lokalizację kopii zapasowych?,1,1-Tak,0-Nie
webmin_subs=Uczyń zmienną Webmina jako substytut dla celu kopii zapasowej?,1,1-Tak,0-Nie
smtp_server=Wyślij e-mail przez serwer SMTP,3,Moduł Czytaj e-maile użytkowników
run_mode=Uruchom kopie zapasowe w,1,0-pierwszym planie (Foreground),1-tle (Background)
nonewtape=Działanie jeżeli taśma jest pełna,1,1-Natychmiast przerwij,0-Poproś o nową taśmę
always_tar=Zawsze używać formatu TAR do kopii zapasowych?,1,1-Tak,0-Nie
error_email=Wyślij e-mail o kopii zapasowej,1,0-Zawsze,1-Tylko w przypadku błędu
simple_sched=Format wybierania harmonogramu,1,1-Prosty,0-Pełny
+6
View File
@@ -0,0 +1,6 @@
date_subs=Fazer substituição <tt>strftime</tt> dos destinos de backup?,1,1-Sim,0-Não
smtp_server=Enviar e-mail via servidor SMTP,3,Ler módulo de Correio do Usuário
run_mode=Executar backups em,1,0-Primeiro plano,1-Plano de fundo
always_tar=Sempre usar formato TAR para backups?,1,1-Sim,0-Não
error_email=Enviar e-mail de backup,1,0-Sempre,1-Só se ocorrerem erros
simple_sched=Formato do seletor de agendamento,1,1-Simples,0-Complexo
+1
View File
@@ -0,0 +1 @@
date_subs=Заменять место назначения резервной копии с помощью <tt>strftime</tt>?,1,1-Да,0-Нет
+1
View File
@@ -0,0 +1 @@
date_subs=Заміняти місце призначення резервної копії за допомогою <tt>strftime</tt>?,1,1-да,0-немає
+5
View File
@@ -0,0 +1,5 @@
edit=1
restore=1
dirs=*
cmds=1
extra=1
+28
View File
@@ -0,0 +1,28 @@
#!/usr/local/bin/perl
# Delete a bunch of backups
require './fsdump-lib.pl';
&foreign_require("cron", "cron-lib.pl");
&ReadParse();
&error_setup($text{'delete_err'});
@d = split(/\0/, $in{'d'});
@d || &error($text{'delete_enone'});
# Delete each one, and its cron job
foreach $d (@d) {
$dump = &get_dump($d);
$access{'edit'} && &can_edit_dir($dump) ||
&error($text{'dump_ecannot2'});
@jobs = &foreign_call("cron", "list_cron_jobs");
($job) = grep { $_->{'command'} eq "$cron_cmd $dump->{'id'}" } @jobs;
&delete_dump($dump);
if ($job) {
&lock_file($job->{'file'});
&foreign_call("cron", "delete_cron_job", $job);
&unlock_file($job->{'file'});
}
}
&webmin_log("delete", "dumps", scalar(@d));
&redirect("");
+193
View File
@@ -0,0 +1,193 @@
#!/usr/local/bin/perl
# edit_dump.cgi
# Edit or create a filesystem backup
require './fsdump-lib.pl';
&foreign_require("cron", "cron-lib.pl");
&ReadParse();
$wet = $gconfig{'webmin_email_to'};
if (!$in{'id'}) {
# Adding a new backup of some type
$access{'edit'} || &error($text{'dump_ecannot1'});
&error_setup($text{'edit_err'});
$in{'dir'} || &error($text{'edit_edir'});
if ($supports_tar && ($config{'always_tar'} || $in{'forcetar'})) {
# Always use tar format
$fs = "tar";
}
else {
# Work out filesystem type
$fs = &directory_filesystem($in{'dir'});
@supp = &supported_filesystems();
if (&indexof($fs, @supp) < 0) {
if ($supports_tar) {
$fs = "tar"; # fall back to tar mode
}
else {
&error(&text('edit_efs', uc($fs)));
}
}
}
&ui_print_header(undef, $text{'edit_title'}, "", "edit");
$dump = { 'dir' => $in{'dir'},
'fs' => $fs,
'rsh' => &has_command("ssh"),
'email' => $wet ? '*' : undef,
$config{'simple_sched'} ?
( 'special' => 'daily' ) :
( 'mins' => '0',
'hours' => '0',
'days' => '*',
'months' => '*',
'weekdays' => '*' ) };
}
else {
# Editing an existing backup
$dump = &get_dump($in{'id'});
$access{'edit'} && &can_edit_dir($dump) ||
&error($text{'dump_ecannot2'});
if ($in{'clone'}) {
&ui_print_header(undef, $text{'edit_title3'}, "", "create");
delete($in{'id'});
}
else {
&ui_print_header(undef, $text{'edit_title2'}, "", "create");
$dump->{'rsh'} = &has_command("ssh") if (!$dump->{'host'});
}
}
@tds = ( "width=30%" );
print &ui_form_start("save_dump.cgi", "post");
print &ui_hidden("id", $in{'id'}),"\n";
print &ui_hidden("fs", $dump->{'fs'}),"\n";
print &ui_hidden_table_start(&text('edit_header', uc($dump->{'fs'})),
"width=100%", 2, "source", 1);
print &ui_table_row($text{'dump_format'},
$dump->{'fs'} eq 'tar' ? $text{'dump_tar'}
: &text('dump_dumpfs', uc($dump->{'fs'})),
undef, \@tds);
if (!&multiple_directory_support($dump->{'fs'})) {
# One directory
print &ui_table_row(&hlink($text{'dump_dir'}, "dir"),
&ui_textbox("dir", $dump->{'dir'}, 50)."\n".
&file_chooser_button("dir", 1),
undef, \@tds);
}
else {
# Multiple directories
print &ui_table_row(&hlink($text{'dump_dirs'}, "dirs"),
&ui_textarea("dir", join("\n", &dump_directories($dump)),
3, 50),
undef, \@tds);
}
&dump_form($dump, \@tds);
print &ui_hidden_table_end();
print &ui_hidden_table_start($text{'edit_header3'}, "width=100%", 4, "opts", 0);
if (defined(&dump_options_form)) {
&dump_options_form($dump, \@tds);
}
if (defined(&verify_dump)) {
# Add option to verify, if supported
print &ui_table_row(&hlink($text{'dump_reverify'},"reverify"),
&ui_yesno_radio("reverify",
int($dump->{'reverify'})),
\@tds);
}
# Extra command-line parameters
if ($access{'extra'}) {
print &ui_table_row(&hlink($text{'dump_extra'}, "extra"),
&ui_textbox("extra", $dump->{'extra'}, 60), 3,
\@tds);
}
# Before and after commands
if ($access{'cmds'}) {
print &ui_table_row(&hlink($text{'dump_before'},"before"),
&ui_textbox("before", $dump->{'before'}, 60)."<br>".
&ui_checkbox("beforefok", 1, $text{'dump_fok'},
!$dump->{'beforefok'}),
3, \@tds);
print &ui_table_row(&hlink($text{'dump_after'},"after"),
&ui_textbox("after", $dump->{'after'}, 60)."<br>".
&ui_checkbox("afterfok", 1, $text{'dump_fok2'},
!$dump->{'afterfok'})."<br>".
&ui_checkbox("afteraok", 1, $text{'dump_aok'},
!$dump->{'afteraok'}),
3, \@tds);
}
print &ui_hidden_table_end();
print &ui_hidden_table_start($text{'edit_header2'}, "width=100%", 4,
"sched", 0);
# Show input for selecting when to run a dump, which can be never, on schedule
# or after some other dump
@dlist = grep { $_->{'id'} ne $in{'id'} } &list_dumps();
if (@dlist) {
$follow = &ui_select("follow", $dump->{'follow'},
[ map { [ $_->{'id'}, &follow_desc($_) ] } @dlist ]);
}
print &ui_table_row(&hlink($text{'edit_enabled'}, "enabled"),
&ui_radio("enabled", $dump->{'follow'} ? 2 :
$dump->{'enabled'} ? 1 : 0,
[ [ 0, $text{'edit_enabled_no'}."<br>" ],
@dlist ?
( [ 2, $text{'edit_enabled_af'}." ".$follow."<br>" ] ) : ( ),
[ 1, $text{'edit_enabled_yes'} ] ]), 3, \@tds);
# Email address to send output to
print &ui_table_row(&hlink($text{'edit_email'}, "email"),
$wet ? &ui_opt_textbox("email",
$dump->{'email'} eq '*' ? undef : $dump->{'email'},
40, &text('edit_email_def', "<tt>$wet</tt>"))
: &ui_textbox("email", $dump->{'email'}, 40));
# Subject line for email message
print &ui_table_row(&hlink($text{'edit_subject'}, "subject"),
&ui_opt_textbox("subject", $dump->{'subject'},
40, $text{'default'}), 3, \@tds);
if (!$config{'simple_sched'} || ($dump && !$dump->{'special'})) {
# Complex Cron time input
print &cron::get_times_input($dump, 0, 4, $text{'edit_when'});
}
else {
# Simple input
print &ui_hidden("special_def", 1),"\n";
print &ui_table_row(&hlink($text{'edit_special'}, "special"),
&ui_select("special", $dump->{'special'},
[ map { [ $_, $cron::text{'edit_special_'.$_} ] }
('hourly', 'daily', 'weekly', 'monthly', 'yearly') ]),
3, \@tds);
}
print &ui_hidden_table_end();
if ($in{'id'}) {
print &ui_form_end([ [ "save", $text{'save'} ],
[ "savenow", $text{'edit_savenow'} ],
[ "restore", $text{'edit_restore'} ],
[ "clone", $text{'edit_clone'} ],
[ "delete", $text{'delete'} ] ]);
}
else {
print &ui_form_end([ [ "create", $text{'create'} ],
[ "savenow", $text{'edit_createnow'} ] ]);
}
&ui_print_footer("", $text{'index_return'});
# follow_desc(&dump)
sub follow_desc
{
local @dirs = &dump_directories($_[0]);
return &text(defined($_[0]->{'level'}) ? 'edit_tolevel' : 'edit_to',
$dirs[0], &dump_dest($_[0]), $_[0]->{'level'});
}
+16
View File
@@ -0,0 +1,16 @@
do 'fsdump-lib.pl';
sub feedback_files
{
local (@rv, $f);
opendir(DIR, $module_config_directory);
foreach $f (readdir(DIR)) {
push(@rv, "$module_config_directory/$f") if ($f =~ /\.dump$/);
}
closedir(DIR);
return @rv;
}
1;
+452
View File
@@ -0,0 +1,452 @@
# freebsd-lib.pl
# supported_filesystems()
# Returns a list of filesystem types on which dumping is supported
sub supported_filesystems
{
local @rv;
push(@rv, "ufs") if (&has_command("dump"));
return @rv;
}
# multiple_directory_support(fs)
# Returns 1 if some filesystem dump supports multiple directories
sub multiple_directory_support
{
return 0;
}
$supports_tar = 1;
$tar_command = &has_command("gtar") || &has_command("tar");
# dump_form(&dump)
sub dump_form
{
# Display common options
print &ui_table_row(&hlink($text{'dump_dest'}, "dest"),
&ui_radio("mode", $_[0]->{'host'} ? 1 : 0,
[ [ 0, $text{'dump_file'}." ".
&ui_textbox("file", $_[0]->{'file'}, 50, undef, undef,
$config{'date_subs'} ?
'placeholder="/backups/filename-%y-%m-%d-%H-%M-%S.tar.gz"' : undef).
" ".&file_chooser_button("file")."<br>" ],
[ 1, &text('dump_host',
&ui_textbox("host", $_[0]->{'host'}, 20),
&ui_textbox("huser", $_[0]->{'huser'}, 15),
&ui_textbox("hfile", $_[0]->{'hfile'}, 40)) ] ]), 3);
if ($_[0]->{'fs'} eq 'tar') {
# Display gnutar options
print &ui_table_row(&hlink($text{'dump_rsh'},"rsh"),
&rsh_command_input("rsh_def", "rsh", $_[0]->{'rsh'}), 3);
# Password option for SSH
print &ui_table_row(&hlink($text{'dump_pass'},"pass"),
&ui_password("pass", $_[0]->{'pass'}, 20), 3);
}
}
sub dump_options_form
{
local ($dump, $tds) = @_;
if ($_[0]->{'fs'} eq 'tar') {
# Display gnutar options
print &ui_table_row(&hlink($text{'dump_label'},"label"),
&ui_textbox("label", $_[0]->{'label'}, 15),
1, $tds);
print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
&ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
$text{'dump_auto'})." kB",
3, $tds);
print &ui_table_row(&hlink($text{'dump_gzip'},"gzip"),
&ui_select("gzip", int($_[0]->{'gzip'}),
[ [ 0, $text{'no'} ],
[ 1, $text{'dump_gzip1'} ] ]), 1, $tds);
print &ui_table_row(&hlink($text{'dump_multi'},"multi"),
&ui_yesno_radio("multi", int($_[0]->{'multi'})),
1, $tds);
print &ui_table_row(&hlink($text{'dump_links'},"links"),
&ui_yesno_radio("links", int($_[0]->{'links'})),
1, $tds);
print &ui_table_row(&hlink($text{'dump_xdev'},"xdev"),
&ui_yesno_radio("xdev", int($_[0]->{'xdev'})),
1, $tds);
}
else {
# Display ufs backup options
print &ui_table_row(&hlink($text{'dump_update'},"update"),
&ui_yesno_radio("update", int($_[0]->{'update'})),
1, $tds);
print &ui_table_row(&hlink($text{'dump_level'},"level"),
&ui_select("level", int($_[0]->{'level'}),
[ map { [ $_, $text{'dump_level_'.$_} ] }
(0 .. 9) ]), 1, $tds);
print &ui_table_row(&hlink($text{'dump_blocks'},"blocks"),
&ui_opt_textbox("blocks", $_[0]->{'blocks'}, 8,
$text{'dump_auto'})." kB",
3, $tds);
print &ui_table_row(&hlink($text{'dump_honour'},"honour"),
&ui_yesno_radio("honour", int($_[0]->{'honour'})),
1, $tds);
}
}
# 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 {
&to_ipaddress($in{'host'}) ||
&to_ip6address($in{'host'}) ||
&error($text{'dump_ehost'});
$_[0]->{'host'} = $in{'host'};
$in{'huser'} =~ /^\S+$/ || &error($text{'dump_ehuser'});
$in{'huser'} =~ /\@/ && &error($text{'dump_ehuser2'});
$_[0]->{'huser'} = $in{'huser'};
$in{'hfile'} || &error($text{'dump_ehfile'});
$_[0]->{'hfile'} = $in{'hfile'};
delete($_[0]->{'file'});
}
if ($_[0]->{'fs'} eq 'tar') {
# Parse tar options
$_[0]->{'rsh'} = &rsh_command_parse("rsh_def", "rsh");
$_[0]->{'pass'} = $in{'pass'};
$in{'label'} =~ /^\S*$/ && length($in{'label'}) < 16 ||
&error($text{'dump_elabel'});
$_[0]->{'label'} = $in{'label'};
if ($in{'blocks_def'}) {
delete($_[0]->{'blocks'});
}
else {
$in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
$_[0]->{'blocks'} = $in{'blocks'};
$in{'gzip'} && &error($text{'dump_egzip'});
}
$_[0]->{'gzip'} = $in{'gzip'};
$_[0]->{'multi'} = $in{'multi'};
$_[0]->{'links'} = $in{'links'};
$_[0]->{'xdev'} = $in{'xdev'};
if ($in{'multi'}) {
!-c $in{'file'} && !-b $in{'file'} ||
&error($text{'dump_emulti'});
$in{'gzip'} && &error($text{'dump_egzip2'});
}
}
else {
# Parse ufs options
local $mp;
foreach $m (&foreign_call("mount", "list_mounted")) {
$mp++ if ($m->[0] eq $in{'dir'});
}
$mp || &error($text{'dump_emp'});
$_[0]->{'update'} = $in{'update'};
$_[0]->{'level'} = $in{'level'};
$_[0]->{'honour'} = $in{'honour'};
if ($in{'blocks_def'}) {
delete($_[0]->{'blocks'});
}
else {
$in{'blocks'} =~ /^\d+$/ || &error($text{'dump_eblocks'});
$_[0]->{'blocks'} = $in{'blocks'};
}
}
}
# execute_dump(&dump, filehandle, escape, background-mode, [time])
# Executes a dump and displays the output
sub execute_dump
{
local $fh = $_[1];
local ($cmd, $flags);
if ($_[0]->{'huser'}) {
$flags = "-f ".quotemeta("$_[0]->{'huser'}\@$_[0]->{'host'}:".
&date_subs($_[0]->{'hfile'}, $_[4]));
}
elsif ($_[0]->{'host'}) {
$flags = "-f ".quotemeta("$_[0]->{'host'}:".
&date_subs($_[0]->{'hfile'}, $_[4]));
}
else {
$flags = "-f ".quotemeta(&date_subs($_[0]->{'file'}, $_[4]));
}
local $tapecmd = $_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar' ? $multi_cmd :
$_[0]->{'multi'} ? undef :
$_[3] && !$config{'nonewtape'} ? $newtape_cmd : $notape_cmd;
if ($_[0]->{'fs'} eq 'tar') {
# Construct tar command
$cmd = "$tar_command -c $flags";
$cmd .= " -V ".quotemeta($_[0]->{'label'}) if ($_[0]->{'label'});
$cmd .= " -L $_[0]->{'blocks'}" if ($_[0]->{'blocks'});
$cmd .= " -z" if ($_[0]->{'gzip'});
$cmd .= " -M" if ($_[0]->{'multi'});
$cmd .= " -h" if ($_[0]->{'links'});
$cmd .= " -l" if ($_[0]->{'xdev'});
$cmd .= " -F ".quotemeta("$tapecmd $_[0]->{'id'}")
if (!$_[0]->{'gzip'} && ($_[0]->{'file'} =~ /^\/dev/ ||
$_[0]->{'hfile'} =~ /^\/dev/));
$cmd .= " --rsh-command=".quotemeta($_[0]->{'rsh'})
if ($_[0]->{'rsh'} && $_[0]->{'host'});
$cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
$cmd .= " ".quotemeta(&date_subs($_[0]->{'dir'}));
}
else {
# Construct ufs dump command
$cmd = "dump -$_[0]->{'level'} $flags";
$cmd .= " -u" if ($_[0]->{'update'});
if ($_[0]->{'blocks'}) {
$cmd .= " -B $_[0]->{'blocks'}";
}
else {
$cmd .= " -a";
}
$cmd .= " -h 0" if ($_[0]->{'honour'});
$cmd .= " $_[0]->{'extra'}" if ($_[0]->{'extra'});
$cmd .= " ".quotemeta(&date_subs($_[0]->{'dir'}));
}
&system_logged("sync");
sleep(1);
$ENV{'DUMP_PASSWORD'} = $_[0]->{'pass'};
local $got = &run_ssh_command($cmd, $fh, $_[2], $_[0]->{'pass'});
if ($_[0]->{'multi'} && $_[0]->{'fs'} eq 'tar') {
# Run multi-file switch command one last time
&execute_command("$multi_cmd ".quotemeta($_[0]->{'id'}).
" >/dev/null 2>&1");
}
return $got ? 0 : 1;
}
# dump_dest(&dump)
sub dump_dest
{
if ($_[0]->{'file'}) {
return "<tt>".&html_escape($_[0]->{'file'})."</tt>";
}
elsif ($_[0]->{'huser'}) {
return "<tt>".&html_escape("$_[0]->{'huser'}\@$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
}
else {
return "<tt>".&html_escape("$_[0]->{'host'}:$_[0]->{'hfile'}")."</tt>";
}
}
# missing_restore_command(filesystem)
sub missing_restore_command
{
return &has_command("restore") ? undef : $cmd;
}
# restore_form(filesystem, [&dump])
sub restore_form
{
local ($fs, $dump, $tds) = @_;
# common options
print &ui_table_row(&hlink($text{'restore_src'}, "rsrc"),
&ui_radio("mode", $_[1]->{'host'} ? 1 : 0,
[ [ 0, $text{'dump_file'}." ".
&ui_textbox("file", $_[1]->{'file'}, 50).
" ".&file_chooser_button("file")."<br>" ],
[ 1, &text('dump_host',
&ui_textbox("host", $_[1]->{'host'}, 20),
&ui_textbox("huser", $_[1]->{'huser'}, 15),
&ui_textbox("hfile", $_[1]->{'hfile'}, 40)) ] ]), 3, $tds);
if ($_[0] eq 'tar') {
# tar restore options
print &ui_table_row(&hlink($text{'restore_rsh'},"rrsh"),
&rsh_command_input("rsh_def", "rsh", $_[1]->{'rsh'}),
3, $tds);
# Password option for SSH
print &ui_table_row(&hlink($text{'dump_pass2'},"pass2"),
&ui_password("pass", $_[1]->{'pass'}, 20),
3, $tds);
# Files to restore
print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
&ui_opt_textbox("files", undef, 40, $text{'restore_all'},
$text{'restore_sel'}), 3, $tds);
# Target dir
print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
&ui_textbox("dir", undef, 50)." ".
&file_chooser_button("dir", 1), 3, $tds);
# Restore permissions?
print &ui_table_row(&hlink($text{'restore_perms'},"perms"),
&ui_yesno_radio("perms", 1), 1, $tds);
# Uncompress?
print &ui_table_row(&hlink($text{'restore_gzip'},"rgzip"),
&ui_select("gzip", $_[1]->{'gzip'},
[ [ 0, $text{'no'} ],
[ 1, $text{'dump_gzip1'} ] ]), 1, $tds);
print &ui_table_row(&hlink($text{'restore_keep'},"keep"),
&ui_yesno_radio("keep", 0), 1, $tds);
# Multiple files
print &ui_table_row(&hlink($text{'restore_multi'},"rmulti"),
&ui_yesno_radio("multi", 0), 1, $tds);
# Show only
print &ui_table_row(&hlink($text{'restore_test'},"rtest"),
&ui_yesno_radio("test", 1), 1, $tds);
}
else {
# ufs restore options, files to restore
print &ui_table_row(&hlink($text{'restore_files'},"rfiles"),
&ui_opt_textbox("files", undef, 40, $text{'restore_all'},
$text{'restore_sel'}), 3, $tds);
# Target dir
print &ui_table_row(&hlink($text{'restore_dir'},"rdir"),
&ui_textbox("dir", undef, 50)." ".
&file_chooser_button("dir", 1), 3, $tds);
# Show only
print &ui_table_row(&hlink($text{'restore_nothing'},"rnothing"),
&ui_yesno_radio("nothing", 1), 1, $tds);
}
}
# 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 "tar") {
$cmd = $tar_command;
if ($in{'test'}) {
$cmd .= " -t -v";
}
else {
$cmd .= " -x";
}
}
else {
$cmd .= "restore".($in{'test'} ? " -t" : " -x");
}
if ($in{'mode'} == 0) {
$in{'file'} || &error($text{'restore_efile'});
$cmd .= " -f ".quotemeta($in{'file'});
}
else {
&to_ipaddress($in{'host'}) ||
&to_ip6address($in{'host'}) ||
&error($text{'restore_ehost'});
$in{'huser'} =~ /^\S*$/ || &error($text{'restore_ehuser'});
$in{'hfile'} || &error($text{'restore_ehfile'});
if ($in{'huser'}) {
$cmd .= " -f ".quotemeta("$in{'huser'}\@$in{'host'}:$in{'hfile'}");
}
else {
$cmd .= " -f ".quotemeta("$in{'host'}:$in{'hfile'}");
}
}
if ($_[0] eq 'tar') {
# parse tar options
$cmd .= " -p" if ($in{'perms'});
$cmd .= " -z" if ($in{'gzip'});
$cmd .= " -k" if ($in{'keep'});
if ($in{'multi'}) {
!-c $in{'file'} && !-b $in{'file'} ||
&error($text{'restore_emulti'});
$in{'mode'} == 0 || &error($text{'restore_emulti2'});
$cmd .= " -M -F ".quotemeta("$rmulti_cmd $in{'file'}");
}
local $rsh = &rsh_command_parse("rsh_def", "rsh");
if ($rsh) {
$cmd .= " --rsh-command=".quotemeta($rsh);
}
$cmd .= " $in{'extra'}" if ($in{'extra'});
if (!$in{'files_def'}) {
$in{'files'} || &error($text{'restore_efiles'});
$cmd .= " $in{'files'}";
}
-d $in{'dir'} || &error($text{'restore_edir'});
$cmd = "cd ".quotemeta($in{'dir'})." && $cmd";
if ($in{'multi'}) {
$cmd = "$rmulti_cmd ".quotemeta($in{'file'})." 1 && $cmd";
}
}
else {
# parse ufs options
$cmd .= " -N" if ($in{'nothing'});
$cmd .= " $in{'extra'}" if ($in{'extra'});
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]);
$ENV{'DUMP_PASSWORD'} = $in{'pass'};
# Need to supply prompts
&foreign_require("proc", "proc-lib.pl");
local ($fh, $fpid) = &foreign_call("proc", "pty_process_exec",
"cd ".quotemeta($in{'dir'})." ; $_[1]");
local $donevolume;
while(1) {
local $rv = &wait_for($fh, "(next volume #)", "(set owner.mode for.*\\[yn\\])", "((.*)\\[yn\\])", "password:", "yes\\/no", "(.*\\n)");
last if ($rv < 0);
print &html_escape($matches[1]);
if ($rv == 0) {
if ($donevolume++) {
return $text{'restore_evolume'};
}
else {
syswrite($fh, "1\n", 2);
}
}
elsif ($rv == 1) {
syswrite($fh, "n\n", 2);
}
elsif ($rv == 2) {
return &text('restore_equestion',
"<tt>$matches[2]</tt>");
}
elsif ($rv == 3) {
syswrite($fh, "$in{'pass'}\n");
}
elsif ($rv == 4) {
syswrite($fh, "yes\n");
}
}
close($fh);
waitpid($fpid, 0);
return $? || undef;
}
1;
+350
View File
@@ -0,0 +1,350 @@
#!/usr/local/bin/perl
# fsdump-lib.pl
# Common functions for doing filesystem backups with dump
BEGIN { push(@INC, ".."); };
use WebminCore;
&init_config();
if ($gconfig{'os_type'} =~ /^\S+\-linux$/) {
do "linux-lib.pl";
}
else {
do "$gconfig{'os_type'}-lib.pl";
}
&foreign_require("mount", "mount-lib.pl");
%access = &get_module_acl();
$cron_cmd = "$module_config_directory/backup.pl";
$newtape_cmd = "$module_config_directory/newtape.pl";
$notape_cmd = "$module_config_directory/notape.pl";
$multi_cmd = "$module_config_directory/multi.pl";
$rmulti_cmd = "$module_config_directory/rmulti.pl";
$ftp_cmd = "$module_config_directory/ftp.pl";
# list_dumps()
# Returns a list of all scheduled dumps
sub list_dumps
{
local (@rv, $f);
opendir(DIR, $module_config_directory);
foreach $f (sort { $a cmp $b } readdir(DIR)) {
next if ($f !~ /^(\S+)\.dump$/);
push(@rv, &get_dump($1));
}
closedir(DIR);
return @rv;
}
# get_dump(id)
sub get_dump
{
local %dump;
&read_file("$module_config_directory/$_[0].dump", \%dump) || return undef;
$dump{'id'} = $_[0];
return \%dump;
}
# save_dump(&dump)
sub save_dump
{
$_[0]->{'id'} = $$.time() if (!$_[0]->{'id'});
&lock_file("$module_config_directory/$_[0]->{'id'}.dump");
&write_file("$module_config_directory/$_[0]->{'id'}.dump", $_[0]);
&unlock_file("$module_config_directory/$_[0]->{'id'}.dump");
}
# delete_dump(&dump)
sub delete_dump
{
&lock_file("$module_config_directory/$_[0]->{'id'}.dump");
unlink("$module_config_directory/$_[0]->{'id'}.dump");
&unlock_file("$module_config_directory/$_[0]->{'id'}.dump");
}
# directory_filesystem(dir)
# Returns the filesystem type of some directory , or the full details
# if requesting an array
sub directory_filesystem
{
local $fs;
foreach my $m (sort { length($a->[0]) <=> length($b->[0]) }
&mount::list_mounted()) {
local $l = length($m->[0]);
if ($m->[0] eq $_[0] || $m->[0] eq "/" ||
(length($_[0]) >= $l && substr($_[0], 0, $l+1) eq $m->[0]."/")) {
$fs = $m;
}
}
return wantarray ? @$fs : $fs->[2];
}
# is_mount_point(dir)
# Returns 1 if some directory is a filesystem mount point
sub is_mount_point
{
local ($dir) = @_;
foreach my $m (&mount::list_mounted()) {
return 1 if ($m->[0] eq $dir);
}
return 0;
}
# same_filesystem(fs1, fs2)
# Returns 1 if type filesystem types are the same
sub same_filesystem
{
local ($fs1, $fs2) = @_;
$fs1 = "ext2" if ($fs1 eq "ext3");
$fs2 = "ext2" if ($fs2 eq "ext3");
return lc($fs1) eq lc($fs2);
}
# date_subs(string, [time])
sub date_subs
{
local ($path, $time) = @_;
local $rv;
if ($config{'date_subs'}) {
eval "use POSIX";
eval "use posix" if ($@);
local @tm = localtime($time || time());
&clear_time_locale();
$rv = strftime($path, @tm);
&reset_time_locale();
}
else {
$rv = $path;
}
if ($config{'webmin_subs'}) {
$rv = &substitute_template($rv, { });
}
return $rv;
}
# execute_before(&dump, handle, escape)
# Executes the before-dump command, and prints the output. Returns 1 on success
# or 0 on failure
sub execute_before
{
my ($dump, $h, $esc) = @_;
if ($dump->{'before'}) {
&set_dump_envs($dump);
&open_execute_command(before, "($dump->{'before'}) 2>&1 </dev/null", 1);
while(<before>) {
print $h $esc ? &html_escape($_) : $_;
}
close(before);
&reset_dump_envs();
return !$?;
}
return 1;
}
# execute_after(&dump, handle, escape)
# Executes the before-dump command, and prints the output. Returns 1 on success
# or 0 on failure
sub execute_after
{
my ($dump, $h, $esc) = @_;
if ($dump->{'after'}) {
&set_dump_envs($dump);
&open_execute_command(after, "($dump->{'after'}) 2>&1 </dev/null", 1);
while(<after>) {
print $h $esc ? &html_escape($_) : $_;
}
close(after);
&reset_dump_envs();
return !$?;
}
return 1;
}
# set_dump_envs(&dump)
# Sets FSDUMP_ environment variables based on attributes of the dump
sub set_dump_envs
{
my ($dump) = @_;
foreach my $k (keys %$dump) {
$ENV{'FSDUMP_'.uc($k)} = $dump->{$k};
}
}
# reset_dump_envs()
# Clear all variables set by set_dump_envs
sub reset_dump_envs
{
foreach my $k (keys %ENV) {
delete($ENV{$k}) if ($k =~ /^FSDUMP_/);
}
}
# running_dumps(&procs)
# Returns a list of backup jobs currently in progress, and their statuses
sub running_dumps
{
local ($p, @rv, %got);
foreach $p (@{$_[0]}) {
if (($p->{'args'} =~ /$cron_cmd\s+(\S+)/ ||
$p->{'args'} =~ /$module_root_directory\/backup.pl\s+(\S+)/) &&
$p->{'args'} !~ /^\/bin\/(sh|bash|csh|tcsh)/) {
local $backup = &get_dump($1);
local $sfile = "$module_config_directory/$1.$p->{'pid'}.status";
local %status;
if (&read_file($sfile, \%status)) {
$backup->{'status'} = \%status;
$backup->{'pid'} = $p->{'pid'};
push(@rv, $backup);
$got{$sfile} = 1 if (!$status{'end'});
}
}
}
# Remove any left over .status files
opendir(DIR, $module_config_directory);
local $f;
foreach $f (readdir(DIR)) {
local $path = "$module_config_directory/$f";
unlink($path) if ($path =~ /\.status$/ && !$got{$path});
}
closedir(DIR);
return @rv;
}
# can_edit_dir(dir)
# Returns 1 if some backup can be used or edited
sub can_edit_dir
{
return 1 if ($access{'dirs'} eq '*');
local ($d, $dd);
local @ddirs = !ref($_[0]) ? ( $_[0] ) :
$supports_multiple ? split(/\s+/, $_[0]->{'dir'}) :
( $_[0]->{'dir'} );
foreach $dd (@ddirs) {
local $anyok = 0;
foreach $d (split(/\t+/, $access{'dirs'})) {
$anyok = 1 if (&is_under_directory($d, $dd));
}
return 0 if (!$anyok);
}
return 1;
}
sub create_wrappers
{
&foreign_require("cron", "cron-lib.pl");
&cron::create_wrapper($notape_cmd, $module_name, "notape.pl");
&cron::create_wrapper($newtape_cmd, $module_name, "newtape.pl");
&cron::create_wrapper($multi_cmd, $module_name, "multi.pl");
&cron::create_wrapper($rmulti_cmd, $module_name, "rmulti.pl");
}
# new_header(title)
sub new_header
{
print "</table></td></tr></table><br>\n";
print "<table border width=100%>\n";
print "<tr $tb> <td><b>$_[0]</b></td> </tr>\n";
print "<tr $cb> <td><table width=100%>\n";
}
# dump_directories(&dump)
sub dump_directories
{
if (!&multiple_directory_support($_[0]->{'fs'})) {
return $_[0]->{'dir'};
}
elsif ($_[0]->{'tabs'}) {
return split(/\t+/, $_[0]->{'dir'});
}
else {
return split(/\s+/, $_[0]->{'dir'});
}
}
# run_ssh_command(command, output-fh, output-mode, password)
# Run some command and display it's output, possibly providing a password
# if one is requested
sub run_ssh_command
{
local ($cmd, $fh, $fhmode, $pass) = @_;
&foreign_require("proc", "proc-lib.pl");
local ($cfh, $fpid) = &proc::pty_process_exec_logged($cmd);
local ($wrong_password, $got_login, $connect_failed);
local $out;
local $stars = ("*" x length($pass));
while(1) {
local $rv = &wait_for($cfh, "password:|Password\\s+for\\s+\\S+:", "yes\\/no", "(^|\\n)\\s*Permission denied.*\n", "ssh: connect.*\n", ".*\n");
if ($wait_for_input !~ /^\s*DUMP:\s+ACLs\s+in\s+inode/i) {
$wait_for_input =~ s/\Q$pass\E/$stars/g;
if ($fhmode) {
print $fh &html_escape($wait_for_input);
}
else {
print $fh $wait_for_input;
}
}
if ($rv == 0) {
syswrite($cfh, "$pass\n");
}
elsif ($rv == 1) {
syswrite($cfh, "yes\n");
}
elsif ($rv == 2) {
$wrong_password++;
last;
}
elsif ($rv == 3) {
$connect_failed++;
}
elsif ($rv < 0) {
last;
}
}
close($cfh);
local $got = waitpid($fpid, 0);
return $?;
}
# rsh_command_input(selname, textname, value)
# Returns HTML for selecting an rsh command
sub rsh_command_input
{
local ($selname, $textname, $rsh) = @_;
local $ssh = &has_command("ssh");
local $r = $ssh && $rsh eq $ssh ? 1 :
$rsh eq $ftp_cmd ? 3 :
$rsh ? 2 : 0;
local @opts = ( $r == 0 ? ( [ 0, $text{'dump_rsh0'} ] ) : ( ),
[ 1, $text{'dump_rsh1'} ],
[ 3, $text{'dump_rsh3'} ] );
if ($r == 2) {
push(@opts, [ 2, $text{'dump_rsh2'}." ".
&ui_textbox($textname, $rsh, 30) ]);
}
return &ui_radio($selname, $r, \@opts);
}
# rsh_command_parse(selname, textname)
# Returns the rsh command to use for a backup/restore, based on %in
sub rsh_command_parse
{
local ($selname, $textname) = @_;
if ($in{$selname} == 0) {
return undef;
}
elsif ($in{$selname} == 1) {
local $ssh = &has_command("ssh");
$ssh || &error($text{'dump_essh'});
return $ssh;
}
elsif ($in{$selname} == 3) {
return $ftp_cmd;
}
else {
$in{$textname} =~ /^(\S+)/ && &has_command("$1") ||
&error($text{'dump_ersh'});
return $in{$textname};
}
}
1;
Executable
+200
View File
@@ -0,0 +1,200 @@
#!/usr/local/bin/perl
# Pass data from stdin to an FTP server
$no_acl_check++;
require './fsdump-lib.pl';
sub start_tls
{
my ($fh, $what) = @_;
eval { require IO::Socket::SSL; IO::Socket::SSL->import(); 1; } ||
&error_exit("FTP server requires TLS, but IO::Socket::SSL is not installed");
IO::Socket::SSL->start_SSL($fh, SSL_verify_mode => 0) ||
&error_exit("FTP $what TLS handshake failed : ".
IO::Socket::SSL::errstr());
}
# Parse args, and get password
select(STDERR); $| = 1; select(STDOUT);
$host = $ARGV[0];
$user = $ARGV[2];
if ($ARGV[3] =~ /touch/) {
$touched = 1;
}
$| = 1;
if (defined($ENV{'DUMP_PASSWORD'})) {
$pass = $ENV{'DUMP_PASSWORD'};
}
else {
open(TTY, "+</dev/tty");
print TTY "Password: ";
$pass = <TTY>;
$pass =~ s/\r|\n//g;
close(TTY);
}
# Read rmt protocol messages
while(1) {
$line = <STDIN>;
$line =~ s/\r|\n//g;
if ($line =~ /^O(.*)/) {
# File to open specified .. connect to FTP server
$file = $1;
$perms = <STDIN>;
$perms = int($perms);
&open_socket($host, 21, "SOCK", \$err);
&error_exit("FTP connection failed : $err") if ($err);
&ftp_command("", 2, \$err) ||
&error_exit("FTP prompt failed : $err");
$ssl_enabled = 0;
if (&ftp_command("AUTH TLS", 2, \$err)) {
&start_tls(\*SOCK, "control");
&ftp_command("PBSZ 0", 2, \$err) ||
&error_exit("FTP TLS setup failed : $err");
&ftp_command("PROT P", 2, \$err) ||
&error_exit("FTP TLS setup failed : $err");
$ssl_enabled = 1;
}
# Login to server
@urv = &ftp_command("USER $user", [ 2, 3 ], \$err);
@urv || &error_exit("FTP login failed : $err");
if (int($urv[1]/100) == 3) {
&ftp_command("PASS $pass", 2, \$err) ||
&error_exit("FTP login failed : $err");
}
&ftp_command("TYPE I", 2, \$err) ||
&error_exit("FTP file type failed : $err");
# Work out what we are doing
$mode = 0;
if (($perms & 0100) || ($perms & 01000) ||
(($perms & 01) || ($perms & 02)) && $touched) {
# Writing new file
$mode = 1;
}
elsif ($perms & 02000) {
# Appending to a file
$mode = 2;
}
elsif (!$perms) {
# Reading from file
$mode = 0;
}
else {
&error_exit("Unknown permissions $perms");
}
print "A0\n";
}
elsif ($line =~ /^W(\d+)/) {
# Write to FTP server
$len = $1;
if ($opened != 1) {
&open_ftp_file($mode);
}
#$opened || &error_exit("FTP connection not opened yet");
read(STDIN, $buf, $len);
$wrote = (print CON $buf);
print "A".($wrote ? $len : 0)."\n";
}
elsif ($line =~ /^R(\d+)/) {
# Read from to FTP server
if ($opened != 2) {
&open_ftp_file(0);
}
$len = $1;
$read = read(CON, $buf, $len);
if ($read >= 0) {
print "A".$read."\n";
print $buf;
}
else {
print "E",int($!),"\n";
print "Read failed : $!\n";
}
}
elsif ($line =~ /^C/) {
# Close FTP connection
if ($opened) {
# Finish transfer
close(CON);
&ftp_command("", 2, \$err) ||
&error_exit("FTP close failed : $err");
}
&ftp_command("QUIT", 2, \$err) ||
&error_exit("FTP quit failed : $err");
close(SOCK);
print "A0\n";
$opened = 0;
}
elsif (!$line) {
# All done!
last;
}
else {
print "E1\nUnknown command $line\n";
}
}
sub error_exit
{
local $err = &html_tags_to_text(join("", @_));
print STDERR $err,"\n";
print "E1\n$err\n";
exit(1);
}
sub html_tags_to_text
{
local ($rv) = @_;
$rv =~ s/<tt>|<\/tt>//g;
$rv =~ s/<b>|<\/b>//g;
$rv =~ s/<i>|<\/i>//g;
$rv =~ s/<u>|<\/u>//g;
$rv =~ s/<pre>|<\/pre>//g;
$rv =~ s/<br>/\n/g;
$rv =~ s/<p>/\n\n/g;
return $rv;
}
sub open_ftp_file
{
local ($mode) = @_;
# Open passive port
local $pasv = &ftp_command("PASV", 2, \$err);
$pasv || &error_exit("FTP port failed : $err");
$pasv =~ /\(([0-9,]+)\)/;
local @n = split(/,/ , $1);
&open_socket("$n[0].$n[1].$n[2].$n[3]", $n[4]*256 + $n[5],
CON, \$err) ||
&error_exit("FTP port failed : $err");
if ($mode == 0) {
# Read from file
&ftp_command("RETR $file", 1, \$err) ||
&error_exit("FTP read failed : $err");
$opened = 2;
}
elsif ($mode == 1) {
# Create new file if requested by the client, or if
# the touch command was specified by the caller
&ftp_command("STOR $file", 1, \$err) ||
&error_exit("FTP write failed : $err");
$touched = 0;
$opened = 1;
}
elsif ($mode == 2) {
# Otherwise append to the file
&ftp_command("APPE $file", 1, \$err) ||
&error_exit("FTP write failed : $err");
$opened = 1;
}
else {
$opened = 0;
}
if ($opened && $ssl_enabled) {
&start_tls(\*CON, "data");
}
}
+1
View File
@@ -0,0 +1 @@
<header> الأمر للتشغيل بعد النسخ الاحتياطي </header> سيتم تشغيل أي أمر shell تقوم بإدخاله في هذا الحقل كجذر بعد الانتهاء من النسخ الاحتياطي ، إما يدويًا أو في الموعد المحدد. سيتم تضمين الإخراج من الأمر في تقرير التفريغ. <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Команда за изпълнение след архивиране </header> Всяка команда на черупка, която въведете в това поле, ще се изпълнява като root веднага след приключване на архивирането, ръчно или по график. Резултатът от командата ще бъде включен в отчета за изхвърляне. <p><hr>
+9
View File
@@ -0,0 +1,9 @@
<header>Ordre a executar després de la còpia</header>
Qualsevol ordre shell que introdueixis en aquest camp s'executarà com a
root tot just després que acabi la còpia, ja sigui manualment o de forma
planificada. La sortida de l'ordre s'inclourà en l'informe de còpia. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Příkaz ke spuštění po zálohování </header> Jakýkoli příkaz shellu, který zadáte do tohoto pole, bude spuštěn jako root ihned po dokončení zálohování, buď ručně nebo podle plánu. Výstup z příkazu bude zahrnut do výpisu výpisu. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Kommando, der skal køres efter sikkerhedskopiering </header> Enhver shell-kommando, som du indtaster i dette felt, vil blive kørt som root lige efter, at sikkerhedskopien er færdig, enten manuelt eller i henhold til planen. Output fra kommandoen vil blive inkluderet i dump-rapporten. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>Befehl nach dem Backup ausführen</header>Jeder Shell-Befehl, den Sie in dieses Feld eingeben, wird nach Abschluss des Backups, entweder manuell oder nach Zeitplan, als root ausgeführt. Die Ausgabe des Befehls wird im Dump-Bericht enthalten sein.<p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Εντολή για εκτέλεση μετά τη δημιουργία αντιγράφων ασφαλείας </header> Οποιαδήποτε εντολή κελύφους που εισαγάγετε σε αυτό το πεδίο θα εκτελεστεί ως root μόλις ολοκληρωθεί το αντίγραφο ασφαλείας, είτε χειροκίνητα είτε σύμφωνα με το χρονοδιάγραμμα. Η έξοδος από την εντολή θα συμπεριληφθεί στην αναφορά απόρριψης. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Comando para ejecutar después de la copia de seguridad </header> Cualquier comando de shell que ingrese en este campo se ejecutará como root justo después de que finalice la copia de seguridad, ya sea manualmente o según lo programado. La salida del comando se incluirá en el informe de volcado. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Babeskopia egin ondoren exekutatzeko agindua </header> Eremu horretan sartzen duzun shell komandoa erro gisa erabiliko da segurtasun kopia amaitu ondoren, eskuz edo ordutegian. Komandoaren irteera iraultzeko txostenean sartuko da. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> دستور اجرا پس از تهیه پشتیبان </header> هر دستور پوسته ای که وارد این قسمت شوید ، درست پس از اتمام تهیه نسخه پشتیبان ، به صورت دستی یا با برنامه ، به صورت ریشه اجرا می شود. خروجی از دستور در گزارش dump گنجانده خواهد شد. <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Komento suorittaa varmuuskopion jälkeen </header> Kaikki kenttään komennot, jotka kirjoitat tähän kenttään, ajetaan pääkäyttäjänä heti, kun varmuuskopiointi on valmis, joko manuaalisesti tai aikataulun mukaan. Komennon tulos sisältyy dump-raporttiin. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Commande à exécuter après la sauvegarde </header> Toute commande shell que vous entrez dans ce champ sera exécutée en tant que root juste après la fin de la sauvegarde, soit manuellement, soit selon le calendrier. La sortie de la commande sera incluse dans le rapport de vidage. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Naredba za pokretanje nakon sigurnosne kopije </header> Svaka naredba ljuske koju unesete u ovo polje pokrenut će se kao root odmah po dovršetku sigurnosne kopije, bilo ručno ili po rasporedu. Izlaz iz naredbe bit će uključen u izvještaj deponiranja. <p><hr>
+8
View File
@@ -0,0 +1,8 @@
<header>Command to run after backup</header>
Any shell command that you enter into this field will be run as root just
after the backup is finished, either manually or on schedule. Output from the
command will be included in the dump report. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Parancs biztonsági mentés után futtatni </header> Minden, a mezőbe beírt shell parancs root felhasználóként fut, közvetlenül a biztonsági mentés befejezése után, manuálisan vagy az ütemezés szerint. A parancs eredményei belekerülnek a dump jelentésbe. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Comando da eseguire dopo il backup </header> Qualsiasi comando della shell immesso in questo campo verrà eseguito come root subito dopo il completamento del backup, manualmente o nei tempi previsti. L&#39;output del comando verrà incluso nel rapporto di dump. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>バックアップ後に実行するコマンド</header>このフィールドに入力したシェルコマンドは、手動またはスケジュールに従って、バックアップが完了した直後にrootとして実行されます。コマンドからの出力は、ダンプレポートに含まれます。 <p><hr>
+6
View File
@@ -0,0 +1,6 @@
<header>백업 후 실행할 명령</header>
수동 또는 일정상의 백업작업 종료된 후에 루트 사용자로 실행할 어떤 쉘 명령을 이 필드에 입력하십시오.
명령의 출력은 덤프 리포트에 포함이 되게 됩니다. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Perintah untuk dijalankan selepas sandaran </header> Sebarang arahan shell yang anda masukkan ke dalam bidang ini akan dijalankan sebagai root sejurus cadangan selesai, sama ada secara manual atau mengikut jadual. Hasil dari arahan akan dimasukkan dalam laporan pembuangan. <p><hr>
+8
View File
@@ -0,0 +1,8 @@
<header>Uit te voeren opdracht nadat een backup gemaakt is</header>
Iedere shell opdracht wat u invult in dit veld word uitgevoerd als root nadat
een backup klaar is, of handmatig of in een gepland schema. Het resultaat van
de opdracht zal worden toegevoegd in het rapport. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Kommando som skal kjøres etter sikkerhetskopiering </header> Enhver skallkommando som du angir i dette feltet, vil bli kjørt som root rett etter at sikkerhetskopien er fullført, enten manuelt eller etter planen. Utgang fra kommandoen vil bli inkludert i dump-rapporten. <p><hr>
+8
View File
@@ -0,0 +1,8 @@
<header>Polecenie uruchamiane po wykonaniu kopii zapasowej</header>
Każde wpisane tu polecenie zostanie uruchomione jako root zaraz po
wykonaniu kopii zapasowej. Dane wyjściowe polecenia zostaną dodane
do raportu zrzutu. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Comando para executar após o backup </header> Qualquer comando shell que você digitar nesse campo será executado como root logo após a conclusão do backup, manualmente ou dentro do cronograma. A saída do comando será incluída no relatório de despejo. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Comando para executar após o backup </header> Qualquer comando shell que você digitar nesse campo será executado como root logo após a conclusão do backup, manualmente ou dentro do cronograma. A saída do comando será incluída no relatório de despejo. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Команда для запуска после резервного копирования </header> Любая команда оболочки, которую вы вводите в это поле, будет запускаться от имени пользователя root сразу после завершения резервного копирования, либо вручную, либо по расписанию. Вывод команды будет включен в отчет дампа. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Príkaz na spustenie po zálohovaní </header> Každý príkaz shellu, ktorý zadáte do tohto poľa, sa spustí ako root ihneď po dokončení zálohovania, buď manuálne alebo podľa plánu. Výstup z príkazu bude zahrnutý do výpisu výpisu. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Kommando att köras efter säkerhetskopiering </header> Alla skalkommandon som du anger i det här fältet kommer att köras som root strax efter att säkerhetskopian är klar, antingen manuellt eller enligt schema. Output från kommandot kommer att inkluderas i dumpningsrapporten. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Yedeklemeden sonra çalıştırma komutu </header> Bu alana girdiğiniz herhangi bir kabuk komutu, yedekleme tamamlandıktan hemen sonra manuel olarak veya zamanlanmış olarak kök olarak çalıştırılır. Komutun çıktısı döküm raporuna dahil edilecektir. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Команда для запуску після резервного копіювання </header> Будь-яка команда оболонки, яку ви введете в це поле, буде запускатися як root відразу після завершення резервного копіювання, вручну або за графіком. Виведення з команди буде включено у звіт про скидання. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>备份后运行的命令</header>备份完成后,无论是手动还是按计划,在此字段中输入的任何shell命令都将以root用户身份运行。命令的输出将包含在转储报告中。 <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>備份後運行的命令</header>備份完成後,無論是手動還是按計劃,在此字段中輸入的任何shell命令都將以root用戶身份運行。命令的輸出將包含在轉儲報告中。 <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> هل تريد تضمين سمات الملف؟ </header> عندما يتم تعيين هذا الخيار على نعم ، فإن النسخة الاحتياطية ستتضمن أي مجموعة سمات موسعة للملفات باستخدام الأمر <tt>attr</tt> . <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Включване на файлови атрибути? </header> Когато тази опция е зададена на Да, резервното копие ще включва всички разширени набори от атрибути на файлове с помощта на командата <tt>attr</tt> . <p><hr>
+8
View File
@@ -0,0 +1,8 @@
<header>Inclou els atributs dels fitxers</header>
Quan es posa aquesta opció a Sí, la còpia inclourà qualsevol conjunt
d'atributs estesos dels fitxers que utilitzin l'ordre <tt>attr</tt>. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Zahrnout atributy souboru? </header> Pokud je tato možnost nastavena na Ano, záloha bude zahrnovat všechny sady rozšířených atributů souborů pomocí příkazu <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Inkluder filattributter? </header> Når denne indstilling er indstillet til Ja, inkluderer sikkerhedskopien alle udvidede attributtsæt med filer ved hjælp af kommandoen <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>Dateiattribute einbeziehen?</header>Wenn diese Option auf Ja gesetzt ist, wird das Backup alle erweiterten Attribute von Dateien einschließen, die mit dem Befehl <tt>attr</tt> gesetzt wurden.<p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Συμπερίληψη χαρακτηριστικών αρχείων; </header> Όταν αυτή η επιλογή έχει οριστεί σε Ναι, το αντίγραφο ασφαλείας θα περιλαμβάνει οποιοδήποτε εκτεταμένο σύνολο χαρακτηριστικών αρχείων χρησιμοποιώντας την εντολή <tt>attr</tt> . <p><hr>
+7
View File
@@ -0,0 +1,7 @@
<header>¿ Incluir los atributos de los ficheros ?</header>
Cuando diga Sí a esta opción, la copia de seguridad incluirá los atributos
extendidos (configurados con el comando <tt>attr</tt>) de los ficheros. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Sartu fitxategi atributuak? </header> Aukera hau Bai ezarrita dagoenean, babeskopiak <tt>attr</tt> komandoa erabiliz fitxategi-multzo hedatu guztiak sartuko ditu. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> ویژگی های پرونده را درج می کنید؟ </header> هنگامی که این گزینه روی Yes تنظیم شده است ، نسخه پشتیبان شامل مجموعه ای از ویژگی های توسعه یافته پرونده با استفاده از دستور <tt>جاذبه می شود</tt> . <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Sisällytetäänkö tiedostomääritteet? </header> Kun tämän vaihtoehdon arvo on Kyllä, varmuuskopio sisältää kaikki laajennetut tiedostojoukot, jotka käyttävät <tt>attr-</tt> komentoa. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Inclure les attributs de fichier? </header> Lorsque cette option est définie sur Oui, la sauvegarde comprendra tout ensemble d&#39;attributs étendus de fichiers à l&#39;aide de la commande <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Uključiti atribute datoteka? </header> Kad je ova opcija postavljena na Da, sigurnosna kopija uključuje sve proširene skupove atributa datoteka pomoću naredbe <tt>attr</tt> . <p><hr>
+7
View File
@@ -0,0 +1,7 @@
<header>Include file attributes?</header>
When this option is set to Yes, the backup will include any extended attributes
set of files using the <tt>attr</tt> command. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Fájlatribútumokat tartalmaz? </header> Ha ezt az opciót Igen-re állítja, a biztonsági mentés az <tt>attr</tt> parancs használatával kiterjeszti a fájlok kiterjesztett attribútumait. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Includere gli attributi di file? </header> Quando questa opzione è impostata su Sì, il backup includerà eventuali set di attributi estesi di file utilizzando il comando <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>ファイル属性を含めますか? </header>このオプションを[はい]に設定すると、 <tt>attr</tt>コマンドを使用してファイルの拡張属性セットがバックアップに含まれます。 <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> 파일 속성을 포함 하시겠습니까? </header> 이 옵션을 예로 설정하면 <tt>attr</tt> 명령을 사용하여 확장 속성 파일 세트가 백업에 포함됩니다. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Sertakan atribut fail? </header> Apabila pilihan ini ditetapkan ke Ya, sandaran akan menyertakan set atribut fail yang diperluas menggunakan perintah <tt>attr</tt> . <p><hr>
+7
View File
@@ -0,0 +1,7 @@
<header>File kenmerken toevoegen?</header>
Wanneer deze optie op "Ja" staat zullen de uitgebreide kenmerken van deze file
worden toegevoegd met gebruik van de <tt>attr</tt> opdracht. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Inkluder filattributter? </header> Når dette alternativet er satt til Ja, vil sikkerhetskopien inkludere alle utvidede attributtsett med filer ved å bruke kommandoen <tt>attr</tt> . <p><hr>
+7
View File
@@ -0,0 +1,7 @@
<header>Dołączyć atrybuty pliku?</header>
Gdy ta opcja jest włączona, to kopia zapasowa będzie zawierała rozszerzone
atrybuty ustawione przez polecenie <tt>attr</tt>. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Incluir atributos de arquivo? </header> Quando esta opção está definida como Sim, o backup incluirá qualquer conjunto de atributos estendidos de arquivos usando o comando <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Incluir atributos de arquivo? </header> Quando esta opção está definida como Sim, o backup incluirá qualquer conjunto de atributos estendidos de arquivos usando o comando <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Включить атрибуты файла? </header> Если для этого параметра установлено значение «Да», резервное копирование будет включать в себя любой расширенный набор атрибутов файлов с помощью команды <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Zahrnúť atribúty súboru? </header> Ak je táto voľba nastavená na Áno, záloha bude obsahovať všetky súbory rozšírených atribútov pomocou príkazu <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Inkludera filattribut? </header> När detta alternativ är inställt på Ja, kommer säkerhetskopian att inkludera alla utvidgade attributuppsättningar med filer med kommandot <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Dosya öznitelikleri dahil edilsin mi? </header> Bu seçenek Evet olarak ayarlandığında, yedekleme <tt>attr</tt> komutunu kullanarak dosya kümesinin genişletilmiş özniteliklerini içerir. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Включити атрибути файлів? </header> Якщо для цього параметра встановлено значення Так, резервна копія буде включати будь-який розширений набір файлів атрибутів за допомогою команди <tt>attr</tt> . <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>包括文件属性? </header>当此选项设置为“是”时,备份将使用<tt>attr</tt>命令包括文件的所有扩展属性集。 <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>包括文件屬性? </header>當此選項設置為“是”時,備份將使用<tt>attr</tt>命令包括文件的所有擴展屬性集。 <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> تخزين البيانات المضغوطة في كتل؟ </header> عند تمكينه ، يتسبب هذا الخيار في تخزين البيانات المضغوطة مؤقتًا في كتل بحيث يمكن كتابتها إلى محرك أقراص بشكل أكثر كفاءة. <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Буфер компресирани данни в блокове? </header> Когато е активирана, тази опция кара компресираните данни да бъдат буферирани в блокове, така че да могат да бъдат записани на касетофон по-ефективно. <p><hr>
+8
View File
@@ -0,0 +1,8 @@
<header>Posa les dades comprimides en blocs</header>
Quan s'activa aquesta opció provoca que les dades comprimides es posin
en blocs en un buffer, de manera que es gravin a una unitat de cinta de
forma més eficient. <p>
<hr>
+1
View File
@@ -0,0 +1 @@
<header> Ukládat komprimovaná data do bloků? </header> Pokud je tato možnost povolena, způsobí to, že komprimovaná data budou uložena do vyrovnávací paměti do bloků, aby bylo možné je zapisovat na páskovou jednotku efektivněji. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Buffer komprimerede data i blokke? </header> Når dette er aktiveret, får denne mulighed til, at komprimerede data buffres i blokke, så de kan skrives til et bånddrev mere effektivt. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header>Komprimierte Daten in Blöcke puffern?</header>Wenn aktiviert, bewirkt diese Option, dass komprimierte Daten in Blöcke gepuffert werden, sodass sie effizienter auf ein Bandlaufwerk geschrieben werden können.<p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Αποθήκευση συμπιεσμένων δεδομένων σε μπλοκ; </header> Όταν είναι ενεργοποιημένη, αυτή η επιλογή αναγκάζει τα συμπιεσμένα δεδομένα να αποθηκευτούν σε μπλοκ ώστε να μπορούν να γραφτούν σε μια μονάδα δίσκου πιο αποτελεσματικά. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> ¿Almacenar datos comprimidos en bloques? </header> Cuando está habilitada, esta opción hace que los datos comprimidos se almacenen en bloques para que puedan escribirse en una unidad de cinta de manera más eficiente. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> Bufferreko datuak konprimitu bloketan? </header> Gaituta dagoenean, konprimitutako datuak blokeetan bufferizatzea eragiten du, zinta unitatean modu eraginkorrago batean idatz dadin. <p><hr>
+1
View File
@@ -0,0 +1 @@
<header> بافر فشرده سازی داده ها را در بلوک؟ </header> در صورت فعال بودن ، این گزینه باعث می شود تا داده های فشرده شده در بلوک ها قرار گیرند تا بتوان با نوشتن آن به نوار درایو کارآمدتر شد. <p style=";text-align:right;direction:rtl"><hr>
+1
View File
@@ -0,0 +1 @@
<header> Puskuri pakatut tiedot lohkoiksi? </header> Kun tämä asetus on käytössä, tämä pakattu tieto puskuroidaan lohkoiksi, jotta se voidaan kirjoittaa nauha-asemaan tehokkaammin. <p><hr>

Some files were not shown because too many files have changed in this diff Show More