1 |
#============================================================= -*-perl-*- |
2 |
# |
3 |
# BackupPC::CGI::View package |
4 |
# |
5 |
# DESCRIPTION |
6 |
# |
7 |
# This module implements the View action for the CGI interface. |
8 |
# |
9 |
# AUTHOR |
10 |
# Craig Barratt <cbarratt@users.sourceforge.net> |
11 |
# |
12 |
# COPYRIGHT |
13 |
# Copyright (C) 2003 Craig Barratt |
14 |
# |
15 |
# This program is free software; you can redistribute it and/or modify |
16 |
# it under the terms of the GNU General Public License as published by |
17 |
# the Free Software Foundation; either version 2 of the License, or |
18 |
# (at your option) any later version. |
19 |
# |
20 |
# This program is distributed in the hope that it will be useful, |
21 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 |
# GNU General Public License for more details. |
24 |
# |
25 |
# You should have received a copy of the GNU General Public License |
26 |
# along with this program; if not, write to the Free Software |
27 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 |
# |
29 |
#======================================================================== |
30 |
# |
31 |
# Version 2.1.0, released 20 Jun 2004. |
32 |
# |
33 |
# See http://backuppc.sourceforge.net. |
34 |
# |
35 |
#======================================================================== |
36 |
|
37 |
package BackupPC::CGI::View; |
38 |
|
39 |
use strict; |
40 |
use BackupPC::CGI::Lib qw(:all); |
41 |
use BackupPC::FileZIO; |
42 |
|
43 |
sub action |
44 |
{ |
45 |
my $Privileged = CheckPermission($In{host}); |
46 |
my $compress = 0; |
47 |
my $fh; |
48 |
my $host = $In{host}; |
49 |
my $num = $In{num}; |
50 |
my $type = $In{type}; |
51 |
my $linkHosts = 0; |
52 |
my($file, $comment); |
53 |
my $ext = $num ne "" ? ".$num" : ""; |
54 |
|
55 |
ErrorExit(eval("qq{$Lang->{Invalid_number__num}}")) |
56 |
if ( $num ne "" && $num !~ /^\d+$/ ); |
57 |
if ( $type eq "XferLOG" ) { |
58 |
$file = "$TopDir/pc/$host/SmbLOG$ext"; |
59 |
$file = "$TopDir/pc/$host/XferLOG$ext" if ( !-f $file && !-f "$file.z"); |
60 |
} elsif ( $type eq "XferLOGbad" ) { |
61 |
$file = "$TopDir/pc/$host/SmbLOG.bad"; |
62 |
$file = "$TopDir/pc/$host/XferLOG.bad" if ( !-f $file && !-f "$file.z"); |
63 |
} elsif ( $type eq "XferErrbad" ) { |
64 |
$file = "$TopDir/pc/$host/SmbLOG.bad"; |
65 |
$file = "$TopDir/pc/$host/XferLOG.bad" if ( !-f $file && !-f "$file.z"); |
66 |
$comment = $Lang->{Extracting_only_Errors}; |
67 |
} elsif ( $type eq "XferErr" ) { |
68 |
$file = "$TopDir/pc/$host/SmbLOG$ext"; |
69 |
$file = "$TopDir/pc/$host/XferLOG$ext" if ( !-f $file && !-f "$file.z"); |
70 |
$comment = $Lang->{Extracting_only_Errors}; |
71 |
} elsif ( $type eq "RestoreLOG" ) { |
72 |
$file = "$TopDir/pc/$host/RestoreLOG$ext"; |
73 |
} elsif ( $type eq "RestoreErr" ) { |
74 |
$file = "$TopDir/pc/$host/RestoreLOG$ext"; |
75 |
$comment = $Lang->{Extracting_only_Errors}; |
76 |
} elsif ( $type eq "ArchiveLOG" ) { |
77 |
$file = "$TopDir/pc/$host/ArchiveLOG$ext"; |
78 |
} elsif ( $type eq "ArchiveErr" ) { |
79 |
$file = "$TopDir/pc/$host/ArchiveLOG$ext"; |
80 |
$comment = $Lang->{Extracting_only_Errors}; |
81 |
} elsif ( $host ne "" && $type eq "config" ) { |
82 |
$file = "$TopDir/pc/$host/config.pl"; |
83 |
$file = "$TopDir/conf/$host.pl" |
84 |
if ( $host ne "config" && -f "$TopDir/conf/$host.pl" |
85 |
&& !-f $file ); |
86 |
} elsif ( $type eq "docs" ) { |
87 |
$file = "$BinDir/../doc/BackupPC.html"; |
88 |
} elsif ( $type eq "config" ) { |
89 |
$file = "$TopDir/conf/config.pl"; |
90 |
} elsif ( $type eq "hosts" ) { |
91 |
$file = "$TopDir/conf/hosts"; |
92 |
$linkHosts = 1; |
93 |
} elsif ( $host ne "" ) { |
94 |
$file = "$TopDir/pc/$host/LOG$ext"; |
95 |
$linkHosts = 1; |
96 |
} else { |
97 |
$file = "$TopDir/log/LOG$ext"; |
98 |
$linkHosts = 1; |
99 |
} |
100 |
if ( $type ne "docs" && !$Privileged ) { |
101 |
ErrorExit($Lang->{Only_privileged_users_can_view_log_or_config_files}); |
102 |
} |
103 |
if ( !-f $file && -f "$file.z" ) { |
104 |
$file .= ".z"; |
105 |
$compress = 1; |
106 |
} |
107 |
my($contentPre, $contentSub, $contentPost); |
108 |
$contentPre .= eval("qq{$Lang->{Log_File__file__comment}}"); |
109 |
if ( defined($fh = BackupPC::FileZIO->open($file, 0, $compress)) ) { |
110 |
my $mtimeStr = $bpc->timeStamp((stat($file))[9], 1); |
111 |
|
112 |
$contentPre .= eval("qq{$Lang->{Contents_of_log_file}}"); |
113 |
|
114 |
$contentPre .= "<pre>"; |
115 |
if ( $type eq "XferErr" || $type eq "XferErrbad" |
116 |
|| $type eq "RestoreErr" |
117 |
|| $type eq "ArchiveErr" ) { |
118 |
$contentSub = sub { |
119 |
# |
120 |
# Because the content might be large, we use |
121 |
# a sub to return the data in 64K chunks. |
122 |
# |
123 |
my($skipped, $c, $s); |
124 |
while ( length($c) < 65536 ) { |
125 |
$s = $fh->readLine(); |
126 |
if ( $s eq "" ) { |
127 |
$c .= eval("qq{$Lang->{skipped__skipped_lines}}") |
128 |
if ( $skipped ); |
129 |
last; |
130 |
} |
131 |
$s =~ s/[\n\r]+//g; |
132 |
if ( $s =~ /smb: \\>/ |
133 |
|| $s =~ /^\s*(\d+) \(\s*\d+\.\d kb\/s\) (.*)$/ |
134 |
|| $s =~ /^tar: dumped \d+ files/ |
135 |
|| $s =~ /^\s*added interface/i |
136 |
|| $s =~ /^\s*restore tar file /i |
137 |
|| $s =~ /^\s*restore directory /i |
138 |
|| $s =~ /^\s*tarmode is now/i |
139 |
|| $s =~ /^\s*Total bytes written/i |
140 |
|| $s =~ /^\s*Domain=/i |
141 |
|| $s =~ /^\s*Getting files newer than/i |
142 |
|| $s =~ /^\s*Output is \/dev\/null/ |
143 |
|| $s =~ /^\s*\([\d.,]* kb\/s\) \(average [\d\.]* kb\/s\)$/ |
144 |
|| $s =~ /^\s+directory \\/ |
145 |
|| $s =~ /^\s*Timezone is/ |
146 |
|| $s =~ /^\s*creating lame (up|low)case table/i |
147 |
|| $s =~ /^\.\// |
148 |
|| $s =~ /^ / ) { |
149 |
$skipped++; |
150 |
next; |
151 |
} |
152 |
$c .= eval("qq{$Lang->{skipped__skipped_lines}}") |
153 |
if ( $skipped ); |
154 |
$skipped = 0; |
155 |
$c .= ${EscHTML($s)} . "\n"; |
156 |
} |
157 |
return $c; |
158 |
}; |
159 |
} elsif ( $linkHosts ) { |
160 |
# |
161 |
# Because the content might be large, we use |
162 |
# a sub to return the data in 64K chunks. |
163 |
# |
164 |
$contentSub = sub { |
165 |
my($c, $s); |
166 |
while ( length($c) < 65536 ) { |
167 |
$s = $fh->readLine(); |
168 |
last if ( $s eq "" ); |
169 |
$s =~ s/[\n\r]+//g; |
170 |
$s = ${EscHTML($s)}; |
171 |
$s =~ s/\b([\w-]+)\b/defined($Hosts->{$1}) |
172 |
? ${HostLink($1)} : $1/eg; |
173 |
$c .= $s . "\n"; |
174 |
} |
175 |
return $c; |
176 |
}; |
177 |
} elsif ( $type eq "config" ) { |
178 |
# |
179 |
# Because the content might be large, we use |
180 |
# a sub to return the data in 64K chunks. |
181 |
# |
182 |
$contentSub = sub { |
183 |
my($c, $s); |
184 |
while ( length($c) < 65536 ) { |
185 |
$s = $fh->readLine(); |
186 |
last if ( $s eq "" ); |
187 |
$s =~ s/[\n\r]+//g; |
188 |
# remove any passwords and user names |
189 |
$s =~ s/(SmbSharePasswd.*=.*['"]).*(['"])/$1****$2/ig; |
190 |
$s =~ s/(SmbShareUserName.*=.*['"]).*(['"])/$1****$2/ig; |
191 |
$s =~ s/(RsyncdPasswd.*=.*['"]).*(['"])/$1****$2/ig; |
192 |
$s =~ s/(ServerMesgSecret.*=.*['"]).*(['"])/$1****$2/ig; |
193 |
$s = ${EscHTML($s)}; |
194 |
$s =~ s[(\$Conf\{.*?\})][ |
195 |
my $c = $1; |
196 |
my $s = lc($c); |
197 |
$s =~ s{(\W)}{sprintf("%%%02x", ord($1) )}gxe; |
198 |
"<a href=\"?action=view&type=docs#item_$s\"><tt>$c</tt></a>" |
199 |
]eg; |
200 |
$c .= $s . "\n"; |
201 |
} |
202 |
return $c; |
203 |
}; |
204 |
} elsif ( $type eq "docs" ) { |
205 |
# |
206 |
# Because the content might be large, we use |
207 |
# a sub to return the data in 64K chunks. |
208 |
# |
209 |
$contentSub = sub { |
210 |
my($c, $s); |
211 |
while ( length($c) < 65536 ) { |
212 |
$s = $fh->readLine(); |
213 |
last if ( $s eq "" ); |
214 |
$c .= $s; |
215 |
} |
216 |
return $c; |
217 |
}; |
218 |
# |
219 |
# Documentation has a different header and no pre or post text, |
220 |
# so just handle it here |
221 |
# |
222 |
Header($Lang->{BackupPC__Documentation}, "", 0, $contentSub); |
223 |
Trailer(); |
224 |
return; |
225 |
} else { |
226 |
# |
227 |
# Because the content might be large, we use |
228 |
# a sub to return the data in 64K chunks. |
229 |
# |
230 |
$contentSub = sub { |
231 |
my($c, $s); |
232 |
while ( length($c) < 65536 ) { |
233 |
$s = $fh->readLine(); |
234 |
last if ( $s eq "" ); |
235 |
$s =~ s/[\n\r]+//g; |
236 |
$s = ${EscHTML($s)}; |
237 |
$c .= $s . "\n"; |
238 |
} |
239 |
return $c; |
240 |
}; |
241 |
} |
242 |
} else { |
243 |
if ( $type eq "docs" ) { |
244 |
ErrorExit(eval("qq{$Lang->{Unable_to_open__file__configuration_problem}}")); |
245 |
} |
246 |
$contentPre .= eval("qq{$Lang->{_pre___Can_t_open_log_file__file}}"); |
247 |
} |
248 |
$contentPost .= "</pre>\n" if ( $type ne "docs" ); |
249 |
Header(eval("qq{$Lang->{Backup_PC__Log_File__file}}"), |
250 |
$contentPre, !-f "$TopDir/pc/$host/backups", |
251 |
$contentSub, $contentPost); |
252 |
Trailer(); |
253 |
$fh->close() if ( defined($fh) ); |
254 |
} |
255 |
|
256 |
1; |