1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/** \file shared/report.c
* Contains reporting functions.
*/
/*-
* This file is part of LCDproc.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Selene Scriven
* 2001, Joris Robijn
* 2005, Peter Marschall
*/
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "report.h"
static int report_level = RPT_INFO;
static int report_dest = RPT_DEST_STORE;
#define MAX_STORED_MSGS 200
static char *stored_msgs[MAX_STORED_MSGS];
static int stored_levels[MAX_STORED_MSGS];
static int num_stored_msgs = 0;
/* local functions */
static void store_report_message(int level, const char *message);
static void flush_messages();
void
report(const int level, const char *format,... /* args */ )
{
/* Check if we should report it */
if (level <= report_level || report_dest == RPT_DEST_STORE) {
char buf[1024];
/*
* Following functions appear to work on RedHat and Debian
* Linux, FreeBSD and Solaris
*/
va_list ap;
va_start(ap, format);
switch (report_dest) {
case RPT_DEST_STDERR:
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
break;
case RPT_DEST_SYSLOG:
vsyslog(LOG_USER | (level + 2), format, ap);
break;
case RPT_DEST_STORE:
vsnprintf(buf, sizeof(buf), format, ap);
buf[sizeof(buf) - 1] = 0;
store_report_message(level, buf);
break;
}
va_end(ap);
}
}
int
set_reporting(char *application_name, int new_level, int new_dest)
{
if (new_level < RPT_CRIT || new_level > RPT_DEBUG) {
report(RPT_ERR, "report level invalid: %d", new_level);
return -1;
}
if (report_dest != RPT_DEST_SYSLOG && new_dest == RPT_DEST_SYSLOG) {
openlog(application_name, 0, LOG_USER);
}
else if (report_dest == RPT_DEST_SYSLOG && new_dest != RPT_DEST_SYSLOG) {
closelog();
}
report_level = new_level;
report_dest = new_dest;
/*
* Flush all messages currently in the message store if the new
* destination is not the store itself.
*/
if (report_dest != RPT_DEST_STORE)
flush_messages();
return 0;
}
/**
* Puts a message into the message store. If the store is full new messages
* are silently discarded.
*/
static void
store_report_message(int level, const char *message)
{
if (num_stored_msgs < MAX_STORED_MSGS) {
stored_msgs[num_stored_msgs] = malloc(strlen(message) + 1);
strcpy(stored_msgs[num_stored_msgs], message);
stored_levels[num_stored_msgs] = level;
num_stored_msgs++;
}
}
/**
* Report all messages contained in the message store to the current report
* destination and release their memory.
*/
static void
flush_messages()
{
int i;
for (i = 0; i < num_stored_msgs; i++) {
report(stored_levels[i], "%s", stored_msgs[i]);
free(stored_msgs[i]);
}
num_stored_msgs = 0;
}
|