Index: app.c =================================================================== --- app.c (revision 25608) +++ app.c (working copy) @@ -231,18 +231,22 @@ } static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL; +static int (*ast_voicemail_count_func)(const char *mailbox, const char *folder) = NULL; static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL; void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder), + int (*voicemail_count_func)(const char *mailbox, const char *folder), int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs)) { ast_has_voicemail_func = has_voicemail_func; + ast_voicemail_count_func = voicemail_count_func; ast_messagecount_func = messagecount_func; } void ast_uninstall_vm_functions(void) { ast_has_voicemail_func = NULL; + ast_voicemail_count_func = NULL; ast_messagecount_func = NULL; } @@ -259,7 +263,20 @@ return 0; } +int ast_app_voicemail_count(const char *mailbox, const char *folder) +{ + static int warned = 0; + if (ast_has_voicemail_func) + return ast_voicemail_count_func(mailbox, folder); + if ((option_verbose > 2) && !warned) { + ast_verbose(VERBOSE_PREFIX_3 "Message count requested for mailbox %s/folder %s but voicemail not loaded.\n", mailbox, folder ? folder : "INBOX"); + warned++; + } + return 0; +} + + int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) { static int warned = 0; Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 25608) +++ apps/app_voicemail.c (working copy) @@ -2003,111 +2003,10 @@ } #ifdef USE_ODBC_STORAGE -static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) -{ - int x = 0; - int res; - SQLHSTMT stmt; - char sql[256]; - char rowdata[20]; - char tmp[256]=""; - char *context; - if (newmsgs) - *newmsgs = 0; - if (oldmsgs) - *oldmsgs = 0; - /* If no mailbox, return immediately */ - if (ast_strlen_zero(mailbox)) - return 0; - - ast_copy_string(tmp, mailbox, sizeof(tmp)); - - context = strchr(tmp, '@'); - if (context) { - *context = '\0'; - context++; - } else - context = "default"; - - odbc_obj *obj; - obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); - goto yuck; - } - snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir LIKE '%%%s/%s/%s'", odbc_table, context, tmp, "INBOX"); - res = SQLPrepare(stmt, sql, SQL_NTS); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = odbc_smart_execute(obj, stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = SQLFetch(stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - *newmsgs = atoi(rowdata); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); - goto yuck; - } - snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir like '%%%s/%s/%s'", odbc_table, context, tmp, "Old"); - res = SQLPrepare(stmt, sql, SQL_NTS); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = odbc_smart_execute(obj, stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = SQLFetch(stmt); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); - if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { - ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - goto yuck; - } - SQLFreeHandle (SQL_HANDLE_STMT, stmt); - *oldmsgs = atoi(rowdata); - x = 1; - } else - ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); - -yuck: - return x; -} - -static int has_voicemail(const char *mailbox, const char *folder) +static int voicemail_count(const char *mailbox, const char *folder) { + ast_log(LOG_DEBUG, "in voicemail_count %s %s\n", mailbox, folder); int nummsgs = 0; int res; SQLHSTMT stmt; @@ -2138,7 +2037,8 @@ ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; } - snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir like '%%%s/%s/%s'", odbc_table, context, tmp, "INBOX"); + snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir like '%%%s/%s/%s'", odbc_table, context, tmp, folder); + ast_log(LOG_DEBUG, "in voicemail_count sql=%s\n", sql); res = SQLPrepare(stmt, sql, SQL_NTS); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); @@ -2169,22 +2069,55 @@ ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: - if (nummsgs>=1) - return 1; - else - return 0; + ast_log(LOG_DEBUG, "in voicemail_count returning %d\n", nummsgs); + return nummsgs; } #else -static int has_voicemail(const char *mailbox, const char *folder) +static int voicemail_count(const char *mailbox, const char *folder) { + ast_log(LOG_DEBUG, "in voicemail_count %s %s\n", mailbox, folder); DIR *dir; struct dirent *de; char fn[256]; char tmp[256]=""; - char *mb, *cur; char *context; + int nummsgs = 0; + if (!folder) + folder = "INBOX"; + /* If no mailbox, return immediately */ + if (ast_strlen_zero(mailbox)) + return 0; + ast_copy_string(tmp, mailbox, sizeof(tmp)); + context = strchr(tmp, '@'); + if (context) { + *context = '\0'; + context++; + } else + context = "default"; + snprintf(fn, sizeof(fn), "%s/%s/%s/%s", VM_SPOOL_DIR, context, tmp, folder); + dir = opendir(fn); + ast_log(LOG_DEBUG, "in voicemail_count dir=%s\n", fn); + if (dir) { + while ((de = readdir(dir))) { + if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) && + !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt")) + nummsgs++; + + } + closedir(dir); + } + + ast_log(LOG_DEBUG, "in voicemail_count returning %d\n", nummsgs); + return nummsgs; +} +#endif + +static int has_voicemail(const char *mailbox, const char *folder) +{ + char tmp[256]=""; + char *mb, *cur; int ret; if (!folder) folder = "INBOX"; @@ -2203,23 +2136,7 @@ } return 0; } - ast_copy_string(tmp, mailbox, sizeof(tmp)); - context = strchr(tmp, '@'); - if (context) { - *context = '\0'; - context++; - } else - context = "default"; - snprintf(fn, sizeof(fn), "%s/%s/%s/%s", VM_SPOOL_DIR, context, tmp, folder); - dir = opendir(fn); - if (!dir) - return 0; - while ((de = readdir(dir))) { - if (!strncasecmp(de->d_name, "msg", 3)) - break; - } - closedir(dir); - if (de) + if (voicemail_count(mailbox,folder) > 0) return 1; return 0; } @@ -2227,12 +2144,8 @@ static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) { - DIR *dir; - struct dirent *de; - char fn[256]; char tmp[256]=""; char *mb, *cur; - char *context; int ret; if (newmsgs) *newmsgs = 0; @@ -2260,43 +2173,11 @@ } return 0; } - ast_copy_string(tmp, mailbox, sizeof(tmp)); - context = strchr(tmp, '@'); - if (context) { - *context = '\0'; - context++; - } else - context = "default"; - if (newmsgs) { - snprintf(fn, sizeof(fn), "%s/%s/%s/INBOX", VM_SPOOL_DIR, context, tmp); - dir = opendir(fn); - if (dir) { - while ((de = readdir(dir))) { - if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) && - !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt")) - (*newmsgs)++; - - } - closedir(dir); - } - } - if (oldmsgs) { - snprintf(fn, sizeof(fn), "%s/%s/%s/Old", VM_SPOOL_DIR, context, tmp); - dir = opendir(fn); - if (dir) { - while ((de = readdir(dir))) { - if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) && - !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt")) - (*oldmsgs)++; - - } - closedir(dir); - } - } + *newmsgs = voicemail_count(mailbox, "INBOX"); + *oldmsgs = voicemail_count(mailbox, "Old"); return 0; } -#endif static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname); @@ -6324,7 +6205,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, voicemail_count, messagecount); #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 25608) +++ apps/app_hasnewvoicemail.c (working copy) @@ -79,22 +79,10 @@ static int hasvoicemail_internal(char *context, char *box, char *folder) { - char vmpath[256]; - DIR *vmdir; - struct dirent *vment; - int count=0; + char mailbox[256]=""; + snprintf(mailbox,sizeof(mailbox),"%s@%s", box, context); - 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; + return ast_app_voicemail_count(mailbox, folder); } static int hasvoicemail_exec(struct ast_channel *chan, void *data) Index: include/asterisk/app.h =================================================================== --- include/asterisk/app.h (revision 25608) +++ include/asterisk/app.h (working copy) @@ -103,6 +103,7 @@ 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 (*voicemail_count_func)(const char *mailbox, const char *folder), int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs)); void ast_uninstall_vm_functions(void); @@ -110,6 +111,9 @@ /*! Determine if a given mailbox has any voicemail */ int ast_app_has_voicemail(const char *mailbox, const char *folder); +/* Count messages in given mailbox/folder */ +int ast_app_voicemail_count(const char *mailbox, const char *folder); + /*! Determine number of new/old messages in a mailbox */ int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);