Skip to content
Snippets Groups Projects
Commit d1f82d7e authored by deuce's avatar deuce
Browse files

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.
parent 0ba3699d
No related branches found
No related tags found
No related merge requests found
#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);
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment