[BACK]Return to log.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Annotation of src/usr.bin/cvs/log.c, Revision 1.9

1.9     ! jfb         1: /*     $OpenBSD: log.c,v 1.8 2004/12/15 06:11:40 jfb Exp $     */
1.1       jfb         2: /*
1.2       jfb         3:  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.1       jfb         4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  *
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. The name of the author may not be used to endorse or promote products
                     13:  *    derived from this software without specific prior written permission.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     16:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     17:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     18:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     19:  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     20:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     21:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     22:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     23:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     24:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: #include <sys/types.h>
                     28:
                     29: #include <errno.h>
                     30: #include <stdio.h>
                     31: #include <string.h>
                     32: #include <stdlib.h>
                     33: #include <unistd.h>
                     34: #include <stdarg.h>
                     35: #include <syslog.h>
                     36:
                     37: #include "log.h"
1.3       jfb        38: #include "cvs.h"
1.1       jfb        39:
                     40: extern char *__progname;
                     41:
1.3       jfb        42:
1.2       jfb        43: #ifdef unused
1.1       jfb        44: static char *cvs_log_levels[] = {
                     45:        "debug",
                     46:        "info",
                     47:        "notice",
                     48:        "warning",
                     49:        "error",
                     50:        "alert",
1.4       jfb        51:        "error",
                     52:        "abort",
1.1       jfb        53: };
1.2       jfb        54: #endif
1.1       jfb        55:
                     56: static int cvs_slpriomap[] = {
                     57:        LOG_DEBUG,
                     58:        LOG_INFO,
                     59:        LOG_NOTICE,
                     60:        LOG_WARNING,
                     61:        LOG_ERR,
                     62:        LOG_ALERT,
                     63:        LOG_ERR,
1.4       jfb        64:        LOG_ERR,
1.1       jfb        65: };
                     66:
                     67: static u_int cvs_log_dest = LD_STD;
                     68: static u_int cvs_log_flags = 0;
                     69:
1.9     ! jfb        70: static struct syslog_data cvs_sl;
1.1       jfb        71:
1.9     ! jfb        72: /* filter manipulation macros */
        !            73: #define CVS_LOG_FLTRRST()    (cvs_log_filters = 0)
        !            74: #define CVS_LOG_FLTRSET(l)   (cvs_log_filters |= (1 << l))
        !            75: #define CVS_LOG_FLTRGET(l)   (cvs_log_filters & (1 << l))
        !            76: #define CVS_LOG_FLTRCLR(l)   (cvs_log_filters &= ~(1 << l))
1.1       jfb        77:
1.9     ! jfb        78: static u_int cvs_log_filters;
1.1       jfb        79:
                     80:
                     81: /*
                     82:  * cvs_log_init()
                     83:  *
                     84:  * Initialize the logging facility of the server.
                     85:  * Returns 0 on success, or -1 on failure.
                     86:  */
                     87: int
                     88: cvs_log_init(u_int dest, u_int flags)
                     89: {
                     90:        int slopt;
                     91:
                     92:        cvs_log_dest = dest;
                     93:        cvs_log_flags = flags;
                     94:
                     95:        /* by default, filter only LP_DEBUG and LP_INFO levels */
1.9     ! jfb        96:        CVS_LOG_FLTRRST();
        !            97:        CVS_LOG_FLTRSET(LP_DEBUG);
        !            98:        CVS_LOG_FLTRSET(LP_INFO);
1.1       jfb        99:
1.8       jfb       100:        /* traces are enabled with the -t command-line option */
1.9     ! jfb       101:        CVS_LOG_FLTRSET(LP_TRACE);
1.8       jfb       102:
1.1       jfb       103:        if (dest & LD_SYSLOG) {
                    104:                slopt = 0;
                    105:
                    106:                if (dest & LD_CONS)
                    107:                        slopt |= LOG_CONS;
                    108:                if (flags & LF_PID)
                    109:                        slopt |= LOG_PID;
                    110:
                    111:                openlog_r(__progname, slopt, LOG_DAEMON, &cvs_sl);
                    112:        }
                    113:
                    114:        return (0);
                    115: }
                    116:
                    117:
                    118: /*
                    119:  * cvs_log_cleanup()
                    120:  *
                    121:  * Cleanup the logging facility.
                    122:  */
                    123: void
                    124: cvs_log_cleanup(void)
                    125: {
1.7       tedu      126:
1.1       jfb       127:        closelog_r(&cvs_sl);
                    128: }
                    129:
                    130:
                    131: /*
                    132:  * cvs_log_filter()
                    133:  *
                    134:  * Apply or remove filters on the logging facility.  The exact operation is
                    135:  * specified by the <how> and <level> arguments.  The <how> arguments tells
                    136:  * how the filters will be affected, and <level> gives the log levels that
                    137:  * will be affected by the change.
                    138:  * Returns 0 on success, or -1 on failure.
                    139:  */
                    140:
                    141: int
                    142: cvs_log_filter(u_int how, u_int level)
                    143: {
                    144:        u_int i;
                    145:
                    146:        if ((level > LP_MAX) && (level != LP_ALL)) {
                    147:                cvs_log(LP_ERR, "invalid log level for filter");
                    148:                return (-1);
                    149:        }
                    150:
                    151:        switch (how) {
                    152:        case LP_FILTER_SET:
                    153:                if (level == LP_ALL)
1.9     ! jfb       154:                        for (i = 0; i <= LP_MAX; i++)
        !           155:                                CVS_LOG_FLTRSET(i);
1.1       jfb       156:                else
1.9     ! jfb       157:                        CVS_LOG_FLTRSET(level);
1.1       jfb       158:                break;
                    159:        case LP_FILTER_UNSET:
                    160:                if (level == LP_ALL)
1.9     ! jfb       161:                        CVS_LOG_FLTRRST();
1.1       jfb       162:                else
1.9     ! jfb       163:                        CVS_LOG_FLTRCLR(level);
1.1       jfb       164:                break;
                    165:        default:
                    166:                return (-1);
                    167:        }
                    168:
                    169:        return (0);
                    170: }
                    171:
                    172:
                    173: /*
                    174:  * cvs_log()
                    175:  *
                    176:  * Log the format-string message
                    177:  * The <fmt> argument should not have a terminating newline, as this is taken
                    178:  * care of by the logging facility.
                    179:  */
                    180: int
                    181: cvs_log(u_int level, const char *fmt, ...)
                    182: {
                    183:        int ret;
                    184:        va_list vap;
                    185:
                    186:        va_start(vap, fmt);
                    187:        ret = cvs_vlog(level, fmt, vap);
                    188:        va_end(vap);
                    189:
                    190:        return (ret);
                    191: }
                    192:
                    193:
                    194: /*
                    195:  * cvs_vlog()
                    196:  *
                    197:  * The <fmt> argument should not have a terminating newline, as this is taken
                    198:  * care of by the logging facility.
                    199:  */
                    200: int
                    201: cvs_vlog(u_int level, const char *fmt, va_list vap)
                    202: {
                    203:        int ecp;
                    204:        char prefix[64], buf[1024], ebuf[32];
                    205:        FILE *out;
                    206:
1.4       jfb       207:        if (level > LP_MAX)
                    208:                return (-1);
1.1       jfb       209:
                    210:        /* apply any filters */
1.9     ! jfb       211:        if (CVS_LOG_FLTRGET(level))
1.1       jfb       212:                return (0);
                    213:
                    214:        if (level == LP_ERRNO)
                    215:                ecp = errno;
1.4       jfb       216:        else
                    217:                ecp = 0;
1.1       jfb       218:
1.3       jfb       219: #ifdef CVS
                    220:        /* The cvs program appends the command name to the program name */
1.8       jfb       221:        if (level == LP_TRACE) {
                    222:                strlcpy(prefix, " -> ", sizeof(prefix));
                    223:                if (cvs_cmdop == CVS_OP_SERVER)
                    224:                        prefix[0] = 'S';
                    225:        } else if (cvs_command != NULL) {
1.4       jfb       226:                if (level == LP_ABORT)
                    227:                        snprintf(prefix, sizeof(prefix), "%s [%s aborted]",
                    228:                            __progname, cvs_command);
                    229:                else
                    230:                        snprintf(prefix, sizeof(prefix), "%s %s", __progname,
                    231:                            cvs_command);
1.6       deraadt   232:        } else /* just use the standard strlcpy */
1.3       jfb       233: #endif
                    234:                strlcpy(prefix, __progname, sizeof(prefix));
                    235:
1.8       jfb       236:        if ((cvs_log_flags & LF_PID) && (level != LP_TRACE)) {
1.1       jfb       237:                snprintf(buf, sizeof(buf), "[%d]", (int)getpid());
                    238:                strlcat(prefix, buf, sizeof(prefix));
                    239:        }
                    240:
                    241:        vsnprintf(buf, sizeof(buf), fmt, vap);
                    242:        if (level == LP_ERRNO) {
                    243:                snprintf(ebuf, sizeof(ebuf), ": %s", strerror(errno));
                    244:                strlcat(buf, ebuf, sizeof(buf));
                    245:        }
                    246:
                    247:        if (cvs_log_dest & LD_STD) {
                    248:                if (level <= LP_NOTICE)
                    249:                        out = stdout;
                    250:                else
                    251:                        out = stderr;
1.3       jfb       252:
                    253: #ifdef CVS
                    254:                if (cvs_cmdop == CVS_OP_SERVER) {
                    255:                        if (out == stdout)
                    256:                                putc('M', out);
                    257:                        else
                    258:                                putc('E', out);
                    259:                        putc(' ', out);
                    260:                }
                    261: #endif
1.1       jfb       262:
1.8       jfb       263:                fputs(prefix, out);
                    264:                if (level != LP_TRACE)
                    265:                        fputs(": ", out);
                    266:                fputs(buf, out);
                    267:                fputc('\n', out);
1.1       jfb       268:        }
                    269:
                    270:        if (cvs_log_dest & LD_SYSLOG)
                    271:                syslog_r(cvs_slpriomap[level], &cvs_sl, "%s", buf);
                    272:
                    273:        /* preserve it just in case we changed it? */
                    274:        if (level == LP_ERRNO)
                    275:                errno = ecp;
                    276:
                    277:        return (0);
1.2       jfb       278: }
                    279:
                    280:
                    281: /*
                    282:  * cvs_printf()
                    283:  *
                    284:  * Wrapper function around printf() that prepends a 'M' or 'E' command when
                    285:  * the program is acting as server.
                    286:  */
                    287: int
                    288: cvs_printf(const char *fmt, ...)
                    289: {
                    290:        int ret;
                    291:        va_list vap;
                    292:
                    293:        va_start(vap, fmt);
                    294:        ret = vprintf(fmt, vap);
                    295:        va_end(vap);
                    296:
                    297:        return (ret);
1.1       jfb       298: }