Wed Jan 8 2020 09:49:53

Asterisk developer's documentation


app_directory.c File Reference

Provide a directory of extensions. More...

#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"
#include "asterisk/utils.h"

Go to the source code of this file.

Data Structures

struct  directory_item
 
struct  itemlist
 

Macros

#define VOICEMAIL_CONFIG   "voicemail.conf"
 

Enumerations

enum  {
  OPT_LISTBYFIRSTNAME = (1 << 0), OPT_SAYEXTENSION = (1 << 1), OPT_FROMVOICEMAIL = (1 << 2), OPT_SELECTFROMMENU = (1 << 3),
  OPT_LISTBYLASTNAME = (1 << 4), OPT_LISTBYEITHER = OPT_LISTBYFIRSTNAME | OPT_LISTBYLASTNAME, OPT_PAUSE = (1 << 5), OPT_NOANSWER = (1 << 6)
}
 
enum  {
  OPT_ARG_FIRSTNAME = 0, OPT_ARG_LASTNAME = 1, OPT_ARG_EITHER = 2, OPT_ARG_PAUSE = 3,
  OPT_ARG_ARRAY_SIZE = 4
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int check_match (struct directory_item **result, const char *item_context, 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, const char *data)
 
static int do_directory (struct ast_channel *chan, struct ast_config *vmcfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, int digits, struct ast_flags *flags, char *opts[])
 
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_configrealtime_directory (char *context)
 
static int search_directory (const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
 
static int search_directory_sub (const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
 
static int select_entry (struct ast_channel *chan, 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 *dialcontext, struct ast_flags *flags, char *opts[])
 
static int select_item_pause (struct ast_channel *chan, struct ast_flags *flags, char *opts[])
 
static int select_item_seq (struct ast_channel *chan, struct directory_item **items, int count, const char *dialcontext, struct ast_flags *flags, char *opts[])
 
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_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static const char app [] = "Directory"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_app_option directory_app_options [128] = { [ 'f' ] = { .flag = OPT_LISTBYFIRSTNAME , .arg_index = OPT_ARG_FIRSTNAME + 1 }, [ 'l' ] = { .flag = OPT_LISTBYLASTNAME , .arg_index = OPT_ARG_LASTNAME + 1 }, [ 'b' ] = { .flag = OPT_LISTBYEITHER , .arg_index = OPT_ARG_EITHER + 1 }, [ 'p' ] = { .flag = OPT_PAUSE , .arg_index = OPT_ARG_PAUSE + 1 }, [ 'e' ] = { .flag = OPT_SAYEXTENSION }, [ 'v' ] = { .flag = OPT_FROMVOICEMAIL }, [ 'm' ] = { .flag = OPT_SELECTFROMMENU }, [ 'n' ] = { .flag = OPT_NOANSWER }, }
 

Detailed Description

Provide a directory of extensions.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file app_directory.c.

Macro Definition Documentation

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 127 of file app_directory.c.

Referenced by realtime_directory().

Enumeration Type Documentation

anonymous enum
Enumerator
OPT_LISTBYFIRSTNAME 
OPT_SAYEXTENSION 
OPT_FROMVOICEMAIL 
OPT_SELECTFROMMENU 
OPT_LISTBYLASTNAME 
OPT_LISTBYEITHER 
OPT_PAUSE 
OPT_NOANSWER 

Definition at line 129 of file app_directory.c.

anonymous enum
Enumerator
OPT_ARG_FIRSTNAME 
OPT_ARG_LASTNAME 
OPT_ARG_EITHER 
OPT_ARG_PAUSE 
OPT_ARG_ARRAY_SIZE 

Definition at line 140 of file app_directory.c.

140  {
141  OPT_ARG_FIRSTNAME = 0,
142  OPT_ARG_LASTNAME = 1,
143  OPT_ARG_EITHER = 2,
144  OPT_ARG_PAUSE = 3,
145  /* This *must* be the last value in this enum! */
146  OPT_ARG_ARRAY_SIZE = 4,
147 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 893 of file app_directory.c.

static void __unreg_module ( void  )
static

Definition at line 893 of file app_directory.c.

static int check_match ( struct directory_item **  result,
const char *  item_context,
const char *  item_fullname,
const char *  item_ext,
const char *  pattern_ext,
int  use_first_name 
)
static

Definition at line 509 of file app_directory.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_strlen_zero(), compare(), directory_item::context, directory_item::exten, directory_item::key, and directory_item::name.

Referenced by search_directory_sub().

510 {
511  struct directory_item *item;
512  const char *key = NULL;
513  int namelen;
514 
515  if (ast_strlen_zero(item_fullname)) {
516  return 0;
517  }
518 
519  /* Set key to last name or first name depending on search mode */
520  if (!use_first_name)
521  key = strchr(item_fullname, ' ');
522 
523  if (key)
524  key++;
525  else
526  key = item_fullname;
527 
528  if (compare(key, pattern_ext))
529  return 0;
530 
531  ast_debug(1, "Found match %s@%s\n", item_ext, item_context);
532 
533  /* Match */
534  item = ast_calloc(1, sizeof(*item));
535  if (!item)
536  return -1;
537  ast_copy_string(item->context, item_context, sizeof(item->context));
538  ast_copy_string(item->name, item_fullname, sizeof(item->name));
539  ast_copy_string(item->exten, item_ext, sizeof(item->exten));
540 
541  ast_copy_string(item->key, key, sizeof(item->key));
542  if (key != item_fullname) {
543  /* Key is the last name. Append first name to key in order to sort Last,First */
544  namelen = key - item_fullname - 1;
545  if (namelen > sizeof(item->key) - strlen(item->key) - 1)
546  namelen = sizeof(item->key) - strlen(item->key) - 1;
547  strncat(item->key, item_fullname, namelen);
548  }
549 
550  *result = item;
551  return 1;
552 }
char context[AST_MAX_CONTEXT+1]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[AST_MAX_EXTENSION+1]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char exten[AST_MAX_EXTENSION+1]
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int compare(const char *text, const char *template)
static int compare ( const char *  text,
const char *  template 
)
static

Definition at line 169 of file app_directory.c.

References ast_strlen_zero().

Referenced by ast_hashtab_create(), and check_match().

170 {
171  char digit;
172 
173  if (ast_strlen_zero(text)) {
174  return -1;
175  }
176 
177  while (*template) {
178  digit = toupper(*text++);
179  switch (digit) {
180  case 0:
181  return -1;
182  case '1':
183  digit = '1';
184  break;
185  case '2':
186  case 'A':
187  case 'B':
188  case 'C':
189  digit = '2';
190  break;
191  case '3':
192  case 'D':
193  case 'E':
194  case 'F':
195  digit = '3';
196  break;
197  case '4':
198  case 'G':
199  case 'H':
200  case 'I':
201  digit = '4';
202  break;
203  case '5':
204  case 'J':
205  case 'K':
206  case 'L':
207  digit = '5';
208  break;
209  case '6':
210  case 'M':
211  case 'N':
212  case 'O':
213  digit = '6';
214  break;
215  case '7':
216  case 'P':
217  case 'Q':
218  case 'R':
219  case 'S':
220  digit = '7';
221  break;
222  case '8':
223  case 'T':
224  case 'U':
225  case 'V':
226  digit = '8';
227  break;
228  case '9':
229  case 'W':
230  case 'X':
231  case 'Y':
232  case 'Z':
233  digit = '9';
234  break;
235 
236  default:
237  if (digit > ' ')
238  return -1;
239  continue;
240  }
241 
242  if (*template++ != digit)
243  return -1;
244  }
245 
246  return 0;
247 }
char * text
Definition: app_queue.c:1091
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int directory_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 759 of file app_directory.c.

References ast_channel::_state, args, 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_set_flag, 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(), CONFIG_STATUS_FILEINVALID, dialcontext, directory_app_options, do_directory(), LOG_ERROR, OPT_ARG_ARRAY_SIZE, OPT_ARG_EITHER, OPT_ARG_FIRSTNAME, OPT_ARG_LASTNAME, OPT_LISTBYFIRSTNAME, OPT_LISTBYLASTNAME, OPT_NOANSWER, parse(), and realtime_directory().

Referenced by load_module().

760 {
761  int res = 0, digit = 3;
762  struct ast_config *cfg, *ucfg;
763  const char *dirintro;
764  char *parse, *opts[OPT_ARG_ARRAY_SIZE] = { 0, };
765  struct ast_flags flags = { 0 };
766  struct ast_flags config_flags = { 0 };
767  enum { FIRST, LAST, BOTH } which = LAST;
768  char digits[9] = "digits/3";
770  AST_APP_ARG(vmcontext);
772  AST_APP_ARG(options);
773  );
774 
775  parse = ast_strdupa(data);
776 
777  AST_STANDARD_APP_ARGS(args, parse);
778 
779  if (args.options && ast_app_parse_options(directory_app_options, &flags, opts, args.options))
780  return -1;
781 
782  if (!(cfg = realtime_directory(args.vmcontext))) {
783  ast_log(LOG_ERROR, "Unable to read the configuration data!\n");
784  return -1;
785  }
786 
787  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
788  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
789  ucfg = NULL;
790  }
791 
792  dirintro = ast_variable_retrieve(cfg, args.vmcontext, "directoryintro");
793  if (ast_strlen_zero(dirintro))
794  dirintro = ast_variable_retrieve(cfg, "general", "directoryintro");
795  /* the above prompts probably should be modified to include 0 for dialing operator
796  and # for exiting (continues in dialplan) */
797 
799  if (!ast_strlen_zero(opts[OPT_ARG_EITHER])) {
800  digit = atoi(opts[OPT_ARG_EITHER]);
801  }
802  which = BOTH;
803  } else if (ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
804  if (!ast_strlen_zero(opts[OPT_ARG_FIRSTNAME])) {
805  digit = atoi(opts[OPT_ARG_FIRSTNAME]);
806  }
807  which = FIRST;
808  } else {
809  if (!ast_strlen_zero(opts[OPT_ARG_LASTNAME])) {
810  digit = atoi(opts[OPT_ARG_LASTNAME]);
811  }
812  which = LAST;
813  }
814 
815  /* If no options specified, search by last name */
818  which = LAST;
819  }
820 
821  if (digit > 9) {
822  digit = 9;
823  } else if (digit < 1) {
824  digit = 3;
825  }
826  digits[7] = digit + '0';
827 
828  if (chan->_state != AST_STATE_UP) {
829  if (!ast_test_flag(&flags, OPT_NOANSWER)) {
830  /* Otherwise answer unless we're supposed to read while on-hook */
831  res = ast_answer(chan);
832  }
833  }
834  for (;;) {
835  if (!ast_strlen_zero(dirintro) && !res) {
836  res = ast_stream_and_wait(chan, dirintro, AST_DIGIT_ANY);
837  } else if (!res) {
838  /* Stop playing sounds as soon as we have a digit. */
839  res = ast_stream_and_wait(chan, "dir-welcome", AST_DIGIT_ANY);
840  if (!res) {
841  res = ast_stream_and_wait(chan, "dir-pls-enter", AST_DIGIT_ANY);
842  }
843  if (!res) {
844  res = ast_stream_and_wait(chan, digits, AST_DIGIT_ANY);
845  }
846  if (!res) {
847  res = ast_stream_and_wait(chan,
848  which == FIRST ? "dir-first" :
849  which == LAST ? "dir-last" :
850  "dir-firstlast", AST_DIGIT_ANY);
851  }
852  if (!res) {
853  res = ast_stream_and_wait(chan, "dir-usingkeypad", AST_DIGIT_ANY);
854  }
855  }
856  ast_stopstream(chan);
857  if (!res)
858  res = ast_waitfordigit(chan, 5000);
859 
860  if (res <= 0)
861  break;
862 
863  res = do_directory(chan, cfg, ucfg, args.vmcontext, args.dialcontext, res, digit, &flags, opts);
864  if (res)
865  break;
866 
867  res = ast_waitstream(chan, AST_DIGIT_ANY);
868  ast_stopstream(chan);
869 
870  if (res)
871  break;
872  }
873 
874  if (ucfg)
875  ast_config_destroy(ucfg);
876  ast_config_destroy(cfg);
877 
878  return res < 0 ? -1 : 0;
879 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
unsigned int flags
Definition: utils.h:201
static struct ast_app_option directory_app_options[128]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static struct ast_config * realtime_directory(char *context)
static char dialcontext[AST_MAX_CONTEXT]
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
Structure used to handle boolean flags.
Definition: utils.h:200
static int do_directory(struct ast_channel *chan, struct ast_config *vmcfg, struct ast_config *ucfg, char *context, char *dialcontext, char digit, int digits, struct ast_flags *flags, char *opts[])
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static int do_directory ( struct ast_channel chan,
struct ast_config vmcfg,
struct ast_config ucfg,
char *  context,
char *  dialcontext,
char  digit,
int  digits,
struct ast_flags flags,
char *  opts[] 
)
static

Definition at line 682 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_readstring(), ast_streamfile(), ast_test_flag, directory_item::entry, ext, directory_item::exten, goto_exten(), ast_channel::language, directory_item::name, OPT_SELECTFROMMENU, option_debug, search_directory(), select_item_menu(), select_item_seq(), and sort_items().

Referenced by directory_exec().

683 {
684  /* Read in the first three digits.. "digit" is the first digit, already read */
685  int res = 0;
687  struct directory_item *item, **ptr, **sorted = NULL;
688  int count, i;
689  char ext[10] = "";
690 
691  if (digit == '0' && !goto_exten(chan, dialcontext, "o")) {
692  return digit;
693  }
694 
695  if (digit == '*' && !goto_exten(chan, dialcontext, "a")) {
696  return digit;
697  }
698 
699  ext[0] = digit;
700  if (ast_readstring(chan, ext + 1, digits - 1, 3000, 3000, "#") < 0)
701  return -1;
702 
703  res = search_directory(context, vmcfg, ucfg, ext, *flags, &alist);
704  if (res)
705  goto exit;
706 
707  /* Count items in the list */
708  count = 0;
709  AST_LIST_TRAVERSE(&alist, item, entry) {
710  count++;
711  }
712 
713  if (count < 1) {
714  res = ast_streamfile(chan, "dir-nomatch", chan->language);
715  goto exit;
716  }
717 
718 
719  /* Create plain array of pointers to items (for sorting) */
720  sorted = ast_calloc(count, sizeof(*sorted));
721 
722  ptr = sorted;
723  AST_LIST_TRAVERSE(&alist, item, entry) {
724  *ptr++ = item;
725  }
726 
727  /* Sort items */
728  sort_items(sorted, count);
729 
730  if (option_debug) {
731  ast_debug(2, "Listing matching entries:\n");
732  for (ptr = sorted, i = 0; i < count; i++, ptr++) {
733  ast_debug(2, "%s: %s\n", ptr[0]->exten, ptr[0]->name);
734  }
735  }
736 
737  if (ast_test_flag(flags, OPT_SELECTFROMMENU)) {
738  /* Offer multiple entries at the same time */
739  res = select_item_menu(chan, sorted, count, dialcontext, flags, opts);
740  } else {
741  /* Offer entries one by one */
742  res = select_item_seq(chan, sorted, count, dialcontext, flags, opts);
743  }
744 
745  if (!res) {
746  res = ast_streamfile(chan, "dir-nomore", chan->language);
747  }
748 
749 exit:
750  if (sorted)
751  ast_free(sorted);
752 
753  while ((item = AST_LIST_REMOVE_HEAD(&alist, entry)))
754  ast_free(item);
755 
756  return res;
757 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define ast_test_flag(p, flag)
Definition: utils.h:63
int option_debug
Definition: asterisk.c:182
struct directory_item::@13 entry
static int goto_exten(struct ast_channel *chan, const char *dialcontext, char *ext)
static int select_item_seq(struct ast_channel *chan, struct directory_item **items, int count, const char *dialcontext, struct ast_flags *flags, char *opts[])
const char * ext
Definition: http.c:112
static void sort_items(struct directory_item **sorted, int count)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static char dialcontext[AST_MAX_CONTEXT]
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static int search_directory(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
static int select_item_menu(struct ast_channel *chan, struct directory_item **items, int count, const char *dialcontext, struct ast_flags *flags, char *opts[])
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
#define ast_calloc(a, b)
Definition: astmm.h:82
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
const ast_string_field language
Definition: channel.h:787
static int goto_exten ( struct ast_channel chan,
const char *  dialcontext,
char *  ext 
)
static

Definition at line 249 of file app_directory.c.

References ast_goto_if_exists(), ast_log(), ast_strlen_zero(), ast_channel::context, LOG_WARNING, ast_channel::macrocontext, and S_OR.

Referenced by do_directory(), and select_item_seq().

250 {
251  if (!ast_goto_if_exists(chan, S_OR(dialcontext, chan->context), ext, 1) ||
252  (!ast_strlen_zero(chan->macrocontext) &&
253  !ast_goto_if_exists(chan, chan->macrocontext, ext, 1))) {
254  return 0;
255  } else {
256  ast_log(LOG_WARNING, "Can't find extension '%s' in current context. "
257  "Not Exiting the Directory!\n", ext);
258  return -1;
259  }
260 }
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
const char * ext
Definition: http.c:112
static char dialcontext[AST_MAX_CONTEXT]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int load_module ( void  )
static

Definition at line 888 of file app_directory.c.

References ast_register_application_xml, and directory_exec().

889 {
891 }
static const char app[]
static int directory_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
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 267 of file app_directory.c.

References ast_app_sayname(), AST_DIGIT_ANY, ast_say_character_str(), ast_stopstream(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_channel::language, OPT_SAYEXTENSION, and S_OR.

Referenced by select_item_menu(), and select_item_seq().

269 {
270  int res = 0;
271  if ((res = ast_app_sayname(chan, ext, context)) >= 0) {
272  ast_stopstream(chan);
273  /* If Option 'e' was specified, also read the extension number with the name */
274  if (ast_test_flag(flags, OPT_SAYEXTENSION)) {
275  ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
276  res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language);
277  }
278  } else {
279  res = ast_say_character_str(chan, S_OR(name, ext), AST_DIGIT_ANY, chan->language);
281  ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
282  res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, chan->language);
283  }
284  }
285 
286  return res;
287 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * ext
Definition: http.c:112
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_app_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
Given a mailbox and context, play that mailbox owner&#39;s name to the channel specified.
Definition: app.c:478
static const char name[]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8421
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static struct ast_config* realtime_directory ( char *  context)
static

Definition at line 430 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_strlen_zero(), ast_true(), ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, LOG_ERROR, LOG_WARNING, mailbox, S_OR, SENTINEL, var, and VOICEMAIL_CONFIG.

Referenced by directory_exec().

431 {
432  struct ast_config *cfg;
433  struct ast_config *rtdata;
434  struct ast_category *cat;
435  struct ast_variable *var;
436  char *mailbox;
437  const char *fullname;
438  const char *hidefromdir, *searchcontexts = NULL;
439  char tmp[100];
440  struct ast_flags config_flags = { 0 };
441 
442  /* Load flat file config. */
443  cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
444 
445  if (!cfg) {
446  /* Loading config failed. */
447  ast_log(LOG_WARNING, "Loading config failed.\n");
448  return NULL;
449  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
450  ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", VOICEMAIL_CONFIG);
451  return NULL;
452  }
453 
454  /* Get realtime entries, categorized by their mailbox number
455  and present in the requested context */
456  if (ast_strlen_zero(context) && (searchcontexts = ast_variable_retrieve(cfg, "general", "searchcontexts"))) {
457  if (ast_true(searchcontexts)) {
458  rtdata = ast_load_realtime_multientry("voicemail", "mailbox LIKE", "%", SENTINEL);
459  context = NULL;
460  } else {
461  rtdata = ast_load_realtime_multientry("voicemail", "mailbox LIKE", "%", "context", "default", SENTINEL);
462  context = "default";
463  }
464  } else {
465  rtdata = ast_load_realtime_multientry("voicemail", "mailbox LIKE", "%", "context", context, SENTINEL);
466  }
467 
468  /* if there are no results, just return the entries from the config file */
469  if (!rtdata) {
470  return cfg;
471  }
472 
473  mailbox = NULL;
474  while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) {
475  const char *context = ast_variable_retrieve(rtdata, mailbox, "context");
476 
477  fullname = ast_variable_retrieve(rtdata, mailbox, "fullname");
478  hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir");
479  if (ast_true(hidefromdir)) {
480  /* Skip hidden */
481  continue;
482  }
483  snprintf(tmp, sizeof(tmp), "no-password,%s", S_OR(fullname, ""));
484 
485  /* Does the context exist within the config file? If not, make one */
486  if (!(cat = ast_category_get(cfg, context))) {
487  if (!(cat = ast_category_new(context, "", 99999))) {
488  ast_log(LOG_WARNING, "Out of memory\n");
489  ast_config_destroy(cfg);
490  if (rtdata) {
491  ast_config_destroy(rtdata);
492  }
493  return NULL;
494  }
495  ast_category_append(cfg, cat);
496  }
497 
498  if ((var = ast_variable_new(mailbox, tmp, ""))) {
499  ast_variable_append(cat, var);
500  } else {
501  ast_log(LOG_WARNING, "Out of memory adding mailbox '%s'\n", mailbox);
502  }
503  }
504  ast_config_destroy(rtdata);
505 
506  return cfg;
507 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
Retrieve a category if it exists.
Definition: config.c:709
#define SENTINEL
Definition: compiler.h:75
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
#define VOICEMAIL_CONFIG
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2650
static int search_directory ( const char *  context,
struct ast_config vmcfg,
struct ast_config ucfg,
const char *  ext,
struct ast_flags  flags,
itemlist alist 
)
static

Definition at line 631 of file app_directory.c.

References ast_category_browse(), ast_debug, ast_strlen_zero(), ast_true(), ast_variable_retrieve(), and search_directory_sub().

Referenced by do_directory().

632 {
633  const char *searchcontexts = ast_variable_retrieve(vmcfg, "general", "searchcontexts");
634  if (ast_strlen_zero(context)) {
635  if (!ast_strlen_zero(searchcontexts) && ast_true(searchcontexts)) {
636  /* Browse each context for a match */
637  int res;
638  const char *catg;
639  for (catg = ast_category_browse(vmcfg, NULL); catg; catg = ast_category_browse(vmcfg, catg)) {
640  if (!strcmp(catg, "general") || !strcmp(catg, "zonemessages")) {
641  continue;
642  }
643 
644  if ((res = search_directory_sub(catg, vmcfg, ucfg, ext, flags, alist))) {
645  return res;
646  }
647  }
648  return 0;
649  } else {
650  ast_debug(1, "Searching by category default\n");
651  return search_directory_sub("default", vmcfg, ucfg, ext, flags, alist);
652  }
653  } else {
654  /* Browse only the listed context for a match */
655  ast_debug(1, "Searching by category %s\n", context);
656  return search_directory_sub(context, vmcfg, ucfg, ext, flags, alist);
657  }
658 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
const char * ext
Definition: http.c:112
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int search_directory_sub(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int search_directory_sub ( const char *  context,
struct ast_config vmcfg,
struct ast_config ucfg,
const char *  ext,
struct ast_flags  flags,
itemlist alist 
)
static

Definition at line 556 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_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), check_match(), directory_item::entry, ast_variable::name, ast_variable::next, OPT_LISTBYFIRSTNAME, OPT_LISTBYLASTNAME, strcasestr(), strsep(), and ast_variable::value.

Referenced by search_directory().

557 {
558  struct ast_variable *v;
559  char buf[AST_MAX_EXTENSION + 1], *pos, *bufptr, *cat;
560  struct directory_item *item;
561  int res;
562 
563  ast_debug(2, "Pattern: %s\n", ext);
564 
565  for (v = ast_variable_browse(vmcfg, context); v; v = v->next) {
566 
567  /* Ignore hidden */
568  if (strcasestr(v->value, "hidefromdir=yes"))
569  continue;
570 
571  ast_copy_string(buf, v->value, sizeof(buf));
572  bufptr = buf;
573 
574  /* password,Full Name,email,pager,options */
575  strsep(&bufptr, ",");
576  pos = strsep(&bufptr, ",");
577 
578  /* No name to compare against */
579  if (ast_strlen_zero(pos)) {
580  continue;
581  }
582 
583  res = 0;
584  if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) {
585  res = check_match(&item, context, pos, v->name, ext, 0 /* use_first_name */);
586  }
587  if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
588  res = check_match(&item, context, pos, v->name, ext, 1 /* use_first_name */);
589  }
590 
591  if (!res)
592  continue;
593  else if (res < 0)
594  return -1;
595 
596  AST_LIST_INSERT_TAIL(alist, item, entry);
597  }
598 
599  if (ucfg) {
600  for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
601  const char *position;
602  if (!strcasecmp(cat, "general"))
603  continue;
604  if (!ast_true(ast_config_option(ucfg, cat, "hasdirectory")))
605  continue;
606 
607  /* Find all candidate extensions */
608  position = ast_variable_retrieve(ucfg, cat, "fullname");
609  if (!position)
610  continue;
611 
612  res = 0;
613  if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) {
614  res = check_match(&item, context, position, cat, ext, 0 /* use_first_name */);
615  }
616  if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
617  res = check_match(&item, context, position, cat, ext, 1 /* use_first_name */);
618  }
619 
620  if (!res)
621  continue;
622  else if (res < 0)
623  return -1;
624 
625  AST_LIST_INSERT_TAIL(alist, item, entry);
626  }
627  }
628  return 0;
629 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
char * strsep(char **str, const char *delims)
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
struct directory_item::@13 entry
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
Definition: config.c:614
const char * ext
Definition: http.c:112
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
static int check_match(struct directory_item **result, const char *item_context, const char *item_fullname, const char *item_ext, const char *pattern_ext, int use_first_name)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char * strcasestr(const char *, const char *)
static int select_entry ( struct ast_channel chan,
const char *  dialcontext,
const struct directory_item item,
struct ast_flags flags 
)
static

Definition at line 289 of file app_directory.c.

References ast_copy_string(), ast_debug, ast_goto_if_exists(), ast_log(), ast_test_flag, directory_item::context, directory_item::exten, ast_channel::exten, LOG_WARNING, directory_item::name, OPT_FROMVOICEMAIL, and S_OR.

Referenced by select_item_menu(), and select_item_seq().

290 {
291  ast_debug(1, "Selecting '%s' - %s@%s\n", item->name, item->exten, S_OR(dialcontext, item->context));
292 
293  if (ast_test_flag(flags, OPT_FROMVOICEMAIL)) {
294  /* We still want to set the exten though */
295  ast_copy_string(chan->exten, item->exten, sizeof(chan->exten));
296  } else if (ast_goto_if_exists(chan, S_OR(dialcontext, item->context), item->exten, 1)) {
298  "Can't find extension '%s' in context '%s'. "
299  "Did you pass the wrong context to Directory?\n",
300  item->exten, S_OR(dialcontext, item->context));
301  return -1;
302  }
303 
304  return 0;
305 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
char context[AST_MAX_CONTEXT+1]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char name[AST_MAX_EXTENSION+1]
static char dialcontext[AST_MAX_CONTEXT]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
char exten[AST_MAX_EXTENSION+1]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int select_item_menu ( struct ast_channel chan,
struct directory_item **  items,
int  count,
const char *  dialcontext,
struct ast_flags flags,
char *  opts[] 
)
static

Definition at line 367 of file app_directory.c.

References AST_DIGIT_ANY, ast_streamfile(), ast_waitfordigit(), ast_waitstream(), directory_item::context, directory_item::exten, ast_channel::language, directory_item::name, play_mailbox_owner(), select_entry(), and select_item_pause().

Referenced by do_directory().

368 {
369  struct directory_item **block, *item;
370  int i, limit, res = 0;
371  char buf[9];
372 
373  /* option p(n): cellphone pause option */
374  select_item_pause(chan, flags, opts);
375 
376  for (block = items; count; block += limit, count -= limit) {
377  limit = count;
378  if (limit > 8)
379  limit = 8;
380 
381  for (i = 0; i < limit && !res; i++) {
382  item = block[i];
383 
384  snprintf(buf, sizeof(buf), "digits/%d", i + 1);
385  /* Press <num> for <name>, [ extension <ext> ] */
386  res = ast_streamfile(chan, "dir-multi1", chan->language);
387  if (!res)
388  res = ast_waitstream(chan, AST_DIGIT_ANY);
389  if (!res)
390  res = ast_streamfile(chan, buf, chan->language);
391  if (!res)
392  res = ast_waitstream(chan, AST_DIGIT_ANY);
393  if (!res)
394  res = ast_streamfile(chan, "dir-multi2", chan->language);
395  if (!res)
396  res = ast_waitstream(chan, AST_DIGIT_ANY);
397  if (!res)
398  res = play_mailbox_owner(chan, item->context, item->exten, item->name, flags);
399  if (!res)
400  res = ast_waitstream(chan, AST_DIGIT_ANY);
401  if (!res)
402  res = ast_waitfordigit(chan, 800);
403  }
404 
405  /* Press "9" for more names. */
406  if (!res && count > limit) {
407  res = ast_streamfile(chan, "dir-multi9", chan->language);
408  if (!res)
409  res = ast_waitstream(chan, AST_DIGIT_ANY);
410  }
411 
412  if (!res) {
413  res = ast_waitfordigit(chan, 3000);
414  }
415 
416  if (res && res > '0' && res < '1' + limit) {
417  return select_entry(chan, dialcontext, block[res - '1'], flags) ? -1 : 1;
418  }
419 
420  if (res < 0)
421  return -1;
422 
423  res = 0;
424  }
425 
426  /* Nothing was selected */
427  return 0;
428 }
static int select_entry(struct ast_channel *chan, const char *dialcontext, const struct directory_item *item, struct ast_flags *flags)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define AST_DIGIT_ANY
Definition: file.h:47
char context[AST_MAX_CONTEXT+1]
static int select_item_pause(struct ast_channel *chan, struct ast_flags *flags, char *opts[])
char name[AST_MAX_EXTENSION+1]
static char dialcontext[AST_MAX_CONTEXT]
char exten[AST_MAX_EXTENSION+1]
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
static int play_mailbox_owner(struct ast_channel *chan, const char *context, const char *ext, const char *name, struct ast_flags *flags)
const ast_string_field language
Definition: channel.h:787
static int select_item_pause ( struct ast_channel chan,
struct ast_flags flags,
char *  opts[] 
)
static

Definition at line 307 of file app_directory.c.

References ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), OPT_ARG_PAUSE, and OPT_PAUSE.

Referenced by select_item_menu(), and select_item_seq().

308 {
309  int res = 0, opt_pause = 0;
310 
311  if (ast_test_flag(flags, OPT_PAUSE) && !ast_strlen_zero(opts[OPT_ARG_PAUSE])) {
312  opt_pause = atoi(opts[OPT_ARG_PAUSE]);
313  if (opt_pause > 3000) {
314  opt_pause = 3000;
315  }
316  res = ast_waitfordigit(chan, opt_pause);
317  }
318  return res;
319 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static int select_item_seq ( struct ast_channel chan,
struct directory_item **  items,
int  count,
const char *  dialcontext,
struct ast_flags flags,
char *  opts[] 
)
static

Definition at line 321 of file app_directory.c.

References AST_DIGIT_ANY, ast_stopstream(), ast_stream_and_wait(), ast_waitfordigit(), directory_item::context, directory_item::exten, goto_exten(), directory_item::name, play_mailbox_owner(), select_entry(), and select_item_pause().

Referenced by do_directory().

322 {
323  struct directory_item *item, **ptr;
324  int i, res, loop;
325 
326  /* option p(n): cellphone pause option */
327  /* allow early press of selection key */
328  res = select_item_pause(chan, flags, opts);
329 
330  for (ptr = items, i = 0; i < count; i++, ptr++) {
331  item = *ptr;
332 
333  for (loop = 3 ; loop > 0; loop--) {
334  if (!res)
335  res = play_mailbox_owner(chan, item->context, item->exten, item->name, flags);
336  if (!res)
337  res = ast_stream_and_wait(chan, "dir-instr", AST_DIGIT_ANY);
338  if (!res)
339  res = ast_waitfordigit(chan, 3000);
340  ast_stopstream(chan);
341 
342  if (res == '0') { /* operator selected */
343  goto_exten(chan, dialcontext, "o");
344  return '0';
345  } else if (res == '1') { /* Name selected */
346  return select_entry(chan, dialcontext, item, flags) ? -1 : 1;
347  } else if (res == '*') {
348  /* Skip to next match in list */
349  break;
350  } else if (res == '#') {
351  /* Exit reading, continue in dialplan */
352  return res;
353  }
354 
355  if (res < 0)
356  return -1;
357 
358  res = 0;
359  }
360  res = 0;
361  }
362 
363  /* Nothing was selected */
364  return 0;
365 }
static int select_entry(struct ast_channel *chan, const char *dialcontext, const struct directory_item *item, struct ast_flags *flags)
#define AST_DIGIT_ANY
Definition: file.h:47
static int goto_exten(struct ast_channel *chan, const char *dialcontext, char *ext)
char context[AST_MAX_CONTEXT+1]
static int select_item_pause(struct ast_channel *chan, struct ast_flags *flags, char *opts[])
char name[AST_MAX_EXTENSION+1]
static char dialcontext[AST_MAX_CONTEXT]
char exten[AST_MAX_EXTENSION+1]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static int play_mailbox_owner(struct ast_channel *chan, const char *context, const char *ext, const char *name, struct ast_flags *flags)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static void sort_items ( struct directory_item **  sorted,
int  count 
)
static

Definition at line 660 of file app_directory.c.

References directory_item::key.

Referenced by do_directory().

661 {
662  int reordered, i;
663  struct directory_item **ptr, *tmp;
664 
665  if (count < 2)
666  return;
667 
668  /* Bubble-sort items by the key */
669  do {
670  reordered = 0;
671  for (ptr = sorted, i = 0; i < count - 1; i++, ptr++) {
672  if (strcasecmp(ptr[0]->key, ptr[1]->key) > 0) {
673  tmp = ptr[0];
674  ptr[0] = ptr[1];
675  ptr[1] = tmp;
676  reordered++;
677  }
678  }
679  } while (reordered);
680 }
static int unload_module ( void  )
static

Definition at line 881 of file app_directory.c.

References ast_unregister_application().

882 {
883  int res;
885  return res;
886 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app[]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 893 of file app_directory.c.

const char app[] = "Directory"
static

Definition at line 122 of file app_directory.c.

Definition at line 893 of file app_directory.c.

struct ast_app_option directory_app_options[128] = { [ 'f' ] = { .flag = OPT_LISTBYFIRSTNAME , .arg_index = OPT_ARG_FIRSTNAME + 1 }, [ 'l' ] = { .flag = OPT_LISTBYLASTNAME , .arg_index = OPT_ARG_LASTNAME + 1 }, [ 'b' ] = { .flag = OPT_LISTBYEITHER , .arg_index = OPT_ARG_EITHER + 1 }, [ 'p' ] = { .flag = OPT_PAUSE , .arg_index = OPT_ARG_PAUSE + 1 }, [ 'e' ] = { .flag = OPT_SAYEXTENSION }, [ 'v' ] = { .flag = OPT_FROMVOICEMAIL }, [ 'm' ] = { .flag = OPT_SELECTFROMMENU }, [ 'n' ] = { .flag = OPT_NOANSWER }, }
static

Definition at line 167 of file app_directory.c.

Referenced by directory_exec().