--- asterisk-1.4.21.2/apps/app_page.c.orig 2008-09-12 18:37:59.000000000 -0500 +++ asterisk-1.4.21.2/apps/app_page.c 2008-09-12 19:07:44.000000000 -0500 @@ -78,7 +78,6 @@ AST_APP_OPTION('r', PAGE_RECORD), }); -#define MAX_DIALS 128 static int page_exec(struct ast_channel *chan, void *data) { @@ -89,7 +88,8 @@ unsigned int confid = ast_random(); struct ast_app *app; int res = 0, pos = 0, i = 0; - struct ast_dial *dials[MAX_DIALS]; + struct ast_dial **dial_list; + unsigned int num_dials; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n"); @@ -117,10 +117,27 @@ snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); + /* Count number of extensions in list by number of ampersands + 1 */ + num_dials = 0; + if (*tmp) { + char *p = tmp; + while (*p) if (*p++ == '&') num_dials++; + num_dials++; + } + dial_list = (struct ast_dial **)ast_malloc(sizeof(struct ast_dial *) * num_dials); + if (dial_list == NULL) { + ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (sizeof(struct ast_dial *) * num_dials)); + ast_module_user_remove(u); + return -1; + } + /* Go through parsing/calling each device */ while ((tech = strsep(&tmp, "&"))) { struct ast_dial *dial = NULL; + /* Ensure dial slot is always initialized */ + dial_list[pos] = NULL; + /* don't call the originating device */ if (!strcasecmp(tech, originator)) continue; @@ -149,7 +166,7 @@ ast_dial_run(dial, chan, 1); /* Put in our dialing array */ - dials[pos++] = dial; + dial_list[pos++] = dial; } if (!ast_test_flag(&flags, PAGE_QUIET)) { @@ -166,7 +183,10 @@ /* Go through each dial attempt cancelling, joining, and destroying */ for (i = 0; i < pos; i++) { - struct ast_dial *dial = dials[i]; + struct ast_dial *dial = dial_list[i]; + + /* Ensure this dial slot is valid */ + if (dial == NULL) continue; /* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */ ast_dial_join(dial); @@ -178,6 +198,7 @@ ast_dial_destroy(dial); } + ast_free(dial_list); ast_module_user_remove(u); return -1;