head 1.9; access; symbols L2_0_9_13:1.9 FSL_1_7_0:1.9 L2_0_9_12:1.9 LMTP2NNTP_1_4_1:1.9 LMTP2NNTP_1_4_0:1.9 FSL_1_6_1:1.9 L2_0_9_11:1.9 FSL_1_6_0:1.8 FSL_1_6b2:1.8 L2_0_9_10:1.8 FSL_1_6b1:1.8 L2_0_9_9:1.8 LMTP2NNTP_1_3_0:1.7 LMTP2NNTP_1_3b2:1.7 LMTP2NNTP_1_3b1:1.7 LMTP2NNTP_1_3a3:1.7 FSL_1_5_0:1.7 LMTP2NNTP_1_3a2:1.7 FSL_1_5a3:1.7 LMTP2NNTP_1_3a1:1.7 FSL_1_5a2:1.7 L2_0_9_8:1.7 FSL_1_5a1:1.7 L2_0_9_7:1.7 L2_0_9_6:1.7 FSL_1_4_0:1.7 FSL_1_4b1:1.7 L2_0_9_5:1.7 FSL_1_4a1:1.7 FSL_1_3_0:1.7 FSL_1_3b1:1.7 L2_0_9_4:1.7 FSL_1_2_1:1.7 L2_0_9_3:1.7 FSL_1_2_0:1.7 L2_0_9_2:1.7 FSL_1_1_0:1.7 FSL_1_1b1:1.7 WORKOFF:1.7.0.2 WORKOFF_BP:1.7 FSL_1_0_8:1.7 LMTP2NNTP_1_2_0:1.7 LMTP2NNTP_1_2b4:1.7 LMTP2NNTP_1_2b3:1.7 LMTP2NNTP_1_2b2:1.7 LMTP2NNTP_1_2b1:1.7 LMTP2NNTP_1_2a8:1.7 LMTP2NNTP_1_2a7:1.7 FSL_1_0_7:1.7 FSL_1_0_6:1.6 FSL_1_0_5:1.6 FSL_1_0_4:1.6 L2_0_9_1:1.6 FSL_1_0_3:1.6 LMTP2NNTP_1_2a6:1.6 FSL_1_0_2:1.6 FSL_1_0_1:1.6 FSL_1_0_0:1.6 FSL_0_9_0:1.6 L2_0_9_0:1.6 FSL_0_1_12:1.5 FSL_0_1_11:1.5 FSL_0_1_10:1.5 FSL_0_1_9:1.5 FSL_0_1_8:1.5 FSL_0_1_7:1.5 FSL_0_1_6:1.5 FSL_0_1_5:1.5 FSL_0_1_1:1.5 LMTP2NNTP_1_2a5:1.4 LMTP2NNTP_1_2a4:1.4 LMTP2NNTP_1_2a3:1.4 LMTP2NNTP_1_2a1:1.3 LMTP2NNTP_1_1_1:1.3 LMTP2NNTP_1_1_0:1.3 LMTP2NNTP_1_1b4:1.3 LMTP2NNTP_1_1b3:1.3 L2_CHANNEL_ONLY_REVAMPING_BEFORE:1.3 LMTP2NNTP_1_1b2:1.3 LMTP2NNTP_1_1b1:1.3 L2_0_1_0:1.3; locks; strict; comment @ * @; 1.9 date 2005.10.03.08.08.11; author rse; state Exp; branches; next 1.8; 1.8 date 2005.01.24.15.03.18; author rse; state Exp; branches; next 1.7; 1.7 date 2003.01.06.11.41.52; author rse; state Exp; branches; next 1.6; 1.6 date 2002.07.30.19.08.25; author rse; state Exp; branches; next 1.5; 1.5 date 2002.07.17.11.19.30; author thl; state Exp; branches; next 1.4; 1.4 date 2002.01.02.17.07.38; author rse; state Exp; branches; next 1.3; 1.3 date 2001.09.07.14.49.08; author thl; state Exp; branches; next 1.2; 1.2 date 2001.09.06.14.37.53; author rse; state Exp; branches; next 1.1; 1.1 date 2001.09.06.11.56.15; author rse; state Exp; branches; next ; desc @@ 1.9 log @Adjust copyright messages for new year 2005. @ text @/* ** OSSP l2 - Flexible Logging ** Copyright (c) 2001-2005 Cable & Wireless ** Copyright (c) 2001-2005 The OSSP Project ** Copyright (c) 2001-2005 Ralf S. Engelschall ** ** This file is part of OSSP l2, a flexible logging library which ** can be found at http://www.ossp.org/pkg/lib/l2/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** l2_format.c: extra formatters */ #include #include "l2.h" #include l2_result_t l2_util_fmt_string( l2_context_t *ctx, const char id, const char *param, char *bufptr, size_t bufsize, size_t *buflen, va_list *ap) { char *cpStr; size_t nStr; cpStr = va_arg(*ap, char *); nStr = (size_t)va_arg(*ap, int); if (cpStr == NULL) return L2_ERR_ARG; if (nStr > bufsize) return L2_ERR_MEM; memcpy(bufptr, cpStr, nStr); *buflen = nStr; return L2_OK; } l2_result_t l2_util_fmt_dump( l2_context_t *ctx, const char id, const char *param, char *bufptr, size_t bufsize, size_t *buflen, va_list *ap) { static const char hex_table[] = "0123456789abcdef"; static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; unsigned char base64_in[3]; unsigned char base64_out[4]; size_t nData; unsigned char *ucpData; unsigned char uc; unsigned char *cpO; unsigned char *cpI; int i; int n; /* fetch data pointer and data size from argument list */ ucpData = va_arg(*ap, unsigned char *); nData = (size_t)va_arg(*ap, int); /* argument sanity check */ if (ucpData == NULL) return L2_ERR_ARG; /* * textual dumping: "foo\1bar" -> "foo\x01bar" */ if (strcmp(param, "text") == 0 || param[0] == '\0') { cpI = ucpData; cpO = (unsigned char *)bufptr; while (cpI < (ucpData+nData)) { uc = *cpI++; if (isprint((int)uc)) { if ((char *)cpO >= (bufptr+bufsize)) return L2_ERR_MEM; *cpO++ = uc; } else if (uc == '\\') { if ((char *)(cpO+1) >= (bufptr+bufsize)) return L2_ERR_MEM; *cpO++ = '\\'; *cpO++ = '\\'; } else if (uc == '\t' || uc == '\r' || uc == '\n') { if ((char *)(cpO+1) >= (bufptr+bufsize)) return L2_ERR_MEM; *cpO++ = '\\'; switch ((int)uc) { case '\t': *cpO++ = 't'; break; case '\r': *cpO++ = 'r'; break; case '\n': *cpO++ = 'n'; break; default: break; } } else { if ((char *)(cpO+3) >= (bufptr+bufsize)) return L2_ERR_MEM; *cpO++ = '\\'; *cpO++ = 'x'; *cpO++ = hex_table[(uc >> 4) & 0xf]; *cpO++ = hex_table[uc & 0xf]; } } *buflen = ((char *)cpO - bufptr); } /* * hexadecimal dumping: "foo\1bar" -> "66:6f:6f:01:62:61:72" */ else if (strcmp(param, "hex") == 0) { if (((nData * 3) - 1) > bufsize) return L2_ERR_MEM; cpO = (unsigned char *)bufptr; for (i = 0; i < nData; i++) { uc = *ucpData++; *cpO++ = hex_table[(uc >> 4) & 0xf]; *cpO++ = hex_table[uc & 0xf]; if (i < (nData - 1)) *cpO++ = ':'; } *buflen = (nData * 3) - 1; } /* * Base64 dumping: "foo\1bar" -> "Zm9vAWJhcg==" */ else if (strcmp(param, "base64") == 0) { /* bulk encoding */ n = 0; while (nData >= 3) { base64_in[0] = *ucpData++; base64_in[1] = *ucpData++; base64_in[2] = *ucpData++; nData -= 3; base64_out[0] = ( base64_in[0] >> 2); base64_out[1] = ((base64_in[0] & 0x03) << 4) + (base64_in[1] >> 4); base64_out[2] = ((base64_in[1] & 0x0f) << 2) + (base64_in[2] >> 6); base64_out[3] = ( base64_in[2] & 0x3f); if (n + 4 > bufsize) return L2_ERR_MEM; bufptr[n++] = base64_table[base64_out[0]]; bufptr[n++] = base64_table[base64_out[1]]; bufptr[n++] = base64_table[base64_out[2]]; bufptr[n++] = base64_table[base64_out[3]]; } /* now worry about padding with remaining 1 or 2 bytes */ if (nData != 0) { base64_in[0] = base64_in[1] = base64_in[2] = '\0'; for (i = 0; i < nData; i++) base64_in[i] = *ucpData++; base64_out[0] = ( base64_in[0] >> 2); base64_out[1] = ((base64_in[0] & 0x03) << 4) + (base64_in[1] >> 4); base64_out[2] = ((base64_in[1] & 0x0f) << 2) + (base64_in[2] >> 6); if (n + 4 > bufsize) return L2_ERR_MEM; bufptr[n++] = base64_table[base64_out[0]]; bufptr[n++] = base64_table[base64_out[1]]; if (nData == 1) bufptr[n++] = '='; else bufptr[n++] = base64_table[base64_out[2]]; bufptr[n++] = '='; } if (n >= bufsize) return L2_ERR_MEM; *buflen = n; } /* anything else is an unknown dumping method... */ else return L2_ERR_ARG; return L2_OK; } l2_result_t l2_util_fmt_errno( l2_context_t *ctx, const char id, const char *param, char *bufptr, size_t bufsize, size_t *buflen, va_list *ap) { sprintf(bufptr, "(%d) %s", errno, strerror(errno)); *buflen = strlen(bufptr); return L2_OK; } @ 1.8 log @Adjust copyright messages for new year 2005. @ text @d3 3 a5 3 ** Copyright (c) 2001-2004 Cable & Wireless ** Copyright (c) 2001-2004 The OSSP Project ** Copyright (c) 2001-2004 Ralf S. Engelschall @ 1.7 log @- remove trailing whitespaces - adjust copyright messages - consistently use "OSSP l2" - consistently talk about "Flexible Logging" - use standard OSSP ASCII-art @ text @d3 3 a5 3 ** Copyright (c) 2001-2003 Cable & Wireless Deutschland GmbH ** Copyright (c) 2001-2003 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001-2003 Ralf S. Engelschall @ 1.6 log @polish for release @ text @d2 4 a5 3 ** OSSP l2 - Logging Library ** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) d7 1 a7 1 ** This file is part of OSSP L2, a flexible logging library which d36 1 a36 1 l2_result_t d38 1 a38 1 l2_context_t *ctx, const char id, const char *param, d55 1 a55 1 l2_result_t d57 1 a57 1 l2_context_t *ctx, const char id, const char *param, d61 1 a61 1 static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" d82 1 a82 1 /* d106 3 a108 3 case '\t': *cpO++ = 't'; break; case '\r': *cpO++ = 'r'; break; case '\n': *cpO++ = 'n'; break; d124 1 a124 1 /* d193 1 a193 1 l2_result_t d197 2 a198 2 { sprintf(bufptr, "(%d) %s", errno, strerror(errno)); @ 1.5 log @added errno formatter from lmtp2nntp @ text @d2 1 a2 1 ** L2 - OSSP Logging Library d7 1 a7 1 ** can be found at http://www.ossp.org/pkg/l2/. @ 1.4 log @bump copyright year @ text @d33 1 d192 9 @ 1.3 log @better readable text dumping @ text @d3 2 a4 2 ** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/) @ 1.2 log @Replace generic L2_ERROR with more granular L2_ERR_XXX and make sure that we always check with "!= L2_OK". @ text @d99 11 @ 1.1 log @Add two cool extra formatter functions ;) l2_util_fmt_string: This can be used like %s, but instead of fetching only a "char *" from the var-args stack, it fetches a "char *" plus a "size_t" and this way allows one to log only a sub-string of a larger string without the need for any temporary buffers, etc. l2_util_fmt_dump: This can be used as "%{type}X" for dumping arbitrary octets. The parameter "type" can be either "text" (the default if only "%X" is used) for dumping the octets as text but with non-printable characters replaced by "\xXX" constructs; "hex" for dumping the octets in hexadecimal as "XX:XX:XX:XX" or "base64" for dumping the octets Base64 encoded. All three are intended for making it easier to produce reasonable L2_LEVEL_DEBUG messages without having to fiddle around with temporary buffers and having to care with non-printable characters. For instance, using... : l2_stream_formatter(st, 'D', l2_util_fmt_dump, NULL); : l2_stream_vlog(st, L2_LEVEL_DEBUG, "%{text}D %{hex}D %{base64}D\n", "foo", 12345, "foo\1bar", 7, "foo\1bar", 7, "foo\1bar", 7); : ...produces "foo\x01bar 66:6f:6f:01:62:61:72 Zm9vAWJhcg==" in the output. @ text @d44 2 d47 1 a47 1 return L2_ERROR; d76 4 d90 1 a90 1 return L2_ERROR; d95 1 a95 1 return L2_ERROR; d101 1 a101 1 return L2_ERROR; d116 1 a116 1 return L2_ERROR; d144 1 a144 1 return L2_ERROR; d159 1 a159 1 return L2_ERROR; d169 1 a169 1 return L2_ERROR; d175 1 a175 1 return L2_ERROR; @