void Log_Write(int level, const char *v, ...) { va_list ap; FILE *plogfile; char initialbuf[8192], *buf; int buflen; int needed; if (nolog) { return; } if (!GetRegInt("ExtendedLogging")) { return; } /* set no log so we don't cause a loop */ nolog = 1; buf = initialbuf; buflen = 8192; va_start(ap, v); needed = xmpp_vsnprintf(buf, buflen, v, ap); va_end(ap); if (needed > buflen) { buflen = needed + 1; buf = malloc(buflen); va_start(ap, v); xmpp_vsnprintf(buf, buflen, v, ap); va_end(ap); } Log_WriteString(level, buf); if (buf != initialbuf) { free(buf); } nolog = 0; }
/** Write a log message to the logger. * Write a log message to the logger for the context for the specified * level and area. This function takes a printf-style format string and a * variable argument list (in va_list) format. This function is not meant * to be called directly, but is used via xmpp_error, xmpp_warn, xmpp_info, * and xmpp_debug. * * @param ctx a Strophe context object * @param level the level at which to log * @param area the area to log for * @param fmt a printf-style format string for the message * @param ap variable argument list supplied for the format string */ void xmpp_log(const xmpp_ctx_t * const ctx, const xmpp_log_level_t level, const char * const area, const char * const fmt, va_list ap) { int oldret, ret; char smbuf[1024]; char *buf; va_list copy; va_copy(copy, ap); ret = xmpp_vsnprintf(smbuf, sizeof(smbuf), fmt, ap); if (ret >= (int)sizeof(smbuf)) { buf = (char *)xmpp_alloc(ctx, ret + 1); if (!buf) { buf = NULL; xmpp_error(ctx, "log", "Failed allocating memory for log message."); va_end(copy); return; } oldret = ret; ret = xmpp_vsnprintf(buf, ret + 1, fmt, copy); if (ret > oldret) { xmpp_error(ctx, "log", "Unexpected error"); xmpp_free(ctx, buf); va_end(copy); return; } } else { buf = smbuf; } va_end(copy); if (ctx->log->handler) ctx->log->handler(ctx->log->userdata, level, area, buf); if (buf != smbuf) xmpp_free(ctx, buf); }
/** Send a raw string to the XMPP server. * This function is a convenience function to send raw string data to the * XMPP server. It is used by Strophe to send short messages instead of * building up an XML stanza with DOM methods. This should be used with care * as it does not validate the data; invalid data may result in immediate * stream termination by the XMPP server. * * @param conn a Strophe connection object * @param fmt a printf-style format string followed by a variable list of * arguments to format */ void xmpp_send_raw_string(xmpp_conn_t * const conn, const char * const fmt, ...) { va_list ap; size_t len; char buf[1024]; /* small buffer for common case */ char *bigbuf; va_start(ap, fmt); len = xmpp_vsnprintf(buf, 1024, fmt, ap); va_end(ap); if (len >= 1024) { /* we need more space for this data, so we allocate a big * enough buffer and print to that */ len++; /* account for trailing \0 */ bigbuf = xmpp_alloc(conn->ctx, len); if (!bigbuf) { xmpp_debug(conn->ctx, "xmpp", "Could not allocate memory for send_raw_string"); return; } va_start(ap, fmt); xmpp_vsnprintf(bigbuf, len, fmt, ap); va_end(ap); xmpp_debug(conn->ctx, "conn", "SENT: %s", bigbuf); /* len - 1 so we don't send trailing \0 */ xmpp_send_raw(conn, bigbuf, len - 1); xmpp_free(conn->ctx, bigbuf); } else { xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); xmpp_send_raw(conn, buf, len); } }