Updates in preparation for 3.0.0beta2:
[BackupPC.git] / lib / BackupPC / CGI / View.pm
index 2a4239b..335fde4 100644 (file)
@@ -28,7 +28,7 @@
 #
 #========================================================================
 #
-# Version 2.1.0_CVS, released 3 Jul 2003.
+# Version 3.0.0beta2, released 11 Nov 2006.
 #
 # See http://backuppc.sourceforge.net.
 #
@@ -52,7 +52,8 @@ sub action
     my($file, $comment);
     my $ext = $num ne "" ? ".$num" : "";
 
-    ErrorExit(eval("qq{$Lang->{Invalid_number__num}}")) if ( $num ne "" && $num !~ /^\d+$/ );
+    ErrorExit(eval("qq{$Lang->{Invalid_number__num}}"))
+                   if ( $num ne "" && $num !~ /^\d+$/ );
     if ( $type eq "XferLOG" ) {
         $file = "$TopDir/pc/$host/SmbLOG$ext";
         $file = "$TopDir/pc/$host/XferLOG$ext" if ( !-f $file && !-f "$file.z");
@@ -72,118 +73,189 @@ sub action
     } elsif ( $type eq "RestoreErr" ) {
         $file = "$TopDir/pc/$host/RestoreLOG$ext";
         $comment = $Lang->{Extracting_only_Errors};
-    } elsif ( $host ne "" && $type eq "config" ) {
-        $file = "$TopDir/pc/$host/config.pl";
-        $file = "$TopDir/conf/$host.pl"
-                    if ( $host ne "config" && -f "$TopDir/conf/$host.pl"
-                                           && !-f $file );
+    } elsif ( $type eq "ArchiveLOG" ) {
+        $file = "$TopDir/pc/$host/ArchiveLOG$ext";
+    } elsif ( $type eq "ArchiveErr" ) {
+        $file = "$TopDir/pc/$host/ArchiveLOG$ext";
+        $comment = $Lang->{Extracting_only_Errors};
+    } elsif ( $type eq "config" ) {
+        # Note: only works for Storage::Text
+        $file = $bpc->{storage}->ConfigPath($host);
+    } elsif ( $type eq "hosts" ) {
+        # Note: only works for Storage::Text
+        $file = $bpc->ConfDir() . "/hosts";
+        $linkHosts = 1;
     } elsif ( $type eq "docs" ) {
         $file = "$BinDir/../doc/BackupPC.html";
-        if ( open(LOG, $file) ) {
-           binmode(LOG);
-            Header($Lang->{BackupPC__Documentation});
-            print while ( <LOG> );
-            close(LOG);
-            Trailer();
+    } elsif ( $host ne "" ) {
+        if ( !defined($In{num}) ) {
+            # get the latest LOG file
+            $file = ($bpc->sortedPCLogFiles($host))[0];
         } else {
-            ErrorExit(eval("qq{$Lang->{Unable_to_open__file__configuration_problem}}"));
+            $file = "$TopDir/pc/$host/LOG$ext";
         }
-        return;
-    } elsif ( $type eq "config" ) {
-        $file = "$TopDir/conf/config.pl";
-    } elsif ( $type eq "hosts" ) {
-        $file = "$TopDir/conf/hosts";
-    } elsif ( $host ne "" ) {
-        $file = "$TopDir/pc/$host/LOG$ext";
+        $linkHosts = 1;
     } else {
-        $file = "$TopDir/log/LOG$ext";
+        $file = "$LogDir/LOG$ext";
         $linkHosts = 1;
     }
-    if ( !$Privileged ) {
+    if ( $type ne "docs" && !$Privileged ) {
         ErrorExit($Lang->{Only_privileged_users_can_view_log_or_config_files});
     }
     if ( !-f $file && -f "$file.z" ) {
         $file .= ".z";
         $compress = 1;
     }
-    Header(eval("qq{$Lang->{Backup_PC__Log_File__file}}")  );
-    print( eval ("qq{$Lang->{Log_File__file__comment}}"));
-    if ( defined($fh = BackupPC::FileZIO->open($file, 0, $compress)) ) {
+    my($contentPre, $contentSub, $contentPost);
+    $contentPre .= eval("qq{$Lang->{Log_File__file__comment}}");
+    if ( $file ne ""
+            && defined($fh = BackupPC::FileZIO->open($file, 0, $compress)) ) {
+
+        $fh->utf8(1);
         my $mtimeStr = $bpc->timeStamp((stat($file))[9], 1);
 
-       print ( eval ("qq{$Lang->{Contents_of_log_file}}"));
+       $contentPre .= eval("qq{$Lang->{Contents_of_log_file}}");
 
-        print "<pre>";
+        $contentPre .= "<pre>";
         if ( $type eq "XferErr" || $type eq "XferErrbad"
-                               || $type eq "RestoreErr" ) {
-           my $skipped;
-            while ( 1 ) {
-                $_ = $fh->readLine();
-                if ( $_ eq "" ) {
-                   print(eval ("qq{$Lang->{skipped__skipped_lines}}"))
-                                                   if ( $skipped );
-                   last;
+                               || $type eq "RestoreErr"
+                               || $type eq "ArchiveErr" ) {
+           $contentSub = sub {
+               #
+               # Because the content might be large, we use
+               # a sub to return the data in 64K chunks.
+               #
+               my($skipped, $c, $s);
+               while ( length($c) < 65536 ) {
+                   $s = $fh->readLine();
+                   if ( $s eq "" ) {
+                       $c .= eval("qq{$Lang->{skipped__skipped_lines}}")
+                                                       if ( $skipped );
+                       last;
+                   }
+                   $s =~ s/[\n\r]+//g;
+                   if ( $s =~ /smb: \\>/
+                           || $s =~ /^\s*(\d+) \(\s*\d+\.\d kb\/s\) (.*)$/
+                           || $s =~ /^tar: dumped \d+ files/
+                           || $s =~ /^\s*added interface/i
+                           || $s =~ /^\s*restore tar file /i
+                           || $s =~ /^\s*restore directory /i
+                           || $s =~ /^\s*tarmode is now/i
+                           || $s =~ /^\s*Total bytes written/i
+                           || $s =~ /^\s*Domain=/i
+                           || $s =~ /^\s*Getting files newer than/i
+                           || $s =~ /^\s*Output is \/dev\/null/
+                           || $s =~ /^\s*\([\d.,]* kb\/s\) \(average [\d\.]* kb\/s\)$/
+                           || $s =~ /^\s+directory \\/
+                           || $s =~ /^\s*Timezone is/
+                           || $s =~ /^\s*creating lame (up|low)case table/i
+                           || $s =~ /^\.\//
+                           || $s =~ /^  / ) {
+                       $skipped++;
+                       next;
+                   }
+                   $c .= eval("qq{$Lang->{skipped__skipped_lines}}")
+                                                        if ( $skipped );
+                   $skipped = 0;
+                   $c .= ${EscHTML($s)} . "\n";
                }
-                if ( /smb: \\>/
-                        || /^\s*(\d+) \(\s*\d+\.\d kb\/s\) (.*)$/
-                        || /^tar: dumped \d+ files/
-                        || /^added interface/i
-                        || /^restore tar file /i
-                        || /^restore directory /i
-                        || /^tarmode is now/i
-                        || /^Total bytes written/i
-                        || /^Domain=/i
-                        || /^Getting files newer than/i
-                        || /^Output is \/dev\/null/
-                        || /^\([\d\.]* kb\/s\) \(average [\d\.]* kb\/s\)$/
-                        || /^\s+directory \\/
-                        || /^Timezone is/
-                        || /^\.\//
-                        || /^  /
-                           ) {
-                   $skipped++;
-                   next;
-               }
-               print(eval("qq{$Lang->{skipped__skipped_lines}}"))
-                                                    if ( $skipped );
-               $skipped = 0;
-                print ${EscHTML($_)};
-            }
+               return $c;
+           };
         } elsif ( $linkHosts ) {
-            while ( 1 ) {
-                $_ = $fh->readLine();
-                last if ( $_ eq "" );
-                my $s = ${EscHTML($_)};
-                $s =~ s/\b([\w-]+)\b/defined($Hosts->{$1})
-                                        ? ${HostLink($1)} : $1/eg;
-                print $s;
-            }
+           #
+           # Because the content might be large, we use
+           # a sub to return the data in 64K chunks.
+           #
+           $contentSub = sub {
+               my($c, $s);
+               while ( length($c) < 65536 ) {
+                   $s = $fh->readLine();
+                   last if ( $s eq "" );
+                   $s =~ s/[\n\r]+//g;
+                   $s = ${EscHTML($s)};
+                   $s =~ s/\b([\w-]+)\b/defined($Hosts->{$1})
+                                           ? ${HostLink($1)} : $1/eg;
+                   $c .= $s . "\n";
+               }
+               return $c;
+            };
         } elsif ( $type eq "config" ) {
-            while ( 1 ) {
-                $_ = $fh->readLine();
-                last if ( $_ eq "" );
-                # remove any passwords and user names
-                s/(SmbSharePasswd.*=.*['"]).*(['"])/$1$2/ig;
-                s/(SmbShareUserName.*=.*['"]).*(['"])/$1$2/ig;
-                s/(RsyncdPasswd.*=.*['"]).*(['"])/$1$2/ig;
-                s/(ServerMesgSecret.*=.*['"]).*(['"])/$1$2/ig;
-                print ${EscHTML($_)};
-            }
+           #
+           # Because the content might be large, we use
+           # a sub to return the data in 64K chunks.
+           #
+           $contentSub = sub {
+               my($c, $s);
+               while ( length($c) < 65536 ) {
+                   $s = $fh->readLine();
+                   last if ( $s eq "" );
+                   $s =~ s/[\n\r]+//g;
+                   # remove any passwords and user names
+                   $s =~ s/(SmbSharePasswd.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(SmbShareUserName.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(RsyncdPasswd.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s =~ s/(ServerMesgSecret.*=.*['"]).*(['"])/$1****$2/ig;
+                   $s = ${EscHTML($s)};
+                   $s =~ s[(\$Conf\{.*?\})][
+                       my $c = $1;
+                       my $s = lc($c);
+                       $s =~ s{(\W)}{sprintf("%%%02x", ord($1) )}gxe;
+                       "<a href=\"?action=view&type=docs#item_$s\"><tt>$c</tt></a>"
+                   ]eg;
+                   $c .= $s . "\n";
+               }
+               return $c;
+            };
+        } elsif ( $type eq "docs" ) {
+           #
+           # Because the content might be large, we use
+           # a sub to return the data in 64K chunks.
+           #
+           $contentSub = sub {
+               my($c, $s);
+               while ( length($c) < 65536 ) {
+                   $s = $fh->readLine();
+                   last if ( $s eq "" );
+                   $c .= $s;
+               }
+               return $c;
+            };
+           #
+           # Documentation has a different header and no pre or post text,
+           # so just handle it here
+           #
+            Header($Lang->{BackupPC__Documentation}, "", 0, $contentSub);
+            Trailer();
+           return;
         } else {
-            while ( 1 ) {
-                $_ = $fh->readLine();
-                last if ( $_ eq "" );
-                print ${EscHTML($_)};
-            }
+           #
+           # Because the content might be large, we use
+           # a sub to return the data in 64K chunks.
+           #
+           $contentSub = sub {
+               my($c, $s);
+               while ( length($c) < 65536 ) {
+                   $s = $fh->readLine();
+                   last if ( $s eq "" );
+                   $s =~ s/[\n\r]+//g;
+                   $s = ${EscHTML($s)};
+                   $c .= $s . "\n";
+               }
+               return $c;
+            };
         }
-        $fh->close();
     } else {
-       printf( eval("qq{$Lang->{_pre___Can_t_open_log_file__file}}"));
+       if ( $type eq "docs" ) {
+           ErrorExit(eval("qq{$Lang->{Unable_to_open__file__configuration_problem}}"));
+       }
+       $contentPre .= eval("qq{$Lang->{_pre___Can_t_open_log_file__file}}");
     }
-    print <<EOF;
-</pre>
-EOF
+    $contentPost .= "</pre>\n" if ( $type ne "docs" );
+    Header(eval("qq{$Lang->{Backup_PC__Log_File__file}}"),
+                    $contentPre, !-f "$TopDir/pc/$host/backups",
+                   $contentSub, $contentPost);
     Trailer();
+    $fh->close() if ( defined($fh) );
 }
 
 1;