Example #1
0
static int
virLogOnceInit(void)
{
    const char *pbm = NULL;

    if (virMutexInit(&virLogMutex) < 0)
        return -1;

    virLogLock();
    if (VIR_ALLOC_N_QUIET(virLogBuffer, virLogSize + 1) < 0) {
        /*
         * The debug buffer is not a critical component, allow startup
         * even in case of failure to allocate it in case of a
         * configuration mistake.
         */
        virLogSize = 64 * 1024;
        if (VIR_ALLOC_N_QUIET(virLogBuffer, virLogSize + 1) < 0) {
            pbm = "Failed to allocate debug buffer: deactivating debug log\n";
            virLogSize = 0;
        } else {
            pbm = "Failed to allocate debug buffer: reduced to 64 kB\n";
        }
    }
    virLogLen = 0;
    virLogStart = 0;
    virLogEnd = 0;
    virLogDefaultPriority = VIR_LOG_DEFAULT;

    if (VIR_ALLOC_QUIET(virLogRegex) >= 0) {
        if (regcomp(virLogRegex, VIR_LOG_REGEX, REG_EXTENDED) != 0)
            VIR_FREE(virLogRegex);
    }

    virLogUnlock();
    if (pbm)
        VIR_WARN("%s", pbm);
    return 0;
}
Example #2
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.  Auto indentation may be applied.
 */
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 (*str && !strpbrk(str, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~")) {
        virBufferAdd(buf, str, -1);
        return;
    }

    if (*str) {
        len = strlen(str);
        if (xalloc_oversized(4, len) ||
            VIR_ALLOC_N_QUIET(escaped, 4 * len + 3) < 0) {
            virBufferSetError(buf, errno);
            return;
        }
    } else {
        virBufferAddLit(buf, "''");
        return;
    }

    cur = str;
    out = escaped;

    *out++ = '\'';
    while (*cur != 0) {
        if (*cur == '\'') {
            *out++ = '\'';
            /* Replace literal ' with a close ', a \', and a open ' */
            *out++ = '\\';
            *out++ = '\'';
        }
        *out++ = *cur++;
    }
    *out++ = '\'';
    *out = 0;

    virBufferAdd(buf, escaped, -1);
    VIR_FREE(escaped);
}
Example #3
0
/**
 * virLogSetBufferSize:
 * @size: size of the buffer in kilobytes or <= 0 to deactivate
 *
 * Dynamically set the size or deactivate the logging buffer used to keep
 * a trace of all recent debug output. Note that the content of the buffer
 * is lost if it gets reallocated.
 *
 * Return -1 in case of failure or 0 in case of success
 */
int
virLogSetBufferSize(int size)
{
    int ret = 0;
    int oldsize;
    char *oldLogBuffer;
    const char *pbm = NULL;

    if (size < 0)
        size = 0;

    if (virLogInitialize() < 0)
        return -1;

    if (size * 1024 == virLogSize)
        return ret;

    virLogLock();

    oldsize = virLogSize;
    oldLogBuffer = virLogBuffer;

    if (INT_MAX / 1024 <= size) {
        pbm = "Requested log size of %d kB too large\n";
        ret = -1;
        goto error;
    }

    virLogSize = size * 1024;
    if (VIR_ALLOC_N_QUIET(virLogBuffer, virLogSize + 1) < 0) {
        pbm = "Failed to allocate debug buffer of %d kB\n";
        virLogBuffer = oldLogBuffer;
        virLogSize = oldsize;
        ret = -1;
        goto error;
    }
    VIR_FREE(oldLogBuffer);
    virLogLen = 0;
    virLogStart = 0;
    virLogEnd = 0;

error:
    virLogUnlock();
    if (pbm)
        VIR_ERROR(pbm, size);
    return ret;
}
Example #4
0
/**
 * virBufferEscape:
 * @buf: the buffer to append to
 * @escape: the escape character to inject
 * @toescape: NUL-terminated list of characters to escape
 * @format: a printf like format string but with only one %s parameter
 * @str: the string argument which needs to be escaped
 *
 * Do a formatted print with a single string to a buffer.  Any characters
 * in the provided list that are contained in @str are escaped with the
 * given escape.  Escaping is not applied to characters specified in @format.
 * Auto indentation may be applied.
 */
void
virBufferEscape(virBufferPtr buf, char escape, const char *toescape,
                const char *format, const char *str)
{
    int len;
    char *escaped, *out;
    const char *cur;

    if ((format == NULL) || (buf == NULL) || (str == NULL))
        return;

    if (buf->error)
        return;

    len = strlen(str);
    if (strcspn(str, toescape) == len) {
        virBufferAsprintf(buf, format, str);
        return;
    }

    if (xalloc_oversized(2, len) ||
        VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
        virBufferSetError(buf, errno);
        return;
    }

    cur = str;
    out = escaped;
    while (*cur != 0) {
        if (strchr(toescape, *cur))
            *out++ = escape;
        *out++ = *cur;
        cur++;
    }
    *out = 0;

    virBufferAsprintf(buf, format, escaped);
    VIR_FREE(escaped);
}
Example #5
0
/**
 * virBitmapNewQuiet:
 * @size: number of bits
 *
 * Allocate a bitmap capable of containing @size bits.
 *
 * Returns a pointer to the allocated bitmap or NULL if memory cannot be
 * allocated. Does not report libvirt errors.
 */
virBitmapPtr
virBitmapNewQuiet(size_t size)
{
    virBitmapPtr bitmap;
    size_t sz;

    if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size || size == 0)
        return NULL;

    sz = VIR_DIV_UP(size, VIR_BITMAP_BITS_PER_UNIT);

    if (VIR_ALLOC_QUIET(bitmap) < 0)
        return NULL;

    if (VIR_ALLOC_N_QUIET(bitmap->map, sz) < 0) {
        VIR_FREE(bitmap);
        return NULL;
    }

    bitmap->max_bit = size;
    bitmap->map_len = sz;
    return bitmap;
}
Example #6
0
int main(int argc, char **argv) {
    size_t i, n;
    int open_max;
    char **origenv;
    char **newenv = NULL;
    char *cwd;
    FILE *log = fopen(abs_builddir "/commandhelper.log", "w");
    int ret = EXIT_FAILURE;

    if (!log)
        goto cleanup;

    for (i = 1; i < argc; i++)
        fprintf(log, "ARG:%s\n", argv[i]);

    origenv = environ;
    n = 0;
    while (*origenv != NULL) {
        n++;
        origenv++;
    }

    if (VIR_ALLOC_N_QUIET(newenv, n) < 0)
        goto cleanup;

    origenv = environ;
    n = i = 0;
    while (*origenv != NULL) {
        newenv[i++] = *origenv;
        n++;
        origenv++;
    }
    qsort(newenv, n, sizeof(newenv[0]), envsort);

    for (i = 0; i < n; i++) {
        /* Ignore the variables used to instruct the loader into
         * behaving differently, as they could throw the tests off. */
        if (!STRPREFIX(newenv[i], "LD_"))
            fprintf(log, "ENV:%s\n", newenv[i]);
    }

    open_max = sysconf(_SC_OPEN_MAX);
    if (open_max < 0)
        goto cleanup;
    for (i = 0; i < open_max; i++) {
        int f;
        int closed;
        if (i == fileno(log))
            continue;
        closed = fcntl(i, F_GETFD, &f) == -1 &&
            errno == EBADF;
        if (!closed)
            fprintf(log, "FD:%zu\n", i);
    }

    fprintf(log, "DAEMON:%s\n", getpgrp() == getsid(0) ? "yes" : "no");
    if (!(cwd = getcwd(NULL, 0)))
        goto cleanup;
    if (strlen(cwd) > strlen(".../commanddata") &&
        STREQ(cwd + strlen(cwd) - strlen("/commanddata"), "/commanddata"))
        strcpy(cwd, ".../commanddata");
    fprintf(log, "CWD:%s\n", cwd);
    VIR_FREE(cwd);

    fprintf(log, "UMASK:%04o\n", umask(0));

    if (argc > 1 && STREQ(argv[1], "--close-stdin")) {
        if (freopen("/dev/null", "r", stdin) != stdin)
            goto cleanup;
        usleep(100*1000);
    }

    char buf[1024];
    ssize_t got;

    fprintf(stdout, "BEGIN STDOUT\n");
    fflush(stdout);
    fprintf(stderr, "BEGIN STDERR\n");
    fflush(stderr);

    for (;;) {
        got = read(STDIN_FILENO, buf, sizeof(buf));
        if (got < 0)
            goto cleanup;
        if (got == 0)
            break;
        if (safewrite(STDOUT_FILENO, buf, got) != got)
            goto cleanup;
        if (safewrite(STDERR_FILENO, buf, got) != got)
            goto cleanup;
    }

    fprintf(stdout, "END STDOUT\n");
    fflush(stdout);
    fprintf(stderr, "END STDERR\n");
    fflush(stderr);

    ret = EXIT_SUCCESS;

 cleanup:
    VIR_FORCE_FCLOSE(log);
    VIR_FREE(newenv);
    return ret;
}
Example #7
0
/**
 * virBufferEscapeString:
 * @buf: the buffer to append to
 * @format: a printf like format string but with only one %s parameter
 * @str: the string argument which needs to be escaped
 *
 * Do a formatted print with a single string to an XML buffer. The
 * string is escaped for use in XML.  If @str is NULL, nothing is
 * added (not even the rest of @format).  Auto indentation may be
 * applied.
 */
void
virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
{
    int len;
    char *escaped, *out;
    const char *cur;
    const char forbidden_characters[] = {
        0x01,   0x02,   0x03,   0x04,   0x05,   0x06,   0x07,   0x08,
        /*\t*/  /*\n*/  0x0B,   0x0C,   /*\r*/  0x0E,   0x0F,   0x10,
        0x11,   0x12,   0x13,   0x14,   0x15,   0x16,   0x17,   0x18,
        0x19,   '"',    '&',    '\'',   '<',    '>',
        '\0'
    };

    if ((format == NULL) || (buf == NULL) || (str == NULL))
        return;

    if (buf->error)
        return;

    len = strlen(str);
    if (strcspn(str, forbidden_characters) == len) {
        virBufferAsprintf(buf, format, str);
        return;
    }

    if (xalloc_oversized(6, len) ||
        VIR_ALLOC_N_QUIET(escaped, 6 * len + 1) < 0) {
        virBufferSetError(buf, errno);
        return;
    }

    cur = str;
    out = escaped;
    while (*cur != 0) {
        if (*cur == '<') {
            *out++ = '&';
            *out++ = 'l';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '>') {
            *out++ = '&';
            *out++ = 'g';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '&') {
            *out++ = '&';
            *out++ = 'a';
            *out++ = 'm';
            *out++ = 'p';
            *out++ = ';';
        } else if (*cur == '"') {
            *out++ = '&';
            *out++ = 'q';
            *out++ = 'u';
            *out++ = 'o';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '\'') {
            *out++ = '&';
            *out++ = 'a';
            *out++ = 'p';
            *out++ = 'o';
            *out++ = 's';
            *out++ = ';';
        } else if (!strchr(forbidden_characters, *cur)) {
            /*
             * default case, just copy !
             * Note that character over 0x80 are likely to give problem
             * with UTF-8 XML, but since our string don't have an encoding
             * it's hard to handle properly we have to assume it's UTF-8 too
             */
            *out++ = *cur;
        } else {
            /* silently ignore control characters */
        }
        cur++;
    }
    *out = 0;

    virBufferAsprintf(buf, format, escaped);
    VIR_FREE(escaped);
}
Example #8
0
/**
 * virBufferEscapeString:
 * @buf: the buffer to append to
 * @format: a printf like format string but with only one %s parameter
 * @str: the string argument which needs to be escaped
 *
 * Do a formatted print with a single string to an XML buffer. The
 * string is escaped for use in XML.  If @str is NULL, nothing is
 * added (not even the rest of @format).  Auto indentation may be
 * applied.
 */
void
virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
{
    int len;
    char *escaped, *out;
    const char *cur;

    if ((format == NULL) || (buf == NULL) || (str == NULL))
        return;

    if (buf->error)
        return;

    len = strlen(str);
    if (strcspn(str, "<>&'\"") == len) {
        virBufferAsprintf(buf, format, str);
        return;
    }

    if (xalloc_oversized(6, len) ||
        VIR_ALLOC_N_QUIET(escaped, 6 * len + 1) < 0) {
        virBufferSetError(buf, errno);
        return;
    }

    cur = str;
    out = escaped;
    while (*cur != 0) {
        if (*cur == '<') {
            *out++ = '&';
            *out++ = 'l';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '>') {
            *out++ = '&';
            *out++ = 'g';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '&') {
            *out++ = '&';
            *out++ = 'a';
            *out++ = 'm';
            *out++ = 'p';
            *out++ = ';';
        } else if (*cur == '"') {
            *out++ = '&';
            *out++ = 'q';
            *out++ = 'u';
            *out++ = 'o';
            *out++ = 't';
            *out++ = ';';
        } else if (*cur == '\'') {
            *out++ = '&';
            *out++ = 'a';
            *out++ = 'p';
            *out++ = 'o';
            *out++ = 's';
            *out++ = ';';
        } else if (((unsigned char)*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
                   (*cur == '\r')) {
            /*
             * default case, just copy !
             * Note that character over 0x80 are likely to give problem
             * with UTF-8 XML, but since our string don't have an encoding
             * it's hard to handle properly we have to assume it's UTF-8 too
             */
            *out++ = *cur;
        }
        cur++;
    }
    *out = 0;

    virBufferAsprintf(buf, format, escaped);
    VIR_FREE(escaped);
}