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 
00080 #include <cfg/syslog.h>
00081 #include <sys/confos.h>
00082 
00083 #include <stdlib.h>
00084 #include <string.h>
00085 #include <stdio.h>
00086 #include <stdarg.h>
00087 #include <io.h>
00088 #include <time.h>
00089 
00090 #include <sys/syslog.h>
00091 
00092 #ifndef SYSLOG_PERROR_ONLY
00093 
00094 #include <sys/socket.h>
00095 #include <arpa/inet.h>
00096 static UDPSOCKET *syslog_sock;
00097 
00098 #endif                          /* SYSLOG_PERROR_ONLY */
00099 
00104 
00105 #ifndef SYSLOG_MAXBUF
00106 
00109 #define SYSLOG_MAXBUF 256
00110 #endif
00111 
00112 static u_short syslog_port = 514;
00113 static int syslog_fac = LOG_USER;
00114 static int syslog_mask = 0xFF;
00115 
00116 static u_long syslog_server;
00117 static int syslog_stat;
00118 static size_t syslog_taglen;
00119 static char *syslog_tag;
00120 static char *syslog_buf;
00121 
00122 static char mon_name[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
00123 
00124 
00135 void vsyslog(int pri, CONST char *fmt, va_list ap)
00136 {
00137     time_t now;
00138     struct _tm *tip;
00139     size_t cnt;
00140 
00141     /* Remove invalid bits. */
00142     pri &= LOG_PRIMASK | LOG_FACMASK;
00143 
00144     /* Check priority against setlog mask values. */
00145     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00146         return;
00147     }
00148 
00149     /* Open log if not done before. */
00150     if (syslog_buf == 0) {
00151         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00152     }
00153 
00154     /* Set default facility if none specified. */
00155     if ((pri & LOG_FACMASK) == 0) {
00156         pri |= syslog_fac;
00157     }
00158 
00159     time(&now);
00160     tip = localtime(&now);
00161     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00162             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00163     cnt = strlen(syslog_buf);
00164 
00165     if (syslog_taglen) {
00166         cnt += syslog_taglen + 2;
00167         if (cnt >= SYSLOG_MAXBUF) {
00168             return;
00169         }
00170         strcat(syslog_buf, syslog_tag);
00171         strcat(syslog_buf, ": ");
00172     }
00173 
00174     /* Potentially dangerous. We need vsnprintf() */
00175     if (cnt + strlen(fmt) >= SYSLOG_MAXBUF) {
00176         return;
00177     }
00178     vsprintf(&syslog_buf[cnt], fmt, ap);
00179     cnt = strlen(syslog_buf);
00180 
00181     /* Output to stderr if requested */
00182     if (syslog_stat & LOG_PERROR) {
00183         _write(_fileno(stderr), syslog_buf, cnt);
00184         _write(_fileno(stderr), "\n", 1);
00185     }
00186 #ifndef SYSLOG_PERROR_ONLY
00187     /*
00188      * Output the message to a remote logger.
00189      */
00190     if (syslog_server) {
00191         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00192     }
00193 #endif
00194 }
00195 
00215 void syslog(int pri, CONST char *fmt, ...)
00216 {
00217     va_list ap;
00218 
00219     va_start(ap, fmt);
00220     vsyslog(pri, (char *) fmt, ap);
00221     va_end(ap);
00222 }
00223 
00224 #ifdef __HARVARD_ARCH__
00225 
00235 void vsyslog_P(int pri, PGM_P fmt, va_list ap)
00236 {
00237     time_t now;
00238     struct _tm *tip;
00239     size_t cnt;
00240 
00241     /* Remove invalid bits. */
00242     pri &= LOG_PRIMASK | LOG_FACMASK;
00243 
00244     /* Check priority against setlog mask values. */
00245     if ((LOG_MASK(LOG_PRI(pri)) & syslog_mask) == 0) {
00246         return;
00247     }
00248 
00249     /* Open log if not done before. */
00250     if (syslog_buf == 0) {
00251         openlog(0, syslog_stat | LOG_NDELAY, syslog_fac);
00252     }
00253 
00254     /* Set default facility if none specified. */
00255     if ((pri & LOG_FACMASK) == 0) {
00256         pri |= syslog_fac;
00257     }
00258 
00259     time(&now);
00260     tip = localtime(&now);
00261     sprintf(syslog_buf, "<%d>%.3s%3d %02d:%02d:%02d %s ", pri, &mon_name[tip->tm_mon * 3],
00262             tip->tm_mday, tip->tm_hour, tip->tm_min, tip->tm_sec, confos.hostname);
00263     cnt = strlen(syslog_buf);
00264 
00265     if (syslog_taglen) {
00266         cnt += syslog_taglen + 2;
00267         if (cnt >= SYSLOG_MAXBUF) {
00268             return;
00269         }
00270         strcat(syslog_buf, syslog_tag);
00271         strcat(syslog_buf, ": ");
00272     }
00273 
00274     /* Potentially dangerous. We need vsnprintf() */
00275     if (cnt + strlen_P(fmt) >= SYSLOG_MAXBUF) {
00276         return;
00277     }
00278     vsprintf_P(&syslog_buf[cnt], fmt, ap);
00279     cnt = strlen(syslog_buf);
00280 
00281     /* Output to stderr if requested */
00282     if (syslog_stat & LOG_PERROR) {
00283         _write(_fileno(stderr), syslog_buf, cnt);
00284         _write(_fileno(stderr), "\n", 1);
00285     }
00286 #ifndef SYSLOG_PERROR_ONLY
00287     /*
00288      * Output the message to a remote logger.
00289      */
00290     if (syslog_server) {
00291         NutUdpSendTo(syslog_sock, syslog_server, syslog_port, syslog_buf, cnt);
00292     }
00293 #endif
00294 }
00295 
00315 void syslog_P(int pri, PGM_P fmt, ...)
00316 {
00317     va_list ap;
00318 
00319     va_start(ap, fmt);
00320     vsyslog_P(pri, fmt, ap);
00321     va_end(ap);
00322 }
00323 
00324 #endif /* __HARVARD_ARCH__ */
00325 
00336 int setlogmask(int logmask)
00337 {
00338     int rc = syslog_mask;
00339 
00340     if (logmask) {
00341         syslog_mask = logmask;
00342     }
00343     return rc;
00344 }
00345 
00354 u_long setlogserver(u_long ip, u_short port)
00355 {
00356     u_long rc = syslog_server;
00357 
00358     syslog_server = ip;
00359     if (port) {
00360         syslog_port = port;
00361     }
00362     return rc;
00363 }
00364 
00396 void openlog(CONST char *ident, int logstat, int logfac)
00397 {
00398     if (ident == 0) {
00399         ident = syslog_tag;
00400         syslog_taglen = 0;
00401     }
00402 
00403     closelog();
00404 
00405     syslog_stat = logstat;
00406     syslog_fac = logfac;
00407     if (ident && *ident) {
00408         syslog_taglen = strlen(ident);
00409         syslog_tag = malloc(syslog_taglen + 1);
00410         strcpy(syslog_tag, ident);
00411     }
00412     if (syslog_stat & LOG_NDELAY) {
00413         if (syslog_buf == 0) {
00414             syslog_buf = malloc(SYSLOG_MAXBUF);
00415         }
00416 #ifndef SYSLOG_PERROR_ONLY
00417         if (syslog_sock == 0) {
00418             syslog_sock = NutUdpCreateSocket(514);
00419         }
00420 #endif
00421     }
00422 }
00423 
00427 void closelog(void)
00428 {
00429     if (syslog_buf) {
00430         free(syslog_buf);
00431         syslog_buf = 0;
00432     }
00433     if (syslog_taglen) {
00434         free(syslog_tag);
00435         syslog_taglen = 0;
00436     }
00437 #ifndef SYSLOG_PERROR_ONLY
00438     if (syslog_sock) {
00439         NutUdpDestroySocket(syslog_sock);
00440         syslog_sock = 0;
00441     }
00442 #endif
00443 }
00444 

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