Index: app.c =================================================================== --- app.c (revision 27194) +++ app.c (working copy) @@ -232,18 +232,22 @@ static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL; static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL; +static int (*ast_messagecount2_func)(const char *mailbox, const char *folder) = NULL; void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder), - int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs)) + int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs), + int (*messagecount2_func)(const char *mailbox, const char *folder)) { ast_has_voicemail_func = has_voicemail_func; ast_messagecount_func = messagecount_func; + ast_messagecount2_func = messagecount2_func; } void ast_uninstall_vm_functions(void) { ast_has_voicemail_func = NULL; ast_messagecount_func = NULL; + ast_messagecount2_func = NULL; } int ast_app_has_voicemail(const char *mailbox, const char *folder) @@ -278,6 +282,20 @@ return 0; } +int ast_app_messagecount2(const char *mailbox, const char *folder) +{ + static int warned = 0; + if (ast_messagecount2_func) + return ast_messagecount2_func(mailbox, folder); + + if (!warned && (option_verbose > 2)) { + warned++; + ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s, folder %s but voicemail not loaded.\n", mailbox, folder); + } + + return 0; +} + int ast_dtmf_stream(struct ast_channel *chan,struct ast_channel *peer,char *digits,int between) { char *ptr; Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 27194) +++ apps/app_voicemail.c (working copy) @@ -2107,7 +2107,7 @@ return x; } -static int has_voicemail(const char *mailbox, const char *folder) +static int messagecount2(const char *mailbox, const char *folder) { int nummsgs = 0; int res; @@ -2176,9 +2176,17 @@ return 0; } +static int has_voicemail(const char *mailbox, const char *folder) +{ + if (messagecount2(mailbox, folder)) + return 1; + else + return 0; +} + #else -static int has_voicemail(const char *mailbox, const char *folder) +static int __has_voicemail(const char *mailbox, const char *folder, int shortcircuit) { DIR *dir; struct dirent *de; @@ -2186,7 +2194,7 @@ char tmp[256]=""; char *mb, *cur; char *context; - int ret; + int ret = 0; if (!folder) folder = "INBOX"; /* If no mailbox, return immediately */ @@ -2198,11 +2206,13 @@ ret = 0; while((cur = strsep(&mb, ","))) { if (!ast_strlen_zero(cur)) { - if (has_voicemail(cur, folder)) - return 1; + if ((ret += __has_voicemail(cur, folder, shortcircuit))) { + if (shortcircuit) + return 1; + } } } - return 0; + return ret; } ast_copy_string(tmp, mailbox, sizeof(tmp)); context = strchr(tmp, '@'); @@ -2216,16 +2226,28 @@ if (!dir) return 0; while ((de = readdir(dir))) { - if (!strncasecmp(de->d_name, "msg", 3)) - break; + if (!strncasecmp(de->d_name, "msg", 3)) { + if (shortcircuit) { + ret = 1; + break; + } else if (!strncasecmp(de->d_name + 8, "txt", 3)) + ret++; + } } closedir(dir); - if (de) - return 1; - return 0; + return ret; } +static int has_voicemail(const char *mailbox, const char *folder) +{ + return __has_voicemail(mailbox, folder, 1); +} +static int messagecount2(const char *mailbox, const char *folder) +{ + return __has_voicemail(mailbox, folder, 0); +} + static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) { DIR *dir; @@ -6325,7 +6347,7 @@ /* compute the location of the voicemail spool directory */ snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); - ast_install_vm_functions(has_voicemail, messagecount); + ast_install_vm_functions(has_voicemail, messagecount, messagecount2); #if defined(USE_ODBC_STORAGE) && !defined(EXTENDED_ODBC_STORAGE) ast_log(LOG_WARNING, "The current ODBC storage table format will be changed soon." Index: apps/app_hasnewvoicemail.c =================================================================== --- apps/app_hasnewvoicemail.c (revision 27194) +++ apps/app_hasnewvoicemail.c (working copy) @@ -77,30 +77,10 @@ LOCAL_USER_DECL; -static int hasvoicemail_internal(char *context, char *box, char *folder) -{ - char vmpath[256]; - DIR *vmdir; - struct dirent *vment; - int count=0; - - snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, box, folder); - if ((vmdir = opendir(vmpath))) { - /* No matter what the format of VM, there will always be a .txt file for each message. */ - while ((vment = readdir(vmdir))) { - if (!strncmp(vment->d_name + 7, ".txt", 4)) { - count++; - } - } - closedir(vmdir); - } - return count; -} - static int hasvoicemail_exec(struct ast_channel *chan, void *data) { struct localuser *u; - char *input, *varname = NULL, *vmbox, *context = "default"; + char *input, *varname = NULL, *vmbox, *context = "default", mailbox[256]; char *vmfolder; int vmcount = 0; static int dep_warning = 0; @@ -152,7 +132,8 @@ priority_jump = 1; } - vmcount = hasvoicemail_internal(context, vmbox, vmfolder); + snprintf(mailbox, sizeof(mailbox), "%s@%s", vmbox, context); + vmcount = ast_app_messagecount2(mailbox, vmfolder); /* Set the count in the channel variable */ if (varname) { snprintf(tmp, sizeof(tmp), "%d", vmcount); @@ -192,12 +173,6 @@ } box = strsep(&args, "|"); - if (strchr(box, '@')) { - context = box; - box = strsep(&context, "@"); - } else { - context = "default"; - } if (args) { folder = args; @@ -205,7 +180,7 @@ folder = "INBOX"; } - snprintf(buf, len, "%d", hasvoicemail_internal(context, box, folder)); + snprintf(buf, len, "%d", ast_app_messagecount2(box, folder)); LOCAL_USER_REMOVE(u); Index: include/asterisk/app.h =================================================================== --- include/asterisk/app.h (revision 27194) +++ include/asterisk/app.h (working copy) @@ -103,7 +103,8 @@ int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec); void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder), - int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs)); + int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs), + int (*messagecount2_func)(const char *mailbox, const char *folder)); void ast_uninstall_vm_functions(void); @@ -113,6 +114,9 @@ /*! Determine number of new/old messages in a mailbox */ int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs); +/*! Determine number of messages in a given mailbox and folder */ +int ast_app_messagecount2(const char *mailbox, const char *folder); + /*! Safely spawn an external program while closing file descriptors \note This replaces the \b system call in all Asterisk modules */