--- apps/app_voicemail.c 2011-02-08 11:41:21.000000000 -0800 +++ apps/app_voicemail.c 2011-04-28 16:45:57.000000000 -0700 @@ -434,6 +434,7 @@ static AST_LIST_HEAD_STATIC(vmstates, vm #define VM_MESSAGEWRAP (1 << 17) /*!< Wrap around from the last message to the first, and vice-versa */ #define VM_FWDURGAUTO (1 << 18) /*!< Autoset of Urgent flag on forwarded Urgent messages set globally */ #define ERROR_LOCK_PATH -100 +#define ERROR_OPEN_PATH -75 #define OPERATOR_EXIT 300 @@ -3693,37 +3695,64 @@ static int remove_file(char *dir, int ms #else #ifndef IMAP_STORAGE /*! - * \brief Find all .txt files - even if they are not in sequence from 0000. + * \brief Recursively find all .txt files on a given path on the filesystem - even if they are not in sequence from 0000. * \param vmu * \param dir * * This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). * - * \return the count of messages, zero or more. + * \return the recursive count of all messages, zero or more. */ static int count_messages(struct ast_vm_user *vmu, char *dir) { - int vmcount = 0; + int vmcount = 0, tmpcount = 0; DIR *vmdir = NULL; struct dirent *vment = NULL; + struct stat fs; + char tmpfile[PATH_MAX] = ""; - if (vm_lock_path(dir)) + if (vm_lock_path(dir)) { + ast_log(AST_LOG_WARNING, "Unable to LOCK mailbox on filesystem. Tried locking: %s\n", dir); return ERROR_LOCK_PATH; + } + + if (!(vmdir = opendir(dir))) { + ast_log(AST_LOG_WARNING, "Unable to OPEN mailbox on filesytem. Tried opening: %s\n", dir); + return ERROR_OPEN_PATH; + } - if ((vmdir = opendir(dir))) { while ((vment = readdir(vmdir))) { - if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { + if ( ( strcmp(vment->d_name, ".") == 0 ) || ( strcmp(vment->d_name, "..") == 0 ) ) { + continue; + } + + /* Use stat to determine if an entry is a file or directory. */ + /* Since readdir only returns path shortened names, */ + /* start by building the entry to be stat'd with "dir" as the */ + /* path and append the entry to create: "dir/entry" */ + + ast_copy_string(tmpfile, dir, sizeof(tmpfile)); + strncat(tmpfile, "/", sizeof(tmpfile) - strlen(tmpfile) - 1); + strncat(tmpfile, vment->d_name, sizeof(tmpfile) - strlen(tmpfile) - 1); + if ( stat(tmpfile, &fs) < 0 ) { + ast_log(AST_LOG_WARNING, "Unable to STAT file %s on mailbox %s on filesystem.\n", tmpfile, dir); + return 0; + } + if (S_ISDIR(fs.st_mode) ) { /* Found a sub-directory so recursively invoke count_messages() */ + if ( (tmpcount = count_messages(vmu, tmpfile)) ) { + vmcount += tmpcount; + } + } else { + if (strlen(vment->d_name) > 7 && !strcmp(vment->d_name + 7, ".txt")) { vmcount++; } } - closedir(vmdir); } + closedir(vmdir); ast_unlock_path(dir); - return vmcount; } - /*! * \brief Renames a message in a mailbox folder. * \param sfn The path to the mailbox information and data file to be renamed. @@ -5272,6 +5301,7 @@ static int leave_voicemail(struct ast_ch char origtime[16]; char dir[PATH_MAX]; char tmpdir[PATH_MAX]; + char mbox_dir[PATH_MAX] = ""; char fn[PATH_MAX]; char prefile[PATH_MAX] = ""; char tempfile[PATH_MAX] = ""; @@ -5531,11 +5561,12 @@ static int leave_voicemail(struct ast_ch goto leave_vm_out; } #else - if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { + sprintf (mbox_dir, "%s%s/%s", VM_SPOOL_DIR, vmu->context, vmu->mailbox); + if (count_messages(vmu, mbox_dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { res = ast_streamfile(chan, "vm-mailboxfull", chan->language); if (!res) res = ast_waitstream(chan, ""); - ast_log(AST_LOG_WARNING, "No more messages possible\n"); + ast_log(AST_LOG_WARNING, "No more messages possible for Mailbox: %s@%s. Counted: %d, Max Msg's: %d\n", vmu->mailbox, vmu->context, count_messages(vmu, mbox_dir), vmu->maxmsg); pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); inprocess_count(vmu->mailbox, vmu->context, -1); goto leave_vm_out;