]> git.sur5r.net Git - bacula/bacula/blobdiff - gui/bweb/cgi/bresto.pl
bweb: Update some GPL2 notice to AGPL
[bacula/bacula] / gui / bweb / cgi / bresto.pl
index 3d3adab9cfdedbe32ea29f8f4281964f079b3809..df92a485990138cbdde7a556c8d5d8ea709c660f 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-
+use strict;
 my $bresto_enable = 1;
 die "bresto is not enabled" if (not $bresto_enable);
 
@@ -13,25 +13,24 @@ die "bresto is not enabled" if (not $bresto_enable);
    The main author of Bweb is Eric Bollengier.
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
-
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation plus additions
-   that are listed in the file LICENSE.
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
 
    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   Affero General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
    Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 
 =head1 VERSION
@@ -373,7 +372,7 @@ sub ls_files
      ) AS listfiles
 WHERE File.FileId = listfiles.id";
 
-    print STDERR $query;
+#    print STDERR $query;
     $self->debug($query);
     my $result = $self->dbh_selectall_arrayref($query);
     $self->debug($result);
@@ -381,6 +380,68 @@ WHERE File.FileId = listfiles.id";
     return $result;
 }
 
+sub ls_special_dirs
+{
+    my ($self) = @_;
+    return undef unless ($self->{curjobids});
+
+    my $pathid = $self->{cwdid};
+    my $jobclause = $self->{curjobids};
+    my $dir_filenameid = $self->get_dir_filenameid();
+
+    my $sq1 =  
+"((SELECT PPathId AS PathId, '..' AS Path
+    FROM  brestore_pathhierarchy 
+   WHERE  PathId = $pathid)
+UNION
+ (SELECT $pathid AS PathId, '.' AS Path))";
+
+    my $sq2 = "
+SELECT tmp.PathId, tmp.Path, LStat, JobId 
+  FROM $sq1 AS tmp  LEFT JOIN ( -- get attributes if any
+       SELECT File1.PathId, File1.JobId, File1.LStat FROM File AS File1
+       WHERE File1.FilenameId = $dir_filenameid
+       AND File1.JobId IN ($jobclause)) AS listfile1
+  ON (tmp.PathId = listfile1.PathId)
+  ORDER BY tmp.Path, JobId DESC
+";
+
+    my $result = $self->dbh_selectall_arrayref($sq2);
+
+    my @return_list;
+    my $prev_dir='';
+    foreach my $refrow (@{$result})
+    {
+       my $dirid = $refrow->[0];
+        my $dir = $refrow->[1];
+        my $lstat = $refrow->[3];
+        my $jobid = $refrow->[2] || 0;
+        next if ($dirid eq $prev_dir);
+        my @return_array = ($dirid,$dir,$lstat,$jobid);
+        push @return_list,(\@return_array);
+        $prev_dir = $dirid;
+    }
+    return \@return_list;
+}
+
+# Let's retrieve the list of the visible dirs in this dir ...
+# First, I need the empty filenameid to locate efficiently
+# the dirs in the file table
+sub get_dir_filenameid
+{
+    my ($self) = @_;
+    if ($self->{dir_filenameid}) {
+        return $self->{dir_filenameid};
+    }
+    my $query = "SELECT FilenameId FROM Filename WHERE Name = ''";
+    my $sth = $self->dbh_prepare($query);
+    $sth->execute();
+    my $result = $sth->fetchrow_arrayref();
+    $sth->finish();
+    return $self->{dir_filenameid} = $result->[0];
+}
+
 # list all directories in a directory, accross curjobids
 # return ($dirid,$dir_basename,$lstat,$jobid)
 sub ls_dirs
@@ -391,23 +452,23 @@ sub ls_dirs
 
     my $pathid = $self->{cwdid};
     my $jobclause = $self->{curjobids};
+    my $filter ='';
+
+    if ($self->{pattern}) {
+        $filter = " AND Path2.Path $self->{sql}->{MATCH} $self->{pattern} ";
+    }
 
     # Let's retrieve the list of the visible dirs in this dir ...
     # First, I need the empty filenameid to locate efficiently
     # the dirs in the file table
-    my $query = "SELECT FilenameId FROM Filename WHERE Name = ''";
-    my $sth = $self->dbh_prepare($query);
-    $sth->execute();
-    my $result = $sth->fetchrow_arrayref();
-    $sth->finish();
-    my $dir_filenameid = $result->[0];
+    my $dir_filenameid = $self->get_dir_filenameid();
 
     # Then we get all the dir entries from File ...
-    $query = "
-SELECT PathId, Path, JobId, Lstat FROM (
+    my $query = "
+SELECT PathId, Path, JobId, LStat FROM (
 
     SELECT Path1.PathId, Path1.Path, lower(Path1.Path),
-           listfile1.JobId, listfile1.Lstat
+           listfile1.JobId, listfile1.LStat
     FROM (
        SELECT DISTINCT brestore_pathhierarchy1.PathId
        FROM brestore_pathhierarchy AS brestore_pathhierarchy1
@@ -416,20 +477,22 @@ SELECT PathId, Path, JobId, Lstat FROM (
        JOIN brestore_pathvisibility AS brestore_pathvisibility1
            ON (brestore_pathhierarchy1.PathId = brestore_pathvisibility1.PathId)
        WHERE brestore_pathhierarchy1.PPathId = $pathid
-       AND brestore_pathvisibility1.jobid IN ($jobclause)) AS listpath1
+       AND brestore_pathvisibility1.jobid IN ($jobclause)
+           $filter
+     ) AS listpath1
    JOIN Path AS Path1 ON (listpath1.PathId = Path1.PathId)
-   LEFT JOIN (
-       SELECT File1.PathId, File1.JobId, File1.Lstat FROM File AS File1
+
+   LEFT JOIN ( -- get attributes if any
+       SELECT File1.PathId, File1.JobId, File1.LStat FROM File AS File1
        WHERE File1.FilenameId = $dir_filenameid
        AND File1.JobId IN ($jobclause)) AS listfile1
        ON (listpath1.PathId = listfile1.PathId)
      ) AS A ORDER BY 2,3 DESC LIMIT $self->{limit} OFFSET $self->{offset} 
 ";
-    $self->debug($query);
-    print STDERR $query;
-    $sth=$self->dbh_prepare($query);
+#    print STDERR $query;
+    my $sth=$self->dbh_prepare($query);
     $sth->execute();
-    $result = $sth->fetchall_arrayref();
+    my $result = $sth->fetchall_arrayref();
     my @return_list;
     my $prev_dir='';
     foreach my $refrow (@{$result})
@@ -551,7 +614,7 @@ sub get_all_file_versions
     my @versions;
     my $query;
     $query =
-"SELECT File.JobId, File.FileId, File.Lstat,
+"SELECT File.JobId, File.FileId, File.LStat,
         File.Md5, Media.VolumeName, Media.InChanger
  FROM File, Job, Client, JobMedia, Media
  WHERE File.FilenameId = $fileid
@@ -836,7 +899,8 @@ sub fill_table_for_restore
     my $FileId = CGI::param('force')?",FileId":"";
 
     my $fileid = join(',', grep { /^\d+$/ } CGI::param('fileid'));
-    my @dirid = grep { /^\d+$/ } CGI::param('dirid');
+    # can get dirid=("10,11", 10, 11)
+    my @dirid = grep { /^\d+$/ } map { split(/,/) } CGI::param('dirid') ;
     my $inclause = join(',', @jobid);
 
     my @union;
@@ -847,17 +911,14 @@ sub fill_table_for_restore
           FROM File WHERE FileId IN ($fileid))";
     }
 
-    # using this is not good because the sql engine doesn't know
-    # what LIKE will use. It will be better to get Path% in perl
-    # but it doesn't work with accents... :(
     foreach my $dirid (@dirid) {
-      push @union, "
+        my $p = $bvfs->get_path($dirid);
+        $p =~ s/([%_\\])/\\$1/g;  # Escape % and _ for LIKE search
+        $p = $bvfs->dbh_quote($p);
+        push @union, "
   (SELECT File.JobId, File.FileIndex, File.FilenameId, File.PathId $FileId
     FROM Path JOIN File USING (PathId)
-   WHERE Path.Path LIKE
-        (SELECT ". $bvfs->dbh_strcat('Path',"'\%'") ." FROM Path
-          WHERE PathId = $dirid
-        )
+   WHERE Path.Path LIKE " . $bvfs->dbh_strcat($p, "'%'") . "
      AND File.JobId IN ($inclause))";
     }
 
@@ -952,7 +1013,7 @@ if (CGI::param('init')) { # used when choosing a job
     $bvfs->update_brestore_table(@jobid);
 }
 
-my $pathid = CGI::param('node') || '';
+my $pathid = CGI::param('node') || CGI::param('pathid') || '';
 my $path = CGI::param('path');
 
 if ($pathid =~ /^(\d+)$/) {
@@ -964,6 +1025,8 @@ if ($pathid =~ /^(\d+)$/) {
 }
 $bvfs->ch_dir($pathid);
 
+#print STDERR "pathid=$pathid\n";
+
 # permit to use a regex filter
 if ($args->{qpattern}) {
     $bvfs->set_pattern($args->{qpattern});
@@ -1006,17 +1069,87 @@ if ($action eq 'restore') {
     print CGI::redirect("bweb.pl?action=dsp_cur_job;jobid=$jobid") ;
     exit 0;
 }
-
 sub escape_quote
 {
     my ($str) = @_;
-    $str =~ s/'/\\'/g;
+    my %esc = (
+        "\n" => '\n',
+        "\r" => '\r',
+        "\t" => '\t',
+        "\f" => '\f',
+        "\b" => '\b',
+        "\"" => '\"',
+        "\\" => '\\\\',
+        "\'" => '\\\'',
+    );
+
+    if (!$str) {
+        return '';
+    }
+
+    $str =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g;
+    $str =~ s/\//\\\//g;
+    $str =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
     return $str;
 }
 
 print CGI::header('application/x-javascript');
 
-if ($action eq 'list_files') {
+
+if ($action eq 'list_files_dirs') {
+# fileid, filenameid, pathid, jobid, name, size, mtime
+    my $jids = join(",", @jobid);
+
+    my $files = $bvfs->ls_special_dirs();
+    # return ($dirid,$dir_basename,$lstat,$jobid)
+    print "[\n";
+    print join(',',
+              map { my @p=Bvfs::parse_lstat($_->[3]); 
+                    '[' . join(',', 
+                               0, # fileid
+                               0, # filenameid
+                               $_->[0], # pathid
+                               "'$jids'", # jobid
+                                '"' . escape_quote($_->[1]) . '"', # name
+                               "'" . $p[7] . "'",                 # size
+                               "'" . strftime('%Y-%m-%d %H:%m:%S', localtime($p[11]||0)) .  "'") .
+                   ']'; 
+              } @$files);
+    print "," if (@$files);
+
+    $files = $bvfs->ls_dirs();
+    # return ($dirid,$dir_basename,$lstat,$jobid)
+    print join(',',
+              map { my @p=Bvfs::parse_lstat($_->[3]); 
+                    '[' . join(',', 
+                               0, # fileid
+                               0, # filenameid
+                               $_->[0], # pathid
+                               "'$jids'", # jobid
+                               '"' . escape_quote($_->[1]) . '"', # name
+                               "'" . $p[7] . "'",                 # size
+                               "'" . strftime('%Y-%m-%d %H:%m:%S', localtime($p[11]||0)) .  "'") .
+                   ']'; 
+              } @$files);
+
+    print "," if (@$files);
+    $files = $bvfs->ls_files();
+    print join(',',
+              map { my @p=Bvfs::parse_lstat($_->[3]); 
+                    '[' . join(',', 
+                               $_->[1],
+                               $_->[0],
+                               $pathid,
+                               $_->[4],
+                                '"' . escape_quote($_->[2]) . '"', # name
+                               "'" . $p[7] . "'",
+                               "'" . strftime('%Y-%m-%d %H:%m:%S', localtime($p[11])) .  "'") .
+                   ']'; 
+              } @$files);
+    print "]\n";
+
+} elsif ($action eq 'list_files') {
     print "[[0,0,0,0,'.',4096,'1970-01-01 00:00:00'],";
     my $files = $bvfs->ls_files();
 #      [ 1, 2, 3, "Bill",  10, '2007-01-01 00:00:00'],
@@ -1029,7 +1162,7 @@ if ($action eq 'list_files') {
                                $_->[0],
                                $pathid,
                                $_->[4],
-                               "'" . escape_quote($_->[2]) . "'",
+                                '"' . escape_quote($_->[2]) . '"', # name
                                "'" . $p[7] . "'",
                                "'" . strftime('%Y-%m-%d %H:%m:%S', localtime($p[11])) .  "'") .
                    ']'; 
@@ -1072,6 +1205,7 @@ if ($action eq 'list_files') {
     my $lst;
 
     # in this mode, we compute the result to get all needed media
+#    print STDERR "force=", CGI::param('force'), "\n";
     if (CGI::param('force')) {
         $table = fill_table_for_restore(@jobid);
         if (!$table) {