[libvirt] [PATCH 02/13] vsh: Remove client specific data, only generic data are kept

Erik Skultety eskultet at redhat.com
Mon Jun 29 15:37:36 UTC 2015


Virt shell (vsh) started as a copy of virsh, but it needs to be split
from virsh, so remove all virsh specific data that cannot/need not be
used with other potential clients like virt-admin
---
 tools/vsh.c | 1505 +----------------------------------------------------------
 tools/vsh.h |   66 +--
 2 files changed, 9 insertions(+), 1562 deletions(-)

diff --git a/tools/vsh.c b/tools/vsh.c
index 609c8f3..8ef04b9 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -32,7 +32,6 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <errno.h>
-#include <getopt.h>
 #include <sys/time.h>
 #include "c-ctype.h"
 #include <fcntl.h>
@@ -63,27 +62,12 @@
 #include "virtypedparam.h"
 #include "virstring.h"
 
-#include "virsh-console.h"
-#include "virsh-domain.h"
-#include "virsh-domain-monitor.h"
-#include "virsh-host.h"
-#include "virsh-interface.h"
-#include "virsh-network.h"
-#include "virsh-nodedev.h"
-#include "virsh-nwfilter.h"
-#include "virsh-pool.h"
-#include "virsh-secret.h"
-#include "virsh-snapshot.h"
-#include "virsh-volume.h"
-
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
 # define SA_SIGINFO 0
 #endif
 
-static char *progname;
-
-static const vshCmdGrp cmdGroups[];
+static const vshCmdGrp *cmdGroups;
 
 /* Bypass header poison */
 #undef strdup
@@ -138,44 +122,6 @@ vshNameSorter(const void *a, const void *b)
     return vshStrcasecmp(*sa, *sb);
 }
 
-double
-vshPrettyCapacity(unsigned long long val, const char **unit)
-{
-    double limit = 1024;
-
-    if (val < limit) {
-        *unit = "B";
-        return val;
-    }
-    limit *= 1024;
-    if (val < limit) {
-        *unit = "KiB";
-        return val / (limit / 1024);
-    }
-    limit *= 1024;
-    if (val < limit) {
-        *unit = "MiB";
-        return val / (limit / 1024);
-    }
-    limit *= 1024;
-    if (val < limit) {
-        *unit = "GiB";
-        return val / (limit / 1024);
-    }
-    limit *= 1024;
-    if (val < limit) {
-        *unit = "TiB";
-        return val / (limit / 1024);
-    }
-    limit *= 1024;
-    if (val < limit) {
-        *unit = "PiB";
-        return val / (limit / 1024);
-    }
-    limit *= 1024;
-    *unit = "EiB";
-    return val / (limit / 1024);
-}
 
 /*
  * Convert the strings separated by ',' into array. The returned
@@ -299,743 +245,14 @@ vshReportError(vshControl *ctl)
 
     vshError(ctl, "%s", last_error->message);
 
- out:
-    vshResetLibvirtError();
-}
-
-/*
- * Detection of disconnections and automatic reconnection support
- */
-static int disconnected; /* we may have been disconnected */
-
-/*
- * vshCatchDisconnect:
- *
- * We get here when the connection was closed.  We can't do much in the
- * handler, just save the fact it was raised.
- */
-static void
-vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
-                   int reason,
-                   void *opaque ATTRIBUTE_UNUSED)
-{
-    if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT)
-        disconnected++;
-}
-
-/* Main Function which should be used for connecting.
- * This function properly handles keepalive settings. */
-virConnectPtr
-vshConnect(vshControl *ctl, const char *uri, bool readonly)
-{
-    virConnectPtr c = NULL;
-    int interval = 5; /* Default */
-    int count = 6;    /* Default */
-    bool keepalive_forced = false;
-
-    if (ctl->keepalive_interval >= 0) {
-        interval = ctl->keepalive_interval;
-        keepalive_forced = true;
-    }
-    if (ctl->keepalive_count >= 0) {
-        count = ctl->keepalive_count;
-        keepalive_forced = true;
-    }
-
-    c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
-                           readonly ? VIR_CONNECT_RO : 0);
-    if (!c)
-        return NULL;
-
-    if (interval > 0 &&
-        virConnectSetKeepAlive(c, interval, count) != 0) {
-        if (keepalive_forced) {
-            vshError(ctl, "%s",
-                     _("Cannot setup keepalive on connection "
-                       "as requested, disconnecting"));
-            virConnectClose(c);
-            return NULL;
-        }
-        vshDebug(ctl, VSH_ERR_INFO, "%s",
-                 _("Failed to setup keepalive on connection\n"));
-    }
-
-    return c;
-}
-
-/*
- * vshReconnect:
- *
- * Reconnect after a disconnect from libvirtd
- *
- */
-static void
-vshReconnect(vshControl *ctl)
-{
-    bool connected = false;
-
-    if (ctl->conn) {
-        int ret;
-
-        connected = true;
-
-        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"));
-    }
-
-    ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly);
-
-    if (!ctl->conn) {
-        if (disconnected)
-            vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
-        else
-            vshError(ctl, "%s", _("failed to connect to the hypervisor"));
-    } 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"));
-    }
-    disconnected = 0;
-    ctl->useGetInfo = false;
-    ctl->useSnapshotOld = false;
-    ctl->blockJobNoBytes = false;
-}
-
-
-/*
- * "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_STRING,
-     .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;
-
-        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"));
-        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->blockJobNoBytes = false;
-    ctl->readonly = ro;
-
-    ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly);
-
-    if (!ctl->conn) {
-        vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
-        return false;
-    }
-
-    if (virConnectRegisterCloseCallback(ctl->conn, vshCatchDisconnect,
-                                        NULL, NULL) < 0)
-        vshError(ctl, "%s", _("Unable to register disconnect callback"));
-
-    return true;
-}
-
-
-#ifndef WIN32
-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);
-}
-
-/**
- * vshAskReedit:
- * @msg: Question to ask user
- *
- * Ask user if he wants to return to previously
- * edited file.
- *
- * Returns 'y' if he wants to
- *         'n' if he doesn't want to
- *         'i' if he wants to try defining it again while ignoring validation
- *         'f' if he forcibly wants to
- *         -1  on error
- *          0  otherwise
- */
-int
-vshAskReedit(vshControl *ctl, const char *msg, bool relax_avail)
-{
-    int c = -1;
-
-    if (!isatty(STDIN_FILENO))
-        return -1;
-
-    vshReportError(ctl);
-
-    if (vshTTYMakeRaw(ctl, false) < 0)
-        return -1;
-
-    while (true) {
-        vshPrint(ctl, "\r%s %s %s: ", msg, _("Try again?"),
-                 relax_avail ? "[y,n,i,f,?]" : "[y,n,f,?]");
-        c = c_tolower(getchar());
-
-        if (c == '?') {
-            vshPrintRaw(ctl,
-                        "",
-                        _("y - yes, start editor again"),
-                        _("n - no, throw away my changes"),
-                        NULL);
-
-            if (relax_avail) {
-                vshPrintRaw(ctl,
-                            _("i - turn off validation and try to redefine again"),
-                            NULL);
-            }
-
-            vshPrintRaw(ctl,
-                        _("f - force, try to redefine again"),
-                        _("? - print this help"),
-                        NULL);
-            continue;
-        } else if (c == 'y' || c == 'n' || c == 'f' ||
-                   (relax_avail && c == 'i')) {
-            break;
-        }
-    }
-
-    vshTTYRestore(ctl);
-
-    vshPrint(ctl, "\r\n");
-    return c;
-}
-#else /* WIN32 */
-int
-vshAskReedit(vshControl *ctl,
-             const char *msg ATTRIBUTE_UNUSED,
-             bool relax_avail ATTRIBUTE_UNUSED)
-{
-    vshDebug(ctl, VSH_ERR_WARNING, "%s", _("This function is not "
-                                           "supported on WIN32 platform"));
-    return 0;
-}
-#endif /* WIN32 */
-
-int vshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED,
-                  const char *bytes, size_t nbytes, void *opaque)
-{
-    int *fd = opaque;
-
-    return safewrite(*fd, bytes, nbytes);
-}
-
-/* ---------------
- * Commands
- * ---------------
- */
-
-/*
- * "help" command
- */
-static const vshCmdInfo info_help[] = {
-    {.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}
-};
-
-static const vshCmdOptDef opts_help[] = {
-    {.name = "command",
-     .type = VSH_OT_STRING,
-     .help = N_("Prints global help, command specific help, or help for a group of related commands")
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdHelp(vshControl *ctl, const vshCmd *cmd)
- {
-    const char *name = NULL;
-
-    if (vshCommandOptString(ctl, cmd, "command", &name) <= 0) {
-        const vshCmdGrp *grp;
-        const vshCmdDef *def;
-
-        vshPrint(ctl, "%s", _("Grouped commands:\n\n"));
-
-        for (grp = cmdGroups; grp->name; grp++) {
-            vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
-                     grp->keyword);
-
-            for (def = grp->commands; def->name; def++) {
-                if (def->flags & VSH_CMD_FLAG_ALIAS)
-                    continue;
-                vshPrint(ctl, "    %-30s %s\n", def->name,
-                         _(vshCmddefGetInfo(def, "help")));
-            }
-
-            vshPrint(ctl, "\n");
-        }
-
-        return true;
-    }
-
-    if (vshCmddefSearch(name)) {
-        return vshCmddefHelp(ctl, name);
-    } else if (vshCmdGrpSearch(name)) {
-        return vshCmdGrpHelp(ctl, name);
-    } else {
-        vshError(ctl, _("command or command group '%s' doesn't exist"), name);
-        return false;
-    }
-}
-
-/* Tree listing helpers.  */
-
-static int
-vshTreePrintInternal(vshControl *ctl,
-                     vshTreeLookup lookup,
-                     void *opaque,
-                     int num_devices,
-                     int devid,
-                     int lastdev,
-                     bool root,
-                     virBufferPtr indent)
-{
-    size_t i;
-    int nextlastdev = -1;
-    int ret = -1;
-    const char *dev = (lookup)(devid, false, opaque);
-
-    if (virBufferError(indent))
-        goto cleanup;
-
-    /* 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;
-    }
-
-    /* Determine the index of the last child device */
-    for (i = 0; i < num_devices; i++) {
-        const char *parent = (lookup)(i, true, opaque);
-
-        if (parent && STREQ(parent, dev))
-            nextlastdev = i;
-    }
-
-    /* If there is a child device, then print another blank line */
-    if (nextlastdev != -1)
-        vshPrint(ctl, "%s  |\n", virBufferCurrentContent(indent));
-
-    /* Finally print all children */
-    virBufferAddLit(indent, "  ");
-    if (virBufferError(indent))
-        goto cleanup;
-    for (i = 0; i < num_devices; i++) {
-        const char *parent = (lookup)(i, true, opaque);
-
-        if (parent && STREQ(parent, dev) &&
-            vshTreePrintInternal(ctl, lookup, opaque,
-                                 num_devices, i, nextlastdev,
-                                 false, indent) < 0)
-            goto cleanup;
-    }
-    virBufferTrim(indent, "  ", -1);
-
-    /* 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));
-
-    if (!root)
-        virBufferTrim(indent, NULL, 2);
-    ret = 0;
- cleanup:
-    return ret;
-}
-
-int
-vshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque,
-             int num_devices, int devid)
-{
-    int ret;
-    virBuffer indent = VIR_BUFFER_INITIALIZER;
-
-    ret = vshTreePrintInternal(ctl, lookup, opaque, num_devices,
-                               devid, devid, true, &indent);
-    if (ret < 0)
-        vshError(ctl, "%s", _("Failed to complete tree listing"));
-    virBufferFreeAndReset(&indent);
-    return ret;
-}
-
-/* Common code for the edit / net-edit / pool-edit functions which follow. */
-char *
-vshEditWriteToTempFile(vshControl *ctl, const char *doc)
-{
-    char *ret;
-    const char *tmpdir;
-    int fd;
-    char ebuf[1024];
-
-    tmpdir = virGetEnvBlockSUID("TMPDIR");
-    if (!tmpdir) tmpdir = "/tmp";
-    if (virAsprintf(&ret, "%s/virshXXXXXX.xml", tmpdir) < 0) {
-        vshError(ctl, "%s", _("out of memory"));
-        return NULL;
-    }
-    fd = mkostemps(ret, 4, O_CLOEXEC);
-    if (fd == -1) {
-        vshError(ctl, _("mkostemps: failed to create temporary file: %s"),
-                 virStrerror(errno, ebuf, sizeof(ebuf)));
-        VIR_FREE(ret);
-        return NULL;
-    }
-
-    if (safewrite(fd, doc, strlen(doc)) == -1) {
-        vshError(ctl, _("write: %s: failed to write to temporary file: %s"),
-                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
-        VIR_FORCE_CLOSE(fd);
-        unlink(ret);
-        VIR_FREE(ret);
-        return NULL;
-    }
-    if (VIR_CLOSE(fd) < 0) {
-        vshError(ctl, _("close: %s: failed to write or close temporary file: %s"),
-                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
-        unlink(ret);
-        VIR_FREE(ret);
-        return NULL;
-    }
-
-    /* Temporary filename: caller frees. */
-    return ret;
-}
-
-/* Characters permitted in $EDITOR environment variable and temp filename. */
-#define ACCEPTED_CHARS \
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/_.:@"
-
-int
-vshEditFile(vshControl *ctl, const char *filename)
-{
-    const char *editor;
-    virCommandPtr cmd;
-    int ret = -1;
-    int outfd = STDOUT_FILENO;
-    int errfd = STDERR_FILENO;
-
-    editor = virGetEnvBlockSUID("VISUAL");
-    if (!editor)
-        editor = virGetEnvBlockSUID("EDITOR");
-    if (!editor)
-        editor = DEFAULT_EDITOR;
-
-    /* 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
-     * is why sudo scrubs it by default).  Conversely, if the editor
-     * is safe, we can run it directly rather than wasting a shell.
-     */
-    if (strspn(editor, ACCEPTED_CHARS) != strlen(editor)) {
-        if (strspn(filename, ACCEPTED_CHARS) != strlen(filename)) {
-            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);
-    }
-
-    virCommandSetInputFD(cmd, STDIN_FILENO);
-    virCommandSetOutputFD(cmd, &outfd);
-    virCommandSetErrorFD(cmd, &errfd);
-    if (virCommandRunAsync(cmd, NULL) < 0 ||
-        virCommandWait(cmd, NULL) < 0) {
-        vshReportError(ctl);
-        goto cleanup;
-    }
-    ret = 0;
-
- cleanup:
-    virCommandFree(cmd);
-    return ret;
-}
-
-char *
-vshEditReadBackFile(vshControl *ctl, const char *filename)
-{
-    char *ret;
-    char ebuf[1024];
-
-    if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) {
-        vshError(ctl,
-                 _("%s: failed to read temporary file: %s"),
-                 filename, virStrerror(errno, ebuf, sizeof(ebuf)));
-        return NULL;
-    }
-    return ret;
-}
-
-
-/*
- * "cd" command
- */
-static const vshCmdInfo info_cd[] = {
-    {.name = "help",
-     .data = N_("change the current directory")
-    },
-    {.name = "desc",
-     .data = N_("Change the current directory.")
-    },
-    {.name = NULL}
-};
-
-static const vshCmdOptDef opts_cd[] = {
-    {.name = "dir",
-     .type = VSH_OT_STRING,
-     .help = N_("directory to switch to (default: home or else root)")
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdCd(vshControl *ctl, const vshCmd *cmd)
-{
-    const char *dir = NULL;
-    char *dir_malloced = NULL;
-    bool ret = true;
-    char ebuf[1024];
-
-    if (!ctl->imode) {
-        vshError(ctl, "%s", _("cd: command valid only in interactive mode"));
-        return false;
-    }
-
-    if (vshCommandOptString(ctl, cmd, "dir", &dir) <= 0)
-        dir = dir_malloced = virGetUserDirectory();
-    if (!dir)
-        dir = "/";
-
-    if (chdir(dir) == -1) {
-        vshError(ctl, _("cd: %s: %s"),
-                 virStrerror(errno, ebuf, sizeof(ebuf)), dir);
-        ret = false;
-    }
-
-    VIR_FREE(dir_malloced);
-    return ret;
-}
-
-/*
- * "pwd" command
- */
-static const vshCmdInfo info_pwd[] = {
-    {.name = "help",
-     .data = N_("print the current directory")
-    },
-    {.name = "desc",
-     .data = N_("Print the current directory.")
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
-{
-    char *cwd;
-    bool ret = true;
-    char ebuf[1024];
-
-    cwd = getcwd(NULL, 0);
-    if (!cwd) {
-        vshError(ctl, _("pwd: cannot get current directory: %s"),
-                 virStrerror(errno, ebuf, sizeof(ebuf)));
-        ret = false;
-    } else {
-        vshPrint(ctl, _("%s\n"), cwd);
-        VIR_FREE(cwd);
-    }
-
-    return ret;
-}
-
-/*
- * "echo" command
- */
-static const vshCmdInfo info_echo[] = {
-    {.name = "help",
-     .data = N_("echo arguments")
-    },
-    {.name = "desc",
-     .data = N_("Echo back arguments, possibly with quoting.")
-    },
-    {.name = NULL}
-};
-
-static const vshCmdOptDef opts_echo[] = {
-    {.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 = "hi",
-     .type = VSH_OT_ALIAS,
-     .help = "string=hello"
-    },
-    {.name = "string",
-     .type = VSH_OT_ARGV,
-     .help = N_("arguments to echo")
-    },
-    {.name = NULL}
-};
-
-/* Exists mainly for debugging virsh, but also handy for adding back
- * quotes for later evaluation.
- */
-static bool
-cmdEcho(vshControl *ctl, const vshCmd *cmd)
-{
-    bool shell = false;
-    bool xml = false;
-    int count = 0;
-    const vshCmdOpt *opt = NULL;
-    char *arg;
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-
-    if (vshCommandOptBool(cmd, "shell"))
-        shell = true;
-    if (vshCommandOptBool(cmd, "xml"))
-        xml = true;
-
-    while ((opt = vshCommandOptArgv(ctl, cmd, opt))) {
-        char *str;
-        virBuffer xmlbuf = VIR_BUFFER_INITIALIZER;
-
-        arg = opt->data;
-
-        if (count)
-            virBufferAddChar(&buf, ' ');
-
-        if (xml) {
-            virBufferEscapeString(&xmlbuf, "%s", arg);
-            if (virBufferError(&xmlbuf)) {
-                vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
-                return false;
-            }
-            str = virBufferContentAndReset(&xmlbuf);
-        } else {
-            str = vshStrdup(ctl, arg);
-        }
-
-        if (shell)
-            virBufferEscapeShell(&buf, str);
-        else
-            virBufferAdd(&buf, str, -1);
-        count++;
-        VIR_FREE(str);
-    }
-
-    if (virBufferError(&buf)) {
-        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
-        return false;
-    }
-    arg = virBufferContentAndReset(&buf);
-    if (arg)
-        vshPrint(ctl, "%s", arg);
-    VIR_FREE(arg);
-    return true;
+ out:
+    vshResetLibvirtError();
 }
 
 /*
- * "quit" command
+ * Detection of disconnections and automatic reconnection support
  */
-static const vshCmdInfo info_quit[] = {
-    {.name = "help",
-     .data = N_("quit this interactive terminal")
-    },
-    {.name = "desc",
-     .data = ""
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdQuit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
-{
-    ctl->imode = false;
-    return true;
-}
+static int disconnected; /* we may have been disconnected */
 
 /* ---------------
  * Utils for work with command definition
@@ -1906,56 +1123,6 @@ vshCommandOptArgv(vshControl *ctl ATTRIBUTE_UNUSED, const vshCmd *cmd,
     return NULL;
 }
 
-/*
- * vshCommandOptTimeoutToMs:
- * @ctl virsh control structure
- * @cmd command reference
- * @timeout result
- *
- * Parse an optional --timeout parameter in seconds, but store the
- * value of the timeout in milliseconds.
- * See vshCommandOptInt()
- */
-int
-vshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout)
-{
-    int ret;
-    unsigned int utimeout;
-
-    if ((ret = vshCommandOptUInt(ctl, cmd, "timeout", &utimeout)) <= 0)
-        return ret;
-
-    /* Ensure that the timeout is not zero and that we can convert
-     * it from seconds to milliseconds without overflowing. */
-    if (utimeout == 0 || utimeout > INT_MAX / 1000) {
-        vshError(ctl,
-                 _("Numeric value '%u' for <%s> option is malformed or out of range"),
-                 utimeout,
-                 "timeout");
-        ret = -1;
-    } else {
-        *timeout = ((int) utimeout) * 1000;
-    }
-
-    return ret;
-}
-
-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;
-}
 
 /*
  * Executes command(s) and returns return code from last command
@@ -2187,13 +1354,14 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser)
                 if (STRNEQ(tmpopt->def->name, "help"))
                     continue;
 
+                const vshCmdDef *help = vshCmddefSearch("help");
                 vshCommandOptFree(first);
                 first = vshMalloc(ctl, sizeof(vshCmdOpt));
-                first->def = &(opts_help[0]);
+                first->def = help->opts;
                 first->data = vshStrdup(ctl, cmd->name);
                 first->next = NULL;
 
-                cmd = vshCmddefSearch("help");
+                cmd = help;
                 opts_required = 0;
                 opts_seen = 0;
                 break;
@@ -2346,33 +1514,6 @@ vshCommandStringParse(vshControl *ctl, char *cmdstr)
  * Misc utils
  * ---------------
  */
-int
-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;
-}
 
 /* Return a non-NULL string representation of a typed parameter; exit
  * if we are out of memory.  */
@@ -2803,49 +1944,6 @@ vshInitDebug(vshControl *ctl)
     }
 }
 
-/*
- * Initialize connection.
- */
-static bool
-vshInit(vshControl *ctl)
-{
-    /* Since we have the commandline arguments parsed, we need to
-     * re-initialize all the debugging to make it work properly */
-    vshInitDebug(ctl);
-
-    if (ctl->conn)
-        return false;
-
-    /* set up the library error handler */
-    virSetErrorFunc(NULL, virshErrorHandler);
-
-    if (virEventRegisterDefaultImpl() < 0)
-        return false;
-
-    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
-        return false;
-    ctl->eventLoopStarted = true;
-
-    if ((ctl->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl,
-                                                NULL)) < 0)
-        return false;
-
-    if (ctl->name) {
-        vshReconnect(ctl);
-        /* 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) {
-            vshReportError(ctl);
-            return false;
-        }
-    }
-
-    return true;
-}
 
 #define LOGFILE_FLAGS (O_WRONLY | O_APPEND | O_CREAT | O_SYNC)
 
@@ -3211,590 +2309,3 @@ vshReadline(vshControl *ctl, const char *prompt)
 }
 
 #endif /* !WITH_READLINE */
-
-static void
-vshDeinitTimer(int timer ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
-{
-    /* nothing to be done here */
-}
-
-/*
- * Deinitialize virsh
- */
-static bool
-vshDeinit(vshControl *ctl)
-{
-    vshReadlineDeinit(ctl);
-    vshCloseLogFile(ctl);
-    VIR_FREE(ctl->name);
-    if (ctl->conn) {
-        int ret;
-        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"));
-    }
-    virResetLastError();
-
-    if (ctl->eventLoopStarted) {
-        int timer;
-
-        virMutexLock(&ctl->lock);
-        ctl->quit = true;
-        /* HACK: Add a dummy timeout to break event loop */
-        timer = virEventAddTimeout(0, vshDeinitTimer, NULL, NULL);
-        virMutexUnlock(&ctl->lock);
-
-        virThreadJoin(&ctl->eventLoop);
-
-        if (timer != -1)
-            virEventRemoveTimeout(timer);
-
-        if (ctl->eventTimerId != -1)
-            virEventRemoveTimeout(ctl->eventTimerId);
-
-        ctl->eventLoopStarted = false;
-    }
-
-    virMutexDestroy(&ctl->lock);
-
-    return true;
-}
-
-/*
- * Print usage
- */
-static void
-vshUsage(void)
-{
-    const vshCmdGrp *grp;
-    const vshCmdDef *cmd;
-
-    fprintf(stdout, _("\n%s [options]... [<command_string>]"
-                      "\n%s [options]... <command> [args...]\n\n"
-                      "  options:\n"
-                      "    -c | --connect=URI      hypervisor connection URI\n"
-                      "    -d | --debug=NUM        debug level [0-4]\n"
-                      "    -e | --escape <char>    set escape sequence for console\n"
-                      "    -h | --help             this help\n"
-                      "    -k | --keepalive-interval=NUM\n"
-                      "                            keepalive interval in seconds, 0 for disable\n"
-                      "    -K | --keepalive-count=NUM\n"
-                      "                            number of possible missed keepalive messages\n"
-                      "    -l | --log=FILE         output logging to file\n"
-                      "    -q | --quiet            quiet mode\n"
-                      "    -r | --readonly         connect readonly\n"
-                      "    -t | --timing           print timing information\n"
-                      "    -v                      short version\n"
-                      "    -V                      long version\n"
-                      "         --version[=TYPE]   version, TYPE is short or long (default short)\n"
-                      "  commands (non interactive mode):\n\n"), progname, progname);
-
-    for (grp = cmdGroups; grp->name; grp++) {
-        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;
-            fprintf(stdout,
-                    "    %-30s %s\n", cmd->name,
-                    _(vshCmddefGetInfo(cmd, "help")));
-        }
-        fprintf(stdout, "\n");
-    }
-
-    fprintf(stdout, "%s",
-            _("\n  (specify help <group> for details about the commands in the group)\n"));
-    fprintf(stdout, "%s",
-            _("\n  (specify help <command> for details about the command)\n\n"));
-    return;
-}
-
-/*
- * 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/");
-
-    vshPrint(ctl, "%s", _("Compiled with support for:\n"));
-    vshPrint(ctl, "%s", _(" Hypervisors:"));
-#ifdef WITH_QEMU
-    vshPrint(ctl, " QEMU/KVM");
-#endif
-#ifdef WITH_LXC
-    vshPrint(ctl, " LXC");
-#endif
-#ifdef WITH_UML
-    vshPrint(ctl, " UML");
-#endif
-#ifdef WITH_XEN
-    vshPrint(ctl, " Xen");
-#endif
-#ifdef WITH_LIBXL
-    vshPrint(ctl, " LibXL");
-#endif
-#ifdef WITH_OPENVZ
-    vshPrint(ctl, " OpenVZ");
-#endif
-#ifdef WITH_VMWARE
-    vshPrint(ctl, " VMWare");
-#endif
-#ifdef WITH_PHYP
-    vshPrint(ctl, " PHYP");
-#endif
-#ifdef WITH_VBOX
-    vshPrint(ctl, " VirtualBox");
-#endif
-#ifdef WITH_ESX
-    vshPrint(ctl, " ESX");
-#endif
-#ifdef WITH_HYPERV
-    vshPrint(ctl, " Hyper-V");
-#endif
-#ifdef WITH_XENAPI
-    vshPrint(ctl, " XenAPI");
-#endif
-#ifdef WITH_BHYVE
-    vshPrint(ctl, " Bhyve");
-#endif
-#ifdef WITH_TEST
-    vshPrint(ctl, " Test");
-#endif
-    vshPrint(ctl, "\n");
-
-    vshPrint(ctl, "%s", _(" Networking:"));
-#ifdef WITH_REMOTE
-    vshPrint(ctl, " Remote");
-#endif
-#ifdef WITH_NETWORK
-    vshPrint(ctl, " Network");
-#endif
-#ifdef WITH_BRIDGE
-    vshPrint(ctl, " Bridging");
-#endif
-#if defined(WITH_INTERFACE)
-    vshPrint(ctl, " Interface");
-# if defined(WITH_NETCF)
-    vshPrint(ctl, " netcf");
-# elif defined(WITH_UDEV)
-    vshPrint(ctl, " udev");
-# endif
-#endif
-#ifdef WITH_NWFILTER
-    vshPrint(ctl, " Nwfilter");
-#endif
-#ifdef WITH_VIRTUALPORT
-    vshPrint(ctl, " VirtualPort");
-#endif
-    vshPrint(ctl, "\n");
-
-    vshPrint(ctl, "%s", _(" Storage:"));
-#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");
-#endif
-#ifdef WITH_STORAGE_RBD
-    vshPrint(ctl, " RBD");
-#endif
-#ifdef WITH_STORAGE_SHEEPDOG
-    vshPrint(ctl, " Sheepdog");
-#endif
-#ifdef WITH_STORAGE_GLUSTER
-    vshPrint(ctl, " Gluster");
-#endif
-    vshPrint(ctl, "\n");
-
-    vshPrint(ctl, "%s", _(" Miscellaneous:"));
-#ifdef WITH_LIBVIRTD
-    vshPrint(ctl, " Daemon");
-#endif
-#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
-#if WITH_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]
- *
- */
-static bool
-vshParseArgv(vshControl *ctl, int argc, char **argv)
-{
-    int arg, len, debug, keepalive;
-    size_t i;
-    int longindex = -1;
-    struct option opt[] = {
-        {"connect", required_argument, NULL, 'c'},
-        {"debug", required_argument, NULL, 'd'},
-        {"escape", required_argument, NULL, 'e'},
-        {"help", no_argument, NULL, 'h'},
-        {"keepalive-interval", required_argument, NULL, 'k'},
-        {"keepalive-count", required_argument, NULL, 'K'},
-        {"log", required_argument, NULL, 'l'},
-        {"quiet", no_argument, NULL, 'q'},
-        {"readonly", no_argument, NULL, 'r'},
-        {"timing", no_argument, NULL, 't'},
-        {"version", optional_argument, NULL, 'v'},
-        {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. */
-    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
-        switch (arg) {
-        case 'c':
-            VIR_FREE(ctl->name);
-            ctl->name = vshStrdup(ctl, optarg);
-            break;
-        case 'd':
-            if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) {
-                vshError(ctl, _("option %s takes a numeric argument"),
-                         longindex == -1 ? "-d" : "--debug");
-                exit(EXIT_FAILURE);
-            }
-            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;
-            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;
-        case 'h':
-            vshUsage();
-            exit(EXIT_SUCCESS);
-            break;
-        case 'k':
-            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) {
-                vshError(ctl,
-                         _("Invalid value for option %s"),
-                         longindex == -1 ? "-k" : "--keepalive-interval");
-                exit(EXIT_FAILURE);
-            }
-
-            if (keepalive < 0) {
-                vshError(ctl,
-                         _("option %s requires a positive integer argument"),
-                         longindex == -1 ? "-k" : "--keepalive-interval");
-                exit(EXIT_FAILURE);
-            }
-            ctl->keepalive_interval = keepalive;
-            break;
-        case 'K':
-            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0) {
-                vshError(ctl,
-                         _("Invalid value for option %s"),
-                         longindex == -1 ? "-K" : "--keepalive-count");
-                exit(EXIT_FAILURE);
-            }
-
-            if (keepalive < 0) {
-                vshError(ctl,
-                         _("option %s requires a positive integer argument"),
-                         longindex == -1 ? "-K" : "--keepalive-count");
-                exit(EXIT_FAILURE);
-            }
-            ctl->keepalive_count = keepalive;
-            break;
-        case 'l':
-            vshCloseLogFile(ctl);
-            ctl->logfile = vshStrdup(ctl, optarg);
-            vshOpenLogFile(ctl);
-            break;
-        case 'q':
-            ctl->quiet = true;
-            break;
-        case 't':
-            ctl->timing = true;
-            break;
-        case 'r':
-            ctl->readonly = true;
-            break;
-        case 'v':
-            if (STRNEQ_NULLABLE(optarg, "long")) {
-                puts(VERSION);
-                exit(EXIT_SUCCESS);
-            }
-            /* fall through */
-        case 'V':
-            vshShowVersion(ctl);
-            exit(EXIT_SUCCESS);
-        case ':':
-            for (i = 0; opt[i].name != NULL; i++) {
-                if (opt[i].val == optopt)
-                    break;
-            }
-            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);
-        case '?':
-            if (optopt)
-                vshError(ctl, _("unsupported option '-%c'. See --help."), optopt);
-            else
-                vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]);
-            exit(EXIT_FAILURE);
-        default:
-            vshError(ctl, _("unknown option"));
-            exit(EXIT_FAILURE);
-        }
-        longindex = -1;
-    }
-
-    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[] = {
-    {.name = "cd",
-     .handler = cmdCd,
-     .opts = opts_cd,
-     .info = info_cd,
-     .flags = VSH_CMD_FLAG_NOCONNECT
-    },
-    {.name = "connect",
-     .handler = cmdConnect,
-     .opts = opts_connect,
-     .info = info_connect,
-     .flags = VSH_CMD_FLAG_NOCONNECT
-    },
-    {.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}
-};
-
-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}
-};
-
-int
-main(int argc, char **argv)
-{
-    vshControl _ctl, *ctl = &_ctl;
-    const char *defaultConn;
-    bool ret = true;
-
-    memset(ctl, 0, sizeof(vshControl));
-    ctl->imode = true;          /* default is interactive mode */
-    ctl->log_fd = -1;           /* Initialize log file descriptor */
-    ctl->debug = VSH_DEBUG_DEFAULT;
-    ctl->escapeChar = "^]";     /* Same default as telnet */
-
-    /* In order to distinguish default from setting to 0 */
-    ctl->keepalive_interval = -1;
-    ctl->keepalive_count = -1;
-
-    ctl->eventPipe[0] = -1;
-    ctl->eventPipe[1] = -1;
-    ctl->eventTimerId = -1;
-
-    if (!setlocale(LC_ALL, "")) {
-        perror("setlocale");
-        /* failure to setup locale is not fatal */
-    }
-    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
-        perror("bindtextdomain");
-        return EXIT_FAILURE;
-    }
-    if (!textdomain(PACKAGE)) {
-        perror("textdomain");
-        return EXIT_FAILURE;
-    }
-
-    if (isatty(STDIN_FILENO)) {
-        ctl->istty = true;
-
-#ifndef WIN32
-        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
-            ctl->istty = false;
-#endif
-    }
-
-    if (virMutexInit(&ctl->lock) < 0) {
-        vshError(ctl, "%s", _("Failed to initialize mutex"));
-        return EXIT_FAILURE;
-    }
-
-    if (virInitialize() < 0) {
-        vshError(ctl, "%s", _("Failed to initialize libvirt"));
-        return EXIT_FAILURE;
-    }
-
-    virFileActivateDirOverride(argv[0]);
-
-    if (!(progname = strrchr(argv[0], '/')))
-        progname = argv[0];
-    else
-        progname++;
-
-    if ((defaultConn = virGetEnvBlockSUID("VIRSH_DEFAULT_CONNECT_URI")))
-        ctl->name = vshStrdup(ctl, defaultConn);
-
-    vshInitDebug(ctl);
-
-    if (!vshParseArgv(ctl, argc, argv) ||
-        !vshInit(ctl)) {
-        vshDeinit(ctl);
-        exit(EXIT_FAILURE);
-    }
-
-    if (!ctl->imode) {
-        ret = vshCommandRun(ctl, ctl->cmd);
-    } else {
-        /* interactive mode */
-        if (!ctl->quiet) {
-            vshPrint(ctl,
-                     _("Welcome to %s, the virtualization interactive terminal.\n\n"),
-                     progname);
-            vshPrint(ctl, "%s",
-                     _("Type:  'help' for help with commands\n"
-                       "       'quit' to quit\n\n"));
-        }
-
-        if (vshReadlineInit(ctl) < 0) {
-            vshDeinit(ctl);
-            exit(EXIT_FAILURE);
-        }
-
-        do {
-            const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
-            ctl->cmdstr =
-                vshReadline(ctl, prompt);
-            if (ctl->cmdstr == NULL)
-                break;          /* EOF */
-            if (*ctl->cmdstr) {
-#if WITH_READLINE
-                add_history(ctl->cmdstr);
-#endif
-                if (vshCommandStringParse(ctl, ctl->cmdstr))
-                    vshCommandRun(ctl, ctl->cmd);
-            }
-            VIR_FREE(ctl->cmdstr);
-        } while (ctl->imode);
-
-        if (ctl->cmdstr == NULL)
-            fputc('\n', stdout);        /* line break after alone prompt */
-    }
-
-    vshDeinit(ctl);
-    exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
-}
diff --git a/tools/vsh.h b/tools/vsh.h
index 345eb99..4b99b65 100644
--- a/tools/vsh.h
+++ b/tools/vsh.h
@@ -37,11 +37,6 @@
 # include "virerror.h"
 # include "virthread.h"
 
-# define VSH_MAX_XML_FILE (10*1024*1024)
-
-# define VSH_PROMPT_RW    "virsh # "
-# define VSH_PROMPT_RO    "virsh > "
-
 # define VIR_FROM_THIS VIR_FROM_NONE
 
 # define GETTIMEOFDAY(T) gettimeofday(T, NULL)
@@ -52,7 +47,6 @@
  * The log configuration
  */
 # define MSG_BUFFER    4096
-# define SIGN_NAME     "virsh"
 # define DIR_MODE      (S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)  /* 0755 */
 # define FILE_MODE     (S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH)                                /* 0644 */
 # define LOCK_MODE     (S_IWUSR | S_IRUSR)                                                    /* 0600 */
@@ -110,22 +104,6 @@ typedef enum {
 } vshCmdOptType;
 
 /*
- * Command group types
- */
-# define VSH_CMD_GRP_DOM_MANAGEMENT   "Domain Management"
-# define VSH_CMD_GRP_DOM_MONITORING   "Domain Monitoring"
-# define VSH_CMD_GRP_STORAGE_POOL     "Storage Pool"
-# define VSH_CMD_GRP_STORAGE_VOL      "Storage Volume"
-# define VSH_CMD_GRP_NETWORK          "Networking"
-# define VSH_CMD_GRP_NODEDEV          "Node Device"
-# define VSH_CMD_GRP_IFACE            "Interface"
-# define VSH_CMD_GRP_NWFILTER         "Network Filter"
-# define VSH_CMD_GRP_SECRET           "Secret"
-# define VSH_CMD_GRP_SNAPSHOT         "Snapshot"
-# define VSH_CMD_GRP_HOST_AND_HV      "Host and Hypervisor"
-# define VSH_CMD_GRP_VIRSH            "Virsh itself"
-
-/*
  * Command Option Flags
  */
 enum {
@@ -143,7 +121,6 @@ typedef struct _vshCmdInfo vshCmdInfo;
 typedef struct _vshCmdOpt vshCmdOpt;
 typedef struct _vshCmdOptDef vshCmdOptDef;
 typedef struct _vshControl vshControl;
-typedef struct _vshCtrlData vshCtrlData;
 
 typedef char **(*vshCompleter)(unsigned int flags);
 
@@ -217,26 +194,16 @@ struct _vshCmd {
  */
 struct _vshControl {
     char *name;                 /* connection name */
-    virConnectPtr conn;         /* connection to hypervisor (MAY BE NULL) */
     vshCmd *cmd;                /* the current command */
     char *cmdstr;               /* string with command */
     bool imode;                 /* interactive mode? */
     bool quiet;                 /* quiet mode */
-    int debug;                  /* print debug messages? */
     bool timing;                /* print timing info? */
-    bool readonly;              /* connect readonly (first time only, not
-                                 * during explicit connect command)
-                                 */
+    int debug;                  /* print debug messages? */
     char *logfile;              /* log file name */
     int log_fd;                 /* log file descriptor */
     char *historydir;           /* readline history directory name */
     char *historyfile;          /* readline history file name */
-    bool useGetInfo;            /* must use virDomainGetInfo, since
-                                   virDomainGetState is not supported */
-    bool useSnapshotOld;        /* cannot use virDomainSnapshotGetParent or
-                                   virDomainSnapshotNumChildren */
-    bool blockJobNoBytes;       /* true if _BANDWIDTH_BYTE blockjob flags
-                                   are missing */
     virThread eventLoop;
     virMutex lock;
     bool eventLoopStarted;
@@ -245,9 +212,6 @@ struct _vshControl {
                                  * event to occur */
     int eventTimerId;           /* id of event loop timeout registration */
 
-    const char *escapeChar;     /* String representation of
-                                   console escape character */
-
     int keepalive_interval;     /* Client keepalive interval */
     int keepalive_count;        /* Client keepalive count */
 
@@ -271,8 +235,6 @@ void vshOutputLogFile(vshControl *ctl, int log_level, const char *format,
     ATTRIBUTE_FMT_PRINTF(3, 0);
 void vshCloseLogFile(vshControl *ctl);
 
-virConnectPtr vshConnect(vshControl *ctl, const char *uri, bool readonly);
-
 const char *vshCmddefGetInfo(const vshCmdDef *cmd, const char *info);
 const vshCmdDef *vshCmddefSearch(const char *cmdname);
 bool vshCmddefHelp(vshControl *ctl, const char *name);
@@ -317,7 +279,6 @@ int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd,
 bool vshCommandOptBool(const vshCmd *cmd, const char *name);
 const vshCmdOpt *vshCommandOptArgv(vshControl *ctl, const vshCmd *cmd,
                                    const vshCmdOpt *opt);
-int vshCommandOptTimeoutToMs(vshControl *ctl, const vshCmd *cmd, int *timeout);
 
 /* Filter flags for various vshCommandOpt*By() functions */
 typedef enum {
@@ -327,12 +288,6 @@ typedef enum {
     VSH_BYMAC  = (1 << 4),
 } vshLookupByFlags;
 
-/* Given an index, return either the name of that device (non-NULL) or
- * of its parent (NULL if a root).  */
-typedef const char * (*vshTreeLookup)(int devid, bool parent, void *opaque);
-int vshTreePrint(vshControl *ctl, vshTreeLookup lookup, void *opaque,
-                 int num_devices, int devid);
-
 void vshPrintExtra(vshControl *ctl, const char *format, ...)
     ATTRIBUTE_FMT_PRINTF(2, 3);
 void vshDebug(vshControl *ctl, int level, const char *format, ...)
@@ -345,33 +300,14 @@ void vshDebug(vshControl *ctl, int level, const char *format, ...)
 # define vshStrcasecmp(S1, S2) strcasecmp(S1, S2)
 int vshNameSorter(const void *a, const void *b);
 
-int vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason);
 virTypedParameterPtr vshFindTypedParamByName(const char *name,
                                              virTypedParameterPtr list,
                                              int count);
 char *vshGetTypedParamValue(vshControl *ctl, virTypedParameterPtr item)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
-char *vshEditWriteToTempFile(vshControl *ctl, const char *doc);
-int vshEditFile(vshControl *ctl, const char *filename);
-char *vshEditReadBackFile(vshControl *ctl, const char *filename);
-int vshAskReedit(vshControl *ctl, const char *msg, bool relax_avail);
-int vshStreamSink(virStreamPtr st, const char *bytes, size_t nbytes,
-                  void *opaque);
-double vshPrettyCapacity(unsigned long long val, const char **unit);
 int vshStringToArray(const char *str, char ***array);
 
-/* Typedefs, function prototypes for job progress reporting.
- * There are used by some long lingering commands like
- * migrate, dump, save, managedsave.
- */
-struct _vshCtrlData {
-    vshControl *ctl;
-    const vshCmd *cmd;
-    int writefd;
-    virConnectPtr dconn;
-};
-
 /* error handling */
 extern virErrorPtr last_error;
 void vshReportError(vshControl *ctl);
-- 
1.9.3




More information about the libvir-list mailing list