syslog.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  * -
00033  * Portions Copyright (c) 1983, 1988, 1993
00034  *      The Regents of the University of California.  All rights reserved.
00035  *
00036  * Redistribution and use in source and binary forms, with or without
00037  * modification, are permitted provided that the following conditions
00038  * are met:
00039  * 1. Redistributions of source code must retain the above copyright
00040  *    notice, this list of conditions and the following disclaimer.
00041  * 2. Redistributions in binary form must reproduce the above copyright
00042  *    notice, this list of conditions and the following disclaimer in the
00043  *    documentation and/or other materials provided with the distribution.
00044  * 3. Neither the name of the University nor the names of its contributors
00045  *    may be used to endorse or promote products derived from this software
00046  *    without specific prior written permission.
00047  *
00048  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00049  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00050  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00051  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00052  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00053  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00054  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00055  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00056  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00057  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00058  * SUCH DAMAGE.
00059  */
00060 
00083 #include <cfg/syslog.h>
00084 #include <sys/confos.h>
00085 
00086 #include <stdlib.h>
00087 #include <string.h>
00088 #include <stdio.h>
00089 #include <stdarg.h>
00090 #include <io.h>
00091 #include <time.h>
00092 
00093 #include <sys/syslog.h>
00094 
00095 #ifndef SYSLOG_PERROR_ONLY
00096 
00097 #include <sys/socket.h>
00098 #include <arpa/inet.h>
00099 static UDPSOCKET *syslog_sock;
00100 
00101 #endif                          /* SYSLOG_PERROR_ONLY */
00102 
00107 
00108 #ifndef SYSLOG_MAXBUF
00109 
00112 #define SYSLOG_MAXBUF 256
00113 #endif
00114 
00115 static uint16_t syslog_port = 514;
00116 static int syslog_fac = LOG_USER;
00117 static int syslog_mask = 0xFF;
00118 
00119 static uint32_t syslog_server;
00120 static int syslog_stat;
00121 static size_t syslog_taglen;
00122 static char *syslog_tag;
00123 static char *syslog_buf;
00124 
00125 static char mon_name[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
00126 
00127 
00138 void vsyslog(int pri, CONST char *fmt, va_list ap)
00139 {
00140     time_t now;
00141     struct _tm *tip;
00142     size_t cnt;
00143 
00144     /* Remove invalid bits. */
00145     pri &= LOG_PRIMASK | LOG_FACMASK;
00146 
00147     /* Check priority against setlog mask values. */
00148     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00149         return;
00150     }
00151 
00152     /* Open log if not done before. */
00153     if (syslog_buf == 0) {
00154         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00155     }
00156 
00157     /* Set default facility if none specified. */
00158     if ((pri & LOG_FACMASK) == 0) {
00159         pri |= syslog_fac;
00160     }
00161 
00162     time(&now);
00163     tip = localtime(&now);
00164     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00165             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00166     cnt = strlen(syslog_buf);
00167 
00168     if (syslog_taglen) {
00169         cnt += syslog_taglen + 2;
00170         if (cnt >= SYSLOG_MAXBUF) {
00171             return;
00172         }
00173         strcat(syslog_buf, syslog_tag);
00174         strcat(syslog_buf, ": ");
00175     }
00176 
00177     /* Potentially dangerous. We need vsnprintf() */
00178     if (cnt + strlen(fmt) >= SYSLOG_MAXBUF) {
00179         return;
00180     }
00181     vsprintf(&syslog_buf[cnt], fmt, ap);
00182     cnt = strlen(syslog_buf);
00183 
00184     /* Output to stderr if requested */
00185     if (syslog_stat & LOG_PERROR) {
00186         _write(_fileno(stderr), syslog_buf, cnt);
00187         _write(_fileno(stderr), "\n", 1);
00188     }
00189 #ifndef SYSLOG_PERROR_ONLY
00190     /*
00191      * Output the message to a remote logger.
00192      */
00193     if (syslog_server) {
00194         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00195     }
00196 #endif
00197 }
00198 
00218 void syslog(int pri, CONST char *fmt, ...)
00219 {
00220     va_list ap;
00221 
00222     va_start(ap, fmt);
00223     vsyslog(pri, (char *) fmt, ap);
00224     va_end(ap);
00225 }
00226 
00227 #ifdef __HARVARD_ARCH__
00228 
00238 void vsyslog_P(int pri, PGM_P fmt, va_list ap)
00239 {
00240     time_t now;
00241     struct _tm *tip;
00242     size_t cnt;
00243 
00244     /* Remove invalid bits. */
00245     pri &= LOG_PRIMASK | LOG_FACMASK;
00246 
00247     /* Check priority against setlog mask values. */
00248     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00249         return;
00250     }
00251 
00252     /* Open log if not done before. */
00253     if (syslog_buf == 0) {
00254         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00255     }
00256 
00257     /* Set default facility if none specified. */
00258     if ((pri & LOG_FACMASK) == 0) {
00259         pri |= syslog_fac;
00260     }
00261 
00262     time(&now);
00263     tip = localtime(&now);
00264     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00265             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00266     cnt = strlen(syslog_buf);
00267 
00268     if (syslog_taglen) {
00269         cnt += syslog_taglen + 2;
00270         if (cnt >= SYSLOG_MAXBUF) {
00271             return;
00272         }
00273         strcat(syslog_buf, syslog_tag);
00274         strcat(syslog_buf, ": ");
00275     }
00276 
00277     /* Potentially dangerous. We need vsnprintf() */
00278     if (cnt + strlen_P(fmt) >= SYSLOG_MAXBUF) {
00279         return;
00280     }
00281     vsprintf_P(&syslog_buf[cnt], fmt, ap);
00282     cnt = strlen(syslog_buf);
00283 
00284     /* Output to stderr if requested */
00285     if (syslog_stat & LOG_PERROR) {
00286         _write(_fileno(stderr), syslog_buf, cnt);
00287         _write(_fileno(stderr), "\n", 1);
00288     }
00289 #ifndef SYSLOG_PERROR_ONLY
00290     /*
00291      * Output the message to a remote logger.
00292      */
00293     if (syslog_server) {
00294         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00295     }
00296 #endif
00297 }
00298 
00318 void syslog_P(int pri, PGM_P fmt, ...)
00319 {
00320     va_list ap;
00321 
00322     va_start(ap, fmt);
00323     vsyslog_P(pri, fmt, ap);
00324     va_end(ap);
00325 }
00326 
00327 #endif /* __HARVARD_ARCH__ */
00328 
00339 int setlogmask(int logmask)
00340 {
00341     int rc = syslog_mask;
00342 
00343     if (logmask) {
00344         syslog_mask = logmask;
00345     }
00346     return rc;
00347 }
00348 
00357 uint32_t setlogserver(uint32_t ip, uint16_t port)
00358 {
00359     uint32_t rc = syslog_server;
00360 
00361     syslog_server = ip;
00362     if (port) {
00363         syslog_port = port;
00364     }
00365     return rc;
00366 }
00367 
00399 void openlog(CONST char *ident, int logstat, int logfac)
00400 {
00401     if (ident == 0) {
00402         ident = syslog_tag;
00403         syslog_taglen = 0;
00404     }
00405 
00406     closelog();
00407 
00408     syslog_stat = logstat;
00409     syslog_fac = logfac;
00410     if (ident && *ident) {
00411         syslog_taglen = strlen(ident);
00412         syslog_tag = malloc(syslog_taglen + 1);
00413         strcpy(syslog_tag, ident);
00414     }
00415     if (syslog_stat & LOG_NDELAY) {
00416         if (syslog_buf == 0) {
00417             syslog_buf = malloc(SYSLOG_MAXBUF);
00418         }
00419 #ifndef SYSLOG_PERROR_ONLY
00420         if (syslog_sock == 0) {
00421             syslog_sock = NutUdpCreateSocket(514);
00422         }
00423 #endif
00424     }
00425 }
00426 
00430 void closelog(void)
00431 {
00432     if (syslog_buf) {
00433         free(syslog_buf);
00434         syslog_buf = 0;
00435     }
00436     if (syslog_taglen) {
00437         free(syslog_tag);
00438         syslog_taglen = 0;
00439     }
00440 #ifndef SYSLOG_PERROR_ONLY
00441     if (syslog_sock) {
00442         NutUdpDestroySocket(syslog_sock);
00443         syslog_sock = 0;
00444     }
00445 #endif
00446 }
00447 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/