From a4713c61c72461e0c584a5dfbcfa371731bd1cd0 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sat, 28 Jul 2012 06:39:41 -0500 Subject: Add syslog functionality from old TCP/IP stack. --- freebsd-userspace/rtems/include/sys/syslog.h | 203 +++++++++++++++++++++++++++ freebsd-userspace/rtems/syslog.c | 192 +++++++++++++++++++++++++ 2 files changed, 395 insertions(+) create mode 100644 freebsd-userspace/rtems/include/sys/syslog.h create mode 100644 freebsd-userspace/rtems/syslog.c (limited to 'freebsd-userspace/rtems') diff --git a/freebsd-userspace/rtems/include/sys/syslog.h b/freebsd-userspace/rtems/include/sys/syslog.h new file mode 100644 index 00000000..a4aba4a1 --- /dev/null +++ b/freebsd-userspace/rtems/include/sys/syslog.h @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 1982, 1986, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)syslog.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD$ + */ + +#ifndef _SYS_SYSLOG_H_ +#define _SYS_SYSLOG_H_ + +#define _PATH_LOG "/var/run/log" +#define _PATH_LOG_PRIV "/var/run/logpriv" +#define _PATH_OLDLOG "/dev/log" /* backward compatibility */ + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ + /* extract priority */ +#define LOG_PRI(p) ((p) & LOG_PRIMASK) +#define LOG_MAKEPRI(fac, pri) ((fac) | (pri)) + +#ifdef SYSLOG_NAMES +#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ + /* mark "facility" */ +#define INTERNAL_MARK LOG_MAKEPRI((LOG_NFACILITIES<<3), 0) +typedef struct _code { + const char *c_name; + int c_val; +} CODE; + +CODE prioritynames[] = { + { "alert", LOG_ALERT, }, + { "crit", LOG_CRIT, }, + { "debug", LOG_DEBUG, }, + { "emerg", LOG_EMERG, }, + { "err", LOG_ERR, }, + { "error", LOG_ERR, }, /* DEPRECATED */ + { "info", LOG_INFO, }, + { "none", INTERNAL_NOPRI, }, /* INTERNAL */ + { "notice", LOG_NOTICE, }, + { "panic", LOG_EMERG, }, /* DEPRECATED */ + { "warn", LOG_WARNING, }, /* DEPRECATED */ + { "warning", LOG_WARNING, }, + { NULL, -1, } +}; +#endif + +/* facility codes */ +#define LOG_KERN (0<<3) /* kernel messages */ +#define LOG_USER (1<<3) /* random user-level messages */ +#define LOG_MAIL (2<<3) /* mail system */ +#define LOG_DAEMON (3<<3) /* system daemons */ +#define LOG_AUTH (4<<3) /* authorization messages */ +#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ +#define LOG_LPR (6<<3) /* line printer subsystem */ +#define LOG_NEWS (7<<3) /* network news subsystem */ +#define LOG_UUCP (8<<3) /* UUCP subsystem */ +#define LOG_CRON (9<<3) /* clock daemon */ +#define LOG_AUTHPRIV (10<<3) /* authorization messages (private) */ + /* Facility #10 clashes in DEC UNIX, where */ + /* it's defined as LOG_MEGASAFE for AdvFS */ + /* event logging. */ +#define LOG_FTP (11<<3) /* ftp daemon */ +#define LOG_NTP (12<<3) /* NTP subsystem */ +#define LOG_SECURITY (13<<3) /* security subsystems (firewalling, etc.) */ +#define LOG_CONSOLE (14<<3) /* /dev/console output */ + + /* other codes through 15 reserved for system use */ +#define LOG_LOCAL0 (16<<3) /* reserved for local use */ +#define LOG_LOCAL1 (17<<3) /* reserved for local use */ +#define LOG_LOCAL2 (18<<3) /* reserved for local use */ +#define LOG_LOCAL3 (19<<3) /* reserved for local use */ +#define LOG_LOCAL4 (20<<3) /* reserved for local use */ +#define LOG_LOCAL5 (21<<3) /* reserved for local use */ +#define LOG_LOCAL6 (22<<3) /* reserved for local use */ +#define LOG_LOCAL7 (23<<3) /* reserved for local use */ + +#define LOG_NFACILITIES 24 /* current number of facilities */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + /* facility of pri */ +#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) + +#ifdef SYSLOG_NAMES +CODE facilitynames[] = { + { "auth", LOG_AUTH, }, + { "authpriv", LOG_AUTHPRIV, }, + { "console", LOG_CONSOLE, }, + { "cron", LOG_CRON, }, + { "daemon", LOG_DAEMON, }, + { "ftp", LOG_FTP, }, + { "kern", LOG_KERN, }, + { "lpr", LOG_LPR, }, + { "mail", LOG_MAIL, }, + { "mark", INTERNAL_MARK, }, /* INTERNAL */ + { "news", LOG_NEWS, }, + { "ntp", LOG_NTP, }, + { "security", LOG_SECURITY, }, + { "syslog", LOG_SYSLOG, }, + { "user", LOG_USER, }, + { "uucp", LOG_UUCP, }, + { "local0", LOG_LOCAL0, }, + { "local1", LOG_LOCAL1, }, + { "local2", LOG_LOCAL2, }, + { "local3", LOG_LOCAL3, }, + { "local4", LOG_LOCAL4, }, + { "local5", LOG_LOCAL5, }, + { "local6", LOG_LOCAL6, }, + { "local7", LOG_LOCAL7, }, + { NULL, -1, } +}; +#endif + +#ifdef _KERNEL +#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */ +#endif + +/* + * arguments to setlogmask. + */ +#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ +#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ + +/* + * Option flags for openlog. + * + * LOG_ODELAY no longer does anything. + * LOG_NDELAY is the inverse of what it used to be. + */ +#define LOG_PID 0x01 /* log the pid with each message */ +#define LOG_CONS 0x02 /* log on the console if errors in sending */ +#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ +#define LOG_NDELAY 0x08 /* don't delay open */ +#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ +#define LOG_PERROR 0x20 /* log to stderr as well */ + +#ifdef _KERNEL + +#else /* not _KERNEL */ + +/* + * Don't use va_list in the vsyslog() prototype. Va_list is typedef'd in two + * places ( and ), so if we include one + * of them here we may collide with the utility's includes. It's unreasonable + * for utilities to have to include one of them to include syslog.h, so we get + * __va_list from and use it. + */ +#include +#include + +__BEGIN_DECLS +void closelog(void); +void openlog(const char *, int, int); +int setlogmask(int); +void syslog(int, const char *, ...); /* JRS __printflike(2, 3); */ +#if __BSD_VISIBLE +void vsyslog(int, const char *, __va_list); /* JRS __printflike(2, 0); */ +#endif +__END_DECLS + +#endif /* !_KERNEL */ + +#endif diff --git a/freebsd-userspace/rtems/syslog.c b/freebsd-userspace/rtems/syslog.c new file mode 100644 index 00000000..10a75a61 --- /dev/null +++ b/freebsd-userspace/rtems/syslog.c @@ -0,0 +1,192 @@ +/* + * RTEMS version of syslog and associated routines + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int LogStatus = LOG_CONS; +static const char *LogTag = "syslog"; +static int LogFacility = LOG_USER; +static int LogMask = 0xff; + +static int LogFd = -1; +static rtems_id LogSemaphore; +extern struct in_addr rtems_bsdnet_log_host_address; + +#define SYSLOG_PORT 514 + +void +syslog (int pri, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vsyslog (pri, fmt, ap); + va_end (ap); +} + +/* + * FIXME: Should cbuf be static? It could be if we put the mutex + * around the entire body of this routine. Then we wouldn't + * have to worry about blowing stacks with a local variable + * that large. Could make cbuf bigger, too. + */ +void +vsyslog (int pri, const char *fmt, va_list ap) +{ + int cnt; + char *cp; + char *msgp, cbuf[200]; + int sent; + + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, + "syslog: unknown facility/priority: %#x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) + return; + + if ((pri & LOG_FACMASK) == 0) + pri |= LogFacility; + + cnt = sprintf (cbuf, "<%d>", pri); + cp = msgp = cbuf + cnt; + if (LogTag) { + const char *lp = LogTag; + while ((*cp = *lp++) != '\0') + cp++; + } + if (LogStatus & LOG_PID) { + rtems_id tid; + rtems_task_ident (RTEMS_SELF, 0, &tid); + cnt = sprintf (cp, "[%#lx]", (unsigned long)tid); + cp += cnt; + } + if (LogTag) { + *cp++ = ':'; + *cp++ = ' '; + } + cnt = vsprintf (cp, fmt, ap); + cnt += cp - cbuf; + if (cbuf[cnt-1] == '\n') + cbuf[--cnt] = '\0'; + + if (LogStatus & LOG_PERROR) + printf ("%s\n", cbuf); + + /* + * Grab the mutex + */ + sent = 0; + if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY) + && (LogFd >= 0) + && (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) { + /* + * Set the destination address/port + */ + struct sockaddr_in farAddress; + farAddress.sin_family = AF_INET; + farAddress.sin_port = htons (SYSLOG_PORT); + farAddress.sin_addr = rtems_bsdnet_log_host_address; + memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero); + + /* + * Send the message + */ + if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0) + sent = 1; + rtems_semaphore_release (LogSemaphore); + } + if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR)) + printf ("%s\n", msgp); +} + +void +openlog (const char *ident, int logstat, int logfac) +{ + rtems_status_code sc; + struct sockaddr_in myAddress; + + if (ident != NULL) + LogTag = ident; + LogStatus = logstat; + if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0) + LogFacility = logfac; + + /* + * Create the socket + */ + if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { + printf ("Can't create syslog socket: %d\n", errno); + return; + } + + /* + * Bind socket to name + */ + myAddress.sin_family = AF_INET; + myAddress.sin_addr.s_addr = INADDR_ANY; + myAddress.sin_port = 0; + memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero); + if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) { + close (LogFd); + LogFd = -1; + printf ("Can't bind syslog socket: %d\n", errno); + return; + } + + /* + * Create the mutex + */ + sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'), + 1, + RTEMS_PRIORITY | + RTEMS_BINARY_SEMAPHORE | + RTEMS_INHERIT_PRIORITY | + RTEMS_NO_PRIORITY_CEILING | + RTEMS_LOCAL, + 0, + &LogSemaphore); + if (sc != RTEMS_SUCCESSFUL) { + printf ("Can't create syslog semaphore: %d\n", sc); + close (LogFd); + LogFd = -1; + } +} + +void +closelog(void) +{ + if (LogFd >= 0) { + close (LogFd); + LogFd = -1; + rtems_semaphore_delete (LogSemaphore); + } +} + +int +setlogmask (int pmask) +{ + int omask; + + omask = LogMask; + if (pmask != 0) + LogMask = pmask; + return (omask); +} -- cgit v1.2.3