diff options
-rw-r--r-- | main/logger.c | 212 |
1 files changed, 105 insertions, 107 deletions
diff --git a/main/logger.c b/main/logger.c index eccf556db..fb9e8ed4f 100644 --- a/main/logger.c +++ b/main/logger.c @@ -286,6 +286,70 @@ static void make_components(struct logchannel *chan) chan->logmask = logmask; } +/*! + * \brief create the filename that will be used for a logger channel. + * + * \param channel The name of the logger channel + * \param[out] filename The filename for the logger channel + * \param size The size of the filename buffer + */ +static void make_filename(const char *channel, char *filename, size_t size) +{ + const char *log_dir_prefix = ""; + const char *log_dir_separator = ""; + + *filename = '\0'; + + if (!strcasecmp(channel, "console")) { + return; + } + + if (!strncasecmp(channel, "syslog", 6)) { + ast_copy_string(filename, channel, size); + return; + } + + /* It's a filename */ + + if (channel[0] != '/') { + log_dir_prefix = ast_config_AST_LOG_DIR; + log_dir_separator = "/"; + } + + if (!ast_strlen_zero(hostname)) { + snprintf(filename, size, "%s%s%s.%s", + log_dir_prefix, log_dir_separator, channel, hostname); + } else { + snprintf(filename, size, "%s%s%s", + log_dir_prefix, log_dir_separator, channel); + } +} + +/*! + * \brief Find a particular logger channel by name + * + * \pre logchannels list is locked + * + * \param channel The name of the logger channel to find + * \retval non-NULL The corresponding logger channel + * \retval NULL Unable to find a logger channel with that particular name + */ +static struct logchannel *find_logchannel(const char *channel) +{ + char filename[PATH_MAX]; + struct logchannel *chan; + + make_filename(channel, filename, sizeof(filename)); + + AST_RWLIST_TRAVERSE(&logchannels, chan, list) { + if (!strcmp(chan->filename, filename)) { + return chan; + } + } + + return NULL; +} + static struct logchannel *make_logchannel(const char *channel, const char *components, int lineno, int dynamic) { struct logchannel *chan; @@ -301,6 +365,8 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo chan->lineno = lineno; chan->dynamic = dynamic; + make_filename(channel, chan->filename, sizeof(chan->filename)); + if (!strcasecmp(channel, "console")) { chan->type = LOGTYPE_CONSOLE; } else if (!strncasecmp(channel, "syslog", 6)) { @@ -322,24 +388,7 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo } chan->type = LOGTYPE_SYSLOG; - ast_copy_string(chan->filename, channel, sizeof(chan->filename)); } else { - const char *log_dir_prefix = ""; - const char *log_dir_separator = ""; - - if (channel[0] != '/') { - log_dir_prefix = ast_config_AST_LOG_DIR; - log_dir_separator = "/"; - } - - if (!ast_strlen_zero(hostname)) { - snprintf(chan->filename, sizeof(chan->filename), "%s%s%s.%s", - log_dir_prefix, log_dir_separator, channel, hostname); - } else { - snprintf(chan->filename, sizeof(chan->filename), "%s%s%s", - log_dir_prefix, log_dir_separator, channel); - } - if (!(chan->fileptr = fopen(chan->filename, "a"))) { /* Can't do real logging here since we're called with a lock * so log to any attached consoles */ @@ -936,13 +985,9 @@ int ast_logger_rotate_channel(const char *log_channel) { struct logchannel *f; int success = AST_LOGGER_FAILURE; + char filename[PATH_MAX]; - struct ast_str *filename = ast_str_create(64); - if (!filename) { - return AST_LOGGER_ALLOC_ERROR; - } - - ast_str_append(&filename, 0, "%s/%s", ast_config_AST_LOG_DIR, log_channel); + make_filename(log_channel, filename, sizeof(filename)); AST_RWLIST_WRLOCK(&logchannels); @@ -957,7 +1002,7 @@ int ast_logger_rotate_channel(const char *log_channel) if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) { fclose(f->fileptr); /* Close file */ f->fileptr = NULL; - if (strcmp(ast_str_buffer(filename), f->filename) == 0) { + if (strcmp(filename, f->filename) == 0) { rotate_file(f->filename); success = AST_LOGGER_SUCCESS; } @@ -967,7 +1012,6 @@ int ast_logger_rotate_channel(const char *log_channel) init_logger_chain(1 /* locked */, NULL); AST_RWLIST_UNLOCK(&logchannels); - ast_free(filename); return success; } @@ -1098,45 +1142,35 @@ static char *handle_logger_show_channels(struct ast_cli_entry *e, int cmd, struc int ast_logger_create_channel(const char *log_channel, const char *components) { struct logchannel *chan; - struct ast_str *filename = ast_str_create(64); - int chan_exists = AST_LOGGER_SUCCESS; if (ast_strlen_zero(components)) { return AST_LOGGER_DECLINE; } - if (!filename) { - return AST_LOGGER_ALLOC_ERROR; - } - - ast_str_append(&filename, 0, "%s/%s", ast_config_AST_LOG_DIR, log_channel); - AST_RWLIST_WRLOCK(&logchannels); - AST_RWLIST_TRAVERSE(&logchannels, chan, list) { - if (!strcmp(ast_str_buffer(filename), chan->filename)) { - chan_exists = AST_LOGGER_FAILURE; - break; - } + chan = find_logchannel(log_channel); + if (chan) { + AST_RWLIST_UNLOCK(&logchannels); + return AST_LOGGER_FAILURE; } - if (!chan_exists) { - chan = make_logchannel(log_channel, components, 0, 1); - if (chan) { - AST_RWLIST_INSERT_HEAD(&logchannels, chan, list); - global_logmask |= chan->logmask; - chan_exists = AST_LOGGER_SUCCESS; - } + chan = make_logchannel(log_channel, components, 0, 1); + if (!chan) { + AST_RWLIST_UNLOCK(&logchannels); + return AST_LOGGER_ALLOC_ERROR; } + + AST_RWLIST_INSERT_HEAD(&logchannels, chan, list); + global_logmask |= chan->logmask; + AST_RWLIST_UNLOCK(&logchannels); - return chan_exists; + return AST_LOGGER_SUCCESS; } static char *handle_logger_add_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct logchannel *chan; - switch (cmd) { case CLI_INIT: e->command = "logger add channel"; @@ -1155,57 +1189,34 @@ static char *handle_logger_add_channel(struct ast_cli_entry *e, int cmd, struct return CLI_SHOWUSAGE; } - AST_RWLIST_WRLOCK(&logchannels); - AST_RWLIST_TRAVERSE(&logchannels, chan, list) { - if (!strcmp(chan->filename, a->argv[3])) { - break; - } - } - - if (chan) { - AST_RWLIST_UNLOCK(&logchannels); - ast_cli(a->fd, "Logger channel '%s' already exists\n", a->argv[3]); + switch (ast_logger_create_channel(a->argv[3], a->argv[4])) { + case AST_LOGGER_SUCCESS: return CLI_SUCCESS; - } - - chan = make_logchannel(a->argv[3], a->argv[4], 0, 1); - if (chan) { - AST_RWLIST_INSERT_HEAD(&logchannels, chan, list); - global_logmask |= chan->logmask; - AST_RWLIST_UNLOCK(&logchannels); + case AST_LOGGER_FAILURE: + ast_cli(a->fd, "Logger channel '%s' already exists\n", a->argv[3]); return CLI_SUCCESS; + case AST_LOGGER_DECLINE: + case AST_LOGGER_ALLOC_ERROR: + default: + ast_cli(a->fd, "ERROR: Unable to create log channel '%s'\n", a->argv[3]); + return CLI_FAILURE; } - - AST_RWLIST_UNLOCK(&logchannels); - ast_cli(a->fd, "ERROR: Unable to create log channel '%s'\n", a->argv[3]); - - return CLI_FAILURE; } int ast_logger_remove_channel(const char *log_channel) { struct logchannel *chan; - struct ast_str *filename = ast_str_create(64); - - if (!filename) { - return AST_LOGGER_ALLOC_ERROR; - } - - ast_str_append(&filename, 0, "%s/%s", ast_config_AST_LOG_DIR, log_channel); AST_RWLIST_WRLOCK(&logchannels); - AST_RWLIST_TRAVERSE_SAFE_BEGIN(&logchannels, chan, list) { - if (chan->dynamic && !strcmp(chan->filename, ast_str_buffer(filename))) { - AST_RWLIST_REMOVE_CURRENT(list); - break; - } - } - AST_RWLIST_TRAVERSE_SAFE_END; - AST_RWLIST_UNLOCK(&logchannels); - if (!chan) { + chan = find_logchannel(log_channel); + if (chan && chan->dynamic) { + AST_RWLIST_REMOVE(&logchannels, chan, list); + } else { + AST_RWLIST_UNLOCK(&logchannels); return AST_LOGGER_FAILURE; } + AST_RWLIST_UNLOCK(&logchannels); if (chan->fileptr) { fclose(chan->fileptr); @@ -1253,30 +1264,17 @@ static char *handle_logger_remove_channel(struct ast_cli_entry *e, int cmd, stru return CLI_SHOWUSAGE; } - AST_RWLIST_WRLOCK(&logchannels); - AST_RWLIST_TRAVERSE_SAFE_BEGIN(&logchannels, chan, list) { - if (chan->dynamic && !strcmp(chan->filename, a->argv[3])) { - AST_RWLIST_REMOVE_CURRENT(list); - break; - } - } - AST_RWLIST_TRAVERSE_SAFE_END; - AST_RWLIST_UNLOCK(&logchannels); - - if (!chan) { + switch (ast_logger_remove_channel(a->argv[3])) { + case AST_LOGGER_SUCCESS: + ast_cli(a->fd, "Removed dynamic logger channel '%s'\n", a->argv[3]); + return CLI_SUCCESS; + case AST_LOGGER_FAILURE: ast_cli(a->fd, "Unable to find dynamic logger channel '%s'\n", a->argv[3]); return CLI_SUCCESS; + default: + ast_cli(a->fd, "Internal failure attempting to delete dynamic logger channel '%s'\n", a->argv[3]); + return CLI_FAILURE; } - - ast_cli(a->fd, "Removed dynamic logger channel '%s'\n", chan->filename); - if (chan->fileptr) { - fclose(chan->fileptr); - chan->fileptr = NULL; - } - ast_free(chan); - chan = NULL; - - return CLI_SUCCESS; } struct verb { |