[libvirt] [virsh] [PATCH BZ#732364] please add a .virsh/rc file

Feniks Gordon Freeman feniksa at rambler.ru
Mon Feb 27 13:55:47 UTC 2012


Hi, libvirt developers

I found very interesting libvirt and i wrote patch for BZ#732264
I added support for parsing ~/.virsh/rc file.
rc file in format KEY = VALUE
symbol '#' - comment
Now, only one value added for parsing - VIRSH_DEFAULT_CONNECT_URI.
This value can be overwrite by env variable VIRSH_DEFAULT_CONNECT_URI.

Thanks

P.S. How to add patch file? As attached file or in mail body?
P.P.S. I am using irc, my nick - fenksa

---
diff --git a/tools/virsh.c b/tools/virsh.c
index e712e53..8360c57 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -33,6 +33,7 @@
 #include <signal.h>
 #include <poll.h>
 #include <strings.h>
+#include <pwd.h>

 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -19313,6 +19314,132 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
     return true;
 }

+#define DEFAULT_RC_FILENAME ".virsh/rc"
+
+static const char*
+vshRcPath(vshControl* ctl) {
+    const char* home;
+    char* path;
+
+    home = virGetUserDirectory(getuid());
+    path = vshMalloc(ctl, strlen(home) + strlen(DEFAULT_RC_FILENAME) + 2);
+
+    memcpy(path, home, strlen(home));
+    path[strlen(home)] = '/';
+    memcpy(path + strlen(home) + 1, DEFAULT_RC_FILENAME,
strlen(DEFAULT_RC_FILENAME));
+
+    VIR_FREE(home);
+
+    return path;
+}
+
+typedef struct {
+    char* buf;
+    int len;
+    int p;
+} RcParseBuffer;
+
+static void
+vshClearRcParseBuffer(RcParseBuffer* buf) {
+    buf->p = 0;
+    bzero(buf->buf, buf->len);
+}
+
+static void
+vshInitRcParseBuffer(vshControl* ctl, RcParseBuffer* buf, int len) {
+    buf->buf = vshMalloc(ctl, len);
+    buf->len = len;
+    vshClearRcParseBuffer(buf);
+};
+
+static void
+vshAddCharRcParseBuffer(RcParseBuffer* buf, char ch) {
+    if (buf->p < buf->len) {
+        buf->buf[buf->p] = ch;
+        buf->p = buf->p + 1;
+    }
+}
+
+static void
+vshParseRc(vshControl *ctl)
+{
+    int fd;
+    const char* fileName = vshRcPath(ctl);
+    bool parseValue = false;
+
+    RcParseBuffer keyBuffer;
+    RcParseBuffer valueBuffer;
+    char buffer[1024];
+
+    vshInitRcParseBuffer(ctl, &keyBuffer, 255);
+    vshInitRcParseBuffer(ctl, &valueBuffer, 255);
+
+    /* open ~/.virsh/rc file */
+    if ((fd = open(fileName, O_RDONLY)) <= 0) {
+        vshDebug(ctl, VSH_ERR_INFO, "can't open file %s\n", fileName);
+        goto cleanup;
+    }
+
+    struct stat statBuf;
+    if (fstat(fd, &statBuf) == -1) {
+        vshDebug(ctl, VSH_ERR_INFO, "file %s not stated\n", fileName);
+        goto cleanup;
+    }
+
+    if (!S_ISREG(statBuf.st_mode)) {
+        vshError(ctl, _("file %s is not regular\n"), fileName);
+        goto cleanup;
+    }
+
+    int bytesRead;
+    while ((bytesRead = read(fd, buffer, sizeof(buffer))) > 0) {
+        for (int i = 0; i < bytesRead; i++) {
+            /* ignore empty spaces and comments */
+            if (buffer[i] == ' ' || buffer[i] == '#') {
+                           continue;
+            }
+
+            /* found separator = */
+            if (buffer[i] == '=') {
+                if (!parseValue) {
+                    parseValue = true;
+                    continue;
+                }
+            }
+
+            /* end of line*/
+            if (buffer[i] == '\n') {
+                if (STREQ(keyBuffer.buf, "VIRSH_DEFAULT_CONNECT_URI")) {
+                    ctl->name = vshStrdup(ctl, valueBuffer.buf);
+                }
+
+                vshClearRcParseBuffer(&keyBuffer);
+                vshClearRcParseBuffer(&valueBuffer);
+
+                parseValue = false;
+                continue;
+            }
+
+            if (parseValue) {
+                vshAddCharRcParseBuffer(&valueBuffer, buffer[i]);
+            } else {
+                vshAddCharRcParseBuffer(&keyBuffer, buffer[i]);
+            }
+        }
+    }
+
+cleanup:
+    if (fd >= 0) {
+        if (close(fd) < 0) {
+            vshError(ctl, _("cannot close file %s"), fileName);
+        }
+    }
+    VIR_FREE(fileName);
+    VIR_FREE(keyBuffer.buf);
+    VIR_FREE(valueBuffer.buf);
+}
+
+
 int
 main(int argc, char **argv)
 {
@@ -19355,6 +19482,8 @@ main(int argc, char **argv)
     else
         progname++;

+    vshParseRc(ctl);
+
     if ((defaultConn = getenv("VIRSH_DEFAULT_CONNECT_URI"))) {
         ctl->name = vshStrdup(ctl, defaultConn);
     }


-- 
With best wishes, Maxim Sditanov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tools_virsh.c.patch
Type: application/octet-stream
Size: 3860 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120227/8cf6b0fe/attachment-0001.obj>


More information about the libvir-list mailing list