From 16755c17628b28a58d75663d7541036344826961 Mon Sep 17 00:00:00 2001
From: cbarratt
+
+
+\${h2("éè¦å
³æ³¨çé误")}
+
+
+ä½ æ³ç°å¨å¯å¨å®åï¼
+
+
+
+EOF
+
+# -----
+
+$Lang{H_BackupPC_Server_Status} = "BackupPC æå¡å¨ç¶æ";
+
+$Lang{BackupPC_Server_Status_General_Info}= <
+
+
+EOF
+
+$Lang{BackupPC_Server_Status} = <
+
+
+\$jobStr
+ 客æ·æº
+ ç±»å
+ ç¨æ·
+ å¼å§æ¶é´
+ å½ä»¤
+ è¿ç¨å·
+ ä¼ è¾è¿ç¨å·
+
+
+EOF
+
+# --------------------------------
+$Lang{BackupPC__Server_Summary} = "BackupPC: 客æ·æºæ¥å";
+$Lang{BackupPC__Archive} = "BackupPC: å¤æ¡£";
+$Lang{BackupPC_Summary} = <
+\$statusStr
+ 客æ·æº
+ ç±»å
+ ç¨æ·
+ æåä¸æ¬¡å°è¯
+ 详æ
+ é误æ¶é´
+ æåä¸æ¬¡éè¯¯ï¼ PING 失败é¤å¤ï¼
+æ \$hostCntGood å°å®¢æ·æºå·²å®æå¤ä»½ï¼æ»æ°æ¯ï¼ +
客æ·æº | +ç¨æ· | +å®å ¨å¤ä»½ä¸ªæ° | +æåä¸æ¬¡å®å ¨å¤ä»½ (天å) | +å®å ¨å¤ä»½å¤§å° (GB) | +å®å ¨å¤ä»½é度 (MB/s) | +å¢éå¤ä»½ä¸ªæ° | +æåä¸æ¬¡å¢éå¤ä»½ (天å) | +æåä¸æ¬¡å¤ä»½ (天å) | +å½åç¶æ | +æåä¸æ¬¡å¤ä»½ç»æ |
+æ \$hostCntNone å°å®¢æ·æºä»æªè¢«å¤ä»½è¿ã +
+
客æ·æº | +ç¨æ· | +å®å ¨å¤ä»½ä¸ªæ° | +æåä¸æ¬¡å®å ¨å¤ä»½ (天å) | +å®å ¨å¤ä»½å¤§å° (GB) | +å®å ¨å¤ä»½é度 (MB/s) | +å¢éå¤ä»½ä¸ªæ° | +æåä¸æ¬¡å¢éå¤ä»½ (天å) | +æåä¸æ¬¡å¤ä»½ (天å) | +å½åç¶æ | +æåä¸æ¬¡å¤ä»½ç»æ |
+
+
+
+EOF
+
+$Lang{BackupPC_Archive2} = <
+ç¹å»å¤ä»½åºåå·æµè§åæ¢å¤æ件ã +
+å¤ä»½åºåå·ï¼ | +ç±»å | +å®æ´ | +å¤ä»½çº§å« | +å¼å§æ¶é´ | +èæ¶ï¼åéï¼ | +è·ç¦»ç°å¨ï¼å¤©åï¼ | +æå¡å¨ä¸å¤ä»½è·¯å¾ | +
+ +\$restoreStr +
+å¤ä»½åºåå·ï¼ | +ç±»å | +æ¥ç | +ä¼ è¾é误æ°ç® | +æåæ件æ°ç® | +æåæ件系ç»å·æ°ç® | +æå Tar æ件æ°ç® | +
+"åææ件"æ¯æåå å·²åå¨å¤ä»½æ± ä¸çæ件ï¼"æ°å¢æ件"æ¯æå¤ä»½æ°åå ¥æ± ä¸çæ件ã +空æ件ä¸è¢«ç»è®¡å¨å ã +
++ | å计 | +åææ件 | +æ°å¢æ件 | +|||||
å¤ä»½åºåå·ï¼ | +ç±»å | +æ件æ°ç® | +大å°(MB) | +å¤ä»½é度(MB/sec) | +æ件æ°ç® | +大å°(MB) | +æ件æ°ç® | +大å°(MB) | +
+å¤ä»½æ± ä¸åææ件åæ°å¢æ件çå缩æ§è½æ¥åã +
++ | åææ件 | +æ°å¢æ件 | +||||||
å¤ä»½åºåå·ï¼ | +ç±»å | +åç¼©çº§å« | +å缩å(MB) | +å缩å(MB) | +åç¼©æ¯ | +å缩å(MB) | +å缩å(MB) | +åç¼©æ¯ | +
+
+ | + |
+ + |
å¤ä»½åºåå· | \$backupNumStr
å¤ä»½æ¶é´ | \$backupTimeStr
æ¢å¤åºåå· | \$Restores[\$i]{num} |
请æ±æ¹ | \$RestoreReq{user} |
请æ±æ¶é´ | \$reqTime |
ç»æ | \$Restores[\$i]{result} |
éè¯¯ä¿¡æ¯ | \$Restores[\$i]{errorMsg} |
æºå®¢æ·æº | \$RestoreReq{hostSrc} |
æºå¤ä»½åºåå· | \$RestoreReq{num} |
æºæä»¶å· | \$RestoreReq{shareSrc} |
ç®ç客æ·æº | \$RestoreReq{hostDest} |
ç®çæä»¶å· | \$RestoreReq{shareDest} |
æ¢å¤å¼å§æ¶é´ | \$startTime |
èæ¶ | \$duration åé |
æä»¶ä¸ªæ° | \$Restores[\$i]{nFiles} |
æ件æ»å¤§å° | \${MB} MB |
ä¼ è¾éç | \$MBperSec MB/sec |
Tar çæè¿ç¨éè¯¯ä¸ªæ° | \$Restores[\$i]{tarCreateErrs} |
ä¼ è¾è¿ç¨éè¯¯ä¸ªæ° | \$Restores[\$i]{xferErrs} |
ä¼ è¾æ¥å¿æ件 | +æ¥çæ¥å¿, +æ¥çé误 + |
+
åå§æ件ï¼ç®å½ | æ¢å¤è³ |
å¤æ¡£åºåå· | \$Archives[\$i]{num} |
请æ±æ¹ | \$ArchiveReq{user} |
请æ±æ¹ | \$reqTime |
ç»æ | \$Archives[\$i]{result} |
éè¯¯ä¿¡æ¯ | \$Archives[\$i]{errorMsg} |
å¼å§æ¶é´ | \$startTime |
èæ¶ | \$duration åé |
ä¼ è¾æ¥å¿æ件 | +æ¥çæ¥å¿, +æ¥çé误 + |
+\${h1("客æ·æºå表")} +
+
客æ·æº | å¤ä»½åºåå· |
æ¢å¤åºåå· | +ç»æ | +å¼å§æ¶é´ | +èæ¶ï¼åéï¼ | +æä»¶ä¸ªæ° | +大å°(MB) | +Tar éè¯¯ä¸ªæ° | +ä¼ è¾éè¯¯ä¸ªæ° | +
+EOF
+
+$Lang{Archive_Summary} = <
+EOF
+
+$Lang{BackupPC__Documentation} = "BackupPC: ææ¡£èµæ";
+
+$Lang{No} = "å¦";
+$Lang{Yes} = "æ¯";
+
+$Lang{The_directory_is_empty} = <
+EOF
+
+$Lang{CfgEdit_Button_Save} = "ä¿å";
+$Lang{CfgEdit_Button_Insert} = "æå
¥";
+$Lang{CfgEdit_Button_Delete} = "å é¤";
+$Lang{CfgEdit_Button_Add} = "æ·»å ";
+$Lang{CfgEdit_Button_Override} = "æ¿æ¢";
+$Lang{CfgEdit_Button_New_Key} = "æ件å·å(Windows Share)";
+
+$Lang{CfgEdit_Error_No_Save}
+ = "é误ï¼æ误ï¼æ æ³ä¿å";
+$Lang{CfgEdit_Error__must_be_an_integer}
+ = "é误ï¼\$var å¿
é¡»æ¯æ´æ°";
+$Lang{CfgEdit_Error__must_be_real_valued_number}
+ = "é误ï¼\$var å¿
é¡»æ¯å®æ°ï¼ä¸è½æ¯æµ®ç¹æ°";
+$Lang{CfgEdit_Error__entry__must_be_an_integer}
+ = "é误ï¼\$var å
容 \$k å¿
é¡»æ¯æ´æ°";
+$Lang{CfgEdit_Error__entry__must_be_real_valued_number}
+ = "é误ï¼\$var å
容 \$k å¿
é¡»æ¯å®æ°ï¼ä¸è½æ¯æµ®ç¹æ°";
+$Lang{CfgEdit_Error__must_be_executable_program}
+ = "é误ï¼\$var å¿
é¡»æ¯å¯æ§è¡ç¨åº";
+$Lang{CfgEdit_Error__must_be_valid_option}
+ = "é误ï¼\$var å¿
é¡»æ¯åæ³é项";
+$Lang{CfgEdit_Error_Copy_host_does_not_exist}
+ = "客æ·æº \$copyHost ä¸åå¨ï¼çæå
¨è®¡ç®æºå \$fullHostãå¦ææ¤å®¢æ·æºä¸æ¯ä½ æ³è¦çï¼è¯·å°å®å é¤ã";
+
+$Lang{CfgEdit_Log_Copy_host_config}
+ = "ç¨æ· \$User æ·è´äºå®¢æ·æº \$fromHost çé
ç½®å°å®¢æ·æº \$host\n";
+$Lang{CfgEdit_Log_Delete_param}
+ = "ç¨æ· \$User ä»é
ç½® \$conf ä¸å é¤äº \$p\n";
+$Lang{CfgEdit_Log_Add_param_value}
+ = "ç¨æ· \$User æ·»å äº \$p å°é
ç½® \$conf ä¸ï¼å¼è®¾ä¸º \$value\n";
+$Lang{CfgEdit_Log_Change_param_value}
+ = "ç¨æ· \$User å°é
ç½® \$conf ä¸ç \$p ä» \$valueOld æ´æ¹ä¸º \$valueNew\n";
+$Lang{CfgEdit_Log_Host_Delete}
+ = "ç¨æ· \$User å é¤äºå®¢æ·æº \$host\n";
+$Lang{CfgEdit_Log_Host_Change}
+ = "ç¨æ· \$User å°å®¢æ·æº \$host ä¸ç \$key ä» \$valueOld æ´æ¹ä¸º \$valueNew\n";
+$Lang{CfgEdit_Log_Host_Add}
+ = "ç¨æ· \$User æ·»å äºå®¢æ·æº \$host: \$value\n";
+
+#end of lang_zh_CN.pm
diff --git a/lib/BackupPC/Lib.pm b/lib/BackupPC/Lib.pm
index 44de3c5..e1dda82 100644
--- a/lib/BackupPC/Lib.pm
+++ b/lib/BackupPC/Lib.pm
@@ -49,6 +49,7 @@ use Socket;
use Cwd;
use Digest::MD5;
use Config;
+use Encode;
use vars qw( $IODirentOk );
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
@@ -451,6 +452,10 @@ sub HostsMTime
# $need is a hash of file attributes we need: type, inode, or nlink.
# If set, these parameters are added to the returned hash.
#
+# To support browsing pre-3.0.0 backups where the charset encoding
+# is typically iso-8859-1, the charsetLegacy option can be set in
+# $need to convert the path from utf8 and convert the names to utf8.
+#
# If IO::Dirent is successful if will get type and inode for free.
# Otherwise, a stat is done on each file, which is more expensive.
#
@@ -459,6 +464,8 @@ sub dirRead
my($bpc, $path, $need) = @_;
my(@entries, $addInode);
+ from_to($path, "utf8", $need->{charsetLegacy})
+ if ( $need->{charsetLegacy} ne "" );
return if ( !opendir(my $fh, $path) );
if ( $IODirentOk ) {
@entries = sort({ $a->{inode} <=> $b->{inode} } readdirent($fh));
@@ -495,6 +502,14 @@ sub dirRead
# sorted above)
#
@entries = sort({ $a->{inode} <=> $b->{inode} } @entries) if ( $addInode );
+ #
+ # for browing pre-3.0.0 backups, map iso-8859-1 to utf8 if requested
+ #
+ if ( $need->{charsetLegacy} ne "" ) {
+ for ( my $i = 0 ; $i < @entries ; $i++ ) {
+ from_to($entries[$i]{name}, $need->{charsetLegacy}, "utf8");
+ }
+ }
return \@entries;
}
@@ -504,9 +519,9 @@ sub dirRead
#
sub dirReadNames
{
- my($bpc, $path) = @_;
+ my($bpc, $path, $need) = @_;
- my $entries = $bpc->dirRead($path);
+ my $entries = $bpc->dirRead($path, $need);
return if ( !defined($entries) );
my @names = map { $_->{name} } @$entries;
return \@names;
@@ -711,7 +726,10 @@ sub ServerMesg
{
my($bpc, $mesg) = @_;
return if ( !defined(my $fh = $bpc->{ServerFD}) );
+ $mesg =~ s/\n/\\n/g;
+ $mesg =~ s/\r/\\r/g;
my $md5 = Digest::MD5->new;
+ $mesg = encode_utf8($mesg);
$md5->add($bpc->{ServerSeed} . $bpc->{ServerMesgCnt}
. $bpc->{Conf}{ServerMesgSecret} . $mesg);
print($fh $md5->b64digest . " $mesg\n");
diff --git a/lib/BackupPC/Storage.pm b/lib/BackupPC/Storage.pm
index e54802b..0f7a43e 100644
--- a/lib/BackupPC/Storage.pm
+++ b/lib/BackupPC/Storage.pm
@@ -52,7 +52,7 @@ sub new
xferErrs xferBadFile xferBadShare tarErrs
compress sizeExistComp sizeNewComp
noFill fillFromNum mangle xferMethod level
- charset
+ charset version
)],
RestoreFields => [qw(
num startTime endTime result errorMsg nFiles size
diff --git a/lib/BackupPC/Storage/Text.pm b/lib/BackupPC/Storage/Text.pm
index 4dea60e..b99648d 100644
--- a/lib/BackupPC/Storage/Text.pm
+++ b/lib/BackupPC/Storage/Text.pm
@@ -84,6 +84,19 @@ sub BackupInfoRead
close(BK_INFO);
}
close(LOCK);
+ #
+ # Default the level and version fields if not present
+ #
+ for ( my $i = 0 ; $i < @Backups ; $i++ ) {
+ if ( defined($Backups[$i]{level}) ) {
+ if ( !defined($Backups[$i]{version}) ) {
+ $Backups[$i]{version} = "3.0.0";
+ }
+ } else {
+ $Backups[$i]{level} = $Backups[$i]{type} eq "incr" ? 1 : 0;
+ $Backups[$i]{version} = "2.1.2";
+ }
+ }
return @Backups;
}
@@ -279,6 +292,7 @@ sub ConfigDataRead
}
%$conf = ( %$conf, %Conf );
}
+
#
# Promote BackupFilesOnly and BackupFilesExclude to hashes
#
@@ -306,6 +320,11 @@ sub ConfigDataRead
delete($conf->{BlackoutWeekDays});
}
+ #
+ # Make sure IncrLevels is defined
+ #
+ $conf->{IncrLevels} = [1] if ( !defined($conf->{IncrLevels}) );
+
return (undef, $conf);
}
diff --git a/lib/BackupPC/View.pm b/lib/BackupPC/View.pm
index cf03983..64d5abe 100644
--- a/lib/BackupPC/View.pm
+++ b/lib/BackupPC/View.pm
@@ -64,10 +64,6 @@ sub new
# are added to the returned hash.
# See BackupPC::Lib::dirRead().
}, $class;
- for ( my $i = 0 ; $i < @{$m->{backups}} ; $i++ ) {
- next if ( defined($m->{backups}[$i]{level}) );
- $m->{backups}[$i]{level} = $m->{backups}[$i]{type} eq "incr" ? 1 : 0;
- }
$m->{topDir} = $m->{bpc}->TopDir();
return $m;
}
@@ -138,7 +134,7 @@ sub dirCache
my $attr;
if ( $mangle ) {
$attr = BackupPC::Attrib->new({ compress => $compress });
- if ( -f $attr->fileName($path) && !$attr->read($path) ) {
+ if ( !$attr->read($path) ) {
$m->{error} = "Can't read attribute file in $path";
$attr = undef;
}
@@ -402,7 +398,7 @@ sub dirHistory
my $attr;
if ( $mangle ) {
$attr = BackupPC::Attrib->new({ compress => $compress });
- if ( -f $attr->fileName($path) && !$attr->read($path) ) {
+ if ( !$attr->read($path) ) {
$m->{error} = "Can't read attribute file in $path";
$attr = undef;
}
diff --git a/lib/BackupPC/Xfer/RsyncFileIO.pm b/lib/BackupPC/Xfer/RsyncFileIO.pm
index 044ee55..221fd3f 100644
--- a/lib/BackupPC/Xfer/RsyncFileIO.pm
+++ b/lib/BackupPC/Xfer/RsyncFileIO.pm
@@ -436,6 +436,8 @@ sub attribSet
my($fio, $f, $placeHolder) = @_;
my($dir, $file);
+ return if ( $placeHolder && $fio->{phase} > 0 );
+
if ( $f->{name} =~ m{(.*)/(.*)}s ) {
$file = $2;
$dir = "$fio->{shareM}/" . $1;
@@ -447,10 +449,13 @@ sub attribSet
$file = $f->{name};
}
- if ( !defined($fio->{attribLastDir}) || $fio->{attribLastDir} ne $dir ) {
+ if ( $dir ne ""
+ && (!defined($fio->{attribLastDir}) || $fio->{attribLastDir} ne $dir) ) {
#
# Flush any directories that don't match the first part
- # of the new directory
+ # of the new directory. Don't flush the top-level directory
+ # (ie: $dir eq "") since the "." might get sorted in the middle
+ # of other top-level directories or files.
#
foreach my $d ( keys(%{$fio->{attrib}}) ) {
next if ( $d eq "" || "$dir/" =~ m{^\Q$d/} );
@@ -459,17 +464,29 @@ sub attribSet
$fio->{attribLastDir} = $dir;
}
if ( !exists($fio->{attrib}{$dir}) ) {
+ $fio->log("attribSet: dir=$dir not found") if ( $fio->{logLevel} >= 4 );
$fio->{attrib}{$dir} = BackupPC::Attrib->new({
compress => $fio->{xfer}{compress},
});
- my $path = $fio->{outDir} . $dir;
- if ( -f $fio->{attrib}{$dir}->fileName($path)
- && !$fio->{attrib}{$dir}->read($path) ) {
- $fio->log(sprintf("Unable to read attribute file %s",
+ my $dirM = $dir;
+ $dirM = $1 . "/" . $fio->{bpc}->fileNameMangle($2)
+ if ( $dirM =~ m{(.*?)/(.*)}s );
+ my $path = $fio->{outDir} . $dirM;
+ if ( -f $fio->{attrib}{$dir}->fileName($path) ) {
+ if ( !$fio->{attrib}{$dir}->read($path) ) {
+ $fio->log(sprintf("Unable to read attribute file %s",
$fio->{attrib}{$dir}->fileName($path)));
+ } else {
+ $fio->log(sprintf("attribRead file %s",
+ $fio->{attrib}{$dir}->fileName($path)))
+ if ( $fio->{logLevel} >= 4 );
+ }
}
+ } else {
+ $fio->log("attribSet: dir=$dir exists") if ( $fio->{logLevel} >= 4 );
}
- $fio->log("attribSet(dir=$dir, file=$file)") if ( $fio->{logLevel} >= 4 );
+ $fio->log("attribSet(dir=$dir, file=$file, size=$f->{size}, placeholder=$placeHolder)")
+ if ( $fio->{logLevel} >= 4 );
my $mode = $f->{mode};
@@ -490,11 +507,6 @@ sub attribWrite
my($fio, $d) = @_;
my($poolWrite);
- #
- # Don't write attributes on 2nd phase - they're already
- # taken care of during the first phase.
- #
- return if ( $fio->{phase} > 0 );
if ( !defined($d) ) {
#
# flush all entries (in reverse order)
@@ -505,6 +517,7 @@ sub attribWrite
return;
}
return if ( !defined($fio->{attrib}{$d}) );
+
#
# Set deleted files in the attributes. Any file in the view
# that doesn't have attributes is flagged as deleted for
@@ -541,7 +554,7 @@ sub attribWrite
}) if ( $fio->{logLevel} >= 2
&& $a->{type} == BPC_FTYPE_FILE );
}
- } elsif ( !$fio->{full} ) {
+ } elsif ( $fio->{phase} == 0 && !$fio->{full} ) {
##print("Delete file $f\n");
$fio->logFileAction("delete", {
%{$fio->{viewCache}{$d}{$f}},
@@ -559,7 +572,7 @@ sub attribWrite
}
}
}
- if ( $fio->{attrib}{$d}->fileCount ) {
+ if ( $fio->{attrib}{$d}->fileCount || $fio->{phase} > 0 ) {
my $data = $fio->{attrib}{$d}->writeData;
my $dirM = $d;
diff --git a/makeDist b/makeDist
index ad21c6f..506fb5d 100755
--- a/makeDist
+++ b/makeDist
@@ -292,6 +292,8 @@ sub InstallFile
print OUT "$1'__TOPDIR__'$2\n";
} elsif ( $file =~ /Lib.pm/ && /^(\s*\$installDir\s*=\s*)'.*'(\s*if\s.*)/ ) {
print OUT "$1'__INSTALLDIR__'$2\n";
+ } elsif ( $file =~ /Lib.pm/ && /^(\s*ConfDir\s*=\>\s*\$confDir eq.*)'.*'(.*)/ ) {
+ print OUT "$1'__CONFDIR__'$2\n";
} elsif ( $file =~ /Lib.pm/ && /^(\s*my \$useFHS\s*=\s*)\d;/ ) {
print OUT "${1}0;\n";
} elsif ( $file =~ /Lib.pm/ && /(.*Version *=> .*)'[\w\d\.]+',/ ) {
--
2.20.1
+
+
+\$ArchiveStr
+ å¤æ¡£åºåå·
+ ç»æ
+ å¼å§æ¶é´
+ èæ¶ï¼åéï¼
+ç®å½ \${EscHTML(\$dirDisplay)} æ¯ç©ºç®å½
+
+EOF
+
+#$Lang{on} = "å¼";
+$Lang{off} = "å
³";
+
+$Lang{backupType_full} = "å®å
¨";
+$Lang{backupType_incr} = "å¢é";
+$Lang{backupType_partial} = "é¨å";
+
+$Lang{failed} = "失败";
+$Lang{success} = "æå";
+$Lang{and} = "å";
+
+# ------
+# Hosts states and reasons
+$Lang{Status_idle} = "空é²";
+$Lang{Status_backup_starting} = "å¤ä»½å·²å¼å§";
+$Lang{Status_backup_in_progress} = "å¤ä»½è¿è¡ä¸";
+$Lang{Status_restore_starting} = "æ¢å¤å·²å¼å§";
+$Lang{Status_restore_in_progress} = "æ¢å¤è¿è¡ä¸";
+$Lang{Status_link_pending} = "æ件é¾æ¥å¾
建ç«";
+$Lang{Status_link_running} = "æ件é¾æ¥å»ºç«ä¸";
+
+$Lang{Reason_backup_done} = "å®æ";
+$Lang{Reason_restore_done} = "æ¢å¤å®æ";
+$Lang{Reason_archive_done} = "å¤æ¡£å®æ";
+$Lang{Reason_nothing_to_do} = "空é²";
+$Lang{Reason_backup_failed} = "å¤ä»½å¤±è´¥";
+$Lang{Reason_restore_failed} = "æ¢å¤å¤±è´¥";
+$Lang{Reason_archive_failed} = "å¤æ¡£å¤±è´¥";
+$Lang{Reason_no_ping} = "ç½ç»è¿æ¥ä¸æ(no ping)";
+$Lang{Reason_backup_canceled_by_user} = "å¤ä»½è¢«ç¨æ·åæ¶";
+$Lang{Reason_restore_canceled_by_user} = "æ¢å¤è¢«ç¨æ·åæ¶";
+$Lang{Reason_archive_canceled_by_user} = "å¤æ¡£è¢«ç¨æ·åæ¶";
+$Lang{Disabled_OnlyManualBackups} = "èªå¨å¤ä»½è¢«å
³é";
+$Lang{Disabled_AllBackupsDisabled} = "å
³é";
+
+
+# ---------
+# Email messages
+
+# No backup ever
+$Lang{EMailNoBackupEverSubj} = "BackupPC: 客æ·æº \$host ä»æªè¢«æåå¤ä»½è¿";
+$Lang{EMailNoBackupEverMesg} = <<'EOF';
+To: $user$domain
+cc:
+Subject: $subj
+$headers
+å°æ¬çç¨æ· $userName,
+
+æ¨ççµè ($host) è¿ä»æ¥æ²¡æ被æ们çå¤ä»½ç³»ç»æåå¤ä»½è¿ã
+æ£å¸¸æ
åµä¸ï¼å½æ¨ççµèä¸ç½ç»è¿æ¥æ¶çµèå¤ä»½ä¼èªå¨è¿è¡ã
+å¦ææ¨å±äºä¸é¢ä¸¤ç§æ
åµï¼è¯·ä¸ç³»ç»ç®¡çåèç³»ï¼
+
+ ï¼ æ¨ççµèç»å¸¸æ¯è¿å¨ç½ç»ä¸çãè¿æå³çå¯è½æ¯æäºé
ç½®
+ æ¹é¢çé®é¢å¯¼è´å¤ä»½æ æ³è¿è¡ã
+
+ ï¼ æ¨ä¸å¸ææ¨ççµè被å¤ä»½ï¼å¹¶ä¸ä¸æ¿åæ¶å°è¿äºçµåé®ä»¶ã
+
+å¦æä¸æ¯ä»¥ä¸è¿äºæ
åµï¼è¯·ç¡®è®¤æ¨ççµèæ¯è¢«è¿æ¥å¨ç½ç»ä¸çã
+
+æ¤è´æ¬ç¤¼ï¼
+
+BackupPC Genie
+http://backuppc.sourceforge.net
+EOF
+
+# No recent backup
+$Lang{EMailNoBackupRecentSubj} = "BackupPC: 客æ·æº \$host æè¿æªè¢«å¤ä»½è¿";
+$Lang{EMailNoBackupRecentMesg} = <<'EOF';
+To: $user$domain
+cc:
+Subject: $subj
+$headers
+å°æ¬çç¨æ· $userName,
+
+æ¨ççµè ($host) å·²ç»æ $days 天没æ被æåå¤ä»½è¿äºãæ¨ççµè
+第ä¸æ¬¡è¢«å¤ä»½æ¯å¨ $firstTime 天åï¼ç´è³ $days 天åå·²ç»è¢«å¤ä»½è¿ $numBackups 次ã
+æ£å¸¸æ
åµä¸ï¼å½æ¨ççµèä¸ç½ç»è¿æ¥æ¶çµèå¤ä»½ä¼èªå¨è¿è¡ã
+
+å¨æè¿ $days 天å
ï¼å¦ææ¨ççµèå·²ç»ä¸ç½ç»è¿æ¥äºè¥å¹²å°æ¶ï¼
+请ä¸ç³»ç»ç®¡çåè系以å¤æ为ä»ä¹å¤ä»½æ²¡æè¿è¡ã
+
+é¤æ¤ä¹å¤ï¼å¦ææ¨ä¸å¨åå
¬å®¤ï¼æ¨åªè½æå¨æ·è´éè¦æ件å°å
¶å®åå¨ä»è´¨ä¸ã
+åºè¯¥æéæ¨çæ¯ï¼å¦ææ¨ççµèç£çæåï¼æ¨å¨æè¿ $days 天å
å建æä¿®æ¹
+çæ件ï¼å
æ¬æ°æ¶å°ççµåé®ä»¶åé件ï¼å°æ æ³è¢«æ¢å¤ã
+
+æ¤è´æ¬ç¤¼ï¼
+
+BackupPC Genie
+http://backuppc.sourceforge.net
+EOF
+
+# Old Outlook files
+$Lang{EMailOutlookBackupSubj} = "BackupPC: 客æ·æº \$host ä¸ç微软 Outlook æ件éè¦å¤ä»½";
+$Lang{EMailOutlookBackupMesg} = <<'EOF';
+To: $user$domain
+cc:
+Subject: $subj
+$headers
+å°æ¬çç¨æ· $userName,
+
+æ¨ççµèä¸ç Outlook æ件 $howLongã
+
+è¿äºæ件å
æ¬æææ¨ççµåé®ä»¶ï¼é件ï¼é讯å½åæ¥ç¨è¡¨ä¿¡æ¯ã
+æ¨ççµè第ä¸æ¬¡è¢«å¤ä»½æ¯å¨ $firstTime 天åï¼ç´è³ $lastTime 天åå·²ç»è¢«
+å¤ä»½è¿ $numBackups 次ãä½æ¯ï¼Outlook å¨è¿è¡æ¶éä½æææå±æ件ï¼
+导è´è¿äºæ件æ æ³è¢«å¤ä»½ã
+
+建议æ¨ä¾ä»¥ä¸æ¹å¼å¤ä»½ Outlook æ件ï¼
+
+1ãé¦å
确认çµèæ¯è¿æ¥å¨ç½è·¯ä¸ï¼
+2ãéåº Outlook åææå
¶å®åºç¨ï¼
+3ã使ç¨ç½é¡µæµè§å¨è®¿é®æ¤é¾æ¥ï¼
+
+ $CgiURL?host=$host
+
+éæ© âå¼å§å¢éå¤ä»½âï¼å¯å¨å¢éå¤ä»½æä½ï¼ç¶åéæ© âè¿å $host 主页â
+并ç¨æµè§å¨ç âå·æ°â åè½æ¥æ£æ¥è¯¥å¤ä»½æä½çç¶æã
+
+æ¤è´æ¬ç¤¼ï¼
+
+BackupPC Genie
+http://backuppc.sourceforge.net
+EOF
+
+$Lang{howLong_not_been_backed_up} = "è¿ä»æªè¢«æåå¤ä»½è¿";
+$Lang{howLong_not_been_backed_up_for_days_days} = "å·²ç»æ \$days 天æªè¢«å¤ä»½è¿";
+
+#######################################################################
+# RSS strings
+#######################################################################
+$Lang{RSS_Doc_Title} = "BackupPC æå¡å¨";
+$Lang{RSS_Doc_Description} = "RSS feed for BackupPC";
+$Lang{RSS_Host_Summary} = <