LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/tools - lvm.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 2 112 1.8 %
Date: 2010-04-13 Functions: 1 8 12.5 %
Branches: 0 72 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
       4                 :            :  *
       5                 :            :  * This file is part of LVM2.
       6                 :            :  *
       7                 :            :  * This copyrighted material is made available to anyone wishing to use,
       8                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       9                 :            :  * of the GNU General Public License v.2.
      10                 :            :  *
      11                 :            :  * You should have received a copy of the GNU General Public License
      12                 :            :  * along with this program; if not, write to the Free Software Foundation,
      13                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "tools.h"
      17                 :            : #include "lvm2cmdline.h"
      18                 :            : 
      19                 :          1 : int main(int argc, char **argv)
      20                 :            : {
      21                 :          1 :         return lvm2_main(argc, argv);
      22                 :            : }
      23                 :            : 
      24                 :            : #ifdef READLINE_SUPPORT
      25                 :            : 
      26                 :            : #  include <readline/readline.h>
      27                 :            : #  include <readline/history.h>
      28                 :            : #  ifndef HAVE_RL_COMPLETION_MATCHES
      29                 :            : #    define rl_completion_matches(a, b) completion_matches((char *)a, b)
      30                 :            : #  endif
      31                 :            : 
      32                 :            : static struct cmdline_context *_cmdline;
      33                 :            : 
      34                 :            : /* List matching commands */
      35                 :          0 : static char *_list_cmds(const char *text, int state)
      36                 :            : {
      37                 :            :         static int i = 0;
      38                 :            :         static size_t len = 0;
      39                 :            : 
      40                 :            :         /* Initialise if this is a new completion attempt */
      41         [ #  # ]:          0 :         if (!state) {
      42                 :          0 :                 i = 0;
      43                 :          0 :                 len = strlen(text);
      44                 :            :         }
      45                 :            : 
      46         [ #  # ]:          0 :         while (i < _cmdline->num_commands)
      47         [ #  # ]:          0 :                 if (!strncmp(text, _cmdline->commands[i++].name, len))
      48                 :          0 :                         return strdup(_cmdline->commands[i - 1].name);
      49                 :            : 
      50                 :          0 :         return NULL;
      51                 :            : }
      52                 :            : 
      53                 :            : /* List matching arguments */
      54                 :          0 : static char *_list_args(const char *text, int state)
      55                 :            : {
      56                 :            :         static int match_no = 0;
      57                 :            :         static size_t len = 0;
      58                 :            :         static struct command *com;
      59                 :            : 
      60                 :            :         /* Initialise if this is a new completion attempt */
      61         [ #  # ]:          0 :         if (!state) {
      62                 :          0 :                 char *s = rl_line_buffer;
      63                 :          0 :                 int j = 0;
      64                 :            : 
      65                 :          0 :                 match_no = 0;
      66                 :          0 :                 com = NULL;
      67                 :          0 :                 len = strlen(text);
      68                 :            : 
      69                 :            :                 /* Find start of first word in line buffer */
      70         [ #  # ]:          0 :                 while (isspace(*s))
      71                 :          0 :                         s++;
      72                 :            : 
      73                 :            :                 /* Look for word in list of commands */
      74         [ #  # ]:          0 :                 for (j = 0; j < _cmdline->num_commands; j++) {
      75                 :            :                         const char *p;
      76                 :          0 :                         char *q = s;
      77                 :            : 
      78                 :          0 :                         p = _cmdline->commands[j].name;
      79         [ #  # ]:          0 :                         while (*p == *q) {
      80                 :          0 :                                 p++;
      81                 :          0 :                                 q++;
      82                 :            :                         }
      83 [ #  # ][ #  # ]:          0 :                         if ((!*p) && *q == ' ') {
      84                 :          0 :                                 com = _cmdline->commands + j;
      85                 :          0 :                                 break;
      86                 :            :                         }
      87                 :            :                 }
      88                 :            : 
      89         [ #  # ]:          0 :                 if (!com)
      90                 :          0 :                         return NULL;
      91                 :            :         }
      92                 :            : 
      93                 :            :         /* Short form arguments */
      94         [ #  # ]:          0 :         if (len < 3) {
      95         [ #  # ]:          0 :                 while (match_no < com->num_args) {
      96                 :            :                         char s[3];
      97                 :            :                         char c;
      98         [ #  # ]:          0 :                         if (!(c = (_cmdline->the_args +
      99                 :          0 :                                    com->valid_args[match_no++])->short_arg))
     100                 :          0 :                                 continue;
     101                 :            : 
     102                 :          0 :                         sprintf(s, "-%c", c);
     103         [ #  # ]:          0 :                         if (!strncmp(text, s, len))
     104                 :          0 :                                 return strdup(s);
     105                 :            :                 }
     106                 :            :         }
     107                 :            : 
     108                 :            :         /* Long form arguments */
     109         [ #  # ]:          0 :         if (match_no < com->num_args)
     110                 :          0 :                 match_no = com->num_args;
     111                 :            : 
     112         [ #  # ]:          0 :         while (match_no - com->num_args < com->num_args) {
     113                 :            :                 const char *l;
     114                 :          0 :                 l = (_cmdline->the_args +
     115                 :          0 :                      com->valid_args[match_no++ - com->num_args])->long_arg;
     116 [ #  # ][ #  # ]:          0 :                 if (*(l + 2) && !strncmp(text, l, len))
     117                 :          0 :                         return strdup(l);
     118                 :            :         }
     119                 :            : 
     120                 :          0 :         return NULL;
     121                 :            : }
     122                 :            : 
     123                 :            : /* Custom completion function */
     124                 :          0 : static char **_completion(const char *text, int start_pos,
     125                 :            :                           int end_pos __attribute((unused)))
     126                 :            : {
     127                 :          0 :         char **match_list = NULL;
     128                 :          0 :         int p = 0;
     129                 :            : 
     130         [ #  # ]:          0 :         while (isspace((int) *(rl_line_buffer + p)))
     131                 :          0 :                 p++;
     132                 :            : 
     133                 :            :         /* First word should be one of our commands */
     134         [ #  # ]:          0 :         if (start_pos == p)
     135                 :          0 :                 match_list = rl_completion_matches(text, _list_cmds);
     136                 :            : 
     137         [ #  # ]:          0 :         else if (*text == '-')
     138                 :          0 :                 match_list = rl_completion_matches(text, _list_args);
     139                 :            :         /* else other args */
     140                 :            : 
     141                 :            :         /* No further completion */
     142                 :          0 :         rl_attempted_completion_over = 1;
     143                 :          0 :         return match_list;
     144                 :            : }
     145                 :            : 
     146                 :          0 : static int _hist_file(char *buffer, size_t size)
     147                 :            : {
     148                 :          0 :         char *e = getenv("HOME");
     149                 :            : 
     150         [ #  # ]:          0 :         if (dm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
     151                 :          0 :                 log_error("$HOME/.lvm_history: path too long");
     152                 :          0 :                 return 0;
     153                 :            :         }
     154                 :            : 
     155                 :          0 :         return 1;
     156                 :            : }
     157                 :            : 
     158                 :          0 : static void _read_history(struct cmd_context *cmd)
     159                 :            : {
     160                 :            :         char hist_file[PATH_MAX];
     161                 :            : 
     162         [ #  # ]:          0 :         if (!_hist_file(hist_file, sizeof(hist_file)))
     163                 :          0 :                 return;
     164                 :            : 
     165         [ #  # ]:          0 :         if (read_history(hist_file))
     166                 :          0 :                 log_very_verbose("Couldn't read history from %s.", hist_file);
     167                 :            : 
     168                 :          0 :         stifle_history(find_config_tree_int(cmd, "shell/history_size",
     169                 :            :                                        DEFAULT_MAX_HISTORY));
     170                 :            : 
     171                 :            : }
     172                 :            : 
     173                 :          0 : static void _write_history(void)
     174                 :            : {
     175                 :            :         char hist_file[PATH_MAX];
     176                 :            : 
     177         [ #  # ]:          0 :         if (!_hist_file(hist_file, sizeof(hist_file)))
     178                 :          0 :                 return;
     179                 :            : 
     180         [ #  # ]:          0 :         if (write_history(hist_file))
     181                 :          0 :                 log_very_verbose("Couldn't write history to %s.", hist_file);
     182                 :            : }
     183                 :            : 
     184                 :          0 : int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline)
     185                 :            : {
     186                 :            :         int argc, ret;
     187                 :          0 :         char *input = NULL, *args[MAX_ARGS], **argv;
     188                 :            : 
     189                 :          0 :         rl_readline_name = "lvm";
     190                 :          0 :         rl_attempted_completion_function = (CPPFunction *) _completion;
     191                 :            : 
     192                 :          0 :         _read_history(cmd);
     193                 :            : 
     194                 :          0 :         _cmdline = cmdline;
     195                 :            : 
     196                 :          0 :         _cmdline->interactive = 1;
     197                 :            :         while (1) {
     198                 :          0 :                 free(input);
     199                 :          0 :                 input = readline("lvm> ");
     200                 :            : 
     201                 :            :                 /* EOF */
     202         [ #  # ]:          0 :                 if (!input) {
     203                 :          0 :                         printf("\n");
     204                 :          0 :                         break;
     205                 :            :                 }
     206                 :            : 
     207                 :            :                 /* empty line */
     208         [ #  # ]:          0 :                 if (!*input)
     209                 :          0 :                         continue;
     210                 :            : 
     211                 :          0 :                 add_history(input);
     212                 :            : 
     213                 :          0 :                 argv = args;
     214                 :            : 
     215         [ #  # ]:          0 :                 if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
     216                 :          0 :                         log_error("Too many arguments, sorry.");
     217                 :          0 :                         continue;
     218                 :            :                 }
     219                 :            : 
     220         [ #  # ]:          0 :                 if (!strcmp(argv[0], "lvm")) {
     221                 :          0 :                         argv++;
     222                 :          0 :                         argc--;
     223                 :            :                 }
     224                 :            : 
     225         [ #  # ]:          0 :                 if (!argc)
     226                 :          0 :                         continue;
     227                 :            : 
     228 [ #  # ][ #  # ]:          0 :                 if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit")) {
     229                 :          0 :                         remove_history(history_length - 1);
     230                 :          0 :                         log_error("Exiting.");
     231                 :          0 :                         break;
     232                 :            :                 }
     233                 :            : 
     234                 :          0 :                 ret = lvm_run_command(cmd, argc, argv);
     235         [ #  # ]:          0 :                 if (ret == ENO_SUCH_CMD)
     236                 :          0 :                         log_error("No such command '%s'.  Try 'help'.",
     237                 :            :                                   argv[0]);
     238                 :            : 
     239 [ #  # ][ #  # ]:          0 :                 if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
     240                 :          0 :                         log_debug(INTERNAL_ERROR "Failed command did not use log_error");
     241                 :          0 :                         log_error("Command failed with status code %d.", ret);
     242                 :            :                 }
     243                 :          0 :                 _write_history();
     244                 :          0 :         }
     245                 :            : 
     246                 :          0 :         free(input);
     247                 :          0 :         return 0;
     248                 :            : }
     249                 :            : 
     250                 :            : #endif  /* READLINE_SUPPORT */

Generated by: LCOV version 1.8