summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spencer <markster@digium.com>2004-01-12 05:05:35 +0000
committerMark Spencer <markster@digium.com>2004-01-12 05:05:35 +0000
commitee342cc3b80db292625e41019a3afd8bb4cdc568 (patch)
tree02f9ec032bd53fec6e9b9004db327ad9991cf73a
parent5520872def04f3fe7cc61f23edf4b9c87007a02d (diff)
Add ww's improved syslog support (bug #587)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1973 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rwxr-xr-xasterisk.c31
-rwxr-xr-xconfigs/logger.conf.sample7
-rwxr-xr-xinclude/asterisk/logger.h36
-rwxr-xr-xlogger.c489
-rwxr-xr-xpbx/pbx_config.c20
5 files changed, 352 insertions, 231 deletions
diff --git a/asterisk.c b/asterisk.c
index b4985e28c..6c45865ba 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -148,13 +148,34 @@ static int fdprint(int fd, const char *s)
return write(fd, s, strlen(s) + 1);
}
+/*
+ * write the string to all attached console clients
+ */
+static void ast_network_puts(const char *string)
+{
+ int x;
+ for (x=0;x<AST_MAX_CONNECTS; x++) {
+ if (consoles[x].fd > -1)
+ fdprint(consoles[x].p[1], string);
+ }
+}
+
+
+/*
+ * write the string to the console, and all attached
+ * console clients
+ */
+void ast_console_puts(const char *string)
+{
+ fputs(string, stdout);
+ fflush(stdout);
+ ast_network_puts(string);
+}
+
static void network_verboser(const char *s, int pos, int replace, int complete)
+ /* ARGUSED */
{
- int x;
- for (x=0;x<AST_MAX_CONNECTS; x++) {
- if (consoles[x].fd > -1)
- fdprint(consoles[x].p[1], s);
- }
+ ast_network_puts(s);
}
static pthread_t lthread;
diff --git a/configs/logger.conf.sample b/configs/logger.conf.sample
index 7d7e73afa..f7e32abb3 100755
--- a/configs/logger.conf.sample
+++ b/configs/logger.conf.sample
@@ -17,9 +17,6 @@ console => notice,warning,error
messages => notice,warning,error
;syslog keyword : This special keyword logs to syslog facility
-;local0 edit /etc/syslog.conf and add
-;local0.* /var/log/myastlog
;
-;syslog => notice,warning,error
-
-
+;syslog.local0 => notice,warning,error
+;
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index 62eb34f65..9278e2b54 100755
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -54,13 +54,39 @@ extern void ast_verbose(const char *fmt, ...)
extern int ast_register_verbose(void (*verboser)(const char *string, int opos, int replacelast, int complete));
extern int ast_unregister_verbose(void (*verboser)(const char *string, int opos, int replacelast, int complete));
extern int ast_verbose_dmesg(void (*verboser)(const char *string, int opos, int replacelast, int complete));
+extern void ast_console_puts(const char *string);
+
#define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
-#define LOG_DEBUG 0, _A_
-#define LOG_EVENT 1, _A_
-#define LOG_NOTICE 2, _A_
-#define LOG_WARNING 3, _A_
-#define LOG_ERROR 4, _A_
+#ifdef LOG_DEBUG
+#undef LOG_DEBUG
+#endif
+#define __LOG_DEBUG 0
+#define LOG_DEBUG __LOG_DEBUG, _A_
+
+#ifdef LOG_EVENT
+#undef LOG_EVENT
+#endif
+#define __LOG_EVENT 1
+#define LOG_EVENT __LOG_EVENT, _A_
+
+#ifdef LOG_NOTICE
+#undef LOG_NOTICE
+#endif
+#define __LOG_NOTICE 2
+#define LOG_NOTICE __LOG_NOTICE, _A_
+
+#ifdef LOG_WARNING
+#undef LOG_WARNING
+#endif
+#define __LOG_WARNING 3
+#define LOG_WARNING __LOG_WARNING, _A_
+
+#ifdef LOG_ERROR
+#undef LOG_ERROR
+#endif
+#define __LOG_ERROR 4
+#define LOG_ERROR __LOG_ERROR, _A_
#if defined(__cplusplus) || defined(c_plusplus)
}
diff --git a/logger.c b/logger.c
index 91c2743d4..d6fa6ab97 100755
--- a/logger.c
+++ b/logger.c
@@ -17,7 +17,6 @@
#include <unistd.h>
#include <time.h>
#include <asterisk/lock.h>
-#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/config.h>
@@ -28,10 +27,23 @@
#include <errno.h>
#include <pthread.h>
#include <sys/stat.h>
-#include <syslog.h>
#include "asterisk.h"
#include "astconf.h"
+#define SYSLOG_NAMES /* so we can map syslog facilities names to their numeric values,
+ from <syslog.h> which is included by logger.h */
+#include <syslog.h>
+static int syslog_level_map[] = {
+ LOG_DEBUG,
+ LOG_INFO, /* arbitrary equivalent of LOG_EVENT */
+ LOG_NOTICE,
+ LOG_WARNING,
+ LOG_ERR
+};
+#define SYSLOG_NLEVELS 5
+
+#include <asterisk/logger.h>
+
#define MAX_MSG_QUEUE 200
static ast_mutex_t msglist_lock = AST_MUTEX_INITIALIZER;
@@ -42,38 +54,38 @@ static struct msglist {
struct msglist *next;
} *list = NULL, *last = NULL;
-struct logfile {
- char fn[256];
- int logflags;
- FILE *f;
+struct logchannel {
+ int logmask;
int facility; /* syslog */
- struct logfile *next;
+ int syslog; /* syslog flag */
+ int console; /* console logging */
+ FILE *fileptr; /* logfile logging */
+ char filename[256];
+ struct logchannel *next;
};
-static struct logfile *logfiles = NULL;
+static struct logchannel *logchannels = NULL;
static int msgcnt = 0;
static FILE *eventlog = NULL;
static char *levels[] = {
- "DEBUG",
- "EVENT",
- "NOTICE",
- "WARNING",
- "ERROR"
+ "DEBUG",
+ "EVENT",
+ "NOTICE",
+ "WARNING",
+ "ERROR"
};
static int colors[] = {
- COLOR_BRGREEN,
- COLOR_BRBLUE,
- COLOR_YELLOW,
- COLOR_BRRED,
- COLOR_RED
+ COLOR_BRGREEN,
+ COLOR_BRBLUE,
+ COLOR_YELLOW,
+ COLOR_BRRED,
+ COLOR_RED
};
-
-
static int make_components(char *s, int lineno)
{
char *w;
@@ -82,120 +94,141 @@ static int make_components(char *s, int lineno)
stringp=s;
w = strsep(&stringp, ",");
while(w) {
- while(*w && (*w < 33))
- w++;
- if (!strcasecmp(w, "debug"))
- res |= (1 << 0);
- else if (!strcasecmp(w, "notice"))
- res |= (1 << 2);
- else if (!strcasecmp(w, "warning"))
- res |= (1 << 3);
- else if (!strcasecmp(w, "error"))
- res |= (1 << 4);
- else {
- fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
- }
- w = strsep(&stringp, ",");
+ while(*w && (*w < 33))
+ w++;
+ if (!strcasecmp(w, "error"))
+ res |= (1 << __LOG_ERROR);
+ else if (!strcasecmp(w, "warning"))
+ res |= (1 << __LOG_WARNING);
+ else if (!strcasecmp(w, "notice"))
+ res |= (1 << __LOG_NOTICE);
+ else if (!strcasecmp(w, "event"))
+ res |= (1 << __LOG_EVENT);
+ else if (!strcasecmp(w, "debug"))
+ res |= (1 << __LOG_DEBUG);
+ else {
+ fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
+ }
+ w = strsep(&stringp, ",");
}
return res;
}
-static struct logfile *make_logfile(char *fn, char *components, int lineno)
+static struct logchannel *make_logchannel(char *channel, char *components, int lineno)
{
- struct logfile *f;
- char tmp[256];
- if (!strlen(fn))
+ struct logchannel *chan;
+ char *facility;
+ CODE *cptr;
+
+ if (!strlen(channel))
return NULL;
- f = malloc(sizeof(struct logfile));
- if (f) {
- memset(f, 0, sizeof(struct logfile));
- strncpy(f->fn, fn, sizeof(f->fn) - 1);
- if (!strcasecmp(fn, "ignore")) {
- f->f = NULL;
- } else if (!strcasecmp(fn, "console")) {
- f->f = stdout;
- } else if (!strcasecmp(fn, "syslog")) {
- f->f = NULL;
- f->facility = LOG_LOCAL0;
+ chan = malloc(sizeof(struct logchannel));
+
+ if (chan) {
+ memset(chan, 0, sizeof(chan));
+ if (!strcasecmp(channel, "console")) {
+ chan->console = 1;
+ } else if (!strncasecmp(channel, "syslog", 6)) {
+ /*
+ * syntax is:
+ * syslog.facility => level,level,level
+ */
+ facility = strchr(channel, '.');
+ if(!facility++ || !facility) {
+ facility = "local0";
+ }
+ /*
+ * Walk through the list of facilitynames (defined in sys/syslog.h)
+ * to see if we can find the one we have been given
+ */
+ chan->facility = -1;
+ cptr = facilitynames;
+ while (cptr->c_name) {
+ if (!strncasecmp(facility, cptr->c_name, sizeof(cptr->c_name))) {
+ chan->facility = cptr->c_val;
+ break;
+ }
+ cptr++;
+ }
+ if (0 > chan->facility) {
+ fprintf(stderr, "Logger Warning: bad syslog facility in logger.conf\n");
+ free(chan);
+ return NULL;
+ }
+
+ chan->syslog = 1;
+ openlog("asterisk", LOG_PID, chan->facility);
} else {
- if (fn[0] == '/')
- strncpy(tmp, fn, sizeof(tmp) - 1);
+ if (channel[0] == '/')
+ strncpy(chan->filename, channel, sizeof(chan->filename) - 1);
else
- snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, fn);
- f->f = fopen(tmp, "a");
- if (!f->f) {
+ snprintf(chan->filename, sizeof(chan->filename), "%s/%s", (char *)ast_config_AST_LOG_DIR, channel);
+ chan->fileptr = fopen(chan->filename, "a");
+ if (!chan->fileptr) {
/* Can't log here, since we're called with a lock */
- fprintf(stderr, "Logger Warning: Unable to open log file '%s': %s\n", tmp, strerror(errno));
+ fprintf(stderr, "Logger Warning: Unable to open log file '%s': %s\n", chan->filename, strerror(errno));
}
}
- f->logflags = make_components(components, lineno);
-
+ chan->logmask = make_components(components, lineno);
}
- return f;
+ return chan;
}
static void init_logger_chain(void)
{
- struct logfile *f, *cur;
+ struct logchannel *chan, *cur;
struct ast_config *cfg;
struct ast_variable *var;
+ /* delete our list of log channels */
ast_mutex_lock(&loglock);
-
- /* Free anything that is here */
- f = logfiles;
- while(f) {
- cur = f->next;
- if (f->f && (f->f != stdout) && (f->f != stderr))
- fclose(f->f);
- free(f);
- f = cur;
+ chan = logchannels;
+ while (chan) {
+ cur = chan->next;
+ free(chan);
+ chan = cur;
}
+ logchannels = NULL;
+ ast_mutex_unlock(&loglock);
- logfiles = NULL;
+ /* close syslog */
+ closelog();
- ast_mutex_unlock(&loglock);
cfg = ast_load("logger.conf");
- ast_mutex_lock(&loglock);
/* If no config file, we're fine */
- if (!cfg) {
- ast_mutex_unlock(&loglock);
- return;
- }
+ if (!cfg)
+ return;
+
+ ast_mutex_lock(&loglock);
var = ast_variable_browse(cfg, "logfiles");
while(var) {
- f = make_logfile(var->name, var->value, var->lineno);
- if (f) {
- f->next = logfiles;
- logfiles = f;
+ chan = make_logchannel(var->name, var->value, var->lineno);
+ if (chan) {
+ chan->next = logchannels;
+ logchannels = chan;
}
var = var->next;
}
- if (!logfiles) {
- /* Gotta have at least one. We'll make a NULL one */
- logfiles = make_logfile("ignore", "", -1);
- }
+
ast_destroy(cfg);
ast_mutex_unlock(&loglock);
-
-
}
int reload_logger(int rotate)
{
char old[AST_CONFIG_MAX_PATH];
char new[AST_CONFIG_MAX_PATH];
- struct logfile *f;
+ struct logchannel *f;
FILE *myf;
int x;
ast_mutex_lock(&loglock);
if (eventlog)
- fclose(eventlog);
+ fclose(eventlog);
else
- rotate = 0;
+ rotate = 0;
eventlog = NULL;
@@ -205,51 +238,47 @@ int reload_logger(int rotate)
if(rotate) {
for(x=0;;x++) {
- snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
- myf = fopen((char *)new, "r");
- if(myf)
- fclose(myf);
- else
- break;
+ snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
+ myf = fopen((char *)new, "r");
+ if(myf)
+ fclose(myf);
+ else
+ break;
}
- /* do it */
+ /* do it */
if (rename(old,new))
fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
}
eventlog = fopen(old, "a");
- f = logfiles;
+ f = logchannels;
while(f) {
- if (f->f && (f->f != stdout) && (f->f != stderr)) {
- fclose(f->f);
- f->f = NULL;
- if(rotate) {
- snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR,f->fn);
+ if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
+ fclose(f->fileptr);
+ f->fileptr = NULL;
+ if(rotate) {
+ strncpy(old, f->filename, sizeof(old));
- for(x=0;;x++) {
- snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR,f->fn,x);
- myf = fopen((char *)new, "r");
- if(myf)
- fclose(myf);
- else
- break;
- }
-
- /* do it */
- if (rename(old,new))
- fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
- }
+ for(x=0;;x++) {
+ snprintf(new, sizeof(new), "%s.%d", f->filename, x);
+ myf = fopen((char *)new, "r");
+ if (myf) {
+ fclose(myf);
+ } else {
+ break;
+ }
+ }
-
- }
-
-
- f = f->next;
+ /* do it */
+ if (rename(old,new))
+ fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
+ }
+ }
+ f = f->next;
}
-
ast_mutex_unlock(&loglock);
if (eventlog) {
@@ -275,13 +304,6 @@ static int handle_logger_reload(int fd, int argc, char *argv[])
return RESULT_SUCCESS;
}
-
-
-
-
-
-
-
static int handle_logger_rotate(int fd, int argc, char *argv[])
{
if(reload_logger(1))
@@ -301,41 +323,33 @@ static struct verb {
static char logger_reload_help[] =
"Usage: logger reload\n"
-" Reopens the log files. Use after a rotating the log files\n";
-
+" Reloads the logger subsystem state. Use after restarting syslogd(8)\n";
static char logger_rotate_help[] =
"Usage: logger reload\n"
" Rotates and Reopens the log files.\n";
-
static struct ast_cli_entry reload_logger_cli =
{ { "logger", "reload", NULL },
handle_logger_reload, "Reopens the log files",
logger_reload_help };
-
static struct ast_cli_entry rotate_logger_cli =
{ { "logger", "rotate", NULL },
handle_logger_rotate, "Reopens the log files",
logger_rotate_help };
-
-
static int handle_SIGXFSZ(int sig) {
- reload_logger(1);
- ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
- if (option_verbose)
- ast_verbose("Rotated Logs Per SIGXFSZ\n");
-
- return 0;
+ reload_logger(1);
+ ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
+ if (option_verbose)
+ ast_verbose("Rotated Logs Per SIGXFSZ\n");
+ return 0;
}
int init_logger(void)
{
- char tmp[AST_CONFIG_MAX_PATH];
-
-
+ char tmp[256];
/* auto rotate if sig SIGXFSZ comes a-knockin */
(void) signal(SIGXFSZ,(void *) handle_SIGXFSZ);
@@ -343,7 +357,8 @@ int init_logger(void)
/* register the relaod logger cli command */
ast_cli_register(&reload_logger_cli);
ast_cli_register(&rotate_logger_cli);
-
+
+ /* create the eventlog */
mkdir((char *)ast_config_AST_LOG_DIR, 0755);
snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
eventlog = fopen((char *)tmp, "a");
@@ -355,89 +370,124 @@ int init_logger(void)
return 0;
} else
ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
+
+ init_logger_chain();
+
+ /* create log channels */
init_logger_chain();
return -1;
}
+static void ast_log_vsyslog(int level, const char *file, int line, const char *function, const char *fmt, va_list args) {
+ char buf[BUFSIZ];
+
+ if(level >= SYSLOG_NLEVELS) {
+ /* we are locked here, so cannot ast_log() */
+ fprintf(stderr, "ast_log_vsyslog called with bogus level: %d\n", level);
+ return;
+ }
+ if(file && line && function) {
+ snprintf(buf, sizeof(buf), "%s[%ld]: %s:%d in %s: ",
+ levels[level], (long)pthread_self(), file, line, function);
+ } else {
+ snprintf(buf, sizeof(buf), "VERBOSE[%ld]: ", (long)pthread_self());
+ level = __LOG_DEBUG;
+ }
+ vsnprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), fmt, args);
+ syslog(syslog_level_map[level], buf);
+}
-extern void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
+/*
+ * send log messages to syslog and/or the console
+ */
+void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
{
- char date[256];
- char tmp[80];
- char tmp2[80];
- char tmp3[80];
- char tmp4[80];
- char linestr[80];
- time_t t;
- struct tm tm;
- struct logfile *f;
+ struct logchannel *chan;
+ char buf[BUFSIZ];
+ time_t t;
+ struct tm tm;
+ char date[256];
+
+ va_list ap;
+
+ if (!option_verbose && !option_debug && (level == __LOG_DEBUG)) {
+ return;
+ }
+
+ /* begin critical section */
+ ast_mutex_lock(&loglock);
+
+ if (level == __LOG_EVENT) {
+ time(&t);
+ localtime_r(&t,&tm);
+ if (&tm) {
+ /* Log events into the event log file, with a different format */
+ strftime(date, sizeof(date), "%b %e %T", &tm);
+ va_start(ap, fmt);
+
+ fprintf(eventlog, "%s asterisk[%d]: ", date, getpid());
+ vfprintf(eventlog, fmt, ap);
+ fflush(eventlog);
+
+ va_end(ap);
+ } else
+ /** Cannot use ast_log() from locked section of ast_log()!
+ ast_log(LOG_WARNING, "Unable to retrieve local time?\n"); **/
+ fprintf(stderr, "ast_log: Unable to retrieve local time for %ld?\n", (long)t);
+ ast_mutex_unlock(&loglock);
+ return;
+ }
+
+ if (logchannels) {
+ chan = logchannels;
+ while(chan) {
+ if (chan->syslog && (chan->logmask & (1 << level))) {
+ va_start(ap, fmt);
+ ast_log_vsyslog(level, file, line, function, fmt, ap);
+ va_end(ap);
+ } else if ((chan->logmask & (1 << level)) && (chan->console || chan->fileptr)) {
+ char linestr[128];
+ char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
- va_list ap;
- if (!option_verbose && !option_debug && (!level)) {
- return;
- }
- ast_mutex_lock(&loglock);
- if (level == 1 /* Event */) {
time(&t);
- localtime_r(&t,&tm);
- if (&tm) {
- /* Log events into the event log file, with a different format */
- strftime(date, sizeof(date), "%b %e %T", &tm);
- fprintf(eventlog, "%s asterisk[%d]: ", date, getpid());
- va_start(ap, fmt);
- vfprintf(eventlog, fmt, ap);
- va_end(ap);
- fflush(eventlog);
- } else
- /** Cannot use ast_log() from locked section of ast_log()!
- ast_log(LOG_WARNING, "Unable to retrieve local time?\n"); **/
- fprintf(stderr, "ast_log: Unable to retrieve local time for %ld?\n", (long)t);
- } else {
- if (logfiles) {
- f = logfiles;
- while(f) {
- if (f->logflags & (1 << level) && f->facility) {
- time(&t);
- localtime_r(&t,&tm);
- strftime(date, sizeof(date), "%b %e %T", &tm);
-
- openlog("asterisk_pbx",LOG_PID,f->facility);
- syslog(LOG_INFO|f->facility,"%s %s[%ld]: File %s, Line %d (%s): ",date,
- levels[level], (long)pthread_self(), file, line, function);
- closelog();
-
- }
- else if (f->logflags & (1 << level) && f->f) {
- if ((f->f != stdout) && (f->f != stderr)) {
- time(&t);
- localtime_r(&t,&tm);
- strftime(date, sizeof(date), "%b %e %T", &tm);
- fprintf(f->f, "%s %s[%ld]: File %s, Line %d (%s): ", date, levels[level], (long)pthread_self(), file, line, function);
- } else {
- sprintf(linestr, "%d", line);
- fprintf(f->f, "%s[%ld]: File %s, Line %s (%s): ",
- term_color(tmp, levels[level], colors[level], 0, sizeof(tmp)),
- (long)pthread_self(),
- term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
- term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
- term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
- }
- va_start(ap, fmt);
- vfprintf(f->f, fmt, ap);
- va_end(ap);
- fflush(f->f);
- }
- f = f->next;
- }
- } else {
- fprintf(stdout, "%s[%ld]: File %s, Line %d (%s): ", levels[level], (long)pthread_self(), file, line, function);
- va_start(ap, fmt);
- vfprintf(stdout, fmt, ap);
- va_end(ap);
- fflush(stdout);
+ localtime_r(&t, &tm);
+ if(!&tm) {
+ /** Cannot use ast_log() from locked section of ast_log()!
+ ast_log(AST_LOG_WARNING, "Unable to retrieve local time?\n"); **/
+ fprintf(stderr, "ast_log: Unable to retrieve local time for %ld?\n", (long)t);
+ ast_mutex_unlock(&loglock);
+ return;
}
+ strftime(date, sizeof(date), "%b %e %T", &tm);
+
+ sprintf(linestr, "%d", line);
+ snprintf(buf, sizeof(buf), "%s %s[%ld]: %s:%s %s: ",
+ date,
+ term_color(tmp1, levels[level], colors[level], 0, sizeof(tmp1)),
+ (long)pthread_self(),
+ term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
+ term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
+ term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
+
+ if (chan->console)
+ ast_console_puts(buf);
+ else
+ fprintf(chan->fileptr, buf);
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ if (chan->console)
+ ast_console_puts(buf);
+ else
+ fprintf(chan->fileptr, buf);
+
+ }
+ chan = chan->next;
}
- ast_mutex_unlock(&loglock);
+ }
+
+ ast_mutex_unlock(&loglock);
+ /* end critical section */
}
extern void ast_verbose(const char *fmt, ...)
@@ -498,6 +548,13 @@ extern void ast_verbose(const char *fmt, ...)
else
replacelast = pos = 0;
va_end(ap);
+
+ va_start(ap, fmt);
+ if(stuff[strlen(stuff)-1] == '\n')
+ stuff[strlen(stuff)-1] = '\0';
+ ast_log_vsyslog(0, NULL, 0, NULL, fmt, ap);
+ va_end(ap);
+
ast_mutex_unlock(&msglist_lock);
}
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index d68c5adf4..b0a55978d 100755
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -903,6 +903,8 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
{
char filename[256];
struct ast_context *c;
+ struct ast_config *cfg;
+ struct ast_variable *var;
int context_header_written;
int incomplete = 0; /* incomplete config write? */
FILE *output;
@@ -922,6 +924,9 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
return RESULT_FAILURE;
}
+ /* Load old file first */
+ cfg = ast_load(config);
+
/* have config path? */
if (argc == 3) {
/* is there extension.conf too? */
@@ -946,6 +951,8 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
if (ast_lock_contexts()) {
ast_cli(fd, "Failed to lock contexts list\n");
ast_mutex_unlock(&save_dialplan_lock);
+ if (cfg)
+ ast_destroy(cfg);
return RESULT_FAILURE;
}
@@ -955,6 +962,8 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
filename);
ast_unlock_contexts();
ast_mutex_unlock(&save_dialplan_lock);
+ if (cfg)
+ ast_destroy(cfg);
return RESULT_FAILURE;
}
@@ -963,6 +972,15 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
static_config ? "yes" : "no",
write_protect_config ? "yes" : "no");
+ var = ast_variable_walk(cfg, "globals");
+ if (var) {
+ fprintf(output, "[globals]\n");
+ while(var) {
+ fprintf(output, "%s => %s", var->name, var->value);
+ var = var->next;
+ }
+ }
+
/* walk all contexts */
c = ast_walk_contexts(NULL);
while (c) {
@@ -1079,6 +1097,8 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
ast_unlock_contexts();
ast_mutex_unlock(&save_dialplan_lock);
fclose(output);
+ if (cfg)
+ ast_destroy(cfg);
if (incomplete) {
ast_cli(fd, "Saved dialplan is incomplete\n");