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