Annotation of embedaddon/libpdel/ppp/ppp_log.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (c) 2001-2002 Packet Design, LLC.
                      4:  * All rights reserved.
                      5:  * 
                      6:  * Subject to the following obligations and disclaimer of warranty,
                      7:  * use and redistribution of this software, in source or object code
                      8:  * forms, with or without modifications are expressly permitted by
                      9:  * Packet Design; provided, however, that:
                     10:  * 
                     11:  *    (i)  Any and all reproductions of the source or object code
                     12:  *         must include the copyright notice above and the following
                     13:  *         disclaimer of warranties; and
                     14:  *    (ii) No rights are granted, in any manner or form, to use
                     15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
                     16:  *         on advertising, endorsements, or otherwise except as such
                     17:  *         appears in the above copyright notice or in the software.
                     18:  * 
                     19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     36:  * THE POSSIBILITY OF SUCH DAMAGE.
                     37:  *
                     38:  * Author: Archie Cobbs <archie@freebsd.org>
                     39:  */
                     40: 
                     41: #include "ppp/ppp_defs.h"
                     42: #include "ppp/ppp_log.h"
                     43: 
                     44: #define LOG_MTYPE      "ppp_log"
                     45: 
                     46: struct ppp_log {
                     47:        void                    *arg;
                     48:        u_int                   refs;
                     49:        ppp_log_vput_t          *vput;
                     50:        ppp_log_close_t         *close;
                     51: };
                     52: 
                     53: /*
                     54:  * Create a new log.
                     55:  */
                     56: struct ppp_log *
                     57: ppp_log_create(void *arg, ppp_log_vput_t *vput, ppp_log_close_t *close)
                     58: {
                     59:        struct ppp_log *log;
                     60: 
                     61:        if ((log = MALLOC(LOG_MTYPE, sizeof(*log))) == NULL)
                     62:                return (NULL);
                     63:        memset(log, 0, sizeof(*log));
                     64:        log->arg = arg;
                     65:        log->vput = vput;
                     66:        log->close = close;
                     67:        log->refs = 1;
                     68:        return (log);
                     69: }
                     70: 
                     71: struct ppp_log *
                     72: ppp_log_dup(struct ppp_log *log)
                     73: {
                     74:        if (log == NULL)
                     75:                return (NULL);
                     76:        log->refs++;
                     77:        return (log);
                     78: }
                     79: 
                     80: void
                     81: ppp_log_close(struct ppp_log **logp)
                     82: {
                     83:        struct ppp_log *const log = *logp;
                     84: 
                     85:        if (log == NULL)
                     86:                return;
                     87:        *logp = NULL;
                     88:        assert(log->refs > 0);
                     89:        if (--log->refs == 0) {
                     90:                if (log->close != NULL)
                     91:                        (*log->close)(log->arg);
                     92:                FREE(LOG_MTYPE, log);
                     93:        }
                     94: }
                     95: 
                     96: void
                     97: ppp_log_put(struct ppp_log *log, int sev, const char *fmt, ...)
                     98: {
                     99:        va_list args;
                    100: 
                    101:        if (log == NULL)
                    102:                return;
                    103:        va_start(args, fmt);
                    104:        ppp_log_vput(log, sev, fmt, args);
                    105:        va_end(args);
                    106: }
                    107: 
                    108: void
                    109: ppp_log_vput(struct ppp_log *log, int sev, const char *fmt, va_list args)
                    110: {
                    111:        int esave;
                    112: 
                    113:        if (log == NULL)
                    114:                return;
                    115:        esave = errno;
                    116:        (*log->vput)(log->arg, sev, fmt, args);
                    117:        errno = esave;
                    118: }
                    119: 
                    120: void
                    121: ppp_log_dump(struct ppp_log *log, int sev, const void *data, size_t len)
                    122: {
                    123:        static const int num = 16;              /* # bytes per line */
                    124:        const u_char *bytes = data;
                    125:        char buf[128];
                    126:        int i, j;
                    127: 
                    128:        /* Dump data */
                    129:        for (i = 0; i < ((len + num - 1) / num) * num; i += num) {
                    130:                snprintf(buf, sizeof(buf), "0x%04x  ", i);
                    131:                for (j = i; j < i + num; j++) {
                    132:                        if (j < len) {
                    133:                                snprintf(buf + strlen(buf),
                    134:                                    sizeof(buf) - strlen(buf),
                    135:                                    "%02x", bytes[j]);
                    136:                        } else {
                    137:                                snprintf(buf + strlen(buf),
                    138:                                    sizeof(buf) - strlen(buf), "  ");
                    139:                        }
                    140:                        if ((j % 2) == 1) {
                    141:                                snprintf(buf + strlen(buf),
                    142:                                    sizeof(buf) - strlen(buf), " ");
                    143:                        }
                    144:                }
                    145:                snprintf(buf + strlen(buf),
                    146:                    sizeof(buf) - strlen(buf), "       ");
                    147:                for (j = i; j < i + num; j++) {
                    148:                        if (j < len) {
                    149:                                snprintf(buf + strlen(buf),
                    150:                                    sizeof(buf) - strlen(buf), "%c",
                    151:                                    isprint(bytes[j]) ?  bytes[j] : '.');
                    152:                        }
                    153:                }
                    154:                ppp_log_put(log, sev, "%s", buf);
                    155:        }
                    156: }
                    157: 
                    158: /***********************************************************************
                    159:                        PREFIX LOG METHODS
                    160: ***********************************************************************/
                    161: 
                    162: struct ppp_log_prefix {
                    163:        struct ppp_log  *log;
                    164:        char            *prefix;
                    165: };
                    166: 
                    167: /* Internal functions */
                    168: static ppp_log_vput_t  ppp_log_prefix_vput;
                    169: static ppp_log_close_t ppp_log_prefix_close;
                    170: 
                    171: /*
                    172:  * Create a new log that prefixes everything before sending
                    173:  * it to another underlying log.
                    174:  *
                    175:  * The underlying log is NOT closed when the returned log is closed.
                    176:  */
                    177: struct ppp_log *
                    178: ppp_log_prefix(struct ppp_log *log, const char *fmt, ...)
                    179: {
                    180:        struct ppp_log_prefix *priv;
                    181:        va_list args;
                    182: 
                    183:        /* If no log or prefix, just duplicate log */
                    184:        if (log == NULL)
                    185:                return (NULL);
                    186:        if (fmt == NULL || *fmt == '\0')
                    187:                return (ppp_log_dup(log));
                    188: 
                    189:        /* Create prefix log */
                    190:        if ((priv = MALLOC(LOG_MTYPE, sizeof(*priv))) == NULL)
                    191:                return (NULL);
                    192:        va_start(args, fmt);
                    193:        VASPRINTF(LOG_MTYPE, &priv->prefix, fmt, args);
                    194:        va_end(args);
                    195:        if (priv->prefix == NULL) {
                    196:                FREE(LOG_MTYPE, priv);
                    197:                return (NULL);
                    198:        }
                    199: 
                    200:        /* Sanity check prefix: we can't handle any formats in it */
                    201:        if (strchr(priv->prefix, '%') != NULL) {
                    202:                errno = EINVAL;
                    203:                return (NULL);
                    204:        }
                    205: 
                    206:        /* Create new log object using prefix log methods */
                    207:        priv->log = ppp_log_dup(log);                   /* can't fail */
                    208:        if ((log = ppp_log_create(priv,
                    209:            ppp_log_prefix_vput, ppp_log_prefix_close)) == NULL) {
                    210:                ppp_log_close(&priv->log);
                    211:                FREE(LOG_MTYPE, priv->prefix);
                    212:                FREE(LOG_MTYPE, priv);
                    213:                return (NULL);
                    214:        }
                    215: 
                    216:        /* Done */
                    217:        return (log);
                    218: }
                    219: 
                    220: static void
                    221: ppp_log_prefix_vput(void *arg, int sev, const char *fmt, va_list args)
                    222: {
                    223:        struct ppp_log_prefix *const priv = arg;
                    224: 
                    225:        const size_t plen = strlen(priv->prefix);
                    226:        const size_t flen = strlen(fmt);
                    227:        char *pfmt;
                    228: 
                    229:        /* Create new format string with prefix prefixed */
                    230:        if ((pfmt = MALLOC(TYPED_MEM_TEMP, plen + flen + 1)) == NULL) {
                    231:                ppp_log_vput(priv->log, sev, fmt, args);        /* salvage */
                    232:                return;
                    233:        }
                    234:        memcpy(pfmt, priv->prefix, plen);
                    235:        memcpy(pfmt + plen, fmt, flen + 1);
                    236: 
                    237:        /* Log same arguments with new format string */
                    238:        ppp_log_vput(priv->log, sev, pfmt, args);
                    239:        FREE(TYPED_MEM_TEMP, pfmt);
                    240: }
                    241: 
                    242: static void
                    243: ppp_log_prefix_close(void *arg)
                    244: {
                    245:        struct ppp_log_prefix *const priv = arg;
                    246: 
                    247:        ppp_log_close(&priv->log);
                    248:        FREE(LOG_MTYPE, priv->prefix);
                    249:        FREE(LOG_MTYPE, priv);
                    250: }
                    251: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>