Files
m241Neelima/components/ip_net2-6.9/ipcom/src/ipcom_syslogd.c
T
2026-07-30 11:19:44 +05:30

996 lines
27 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_syslogd.c,v $ $Revision: 1.97.10.5 $
* $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_syslogd.c,v $
* $Author: csun $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipcom_config.h"
/* Default syslog daemon flags. */
#define IPCOM_SYSLOG_FLAGS (IP_LOG_PID)
/* Optimize syslog on memory instead of speed. */
#define IPCOM_SYSLOG_MEM_OPT
/* Define to enable syslog file system support */
#if IPCOM_USE_FILE != IPCOM_FILE_NONE && !defined(IP_PORT_OSE5)
#define IPCOM_SYSLOG_FILE
#endif
/* Define to enable syslog UDP system support */
#if IPCOM_USE_SOCK != IPCOM_SOCK_NONE
#ifdef IP_DEBUG
#define IPCOM_SYSLOG_UDP
#endif
#endif
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_clib.h"
#include "ipcom_clib2.h"
#include "ipcom_time.h"
#include "ipcom_os.h"
#include "ipcom_syslog.h"
#include "ipcom_err.h"
#include "ipcom_sysvar.h"
#include "ipcom_shell.h"
#ifdef IPCOM_SYSLOG_UDP
#include "ipcom_sock.h"
#include "ipcom_inet.h"
#endif
#include <stdarg.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* Maximum size of a syslog ident. */
#define IPCOM_SYSLOG_MAX_IDENT 16
#ifdef IPCOM_USE_TIME
#define IPCOM_SYSLOGD_TIMESTRING_LEN (32 + 2)
#endif
#ifndef IPCOM_SYSLOG_FILE_MAXSIZE
#define IPCOM_SYSLOG_FILE_MAXSIZE 32768
#endif
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
*===========================================================================
* Ipcom_syslog_entry
*===========================================================================
*/
typedef struct Ipcom_syslog_entry_struct
{
#ifdef IP_ASSERT
Ip_u32 magic;
#endif
struct Ipcom_syslog_entry_struct *next;
Ip_u32 priority;
Ip_u32 missed;
Ip_pid_t pid; /* optional, 0 if not set. */
int loglen;
Ip_u8 logdata[3]; /* 3 bytes space for \n\r and \0. */
}
Ipcom_syslog_entry;
/*
*===========================================================================
* Ipcom_syslog_facility
*===========================================================================
*/
typedef struct Ipcom_syslog_facility_struct
{
Ip_u32 flags;
Ip_u16 hdr_space;
Ip_s16 priority;
char buf[IPCOM_SYSLOG_MAX_IDENT+1];
}
Ipcom_syslog_facility;
/*
*===========================================================================
* ipcom_syslogd_data
*===========================================================================
*/
typedef struct Ipcom_syslogd_data_struct
{
Ipcom_syslog_facility *logf[IPCOM_LOG_FACILITY_MAX];
Ipcom_ipc ipc;
int q_num;
int q_max;
Ip_u32 missed;
#ifdef IPCOM_SYSLOG_FILE
int file_size;
char *file_name;
IP_FILE *file_fp;
int file_tries;
Ip_size_t file_maxsize;
#endif
#ifdef IPCOM_SYSLOG_UDP
union Ip_sockaddr_union udp_addr;
Ip_fd udp_fd;
#endif
}
Ipcom_syslogd_data;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC Ip_err ipcom_syslogd_init(void *ununsed);
IP_PUBLIC Ip_err ipcom_syslogd_start(void);
IP_PUBLIC void ipcom_vsyslog(Ip_u32 priority, const char *format, va_list ap);
IP_STATIC IPCOM_PROCESS(ipcom_syslogd);
IP_STATIC Ip_u32 ipcom_checklog(Ip_u32 priority, Ip_u32 *missedp, Ip_u32 *flagsp);
/* ipcom_adjustlog() must be called for each ipcom_checklog() that does not
* result in ipcom_syslogd_syslog() being called or the size of the syslog
* queue will be corrupt (too large).
*/
IP_STATIC void ipcom_adjustlog(Ip_u32 missed);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC Ipcom_syslogd_data ipcom_logd;
IP_STATIC Ipcom_once_t ipcom_syslogd_once = IPCOM_ONCE_INIT;
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_checklog
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_u32
ipcom_checklog(Ip_u32 priority, Ip_u32 *missedp, Ip_u32 *flagsp)
{
Ipcom_syslog_facility *fcy;
Ip_u32 facility;
Ip_u32 msr;
Ip_u32 hdr_space = 0;
if (ipcom_once(&ipcom_syslogd_once, ipcom_syslogd_init, IP_NULL) != IPCOM_SUCCESS)
return 0;
ip_assert(ipcom_logd.q_max >= 20);
/* syslogd queue full. */
if ((ipcom_logd.q_num + ((int)IPCOM_LOG_PRI(priority) * ipcom_logd.q_max / 20)) >= ipcom_logd.q_max)
{
msr = ipcom_interrupt_disable();
ipcom_logd.missed++;
goto leave;
}
/* Invalid facility, ignore. */
facility = IPCOM_LOG_FAC(priority);
if (facility >= IPCOM_LOG_FACILITY_MAX)
return 0;
msr = ipcom_interrupt_disable();
if (ipcom_logd.logf[facility] == IP_NULL)
{
ipcom_interrupt_enable(msr);
ipcom_openlog(IP_NULL, 0, facility << 3);
msr = ipcom_interrupt_disable();
}
fcy = ipcom_logd.logf[facility];
ip_assert(fcy != IP_NULL);
/* Not logging this priority. */
if ((Ip_s16)IPCOM_LOG_PRI(priority) > fcy->priority)
goto leave;
/* Return the number of missed logs. */
ipcom_logd.q_num++;
*missedp = ipcom_logd.missed;
ipcom_logd.missed = 0;
*flagsp = fcy->flags;
hdr_space = (Ip_u32)fcy->hdr_space;
leave:
ipcom_interrupt_enable(msr);
return hdr_space;
}
/*
*===========================================================================
* ipcom_adjustlog
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipcom_adjustlog(Ip_u32 missed)
{
Ip_u32 msr;
msr = ipcom_interrupt_disable();
ipcom_logd.q_num--;
ipcom_logd.missed += (missed + 1);
ipcom_interrupt_enable(msr);
}
/*
*===========================================================================
* ipcom_syslogd_log
*===========================================================================
* Description: Called by syslogd daemon to log syslog.
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipcom_syslogd_log(const char *output, Ip_u32 priority)
{
#if defined(IPCOM_SYSLOG_FILE) || defined(IPCOM_SYSLOG_UDP)
int len = (int)ipcom_strlen(output);
#endif
#ifdef IPCOM_SYSLOG_FILE
ipcom_logd.file_maxsize = (Ip_size_t)ipcom_sysvar_get_as_int("ipcom.syslogd.file.max", IPCOM_SYSLOG_FILE_MAXSIZE);
ipcom_logd.file_maxsize = IP_MAX(1024, ipcom_logd.file_maxsize);
#endif
/*********** Debug printf ***********/
#ifdef IP_DEBUG
(void)ipcom_debug_printf("%s", output);
#endif
/*********** File system ***********/
#ifdef IPCOM_SYSLOG_FILE
if (ipcom_logd.file_name != IP_NULL)
{
if (ipcom_logd.file_fp == IP_NULL)
{
char buf[48];
/* No syslog file open, remove old backup and create new. */
ipcom_snprintf(buf, sizeof(buf), "%s.0", ipcom_logd.file_name);
(void)ipcom_unlink(buf);
(void)ipcom_rename(ipcom_logd.file_name, buf);
ipcom_logd.file_size = 0;
/* Create new syslog file. */
file_retry:
ipcom_logd.file_fp = ipcom_fopen(ipcom_logd.file_name, "w");
if (ipcom_logd.file_fp == IP_NULL)
{
#ifdef IP_DEBUG
(void)ipcom_debug_printf("IPCOM SYSLOG WARNING: failed to open syslog file '%s'\n",
ipcom_logd.file_name);
#endif /* IP_DEBUG */
++ipcom_logd.file_tries;
if (ipcom_logd.file_tries < 5)
{
ipcom_millisleep((unsigned int) (ipcom_logd.file_tries * 100));
goto file_retry;
}
if (ipcom_logd.file_tries > 20)
{
ipcom_free(ipcom_logd.file_name); /* to avoid excessive spam */
ipcom_logd.file_name = IP_NULL;
}
}
}
if (ipcom_logd.file_fp != IP_NULL)
{
/* Write file to disk. Flush output to make sure written. */
(void)ipcom_fprintf(ipcom_logd.file_fp, "%s", output);
(void)ipcom_fflush(ipcom_logd.file_fp);
/* Check max size to not overflow disk. */
ipcom_logd.file_size += len;
if (ipcom_logd.file_size > (int)ipcom_logd.file_maxsize)
{
/* syslog reached max size, close file to create a backup. */
(void)ipcom_fclose(ipcom_logd.file_fp);
ipcom_logd.file_fp = IP_NULL;
}
}
}
#endif /* IPCOM_SYSLOG_FILE */
#ifdef IPCOM_SYSLOG_UDP
if (ipcom_logd.udp_addr.sa.sa_family != 0
&& IPCOM_LOG_FAC(priority) != IPCOM_LOG_FAC(IPCOM_LOG_IPNET)
&& IPCOM_LOG_FAC(priority) != IPCOM_LOG_FAC(IPCOM_LOG_IPLITE)
&& IPCOM_LOG_FAC(priority) != IPCOM_LOG_FAC(IPCOM_LOG_IPIPSEC)
&& IPCOM_LOG_FAC(priority) != IPCOM_LOG_FAC(IPCOM_LOG_IPFIREWALL)
&& IPCOM_LOG_FAC(priority) != IPCOM_LOG_FAC(IPCOM_LOG_IPPPP))
{
if (ipcom_logd.udp_fd == IP_INVALID_SOCKET)
{
ipcom_logd.udp_fd = ipcom_socket(ipcom_logd.udp_addr.sa.sa_family, IP_SOCK_DGRAM, 0);
if (ipcom_logd.udp_fd != IP_INVALID_SOCKET)
{
/* Connect to destination. */
if (ipcom_connect(ipcom_logd.udp_fd, (struct Ip_sockaddr *)&ipcom_logd.udp_addr, IPCOM_SA_LEN_GET(&ipcom_logd.udp_addr.sa)) == IP_SOCKERR)
{
ipcom_socketclose(ipcom_logd.udp_fd);
ipcom_logd.udp_fd = IP_INVALID_SOCKET;
}
}
}
if (ipcom_logd.udp_fd != IP_INVALID_SOCKET)
{
(void)ipcom_socketwrite(ipcom_logd.udp_fd, (IP_CONST void *)output, (Ip_size_t)len);
}
}
#else
(void)priority;
#endif /* IPCOM_SYSLOG_UDP */
}
/*
*===========================================================================
* ipcom_syslogd
*===========================================================================
*/
IP_STATIC
IPCOM_PROCESS(ipcom_syslogd)
{
Ip_err ret;
Ipcom_syslog_entry *se;
char buf[128];
ipcom_proc_init();
(void)ipcom_ipc_install();
#ifdef IP_PORT_VXWORKS
/* Wait a while so that the vxWorks logo is printed before we start to output
* syslog entries. Otherwise the output becomes garbled and virtually unreadable.
*/
ipcom_millisleep(3000);
#endif
for (;;)
{
int i, len;
Ip_u32 msr;
Ip_u8 *logdata;
#ifdef IPCOM_USE_TIME
char tbuf[26];
Ip_time_t ct;
char *tmstr;
#endif
Ip_u16 fcy_hdr_space;
char fcy_buf[IPCOM_SYSLOG_MAX_IDENT+1];
ret = ipcom_ipc_receive(IP_NULL, &se, -1);
if (ret != IPCOM_SUCCESS)
continue;
ip_assert(se != IP_NULL);
ip_assert(se->magic == 0x07413370);
i = 0;
/* Do checklog if it hasn't already been done by the client */
if ((int)se->missed < 0)
{
Ip_u32 flags;
/* The 'missed' entry really contains the used header space */
i = -(int)se->missed;
/* Do an 11'th hour checklog */
if (ipcom_checklog(se->priority, &se->missed, &flags) <= 0)
{
/* Ignore this log request */
ipcom_ipc_free(se);
continue;
}
if (!IP_BIT_ISSET(flags, IP_LOG_PID))
{
se->pid = 0;
}
}
/* First print number of missed log entries. */
if (se->missed > 0)
{
ipcom_sprintf(buf, "*** lost %ld log entries ***\n", se->missed);
(void)ipcom_syslogd_log(buf, IPCOM_LOG_SYSLOG | IPCOM_LOG_INFO);
}
/* Get facility info. */
msr = ipcom_interrupt_disable();
ipcom_logd.q_num--;
{
Ipcom_syslog_facility *fcy;
fcy = ipcom_logd.logf[se->priority >> 3];
if (fcy != IP_NULL)
{
fcy_hdr_space = fcy->hdr_space;
ipcom_strcpy(fcy_buf, fcy->buf);
}
else
fcy_hdr_space = 0xffff;
}
ipcom_interrupt_enable(msr);
if (fcy_hdr_space == 0xffff)
{
ipcom_ipc_free(se);
continue;
}
if (i == 0)
i = fcy_hdr_space;
logdata = &se->logdata[0];
/* Append linefeed and null-terminate. */
BOUNDS_CHECKING_OFF;
logdata[(long)(i + se->loglen)] = '\n';
logdata[(long)(i + se->loglen+1)] = '\0';
/* Prepend priority text string. */
len = (int)ipcom_strlen(ipcom_syslog_priority_names[se->priority & 0x7]) + 2;
ipcom_strcpy((char *)logdata + i - len, ipcom_syslog_priority_names[se->priority & 0x7]);
logdata[i - 1] = ' ';
logdata[i - 2] = ':';
i -= len;
ip_assert(i >= 0);
/* Prepend ': ' in preparation for facility string & optional hex [pid] */
logdata[i - 1] = ' ';
logdata[i - 2] = ':';
i -= 2;
ip_assert(i >= 0);
/* Optionally prepend pid string. */
if (se->pid != 0)
{
len = ipcom_sprintf(buf, "[%lx]", (Ip_u32)se->pid);
ipcom_memcpy((char *)logdata + i - len, buf, (Ip_size_t)len);
i -= len;
ip_assert(i >= 0);
}
/* Prepend facility text string. */
len = (int)ipcom_strlen(fcy_buf); /*lint !e645 Symbol 'fcy_buf' may not have been initialized */
ipcom_memcpy((char *)logdata + i - len, fcy_buf, (Ip_size_t)len);
i -= len;
ip_assert(i >= 0);
/* Optionally prepend time. */
#ifdef IPCOM_USE_TIME
ct = ipcom_time(0);
tmstr = ipcom_ctime_r(&ct, tbuf);
len = (int)ipcom_strlen(tmstr) + 1; /* only +1 due to internal linefeed. */
ip_assert((i - len) >= 0);
ipcom_strcpy((char *)logdata + i - len, tmstr);
logdata[i - 1] = ' ';
logdata[i - 2] = ':';
i -= len;
#endif /* IPCOM_USE_TIME */
BOUNDS_CHECKING_ON;
/* Log */
ipcom_syslogd_log((const char *)logdata + i, se->priority);
/* Free IPC buffer. */
ipcom_ipc_free(se);
} /* for(;;) */
/* Remember this if we in the future would like to shut down the daemon
* ipcom_proc_exit();
*/
}
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_openlog
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void
ipcom_openlog(const char *ident, Ip_u32 option, Ip_u32 facility)
{
Ipcom_syslog_facility *fcy;
Ip_u32 msr;
(void)option;
if (ipcom_once(&ipcom_syslogd_once, ipcom_syslogd_init, IP_NULL) != IPCOM_SUCCESS)
{
IP_PANIC();
return;
}
facility = IPCOM_LOG_FAC(facility);
if (facility >= IPCOM_LOG_FACILITY_MAX)
return;
msr = ipcom_interrupt_disable();
if (ipcom_logd.logf[facility] != IP_NULL)
goto leave;
ipcom_interrupt_enable(msr);
fcy = ipcom_malloc(sizeof(Ipcom_syslog_facility));
if (fcy == IP_NULL)
goto leave;
/* Initiliaze facility entry. */
ipcom_memset(fcy, 0, sizeof(Ipcom_syslog_facility));
fcy->priority = (Ip_s16)ipcom_sysvar_get_as_int("ipcom.syslogd.default_priority", IPCOM_LOG_INFO);
fcy->hdr_space = IPCOM_LOG_PRI_MAXLEN + 10; /* 10 = [hex pid] */
#ifdef IPCOM_SYSLOG_FLAGS
fcy->flags = IPCOM_SYSLOG_FLAGS;
#endif
if (ident != IP_NULL)
ipcom_strncpy(fcy->buf, ident, IPCOM_SYSLOG_MAX_IDENT);
else
ipcom_strncpy(fcy->buf, ipcom_syslog_facility_names[facility], IPCOM_SYSLOG_MAX_IDENT);
fcy->hdr_space = (Ip_u16) (fcy->hdr_space + (Ip_u16) (ipcom_strlen(fcy->buf) + 2));
#ifdef IPCOM_USE_TIME
fcy->hdr_space = (Ip_u16) (fcy->hdr_space + IPCOM_SYSLOGD_TIMESTRING_LEN);
#endif
/* Store facility entry. */
msr = ipcom_interrupt_disable();
ip_assert(ipcom_logd.logf[facility] == IP_NULL);
ipcom_logd.logf[facility] = fcy;
leave:
ipcom_interrupt_enable(msr);
}
/*
*===========================================================================
* ipcom_closelog
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void
ipcom_closelog(void)
{
/* Since we got no facility we can't close the logs...bah! */
}
/*
*===========================================================================
* ipcom_setlogmask_on
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_setlogmask_on(int maskpri, Ip_u32 facility)
{
Ipcom_syslog_facility *fcy;
int old_priority = -1;
Ip_u32 msr;
facility = IPCOM_LOG_FAC(facility);
if (facility >= IPCOM_LOG_FACILITY_MAX)
return -1;
msr = ipcom_interrupt_disable();
#ifdef IP_PORT_OSE5
if (ipcom_logd.logf[facility] == IP_NULL)
{
ipcom_interrupt_enable(msr);
ipcom_openlog(IP_NULL, 0, facility << 3);
msr = ipcom_interrupt_disable();
}
#endif
fcy = ipcom_logd.logf[facility];
if (fcy != IP_NULL)
{
old_priority = fcy->priority;
fcy->priority = (Ip_s16)IPCOM_LOG_PRI(maskpri);
}
ipcom_interrupt_enable(msr);
return old_priority;
}
/*
*===========================================================================
* ipcom_getlogmask_on
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_getlogmask_on(Ip_u32 facility)
{
Ipcom_syslog_facility *fcy;
int priority = -1;
Ip_u32 msr;
facility = IPCOM_LOG_FAC(facility);
if (facility >= IPCOM_LOG_FACILITY_MAX)
return -1;
msr = ipcom_interrupt_disable();
#ifdef IP_PORT_OSE5
if (ipcom_logd.logf[facility] == IP_NULL)
{
ipcom_interrupt_enable(msr);
ipcom_openlog(IP_NULL, 0, facility << 3);
msr = ipcom_interrupt_disable();
}
#endif
fcy = ipcom_logd.logf[facility];
if (fcy != IP_NULL)
priority = fcy->priority;
ipcom_interrupt_enable(msr);
return priority;
}
/*
*===========================================================================
* ipcom_setlogfile
*===========================================================================
* Description: Set logfile.
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_setlogfile(const char *file)
{
#ifdef IPCOM_SYSLOG_FILE
if (ipcom_once(&ipcom_syslogd_once, ipcom_syslogd_init, IP_NULL) != IPCOM_SUCCESS)
{
IP_PANIC();
return 0;
}
if (ipcom_logd.file_name != IP_NULL)
{
ipcom_free(ipcom_logd.file_name);
ipcom_logd.file_name = IP_NULL;
}
if (ipcom_logd.file_fp != IP_NULL)
{
(void)ipcom_fclose(ipcom_logd.file_fp);
ipcom_logd.file_fp = IP_NULL;
}
if (file != IP_NULL)
{
ipcom_logd.file_name = ipcom_strdup(file);
if (ipcom_logd.file_name == IP_NULL)
return -1;
}
#else
(void)file;
#endif
return 0;
}
/*
*===========================================================================
* ipcom_setlogudp
*===========================================================================
* Description: Set log IP address & port for UDP syslog output.
* Parameters:
* Returns:
*
*/
IP_PUBLIC int
ipcom_setlogudp(const char *ipaddr, Ip_u16 port)
{
#ifdef IPCOM_SYSLOG_UDP
if (ipcom_once(&ipcom_syslogd_once, ipcom_syslogd_init, IP_NULL) != IPCOM_SUCCESS)
{
IP_PANIC();
return 0;
}
if (ipaddr != IP_NULL && port != 0)
{
int ret;
#ifdef IPCOM_USE_INET6
if (ipcom_strchr(ipaddr, ':'))
{
ret = ipcom_getsockaddrbyaddrname(IP_AF_INET6, IP_FALSE /* no DNS */, (IP_CONST char *)ipaddr, &ipcom_logd.udp_addr.sa);
ipcom_logd.udp_addr.sin6.sin6_port = ip_htons(port);
if (ret != 0)
return -1;
}
#endif
#ifdef IPCOM_USE_INET
ret = ipcom_getsockaddrbyaddrname(IP_AF_INET, IP_FALSE /* no DNS */, (IP_CONST char *)ipaddr, &ipcom_logd.udp_addr.sa);
ipcom_logd.udp_addr.sin.sin_port = ip_htons(port);
if (ret != 0)
return -1;
#endif
}
else
ipcom_logd.udp_addr.sa.sa_family = 0; /* disabled */
if (ipcom_logd.udp_fd != IP_INVALID_SOCKET)
{
(void)ipcom_socketclose(ipcom_logd.udp_fd);
ipcom_logd.udp_fd = IP_INVALID_SOCKET;
}
#else
(void)ipaddr;
(void)port;
#endif /* IPCOM_SYSLOG_UDP */
return 0;
}
/*
*===========================================================================
* ipcom_vsyslog
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void
ipcom_vsyslog(Ip_u32 priority, const char *format, va_list ap)
{
Ip_u32 hdr_space;
Ip_u32 missed, flags;
Ip_err retval;
hdr_space = ipcom_checklog(priority, &missed, &flags);
if (hdr_space > 0)
{
Ipcom_syslog_entry *se;
char *logdata;
int loglen;
#ifdef IPCOM_SYSLOG_MEM_OPT
static char buf[IPCOM_SYSLOG_MAX_SIZE+1];
loglen = ipcom_vsnprintf(buf, IPCOM_SYSLOG_MAX_SIZE, format, ap);
/* Some vsnprintf return -1 if buffer is full, i.e. we will
* not even get the truncated output, bah!
*/
if (loglen <= 0)
{
ipcom_adjustlog(missed);
return;
}
se = ipcom_ipc_malloc(sizeof(Ipcom_syslog_entry) + (Ip_size_t)hdr_space + (Ip_size_t)loglen);
if (se == IP_NULL)
return;
logdata = (char *)&se->logdata[0];
ipcom_memcpy(logdata + hdr_space, buf, IP_MIN((Ip_size_t) loglen, sizeof(buf)));
#else
se = ipcom_ipc_malloc(sizeof(Ipcom_syslog_entry) + hdr_space + IPCOM_SYSLOG_MAX_SIZE);
if (se == IP_NULL)
return;
logdata = (char *)&se->logdata[0];
loglen = ipcom_vsnprintf(logdata + hdr_space, IPCOM_SYSLOG_MAX_SIZE, format, ap);
/* Some vsnprintf return -1 if buffer is full, i.e. we will
* not even get the truncated output, bah!
*/
if (loglen <= 0)
{
ipcom_adjustlog(missed);
ipcom_ipc_free(se);
return;
}
#endif /* IPCOM_SYSLOG_MEM_OPT */
/* C99 standard -> truncated. */
if (loglen >= IPCOM_SYSLOG_MAX_SIZE)
{
loglen = IPCOM_SYSLOG_MAX_SIZE;
logdata[hdr_space + IPCOM_SYSLOG_MAX_SIZE - 1] = '*';
}
IP_ASSERTLINE(se->magic = 0x07413370);
se->priority = priority;
se->loglen = loglen;
se->missed = missed;
if (IP_BIT_ISSET(flags, IP_LOG_PID))
se->pid = ipcom_getpid();
else
se->pid = 0;
/* Send log entry to syslog daemon. */
while (ipcom_ipc_isopen(&ipcom_logd.ipc) == IP_FALSE)
{
ipcom_millisleep(10);
}
retval = ipcom_ipc_send(&ipcom_logd.ipc, se);
ip_assert(retval == IPCOM_SUCCESS);
(void)retval;
}
}
/*
*===========================================================================
* ipcom_syslog
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
#if !defined(IPCOM_SYSLOG) || IPCOM_SYSLOG == 1
IP_PUBLIC void
ipcom_syslog(Ip_u32 priority, const char *format, ...)
{
va_list ap;
va_start(ap, format);
ipcom_vsyslog(priority, format, ap);
va_end(ap);
}
#endif
/*
*===========================================================================
* ipcom_syslogd_init
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_PUBLIC Ip_err
ipcom_syslogd_init(void *ununsed)
{
Ipcom_proc_attr attr;
Ip_err retval;
(void)ununsed;
ipcom_memset(&ipcom_logd, 0, sizeof(Ipcom_syslogd_data));
ipcom_logd.q_max = ipcom_sysvar_get_as_int("ipcom.syslogd.queue.max", 128);
ipcom_logd.q_max = IP_MAX(20, ipcom_logd.q_max);
#ifdef IPCOM_SYSLOG_FILE
ipcom_logd.file_maxsize = (Ip_size_t)ipcom_sysvar_get_as_int("ipcom.syslogd.file.max", IPCOM_SYSLOG_FILE_MAXSIZE);
ipcom_logd.file_maxsize = IP_MAX(1024, ipcom_logd.file_maxsize);
#endif
#ifdef IPCOM_SYSLOG_UDP
ipcom_logd.udp_fd = IP_INVALID_SOCKET;
#endif
ipcom_proc_attr_init(&attr);
#ifdef IP_DEBUG
attr.priority = IPCOM_PRIORITY_MAX;
#endif
retval = ipcom_proc_acreate("ipcom_syslogd", ipcom_syslogd, &attr, IP_NULL);
if (retval != IPCOM_SUCCESS)
return retval;
retval = ipcom_ipc_open(&ipcom_logd.ipc, "ipcom_syslogd", -1);
ip_assert(retval == IPCOM_SUCCESS);
return retval;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/