vtysh_main.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:6k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* Virtual terminal interface shell.
  2.  * Copyright (C) 2000 Kunihiro Ishiguro
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  6.  * GNU Zebra is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  *
  11.  * GNU Zebra is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19.  * 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include <sys/un.h>
  23. #include <setjmp.h>
  24. #include <sys/wait.h>
  25. #include <pwd.h>
  26. #include <readline/readline.h>
  27. #include <readline/history.h>
  28. #include "version.h"
  29. #include "getopt.h"
  30. #include "command.h"
  31. #include "vtysh/vtysh.h"
  32. #include "vtysh/vtysh_user.h"
  33. /* VTY shell program name. */
  34. char *progname;
  35. /* Configuration file name.  Usually this is configurable, but vtysh
  36.    has static configuration file only.  */
  37. char *config_file = NULL;
  38. /* Configuration file and directory. */
  39. char *config_current = NULL;
  40. char config_default[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
  41. /* Integrated configuration file. */
  42. char *integrate_file = NULL;
  43. char *integrate_current = NULL;
  44. #if 0
  45. char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
  46. #endif
  47. /* Flag for indicate executing child command. */
  48. int execute_flag = 0;
  49. /* For sigsetjmp() & siglongjmp(). */
  50. static sigjmp_buf jmpbuf;
  51. /* Flag for avoid recursive siglongjmp() call. */
  52. static int jmpflag = 0;
  53. /* A static variable for holding the line. */
  54. static char *line_read;
  55. /* Master of threads. */
  56. struct thread_master *master;
  57. /* SIGTSTP handler.  This function care user's ^Z input. */
  58. void
  59. sigtstp (int sig)
  60. {
  61.   /* Execute "end" command. */
  62.   vtysh_execute ("end");
  63.   
  64.   /* Initialize readline. */
  65.   rl_initialize ();
  66.   printf ("n");
  67.   /* Check jmpflag for duplicate siglongjmp(). */
  68.   if (! jmpflag)
  69.     return;
  70.   jmpflag = 0;
  71.   /* Back to main command loop. */
  72.   siglongjmp (jmpbuf, 1);
  73. }
  74. /* SIGINT handler.  This function care user's ^Z input.  */
  75. void
  76. sigint (int sig)
  77. {
  78.   /* Check this process is not child process. */
  79.   if (! execute_flag)
  80.     {
  81.       rl_initialize ();
  82.       printf ("n");
  83.       rl_forced_update_display ();
  84.     }
  85. }
  86. /* Signale wrapper. */
  87. RETSIGTYPE *
  88. signal_set (int signo, void (*func)(int))
  89. {
  90.   int ret;
  91.   struct sigaction sig;
  92.   struct sigaction osig;
  93.   sig.sa_handler = func;
  94.   sigemptyset (&sig.sa_mask);
  95.   sig.sa_flags = 0;
  96. #ifdef SA_RESTART
  97.   sig.sa_flags |= SA_RESTART;
  98. #endif /* SA_RESTART */
  99.   ret = sigaction (signo, &sig, &osig);
  100.   if (ret < 0) 
  101.     return (SIG_ERR);
  102.   else
  103.     return (osig.sa_handler);
  104. }
  105. /* Initialization of signal handles. */
  106. void
  107. signal_init ()
  108. {
  109.   signal_set (SIGINT, sigint);
  110.   signal_set (SIGTSTP, sigtstp);
  111.   signal_set (SIGPIPE, SIG_IGN);
  112. }
  113. /* Help information display. */
  114. static void
  115. usage (int status)
  116. {
  117.   if (status != 0)
  118.     fprintf (stderr, "Try `%s --help' for more information.n", progname);
  119.   else
  120.     {    
  121.       printf ("Usage : %s [OPTION...]nn
  122. Daemon which manages kernel routing table management and 
  123. redistribution between different routing protocols.nn
  124. -b, --boot               Execute boot startup configurationn
  125. -e, --eval               Execute argument as commandn
  126. -h, --help               Display this help and exitn
  127. n
  128. Report bugs to %sn", progname, ZEBRA_BUG_ADDRESS);
  129.     }
  130.   exit (status);
  131. }
  132. /* VTY shell options, we use GNU getopt library. */
  133. struct option longopts[] = 
  134. {
  135.   { "boot",                no_argument,             NULL, 'b'},
  136.   { "eval",                 required_argument,       NULL, 'e'},
  137.   { "help",                 no_argument,             NULL, 'h'},
  138.   { 0 }
  139. };
  140. /* Read a string, and return a pointer to it.  Returns NULL on EOF. */
  141. char *
  142. vtysh_rl_gets ()
  143. {
  144.   /* If the buffer has already been allocated, return the memory
  145.      to the free pool. */
  146.   if (line_read)
  147.     {
  148.       free (line_read);
  149.       line_read = NULL;
  150.     }
  151.      
  152.   /* Get a line from the user.  Change prompt according to node.  XXX. */
  153.   line_read = readline (vtysh_prompt ());
  154.      
  155.   /* If the line has any text in it, save it on the history. */
  156.   if (line_read && *line_read)
  157.     add_history (line_read);
  158.      
  159.   return (line_read);
  160. }
  161. /* VTY shell main routine. */
  162. int
  163. main (int argc, char **argv, char **env)
  164. {
  165.   char *p;
  166.   int opt;
  167.   int eval_flag = 0;
  168.   int boot_flag = 0;
  169.   char *eval_line = NULL;
  170.   char *integrated_file = NULL;
  171.   /* Preserve name of myself. */
  172.   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  173.   /* Option handling. */
  174.   while (1) 
  175.     {
  176.       opt = getopt_long (argc, argv, "be:h", longopts, 0);
  177.     
  178.       if (opt == EOF)
  179. break;
  180.       switch (opt) 
  181. {
  182. case 0:
  183.   break;
  184. case 'b':
  185.   boot_flag = 1;
  186.   break;
  187. case 'e':
  188.   eval_flag = 1;
  189.   eval_line = optarg;
  190.   break;
  191. case 'h':
  192.   usage (0);
  193.   break;
  194. case 'i':
  195.   integrated_file = strdup (optarg);
  196. default:
  197.   usage (1);
  198.   break;
  199. }
  200.     }
  201.   /* Initialize user input buffer. */
  202.   line_read = NULL;
  203.   /* Signal and others. */
  204.   signal_init ();
  205.   /* Make vty structure and register commands. */
  206.   vtysh_init_vty ();
  207.   vtysh_init_cmd ();
  208.   vtysh_user_init ();
  209.   vtysh_config_init ();
  210.   vty_init_vtysh ();
  211.   sort_node ();
  212.   vtysh_connect_all ();
  213.   /* Read vtysh configuration file. */
  214.   vtysh_read_config (config_file, config_current, config_default);
  215.   /* If eval mode */
  216.   if (eval_flag)
  217.     {
  218.       vtysh_execute_no_pager (eval_line);
  219.       exit (0);
  220.     }
  221.   
  222.   /* Boot startup configuration file. */
  223.   if (boot_flag)
  224.     {
  225.       vtysh_read_config (integrate_file, integrate_current, integrate_default);
  226.       exit (0);
  227.     }
  228.   vtysh_pager_init ();
  229.   vtysh_readline_init ();
  230.   vty_hello (vty);
  231.   vtysh_auth ();
  232.   /* Preparation for longjmp() in sigtstp(). */
  233.   sigsetjmp (jmpbuf, 1);
  234.   jmpflag = 1;
  235.   /* Main command loop. */
  236.   while (vtysh_rl_gets ())
  237.     vtysh_execute (line_read);
  238.   printf ("n");
  239.   /* Rest in peace. */
  240.   exit (0);
  241. }