Index: build_tools/cflags-devmode.xml
===================================================================
--- build_tools/cflags-devmode.xml (revision 298905)
+++ build_tools/cflags-devmode.xml (working copy)
@@ -14,9 +14,4 @@
-
- BFD
- DLADDR
- no
-
Index: build_tools/cflags.xml
===================================================================
--- build_tools/cflags.xml (revision 298854)
+++ build_tools/cflags.xml (working copy)
@@ -5,6 +5,11 @@
+
+ BFD
+ DLADDR
+ no
+
Index: main/logger.c
===================================================================
--- main/logger.c (revision 298905)
+++ main/logger.c (working copy)
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#if ((defined(AST_DEVMODE)) && (defined(linux)))
# include
# define MAX_BACKTRACE_FRAMES 20
@@ -46,6 +47,9 @@
# include
# endif
#endif
+#ifdef HAVE_CAP
+#include
+#endif /* HAVE_CAP */
#define SYSLOG_NAMES /* so we can map syslog facilities names to their numeric values,
from which is included by logger.h */
@@ -106,7 +110,7 @@
struct logchannel {
int logmask; /* What to log to this channel */
int disabled; /* If this channel is disabled or not */
- int facility; /* syslog facility */
+ int facility; /* syslog facility */
enum logtypes type; /* Type of log channel */
FILE *fileptr; /* logfile logging file pointer */
char filename[256]; /* Filename */
@@ -177,6 +181,69 @@
return res;
}
+static FILE *ast_openlog(char *ident, int option, int facility)
+{
+ int res, fd[2], i;
+ sigset_t fullset, oldset;
+ char argv1[12];
+#ifdef HAVE_CAP
+ cap_t cap;
+#endif
+
+ if (pipe(fd)) {
+ fprintf(stderr, "Pipe failed: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ sigfillset(&fullset);
+ pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+ if ((res = fork()) < 0) {
+ fprintf(stderr, "Fork failed: %s\n", strerror(errno));
+ return NULL;
+ }
+ if (res) {
+ FILE *logger;
+ close(fd[0]);
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ if (!(logger = fdopen(fd[1], "a"))) {
+ fprintf(stderr, "fdopen(3) failed: %s\n", strerror(errno));
+ close(fd[1]);
+ return NULL;
+ }
+ return logger;
+ }
+
+#ifdef HAVE_CAP
+ cap = cap_from_text("cap_net_admin-eip");
+
+ if (cap_set_proc(cap)) {
+ /* Careful with order! Logging cannot happen after we close FDs */
+ ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
+ }
+ cap_free(cap);
+#endif
+ if (ast_opt_high_priority) {
+ ast_set_priority(0);
+ }
+ signal(SIGPIPE, SIG_DFL);
+
+ /* Close writer, close everything else */
+ close(fd[1]);
+ if (dup2(fd[0], STDIN_FILENO)) {
+ fprintf(stderr, "Failed to duplicate file descriptor: %s\n", strerror(errno));
+ close(fd[0]);
+ exit(1);
+ }
+
+ for (i = STDIN_FILENO + 1; i < 4096; i++) {
+ fcntl(i, F_SETFD, FD_CLOEXEC | fcntl(i, F_GETFD));
+ }
+
+ snprintf(argv1, sizeof(argv1), "%d", facility);
+ execlp("astsyslogger", argv1, (char *) NULL);
+ exit(0);
+}
+
static struct logchannel *make_logchannel(char *channel, char *components, int lineno)
{
struct logchannel *chan;
@@ -262,7 +329,7 @@
chan->type = LOGTYPE_SYSLOG;
snprintf(chan->filename, sizeof(chan->filename), "%s", channel);
- openlog("asterisk", LOG_PID, chan->facility);
+ chan->fileptr = ast_openlog("asterisk", LOG_PID, chan->facility);
} else {
if (!ast_strlen_zero(hostname)) {
snprintf(chan->filename, sizeof(chan->filename), "%s/%s.%s",
@@ -291,17 +358,19 @@
/* delete our list of log channels */
AST_LIST_LOCK(&logchannels);
- while ((chan = AST_LIST_REMOVE_HEAD(&logchannels, list)))
+ while ((chan = AST_LIST_REMOVE_HEAD(&logchannels, list))) {
+ if (chan->fileptr) {
+ fclose(chan->fileptr);
+ }
free(chan);
+ }
AST_LIST_UNLOCK(&logchannels);
-
+
global_logmask = 0;
errno = 0;
- /* close syslog */
- closelog();
-
+
cfg = ast_config_load("logger.conf");
-
+
/* If no config file, we're fine, set default options. */
if (!cfg) {
if (errno)
@@ -653,14 +722,12 @@
}
}
- closelog(); /* syslog */
-
AST_LIST_UNLOCK(&logchannels);
return;
}
-static void __attribute__((format(printf, 5, 0))) ast_log_vsyslog(int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+static void __attribute__((format(printf, 5, 0))) ast_log_vsyslog(FILE *logger, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
{
char buf[BUFSIZ];
char *s;
@@ -683,7 +750,7 @@
s = buf + strlen(buf);
vsnprintf(s, sizeof(buf) - strlen(buf), fmt, args);
term_strip(s, s, strlen(s) + 1);
- syslog(syslog_level_map[level], "%s", buf);
+ fprintf(logger, "%c%s", syslog_level_map[level], buf);
}
/*!
@@ -762,7 +829,7 @@
/* Check syslog channels */
if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << level))) {
va_start(ap, fmt);
- ast_log_vsyslog(level, file, line, function, fmt, ap);
+ ast_log_vsyslog(chan->fileptr, level, file, line, function, fmt, ap);
va_end(ap);
/* Console channels */
} else if ((chan->logmask & (1 << level)) && (chan->type == LOGTYPE_CONSOLE)) {
Index: utils/astsyslogger.c
===================================================================
--- utils/astsyslogger.c (revision 0)
+++ utils/astsyslogger.c (revision 0)
@@ -0,0 +1,55 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Tilghman Lesher
+ *
+ * Tilghman Lesher
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+/*\brief Rationale:
+ * The purpose of this file is to ensure that logging to the syslog
+ * may occur on multiple facilities. Unfortunately, the syslog
+ * API applies globally to the process and there is not a way to ensure
+ * that multiple facilities may be used at once. One call to openlog(3)
+ * supercedes all previous calls. While we could use locking to ensure
+ * that only one thread may access the syslog API at one time, because
+ * we are dealing with logging, contention for such a lock becomes a huge
+ * issue.
+ */
+int main(int argc, char *argv[])
+{
+ char id[128], buf[4096];
+ int facility;
+
+ if (argc < 2 || sscanf(argv[1], "%d", &facility) < 1) {
+ fprintf(stderr, "Usage: %s \n", argv[0]);
+ exit(1);
+ }
+
+ snprintf(id, sizeof(id), "asterisk[%d]", (int) getppid());
+ openlog(id, 0, facility);
+
+ while (fgets(buf, sizeof(buf), stdin)) {
+ syslog(buf[0], "%s", &buf[1]);
+ }
+
+ closelog();
+ return 0;
+}
+
Property changes on: utils/astsyslogger.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ 'Date Author Id Revision Yoyo'
Added: svn:eol-style
+ native
Index: utils/Makefile
===================================================================
--- utils/Makefile (revision 298854)
+++ utils/Makefile (working copy)
@@ -26,7 +26,7 @@
# changes are made to ast_expr2.y or ast_expr2.fl (or the corresponding .c files),
# as a regression test. Others (mere mortals?) need not bother, but they are
# more than welcome to play! The regression test itself is in expr2.testinput.
-ALL_UTILS:=astman smsq stereorize streamplayer aelparse muted
+ALL_UTILS:=astman smsq stereorize streamplayer aelparse muted astsyslogger
UTILS:=$(ALL_UTILS)
include $(ASTTOPDIR)/Makefile.rules