Newer
Older
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
goto out;
}
}
}
if (c->cdr) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_2 "CDR updated on %s\n",c->name);
ast_cdr_update(c);
}
} else {
if (option_verbose > 0) {
char *status;
status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
if (!status)
status = "UNKNOWN";
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_2 "Auto fallthrough, channel '%s' status is '%s'\n", c->name, status);
if (!strcasecmp(status, "CONGESTION"))
res = pbx_builtin_congestion(c, "10");
else if (!strcasecmp(status, "CHANUNAVAIL"))
res = pbx_builtin_congestion(c, "10");
else if (!strcasecmp(status, "BUSY"))
res = pbx_builtin_busy(c, "10");
goto out;
}
}
}
if (firstpass)
ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
out:
if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
c->exten[0] = 'h';
c->exten[1] = '\0';
while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
/* Something bad happened, or a hangup has been requested. */
if (option_debug)
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
break;
}
c->priority++;
}
}
if (res != AST_PBX_KEEPALIVE)
ast_hangup(c);
return 0;
}
static void *pbx_thread(void *data)
{
/* Oh joyeous kernel, we're a new thread, with nothing to do but
answer this channel and get it going. The setjmp stuff is fairly
confusing, but necessary to get smooth transitions between
the execution of different applications (without the use of
additional threads) */
struct ast_channel *c = data;
ast_pbx_run(c);
}
int ast_pbx_start(struct ast_channel *c)
{
pthread_t t;
if (!c) {
ast_log(LOG_WARNING, "Asked to start thread on NULL channel?\n");
return -1;
}
/* Start a new thread, and get something handling this channel. */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (ast_pthread_create(&t, &attr, pbx_thread, c)) {
ast_log(LOG_WARNING, "Failed to create new channel thread\n");
return -1;
}
return 0;
}
int pbx_set_autofallthrough(int newval)
{
int oldval;
oldval = autofallthrough;
if (oldval != newval)
autofallthrough = newval;
return oldval;
}
* This function locks contexts list by &conlist, search for the right context
* structure, leave context list locked and call ast_context_remove_include2
* which removes include, unlock contexts list and return ...
*/
int ast_context_remove_include(const char *context, const char *include, const char *registrar)
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
{
struct ast_context *c;
if (ast_lock_contexts()) return -1;
/* walk contexts and search for the right one ...*/
c = ast_walk_contexts(NULL);
while (c) {
/* we found one ... */
if (!strcmp(ast_get_context_name(c), context)) {
int ret;
/* remove include from this context ... */
ret = ast_context_remove_include2(c, include, registrar);
ast_unlock_contexts();
/* ... return results */
return ret;
}
c = ast_walk_contexts(c);
}
/* we can't find the right one context */
ast_unlock_contexts();
return -1;
}
/*
* When we call this function, &conlock lock must be locked, because when
* we giving *con argument, some process can remove/change this context
* and after that there can be segfault.
*
* This function locks given context, removes include, unlock context and
* return.
*/
int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
if (ast_mutex_lock(&con->lock)) return -1;
/* walk includes */
i = con->includes;
while (i) {
/* find our include */
if (!strcmp(i->name, include) &&
Mark Spencer
committed
(!registrar || !strcmp(i->registrar, registrar))) {
/* remove from list */
if (pi)
pi->next = i->next;
else
con->includes = i->next;
/* free include and return */
free(i);
ast_mutex_unlock(&con->lock);
return 0;
}
pi = i;
i = i->next;
}
/* we can't find the right include */
ast_mutex_unlock(&con->lock);
return -1;
}
/*
* This function locks contexts list by &conlist, search for the rigt context
* structure, leave context list locked and call ast_context_remove_switch2
* which removes switch, unlock contexts list and return ...
*/
int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
struct ast_context *c;
if (ast_lock_contexts()) return -1;
/* walk contexts and search for the right one ...*/
c = ast_walk_contexts(NULL);
while (c) {
/* we found one ... */
if (!strcmp(ast_get_context_name(c), context)) {
int ret;
/* remove switch from this context ... */
ret = ast_context_remove_switch2(c, sw, data, registrar);
ast_unlock_contexts();
/* ... return results */
return ret;
}
c = ast_walk_contexts(c);
}
/* we can't find the right one context */
ast_unlock_contexts();
/*
* When we call this function, &conlock lock must be locked, because when
* we giving *con argument, some process can remove/change this context
* and after that there can be segfault.
*
* This function locks given context, removes switch, unlock context and
* return.
*/
int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
if (ast_mutex_lock(&con->lock)) return -1;
/* walk switchs */
i = con->alts;
while (i) {
/* find our switch */
if (!strcmp(i->name, sw) && !strcmp(i->data, data) &&
Mark Spencer
committed
(!registrar || !strcmp(i->registrar, registrar))) {
/* remove from list */
if (pi)
pi->next = i->next;
else
con->alts = i->next;
/* free switch and return */
free(i);
ast_mutex_unlock(&con->lock);
return 0;
}
pi = i;
i = i->next;
}
/* we can't find the right switch */
ast_mutex_unlock(&con->lock);
return -1;
}
/*
* This functions lock contexts list, search for the right context,
* call ast_context_remove_extension2, unlock contexts list and return.
* In this function we are using
*/
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
{
struct ast_context *c;
if (ast_lock_contexts()) return -1;
/* walk contexts ... */
c = ast_walk_contexts(NULL);
while (c) {
/* ... search for the right one ... */
if (!strcmp(ast_get_context_name(c), context)) {
/* ... remove extension ... */
int ret = ast_context_remove_extension2(c, extension, priority,
registrar);
/* ... unlock contexts list and return */
ast_unlock_contexts();
return ret;
}
c = ast_walk_contexts(c);
}
/* we can't find the right context */
ast_unlock_contexts();
return -1;
}
/*
* When do you want to call this function, make sure that &conlock is locked,
* because some process can handle with your *con context before you lock
* it.
*
* This functionc locks given context, search for the right extension and
* fires out all peer in this extensions with given priority. If priority
* is set to 0, all peers are removed. After that, unlock context and
* return.
*/
int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
{
struct ast_exten *exten, *prev_exten = NULL;
if (ast_mutex_lock(&con->lock)) return -1;
/* go through all extensions in context and search the right one ... */
exten = con->root;
while (exten) {
/* look for right extension */
if (!strcmp(exten->exten, extension) &&
Mark Spencer
committed
(!registrar || !strcmp(exten->registrar, registrar))) {
struct ast_exten *peer;
/* should we free all peers in this extension? (priority == 0)? */
if (priority == 0) {
/* remove this extension from context list */
if (prev_exten)
prev_exten->next = exten->next;
else
con->root = exten->next;
/* fire out all peers */
peer = exten;
while (peer) {
exten = peer->peer;
if (!peer->priority==PRIORITY_HINT)
ast_remove_hint(peer);
peer->datad(peer->data);
free(peer);
peer = exten;
}
ast_mutex_unlock(&con->lock);
return 0;
} else {
/* remove only extension with exten->priority == priority */
struct ast_exten *previous_peer = NULL;
peer = exten;
while (peer) {
/* is this our extension? */
if (peer->priority == priority &&
Mark Spencer
committed
(!registrar || !strcmp(peer->registrar, registrar) )) {
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
/* we are first priority extension? */
if (!previous_peer) {
/* exists previous extension here? */
if (prev_exten) {
/* yes, so we must change next pointer in
* previous connection to next peer
*/
if (peer->peer) {
prev_exten->next = peer->peer;
peer->peer->next = exten->next;
} else
prev_exten->next = exten->next;
} else {
/* no previous extension, we are first
* extension, so change con->root ...
*/
if (peer->peer)
con->root = peer->peer;
else
con->root = exten->next;
}
} else {
/* we are not first priority in extension */
previous_peer->peer = peer->peer;
}
/* now, free whole priority extension */
if (peer->priority==PRIORITY_HINT)
ast_remove_hint(peer);
ast_mutex_unlock(&con->lock);
return 0;
} else {
/* this is not right extension, skip to next peer */
previous_peer = peer;
peer = peer->peer;
}
}
ast_mutex_unlock(&con->lock);
return -1;
}
}
prev_exten = exten;
exten = exten->next;
}
/* we can't find right extension */
ast_mutex_unlock(&con->lock);
int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
Mark Spencer
committed
struct ast_app *tmp, *prev, *cur;
int length;
length = sizeof(struct ast_app);
length += strlen(app) + 1;
if (ast_mutex_lock(&applock)) {
ast_log(LOG_ERROR, "Unable to lock application list\n");
return -1;
}
tmp = apps;
while(tmp) {
if (!strcasecmp(app, tmp->name)) {
ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
ast_mutex_unlock(&applock);
tmp = malloc(length);
memset(tmp, 0, length);
strcpy(tmp->name, app);
tmp->synopsis = synopsis;
tmp->description = description;
Mark Spencer
committed
/* Store in alphabetical order */
cur = apps;
prev = NULL;
while(cur) {
if (strcasecmp(tmp->name, cur->name) < 0)
break;
prev = cur;
cur = cur->next;
}
if (prev) {
tmp->next = prev->next;
prev->next = tmp;
} else {
tmp->next = apps;
apps = tmp;
}
ast_log(LOG_ERROR, "Out of memory\n");
ast_mutex_unlock(&applock);
ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
ast_mutex_unlock(&applock);
if (ast_mutex_lock(&switchlock)) {
ast_log(LOG_ERROR, "Unable to lock switch lock\n");
if (!strcasecmp(tmp->name, sw->name))
break;
prev = tmp;
ast_mutex_unlock(&switchlock);
ast_log(LOG_WARNING, "Switch '%s' already found\n", sw->name);
return -1;
}
sw->next = NULL;
if (prev)
prev->next = sw;
else
switches = sw;
ast_mutex_unlock(&switchlock);
void ast_unregister_switch(struct ast_switch *sw)
if (ast_mutex_lock(&switchlock)) {
ast_log(LOG_ERROR, "Unable to lock switch lock\n");
return;
if (tmp == sw) {
if (prev)
prev->next = tmp->next;
else
switches = tmp->next;
tmp->next = NULL;
break;
ast_mutex_unlock(&switchlock);
/*
* Help for CLI commands ...
*/
static char show_application_help[] =
"Usage: show application <application> [<application> [<application> [...]]]\n"
" Describes a particular application.\n";
static char show_applications_help[] =
"Usage: show applications [{like|describing} <text>]\n"
" List applications which are currently available.\n"
" If 'like', <text> will be a substring of the app name\n"
" If 'describing', <text> will be a substring of the description\n";
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
static char show_dialplan_help[] =
"Usage: show dialplan [exten@][context]\n"
" Show dialplan\n";
static char show_switches_help[] =
"Usage: show switches\n"
" Show registered switches\n";
/*
* IMPLEMENTATION OF CLI FUNCTIONS IS IN THE SAME ORDER AS COMMANDS HELPS
*
*/
/*
* 'show application' CLI command implementation functions ...
*/
/*
* There is a possibility to show informations about more than one
* application at one time. You can type 'show application Dial Echo' and
* you will see informations about these two applications ...
*/
static char *complete_show_application(char *line, char *word,
int pos, int state)
if (ast_mutex_lock(&applock)) {
ast_log(LOG_ERROR, "Unable to lock application list\n");
/* ... walk all applications ... */
a = apps;
while (a) {
/* ... check if word matches this application ... */
if (!strncasecmp(word, a->name, strlen(word))) {
/* ... if this is right app serve it ... */
if (++which > state) {
char *ret = strdup(a->name);
ast_mutex_unlock(&applock);
ast_mutex_unlock(&applock);
}
static int handle_show_application(int fd, int argc, char *argv[])
{
if (argc < 3) return RESULT_SHOWUSAGE;
/* try to lock applications list ... */
if (ast_mutex_lock(&applock)) {
ast_log(LOG_ERROR, "Unable to lock application list\n");
return -1;
}
/* ... go through all applications ... */
a = apps;
while (a) {
/* ... compare this application name with all arguments given
* to 'show application' command ... */
for (app = 2; app < argc; app++) {
if (!strcasecmp(a->name, argv[app])) {
/* Maximum number of characters added by terminal coloring is 22 */
char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40];
char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
int synopsis_size, description_size;
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
if (a->synopsis)
synopsis_size = strlen(a->synopsis) + 23;
else
synopsis_size = strlen("Not available") + 23;
synopsis = alloca(synopsis_size);
if (a->description)
description_size = strlen(a->description) + 23;
else
description_size = strlen("Not available") + 23;
description = alloca(description_size);
if (synopsis && description) {
snprintf(info, 64 + AST_MAX_APP, "\n -= Info about application '%s' =- \n\n", a->name);
term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
term_color(syntitle, "[Synopsis]:\n", COLOR_MAGENTA, 0, 40);
term_color(destitle, "[Description]:\n", COLOR_MAGENTA, 0, 40);
term_color(synopsis,
a->synopsis ? a->synopsis : "Not available",
COLOR_CYAN, 0, synopsis_size);
term_color(description,
a->description ? a->description : "Not available",
COLOR_CYAN, 0, description_size);
ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description);
} else {
/* ... one of our applications, show info ...*/
ast_cli(fd,"\n -= Info about application '%s' =- \n\n"
"[Synopsis]:\n %s\n\n"
"[Description]:\n%s\n",
a->name,
a->synopsis ? a->synopsis : "Not available",
a->description ? a->description : "Not available");
ast_mutex_unlock(&applock);
/* we found at least one app? no? */
if (no_registered_app) {
ast_cli(fd, "Your application(s) is (are) not registered\n");
return RESULT_FAILURE;
}
static int handle_show_switches(int fd, int argc, char *argv[])
struct ast_switch *sw;
if (!switches) {
ast_cli(fd, "There are no registered alternative switches\n");
return RESULT_SUCCESS;
}
/* ... we have applications ... */
ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n");
if (ast_mutex_lock(&switchlock)) {
ast_log(LOG_ERROR, "Unable to lock switches\n");
return -1;
}
sw = switches;
while (sw) {
ast_cli(fd, "%s: %s\n", sw->name, sw->description);
sw = sw->next;
}
ast_mutex_unlock(&switchlock);
return RESULT_SUCCESS;
}
/*
* 'show applications' CLI command implementation functions ...
*/
static int handle_show_applications(int fd, int argc, char *argv[])
{
struct ast_app *a;
int like=0, describing=0;
int total_match = 0; /* Number of matches in like clause */
int total_apps = 0; /* Number of apps registered */
if (ast_mutex_lock(&applock)) {
ast_log(LOG_ERROR, "Unable to lock application list\n");
return -1;
}
/* ... have we got at least one application (first)? no? */
if (!apps) {
ast_cli(fd, "There are no registered applications\n");
ast_mutex_unlock(&applock);
/* show applications like <keyword> */
if ((argc == 4) && (!strcmp(argv[2], "like"))) {
like = 1;
} else if ((argc > 3) && (!strcmp(argv[2], "describing"))) {
describing = 1;
}
/* show applications describing <keyword1> [<keyword2>] [...] */
if ((!like) && (!describing)) {
ast_cli(fd, " -= Registered Asterisk Applications =-\n");
} else {
ast_cli(fd, " -= Matching Asterisk Applications =-\n");
}
for (a = apps; a; a = a->next) {
/* ... show informations about applications ... */
if (like) {
if (ast_strcasestr(a->name, argv[3])) {
printapp = 1;
}
} else if (describing) {
if (a->description) {
/* Match all words on command line */
int i;
printapp = 1;
for (i=3;i<argc;i++) {
if (! ast_strcasestr(a->description, argv[i])) {
printapp = 0;
}
}
}
} else {
printapp = 1;
}
if (printapp) {
ast_cli(fd," %20s: %s\n", a->name, a->synopsis ? a->synopsis : "<Synopsis not available>");
}
if ((!like) && (!describing)) {
ast_cli(fd, " -= %d Applications Registered =-\n",total_apps);
} else {
ast_cli(fd, " -= %d Applications Matching =-\n",total_match);
}
ast_mutex_unlock(&applock);
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
static char *complete_show_applications(char *line, char *word, int pos, int state)
{
if (pos == 2) {
if (ast_strlen_zero(word)) {
switch (state) {
case 0:
return strdup("like");
case 1:
return strdup("describing");
default:
return NULL;
}
} else if (! strncasecmp(word, "like", strlen(word))) {
if (state == 0) {
return strdup("like");
} else {
return NULL;
}
} else if (! strncasecmp(word, "describing", strlen(word))) {
if (state == 0) {
return strdup("describing");
} else {
return NULL;
}
}
}
return NULL;
}
/*
* 'show dialplan' CLI command implementation functions ...
*/
static char *complete_show_dialplan_context(char *line, char *word, int pos,
int state)
{
struct ast_context *c;
int which = 0;
/* we are do completion of [exten@]context on second position only */
if (pos != 2) return NULL;
/* try to lock contexts list ... */
if (ast_lock_contexts()) {
ast_log(LOG_ERROR, "Unable to lock context list\n");
return NULL;
}
/* ... walk through all contexts ... */
c = ast_walk_contexts(NULL);
while(c) {
/* ... word matches context name? yes? ... */
if (!strncasecmp(word, ast_get_context_name(c), strlen(word))) {
/* ... for serve? ... */
if (++which > state) {
/* ... yes, serve this context name ... */
char *ret = strdup(ast_get_context_name(c));
ast_unlock_contexts();
return ret;
}
/* ... unlock and return */
ast_unlock_contexts();
return NULL;
}
static int handle_show_dialplan(int fd, int argc, char *argv[])
{
struct ast_context *c;
char *exten = NULL, *context = NULL;
int context_existence = 0, extension_existence = 0;
/* Variables used for different counters */
int total_context = 0, total_exten = 0, total_prio = 0;
if (argc != 3 && argc != 2) return -1;
/* we obtain [exten@]context? if yes, split them ... */
if (argc == 3) {
char *splitter = argv[2];
/* is there a '@' character? */
if (strchr(argv[2], '@')) {
/* yes, split into exten & context ... */
exten = strsep(&splitter, "@");
context = splitter;
/* check for length and change to NULL if ast_strlen_zero() */
if (ast_strlen_zero(exten)) exten = NULL;
if (ast_strlen_zero(context)) context = NULL;
} else
{
/* no '@' char, only context given */
context = argv[2];
if (ast_strlen_zero(context)) context = NULL;
}
}
/* try to lock contexts */
if (ast_lock_contexts()) {
ast_log(LOG_WARNING, "Failed to lock contexts list\n");
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
return RESULT_FAILURE;
}
/* walk all contexts ... */
c = ast_walk_contexts(NULL);
while (c) {
/* show this context? */
if (!context ||
!strcmp(ast_get_context_name(c), context)) {
context_existence = 1;
/* try to lock context before walking in ... */
if (!ast_lock_context(c)) {
struct ast_exten *e;
struct ast_include *i;
struct ast_ignorepat *ip;
struct ast_sw *sw;
char buf[256], buf2[256];
int context_info_printed = 0;
/* are we looking for exten too? if yes, we print context
* if we our extension only
*/
if (!exten) {
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
ast_get_context_name(c), ast_get_context_registrar(c));
context_info_printed = 1;
}
/* walk extensions ... */
e = ast_walk_context_extensions(c, NULL);
while (e) {
struct ast_exten *p;
/* looking for extension? is this our extension? */
if (exten &&
strcmp(ast_get_extension_name(e), exten))
{
/* we are looking for extension and it's not our
* extension, so skip to next extension */
e = ast_walk_context_extensions(c, e);
continue;
}
extension_existence = 1;
/* may we print context info? */
if (!context_info_printed) {
ast_cli(fd, "[ Context '%s' created by '%s' ]\n",
ast_get_context_name(c),
ast_get_context_registrar(c));
context_info_printed = 1;
}
/* write extension name and first peer */
bzero(buf, sizeof(buf));
snprintf(buf, sizeof(buf), "'%s' =>",
ast_get_extension_name(e));
snprintf(buf2, sizeof(buf2),
"%d. %s(%s)",
ast_get_extension_priority(e),
ast_get_extension_app(e),
(char *)ast_get_extension_app_data(e));
ast_cli(fd, " %-17s %-45s [%s]\n", buf, buf2,
ast_get_extension_registrar(e));
/* walk next extension peers */
p = ast_walk_extension_priorities(e, e);
while (p) {
bzero((void *)buf, sizeof(buf));
if (ast_get_extension_label(p))
snprintf(buf, sizeof(buf), " [%s]", ast_get_extension_label(p));
snprintf(buf2, sizeof(buf2),
"%d. %s(%s)",
ast_get_extension_priority(p),
ast_get_extension_app(p),
(char *)ast_get_extension_app_data(p));
ast_cli(fd," %-17s %-45s [%s]\n",
ast_get_extension_registrar(p));
p = ast_walk_extension_priorities(e, p);
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
/* include & ignorepat we all printing if we are not
* looking for exact extension
*/
if (!exten) {
if (ast_walk_context_extensions(c, NULL))
ast_cli(fd, "\n");
/* walk included and write info ... */
i = ast_walk_context_includes(c, NULL);
while (i) {
bzero(buf, sizeof(buf));
snprintf(buf, sizeof(buf), "'%s'",
ast_get_include_name(i));
ast_cli(fd, " Include => %-45s [%s]\n",
buf, ast_get_include_registrar(i));
i = ast_walk_context_includes(c, i);
}
/* walk ignore patterns and write info ... */
ip = ast_walk_context_ignorepats(c, NULL);
while (ip) {
bzero(buf, sizeof(buf));
snprintf(buf, sizeof(buf), "'%s'",
ast_get_ignorepat_name(ip));
ast_cli(fd, " Ignore pattern => %-45s [%s]\n",
buf, ast_get_ignorepat_registrar(ip));
ip = ast_walk_context_ignorepats(c, ip);
}
sw = ast_walk_context_switches(c, NULL);
while(sw) {
bzero(buf, sizeof(buf));
snprintf(buf, sizeof(buf), "'%s/%s'",
ast_get_switch_name(sw),
ast_get_switch_data(sw));
ast_cli(fd, " Alt. Switch => %-45s [%s]\n",
buf, ast_get_switch_registrar(sw));
sw = ast_walk_context_switches(c, sw);
}
}
ast_unlock_context(c);
/* if we print something in context, make an empty line */
if (context_info_printed) ast_cli(fd, "\n");
ast_unlock_contexts();
/* check for input failure and throw some error messages */
if (context && !context_existence) {
ast_cli(fd, "There is no existence of '%s' context\n",
context);
return RESULT_FAILURE;
}
if (exten && !extension_existence) {
if (context)
ast_cli(fd, "There is no existence of %s@%s extension\n",
exten, context);
else
ast_cli(fd,
"There is no existence of '%s' extension in all contexts\n",
exten);
return RESULT_FAILURE;
}
ast_cli(fd,"-= %d extensions (%d priorities) in %d contexts. =-\n",total_exten, total_prio, total_context);