~xnox/ubuntu/quantal/lvm2/merge95

« back to all changes in this revision

Viewing changes to .pc/implicit-pointer.patch/tools/lvm.c

  • Committer: Dmitrijs Ledkovs
  • Date: 2012-08-15 09:45:58 UTC
  • Revision ID: dmitrijs.ledkovs@canonical.com-20120815094558-1fugetlxzs49g6g9
quilt push

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
int main(int argc, char **argv)
 
20
{
 
21
        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
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
        if (!state) {
 
42
                i = 0;
 
43
                len = strlen(text);
 
44
        }
 
45
 
 
46
        while (i < _cmdline->num_commands)
 
47
                if (!strncmp(text, _cmdline->commands[i++].name, len))
 
48
                        return strdup(_cmdline->commands[i - 1].name);
 
49
 
 
50
        return NULL;
 
51
}
 
52
 
 
53
/* List matching arguments */
 
54
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
        if (!state) {
 
62
                char *s = rl_line_buffer;
 
63
                int j;
 
64
 
 
65
                match_no = 0;
 
66
                com = NULL;
 
67
                len = strlen(text);
 
68
 
 
69
                /* Find start of first word in line buffer */
 
70
                while (isspace(*s))
 
71
                        s++;
 
72
 
 
73
                /* Look for word in list of commands */
 
74
                for (j = 0; j < _cmdline->num_commands; j++) {
 
75
                        const char *p;
 
76
                        char *q = s;
 
77
 
 
78
                        p = _cmdline->commands[j].name;
 
79
                        while (*p == *q) {
 
80
                                p++;
 
81
                                q++;
 
82
                        }
 
83
                        if ((!*p) && *q == ' ') {
 
84
                                com = _cmdline->commands + j;
 
85
                                break;
 
86
                        }
 
87
                }
 
88
        }
 
89
 
 
90
        if (!com)
 
91
                return NULL;
 
92
 
 
93
        /* Short form arguments */
 
94
        if (len < 3) {
 
95
                while (match_no < com->num_args) {
 
96
                        char s[3];
 
97
                        char c;
 
98
                        if (!(c = (_cmdline->arg_props +
 
99
                                   com->valid_args[match_no++])->short_arg))
 
100
                                continue;
 
101
 
 
102
                        sprintf(s, "-%c", c);
 
103
                        if (!strncmp(text, s, len))
 
104
                                return strdup(s);
 
105
                }
 
106
        }
 
107
 
 
108
        /* Long form arguments */
 
109
        if (match_no < com->num_args)
 
110
                match_no = com->num_args;
 
111
 
 
112
        while (match_no - com->num_args < com->num_args) {
 
113
                const char *l;
 
114
                l = (_cmdline->arg_props +
 
115
                     com->valid_args[match_no++ - com->num_args])->long_arg;
 
116
                if (*(l + 2) && !strncmp(text, l, len))
 
117
                        return strdup(l);
 
118
        }
 
119
 
 
120
        return NULL;
 
121
}
 
122
 
 
123
/* Custom completion function */
 
124
static char **_completion(const char *text, int start_pos,
 
125
                          int end_pos __attribute__((unused)))
 
126
{
 
127
        char **match_list = NULL;
 
128
        int p = 0;
 
129
 
 
130
        while (isspace((int) *(rl_line_buffer + p)))
 
131
                p++;
 
132
 
 
133
        /* First word should be one of our commands */
 
134
        if (start_pos == p)
 
135
                match_list = rl_completion_matches(text, _list_cmds);
 
136
 
 
137
        else if (*text == '-')
 
138
                match_list = rl_completion_matches(text, _list_args);
 
139
        /* else other args */
 
140
 
 
141
        /* No further completion */
 
142
        rl_attempted_completion_over = 1;
 
143
        return match_list;
 
144
}
 
145
 
 
146
static int _hist_file(char *buffer, size_t size)
 
147
{
 
148
        char *e = getenv("HOME");
 
149
 
 
150
        if (dm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
 
151
                log_error("$HOME/.lvm_history: path too long");
 
152
                return 0;
 
153
        }
 
154
 
 
155
        return 1;
 
156
}
 
157
 
 
158
static void _read_history(struct cmd_context *cmd)
 
159
{
 
160
        char hist_file[PATH_MAX];
 
161
 
 
162
        if (!_hist_file(hist_file, sizeof(hist_file)))
 
163
                return;
 
164
 
 
165
        if (read_history(hist_file))
 
166
                log_very_verbose("Couldn't read history from %s.", hist_file);
 
167
 
 
168
        stifle_history(find_config_tree_int(cmd, "shell/history_size",
 
169
                                       DEFAULT_MAX_HISTORY));
 
170
}
 
171
 
 
172
static void _write_history(void)
 
173
{
 
174
        char hist_file[PATH_MAX];
 
175
 
 
176
        if (!_hist_file(hist_file, sizeof(hist_file)))
 
177
                return;
 
178
 
 
179
        if (write_history(hist_file))
 
180
                log_very_verbose("Couldn't write history to %s.", hist_file);
 
181
}
 
182
 
 
183
int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline)
 
184
{
 
185
        int argc, ret;
 
186
        char *input = NULL, *args[MAX_ARGS], **argv;
 
187
 
 
188
        rl_readline_name = "lvm";
 
189
        rl_attempted_completion_function = (CPPFunction *) _completion;
 
190
 
 
191
        _read_history(cmd);
 
192
 
 
193
        _cmdline = cmdline;
 
194
 
 
195
        _cmdline->interactive = 1;
 
196
        while (1) {
 
197
                free(input);
 
198
                input = readline("lvm> ");
 
199
 
 
200
                /* EOF */
 
201
                if (!input) {
 
202
                        printf("\n");
 
203
                        break;
 
204
                }
 
205
 
 
206
                /* empty line */
 
207
                if (!*input)
 
208
                        continue;
 
209
 
 
210
                add_history(input);
 
211
 
 
212
                argv = args;
 
213
 
 
214
                if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
 
215
                        log_error("Too many arguments, sorry.");
 
216
                        continue;
 
217
                }
 
218
 
 
219
                if (!argc)
 
220
                        continue;
 
221
 
 
222
                if (!strcmp(argv[0], "lvm")) {
 
223
                        argv++;
 
224
                        argc--;
 
225
                }
 
226
 
 
227
                if (!argc)
 
228
                        continue;
 
229
 
 
230
                if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit")) {
 
231
                        remove_history(history_length - 1);
 
232
                        log_error("Exiting.");
 
233
                        break;
 
234
                }
 
235
 
 
236
                ret = lvm_run_command(cmd, argc, argv);
 
237
                if (ret == ENO_SUCH_CMD)
 
238
                        log_error("No such command '%s'.  Try 'help'.",
 
239
                                  argv[0]);
 
240
 
 
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);
 
244
                }
 
245
                _write_history();
 
246
        }
 
247
 
 
248
        free(input);
 
249
        return 0;
 
250
}
 
251
 
 
252
#endif  /* READLINE_SUPPORT */