<p>fixeria has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/20892">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">vty/command: fix: restrict the expert mode to the current session<br><br>Having the expert mode flag stored in the global 'host' structure<br>was a bad idea, because this way it applies globally.  In other<br>words, if user Bob activates the expert mode in his dedicated<br>session (e.g. a telnet connection), then not only him, but all<br>other users would see the hidden commands in their VTYs.<br><br>Moreover, if somebody deactivates the expert mode, it would also<br>affect the Bob's VTY session.  And finally, terminating a VTY<br>session would not deactivate the expert mode.<br><br>Let's move that flag from the global 'struct host' to 'struct vty'<br>representing an individual VTY session, so then the expert mode<br>would only affect the session where it was activated.<br><br>In functions related to the XML VTY reference generation we don't<br>have access to 'struct vty' (there may be no VTY session at all).<br>Add two additional arguments to vty_dump_nodes(), indicating the<br>global flag mask and a matching mode.  This would allow to match<br>the VTY commands in many different ways, e.g. one can dump hidden<br>commands only, or all commands except the library specific ones.<br><br>Change-Id: Iba13f0949061e3dadf9cf92829d15e97074fe4ad<br>Related: SYS#4910<br>---<br>M include/osmocom/vty/command.h<br>M include/osmocom/vty/vty.h<br>M src/vty/command.c<br>3 files changed, 41 insertions(+), 20 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/92/20892/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h</span><br><span>index eb7ee35..b608848 100644</span><br><span>--- a/include/osmocom/vty/command.h</span><br><span>+++ b/include/osmocom/vty/command.h</span><br><span>@@ -67,9 +67,6 @@</span><br><span> </span><br><span>       /*! VTY application information */</span><br><span>   const struct vty_app_info *app_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /*! Whether the expert mode is enabled. */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool expert_mode;</span><br><span> };</span><br><span> </span><br><span> /*! There are some command levels which called from command node. */</span><br><span>diff --git a/include/osmocom/vty/vty.h b/include/osmocom/vty/vty.h</span><br><span>index 6a82d7e..d34433f 100644</span><br><span>--- a/include/osmocom/vty/vty.h</span><br><span>+++ b/include/osmocom/vty/vty.h</span><br><span>@@ -165,6 +165,9 @@</span><br><span>   /*! When reading from a config file, these are the indenting characters expected for children of</span><br><span>      * the current VTY node. */</span><br><span>  char *indent;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! Whether the expert mode is enabled. */</span><br><span style="color: hsl(120, 100%, 40%);">+    bool expert_mode;</span><br><span> };</span><br><span> </span><br><span> /* Small macro to determine newline is newline only or linefeed needed. */</span><br><span>diff --git a/src/vty/command.c b/src/vty/command.c</span><br><span>index 7ea1971..c233aa6 100644</span><br><span>--- a/src/vty/command.c</span><br><span>+++ b/src/vty/command.c</span><br><span>@@ -773,8 +773,23 @@</span><br><span> </span><br><span> /*</span><br><span>  * Dump all nodes and commands associated with a given node as XML via a print_func_t.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (gflag_mask, match = false) - print only those commands with non-matching flags.</span><br><span style="color: hsl(120, 100%, 40%);">+ * (gflag_mask, match = true) - print only those commands with matching flags.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Some examples:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Print all commands except deprecated and hidden (default mode):</span><br><span style="color: hsl(120, 100%, 40%);">+ *    (CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN, false)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Print only deprecated and hidden commands:</span><br><span style="color: hsl(120, 100%, 40%);">+ *    (CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN, true)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Print all commands except deprecated (expert mode):</span><br><span style="color: hsl(120, 100%, 40%);">+ *    (CMD_ATTR_DEPRECATED, false)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Print only hidden commands:</span><br><span style="color: hsl(120, 100%, 40%);">+ *    (CMD_ATTR_HIDDEN, true)</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static int vty_dump_nodes(print_func_t print_func, void *data, const char *newline)</span><br><span style="color: hsl(120, 100%, 40%);">+static int vty_dump_nodes(print_func_t print_func, void *data, const char *newline,</span><br><span style="color: hsl(120, 100%, 40%);">+                   unsigned char gflag_mask, bool match)</span><br><span> {</span><br><span>         int i, j;</span><br><span>    int same_name_count;</span><br><span>@@ -797,9 +812,9 @@</span><br><span>                   const struct cmd_element *elem = vector_slot(cnode->cmd_vector, j);</span><br><span>                       if (!vty_command_is_common(elem))</span><br><span>                            continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (elem->attr & CMD_ATTR_DEPRECATED)</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!match && (elem->attr & gflag_mask) != 0x00)</span><br><span>                              continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!host.expert_mode && (elem->attr & CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (match && (elem->attr & gflag_mask) == 0x00)</span><br><span>                               continue;</span><br><span>                    vty_dump_element(elem, print_func, data, newline);</span><br><span>           }</span><br><span>@@ -835,9 +850,9 @@</span><br><span>                      const struct cmd_element *elem = vector_slot(cnode->cmd_vector, j);</span><br><span>                       if (vty_command_is_common(elem))</span><br><span>                             continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (elem->attr & CMD_ATTR_DEPRECATED)</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!match && (elem->attr & gflag_mask) != 0x00)</span><br><span>                              continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!host.expert_mode && (elem->attr & CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (match && (elem->attr & gflag_mask) == 0x00)</span><br><span>                               continue;</span><br><span>                    vty_dump_element(elem, print_func, data, newline);</span><br><span>           }</span><br><span>@@ -863,7 +878,10 @@</span><br><span> </span><br><span> static int vty_dump_xml_ref_to_vty(struct vty *vty)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        return vty_dump_nodes(print_func_vty, vty, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned char gflag_mask = CMD_ATTR_DEPRECATED;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!vty->expert_mode)</span><br><span style="color: hsl(120, 100%, 40%);">+             gflag_mask |= CMD_ATTR_HIDDEN;</span><br><span style="color: hsl(120, 100%, 40%);">+        return vty_dump_nodes(print_func_vty, vty, VTY_NEWLINE, gflag_mask, false);</span><br><span> }</span><br><span> </span><br><span> static int print_func_stream(void *data, const char *format, ...)</span><br><span>@@ -895,17 +913,21 @@</span><br><span>  */</span><br><span> int vty_dump_xml_ref_mode(FILE *stream, enum vty_ref_gen_mode mode)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned char gflag_mask;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  switch (mode) {</span><br><span>      case VTY_REF_GEN_MODE_EXPERT:</span><br><span style="color: hsl(0, 100%, 40%);">-           host.expert_mode = true;</span><br><span style="color: hsl(120, 100%, 40%);">+              /* All commands except deprecated */</span><br><span style="color: hsl(120, 100%, 40%);">+          gflag_mask = CMD_ATTR_DEPRECATED;</span><br><span>            break;</span><br><span>       case VTY_REF_GEN_MODE_DEFAULT:</span><br><span>       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                host.expert_mode = false;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* All commands except deprecated and hidden */</span><br><span style="color: hsl(120, 100%, 40%);">+               gflag_mask = CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN;</span><br><span>          break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return vty_dump_nodes(print_func_stream, stream, "\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     return vty_dump_nodes(print_func_stream, stream, "\n", gflag_mask, false);</span><br><span> }</span><br><span> </span><br><span> /*! Print the XML reference of all VTY nodes to the given stream.</span><br><span>@@ -2051,7 +2073,7 @@</span><br><span> </span><br><span>               if (cmd_element->attr & CMD_ATTR_DEPRECATED)</span><br><span>                  continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!host.expert_mode && (cmd_element->attr & CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!vty->expert_mode && (cmd_element->attr & CMD_ATTR_HIDDEN))</span><br><span>                    continue;</span><br><span> </span><br><span>                strvec = cmd_element->strvec;</span><br><span>@@ -2923,7 +2945,7 @@</span><br><span>     else</span><br><span>                 vty->node = AUTH_ENABLE_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    host.expert_mode = argc > 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       vty->expert_mode = argc > 0;</span><br><span> </span><br><span>       return CMD_SUCCESS;</span><br><span> }</span><br><span>@@ -2935,7 +2957,7 @@</span><br><span>     if (vty->node == ENABLE_NODE)</span><br><span>             vty->node = VIEW_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   host.expert_mode = false;</span><br><span style="color: hsl(120, 100%, 40%);">+     vty->expert_mode = false;</span><br><span> </span><br><span>     return CMD_SUCCESS;</span><br><span> }</span><br><span>@@ -3123,7 +3145,7 @@</span><br><span> }</span><br><span> </span><br><span> /* Compose flag bit-mask for all commands within the given node */</span><br><span style="color: hsl(0, 100%, 40%);">-static unsigned int node_flag_mask(const struct cmd_node *cnode)</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned int node_flag_mask(const struct cmd_node *cnode, bool expert_mode)</span><br><span> {</span><br><span>     unsigned int flag_mask = 0x00;</span><br><span>       unsigned int f, i;</span><br><span>@@ -3137,7 +3159,7 @@</span><br><span>                           continue;</span><br><span>                    if (cmd->attr & CMD_ATTR_DEPRECATED)</span><br><span>                          continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (!host.expert_mode && (cmd->attr & CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (!expert_mode && (cmd->attr & CMD_ATTR_HIDDEN))</span><br><span>                            continue;</span><br><span>                    if (~cmd->usrattr & ((unsigned)1 << f))</span><br><span>                                 continue;</span><br><span>@@ -3221,14 +3243,14 @@</span><br><span>  struct cmd_element *cmd;</span><br><span> </span><br><span>         if (argc > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                flag_mask = node_flag_mask(cnode);</span><br><span style="color: hsl(120, 100%, 40%);">+            flag_mask = node_flag_mask(cnode, vty->expert_mode);</span><br><span> </span><br><span>  for (i = 0; i < vector_active(cnode->cmd_vector); i++) {</span><br><span>               if ((cmd = vector_slot(cnode->cmd_vector, i)) == NULL)</span><br><span>                    continue;</span><br><span>            if (cmd->attr & CMD_ATTR_DEPRECATED)</span><br><span>                  continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!host.expert_mode && (cmd->attr & CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!vty->expert_mode && (cmd->attr & CMD_ATTR_HIDDEN))</span><br><span>                    continue;</span><br><span>            if (!argc)</span><br><span>                   vty_out(vty, "  %s%s", cmd->string, VTY_NEWLINE);</span><br><span>@@ -4302,7 +4324,6 @@</span><br><span>       host.lines = -1;</span><br><span>     host.motd = default_motd;</span><br><span>    host.motdfile = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-   host.expert_mode = false;</span><br><span> </span><br><span>        /* Install top nodes. */</span><br><span>     install_node_bare(&view_node, NULL);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/20892">change 20892</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/20892"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Iba13f0949061e3dadf9cf92829d15e97074fe4ad </div>
<div style="display:none"> Gerrit-Change-Number: 20892 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>