Index: pbx/pbx_config.c =================================================================== RCS file: /usr/cvsroot/asterisk/pbx/pbx_config.c,v retrieving revision 1.43 diff -u -r1.43 pbx_config.c --- pbx/pbx_config.c 21 Jun 2004 14:20:03 -0000 1.43 +++ pbx/pbx_config.c 23 Jun 2004 22:21:00 -0000 @@ -1572,6 +1572,7 @@ ast_cli_unregister(&context_add_ignorepat_cli); ast_cli_unregister(&reload_extensions_cli); ast_context_destroy(NULL, registrar); + ast_cleanup_labels(); return 0; } @@ -1608,10 +1609,15 @@ if ((con=ast_context_create(&local_contexts,cxt, registrar))) { v = ast_variable_browse(cfg, cxt); while(v) { - if (!strcasecmp(v->name, "exten")) { + if (!strncasecmp(v->name, "exten", 5)) { char *stringp=NULL; int ipri = -2; char realext[256]=""; + char label[256]=""; + + if (v->name[5] == ':') { + strncpy(label,v->name + 6,sizeof(label)); + } tc = strdup(v->value); if(tc!=NULL){ stringp=tc; @@ -1667,7 +1673,8 @@ if (ipri) { if (ast_add_extension2(con, 0, realext, ipri, cidmatch, appl, strdup(data), FREE, registrar)) { ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno); - } + } else if (label[0]) + ast_add_label(label, cxt, realext, ipri); } free(tc); } else fprintf(stderr,"Error strdup returned NULL in %s\n",__PRETTY_FUNCTION__); @@ -1729,6 +1736,7 @@ int reload(void) { ast_context_destroy(NULL, registrar); + ast_cleanup_labels(); /* For martin's global variables, don't clear them on reload */ #if 0 pbx_builtin_clear_globals(); Index: pbx.c =================================================================== RCS file: /usr/cvsroot/asterisk/pbx.c,v retrieving revision 1.128 diff -u -r1.128 pbx.c --- pbx.c 22 Jun 2004 17:42:13 -0000 1.128 +++ pbx.c 23 Jun 2004 22:21:01 -0000 @@ -389,6 +389,80 @@ struct ast_hint *hints = NULL; struct ast_state_cb *statecbs = NULL; +/* Lock for label list */ +AST_MUTEX_DEFINE_STATIC(label_lock); +static struct ast_label *labels = NULL; + +struct ast_label *ast_lookup_label(char *label) +{ + struct ast_label *temp = labels, *result = NULL; + while (temp) { + if (!strcmp(label, temp->label)) { + result = temp; + break; + } + temp = temp->next; + } + return result; +} + +void ast_add_label(char *label, char *context, char *exten, int priority) +{ + struct ast_label *newlabel; + + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "Adding label %s\n", label); + } + if ((newlabel = malloc(sizeof(struct ast_label)))) { + memset(newlabel,0,sizeof(struct ast_label)); + strncpy(newlabel->label, label, 255); + strncpy(newlabel->context, context, 255); + strncpy(newlabel->exten, exten, AST_MAX_EXTENSION); + newlabel->priority = priority; + + ast_mutex_lock(&label_lock); + newlabel->next = labels; + labels = newlabel; + ast_mutex_unlock(&label_lock); + } else { + ast_log(LOG_ERROR, "Out of memory\n"); + } +} + +static int handle_show_labels(int fd, int argc, char *argv[]) +{ + struct ast_label *tmp = labels; + + if (ast_mutex_trylock(&label_lock)) { + ast_log(LOG_ERROR, "Failed to lock label list\n"); + return RESULT_FAILURE; + } else { + if (tmp) { + ast_cli(fd, "%-15.15s %-15.15s %-15.15s %3s\n", "Label", "Context", "Extension", "Pri"); + } else { + ast_cli(fd, "There are no labels currently defined\n"); + } + while (tmp) { + ast_cli(fd, "%-15.15s %-15.15s %-15.15s %3d\n", tmp->label, tmp->context, tmp->exten, tmp->priority); + tmp = tmp->next; + } + ast_mutex_unlock(&label_lock); + } + return RESULT_SUCCESS; +} + +void ast_cleanup_labels(void) +{ + /* For use when unloading/reloading config */ + ast_mutex_lock(&label_lock); + while (labels) { + struct ast_label *next = labels->next; + free(labels); + labels = next; + } + ast_mutex_unlock(&label_lock); +} + int pbx_exec(struct ast_channel *c, /* Channel */ struct ast_app *app, void *data, /* Data for execution */ @@ -806,6 +880,25 @@ /* length is zero */ *ret = "0"; } + } else if (!strncasecmp(var,"LABEL(",6)) { + int len=strlen(var); + if (strrchr(var,')')) { + char cp3[80]; + struct ast_label *label; + strncpy(cp3, var, sizeof(cp3) - 1); + cp3[len - 6 - 1] = '\0'; + label = ast_lookup_label(cp3); + if (label) { + sprintf(workspace,"%s|%s|%d",label->context,label->exten,label->priority); + *ret = workspace; + } else { + *ret = ""; + ast_log(LOG_WARNING, "Invalid label: %s\n", cp3); + } + } else { + *ret = ""; + ast_log(LOG_ERROR, "Invalid label specification: %s\n", var); + } } else if ((first=strchr(var,':'))) { strncpy(tmpvar, var, sizeof(tmpvar) - 1); first = strchr(tmpvar, ':'); @@ -2342,6 +2435,10 @@ /* * Help for CLI commands ... */ +static char show_labels_help[] = +"Usage: show labels\n" +" Lists labels in the dialplan.\n"; + static char show_application_help[] = "Usage: show application [ [ [...]]]\n" " Describes a particular application.\n"; @@ -2777,6 +2874,11 @@ /* * CLI entries for upper commands ... */ +static struct ast_cli_entry show_labels_cli = + { { "show", "labels", NULL }, + handle_show_labels, "Shows registered labels", + show_labels_help }; + static struct ast_cli_entry show_applications_cli = { { "show", "applications", NULL }, handle_show_applications, "Shows registered applications", @@ -4605,7 +4707,7 @@ } if ((branch==NULL) || ast_strlen_zero(branch)) { - ast_log(LOG_NOTICE, "Not taking any branch\n"); + /* ast_log(LOG_NOTICE, "Not taking any branch\n"); */ return(0); } @@ -4673,6 +4775,7 @@ ast_verbose( "Registering builtin applications:\n"); } AST_LIST_HEAD_INIT(&globals); + ast_cli_register(&show_labels_cli); ast_cli_register(&show_applications_cli); ast_cli_register(&show_application_cli); ast_cli_register(&show_dialplan_cli); Index: include/asterisk/pbx.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/pbx.h,v retrieving revision 1.24 diff -u -r1.24 pbx.h --- include/asterisk/pbx.h 6 Apr 2004 22:17:32 -0000 1.24 +++ include/asterisk/pbx.h 23 Jun 2004 22:21:01 -0000 @@ -75,6 +75,13 @@ (seconds) */ }; +struct ast_label { + char label[256]; + char context[256]; + char exten[AST_MAX_EXTENSION]; + int priority; + struct ast_label *next; +}; //! Register an alternative switch /*! @@ -533,6 +540,10 @@ int ast_extension_patmatch(const char *pattern, const char *data); +void ast_add_label(char *label, char *context, char *exten, int priority); +struct ast_label *ast_lookup_label(char *label); +void ast_cleanup_labels(void); + #if defined(__cplusplus) || defined(c_plusplus) } #endif