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; }
/** * 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); }
/** * 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; }
/** * 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); }
/** * 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; }
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; }
/** * 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); }
/** * 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); }