From: Jeff Peeler Date: Thu, 12 Jun 2008 15:46:08 +0000 (+0000) Subject: (closes issue #12193) X-Git-Tag: 1.4.22-rc1~218 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0c0a5cdc73b022e9904d9ed15258b5b25f9edad3;p=thirdparty%2Fasterisk.git (closes issue #12193) Reported by: davidw Patch by: Corydon76, modified by me to work properly with ParkAndAnnounce app git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@122208 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c index 0e89c73ac0..9e9f1604d3 100644 --- a/apps/app_parkandannounce.c +++ b/apps/app_parkandannounce.c @@ -76,14 +76,13 @@ static char *descrip = static int parkandannounce_exec(struct ast_channel *chan, void *data) { - int res=0; char *return_context; int lot, timeout = 0, dres; char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr; char *template, *tpl_working, *tpl_current; char *tmp[100]; char buf[13]; - int looptemp=0,i=0; + int looptemp = 0,i = 0, res = 0; char *s; struct ast_channel *dchan; @@ -101,7 +100,7 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data) s = ast_strdupa(data); - template=strsep(&s,"|"); + template = strsep(&s,"|"); if(! template) { ast_log(LOG_WARNING, "PARK: An announce template must be defined\n"); ast_module_user_remove(u); @@ -112,14 +111,14 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data) timeout = atoi(strsep(&s, "|")); timeout *= 1000; } - dial=strsep(&s, "|"); + dial = strsep(&s, "|"); if(!dial) { ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n"); ast_module_user_remove(u); return -1; } else { - dialtech=strsep(&dial, "/"); - dialstr=dial; + dialtech = strsep(&dial, "/"); + dialstr = dial; ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr); } @@ -170,9 +169,10 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data) /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ - ast_masq_park_call(chan, NULL, timeout, &lot); - - res=-1; + res = ast_masq_park_call(chan, NULL, timeout, &lot); + if (res == -1) { + goto finish; + } ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); @@ -209,15 +209,15 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data) ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template); tpl_working = template; - tpl_current=strsep(&tpl_working, ":"); + tpl_current = strsep(&tpl_working, ":"); while(tpl_current && looptemp < ARRAY_LEN(tmp)) { tmp[looptemp]=tpl_current; looptemp++; - tpl_current=strsep(&tpl_working,":"); + tpl_current = strsep(&tpl_working,":"); } - for(i=0; ilanguage); @@ -234,9 +234,9 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data) ast_stopstream(dchan); ast_hangup(dchan); - + +finish: ast_module_user_remove(u); - return res; } diff --git a/res/res_features.c b/res/res_features.c index 32f01ee2f4..e275a8c33f 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -326,14 +326,26 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, in /* Check for channel variable PARKINGEXTEN */ parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"); if (!ast_strlen_zero(parkingexten)) { - if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) { + /*!\note The API forces us to specify a numeric parking slot, even + * though the architecture would tend to support non-numeric extensions + * (as are possible with SIP, for example). Hence, we enforce that + * limitation here. If extout was not numeric, we could permit + * arbitrary non-numeric extensions. + */ + if (sscanf(parkingexten, "%d", &x) != 1 || x < 0) { + ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten); + ast_mutex_unlock(&parking_lock); + free(pu); + return 1; /* Continue execution if possible */ + } + snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x); + + if (ast_exists_extension(NULL, parking_con, pu->parkingexten, 1, NULL)) { ast_mutex_unlock(&parking_lock); free(pu); ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con); return 1; /* Continue execution if possible */ } - ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten)); - x = atoi(parkingexten); } else { /* Select parking space within range */ parking_range = parking_stop - parking_start+1; @@ -358,6 +370,7 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, in /* Set pointer for next parking */ if (parkfindnext) parking_offset = x - parking_start + 1; + snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x); } chan->appl = "Parked Call"; @@ -398,8 +411,6 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, in if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d@%s. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parking_con, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000)); - if (pu->parkingnum != -1) - snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x); manager_event(EVENT_FLAG_CALL, "ParkedCall", "Exten: %s\r\n" "Channel: %s\r\n" @@ -424,7 +435,7 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, in if (!con) /* Still no context? Bad */ ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con); /* Tell the peer channel the number of the parking space */ - if (peer && ((pu->parkingnum != -1 && ast_strlen_zero(orig_chan_name)) || !strcasecmp(peer->name, orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */ + if (peer && (ast_strlen_zero(orig_chan_name) || !strcasecmp(peer->name, orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */ /* Make sure we don't start saying digits to the channel being parked */ ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM); ast_say_digits(peer, pu->parkingnum, "", peer->language); @@ -458,6 +469,7 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int struct ast_channel *chan; struct ast_frame *f; char *orig_chan_name = NULL; + int park_status; /* Make a new, fake channel that we'll use to masquerade in the real one */ if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) { @@ -480,7 +492,12 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int orig_chan_name = ast_strdupa(chan->name); - park_call_full(chan, peer, timeout, extout, orig_chan_name); + park_status = park_call_full(chan, peer, timeout, extout, orig_chan_name); + if (park_status == 1) { + /* would be nice to play: "invalid parking extension" */ + ast_hangup(chan); + return -1; + } return 0; }