summaryrefslogtreecommitdiff
path: root/apps/app_voicemail.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2013-12-19 16:52:43 +0000
committerRichard Mudgett <rmudgett@digium.com>2013-12-19 16:52:43 +0000
commite4803bbd9eba2705615e2495de0ed0c35051dd45 (patch)
treefe8787ab22e2c694e93c4ec2757e3d8ca4c681dc /apps/app_voicemail.c
parent2882c5f9f1f1c81a5a2bae35825d81070bb10164 (diff)
Voicemail: Remove mailbox identifier format (box@context) assumptions in the system.
This change is in preparation for external MWI support. Removed code from the system for normal mailbox handling that appends @default to the mailbox identifier if it does not have a context. The only exception is the legacy hasvoicemail users.conf option. The legacy option will only work for app_voicemail mailboxes. The system cannot make any assumptions about the format of the mailbox identifer used by app_voicemail. chan_sip and chan_dahdi/sig_pri had the most changes because they both tried to interpret the mailbox identifier. chan_sip just stored and compared the two components. chan_dahdi actually used the box information. The ISDN MWI support configuration options had to be reworked because chan_dahdi was parsing the box@context format to get the box number. As a result the mwi_vm_boxes chan_dahdi.conf option was added and is documented in the chan_dahdi.conf.sample file. Review: https://reviewboard.asterisk.org/r/3072/ ........ Merged revisions 404348 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404350 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_voicemail.c')
-rw-r--r--apps/app_voicemail.c146
1 files changed, 95 insertions, 51 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 36692981b..05b0cfb09 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -1111,6 +1111,34 @@ static int vm_test_destroy_user(const char *context, const char *mailbox);
static int vm_test_create_user(const char *context, const char *mailbox);
#endif
+/*!
+ * \internal
+ * \brief Parse the given mailbox_id into mailbox and context.
+ * \since 12.0.0
+ *
+ * \param mailbox_id The mailbox@context string to separate.
+ * \param mailbox Where the mailbox part will start.
+ * \param context Where the context part will start. ("default" if not present)
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int separate_mailbox(char *mailbox_id, char **mailbox, char **context)
+{
+ if (ast_strlen_zero(mailbox_id) || !mailbox || !context) {
+ return -1;
+ }
+ *context = mailbox_id;
+ *mailbox = strsep(context, "@");
+ if (ast_strlen_zero(*mailbox)) {
+ return -1;
+ }
+ if (ast_strlen_zero(*context)) {
+ *context = "default";
+ }
+ return 0;
+}
+
struct ao2_container *inprocess_container;
struct inprocess {
@@ -2502,15 +2530,22 @@ static int imap_check_limits(struct ast_channel *chan, struct vm_state *vms, str
/*!
* \brief Gets the number of messages that exist in a mailbox folder.
- * \param context
- * \param mailbox
+ * \param mailbox_id
* \param folder
*
* This method is used when IMAP backend is used.
* \return The number of messages in this mailbox folder (zero or more).
*/
-static int messagecount(const char *context, const char *mailbox, const char *folder)
+static int messagecount(const char *mailbox_id, const char *folder)
{
+ char *context;
+ char *mailbox;
+
+ if (ast_strlen_zero(mailbox_id)
+ || separate_mailbox(ast_strdupa(mailbox_id), &mailbox, &context)) {
+ return 0;
+ }
+
if (ast_strlen_zero(folder) || !strcmp(folder, "INBOX")) {
return __messagecount(context, mailbox, "INBOX") + __messagecount(context, mailbox, "Urgent");
} else {
@@ -2533,9 +2568,12 @@ static int imap_store_file(const char *dir, const char *mailboxuser, const char
STRING str;
int ret; /* for better error checking */
char *imap_flags = NIL;
- int msgcount = (messagecount(vmu->context, vmu->mailbox, "INBOX") + messagecount(vmu->context, vmu->mailbox, "Old"));
+ int msgcount;
int box = NEW_FOLDER;
+ snprintf(mailbox, sizeof(mailbox), "%s@%s", vmu->mailbox, vmu->context);
+ msgcount = messagecount(mailbox, "INBOX") + messagecount(mailbox, "Old");
+
/* Back out early if this is a greeting and we don't want to store greetings in IMAP */
if (msgnum < 0) {
if(!imapgreetings) {
@@ -5612,16 +5650,17 @@ static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *
/*!
* \brief Gets the number of messages that exist in a mailbox folder.
- * \param context
- * \param mailbox
+ * \param mailbox_id
* \param folder
*
* This method is used when ODBC backend is used.
* \return The number of messages in this mailbox folder (zero or more).
*/
-static int messagecount(const char *context, const char *mailbox, const char *folder)
+static int messagecount(const char *mailbox_id, const char *folder)
{
struct odbc_obj *obj = NULL;
+ char *context;
+ char *mailbox;
int nummsgs = 0;
int res;
SQLHSTMT stmt = NULL;
@@ -5630,7 +5669,8 @@ static int messagecount(const char *context, const char *mailbox, const char *fo
struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
/* If no mailbox, return immediately */
- if (ast_strlen_zero(mailbox)) {
+ if (ast_strlen_zero(mailbox_id)
+ || separate_mailbox(ast_strdupa(mailbox_id), &mailbox, &context)) {
return 0;
}
@@ -5681,16 +5721,16 @@ yuck:
* This invokes the messagecount(). Here we are interested in the presence of messages (> 0) only, not the actual count.
* \return 1 if the folder has one or more messages. zero otherwise.
*/
-static int has_voicemail(const char *mailbox, const char *folder)
+static int has_voicemail(const char *mailboxes, const char *folder)
{
- char tmp[256], *tmp2 = tmp, *box, *context;
- ast_copy_string(tmp, mailbox, sizeof(tmp));
- while ((context = box = strsep(&tmp2, ",&"))) {
- strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = "default";
- if (messagecount(context, box, folder))
+ char *parse;
+ char *mailbox;
+
+ parse = ast_strdupa(mailboxes);
+ while ((mailbox = strsep(&parse, ",&"))) {
+ if (messagecount(mailbox, folder)) {
return 1;
+ }
}
return 0;
}
@@ -5778,8 +5818,16 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i
#endif
#if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
-static int messagecount(const char *context, const char *mailbox, const char *folder)
+static int messagecount(const char *mailbox_id, const char *folder)
{
+ char *context;
+ char *mailbox;
+
+ if (ast_strlen_zero(mailbox_id)
+ || separate_mailbox(ast_strdupa(mailbox_id), &mailbox, &context)) {
+ return 0;
+ }
+
return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0));
}
@@ -7742,13 +7790,11 @@ static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu,
static void queue_mwi_event(const char *channel_id, const char *box, int urgent, int new, int old)
{
- char *mailbox, *context;
+ char *mailbox;
+ char *context;
- /* Strip off @default */
- context = mailbox = ast_strdupa(box);
- strsep(&context, "@");
- if (ast_strlen_zero(context)) {
- context = "default";
+ if (separate_mailbox(ast_strdupa(box), &mailbox, &context)) {
+ return;
}
ast_publish_mwi_state_channel(mailbox, context, new + urgent, old, channel_id);
@@ -11999,7 +12045,9 @@ static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, ch
{
struct ast_vm_user svm;
struct ast_vm_user *vmu = NULL;
- char *tmp, *mailbox, *context, *parse;
+ char *parse;
+ char *mailbox;
+ char *context;
int res = 0;
AST_DECLARE_APP_ARGS(arg,
@@ -12018,19 +12066,13 @@ static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, ch
parse = ast_strdupa(args);
AST_STANDARD_APP_ARGS(arg, parse);
- if (ast_strlen_zero(arg.mailbox_context) || ast_strlen_zero(arg.attribute)) {
+ if (ast_strlen_zero(arg.mailbox_context)
+ || ast_strlen_zero(arg.attribute)
+ || separate_mailbox(ast_strdupa(arg.mailbox_context), &mailbox, &context)) {
ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
return -1;
}
- tmp = ast_strdupa(arg.mailbox_context);
- mailbox = strsep(&tmp, "@");
- context = strsep(&tmp, "");
-
- if (ast_strlen_zero(context)) {
- context = "default";
- }
-
vmu = find_user(&svm, context, mailbox);
if (!strncasecmp(arg.attribute, "exists", 5)) {
@@ -12054,8 +12096,13 @@ static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, ch
} else if (!strncasecmp(arg.attribute, "tz", 2)) {
ast_copy_string(buf, vmu->zonetag, len);
} else if (!strncasecmp(arg.attribute, "count", 5)) {
+ char *mailbox_id;
+
+ mailbox_id = ast_alloca(strlen(mailbox) + strlen(context) + 2);
+ sprintf(mailbox_id, "%s@%s", mailbox, context);/* Safe */
+
/* If mbxfolder is empty messagecount will default to INBOX */
- res = messagecount(context, mailbox, arg.folder);
+ res = messagecount(mailbox_id, arg.folder);
if (res < 0) {
ast_log(LOG_ERROR, "Unable to retrieve message count for mailbox %s\n", arg.mailbox_context);
return -1;
@@ -12592,14 +12639,17 @@ static void mwi_unsub_event_cb(struct stasis_subscription_change *change)
static void mwi_sub_event_cb(struct stasis_subscription_change *change)
{
struct mwi_sub_task *mwist;
- char *context = ast_strdupa(stasis_topic_name(change->topic));
+ char *context;
char *mailbox;
- if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) {
+ mwist = ast_calloc(1, (sizeof(*mwist)));
+ if (!mwist) {
return;
}
- mailbox = strsep(&context, "@");
+ if (separate_mailbox(ast_strdupa(stasis_topic_name(change->topic)), &mailbox, &context)) {
+ return;
+ }
mwist->mailbox = ast_strdup(mailbox);
mwist->context = ast_strdup(context);
@@ -13668,26 +13718,20 @@ static int write_password_to_file(const char *secretfn, const char *password) {
static int vmsayname_exec(struct ast_channel *chan, const char *data)
{
char *context;
- char *args_copy;
+ char *mailbox;
int res;
- if (ast_strlen_zero(data)) {
+ if (ast_strlen_zero(data)
+ || separate_mailbox(ast_strdupa(data), &mailbox, &context)) {
ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n");
return -1;
}
- args_copy = ast_strdupa(data);
- if ((context = strchr(args_copy, '@'))) {
- *context++ = '\0';
- } else {
- context = "default";
- }
-
- if ((res = sayname(chan, args_copy, context)) < 0) {
- ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context);
+ if ((res = sayname(chan, mailbox, context)) < 0) {
+ ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", mailbox, context);
res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
if (!res) {
- res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
+ res = ast_say_character_str(chan, mailbox, AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
}
}
@@ -13925,9 +13969,9 @@ AST_TEST_DEFINE(test_voicemail_msgcount)
new = old = urgent = 0;
for (j = 0; j < 3; j++) {
- if (ast_app_messagecount(testcontext, testmailbox, folders[j]) != expected_results[i][9 + j]) {
+ if (ast_app_messagecount(testspec, folders[j]) != expected_results[i][9 + j]) {
ast_test_status_update(test, "messagecount(%s, %s) returned %d and we expected %d\n",
- testspec, folders[j], ast_app_messagecount(testcontext, testmailbox, folders[j]), expected_results[i][9 + j]);
+ testspec, folders[j], ast_app_messagecount(testspec, folders[j]), expected_results[i][9 + j]);
res = AST_TEST_FAIL;
}
}