|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Copyright (c) 2005 Christophe Varoqui
|
|
Packit Service |
0af388 |
* Copyright (c) 2005 Benjamin Marzinski, Redhat
|
|
Packit Service |
0af388 |
* Copyright (c) 2005 Jun'ichi Nomura, NEC
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
#include <stdio.h>
|
|
Packit Service |
0af388 |
#include <stdlib.h>
|
|
Packit Service |
0af388 |
#include <stdarg.h>
|
|
Packit Service |
0af388 |
#include <string.h>
|
|
Packit Service |
0af388 |
#include <syslog.h>
|
|
Packit Service |
0af388 |
#include <time.h>
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#include "memory.h"
|
|
Packit Service |
0af388 |
#include "log.h"
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define ALIGN(len, s) (((len)+(s)-1)/(s)*(s))
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
struct logarea* la;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#if LOGDBG
|
|
Packit Service |
0af388 |
static void dump_logarea (void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct logmsg * msg;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
logdbg(stderr, "\n==== area: start addr = %p, end addr = %p ====\n",
|
|
Packit Service |
0af388 |
la->start, la->end);
|
|
Packit Service |
0af388 |
logdbg(stderr, "|addr |next |prio|msg\n");
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
for (msg = (struct logmsg *)la->head; (void *)msg != la->tail;
|
|
Packit Service |
0af388 |
msg = msg->next)
|
|
Packit Service |
0af388 |
logdbg(stderr, "|%p |%p |%i |%s\n", (void *)msg, msg->next,
|
|
Packit Service |
0af388 |
msg->prio, (char *)&msg->str);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
logdbg(stderr, "|%p |%p |%i |%s\n", (void *)msg, msg->next,
|
|
Packit Service |
0af388 |
msg->prio, (char *)&msg->str);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
logdbg(stderr, "\n\n");
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
#endif
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int logarea_init (int size)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
logdbg(stderr,"enter logarea_init\n");
|
|
Packit Service |
0af388 |
la = (struct logarea *)MALLOC(sizeof(struct logarea));
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (!la)
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (size < MAX_MSG_SIZE)
|
|
Packit Service |
0af388 |
size = DEFAULT_AREA_SIZE;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
la->start = MALLOC(size);
|
|
Packit Service |
0af388 |
if (!la->start) {
|
|
Packit Service |
0af388 |
FREE(la);
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
memset(la->start, 0, size);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
la->empty = 1;
|
|
Packit Service |
0af388 |
la->end = la->start + size;
|
|
Packit Service |
0af388 |
la->head = la->start;
|
|
Packit Service |
0af388 |
la->tail = la->start;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
la->buff = MALLOC(MAX_MSG_SIZE + sizeof(struct logmsg));
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (!la->buff) {
|
|
Packit Service |
0af388 |
FREE(la->start);
|
|
Packit Service |
0af388 |
FREE(la);
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
int log_init(char *program_name, int size)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
logdbg(stderr,"enter log_init\n");
|
|
Packit Service |
0af388 |
openlog(program_name, 0, LOG_DAEMON);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (logarea_init(size))
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
void free_logarea (void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
FREE(la->start);
|
|
Packit Service |
0af388 |
FREE(la->buff);
|
|
Packit Service |
0af388 |
FREE(la);
|
|
Packit Service |
0af388 |
return;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
void log_close (void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
free_logarea();
|
|
Packit Service |
0af388 |
closelog();
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
void log_reset (char *program_name)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
closelog();
|
|
Packit Service |
0af388 |
tzset();
|
|
Packit Service |
0af388 |
openlog(program_name, 0, LOG_DAEMON);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
int log_enqueue (int prio, const char * fmt, va_list ap)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int len, fwd;
|
|
Packit Service |
0af388 |
char buff[MAX_MSG_SIZE];
|
|
Packit Service |
0af388 |
struct logmsg * msg;
|
|
Packit Service |
0af388 |
struct logmsg * lastmsg;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
lastmsg = (struct logmsg *)la->tail;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (!la->empty) {
|
|
Packit Service |
0af388 |
fwd = sizeof(struct logmsg) +
|
|
Packit Service |
0af388 |
strlen((char *)&lastmsg->str) * sizeof(char) + 1;
|
|
Packit Service |
0af388 |
la->tail += ALIGN(fwd, sizeof(void *));
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
vsnprintf(buff, MAX_MSG_SIZE, fmt, ap);
|
|
Packit Service |
0af388 |
len = ALIGN(sizeof(struct logmsg) + strlen(buff) * sizeof(char) + 1,
|
|
Packit Service |
0af388 |
sizeof(void *));
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* not enough space on tail : rewind */
|
|
Packit Service |
0af388 |
if (la->head <= la->tail && len > (la->end - la->tail)) {
|
|
Packit Service |
0af388 |
logdbg(stderr, "enqueue: rewind tail to %p\n", la->tail);
|
|
Packit Service |
0af388 |
if (la->head == la->start ) {
|
|
Packit Service |
0af388 |
logdbg(stderr, "enqueue: can not rewind tail, drop msg\n");
|
|
Packit Service |
0af388 |
la->tail = lastmsg;
|
|
Packit Service |
0af388 |
return 1; /* can't reuse */
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
la->tail = la->start;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (la->empty)
|
|
Packit Service |
0af388 |
la->head = la->start;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* not enough space on head : drop msg */
|
|
Packit Service |
0af388 |
if (la->head > la->tail && len >= (la->head - la->tail)) {
|
|
Packit Service |
0af388 |
logdbg(stderr, "enqueue: log area overrun, drop msg\n");
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (!la->empty)
|
|
Packit Service |
0af388 |
la->tail = lastmsg;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* ok, we can stage the msg in the area */
|
|
Packit Service |
0af388 |
la->empty = 0;
|
|
Packit Service |
0af388 |
msg = (struct logmsg *)la->tail;
|
|
Packit Service |
0af388 |
msg->prio = prio;
|
|
Packit Service |
0af388 |
memcpy((void *)&msg->str, buff, strlen(buff) + 1);
|
|
Packit Service |
0af388 |
lastmsg->next = la->tail;
|
|
Packit Service |
0af388 |
msg->next = la->head;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
logdbg(stderr, "enqueue: %p, %p, %i, %s\n", (void *)msg, msg->next,
|
|
Packit Service |
0af388 |
msg->prio, (char *)&msg->str);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#if LOGDBG
|
|
Packit Service |
0af388 |
dump_logarea();
|
|
Packit Service |
0af388 |
#endif
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
int log_dequeue (void * buff)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct logmsg * src = (struct logmsg *)la->head;
|
|
Packit Service |
0af388 |
struct logmsg * dst = (struct logmsg *)buff;
|
|
Packit Service |
0af388 |
struct logmsg * lst = (struct logmsg *)la->tail;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (la->empty)
|
|
Packit Service |
0af388 |
return 1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
int len = strlen((char *)&src->str) * sizeof(char) +
|
|
Packit Service |
0af388 |
sizeof(struct logmsg) + 1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
dst->prio = src->prio;
|
|
Packit Service |
0af388 |
memcpy(dst, src, len);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (la->tail == la->head)
|
|
Packit Service |
0af388 |
la->empty = 1; /* we purge the last logmsg */
|
|
Packit Service |
0af388 |
else {
|
|
Packit Service |
0af388 |
la->head = src->next;
|
|
Packit Service |
0af388 |
lst->next = la->head;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
logdbg(stderr, "dequeue: %p, %p, %i, %s\n",
|
|
Packit Service |
0af388 |
(void *)src, src->next, src->prio, (char *)&src->str);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
memset((void *)src, 0, len);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* this one can block under memory pressure
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
void log_syslog (void * buff)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct logmsg * msg = (struct logmsg *)buff;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
syslog(msg->prio, "%s", (char *)&msg->str);
|
|
Packit Service |
0af388 |
}
|