2
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
5
* This file is part of LVM2.
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.
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
17
#include "lvm2cmdline.h"
19
int main(int argc, char **argv)
21
return lvm2_main(argc, argv);
24
#ifdef READLINE_SUPPORT
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)
32
static struct cmdline_context *_cmdline;
34
/* List matching commands */
35
static char *_list_cmds(const char *text, int state)
38
static size_t len = 0;
40
/* Initialise if this is a new completion attempt */
46
while (i < _cmdline->num_commands)
47
if (!strncmp(text, _cmdline->commands[i++].name, len))
48
return strdup(_cmdline->commands[i - 1].name);
53
/* List matching arguments */
54
static char *_list_args(const char *text, int state)
56
static int match_no = 0;
57
static size_t len = 0;
58
static struct command *com;
60
/* Initialise if this is a new completion attempt */
62
char *s = rl_line_buffer;
69
/* Find start of first word in line buffer */
73
/* Look for word in list of commands */
74
for (j = 0; j < _cmdline->num_commands; j++) {
78
p = _cmdline->commands[j].name;
83
if ((!*p) && *q == ' ') {
84
com = _cmdline->commands + j;
93
/* Short form arguments */
95
while (match_no < com->num_args) {
98
if (!(c = (_cmdline->arg_props +
99
com->valid_args[match_no++])->short_arg))
102
sprintf(s, "-%c", c);
103
if (!strncmp(text, s, len))
108
/* Long form arguments */
109
if (match_no < com->num_args)
110
match_no = com->num_args;
112
while (match_no - com->num_args < com->num_args) {
114
l = (_cmdline->arg_props +
115
com->valid_args[match_no++ - com->num_args])->long_arg;
116
if (*(l + 2) && !strncmp(text, l, len))
123
/* Custom completion function */
124
static char **_completion(const char *text, int start_pos,
125
int end_pos __attribute__((unused)))
127
char **match_list = NULL;
130
while (isspace((int) *(rl_line_buffer + p)))
133
/* First word should be one of our commands */
135
match_list = rl_completion_matches(text, _list_cmds);
137
else if (*text == '-')
138
match_list = rl_completion_matches(text, _list_args);
139
/* else other args */
141
/* No further completion */
142
rl_attempted_completion_over = 1;
146
static int _hist_file(char *buffer, size_t size)
148
char *e = getenv("HOME");
150
if (dm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
151
log_error("$HOME/.lvm_history: path too long");
158
static void _read_history(struct cmd_context *cmd)
160
char hist_file[PATH_MAX];
162
if (!_hist_file(hist_file, sizeof(hist_file)))
165
if (read_history(hist_file))
166
log_very_verbose("Couldn't read history from %s.", hist_file);
168
stifle_history(find_config_tree_int(cmd, "shell/history_size",
169
DEFAULT_MAX_HISTORY));
172
static void _write_history(void)
174
char hist_file[PATH_MAX];
176
if (!_hist_file(hist_file, sizeof(hist_file)))
179
if (write_history(hist_file))
180
log_very_verbose("Couldn't write history to %s.", hist_file);
183
int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline)
186
char *input = NULL, *args[MAX_ARGS], **argv;
188
rl_readline_name = "lvm";
189
rl_attempted_completion_function = (CPPFunction *) _completion;
195
_cmdline->interactive = 1;
198
input = readline("lvm> ");
214
if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
215
log_error("Too many arguments, sorry.");
222
if (!strcmp(argv[0], "lvm")) {
230
if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit")) {
231
remove_history(history_length - 1);
232
log_error("Exiting.");
236
ret = lvm_run_command(cmd, argc, argv);
237
if (ret == ENO_SUCH_CMD)
238
log_error("No such command '%s'. Try 'help'.",
241
if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
242
log_debug(INTERNAL_ERROR "Failed command did not use log_error");
243
log_error("Command failed with status code %d.", ret);
252
#endif /* READLINE_SUPPORT */