diff options
Diffstat (limited to 'main')
79 files changed, 1333 insertions, 1595 deletions
diff --git a/main/acl.c b/main/acl.c index 43035329c..1d628e6b2 100644 --- a/main/acl.c +++ b/main/acl.c @@ -1028,4 +1028,3 @@ int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindad ast_sockaddr_set_port(ourip, port); return res; } - diff --git a/main/alaw.c b/main/alaw.c index c5069f358..ced9f16a2 100644 --- a/main/alaw.c +++ b/main/alaw.c @@ -214,4 +214,3 @@ void ast_alaw_init(void) #endif /* TEST_TANDEM_TRANSCODING */ } - diff --git a/main/alertpipe.c b/main/alertpipe.c index fa6ec7bcc..7932a7346 100644 --- a/main/alertpipe.c +++ b/main/alertpipe.c @@ -55,17 +55,8 @@ int ast_alertpipe_init(int alert_pipe[2]) ast_log(LOG_WARNING, "Failed to create alert pipe: %s\n", strerror(errno)); return -1; } else { - int flags = fcntl(alert_pipe[0], F_GETFL); - if (fcntl(alert_pipe[0], F_SETFL, flags | O_NONBLOCK) < 0) { - ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n", - strerror(errno)); - ast_alertpipe_close(alert_pipe); - return -1; - } - flags = fcntl(alert_pipe[1], F_GETFL); - if (fcntl(alert_pipe[1], F_SETFL, flags | O_NONBLOCK) < 0) { - ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n", - strerror(errno)); + if (ast_fd_set_flags(alert_pipe[0], O_NONBLOCK) + || ast_fd_set_flags(alert_pipe[1], O_NONBLOCK)) { ast_alertpipe_close(alert_pipe); return -1; } diff --git a/main/app.c b/main/app.c index 04aca2b8c..331c82750 100644 --- a/main/app.c +++ b/main/app.c @@ -1029,30 +1029,42 @@ int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, in { struct linear_state *lin; char tmpf[256]; - int res = -1; int autoclose = 0; + if (fd < 0) { if (ast_strlen_zero(filename)) { return -1; } + autoclose = 1; + if (filename[0] == '/') { ast_copy_string(tmpf, filename, sizeof(tmpf)); } else { snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename); } - if ((fd = open(tmpf, O_RDONLY)) < 0) { + + fd = open(tmpf, O_RDONLY); + if (fd < 0) { ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno)); return -1; } } - if ((lin = ast_calloc(1, sizeof(*lin)))) { - lin->fd = fd; - lin->allowoverride = allowoverride; - lin->autoclose = autoclose; - res = ast_activate_generator(chan, &linearstream, lin); + + lin = ast_calloc(1, sizeof(*lin)); + if (!lin) { + if (autoclose) { + close(fd); + } + + return -1; } - return res; + + lin->fd = fd; + lin->allowoverride = allowoverride; + lin->autoclose = autoclose; + + return ast_activate_generator(chan, &linearstream, lin); } static int control_streamfile(struct ast_channel *chan, @@ -1351,10 +1363,10 @@ int ast_control_tone(struct ast_channel *chan, const char *tone) ts = ast_get_indication_tone(zone ? zone : ast_channel_zone(chan), tone_indication); if (ast_playtones_start(chan, 0, ts ? ts->data : tone_indication, 0)) { - return -1; + res = -1; } - for (;;) { + while (!res) { struct ast_frame *fr; if (ast_waitfor(chan, -1) < 0) { @@ -3428,4 +3440,3 @@ int app_init(void) } return 0; } - diff --git a/main/ast_expr2.c b/main/ast_expr2.c index 1b866facf..4699b46ce 100644 --- a/main/ast_expr2.c +++ b/main/ast_expr2.c @@ -2,20 +2,20 @@ /* A Bison parser, made by GNU Bison 2.4.1. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -28,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -78,14 +78,14 @@ /* Line 189 of yacc.c */ #line 1 "ast_expr2.y" -/* Written by Pace Willisson (pace@blitz.com) +/* Written by Pace Willisson (pace@blitz.com) * and placed in the public domain. * * Largely rewritten by J.T. Conklin (jtc@wimsey.com) * * And then overhauled twice by Steve Murphy (murf@digium.com) * to add double-quoted strings, allow mult. spaces, improve - * error messages, and then to fold in a flex scanner for the + * error messages, and then to fold in a flex scanner for the * yylex operation. * * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $ @@ -98,7 +98,7 @@ #include <stdio.h> #if !defined(STANDALONE) && !defined(STANDALONE2) \ - + ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #else #ifndef __USE_ISOC99 @@ -337,7 +337,7 @@ enum node_type { AST_EXPR_NODE_COMMA, AST_EXPR_NODE_STRING, AST_EXPR_NODE_VAL } ; -struct expr_node +struct expr_node { enum node_type type; struct val *val; @@ -355,7 +355,7 @@ struct parse_io yyscan_t scanner; struct ast_channel *chan; }; - + static int chk_div __P((FP___TYPE, FP___TYPE)); static int chk_minus __P((FP___TYPE, FP___TYPE, FP___TYPE)); static int chk_plus __P((FP___TYPE, FP___TYPE, FP___TYPE)); @@ -407,7 +407,7 @@ typedef struct yyltype define it here, we have no definition yet for YYSTYPE. */ int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); - + /* I wanted to add args to the yyerror routine, so I could print out some useful info about the error. Not as easy as it looks, but it is possible. */ @@ -1229,7 +1229,7 @@ int yydebug; # define YYMAXDEPTH 10000 #endif - + #if YYERROR_VERBOSE @@ -1440,7 +1440,7 @@ yysyntax_error (char *yyresult, int yystate, int yychar) } } #endif /* YYERROR_VERBOSE */ - + /*-----------------------------------------------. | Release the memory associated to this symbol. | @@ -2011,7 +2011,7 @@ yyreduce: if( (yyvsp[(1) - (1)].val)->type == AST_EXPR_number ) ((struct parse_io *)parseio)->val->u.i = (yyvsp[(1) - (1)].val)->u.i; else - ((struct parse_io *)parseio)->val->u.s = (yyvsp[(1) - (1)].val)->u.s; + ((struct parse_io *)parseio)->val->u.s = (yyvsp[(1) - (1)].val)->u.s; free((yyvsp[(1) - (1)].val)); ;} break; @@ -2022,7 +2022,7 @@ yyreduce: #line 382 "ast_expr2.y" {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1); ((struct parse_io *)parseio)->val->type = AST_EXPR_string; - ((struct parse_io *)parseio)->val->u.s = strdup(""); + ((struct parse_io *)parseio)->val->u.s = strdup(""); ;} break; @@ -2081,7 +2081,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 412 "ast_expr2.y" { (yyval.val) = (yyvsp[(2) - (3)].val); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0; DESTROY((yyvsp[(1) - (3)].val)); DESTROY((yyvsp[(3) - (3)].val)); ;} break; @@ -2091,8 +2091,8 @@ yyreduce: /* Line 1455 of yacc.c */ #line 416 "ast_expr2.y" { (yyval.val) = op_or ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2100,9 +2100,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 420 "ast_expr2.y" - { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2111,7 +2111,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 424 "ast_expr2.y" { (yyval.val) = op_eq ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2121,7 +2121,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 428 "ast_expr2.y" { (yyval.val) = op_gt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2130,9 +2130,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 432 "ast_expr2.y" - { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2140,9 +2140,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 436 "ast_expr2.y" - { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2150,9 +2150,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 440 "ast_expr2.y" - { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2160,9 +2160,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 444 "ast_expr2.y" - { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2170,9 +2170,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 448 "ast_expr2.y" - { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2180,9 +2180,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 452 "ast_expr2.y" - { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2190,9 +2190,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 456 "ast_expr2.y" - { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val)); - DESTROY((yyvsp[(1) - (2)].val)); - (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; + { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val)); + DESTROY((yyvsp[(1) - (2)].val)); + (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2200,9 +2200,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 460 "ast_expr2.y" - { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val)); - DESTROY((yyvsp[(1) - (2)].val)); - (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; + { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val)); + DESTROY((yyvsp[(1) - (2)].val)); + (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2210,9 +2210,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 464 "ast_expr2.y" - { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2220,9 +2220,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 468 "ast_expr2.y" - { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2230,9 +2230,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 472 "ast_expr2.y" - { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2240,9 +2240,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 476 "ast_expr2.y" - { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2250,9 +2250,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 480 "ast_expr2.y" - { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2260,10 +2260,10 @@ yyreduce: /* Line 1455 of yacc.c */ #line 484 "ast_expr2.y" - { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val)); - DESTROY((yyvsp[(2) - (5)].val)); - DESTROY((yyvsp[(4) - (5)].val)); - (yyloc).first_column = (yylsp[(1) - (5)]).first_column; (yyloc).last_column = (yylsp[(3) - (5)]).last_column; + { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val)); + DESTROY((yyvsp[(2) - (5)].val)); + DESTROY((yyvsp[(4) - (5)].val)); + (yyloc).first_column = (yylsp[(1) - (5)]).first_column; (yyloc).last_column = (yylsp[(3) - (5)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2271,9 +2271,9 @@ yyreduce: /* Line 1455 of yacc.c */ #line 489 "ast_expr2.y" - { (yyval.val) = op_tildetilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); - DESTROY((yyvsp[(2) - (3)].val)); - (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; + { (yyval.val) = op_tildetilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); + DESTROY((yyvsp[(2) - (3)].val)); + (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; @@ -2528,7 +2528,7 @@ make_number (FP___TYPE i) vp->type = AST_EXPR_number; vp->u.i = i; - return vp; + return vp; } static struct val * @@ -2556,7 +2556,7 @@ make_str (const char *s) } if (isint) vp->type = AST_EXPR_numeric_string; - else + else vp->type = AST_EXPR_string; return vp; @@ -2565,12 +2565,12 @@ make_str (const char *s) static void free_value (struct val *vp) -{ +{ if (vp==NULL) { return; } if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string) - free (vp->u.s); + free (vp->u.s); free(vp); } @@ -2579,7 +2579,7 @@ static int to_number (struct val *vp) { FP___TYPE i; - + if (vp == NULL) { ast_log(LOG_WARNING,"vp==NULL in to_number()\n"); return(0); @@ -2611,13 +2611,13 @@ strip_quotes(struct val *vp) { if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string) return; - + if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' ) { char *f, *t; f = vp->u.s; t = vp->u.s; - + while( *f ) { if( *f && *f != '"' ) @@ -2672,7 +2672,7 @@ void ast_log(int level, const char *file, int line, const char *function, const { va_list vars; va_start(vars,fmt); - + printf("LOG: lev:%d file:%s line:%d func: %s ", level, file, line, function); vprintf(fmt, vars); @@ -2685,14 +2685,14 @@ int main(int argc,char **argv) { char s[4096]; char out[4096]; FILE *infile; - + if( !argv[1] ) exit(20); - + if( access(argv[1],F_OK)== 0 ) { int ret; - + infile = fopen(argv[1],"r"); if( !infile ) { @@ -2703,7 +2703,7 @@ int main(int argc,char **argv) { { if( s[strlen(s)-1] == '\n' ) s[strlen(s)-1] = 0; - + ret = ast_expr(s, out, sizeof(out), NULL); printf("Expression: %s Result: [%d] '%s'\n", s, ret, out); @@ -2733,7 +2733,7 @@ int main(int argc,char **argv) { static void destroy_arglist(struct expr_node *arglist) { struct expr_node *arglist_next; - + while (arglist) { arglist_next = arglist->right; @@ -2752,7 +2752,7 @@ static char *compose_func_args(struct expr_node *arglist) struct expr_node *t = arglist; char *argbuf; int total_len = 0; - + while (t) { if (t != arglist) total_len += 1; /* for the sep */ @@ -2762,7 +2762,7 @@ static char *compose_func_args(struct expr_node *arglist) else total_len += strlen(t->val->u.s); } - + t = t->right; } total_len++; /* for the null */ @@ -2772,10 +2772,10 @@ static char *compose_func_args(struct expr_node *arglist) t = arglist; while (t) { char numbuf[30]; - + if (t != arglist) strcat(argbuf,","); - + if (t->val) { if (t->val->type == AST_EXPR_number) { sprintf(numbuf,FP___PRINTF,t->val->u.i); @@ -3055,7 +3055,7 @@ static struct val *op_func(struct val *funcname, struct expr_node *arglist, stru ast_log(LOG_WARNING,"Hey! chan is NULL.\n"); if (!f) ast_log(LOG_WARNING,"Hey! could not find func %s.\n", funcname->u.s); - + if (f && chan) { if (f->read) { char workspace[512]; @@ -3070,7 +3070,7 @@ static struct val *op_func(struct val *funcname, struct expr_node *arglist, stru ast_log(LOG_ERROR,"Error! Function '%s' cannot be read!\n", funcname->u.s); return (make_number ((FP___TYPE)0.0)); } - + } else { ast_log(LOG_ERROR, "Error! '%s' doesn't appear to be an available function!\n", funcname->u.s); return (make_number ((FP___TYPE)0.0)); @@ -3101,7 +3101,7 @@ op_or (struct val *a, struct val *b) return (a); } } - + static struct val * op_and (struct val *a, struct val *b) { @@ -3118,11 +3118,11 @@ op_and (struct val *a, struct val *b) static struct val * op_eq (struct val *a, struct val *b) { - struct val *r; + struct val *r; if (isstring (a) || isstring (b)) { to_string (a); - to_string (b); + to_string (b); r = make_number ((FP___TYPE)(strcoll (a->u.s, b->u.s) == 0)); } else { #ifdef DEBUG_FOR_CONVERSIONS @@ -3397,7 +3397,7 @@ op_compl (struct val *a) { int v1 = 1; struct val *r; - + if( !a ) { v1 = 0; @@ -3410,7 +3410,7 @@ op_compl (struct val *a) if( a->u.i == 0 ) v1 = 0; break; - + case AST_EXPR_string: if( a->u.s == 0 ) v1 = 0; @@ -3424,7 +3424,7 @@ op_compl (struct val *a) v1 = atoi(a->u.s); } break; - + case AST_EXPR_numeric_string: if( a->u.s == 0 ) v1 = 0; @@ -3440,7 +3440,7 @@ op_compl (struct val *a) break; } } - + r = make_number (!v1); free_value (a); return r; @@ -3511,7 +3511,7 @@ op_div (struct val *a, struct val *b) } if (b->u.i == 0) { - ast_log(LOG_WARNING, "division by zero\n"); + ast_log(LOG_WARNING, "division by zero\n"); free_value(a); free_value(b); return make_number(INT_MAX); @@ -3525,7 +3525,7 @@ op_div (struct val *a, struct val *b) free_value (b); return r; } - + static struct val * op_rem (struct val *a, struct val *b) { @@ -3551,7 +3551,7 @@ op_rem (struct val *a, struct val *b) free_value (b); return r; } - + static struct val * op_colon (struct val *a, struct val *b) @@ -3574,7 +3574,7 @@ op_colon (struct val *a, struct val *b) ast_log(LOG_WARNING, "regcomp() error : %s\n", errbuf); free_value(a); free_value(b); - return make_str(""); + return make_str(""); } /* compare string against pattern */ @@ -3602,7 +3602,7 @@ op_colon (struct val *a, struct val *b) return v; } - + static struct val * op_eqtilde (struct val *a, struct val *b) @@ -3625,7 +3625,7 @@ op_eqtilde (struct val *a, struct val *b) ast_log(LOG_WARNING, "regcomp() error : %s\n", errbuf); free_value(a); free_value(b); - return make_str(""); + return make_str(""); } /* compare string against pattern */ @@ -3688,4 +3688,3 @@ op_tildetilde (struct val *a, struct val *b) return v; } - diff --git a/main/ast_expr2.h b/main/ast_expr2.h index 1fefe11f7..628283405 100644 --- a/main/ast_expr2.h +++ b/main/ast_expr2.h @@ -2,20 +2,20 @@ /* A Bison parser, made by GNU Bison 2.4.1. */ /* Skeleton interface for Bison's Yacc-like parsers in C - + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -28,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -101,6 +101,3 @@ typedef struct YYLTYPE # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif - - - diff --git a/main/ast_expr2.y b/main/ast_expr2.y index 7163a7132..08ed76a43 100644 --- a/main/ast_expr2.y +++ b/main/ast_expr2.y @@ -1,12 +1,12 @@ %{ -/* Written by Pace Willisson (pace@blitz.com) +/* Written by Pace Willisson (pace@blitz.com) * and placed in the public domain. * * Largely rewritten by J.T. Conklin (jtc@wimsey.com) * * And then overhauled twice by Steve Murphy (murf@digium.com) * to add double-quoted strings, allow mult. spaces, improve - * error messages, and then to fold in a flex scanner for the + * error messages, and then to fold in a flex scanner for the * yylex operation. * * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $ @@ -19,7 +19,7 @@ #include <stdio.h> #if !defined(STANDALONE) && !defined(STANDALONE2) \ - + ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #else #ifndef __USE_ISOC99 @@ -258,7 +258,7 @@ enum node_type { AST_EXPR_NODE_COMMA, AST_EXPR_NODE_STRING, AST_EXPR_NODE_VAL } ; -struct expr_node +struct expr_node { enum node_type type; struct val *val; @@ -276,7 +276,7 @@ struct parse_io yyscan_t scanner; struct ast_channel *chan; }; - + static int chk_div __P((FP___TYPE, FP___TYPE)); static int chk_minus __P((FP___TYPE, FP___TYPE, FP___TYPE)); static int chk_plus __P((FP___TYPE, FP___TYPE, FP___TYPE)); @@ -328,14 +328,14 @@ typedef struct yyltype define it here, we have no definition yet for YYSTYPE. */ int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); - + /* I wanted to add args to the yyerror routine, so I could print out some useful info about the error. Not as easy as it looks, but it is possible. */ #define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio) #define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);} %} - + %pure-parser %locations /* %debug for when you are having big problems */ @@ -357,7 +357,7 @@ extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t)); %left <val> TOK_AND %left <val> TOK_EQ TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE %left <val> TOK_PLUS TOK_MINUS -%left <val> TOK_MULT TOK_DIV TOK_MOD +%left <val> TOK_MULT TOK_DIV TOK_MOD %right <val> TOK_COMPL %left <val> TOK_COLON TOK_EQTILDE TOK_TILDETILDE %left <val> TOK_RP TOK_LP @@ -366,8 +366,8 @@ extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t)); %type <arglist> arglist %type <val> start expr -%destructor { free_value($$); } expr TOKEN TOK_COND TOK_COLONCOLON TOK_OR TOK_AND TOK_EQ - TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE TOK_PLUS TOK_MINUS TOK_MULT TOK_DIV TOK_MOD TOK_COMPL TOK_COLON TOK_EQTILDE +%destructor { free_value($$); } expr TOKEN TOK_COND TOK_COLONCOLON TOK_OR TOK_AND TOK_EQ + TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE TOK_PLUS TOK_MINUS TOK_MULT TOK_DIV TOK_MOD TOK_COMPL TOK_COLON TOK_EQTILDE TOK_RP TOK_LP TOK_TILDETILDE %% @@ -377,12 +377,12 @@ start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(st if( $1->type == AST_EXPR_number ) ((struct parse_io *)parseio)->val->u.i = $1->u.i; else - ((struct parse_io *)parseio)->val->u.s = $1->u.s; + ((struct parse_io *)parseio)->val->u.s = $1->u.s; free($1); } | {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1); ((struct parse_io *)parseio)->val->type = AST_EXPR_string; - ((struct parse_io *)parseio)->val->u.s = strdup(""); + ((struct parse_io *)parseio)->val->u.s = strdup(""); } ; @@ -402,7 +402,7 @@ arglist: expr { $$ = alloc_expr_node(AST_EXPR_NODE_VAL); $$->val = $1;} $$ = $1; t->right = x; x->val = make_str("");} ; -expr: +expr: TOKEN TOK_LP arglist TOK_RP { $$ = op_func($1,$3, ((struct parse_io *)parseio)->chan); DESTROY($2); DESTROY($4); @@ -411,85 +411,85 @@ expr: } | TOKEN {$$ = $1;} | TOK_LP expr TOK_RP { $$ = $2; - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0; DESTROY($1); DESTROY($3); } | expr TOK_OR expr { $$ = op_or ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_AND expr { $$ = op_and ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_AND expr { $$ = op_and ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} | expr TOK_EQ expr { $$ = op_eq ($1, $3); - DESTROY($2); + DESTROY($2); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} | expr TOK_GT expr { $$ = op_gt ($1, $3); - DESTROY($2); + DESTROY($2); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_LT expr { $$ = op_lt ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_LT expr { $$ = op_lt ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_GE expr { $$ = op_ge ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_GE expr { $$ = op_ge ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_LE expr { $$ = op_le ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_LE expr { $$ = op_le ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_NE expr { $$ = op_ne ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_NE expr { $$ = op_ne ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_PLUS expr { $$ = op_plus ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_PLUS expr { $$ = op_plus ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_MINUS expr { $$ = op_minus ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_MINUS expr { $$ = op_minus ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | TOK_MINUS expr %prec TOK_COMPL { $$ = op_negate ($2); - DESTROY($1); - @$.first_column = @1.first_column; @$.last_column = @2.last_column; + | TOK_MINUS expr %prec TOK_COMPL { $$ = op_negate ($2); + DESTROY($1); + @$.first_column = @1.first_column; @$.last_column = @2.last_column; @$.first_line=0; @$.last_line=0;} - | TOK_COMPL expr { $$ = op_compl ($2); - DESTROY($1); - @$.first_column = @1.first_column; @$.last_column = @2.last_column; + | TOK_COMPL expr { $$ = op_compl ($2); + DESTROY($1); + @$.first_column = @1.first_column; @$.last_column = @2.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_MULT expr { $$ = op_times ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_MULT expr { $$ = op_times ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_DIV expr { $$ = op_div ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_DIV expr { $$ = op_div ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_MOD expr { $$ = op_rem ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_MOD expr { $$ = op_rem ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_COLON expr { $$ = op_colon ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_COLON expr { $$ = op_colon ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_EQTILDE expr { $$ = op_eqtilde ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_EQTILDE expr { $$ = op_eqtilde ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_COND expr TOK_COLONCOLON expr { $$ = op_cond ($1, $3, $5); - DESTROY($2); - DESTROY($4); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_COND expr TOK_COLONCOLON expr { $$ = op_cond ($1, $3, $5); + DESTROY($2); + DESTROY($4); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} - | expr TOK_TILDETILDE expr { $$ = op_tildetilde ($1, $3); - DESTROY($2); - @$.first_column = @1.first_column; @$.last_column = @3.last_column; + | expr TOK_TILDETILDE expr { $$ = op_tildetilde ($1, $3); + DESTROY($2); + @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;} ; @@ -521,7 +521,7 @@ make_number (FP___TYPE i) vp->type = AST_EXPR_number; vp->u.i = i; - return vp; + return vp; } static struct val * @@ -549,7 +549,7 @@ make_str (const char *s) } if (isint) vp->type = AST_EXPR_numeric_string; - else + else vp->type = AST_EXPR_string; return vp; @@ -558,12 +558,12 @@ make_str (const char *s) static void free_value (struct val *vp) -{ +{ if (vp==NULL) { return; } if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string) - free (vp->u.s); + free (vp->u.s); free(vp); } @@ -572,7 +572,7 @@ static int to_number (struct val *vp) { FP___TYPE i; - + if (vp == NULL) { ast_log(LOG_WARNING,"vp==NULL in to_number()\n"); return(0); @@ -604,13 +604,13 @@ strip_quotes(struct val *vp) { if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string) return; - + if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' ) { char *f, *t; f = vp->u.s; t = vp->u.s; - + while( *f ) { if( *f && *f != '"' ) @@ -665,7 +665,7 @@ void ast_log(int level, const char *file, int line, const char *function, const { va_list vars; va_start(vars,fmt); - + printf("LOG: lev:%d file:%s line:%d func: %s ", level, file, line, function); vprintf(fmt, vars); @@ -678,14 +678,14 @@ int main(int argc,char **argv) { char s[4096]; char out[4096]; FILE *infile; - + if( !argv[1] ) exit(20); - + if( access(argv[1],F_OK)== 0 ) { int ret; - + infile = fopen(argv[1],"r"); if( !infile ) { @@ -696,7 +696,7 @@ int main(int argc,char **argv) { { if( s[strlen(s)-1] == '\n' ) s[strlen(s)-1] = 0; - + ret = ast_expr(s, out, sizeof(out), NULL); printf("Expression: %s Result: [%d] '%s'\n", s, ret, out); @@ -726,7 +726,7 @@ int main(int argc,char **argv) { static void destroy_arglist(struct expr_node *arglist) { struct expr_node *arglist_next; - + while (arglist) { arglist_next = arglist->right; @@ -745,7 +745,7 @@ static char *compose_func_args(struct expr_node *arglist) struct expr_node *t = arglist; char *argbuf; int total_len = 0; - + while (t) { if (t != arglist) total_len += 1; /* for the sep */ @@ -755,7 +755,7 @@ static char *compose_func_args(struct expr_node *arglist) else total_len += strlen(t->val->u.s); } - + t = t->right; } total_len++; /* for the null */ @@ -765,10 +765,10 @@ static char *compose_func_args(struct expr_node *arglist) t = arglist; while (t) { char numbuf[30]; - + if (t != arglist) strcat(argbuf,","); - + if (t->val) { if (t->val->type == AST_EXPR_number) { sprintf(numbuf,FP___PRINTF,t->val->u.i); @@ -1048,7 +1048,7 @@ static struct val *op_func(struct val *funcname, struct expr_node *arglist, stru ast_log(LOG_WARNING,"Hey! chan is NULL.\n"); if (!f) ast_log(LOG_WARNING,"Hey! could not find func %s.\n", funcname->u.s); - + if (f && chan) { if (f->read) { char workspace[512]; @@ -1063,7 +1063,7 @@ static struct val *op_func(struct val *funcname, struct expr_node *arglist, stru ast_log(LOG_ERROR,"Error! Function '%s' cannot be read!\n", funcname->u.s); return (make_number ((FP___TYPE)0.0)); } - + } else { ast_log(LOG_ERROR, "Error! '%s' doesn't appear to be an available function!\n", funcname->u.s); return (make_number ((FP___TYPE)0.0)); @@ -1094,7 +1094,7 @@ op_or (struct val *a, struct val *b) return (a); } } - + static struct val * op_and (struct val *a, struct val *b) { @@ -1111,11 +1111,11 @@ op_and (struct val *a, struct val *b) static struct val * op_eq (struct val *a, struct val *b) { - struct val *r; + struct val *r; if (isstring (a) || isstring (b)) { to_string (a); - to_string (b); + to_string (b); r = make_number ((FP___TYPE)(strcoll (a->u.s, b->u.s) == 0)); } else { #ifdef DEBUG_FOR_CONVERSIONS @@ -1390,7 +1390,7 @@ op_compl (struct val *a) { int v1 = 1; struct val *r; - + if( !a ) { v1 = 0; @@ -1403,7 +1403,7 @@ op_compl (struct val *a) if( a->u.i == 0 ) v1 = 0; break; - + case AST_EXPR_string: if( a->u.s == 0 ) v1 = 0; @@ -1417,7 +1417,7 @@ op_compl (struct val *a) v1 = atoi(a->u.s); } break; - + case AST_EXPR_numeric_string: if( a->u.s == 0 ) v1 = 0; @@ -1433,7 +1433,7 @@ op_compl (struct val *a) break; } } - + r = make_number (!v1); free_value (a); return r; @@ -1504,7 +1504,7 @@ op_div (struct val *a, struct val *b) } if (b->u.i == 0) { - ast_log(LOG_WARNING, "division by zero\n"); + ast_log(LOG_WARNING, "division by zero\n"); free_value(a); free_value(b); return make_number(INT_MAX); @@ -1518,7 +1518,7 @@ op_div (struct val *a, struct val *b) free_value (b); return r; } - + static struct val * op_rem (struct val *a, struct val *b) { @@ -1544,7 +1544,7 @@ op_rem (struct val *a, struct val *b) free_value (b); return r; } - + static struct val * op_colon (struct val *a, struct val *b) @@ -1567,7 +1567,7 @@ op_colon (struct val *a, struct val *b) ast_log(LOG_WARNING, "regcomp() error : %s\n", errbuf); free_value(a); free_value(b); - return make_str(""); + return make_str(""); } /* compare string against pattern */ @@ -1595,7 +1595,7 @@ op_colon (struct val *a, struct val *b) return v; } - + static struct val * op_eqtilde (struct val *a, struct val *b) @@ -1618,7 +1618,7 @@ op_eqtilde (struct val *a, struct val *b) ast_log(LOG_WARNING, "regcomp() error : %s\n", errbuf); free_value(a); free_value(b); - return make_str(""); + return make_str(""); } /* compare string against pattern */ diff --git a/main/ast_expr2f.c b/main/ast_expr2f.c index 1f67d460d..f52b92953 100644 --- a/main/ast_expr2f.c +++ b/main/ast_expr2f.c @@ -36,7 +36,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -53,7 +53,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; @@ -186,7 +186,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) - + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -248,7 +248,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -603,7 +603,7 @@ struct parse_io yyscan_t scanner; struct ast_channel *chan; }; - + void ast_yyset_column(int column_no, yyscan_t yyscanner); int ast_yyget_column(yyscan_t yyscanner); static int curlycount = 0; @@ -670,9 +670,9 @@ static int yy_init_globals (yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r - + # define yylloc yyg->yylloc_r - + int ast_yylex_init (yyscan_t* scanner); int ast_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); @@ -711,9 +711,9 @@ YYSTYPE * ast_yyget_lval (yyscan_t yyscanner ); void ast_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); YYLTYPE *ast_yyget_lloc (yyscan_t yyscanner ); - + void ast_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - + /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -727,7 +727,7 @@ extern int ast_yywrap (yyscan_t yyscanner ); #endif static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - + #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif @@ -1726,7 +1726,7 @@ static void ast_yy_load_buffer_state (yyscan_t yyscanner) YY_BUFFER_STATE ast_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + b = (YY_BUFFER_STATE) ast_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in ast_yy_create_buffer()" ); @@ -1770,7 +1770,7 @@ static void ast_yy_load_buffer_state (yyscan_t yyscanner) #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ - + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a ast_yyrestart() or at EOF. @@ -1796,7 +1796,7 @@ extern int isatty (int ); } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - + errno = oerrno; } @@ -1902,9 +1902,9 @@ static void ast_yyensure_buffer_stack (yyscan_t yyscanner) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in ast_yyensure_buffer_stack()" ); - + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -1933,12 +1933,12 @@ static void ast_yyensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE ast_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) @@ -1974,7 +1974,7 @@ YY_BUFFER_STATE ast_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yys */ YY_BUFFER_STATE ast_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) { - + return ast_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); } @@ -1991,7 +1991,7 @@ YY_BUFFER_STATE ast_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , char *buf; yy_size_t n; int i; - + /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) ast_yyalloc(n ,yyscanner ); @@ -2059,10 +2059,10 @@ YY_EXTRA_TYPE ast_yyget_extra (yyscan_t yyscanner) int ast_yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yylineno; } @@ -2072,10 +2072,10 @@ int ast_yyget_lineno (yyscan_t yyscanner) int ast_yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yycolumn; } @@ -2136,8 +2136,8 @@ void ast_yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ast_yyset_lineno called with no buffer" , yyscanner); - + yy_fatal_error( "ast_yyset_lineno called with no buffer" , yyscanner); + yylineno = line_number; } @@ -2151,8 +2151,8 @@ void ast_yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ast_yyset_column called with no buffer" , yyscanner); - + yy_fatal_error( "ast_yyset_column called with no buffer" , yyscanner); + yycolumn = column_no; } @@ -2205,13 +2205,13 @@ YYLTYPE *ast_yyget_lloc (yyscan_t yyscanner) struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } - + void ast_yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } - + /* User-visible API */ /* ast_yylex_init is special because it creates the scanner itself, so it is @@ -2259,20 +2259,20 @@ int ast_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals errno = EINVAL; return 1; } - + *ptr_yy_globals = (yyscan_t) ast_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - + if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } - + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - + ast_yyset_extra (yy_user_defined, *ptr_yy_globals); - + return yy_init_globals ( *ptr_yy_globals ); } @@ -2487,7 +2487,7 @@ void ast_expr_clear_extra_error_info(void) extra_error_message[0] = 0; } -static const char * const expr2_token_equivs1[] = +static const char * const expr2_token_equivs1[] = { "TOKEN", "TOK_COND", @@ -2513,7 +2513,7 @@ static const char * const expr2_token_equivs1[] = "TOK_LP" }; -static const char * const expr2_token_equivs2[] = +static const char * const expr2_token_equivs2[] = { "<token>", "?", @@ -2624,4 +2624,3 @@ int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio ) free(s2); return(0); } - diff --git a/main/asterisk.c b/main/asterisk.c index 0026b36d7..01107e217 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -795,12 +795,35 @@ static int swapmode(int *used, int *total) static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { uint64_t physmem, freeram; +#if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL) uint64_t freeswap = 0; +#endif int nprocs = 0; long uptime = 0; int totalswap = 0; #if defined(HAVE_SYSINFO) struct sysinfo sys_info; +#elif defined(HAVE_SYSCTL) + static int pageshift; + struct vmtotal vmtotal; + struct timeval boottime; + time_t now; + int mib[2], pagesize, usedswap = 0; + size_t len; +#endif + + switch (cmd) { + case CLI_INIT: + e->command = "core show sysinfo"; + e->usage = + "Usage: core show sysinfo\n" + " List current system information.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + +#if defined(HAVE_SYSINFO) sysinfo(&sys_info); uptime = sys_info.uptime / 3600; physmem = sys_info.totalram * sys_info.mem_unit; @@ -809,12 +832,6 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024; nprocs = sys_info.procs; #elif defined(HAVE_SYSCTL) - static int pageshift; - struct vmtotal vmtotal; - struct timeval boottime; - time_t now; - int mib[2], pagesize, usedswap = 0; - size_t len; /* calculate the uptime by looking at boottime */ time(&now); mib[0] = CTL_KERN; @@ -862,17 +879,6 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl #endif #endif - switch (cmd) { - case CLI_INIT: - e->command = "core show sysinfo"; - e->usage = - "Usage: core show sysinfo\n" - " List current system information.\n"; - return NULL; - case CLI_GENERATE: - return NULL; - } - ast_cli(a->fd, "\nSystem Statistics\n"); ast_cli(a->fd, "-----------------\n"); ast_cli(a->fd, " System Uptime: %ld hours\n", uptime); @@ -881,7 +887,7 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl #if defined(HAVE_SYSINFO) ast_cli(a->fd, " Buffer RAM: %" PRIu64 " KiB\n", ((uint64_t) sys_info.bufferram * sys_info.mem_unit) / 1024); #endif -#if defined(HAVE_SWAPCTL) || defined(HAVE_SYSINFO) +#if defined(HAVE_SYSINFO) || defined(HAVE_SWAPCTL) ast_cli(a->fd, " Total Swap Space: %d KiB\n", totalswap); ast_cli(a->fd, " Free Swap Space: %" PRIu64 " KiB\n\n", freeswap); #endif @@ -1691,18 +1697,21 @@ static void *listener(void *unused) int s; socklen_t len; int x; - int flags; + int poll_result; struct pollfd fds[1]; + for (;;) { - if (ast_socket < 0) + if (ast_socket < 0) { return NULL; + } fds[0].fd = ast_socket; fds[0].events = POLLIN; - s = ast_poll(fds, 1, -1); + poll_result = ast_poll(fds, 1, -1); pthread_testcancel(); - if (s < 0) { - if (errno != EINTR) + if (poll_result < 0) { + if (errno != EINTR) { ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); + } continue; } len = sizeof(sunaddr); @@ -1716,6 +1725,7 @@ static void *listener(void *unused) /* turn on socket credentials passing. */ if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) { ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n"); + close(s); } else #endif { @@ -1729,8 +1739,7 @@ static void *listener(void *unused) close(s); break; } - flags = fcntl(consoles[x].p[1], F_GETFL); - fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK); + ast_fd_set_flags(consoles[x].p[1], O_NONBLOCK); consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */ /* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able to know if the user didn't send the credentials. */ @@ -2517,52 +2526,6 @@ static int remoteconsolehandler(const char *s) (s[4] == '\0' || isspace(s[4]))) { quit_handler(0, SHUTDOWN_FAST, 0); ret = 1; - } else if (s[0]) { - char *shrunk = ast_strdupa(s); - char *cur; - char *prev; - - /* - * Remove duplicate spaces from shrunk for matching purposes. - * - * shrunk has at least one character in it to start with or we - * couldn't get here. - */ - for (prev = shrunk, cur = shrunk + 1; *cur; ++cur) { - if (*prev == ' ' && *cur == ' ') { - /* Skip repeated space delimiter. */ - continue; - } - *++prev = *cur; - } - *++prev = '\0'; - - if (strncasecmp(shrunk, "core set verbose ", 17) == 0) { - /* - * We need to still set the rasterisk option_verbose in case we are - * talking to an earlier version which doesn't prefilter verbose - * levels. This is really a compromise as we should always take - * whatever the server sends. - */ - - if (!strncasecmp(shrunk + 17, "off", 3)) { - ast_verb_console_set(0); - } else { - int verbose_new; - int atleast; - - atleast = 8; - if (strncasecmp(shrunk + 17, "atleast ", atleast)) { - atleast = 0; - } - - if (sscanf(shrunk + 17 + atleast, "%30d", &verbose_new) == 1) { - if (!atleast || ast_verb_console_get() < verbose_new) { - ast_verb_console_set(verbose_new); - } - } - } - } } return ret; @@ -2887,6 +2850,9 @@ static void send_rasterisk_connect_commands(void) fdsend(ast_consock, buf); } + /* Leave verbose filtering to the server. */ + option_verbose = INT_MAX; + if (!ast_opt_mute) { fdsend(ast_consock, "logger mute silent"); } else { @@ -3236,20 +3202,10 @@ static char *cli_complete(EditLine *editline, int ch) #define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\"" char *mbuf; char *new_mbuf; - int mlen = 0, maxmbuf = 2048; - - /* Start with a 2048 byte buffer */ - mbuf = ast_malloc(maxmbuf); - - /* This will run snprintf twice at most. */ - while (mbuf && (mlen = snprintf(mbuf, maxmbuf, CMD_MATCHESARRAY, lf->buffer, ptr)) > maxmbuf) { - /* Return value does not include space for NULL terminator. */ - maxmbuf = mlen + 1; - ast_free(mbuf); - mbuf = ast_malloc(maxmbuf); - } + int mlen = 0; + int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr); - if (!mbuf) { + if (maxmbuf == -1) { *((char *) lf->cursor) = savechr; return (char *)(CC_ERROR); @@ -3262,9 +3218,9 @@ static char *cli_complete(EditLine *editline, int ch) while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { if (mlen + 1024 > maxmbuf) { - /* Expand buffer to the next 1024 byte increment. */ + /* Expand buffer to the next 1024 byte increment plus a NULL terminator. */ maxmbuf = mlen + 1024; - new_mbuf = ast_realloc(mbuf, maxmbuf); + new_mbuf = ast_realloc(mbuf, maxmbuf + 1); if (!new_mbuf) { ast_free(mbuf); *((char *) lf->cursor) = savechr; @@ -3277,6 +3233,7 @@ static char *cli_complete(EditLine *editline, int ch) res = read(ast_consock, mbuf + mlen, 1024); if (res > 0) { mlen += res; + mbuf[mlen] = '\0'; } } mbuf[mlen] = '\0'; diff --git a/main/astfd.c b/main/astfd.c index a96471d60..e9bc142f1 100644 --- a/main/astfd.c +++ b/main/astfd.c @@ -306,4 +306,3 @@ int ast_fd_init(void) return 0; } #endif /* defined(DEBUG_FD_LEAKS) */ - diff --git a/main/astmm.c b/main/astmm.c index d53323aba..59baa4221 100644 --- a/main/astmm.c +++ b/main/astmm.c @@ -1466,7 +1466,7 @@ static void mm_atexit_dump(void) /* * Put the alloced list back into regions[]. * - * We have do do this because we can get called before all other + * We have do this because we can get called before all other * threads have terminated. */ mm_atexit_hash_restore(&alloced_atexit); diff --git a/main/astobj2_container.c b/main/astobj2_container.c index 466c10372..ae20fa639 100644 --- a/main/astobj2_container.c +++ b/main/astobj2_container.c @@ -1236,4 +1236,3 @@ int container_init(void) return 0; } - diff --git a/main/astobj2_hash.c b/main/astobj2_hash.c index f5c678740..da0ae8dea 100644 --- a/main/astobj2_hash.c +++ b/main/astobj2_hash.c @@ -1153,4 +1153,3 @@ struct ao2_container *__ao2_container_alloc_list_debug(unsigned int ao2_options, return __ao2_container_alloc_hash_debug(ao2_options, container_options, 1, NULL, sort_fn, cmp_fn, tag, file, line, func, ref_debug); } - diff --git a/main/astobj2_rbtree.c b/main/astobj2_rbtree.c index 4362b83cb..d2c2ebf3f 100644 --- a/main/astobj2_rbtree.c +++ b/main/astobj2_rbtree.c @@ -2097,4 +2097,3 @@ struct ao2_container *__ao2_container_alloc_rbtree_debug(unsigned int ao2_option tag, file, line, func, ref_debug); return rb_ao2_container_init(self, container_options, sort_fn, cmp_fn); } - diff --git a/main/bridge.c b/main/bridge.c index f689b297f..8284fd3af 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -2495,6 +2495,8 @@ int ast_bridge_add_channel(struct ast_bridge *bridge, struct ast_channel *chan, RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup); RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup); + ast_moh_stop(chan); + ast_channel_lock(chan); chan_bridge = ast_channel_get_bridge(chan); ast_channel_unlock(chan); @@ -3806,7 +3808,7 @@ void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct a data->average_talking_energy = talker_energy; } else if ((data->average_talking_energy < talker_energy) && is_keyframe) { if (data->chan_old_vsrc) { - ast_channel_unref(data->chan_old_vsrc); + data->chan_old_vsrc = ast_channel_unref(data->chan_old_vsrc); } if (data->chan_vsrc) { data->chan_old_vsrc = data->chan_vsrc; diff --git a/main/bridge_basic.c b/main/bridge_basic.c index 93da8cecb..53a4be703 100644 --- a/main/bridge_basic.c +++ b/main/bridge_basic.c @@ -3666,4 +3666,3 @@ void ast_bridging_init_basic(void) ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, feature_attended_transfer, NULL); ast_bridge_features_register(AST_BRIDGE_BUILTIN_BLINDTRANSFER, feature_blind_transfer, NULL); } - diff --git a/main/bucket.c b/main/bucket.c index 7618761b9..084d25368 100644 --- a/main/bucket.c +++ b/main/bucket.c @@ -560,33 +560,10 @@ struct ast_json *ast_bucket_json(const struct ast_bucket *bucket) } /*! \brief Hashing function for file metadata */ -static int bucket_file_metadata_hash(const void *obj, const int flags) -{ - const struct ast_bucket_metadata *object; - const char *key; - - switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { - case OBJ_KEY: - key = obj; - return ast_str_hash(key); - case OBJ_POINTER: - object = obj; - return ast_str_hash(object->name); - default: - /* Hash can only work on something with a full key */ - ast_assert(0); - return 0; - } -} +AO2_STRING_FIELD_HASH_FN(ast_bucket_metadata, name) /*! \brief Comparison function for file metadata */ -static int bucket_file_metadata_cmp(void *obj, void *arg, int flags) -{ - struct ast_bucket_metadata *metadata1 = obj, *metadata2 = arg; - const char *name = arg; - - return !strcmp(metadata1->name, flags & OBJ_KEY ? name : metadata2->name) ? CMP_MATCH | CMP_STOP : 0; -} +AO2_STRING_FIELD_CMP_FN(ast_bucket_metadata, name) /*! \brief Destructor for bucket files */ static void bucket_file_destroy(void *obj) @@ -616,7 +593,7 @@ static void *bucket_file_alloc(const char *name) } file->metadata = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, METADATA_BUCKETS, - bucket_file_metadata_hash, bucket_file_metadata_cmp); + ast_bucket_metadata_hash_fn, ast_bucket_metadata_cmp_fn); if (!file->metadata) { return NULL; } @@ -851,33 +828,10 @@ void ast_bucket_file_temporary_destroy(struct ast_bucket_file *file) } /*! \brief Hashing function for scheme container */ -static int bucket_scheme_hash(const void *obj, const int flags) -{ - const struct ast_bucket_scheme *object; - const char *key; - - switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { - case OBJ_KEY: - key = obj; - return ast_str_hash(key); - case OBJ_POINTER: - object = obj; - return ast_str_hash(object->name); - default: - /* Hash can only work on something with a full key */ - ast_assert(0); - return 0; - } -} +AO2_STRING_FIELD_HASH_FN(ast_bucket_scheme, name) /*! \brief Comparison function for scheme container */ -static int bucket_scheme_cmp(void *obj, void *arg, int flags) -{ - struct ast_bucket_scheme *scheme1 = obj, *scheme2 = arg; - const char *name = arg; - - return !strcmp(scheme1->name, flags & OBJ_KEY ? name : scheme2->name) ? CMP_MATCH | CMP_STOP : 0; -} +AO2_STRING_FIELD_CMP_FN(ast_bucket_scheme, name) /*! \brief Cleanup function for graceful shutdowns */ static void bucket_cleanup(void) @@ -910,8 +864,8 @@ int ast_bucket_init(void) { ast_register_cleanup(&bucket_cleanup); - schemes = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, SCHEME_BUCKETS, bucket_scheme_hash, - bucket_scheme_cmp); + schemes = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, SCHEME_BUCKETS, + ast_bucket_scheme_hash_fn, ast_bucket_scheme_cmp_fn); if (!schemes) { ast_log(LOG_ERROR, "Failed to create container for Bucket schemes\n"); return -1; diff --git a/main/ccss.c b/main/ccss.c index 2a939abfd..f11fe1db6 100644 --- a/main/ccss.c +++ b/main/ccss.c @@ -1386,19 +1386,8 @@ struct generic_monitor_pvt { int core_id; }; -static int generic_monitor_hash_fn(const void *obj, const int flags) -{ - const struct generic_monitor_instance_list *generic_list = obj; - return ast_str_hash(generic_list->device_name); -} - -static int generic_monitor_cmp_fn(void *obj, void *arg, int flags) -{ - const struct generic_monitor_instance_list *generic_list1 = obj; - const struct generic_monitor_instance_list *generic_list2 = arg; - - return !strcmp(generic_list1->device_name, generic_list2->device_name) ? CMP_MATCH | CMP_STOP : 0; -} +AO2_STRING_FIELD_HASH_FN(generic_monitor_instance_list, device_name) +AO2_STRING_FIELD_CMP_FN(generic_monitor_instance_list, device_name) static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name) { @@ -2859,7 +2848,7 @@ static void *generic_recall(void *data) return NULL; } ao2_ref(tmp_cap, -1); - + /* We have a channel. It's time now to set up the datastore of recalled CC interfaces. * This will be a common task for all recall functions. If it were possible, I'd have * the core do it automatically, but alas I cannot. Instead, I will provide a public @@ -4671,8 +4660,8 @@ int ast_cc_init(void) return -1; } if (!(generic_monitors = ao2_t_container_alloc(CC_CORE_INSTANCES_BUCKETS, - generic_monitor_hash_fn, generic_monitor_cmp_fn, - "Create generic monitor container"))) { + generic_monitor_instance_list_hash_fn, generic_monitor_instance_list_cmp_fn, + "Create generic monitor container"))) { return -1; } if (!(cc_core_taskprocessor = ast_taskprocessor_get("CCSS_core", TPS_REF_DEFAULT))) { diff --git a/main/cdr.c b/main/cdr.c index 60532fe9f..90371a46a 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -241,8 +241,29 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct module_config, general), - .category = "^general$", - .category_match = ACO_WHITELIST, + .category = "general", + .category_match = ACO_WHITELIST_EXACT, +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "csv", + "custom", + "manager", + "odbc", + "pgsql", + "radius", + "sqlite", + "tds", + "mysql", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; static void *module_config_alloc(void); @@ -252,8 +273,7 @@ static void module_config_post_apply(void); /*! \brief The file definition */ static struct aco_file module_file_conf = { .filename = "cdr.conf", - .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)", - .types = ACO_TYPES(&general_option), + .types = ACO_TYPES(&general_option, &ignore_option), }; CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc, @@ -2074,7 +2094,12 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str if (!peer && !caller) { return; } - if (filter_channel_snapshot(peer) || (caller && filter_channel_snapshot(caller))) { + + if (peer && filter_channel_snapshot(peer)) { + return; + } + + if (caller && filter_channel_snapshot(caller)) { return; } @@ -2454,12 +2479,12 @@ static void bridge_candidate_add_to_cdr(struct cdr_object *cdr, * \param cand_cdr The \ref cdr_object that is a candidate * */ -static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr) +static void bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *base_cand_cdr) { struct cdr_object_snapshot *party_a; struct cdr_object *cand_cdr; - SCOPED_AO2LOCK(lock, base_cand_cdr); + ao2_lock(base_cand_cdr); for (cand_cdr = base_cand_cdr; cand_cdr; cand_cdr = cand_cdr->next) { /* Skip any records that are not in this bridge */ @@ -2471,7 +2496,7 @@ static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *b if (!strcasecmp(cdr->party_a.snapshot->name, cand_cdr->party_a.snapshot->name) || (cdr->party_b.snapshot && !strcasecmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name))) { - return 0; + break; } party_a = cdr_object_pick_party_a(&cdr->party_a, &cand_cdr->party_a); @@ -2479,7 +2504,7 @@ static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *b * Party B */ if (!strcasecmp(party_a->snapshot->name, cdr->party_a.snapshot->name)) { bridge_candidate_add_to_cdr(cdr, &cand_cdr->party_a); - return 0; + break; } /* We're Party B. Check if we can add ourselves immediately or if we need @@ -2499,9 +2524,11 @@ static int bridge_candidate_process(struct cdr_object *cdr, struct cdr_object *b */ memset(&cand_cdr->end, 0, sizeof(cand_cdr->end)); } - return 0; + + break; } - return 0; + + ao2_unlock(base_cand_cdr); } /*! @@ -2584,6 +2611,7 @@ static void handle_standard_bridge_enter_message(struct cdr_object *cdr, ao2_lock(cdr); +try_again: for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) { if (it_cdr->fn_table->process_party_a) { CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr, @@ -2636,7 +2664,7 @@ static void handle_standard_bridge_enter_message(struct cdr_object *cdr, /* This is guaranteed to succeed: the new CDR is created in the single state * and will be able to handle the bridge enter message */ - handle_standard_bridge_enter_message(cdr, bridge, channel); + goto try_again; } } ao2_unlock(cdr); @@ -2845,32 +2873,39 @@ int ast_cdr_backend_unsuspend(const char *name) int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be) { - struct cdr_beitem *i = NULL; + struct cdr_beitem *i; + struct cdr_beitem *cur; - if (!name) + if (!name) { return -1; + } if (!be) { ast_log(LOG_WARNING, "CDR engine '%s' lacks backend\n", name); + + return -1; + } + + i = ast_calloc(1, sizeof(*i)); + if (!i) { return -1; } + i->be = be; + ast_copy_string(i->name, name, sizeof(i->name)); + ast_copy_string(i->desc, desc, sizeof(i->desc)); + AST_RWLIST_WRLOCK(&be_list); - AST_RWLIST_TRAVERSE(&be_list, i, list) { - if (!strcasecmp(name, i->name)) { + AST_RWLIST_TRAVERSE(&be_list, cur, list) { + if (!strcasecmp(name, cur->name)) { ast_log(LOG_WARNING, "Already have a CDR backend called '%s'\n", name); AST_RWLIST_UNLOCK(&be_list); + ast_free(i); + return -1; } } - if (!(i = ast_calloc(1, sizeof(*i)))) - return -1; - - i->be = be; - ast_copy_string(i->name, name, sizeof(i->name)); - ast_copy_string(i->desc, desc, sizeof(i->desc)); - AST_RWLIST_INSERT_HEAD(&be_list, i, list); AST_RWLIST_UNLOCK(&be_list); @@ -4146,7 +4181,7 @@ static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_ if (!ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) { ast_cli(a->fd, "Cannot submit CDR batch: CDR engine disabled.\n"); - } else if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) { + } else if (!ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) { ast_cli(a->fd, "Cannot submit CDR batch: batch mode not enabled.\n"); } else { submit_unscheduled_batch(); diff --git a/main/cel.c b/main/cel.c index 0cdf1be00..31cd04542 100644 --- a/main/cel.c +++ b/main/cel.c @@ -244,15 +244,28 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct cel_config, general), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "manager", + "radius", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; /*! \brief The config file to be processed for the module. */ static struct aco_file cel_conf = { .filename = "cel.conf", /*!< The name of the config file */ - .types = ACO_TYPES(&general_option), /*!< The mapping object types to be processed */ - .skip_category = "(^manager$|^radius$)", /*!< Config sections used by existing modules. Do not add to this list. */ + .types = ACO_TYPES(&general_option, &ignore_option), /*!< The mapping object types to be processed */ }; static int cel_pre_apply_config(void); @@ -318,129 +331,16 @@ struct cel_backend { }; /*! \brief Hashing function for cel_backend */ -static int cel_backend_hash(const void *obj, int flags) -{ - const struct cel_backend *backend; - const char *name; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - backend = obj; - name = backend->name; - break; - case OBJ_SEARCH_KEY: - name = obj; - break; - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } - - return ast_str_hash(name); -} +AO2_STRING_FIELD_HASH_FN(cel_backend, name) /*! \brief Comparator function for cel_backend */ -static int cel_backend_cmp(void *obj, void *arg, int flags) -{ - const struct cel_backend *object_left = obj; - const struct cel_backend *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->name; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->name, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - /* - * We could also use a partial key struct containing a length - * so strlen() does not get called for every comparison instead. - */ - cmp = strncmp(object_left->name, right_key, strlen(right_key)); - break; - default: - /* - * What arg points to is specific to this traversal callback - * and has no special meaning to astobj2. - */ - cmp = 0; - break; - } - if (cmp) { - return 0; - } - /* - * At this point the traversal callback is identical to a sorted - * container. - */ - return CMP_MATCH; -} +AO2_STRING_FIELD_CMP_FN(cel_backend, name) /*! \brief Hashing function for dialstatus container */ -static int dialstatus_hash(const void *obj, int flags) -{ - const struct cel_dialstatus *dialstatus; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - dialstatus = obj; - key = dialstatus->uniqueid; - break; - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} +AO2_STRING_FIELD_HASH_FN(cel_dialstatus, uniqueid) /*! \brief Comparator function for dialstatus container */ -static int dialstatus_cmp(void *obj, void *arg, int flags) -{ - struct cel_dialstatus *object_left = obj; - struct cel_dialstatus *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->uniqueid; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->uniqueid, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - /* - * We could also use a partial key struct containing a length - * so strlen() does not get called for every comparison instead. - */ - cmp = strncmp(object_left->uniqueid, right_key, strlen(right_key)); - break; - default: - /* - * What arg points to is specific to this traversal callback - * and has no special meaning to astobj2. - */ - cmp = 0; - break; - } - if (cmp) { - return 0; - } - /* - * At this point the traversal callback is identical to a sorted - * container. - */ - return CMP_MATCH; -} +AO2_STRING_FIELD_CMP_FN(cel_dialstatus, uniqueid) unsigned int ast_cel_check_enabled(void) { @@ -1654,71 +1554,14 @@ static int create_routes(void) return ret; } -static int lid_hash(const void *obj, const int flags) -{ - const struct cel_linkedid *lid; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - lid = obj; - key = lid->id; - break; - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} - -static int lid_cmp(void *obj, void *arg, int flags) -{ - const struct cel_linkedid *object_left = obj; - const struct cel_linkedid *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->id; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->id, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - /* - * We could also use a partial key struct containing a length - * so strlen() does not get called for every comparison instead. - */ - cmp = strncmp(object_left->id, right_key, strlen(right_key)); - break; - default: - /* - * What arg points to is specific to this traversal callback - * and has no special meaning to astobj2. - */ - cmp = 0; - break; - } - if (cmp) { - return 0; - } - /* - * At this point the traversal callback is identical to a sorted - * container. - */ - return CMP_MATCH; -} +AO2_STRING_FIELD_HASH_FN(cel_linkedid, id) +AO2_STRING_FIELD_CMP_FN(cel_linkedid, id) int ast_cel_engine_init(void) { struct ao2_container *container; - container = ao2_container_alloc(NUM_APP_BUCKETS, lid_hash, lid_cmp); + container = ao2_container_alloc(NUM_APP_BUCKETS, cel_linkedid_hash_fn, cel_linkedid_cmp_fn); ao2_global_obj_replace_unref(cel_linkedids, container); ao2_cleanup(container); if (!container) { @@ -1727,7 +1570,7 @@ int ast_cel_engine_init(void) } container = ao2_container_alloc(NUM_DIALSTATUS_BUCKETS, - dialstatus_hash, dialstatus_cmp); + cel_dialstatus_hash_fn, cel_dialstatus_cmp_fn); ao2_global_obj_replace_unref(cel_dialstatus_store, container); ao2_cleanup(container); if (!container) { @@ -1745,7 +1588,7 @@ int ast_cel_engine_init(void) return -1; } - container = ao2_container_alloc(BACKEND_BUCKETS, cel_backend_hash, cel_backend_cmp); + container = ao2_container_alloc(BACKEND_BUCKETS, cel_backend_hash_fn, cel_backend_cmp_fn); ao2_global_obj_replace_unref(cel_backends, container); ao2_cleanup(container); if (!container) { @@ -1824,9 +1667,9 @@ void ast_cel_publish_event(struct ast_channel *chan, struct ast_json *cel_blob; struct stasis_message *message; - cel_blob = ast_json_pack("{s: i, s: O}", + cel_blob = ast_json_pack("{s: i, s: o}", "event_type", event_type, - "event_details", blob); + "event_details", ast_json_ref(blob)); message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), cel_generic_type(), cel_blob); if (message) { diff --git a/main/channel.c b/main/channel.c index d22c98738..48963c729 100644 --- a/main/channel.c +++ b/main/channel.c @@ -11033,4 +11033,3 @@ void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag) ast_clear_flag(ast_channel_flags(chan), flag); ast_channel_unlock(chan); } - diff --git a/main/cli.c b/main/cli.c index 8e0cc3bd3..fe20c3401 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1418,6 +1418,8 @@ static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, str } else if (a->pos == 5) { return ast_cli_complete(a->word, completions_off, a->n); } + + return NULL; } if (cmd == (CLI_HANDLER + 1000)) { @@ -1520,17 +1522,20 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar return CLI_FAILURE; } - output = ast_str_create(8192); - if (!output) { - return CLI_FAILURE; - } - chan = ast_channel_get_by_name(a->argv[3]); if (!chan) { ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); + return CLI_SUCCESS; } + output = ast_str_create(8192); + if (!output) { + ast_channel_unref(chan); + + return CLI_FAILURE; + } + now = ast_tvnow(); ast_channel_lock(chan); diff --git a/main/codec.c b/main/codec.c index d0e63682b..05cee4ab6 100644 --- a/main/codec.c +++ b/main/codec.c @@ -75,24 +75,7 @@ struct internal_ast_codec { int __ast_codec_register_with_format(struct ast_codec *codec, const char *format_name, struct ast_module *mod); -static int codec_hash(const void *obj, int flags) -{ - const struct ast_codec *codec; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - return ast_str_hash(key); - case OBJ_SEARCH_OBJECT: - codec = obj; - return ast_str_hash(codec->name); - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } -} +AO2_STRING_FIELD_HASH_FN(ast_codec, name) static int codec_cmp(void *obj, void *arg, int flags) { @@ -267,7 +250,8 @@ static void codec_shutdown(void) int ast_codec_init(void) { - codecs = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CODEC_BUCKETS, codec_hash, codec_cmp); + codecs = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CODEC_BUCKETS, + ast_codec_hash_fn, codec_cmp); if (!codecs) { return -1; } diff --git a/main/config_options.c b/main/config_options.c index f52d3c410..3ac5590ec 100644 --- a/main/config_options.c +++ b/main/config_options.c @@ -98,6 +98,7 @@ static char *aco_option_type_string[] = { "String", /* OPT_STRINGFIELD_T, */ "Unsigned Integer", /* OPT_UINT_T, */ "Boolean", /* OPT_YESNO_T, */ + "Time Length", /* OPT_TIMELEN_T, */ }; #endif /* AST_XML_DOCS */ @@ -133,7 +134,7 @@ static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *va static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj); #ifdef AST_XML_DOCS -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches); +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match); static int xmldoc_update_config_option(struct aco_type **types, const char *module, const char *name, const char *object_name, const char *default_value, unsigned int regex, enum aco_option_type type); #endif @@ -375,6 +376,8 @@ static int find_option_cb(void *obj, void *arg, int flags) switch (match->match_type) { case ACO_EXACT: return strcasecmp(name, match->name) ? 0 : CMP_MATCH | CMP_STOP; + case ACO_PREFIX: + return strncasecmp(name, match->name, strlen(match->name)) ? 0 : CMP_MATCH | CMP_STOP; case ACO_REGEX: return regexec(match->name_regex, name, 0, NULL, 0) ? 0 : CMP_MATCH | CMP_STOP; } @@ -404,6 +407,45 @@ struct ao2_container *aco_option_container_alloc(void) return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp); } +static int internal_aco_type_category_check(struct aco_type *match, const char *category) +{ + const char **categories = (const char **)match->category; + + switch (match->category_match) { + case ACO_WHITELIST: + return regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_BLACKLIST: + return !regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_WHITELIST_EXACT: + return strcasecmp(match->category, category); + + case ACO_BLACKLIST_EXACT: + return !strcasecmp(match->category, category); + + case ACO_WHITELIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return 0; + } + categories++; + } + return -1; + + case ACO_BLACKLIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return -1; + } + categories++; + } + return 0; + } + + return -1; +} + static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast_config *cfg, const char *category) { size_t x; @@ -412,7 +454,7 @@ static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast for (x = 0, match = file->types[x]; match; match = file->types[++x]) { /* First make sure we are an object that can service this category */ - if (!regexec(match->internal->regex, category, 0, NULL, 0) == !match->category_match) { + if (internal_aco_type_category_check(match, category)) { continue; } @@ -485,6 +527,10 @@ static int process_category(struct ast_config *cfg, struct aco_info *info, struc return -1; } + if (type->type == ACO_IGNORE) { + return 0; + } + field = info->internal->pending + type->item_offset; if (!*field) { ast_log(LOG_ERROR, "In %s: %s - No object to update!\n", file->filename, cat); @@ -570,7 +616,7 @@ enum aco_process_status aco_process_ast_config(struct aco_info *info, struct aco { if (!info->internal) { ast_log(LOG_ERROR, "Attempt to process %s with uninitialized aco_info\n", file->filename); - goto error; + return ACO_PROCESS_ERROR; } if (!(info->internal->pending = info->snapshot_alloc())) { @@ -633,6 +679,10 @@ enum aco_process_status aco_process_config(struct aco_info *info, int reload) for (i = 0, match = file->types[i]; match; match = file->types[++i]) { void **field = info->internal->pending + match->item_offset; + if (match->type == ACO_IGNORE) { + continue; + } + if (match->type != ACO_GLOBAL || !*field) { continue; } @@ -799,9 +849,19 @@ static int internal_type_init(struct aco_type *type) return -1; } - if (!(type->internal->regex = build_regex(type->category))) { - internal_type_destroy(type); - return -1; + switch (type->category_match) { + case ACO_BLACKLIST: + case ACO_WHITELIST: + if (!(type->internal->regex = build_regex(type->category))) { + internal_type_destroy(type); + return -1; + } + break; + case ACO_BLACKLIST_EXACT: + case ACO_WHITELIST_EXACT: + case ACO_BLACKLIST_ARRAY: + case ACO_WHITELIST_ARRAY: + break; } if (!(type->internal->opts = aco_option_container_alloc())) { @@ -830,7 +890,8 @@ int aco_info_init(struct aco_info *info) #ifdef AST_XML_DOCS if (!info->hidden && !type->hidden && - xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match == ACO_WHITELIST)) { + type->type != ACO_IGNORE && + xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match)) { goto error; } #endif /* AST_XML_DOCS */ @@ -991,7 +1052,7 @@ static char *complete_config_option(const char *module, const char *option, cons /*! \internal * \brief Update the XML documentation for a config type based on its registration */ -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches) +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match) { RAII_VAR(struct ast_xml_xpath_results *, results, NULL, ast_xml_xpath_results_free); RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup); @@ -1030,7 +1091,18 @@ static int xmldoc_update_config_type(const char *module, const char *name, const } ast_xml_set_text(tmp, category); - ast_xml_set_attribute(tmp, "match", matches ? "true" : "false"); + switch (category_match) { + case ACO_WHITELIST: + case ACO_WHITELIST_EXACT: + case ACO_WHITELIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "true"); + break; + case ACO_BLACKLIST: + case ACO_BLACKLIST_EXACT: + case ACO_BLACKLIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "false"); + break; + } if (!ast_strlen_zero(matchfield) && !(tmp = ast_xml_new_child(matchinfo, "field"))) { ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module); @@ -129,6 +129,20 @@ DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb ORDER BY ke DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ? ORDER BY key") DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))") +/* This query begs an explanation: + * + * First, the parameter binding syntax used here is slightly different than the other + * queries in that we use a numbered parameter so that we can bind once and get the same + * value substituted multiple times within the executed query. + * + * Second, the key comparison is being used to find all keys that are lexicographically + * greater than the provided key, but less than the provided key with a high (but + * invalid) Unicode codepoint appended to it. This will give us all keys in the database + * that have 'key' as a prefix and performs much better than the equivalent "LIKE key || + * '%'" operation. + */ +DEFINE_SQL_STATEMENT(gettree_prefix_stmt, "SELECT key, value FROM astdb WHERE key > ?1 AND key <= ?1 || X'ffff'") + static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len) { ast_mutex_lock(&dblock); @@ -169,6 +183,7 @@ static void clean_statements(void) clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql); clean_stmt(&gettree_stmt, gettree_stmt_sql); clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql); + clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql); clean_stmt(&showkey_stmt, showkey_stmt_sql); clean_stmt(&put_stmt, put_stmt_sql); clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql); @@ -184,6 +199,7 @@ static int init_statements(void) || init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql)) || init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql)) || init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql)) + || init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql, sizeof(gettree_prefix_stmt_sql)) || init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql)) || init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql)); } @@ -475,19 +491,64 @@ int ast_db_deltree(const char *family, const char *keytree) return res; } +static struct ast_db_entry *db_gettree_common(sqlite3_stmt *stmt) +{ + struct ast_db_entry *head = NULL, *prev = NULL, *cur; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + const char *key, *value; + size_t key_len, value_len; + + key = (const char *) sqlite3_column_text(stmt, 0); + value = (const char *) sqlite3_column_text(stmt, 1); + + if (!key || !value) { + break; + } + + key_len = strlen(key); + value_len = strlen(value); + + cur = ast_malloc(sizeof(*cur) + key_len + value_len + 2); + if (!cur) { + break; + } + + cur->next = NULL; + cur->key = cur->data + value_len + 1; + memcpy(cur->data, value, value_len + 1); + memcpy(cur->key, key, key_len + 1); + + if (prev) { + prev->next = cur; + } else { + head = cur; + } + prev = cur; + } + + return head; +} + struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree) { char prefix[MAX_DB_FIELD]; sqlite3_stmt *stmt = gettree_stmt; - struct ast_db_entry *cur, *last = NULL, *ret = NULL; + size_t res = 0; + struct ast_db_entry *ret; if (!ast_strlen_zero(family)) { if (!ast_strlen_zero(keytree)) { /* Family and key tree */ - snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree); + res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree); } else { /* Family only */ - snprintf(prefix, sizeof(prefix), "/%s", family); + res = snprintf(prefix, sizeof(prefix), "/%s", family); + } + + if (res >= sizeof(prefix)) { + ast_log(LOG_WARNING, "Requested prefix is too long: %s\n", keytree); + return NULL; } } else { prefix[0] = '\0'; @@ -495,41 +556,47 @@ struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree) } ast_mutex_lock(&dblock); - if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) { - ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb)); + if (res && (sqlite3_bind_text(stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK)) { + ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb)); sqlite3_reset(stmt); ast_mutex_unlock(&dblock); return NULL; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - const char *key_s, *value_s; - if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) { - break; - } - if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) { - break; - } - if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) { - break; - } - cur->next = NULL; - cur->key = cur->data + strlen(value_s) + 1; - strcpy(cur->data, value_s); - strcpy(cur->key, key_s); - if (last) { - last->next = cur; - } else { - ret = cur; - } - last = cur; - } + ret = db_gettree_common(stmt); sqlite3_reset(stmt); ast_mutex_unlock(&dblock); return ret; } +struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_prefix) +{ + char prefix[MAX_DB_FIELD]; + size_t res; + struct ast_db_entry *ret; + + res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, key_prefix); + if (res >= sizeof(prefix)) { + ast_log(LOG_WARNING, "Requested key prefix is too long: %s\n", key_prefix); + return NULL; + } + + ast_mutex_lock(&dblock); + if (sqlite3_bind_text(gettree_prefix_stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK) { + ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb)); + sqlite3_reset(gettree_prefix_stmt); + ast_mutex_unlock(&dblock); + return NULL; + } + + ret = db_gettree_common(gettree_prefix_stmt); + sqlite3_reset(gettree_prefix_stmt); + ast_mutex_unlock(&dblock); + + return ret; +} + void ast_db_freetree(struct ast_db_entry *dbe) { struct ast_db_entry *last; @@ -962,8 +1029,8 @@ static void *db_sync_thread(void *data) ast_mutex_lock(&dblock); ast_db_begin_transaction(); for (;;) { - /* If dosync is set, db_sync() was called during sleep(1), - * and the pending transaction should be committed. + /* If dosync is set, db_sync() was called during sleep(1), + * and the pending transaction should be committed. * Otherwise, block until db_sync() is called. */ while (!dosync) { diff --git a/main/dns.c b/main/dns.c index 320d91768..de26c8d7c 100644 --- a/main/dns.c +++ b/main/dns.c @@ -340,4 +340,3 @@ struct ao2_container *ast_dns_get_nameservers(void) return nameservers; } - diff --git a/main/editline/INSTALL b/main/editline/INSTALL index 16fb6ffd1..05e00f71c 100644 --- a/main/editline/INSTALL +++ b/main/editline/INSTALL @@ -29,7 +29,7 @@ Optionally, pass any of the following (not a definitive list) arguments to --prefix=<install-root-dir> Set the base directory in which to install. For example: - + ./configure --prefix=/usr/local will cause files to be installed into /usr/local/bin, /usr/local/man, @@ -51,7 +51,7 @@ CFLAGS="?" CPPFLAGS="?" Pass these flags to the C preprocessor. Note that CFLAGS is not passed - to 'cpp' when 'configure' is looking for include files, so you must use + to 'cpp' when 'configure' is looking for include files, so you must use CPPFLAGS instead if you need to help 'configure' find header files. LD_LIBRARY_PATH="?" diff --git a/main/editline/chared.c b/main/editline/chared.c index 8eaeb3b54..d0a03e2ad 100644 --- a/main/editline/chared.c +++ b/main/editline/chared.c @@ -515,7 +515,7 @@ ch_enlargebufs(el, addlen) /* zero the newly added memory, leave old data in */ (void) memset(&newbuffer[sz], 0, newsz - sz); - + oldbuf = el->el_line.buffer; el->el_line.buffer = newbuffer; @@ -554,7 +554,7 @@ ch_enlargebufs(el, addlen) el->el_chared.c_undo.ptr = el->el_line.buffer + (el->el_chared.c_undo.ptr - oldbuf); el->el_chared.c_undo.buf = newbuffer; - + if (!hist_enlargebuf(el, sz, newsz)) return 0; diff --git a/main/editline/configure b/main/editline/configure index d5d0a4dea..ea180bce2 100755 --- a/main/editline/configure +++ b/main/editline/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 +# Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -932,15 +932,15 @@ case "${host}" in if echo ${host} | grep -q cygwin ; then \ echo "cygwin detected"; \ S_CFLAGS=""; \ - echo "/* cygdef.h. Generated automatically by configure. */ + echo "/* cygdef.h. Generated automatically by configure. */ #ifndef _CYGDEF_H_ #define _CYGDEF_H_ 1 #include <sys/ioctl.h> #define __linux__ 1 - + typedef void (*sig_t)(int); - + #endif /* _CYGDEF_H_ */" > cygdef.h; \ echo " @@ -1092,13 +1092,13 @@ else /*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; - ?:/*) + ?:/*) ac_cv_path_AR="$AR" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" - for ac_dir in $ac_dummy; do + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_AR="$ac_dir/$ac_word" @@ -1348,7 +1348,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF - + else echo "$ac_t""no" 1>&6 \ @@ -1386,7 +1386,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF - + else echo "$ac_t""no" 1>&6 \ @@ -1428,7 +1428,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF - + else echo "$ac_t""no" 1>&6 \ @@ -1466,7 +1466,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF - + else echo "$ac_t""no" 1>&6 \ @@ -1515,7 +1515,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF - + else echo "$ac_t""no" 1>&6 fi @@ -1571,7 +1571,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 fi @@ -1626,7 +1626,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 CCSRCS="$CCSRCS np/fgetln.c" @@ -1682,7 +1682,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 CCSRCS="$CCSRCS np/vis.c" @@ -1738,7 +1738,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 CCSRCS="$CCSRCS np/unvis.c" @@ -1794,7 +1794,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 CCSRCS="$CCSRCS np/strlcpy.c" @@ -1850,7 +1850,7 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF - + else echo "$ac_t""no" 1>&6 CCSRCS="$CCSRCS np/strlcat.c" @@ -2460,5 +2460,3 @@ EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - - diff --git a/main/editline/configure.in b/main/editline/configure.in index d8bc706b1..bd99b5a86 100644 --- a/main/editline/configure.in +++ b/main/editline/configure.in @@ -1,6 +1,6 @@ -dnl +dnl dnl Process this file with autoconf to produce a configure script. -dnl +dnl AC_INIT(Makefile.in) dnl If CFLAGS isn't defined and using gcc, set CFLAGS to something reasonable. @@ -36,15 +36,15 @@ case "${host}" in if echo ${host} | grep -q cygwin ; then \ echo "cygwin detected"; \ S_CFLAGS=""; \ - echo "/* cygdef.h. Generated automatically by configure. */ + echo "/* cygdef.h. Generated automatically by configure. */ #ifndef _CYGDEF_H_ #define _CYGDEF_H_ 1 #include <sys/ioctl.h> #define __linux__ 1 - + typedef void (*sig_t)(int); - + #endif /* _CYGDEF_H_ */" > cygdef.h; \ echo " @@ -155,10 +155,10 @@ else fi -dnl +dnl dnl File lists. This is done here instead of in the Makefile in order to avoid dnl the need for conditionals. -dnl +dnl dnl .c files. ACSRCS="common.c emacs.c vi.c" @@ -275,4 +275,3 @@ AC_SUBST(TCSRCS) AC_CONFIG_HEADER(config.h) AC_OUTPUT([Makefile makelist]) - diff --git a/main/editline/install-sh b/main/editline/install-sh index ebc66913e..058b26c82 100755 --- a/main/editline/install-sh +++ b/main/editline/install-sh @@ -115,7 +115,7 @@ fi if [ x"$dir_arg" != x ]; then dst=$src src="" - + if [ -d $dst ]; then instcmd=: else @@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad +# might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] @@ -134,7 +134,7 @@ else echo "install: $src does not exist" exit 1 fi - + if [ x"$dst" = x ] then echo "install: no destination specified" @@ -162,7 +162,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then -defaultIFS=' +defaultIFS=' ' IFS="${IFS-${defaultIFS}}" @@ -201,17 +201,17 @@ else # If we're going to rename the final executable, determine the name now. - if [ x"$transformarg" = x ] + if [ x"$transformarg" = x ] then dstfile=`basename $dst` else - dstfile=`basename $dst $transformbasename | + dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename - if [ x"$dstfile" = x ] + if [ x"$dstfile" = x ] then dstfile=`basename $dst` else @@ -242,7 +242,7 @@ else # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile + $doit $mvcmd $dsttmp $dstdir/$dstfile fi && diff --git a/main/editline/map.c b/main/editline/map.c index 4187cb597..448c3c0ca 100644 --- a/main/editline/map.c +++ b/main/editline/map.c @@ -369,7 +369,7 @@ private const el_action_t el_map_vi_insert[] = { * NOTE: These mappings do NOT Correspond well * to the KSH VI editing assignments. * On the other and they are convenient and - * many people have have gotten used to them. + * many people have gotten used to them. */ /* 0 */ ED_UNASSIGNED, /* ^@ */ /* 1 */ ED_MOVE_TO_BEG, /* ^A */ diff --git a/main/editline/np/unvis.c b/main/editline/np/unvis.c index 844a5581b..0a26e3d63 100644 --- a/main/editline/np/unvis.c +++ b/main/editline/np/unvis.c @@ -105,7 +105,7 @@ __unvis13(cp, c, astate, flag) || *astate == S_HEX2) { *astate = S_GROUND; return (UNVIS_VALID); - } + } return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } @@ -116,7 +116,7 @@ __unvis13(cp, c, astate, flag) if (c == '\\') { *astate = S_START; return (0); - } + } if ((flag & VIS_HTTPSTYLE) && c == '%') { *astate = S_HEX1; return (0); @@ -193,7 +193,7 @@ __unvis13(cp, c, astate, flag) } *astate = S_GROUND; return (UNVIS_SYNBAD); - + case S_META: if (c == '-') *astate = S_META1; @@ -204,12 +204,12 @@ __unvis13(cp, c, astate, flag) return (UNVIS_SYNBAD); } return (0); - + case S_META1: *astate = S_GROUND; *cp |= c; return (UNVIS_VALID); - + case S_CTRL: if (c == '?') *cp |= 0177; @@ -220,15 +220,15 @@ __unvis13(cp, c, astate, flag) case S_OCTAL2: /* second possible octal digit */ if (isoctal(c)) { - /* - * yes - and maybe a third + /* + * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; + *astate = S_OCTAL3; return (0); - } - /* - * no - done with current sequence, push back passed char + } + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); @@ -249,8 +249,8 @@ __unvis13(cp, c, astate, flag) *astate = S_HEX2; return (0); } - /* - * no - done with current sequence, push back passed char + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); @@ -261,9 +261,9 @@ __unvis13(cp, c, astate, flag) return (UNVIS_VALID); } return (UNVIS_VALIDPUSH); - default: - /* - * decoder in unknown state - (probably uninitialized) + default: + /* + * decoder in unknown state - (probably uninitialized) */ *astate = S_GROUND; return (UNVIS_SYNBAD); @@ -271,7 +271,7 @@ __unvis13(cp, c, astate, flag) } /* - * strunvis - decode src into dst + * strunvis - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. diff --git a/main/editline/np/vis.c b/main/editline/np/vis.c index bd8192440..264dce629 100644 --- a/main/editline/np/vis.c +++ b/main/editline/np/vis.c @@ -111,7 +111,7 @@ do \ SVIS(dst, c, flag, nextc, extra); \ } \ while (/*CONSTCOND*/0) - + /* * This is SVIS, the central macro of vis. * dst: Pointer to the destination buffer @@ -219,10 +219,10 @@ svis(dst, c, flag, nextc, extra) * be encoded, too. These functions are useful e. g. to * encode strings in such a way so that they are not interpreted * by a shell. - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strsvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. @@ -294,7 +294,7 @@ char * vis(dst, c, flag, nextc) char *dst; int c, flag, nextc; - + { char *extra; @@ -312,10 +312,10 @@ vis(dst, c, flag, nextc) /* * strvis, strvisx - visually encode characters from src into dst - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. diff --git a/main/editline/read.h b/main/editline/read.h index b01e77db2..716a51693 100644 --- a/main/editline/read.h +++ b/main/editline/read.h @@ -47,7 +47,7 @@ typedef int (*el_rfunc_t)(EditLine *, char *); typedef struct el_read_t { el_rfunc_t read_char; /* Function to read a character */ } el_read_t; - + protected int read_init(EditLine *); protected int el_read_setfn(EditLine *, el_rfunc_t); protected el_rfunc_t el_read_getfn(EditLine *); diff --git a/main/editline/readline.c b/main/editline/readline.c index 48a843df2..7389c1886 100644 --- a/main/editline/readline.c +++ b/main/editline/readline.c @@ -250,7 +250,7 @@ rl_initialize(void) break; } } - + /* read settings from configuration file */ el_source(e, NULL); @@ -1531,7 +1531,7 @@ rl_complete_internal(int what_to_do) maxlen = match_len; } matches_num = i - 1; - + /* newline to get on next line from command line */ fprintf(e->el_outfile, "\n"); diff --git a/main/editline/refresh.c b/main/editline/refresh.c index fcebe1253..fe3ac440f 100644 --- a/main/editline/refresh.c +++ b/main/editline/refresh.c @@ -166,7 +166,7 @@ re_putc(EditLine *el, int c, int shift) for(i=1; i < lins; i++) el->el_vdisplay[i-1] = el->el_vdisplay[i]; - firstline[0] = '\0'; /* empty the string */ + firstline[0] = '\0'; /* empty the string */ el->el_vdisplay[i-1] = firstline; } else el->el_refresh.r_cursor.v++; @@ -1002,7 +1002,7 @@ re_fastputc(EditLine *el, int c) if (el->el_cursor.v + 1 >= el->el_term.t_size.v) { int i, lins = el->el_term.t_size.v; char *firstline = el->el_display[0]; - + for(i=1; i < lins; i++) el->el_display[i-1] = el->el_display[i]; @@ -1064,7 +1064,7 @@ re_fastaddc(EditLine *el) /* re_clear_display(): - * clear the screen buffers so that new new prompt starts fresh. + * clear the screen buffers so that new prompt starts fresh. */ protected void re_clear_display(EditLine *el) diff --git a/main/editline/term.c b/main/editline/term.c index 00b68ed33..6814cc4ca 100644 --- a/main/editline/term.c +++ b/main/editline/term.c @@ -428,7 +428,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) */ tlen = 0; for (tmp = tlist; tmp < &tlist[T_str]; tmp++) - if (*tmp != NULL && *tmp != '\0' && *tmp != *str) { + if (*tmp != NULL && **tmp != '\0' && *tmp != *str) { char *ptr; for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++) @@ -640,7 +640,7 @@ mc_again: (el->el_cursor.h & 0370); i < (where & 0370); i += 8) - term__putc('\t'); + term__putc('\t'); /* then tab over */ el->el_cursor.h = where & 0370; } diff --git a/main/endpoints.c b/main/endpoints.c index 80e7f87fd..88506a4c8 100644 --- a/main/endpoints.c +++ b/main/endpoints.c @@ -78,53 +78,8 @@ struct ast_endpoint { struct stasis_forward *tech_forward; }; -static int endpoint_hash(const void *obj, int flags) -{ - const struct ast_endpoint *endpoint; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - return ast_str_hash(key); - case OBJ_SEARCH_OBJECT: - endpoint = obj; - return ast_str_hash(endpoint->id); - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } -} - -static int endpoint_cmp(void *obj, void *arg, int flags) -{ - const struct ast_endpoint *left = obj; - const struct ast_endpoint *right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = right->id; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(left->id, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(left->id, right_key, strlen(right_key)); - break; - default: - ast_assert(0); - cmp = 0; - break; - } - if (cmp) { - return 0; - } - - return CMP_MATCH; -} +AO2_STRING_FIELD_HASH_FN(ast_endpoint, id) +AO2_STRING_FIELD_CMP_FN(ast_endpoint, id) struct ast_endpoint *ast_endpoint_find_by_id(const char *id) { @@ -524,14 +479,14 @@ int ast_endpoint_init(void) { ast_register_cleanup(endpoint_cleanup); - endpoints = ao2_container_alloc(ENDPOINT_BUCKETS, endpoint_hash, - endpoint_cmp); + endpoints = ao2_container_alloc(ENDPOINT_BUCKETS, ast_endpoint_hash_fn, + ast_endpoint_cmp_fn); if (!endpoints) { return -1; } - tech_endpoints = ao2_container_alloc(TECH_ENDPOINT_BUCKETS, endpoint_hash, - endpoint_cmp); + tech_endpoints = ao2_container_alloc(TECH_ENDPOINT_BUCKETS, ast_endpoint_hash_fn, + ast_endpoint_cmp_fn); if (!tech_endpoints) { return -1; } diff --git a/main/features_config.c b/main/features_config.c index 2689687cc..e2d405740 100644 --- a/main/features_config.c +++ b/main/features_config.c @@ -219,7 +219,7 @@ The <replaceable>DYNAMIC_FEATURES</replaceable> is a <literal>#</literal> separated list of either applicationmap item names or featuregroup names.</para> </description> - <configOption name="^.*$" regex="true"> + <configOption name=""> <synopsis>A custom feature to invoke during a bridged call</synopsis> <description> <para>Each item listed here is a comma-separated list of parameters that determine @@ -272,7 +272,7 @@ DTMF sequence used to invoke an applicationmap item to be overridden with a different sequence.</para> </description> - <configOption name="^.*$" regex="true"> + <configOption name=""> <synopsis>Applicationmap item to place in the feature group</synopsis> <description> <para>Each item here must be a name of an item in the applicationmap. The @@ -578,24 +578,24 @@ struct features_config { static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "globals", - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", .item_offset = offsetof(struct features_config, global), }; static struct aco_type featuremap_option = { .type = ACO_GLOBAL, .name = "featuremap", - .category_match = ACO_WHITELIST, - .category = "^featuremap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "featuremap", .item_offset = offsetof(struct features_config, featuremap), }; static struct aco_type applicationmap_option = { .type = ACO_GLOBAL, .name = "applicationmap", - .category_match = ACO_WHITELIST, - .category = "^applicationmap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "applicationmap", .item_offset = offsetof(struct features_config, applicationmap), }; @@ -1851,13 +1851,13 @@ static int load_config(void) aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options, DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, applicationmap_options, "", applicationmap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, featuregroup_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, featuregroup_options, "", featuregroup_handler, 0); - aco_option_register_custom_nodoc(&cfg_info, "^.*$", ACO_REGEX, parkinglot_options, + aco_option_register_custom_nodoc(&cfg_info, "", ACO_PREFIX, parkinglot_options, "", unsupported_handler, 0); if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) { diff --git a/main/format.c b/main/format.c index 758a7fc5e..b81a1f1d4 100644 --- a/main/format.c +++ b/main/format.c @@ -64,53 +64,8 @@ struct format_interface { /*! \brief Container for registered format interfaces */ static struct ao2_container *interfaces; -static int format_interface_hash(const void *obj, int flags) -{ - const struct format_interface *format_interface; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - return ast_str_hash(key); - case OBJ_SEARCH_OBJECT: - format_interface = obj; - return ast_str_hash(format_interface->codec); - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } -} - -static int format_interface_cmp(void *obj, void *arg, int flags) -{ - const struct format_interface *left = obj; - const struct format_interface *right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - cmp = strcmp(left->codec, right->codec); - break; - case OBJ_SEARCH_KEY: - cmp = strcmp(left->codec, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(left->codec, right_key, strlen(right_key)); - break; - default: - ast_assert(0); - cmp = 0; - break; - } - if (cmp) { - return 0; - } - - return CMP_MATCH; -} +AO2_STRING_FIELD_HASH_FN(format_interface, codec) +AO2_STRING_FIELD_CMP_FN(format_interface, codec) /*! \brief Function called when the process is shutting down */ static void format_shutdown(void) @@ -121,8 +76,8 @@ static void format_shutdown(void) int ast_format_init(void) { - interfaces = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, FORMAT_INTERFACE_BUCKETS, format_interface_hash, - format_interface_cmp); + interfaces = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, FORMAT_INTERFACE_BUCKETS, + format_interface_hash_fn, format_interface_cmp_fn); if (!interfaces) { return -1; } diff --git a/main/format_cache.c b/main/format_cache.c index 00563e899..3de1951a3 100644 --- a/main/format_cache.c +++ b/main/format_cache.c @@ -541,4 +541,3 @@ int ast_format_cache_is_slinear(struct ast_format *format) return 0; } - diff --git a/main/format_compatibility.c b/main/format_compatibility.c index 0f1dff7c8..6a4dacbb1 100644 --- a/main/format_compatibility.c +++ b/main/format_compatibility.c @@ -271,4 +271,3 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield) } return NULL; } - diff --git a/main/fskmodem.c b/main/fskmodem.c index dee5f5cf7..63f7ce8e1 100644 --- a/main/fskmodem.c +++ b/main/fskmodem.c @@ -32,4 +32,3 @@ #else #include "fskmodem_float.c" #endif - diff --git a/main/http.c b/main/http.c index d1a443a4f..e8d395b15 100644 --- a/main/http.c +++ b/main/http.c @@ -1955,9 +1955,7 @@ static void *httpd_helper_thread(void *data) } /* make sure socket is non-blocking */ - flags = fcntl(ser->fd, F_GETFL); - flags |= O_NONBLOCK; - fcntl(ser->fd, F_SETFL, flags); + ast_fd_set_flags(ser->fd, O_NONBLOCK); /* Setup HTTP worker private data to keep track of request body reading. */ ao2_cleanup(ser->private_data); diff --git a/main/indications.c b/main/indications.c index 02a68b7ca..488868076 100644 --- a/main/indications.c +++ b/main/indications.c @@ -1194,4 +1194,3 @@ int ast_indications_reload(void) { return load_indications(1); } - diff --git a/main/jitterbuf.c b/main/jitterbuf.c index df3164f39..21c11043b 100644 --- a/main/jitterbuf.c +++ b/main/jitterbuf.c @@ -358,7 +358,7 @@ static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, l frame->type = type; /* - * frames are a circular list, jb-frames points to to the lowest ts, + * frames are a circular list, jb-frames points to the lowest ts, * jb->frames->prev points to the highest ts */ diff --git a/main/loader.c b/main/loader.c index 7d792b08e..b9baf3e93 100644 --- a/main/loader.c +++ b/main/loader.c @@ -54,7 +54,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/features_config.h" #include "asterisk/dsp.h" #include "asterisk/udptl.h" -#include "asterisk/heap.h" +#include "asterisk/vector.h" #include "asterisk/app.h" #include "asterisk/test.h" #include "asterisk/sounds_index.h" @@ -112,6 +112,8 @@ static const unsigned char expected_key[] = static char buildopt_sum[33] = AST_BUILDOPT_SUM; +AST_VECTOR(module_vector, struct ast_module *); + /*! * \brief Internal flag to indicate all modules have been initially loaded. */ @@ -137,13 +139,34 @@ struct ast_module { /*! This module is being held open until it's time to shutdown. */ unsigned int keepuntilshutdown:1; } flags; - AST_LIST_ENTRY(ast_module) list_entry; AST_DLLIST_ENTRY(ast_module) entry; char resource[0]; }; static AST_DLLIST_HEAD_STATIC(module_list, ast_module); +static int module_vector_strcasecmp(struct ast_module *a, struct ast_module *b) +{ + return strcasecmp(a->resource, b->resource); +} + +static int module_vector_cmp(struct ast_module *a, struct ast_module *b) +{ + /* if load_pri is not set, default is 128. Lower is better */ + int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER) + ? a->info->load_pri : AST_MODPRI_DEFAULT; + int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER) + ? b->info->load_pri : AST_MODPRI_DEFAULT; + + /* + * Returns comparison values for a vector sorted by priority. + * <0 a_pri < b_pri + * =0 a_pri == b_pri + * >0 a_pri > b_pri + */ + return a_pri - b_pri; +} + const char *ast_module_name(const struct ast_module *mod) { if (!mod || !mod->info) { @@ -171,38 +194,51 @@ static int do_full_reload = 0; static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item); -/* when dynamic modules are being loaded, ast_module_register() will - need to know what filename the module was loaded from while it - is being registered -*/ -static struct ast_module *resource_being_loaded; - -/* XXX: should we check for duplicate resource names here? */ +/*! + * \internal + * + * This variable is set by load_dynamic_module so ast_module_register + * can know what pointer is being registered. + * + * This is protected by the module_list lock. + */ +static struct ast_module * volatile resource_being_loaded; +/*! + * \internal + * \brief Used by AST_MODULE_INFO to register with the module loader. + * + * This function is automatically called when each module is opened. + * It must never be used from outside AST_MODULE_INFO. + */ void ast_module_register(const struct ast_module_info *info) { - struct ast_module *mod = resource_being_loaded; + struct ast_module *mod; + + /* + * This lock protects resource_being_loaded as well as the module + * list. Normally we already have a lock on module_list when we + * begin the load but locking again from here prevents corruption + * if an asterisk module is dlopen'ed from outside the module loader. + */ + AST_DLLIST_LOCK(&module_list); + mod = resource_being_loaded; + if (!mod) { + AST_DLLIST_UNLOCK(&module_list); + return; + } ast_debug(5, "Registering module %s\n", info->name); + /* This tells load_dynamic_module that we're registered. */ + resource_being_loaded = NULL; + mod->info = info; #ifdef REF_DEBUG mod->ref_debug = ao2_t_alloc(0, NULL, info->name); #endif AST_LIST_HEAD_INIT(&mod->users); - /* during startup, before the loader has been initialized, - there are no threads, so there is no need to take the lock - on this list to manipulate it. it is also possible that it - might be unsafe to use the list lock at that point... so - let's avoid it altogether - */ - AST_DLLIST_LOCK(&module_list); - /* it is paramount that the new entry be placed at the tail of - the list, otherwise the code that uses dlopen() to load - dynamic modules won't be able to find out if the module it - just opened was registered or failed to load - */ AST_DLLIST_INSERT_TAIL(&module_list, mod, entry); AST_DLLIST_UNLOCK(&module_list); @@ -210,6 +246,15 @@ void ast_module_register(const struct ast_module_info *info) *((struct ast_module **) &(info->self)) = mod; } +static void module_destroy(struct ast_module *mod) +{ + AST_LIST_HEAD_DESTROY(&mod->users); +#ifdef REF_DEBUG + ao2_cleanup(mod->ref_debug); +#endif + ast_free(mod); +} + void ast_module_unregister(const struct ast_module_info *info) { struct ast_module *mod = NULL; @@ -230,11 +275,7 @@ void ast_module_unregister(const struct ast_module_info *info) if (mod) { ast_debug(5, "Unregistering module %s\n", info->name); - AST_LIST_HEAD_DESTROY(&mod->users); -#ifdef REF_DEBUG - ao2_cleanup(mod->ref_debug); -#endif - ast_free(mod); + module_destroy(mod); } } @@ -382,35 +423,39 @@ static int verify_key(const unsigned char *key) return -1; } -static int resource_name_match(const char *name1_in, const char *name2_in) +static size_t resource_name_baselen(const char *name) { - char *name1 = (char *) name1_in; - char *name2 = (char *) name2_in; + size_t len = strlen(name); - /* trim off any .so extensions */ - if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) { - name1 = ast_strdupa(name1); - name1[strlen(name1) - 3] = '\0'; + if (len > 3 && !strcasecmp(name + len - 3, ".so")) { + return len - 3; } - if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) { - name2 = ast_strdupa(name2); - name2[strlen(name2) - 3] = '\0'; + + return len; +} + +static int resource_name_match(const char *name1, size_t baselen1, const char *name2) +{ + if (baselen1 != resource_name_baselen(name2)) { + return -1; } - return strcasecmp(name1, name2); + return strncasecmp(name1, name2, baselen1); } static struct ast_module *find_resource(const char *resource, int do_lock) { struct ast_module *cur; + size_t resource_baselen = resource_name_baselen(resource); if (do_lock) { AST_DLLIST_LOCK(&module_list); } AST_DLLIST_TRAVERSE(&module_list, cur, entry) { - if (!resource_name_match(resource, cur->resource)) + if (!resource_name_match(resource, resource_baselen, cur->resource)) { break; + } } if (do_lock) { @@ -500,96 +545,93 @@ static void unload_dynamic_module(struct ast_module *mod) #endif } -static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required); - #define MODULE_LOCAL_ONLY (void *)-1 -static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap) +/*! + * \internal + * \brief Attempt to dlopen a module. + * + * \param resource_in The module name to load. + * \param so_ext ".so" or blank if ".so" is already part of resource_in. + * \param filename Passed directly to dlopen. + * \param flags Passed directly to dlopen. + * \param suppress_logging Do not log any error from dlopen. + * + * \return Pointer to opened module, NULL on error. + * + * \warning module_list must be locked before calling this function. + */ +static struct ast_module *load_dlopen(const char *resource_in, const char *so_ext, + const char *filename, int flags, unsigned int suppress_logging) { - char fn[PATH_MAX] = ""; - void *lib = NULL; struct ast_module *mod; - unsigned int wants_global; - int space; /* room needed for the descriptor */ - int missing_so = 0; - space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1; - if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) { - missing_so = 1; - space += 3; /* room for the extra ".so" */ - } - - snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : ""); + ast_assert(!resource_being_loaded); - /* make a first load of the module in 'quiet' mode... don't try to resolve - any symbols, and don't export any symbols. this will allow us to peek into - the module's info block (if available) to see what flags it has set */ - - resource_being_loaded = ast_calloc(1, space); - if (!resource_being_loaded) + mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1); + if (!mod) { return NULL; - strcpy(resource_being_loaded->resource, resource_in); - if (missing_so) - strcat(resource_being_loaded->resource, ".so"); + } + + sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */ - if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_GLOBAL))) { - if (!suppress_logging) { + resource_being_loaded = mod; + mod->lib = dlopen(filename, flags); + if (resource_being_loaded) { + resource_being_loaded = NULL; + if (mod->lib) { + ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in); + logged_dlclose(resource_in, mod->lib); + } else if (!suppress_logging) { ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); } - ast_free(resource_being_loaded); - return NULL; - } + ast_free(mod); - /* the dlopen() succeeded, let's find out if the module - registered itself */ - /* note that this will only work properly as long as - ast_module_register() (which is called by the module's - constructor) places the new module at the tail of the - module_list - */ - if (resource_being_loaded != (mod = AST_DLLIST_LAST(&module_list))) { - ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in); - /* no, it did not, so close it and return */ - logged_dlclose(resource_in, lib); - /* note that the module's destructor will call ast_module_unregister(), - which will free the structure we allocated in resource_being_loaded */ return NULL; } - wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS); + return mod; +} + +static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging) +{ + char fn[PATH_MAX]; + struct ast_module *mod; + size_t resource_in_len = strlen(resource_in); + int exports_globals; + const char *so_ext = ""; - /* if we are being asked only to load modules that provide global symbols, - and this one does not, then close it and return */ - if (global_symbols_only && !wants_global) { - logged_dlclose(resource_in, lib); - return MODULE_LOCAL_ONLY; + if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) { + so_ext = ".so"; } - logged_dlclose(resource_in, lib); - resource_being_loaded = NULL; + snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext); - /* start the load process again */ - resource_being_loaded = ast_calloc(1, space); - if (!resource_being_loaded) - return NULL; - strcpy(resource_being_loaded->resource, resource_in); - if (missing_so) - strcat(resource_being_loaded->resource, ".so"); + /* Try loading in quiet mode first with flags to export global symbols. + * If the module does not want to export globals we will close and reopen. */ + mod = load_dlopen(resource_in, so_ext, fn, + global_symbols_only ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL, + suppress_logging); - if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) { - ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); - ast_free(resource_being_loaded); + if (!mod) { return NULL; } - /* since the module was successfully opened, and it registered itself - the previous time we did that, we're going to assume it worked this - time too :) */ + exports_globals = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS); + if ((global_symbols_only && exports_globals) || (!global_symbols_only && !exports_globals)) { + /* The first dlopen had the correct flags. */ + return mod; + } - AST_DLLIST_LAST(&module_list)->lib = lib; - resource_being_loaded = NULL; + /* Close the module so we can reopen with correct flags. */ + logged_dlclose(resource_in, mod->lib); + if (global_symbols_only) { + return MODULE_LOCAL_ONLY; + } - return AST_DLLIST_LAST(&module_list); + return load_dlopen(resource_in, so_ext, fn, + exports_globals ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL, + 0); } int modules_shutdown(void) @@ -623,11 +665,7 @@ int modules_shutdown(void) ast_verb(1, "Unloading %s\n", mod->resource); mod->info->unload(); } - AST_LIST_HEAD_DESTROY(&mod->users); -#ifdef REF_DEBUG - ao2_cleanup(mod->ref_debug); -#endif - free(mod); + module_destroy(mod); somethingchanged = 1; } AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END; @@ -947,6 +985,7 @@ enum ast_module_reload_result ast_module_reload(const char *name) struct ast_module *cur; enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND; int i; + size_t name_baselen = name ? resource_name_baselen(name) : 0; /* If we aren't fully booted, we just pretend we reloaded but we queue this up to run once we are booted up. */ @@ -1000,8 +1039,9 @@ enum ast_module_reload_result ast_module_reload(const char *name) AST_DLLIST_TRAVERSE(&module_list, cur, entry) { const struct ast_module_info *info = cur->info; - if (name && resource_name_match(name, cur->resource)) + if (name && resource_name_match(name, name_baselen, cur->resource)) { continue; + } if (!cur->flags.running || cur->flags.declined) { if (res == AST_MODULE_RELOAD_NOT_FOUND) { @@ -1122,13 +1162,13 @@ static enum ast_module_load_result start_resource(struct ast_module *mod) /*! loads a resource based upon resource_name. If global_symbols_only is set * only modules with global symbols will be loaded. * - * If the ast_heap is provided (not NULL) the module is found and added to the - * heap without running the module's load() function. By doing this, modules - * added to the resource_heap can be initialized later in order by priority. + * If the module_vector is provided (not NULL) the module is found and added to the + * vector without running the module's load() function. By doing this, modules + * can be initialized later in order by priority and dependencies. * - * If the ast_heap is not provided, the module's load function will be executed + * If the module_vector is not provided, the module's load function will be executed * immediately */ -static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required) +static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct module_vector *resource_heap, int required) { struct ast_module *mod; enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; @@ -1141,7 +1181,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) return AST_MODULE_LOAD_SKIP; } else { - mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging, resource_heap); + mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging); if (mod == MODULE_LOCAL_ONLY) { return AST_MODULE_LOAD_SKIP; } @@ -1154,21 +1194,26 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi } if (inspect_module(mod)) { - ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); - unload_dynamic_module(mod); - return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + goto prestart_error; } mod->flags.declined = 0; if (resource_heap) { - ast_heap_push(resource_heap, mod); + if (AST_VECTOR_ADD_SORTED(resource_heap, mod, module_vector_cmp)) { + goto prestart_error; + } res = AST_MODULE_LOAD_PRIORITY; } else { res = start_resource(mod); } return res; + +prestart_error: + ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); + unload_dynamic_module(mod); + return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; } int ast_load_resource(const char *resource_name) @@ -1195,9 +1240,10 @@ AST_LIST_HEAD_NOLOCK(load_order, load_order_entry); static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required) { struct load_order_entry *order; + size_t resource_baselen = resource_name_baselen(resource); AST_LIST_TRAVERSE(load_order, order, entry) { - if (!resource_name_match(order->resource, resource)) { + if (!resource_name_match(resource, resource_baselen, order->resource)) { /* Make sure we have the proper setting for the required field (we might have both load= and required= lines in modules.conf) */ order->required |= required; @@ -1215,23 +1261,6 @@ static struct load_order_entry *add_to_load_order(const char *resource, struct l return order; } -static int mod_load_cmp(void *a, void *b) -{ - struct ast_module *a_mod = (struct ast_module *) a; - struct ast_module *b_mod = (struct ast_module *) b; - /* if load_pri is not set, default is 128. Lower is better */ - int a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128; - int b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128; - - /* - * Returns comparison values for a min-heap - * <0 a_pri > b_pri - * =0 a_pri == b_pri - * >0 a_pri < b_pri - */ - return b_pri - a_pri; -} - AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry); /*! loads modules in order by load_pri, updates mod_count @@ -1239,9 +1268,8 @@ AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry); */ static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count) { - struct ast_heap *resource_heap; + struct module_vector resource_heap; struct load_order_entry *order; - struct ast_module *mod; struct load_retries load_retries; int count = 0; int res = 0; @@ -1250,7 +1278,9 @@ static int load_resource_list(struct load_order *load_order, unsigned int global AST_LIST_HEAD_INIT_NOLOCK(&load_retries); - if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) { + if (AST_VECTOR_INIT(&resource_heap, 500)) { + ast_log(LOG_ERROR, "Failed to initialize module loader.\n"); + return -1; } @@ -1259,7 +1289,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global enum ast_module_load_result lres; /* Suppress log messages unless this is the last pass */ - lres = load_resource(order->resource, global_symbols, 1, resource_heap, order->required); + lres = load_resource(order->resource, global_symbols, 1, &resource_heap, order->required); ast_debug(3, "PASS 0: %-46s %d %d\n", order->resource, lres, global_symbols); switch (lres) { case AST_MODULE_LOAD_SUCCESS: @@ -1283,7 +1313,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global */ break; case AST_MODULE_LOAD_PRIORITY: - /* load_resource worked and the module was added to the priority heap */ + /* load_resource worked and the module was added to the priority vector */ AST_LIST_REMOVE_CURRENT(entry); ast_free(order->resource); ast_free(order); @@ -1298,7 +1328,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global enum ast_module_load_result lres; /* Suppress log messages unless this is the last pass */ - lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), resource_heap, order->required); + lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), &resource_heap, order->required); ast_debug(3, "PASS %d %-46s %d %d\n", i + 1, order->resource, lres, global_symbols); switch (lres) { /* These are all retryable. */ @@ -1336,7 +1366,8 @@ static int load_resource_list(struct load_order *load_order, unsigned int global } /* second remove modules from heap sorted by priority */ - while ((mod = ast_heap_pop(resource_heap))) { + for (i = 0; i < AST_VECTOR_SIZE(&resource_heap); i++) { + struct ast_module *mod = AST_VECTOR_GET(&resource_heap, i); enum ast_module_load_result lres; lres = start_resource(mod); @@ -1366,7 +1397,7 @@ done: if (mod_count) { *mod_count += count; } - ast_heap_destroy(resource_heap); + AST_VECTOR_FREE(&resource_heap); return res; } @@ -1444,11 +1475,15 @@ int load_modules(unsigned int preload_only) /* now scan the config for any modules we are prohibited from loading and remove them from the load order */ for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { - if (strcasecmp(v->name, "noload")) + size_t baselen; + + if (strcasecmp(v->name, "noload")) { continue; + } + baselen = resource_name_baselen(v->value); AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { - if (!resource_name_match(order->resource, v->value)) { + if (!resource_name_match(v->value, baselen, order->resource)) { AST_LIST_REMOVE_CURRENT(entry); ast_free(order->resource); ast_free(order); @@ -1500,33 +1535,57 @@ void ast_update_use_count(void) AST_LIST_UNLOCK(&updaters); } +/*! + * \internal + * \brief Build an alpha sorted list of modules. + * + * \param alpha_module_list Pointer to uninitialized module_vector. + * + * This function always initializes alpha_module_list. + * + * \pre module_list must be locked. + */ +static int alpha_module_list_create(struct module_vector *alpha_module_list) +{ + struct ast_module *cur; + + if (AST_VECTOR_INIT(alpha_module_list, 32)) { + return -1; + } + + AST_DLLIST_TRAVERSE(&module_list, cur, entry) { + if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) { + return -1; + } + } + + return 0; +} + int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level), const char *like) { - struct ast_module *cur; - int unlock = -1; int total_mod_loaded = 0; - AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE; + struct module_vector alpha_module_list; - if (AST_DLLIST_TRYLOCK(&module_list)) { - unlock = 0; - } + AST_DLLIST_LOCK(&module_list); - AST_DLLIST_TRAVERSE(&module_list, cur, entry) { - AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource); - } + if (!alpha_module_list_create(&alpha_module_list)) { + int idx; - while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) { - total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, - cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level); - } + for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) { + struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx); - if (unlock) { - AST_DLLIST_UNLOCK(&module_list); + total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, + cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level); + } } + AST_DLLIST_UNLOCK(&module_list); + AST_VECTOR_FREE(&alpha_module_list); + return total_mod_loaded; } @@ -1536,22 +1595,24 @@ int ast_update_module_list_data(int (*modentry)(const char *module, const char * void *data), const char *like, void *data) { - struct ast_module *cur; int total_mod_loaded = 0; - AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE; + struct module_vector alpha_module_list; AST_DLLIST_LOCK(&module_list); - AST_DLLIST_TRAVERSE(&module_list, cur, entry) { - AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource); - } + if (!alpha_module_list_create(&alpha_module_list)) { + int idx; - while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) { - total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, - cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data); + for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) { + struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx); + + total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, + cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data); + } } AST_DLLIST_UNLOCK(&module_list); + AST_VECTOR_FREE(&alpha_module_list); return total_mod_loaded; } @@ -1563,23 +1624,25 @@ int ast_update_module_list_condition(int (*modentry)(const char *module, const c void *data, const char *condition), const char *like, void *data, const char *condition) { - struct ast_module *cur; int conditions_met = 0; - AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE; + struct module_vector alpha_module_list; AST_DLLIST_LOCK(&module_list); - AST_DLLIST_TRAVERSE(&module_list, cur, entry) { - AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource); - } + if (!alpha_module_list_create(&alpha_module_list)) { + int idx; - while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) { - conditions_met += modentry(cur->resource, cur->info->description, cur->usecount, - cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data, - condition); + for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) { + struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx); + + conditions_met += modentry(cur->resource, cur->info->description, cur->usecount, + cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data, + condition); + } } AST_DLLIST_UNLOCK(&module_list); + AST_VECTOR_FREE(&alpha_module_list); return conditions_met; } diff --git a/main/manager.c b/main/manager.c index 5bc87d547..4e611a085 100644 --- a/main/manager.c +++ b/main/manager.c @@ -247,14 +247,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") <parameter name="DNID"> <para>Dialed number identifier</para> </parameter> + <parameter name="EffectiveConnectedLineNum"> + </parameter> + <parameter name="EffectiveConnectedLineName"> + </parameter> <parameter name="TimeToHangup"> <para>Absolute lifetime of the channel</para> </parameter> <parameter name="BridgeID"> <para>Identifier of the bridge the channel is in, may be empty if not in one</para> </parameter> - <parameter name="Linkedid"> - </parameter> <parameter name="Application"> <para>Application currently executing on the channel</para> </parameter> @@ -2344,11 +2346,12 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_ AST_RWLIST_UNLOCK(&actions); return ret; } - authority = ast_str_alloca(MAX_AUTH_PERM_STRING); if (a->argc < 4) { return CLI_SHOWUSAGE; } + authority = ast_str_alloca(MAX_AUTH_PERM_STRING); + #ifdef AST_XML_DOCS /* setup the titles */ term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40); @@ -2376,6 +2379,22 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_ char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1); char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1); char *responses = ast_xmldoc_printable("None", 1); + + if (!syntax || !synopsis || !description || !arguments + || !seealso || !privilege || !responses) { + ast_free(syntax); + ast_free(synopsis); + ast_free(description); + ast_free(arguments); + ast_free(seealso); + ast_free(privilege); + ast_free(responses); + ast_cli(a->fd, "Allocation failure.\n"); + AST_RWLIST_UNLOCK(&actions); + + return CLI_FAILURE; + } + ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s", syntax_title, syntax, synopsis_title, synopsis, @@ -2403,6 +2422,14 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_ ast_cli(a->fd, "Event: %s\n", cur->final_response->name); print_event_instance(a, cur->final_response); } + + ast_free(syntax); + ast_free(synopsis); + ast_free(description); + ast_free(arguments); + ast_free(seealso); + ast_free(privilege); + ast_free(responses); } else #endif { @@ -4558,6 +4585,7 @@ static int action_status(struct mansession *s, const struct message *m) struct timeval now; long elapsed_seconds; struct ast_bridge *bridge; + struct ast_party_id effective_id; ast_channel_lock(chan); @@ -4586,10 +4614,12 @@ static int action_status(struct mansession *s, const struct message *m) channels++; bridge = ast_channel_get_bridge(chan); + effective_id = ast_channel_connected_effective_id(chan); astman_append(s, "Event: Status\r\n" "Privilege: Call\r\n" + /* v-- Start channel snapshot headers */ "Channel: %s\r\n" "ChannelState: %u\r\n" "ChannelStateDesc: %s\r\n" @@ -4602,13 +4632,14 @@ static int action_status(struct mansession *s, const struct message *m) "Exten: %s\r\n" "Priority: %d\r\n" "Uniqueid: %s\r\n" + "Linkedid: %s\r\n" + /* ^-- End channel snapshot headers */ "Type: %s\r\n" "DNID: %s\r\n" "EffectiveConnectedLineNum: %s\r\n" "EffectiveConnectedLineName: %s\r\n" "TimeToHangup: %ld\r\n" "BridgeID: %s\r\n" - "Linkedid: %s\r\n" "Application: %s\r\n" "Data: %s\r\n" "Nativeformats: %s\r\n" @@ -4622,6 +4653,7 @@ static int action_status(struct mansession *s, const struct message *m) "%s" "%s" "\r\n", + /* v-- Start channel snapshot headers */ ast_channel_name(chan), ast_channel_state(chan), ast_state2str(ast_channel_state(chan)), @@ -4634,13 +4666,14 @@ static int action_status(struct mansession *s, const struct message *m) ast_channel_exten(chan), ast_channel_priority(chan), ast_channel_uniqueid(chan), + ast_channel_linkedid(chan), + /* ^-- End channel snapshot headers */ ast_channel_tech(chan)->type, S_OR(ast_channel_dialed(chan)->number.str, ""), - S_COR(ast_channel_connected_effective_id(chan).number.valid, ast_channel_connected_effective_id(chan).number.str, "<unknown>"), - S_COR(ast_channel_connected_effective_id(chan).name.valid, ast_channel_connected_effective_id(chan).name.str, "<unknown>"), + S_COR(effective_id.number.valid, effective_id.number.str, "<unknown>"), + S_COR(effective_id.name.valid, effective_id.name.str, "<unknown>"), (long)ast_channel_whentohangup(chan)->tv_sec, bridge ? bridge->uniqueid : "", - ast_channel_linkedid(chan), ast_channel_appl(chan), ast_channel_data(chan), ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf), @@ -6684,9 +6717,7 @@ static void *session_do(void *data) } /* make sure socket is non-blocking */ - flags = fcntl(ser->fd, F_GETFL); - flags |= O_NONBLOCK; - fcntl(ser->fd, F_SETFL, flags); + ast_fd_set_flags(ser->fd, O_NONBLOCK); ao2_lock(session); /* Hook to the tail of the event queue */ diff --git a/main/manager_channels.c b/main/manager_channels.c index ffcd7f7e5..71c17322a 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -1300,4 +1300,3 @@ int manager_channels_init(void) return 0; } - diff --git a/main/manager_endpoints.c b/main/manager_endpoints.c index b2a45734a..4d997e622 100644 --- a/main/manager_endpoints.c +++ b/main/manager_endpoints.c @@ -87,4 +87,3 @@ int manager_endpoints_init(void) return 0; } - diff --git a/main/manager_system.c b/main/manager_system.c index b852c52e6..7a4896a68 100644 --- a/main/manager_system.c +++ b/main/manager_system.c @@ -44,7 +44,6 @@ static void manager_system_shutdown(void) int manager_system_init(void) { - int ret = 0; struct stasis_topic *manager_topic; struct stasis_topic *system_topic; struct stasis_message_router *message_router; @@ -69,13 +68,5 @@ int manager_system_init(void) ast_register_cleanup(manager_system_shutdown); - /* If somehow we failed to add any routes, just shut down the whole - * thing and fail it. - */ - if (ret) { - manager_system_shutdown(); - return -1; - } - return 0; } diff --git a/main/media_index.c b/main/media_index.c index 60bdfe3fd..72bc1ccbe 100644 --- a/main/media_index.c +++ b/main/media_index.c @@ -589,4 +589,3 @@ int ast_media_index_update(struct ast_media_index *index, { return media_index_update(index, variant, NULL); } - diff --git a/main/named_acl.c b/main/named_acl.c index 3b81c8c38..9ea89903e 100644 --- a/main/named_acl.c +++ b/main/named_acl.c @@ -82,8 +82,8 @@ static void *named_acl_find(struct ao2_container *container, const char *cat); static struct aco_type named_acl_type = { .type = ACO_ITEM, /*!< named_acls are items stored in containers, not individual global objects */ .name = "named_acl", - .category_match = ACO_BLACKLIST, - .category = "^general$", /*!< Match everything but "general" */ + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", /*!< Match everything but "general" */ .item_alloc = named_acl_alloc, /*!< A callback to allocate a new named_acl based on category */ .item_find = named_acl_find, /*!< A callback to find a named_acl in some container of named_acls */ .item_offset = offsetof(struct named_acl_config, named_acl_list), /*!< Could leave this out since 0 */ @@ -107,19 +107,8 @@ struct named_acl { char name[ACL_NAME_LENGTH]; /* Same max length as a configuration category */ }; -static int named_acl_hash_fn(const void *obj, const int flags) -{ - const struct named_acl *entry = obj; - return ast_str_hash(entry->name); -} - -static int named_acl_cmp_fn(void *obj, void *arg, const int flags) -{ - struct named_acl *entry1 = obj; - struct named_acl *entry2 = arg; - - return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0; -} +AO2_STRING_FIELD_HASH_FN(named_acl, name) +AO2_STRING_FIELD_CMP_FN(named_acl, name) /*! \brief destructor for named_acl_config */ static void named_acl_config_destructor(void *obj) @@ -403,7 +392,7 @@ static int publish_acl_change(const char *name) return 0; publish_failure: - ast_log(LOG_ERROR, "Failed to to issue ACL change message for %s.\n", + ast_log(LOG_ERROR, "Failed to issue ACL change message for %s.\n", ast_strlen_zero(name) ? "all named ACLs" : name); return -1; } diff --git a/main/named_locks.c b/main/named_locks.c index 596048388..6b41f2adb 100644 --- a/main/named_locks.c +++ b/main/named_locks.c @@ -39,46 +39,8 @@ struct ast_named_lock { char key[0]; }; -static int named_locks_hash(const void *obj, const int flags) -{ - const struct ast_named_lock *lock = obj; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - return ast_str_hash(obj); - case OBJ_SEARCH_OBJECT: - return ast_str_hash(lock->key); - default: - /* Hash can only work on something with a full key. */ - ast_assert(0); - return 0; - } -} - -static int named_locks_cmp(void *obj_left, void *obj_right, int flags) -{ - const struct ast_named_lock *object_left = obj_left; - const struct ast_named_lock *object_right = obj_right; - const char *right_key = obj_right; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->key; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->key, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(object_left->key, right_key, strlen(right_key)); - break; - default: - cmp = 0; - break; - } - - return cmp ? 0 : CMP_MATCH; -} +AO2_STRING_FIELD_HASH_FN(ast_named_lock, key) +AO2_STRING_FIELD_CMP_FN(ast_named_lock, key) static void named_locks_shutdown(void) { @@ -88,7 +50,7 @@ static void named_locks_shutdown(void) int ast_named_locks_init(void) { named_locks = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, - NAMED_LOCKS_BUCKETS, named_locks_hash, NULL, named_locks_cmp); + NAMED_LOCKS_BUCKETS, ast_named_lock_hash_fn, NULL, ast_named_lock_cmp_fn); if (!named_locks) { return -1; } diff --git a/main/netsock2.c b/main/netsock2.c index 73595fe84..5f94a750a 100644 --- a/main/netsock2.c +++ b/main/netsock2.c @@ -609,7 +609,7 @@ int ast_set_qos(int sockfd, int tos, int cos, const char *desc) /* If the sock address is IPv6, the TCLASS field must be set. */ set_tclass = !ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr) ? 1 : 0; - /* If the the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */ + /* If the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */ set_tos = (!set_tclass || (set_tclass && ast_sockaddr_is_any(&addr))) ? 1 : 0; if (set_tos) { diff --git a/main/pbx.c b/main/pbx.c index cfc5f7f9f..b313e0528 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -2823,7 +2823,6 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, struct ast_exten *e; struct ast_app *app; char *substitute = NULL; - int res; struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ char passdata[EXT_DATA_SIZE]; int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE); @@ -2840,9 +2839,12 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, ast_unlock_contexts(); return -1; /* success, we found it */ } else if (action == E_FINDLABEL) { /* map the label to a priority */ - res = e->priority; + int res = e->priority; + ast_unlock_contexts(); - return res; /* the priority we were looking for */ + + /* the priority we were looking for */ + return res; } else { /* spawn */ if (!e->cached_app) e->cached_app = pbx_findapp(e->app); @@ -2892,7 +2894,7 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, } else { if (!q.swo->exec) { ast_log(LOG_WARNING, "No execution engine for switch %s\n", q.swo->name); - res = -1; + return -1; } return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data); } @@ -5256,8 +5258,8 @@ static char *handle_show_hint(struct ast_cli_entry *e, int cmd, struct ast_cli_a ast_cli(a->fd, "%-20.20s: %-20.20s State:%-15.15s Presence:%-15.15s Watchers %2d\n", buf, ast_get_extension_app(hint->exten), - ast_extension_state2str(hint->laststate), - ast_presence_state2str(hint->last_presence_state), + ast_extension_state2str(hint->laststate), + ast_presence_state2str(hint->last_presence_state), watchers); num++; } diff --git a/main/plc.c b/main/plc.c index 4421e7a0c..ade8161ea 100644 --- a/main/plc.c +++ b/main/plc.c @@ -138,7 +138,7 @@ int plc_rx(plc_state_t *s, int16_t amp[], int len) float old_weight; float new_weight; float gain; - + if (s->missing_samples) { /* Although we have a real signal, we need to smooth it to fit well with the synthetic signal we used for the previous block */ diff --git a/main/poll.c b/main/poll.c index e0f695504..166e570b4 100644 --- a/main/poll.c +++ b/main/poll.c @@ -303,5 +303,3 @@ int ast_poll2(struct pollfd *pArray, unsigned long n_fds, struct timeval *tv) return ready_descriptors; #endif } - - diff --git a/main/rtp_engine.c b/main/rtp_engine.c index e7032724b..6bedd1767 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -887,6 +887,25 @@ void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp ast_rwlock_unlock(&codecs->codecs_lock); } +enum ast_media_type ast_rtp_codecs_get_stream_type(struct ast_rtp_codecs *codecs) +{ + enum ast_media_type stream_type = AST_MEDIA_TYPE_UNKNOWN; + int payload; + struct ast_rtp_payload_type *type; + + ast_rwlock_rdlock(&codecs->codecs_lock); + for (payload = 0; payload < AST_VECTOR_SIZE(&codecs->payloads); ++payload) { + type = AST_VECTOR_GET(&codecs->payloads, payload); + if (type && type->asterisk_format) { + stream_type = ast_format_get_type(type->format); + break; + } + } + ast_rwlock_unlock(&codecs->codecs_lock); + + return stream_type; +} + struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload) { struct ast_rtp_payload_type *type = NULL; @@ -2217,7 +2236,7 @@ static void set_next_mime_type(struct ast_format *format, int rtp_code, const ch } /* Make sure any previous value in ast_rtp_mime_types is cleaned up */ - memset(&ast_rtp_mime_types[x], 0, sizeof(struct ast_rtp_mime_type)); + memset(&ast_rtp_mime_types[x], 0, sizeof(struct ast_rtp_mime_type)); if (format) { ast_rtp_mime_types[x].payload_type.asterisk_format = 1; ast_rtp_mime_types[x].payload_type.format = ao2_bump(format); @@ -2482,10 +2501,10 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize) { struct rtcp_message_payload *payload = stasis_message_data(msg); - RAII_VAR(struct ast_json *, json_rtcp_report, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, json_rtcp_report_blocks, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, json_rtcp_sender_info, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, json_channel, NULL, ast_json_unref); + struct ast_json *json_rtcp_report = NULL; + struct ast_json *json_rtcp_report_blocks; + struct ast_json *json_rtcp_sender_info = NULL; + struct ast_json *json_channel = NULL; int i; json_rtcp_report_blocks = ast_json_array_create(); @@ -2496,20 +2515,19 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg, for (i = 0; i < payload->report->reception_report_count && payload->report->report_block[i]; i++) { struct ast_json *json_report_block; char str_lsr[32]; + snprintf(str_lsr, sizeof(str_lsr), "%u", payload->report->report_block[i]->lsr); json_report_block = ast_json_pack("{s: i, s: i, s: i, s: i, s: i, s: s, s: i}", - "source_ssrc", payload->report->report_block[i]->source_ssrc, - "fraction_lost", payload->report->report_block[i]->lost_count.fraction, - "packets_lost", payload->report->report_block[i]->lost_count.packets, - "highest_seq_no", payload->report->report_block[i]->highest_seq_no, - "ia_jitter", payload->report->report_block[i]->ia_jitter, - "lsr", str_lsr, - "dlsr", payload->report->report_block[i]->dlsr); - if (!json_report_block) { - return NULL; - } - - if (ast_json_array_append(json_rtcp_report_blocks, json_report_block)) { + "source_ssrc", payload->report->report_block[i]->source_ssrc, + "fraction_lost", payload->report->report_block[i]->lost_count.fraction, + "packets_lost", payload->report->report_block[i]->lost_count.packets, + "highest_seq_no", payload->report->report_block[i]->highest_seq_no, + "ia_jitter", payload->report->report_block[i]->ia_jitter, + "lsr", str_lsr, + "dlsr", payload->report->report_block[i]->dlsr); + if (!json_report_block + || ast_json_array_append(json_rtcp_report_blocks, json_report_block)) { + ast_json_unref(json_rtcp_report_blocks); return NULL; } } @@ -2517,25 +2535,27 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg, if (payload->report->type == AST_RTP_RTCP_SR) { char sec[32]; char usec[32]; + snprintf(sec, sizeof(sec), "%lu", (unsigned long)payload->report->sender_information.ntp_timestamp.tv_sec); snprintf(usec, sizeof(usec), "%lu", (unsigned long)payload->report->sender_information.ntp_timestamp.tv_usec); json_rtcp_sender_info = ast_json_pack("{s: s, s: s, s: i, s: i, s: i}", - "ntp_timestamp_sec", sec, - "ntp_timestamp_usec", usec, - "rtp_timestamp", payload->report->sender_information.rtp_timestamp, - "packets", payload->report->sender_information.packet_count, - "octets", payload->report->sender_information.octet_count); + "ntp_timestamp_sec", sec, + "ntp_timestamp_usec", usec, + "rtp_timestamp", payload->report->sender_information.rtp_timestamp, + "packets", payload->report->sender_information.packet_count, + "octets", payload->report->sender_information.octet_count); if (!json_rtcp_sender_info) { + ast_json_unref(json_rtcp_report_blocks); return NULL; } } json_rtcp_report = ast_json_pack("{s: i, s: i, s: i, s: o, s: o}", - "ssrc", payload->report->ssrc, - "type", payload->report->type, - "report_count", payload->report->reception_report_count, - "sender_information", json_rtcp_sender_info ? ast_json_ref(json_rtcp_sender_info) : ast_json_ref(ast_json_null()), - "report_blocks", ast_json_ref(json_rtcp_report_blocks)); + "ssrc", payload->report->ssrc, + "type", payload->report->type, + "report_count", payload->report->reception_report_count, + "sender_information", json_rtcp_sender_info ?: ast_json_null(), + "report_blocks", json_rtcp_report_blocks); if (!json_rtcp_report) { return NULL; } @@ -2543,14 +2563,15 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg, if (payload->snapshot) { json_channel = ast_channel_snapshot_to_json(payload->snapshot, sanitize); if (!json_channel) { + ast_json_unref(json_rtcp_report); return NULL; } } return ast_json_pack("{s: o, s: o, s: o}", - "channel", payload->snapshot ? ast_json_ref(json_channel) : ast_json_ref(ast_json_null()), - "rtcp_report", ast_json_ref(json_rtcp_report), - "blob", ast_json_deep_copy(payload->blob)); + "channel", payload->snapshot ? json_channel : ast_json_null(), + "rtcp_report", json_rtcp_report, + "blob", ast_json_deep_copy(payload->blob) ?: ast_json_null()); } static void rtp_rtcp_report_dtor(void *obj) diff --git a/main/sdp_srtp.c b/main/sdp_srtp.c index 3d1d85039..4116f20cc 100644 --- a/main/sdp_srtp.c +++ b/main/sdp_srtp.c @@ -438,4 +438,3 @@ char *ast_sdp_get_rtp_profile(unsigned int sdes_active, struct ast_rtp_instance } } } - diff --git a/main/security_events.c b/main/security_events.c index d549d6201..392b2b459 100644 --- a/main/security_events.c +++ b/main/security_events.c @@ -314,7 +314,7 @@ <parameter name="ReceivedChallenge" required="false"> <para>The challenge that was received.</para> </parameter> - <parameter name="RecievedHash" required="false"> + <parameter name="ReceivedHash" required="false"> <para>The hash that was received.</para> </parameter> </syntax> @@ -1196,5 +1196,3 @@ int ast_security_event_report(const struct ast_security_event_common *sec) return 0; } - - diff --git a/main/smoother.c b/main/smoother.c index 720ad8549..36fa74373 100644 --- a/main/smoother.c +++ b/main/smoother.c @@ -224,4 +224,3 @@ void ast_smoother_free(struct ast_smoother *s) ao2_cleanup(s->format); ast_free(s); } - diff --git a/main/sorcery.c b/main/sorcery.c index cb0aff538..c20854f88 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -336,101 +336,14 @@ static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type } /*! \brief Hashing function for sorcery wizards */ -static int sorcery_wizard_hash(const void *obj, const int flags) -{ - const struct ast_sorcery_internal_wizard *object; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - object = obj; - key = object->callbacks.name; - break; - default: - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} +AO2_STRING_FIELD_HASH_FN(ast_sorcery_internal_wizard, callbacks.name) /*! \brief Comparator function for sorcery wizards */ -static int sorcery_wizard_cmp(void *obj, void *arg, int flags) -{ - const struct ast_sorcery_internal_wizard *object_left = obj; - const struct ast_sorcery_internal_wizard *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->callbacks.name; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->callbacks.name, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(object_left->callbacks.name, right_key, strlen(right_key)); - break; - default: - cmp = 0; - break; - } - if (cmp) { - return 0; - } - return CMP_MATCH; -} +AO2_STRING_FIELD_CMP_FN(ast_sorcery_internal_wizard, callbacks.name) /*! \brief Hashing function for sorcery wizards */ -static int object_type_field_hash(const void *obj, const int flags) -{ - const struct ast_sorcery_object_field *object_field; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - object_field = obj; - key = object_field->name; - break; - default: - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} - -static int object_type_field_cmp(void *obj, void *arg, int flags) -{ - const struct ast_sorcery_object_field *field_left = obj; - const struct ast_sorcery_object_field *field_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = field_right->name; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(field_left->name, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(field_left->name, right_key, strlen(right_key)); - break; - default: - cmp = 0; - break; - } - if (cmp) { - return 0; - } - return CMP_MATCH; -} +AO2_STRING_FIELD_HASH_FN(ast_sorcery_object_field, name) +AO2_STRING_FIELD_CMP_FN(ast_sorcery_object_field, name) /*! \brief Cleanup function for graceful shutdowns */ static void sorcery_cleanup(void) @@ -446,53 +359,10 @@ static void sorcery_cleanup(void) } /*! \brief Compare function for sorcery instances */ -static int sorcery_instance_cmp(void *obj, void *arg, int flags) -{ - const struct ast_sorcery *object_left = obj; - const struct ast_sorcery *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->module_name; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->module_name, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(object_left->module_name, right_key, strlen(right_key)); - break; - default: - cmp = 0; - break; - } - if (cmp) { - return 0; - } - return CMP_MATCH; -} +AO2_STRING_FIELD_CMP_FN(ast_sorcery, module_name) /*! \brief Hashing function for sorcery instances */ -static int sorcery_instance_hash(const void *obj, const int flags) -{ - const struct ast_sorcery *object; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - object = obj; - key = object->module_name; - break; - default: - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} +AO2_STRING_FIELD_HASH_FN(ast_sorcery, module_name) int ast_sorcery_init(void) { @@ -511,7 +381,7 @@ int ast_sorcery_init(void) } wizards = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, WIZARD_BUCKETS, - sorcery_wizard_hash, NULL, sorcery_wizard_cmp); + ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn); if (!wizards) { sorcery_cleanup(); return -1; @@ -524,7 +394,7 @@ int ast_sorcery_init(void) } instances = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0, INSTANCE_BUCKETS, - sorcery_instance_hash, NULL, sorcery_instance_cmp); + ast_sorcery_hash_fn, NULL, ast_sorcery_cmp_fn); if (!instances) { sorcery_cleanup(); return -1; @@ -724,53 +594,10 @@ static void sorcery_destructor(void *obj) } /*! \brief Hashing function for sorcery types */ -static int sorcery_type_hash(const void *obj, const int flags) -{ - const struct ast_sorcery_object_type *object; - const char *key; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_KEY: - key = obj; - break; - case OBJ_SEARCH_OBJECT: - object = obj; - key = object->name; - break; - default: - ast_assert(0); - return 0; - } - return ast_str_hash(key); -} +AO2_STRING_FIELD_HASH_FN(ast_sorcery_object_type, name) /*! \brief Comparator function for sorcery types */ -static int sorcery_type_cmp(void *obj, void *arg, int flags) -{ - const struct ast_sorcery_object_type *object_left = obj; - const struct ast_sorcery_object_type *object_right = arg; - const char *right_key = arg; - int cmp; - - switch (flags & OBJ_SEARCH_MASK) { - case OBJ_SEARCH_OBJECT: - right_key = object_right->name; - /* Fall through */ - case OBJ_SEARCH_KEY: - cmp = strcmp(object_left->name, right_key); - break; - case OBJ_SEARCH_PARTIAL_KEY: - cmp = strncmp(object_left->name, right_key, strlen(right_key)); - break; - default: - cmp = 0; - break; - } - if (cmp) { - return 0; - } - return CMP_MATCH; -} +AO2_STRING_FIELD_CMP_FN(ast_sorcery_object_type, name) struct ast_sorcery *__ast_sorcery_open(const char *module_name) { @@ -787,7 +614,9 @@ struct ast_sorcery *__ast_sorcery_open(const char *module_name) goto done; } - if (!(sorcery->types = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, TYPE_BUCKETS, sorcery_type_hash, sorcery_type_cmp))) { + sorcery->types = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, TYPE_BUCKETS, + ast_sorcery_object_type_hash_fn, ast_sorcery_object_type_cmp_fn); + if (!sorcery->types) { ao2_ref(sorcery, -1); sorcery = NULL; goto done; @@ -863,7 +692,7 @@ static struct ast_sorcery_object_type *sorcery_object_type_alloc(const char *typ } object_type->fields = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, - OBJECT_FIELD_BUCKETS, object_type_field_hash, NULL, object_type_field_cmp); + OBJECT_FIELD_BUCKETS, ast_sorcery_object_field_hash_fn, NULL, ast_sorcery_object_field_cmp_fn); if (!object_type->fields) { ao2_ref(object_type, -1); return NULL; diff --git a/main/stasis.c b/main/stasis.c index 63d17dfaf..5f080d1a3 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -1436,8 +1436,8 @@ static struct aco_type threadpool_option = { .type = ACO_GLOBAL, .name = "threadpool", .item_offset = offsetof(struct stasis_config, threadpool_options), - .category = "^threadpool$", - .category_match = ACO_WHITELIST, + .category = "threadpool", + .category_match = ACO_WHITELIST_EXACT, }; static struct aco_type *threadpool_options[] = ACO_TYPES(&threadpool_option); @@ -1447,8 +1447,8 @@ static struct aco_type declined_option = { .type = ACO_GLOBAL, .name = "declined_message_types", .item_offset = offsetof(struct stasis_config, declined_message_types), - .category_match = ACO_WHITELIST, - .category = "^declined_message_types$", + .category_match = ACO_WHITELIST_EXACT, + .category = "declined_message_types", }; struct aco_type *declined_options[] = ACO_TYPES(&declined_option); @@ -1651,4 +1651,3 @@ int stasis_init(void) return 0; } - diff --git a/main/stasis_cache.c b/main/stasis_cache.c index b0973b984..f5037a42e 100644 --- a/main/stasis_cache.c +++ b/main/stasis_cache.c @@ -930,4 +930,3 @@ int stasis_cache_init(void) return 0; } - diff --git a/main/stasis_cache_pattern.c b/main/stasis_cache_pattern.c index 7ccf1c181..3106cb33e 100644 --- a/main/stasis_cache_pattern.c +++ b/main/stasis_cache_pattern.c @@ -212,4 +212,3 @@ struct stasis_topic *stasis_cp_single_topic_cached( } return stasis_caching_get_topic(one->topic_cached); } - diff --git a/main/stasis_channels.c b/main/stasis_channels.c index 0479bd9e9..ed460cca4 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -174,9 +174,21 @@ static const char *channel_snapshot_get_name(struct stasis_message *message) */ static int channel_snapshot_hash_cb(const void *obj, const int flags) { - const struct ast_channel_snapshot *snapshot = obj; - const char *name = (flags & OBJ_KEY) ? obj : snapshot->name; - return ast_str_case_hash(name); + const struct ast_channel_snapshot *object = obj; + const char *key; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: + key = obj; + break; + case OBJ_SEARCH_OBJECT: + key = object->name; + break; + default: + ast_assert(0); + return 0; + } + return ast_str_case_hash(key); } /*! @@ -185,10 +197,28 @@ static int channel_snapshot_hash_cb(const void *obj, const int flags) */ static int channel_snapshot_cmp_cb(void *obj, void *arg, int flags) { - struct ast_channel_snapshot *left = obj; - struct ast_channel_snapshot *right = arg; - const char *match = (flags & OBJ_KEY) ? arg : right->name; - return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP); + const struct ast_channel_snapshot *object_left = obj; + const struct ast_channel_snapshot *object_right = arg; + const char *right_key = arg; + int cmp; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: + right_key = object_right->name; + case OBJ_SEARCH_KEY: + cmp = strcasecmp(object_left->name, right_key); + break; + case OBJ_SEARCH_PARTIAL_KEY: + cmp = strncasecmp(object_left->name, right_key, strlen(right_key)); + break; + default: + cmp = 0; + break; + } + if (cmp) { + return 0; + } + return CMP_MATCH; } static void channel_snapshot_dtor(void *obj) @@ -237,22 +267,24 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "")); ast_string_field_set(snapshot, caller_number, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "")); - ast_string_field_set(snapshot, caller_dnid, S_OR(ast_channel_dialed(chan)->number.str, "")); ast_string_field_set(snapshot, caller_subaddr, S_COR(ast_channel_caller(chan)->id.subaddress.valid, ast_channel_caller(chan)->id.subaddress.str, "")); - ast_string_field_set(snapshot, dialed_subaddr, - S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, "")); ast_string_field_set(snapshot, caller_ani, S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, "")); + ast_string_field_set(snapshot, caller_rdnis, S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, "")); + ast_string_field_set(snapshot, caller_dnid, S_OR(ast_channel_dialed(chan)->number.str, "")); + ast_string_field_set(snapshot, dialed_subaddr, + S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, "")); ast_string_field_set(snapshot, connected_name, S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, "")); ast_string_field_set(snapshot, connected_number, S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, "")); + ast_string_field_set(snapshot, language, ast_channel_language(chan)); if ((bridge = ast_channel_get_bridge(chan))) { @@ -295,31 +327,33 @@ static void ast_channel_publish_dial_internal(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward) { - RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup); - RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); - RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); - RAII_VAR(struct ast_channel_snapshot *, caller_snapshot, NULL, ao2_cleanup); - RAII_VAR(struct ast_channel_snapshot *, peer_snapshot, NULL, ao2_cleanup); - RAII_VAR(struct ast_channel_snapshot *, forwarded_snapshot, NULL, ao2_cleanup); + struct ast_multi_channel_blob *payload; + struct stasis_message *msg; + struct ast_json *blob; + struct ast_channel_snapshot *peer_snapshot; if (!ast_channel_dial_type()) { return; } ast_assert(peer != NULL); + blob = ast_json_pack("{s: s, s: s, s: s}", - "dialstatus", S_OR(dialstatus, ""), - "forward", S_OR(forward, ""), - "dialstring", S_OR(dialstring, "")); + "dialstatus", S_OR(dialstatus, ""), + "forward", S_OR(forward, ""), + "dialstring", S_OR(dialstring, "")); if (!blob) { return; } payload = ast_multi_channel_blob_create(blob); + ast_json_unref(blob); if (!payload) { return; } if (caller) { + struct ast_channel_snapshot *caller_snapshot; + ast_channel_lock(caller); if (ast_strlen_zero(dialstatus)) { caller_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(caller)); @@ -328,9 +362,11 @@ static void ast_channel_publish_dial_internal(struct ast_channel *caller, } ast_channel_unlock(caller); if (!caller_snapshot) { + ao2_ref(payload, -1); return; } ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot); + ao2_ref(caller_snapshot, -1); } ast_channel_lock(peer); @@ -341,26 +377,32 @@ static void ast_channel_publish_dial_internal(struct ast_channel *caller, } ast_channel_unlock(peer); if (!peer_snapshot) { + ao2_ref(payload, -1); return; } ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot); + ao2_ref(peer_snapshot, -1); if (forwarded) { + struct ast_channel_snapshot *forwarded_snapshot; + ast_channel_lock(forwarded); forwarded_snapshot = ast_channel_snapshot_create(forwarded); ast_channel_unlock(forwarded); if (!forwarded_snapshot) { + ao2_ref(payload, -1); return; } ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot); + ao2_ref(forwarded_snapshot, -1); } msg = stasis_message_create(ast_channel_dial_type(), payload); - if (!msg) { - return; + ao2_ref(payload, -1); + if (msg) { + publish_message_for_channel_topics(msg, caller); + ao2_ref(msg, -1); } - - publish_message_for_channel_topics(msg, caller); } static void remove_dial_masquerade(struct ast_channel *peer); @@ -454,33 +496,33 @@ struct stasis_message *ast_channel_blob_create_from_cache(const char *channel_id struct stasis_message_type *type, struct ast_json *blob) { - RAII_VAR(struct ast_channel_snapshot *, snapshot, - NULL, - ao2_cleanup); + struct ast_channel_snapshot *snapshot; + struct stasis_message *msg; if (!type) { return NULL; } snapshot = ast_channel_snapshot_get_latest(channel_id); - - return create_channel_blob_message(snapshot, type, blob); + msg = create_channel_blob_message(snapshot, type, blob); + ao2_cleanup(snapshot); + return msg; } struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob) { - RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); + struct ast_channel_snapshot *snapshot; + struct stasis_message *msg; if (!type) { return NULL; } - if (chan) { - snapshot = ast_channel_snapshot_create(chan); - } - - return create_channel_blob_message(snapshot, type, blob); + snapshot = chan ? ast_channel_snapshot_create(chan) : NULL; + msg = create_channel_blob_message(snapshot, type, blob); + ao2_cleanup(snapshot); + return msg; } /*! \brief A channel snapshot wrapper object used in \ref ast_multi_channel_blob objects */ @@ -492,31 +534,37 @@ struct channel_role_snapshot { /*! \brief A multi channel blob data structure for multi_channel_blob stasis messages */ struct ast_multi_channel_blob { struct ao2_container *channel_snapshots; /*!< A container holding the snapshots */ - struct ast_json *blob; /*< A blob of JSON data */ + struct ast_json *blob; /*!< A blob of JSON data */ }; /*! * \internal - * \brief Standard comparison function for \ref channel_role_snapshot objects + * \brief Comparison function for \ref channel_role_snapshot objects */ -static int channel_role_single_cmp_cb(void *obj, void *arg, int flags) -{ - struct channel_role_snapshot *left = obj; - struct channel_role_snapshot *right = arg; - const char *match = (flags & OBJ_KEY) ? arg : right->role; - return strcasecmp(left->role, match) ? 0 : (CMP_MATCH | CMP_STOP); -} - -/*! - * \internal - * \brief Multi comparison function for \ref channel_role_snapshot objects - */ -static int channel_role_multi_cmp_cb(void *obj, void *arg, int flags) -{ - struct channel_role_snapshot *left = obj; - struct channel_role_snapshot *right = arg; - const char *match = (flags & OBJ_KEY) ? arg : right->role; - return strcasecmp(left->role, match) ? 0 : (CMP_MATCH); +static int channel_role_cmp_cb(void *obj, void *arg, int flags) +{ + const struct channel_role_snapshot *object_left = obj; + const struct channel_role_snapshot *object_right = arg; + const char *right_key = arg; + int cmp; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: + right_key = object_right->role; + case OBJ_SEARCH_KEY: + cmp = strcasecmp(object_left->role, right_key); + break; + case OBJ_SEARCH_PARTIAL_KEY: + cmp = strncasecmp(object_left->role, right_key, strlen(right_key)); + break; + default: + cmp = 0; + break; + } + if (cmp) { + return 0; + } + return CMP_MATCH; } /*! @@ -525,9 +573,21 @@ static int channel_role_multi_cmp_cb(void *obj, void *arg, int flags) */ static int channel_role_hash_cb(const void *obj, const int flags) { - const struct channel_role_snapshot *snapshot = obj; - const char *name = (flags & OBJ_KEY) ? obj : snapshot->role; - return ast_str_case_hash(name); + const struct channel_role_snapshot *object = obj; + const char *key; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: + key = obj; + break; + case OBJ_SEARCH_OBJECT: + key = object->role; + break; + default: + ast_assert(0); + return 0; + } + return ast_str_case_hash(key); } /*! @@ -544,89 +604,80 @@ static void multi_channel_blob_dtor(void *obj) struct ast_multi_channel_blob *ast_multi_channel_blob_create(struct ast_json *blob) { - RAII_VAR(struct ast_multi_channel_blob *, obj, - ao2_alloc(sizeof(*obj), multi_channel_blob_dtor), - ao2_cleanup); + struct ast_multi_channel_blob *obj; ast_assert(blob != NULL); + obj = ao2_alloc(sizeof(*obj), multi_channel_blob_dtor); if (!obj) { return NULL; } obj->channel_snapshots = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, - channel_role_hash_cb, channel_role_single_cmp_cb); + channel_role_hash_cb, channel_role_cmp_cb); if (!obj->channel_snapshots) { + ao2_ref(obj, -1); return NULL; } obj->blob = ast_json_ref(blob); - - ao2_ref(obj, +1); return obj; } struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid) { - RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct stasis_message *message; struct ast_channel_snapshot *snapshot; ast_assert(!ast_strlen_zero(uniqueid)); - message = stasis_cache_get(ast_channel_cache(), - ast_channel_snapshot_type(), - uniqueid); + message = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(), + uniqueid); if (!message) { return NULL; } - snapshot = stasis_message_data(message); - if (!snapshot) { - return NULL; - } - ao2_ref(snapshot, +1); + snapshot = ao2_bump(stasis_message_data(message)); + ao2_ref(message, -1); return snapshot; } struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name) { - RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct stasis_message *message; struct ast_channel_snapshot *snapshot; ast_assert(!ast_strlen_zero(name)); - message = stasis_cache_get(ast_channel_cache_by_name(), - ast_channel_snapshot_type(), - name); + message = stasis_cache_get(ast_channel_cache_by_name(), ast_channel_snapshot_type(), + name); if (!message) { return NULL; } - snapshot = stasis_message_data(message); - if (!snapshot) { - return NULL; - } - ao2_ref(snapshot, +1); + snapshot = ao2_bump(stasis_message_data(message)); + ao2_ref(message, -1); return snapshot; } static void channel_role_snapshot_dtor(void *obj) { struct channel_role_snapshot *role_snapshot = obj; + ao2_cleanup(role_snapshot->snapshot); } void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot) { - RAII_VAR(struct channel_role_snapshot *, role_snapshot, NULL, ao2_cleanup); + struct channel_role_snapshot *role_snapshot; int role_len = strlen(role) + 1; if (!obj || ast_strlen_zero(role) || !snapshot) { return; } - role_snapshot = ao2_alloc_options(sizeof(*role_snapshot) + role_len, channel_role_snapshot_dtor, - AO2_ALLOC_OPT_LOCK_NOLOCK); + role_snapshot = ao2_alloc_options(sizeof(*role_snapshot) + role_len, + channel_role_snapshot_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!role_snapshot) { return; } @@ -634,40 +685,49 @@ void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, cons role_snapshot->snapshot = snapshot; ao2_ref(role_snapshot->snapshot, +1); ao2_link(obj->channel_snapshots, role_snapshot); + ao2_ref(role_snapshot, -1); } struct ast_channel_snapshot *ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role) { struct channel_role_snapshot *role_snapshot; + struct ast_channel_snapshot *snapshot; if (!obj || ast_strlen_zero(role)) { return NULL; } - role_snapshot = ao2_find(obj->channel_snapshots, role, OBJ_KEY); + role_snapshot = ao2_find(obj->channel_snapshots, role, OBJ_SEARCH_KEY); /* Note that this function does not increase the ref count on snapshot */ if (!role_snapshot) { return NULL; } + snapshot = role_snapshot->snapshot; ao2_ref(role_snapshot, -1); - return role_snapshot->snapshot; + return snapshot; } struct ao2_container *ast_multi_channel_blob_get_channels(struct ast_multi_channel_blob *obj, const char *role) { - RAII_VAR(struct ao2_container *, ret_container, - ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_snapshot_hash_cb, channel_snapshot_cmp_cb), - ao2_cleanup); + struct ao2_container *ret_container; struct ao2_iterator *it_role_snapshots; struct channel_role_snapshot *role_snapshot; char *arg; - if (!obj || ast_strlen_zero(role) || !ret_container) { + if (!obj || ast_strlen_zero(role)) { return NULL; } - arg = ast_strdupa(role); - it_role_snapshots = ao2_callback(obj->channel_snapshots, OBJ_MULTIPLE | OBJ_KEY, channel_role_multi_cmp_cb, arg); + ret_container = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, + channel_snapshot_hash_cb, channel_snapshot_cmp_cb); + if (!ret_container) { + return NULL; + } + + arg = ast_strdupa(role); + it_role_snapshots = ao2_callback(obj->channel_snapshots, + OBJ_MULTIPLE | OBJ_SEARCH_KEY, channel_role_cmp_cb, arg); if (!it_role_snapshots) { + ao2_ref(ret_container, -1); return NULL; } @@ -677,7 +737,6 @@ struct ao2_container *ast_multi_channel_blob_get_channels(struct ast_multi_chann } ao2_iterator_destroy(it_role_snapshots); - ao2_ref(ret_container, +1); return ret_container; } @@ -702,8 +761,8 @@ void ast_channel_stage_snapshot_done(struct ast_channel *chan) void ast_channel_publish_snapshot(struct ast_channel *chan) { - RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); - RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct ast_channel_snapshot *snapshot; + struct stasis_message *message; if (!ast_channel_snapshot_type()) { return; @@ -719,12 +778,14 @@ void ast_channel_publish_snapshot(struct ast_channel *chan) } message = stasis_message_create(ast_channel_snapshot_type(), snapshot); + ao2_ref(snapshot, -1); if (!message) { return; } ast_assert(ast_channel_topic(chan) != NULL); stasis_publish(ast_channel_topic(chan), message); + ao2_ref(message, -1); } void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob) @@ -738,8 +799,8 @@ void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_mes message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), type, blob); if (message) { stasis_publish(ast_channel_topic(chan), message); + ao2_ref(message, -1); } - ao2_cleanup(message); } void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob) @@ -753,8 +814,8 @@ void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_ty message = ast_channel_blob_create(chan, type, blob); if (message) { stasis_publish(ast_channel_topic(chan), message); + ao2_ref(message, -1); } - ao2_cleanup(message); } void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value) @@ -789,78 +850,88 @@ void ast_channel_publish_varset(struct ast_channel *chan, const char *name, cons static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg) { - RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); + struct ast_str *channel_event_string; struct ast_channel_blob *obj = stasis_message_data(msg); const char *variable = ast_json_string_get(ast_json_object_get(obj->blob, "variable")); - RAII_VAR(char *, value, ast_escape_c_alloc( - ast_json_string_get(ast_json_object_get(obj->blob, "value"))), ast_free); + char *value; + struct ast_manager_event_blob *ev; + value = ast_escape_c_alloc(ast_json_string_get(ast_json_object_get(obj->blob, + "value"))); if (!value) { return NULL; } if (obj->snapshot) { - channel_event_string = - ast_manager_build_channel_state_string(obj->snapshot); + channel_event_string = ast_manager_build_channel_state_string(obj->snapshot); } else { channel_event_string = ast_str_create(35); ast_str_set(&channel_event_string, 0, - "Channel: none\r\n" - "Uniqueid: none\r\n"); + "Channel: none\r\n" + "Uniqueid: none\r\n"); } - if (!channel_event_string) { + ast_free(value); return NULL; } - return ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet", + ev = ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet", "%s" "Variable: %s\r\n" "Value: %s\r\n", ast_str_buffer(channel_event_string), variable, value); + ast_free(channel_event_string); + ast_free(value); + return ev; } static struct ast_manager_event_blob *agent_login_to_ami(struct stasis_message *msg) { - RAII_VAR(struct ast_str *, channel_string, NULL, ast_free); + struct ast_str *channel_string; struct ast_channel_blob *obj = stasis_message_data(msg); const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent")); + struct ast_manager_event_blob *ev; channel_string = ast_manager_build_channel_state_string(obj->snapshot); if (!channel_string) { return NULL; } - return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin", + ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin", "%s" "Agent: %s\r\n", ast_str_buffer(channel_string), agent); + ast_free(channel_string); + return ev; } static struct ast_manager_event_blob *agent_logoff_to_ami(struct stasis_message *msg) { - RAII_VAR(struct ast_str *, channel_string, NULL, ast_free); + struct ast_str *channel_string; struct ast_channel_blob *obj = stasis_message_data(msg); const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent")); long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime")); + struct ast_manager_event_blob *ev; channel_string = ast_manager_build_channel_state_string(obj->snapshot); if (!channel_string) { return NULL; } - return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff", + ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff", "%s" "Agent: %s\r\n" "Logintime: %ld\r\n", ast_str_buffer(channel_string), agent, logintime); + ast_free(channel_string); + return ev; } void ast_publish_channel_state(struct ast_channel *chan) { - RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); - RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct ast_channel_snapshot *snapshot; + struct stasis_message *message; if (!ast_channel_snapshot_type()) { return; @@ -877,12 +948,14 @@ void ast_publish_channel_state(struct ast_channel *chan) } message = stasis_message_create(ast_channel_snapshot_type(), snapshot); + ao2_ref(snapshot, -1); if (!message) { return; } ast_assert(ast_channel_topic(chan) != NULL); stasis_publish(ast_channel_topic(chan), message); + ao2_ref(message, -1); } struct ast_json *ast_channel_snapshot_to_json( @@ -892,8 +965,9 @@ struct ast_json *ast_channel_snapshot_to_json( struct ast_json *json_chan; if (snapshot == NULL - || (sanitize && sanitize->channel_snapshot - && sanitize->channel_snapshot(snapshot))) { + || (sanitize + && sanitize->channel_snapshot + && sanitize->channel_snapshot(snapshot))) { return NULL; } @@ -967,7 +1041,7 @@ static struct ast_json *channel_blob_to_json( const char *type, const struct stasis_message_sanitizer *sanitize) { - RAII_VAR(struct ast_json *, out, NULL, ast_json_unref); + struct ast_json *to_json; struct ast_channel_blob *channel_blob = stasis_message_data(message); struct ast_json *blob = channel_blob->blob; struct ast_channel_snapshot *snapshot = channel_blob->snapshot; @@ -975,36 +1049,38 @@ static struct ast_json *channel_blob_to_json( int res = 0; if (blob == NULL || ast_json_is_null(blob)) { - out = ast_json_object_create(); + to_json = ast_json_object_create(); } else { /* blobs are immutable, so shallow copies are fine */ - out = ast_json_copy(blob); + to_json = ast_json_copy(blob); } - - if (!out) { + if (!to_json) { return NULL; } - res |= ast_json_object_set(out, "type", ast_json_string_create(type)); - res |= ast_json_object_set(out, "timestamp", + res |= ast_json_object_set(to_json, "type", ast_json_string_create(type)); + res |= ast_json_object_set(to_json, "timestamp", ast_json_timeval(*tv, NULL)); /* For global channel messages, the snapshot is optional */ if (snapshot) { - struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize); + struct ast_json *json_channel; + json_channel = ast_channel_snapshot_to_json(snapshot, sanitize); if (!json_channel) { + ast_json_unref(to_json); return NULL; } - res |= ast_json_object_set(out, "channel", json_channel); + res |= ast_json_object_set(to_json, "channel", json_channel); } if (res != 0) { + ast_json_unref(to_json); return NULL; } - return ast_json_ref(out); + return to_json; } static struct ast_json *dtmf_end_to_json( diff --git a/main/stdtime/localtime.c b/main/stdtime/localtime.c index 5b5526e6f..f8050c95c 100644 --- a/main/stdtime/localtime.c +++ b/main/stdtime/localtime.c @@ -1057,7 +1057,7 @@ static int tzload(const char *name, struct state * const sp, const int doextend) int result; /* for temporary struct state -- - * macro flags the the struct as a stack temp. + * macro flags the struct as a stack temp. * to prevent use within add_notify() */ SP_STACK_INIT(ts); @@ -1508,16 +1508,14 @@ static int tzparse(const char *name, struct state *sp, const int lastditch) } } else { long theirstdoffset; - long theirdstoffset; long theiroffset; - int isdst; int i; int j; if (*name != '\0') return -1; /* - ** Initial values of theirstdoffset and theirdstoffset. + ** Initial values of theirstdoffset. */ theirstdoffset = 0; for (i = 0; i < sp->timecnt; ++i) { @@ -1528,19 +1526,6 @@ static int tzparse(const char *name, struct state *sp, const int lastditch) break; } } - theirdstoffset = 0; - for (i = 0; i < sp->timecnt; ++i) { - j = sp->types[i]; - if (sp->ttis[j].tt_isdst) { - theirdstoffset = - -sp->ttis[j].tt_gmtoff; - break; - } - } - /* - ** Initially we're assumed to be in standard time. - */ - isdst = FALSE; theiroffset = theirstdoffset; /* ** Now juggle transition times and types @@ -1552,32 +1537,13 @@ static int tzparse(const char *name, struct state *sp, const int lastditch) if (sp->ttis[j].tt_ttisgmt) { /* No adjustment to transition time */ } else { - /* - ** If summer time is in effect, and the - ** transition time was not specified as - ** standard time, add the summer time - ** offset to the transition time; - ** otherwise, add the standard time - ** offset to the transition time. - */ - /* - ** Transitions from DST to DDST - ** will effectively disappear since - ** POSIX provides for only one DST - ** offset. - */ - if (isdst && !sp->ttis[j].tt_ttisstd) { - sp->ats[i] += dstoffset - - theirdstoffset; - } else { - sp->ats[i] += stdoffset - - theirstdoffset; - } + /* Add the standard time offset to the transition time. */ + sp->ats[i] += stdoffset - theirstdoffset; } theiroffset = -sp->ttis[j].tt_gmtoff; - if (sp->ttis[j].tt_isdst) - theirdstoffset = theiroffset; - else theirstdoffset = theiroffset; + if (!sp->ttis[j].tt_isdst) { + theirstdoffset = theiroffset; + } } /* ** Finally, fill in ttis. @@ -1811,7 +1777,7 @@ void ast_get_dst_info(const time_t * const timep, int *dst_enabled, time_t *dst_ return; /* If the desired time exceeds the bounds of the defined time transitions - * then give give up on determining DST info and simply look for gmt offset + * then give up on determining DST info and simply look for gmt offset * This requires that I adjust the given time using increments of Gregorian * repeats to place the time within the defined time transitions in the * timezone structure. @@ -2587,4 +2553,3 @@ char *ast_strptime(const char *s, const char *format, struct ast_tm *tm) { return ast_strptime_locale(s, format, tm, NULL); } - diff --git a/main/tcptls.c b/main/tcptls.c index ef22094bf..3c2d6788f 100644 --- a/main/tcptls.c +++ b/main/tcptls.c @@ -805,7 +805,7 @@ void *ast_tcptls_server_root(void *data) pthread_t launched; for (;;) { - int i, flags; + int i; if (desc->periodic_fn) { desc->periodic_fn(desc); @@ -843,8 +843,7 @@ void *ast_tcptls_server_root(void *data) close(fd); continue; } - flags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + ast_fd_clear_flags(fd, O_NONBLOCK); tcptls_session->fd = fd; tcptls_session->parent = desc; ast_sockaddr_copy(&tcptls_session->remote_address, &addr); @@ -1061,7 +1060,6 @@ void ast_ssl_teardown(struct ast_tls_config *cfg) struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session) { struct ast_tcptls_session_args *desc; - int flags; if (!(desc = tcptls_session->parent)) { goto client_start_error; @@ -1075,8 +1073,7 @@ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_se goto client_start_error; } - flags = fcntl(desc->accept_fd, F_GETFL); - fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK); + ast_fd_clear_flags(desc->accept_fd, O_NONBLOCK); if (desc->tls_cfg) { desc->tls_cfg->enabled = 1; @@ -1164,7 +1161,6 @@ error: void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) { - int flags; int x = 1; int tls_changed = 0; @@ -1267,8 +1263,7 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name); goto error; } - flags = fcntl(desc->accept_fd, F_GETFL); - fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); + ast_fd_set_flags(desc->accept_fd, O_NONBLOCK); if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) { ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n", desc->name, diff --git a/main/tdd.c b/main/tdd.c index a590e3b2f..4f4d75061 100644 --- a/main/tdd.c +++ b/main/tdd.c @@ -362,4 +362,3 @@ int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *str) } return bytes; } - diff --git a/main/threadpool.c b/main/threadpool.c index 6240b7329..e3d0e40fd 100644 --- a/main/threadpool.c +++ b/main/threadpool.c @@ -702,7 +702,7 @@ static int kill_threads(void *obj, void *arg, int flags) /*! * \brief ao2 callback to zombify a set number of threads. * - * Threads will be zombified as long as as the counter has not reached + * Threads will be zombified as long as the counter has not reached * zero. The counter is decremented with each thread that is zombified. * * Zombifying a thread involves removing it from its current container, @@ -1093,7 +1093,7 @@ static void worker_active(struct worker_thread *worker) { int alive; - /* The following is equivalent to + /* The following is equivalent to * * while (threadpool_execute(worker->pool)); * diff --git a/main/threadstorage.c b/main/threadstorage.c index 4c46a0f58..c97dca921 100644 --- a/main/threadstorage.c +++ b/main/threadstorage.c @@ -167,7 +167,7 @@ static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e, pthread_mutex_unlock(&threadstoragelock); ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : ""); - + return CLI_SUCCESS; } @@ -226,7 +226,7 @@ static char *handle_cli_threadstorage_show_summary(struct ast_cli_entry *e, int } pthread_mutex_unlock(&threadstoragelock); - + AST_LIST_TRAVERSE(&file_summary, file, entry) { len += file->len; count += file->count; @@ -262,4 +262,3 @@ void threadstorage_init(void) } #endif /* !defined(DEBUG_THREADLOCALS) */ - diff --git a/main/translate.c b/main/translate.c index 4ffe27c33..240e4956a 100644 --- a/main/translate.c +++ b/main/translate.c @@ -34,7 +34,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include <sys/time.h> #include <sys/resource.h> #include <math.h> -#include <stdlib.h> #include "asterisk/lock.h" #include "asterisk/channel.h" @@ -499,6 +498,7 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a ast_log(LOG_WARNING, "No translator path from %s to %s\n", ast_format_get_name(src), ast_format_get_name(dst)); AST_RWLIST_UNLOCK(&translators); + ast_translator_free_path(head); return NULL; } if ((t->dst_codec.sample_rate == ast_format_get_sample_rate(dst)) && (t->dst_codec.type == ast_format_get_type(dst))) { @@ -507,9 +507,7 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a if (!(cur = newpvt(t, explicit_dst))) { ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n", ast_format_get_name(src), ast_format_get_name(dst)); - if (head) { - ast_translator_free_path(head); - } + ast_translator_free_path(head); AST_RWLIST_UNLOCK(&translators); return NULL; } @@ -1323,6 +1321,13 @@ void ast_translator_deactivate(struct ast_translator *t) AST_RWLIST_UNLOCK(&translators); } +/*! Calculate the absolute difference between sample rate of two formats. */ +#define format_sample_rate_absdiff(fmt1, fmt2) ({ \ + unsigned int rate1 = ast_format_get_sample_rate(fmt1); \ + unsigned int rate2 = ast_format_get_sample_rate(fmt2); \ + (rate1 > rate2 ? rate1 - rate2 : rate2 - rate1); \ +}) + /*! \brief Calculate our best translator source format, given costs, and a desired destination */ int ast_translator_best_choice(struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, @@ -1407,10 +1412,8 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap, beststeps = matrix_get(x, y)->multistep; } else if (matrix_get(x, y)->table_cost == besttablecost && matrix_get(x, y)->multistep == beststeps) { - int gap_selected = abs(ast_format_get_sample_rate(best) - - ast_format_get_sample_rate(bestdst)); - int gap_current = abs(ast_format_get_sample_rate(src) - - ast_format_get_sample_rate(dst)); + unsigned int gap_selected = format_sample_rate_absdiff(best, bestdst); + unsigned int gap_current = format_sample_rate_absdiff(src, dst); if (gap_current < gap_selected) { /* better than what we have so far */ diff --git a/main/udptl.c b/main/udptl.c index a568cd1ec..83989f738 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -239,9 +239,9 @@ static int udptl_pre_apply_config(void); static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "global", - .category_match = ACO_WHITELIST, + .category_match = ACO_WHITELIST_EXACT, .item_offset = offsetof(struct udptl_config, general), - .category = "^general$", + .category = "general", }; static struct aco_type *general_options[] = ACO_TYPES(&general_option); @@ -1014,7 +1014,6 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s int x; int startplace; int i; - long int flags; RAII_VAR(struct udptl_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); if (!cfg || !cfg->general) { @@ -1045,8 +1044,7 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno)); return NULL; } - flags = fcntl(udptl->fd, F_GETFL); - fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK); + ast_fd_set_flags(udptl->fd, O_NONBLOCK); #ifdef SO_NO_CHECK if (cfg->general->nochecksums) diff --git a/main/ulaw.c b/main/ulaw.c index 76e4b0419..a067845cc 100644 --- a/main/ulaw.c +++ b/main/ulaw.c @@ -248,4 +248,3 @@ void ast_ulaw_init(void) ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n"); #endif /* TEST_TANDEM_TRANSCODING */ } - diff --git a/main/utils.c b/main/utils.c index 034203046..b4ecffd7e 100644 --- a/main/utils.c +++ b/main/utils.c @@ -2664,7 +2664,7 @@ void ast_set_default_eid(struct ast_eid *eid) unsigned char full_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; s = socket(AF_INET, SOCK_STREAM, 0); - if (s <= 0) { + if (s < 0) { ast_log(LOG_WARNING, "Unable to open socket for seeding global EID. " "You will have to set it manually.\n"); return; @@ -2798,3 +2798,37 @@ int ast_compare_versions(const char *version1, const char *version2) } return extra[0] - extra[1]; } + +int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op, + const char *file, int lineno, const char *function) +{ + int f; + + f = fcntl(fd, F_GETFL); + if (f == -1) { + ast_log(__LOG_ERROR, file, lineno, function, + "Failed to get fcntl() flags for file descriptor: %s\n", strerror(errno)); + return -1; + } + + switch (op) { + case AST_FD_FLAG_SET: + f |= flags; + break; + case AST_FD_FLAG_CLEAR: + f &= ~flags; + break; + default: + ast_assert(0); + break; + } + + f = fcntl(fd, F_SETFL, f); + if (f == -1) { + ast_log(__LOG_ERROR, file, lineno, function, + "Failed to set fcntl() flags for file descriptor: %s\n", strerror(errno)); + return -1; + } + + return 0; +} diff --git a/main/xml.c b/main/xml.c index bd82b5cbf..46fe198e4 100644 --- a/main/xml.c +++ b/main/xml.c @@ -386,4 +386,3 @@ struct ast_xml_xpath_results *ast_xml_query(struct ast_xml_doc *doc, const char } #endif /* defined(HAVE_LIBXML2) */ - diff --git a/main/xmldoc.c b/main/xmldoc.c index da753cd15..86ccec020 100644 --- a/main/xmldoc.c +++ b/main/xmldoc.c @@ -1413,7 +1413,7 @@ static int xmldoc_parse_example(struct ast_xml_node *fixnode, struct ast_str **b static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *tabs, const char *posttabs, struct ast_str **buffer) { struct ast_xml_node *node = fixnode; - int ret = 0, i, count = 0; + int ret = 0, i; if (!node || !ast_xml_node_get_children(node)) { return ret; @@ -1440,8 +1440,8 @@ static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *ta /* parse <para> elements inside special tags. */ for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) { /* first <para> just print it without tabs at the begining. */ - if ((xmldoc_parse_para(node, (!count ? "" : tabs), posttabs, buffer) == 2) - || (xmldoc_parse_info(node, (!count ? "": tabs), posttabs, buffer) == 2)) { + if ((xmldoc_parse_para(node, "", posttabs, buffer) == 2) + || (xmldoc_parse_info(node, "", posttabs, buffer) == 2)) { ret = 2; } } @@ -2950,5 +2950,3 @@ int ast_xmldoc_load_documentation(void) } #endif /* AST_XML_DOCS */ - - |