From d1f82d7e4d130d3d8b3b9a9ffa0186fa58c41ebd Mon Sep 17 00:00:00 2001 From: deuce <> Date: Fri, 10 Nov 2006 18:51:05 +0000 Subject: [PATCH] Cross-platform syslog logging stuff. Allows UDP syslog logging on any system... On Win32, will default to logging to localhost whereas on *nix, the openlog(), syslog(), and vsyslog() functions are wrappers if no log host is set with xp_set_loghost() Untested, unused, not part of xpdev builds currently. --- src/xpdev/xp_syslog.c | 152 ++++++++++++++++++++++++++++++++++++++++++ src/xpdev/xp_syslog.h | 57 ++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/xpdev/xp_syslog.c create mode 100644 src/xpdev/xp_syslog.h diff --git a/src/xpdev/xp_syslog.c b/src/xpdev/xp_syslog.c new file mode 100644 index 0000000000..a03669b829 --- /dev/null +++ b/src/xpdev/xp_syslog.c @@ -0,0 +1,152 @@ +#include <stdarg.h> +#ifdef __unix__ +#include <syslog.h> +#endif + +#include "xp_syslog.h" +#include "sockwrap.h" +#include "gen_defs.h" + +static SOCKET syslog_sock=INVALID_SOCKET; +static char log_host[1025]= +#ifdef __unix__ +""; +#else +"localhost"; +#endif + +static char syslog_tag[33]="undefined"; +static int default_facility=LOG_USER; + +static u_long resolve_ip(char *addr) +{ + HOSTENT* host; + char* p; + + if(*addr==0) + return((u_long)INADDR_NONE); + + for(p=addr;*p;p++) + if(*p!='.' && !isdigit(*p)) + break; + if(!(*p)) + return(inet_addr(addr)); + if((host=gethostbyname(addr))==NULL) + return((u_long)INADDR_NONE); + return(*((ulong*)host->h_addr_list[0])); +} + +void xp_set_loghost(const char *hostname) +{ + SAFECOPY(log_host, hostname); +} + +void xp_openlog(const char *ident, int logopt, int facility) +{ + int sock; + SOCKADDR_IN syslog_addr; + socklen_t syslog_len; + +#ifdef __unix__ + if(!log_host[0]) { + openlog(ident,logopt,facility); + return; + } +#endif + + memset(&syslog_addr, 0, sizeof(syslog_addr)); + syslog_addr.sin_addr.s_addr=INADDR_ANY; + syslog_addr.sin_family=AF_INET; + syslog_addr.sin_port=htons(SYSLOG_PORT); + + syslog_sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(syslog_sock==INVALID_SOCKET) + return; + /* + * If the bind() fails, that's OK... we're just trying to set the source port to + * 514 here as reccomended by the RFC. This isn't REQUIRED though. + */ + bind(syslog_sock, (struct sockaddr *)&syslog_addr, sizeof(syslog_addr)); + syslog_addr.sin_addr.s_addr=resolve_ip(log_host); + if(connect(syslog_sock, (struct sockaddr *)&syslog_addr, sizeof(syslog_addr))) { + closesocket(syslog_sock); + syslog_sock=INVALID_SOCKET; + return; + } + + SAFECOPY(syslog_tag, ident); +} + +void xp_vsyslog(int priority, const char *message, va_list va) +{ + int orig_errno=ERROR_VALUE; + time_t now; + char timestr[32]; + char msg_to_send[1025]; + char format[1025]; + char *msg_end; + char *p; + int i; + +#ifdef __unix__ + if(!log_host[0]) { + vsyslog(priority, message, va); + return; + } +#endif + + /* Ensure we can even send this thing */ + if(syslog_sock==INVALID_SOCKET) + return; + + /* Check for valid priority */ + if(priority & ~(LOG_PRIMASK|LOG_FACMASK)) { + i=priority; + /* Fix to something legal */ + priority &= (LOG_PRIMASK|LOG_FACMASK); + /* Ooooo... re-entrant! */ + syslog(priority,"Unknown priority %x",i); + } + + /* Set default facility if needed */ + if(!(priority & LOG_FACMASK)) + priority |= default_facility; + + time(&now); + ctime_r(&now, timestr); + /* Remove trailing \n */ + timestr[24]=0; + + snprintf(format, sizeof(format), "<%d>%.15s %.32s: %s", priority, timestr+4 /* Remove day of week */, syslog_tag, message); + format[sizeof(format)-1]=0; + vsnprintf(msg_to_send, sizeof(msg_to_send), format, va); + msg_to_send[sizeof(msg_to_send)-1]=0; + + /* Clean out invalid chars (as per RFC3164) */ + msg_end=msg_to_send+sizeof(msg_to_send)-1; + for(p=msg_to_send; *p; p++) { + if(*p<32) { + i=strlen(p); + memmove(p, p+1, i); + *p='^'; + p++; + *p|=0x40; + if(p+i > msg_end) + *msg_end=0; + else + *(p+i)=0; + } + else if(*p>126) + *p=' '; + } + sendsocket(syslog_sock, msg_to_send, strlen(msg_to_send)); +} + +void xp_syslog(int priority, const char *message, ...) +{ + va_list va; + + va_start(va, message); + vsyslog(priority, message, va); + va_end(va); +} diff --git a/src/xpdev/xp_syslog.h b/src/xpdev/xp_syslog.h new file mode 100644 index 0000000000..0e890e3a43 --- /dev/null +++ b/src/xpdev/xp_syslog.h @@ -0,0 +1,57 @@ +#ifndef XP_SYSLOG_H_ +#define XP_SYSLOG_H_ +#include <stdarg.h> + + +/* priorities */ +#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_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 */ + +/* facility codes */ +#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 */ + +/* Masks to extract parts */ +#define LOG_PRIMASK 0x07 /* mask to extract priority part */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + +/* Port number */ +#define SYSLOG_PORT 514 + +void xp_set_loghost(const char *hostname); +void xp_openlog(const char *ident, int logopt, int facility); +void xp_vsyslog(int priority, const char *message, va_list va); +void xp_syslog(int priority, const char *message, ...); + +#endif -- GitLab