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 
00086 #include <cfg/syslog.h>
00087 #include <sys/confos.h>
00088 
00089 #include <stdlib.h>
00090 #include <string.h>
00091 #include <stdio.h>
00092 #include <stdarg.h>
00093 #include <io.h>
00094 #include <time.h>
00095 #include <memdebug.h>
00096 
00097 #include <sys/syslog.h>
00098 
00099 #ifndef SYSLOG_PERROR_ONLY
00100 
00101 #include <sys/socket.h>
00102 #include <arpa/inet.h>
00103 static UDPSOCKET *syslog_sock;
00104 
00105 #endif                          /* SYSLOG_PERROR_ONLY */
00106 
00111 
00112 #ifndef SYSLOG_MAXBUF
00113 
00116 #define SYSLOG_MAXBUF 256
00117 #endif
00118 
00119 static uint16_t syslog_port = 514;
00120 static int syslog_fac = LOG_USER;
00121 static int syslog_mask = 0xFF;
00122 
00123 static uint32_t syslog_server;
00124 static int syslog_stat;
00125 static size_t syslog_taglen;
00126 static char *syslog_tag;
00127 static char *syslog_buf;
00128 
00129 static char mon_name[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
00130 
00131 
00142 void vsyslog(int pri, CONST char *fmt, va_list ap)
00143 {
00144     time_t now;
00145     struct _tm *tip;
00146     size_t cnt;
00147 
00148     /* Remove invalid bits. */
00149     pri &= LOG_PRIMASK | LOG_FACMASK;
00150 
00151     /* Check priority against setlog mask values. */
00152     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00153         return;
00154     }
00155 
00156     /* Open log if not done before. */
00157     if (syslog_buf == 0) {
00158         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00159     }
00160 
00161     /* Set default facility if none specified. */
00162     if ((pri & LOG_FACMASK) == 0) {
00163         pri |= syslog_fac;
00164     }
00165 
00166     time(&now);
00167     tip = localtime(&now);
00168     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00169             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00170     cnt = strlen(syslog_buf);
00171 
00172     if (syslog_taglen) {
00173         cnt += syslog_taglen + 2;
00174         if (cnt >= SYSLOG_MAXBUF) {
00175             return;
00176         }
00177         strcat(syslog_buf, syslog_tag);
00178         strcat(syslog_buf, ": ");
00179     }
00180 
00181     /* Potentially dangerous. We need vsnprintf() */
00182     if (cnt + strlen(fmt) >= SYSLOG_MAXBUF) {
00183         return;
00184     }
00185     vsprintf(&syslog_buf[cnt], fmt, ap);
00186     cnt = strlen(syslog_buf);
00187 
00188     /* Output to stderr if requested */
00189     if (syslog_stat & LOG_PERROR) {
00190         _write(_fileno(stderr), syslog_buf, cnt);
00191         _write(_fileno(stderr), "\n", 1);
00192     }
00193 #ifndef SYSLOG_PERROR_ONLY
00194     /*
00195      * Output the message to a remote logger.
00196      */
00197     if (syslog_server) {
00198         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00199     }
00200 #endif
00201 }
00202 
00222 void syslog(int pri, CONST char *fmt, ...)
00223 {
00224     va_list ap;
00225 
00226     va_start(ap, fmt);
00227     vsyslog(pri, (char *) fmt, ap);
00228     va_end(ap);
00229 }
00230 
00231 #ifdef __HARVARD_ARCH__
00232 
00242 void vsyslog_P(int pri, PGM_P fmt, va_list ap)
00243 {
00244     time_t now;
00245     struct _tm *tip;
00246     size_t cnt;
00247 
00248     /* Remove invalid bits. */
00249     pri &= LOG_PRIMASK | LOG_FACMASK;
00250 
00251     /* Check priority against setlog mask values. */
00252     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00253         return;
00254     }
00255 
00256     /* Open log if not done before. */
00257     if (syslog_buf == 0) {
00258         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00259     }
00260 
00261     /* Set default facility if none specified. */
00262     if ((pri & LOG_FACMASK) == 0) {
00263         pri |= syslog_fac;
00264     }
00265 
00266     time(&now);
00267     tip = localtime(&now);
00268     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00269             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00270     cnt = strlen(syslog_buf);
00271 
00272     if (syslog_taglen) {
00273         cnt += syslog_taglen + 2;
00274         if (cnt >= SYSLOG_MAXBUF) {
00275             return;
00276         }
00277         strcat(syslog_buf, syslog_tag);
00278         strcat(syslog_buf, ": ");
00279     }
00280 
00281     /* Potentially dangerous. We need vsnprintf() */
00282     if (cnt + strlen_P(fmt) >= SYSLOG_MAXBUF) {
00283         return;
00284     }
00285     vsprintf_P(&syslog_buf[cnt], fmt, ap);
00286     cnt = strlen(syslog_buf);
00287 
00288     /* Output to stderr if requested */
00289     if (syslog_stat & LOG_PERROR) {
00290         _write(_fileno(stderr), syslog_buf, cnt);
00291         _write(_fileno(stderr), "\n", 1);
00292     }
00293 #ifndef SYSLOG_PERROR_ONLY
00294     /*
00295      * Output the message to a remote logger.
00296      */
00297     if (syslog_server) {
00298         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00299     }
00300 #endif
00301 }
00302 
00322 void syslog_P(int pri, PGM_P fmt, ...)
00323 {
00324     va_list ap;
00325 
00326     va_start(ap, fmt);
00327     vsyslog_P(pri, fmt, ap);
00328     va_end(ap);
00329 }
00330 
00331 #endif /* __HARVARD_ARCH__ */
00332 
00343 int setlogmask(int logmask)
00344 {
00345     int rc = syslog_mask;
00346 
00347     if (logmask) {
00348         syslog_mask = logmask;
00349     }
00350     return rc;
00351 }
00352 
00361 uint32_t setlogserver(uint32_t ip, uint16_t port)
00362 {
00363     uint32_t rc = syslog_server;
00364 
00365     syslog_server = ip;
00366     if (port) {
00367         syslog_port = port;
00368     }
00369     return rc;
00370 }
00371 
00403 void openlog(CONST char *ident, int logstat, int logfac)
00404 {
00405     if (ident == 0) {
00406         ident = syslog_tag;
00407         syslog_taglen = 0;
00408     }
00409 
00410     closelog();
00411 
00412     syslog_stat = logstat;
00413     syslog_fac = logfac;
00414     if (ident && *ident) {
00415         syslog_taglen = strlen(ident);
00416         syslog_tag = malloc(syslog_taglen + 1);
00417         strcpy(syslog_tag, ident);
00418     }
00419     if (syslog_stat & LOG_NDELAY) {
00420         if (syslog_buf == 0) {
00421             syslog_buf = malloc(SYSLOG_MAXBUF);
00422         }
00423 #ifndef SYSLOG_PERROR_ONLY
00424         if (syslog_sock == 0) {
00425             syslog_sock = NutUdpCreateSocket(514);
00426         }
00427 #endif
00428     }
00429 }
00430 
00434 void closelog(void)
00435 {
00436     if (syslog_buf) {
00437         free(syslog_buf);
00438         syslog_buf = 0;
00439     }
00440     if (syslog_taglen) {
00441         free(syslog_tag);
00442         syslog_taglen = 0;
00443     }
00444 #ifndef SYSLOG_PERROR_ONLY
00445     if (syslog_sock) {
00446         NutUdpDestroySocket(syslog_sock);
00447         syslog_sock = 0;
00448     }
00449 #endif
00450 }
00451 

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