]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add .bvfs_ls_all_files command
authorEric Bollengier <eric@baculasystems.com>
Wed, 13 Jan 2021 08:37:40 +0000 (09:37 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:02:59 +0000 (09:02 +0100)
bacula/src/cats/bvfs.c
bacula/src/cats/bvfs.h
bacula/src/cats/sql_cmds.c
bacula/src/cats/sql_cmds.h
bacula/src/dird/ua_dotcmds.c

index 723748c457d99517c4dae42dfc1e7bf58e27039d..0ccd5438992748e06a6bf161cdf01d0ae954843c 100644 (file)
@@ -1207,7 +1207,41 @@ bool Bvfs::ls_dirs()
    return nb_record == limit;
 }
 
-void build_ls_files_query(BDB *db, POOL_MEM &query,
+/* List all files from a set of jobs */
+bool Bvfs::ls_all_files()
+{
+   POOL_MEM query;
+   POOL_MEM filter;
+
+   if (*jobids == 0) {
+      return false;
+   }
+
+   if (*pattern) {
+      Mmsg(filter, " AND File.Filename %s '%s' ",
+           match_query[db->bdb_get_type_index()], pattern);
+
+   } else if (*filename) {
+      Mmsg(filter, " AND File.Filename = '%s' ", filename);
+   }
+
+   Mmsg(query, sql_bvfs_list_all_files[db->bdb_get_type_index()],
+        filter.c_str(), jobids, limit, offset);
+
+   /* TODO: check all parent directories to know if we can
+    * list the files here.
+    */
+   Dmsg1(dbglevel_sql, "q=%s\n", query.c_str());
+
+   db->bdb_lock();
+   db->bdb_sql_query(query.c_str(), list_entries, user_data);
+   nb_record = db->sql_num_rows();
+   db->bdb_unlock();
+
+   return nb_record == limit;
+}
+
+static void build_ls_files_query(BDB *db, POOL_MEM &query,
                           const char *JobId, const char *PathId,
                           const char *filter, int64_t limit, int64_t offset)
 {
index 3544a9d5d04c1975a280942ff46d15fd7912cb8d..41a2299af65305ac09249220617645d7a5cb3145 100644 (file)
@@ -116,7 +116,7 @@ public:
     * Returns true if the directory exists
     */
    bool ch_dir(const char *path);
-
+   bool ls_all_files();         /* Returns true if we have more files to read */
    bool ls_files();             /* Returns true if we have more files to read */
    bool ls_dirs();              /* Returns true if we have more dir to read */
    void ls_special_dirs();      /* get . and .. */
index e3d388e7a5309095ab849138c3de46e05fa307bb..d892e1e2309a0e3338e19efbde33259206da195d 100644 (file)
@@ -759,6 +759,34 @@ const char *sql_bvfs_select[] =
    default_sql_bvfs_select
 };
 
+static const char *sql_bvfs_list_all_files_default = 
+"SELECT 'F', File.PathId, Path.Path || File.Filename, "
+        "File.JobId, File.LStat, File.FileId "
+"FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) "
+"WHERE File.Filename != '' "
+  "AND File.FileIndex > 0 "
+  " %s "                     /* AND Name LIKE '' */
+  "AND Job.JobId IN ( %s) ORDER BY File.FileId " // Needed to support LIMIT/OFFSET 
+   "LIMIT %lld OFFSET %lld";
+
+const char *sql_bvfs_list_all_files[] = {
+   /* MySQL */
+"SELECT 'F', File.PathId, CONCAT(Path.Path, File.Filename), "
+        "File.JobId, File.LStat, File.FileId "
+"FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) "
+"WHERE File.Filename != '' "
+  "AND File.FileIndex > 0 "
+  " %s "                     /* AND Name LIKE '' */
+  "AND Job.JobId IN (%s) ORDER BY File.FileId " // Needed to support LIMIT/OFFSET
+ "LIMIT %lld OFFSET %lld",
+
+   /* PostgreSQL */
+   sql_bvfs_list_all_files_default,
+
+   /* SQLite */
+   sql_bvfs_list_all_files_default
+};
+
 static const char *sql_bvfs_list_files_default = 
 "SELECT 'F', T.PathId, T.Filename, "
         "File.JobId, File.LStat, File.FileId "
index b8d6f0baad28e76a600b16d6a8b3dc2e44ac608e..bac92eaee385502a18824ee939b62ae150d1349a 100644 (file)
@@ -56,6 +56,7 @@ extern const char CATS_IMP_EXP *select_recent_version[];
 extern const char CATS_IMP_EXP *select_recent_version_with_basejob[];
 extern const char CATS_IMP_EXP *select_recent_version_with_basejob_and_delta[];
 extern const char CATS_IMP_EXP *sel_JobMedia;
+extern const char CATS_IMP_EXP *sql_bvfs_list_all_files[];
 extern const char CATS_IMP_EXP *sql_bvfs_list_files[];
 extern const char CATS_IMP_EXP *sql_bvfs_select[];
 extern const char CATS_IMP_EXP *sql_get_max_connections[];
index 565f44c4b15ff15cd8314912440cda1bec04eeaa..96ac50193c227c9dfa8d86933a7dc78caa0712fc 100644 (file)
@@ -70,6 +70,7 @@ static bool catalogscmd(UAContext *ua, const char *cmd);
 static bool dot_ls_cmd(UAContext *ua, const char *cmd);
 static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd);
 static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd);
+static bool dot_bvfs_ls_all_files(UAContext *ua, const char *cmd);
 static bool dot_bvfs_update(UAContext *ua, const char *cmd);
 static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd);
 static bool dot_bvfs_versions(UAContext *ua, const char *cmd);
@@ -127,6 +128,7 @@ static struct cmdstruct commands[] = { /* help */  /* can be used in runscript *
  { NT_(".actiononpurge"),aopcmd,                 NULL,       true},
  { NT_(".bvfs_lsdirs"), dot_bvfs_lsdirs,         NULL,       true},
  { NT_(".bvfs_lsfiles"),dot_bvfs_lsfiles,        NULL,       true},
+ { NT_(".bvfs_ls_all_files"),dot_bvfs_ls_all_files, NULL,    true},
  { NT_(".bvfs_get_volumes"),dot_bvfs_get_volumes,NULL,       true},
  { NT_(".bvfs_update"), dot_bvfs_update,         NULL,       true},
  { NT_(".bvfs_get_jobids"), dot_bvfs_get_jobids, NULL,       true},
@@ -580,10 +582,14 @@ static bool bvfs_parse_arg(UAContext *ua,
                            char **username,
                            int *limit, int *offset)
 {
-   *pathid=0;
+   if (pathid) {
+      *pathid=0;
+   }
+   if (path) {
+      *path=NULL;
+   }
    *limit=2000;
    *offset=0;
-   *path=NULL;
    *username=NULL;
    if (jobid) {
       *jobid=NULL;
@@ -593,13 +599,13 @@ static bool bvfs_parse_arg(UAContext *ua,
       if (!ua->argv[i]) {
          continue;
       }
-      if (strcasecmp(ua->argk[i], NT_("pathid")) == 0) {
+      if (pathid && strcasecmp(ua->argk[i], NT_("pathid")) == 0) {
          if (is_a_number(ua->argv[i])) {
             *pathid = str_to_int64(ua->argv[i]);
          }
       }
 
-      if (strcasecmp(ua->argk[i], NT_("path")) == 0) {
+      if (path && strcasecmp(ua->argk[i], NT_("path")) == 0) {
          *path = ua->argv[i];
       }
 
@@ -649,8 +655,10 @@ static bool bvfs_parse_arg(UAContext *ua,
       return false;
    }
 
-   if (!(*pathid || *path)) {
-      return false;
+   if (path && pathid) {
+      if (!(*pathid || *path)) {
+         return false;
+      }
    }
 
    return true;
@@ -1139,6 +1147,61 @@ bail_out:
    return true;
 }
 
+/*
+ * .bvfs_ls_all_files jobid=1,2,3,4
+ */
+static bool dot_bvfs_ls_all_files(UAContext *ua, const char *cmd)
+{
+   int limit=2000, offset=0;
+   char *jobid=NULL, *username=NULL;
+   char *pattern=NULL, *filename=NULL;
+   int i;
+
+   if (!bvfs_parse_arg(ua, NULL, NULL, &jobid, &username,
+                       &limit, &offset))
+   {
+      ua->error_msg("Can't find jobid argument\n");
+      return true;              /* not enough param */
+   }
+   if ((i = find_arg_with_value(ua, "pattern")) >= 0) {
+      pattern = ua->argv[i];
+   }
+   if ((i = find_arg_with_value(ua, "filename")) >= 0) {
+      filename = ua->argv[i];
+   }
+
+   if (!open_new_client_db(ua)) {
+      return 1;
+   }
+
+   Bvfs fs(ua->jcr, ua->db);
+   bvfs_set_acl(ua, &fs);
+   fs.set_username(username);
+   if (str_to_int64(jobid) == 0) {
+      if (get_client_jobids(ua, &fs) <= 0) {
+         goto bail_out;
+      }
+   } else {
+      fs.set_jobids(jobid);
+   }
+   fs.set_handler(bvfs_result_handler, ua);
+   fs.set_limit(limit);
+   ua->bvfs = &fs;
+   if (pattern) {
+      fs.set_pattern(pattern);
+   }
+   if (filename) {
+      fs.set_filename(filename);
+   }
+
+   fs.set_offset(offset);
+   fs.ls_all_files();
+
+bail_out:
+   ua->bvfs = NULL;
+   return true;
+}
+
 /*
  * .bvfs_lsdirs jobid=1,2,3,4 pathid=10
  * .bvfs_lsdirs jobid=1,2,3,4 path=/