diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4f965185d8..189c5975fd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -27,6 +27,7 @@ virBufferContentAndReset; virBufferError; virBufferEscape; virBufferEscapeSexpr; +virBufferEscapeShell; virBufferEscapeString; virBufferFreeAndReset; virBufferStrcat; diff --git a/src/util/buf.c b/src/util/buf.c index fa12855a72..34347b5dd5 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -485,6 +485,60 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) buf->content[buf->use] = '\0'; } +/** + * virBufferEscapeShell: + * @buf: the buffer to append to + * @str: an unquoted string + * + * Quotes a string so that the shell (/bin/sh) will interpret the + * quoted string to mean str. + */ +void +virBufferEscapeShell(virBufferPtr buf, const char *str) +{ + int len; + char *escaped, *out; + const char *cur; + + if ((buf == NULL) || (str == NULL)) + return; + + if (buf->error) + return; + + /* Only quote if str includes shell metacharacters. */ + if (!strpbrk(str, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~")) { + virBufferAdd(buf, str, -1); + return; + } + + len = strlen(str); + if (xalloc_oversized(4, len) || + VIR_ALLOC_N(escaped, 4 * len + 3) < 0) { + virBufferSetError(buf); + return; + } + + cur = str; + out = escaped; + + *out++ = '\''; + while (*cur != 0) { + *out++ = *cur++; + if (*cur == '\'') { + /* Replace literal ' with a close ', a \', and a open ' */ + *out++ = '\\'; + *out++ = '\''; + *out++ = '\''; + } + } + *out++ = '\''; + *out = 0; + + virBufferAdd(buf, escaped, -1); + VIR_FREE(escaped); +} + /** * virBufferStrcat: * @buf: the buffer to dump diff --git a/src/util/buf.h b/src/util/buf.h index e545ed902d..1d0e790b61 100644 --- a/src/util/buf.h +++ b/src/util/buf.h @@ -52,6 +52,7 @@ void virBufferEscapeString(const virBufferPtr buf, const char *format, const cha void virBufferEscapeSexpr(const virBufferPtr buf, const char *format, const char *str); void virBufferEscape(const virBufferPtr buf, const char *toescape, const char *format, const char *str); void virBufferURIEncodeString (const virBufferPtr buf, const char *str); +void virBufferEscapeShell(virBufferPtr buf, const char *str); # define virBufferAddLit(buf_, literal_string_) \ virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)