#include "asterisk.h"
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/say.h"
#include "asterisk/app.h"
Go to the source code of this file.
Data Structures | |
struct | directory_item |
struct | itemlist |
Defines | |
#define | NUMDIGITS 3 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
Enumerations | |
enum | { OPT_LISTBYFIRSTNAME = (1 << 0), OPT_SAYEXTENSION = (1 << 1), OPT_FROMVOICEMAIL = (1 << 2), OPT_SELECTFROMMENU = (1 << 3) } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | check_match (struct directory_item **result, const char *item_fullname, const char *item_ext, const char *pattern_ext, int use_first_name) |
static int | compare (const char *text, const char *template) |
static int | directory_exec (struct ast_channel *chan, void *data) |
static int | do_directory (struct ast_channel *chan, struct ast_config *vmcfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, struct ast_flags *flags) |
static int | goto_exten (struct ast_channel *chan, const char *dialcontext, char *ext) |
static int | load_module (void) |
static int | play_mailbox_owner (struct ast_channel *chan, const char *context, const char *ext, const char *name, struct ast_flags *flags) |
static struct ast_config * | realtime_directory (char *context) |
static int | search_directory (const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, int use_first_name, itemlist *alist) |
static int | select_entry (struct ast_channel *chan, const char *context, const char *dialcontext, const struct directory_item *item, struct ast_flags *flags) |
static int | select_item_menu (struct ast_channel *chan, struct directory_item **items, int count, const char *context, const char *dialcontext, struct ast_flags *flags) |
static int | select_item_seq (struct ast_channel *chan, struct directory_item **items, int count, const char *context, const char *dialcontext, struct ast_flags *flags) |
static void | sort_items (struct directory_item **sorted, int count) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Directory" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static char * | app = "Directory" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static struct ast_app_option | directory_app_options [128] = { [ 'f' ] = { .flag = OPT_LISTBYFIRSTNAME }, [ 'e' ] = { .flag = OPT_SAYEXTENSION }, [ 'v' ] = { .flag = OPT_FROMVOICEMAIL }, [ 'm' ] = { .flag = OPT_SELECTFROMMENU },} |
enum { ... } | directory_option_flags |
static char * | synopsis = "Provide directory of voicemail extensions" |
Definition in file app_directory.c.
#define NUMDIGITS 3 |
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 79 of file app_directory.c.
Referenced by load_config(), load_module(), realtime_directory(), and vm_change_password().
anonymous enum |
Definition at line 84 of file app_directory.c.
00084 { 00085 OPT_LISTBYFIRSTNAME = (1 << 0), 00086 OPT_SAYEXTENSION = (1 << 1), 00087 OPT_FROMVOICEMAIL = (1 << 2), 00088 OPT_SELECTFROMMENU = (1 << 3), 00089 } directory_option_flags;
static void __reg_module | ( | void | ) | [static] |
Definition at line 849 of file app_directory.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 849 of file app_directory.c.
static int check_match | ( | struct directory_item ** | result, | |
const char * | item_fullname, | |||
const char * | item_ext, | |||
const char * | pattern_ext, | |||
int | use_first_name | |||
) | [static] |
Definition at line 525 of file app_directory.c.
References ast_calloc, ast_copy_string(), compare(), and directory_item::key.
Referenced by search_directory().
00526 { 00527 struct directory_item *item; 00528 const char *key = NULL; 00529 int namelen; 00530 00531 00532 /* Set key to last name or first name depending on search mode */ 00533 if (!use_first_name) 00534 key = strchr(item_fullname, ' '); 00535 00536 if (key) 00537 key++; 00538 else 00539 key = item_fullname; 00540 00541 if (compare(key, pattern_ext)) 00542 return 0; 00543 00544 /* Match */ 00545 item = ast_calloc(1, sizeof(*item)); 00546 if (!item) 00547 return -1; 00548 ast_copy_string(item->name, item_fullname, sizeof(item->name)); 00549 ast_copy_string(item->exten, item_ext, sizeof(item->exten)); 00550 00551 ast_copy_string(item->key, key, sizeof(item->key)); 00552 if (key != item_fullname) { 00553 /* Key is the last name. Append first name to key in order to sort Last,First */ 00554 namelen = key - item_fullname - 1; 00555 if (namelen > sizeof(item->key) - strlen(item->key) - 1) 00556 namelen = sizeof(item->key) - strlen(item->key) - 1; 00557 strncat(item->key, item_fullname, namelen); 00558 } 00559 00560 *result = item; 00561 return 1; 00562 }
static int compare | ( | const char * | text, | |
const char * | template | |||
) | [static] |
Definition at line 221 of file app_directory.c.
References ast_strlen_zero().
Referenced by check_match().
00222 { 00223 char digit; 00224 00225 if (ast_strlen_zero(text)) { 00226 return -1; 00227 } 00228 00229 while (*template) { 00230 digit = toupper(*text++); 00231 switch (digit) { 00232 case 0: 00233 return -1; 00234 case '1': 00235 digit = '1'; 00236 break; 00237 case '2': 00238 case 'A': 00239 case 'B': 00240 case 'C': 00241 digit = '2'; 00242 break; 00243 case '3': 00244 case 'D': 00245 case 'E': 00246 case 'F': 00247 digit = '3'; 00248 break; 00249 case '4': 00250 case 'G': 00251 case 'H': 00252 case 'I': 00253 digit = '4'; 00254 break; 00255 case '5': 00256 case 'J': 00257 case 'K': 00258 case 'L': 00259 digit = '5'; 00260 break; 00261 case '6': 00262 case 'M': 00263 case 'N': 00264 case 'O': 00265 digit = '6'; 00266 break; 00267 case '7': 00268 case 'P': 00269 case 'Q': 00270 case 'R': 00271 case 'S': 00272 digit = '7'; 00273 break; 00274 case '8': 00275 case 'T': 00276 case 'U': 00277 case 'V': 00278 digit = '8'; 00279 break; 00280 case '9': 00281 case 'W': 00282 case 'X': 00283 case 'Y': 00284 case 'Z': 00285 digit = '9'; 00286 break; 00287 00288 default: 00289 if (digit > ' ') 00290 return -1; 00291 continue; 00292 } 00293 00294 if (*template++ != digit) 00295 return -1; 00296 } 00297 00298 return 0; 00299 }
static int directory_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 743 of file app_directory.c.
References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_config_destroy(), ast_config_load, AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, ast_log(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), ast_waitfordigit(), ast_waitstream(), chan, dialcontext, directory_app_options, do_directory(), ast_flags::flags, LOG_ERROR, LOG_WARNING, OPT_LISTBYFIRSTNAME, parse(), and realtime_directory().
Referenced by load_module().
00744 { 00745 int res = 0; 00746 struct ast_config *cfg, *ucfg; 00747 const char *dirintro; 00748 char *parse, *opts[0]; 00749 struct ast_flags flags = { 0 }; 00750 struct ast_flags config_flags = { 0 }; 00751 AST_DECLARE_APP_ARGS(args, 00752 AST_APP_ARG(vmcontext); 00753 AST_APP_ARG(dialcontext); 00754 AST_APP_ARG(options); 00755 ); 00756 00757 if (ast_strlen_zero(data)) { 00758 ast_log(LOG_WARNING, "Directory requires an argument (context[,dialcontext])\n"); 00759 return -1; 00760 } 00761 00762 parse = ast_strdupa(data); 00763 00764 AST_STANDARD_APP_ARGS(args, parse); 00765 00766 if (args.options && ast_app_parse_options(directory_app_options, &flags, opts, args.options)) 00767 return -1; 00768 00769 if (ast_strlen_zero(args.dialcontext)) 00770 args.dialcontext = args.vmcontext; 00771 00772 cfg = realtime_directory(args.vmcontext); 00773 if (!cfg) { 00774 ast_log(LOG_ERROR, "Unable to read the configuration data!\n"); 00775 return -1; 00776 } 00777 00778 ucfg = ast_config_load("users.conf", config_flags); 00779 00780 dirintro = ast_variable_retrieve(cfg, args.vmcontext, "directoryintro"); 00781 if (ast_strlen_zero(dirintro)) 00782 dirintro = ast_variable_retrieve(cfg, "general", "directoryintro"); 00783 if (ast_strlen_zero(dirintro)) 00784 dirintro = ast_test_flag(&flags, OPT_LISTBYFIRSTNAME) ? "dir-intro-fn" : "dir-intro"; 00785 00786 if (chan->_state != AST_STATE_UP) 00787 res = ast_answer(chan); 00788 00789 for (;;) { 00790 if (!res) 00791 res = ast_stream_and_wait(chan, dirintro, AST_DIGIT_ANY); 00792 ast_stopstream(chan); 00793 if (!res) 00794 res = ast_waitfordigit(chan, 5000); 00795 00796 if (res <= 0) 00797 break; 00798 00799 res = do_directory(chan, cfg, ucfg, args.vmcontext, args.dialcontext, res, &flags); 00800 if (res) 00801 break; 00802 00803 res = ast_waitstream(chan, AST_DIGIT_ANY); 00804 ast_stopstream(chan); 00805 00806 if (res) 00807 break; 00808 } 00809 00810 if (ucfg) 00811 ast_config_destroy(ucfg); 00812 ast_config_destroy(cfg); 00813 00814 return res < 0 ? -1 : 0; 00815 }
static int do_directory | ( | struct ast_channel * | chan, | |
struct ast_config * | vmcfg, | |||
struct ast_config * | ucfg, | |||
char * | context, | |||
char * | dialcontext, | |||
char | digit, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 659 of file app_directory.c.
References ast_calloc, ast_debug, ast_free, AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_readstring(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, chan, directory_item::entry, ext, directory_item::exten, goto_exten(), ast_channel::language, LOG_DEBUG, LOG_WARNING, directory_item::name, NUMDIGITS, OPT_LISTBYFIRSTNAME, OPT_SELECTFROMMENU, option_debug, search_directory(), select_item_menu(), select_item_seq(), and sort_items().
Referenced by directory_exec().
00660 { 00661 /* Read in the first three digits.. "digit" is the first digit, already read */ 00662 int res = 0; 00663 itemlist alist = AST_LIST_HEAD_NOLOCK_INIT_VALUE; 00664 struct directory_item *item, **ptr, **sorted = NULL; 00665 int count, i; 00666 char ext[NUMDIGITS + 1] = ""; 00667 00668 if (ast_strlen_zero(context)) { 00669 ast_log(LOG_WARNING, 00670 "Directory must be called with an argument " 00671 "(context in which to interpret extensions)\n"); 00672 return -1; 00673 } 00674 00675 if (digit == '0' && !goto_exten(chan, dialcontext, "o")) { 00676 return 0; 00677 } 00678 00679 if (digit == '*' && !goto_exten(chan, dialcontext, "a")) { 00680 return 0; 00681 } 00682 00683 ext[0] = digit; 00684 if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) 00685 return -1; 00686 00687 res = search_directory(context, vmcfg, ucfg, ext, ast_test_flag(flags, OPT_LISTBYFIRSTNAME), &alist); 00688 if (res) 00689 goto exit; 00690 00691 /* Count items in the list */ 00692 count = 0; 00693 AST_LIST_TRAVERSE(&alist, item, entry) { 00694 count++; 00695 } 00696 00697 if (count < 1) { 00698 res = ast_streamfile(chan, "dir-nomatch", chan->language); 00699 goto exit; 00700 } 00701 00702 00703 /* Create plain array of pointers to items (for sorting) */ 00704 sorted = ast_calloc(count, sizeof(*sorted)); 00705 00706 ptr = sorted; 00707 AST_LIST_TRAVERSE(&alist, item, entry) { 00708 *ptr++ = item; 00709 } 00710 00711 /* Sort items */ 00712 sort_items(sorted, count); 00713 00714 if (option_debug) { 00715 ast_debug(2, "Listing matching entries:\n"); 00716 for (ptr = sorted, i = 0; i < count; i++, ptr++) { 00717 ast_log(LOG_DEBUG, "%s: %s\n", ptr[0]->exten, ptr[0]->name); 00718 } 00719 } 00720 00721 if (ast_test_flag(flags, OPT_SELECTFROMMENU)) { 00722 /* Offer multiple entries at the same time */ 00723 res = select_item_menu(chan, sorted, count, context, dialcontext, flags); 00724 } else { 00725 /* Offer entries one by one */ 00726 res = select_item_seq(chan, sorted, count, context, dialcontext, flags); 00727 } 00728 00729 if (!res) { 00730 res = ast_streamfile(chan, "dir-nomore", chan->language); 00731 } 00732 00733 exit: 00734 if (sorted) 00735 ast_free(sorted); 00736 00737 while ((item = AST_LIST_REMOVE_HEAD(&alist, entry))) 00738 ast_free(item); 00739 00740 return res; 00741 }
static int goto_exten | ( | struct ast_channel * | chan, | |
const char * | dialcontext, | |||
char * | ext | |||
) | [static] |
Definition at line 646 of file app_directory.c.
References ast_goto_if_exists(), ast_log(), ast_strlen_zero(), chan, LOG_WARNING, and ast_channel::macrocontext.
Referenced by do_directory().
00647 { 00648 if (!ast_goto_if_exists(chan, dialcontext, ext, 1) || 00649 (!ast_strlen_zero(chan->macrocontext) && 00650 !ast_goto_if_exists(chan, chan->macrocontext, ext, 1))) { 00651 return 0; 00652 } else { 00653 ast_log(LOG_WARNING, "Can't find extension '%s' in current context. " 00654 "Not Exiting the Directory!\n", ext); 00655 return -1; 00656 } 00657 }
static int load_module | ( | void | ) | [static] |
Definition at line 824 of file app_directory.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_register_application, ast_variable_retrieve(), directory_exec(), LOG_WARNING, and VOICEMAIL_CONFIG.
00825 { 00826 #ifdef ODBC_STORAGE 00827 struct ast_flags config_flags = { 0 }; 00828 struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 00829 const char *tmp; 00830 00831 if (cfg) { 00832 if ((tmp = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 00833 ast_copy_string(odbc_database, tmp, sizeof(odbc_database)); 00834 } 00835 if ((tmp = ast_variable_retrieve(cfg, "general", "odbctable"))) { 00836 ast_copy_string(odbc_table, tmp, sizeof(odbc_table)); 00837 } 00838 if ((tmp = ast_variable_retrieve(cfg, "general", "format"))) { 00839 ast_copy_string(vmfmts, tmp, sizeof(vmfmts)); 00840 } 00841 ast_config_destroy(cfg); 00842 } else 00843 ast_log(LOG_WARNING, "Unable to load " VOICEMAIL_CONFIG " - ODBC defaults will be used\n"); 00844 #endif 00845 00846 return ast_register_application(app, directory_exec, synopsis, descrip); 00847 }
static int play_mailbox_owner | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | ext, | |||
const char * | name, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 306 of file app_directory.c.
References ast_config_AST_SPOOL_DIR, AST_DIGIT_ANY, ast_filedelete(), ast_fileexists(), ast_say_character_str(), ast_stopstream(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, chan, ast_channel::language, OPT_SAYEXTENSION, and S_OR.
Referenced by select_item_menu(), and select_item_seq().
00308 { 00309 int res = 0; 00310 char fn[256]; 00311 00312 /* Check for the VoiceMail2 greeting first */ 00313 snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/greet", 00314 ast_config_AST_SPOOL_DIR, context, ext); 00315 #ifdef ODBC_STORAGE 00316 retrieve_file(fn); 00317 #endif 00318 00319 if (ast_fileexists(fn, NULL, chan->language) <= 0) { 00320 /* no file, check for an old-style Voicemail greeting */ 00321 snprintf(fn, sizeof(fn), "%s/vm/%s/greet", 00322 ast_config_AST_SPOOL_DIR, ext); 00323 } 00324 #ifdef ODBC_STORAGE 00325 retrieve_file(fn); 00326 #endif 00327 00328 if (ast_fileexists(fn, NULL, chan->language) > 0) { 00329 res = ast_stream_and_wait(chan, fn, AST_DIGIT_ANY); 00330 ast_stopstream(chan); 00331 /* If Option 'e' was specified, also read the extension number with the name */ 00332 if (ast_test_flag(flags, OPT_SAYEXTENSION)) { 00333 ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 00334 res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language); 00335 } 00336 } else { 00337 res = ast_say_character_str(chan, S_OR(name, ext), AST_DIGIT_ANY, chan->language); 00338 if (!ast_strlen_zero(name) && ast_test_flag(flags, OPT_SAYEXTENSION)) { 00339 ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 00340 res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language); 00341 } 00342 } 00343 #ifdef ODBC_STORAGE 00344 ast_filedelete(fn, NULL); 00345 #endif 00346 00347 return res; 00348 }
static struct ast_config* realtime_directory | ( | char * | context | ) | [static] |
Definition at line 463 of file app_directory.c.
References ast_category_append(), ast_category_browse(), ast_category_get(), ast_category_new(), ast_config_destroy(), ast_config_load, ast_load_realtime_multientry(), ast_log(), ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), LOG_WARNING, mailbox, var, and VOICEMAIL_CONFIG.
Referenced by directory_exec().
00464 { 00465 struct ast_config *cfg; 00466 struct ast_config *rtdata; 00467 struct ast_category *cat; 00468 struct ast_variable *var; 00469 char *mailbox; 00470 const char *fullname; 00471 const char *hidefromdir; 00472 char tmp[100]; 00473 struct ast_flags config_flags = { 0 }; 00474 00475 /* Load flat file config. */ 00476 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 00477 00478 if (!cfg) { 00479 /* Loading config failed. */ 00480 ast_log(LOG_WARNING, "Loading config failed.\n"); 00481 return NULL; 00482 } 00483 00484 /* Get realtime entries, categorized by their mailbox number 00485 and present in the requested context */ 00486 rtdata = ast_load_realtime_multientry("voicemail", "mailbox LIKE", "%", "context", context, NULL); 00487 00488 /* if there are no results, just return the entries from the config file */ 00489 if (!rtdata) 00490 return cfg; 00491 00492 /* Does the context exist within the config file? If not, make one */ 00493 cat = ast_category_get(cfg, context); 00494 if (!cat) { 00495 cat = ast_category_new(context, "", 99999); 00496 if (!cat) { 00497 ast_log(LOG_WARNING, "Out of memory\n"); 00498 ast_config_destroy(cfg); 00499 if (rtdata) { 00500 ast_config_destroy(rtdata); 00501 } 00502 return NULL; 00503 } 00504 ast_category_append(cfg, cat); 00505 } 00506 00507 mailbox = NULL; 00508 while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) { 00509 fullname = ast_variable_retrieve(rtdata, mailbox, "fullname"); 00510 hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir"); 00511 snprintf(tmp, sizeof(tmp), "no-password,%s,hidefromdir=%s", 00512 fullname ? fullname : "", 00513 hidefromdir ? hidefromdir : "no"); 00514 var = ast_variable_new(mailbox, tmp, ""); 00515 if (var) 00516 ast_variable_append(cat, var); 00517 else 00518 ast_log(LOG_WARNING, "Out of memory adding mailbox '%s'\n", mailbox); 00519 } 00520 ast_config_destroy(rtdata); 00521 00522 return cfg; 00523 }
static int search_directory | ( | const char * | context, | |
struct ast_config * | vmcfg, | |||
struct ast_config * | ucfg, | |||
const char * | ext, | |||
int | use_first_name, | |||
itemlist * | alist | |||
) | [static] |
Definition at line 566 of file app_directory.c.
References ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_MAX_EXTENSION, ast_true(), ast_variable_browse(), ast_variable_retrieve(), buf, check_match(), directory_item::entry, ast_variable::name, ast_variable::next, S_OR, strcasestr(), strsep(), and ast_variable::value.
Referenced by do_directory().
00567 { 00568 struct ast_variable *v; 00569 char buf[AST_MAX_EXTENSION + 1], *pos, *bufptr, *cat; 00570 struct directory_item *item; 00571 int res; 00572 00573 ast_debug(2, "Pattern: %s\n", ext); 00574 00575 for (v = ast_variable_browse(vmcfg, context); v; v = v->next) { 00576 00577 /* Ignore hidden */ 00578 if (strcasestr(v->value, "hidefromdir=yes")) 00579 continue; 00580 00581 ast_copy_string(buf, v->value, sizeof(buf)); 00582 bufptr = buf; 00583 00584 /* password,Full Name,email,pager,options */ 00585 strsep(&bufptr, ","); 00586 pos = strsep(&bufptr, ","); 00587 00588 res = check_match(&item, S_OR(pos, ""), v->name, ext, use_first_name); 00589 if (!res) 00590 continue; 00591 else if (res < 0) 00592 return -1; 00593 00594 AST_LIST_INSERT_TAIL(alist, item, entry); 00595 } 00596 00597 00598 if (ucfg) { 00599 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 00600 const char *pos; 00601 if (!strcasecmp(cat, "general")) 00602 continue; 00603 if (!ast_true(ast_config_option(ucfg, cat, "hasdirectory"))) 00604 continue; 00605 00606 /* Find all candidate extensions */ 00607 pos = ast_variable_retrieve(ucfg, cat, "fullname"); 00608 if (!pos) 00609 continue; 00610 00611 res = check_match(&item, pos, cat, ext, use_first_name); 00612 if (!res) 00613 continue; 00614 else if (res < 0) 00615 return -1; 00616 00617 AST_LIST_INSERT_TAIL(alist, item, entry); 00618 } 00619 } 00620 00621 return 0; 00622 }
static int select_entry | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | dialcontext, | |||
const struct directory_item * | item, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 350 of file app_directory.c.
References ast_copy_string(), ast_debug, ast_goto_if_exists(), ast_log(), ast_test_flag, chan, ast_channel::exten, directory_item::exten, LOG_WARNING, directory_item::name, and OPT_FROMVOICEMAIL.
Referenced by select_item_menu(), and select_item_seq().
00351 { 00352 ast_debug(1, "Selecting '%s' - %s@%s\n", item->name, item->exten, dialcontext); 00353 00354 if (ast_test_flag(flags, OPT_FROMVOICEMAIL)) { 00355 /* We still want to set the exten though */ 00356 ast_copy_string(chan->exten, item->exten, sizeof(chan->exten)); 00357 } else if (ast_goto_if_exists(chan, dialcontext, item->exten, 1)) { 00358 ast_log(LOG_WARNING, 00359 "Can't find extension '%s' in context '%s'. " 00360 "Did you pass the wrong context to Directory?\n", 00361 item->exten, dialcontext); 00362 return -1; 00363 } 00364 00365 return 0; 00366 }
static int select_item_menu | ( | struct ast_channel * | chan, | |
struct directory_item ** | items, | |||
int | count, | |||
const char * | context, | |||
const char * | dialcontext, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 403 of file app_directory.c.
References AST_DIGIT_ANY, ast_streamfile(), ast_waitfordigit(), ast_waitstream(), buf, chan, directory_item::exten, ast_channel::language, directory_item::name, play_mailbox_owner(), and select_entry().
Referenced by do_directory().
00404 { 00405 struct directory_item **block, *item; 00406 int i, limit, res = 0; 00407 char buf[9]; 00408 00409 for (block = items; count; block += limit, count -= limit) { 00410 limit = count; 00411 if (limit > 8) 00412 limit = 8; 00413 00414 for (i = 0; i < limit && !res; i++) { 00415 item = block[i]; 00416 00417 snprintf(buf, sizeof(buf), "digits/%d", i + 1); 00418 /* Press <num> for <name>, [ extension <ext> ] */ 00419 res = ast_streamfile(chan, "dir-multi1", chan->language); 00420 if (!res) 00421 res = ast_waitstream(chan, AST_DIGIT_ANY); 00422 if (!res) 00423 res = ast_streamfile(chan, buf, chan->language); 00424 if (!res) 00425 res = ast_waitstream(chan, AST_DIGIT_ANY); 00426 if (!res) 00427 res = ast_streamfile(chan, "dir-multi2", chan->language); 00428 if (!res) 00429 res = ast_waitstream(chan, AST_DIGIT_ANY); 00430 if (!res) 00431 res = play_mailbox_owner(chan, context, item->exten, item->name, flags); 00432 if (!res) 00433 res = ast_waitstream(chan, AST_DIGIT_ANY); 00434 if (!res) 00435 res = ast_waitfordigit(chan, 800); 00436 } 00437 00438 /* Press "9" for more names. */ 00439 if (!res && count > limit) { 00440 res = ast_streamfile(chan, "dir-multi9", chan->language); 00441 if (!res) 00442 res = ast_waitstream(chan, AST_DIGIT_ANY); 00443 } 00444 00445 if (!res) { 00446 res = ast_waitfordigit(chan, 3000); 00447 } 00448 00449 if (res && res > '0' && res < '1' + limit) { 00450 return select_entry(chan, context, dialcontext, block[res - '1'], flags) ? -1 : 1; 00451 } 00452 00453 if (res < 0) 00454 return -1; 00455 00456 res = 0; 00457 } 00458 00459 /* Nothing was selected */ 00460 return 0; 00461 }
static int select_item_seq | ( | struct ast_channel * | chan, | |
struct directory_item ** | items, | |||
int | count, | |||
const char * | context, | |||
const char * | dialcontext, | |||
struct ast_flags * | flags | |||
) | [static] |
Definition at line 368 of file app_directory.c.
References AST_DIGIT_ANY, ast_stopstream(), ast_stream_and_wait(), ast_waitfordigit(), chan, directory_item::exten, directory_item::name, play_mailbox_owner(), and select_entry().
Referenced by do_directory().
00369 { 00370 struct directory_item *item, **ptr; 00371 int i, res, loop; 00372 00373 for (ptr = items, i = 0; i < count; i++, ptr++) { 00374 item = *ptr; 00375 00376 for (loop = 3 ; loop > 0; loop--) { 00377 res = play_mailbox_owner(chan, context, item->exten, item->name, flags); 00378 00379 if (!res) 00380 res = ast_stream_and_wait(chan, "dir-instr", AST_DIGIT_ANY); 00381 if (!res) 00382 res = ast_waitfordigit(chan, 3000); 00383 ast_stopstream(chan); 00384 00385 if (res == '1') { /* Name selected */ 00386 return select_entry(chan, context, dialcontext, item, flags) ? -1 : 1; 00387 } else if (res == '*') { 00388 /* Skip to next match in list */ 00389 break; 00390 } 00391 00392 if (res < 0) 00393 return -1; 00394 00395 res = 0; 00396 } 00397 } 00398 00399 /* Nothing was selected */ 00400 return 0; 00401 }
static void sort_items | ( | struct directory_item ** | sorted, | |
int | count | |||
) | [static] |
Definition at line 624 of file app_directory.c.
References directory_item::key.
Referenced by do_directory().
00625 { 00626 int reordered, i; 00627 struct directory_item **ptr, *tmp; 00628 00629 if (count < 2) 00630 return; 00631 00632 /* Bubble-sort items by the key */ 00633 do { 00634 reordered = 0; 00635 for (ptr = sorted, i = 0; i < count - 1; i++, ptr++) { 00636 if (strcasecmp(ptr[0]->key, ptr[1]->key) > 0) { 00637 tmp = ptr[0]; 00638 ptr[0] = ptr[1]; 00639 ptr[1] = tmp; 00640 reordered++; 00641 } 00642 } 00643 } while (reordered); 00644 }
static int unload_module | ( | void | ) | [static] |
Definition at line 817 of file app_directory.c.
References ast_unregister_application().
00818 { 00819 int res; 00820 res = ast_unregister_application(app); 00821 return res; 00822 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Directory" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 849 of file app_directory.c.
char* app = "Directory" [static] |
Definition at line 50 of file app_directory.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 849 of file app_directory.c.
char* descrip [static] |
Definition at line 53 of file app_directory.c.
struct ast_app_option directory_app_options[128] = { [ 'f' ] = { .flag = OPT_LISTBYFIRSTNAME }, [ 'e' ] = { .flag = OPT_SAYEXTENSION }, [ 'v' ] = { .flag = OPT_FROMVOICEMAIL }, [ 'm' ] = { .flag = OPT_SELECTFROMMENU },} [static] |
enum { ... } directory_option_flags |
char* synopsis = "Provide directory of voicemail extensions" [static] |
Definition at line 52 of file app_directory.c.