]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #7319 Introduce 'du' command inside restore menu
authorMichal Rakowski <michal.rakowski@baculasystems.com>
Sun, 14 Feb 2021 22:31:15 +0000 (23:31 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:04 +0000 (09:03 +0100)
Description:
-----------

Restore menu's du commands mimics Linux 'du' commands in terms that it
simply sums size of all files in directories below. For files, it simply
prints it's sizes.

TREE_NODE`s delta_seq size was reduced to int16_t since we don't expect
it to be any bigger at all while it reduced struct`s size a little bit
(it was still expanded by the `size` filed though).

bacula/src/dird/ua_tree.c
bacula/src/lib/tree.h

index 088268c5dfbb0bff48d3db822c26171e9db026b8..68f1efd557a695427c7252b4339275009456918d 100644 (file)
@@ -55,6 +55,7 @@ static int unmarkcmd(UAContext *ua, TREE_CTX *tree);
 static int unmarkdircmd(UAContext *ua, TREE_CTX *tree);
 static int quitcmd(UAContext *ua, TREE_CTX *tree);
 static int donecmd(UAContext *ua, TREE_CTX *tree);
+static int ducmd(UAContext *ua, TREE_CTX *tree);
 static int dot_lsdircmd(UAContext *ua, TREE_CTX *tree);
 static int dot_lscmd(UAContext *ua, TREE_CTX *tree);
 static int dot_helpcmd(UAContext *ua, TREE_CTX *tree);
@@ -71,6 +72,7 @@ static struct cmdstruct commands[] = {
  { NT_("dir"),        dircmd,       _("long list current directory, wildcards allowed")},
  { NT_(".dir"),       dot_dircmd,   _("long list current directory, wildcards allowed")},
  { NT_("done"),       donecmd,      _("leave file selection mode")},
+ { NT_("du"),         ducmd,        _("show size of files/directories")},
  { NT_("estimate"),   estimatecmd,  _("estimate restore size")},
  { NT_("exit"),       donecmd,      _("same as done command")},
  { NT_("find"),       findcmd,      _("find files, wildcards allowed")},
@@ -264,6 +266,7 @@ int insert_tree_handler(void *ctx, int num_fields, char **row)
       node->FileIndex = FileIndex;
       node->JobId = JobId;
       node->type = type;
+      node->size = statp.st_size;
       node->soft_link = S_ISLNK(statp.st_mode) != 0;
       node->delta_seq = delta_seq;
       node->can_access = can_access;
@@ -561,8 +564,28 @@ static int dot_lscmd(UAContext *ua, TREE_CTX *tree)
 
    return 1;
 }
+/* This helper sums size of all files in directories below recursively. If node is a file, it returns it's size */
+static uint64_t sum_tree_level(TREE_NODE *node) {
+   uint64_t size = 0;
 
-static int lscmd(UAContext *ua, TREE_CTX *tree)
+   if (!tree_node_has_child(node)) {
+      size = node->size;
+   } else {
+      TREE_NODE *s_node;
+      foreach_child(s_node, node) {
+         if (s_node->child.size() == 0) {
+            size+=s_node->size;
+         } else {
+            size+=sum_tree_level(s_node);
+         }
+      }
+   }
+
+   return size;
+}
+
+/* List files and directories, 'du' switch decides if size is printed as well */
+static int list_files(UAContext *ua, TREE_CTX *tree, bool du)
 {
    TREE_NODE *node;
 
@@ -579,12 +602,30 @@ static int lscmd(UAContext *ua, TREE_CTX *tree)
          } else {
             tag = "";
          }
-         ua->send_msg("%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+
+         if (du) {
+            char ed1[30];
+            uint64_t size = sum_tree_level(node);
+            edit_uint64_with_suffix(size, ed1);
+            ua->send_msg("%-7s   %s%s%s\n", ed1, tag, node->fname, tree_node_has_child(node)?"/":"");
+         } else {
+            ua->send_msg("%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+         }
       }
    }
    return 1;
 }
 
+static int lscmd(UAContext *ua, TREE_CTX *tree)
+{
+   return list_files(ua, tree, false);
+}
+
+static int ducmd(UAContext *ua, TREE_CTX *tree)
+{
+   return list_files(ua, tree, true);
+}
+
 /*
  * Ls command that lists only the marked files
  */
index 55d5aadfd80e6f919bd0d1946f32c1ab80eac7b6..30b8748539cf7e198453d9117cc6782415a2888c 100644 (file)
@@ -61,8 +61,9 @@ struct s_tree_node {
    char *fname;                       /* file name */
    int32_t FileIndex;                 /* file index */
    uint32_t JobId;                    /* JobId */
-   int32_t delta_seq;                 /* current delta sequence */
+   int16_t delta_seq;                 /* current delta sequence */
    uint16_t fname_len;                /* filename length */
+   uint64_t size;                     /* Size of file or directory (as a sum of files inside) */
    int type: 8;                       /* node type */
    unsigned int extract: 1;           /* extract item */
    unsigned int extract_dir: 1;       /* extract dir entry only */
@@ -85,8 +86,9 @@ struct s_tree_root {
    const char *fname;                 /* file name */
    int32_t FileIndex;                 /* file index */
    uint32_t JobId;                    /* JobId */
-   int32_t delta_seq;                 /* current delta sequence */
+   int16_t delta_seq;                 /* current delta sequence */
    uint16_t fname_len;                /* filename length */
+   uint64_t size;                     /* Size of file or directory (as a sum of files inside) */
    unsigned int type: 8;              /* node type */
    unsigned int extract: 1;           /* extract item */
    unsigned int extract_dir: 1;       /* extract dir entry only */