Annotation of embedaddon/libpdel/ppp/ppp_log.c, revision 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>