void server_generic_log_client(server_generic_client_t *cnx, prelude_log_t priority, const char *fmt, ...) { va_list ap; int ret = 0; prelude_string_t *out; char addr[128] = { 0 }; prelude_string_new(&out); if ( ((struct sockaddr *) &cnx->sa)->sa_family == AF_UNIX ) snprintf(addr, sizeof(addr), "unix"); else { void *in_addr; const char *str; unsigned int port; #ifdef HAVE_IPV6 port = ntohs(cnx->sa.sin6_port); #else port = ntohs(cnx->sa.sin_port); #endif in_addr = prelude_sockaddr_get_inaddr((struct sockaddr *) &cnx->sa); if ( ! in_addr ) goto out; str = inet_ntop(((struct sockaddr *)&cnx->sa)->sa_family, in_addr, addr, sizeof(addr)); if ( str ) snprintf(addr + strlen(addr), sizeof(addr) - strlen(addr), ":%u", port); } if ( cnx->ident && cnx->permission ) { ret = prelude_string_sprintf(out, " 0x%" PRELUDE_PRIx64, cnx->ident); if ( ret < 0 ) goto out; ret = prelude_connection_permission_to_string(cnx->permission, out); } ret = prelude_string_sprintf(out, "]: "); if ( ret < 0 ) goto out; va_start(ap, fmt); ret = prelude_string_vprintf(out, fmt, ap); va_end(ap); prelude_log(priority, "[%s%s", addr, prelude_string_get_string(out)); out: prelude_string_destroy(out); }
/** * prelude_string_sprintf: * @string: Pointer to a #prelude_string_t object. * @fmt: Format string to use. * @...: Variable argument list. * * Produce output according to @fmt, and write output to the given * @string. See snprintf(3) to learn more about @fmt format. * * Returns: The number of characters written, or a negative value if an error occured. */ int prelude_string_sprintf(prelude_string_t *string, const char *fmt, ...) { int ret; va_list ap; prelude_return_val_if_fail(string, prelude_error(PRELUDE_ERROR_ASSERTION)); prelude_return_val_if_fail(fmt, prelude_error(PRELUDE_ERROR_ASSERTION)); va_start(ap, fmt); ret = prelude_string_vprintf(string, fmt, ap); va_end(ap); return ret; }
/** * prelude_string_vprintf: * @string: Pointer to a #prelude_string_t object. * @fmt: Format string to use. * @ap: Variable argument list. * * Produce output according to @fmt, storing argument provided in @ap * variable argument list, and write the output to the given @string. * See sprintf(3) for more information on @fmt format. * * Returns: The number of characters written, or a negative value if an error occured. */ int prelude_string_vprintf(prelude_string_t *string, const char *fmt, va_list ap) { int ret; va_list bkp; prelude_return_val_if_fail(string, prelude_error(PRELUDE_ERROR_ASSERTION)); prelude_return_val_if_fail(fmt, prelude_error(PRELUDE_ERROR_ASSERTION)); if ( ! (string->flags & PRELUDE_STRING_OWN_DATA) ) { ret = allocate_more_chunk_if_needed(string, 0); if ( ret < 0 ) return ret; } PRELUDE_VA_COPY(bkp, ap); ret = vsnprintf(string->data.rwbuf + string->index, string->size - string->index, fmt, ap); /* * From sprintf(3) on GNU/Linux: * * snprintf and vsnprintf do not write more than * size bytes (including the trailing '\0'), and return -1 if * the output was truncated due to this limit. (Thus until * glibc 2.0.6. Since glibc 2.1 these functions follow the * C99 standard and return the number of characters (exclud- * ing the trailing '\0') which would have been written to * the final string if enough space had been available.) */ if ( ret >= 0 && (size_t) ret < string->size - string->index ) { string->index += ret; goto end; } ret = allocate_more_chunk_if_needed(string, (ret < 0) ? 0 : ret + 1); if ( ret < 0 ) goto end; ret = prelude_string_vprintf(string, fmt, bkp); end: va_end(bkp); return ret; }
static void send_error(prelude_msgbuf_t *msgbuf, const char *fmt, ...) { int ret; va_list ap; prelude_string_t *out; va_start(ap, fmt); ret = prelude_string_new(&out); if ( ret < 0 ) return; prelude_string_vprintf(out, fmt, ap); va_end(ap); send_string(msgbuf, out, PRELUDE_MSG_OPTION_ERROR); prelude_string_destroy(out); }