virsh.c 83.8 KB
Newer Older
1
/*
2
 * virsh.c: a shell to exercise the libvirt API
3
 *
4
 * Copyright (C) 2005, 2007-2013 Red Hat, Inc.
5
 *
O
Osier Yang 已提交
6 7 8 9 10 11 12 13 14 15 16
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20
 *
 * Daniel Veillard <veillard@redhat.com>
K
Karel Zak 已提交
21
 * Karel Zak <kzak@redhat.com>
K
Karel Zak 已提交
22
 * Daniel P. Berrange <berrange@redhat.com>
23 24
 */

25
#include <config.h>
E
Eric Blake 已提交
26
#include "virsh.h"
27

28
#include <assert.h>
29
#include <stdio.h>
K
Karel Zak 已提交
30 31 32
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
33
#include <unistd.h>
34
#include <errno.h>
K
Karel Zak 已提交
35
#include <getopt.h>
K
Karel Zak 已提交
36
#include <sys/time.h>
J
Jim Meyering 已提交
37
#include "c-ctype.h"
38
#include <fcntl.h>
39
#include <locale.h>
40
#include <time.h>
41
#include <limits.h>
42
#include <sys/stat.h>
43
#include <inttypes.h>
E
Eric Blake 已提交
44
#include <strings.h>
K
Karel Zak 已提交
45

46 47 48
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
49
#include <libxml/xmlsave.h>
50

51
#ifdef HAVE_READLINE_READLINE_H
52 53
# include <readline/readline.h>
# include <readline/history.h>
54
#endif
K
Karel Zak 已提交
55

56
#include "internal.h"
57
#include "virerror.h"
58
#include "base64.h"
59
#include "virbuffer.h"
60
#include "console.h"
61
#include "viralloc.h"
62
#include "virxml.h"
63 64
#include <libvirt/libvirt-qemu.h>
#include <libvirt/libvirt-lxc.h>
E
Eric Blake 已提交
65
#include "virfile.h"
66
#include "configmake.h"
67
#include "virthread.h"
68
#include "vircommand.h"
69
#include "virkeycode.h"
70
#include "virnetdevbandwidth.h"
71
#include "virbitmap.h"
H
Hu Tao 已提交
72
#include "conf/domain_conf.h"
73
#include "virtypedparam.h"
74
#include "virstring.h"
K
Karel Zak 已提交
75

E
Eric Blake 已提交
76
#include "virsh-domain.h"
77
#include "virsh-domain-monitor.h"
E
Eric Blake 已提交
78
#include "virsh-host.h"
E
Eric Blake 已提交
79
#include "virsh-interface.h"
E
Eric Blake 已提交
80
#include "virsh-network.h"
E
Eric Blake 已提交
81
#include "virsh-nodedev.h"
E
Eric Blake 已提交
82
#include "virsh-nwfilter.h"
E
Eric Blake 已提交
83
#include "virsh-pool.h"
E
Eric Blake 已提交
84
#include "virsh-secret.h"
E
Eric Blake 已提交
85
#include "virsh-snapshot.h"
E
Eric Blake 已提交
86
#include "virsh-volume.h"
E
Eric Blake 已提交
87

K
Karel Zak 已提交
88 89
static char *progname;

90
static const vshCmdGrp cmdGroups[];
K
Karel Zak 已提交
91

E
Eric Blake 已提交
92 93
/* Bypass header poison */
#undef strdup
94

E
Eric Blake 已提交
95
void *
E
Eric Blake 已提交
96 97
_vshMalloc(vshControl *ctl, size_t size, const char *filename, int line)
{
E
Eric Blake 已提交
98
    char *x;
E
Eric Blake 已提交
99

E
Eric Blake 已提交
100
    if (VIR_ALLOC_N(x, size) == 0)
E
Eric Blake 已提交
101 102 103 104 105 106
        return x;
    vshError(ctl, _("%s: %d: failed to allocate %d bytes"),
             filename, line, (int) size);
    exit(EXIT_FAILURE);
}

E
Eric Blake 已提交
107 108 109
void *
_vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename,
           int line)
E
Eric Blake 已提交
110
{
E
Eric Blake 已提交
111
    char *x;
E
Eric Blake 已提交
112

E
Eric Blake 已提交
113 114
    if (!xalloc_oversized(nmemb, size) &&
        VIR_ALLOC_N(x, nmemb * size) == 0)
E
Eric Blake 已提交
115 116 117 118 119 120
        return x;
    vshError(ctl, _("%s: %d: failed to allocate %d bytes"),
             filename, line, (int) (size*nmemb));
    exit(EXIT_FAILURE);
}

E
Eric Blake 已提交
121
char *
E
Eric Blake 已提交
122 123 124 125
_vshStrdup(vshControl *ctl, const char *s, const char *filename, int line)
{
    char *x;

126
    if (VIR_STRDUP(x, s) >= 0)
E
Eric Blake 已提交
127 128 129 130 131 132 133 134
        return x;
    vshError(ctl, _("%s: %d: failed to allocate %lu bytes"),
             filename, line, (unsigned long)strlen(s));
    exit(EXIT_FAILURE);
}

/* Poison the raw allocating identifiers in favor of our vsh variants.  */
#define strdup use_vshStrdup_instead_of_strdup
135

136
int
137 138 139 140
vshNameSorter(const void *a, const void *b)
{
    const char **sa = (const char**)a;
    const char **sb = (const char**)b;
141

142
    return vshStrcasecmp(*sa, *sb);
143 144
}

E
Eric Blake 已提交
145
double
E
Eric Blake 已提交
146
vshPrettyCapacity(unsigned long long val, const char **unit)
E
Eric Blake 已提交
147
{
148
    if (val < 1024) {
149
        *unit = "B";
150 151
        return (double)val;
    } else if (val < (1024.0l * 1024.0l)) {
152
        *unit = "KiB";
153 154
        return (((double)val / 1024.0l));
    } else if (val < (1024.0l * 1024.0l * 1024.0l)) {
155
        *unit = "MiB";
156
        return (double)val / (1024.0l * 1024.0l);
157
    } else if (val < (1024.0l * 1024.0l * 1024.0l * 1024.0l)) {
158
        *unit = "GiB";
159
        return (double)val / (1024.0l * 1024.0l * 1024.0l);
160
    } else {
161
        *unit = "TiB";
162
        return (double)val / (1024.0l * 1024.0l * 1024.0l * 1024.0l);
163 164 165
    }
}

166
/*
167 168 169
 * Convert the strings separated by ',' into array. The returned
 * array is a NULL terminated string list. The caller has to free
 * the array using virStringFreeList or a similar method.
170 171 172 173 174
 *
 * Returns the length of the filled array on success, or -1
 * on error.
 */
int
175
vshStringToArray(const char *str,
176 177
                 char ***array)
{
178
    char *str_copied = vshStrdup(NULL, str);
179
    char *str_tok = NULL;
E
Eric Blake 已提交
180
    char *tmp;
181 182
    unsigned int nstr_tokens = 0;
    char **arr = NULL;
E
Eric Blake 已提交
183
    size_t len = strlen(str_copied);
184

E
Eric Blake 已提交
185 186
    /* tokenize the string from user and save its parts into an array */
    nstr_tokens = 1;
187

E
Eric Blake 已提交
188 189 190 191 192
    /* count the delimiters, recognizing ,, as an escape for a
     * literal comma */
    str_tok = str_copied;
    while ((str_tok = strchr(str_tok, ','))) {
        if (str_tok[1] == ',')
193
            str_tok++;
E
Eric Blake 已提交
194 195 196 197
        else
            nstr_tokens++;
        str_tok++;
    }
198

199 200
    /* reserve the NULL element at the end */
    if (VIR_ALLOC_N(arr, nstr_tokens + 1) < 0) {
E
Eric Blake 已提交
201 202 203
        VIR_FREE(str_copied);
        return -1;
    }
204

E
Eric Blake 已提交
205 206 207 208 209 210 211 212 213 214 215
    /* tokenize the input string, while treating ,, as a literal comma */
    nstr_tokens = 0;
    tmp = str_tok = str_copied;
    while ((tmp = strchr(tmp, ','))) {
        if (tmp[1] == ',') {
            memmove(&tmp[1], &tmp[2], len - (tmp - str_copied) - 2 + 1);
            len--;
            tmp++;
            continue;
        }
        *tmp++ = '\0';
216
        arr[nstr_tokens++] = vshStrdup(NULL, str_tok);
E
Eric Blake 已提交
217
        str_tok = tmp;
218
    }
219
    arr[nstr_tokens++] = vshStrdup(NULL, str_tok);
220 221

    *array = arr;
222
    VIR_FREE(str_copied);
223 224
    return nstr_tokens;
}
225

E
Eric Blake 已提交
226
virErrorPtr last_error;
J
John Levon 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239

/*
 * Quieten libvirt until we're done with the command.
 */
static void
virshErrorHandler(void *unused ATTRIBUTE_UNUSED, virErrorPtr error)
{
    virFreeError(last_error);
    last_error = virSaveLastError();
    if (getenv("VIRSH_DEBUG") != NULL)
        virDefaultErrorFunc(error);
}

240 241 242 243 244 245 246 247 248
/* Store a libvirt error that is from a helper API that doesn't raise errors
 * so it doesn't get overwritten */
void
vshSaveLibvirtError(void)
{
    virFreeError(last_error);
    last_error = virSaveLastError();
}

249 250 251
/*
 * Reset libvirt error on graceful fallback paths
 */
E
Eric Blake 已提交
252
void
253 254 255 256 257 258
vshResetLibvirtError(void)
{
    virFreeError(last_error);
    last_error = NULL;
}

J
John Levon 已提交
259 260 261 262 263 264 265 266
/*
 * Report an error when a command finishes.  This is better than before
 * (when correct operation would report errors), but it has some
 * problems: we lose the smarter formatting of virDefaultErrorFunc(),
 * and it can become harder to debug problems, if errors get reported
 * twice during one command.  This case shouldn't really happen anyway,
 * and it's IMHO a bug that libvirt does that sometimes.
 */
E
Eric Blake 已提交
267
void
E
Eric Blake 已提交
268
vshReportError(vshControl *ctl)
J
John Levon 已提交
269
{
270 271 272 273 274 275 276 277
    if (last_error == NULL) {
        /* Calling directly into libvirt util functions won't trigger the
         * error callback (which sets last_error), so check it ourselves.
         *
         * If the returned error has CODE_OK, this most likely means that
         * no error was ever raised, so just ignore */
        last_error = virSaveLastError();
        if (!last_error || last_error->code == VIR_ERR_OK)
278
            goto out;
279
    }
J
John Levon 已提交
280 281

    if (last_error->code == VIR_ERR_OK) {
282
        vshError(ctl, "%s", _("unknown error"));
J
John Levon 已提交
283 284 285
        goto out;
    }

286
    vshError(ctl, "%s", last_error->message);
J
John Levon 已提交
287 288

out:
289
    vshResetLibvirtError();
J
John Levon 已提交
290 291
}

292 293 294 295 296 297 298 299
/*
 * Detection of disconnections and automatic reconnection support
 */
static int disconnected = 0; /* we may have been disconnected */

/*
 * vshCatchDisconnect:
 *
300 301
 * We get here when the connection was closed.  We can't do much in the
 * handler, just save the fact it was raised.
302
 */
L
Laine Stump 已提交
303
static void
304 305 306 307 308 309
vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
                   int reason,
                   void *opaque ATTRIBUTE_UNUSED)
{
    if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT)
        disconnected++;
310 311 312 313 314
}

/*
 * vshReconnect:
 *
L
Laine Stump 已提交
315
 * Reconnect after a disconnect from libvirtd
316 317
 *
 */
L
Laine Stump 已提交
318
static void
319 320 321 322
vshReconnect(vshControl *ctl)
{
    bool connected = false;

323 324 325
    if (ctl->conn) {
        int ret;

326
        connected = true;
327 328 329 330 331 332 333 334

        virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect);
        ret = virConnectClose(ctl->conn);
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
335
    }
336 337 338 339

    ctl->conn = virConnectOpenAuth(ctl->name,
                                   virConnectAuthPtrDefault,
                                   ctl->readonly ? VIR_CONNECT_RO : 0);
340
    if (!ctl->conn) {
341 342 343 344
        if (disconnected)
            vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
        else
            vshError(ctl, "%s", _("failed to connect to the hypervisor"));
345 346 347 348 349 350 351
    } else {
        if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
                                            NULL, NULL) < 0)
            vshError(ctl, "%s", _("Unable to register disconnect callback"));
        if (connected)
            vshError(ctl, "%s", _("Reconnected to the hypervisor"));
    }
352
    disconnected = 0;
353
    ctl->useGetInfo = false;
354
    ctl->useSnapshotOld = false;
355
}
356

357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392

/*
 * "connect" command
 */
static const vshCmdInfo info_connect[] = {
    {.name = "help",
     .data = N_("(re)connect to hypervisor")
    },
    {.name = "desc",
     .data = N_("Connect to local hypervisor. This is built-in "
                "command after shell start up.")
    },
    {.name = NULL}
};

static const vshCmdOptDef opts_connect[] = {
    {.name = "name",
     .type = VSH_OT_DATA,
     .flags = VSH_OFLAG_EMPTY_OK,
     .help = N_("hypervisor connection URI")
    },
    {.name = "readonly",
     .type = VSH_OT_BOOL,
     .help = N_("read-only connection")
    },
    {.name = NULL}
};

static bool
cmdConnect(vshControl *ctl, const vshCmd *cmd)
{
    bool ro = vshCommandOptBool(cmd, "readonly");
    const char *name = NULL;

    if (ctl->conn) {
        int ret;
393 394 395 396 397 398 399 400

        virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect);
        ret = virConnectClose(ctl->conn);
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
        ctl->conn = NULL;
    }

    VIR_FREE(ctl->name);
    if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0)
        return false;

    ctl->name = vshStrdup(ctl, name);

    ctl->useGetInfo = false;
    ctl->useSnapshotOld = false;
    ctl->readonly = ro;

    ctl->conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault,
                                   ctl->readonly ? VIR_CONNECT_RO : 0);

417
    if (!ctl->conn) {
418
        vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
419 420 421 422 423 424
        return false;
    }

    if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
                                        NULL, NULL) < 0)
        vshError(ctl, "%s", _("Unable to register disconnect callback"));
425

426
    return true;
427 428 429
}


430
#ifndef WIN32
431 432 433 434 435 436 437 438 439 440 441 442 443
static void
vshPrintRaw(vshControl *ctl, ...)
{
    va_list ap;
    char *key;

    va_start(ap, ctl);
    while ((key = va_arg(ap, char *)) != NULL) {
        vshPrint(ctl, "%s\r\n", key);
    }
    va_end(ap);
}

444 445 446 447 448 449 450 451 452 453 454 455 456
/**
 * vshAskReedit:
 * @msg: Question to ask user
 *
 * Ask user if he wants to return to previously
 * edited file.
 *
 * Returns 'y' if he wants to
 *         'f' if he forcibly wants to
 *         'n' if he doesn't want to
 *         -1  on error
 *          0  otherwise
 */
E
Eric Blake 已提交
457
int
458 459 460 461 462 463 464 465
vshAskReedit(vshControl *ctl, const char *msg)
{
    int c = -1;
    struct termios ttyattr;

    if (!isatty(STDIN_FILENO))
        return -1;

E
Eric Blake 已提交
466
    vshReportError(ctl);
467 468 469 470 471 472 473 474 475 476 477

    if (vshMakeStdinRaw(&ttyattr, false) < 0)
        return -1;

    while (true) {
        /* TRANSLATORS: For now, we aren't using LC_MESSAGES, and the user
         * choices really are limited to just 'y', 'n', 'f' and '?'  */
        vshPrint(ctl, "\r%s %s", msg, _("Try again? [y,n,f,?]:"));
        c = c_tolower(getchar());

        if (c == '?') {
478 479 480 481 482 483 484
            vshPrintRaw(ctl,
                        "",
                        _("y - yes, start editor again"),
                        _("n - no, throw away my changes"),
                        _("f - force, try to redefine again"),
                        _("? - print this help"),
                        NULL);
485 486 487 488 489 490 491 492 493 494
            continue;
        } else if (c == 'y' || c == 'n' || c == 'f') {
            break;
        }
    }

    tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr);

    vshPrint(ctl, "\r\n");
    return c;
495 496
}
#else /* WIN32 */
497
int
498 499
vshAskReedit(vshControl *ctl, const char *msg ATTRIBUTE_UNUSED)
{
500 501 502 503
    vshDebug(ctl, VSH_ERR_WARNING, "%s", _("This function is not "
                                           "supported on WIN32 platform"));
    return 0;
}
504
#endif /* WIN32 */
505

E
Eric Blake 已提交
506 507
int vshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
                  const char *bytes, size_t nbytes, void *opaque)
508 509 510 511 512 513
{
    int *fd = opaque;

    return safewrite(*fd, bytes, nbytes);
}

K
Karel Zak 已提交
514 515 516 517 518 519
/* ---------------
 * Commands
 * ---------------
 */

/*
520
 * "help" command
K
Karel Zak 已提交
521
 */
522
static const vshCmdInfo info_help[] = {
523 524 525 526 527 528 529 530
    {.name = "help",
     .data = N_("print help")
    },
    {.name = "desc",
     .data = N_("Prints global help, command specific help, or help for a\n"
                "    group of related commands")
    },
    {.name = NULL}
K
Karel Zak 已提交
531 532
};

533
static const vshCmdOptDef opts_help[] = {
534 535 536 537 538
    {.name = "command",
     .type = VSH_OT_DATA,
     .help = N_("Prints global help, command specific help, or help for a group of related commands")
    },
    {.name = NULL}
K
Karel Zak 已提交
539 540
};

E
Eric Blake 已提交
541
static bool
542
cmdHelp(vshControl *ctl, const vshCmd *cmd)
543
 {
544
    const char *name = NULL;
545

546
    if (vshCommandOptString(cmd, "command", &name) <= 0) {
547
        const vshCmdGrp *grp;
548
        const vshCmdDef *def;
549

550 551 552 553 554 555
        vshPrint(ctl, "%s", _("Grouped commands:\n\n"));

        for (grp = cmdGroups; grp->name; grp++) {
            vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
                     grp->keyword);

556 557 558
            for (def = grp->commands; def->name; def++) {
                if (def->flags & VSH_CMD_FLAG_ALIAS)
                    continue;
559 560
                vshPrint(ctl, "    %-30s %s\n", def->name,
                         _(vshCmddefGetInfo(def, "help")));
561
            }
562 563 564 565

            vshPrint(ctl, "\n");
        }

E
Eric Blake 已提交
566
        return true;
567
    }
568

E
Eric Blake 已提交
569
    if (vshCmddefSearch(name)) {
570
        return vshCmddefHelp(ctl, name);
E
Eric Blake 已提交
571
    } else if (vshCmdGrpSearch(name)) {
572 573 574
        return vshCmdGrpHelp(ctl, name);
    } else {
        vshError(ctl, _("command or command group '%s' doesn't exist"), name);
E
Eric Blake 已提交
575
        return false;
K
Karel Zak 已提交
576 577 578
    }
}

579 580 581 582 583 584 585 586 587 588 589
/* Tree listing helpers.  */

static int
vshTreePrintInternal(vshControl *ctl,
                     vshTreeLookup lookup,
                     void *opaque,
                     int num_devices,
                     int devid,
                     int lastdev,
                     bool root,
                     virBufferPtr indent)
590
{
591
    size_t i;
592 593 594
    int nextlastdev = -1;
    int ret = -1;
    const char *dev = (lookup)(devid, false, opaque);
595

596
    if (virBufferError(indent))
597 598
        goto cleanup;

599 600 601 602 603 604 605 606 607 608
    /* Print this device, with indent if not at root */
    vshPrint(ctl, "%s%s%s\n", virBufferCurrentContent(indent),
             root ? "" : "+- ", dev);

    /* Update indent to show '|' or ' ' for child devices */
    if (!root) {
        virBufferAddChar(indent, devid == lastdev ? ' ' : '|');
        virBufferAddChar(indent, ' ');
        if (virBufferError(indent))
            goto cleanup;
609 610
    }

611
    /* Determine the index of the last child device */
612
    for (i = 0; i < num_devices; i++) {
613
        const char *parent = (lookup)(i, true, opaque);
614

615 616 617
        if (parent && STREQ(parent, dev))
            nextlastdev = i;
    }
618

619 620 621
    /* If there is a child device, then print another blank line */
    if (nextlastdev != -1)
        vshPrint(ctl, "%s  |\n", virBufferCurrentContent(indent));
622

623 624
    /* Finally print all children */
    virBufferAddLit(indent, "  ");
625 626
    if (virBufferError(indent))
        goto cleanup;
627
    for (i = 0; i < num_devices; i++) {
628
        const char *parent = (lookup)(i, true, opaque);
629

630 631 632 633 634
        if (parent && STREQ(parent, dev) &&
            vshTreePrintInternal(ctl, lookup, opaque,
                                 num_devices, i, nextlastdev,
                                 false, indent) < 0)
            goto cleanup;
635
    }
J
Ján Tomko 已提交
636
    virBufferTrim(indent, "  ", -1);
637

638 639 640 641
    /* If there was no child device, and we're the last in
     * a list of devices, then print another blank line */
    if (nextlastdev == -1 && devid == lastdev)
        vshPrint(ctl, "%s\n", virBufferCurrentContent(indent));
642

J
Ján Tomko 已提交
643 644
    if (!root)
        virBufferTrim(indent, NULL, 2);
645
    ret = 0;
646 647 648 649
cleanup:
    return ret;
}

E
Eric Blake 已提交
650
int
651 652
vshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque,
             int num_devices, int devid)
653
{
654 655
    int ret;
    virBuffer indent = VIR_BUFFER_INITIALIZER;
656

657 658 659 660 661
    ret = vshTreePrintInternal(ctl, lookup, opaque, num_devices,
                               devid, devid, true, &indent);
    if (ret < 0)
        vshError(ctl, "%s", _("Failed to complete tree listing"));
    virBufferFreeAndReset(&indent);
662
    return ret;
663
}
664

665
/* Common code for the edit / net-edit / pool-edit functions which follow. */
E
Eric Blake 已提交
666
char *
E
Eric Blake 已提交
667
vshEditWriteToTempFile(vshControl *ctl, const char *doc)
668 669 670 671
{
    char *ret;
    const char *tmpdir;
    int fd;
672
    char ebuf[1024];
673

674
    tmpdir = getenv("TMPDIR");
675
    if (!tmpdir) tmpdir = "/tmp";
676 677 678 679
    if (virAsprintf(&ret, "%s/virshXXXXXX.xml", tmpdir) < 0) {
        vshError(ctl, "%s", _("out of memory"));
        return NULL;
    }
680
    fd = mkostemps(ret, 4, O_CLOEXEC);
681
    if (fd == -1) {
682
        vshError(ctl, _("mkostemps: failed to create temporary file: %s"),
683
                 virStrerror(errno, ebuf, sizeof(ebuf)));
684
        VIR_FREE(ret);
685 686 687
        return NULL;
    }

688
    if (safewrite(fd, doc, strlen(doc)) == -1) {
689
        vshError(ctl, _("write: %s: failed to write to temporary file: %s"),
690
                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
S
Stefan Berger 已提交
691
        VIR_FORCE_CLOSE(fd);
692
        unlink(ret);
693
        VIR_FREE(ret);
694 695
        return NULL;
    }
S
Stefan Berger 已提交
696
    if (VIR_CLOSE(fd) < 0) {
697
        vshError(ctl, _("close: %s: failed to write or close temporary file: %s"),
698
                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
699
        unlink(ret);
700
        VIR_FREE(ret);
701 702 703 704 705 706 707 708 709 710 711
        return NULL;
    }

    /* Temporary filename: caller frees. */
    return ret;
}

/* Characters permitted in $EDITOR environment variable and temp filename. */
#define ACCEPTED_CHARS \
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/_.:@"

E
Eric Blake 已提交
712
int
E
Eric Blake 已提交
713
vshEditFile(vshControl *ctl, const char *filename)
714 715
{
    const char *editor;
E
Eric Blake 已提交
716 717 718 719
    virCommandPtr cmd;
    int ret = -1;
    int outfd = STDOUT_FILENO;
    int errfd = STDERR_FILENO;
720

721
    editor = getenv("VISUAL");
E
Eric Blake 已提交
722
    if (!editor)
723
        editor = getenv("EDITOR");
E
Eric Blake 已提交
724 725
    if (!editor)
        editor = "vi"; /* could be cruel & default to ed(1) here */
726

727 728 729 730 731
    /* Check that filename doesn't contain shell meta-characters, and
     * if it does, refuse to run.  Follow the Unix conventions for
     * EDITOR: the user can intentionally specify command options, so
     * we don't protect any shell metacharacters there.  Lots more
     * than virsh will misbehave if EDITOR has bogus contents (which
E
Eric Blake 已提交
732 733
     * is why sudo scrubs it by default).  Conversely, if the editor
     * is safe, we can run it directly rather than wasting a shell.
734
     */
735 736
    if (strspn(editor, ACCEPTED_CHARS) != strlen(editor)) {
        if (strspn(filename, ACCEPTED_CHARS) != strlen(filename)) {
E
Eric Blake 已提交
737 738 739 740 741 742 743 744 745 746
            vshError(ctl,
                     _("%s: temporary filename contains shell meta or other "
                       "unacceptable characters (is $TMPDIR wrong?)"),
                     filename);
            return -1;
        }
        cmd = virCommandNewArgList("sh", "-c", NULL);
        virCommandAddArgFormat(cmd, "%s %s", editor, filename);
    } else {
        cmd = virCommandNewArgList(editor, filename, NULL);
747 748
    }

E
Eric Blake 已提交
749 750 751 752 753
    virCommandSetInputFD(cmd, STDIN_FILENO);
    virCommandSetOutputFD(cmd, &outfd);
    virCommandSetErrorFD(cmd, &errfd);
    if (virCommandRunAsync(cmd, NULL) < 0 ||
        virCommandWait(cmd, NULL) < 0) {
E
Eric Blake 已提交
754
        vshReportError(ctl);
E
Eric Blake 已提交
755
        goto cleanup;
756
    }
E
Eric Blake 已提交
757
    ret = 0;
758

E
Eric Blake 已提交
759 760 761
cleanup:
    virCommandFree(cmd);
    return ret;
762 763
}

E
Eric Blake 已提交
764
char *
E
Eric Blake 已提交
765
vshEditReadBackFile(vshControl *ctl, const char *filename)
766 767
{
    char *ret;
768
    char ebuf[1024];
769

E
Eric Blake 已提交
770
    if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) {
771
        vshError(ctl,
772
                 _("%s: failed to read temporary file: %s"),
773
                 filename, virStrerror(errno, ebuf, sizeof(ebuf)));
774 775 776 777 778
        return NULL;
    }
    return ret;
}

779

P
Paolo Bonzini 已提交
780 781 782 783
/*
 * "cd" command
 */
static const vshCmdInfo info_cd[] = {
784 785 786 787 788 789 790
    {.name = "help",
     .data = N_("change the current directory")
    },
    {.name = "desc",
     .data = N_("Change the current directory.")
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
791 792 793
};

static const vshCmdOptDef opts_cd[] = {
794 795 796 797 798
    {.name = "dir",
     .type = VSH_OT_DATA,
     .help = N_("directory to switch to (default: home or else root)")
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
799 800
};

E
Eric Blake 已提交
801
static bool
802
cmdCd(vshControl *ctl, const vshCmd *cmd)
P
Paolo Bonzini 已提交
803
{
804
    const char *dir = NULL;
805
    char *dir_malloced = NULL;
E
Eric Blake 已提交
806
    bool ret = true;
807
    char ebuf[1024];
P
Paolo Bonzini 已提交
808 809

    if (!ctl->imode) {
810
        vshError(ctl, "%s", _("cd: command valid only in interactive mode"));
E
Eric Blake 已提交
811
        return false;
P
Paolo Bonzini 已提交
812 813
    }

814
    if (vshCommandOptString(cmd, "dir", &dir) <= 0) {
815
        dir = dir_malloced = virGetUserDirectory();
P
Paolo Bonzini 已提交
816 817 818 819
    }
    if (!dir)
        dir = "/";

P
Phil Petty 已提交
820
    if (chdir(dir) == -1) {
821 822
        vshError(ctl, _("cd: %s: %s"),
                 virStrerror(errno, ebuf, sizeof(ebuf)), dir);
E
Eric Blake 已提交
823
        ret = false;
P
Paolo Bonzini 已提交
824 825
    }

826
    VIR_FREE(dir_malloced);
P
Phil Petty 已提交
827
    return ret;
P
Paolo Bonzini 已提交
828 829 830 831 832 833
}

/*
 * "pwd" command
 */
static const vshCmdInfo info_pwd[] = {
834 835 836 837 838 839 840
    {.name = "help",
     .data = N_("print the current directory")
    },
    {.name = "desc",
     .data = N_("Print the current directory.")
    },
    {.name = NULL}
P
Paolo Bonzini 已提交
841 842
};

E
Eric Blake 已提交
843
static bool
P
Paolo Bonzini 已提交
844 845 846
cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
    char *cwd;
847
    bool ret = true;
848
    char ebuf[1024];
P
Paolo Bonzini 已提交
849

850 851
    cwd = getcwd(NULL, 0);
    if (!cwd) {
852
        vshError(ctl, _("pwd: cannot get current directory: %s"),
853
                 virStrerror(errno, ebuf, sizeof(ebuf)));
854 855
        ret = false;
    } else {
856
        vshPrint(ctl, _("%s\n"), cwd);
857 858
        VIR_FREE(cwd);
    }
P
Paolo Bonzini 已提交
859

860
    return ret;
P
Paolo Bonzini 已提交
861 862
}

E
Eric Blake 已提交
863 864 865 866
/*
 * "echo" command
 */
static const vshCmdInfo info_echo[] = {
867 868 869 870 871 872 873
    {.name = "help",
     .data = N_("echo arguments")
    },
    {.name = "desc",
     .data = N_("Echo back arguments, possibly with quoting.")
    },
    {.name = NULL}
E
Eric Blake 已提交
874 875 876
};

static const vshCmdOptDef opts_echo[] = {
877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
    {.name = "shell",
     .type = VSH_OT_BOOL,
     .help = N_("escape for shell use")
    },
    {.name = "xml",
     .type = VSH_OT_BOOL,
     .help = N_("escape for XML use")
    },
    {.name = "str",
     .type = VSH_OT_ALIAS,
     .help = "string"
    },
    {.name = "string",
     .type = VSH_OT_ARGV,
     .help = N_("arguments to echo")
    },
    {.name = NULL}
E
Eric Blake 已提交
894 895 896 897 898
};

/* Exists mainly for debugging virsh, but also handy for adding back
 * quotes for later evaluation.
 */
E
Eric Blake 已提交
899
static bool
900
cmdEcho(vshControl *ctl, const vshCmd *cmd)
E
Eric Blake 已提交
901 902 903 904
{
    bool shell = false;
    bool xml = false;
    int count = 0;
905
    const vshCmdOpt *opt = NULL;
E
Eric Blake 已提交
906 907 908 909 910 911 912 913
    char *arg;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (vshCommandOptBool(cmd, "shell"))
        shell = true;
    if (vshCommandOptBool(cmd, "xml"))
        xml = true;

914
    while ((opt = vshCommandOptArgv(cmd, opt))) {
915 916
        char *str;
        virBuffer xmlbuf = VIR_BUFFER_INITIALIZER;
E
Eric Blake 已提交
917

918
        arg = opt->data;
919

E
Eric Blake 已提交
920 921
        if (count)
            virBufferAddChar(&buf, ' ');
922

E
Eric Blake 已提交
923
        if (xml) {
924 925 926 927
            virBufferEscapeString(&xmlbuf, "%s", arg);
            if (virBufferError(&buf)) {
                vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
                return false;
E
Eric Blake 已提交
928
            }
929 930 931
            str = virBufferContentAndReset(&xmlbuf);
        } else {
            str = vshStrdup(ctl, arg);
E
Eric Blake 已提交
932
        }
933 934 935 936 937

        if (shell)
            virBufferEscapeShell(&buf, str);
        else
            virBufferAdd(&buf, str, -1);
E
Eric Blake 已提交
938
        count++;
939
        VIR_FREE(str);
E
Eric Blake 已提交
940 941 942 943
    }

    if (virBufferError(&buf)) {
        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
E
Eric Blake 已提交
944
        return false;
E
Eric Blake 已提交
945 946 947 948 949
    }
    arg = virBufferContentAndReset(&buf);
    if (arg)
        vshPrint(ctl, "%s", arg);
    VIR_FREE(arg);
E
Eric Blake 已提交
950
    return true;
E
Eric Blake 已提交
951 952
}

K
Karel Zak 已提交
953 954 955
/*
 * "quit" command
 */
956
static const vshCmdInfo info_quit[] = {
957 958 959 960 961 962 963
    {.name = "help",
     .data = N_("quit this interactive terminal")
    },
    {.name = "desc",
     .data = ""
    },
    {.name = NULL}
K
Karel Zak 已提交
964 965
};

E
Eric Blake 已提交
966
static bool
967
cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
968
{
E
Eric Blake 已提交
969 970
    ctl->imode = false;
    return true;
K
Karel Zak 已提交
971 972
}

973 974 975 976
/* ---------------
 * Utils for work with command definition
 * ---------------
 */
E
Eric Blake 已提交
977
const char *
978 979 980
vshCmddefGetInfo(const vshCmdDef * cmd, const char *name)
{
    const vshCmdInfo *info;
981

982 983 984 985 986 987
    for (info = cmd->info; info && info->name; info++) {
        if (STREQ(info->name, name))
            return info->data;
    }
    return NULL;
}
988

989 990 991 992 993
/* Validate that the options associated with cmd can be parsed.  */
static int
vshCmddefOptParse(const vshCmdDef *cmd, uint32_t *opts_need_arg,
                  uint32_t *opts_required)
{
994
    size_t i;
995
    bool optional = false;
996

997 998
    *opts_need_arg = 0;
    *opts_required = 0;
999

1000 1001
    if (!cmd->opts)
        return 0;
1002

1003 1004
    for (i = 0; cmd->opts[i].name; i++) {
        const vshCmdOptDef *opt = &cmd->opts[i];
1005 1006 1007 1008

        if (i > 31)
            return -1; /* too many options */
        if (opt->type == VSH_OT_BOOL) {
E
Eric Blake 已提交
1009
            if (opt->flags & VSH_OFLAG_REQ)
1010 1011 1012
                return -1; /* bool options can't be mandatory */
            continue;
        }
E
Eric Blake 已提交
1013
        if (opt->type == VSH_OT_ALIAS) {
1014
            size_t j;
E
Eric Blake 已提交
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
            if (opt->flags || !opt->help)
                return -1; /* alias options are tracked by the original name */
            for (j = i + 1; cmd->opts[j].name; j++) {
                if (STREQ(opt->help, cmd->opts[j].name))
                    break;
            }
            if (!cmd->opts[j].name)
                return -1; /* alias option must map to a later option name */
            continue;
        }
E
Eric Blake 已提交
1025 1026
        if (opt->flags & VSH_OFLAG_REQ_OPT) {
            if (opt->flags & VSH_OFLAG_REQ)
L
Lai Jiangshan 已提交
1027 1028 1029 1030
                *opts_required |= 1 << i;
            continue;
        }

1031
        *opts_need_arg |= 1 << i;
E
Eric Blake 已提交
1032
        if (opt->flags & VSH_OFLAG_REQ) {
1033 1034 1035 1036 1037 1038
            if (optional)
                return -1; /* mandatory options must be listed first */
            *opts_required |= 1 << i;
        } else {
            optional = true;
        }
1039 1040 1041

        if (opt->type == VSH_OT_ARGV && cmd->opts[i + 1].name)
            return -1; /* argv option must be listed last */
1042 1043 1044 1045
    }
    return 0;
}

1046 1047 1048 1049 1050
static vshCmdOptDef helpopt = {
    .name = "help",
    .type = VSH_OT_BOOL,
    .help = N_("print help for this function")
};
1051
static const vshCmdOptDef *
1052
vshCmddefGetOption(vshControl *ctl, const vshCmdDef *cmd, const char *name,
1053
                   uint32_t *opts_seen, int *opt_index)
1054
{
1055
    size_t i;
1056

1057 1058 1059 1060
    if (STREQ(name, helpopt.name)) {
        return &helpopt;
    }

1061 1062
    for (i = 0; cmd->opts && cmd->opts[i].name; i++) {
        const vshCmdOptDef *opt = &cmd->opts[i];
1063

1064
        if (STREQ(opt->name, name)) {
E
Eric Blake 已提交
1065 1066 1067 1068
            if (opt->type == VSH_OT_ALIAS) {
                name = opt->help;
                continue;
            }
1069
            if ((*opts_seen & (1 << i)) && opt->type != VSH_OT_ARGV) {
1070 1071 1072
                vshError(ctl, _("option --%s already seen"), name);
                return NULL;
            }
1073 1074
            *opts_seen |= 1 << i;
            *opt_index = i;
K
Karel Zak 已提交
1075
            return opt;
1076 1077 1078
        }
    }

1079 1080 1081 1082
    if (STRNEQ(cmd->name, "help")) {
        vshError(ctl, _("command '%s' doesn't support option --%s"),
                 cmd->name, name);
    }
K
Karel Zak 已提交
1083 1084 1085
    return NULL;
}

1086
static const vshCmdOptDef *
1087 1088
vshCmddefGetData(const vshCmdDef *cmd, uint32_t *opts_need_arg,
                 uint32_t *opts_seen)
1089
{
1090
    size_t i;
1091
    const vshCmdOptDef *opt;
K
Karel Zak 已提交
1092

1093 1094 1095 1096
    if (!*opts_need_arg)
        return NULL;

    /* Grab least-significant set bit */
E
Eric Blake 已提交
1097
    i = ffs(*opts_need_arg) - 1;
1098
    opt = &cmd->opts[i];
1099
    if (opt->type != VSH_OT_ARGV)
1100
        *opts_need_arg &= ~(1 << i);
1101
    *opts_seen |= 1 << i;
1102
    return opt;
K
Karel Zak 已提交
1103 1104
}

1105 1106 1107
/*
 * Checks for required options
 */
1108
static int
1109 1110
vshCommandCheckOpts(vshControl *ctl, const vshCmd *cmd, uint32_t opts_required,
                    uint32_t opts_seen)
1111
{
1112
    const vshCmdDef *def = cmd->def;
1113
    size_t i;
1114 1115 1116 1117 1118 1119 1120 1121

    opts_required &= ~opts_seen;
    if (!opts_required)
        return 0;

    for (i = 0; def->opts[i].name; i++) {
        if (opts_required & (1 << i)) {
            const vshCmdOptDef *opt = &def->opts[i];
1122

1123
            vshError(ctl,
1124
                     opt->type == VSH_OT_DATA || opt->type == VSH_OT_ARGV ?
1125 1126 1127
                     _("command '%s' requires <%s> option") :
                     _("command '%s' requires --%s option"),
                     def->name, opt->name);
1128 1129
        }
    }
1130
    return -1;
1131 1132
}

E
Eric Blake 已提交
1133
const vshCmdDef *
1134 1135
vshCmddefSearch(const char *cmdname)
{
1136
    const vshCmdGrp *g;
1137
    const vshCmdDef *c;
1138

1139 1140
    for (g = cmdGroups; g->name; g++) {
        for (c = g->commands; c->name; c++) {
1141
            if (STREQ(c->name, cmdname))
1142 1143 1144 1145
                return c;
        }
    }

K
Karel Zak 已提交
1146 1147 1148
    return NULL;
}

E
Eric Blake 已提交
1149
const vshCmdGrp *
1150 1151 1152 1153 1154
vshCmdGrpSearch(const char *grpname)
{
    const vshCmdGrp *g;

    for (g = cmdGroups; g->name; g++) {
1155
        if (STREQ(g->name, grpname) || STREQ(g->keyword, grpname))
1156 1157 1158 1159 1160 1161
            return g;
    }

    return NULL;
}

E
Eric Blake 已提交
1162
bool
1163 1164 1165 1166 1167 1168 1169
vshCmdGrpHelp(vshControl *ctl, const char *grpname)
{
    const vshCmdGrp *grp = vshCmdGrpSearch(grpname);
    const vshCmdDef *cmd = NULL;

    if (!grp) {
        vshError(ctl, _("command group '%s' doesn't exist"), grpname);
E
Eric Blake 已提交
1170
        return false;
1171 1172 1173 1174 1175
    } else {
        vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
                 grp->keyword);

        for (cmd = grp->commands; cmd->name; cmd++) {
1176 1177
            if (cmd->flags & VSH_CMD_FLAG_ALIAS)
                continue;
1178 1179 1180 1181 1182
            vshPrint(ctl, "    %-30s %s\n", cmd->name,
                     _(vshCmddefGetInfo(cmd, "help")));
        }
    }

E
Eric Blake 已提交
1183
    return true;
1184 1185
}

E
Eric Blake 已提交
1186
bool
1187
vshCmddefHelp(vshControl *ctl, const char *cmdname)
1188
{
1189
    const vshCmdDef *def = vshCmddefSearch(cmdname);
1190

K
Karel Zak 已提交
1191
    if (!def) {
1192
        vshError(ctl, _("command '%s' doesn't exist"), cmdname);
E
Eric Blake 已提交
1193
        return false;
1194
    } else {
E
Eric Blake 已提交
1195 1196
        /* Don't translate desc if it is "".  */
        const char *desc = vshCmddefGetInfo(def, "desc");
E
Eric Blake 已提交
1197
        const char *help = _(vshCmddefGetInfo(def, "help"));
1198
        char buf[256];
1199 1200
        uint32_t opts_need_arg;
        uint32_t opts_required;
1201
        bool shortopt = false; /* true if 'arg' works instead of '--opt arg' */
1202 1203 1204 1205

        if (vshCmddefOptParse(def, &opts_need_arg, &opts_required)) {
            vshError(ctl, _("internal error: bad options in command: '%s'"),
                     def->name);
E
Eric Blake 已提交
1206
            return false;
1207
        }
K
Karel Zak 已提交
1208

1209
        fputs(_("  NAME\n"), stdout);
1210 1211
        fprintf(stdout, "    %s - %s\n", def->name, help);

1212 1213 1214 1215 1216
        fputs(_("\n  SYNOPSIS\n"), stdout);
        fprintf(stdout, "    %s", def->name);
        if (def->opts) {
            const vshCmdOptDef *opt;
            for (opt = def->opts; opt->name; opt++) {
1217
                const char *fmt = "%s";
1218 1219
                switch (opt->type) {
                case VSH_OT_BOOL:
1220
                    fmt = "[--%s]";
1221 1222
                    break;
                case VSH_OT_INT:
E
Eric Blake 已提交
1223
                    /* xgettext:c-format */
E
Eric Blake 已提交
1224
                    fmt = ((opt->flags & VSH_OFLAG_REQ) ? "<%s>"
1225
                           : _("[--%s <number>]"));
1226 1227
                    if (!(opt->flags & VSH_OFLAG_REQ_OPT))
                        shortopt = true;
1228 1229
                    break;
                case VSH_OT_STRING:
E
Eric Blake 已提交
1230 1231
                    /* xgettext:c-format */
                    fmt = _("[--%s <string>]");
1232 1233
                    if (!(opt->flags & VSH_OFLAG_REQ_OPT))
                        shortopt = true;
1234 1235
                    break;
                case VSH_OT_DATA:
E
Eric Blake 已提交
1236
                    fmt = ((opt->flags & VSH_OFLAG_REQ) ? "<%s>" : "[<%s>]");
1237 1238
                    if (!(opt->flags & VSH_OFLAG_REQ_OPT))
                        shortopt = true;
1239 1240 1241
                    break;
                case VSH_OT_ARGV:
                    /* xgettext:c-format */
1242 1243 1244 1245 1246 1247 1248 1249
                    if (shortopt) {
                        fmt = (opt->flags & VSH_OFLAG_REQ)
                            ? _("{[--%s] <string>}...")
                            : _("[[--%s] <string>]...");
                    } else {
                        fmt = (opt->flags & VSH_OFLAG_REQ) ? _("<%s>...")
                            : _("[<%s>]...");
                    }
1250
                    break;
E
Eric Blake 已提交
1251 1252 1253
                case VSH_OT_ALIAS:
                    /* aliases are intentionally undocumented */
                    continue;
1254
                }
1255
                fputc(' ', stdout);
E
Eric Blake 已提交
1256
                fprintf(stdout, fmt, opt->name);
1257
            }
K
Karel Zak 已提交
1258
        }
1259 1260 1261
        fputc('\n', stdout);

        if (desc[0]) {
1262
            /* Print the description only if it's not empty.  */
1263
            fputs(_("\n  DESCRIPTION\n"), stdout);
E
Eric Blake 已提交
1264
            fprintf(stdout, "    %s\n", _(desc));
K
Karel Zak 已提交
1265
        }
1266

1267
        if (def->opts && def->opts->name) {
1268
            const vshCmdOptDef *opt;
1269
            fputs(_("\n  OPTIONS\n"), stdout);
1270
            for (opt = def->opts; opt->name; opt++) {
1271 1272
                switch (opt->type) {
                case VSH_OT_BOOL:
K
Karel Zak 已提交
1273
                    snprintf(buf, sizeof(buf), "--%s", opt->name);
1274 1275
                    break;
                case VSH_OT_INT:
1276
                    snprintf(buf, sizeof(buf),
E
Eric Blake 已提交
1277
                             (opt->flags & VSH_OFLAG_REQ) ? _("[--%s] <number>")
1278
                             : _("--%s <number>"), opt->name);
1279 1280
                    break;
                case VSH_OT_STRING:
1281
                    /* OT_STRING should never be VSH_OFLAG_REQ */
1282
                    snprintf(buf, sizeof(buf), _("--%s <string>"), opt->name);
1283 1284
                    break;
                case VSH_OT_DATA:
1285 1286
                    snprintf(buf, sizeof(buf), _("[--%s] <string>"),
                             opt->name);
1287 1288
                    break;
                case VSH_OT_ARGV:
1289 1290 1291
                    snprintf(buf, sizeof(buf),
                             shortopt ? _("[--%s] <string>") : _("<%s>"),
                             opt->name);
1292
                    break;
E
Eric Blake 已提交
1293 1294
                case VSH_OT_ALIAS:
                    continue;
1295
                }
1296

E
Eric Blake 已提交
1297
                fprintf(stdout, "    %-15s  %s\n", buf, _(opt->help));
1298
            }
K
Karel Zak 已提交
1299 1300 1301
        }
        fputc('\n', stdout);
    }
E
Eric Blake 已提交
1302
    return true;
K
Karel Zak 已提交
1303 1304 1305 1306 1307 1308
}

/* ---------------
 * Utils for work with runtime commands data
 * ---------------
 */
1309 1310 1311
static void
vshCommandOptFree(vshCmdOpt * arg)
{
K
Karel Zak 已提交
1312 1313
    vshCmdOpt *a = arg;

1314
    while (a) {
K
Karel Zak 已提交
1315
        vshCmdOpt *tmp = a;
1316

K
Karel Zak 已提交
1317 1318
        a = a->next;

1319 1320
        VIR_FREE(tmp->data);
        VIR_FREE(tmp);
K
Karel Zak 已提交
1321 1322 1323 1324
    }
}

static void
1325
vshCommandFree(vshCmd *cmd)
1326
{
K
Karel Zak 已提交
1327 1328
    vshCmd *c = cmd;

1329
    while (c) {
K
Karel Zak 已提交
1330
        vshCmd *tmp = c;
1331

K
Karel Zak 已提交
1332 1333 1334 1335
        c = c->next;

        if (tmp->opts)
            vshCommandOptFree(tmp->opts);
1336
        VIR_FREE(tmp);
K
Karel Zak 已提交
1337 1338 1339
    }
}

E
Eric Blake 已提交
1340 1341 1342 1343 1344
/**
 * vshCommandOpt:
 * @cmd: parsed command line to search
 * @name: option name to search for
 * @opt: result of the search
1345
 * @needData: true if option must be non-boolean
E
Eric Blake 已提交
1346 1347 1348 1349
 *
 * Look up an option passed to CMD by NAME.  Returns 1 with *OPT set
 * to the option if found, 0 with *OPT set to NULL if the name is
 * valid and the option is not required, -1 with *OPT set to NULL if
1350 1351 1352
 * the option is required but not present, and assert if NAME is not
 * valid (which indicates a programming error).  No error messages are
 * issued if a value is returned.
K
Karel Zak 已提交
1353
 */
1354 1355 1356
static int
vshCommandOpt(const vshCmd *cmd, const char *name, vshCmdOpt **opt,
              bool needData)
1357
{
E
Eric Blake 已提交
1358 1359
    vshCmdOpt *candidate = cmd->opts;
    const vshCmdOptDef *valid = cmd->def->opts;
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
    int ret = 0;

    /* See if option is valid and/or required.  */
    *opt = NULL;
    while (valid) {
        assert(valid->name);
        if (STREQ(name, valid->name))
            break;
        valid++;
    }
    assert(!needData || valid->type != VSH_OT_BOOL);
    if (valid->flags & VSH_OFLAG_REQ)
        ret = -1;
1373

E
Eric Blake 已提交
1374 1375 1376 1377
    /* See if option is present on command line.  */
    while (candidate) {
        if (STREQ(candidate->def->name, name)) {
            *opt = candidate;
1378 1379
            ret = 1;
            break;
E
Eric Blake 已提交
1380 1381
        }
        candidate = candidate->next;
K
Karel Zak 已提交
1382
    }
1383
    return ret;
K
Karel Zak 已提交
1384 1385
}

E
Eric Blake 已提交
1386 1387
/**
 * vshCommandOptInt:
1388 1389 1390 1391 1392 1393 1394
 * @cmd command reference
 * @name option name
 * @value result
 *
 * Convert option to int
 * Return value:
 * >0 if option found and valid (@value updated)
E
Eric Blake 已提交
1395
 * 0 if option not found and not required (@value untouched)
1396
 * <0 in all other cases (@value untouched)
K
Karel Zak 已提交
1397
 */
E
Eric Blake 已提交
1398
int
1399
vshCommandOptInt(const vshCmd *cmd, const char *name, int *value)
1400
{
E
Eric Blake 已提交
1401 1402
    vshCmdOpt *arg;
    int ret;
1403

1404
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1405 1406 1407
    if (ret <= 0)
        return ret;

E
Eric Blake 已提交
1408 1409 1410
    if (virStrToLong_i(arg->data, NULL, 10, value) < 0)
        return -1;
    return 1;
K
Karel Zak 已提交
1411 1412
}

1413

E
Eric Blake 已提交
1414 1415 1416 1417 1418 1419
/**
 * vshCommandOptUInt:
 * @cmd command reference
 * @name option name
 * @value result
 *
1420 1421 1422
 * Convert option to unsigned int
 * See vshCommandOptInt()
 */
E
Eric Blake 已提交
1423
int
1424 1425
vshCommandOptUInt(const vshCmd *cmd, const char *name, unsigned int *value)
{
E
Eric Blake 已提交
1426 1427
    vshCmdOpt *arg;
    int ret;
1428

1429
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1430 1431 1432
    if (ret <= 0)
        return ret;

E
Eric Blake 已提交
1433 1434 1435
    if (virStrToLong_ui(arg->data, NULL, 10, value) < 0)
        return -1;
    return 1;
1436 1437 1438
}


1439
/*
E
Eric Blake 已提交
1440 1441 1442 1443 1444
 * vshCommandOptUL:
 * @cmd command reference
 * @name option name
 * @value result
 *
1445 1446 1447
 * Convert option to unsigned long
 * See vshCommandOptInt()
 */
E
Eric Blake 已提交
1448
int
1449
vshCommandOptUL(const vshCmd *cmd, const char *name, unsigned long *value)
1450
{
E
Eric Blake 已提交
1451 1452
    vshCmdOpt *arg;
    int ret;
1453

1454
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1455 1456 1457
    if (ret <= 0)
        return ret;

E
Eric Blake 已提交
1458 1459 1460
    if (virStrToLong_ul(arg->data, NULL, 10, value) < 0)
        return -1;
    return 1;
1461 1462
}

E
Eric Blake 已提交
1463 1464 1465 1466 1467 1468
/**
 * vshCommandOptString:
 * @cmd command reference
 * @name option name
 * @value result
 *
K
Karel Zak 已提交
1469
 * Returns option as STRING
E
Eric Blake 已提交
1470 1471 1472 1473
 * Return value:
 * >0 if option found and valid (@value updated)
 * 0 if option not found and not required (@value untouched)
 * <0 in all other cases (@value untouched)
K
Karel Zak 已提交
1474
 */
E
Eric Blake 已提交
1475
int
1476
vshCommandOptString(const vshCmd *cmd, const char *name, const char **value)
1477
{
E
Eric Blake 已提交
1478 1479 1480
    vshCmdOpt *arg;
    int ret;

1481
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1482 1483
    if (ret <= 0)
        return ret;
1484

E
Eric Blake 已提交
1485
    if (!*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK)) {
E
Eric Blake 已提交
1486 1487 1488 1489
        return -1;
    }
    *value = arg->data;
    return 1;
K
Karel Zak 已提交
1490 1491
}

1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517
/**
 * vshCommandOptStringReq:
 * @ctl virsh control structure
 * @cmd command structure
 * @name option name
 * @value result (updated to NULL or the option argument)
 *
 * Gets a option argument as string.
 *
 * Returns 0 on success or when the option is not present and not
 * required, *value is set to the option argument. On error -1 is
 * returned and error message printed.
 */
int
vshCommandOptStringReq(vshControl *ctl,
                       const vshCmd *cmd,
                       const char *name,
                       const char **value)
{
    vshCmdOpt *arg;
    int ret;
    const char *error = NULL;

    /* clear out the value */
    *value = NULL;

1518
    ret = vshCommandOpt(cmd, name, &arg, true);
1519 1520 1521 1522 1523 1524
    /* option is not required and not present */
    if (ret == 0)
        return 0;
    /* this should not be propagated here, just to be sure */
    if (ret == -1)
        error = N_("Mandatory option not present");
1525
    else if (!*arg->data && !(arg->def->flags & VSH_OFLAG_EMPTY_OK))
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
        error = N_("Option argument is empty");

    if (error) {
        vshError(ctl, _("Failed to get option '%s': %s"), name, _(error));
        return -1;
    }

    *value = arg->data;
    return 0;
}

E
Eric Blake 已提交
1537 1538 1539 1540 1541 1542
/**
 * vshCommandOptLongLong:
 * @cmd command reference
 * @name option name
 * @value result
 *
1543
 * Returns option as long long
1544
 * See vshCommandOptInt()
1545
 */
E
Eric Blake 已提交
1546
int
1547 1548
vshCommandOptLongLong(const vshCmd *cmd, const char *name,
                      long long *value)
1549
{
E
Eric Blake 已提交
1550 1551
    vshCmdOpt *arg;
    int ret;
1552

1553
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1554 1555 1556
    if (ret <= 0)
        return ret;

E
Eric Blake 已提交
1557 1558 1559
    if (virStrToLong_ll(arg->data, NULL, 10, value) < 0)
        return -1;
    return 1;
1560 1561
}

E
Eric Blake 已提交
1562 1563 1564 1565 1566 1567 1568 1569 1570
/**
 * vshCommandOptULongLong:
 * @cmd command reference
 * @name option name
 * @value result
 *
 * Returns option as long long
 * See vshCommandOptInt()
 */
E
Eric Blake 已提交
1571
int
1572 1573 1574
vshCommandOptULongLong(const vshCmd *cmd, const char *name,
                       unsigned long long *value)
{
E
Eric Blake 已提交
1575 1576
    vshCmdOpt *arg;
    int ret;
1577

1578
    ret = vshCommandOpt(cmd, name, &arg, true);
E
Eric Blake 已提交
1579 1580 1581
    if (ret <= 0)
        return ret;

E
Eric Blake 已提交
1582 1583 1584
    if (virStrToLong_ull(arg->data, NULL, 10, value) < 0)
        return -1;
    return 1;
1585 1586 1587
}


E
Eric Blake 已提交
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598
/**
 * vshCommandOptScaledInt:
 * @cmd command reference
 * @name option name
 * @value result
 * @scale default of 1 or 1024, if no suffix is present
 * @max maximum value permitted
 *
 * Returns option as long long, scaled according to suffix
 * See vshCommandOptInt()
 */
E
Eric Blake 已提交
1599
int
E
Eric Blake 已提交
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
vshCommandOptScaledInt(const vshCmd *cmd, const char *name,
                       unsigned long long *value, int scale,
                       unsigned long long max)
{
    const char *str;
    int ret;
    char *end;

    ret = vshCommandOptString(cmd, name, &str);
    if (ret <= 0)
        return ret;
    if (virStrToLong_ull(str, &end, 10, value) < 0 ||
        virScaleInteger(value, end, scale, max) < 0)
        return -1;
    return 1;
}


E
Eric Blake 已提交
1618 1619 1620 1621 1622 1623 1624 1625 1626
/**
 * vshCommandOptBool:
 * @cmd command reference
 * @name option name
 *
 * Returns true/false if the option exists.  Note that this does NOT
 * validate whether the option is actually boolean, or even whether
 * name is legal; so that this can be used to probe whether a data
 * option is present without actually using that data.
K
Karel Zak 已提交
1627
 */
E
Eric Blake 已提交
1628
bool
1629
vshCommandOptBool(const vshCmd *cmd, const char *name)
1630
{
E
Eric Blake 已提交
1631 1632
    vshCmdOpt *dummy;

1633
    return vshCommandOpt(cmd, name, &dummy, false) == 1;
K
Karel Zak 已提交
1634 1635
}

E
Eric Blake 已提交
1636 1637 1638 1639 1640
/**
 * vshCommandOptArgv:
 * @cmd command reference
 * @opt starting point for the search
 *
1641 1642
 * Returns the next argv argument after OPT (or the first one if OPT
 * is NULL), or NULL if no more are present.
1643
 *
1644
 * Requires that a VSH_OT_ARGV option be last in the
1645 1646
 * list of supported options in CMD->def->opts.
 */
E
Eric Blake 已提交
1647
const vshCmdOpt *
1648
vshCommandOptArgv(const vshCmd *cmd, const vshCmdOpt *opt)
1649
{
1650
    opt = opt ? opt->next : cmd->opts;
1651 1652

    while (opt) {
E
Eric Blake 已提交
1653
        if (opt->def->type == VSH_OT_ARGV) {
1654
            return opt;
1655 1656 1657 1658 1659 1660
        }
        opt = opt->next;
    }
    return NULL;
}

J
Jim Meyering 已提交
1661 1662 1663
/* Determine whether CMD->opts includes an option with name OPTNAME.
   If not, give a diagnostic and return false.
   If so, return true.  */
1664 1665
bool
vshCmdHasOption(vshControl *ctl, const vshCmd *cmd, const char *optname)
J
Jim Meyering 已提交
1666 1667 1668 1669 1670 1671
{
    /* Iterate through cmd->opts, to ensure that there is an entry
       with name OPTNAME and type VSH_OT_DATA. */
    bool found = false;
    const vshCmdOpt *opt;
    for (opt = cmd->opts; opt; opt = opt->next) {
1672
        if (STREQ(opt->def->name, optname) && opt->def->type == VSH_OT_DATA) {
J
Jim Meyering 已提交
1673 1674 1675 1676 1677 1678
            found = true;
            break;
        }
    }

    if (!found)
1679
        vshError(ctl, _("internal error: virsh %s: no %s VSH_OT_DATA option"),
J
Jim Meyering 已提交
1680 1681 1682
                 cmd->def->name, optname);
    return found;
}
1683

1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
static bool
vshConnectionUsability(vshControl *ctl, virConnectPtr conn)
{
    if (!conn ||
        virConnectIsAlive(conn) == 0) {
        vshError(ctl, "%s", _("no valid connection"));
        return false;
    }

    /* The connection is considered dead only if
     * virConnectIsAlive() successfuly says so.
     */
    vshResetLibvirtError();

    return true;
}

K
Karel Zak 已提交
1701 1702 1703
/*
 * Executes command(s) and returns return code from last command
 */
E
Eric Blake 已提交
1704
static bool
1705
vshCommandRun(vshControl *ctl, const vshCmd *cmd)
1706
{
E
Eric Blake 已提交
1707
    bool ret = true;
1708 1709

    while (cmd) {
K
Karel Zak 已提交
1710
        struct timeval before, after;
1711
        bool enable_timing = ctl->timing;
1712

1713 1714
        if ((ctl->conn == NULL || disconnected) &&
            !(cmd->def->flags & VSH_CMD_FLAG_NOCONNECT))
1715 1716
            vshReconnect(ctl);

1717 1718 1719
        if (enable_timing)
            GETTIMEOFDAY(&before);

1720 1721 1722 1723 1724 1725 1726
        if ((cmd->def->flags & VSH_CMD_FLAG_NOCONNECT) ||
            vshConnectionUsability(ctl, ctl->conn)) {
            ret = cmd->def->handler(ctl, cmd);
        } else {
            /* connection is not usable, return error */
            ret = false;
        }
1727

1728 1729 1730
        if (enable_timing)
            GETTIMEOFDAY(&after);

1731 1732 1733 1734 1735 1736 1737 1738 1739 1740
        /* try to automatically catch disconnections */
        if (!ret &&
            ((last_error != NULL) &&
             (((last_error->code == VIR_ERR_SYSTEM_ERROR) &&
               (last_error->domain == VIR_FROM_REMOTE)) ||
              (last_error->code == VIR_ERR_RPC) ||
              (last_error->code == VIR_ERR_NO_CONNECT) ||
              (last_error->code == VIR_ERR_INVALID_CONN))))
            disconnected++;

1741
        if (!ret)
E
Eric Blake 已提交
1742
            vshReportError(ctl);
J
John Levon 已提交
1743

1744
        if (!ret && disconnected != 0)
1745 1746
            vshReconnect(ctl);

1747
        if (STREQ(cmd->def->name, "quit"))        /* hack ... */
K
Karel Zak 已提交
1748 1749
            return ret;

E
Eric Blake 已提交
1750
        if (enable_timing) {
1751
            double diff_ms = (((after.tv_sec - before.tv_sec) * 1000.0) +
E
Eric Blake 已提交
1752 1753 1754 1755
                              ((after.tv_usec - before.tv_usec) / 1000.0));

            vshPrint(ctl, _("\n(Time: %.3f ms)\n\n"), diff_ms);
        } else {
K
Karel Zak 已提交
1756
            vshPrintExtra(ctl, "\n");
E
Eric Blake 已提交
1757
        }
K
Karel Zak 已提交
1758 1759 1760 1761 1762 1763
        cmd = cmd->next;
    }
    return ret;
}

/* ---------------
1764
 * Command parsing
K
Karel Zak 已提交
1765 1766 1767
 * ---------------
 */

1768 1769 1770 1771 1772 1773 1774
typedef enum {
    VSH_TK_ERROR, /* Failed to parse a token */
    VSH_TK_ARG, /* Arbitrary argument, might be option or empty */
    VSH_TK_SUBCMD_END, /* Separation between commands */
    VSH_TK_END /* No more commands */
} vshCommandToken;

E
Eric Blake 已提交
1775 1776 1777 1778
typedef struct _vshCommandParser vshCommandParser;
struct _vshCommandParser {
    vshCommandToken(*getNextArg)(vshControl *, vshCommandParser *,
                                 char **);
L
Lai Jiangshan 已提交
1779
    /* vshCommandStringGetArg() */
1780
    char *pos;
L
Lai Jiangshan 已提交
1781 1782 1783
    /* vshCommandArgvGetArg() */
    char **arg_pos;
    char **arg_end;
E
Eric Blake 已提交
1784
};
1785

E
Eric Blake 已提交
1786
static bool
1787
vshCommandParse(vshControl *ctl, vshCommandParser *parser)
1788
{
K
Karel Zak 已提交
1789 1790 1791
    char *tkdata = NULL;
    vshCmd *clast = NULL;
    vshCmdOpt *first = NULL;
1792

K
Karel Zak 已提交
1793 1794 1795 1796
    if (ctl->cmd) {
        vshCommandFree(ctl->cmd);
        ctl->cmd = NULL;
    }
1797

1798
    while (1) {
K
Karel Zak 已提交
1799
        vshCmdOpt *last = NULL;
1800
        const vshCmdDef *cmd = NULL;
1801
        vshCommandToken tk;
L
Lai Jiangshan 已提交
1802
        bool data_only = false;
1803 1804 1805
        uint32_t opts_need_arg = 0;
        uint32_t opts_required = 0;
        uint32_t opts_seen = 0;
1806

K
Karel Zak 已提交
1807
        first = NULL;
1808

1809
        while (1) {
1810
            const vshCmdOptDef *opt = NULL;
1811

K
Karel Zak 已提交
1812
            tkdata = NULL;
1813
            tk = parser->getNextArg(ctl, parser, &tkdata);
1814 1815

            if (tk == VSH_TK_ERROR)
K
Karel Zak 已提交
1816
                goto syntaxError;
H
Hu Tao 已提交
1817 1818
            if (tk != VSH_TK_ARG) {
                VIR_FREE(tkdata);
1819
                break;
H
Hu Tao 已提交
1820
            }
1821 1822

            if (cmd == NULL) {
K
Karel Zak 已提交
1823 1824
                /* first token must be command name */
                if (!(cmd = vshCmddefSearch(tkdata))) {
1825
                    vshError(ctl, _("unknown command: '%s'"), tkdata);
1826
                    goto syntaxError;   /* ... or ignore this command only? */
K
Karel Zak 已提交
1827
                }
1828 1829 1830 1831 1832 1833 1834
                if (vshCmddefOptParse(cmd, &opts_need_arg,
                                      &opts_required) < 0) {
                    vshError(ctl,
                             _("internal error: bad options in command: '%s'"),
                             tkdata);
                    goto syntaxError;
                }
1835
                VIR_FREE(tkdata);
L
Lai Jiangshan 已提交
1836 1837 1838 1839
            } else if (data_only) {
                goto get_data;
            } else if (tkdata[0] == '-' && tkdata[1] == '-' &&
                       c_isalnum(tkdata[2])) {
1840
                char *optstr = strchr(tkdata + 2, '=');
C
Cole Robinson 已提交
1841
                int opt_index = 0;
1842

1843 1844 1845 1846
                if (optstr) {
                    *optstr = '\0'; /* convert the '=' to '\0' */
                    optstr = vshStrdup(ctl, optstr + 1);
                }
1847
                /* Special case 'help' to ignore all spurious options */
1848
                if (!(opt = vshCmddefGetOption(ctl, cmd, tkdata + 2,
1849
                                               &opts_seen, &opt_index))) {
1850
                    VIR_FREE(optstr);
1851 1852
                    if (STREQ(cmd->name, "help"))
                        continue;
K
Karel Zak 已提交
1853 1854
                    goto syntaxError;
                }
1855
                VIR_FREE(tkdata);
K
Karel Zak 已提交
1856 1857 1858

                if (opt->type != VSH_OT_BOOL) {
                    /* option data */
1859 1860 1861
                    if (optstr)
                        tkdata = optstr;
                    else
1862
                        tk = parser->getNextArg(ctl, parser, &tkdata);
1863
                    if (tk == VSH_TK_ERROR)
K
Karel Zak 已提交
1864
                        goto syntaxError;
1865
                    if (tk != VSH_TK_ARG) {
1866
                        vshError(ctl,
1867
                                 _("expected syntax: --%s <%s>"),
1868 1869
                                 opt->name,
                                 opt->type ==
1870
                                 VSH_OT_INT ? _("number") : _("string"));
K
Karel Zak 已提交
1871 1872
                        goto syntaxError;
                    }
1873 1874
                    if (opt->type != VSH_OT_ARGV)
                        opts_need_arg &= ~(1 << opt_index);
1875 1876 1877 1878 1879 1880 1881 1882
                } else {
                    tkdata = NULL;
                    if (optstr) {
                        vshError(ctl, _("invalid '=' after option --%s"),
                                opt->name);
                        VIR_FREE(optstr);
                        goto syntaxError;
                    }
K
Karel Zak 已提交
1883
                }
L
Lai Jiangshan 已提交
1884 1885 1886 1887
            } else if (tkdata[0] == '-' && tkdata[1] == '-' &&
                       tkdata[2] == '\0') {
                data_only = true;
                continue;
1888
            } else {
L
Lai Jiangshan 已提交
1889
get_data:
1890
                /* Special case 'help' to ignore spurious data */
1891
                if (!(opt = vshCmddefGetData(cmd, &opts_need_arg,
1892 1893
                                             &opts_seen)) &&
                     STRNEQ(cmd->name, "help")) {
1894
                    vshError(ctl, _("unexpected data '%s'"), tkdata);
K
Karel Zak 已提交
1895 1896 1897 1898 1899
                    goto syntaxError;
                }
            }
            if (opt) {
                /* save option */
1900
                vshCmdOpt *arg = vshMalloc(ctl, sizeof(vshCmdOpt));
1901

K
Karel Zak 已提交
1902 1903 1904 1905
                arg->def = opt;
                arg->data = tkdata;
                arg->next = NULL;
                tkdata = NULL;
1906

K
Karel Zak 已提交
1907 1908 1909 1910 1911
                if (!first)
                    first = arg;
                if (last)
                    last->next = arg;
                last = arg;
1912

1913
                vshDebug(ctl, VSH_ERR_INFO, "%s: %s(%s): %s\n",
1914 1915
                         cmd->name,
                         opt->name,
1916 1917
                         opt->type != VSH_OT_BOOL ? _("optdata") : _("bool"),
                         opt->type != VSH_OT_BOOL ? arg->data : _("(none)"));
K
Karel Zak 已提交
1918 1919
            }
        }
1920

D
Daniel Veillard 已提交
1921
        /* command parsed -- allocate new struct for the command */
K
Karel Zak 已提交
1922
        if (cmd) {
1923
            vshCmd *c = vshMalloc(ctl, sizeof(vshCmd));
1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
            vshCmdOpt *tmpopt = first;

            /* if we encountered --help, replace parsed command with
             * 'help <cmdname>' */
            for (tmpopt = first; tmpopt; tmpopt = tmpopt->next) {
                if (STRNEQ(tmpopt->def->name, "help"))
                    continue;

                vshCommandOptFree(first);
                first = vshMalloc(ctl, sizeof(vshCmdOpt));
                first->def = &(opts_help[0]);
                first->data = vshStrdup(ctl, cmd->name);
                first->next = NULL;

                cmd = vshCmddefSearch("help");
                opts_required = 0;
                opts_seen = 0;
                break;
            }
1943

K
Karel Zak 已提交
1944 1945 1946 1947
            c->opts = first;
            c->def = cmd;
            c->next = NULL;

1948
            if (vshCommandCheckOpts(ctl, c, opts_required, opts_seen) < 0) {
1949
                VIR_FREE(c);
1950
                goto syntaxError;
1951
            }
1952

K
Karel Zak 已提交
1953 1954 1955 1956 1957 1958
            if (!ctl->cmd)
                ctl->cmd = c;
            if (clast)
                clast->next = c;
            clast = c;
        }
1959 1960 1961

        if (tk == VSH_TK_END)
            break;
K
Karel Zak 已提交
1962
    }
1963

E
Eric Blake 已提交
1964
    return true;
K
Karel Zak 已提交
1965

1966
 syntaxError:
1967
    if (ctl->cmd) {
K
Karel Zak 已提交
1968
        vshCommandFree(ctl->cmd);
1969 1970
        ctl->cmd = NULL;
    }
K
Karel Zak 已提交
1971 1972
    if (first)
        vshCommandOptFree(first);
1973
    VIR_FREE(tkdata);
E
Eric Blake 已提交
1974
    return false;
K
Karel Zak 已提交
1975 1976
}

1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
/* --------------------
 * Command argv parsing
 * --------------------
 */

static vshCommandToken ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
vshCommandArgvGetArg(vshControl *ctl, vshCommandParser *parser, char **res)
{
    if (parser->arg_pos == parser->arg_end) {
        *res = NULL;
        return VSH_TK_END;
    }

    *res = vshStrdup(ctl, *parser->arg_pos);
    parser->arg_pos++;
    return VSH_TK_ARG;
}

E
Eric Blake 已提交
1995 1996
static bool
vshCommandArgvParse(vshControl *ctl, int nargs, char **argv)
1997 1998 1999 2000
{
    vshCommandParser parser;

    if (nargs <= 0)
E
Eric Blake 已提交
2001
        return false;
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073

    parser.arg_pos = argv;
    parser.arg_end = argv + nargs;
    parser.getNextArg = vshCommandArgvGetArg;
    return vshCommandParse(ctl, &parser);
}

/* ----------------------
 * Command string parsing
 * ----------------------
 */

static vshCommandToken ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res)
{
    bool single_quote = false;
    bool double_quote = false;
    int sz = 0;
    char *p = parser->pos;
    char *q = vshStrdup(ctl, p);

    *res = q;

    while (*p && (*p == ' ' || *p == '\t'))
        p++;

    if (*p == '\0')
        return VSH_TK_END;
    if (*p == ';') {
        parser->pos = ++p;             /* = \0 or begin of next command */
        return VSH_TK_SUBCMD_END;
    }

    while (*p) {
        /* end of token is blank space or ';' */
        if (!double_quote && !single_quote &&
            (*p == ' ' || *p == '\t' || *p == ';'))
            break;

        if (!double_quote && *p == '\'') { /* single quote */
            single_quote = !single_quote;
            p++;
            continue;
        } else if (!single_quote && *p == '\\') { /* escape */
            /*
             * The same as the bash, a \ in "" is an escaper,
             * but a \ in '' is not an escaper.
             */
            p++;
            if (*p == '\0') {
                vshError(ctl, "%s", _("dangling \\"));
                return VSH_TK_ERROR;
            }
        } else if (!single_quote && *p == '"') { /* double quote */
            double_quote = !double_quote;
            p++;
            continue;
        }

        *q++ = *p++;
        sz++;
    }
    if (double_quote) {
        vshError(ctl, "%s", _("missing \""));
        return VSH_TK_ERROR;
    }

    *q = '\0';
    parser->pos = p;
    return VSH_TK_ARG;
}

E
Eric Blake 已提交
2074 2075
static bool
vshCommandStringParse(vshControl *ctl, char *cmdstr)
2076 2077 2078 2079
{
    vshCommandParser parser;

    if (cmdstr == NULL || *cmdstr == '\0')
E
Eric Blake 已提交
2080
        return false;
2081 2082 2083 2084 2085 2086

    parser.pos = cmdstr;
    parser.getNextArg = vshCommandStringGetArg;
    return vshCommandParse(ctl, &parser);
}

K
Karel Zak 已提交
2087
/* ---------------
2088
 * Misc utils
K
Karel Zak 已提交
2089 2090
 * ---------------
 */
E
Eric Blake 已提交
2091
int
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason)
{
    virDomainInfo info;

    if (reason)
        *reason = -1;

    if (!ctl->useGetInfo) {
        int state;
        if (virDomainGetState(dom, &state, reason, 0) < 0) {
            virErrorPtr err = virGetLastError();
            if (err && err->code == VIR_ERR_NO_SUPPORT)
                ctl->useGetInfo = true;
            else
                return -1;
        } else {
            return state;
        }
    }

    /* fall back to virDomainGetInfo if virDomainGetState is not supported */
    if (virDomainGetInfo(dom, &info) < 0)
        return -1;
    else
        return info.state;
}

2119 2120
/* Return a non-NULL string representation of a typed parameter; exit
 * if we are out of memory.  */
E
Eric Blake 已提交
2121
char *
2122 2123 2124 2125 2126
vshGetTypedParamValue(vshControl *ctl, virTypedParameterPtr item)
{
    int ret = 0;
    char *str = NULL;

2127
    switch (item->type) {
2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148
    case VIR_TYPED_PARAM_INT:
        ret = virAsprintf(&str, "%d", item->value.i);
        break;

    case VIR_TYPED_PARAM_UINT:
        ret = virAsprintf(&str, "%u", item->value.ui);
        break;

    case VIR_TYPED_PARAM_LLONG:
        ret = virAsprintf(&str, "%lld", item->value.l);
        break;

    case VIR_TYPED_PARAM_ULLONG:
        ret = virAsprintf(&str, "%llu", item->value.ul);
        break;

    case VIR_TYPED_PARAM_DOUBLE:
        ret = virAsprintf(&str, "%f", item->value.d);
        break;

    case VIR_TYPED_PARAM_BOOLEAN:
E
Eric Blake 已提交
2149
        str = vshStrdup(ctl, item->value.b ? _("yes") : _("no"));
2150 2151
        break;

2152 2153 2154 2155
    case VIR_TYPED_PARAM_STRING:
        str = vshStrdup(ctl, item->value.s);
        break;

2156
    default:
2157
        vshError(ctl, _("unimplemented parameter type %d"), item->type);
2158 2159
    }

2160
    if (ret < 0) {
2161
        vshError(ctl, "%s", _("Out of memory"));
2162 2163
        exit(EXIT_FAILURE);
    }
2164 2165 2166
    return str;
}

E
Eric Blake 已提交
2167
void
2168
vshDebug(vshControl *ctl, int level, const char *format, ...)
2169
{
K
Karel Zak 已提交
2170
    va_list ap;
2171
    char *str;
K
Karel Zak 已提交
2172

2173 2174 2175 2176 2177 2178 2179
    /* Aligning log levels to that of libvirt.
     * Traces with levels >=  user-specified-level
     * gets logged into file
     */
    if (level < ctl->debug)
        return;

2180
    va_start(ap, format);
2181
    vshOutputLogFile(ctl, level, format, ap);
2182 2183
    va_end(ap);

K
Karel Zak 已提交
2184
    va_start(ap, format);
2185 2186 2187 2188 2189
    if (virVasprintf(&str, format, ap) < 0) {
        /* Skip debug messages on low memory */
        va_end(ap);
        return;
    }
K
Karel Zak 已提交
2190
    va_end(ap);
2191 2192
    fputs(str, stdout);
    VIR_FREE(str);
K
Karel Zak 已提交
2193 2194
}

E
Eric Blake 已提交
2195
void
2196
vshPrintExtra(vshControl *ctl, const char *format, ...)
2197
{
K
Karel Zak 已提交
2198
    va_list ap;
2199
    char *str;
2200

2201
    if (ctl && ctl->quiet)
K
Karel Zak 已提交
2202
        return;
2203

K
Karel Zak 已提交
2204
    va_start(ap, format);
2205 2206 2207 2208 2209
    if (virVasprintf(&str, format, ap) < 0) {
        vshError(ctl, "%s", _("Out of memory"));
        va_end(ap);
        return;
    }
K
Karel Zak 已提交
2210
    va_end(ap);
2211
    fputs(str, stdout);
2212
    VIR_FREE(str);
K
Karel Zak 已提交
2213 2214
}

K
Karel Zak 已提交
2215

2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262
bool
vshTTYIsInterruptCharacter(vshControl *ctl,
                           const char chr)
{
    if (ctl->istty &&
        ctl->termattr.c_cc[VINTR] == chr)
        return true;

    return false;
}


int
vshTTYDisableInterrupt(vshControl *ctl)
{
    struct termios termset = ctl->termattr;

    if (!ctl->istty)
        return -1;

    /* check if we need to set the terminal */
    if (termset.c_cc[VINTR] == _POSIX_VDISABLE)
        return 0;

    termset.c_cc[VINTR] = _POSIX_VDISABLE;
    termset.c_lflag &= ~ICANON;

    if (tcsetattr(STDIN_FILENO, TCSANOW, &termset) < 0)
        return -1;

    return 0;
}


int
vshTTYRestore(vshControl *ctl)
{
    if (!ctl->istty)
        return 0;

    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &ctl->termattr) < 0)
        return -1;

    return 0;
}


E
Eric Blake 已提交
2263
void
2264
vshError(vshControl *ctl, const char *format, ...)
2265
{
K
Karel Zak 已提交
2266
    va_list ap;
2267
    char *str;
2268

2269 2270 2271 2272 2273
    if (ctl != NULL) {
        va_start(ap, format);
        vshOutputLogFile(ctl, VSH_ERR_ERROR, format, ap);
        va_end(ap);
    }
2274

2275 2276 2277 2278
    /* Most output is to stdout, but if someone ran virsh 2>&1, then
     * printing to stderr will not interleave correctly with stdout
     * unless we flush between every transition between streams.  */
    fflush(stdout);
2279
    fputs(_("error: "), stderr);
2280

K
Karel Zak 已提交
2281
    va_start(ap, format);
2282 2283 2284
    /* We can't recursively call vshError on an OOM situation, so ignore
       failure here. */
    ignore_value(virVasprintf(&str, format, ap));
K
Karel Zak 已提交
2285 2286
    va_end(ap);

2287
    fprintf(stderr, "%s\n", NULLSTR(str));
2288
    fflush(stderr);
2289
    VIR_FREE(str);
K
Karel Zak 已提交
2290 2291
}

2292

J
Jiri Denemark 已提交
2293 2294 2295 2296 2297
static void
vshEventLoop(void *opaque)
{
    vshControl *ctl = opaque;

2298 2299 2300 2301 2302 2303 2304 2305 2306 2307
    while (1) {
        bool quit;
        virMutexLock(&ctl->lock);
        quit = ctl->quit;
        virMutexUnlock(&ctl->lock);

        if (quit)
            break;

        if (virEventRunDefaultImpl() < 0)
E
Eric Blake 已提交
2308
            vshReportError(ctl);
J
Jiri Denemark 已提交
2309 2310 2311 2312
    }
}


K
Karel Zak 已提交
2313
/*
M
Martin Kletzander 已提交
2314
 * Initialize debug settings.
K
Karel Zak 已提交
2315
 */
M
Martin Kletzander 已提交
2316 2317
static void
vshInitDebug(vshControl *ctl)
2318
{
2319 2320
    char *debugEnv;

J
Jiri Denemark 已提交
2321
    if (ctl->debug == VSH_DEBUG_DEFAULT) {
2322 2323 2324
        /* log level not set from commandline, check env variable */
        debugEnv = getenv("VIRSH_DEBUG");
        if (debugEnv) {
J
Jiri Denemark 已提交
2325 2326 2327
            int debug;
            if (virStrToLong_i(debugEnv, NULL, 10, &debug) < 0 ||
                debug < VSH_ERR_DEBUG || debug > VSH_ERR_ERROR) {
2328 2329
                vshError(ctl, "%s",
                         _("VIRSH_DEBUG not set with a valid numeric value"));
J
Jiri Denemark 已提交
2330 2331
            } else {
                ctl->debug = debug;
2332 2333 2334 2335 2336 2337 2338 2339 2340
            }
        }
    }

    if (ctl->logfile == NULL) {
        /* log file not set from cmdline */
        debugEnv = getenv("VIRSH_LOG_FILE");
        if (debugEnv && *debugEnv) {
            ctl->logfile = vshStrdup(ctl, debugEnv);
M
Martin Kletzander 已提交
2341
            vshOpenLogFile(ctl);
2342 2343
        }
    }
M
Martin Kletzander 已提交
2344 2345 2346 2347 2348 2349 2350 2351
}

/*
 * Initialize connection.
 */
static bool
vshInit(vshControl *ctl)
{
M
Martin Kletzander 已提交
2352 2353 2354 2355
    /* Since we have the commandline arguments parsed, we need to
     * re-initialize all the debugging to make it work properly */
    vshInitDebug(ctl);

M
Martin Kletzander 已提交
2356 2357
    if (ctl->conn)
        return false;
2358

2359 2360
    /* set up the library error handler */
    virSetErrorFunc(NULL, virshErrorHandler);
2361

2362
    if (virEventRegisterDefaultImpl() < 0)
E
Eric Blake 已提交
2363
        return false;
2364

J
Jiri Denemark 已提交
2365 2366 2367 2368
    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
        return false;
    ctl->eventLoopStarted = true;

2369
    if (ctl->name) {
2370
        vshReconnect(ctl);
2371 2372 2373 2374 2375 2376 2377
        /* Connecting to a named connection must succeed, but we delay
         * connecting to the default connection until we need it
         * (since the first command might be 'connect' which allows a
         * non-default connection, or might be 'help' which needs no
         * connection).
         */
        if (!ctl->conn) {
E
Eric Blake 已提交
2378
            vshReportError(ctl);
2379 2380
            return false;
        }
2381
    }
K
Karel Zak 已提交
2382

E
Eric Blake 已提交
2383
    return true;
K
Karel Zak 已提交
2384 2385
}

2386 2387
#define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC)

2388 2389 2390 2391 2392
/**
 * vshOpenLogFile:
 *
 * Open log file.
 */
E
Eric Blake 已提交
2393
void
2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406
vshOpenLogFile(vshControl *ctl)
{
    struct stat st;

    if (ctl->logfile == NULL)
        return;

    /* check log file */
    if (stat(ctl->logfile, &st) == -1) {
        switch (errno) {
            case ENOENT:
                break;
            default:
2407
                vshError(ctl, "%s",
J
Jim Meyering 已提交
2408
                         _("failed to get the log file information"));
2409
                exit(EXIT_FAILURE);
2410 2411 2412
        }
    } else {
        if (!S_ISREG(st.st_mode)) {
2413 2414
            vshError(ctl, "%s", _("the log path is not a file"));
            exit(EXIT_FAILURE);
2415 2416 2417 2418
        }
    }

    /* log file open */
2419
    if ((ctl->log_fd = open(ctl->logfile, LOGFILE_FLAGS, FILE_MODE)) < 0) {
2420
        vshError(ctl, "%s",
J
Jim Meyering 已提交
2421
                 _("failed to open the log file. check the log file path"));
2422
        exit(EXIT_FAILURE);
2423 2424 2425 2426 2427 2428 2429 2430
    }
}

/**
 * vshOutputLogFile:
 *
 * Outputting an error to log file.
 */
E
Eric Blake 已提交
2431
void
2432 2433
vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
                 va_list ap)
2434
{
2435
    virBuffer buf = VIR_BUFFER_INITIALIZER;
J
John Ferlan 已提交
2436
    char *str = NULL;
2437
    size_t len;
2438
    const char *lvl = "";
2439
    time_t stTime;
2440
    struct tm stTm;
2441 2442 2443 2444 2445 2446 2447 2448 2449

    if (ctl->log_fd == -1)
        return;

    /**
     * create log format
     *
     * [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
    */
2450 2451
    time(&stTime);
    localtime_r(&stTime, &stTm);
2452
    virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
2453 2454 2455 2456 2457 2458
                      (1900 + stTm.tm_year),
                      (1 + stTm.tm_mon),
                      stTm.tm_mday,
                      stTm.tm_hour,
                      stTm.tm_min,
                      stTm.tm_sec,
2459 2460
                      SIGN_NAME,
                      (int) getpid());
2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480
    switch (log_level) {
        case VSH_ERR_DEBUG:
            lvl = LVL_DEBUG;
            break;
        case VSH_ERR_INFO:
            lvl = LVL_INFO;
            break;
        case VSH_ERR_NOTICE:
            lvl = LVL_INFO;
            break;
        case VSH_ERR_WARNING:
            lvl = LVL_WARNING;
            break;
        case VSH_ERR_ERROR:
            lvl = LVL_ERROR;
            break;
        default:
            lvl = LVL_DEBUG;
            break;
    }
2481 2482 2483
    virBufferAsprintf(&buf, "%s ", lvl);
    virBufferVasprintf(&buf, msg_format, ap);
    virBufferAddChar(&buf, '\n');
2484

2485 2486
    if (virBufferError(&buf))
        goto error;
2487

2488 2489 2490 2491 2492
    str = virBufferContentAndReset(&buf);
    len = strlen(str);
    if (len > 1 && str[len - 2] == '\n') {
        str[len - 1] = '\0';
        len--;
2493
    }
2494

2495 2496 2497 2498
    /* write log */
    if (safewrite(ctl->log_fd, str, len) < 0)
        goto error;

2499
    VIR_FREE(str);
2500 2501 2502 2503 2504 2505 2506
    return;

error:
    vshCloseLogFile(ctl);
    vshError(ctl, "%s", _("failed to write the log file"));
    virBufferFreeAndReset(&buf);
    VIR_FREE(str);
2507 2508 2509 2510 2511 2512 2513
}

/**
 * vshCloseLogFile:
 *
 * Close log file.
 */
E
Eric Blake 已提交
2514
void
2515 2516
vshCloseLogFile(vshControl *ctl)
{
2517 2518
    char ebuf[1024];

2519
    /* log file close */
2520 2521
    if (VIR_CLOSE(ctl->log_fd) < 0) {
        vshError(ctl, _("%s: failed to write log file: %s"),
2522 2523
                 ctl->logfile ? ctl->logfile : "?",
                 virStrerror(errno, ebuf, sizeof(ebuf)));
2524 2525 2526
    }

    if (ctl->logfile) {
2527
        VIR_FREE(ctl->logfile);
2528 2529 2530 2531
        ctl->logfile = NULL;
    }
}

2532
#ifdef USE_READLINE
2533

K
Karel Zak 已提交
2534 2535 2536 2537 2538
/* -----------------
 * Readline stuff
 * -----------------
 */

2539
/*
K
Karel Zak 已提交
2540 2541
 * Generator function for command completion.  STATE lets us
 * know whether to start from scratch; without any state
2542
 * (i.e. STATE == 0), then we start at the top of the list.
K
Karel Zak 已提交
2543 2544
 */
static char *
2545 2546
vshReadlineCommandGenerator(const char *text, int state)
{
2547
    static int grp_list_index, cmd_list_index, len;
K
Karel Zak 已提交
2548
    const char *name;
2549 2550
    const vshCmdGrp *grp;
    const vshCmdDef *cmds;
K
Karel Zak 已提交
2551 2552

    if (!state) {
2553 2554
        grp_list_index = 0;
        cmd_list_index = 0;
2555
        len = strlen(text);
K
Karel Zak 已提交
2556 2557
    }

2558 2559
    grp = cmdGroups;

K
Karel Zak 已提交
2560
    /* Return the next name which partially matches from the
2561
     * command list.
K
Karel Zak 已提交
2562
     */
2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576
    while (grp[grp_list_index].name) {
        cmds = grp[grp_list_index].commands;

        if (cmds[cmd_list_index].name) {
            while ((name = cmds[cmd_list_index].name)) {
                cmd_list_index++;

                if (STREQLEN(name, text, len))
                    return vshStrdup(NULL, name);
            }
        } else {
            cmd_list_index = 0;
            grp_list_index++;
        }
K
Karel Zak 已提交
2577 2578 2579 2580 2581 2582 2583
    }

    /* If no names matched, then return NULL. */
    return NULL;
}

static char *
2584 2585
vshReadlineOptionsGenerator(const char *text, int state)
{
K
Karel Zak 已提交
2586
    static int list_index, len;
2587
    static const vshCmdDef *cmd = NULL;
K
Karel Zak 已提交
2588
    const char *name;
K
Karel Zak 已提交
2589 2590 2591 2592 2593 2594 2595 2596 2597

    if (!state) {
        /* determine command name */
        char *p;
        char *cmdname;

        if (!(p = strchr(rl_line_buffer, ' ')))
            return NULL;

2598
        cmdname = vshCalloc(NULL, (p - rl_line_buffer) + 1, 1);
2599
        memcpy(cmdname, rl_line_buffer, p - rl_line_buffer);
K
Karel Zak 已提交
2600 2601 2602

        cmd = vshCmddefSearch(cmdname);
        list_index = 0;
2603
        len = strlen(text);
2604
        VIR_FREE(cmdname);
K
Karel Zak 已提交
2605 2606 2607 2608
    }

    if (!cmd)
        return NULL;
2609

2610 2611 2612
    if (!cmd->opts)
        return NULL;

K
Karel Zak 已提交
2613
    while ((name = cmd->opts[list_index].name)) {
2614
        const vshCmdOptDef *opt = &cmd->opts[list_index];
K
Karel Zak 已提交
2615
        char *res;
2616

K
Karel Zak 已提交
2617
        list_index++;
2618

2619
        if (opt->type == VSH_OT_DATA || opt->type == VSH_OT_ARGV)
K
Karel Zak 已提交
2620 2621
            /* ignore non --option */
            continue;
2622

K
Karel Zak 已提交
2623
        if (len > 2) {
2624
            if (STRNEQLEN(name, text + 2, len - 2))
K
Karel Zak 已提交
2625 2626
                continue;
        }
2627
        res = vshMalloc(NULL, strlen(name) + 3);
2628
        snprintf(res, strlen(name) + 3,  "--%s", name);
K
Karel Zak 已提交
2629 2630 2631 2632 2633 2634 2635 2636
        return res;
    }

    /* If no names matched, then return NULL. */
    return NULL;
}

static char **
2637 2638 2639
vshReadlineCompletion(const char *text, int start,
                      int end ATTRIBUTE_UNUSED)
{
K
Karel Zak 已提交
2640 2641
    char **matches = (char **) NULL;

2642
    if (start == 0)
K
Karel Zak 已提交
2643
        /* command name generator */
2644
        matches = rl_completion_matches(text, vshReadlineCommandGenerator);
K
Karel Zak 已提交
2645 2646
    else
        /* commands options */
2647
        matches = rl_completion_matches(text, vshReadlineOptionsGenerator);
K
Karel Zak 已提交
2648 2649 2650 2651
    return matches;
}


2652 2653
static int
vshReadlineInit(vshControl *ctl)
2654
{
2655 2656
    char *userdir = NULL;

K
Karel Zak 已提交
2657 2658 2659 2660 2661
    /* Allow conditional parsing of the ~/.inputrc file. */
    rl_readline_name = "virsh";

    /* Tell the completer that we want a crack first. */
    rl_attempted_completion_function = vshReadlineCompletion;
2662 2663 2664

    /* Limit the total size of the history buffer */
    stifle_history(500);
2665

2666
    /* Prepare to read/write history from/to the $XDG_CACHE_HOME/virsh/history file */
2667
    userdir = virGetUserCacheDirectory();
2668

2669 2670
    if (userdir == NULL) {
        vshError(ctl, "%s", _("Could not determine home directory"));
2671
        return -1;
2672
    }
2673

2674
    if (virAsprintf(&ctl->historydir, "%s/virsh", userdir) < 0) {
2675
        vshError(ctl, "%s", _("Out of memory"));
2676
        VIR_FREE(userdir);
2677 2678 2679 2680 2681
        return -1;
    }

    if (virAsprintf(&ctl->historyfile, "%s/history", ctl->historydir) < 0) {
        vshError(ctl, "%s", _("Out of memory"));
2682
        VIR_FREE(userdir);
2683 2684 2685
        return -1;
    }

2686
    VIR_FREE(userdir);
2687 2688 2689 2690 2691 2692 2693

    read_history(ctl->historyfile);

    return 0;
}

static void
2694
vshReadlineDeinit(vshControl *ctl)
2695 2696
{
    if (ctl->historyfile != NULL) {
2697 2698
        if (virFileMakePathWithMode(ctl->historydir, 0755) < 0 &&
            errno != EEXIST) {
2699 2700
            char ebuf[1024];
            vshError(ctl, _("Failed to create '%s': %s"),
2701
                     ctl->historydir, virStrerror(errno, ebuf, sizeof(ebuf)));
E
Eric Blake 已提交
2702
        } else {
2703
            write_history(ctl->historyfile);
E
Eric Blake 已提交
2704
        }
2705 2706
    }

2707 2708
    VIR_FREE(ctl->historydir);
    VIR_FREE(ctl->historyfile);
K
Karel Zak 已提交
2709 2710
}

2711
static char *
2712
vshReadline(vshControl *ctl ATTRIBUTE_UNUSED, const char *prompt)
2713
{
2714
    return readline(prompt);
2715 2716
}

2717
#else /* !USE_READLINE */
2718

2719
static int
2720
vshReadlineInit(vshControl *ctl ATTRIBUTE_UNUSED)
2721 2722 2723 2724 2725
{
    /* empty */
    return 0;
}

2726
static void
2727
vshReadlineDeinit(vshControl *ctl ATTRIBUTE_UNUSED)
2728 2729 2730 2731 2732
{
    /* empty */
}

static char *
2733
vshReadline(vshControl *ctl, const char *prompt)
2734 2735 2736 2737 2738
{
    char line[1024];
    char *r;
    int len;

2739 2740
    fputs(prompt, stdout);
    r = fgets(line, sizeof(line), stdin);
2741 2742 2743
    if (r == NULL) return NULL; /* EOF */

    /* Chomp trailing \n */
2744
    len = strlen(r);
2745 2746 2747
    if (len > 0 && r[len-1] == '\n')
        r[len-1] = '\0';

2748
    return vshStrdup(ctl, r);
2749 2750
}

2751
#endif /* !USE_READLINE */
2752

2753 2754 2755 2756 2757 2758
static void
vshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
{
    /* nothing to be done here */
}

K
Karel Zak 已提交
2759
/*
J
Jim Meyering 已提交
2760
 * Deinitialize virsh
K
Karel Zak 已提交
2761
 */
E
Eric Blake 已提交
2762
static bool
2763
vshDeinit(vshControl *ctl)
2764
{
2765
    vshReadlineDeinit(ctl);
2766
    vshCloseLogFile(ctl);
2767
    VIR_FREE(ctl->name);
K
Karel Zak 已提交
2768
    if (ctl->conn) {
2769
        int ret;
2770 2771 2772 2773 2774 2775 2776
        virConnectUnregisterCloseCallback(ctl->conn, vshCatchDisconnect);
        ret = virConnectClose(ctl->conn);
        if (ret < 0)
            vshError(ctl, "%s", _("Failed to disconnect from the hypervisor"));
        else if (ret > 0)
            vshError(ctl, "%s", _("One or more references were leaked after "
                                  "disconnect from the hypervisor"));
K
Karel Zak 已提交
2777
    }
D
Daniel P. Berrange 已提交
2778 2779
    virResetLastError();

J
Jiri Denemark 已提交
2780
    if (ctl->eventLoopStarted) {
2781 2782 2783 2784
        int timer;

        virMutexLock(&ctl->lock);
        ctl->quit = true;
J
Jiri Denemark 已提交
2785
        /* HACK: Add a dummy timeout to break event loop */
2786 2787 2788 2789 2790
        timer = virEventAddTimeout(0, vshDeinitTimer, NULL, NULL);
        virMutexUnlock(&ctl->lock);

        virThreadJoin(&ctl->eventLoop);

J
Jiri Denemark 已提交
2791 2792 2793 2794 2795 2796
        if (timer != -1)
            virEventRemoveTimeout(timer);

        ctl->eventLoopStarted = false;
    }

2797 2798
    virMutexDestroy(&ctl->lock);

E
Eric Blake 已提交
2799
    return true;
K
Karel Zak 已提交
2800
}
2801

K
Karel Zak 已提交
2802 2803 2804
/*
 * Print usage
 */
E
Eric Blake 已提交
2805
static void
2806
vshUsage(void)
2807
{
2808
    const vshCmdGrp *grp;
2809
    const vshCmdDef *cmd;
2810

L
Lai Jiangshan 已提交
2811 2812
    fprintf(stdout, _("\n%s [options]... [<command_string>]"
                      "\n%s [options]... <command> [args...]\n\n"
2813
                      "  options:\n"
2814
                      "    -c | --connect=URI      hypervisor connection URI\n"
2815
                      "    -r | --readonly         connect readonly\n"
2816
                      "    -d | --debug=NUM        debug level [0-4]\n"
2817 2818 2819
                      "    -h | --help             this help\n"
                      "    -q | --quiet            quiet mode\n"
                      "    -t | --timing           print timing information\n"
2820 2821 2822 2823 2824
                      "    -l | --log=FILE         output logging to file\n"
                      "    -v                      short version\n"
                      "    -V                      long version\n"
                      "         --version[=TYPE]   version, TYPE is short or long (default short)\n"
                      "    -e | --escape <char>    set escape sequence for console\n\n"
2825
                      "  commands (non interactive mode):\n\n"), progname, progname);
2826

2827
    for (grp = cmdGroups; grp->name; grp++) {
E
Eric Blake 已提交
2828 2829 2830 2831 2832
        fprintf(stdout, _(" %s (help keyword '%s')\n"),
                grp->name, grp->keyword);
        for (cmd = grp->commands; cmd->name; cmd++) {
            if (cmd->flags & VSH_CMD_FLAG_ALIAS)
                continue;
2833
            fprintf(stdout,
E
Eric Blake 已提交
2834 2835 2836
                    "    %-30s %s\n", cmd->name,
                    _(vshCmddefGetInfo(cmd, "help")));
        }
2837 2838 2839 2840 2841
        fprintf(stdout, "\n");
    }

    fprintf(stdout, "%s",
            _("\n  (specify help <group> for details about the commands in the group)\n"));
2842 2843 2844
    fprintf(stdout, "%s",
            _("\n  (specify help <command> for details about the command)\n\n"));
    return;
K
Karel Zak 已提交
2845 2846
}

2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
/*
 * Show version and options compiled in
 */
static void
vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
{
    /* FIXME - list a copyright blurb, as in GNU programs?  */
    vshPrint(ctl, _("Virsh command line tool of libvirt %s\n"), VERSION);
    vshPrint(ctl, _("See web site at %s\n\n"), "http://libvirt.org/");

L
Laine Stump 已提交
2857 2858
    vshPrint(ctl, "%s", _("Compiled with support for:\n"));
    vshPrint(ctl, "%s", _(" Hypervisors:"));
2859
#ifdef WITH_QEMU
2860
    vshPrint(ctl, " QEMU/KVM");
2861
#endif
D
Doug Goldstein 已提交
2862 2863 2864
#ifdef WITH_LXC
    vshPrint(ctl, " LXC");
#endif
2865 2866 2867
#ifdef WITH_UML
    vshPrint(ctl, " UML");
#endif
D
Doug Goldstein 已提交
2868 2869 2870 2871 2872 2873
#ifdef WITH_XEN
    vshPrint(ctl, " Xen");
#endif
#ifdef WITH_LIBXL
    vshPrint(ctl, " LibXL");
#endif
2874 2875 2876
#ifdef WITH_OPENVZ
    vshPrint(ctl, " OpenVZ");
#endif
D
Doug Goldstein 已提交
2877 2878
#ifdef WITH_VMWARE
    vshPrint(ctl, " VMWare");
2879
#endif
D
Doug Goldstein 已提交
2880 2881
#ifdef WITH_PHYP
    vshPrint(ctl, " PHYP");
2882
#endif
D
Doug Goldstein 已提交
2883 2884
#ifdef WITH_VBOX
    vshPrint(ctl, " VirtualBox");
2885 2886 2887 2888
#endif
#ifdef WITH_ESX
    vshPrint(ctl, " ESX");
#endif
D
Doug Goldstein 已提交
2889 2890
#ifdef WITH_HYPERV
    vshPrint(ctl, " Hyper-V");
2891
#endif
D
Doug Goldstein 已提交
2892 2893
#ifdef WITH_XENAPI
    vshPrint(ctl, " XenAPI");
2894 2895 2896 2897 2898 2899
#endif
#ifdef WITH_TEST
    vshPrint(ctl, " Test");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
2900
    vshPrint(ctl, "%s", _(" Networking:"));
2901 2902 2903 2904 2905 2906 2907 2908 2909
#ifdef WITH_REMOTE
    vshPrint(ctl, " Remote");
#endif
#ifdef WITH_NETWORK
    vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
    vshPrint(ctl, " Bridging");
#endif
2910
#if defined(WITH_INTERFACE)
D
Doug Goldstein 已提交
2911
    vshPrint(ctl, " Interface");
2912 2913
# if defined(WITH_NETCF)
    vshPrint(ctl, " netcf");
2914
# elif defined(WITH_UDEV)
2915
    vshPrint(ctl, " udev");
2916
# endif
2917 2918 2919 2920 2921 2922 2923 2924 2925
#endif
#ifdef WITH_NWFILTER
    vshPrint(ctl, " Nwfilter");
#endif
#ifdef WITH_VIRTUALPORT
    vshPrint(ctl, " VirtualPort");
#endif
    vshPrint(ctl, "\n");

L
Laine Stump 已提交
2926
    vshPrint(ctl, "%s", _(" Storage:"));
2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946
#ifdef WITH_STORAGE_DIR
    vshPrint(ctl, " Dir");
#endif
#ifdef WITH_STORAGE_DISK
    vshPrint(ctl, " Disk");
#endif
#ifdef WITH_STORAGE_FS
    vshPrint(ctl, " Filesystem");
#endif
#ifdef WITH_STORAGE_SCSI
    vshPrint(ctl, " SCSI");
#endif
#ifdef WITH_STORAGE_MPATH
    vshPrint(ctl, " Multipath");
#endif
#ifdef WITH_STORAGE_ISCSI
    vshPrint(ctl, " iSCSI");
#endif
#ifdef WITH_STORAGE_LVM
    vshPrint(ctl, " LVM");
2947 2948 2949
#endif
#ifdef WITH_STORAGE_RBD
    vshPrint(ctl, " RBD");
2950 2951 2952
#endif
#ifdef WITH_STORAGE_SHEEPDOG
    vshPrint(ctl, " Sheepdog");
2953 2954 2955
#endif
    vshPrint(ctl, "\n");

2956
    vshPrint(ctl, "%s", _(" Miscellaneous:"));
2957 2958 2959
#ifdef WITH_LIBVIRTD
    vshPrint(ctl, " Daemon");
#endif
2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
#ifdef WITH_NODE_DEVICES
    vshPrint(ctl, " Nodedev");
#endif
#ifdef WITH_SECDRIVER_APPARMOR
    vshPrint(ctl, " AppArmor");
#endif
#ifdef WITH_SECDRIVER_SELINUX
    vshPrint(ctl, " SELinux");
#endif
#ifdef WITH_SECRETS
    vshPrint(ctl, " Secrets");
#endif
#ifdef ENABLE_DEBUG
    vshPrint(ctl, " Debug");
#endif
#ifdef WITH_DTRACE_PROBES
    vshPrint(ctl, " DTrace");
#endif
#ifdef USE_READLINE
    vshPrint(ctl, " Readline");
#endif
#ifdef WITH_DRIVER_MODULES
    vshPrint(ctl, " Modular");
#endif
    vshPrint(ctl, "\n");
}

static bool
vshAllowedEscapeChar(char c)
{
    /* Allowed escape characters:
     * a-z A-Z @ [ \ ] ^ _
     */
    return ('a' <= c && c <= 'z') ||
        ('@' <= c && c <= '_');
}

/*
 * argv[]:  virsh [options] [command]
 *
 */
E
Eric Blake 已提交
3001
static bool
3002 3003
vshParseArgv(vshControl *ctl, int argc, char **argv)
{
3004 3005
    int arg, len, debug;
    size_t i;
3006
    int longindex = -1;
3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022
    struct option opt[] = {
        {"debug", required_argument, NULL, 'd'},
        {"help", no_argument, NULL, 'h'},
        {"quiet", no_argument, NULL, 'q'},
        {"timing", no_argument, NULL, 't'},
        {"version", optional_argument, NULL, 'v'},
        {"connect", required_argument, NULL, 'c'},
        {"readonly", no_argument, NULL, 'r'},
        {"log", required_argument, NULL, 'l'},
        {"escape", required_argument, NULL, 'e'},
        {NULL, 0, NULL, 0}
    };

    /* Standard (non-command) options. The leading + ensures that no
     * argument reordering takes place, so that command options are
     * not confused with top-level virsh options. */
3023
    while ((arg = getopt_long(argc, argv, "+:d:hqtc:vVrl:e:", opt, &longindex)) != -1) {
3024 3025
        switch (arg) {
        case 'd':
3026
            if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
3027 3028
                vshError(ctl, _("option %s takes a numeric argument"),
                         longindex == -1 ? "-d" : "--debug");
3029 3030
                exit(EXIT_FAILURE);
            }
3031 3032 3033 3034 3035
            if (debug < VSH_ERR_DEBUG || debug > VSH_ERR_ERROR)
                vshError(ctl, _("ignoring debug level %d out of range [%d-%d]"),
                         debug, VSH_ERR_DEBUG, VSH_ERR_ERROR);
            else
                ctl->debug = debug;
3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047
            break;
        case 'h':
            vshUsage();
            exit(EXIT_SUCCESS);
            break;
        case 'q':
            ctl->quiet = true;
            break;
        case 't':
            ctl->timing = true;
            break;
        case 'c':
M
Martin Kletzander 已提交
3048
            VIR_FREE(ctl->name);
3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063
            ctl->name = vshStrdup(ctl, optarg);
            break;
        case 'v':
            if (STRNEQ_NULLABLE(optarg, "long")) {
                puts(VERSION);
                exit(EXIT_SUCCESS);
            }
            /* fall through */
        case 'V':
            vshShowVersion(ctl);
            exit(EXIT_SUCCESS);
        case 'r':
            ctl->readonly = true;
            break;
        case 'l':
M
Martin Kletzander 已提交
3064
            vshCloseLogFile(ctl);
3065
            ctl->logfile = vshStrdup(ctl, optarg);
M
Martin Kletzander 已提交
3066
            vshOpenLogFile(ctl);
3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080
            break;
        case 'e':
            len = strlen(optarg);

            if ((len == 2 && *optarg == '^' &&
                 vshAllowedEscapeChar(optarg[1])) ||
                (len == 1 && *optarg != '^')) {
                ctl->escapeChar = optarg;
            } else {
                vshError(ctl, _("Invalid string '%s' for escape sequence"),
                         optarg);
                exit(EXIT_FAILURE);
            }
            break;
3081
        case ':':
3082
            for (i = 0; opt[i].name != NULL; i++) {
3083 3084
                if (opt[i].val == optopt)
                    break;
3085
            }
3086 3087 3088 3089 3090 3091
            if (opt[i].name)
                vshError(ctl, _("option '-%c'/'--%s' requires an argument"),
                         optopt, opt[i].name);
            else
                vshError(ctl, _("option '-%c' requires an argument"), optopt);
            exit(EXIT_FAILURE);
3092
        case '?':
3093 3094 3095 3096
            if (optopt)
                vshError(ctl, _("unsupported option '-%c'. See --help."), optopt);
            else
                vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]);
3097
            exit(EXIT_FAILURE);
3098
        default:
3099
            vshError(ctl, _("unknown option"));
3100 3101
            exit(EXIT_FAILURE);
        }
3102
        longindex = -1;
3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118
    }

    if (argc > optind) {
        /* parse command */
        ctl->imode = false;
        if (argc - optind == 1) {
            vshDebug(ctl, VSH_ERR_INFO, "commands: \"%s\"\n", argv[optind]);
            return vshCommandStringParse(ctl, argv[optind]);
        } else {
            return vshCommandArgvParse(ctl, argc - optind, argv + optind);
        }
    }
    return true;
}

static const vshCmdDef virshCmds[] = {
3119 3120 3121 3122 3123
    {.name = "cd",
     .handler = cmdCd,
     .opts = opts_cd,
     .info = info_cd,
     .flags = VSH_CMD_FLAG_NOCONNECT
3124 3125 3126 3127 3128 3129
    },
    {.name = "connect",
     .handler = cmdConnect,
     .opts = opts_connect,
     .info = info_connect,
     .flags = VSH_CMD_FLAG_NOCONNECT
3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161
    },
    {.name = "echo",
     .handler = cmdEcho,
     .opts = opts_echo,
     .info = info_echo,
     .flags = VSH_CMD_FLAG_NOCONNECT
    },
    {.name = "exit",
     .handler = cmdQuit,
     .opts = NULL,
     .info = info_quit,
     .flags = VSH_CMD_FLAG_NOCONNECT
    },
    {.name = "help",
     .handler = cmdHelp,
     .opts = opts_help,
     .info = info_help,
     .flags = VSH_CMD_FLAG_NOCONNECT
    },
    {.name = "pwd",
     .handler = cmdPwd,
     .opts = NULL,
     .info = info_pwd,
     .flags = VSH_CMD_FLAG_NOCONNECT
    },
    {.name = "quit",
     .handler = cmdQuit,
     .opts = NULL,
     .info = info_quit,
     .flags = VSH_CMD_FLAG_NOCONNECT
    },
    {.name = NULL}
3162
};
3163

3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178
static const vshCmdGrp cmdGroups[] = {
    {VSH_CMD_GRP_DOM_MANAGEMENT, "domain", domManagementCmds},
    {VSH_CMD_GRP_DOM_MONITORING, "monitor", domMonitoringCmds},
    {VSH_CMD_GRP_HOST_AND_HV, "host", hostAndHypervisorCmds},
    {VSH_CMD_GRP_IFACE, "interface", ifaceCmds},
    {VSH_CMD_GRP_NWFILTER, "filter", nwfilterCmds},
    {VSH_CMD_GRP_NETWORK, "network", networkCmds},
    {VSH_CMD_GRP_NODEDEV, "nodedev", nodedevCmds},
    {VSH_CMD_GRP_SECRET, "secret", secretCmds},
    {VSH_CMD_GRP_SNAPSHOT, "snapshot", snapshotCmds},
    {VSH_CMD_GRP_STORAGE_POOL, "pool", storagePoolCmds},
    {VSH_CMD_GRP_STORAGE_VOL, "volume", storageVolCmds},
    {VSH_CMD_GRP_VIRSH, "virsh", virshCmds},
    {NULL, NULL, NULL}
};
K
Karel Zak 已提交
3179

3180 3181 3182 3183
int
main(int argc, char **argv)
{
    vshControl _ctl, *ctl = &_ctl;
3184
    char *defaultConn;
E
Eric Blake 已提交
3185
    bool ret = true;
K
Karel Zak 已提交
3186

3187 3188 3189
    memset(ctl, 0, sizeof(vshControl));
    ctl->imode = true;          /* default is interactive mode */
    ctl->log_fd = -1;           /* Initialize log file descriptor */
J
Jiri Denemark 已提交
3190
    ctl->debug = VSH_DEBUG_DEFAULT;
E
Eric Blake 已提交
3191
    ctl->escapeChar = "^]";     /* Same default as telnet */
3192

3193

3194 3195
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
3196
        /* failure to setup locale is not fatal */
3197
    }
3198
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
3199
        perror("bindtextdomain");
E
Eric Blake 已提交
3200
        return EXIT_FAILURE;
3201
    }
3202
    if (!textdomain(PACKAGE)) {
3203
        perror("textdomain");
E
Eric Blake 已提交
3204
        return EXIT_FAILURE;
3205 3206
    }

3207 3208 3209 3210 3211 3212 3213
    if (isatty(STDIN_FILENO)) {
        ctl->istty = true;

        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
            ctl->istty = false;
    }

3214 3215 3216 3217 3218
    if (virMutexInit(&ctl->lock) < 0) {
        vshError(ctl, "%s", _("Failed to initialize mutex"));
        return EXIT_FAILURE;
    }

3219 3220 3221 3222 3223
    if (virInitialize() < 0) {
        vshError(ctl, "%s", _("Failed to initialize libvirt"));
        return EXIT_FAILURE;
    }

3224
    if (!(progname = strrchr(argv[0], '/')))
K
Karel Zak 已提交
3225 3226 3227
        progname = argv[0];
    else
        progname++;
3228

3229
    if ((defaultConn = getenv("VIRSH_DEFAULT_CONNECT_URI"))) {
E
Eric Blake 已提交
3230
        ctl->name = vshStrdup(ctl, defaultConn);
3231 3232
    }

M
Martin Kletzander 已提交
3233
    vshInitDebug(ctl);
3234

M
Martin Kletzander 已提交
3235 3236
    if (!vshParseArgv(ctl, argc, argv) ||
        !vshInit(ctl)) {
D
Daniel P. Berrange 已提交
3237
        vshDeinit(ctl);
K
Karel Zak 已提交
3238
        exit(EXIT_FAILURE);
D
Daniel P. Berrange 已提交
3239
    }
3240

K
Karel Zak 已提交
3241
    if (!ctl->imode) {
3242
        ret = vshCommandRun(ctl, ctl->cmd);
3243
    } else {
K
Karel Zak 已提交
3244 3245
        /* interactive mode */
        if (!ctl->quiet) {
K
Karel Zak 已提交
3246
            vshPrint(ctl,
3247
                     _("Welcome to %s, the virtualization interactive terminal.\n\n"),
3248
                     progname);
J
Jim Meyering 已提交
3249
            vshPrint(ctl, "%s",
3250
                     _("Type:  'help' for help with commands\n"
3251
                       "       'quit' to quit\n\n"));
K
Karel Zak 已提交
3252
        }
3253 3254 3255 3256 3257 3258

        if (vshReadlineInit(ctl) < 0) {
            vshDeinit(ctl);
            exit(EXIT_FAILURE);
        }

K
Karel Zak 已提交
3259
        do {
3260
            const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
3261
            ctl->cmdstr =
3262
                vshReadline(ctl, prompt);
3263 3264
            if (ctl->cmdstr == NULL)
                break;          /* EOF */
K
Karel Zak 已提交
3265
            if (*ctl->cmdstr) {
3266
#if USE_READLINE
K
Karel Zak 已提交
3267
                add_history(ctl->cmdstr);
3268
#endif
3269
                if (vshCommandStringParse(ctl, ctl->cmdstr))
K
Karel Zak 已提交
3270 3271
                    vshCommandRun(ctl, ctl->cmd);
            }
3272
            VIR_FREE(ctl->cmdstr);
3273
        } while (ctl->imode);
K
Karel Zak 已提交
3274

3275 3276
        if (ctl->cmdstr == NULL)
            fputc('\n', stdout);        /* line break after alone prompt */
K
Karel Zak 已提交
3277
    }
3278

K
Karel Zak 已提交
3279 3280
    vshDeinit(ctl);
    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
3281
}