zoukankan      html  css  js  c++  java
  • quagga源码分析--通用库command

    quagga作为一个路由器软件,自然要提供人机接口。

    quagga提供snmp管理接口,而且,自然就会有对应的命令行管理格式,当然一般路由软件不会提供界面形式的,也许有webui,然而quagga并没有。

    我们要看的就是这个命令行处理的代码 command。

    接触过类似命令行的朋友肯定有一点点好奇吧,那么数量庞大的命令和参数输入,还可以提供提示和自动补齐,这肯定不是一件很简单的事情。

    下面是一个配置示例:

    1 !
    2 interface bge0
    3 ip ospf authentication message-digest
    4 ip ospf message-digest-key 1 md5 ABCDEFGHIJK
    5 !
    6 router ospf
    7 network 192.168.0.0/16 area 0.0.0.1
    8 area 0.0.0.1 authentication message-digest

    哦哦,看到这样的命令,实在是头疼。

    嗯,不废话了,我们还是看代码吧,看command是怎么处理这令人头疼的命令行吧:

     1 void cmd_init(int terminal) {
     2    ......
     3 
     4     cmdvec = vector_init(VECTOR_MIN_SIZE);
     5   
     6     /* Install top nodes. */
     7     install_node(&view_node, NULL);
     8     install_node(&enable_node, NULL);
     9 
    10     /* Each node's basic commands. */
    11     install_element(VIEW_NODE, &show_version_cmd);
    12 
    13     .....
    14 }

    这个就是命令行初始化的简化版本。

    quagg使用了非常常见的树形列表来描述所有的命令, cmdvec包含所有的顶层命令节点,节点下面是当前节点的所包含的命令元素.

     1 struct cmd_node 
     2 {
     3   /* Node index. */
     4   enum node_type node;        
     5 
     6   /* Prompt character at vty interface. */
     7   const char *prompt;            
     8 
     9   /* Is this node's configuration goes to vtysh ? */
    10   int vtysh;
    11   
    12   /* Node's configuration write function */
    13   int (*func) (struct vty *);
    14 
    15   /* Vector of this node's command list. */
    16   vector cmd_vector;    
    17 };

    上面已经举过命令行的具体例子,解释和执行命令行的函数如下:

    1 extern vector cmd_make_strvec (const char *);
    2 extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);

    通过查找匹配,找到对应的函数执行:

    1 /* Execute matched command. */
    2     return (*matched_element->func)(matched_element, vty, argc, argv);

    执行的函数由如下的宏声明:

     1 /* helper defines for end-user DEFUN* macros */
     2 #define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) 
     3   struct cmd_element cmdname = 
     4   { 
     5     .string = cmdstr, 
     6     .func = funcname, 
     7     .doc = helpstr, 
     8     .attr = attrs, 
     9     .daemon = dnum, 
    10   };
    11 
    12 #define DEFUN_CMD_FUNC_DECL(funcname) 
    13   static int funcname (struct cmd_element *, struct vty *, int, const char *[]);
    14 
    15 #define DEFUN_CMD_FUNC_TEXT(funcname) 
    16   static int funcname 
    17     (struct cmd_element *self __attribute__ ((unused)), 
    18      struct vty *vty __attribute__ ((unused)), 
    19      int argc __attribute__ ((unused)), 
    20      const char *argv[] __attribute__ ((unused)) )
    21 
    22 #define DEFUN(funcname, cmdname, cmdstr, helpstr) 
    23   DEFUN_CMD_FUNC_DECL(funcname) 
    24   DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) 
    25   DEFUN_CMD_FUNC_TEXT(funcname)

    然后看一个具体命令行声明:

     1 /* Configration from terminal */
     2 DEFUN(config_terminal,
     3       config_terminal_cmd,
     4       "configure terminal",
     5       "Configuration from vty interface
    "
     6       "Configuration terminal
    ") {
     7     if (vty_config_lock(vty)) vty->node = CONFIG_NODE;
     8     else {
     9         vty_out(vty, "VTY configuration is locked by other VTY%s", VTY_NEWLINE);
    10         return CMD_WARNING;
    11     }
    12     return CMD_SUCCESS;
    13 }

    这是进入配置模式的命令。

    嗯,这个就看到这里吧!

  • 相关阅读:
    enca工具,检测文件编码
    ubuntu 支持gbk
    LinkedList线程安全问题
    php防止form重复提交的方法
    Linux 内存泄露调试工具
    从B树、B+树、B*树谈到R 树
    Ubuntu 语言设置
    wwwauthenticate
    Lua脚本语法说明
    jQuery学习总结之元素的相对定位和选择器持续更新中
  • 原文地址:https://www.cnblogs.com/danxi/p/5840601.html
Copyright © 2011-2022 走看看