2 * vsh.c: common data to be used by clients to exercise the libvirt API
4 * Copyright (C) 2005-2019 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
36 # include <readline/readline.h>
37 # include <readline/history.h>
42 #include "virbuffer.h"
44 #include <libvirt/libvirt-qemu.h>
45 #include <libvirt/libvirt-lxc.h>
47 #include "virthread.h"
48 #include "vircommand.h"
49 #include "conf/domain_conf.h"
50 #include "virtypedparam.h"
51 #include "virstring.h"
53 /* Gnulib doesn't guarantee SA_SIGINFO support. */
59 /* For autocompletion */
60 vshControl
*autoCompleteOpaque
;
63 /* NOTE: It would be much nicer to have these two as part of vshControl
64 * structure, unfortunately readline doesn't support passing opaque data
65 * and only relies on static data accessible from the user-side callback
67 const vshCmdGrp
*cmdGroups
;
68 const vshCmdDef
*cmdSet
;
71 /* simple handler for oom conditions */
76 fputs(_("error: Out of memory\n"), stderr
);
83 vshPrettyCapacity(unsigned long long val
, const char **unit
)
94 return val
/ (limit
/ 1024);
99 return val
/ (limit
/ 1024);
104 return val
/ (limit
/ 1024);
109 return val
/ (limit
/ 1024);
114 return val
/ (limit
/ 1024);
118 return val
/ (limit
/ 1024);
123 _vshMalloc(vshControl
*ctl
, size_t size
, const char *filename
, int line
)
127 if (VIR_ALLOC_N(x
, size
) == 0)
129 vshError(ctl
, _("%s: %d: failed to allocate %d bytes"),
130 filename
, line
, (int) size
);
135 _vshCalloc(vshControl
*ctl
, size_t nmemb
, size_t size
, const char *filename
,
140 if (!xalloc_oversized(nmemb
, size
) &&
141 VIR_ALLOC_N(x
, nmemb
* size
) == 0)
143 vshError(ctl
, _("%s: %d: failed to allocate %d bytes"),
144 filename
, line
, (int) (size
*nmemb
));
149 _vshStrdup(vshControl
*ctl
, const char *s
, const char *filename
, int line
)
153 if (VIR_STRDUP(x
, s
) >= 0)
155 vshError(ctl
, _("%s: %d: failed to allocate %lu bytes"),
156 filename
, line
, (unsigned long)strlen(s
));
161 vshNameSorter(const void *a
, const void *b
)
163 const char **sa
= (const char**)a
;
164 const char **sb
= (const char**)b
;
166 return vshStrcasecmp(*sa
, *sb
);
171 * Convert the strings separated by ',' into array. The returned
172 * array is a NULL terminated string list. The caller has to free
173 * the array using virStringListFree or a similar method.
175 * Returns the length of the filled array on success, or -1
179 vshStringToArray(const char *str
,
182 char *str_copied
= vshStrdup(NULL
, str
);
183 char *str_tok
= NULL
;
185 unsigned int nstr_tokens
= 0;
187 size_t len
= strlen(str_copied
);
189 /* tokenize the string from user and save its parts into an array */
192 /* count the delimiters, recognizing ,, as an escape for a
194 str_tok
= str_copied
;
195 while ((str_tok
= strchr(str_tok
, ','))) {
196 if (str_tok
[1] == ',')
203 /* reserve the NULL element at the end */
204 if (VIR_ALLOC_N(arr
, nstr_tokens
+ 1) < 0) {
205 VIR_FREE(str_copied
);
209 /* tokenize the input string, while treating ,, as a literal comma */
211 tmp
= str_tok
= str_copied
;
212 while ((tmp
= strchr(tmp
, ','))) {
214 memmove(&tmp
[1], &tmp
[2], len
- (tmp
- str_copied
) - 2 + 1);
220 arr
[nstr_tokens
++] = vshStrdup(NULL
, str_tok
);
223 arr
[nstr_tokens
++] = vshStrdup(NULL
, str_tok
);
226 VIR_FREE(str_copied
);
230 virErrorPtr last_error
;
233 * Quieten libvirt until we're done with the command.
236 vshErrorHandler(void *opaque ATTRIBUTE_UNUSED
,
237 virErrorPtr error ATTRIBUTE_UNUSED
)
239 virFreeError(last_error
);
240 last_error
= virSaveLastError();
243 /* Store a libvirt error that is from a helper API that doesn't raise errors
244 * so it doesn't get overwritten */
246 vshSaveLibvirtError(void)
248 virFreeError(last_error
);
249 last_error
= virSaveLastError();
253 /* Store libvirt error from helper API but don't overwrite existing errors */
255 vshSaveLibvirtHelperError(void)
260 if (virGetLastErrorCode() == VIR_ERR_OK
)
263 vshSaveLibvirtError();
268 * Reset libvirt error on graceful fallback paths
271 vshResetLibvirtError(void)
273 virFreeError(last_error
);
279 * Report an error when a command finishes. This is better than before
280 * (when correct operation would report errors), but it has some
281 * problems: we lose the smarter formatting of virDefaultErrorFunc(),
282 * and it can become harder to debug problems, if errors get reported
283 * twice during one command. This case shouldn't really happen anyway,
284 * and it's IMHO a bug that libvirt does that sometimes.
287 vshReportError(vshControl
*ctl
)
289 if (last_error
== NULL
) {
290 /* Calling directly into libvirt util functions won't trigger the
291 * error callback (which sets last_error), so check it ourselves.
293 * If the returned error has CODE_OK, this most likely means that
294 * no error was ever raised, so just ignore */
295 last_error
= virSaveLastError();
296 if (!last_error
|| last_error
->code
== VIR_ERR_OK
)
300 if (last_error
->code
== VIR_ERR_OK
) {
301 vshError(ctl
, "%s", _("unknown error"));
305 vshError(ctl
, "%s", last_error
->message
);
308 vshResetLibvirtError();
312 * Detection of disconnections and automatic reconnection support
314 static int disconnected
; /* we may have been disconnected */
317 * Utils for work with command definition
321 vshCmddefGetInfo(const vshCmdDef
* cmd
, const char *name
)
323 const vshCmdInfo
*info
;
325 for (info
= cmd
->info
; info
&& info
->name
; info
++) {
326 if (STREQ(info
->name
, name
))
332 /* Check if the internal command definitions are correct */
334 vshCmddefCheckInternals(vshControl
*ctl
,
335 const vshCmdDef
*cmd
)
338 const char *help
= NULL
;
340 /* in order to perform the validation resolve the alias first */
341 if (cmd
->flags
& VSH_CMD_FLAG_ALIAS
) {
343 vshError(ctl
, _("command '%s' has inconsistent alias"), cmd
->name
);
346 cmd
= vshCmddefSearch(cmd
->alias
);
349 /* Each command has to provide a non-empty help string. */
350 if (!(help
= vshCmddefGetInfo(cmd
, "help")) || !*help
) {
351 vshError(ctl
, _("command '%s' lacks help"), cmd
->name
);
358 for (i
= 0; cmd
->opts
[i
].name
; i
++) {
359 const vshCmdOptDef
*opt
= &cmd
->opts
[i
];
362 vshError(ctl
, _("command '%s' has too many options"), cmd
->name
);
363 return -1; /* too many options */
369 if (opt
->flags
& VSH_OFLAG_REQ
) {
370 vshError(ctl
, _("command '%s' misused VSH_OFLAG_REQ"),
372 return -1; /* neither bool nor string options can be mandatory */
378 char *name
= (char *)opt
->help
; /* cast away const */
381 if (opt
->flags
|| !opt
->help
) {
382 vshError(ctl
, _("command '%s' has incorrect alias option"),
384 return -1; /* alias options are tracked by the original name */
386 if ((p
= strchr(name
, '=')) &&
387 VIR_STRNDUP(name
, name
, p
- name
) < 0)
389 for (j
= i
+ 1; cmd
->opts
[j
].name
; j
++) {
390 if (STREQ(name
, cmd
->opts
[j
].name
) &&
391 cmd
->opts
[j
].type
!= VSH_OT_ALIAS
)
394 if (name
!= opt
->help
) {
396 /* If alias comes with value, replacement must not be bool */
397 if (cmd
->opts
[j
].type
== VSH_OT_BOOL
) {
398 vshError(ctl
, _("command '%s' has mismatched alias type"),
403 if (!cmd
->opts
[j
].name
) {
404 vshError(ctl
, _("command '%s' has missing alias option"),
406 return -1; /* alias option must map to a later option name */
411 if (cmd
->opts
[i
+ 1].name
) {
412 vshError(ctl
, _("command '%s' does not list argv option last"),
414 return -1; /* argv option must be listed last */
419 if (!(opt
->flags
& VSH_OFLAG_REQ
)) {
420 vshError(ctl
, _("command '%s' has non-required VSH_OT_DATA"),
422 return -1; /* OT_DATA should always be required. */
433 /* Parse the options associated with @cmd, i.e. test whether options are
434 * required or need an argument.
436 * Returns -1 on error or 0 on success, filling the caller-provided bitmaps
437 * which keep track of required options and options needing an argument.
440 vshCmddefOptParse(const vshCmdDef
*cmd
, uint64_t *opts_need_arg
,
441 uint64_t *opts_required
)
444 bool optional
= false;
452 for (i
= 0; cmd
->opts
[i
].name
; i
++) {
453 const vshCmdOptDef
*opt
= &cmd
->opts
[i
];
455 if (opt
->type
== VSH_OT_BOOL
) {
460 if (opt
->flags
& VSH_OFLAG_REQ_OPT
) {
461 if (opt
->flags
& VSH_OFLAG_REQ
)
462 *opts_required
|= 1ULL << i
;
468 if (opt
->type
== VSH_OT_ALIAS
)
469 continue; /* skip the alias option */
471 *opts_need_arg
|= 1ULL << i
;
472 if (opt
->flags
& VSH_OFLAG_REQ
) {
473 if (optional
&& opt
->type
!= VSH_OT_ARGV
)
474 return -1; /* mandatory options must be listed first */
475 *opts_required
|= 1ULL << i
;
484 static vshCmdOptDef helpopt
= {
487 .help
= N_("print help for this function")
489 static const vshCmdOptDef
*
490 vshCmddefGetOption(vshControl
*ctl
, const vshCmdDef
*cmd
, const char *name
,
491 uint64_t *opts_seen
, size_t *opt_index
, char **optstr
,
495 const vshCmdOptDef
*ret
= NULL
;
498 if (STREQ(name
, helpopt
.name
))
501 for (i
= 0; cmd
->opts
&& cmd
->opts
[i
].name
; i
++) {
502 const vshCmdOptDef
*opt
= &cmd
->opts
[i
];
504 if (STREQ(opt
->name
, name
)) {
505 if (opt
->type
== VSH_OT_ALIAS
) {
508 /* Two types of replacements:
509 opt->help = "string": straight replacement of name
510 opt->help = "string=value": treat boolean flag as
511 alias of option and its default value */
513 if (VIR_STRDUP(alias
, opt
->help
) < 0)
516 if ((value
= strchr(name
, '='))) {
520 vshError(ctl
, _("invalid '=' after option --%s"),
524 if (VIR_STRDUP(*optstr
, value
+ 1) < 0)
529 if ((*opts_seen
& (1ULL << i
)) && opt
->type
!= VSH_OT_ARGV
) {
531 vshError(ctl
, _("option --%s already seen"), name
);
534 *opts_seen
|= 1ULL << i
;
541 if (STRNEQ(cmd
->name
, "help") && report
) {
542 vshError(ctl
, _("command '%s' doesn't support option --%s"),
550 static const vshCmdOptDef
*
551 vshCmddefGetData(const vshCmdDef
*cmd
, uint64_t *opts_need_arg
,
555 const vshCmdOptDef
*opt
;
560 /* Grab least-significant set bit */
561 i
= ffsl(*opts_need_arg
) - 1;
563 if (opt
->type
!= VSH_OT_ARGV
)
564 *opts_need_arg
&= ~(1ULL << i
);
565 *opts_seen
|= 1ULL << i
;
570 * Checks for required options
573 vshCommandCheckOpts(vshControl
*ctl
, const vshCmd
*cmd
, uint64_t opts_required
,
576 const vshCmdDef
*def
= cmd
->def
;
579 opts_required
&= ~opts_seen
;
583 for (i
= 0; def
->opts
[i
].name
; i
++) {
584 if (opts_required
& (1ULL << i
)) {
585 const vshCmdOptDef
*opt
= &def
->opts
[i
];
588 opt
->type
== VSH_OT_DATA
|| opt
->type
== VSH_OT_ARGV
?
589 _("command '%s' requires <%s> option") :
590 _("command '%s' requires --%s option"),
591 def
->name
, opt
->name
);
597 static const vshCmdDef
*
598 vshCmdDefSearchGrp(const char *cmdname
)
603 for (g
= cmdGroups
; g
->name
; g
++) {
604 for (c
= g
->commands
; c
->name
; c
++) {
605 if (STREQ(c
->name
, cmdname
))
613 static const vshCmdDef
*
614 vshCmdDefSearchSet(const char *cmdname
)
618 for (s
= cmdSet
; s
->name
; s
++) {
619 if (STREQ(s
->name
, cmdname
))
627 vshCmddefSearch(const char *cmdname
)
630 return vshCmdDefSearchGrp(cmdname
);
632 return vshCmdDefSearchSet(cmdname
);
636 vshCmdGrpSearch(const char *grpname
)
640 for (g
= cmdGroups
; g
->name
; g
++) {
641 if (STREQ(g
->name
, grpname
) || STREQ(g
->keyword
, grpname
))
649 vshCmdGrpHelp(vshControl
*ctl
, const vshCmdGrp
*grp
)
651 const vshCmdDef
*cmd
= NULL
;
653 vshPrint(ctl
, _(" %s (help keyword '%s'):\n"), grp
->name
,
656 for (cmd
= grp
->commands
; cmd
->name
; cmd
++) {
657 if (cmd
->flags
& VSH_CMD_FLAG_ALIAS
)
659 vshPrint(ctl
, " %-30s %s\n", cmd
->name
,
660 _(vshCmddefGetInfo(cmd
, "help")));
667 vshCmddefHelp(vshControl
*ctl
, const vshCmdDef
*def
)
669 const char *desc
= NULL
;
671 uint64_t opts_need_arg
;
672 uint64_t opts_required
;
673 bool shortopt
= false; /* true if 'arg' works instead of '--opt arg' */
675 if (vshCmddefOptParse(def
, &opts_need_arg
, &opts_required
)) {
676 vshError(ctl
, _("internal error: bad options in command: '%s'"),
681 fputs(_(" NAME\n"), stdout
);
682 fprintf(stdout
, " %s - %s\n", def
->name
,
683 _(vshCmddefGetInfo(def
, "help")));
685 fputs(_("\n SYNOPSIS\n"), stdout
);
686 fprintf(stdout
, " %s", def
->name
);
688 const vshCmdOptDef
*opt
;
689 for (opt
= def
->opts
; opt
->name
; opt
++) {
690 const char *fmt
= "%s";
696 /* xgettext:c-format */
697 fmt
= ((opt
->flags
& VSH_OFLAG_REQ
) ? "<%s>"
698 : _("[--%s <number>]"));
699 if (!(opt
->flags
& VSH_OFLAG_REQ_OPT
))
703 /* xgettext:c-format */
704 fmt
= _("[--%s <string>]");
705 if (!(opt
->flags
& VSH_OFLAG_REQ_OPT
))
709 fmt
= ((opt
->flags
& VSH_OFLAG_REQ
) ? "<%s>" : "[<%s>]");
710 if (!(opt
->flags
& VSH_OFLAG_REQ_OPT
))
714 /* xgettext:c-format */
716 fmt
= (opt
->flags
& VSH_OFLAG_REQ
)
717 ? _("{[--%s] <string>}...")
718 : _("[[--%s] <string>]...");
720 fmt
= (opt
->flags
& VSH_OFLAG_REQ
) ? _("<%s>...")
725 /* aliases are intentionally undocumented */
729 fprintf(stdout
, fmt
, opt
->name
);
734 desc
= vshCmddefGetInfo(def
, "desc");
736 /* Print the description only if it's not empty. */
737 fputs(_("\n DESCRIPTION\n"), stdout
);
738 fprintf(stdout
, " %s\n", _(desc
));
741 if (def
->opts
&& def
->opts
->name
) {
742 const vshCmdOptDef
*opt
;
743 fputs(_("\n OPTIONS\n"), stdout
);
744 for (opt
= def
->opts
; opt
->name
; opt
++) {
747 snprintf(buf
, sizeof(buf
), "--%s", opt
->name
);
750 snprintf(buf
, sizeof(buf
),
751 (opt
->flags
& VSH_OFLAG_REQ
) ? _("[--%s] <number>")
752 : _("--%s <number>"), opt
->name
);
755 snprintf(buf
, sizeof(buf
), _("--%s <string>"), opt
->name
);
758 snprintf(buf
, sizeof(buf
), _("[--%s] <string>"),
762 snprintf(buf
, sizeof(buf
),
763 shortopt
? _("[--%s] <string>") : _("<%s>"),
770 fprintf(stdout
, " %-15s %s\n", buf
, _(opt
->help
));
779 * Utils for work with runtime commands data
783 vshCommandOptFree(vshCmdOpt
* arg
)
798 vshCommandFree(vshCmd
*cmd
)
807 vshCommandOptFree(tmp
->opts
);
814 * @cmd: parsed command line to search
815 * @name: option name to search for
816 * @opt: result of the search
817 * @needData: true if option must be non-boolean
819 * Look up an option passed to CMD by NAME. Returns 1 with *OPT set
820 * to the option if found, 0 with *OPT set to NULL if the name is
821 * valid and the option is not required, -1 with *OPT set to NULL if
822 * the option is required but not present, and assert if NAME is not
823 * valid (which indicates a programming error) unless cmd->skipChecks
824 * is set. No error messages are issued if a value is returned.
827 vshCommandOpt(const vshCmd
*cmd
, const char *name
, vshCmdOpt
**opt
,
830 vshCmdOpt
*candidate
= cmd
->opts
;
831 const vshCmdOptDef
*valid
= cmd
->def
->opts
;
834 /* See if option is valid and/or required. */
837 while (valid
&& valid
->name
) {
838 if (STREQ(name
, valid
->name
))
843 if (!cmd
->skipChecks
)
844 assert(valid
&& (!needData
|| valid
->type
!= VSH_OT_BOOL
));
846 if (valid
&& valid
->flags
& VSH_OFLAG_REQ
)
849 /* See if option is present on command line. */
851 if (STREQ(candidate
->def
->name
, name
)) {
856 candidate
= candidate
->next
;
863 * @ctl virtshell control structure
864 * @cmd command reference
868 * Convert option to int.
869 * On error, a message is displayed.
872 * >0 if option found and valid (@value updated)
873 * 0 if option not found and not required (@value untouched)
874 * <0 in all other cases (@value untouched)
877 vshCommandOptInt(vshControl
*ctl
, const vshCmd
*cmd
,
878 const char *name
, int *value
)
883 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
886 if ((ret
= virStrToLong_i(arg
->data
, NULL
, 10, value
)) < 0)
888 _("Numeric value '%s' for <%s> option is malformed or out of range"),
897 vshCommandOptUIntInternal(vshControl
*ctl
,
906 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
910 ret
= virStrToLong_ui(arg
->data
, NULL
, 10, value
);
912 ret
= virStrToLong_uip(arg
->data
, NULL
, 10, value
);
915 _("Numeric value '%s' for <%s> option is malformed or out of range"),
925 * @ctl virtshell control structure
926 * @cmd command reference
930 * Convert option to unsigned int, reject negative numbers
931 * See vshCommandOptInt()
934 vshCommandOptUInt(vshControl
*ctl
, const vshCmd
*cmd
,
935 const char *name
, unsigned int *value
)
937 return vshCommandOptUIntInternal(ctl
, cmd
, name
, value
, false);
941 * vshCommandOptUIntWrap:
942 * @ctl virtshell control structure
943 * @cmd command reference
947 * Convert option to unsigned int, wraps negative numbers to positive
948 * See vshCommandOptInt()
951 vshCommandOptUIntWrap(vshControl
*ctl
, const vshCmd
*cmd
,
952 const char *name
, unsigned int *value
)
954 return vshCommandOptUIntInternal(ctl
, cmd
, name
, value
, true);
958 vshCommandOptULInternal(vshControl
*ctl
,
961 unsigned long *value
,
967 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
971 ret
= virStrToLong_ul(arg
->data
, NULL
, 10, value
);
973 ret
= virStrToLong_ulp(arg
->data
, NULL
, 10, value
);
976 _("Numeric value '%s' for <%s> option is malformed or out of range"),
986 * @ctl virtshell control structure
987 * @cmd command reference
991 * Convert option to unsigned long
992 * See vshCommandOptInt()
995 vshCommandOptUL(vshControl
*ctl
, const vshCmd
*cmd
,
996 const char *name
, unsigned long *value
)
998 return vshCommandOptULInternal(ctl
, cmd
, name
, value
, false);
1002 * vshCommandOptULWrap:
1003 * @ctl virtshell control structure
1004 * @cmd command reference
1008 * Convert option to unsigned long, wraps negative numbers to positive
1009 * See vshCommandOptInt()
1012 vshCommandOptULWrap(vshControl
*ctl
, const vshCmd
*cmd
,
1013 const char *name
, unsigned long *value
)
1015 return vshCommandOptULInternal(ctl
, cmd
, name
, value
, true);
1019 * vshCommandOptStringQuiet:
1020 * @ctl virtshell control structure
1021 * @cmd command reference
1025 * Returns option as STRING. On error -1 is returned but no error is set.
1027 * >0 if option found and valid (@value updated)
1028 * 0 if option not found and not required (@value untouched)
1029 * <0 in all other cases (@value untouched)
1032 vshCommandOptStringQuiet(vshControl
*ctl ATTRIBUTE_UNUSED
, const vshCmd
*cmd
,
1033 const char *name
, const char **value
)
1038 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
1041 if (!*arg
->data
&& !(arg
->def
->flags
& VSH_OFLAG_EMPTY_OK
))
1048 * vshCommandOptStringReq:
1049 * @ctl virtshell control structure
1050 * @cmd command structure
1052 * @value result (updated to NULL or the option argument)
1054 * Gets a option argument as string.
1056 * Returns 0 on success or when the option is not present and not
1057 * required, *value is set to the option argument. On error -1 is
1058 * returned and error message printed.
1061 vshCommandOptStringReq(vshControl
*ctl
,
1068 const char *error
= NULL
;
1070 /* clear out the value */
1073 ret
= vshCommandOpt(cmd
, name
, &arg
, true);
1074 /* option is not required and not present */
1077 /* this should not be propagated here, just to be sure */
1079 error
= N_("Mandatory option not present");
1080 else if (!*arg
->data
&& !(arg
->def
->flags
& VSH_OFLAG_EMPTY_OK
))
1081 error
= N_("Option argument is empty");
1084 if (!cmd
->skipChecks
)
1085 vshError(ctl
, _("Failed to get option '%s': %s"), name
, _(error
));
1094 * vshCommandOptLongLong:
1095 * @ctl virtshell control structure
1096 * @cmd command reference
1100 * Returns option as long long
1101 * See vshCommandOptInt()
1104 vshCommandOptLongLong(vshControl
*ctl
, const vshCmd
*cmd
,
1105 const char *name
, long long *value
)
1110 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
1113 if ((ret
= virStrToLong_ll(arg
->data
, NULL
, 10, value
)) < 0)
1115 _("Numeric value '%s' for <%s> option is malformed or out of range"),
1124 vshCommandOptULongLongInternal(vshControl
*ctl
,
1127 unsigned long long *value
,
1133 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
1137 ret
= virStrToLong_ull(arg
->data
, NULL
, 10, value
);
1139 ret
= virStrToLong_ullp(arg
->data
, NULL
, 10, value
);
1142 _("Numeric value '%s' for <%s> option is malformed or out of range"),
1151 * vshCommandOptULongLong:
1152 * @ctl virtshell control structure
1153 * @cmd command reference
1157 * Returns option as long long, rejects negative numbers
1158 * See vshCommandOptInt()
1161 vshCommandOptULongLong(vshControl
*ctl
, const vshCmd
*cmd
,
1162 const char *name
, unsigned long long *value
)
1164 return vshCommandOptULongLongInternal(ctl
, cmd
, name
, value
, false);
1168 * vshCommandOptULongLongWrap:
1169 * @ctl virtshell control structure
1170 * @cmd command reference
1174 * Returns option as long long, wraps negative numbers to positive
1175 * See vshCommandOptInt()
1178 vshCommandOptULongLongWrap(vshControl
*ctl
, const vshCmd
*cmd
,
1179 const char *name
, unsigned long long *value
)
1181 return vshCommandOptULongLongInternal(ctl
, cmd
, name
, value
, true);
1185 * vshCommandOptScaledInt:
1186 * @ctl virtshell control structure
1187 * @cmd command reference
1190 * @scale default of 1 or 1024, if no suffix is present
1191 * @max maximum value permitted
1193 * Returns option as long long, scaled according to suffix
1194 * See vshCommandOptInt()
1197 vshCommandOptScaledInt(vshControl
*ctl
, const vshCmd
*cmd
,
1198 const char *name
, unsigned long long *value
,
1199 int scale
, unsigned long long max
)
1205 if ((ret
= vshCommandOpt(cmd
, name
, &arg
, true)) <= 0)
1208 if (virStrToLong_ullp(arg
->data
, &end
, 10, value
) < 0 ||
1209 virScaleInteger(value
, end
, scale
, max
) < 0) {
1211 _("Scaled numeric value '%s' for <%s> option is malformed or "
1212 "out of range"), arg
->data
, name
);
1221 * vshCommandOptBool:
1222 * @cmd command reference
1225 * Returns true/false if the option exists. Note that this does NOT
1226 * validate whether the option is actually boolean, or even whether
1227 * name is legal; so that this can be used to probe whether a data
1228 * option is present without actually using that data.
1231 vshCommandOptBool(const vshCmd
*cmd
, const char *name
)
1235 return vshCommandOpt(cmd
, name
, &dummy
, false) == 1;
1239 * vshCommandOptArgv:
1240 * @ctl virtshell control structure
1241 * @cmd command reference
1242 * @opt starting point for the search
1244 * Returns the next argv argument after OPT (or the first one if OPT
1245 * is NULL), or NULL if no more are present.
1247 * Requires that a VSH_OT_ARGV option be last in the
1248 * list of supported options in CMD->def->opts.
1251 vshCommandOptArgv(vshControl
*ctl ATTRIBUTE_UNUSED
, const vshCmd
*cmd
,
1252 const vshCmdOpt
*opt
)
1254 opt
= opt
? opt
->next
: cmd
->opts
;
1257 if (opt
->def
->type
== VSH_OT_ARGV
)
1266 * vshBlockJobOptionBandwidth:
1267 * @ctl: virsh control data
1268 * @cmd: virsh command description
1269 * @bytes: return bandwidth in bytes/s instead of MiB/s
1270 * @bandwidth: return value
1272 * Extracts the value of --bandwidth either as a wrap-able number without scale
1273 * or as a scaled integer. The returned value is checked to fit into a unsigned
1274 * long data type. This is a legacy compatibility function and it should not
1275 * be used for things other the block job APIs.
1277 * Returns 0 on success, -1 on error.
1280 vshBlockJobOptionBandwidth(vshControl
*ctl
,
1283 unsigned long *bandwidth
)
1287 unsigned long long bw
;
1290 if ((ret
= vshCommandOpt(cmd
, "bandwidth", &arg
, true)) <= 0)
1293 /* due to historical reasons we declare to parse negative numbers and wrap
1294 * them to the unsigned data type. */
1295 if (virStrToLong_ul(arg
->data
, NULL
, 10, bandwidth
) < 0) {
1296 /* try to parse the number as scaled size in this case we don't accept
1297 * wrapping since it would be ridiculous. In case of a 32 bit host,
1298 * limit the value to ULONG_MAX */
1299 if (virStrToLong_ullp(arg
->data
, &end
, 10, &bw
) < 0 ||
1300 virScaleInteger(&bw
, end
, 1, ULONG_MAX
) < 0) {
1302 _("Scaled numeric value '%s' for <--bandwidth> option is "
1303 "malformed or out of range"), arg
->data
);
1318 * Executes command(s) and returns return code from last command
1321 vshCommandRun(vshControl
*ctl
, const vshCmd
*cmd
)
1323 const vshClientHooks
*hooks
= ctl
->hooks
;
1327 struct timeval before
, after
;
1328 bool enable_timing
= ctl
->timing
;
1331 GETTIMEOFDAY(&before
);
1333 if ((cmd
->def
->flags
& VSH_CMD_FLAG_NOCONNECT
) ||
1334 (hooks
&& hooks
->connHandler
&& hooks
->connHandler(ctl
))) {
1335 ret
= cmd
->def
->handler(ctl
, cmd
);
1337 /* connection is not usable, return error */
1342 GETTIMEOFDAY(&after
);
1344 /* try to automatically catch disconnections */
1346 ((last_error
!= NULL
) &&
1347 (((last_error
->code
== VIR_ERR_SYSTEM_ERROR
) &&
1348 (last_error
->domain
== VIR_FROM_REMOTE
)) ||
1349 (last_error
->code
== VIR_ERR_RPC
) ||
1350 (last_error
->code
== VIR_ERR_NO_CONNECT
) ||
1351 (last_error
->code
== VIR_ERR_INVALID_CONN
))))
1355 vshReportError(ctl
);
1357 if (STREQ(cmd
->def
->name
, "quit") ||
1358 STREQ(cmd
->def
->name
, "exit")) /* hack ... */
1361 if (enable_timing
) {
1362 double diff_ms
= (((after
.tv_sec
- before
.tv_sec
) * 1000.0) +
1363 ((after
.tv_usec
- before
.tv_usec
) / 1000.0));
1365 vshPrint(ctl
, _("\n(Time: %.3f ms)\n\n"), diff_ms
);
1367 vshPrintExtra(ctl
, "\n");
1380 VSH_TK_ERROR
, /* Failed to parse a token */
1381 VSH_TK_ARG
, /* Arbitrary argument, might be option or empty */
1382 VSH_TK_SUBCMD_END
, /* Separation between commands */
1383 VSH_TK_END
/* No more commands */
1386 typedef struct _vshCommandParser vshCommandParser
;
1387 struct _vshCommandParser
{
1388 vshCommandToken(*getNextArg
)(vshControl
*, vshCommandParser
*,
1390 /* vshCommandStringGetArg() */
1392 /* vshCommandArgvGetArg() */
1398 vshCommandParse(vshControl
*ctl
, vshCommandParser
*parser
, vshCmd
**partial
)
1400 char *tkdata
= NULL
;
1401 vshCmd
*clast
= NULL
;
1402 vshCmdOpt
*first
= NULL
;
1403 const vshCmdDef
*cmd
= NULL
;
1406 vshCommandFree(ctl
->cmd
);
1411 vshCmdOpt
*last
= NULL
;
1413 bool data_only
= false;
1414 uint64_t opts_need_arg
= 0;
1415 uint64_t opts_required
= 0;
1416 uint64_t opts_seen
= 0;
1422 vshCommandFree(*partial
);
1427 const vshCmdOptDef
*opt
= NULL
;
1430 tk
= parser
->getNextArg(ctl
, parser
, &tkdata
, true);
1432 if (tk
== VSH_TK_ERROR
)
1434 if (tk
!= VSH_TK_ARG
) {
1440 /* first token must be command name or comment */
1441 if (*tkdata
== '#') {
1444 tk
= parser
->getNextArg(ctl
, parser
, &tkdata
, false);
1445 } while (tk
== VSH_TK_ARG
);
1448 } else if (!(cmd
= vshCmddefSearch(tkdata
))) {
1450 vshError(ctl
, _("unknown command: '%s'"), tkdata
);
1451 goto syntaxError
; /* ... or ignore this command only? */
1454 /* aliases need to be resolved to the actual commands */
1455 if (cmd
->flags
& VSH_CMD_FLAG_ALIAS
) {
1457 tkdata
= vshStrdup(ctl
, cmd
->alias
);
1458 cmd
= vshCmddefSearch(tkdata
);
1460 if (vshCmddefOptParse(cmd
, &opts_need_arg
,
1461 &opts_required
) < 0) {
1464 _("internal error: bad options in command: '%s'"),
1469 } else if (data_only
) {
1471 } else if (tkdata
[0] == '-' && tkdata
[1] == '-' &&
1472 c_isalnum(tkdata
[2])) {
1473 char *optstr
= strchr(tkdata
+ 2, '=');
1474 size_t opt_index
= 0;
1477 *optstr
= '\0'; /* convert the '=' to '\0' */
1478 optstr
= vshStrdup(ctl
, optstr
+ 1);
1480 /* Special case 'help' to ignore all spurious options */
1481 if (!(opt
= vshCmddefGetOption(ctl
, cmd
, tkdata
+ 2,
1482 &opts_seen
, &opt_index
,
1483 &optstr
, partial
== NULL
))) {
1485 if (STREQ(cmd
->name
, "help"))
1491 if (opt
->type
!= VSH_OT_BOOL
) {
1496 tk
= parser
->getNextArg(ctl
, parser
, &tkdata
, true);
1497 if (tk
== VSH_TK_ERROR
)
1499 if (tk
!= VSH_TK_ARG
) {
1501 vshCmdOpt
*arg
= vshMalloc(ctl
, sizeof(vshCmdOpt
));
1513 _("expected syntax: --%s <%s>"),
1516 VSH_OT_INT
? _("number") : _("string"));
1520 if (opt
->type
!= VSH_OT_ARGV
)
1521 opts_need_arg
&= ~(1ULL << opt_index
);
1526 vshError(ctl
, _("invalid '=' after option --%s"),
1532 } else if (tkdata
[0] == '-' && tkdata
[1] == '-' &&
1533 tkdata
[2] == '\0') {
1539 /* Special case 'help' to ignore spurious data */
1540 if (!(opt
= vshCmddefGetData(cmd
, &opts_need_arg
,
1542 STRNEQ(cmd
->name
, "help")) {
1544 vshError(ctl
, _("unexpected data '%s'"), tkdata
);
1550 vshCmdOpt
*arg
= vshMalloc(ctl
, sizeof(vshCmdOpt
));
1564 vshDebug(ctl
, VSH_ERR_INFO
, "%s: %s(%s): %s\n",
1567 opt
->type
!= VSH_OT_BOOL
? _("optdata") : _("bool"),
1568 opt
->type
!= VSH_OT_BOOL
? arg
->data
: _("(none)"));
1572 /* command parsed -- allocate new struct for the command */
1574 vshCmd
*c
= vshMalloc(ctl
, sizeof(vshCmd
));
1575 vshCmdOpt
*tmpopt
= first
;
1577 /* if we encountered --help, replace parsed command with
1578 * 'help <cmdname>' */
1579 for (tmpopt
= first
; tmpopt
; tmpopt
= tmpopt
->next
) {
1580 const vshCmdDef
*help
;
1581 if (STRNEQ(tmpopt
->def
->name
, "help"))
1584 help
= vshCmddefSearch("help");
1585 vshCommandOptFree(first
);
1586 first
= vshMalloc(ctl
, sizeof(vshCmdOpt
));
1587 first
->def
= help
->opts
;
1588 first
->data
= vshStrdup(ctl
, cmd
->name
);
1603 vshCommandCheckOpts(ctl
, c
, opts_required
, opts_seen
) < 0) {
1609 vshCommandFree(*partial
);
1620 if (tk
== VSH_TK_END
)
1630 tmp
= vshMalloc(ctl
, sizeof(*tmp
));
1636 vshCommandFree(ctl
->cmd
);
1638 vshCommandOptFree(first
);
1644 /* --------------------
1645 * Command argv parsing
1646 * --------------------
1649 static vshCommandToken
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
1650 vshCommandArgvGetArg(vshControl
*ctl
, vshCommandParser
*parser
, char **res
,
1651 bool report ATTRIBUTE_UNUSED
)
1653 if (parser
->arg_pos
== parser
->arg_end
) {
1658 *res
= vshStrdup(ctl
, *parser
->arg_pos
);
1664 vshCommandArgvParse(vshControl
*ctl
, int nargs
, char **argv
)
1666 vshCommandParser parser
;
1671 parser
.arg_pos
= argv
;
1672 parser
.arg_end
= argv
+ nargs
;
1673 parser
.getNextArg
= vshCommandArgvGetArg
;
1674 return vshCommandParse(ctl
, &parser
, NULL
);
1677 /* ----------------------
1678 * Command string parsing
1679 * ----------------------
1682 static vshCommandToken
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
1683 vshCommandStringGetArg(vshControl
*ctl
, vshCommandParser
*parser
, char **res
,
1686 bool single_quote
= false;
1687 bool double_quote
= false;
1689 char *p
= parser
->pos
;
1690 char *q
= vshStrdup(ctl
, p
);
1694 while (*p
== ' ' || *p
== '\t' || (*p
== '\\' && p
[1] == '\n'))
1695 p
+= 1 + (*p
== '\\');
1699 if (*p
== ';' || *p
== '\n') {
1700 parser
->pos
= ++p
; /* = \0 or begin of next command */
1701 return VSH_TK_SUBCMD_END
;
1703 if (*p
== '#') { /* Argument starting with # is comment to end of line */
1704 while (*p
&& *p
!= '\n')
1706 parser
->pos
= p
+ !!*p
;
1707 return VSH_TK_SUBCMD_END
;
1711 /* end of token is blank space or ';' */
1712 if (!double_quote
&& !single_quote
&&
1713 (*p
== ' ' || *p
== '\t' || *p
== ';' || *p
== '\n'))
1716 if (!double_quote
&& *p
== '\'') { /* single quote */
1717 single_quote
= !single_quote
;
1720 } else if (!single_quote
&& *p
== '\\') { /* escape */
1722 * The same as in shell, a \ in "" is an escaper,
1723 * but a \ in '' is not an escaper.
1728 vshError(ctl
, "%s", _("dangling \\"));
1729 return VSH_TK_ERROR
;
1730 } else if (*p
== '\n') {
1731 /* Elide backslash-newline entirely */
1735 } else if (!single_quote
&& *p
== '"') { /* double quote */
1736 double_quote
= !double_quote
;
1746 vshError(ctl
, "%s", _("missing \""));
1747 return VSH_TK_ERROR
;
1756 vshCommandStringParse(vshControl
*ctl
, char *cmdstr
, vshCmd
**partial
)
1758 vshCommandParser parser
;
1760 if (cmdstr
== NULL
|| *cmdstr
== '\0')
1763 parser
.pos
= cmdstr
;
1764 parser
.getNextArg
= vshCommandStringGetArg
;
1765 return vshCommandParse(ctl
, &parser
, partial
);
1769 * virshCommandOptTimeoutToMs:
1770 * @ctl virsh control structure
1771 * @cmd command reference
1774 * Parse an optional --timeout parameter in seconds, but store the
1775 * value of the timeout in milliseconds.
1776 * See vshCommandOptInt()
1779 vshCommandOptTimeoutToMs(vshControl
*ctl
, const vshCmd
*cmd
, int *timeout
)
1782 unsigned int utimeout
;
1784 if ((ret
= vshCommandOptUInt(ctl
, cmd
, "timeout", &utimeout
)) <= 0)
1787 /* Ensure that the timeout is not zero and that we can convert
1788 * it from seconds to milliseconds without overflowing. */
1789 if (utimeout
== 0 || utimeout
> INT_MAX
/ 1000) {
1791 _("Numeric value '%u' for <%s> option is malformed or out of range"),
1796 *timeout
= ((int) utimeout
) * 1000;
1808 /* Return a non-NULL string representation of a typed parameter; exit
1809 * if we are out of memory. */
1811 vshGetTypedParamValue(vshControl
*ctl
, virTypedParameterPtr item
)
1816 switch (item
->type
) {
1817 case VIR_TYPED_PARAM_INT
:
1818 ret
= virAsprintf(&str
, "%d", item
->value
.i
);
1821 case VIR_TYPED_PARAM_UINT
:
1822 ret
= virAsprintf(&str
, "%u", item
->value
.ui
);
1825 case VIR_TYPED_PARAM_LLONG
:
1826 ret
= virAsprintf(&str
, "%lld", item
->value
.l
);
1829 case VIR_TYPED_PARAM_ULLONG
:
1830 ret
= virAsprintf(&str
, "%llu", item
->value
.ul
);
1833 case VIR_TYPED_PARAM_DOUBLE
:
1834 ret
= virAsprintf(&str
, "%f", item
->value
.d
);
1837 case VIR_TYPED_PARAM_BOOLEAN
:
1838 str
= vshStrdup(ctl
, item
->value
.b
? _("yes") : _("no"));
1841 case VIR_TYPED_PARAM_STRING
:
1842 str
= vshStrdup(ctl
, item
->value
.s
);
1846 vshError(ctl
, _("unimplemented parameter type %d"), item
->type
);
1850 vshError(ctl
, "%s", _("Out of memory"));
1857 vshDebug(vshControl
*ctl
, int level
, const char *format
, ...)
1862 /* Aligning log levels to that of libvirt.
1863 * Traces with levels >= user-specified-level
1864 * gets logged into file
1866 if (level
< ctl
->debug
)
1869 va_start(ap
, format
);
1870 vshOutputLogFile(ctl
, level
, format
, ap
);
1873 va_start(ap
, format
);
1874 if (virVasprintf(&str
, format
, ap
) < 0) {
1875 /* Skip debug messages on low memory */
1885 vshPrintExtra(vshControl
*ctl
, const char *format
, ...)
1890 if (ctl
&& ctl
->quiet
)
1893 va_start(ap
, format
);
1894 if (virVasprintfQuiet(&str
, format
, ap
) < 0)
1903 vshPrint(vshControl
*ctl ATTRIBUTE_UNUSED
, const char *format
, ...)
1908 va_start(ap
, format
);
1909 if (virVasprintfQuiet(&str
, format
, ap
) < 0)
1918 vshTTYIsInterruptCharacter(vshControl
*ctl ATTRIBUTE_UNUSED
,
1919 const char chr ATTRIBUTE_UNUSED
)
1923 ctl
->termattr
.c_cc
[VINTR
] == chr
)
1932 vshTTYAvailable(vshControl
*ctl
)
1939 vshTTYDisableInterrupt(vshControl
*ctl ATTRIBUTE_UNUSED
)
1942 struct termios termset
= ctl
->termattr
;
1947 /* check if we need to set the terminal */
1948 if (termset
.c_cc
[VINTR
] == _POSIX_VDISABLE
)
1951 termset
.c_cc
[VINTR
] = _POSIX_VDISABLE
;
1952 termset
.c_lflag
&= ~ICANON
;
1954 if (tcsetattr(STDIN_FILENO
, TCSANOW
, &termset
) < 0)
1963 vshTTYRestore(vshControl
*ctl ATTRIBUTE_UNUSED
)
1969 if (tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &ctl
->termattr
) < 0)
1977 #if !defined(WIN32) && !defined(HAVE_CFMAKERAW)
1978 /* provide fallback in case cfmakeraw isn't available */
1980 cfmakeraw(struct termios
*attr
)
1982 attr
->c_iflag
&= ~(IGNBRK
| BRKINT
| PARMRK
| ISTRIP
1983 | INLCR
| IGNCR
| ICRNL
| IXON
);
1984 attr
->c_oflag
&= ~OPOST
;
1985 attr
->c_lflag
&= ~(ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
1986 attr
->c_cflag
&= ~(CSIZE
| PARENB
);
1987 attr
->c_cflag
|= CS8
;
1989 #endif /* !WIN32 && !HAVE_CFMAKERAW */
1993 vshTTYMakeRaw(vshControl
*ctl ATTRIBUTE_UNUSED
,
1994 bool report_errors ATTRIBUTE_UNUSED
)
1997 struct termios rawattr
= ctl
->termattr
;
2001 if (report_errors
) {
2003 _("unable to make terminal raw: console isn't a tty"));
2009 cfmakeraw(&rawattr
);
2011 if (tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &rawattr
) < 0) {
2013 vshError(ctl
, _("unable to set tty attributes: %s"),
2014 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2024 vshError(vshControl
*ctl
, const char *format
, ...)
2030 va_start(ap
, format
);
2031 vshOutputLogFile(ctl
, VSH_ERR_ERROR
, format
, ap
);
2035 /* Most output is to stdout, but if someone ran virsh 2>&1, then
2036 * printing to stderr will not interleave correctly with stdout
2037 * unless we flush between every transition between streams. */
2039 fputs(_("error: "), stderr
);
2041 va_start(ap
, format
);
2042 /* We can't recursively call vshError on an OOM situation, so ignore
2044 ignore_value(virVasprintf(&str
, format
, ap
));
2047 fprintf(stderr
, "%s\n", NULLSTR(str
));
2054 vshEventLoop(void *opaque
)
2056 vshControl
*ctl
= opaque
;
2060 virMutexLock(&ctl
->lock
);
2062 virMutexUnlock(&ctl
->lock
);
2067 if (virEventRunDefaultImpl() < 0)
2068 vshReportError(ctl
);
2074 * Helpers for waiting for a libvirt event.
2077 /* We want to use SIGINT to cancel a wait; but as signal handlers
2078 * don't have an opaque argument, we have to use static storage. */
2079 static int vshEventFd
= -1;
2080 static struct sigaction vshEventOldAction
;
2083 /* Signal handler installed in vshEventStart, removed in vshEventCleanup. */
2085 vshEventInt(int sig ATTRIBUTE_UNUSED
,
2086 siginfo_t
*siginfo ATTRIBUTE_UNUSED
,
2087 void *context ATTRIBUTE_UNUSED
)
2089 char reason
= VSH_EVENT_INTERRUPT
;
2090 if (vshEventFd
>= 0)
2091 ignore_value(safewrite(vshEventFd
, &reason
, 1));
2095 /* Event loop handler used to limit length of waiting for any other event. */
2097 vshEventTimeout(int timer ATTRIBUTE_UNUSED
,
2100 vshControl
*ctl
= opaque
;
2101 char reason
= VSH_EVENT_TIMEOUT
;
2103 if (ctl
->eventPipe
[1] >= 0)
2104 ignore_value(safewrite(ctl
->eventPipe
[1], &reason
, 1));
2110 * @ctl vsh command struct
2111 * @timeout_ms max wait time in milliseconds, or 0 for indefinite
2113 * Set up a wait for a libvirt event. The wait can be canceled by
2114 * SIGINT or by calling vshEventDone() in your event handler. If
2115 * @timeout_ms is positive, the wait will also end if the timeout
2116 * expires. Call vshEventWait() to block the main thread (the event
2117 * handler runs in the event loop thread). When done (including if
2118 * there was an error registering for an event), use vshEventCleanup()
2119 * to quit waiting. Returns 0 on success, -1 on failure. */
2121 vshEventStart(vshControl
*ctl
, int timeout_ms
)
2123 struct sigaction action
;
2125 assert(ctl
->eventPipe
[0] == -1 && ctl
->eventPipe
[1] == -1 &&
2126 vshEventFd
== -1 && ctl
->eventTimerId
>= 0);
2127 if (pipe2(ctl
->eventPipe
, O_CLOEXEC
) < 0) {
2130 vshError(ctl
, _("failed to create pipe: %s"),
2131 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2134 vshEventFd
= ctl
->eventPipe
[1];
2136 action
.sa_sigaction
= vshEventInt
;
2137 action
.sa_flags
= SA_SIGINFO
;
2138 sigemptyset(&action
.sa_mask
);
2139 sigaction(SIGINT
, &action
, &vshEventOldAction
);
2142 virEventUpdateTimeout(ctl
->eventTimerId
, timeout_ms
);
2150 * @ctl vsh command struct
2152 * Call this from an event callback to let the main thread quit
2153 * blocking on further events.
2156 vshEventDone(vshControl
*ctl
)
2158 char reason
= VSH_EVENT_DONE
;
2160 if (ctl
->eventPipe
[1] >= 0)
2161 ignore_value(safewrite(ctl
->eventPipe
[1], &reason
, 1));
2167 * @ctl vsh command struct
2169 * Call this in the main thread after calling vshEventStart() then
2170 * registering for one or more events. This call will block until
2171 * SIGINT, the timeout registered at the start, or until one of your
2172 * event handlers calls vshEventDone(). Returns an enum VSH_EVENT_*
2173 * stating how the wait concluded, or -1 on error.
2176 vshEventWait(vshControl
*ctl
)
2181 assert(ctl
->eventPipe
[0] >= 0);
2182 while ((rv
= read(ctl
->eventPipe
[0], &buf
, 1)) < 0 && errno
== EINTR
);
2188 vshError(ctl
, _("failed to determine loop exit status: %s"),
2189 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2198 * @ctl vsh control struct
2200 * Call at the end of any function that has used vshEventStart(), to
2201 * tear down any remaining SIGINT or timeout handlers.
2204 vshEventCleanup(vshControl
*ctl
)
2206 if (vshEventFd
>= 0) {
2207 sigaction(SIGINT
, &vshEventOldAction
, NULL
);
2210 VIR_FORCE_CLOSE(ctl
->eventPipe
[0]);
2211 VIR_FORCE_CLOSE(ctl
->eventPipe
[1]);
2212 virEventUpdateTimeout(ctl
->eventTimerId
, -1);
2215 #define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC)
2223 vshOpenLogFile(vshControl
*ctl
)
2225 if (ctl
->logfile
== NULL
)
2228 if ((ctl
->log_fd
= open(ctl
->logfile
, LOGFILE_FLAGS
, FILE_MODE
)) < 0) {
2230 _("failed to open the log file. check the log file path"));
2238 * Outputting an error to log file.
2241 vshOutputLogFile(vshControl
*ctl
, int log_level
, const char *msg_format
,
2244 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
2247 const char *lvl
= "";
2251 if (ctl
->log_fd
== -1)
2257 * [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
2260 localtime_r(&stTime
, &stTm
);
2261 virBufferAsprintf(&buf
, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
2262 (1900 + stTm
.tm_year
),
2270 switch (log_level
) {
2277 case VSH_ERR_NOTICE
:
2280 case VSH_ERR_WARNING
:
2290 virBufferAsprintf(&buf
, "%s ", lvl
);
2291 virBufferVasprintf(&buf
, msg_format
, ap
);
2292 virBufferTrim(&buf
, "\n", -1);
2293 virBufferAddChar(&buf
, '\n');
2295 if (virBufferError(&buf
))
2298 str
= virBufferContentAndReset(&buf
);
2302 if (safewrite(ctl
->log_fd
, str
, len
) < 0)
2309 vshCloseLogFile(ctl
);
2310 vshError(ctl
, "%s", _("failed to write the log file"));
2311 virBufferFreeAndReset(&buf
);
2321 vshCloseLogFile(vshControl
*ctl
)
2325 /* log file close */
2326 if (VIR_CLOSE(ctl
->log_fd
) < 0) {
2327 vshError(ctl
, _("%s: failed to write log file: %s"),
2328 ctl
->logfile
? ctl
->logfile
: "?",
2329 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2333 VIR_FREE(ctl
->logfile
);
2334 ctl
->logfile
= NULL
;
2340 vshPrintRaw(vshControl
*ctl
, ...)
2346 while ((key
= va_arg(ap
, char *)) != NULL
)
2347 vshPrint(ctl
, "%s\r\n", key
);
2353 * @msg: Question to ask user
2355 * Ask user if he wants to return to previously
2358 * Returns 'y' if he wants to
2359 * 'n' if he doesn't want to
2360 * 'i' if he wants to try defining it again while ignoring validation
2361 * 'f' if he forcibly wants to
2366 vshAskReedit(vshControl
*ctl
, const char *msg
, bool relax_avail
)
2370 if (!isatty(STDIN_FILENO
))
2373 vshReportError(ctl
);
2375 if (vshTTYMakeRaw(ctl
, false) < 0)
2379 vshPrint(ctl
, "\r%s %s %s: ", msg
, _("Try again?"),
2380 relax_avail
? "[y,n,i,f,?]" : "[y,n,f,?]");
2381 c
= c_tolower(getchar());
2386 _("y - yes, start editor again"),
2387 _("n - no, throw away my changes"),
2392 _("i - turn off validation and try to redefine "
2398 _("f - force, try to redefine again"),
2399 _("? - print this help"),
2402 } else if (c
== 'y' || c
== 'n' || c
== 'f' ||
2403 (relax_avail
&& c
== 'i')) {
2410 vshPrint(ctl
, "\r\n");
2415 vshAskReedit(vshControl
*ctl
,
2416 const char *msg ATTRIBUTE_UNUSED
,
2417 bool relax_avail ATTRIBUTE_UNUSED
)
2419 vshDebug(ctl
, VSH_ERR_WARNING
, "%s", _("This function is not "
2420 "supported on WIN32 platform"));
2426 /* Common code for the edit / net-edit / pool-edit functions which follow. */
2428 vshEditWriteToTempFile(vshControl
*ctl
, const char *doc
)
2435 tmpdir
= virGetEnvBlockSUID("TMPDIR");
2436 if (!tmpdir
) tmpdir
= "/tmp";
2437 if (virAsprintf(&ret
, "%s/virshXXXXXX.xml", tmpdir
) < 0) {
2438 vshError(ctl
, "%s", _("out of memory"));
2441 fd
= mkostemps(ret
, 4, O_CLOEXEC
);
2443 vshError(ctl
, _("mkostemps: failed to create temporary file: %s"),
2444 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2449 if (safewrite(fd
, doc
, strlen(doc
)) == -1) {
2450 vshError(ctl
, _("write: %s: failed to write to temporary file: %s"),
2451 ret
, virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2452 VIR_FORCE_CLOSE(fd
);
2457 if (VIR_CLOSE(fd
) < 0) {
2458 vshError(ctl
, _("close: %s: failed to write or close temporary file: %s"),
2459 ret
, virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2465 /* Temporary filename: caller frees. */
2469 /* Characters permitted in $EDITOR environment variable and temp filename. */
2470 #define ACCEPTED_CHARS \
2471 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/_.:@"
2474 vshEditFile(vshControl
*ctl
, const char *filename
)
2479 int outfd
= STDOUT_FILENO
;
2480 int errfd
= STDERR_FILENO
;
2482 editor
= virGetEnvBlockSUID("VISUAL");
2484 editor
= virGetEnvBlockSUID("EDITOR");
2486 editor
= DEFAULT_EDITOR
;
2488 /* Check that filename doesn't contain shell meta-characters, and
2489 * if it does, refuse to run. Follow the Unix conventions for
2490 * EDITOR: the user can intentionally specify command options, so
2491 * we don't protect any shell metacharacters there. Lots more
2492 * than virsh will misbehave if EDITOR has bogus contents (which
2493 * is why sudo scrubs it by default). Conversely, if the editor
2494 * is safe, we can run it directly rather than wasting a shell.
2496 if (strspn(editor
, ACCEPTED_CHARS
) != strlen(editor
)) {
2497 if (strspn(filename
, ACCEPTED_CHARS
) != strlen(filename
)) {
2499 _("%s: temporary filename contains shell meta or other "
2500 "unacceptable characters (is $TMPDIR wrong?)"),
2504 cmd
= virCommandNewArgList("sh", "-c", NULL
);
2505 virCommandAddArgFormat(cmd
, "%s %s", editor
, filename
);
2507 cmd
= virCommandNewArgList(editor
, filename
, NULL
);
2510 virCommandSetInputFD(cmd
, STDIN_FILENO
);
2511 virCommandSetOutputFD(cmd
, &outfd
);
2512 virCommandSetErrorFD(cmd
, &errfd
);
2513 if (virCommandRunAsync(cmd
, NULL
) < 0 ||
2514 virCommandWait(cmd
, NULL
) < 0) {
2515 vshReportError(ctl
);
2521 virCommandFree(cmd
);
2526 vshEditReadBackFile(vshControl
*ctl
, const char *filename
)
2531 if (virFileReadAll(filename
, VSH_MAX_XML_FILE
, &ret
) == -1) {
2533 _("%s: failed to read temporary file: %s"),
2534 filename
, virStrerror(errno
, ebuf
, sizeof(ebuf
)));
2541 /* Tree listing helpers. */
2544 vshTreePrintInternal(vshControl
*ctl
,
2545 vshTreeLookup lookup
,
2551 virBufferPtr indent
)
2554 int nextlastdev
= -1;
2556 const char *dev
= (lookup
)(devid
, false, opaque
);
2558 if (virBufferError(indent
))
2561 /* Print this device, with indent if not at root */
2562 vshPrint(ctl
, "%s%s%s\n", virBufferCurrentContent(indent
),
2563 root
? "" : "+- ", dev
);
2565 /* Update indent to show '|' or ' ' for child devices */
2567 virBufferAddChar(indent
, devid
== lastdev
? ' ' : '|');
2568 virBufferAddChar(indent
, ' ');
2569 if (virBufferError(indent
))
2573 /* Determine the index of the last child device */
2574 for (i
= 0; i
< num_devices
; i
++) {
2575 const char *parent
= (lookup
)(i
, true, opaque
);
2577 if (parent
&& STREQ(parent
, dev
))
2581 /* If there is a child device, then print another blank line */
2582 if (nextlastdev
!= -1)
2583 vshPrint(ctl
, "%s |\n", virBufferCurrentContent(indent
));
2585 /* Finally print all children */
2586 virBufferAddLit(indent
, " ");
2587 if (virBufferError(indent
))
2589 for (i
= 0; i
< num_devices
; i
++) {
2590 const char *parent
= (lookup
)(i
, true, opaque
);
2592 if (parent
&& STREQ(parent
, dev
) &&
2593 vshTreePrintInternal(ctl
, lookup
, opaque
,
2594 num_devices
, i
, nextlastdev
,
2598 virBufferTrim(indent
, " ", -1);
2600 /* If there was no child device, and we're the last in
2601 * a list of devices, then print another blank line */
2602 if (nextlastdev
== -1 && devid
== lastdev
)
2603 vshPrint(ctl
, "%s\n", virBufferCurrentContent(indent
));
2606 virBufferTrim(indent
, NULL
, 2);
2613 vshTreePrint(vshControl
*ctl
, vshTreeLookup lookup
, void *opaque
,
2614 int num_devices
, int devid
)
2617 virBuffer indent
= VIR_BUFFER_INITIALIZER
;
2619 ret
= vshTreePrintInternal(ctl
, lookup
, opaque
, num_devices
,
2620 devid
, devid
, true, &indent
);
2622 vshError(ctl
, "%s", _("Failed to complete tree listing"));
2623 virBufferFreeAndReset(&indent
);
2629 /* -----------------
2635 * vshReadlineCommandGenerator:
2636 * @text: optional command prefix
2638 * Generator function for command completion.
2640 * Returns a string list of commands with @text prefix,
2641 * NULL if there's no such command.
2644 vshReadlineCommandGenerator(const char *text
)
2646 size_t grp_list_index
= 0, cmd_list_index
= 0;
2647 size_t len
= strlen(text
);
2649 const vshCmdGrp
*grp
;
2650 const vshCmdDef
*cmds
;
2651 size_t ret_size
= 0;
2656 /* Return the next name which partially matches from the
2659 while (grp
[grp_list_index
].name
) {
2660 cmds
= grp
[grp_list_index
].commands
;
2662 if (cmds
[cmd_list_index
].name
) {
2663 while ((name
= cmds
[cmd_list_index
].name
)) {
2664 if (cmds
[cmd_list_index
++].flags
& VSH_CMD_FLAG_ALIAS
)
2667 if (STREQLEN(name
, text
, len
)) {
2668 if (VIR_REALLOC_N(ret
, ret_size
+ 2) < 0) {
2669 virStringListFree(ret
);
2672 ret
[ret_size
] = vshStrdup(NULL
, name
);
2674 /* Terminate the string list properly. */
2675 ret
[ret_size
] = NULL
;
2688 vshReadlineOptionsGenerator(const char *text
,
2689 const vshCmdDef
*cmd
,
2692 size_t list_index
= 0;
2693 size_t len
= strlen(text
);
2695 size_t ret_size
= 0;
2704 while ((name
= cmd
->opts
[list_index
].name
)) {
2705 bool exists
= false;
2706 vshCmdOpt
*opt
= last
->opts
;
2712 /* provide auto-complete only when the text starts with -- */
2713 if (STRNEQLEN(text
, "--", 2))
2715 if (STRNEQLEN(name
, text
+ 2, len
- 2))
2717 } else if (STRNEQLEN(text
, "--", len
)) {
2722 if (STREQ(opt
->def
->name
, name
) && opt
->def
->type
!= VSH_OT_ARGV
) {
2733 if (VIR_REALLOC_N(ret
, ret_size
+ 2) < 0) {
2734 virStringListFree(ret
);
2738 name_len
= strlen(name
);
2739 ret
[ret_size
] = vshMalloc(NULL
, name_len
+ 3);
2740 snprintf(ret
[ret_size
], name_len
+ 3, "--%s", name
);
2742 /* Terminate the string list properly. */
2743 ret
[ret_size
] = NULL
;
2750 static const vshCmdOptDef
*
2751 vshReadlineCommandFindOpt(const vshCmd
*partial
,
2754 const vshCmd
*tmp
= partial
;
2756 while (tmp
&& tmp
->next
) {
2757 if (tmp
->def
== tmp
->next
->def
&&
2763 if (tmp
&& tmp
->opts
) {
2764 const vshCmdOpt
*opt
= tmp
->opts
;
2767 if (STREQ_NULLABLE(opt
->data
, text
) ||
2768 STREQ_NULLABLE(opt
->data
, " "))
2780 vshCompleterFilter(char ***list
,
2783 char **newList
= NULL
;
2784 size_t newList_len
= 0;
2788 if (!list
|| !*list
)
2791 list_len
= virStringListLength((const char **) *list
);
2793 if (VIR_ALLOC_N(newList
, list_len
+ 1) < 0)
2796 for (i
= 0; i
< list_len
; i
++) {
2797 if (!STRPREFIX((*list
)[i
], text
)) {
2798 VIR_FREE((*list
)[i
]);
2802 VIR_STEAL_PTR(newList
[newList_len
], (*list
)[i
]);
2806 ignore_value(VIR_REALLOC_N_QUIET(newList
, newList_len
+ 1));
2814 vshReadlineParse(const char *text
, int state
)
2816 static vshCmd
*partial
;
2818 static size_t list_index
;
2819 const vshCmdDef
*cmd
= NULL
;
2820 const vshCmdOptDef
*opt
= NULL
;
2824 char *buf
= vshStrdup(NULL
, rl_line_buffer
);
2826 vshCommandFree(partial
);
2828 virStringListFree(list
);
2832 *(buf
+ rl_point
) = '\0';
2834 vshCommandStringParse(NULL
, buf
, &partial
);
2840 partial
->skipChecks
= true;
2843 if (cmd
&& STREQ(cmd
->name
, text
)) {
2844 /* Corner case - some commands share prefix (e.g.
2845 * dump and dumpxml). If user typed 'dump<TAB><TAB>',
2846 * then @text = "dump" and we want to offer command
2847 * completion. If they typed 'dump <TAB><TAB>' then
2848 * @text = "" (the space after the command) and we
2849 * want to offer options completion for dump command.
2854 opt
= vshReadlineCommandFindOpt(partial
, text
);
2859 list
= vshReadlineCommandGenerator(text
);
2861 if (!opt
|| (opt
->type
!= VSH_OT_DATA
&&
2862 opt
->type
!= VSH_OT_STRING
&&
2863 opt
->type
!= VSH_OT_ARGV
))
2864 list
= vshReadlineOptionsGenerator(text
, cmd
, partial
);
2866 if (opt
&& opt
->completer
) {
2867 char **completer_list
= opt
->completer(autoCompleteOpaque
,
2869 opt
->completer_flags
);
2871 /* For string list returned by completer we have to do
2872 * filtering based on @text because completer returns all
2873 * possible strings. */
2875 if (completer_list
&&
2876 (vshCompleterFilter(&completer_list
, text
) < 0 ||
2877 virStringListMerge(&list
, &completer_list
) < 0)) {
2878 virStringListFree(completer_list
);
2886 ret
= vshStrdup(NULL
, list
[list_index
]);
2891 !rl_completion_quote_character
) {
2892 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
2893 virBufferEscapeShell(&buf
, ret
);
2895 ret
= virBufferContentAndReset(&buf
);
2900 vshCommandFree(partial
);
2902 virStringListFree(list
);
2912 vshReadlineCompletion(const char *text
,
2913 int start ATTRIBUTE_UNUSED
,
2914 int end ATTRIBUTE_UNUSED
)
2916 char **matches
= (char **) NULL
;
2918 matches
= rl_completion_matches(text
, vshReadlineParse
);
2924 vshReadlineCharIsQuoted(char *line
, int idx
)
2927 line
[idx
- 1] == '\\' &&
2928 !vshReadlineCharIsQuoted(line
, idx
- 1);
2932 # define HISTSIZE_MAX 500000
2935 vshReadlineInit(vshControl
*ctl
)
2937 char *userdir
= NULL
;
2938 int max_history
= 500;
2940 char *histsize_env
= NULL
;
2941 const char *histsize_str
= NULL
;
2942 const char *break_characters
= " \t\n\\`@$><=;|&{(";
2943 const char *quote_characters
= "\"'";
2945 /* Opaque data for autocomplete callbacks. */
2946 autoCompleteOpaque
= ctl
;
2948 rl_readline_name
= ctl
->name
;
2950 /* Tell the completer that we want a crack first. */
2951 rl_attempted_completion_function
= vshReadlineCompletion
;
2953 rl_basic_word_break_characters
= break_characters
;
2955 rl_completer_quote_characters
= quote_characters
;
2956 rl_char_is_quoted_p
= vshReadlineCharIsQuoted
;
2958 if (virAsprintf(&histsize_env
, "%s_HISTSIZE", ctl
->env_prefix
) < 0)
2961 /* Limit the total size of the history buffer */
2962 if ((histsize_str
= virGetEnvBlockSUID(histsize_env
))) {
2963 if (virStrToLong_i(histsize_str
, NULL
, 10, &max_history
) < 0) {
2964 vshError(ctl
, _("Bad $%s value."), histsize_env
);
2966 } else if (max_history
> HISTSIZE_MAX
|| max_history
< 0) {
2967 vshError(ctl
, _("$%s value should be between 0 "
2969 histsize_env
, HISTSIZE_MAX
);
2973 stifle_history(max_history
);
2975 /* Prepare to read/write history from/to the
2976 * $XDG_CACHE_HOME/virtshell/history file
2978 userdir
= virGetUserCacheDirectory();
2980 if (userdir
== NULL
) {
2981 vshError(ctl
, "%s", _("Could not determine home directory"));
2985 if (virAsprintf(&ctl
->historydir
, "%s/%s", userdir
, ctl
->name
) < 0) {
2986 vshError(ctl
, "%s", _("Out of memory"));
2990 if (virAsprintf(&ctl
->historyfile
, "%s/history", ctl
->historydir
) < 0) {
2991 vshError(ctl
, "%s", _("Out of memory"));
2995 read_history(ctl
->historyfile
);
3000 VIR_FREE(histsize_env
);
3005 vshReadlineDeinit(vshControl
*ctl
)
3007 if (ctl
->historyfile
!= NULL
) {
3008 if (virFileMakePathWithMode(ctl
->historydir
, 0755) < 0 &&
3011 vshError(ctl
, _("Failed to create '%s': %s"),
3012 ctl
->historydir
, virStrerror(errno
, ebuf
, sizeof(ebuf
)));
3014 write_history(ctl
->historyfile
);
3018 VIR_FREE(ctl
->historydir
);
3019 VIR_FREE(ctl
->historyfile
);
3023 vshReadline(vshControl
*ctl ATTRIBUTE_UNUSED
, const char *prompt
)
3025 return readline(prompt
);
3028 #else /* !WITH_READLINE */
3031 vshReadlineInit(vshControl
*ctl ATTRIBUTE_UNUSED
)
3038 vshReadlineDeinit(vshControl
*ctl ATTRIBUTE_UNUSED
)
3044 vshReadline(vshControl
*ctl
, const char *prompt
)
3050 fputs(prompt
, stdout
);
3051 r
= fgets(line
, sizeof(line
), stdin
);
3052 if (r
== NULL
) return NULL
; /* EOF */
3054 /* Chomp trailing \n */
3056 if (len
> 0 && r
[len
-1] == '\n')
3059 return vshStrdup(ctl
, r
);
3062 #endif /* !WITH_READLINE */
3065 * Initialize debug settings.
3068 vshInitDebug(vshControl
*ctl
)
3070 const char *debugEnv
;
3073 if (ctl
->debug
== VSH_DEBUG_DEFAULT
) {
3074 if (virAsprintf(&env
, "%s_DEBUG", ctl
->env_prefix
) < 0)
3077 /* log level not set from commandline, check env variable */
3078 debugEnv
= virGetEnvAllowSUID(env
);
3081 if (virStrToLong_i(debugEnv
, NULL
, 10, &debug
) < 0 ||
3082 debug
< VSH_ERR_DEBUG
|| debug
> VSH_ERR_ERROR
) {
3083 vshError(ctl
, _("%s_DEBUG not set with a valid numeric value"),
3092 if (ctl
->logfile
== NULL
) {
3093 if (virAsprintf(&env
, "%s_LOG_FILE", ctl
->env_prefix
) < 0)
3096 /* log file not set from cmdline */
3097 debugEnv
= virGetEnvBlockSUID(env
);
3098 if (debugEnv
&& *debugEnv
) {
3099 ctl
->logfile
= vshStrdup(ctl
, debugEnv
);
3100 vshOpenLogFile(ctl
);
3110 * Initialize global data
3113 vshInit(vshControl
*ctl
, const vshCmdGrp
*groups
, const vshCmdDef
*set
)
3116 vshError(ctl
, "%s", _("client hooks cannot be NULL"));
3120 if (!groups
&& !set
) {
3121 vshError(ctl
, "%s", _("command groups and command set "
3122 "cannot both be NULL"));
3129 if (vshInitDebug(ctl
) < 0 ||
3130 (ctl
->imode
&& vshReadlineInit(ctl
) < 0))
3137 vshInitReload(vshControl
*ctl
)
3139 if (!cmdGroups
&& !cmdSet
) {
3140 vshError(ctl
, "%s", _("command groups and command are both NULL "
3141 "run vshInit before reloading"));
3145 if (vshInitDebug(ctl
) < 0)
3149 vshReadlineDeinit(ctl
);
3150 if (ctl
->imode
&& vshReadlineInit(ctl
) < 0)
3157 vshDeinit(vshControl
*ctl
)
3159 /* NB: Don't make calling of vshReadlineDeinit conditional on active
3160 * interactive mode. */
3161 vshReadlineDeinit(ctl
);
3162 vshCloseLogFile(ctl
);
3165 /* -----------------------------------------------
3166 * Generic commands available to use by any client
3167 * -----------------------------------------------
3169 const vshCmdOptDef opts_help
[] = {
3171 .type
= VSH_OT_STRING
,
3172 .help
= N_("Prints global help, command specific help, or help for a group of related commands")
3177 const vshCmdInfo info_help
[] = {
3179 .data
= N_("print help")
3182 .data
= N_("Prints global help, command specific help, or help for a\n"
3183 " group of related commands")
3189 cmdHelp(vshControl
*ctl
, const vshCmd
*cmd
)
3191 const vshCmdDef
*def
= NULL
;
3192 const vshCmdGrp
*grp
= NULL
;
3193 const char *name
= NULL
;
3195 if (vshCommandOptStringQuiet(ctl
, cmd
, "command", &name
) <= 0) {
3196 vshPrint(ctl
, "%s", _("Grouped commands:\n\n"));
3198 for (grp
= cmdGroups
; grp
->name
; grp
++) {
3199 vshPrint(ctl
, _(" %s (help keyword '%s'):\n"), grp
->name
,
3202 for (def
= grp
->commands
; def
->name
; def
++) {
3203 if (def
->flags
& VSH_CMD_FLAG_ALIAS
)
3205 vshPrint(ctl
, " %-30s %s\n", def
->name
,
3206 _(vshCmddefGetInfo(def
, "help")));
3209 vshPrint(ctl
, "\n");
3215 if ((def
= vshCmddefSearch(name
))) {
3216 if (def
->flags
& VSH_CMD_FLAG_ALIAS
)
3217 def
= vshCmddefSearch(def
->alias
);
3218 return vshCmddefHelp(ctl
, def
);
3219 } else if ((grp
= vshCmdGrpSearch(name
))) {
3220 return vshCmdGrpHelp(ctl
, grp
);
3222 vshError(ctl
, _("command or command group '%s' doesn't exist"), name
);
3227 const vshCmdOptDef opts_cd
[] = {
3229 .type
= VSH_OT_STRING
,
3230 .help
= N_("directory to switch to (default: home or else root)")
3235 const vshCmdInfo info_cd
[] = {
3237 .data
= N_("change the current directory")
3240 .data
= N_("Change the current directory.")
3246 cmdCd(vshControl
*ctl
, const vshCmd
*cmd
)
3248 const char *dir
= NULL
;
3249 char *dir_malloced
= NULL
;
3254 vshError(ctl
, "%s", _("cd: command valid only in interactive mode"));
3258 if (vshCommandOptStringQuiet(ctl
, cmd
, "dir", &dir
) <= 0)
3259 dir
= dir_malloced
= virGetUserDirectory();
3263 if (chdir(dir
) == -1) {
3264 vshError(ctl
, _("cd: %s: %s"),
3265 virStrerror(errno
, ebuf
, sizeof(ebuf
)), dir
);
3269 VIR_FREE(dir_malloced
);
3273 const vshCmdOptDef opts_echo
[] = {
3275 .type
= VSH_OT_BOOL
,
3276 .help
= N_("escape for shell use")
3279 .type
= VSH_OT_BOOL
,
3280 .help
= N_("escape for XML use")
3283 .type
= VSH_OT_BOOL
,
3284 .help
= N_("output to stderr"),
3287 .type
= VSH_OT_ALIAS
,
3291 .type
= VSH_OT_ALIAS
,
3292 .help
= "string=hello"
3295 .type
= VSH_OT_ARGV
,
3296 .help
= N_("arguments to echo")
3301 const vshCmdInfo info_echo
[] = {
3303 .data
= N_("echo arguments")
3306 .data
= N_("Echo back arguments, possibly with quoting.")
3311 /* Exists mainly for debugging virsh, but also handy for adding back
3312 * quotes for later evaluation.
3315 cmdEcho(vshControl
*ctl
, const vshCmd
*cmd
)
3321 const vshCmdOpt
*opt
= NULL
;
3323 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
3325 if (vshCommandOptBool(cmd
, "shell"))
3327 if (vshCommandOptBool(cmd
, "xml"))
3329 if (vshCommandOptBool(cmd
, "err"))
3332 while ((opt
= vshCommandOptArgv(ctl
, cmd
, opt
))) {
3334 virBuffer xmlbuf
= VIR_BUFFER_INITIALIZER
;
3339 virBufferAddChar(&buf
, ' ');
3342 virBufferEscapeString(&xmlbuf
, "%s", arg
);
3343 if (virBufferError(&xmlbuf
)) {
3344 vshError(ctl
, "%s", _("Failed to allocate XML buffer"));
3347 str
= virBufferContentAndReset(&xmlbuf
);
3349 str
= vshStrdup(ctl
, arg
);
3353 virBufferEscapeShell(&buf
, str
);
3355 virBufferAdd(&buf
, str
, -1);
3360 if (virBufferError(&buf
)) {
3361 vshError(ctl
, "%s", _("Failed to allocate XML buffer"));
3364 arg
= virBufferContentAndReset(&buf
);
3367 vshError(ctl
, "%s", arg
);
3369 vshPrint(ctl
, "%s", arg
);
3375 const vshCmdInfo info_pwd
[] = {
3377 .data
= N_("print the current directory")
3380 .data
= N_("Print the current directory.")
3386 cmdPwd(vshControl
*ctl
, const vshCmd
*cmd ATTRIBUTE_UNUSED
)
3392 cwd
= getcwd(NULL
, 0);
3394 vshError(ctl
, _("pwd: cannot get current directory: %s"),
3395 virStrerror(errno
, ebuf
, sizeof(ebuf
)));
3398 vshPrint(ctl
, _("%s\n"), cwd
);
3405 const vshCmdInfo info_quit
[] = {
3407 .data
= N_("quit this interactive terminal")
3416 cmdQuit(vshControl
*ctl
, const vshCmd
*cmd ATTRIBUTE_UNUSED
)
3422 /* -----------------
3424 * ----------------- */
3426 const vshCmdInfo info_selftest
[] = {
3428 .data
= N_("internal command for testing virt shells")
3431 .data
= N_("internal use only")
3436 /* Prints help for every command.
3437 * That runs vshCmddefOptParse which validates
3438 * the per-command options structure. */
3440 cmdSelfTest(vshControl
*ctl
,
3441 const vshCmd
*cmd ATTRIBUTE_UNUSED
)
3443 const vshCmdGrp
*grp
;
3444 const vshCmdDef
*def
;
3446 for (grp
= cmdGroups
; grp
->name
; grp
++) {
3447 for (def
= grp
->commands
; def
->name
; def
++) {
3448 if (vshCmddefCheckInternals(ctl
, def
) < 0)
3456 /* ----------------------
3457 * Autocompletion command
3458 * ---------------------- */
3460 const vshCmdOptDef opts_complete
[] = {
3462 .type
= VSH_OT_ARGV
,
3463 .flags
= VSH_OFLAG_EMPTY_OK
,
3464 .help
= N_("partial string to autocomplete")
3469 const vshCmdInfo info_complete
[] = {
3471 .data
= N_("internal command for autocompletion")
3474 .data
= N_("internal use only")
3480 #ifdef WITH_READLINE
3482 cmdComplete(vshControl
*ctl
, const vshCmd
*cmd
)
3485 const vshClientHooks
*hooks
= ctl
->hooks
;
3486 int stdin_fileno
= STDIN_FILENO
;
3487 const char *arg
= "";
3488 const vshCmdOpt
*opt
= NULL
;
3489 char **matches
= NULL
, **iter
;
3490 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
3492 if (vshCommandOptStringQuiet(ctl
, cmd
, "string", &arg
) <= 0)
3495 /* This command is flagged VSH_CMD_FLAG_NOCONNECT because we
3496 * need to prevent auth hooks reading any input. Therefore, we
3497 * have to close stdin and then connect ourselves. */
3498 VIR_FORCE_CLOSE(stdin_fileno
);
3500 if (!(hooks
&& hooks
->connHandler
&& hooks
->connHandler(ctl
)))
3503 while ((opt
= vshCommandOptArgv(ctl
, cmd
, opt
))) {
3504 if (virBufferUse(&buf
) != 0)
3505 virBufferAddChar(&buf
, ' ');
3506 virBufferAddStr(&buf
, opt
->data
);
3510 if (virBufferCheckError(&buf
) < 0)
3513 vshReadlineInit(ctl
);
3515 if (!(rl_line_buffer
= virBufferContentAndReset(&buf
)) &&
3516 VIR_STRDUP(rl_line_buffer
, "") < 0)
3519 /* rl_point is current cursor position in rl_line_buffer.
3520 * In our case it's at the end of the whole line. */
3521 rl_point
= strlen(rl_line_buffer
);
3523 if (!(matches
= vshReadlineCompletion(arg
, 0, 0)))
3526 for (iter
= matches
; *iter
; iter
++) {
3527 if (iter
== matches
&& matches
[1])
3529 printf("%s\n", *iter
);
3534 virBufferFreeAndReset(&buf
);
3535 virStringListFree(matches
);
3540 #else /* !WITH_READLINE */
3544 cmdComplete(vshControl
*ctl ATTRIBUTE_UNUSED
,
3545 const vshCmd
*cmd ATTRIBUTE_UNUSED
)
3549 #endif /* !WITH_READLINE */