app_directory: add ability to specify configuration file

Adds option to app_directory to specify a filename from which to
read configuration instead of voicemail.conf ie;

same => n,Directory(,,c(directory.conf))

This configuration should contain a list of extensions using the
voicemail.conf format, ie;

2020=2020,Dog Dog,,,,attach=no|saycid=no|envelope=no|delete=no

ASTERISK-30404

Change-Id: Id58ccb1344ad1e563fa10db12f172fbd104a9d13
This commit is contained in:
Mike Bradeen 2023-01-25 15:27:31 -07:00 committed by Friendly Automation
parent 8a45cd7af4
commit 70856e865f
1 changed files with 15 additions and 6 deletions

View File

@ -103,6 +103,10 @@
receiver to their ear while entering DTMF.</para> receiver to their ear while entering DTMF.</para>
<argument name="n" required="true" /> <argument name="n" required="true" />
</option> </option>
<option name="c">
<para>Load the specified config file instead of voicemail.conf</para>
<argument name="filename" required="true" />
</option>
</optionlist> </optionlist>
<note><para>Only one of the <replaceable>f</replaceable>, <replaceable>l</replaceable>, or <replaceable>b</replaceable> <note><para>Only one of the <replaceable>f</replaceable>, <replaceable>l</replaceable>, or <replaceable>b</replaceable>
options may be specified. <emphasis>If more than one is specified</emphasis>, then Directory will act as options may be specified. <emphasis>If more than one is specified</emphasis>, then Directory will act as
@ -114,7 +118,7 @@
<description> <description>
<para>This application will present the calling channel with a directory of extensions from which they can search <para>This application will present the calling channel with a directory of extensions from which they can search
by name. The list of names and corresponding extensions is retrieved from the by name. The list of names and corresponding extensions is retrieved from the
voicemail configuration file, <filename>voicemail.conf</filename>.</para> voicemail configuration file, <filename>voicemail.conf</filename>, or from the specified filename.</para>
<para>This application will immediately exit if one of the following DTMF digits are <para>This application will immediately exit if one of the following DTMF digits are
received and the extension to jump to exists:</para> received and the extension to jump to exists:</para>
<para><literal>0</literal> - Jump to the 'o' extension, if it exists.</para> <para><literal>0</literal> - Jump to the 'o' extension, if it exists.</para>
@ -153,6 +157,7 @@ enum {
OPT_PAUSE = (1 << 5), OPT_PAUSE = (1 << 5),
OPT_NOANSWER = (1 << 6), OPT_NOANSWER = (1 << 6),
OPT_ALIAS = (1 << 7), OPT_ALIAS = (1 << 7),
OPT_CONFIG_FILE = (1 << 8),
}; };
enum { enum {
@ -160,8 +165,9 @@ enum {
OPT_ARG_LASTNAME = 1, OPT_ARG_LASTNAME = 1,
OPT_ARG_EITHER = 2, OPT_ARG_EITHER = 2,
OPT_ARG_PAUSE = 3, OPT_ARG_PAUSE = 3,
OPT_ARG_FILENAME = 4,
/* This *must* be the last value in this enum! */ /* This *must* be the last value in this enum! */
OPT_ARG_ARRAY_SIZE = 4, OPT_ARG_ARRAY_SIZE = 5,
}; };
struct directory_item { struct directory_item {
@ -183,6 +189,7 @@ AST_APP_OPTIONS(directory_app_options, {
AST_APP_OPTION('m', OPT_SELECTFROMMENU), AST_APP_OPTION('m', OPT_SELECTFROMMENU),
AST_APP_OPTION('n', OPT_NOANSWER), AST_APP_OPTION('n', OPT_NOANSWER),
AST_APP_OPTION('a', OPT_ALIAS), AST_APP_OPTION('a', OPT_ALIAS),
AST_APP_OPTION_ARG('c', OPT_CONFIG_FILE, OPT_ARG_FILENAME),
}); });
static int compare(const char *text, const char *template) static int compare(const char *text, const char *template)
@ -458,7 +465,7 @@ static int select_item_menu(struct ast_channel *chan, struct directory_item **it
AST_THREADSTORAGE(commonbuf); AST_THREADSTORAGE(commonbuf);
static struct ast_config *realtime_directory(char *context) static struct ast_config *realtime_directory(char *context, const char *filename)
{ {
struct ast_config *cfg; struct ast_config *cfg;
struct ast_config *rtdata = NULL; struct ast_config *rtdata = NULL;
@ -475,14 +482,14 @@ static struct ast_config *realtime_directory(char *context)
} }
/* Load flat file config. */ /* Load flat file config. */
cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); cfg = ast_config_load(filename, config_flags);
if (!cfg) { if (!cfg) {
/* Loading config failed. */ /* Loading config failed. */
ast_log(LOG_WARNING, "Loading config failed.\n"); ast_log(LOG_WARNING, "Loading config failed.\n");
return NULL; return NULL;
} else if (cfg == CONFIG_STATUS_FILEINVALID) { } else if (cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", VOICEMAIL_CONFIG); ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", filename);
return NULL; return NULL;
} }
@ -867,7 +874,9 @@ static int directory_exec(struct ast_channel *chan, const char *data)
if (args.options && ast_app_parse_options(directory_app_options, &flags, opts, args.options)) if (args.options && ast_app_parse_options(directory_app_options, &flags, opts, args.options))
return -1; return -1;
if (!(cfg = realtime_directory(args.vmcontext))) { cfg = realtime_directory(args.vmcontext, S_OR(opts[OPT_ARG_FILENAME], VOICEMAIL_CONFIG));
if (!cfg) {
ast_log(LOG_ERROR, "Unable to read the configuration data!\n"); ast_log(LOG_ERROR, "Unable to read the configuration data!\n");
return -1; return -1;
} }