Merge in ast_strftime branch, which changes timestamps to be accurate to the microsec...
[asterisk/asterisk.git] / apps / app_voicemail.c
index 4ec85b6..4c051dc 100644 (file)
@@ -35,7 +35,7 @@ c-client (http://www.washington.edu/imap/
  *
  *
  *
- * \note  This file is now almost impossible to work with, due to all #ifdefs.
+ * \note  This file is now almost impossible to work with, due to all \#ifdefs.
  *        Feels like the database code before realtime. Someone - please come up
  *        with a plan to clean this up.
  */
@@ -370,7 +370,7 @@ struct ast_vm_user {
        char uniqueid[20];               /*!< Unique integer identifier */
        char exit[80];
        char attachfmt[20];              /*!< Attachment format */
-       unsigned int flags;              /*!< VM_ flags */      
+       uint64_t flags;              /*!< VM_ flags */  
        int saydurationm;
        int maxmsg;                      /*!< Maximum number of msgs per folder for this mailbox */
        int maxsecs;                     /*!< Maximum number of seconds per message for this mailbox */
@@ -495,7 +495,7 @@ static char *descrip_vm =
        "           message. The units are whole-number decibels (dB).\n"
        "    s    - Skip the playback of instructions for leaving a message to the\n"
        "           calling party.\n"
-       "    u    - Play the 'unavailable greeting.\n";
+       "    u    - Play the 'unavailable' greeting.\n";
 
 static char *synopsis_vmain = "Check Voicemail messages";
 
@@ -619,9 +619,9 @@ static struct ast_flags globalflags = {0};
 
 static int saydurationminfo;
 
-static char dialcontext[AST_MAX_CONTEXT];
-static char callcontext[AST_MAX_CONTEXT];
-static char exitcontext[AST_MAX_CONTEXT];
+static char dialcontext[AST_MAX_CONTEXT] = "";
+static char callcontext[AST_MAX_CONTEXT] = "";
+static char exitcontext[AST_MAX_CONTEXT] = "";
 
 static char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64];
 
@@ -665,12 +665,9 @@ static void populate_defaults(struct ast_vm_user *vmu)
        ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);     
        if (saydurationminfo)
                vmu->saydurationm = saydurationminfo;
-       if (callcontext)
-               ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
-       if (dialcontext)
-               ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
-       if (exitcontext)
-               ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
+       ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
+       ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
+       ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
        if (vmmaxsecs)
                vmu->maxsecs = vmmaxsecs;
        if (maxmsg)
@@ -1967,10 +1964,10 @@ static char *quote(const char *from, char *to, size_t len)
  * fill in *tm for current time according to the proper timezone, if any.
  * Return tm so it can be used as a function argument.
  */
-static const struct tm *vmu_tm(const struct ast_vm_user *vmu, struct tm *tm)
+static const struct ast_tm *vmu_tm(const struct ast_vm_user *vmu, struct ast_tm *tm)
 {
        const struct vm_zone *z = NULL;
-       time_t t = time(NULL);
+       struct timeval t = ast_tvnow();
 
        /* Does this user have a timezone specified? */
        if (!ast_strlen_zero(vmu->zonetag)) {
@@ -2010,7 +2007,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
        char fname[256];
        char dur[256];
        char tmpcmd[256];
-       struct tm tm;
+       struct ast_tm tm;
        char *passdata2;
        size_t len_passdata;
        char *greeting_attachment;
@@ -2032,11 +2029,11 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
                *greeting_attachment++ = '\0';
 
        snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
-       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
+       ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
        fprintf(p, "Date: %s" ENDL, date);
 
        /* Set date format for voicemail mail */
-       strftime(date, sizeof(date), emaildateformat, &tm);
+       ast_strftime(date, sizeof(date), emaildateformat, &tm);
 
        if (!ast_strlen_zero(fromstring)) {
                struct ast_channel *ast;
@@ -2193,7 +2190,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *c
        }
        if (!strcmp(format, "wav49"))
                format = "WAV";
-       ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
+       ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %lld\n", attach, format, attach_user_voicemail, (unsigned long long)ast_test_flag((&globalflags), VM_ATTACH));
        /* Make a temporary file instead of piping directly to sendmail, in case the mail
           command hangs */
        if ((p = vm_mkftemp(tmp)) == NULL) {
@@ -2217,7 +2214,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
        char dur[PATH_MAX];
        char tmp[80] = "/tmp/astmail-XXXXXX";
        char tmp2[PATH_MAX];
-       struct tm tm;
+       struct ast_tm tm;
        FILE *p;
 
        if ((p = vm_mkftemp(tmp)) == NULL) {
@@ -2230,7 +2227,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
        else 
                snprintf(who, sizeof(who), "%s@%s", srcemail, host);
        snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
-       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
+       ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
        fprintf(p, "Date: %s\n", date);
 
        if (*pagerfromstring) {
@@ -2269,7 +2266,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
        } else
                fprintf(p, "Subject: New VM\n\n");
 
-       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
+       ast_strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
        if (pagerbody) {
                struct ast_channel *ast;
                if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
@@ -2296,11 +2293,10 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char
 
 static int get_date(char *s, int len)
 {
-       struct tm tm;
-       time_t t;
-       t = time(0);
+       struct ast_tm tm;
+       struct timeval t = ast_tvnow();
        ast_localtime(&t, &tm, NULL);
-       return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
+       return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm);
 }
 
 static int invent_message(struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
@@ -2311,7 +2307,7 @@ static int invent_message(struct ast_channel *chan, char *context, char *ext, in
 
        snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
 
-       if ((res = create_dirpath(dest, sizeof(dest), context, ext, "greet"))) {
+       if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) {
                ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
                return -1;
        }
@@ -2647,7 +2643,7 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
         ast_debug(3,"Mailbox is set to %s\n",mailbox);
 
        /* If no mailbox, return immediately */
-       if (ast_strlen_zero(mailbox))
+       if (ast_strlen_zero(mailbox)) 
                return 0;
 
        if (strchr(mailbox, ',')) {
@@ -2694,7 +2690,7 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
                free_user(vmu);
                return -1;
        }
+
        /* check if someone is accessing this box right now... */
        if ((vms_p = get_vm_state_by_imapuser(vmu->imapuser, 1)) || (vms_p = get_vm_state_by_mailbox(mailboxnc, 1))) {
                ast_debug(3,"Returning before search - user is logged in\n");
@@ -2703,7 +2699,7 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
                free_user(vmu);
                return 0;
        }
+
        /* add one if not there... */
        if (!(vms_p = get_vm_state_by_imapuser(vmu->imapuser, 0)) && !(vms_p = get_vm_state_by_mailbox(mailboxnc, 0))) {
                ast_debug(3,"Adding new vmstate for %s\n",vmu->imapuser);
@@ -2991,7 +2987,7 @@ static void run_externnotify(char *context, char *extension)
 }
 
 struct leave_vm_options {
-       unsigned int flags;
+       uint64_t flags;
        signed char record_gain;
 };
 
@@ -3018,7 +3014,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
        char priority[16];
        char origtime[16];
        char dir[PATH_MAX], tmpdir[PATH_MAX];
-       char dest[PATH_MAX];
        char fn[PATH_MAX];
        char prefile[PATH_MAX] = "";
        char tempfile[PATH_MAX] = "";
@@ -3055,16 +3050,14 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
        if (strcmp(vmu->context, "default"))
                snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
        else
-               ast_copy_string(ext_context, vmu->context, sizeof(ext_context));
+               ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
        if (ast_test_flag(options, OPT_BUSY_GREETING)) {
-               res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
                snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
        } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
-               res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
                snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
        }
        snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
-       if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
+       if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
                ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
                return -1;
        }
@@ -3074,7 +3067,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
        DISPOSE(tempfile, -1);
        /* It's easier just to try to make it than to check for its existence */
        create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
-       create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
 
        /* Check current or macro-calling context for special extensions */
        if (ast_test_flag(vmu, VM_OPERATOR)) {
@@ -3187,8 +3179,25 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
                        ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
                        return -1;
                }
-               if((vms = get_vm_state_by_mailbox(ext,0))) 
-                       vms->newmessages++; /*still need to increment new message count*/
+               if(!(vms = get_vm_state_by_mailbox(ext,0))) {
+               /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
+                * rarely be used*/
+                       if (!(vms = ast_calloc(1, sizeof(*vms)))) {
+                               ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
+                               return -1;
+                       }
+                       ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
+                       ast_copy_string(vms->username, ext, sizeof(vms->username));
+                       vms->mailstream = NIL;
+                       ast_debug(3, "Copied %s to %s\n", vmu->imapuser, vms->imapuser);
+                       vms->updated=1;
+                       ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
+                       init_vm_state(vms);
+                       vmstate_insert(vms);
+                       vms = get_vm_state_by_mailbox(ext,0);
+               }
+               vms->newmessages++;
+               
                /* here is a big difference! We add one to it later */
                msgnum = newmsgs + oldmsgs;
                ast_debug(3, "Messagecount set to %d\n",msgnum);
@@ -3320,6 +3329,11 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
                                        ast_filerename(tmptxtfile, fn, NULL);
                                        rename(tmptxtfile, txtfile);
 
+                                       /* Properly set permissions on voicemail text descriptor file.
+                                          Unfortunately mkstemp() makes this file 0600 on most unix systems. */
+                                       if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0)
+                                               ast_log(LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
+
                                        ast_unlock_path(dir);
                                        if (ast_check_realtime("voicemail_data")) {
                                                snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
@@ -4158,6 +4172,7 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
        char *temp;
        char todir[256];
        int todircount=0;
+       struct vm_state *dstvms;
 #endif
        char username[70]="";
        int res = 0, cmd = 0;
@@ -4348,7 +4363,19 @@ static int forward_message(struct ast_channel *chan, char *context, struct vm_st
                                /* should not assume "fmt" here! */
                                save_body(body,vms,"2",fmt);
  
-                               STORE(todir, vmtmp->mailbox, vmtmp->context, vms->curmsg, chan, vmtmp, fmt, duration, vms);
+                               /* get destination mailbox */
+                               dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
+                               if (dstvms) {
+                                       init_mailstream(dstvms, 0);
+                                       if (!dstvms->mailstream) {
+                                               ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
+                                       } else {
+                                               STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
+                                               run_externnotify(vmtmp->context, vmtmp->mailbox); 
+                                       }
+                               } else {
+                                       ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
+                               }
 
                                if (!ast_strlen_zero(vmtmp->serveremail))
                                        myserveremail = vmtmp->serveremail;
@@ -4444,8 +4471,7 @@ static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *v
        /* Set the DIFF_* variables */
        ast_localtime(&t, &time_now, NULL);
        tv_now = ast_tvnow();
-       tnow = tv_now.tv_sec;
-       ast_localtime(&tnow, &time_then, NULL);
+       ast_localtime(&tv_now, &time_then, NULL);
 
        /* Day difference */
        if (time_now.tm_year == time_then.tm_year)
@@ -5031,8 +5057,7 @@ static int imap_retrieve_file (char *dir, int msgnum, char *mailbox, char *conte
                return -1;
        }
 
-       for (i = 0; i < vms_p->mailstream->nmsgs; i++)
-       {
+       for (i = 0; i < vms_p->mailstream->nmsgs; i++) {
                mail_fetchstructure(vms_p->mailstream, i + 1, &body);
                /* We have the body, now we extract the file name of the first attachment. */
                if (body->nested.part->next && body->nested.part->next->body.parameter->value) {
@@ -5042,8 +5067,7 @@ static int imap_retrieve_file (char *dir, int msgnum, char *mailbox, char *conte
                        return -1;
                }
                filename = strsep(&attachment, ".");
-               if (!strcmp(filename, file))
-               {
+               if (!strcmp(filename, file)) {
                        ast_copy_string(vms_p->fn, dir, sizeof(vms_p->fn));
                        vms_p->msgArray[vms_p->curmsg] = i + 1;
                        save_body(body, vms_p, "2", attachment);
@@ -5083,8 +5107,7 @@ static int imap_delete_old_greeting (char *dir, struct vm_state *vms)
                        return -1;
                }
                filename = strsep(&attachment, ".");
-               if (!strcmp(filename, file))
-               {
+               if (!strcmp(filename, file)) {
                        sprintf (arg,"%d", i+1);
                        mail_setflag (vms->mailstream,arg,"\\DELETED");
                }
@@ -6380,13 +6403,11 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
 
 static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
 {
-       int res;
        int cmd = 0;
        int retries = 0;
        int duration = 0;
        char prefile[PATH_MAX] = "";
        unsigned char buf[256];
-       char dest[PATH_MAX];
        int bytes = 0;
 
        if (ast_adsi_available(chan)) {
@@ -6399,10 +6420,6 @@ static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, st
        }
 
        snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
-       if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
-               ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
-               return -1;
-       }
        while((cmd >= 0) && (cmd != 't')) {
                if (cmd)
                        retries = 0;
@@ -6705,7 +6722,6 @@ static int vm_execmain(struct ast_channel *chan, void *data)
        int res=-1;
        int cmd=0;
        int valid = 0;
-       struct ast_module_user *u;
        char prefixstr[80] ="";
        char ext_context[256]="";
        int box;
@@ -6722,7 +6738,6 @@ static int vm_execmain(struct ast_channel *chan, void *data)
 #ifdef IMAP_STORAGE
        int deleted = 0;
 #endif
-       u = ast_module_user_add(chan);
 
        /* Add the vm_state to the active list and keep it active */
        memset(&vms, 0, sizeof(vms));
@@ -6748,16 +6763,13 @@ static int vm_execmain(struct ast_channel *chan, void *data)
                AST_STANDARD_APP_ARGS(args, parse);
 
                if (args.argc == 2) {
-                       if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
-                               ast_module_user_remove(u);
+                       if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
                                return -1;
-                       }
                        if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
                                int gain;
                                if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
                                        if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
                                                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
-                                               ast_module_user_remove(u);
                                                return -1;
                                        } else {
                                                record_gain = (signed char) gain;
@@ -7247,7 +7259,6 @@ out:
                free(vms.deleted);
        if (vms.heard)
                free(vms.heard);
-       ast_module_user_remove(u);
 
        return res;
 }
@@ -7255,7 +7266,6 @@ out:
 static int vm_exec(struct ast_channel *chan, void *data)
 {
        int res = 0;
-       struct ast_module_user *u;
        char *tmp;
        struct leave_vm_options leave_options;
        struct ast_flags flags = { 0 };
@@ -7264,8 +7274,6 @@ static int vm_exec(struct ast_channel *chan, void *data)
                AST_APP_ARG(argv0);
                AST_APP_ARG(argv1);
        );
-
-       u = ast_module_user_add(chan);
        
        memset(&leave_options, 0, sizeof(leave_options));
 
@@ -7276,17 +7284,14 @@ static int vm_exec(struct ast_channel *chan, void *data)
                tmp = ast_strdupa(data);
                AST_STANDARD_APP_ARGS(args, tmp);
                if (args.argc == 2) {
-                       if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
-                               ast_module_user_remove(u);
+                       if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
                                return -1;
-                       }
                        ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING);
                        if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
                                int gain;
 
                                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
                                        ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
-                                       ast_module_user_remove(u);
                                        return -1;
                                } else {
                                        leave_options.record_gain = (signed char) gain;
@@ -7296,14 +7301,10 @@ static int vm_exec(struct ast_channel *chan, void *data)
        } else {
                char tmp[256];
                res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
-               if (res < 0) {
-                       ast_module_user_remove(u);
+               if (res < 0)
                        return res;
-               }
-               if (ast_strlen_zero(tmp)) {
-                       ast_module_user_remove(u);
+               if (ast_strlen_zero(tmp))
                        return 0;
-               }
                args.argv0 = ast_strdupa(tmp);
        }
 
@@ -7314,8 +7315,6 @@ static int vm_exec(struct ast_channel *chan, void *data)
                pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
                res = 0;
        }
-       
-       ast_module_user_remove(u);
 
        return res;
 }
@@ -7387,7 +7386,6 @@ static int append_mailbox(char *context, char *mbox, char *data)
 
 static int vm_box_exists(struct ast_channel *chan, void *data) 
 {
-       struct ast_module_user *u;
        struct ast_vm_user svm;
        char *context, *box;
        AST_DECLARE_APP_ARGS(args,
@@ -7401,8 +7399,6 @@ static int vm_box_exists(struct ast_channel *chan, void *data)
                return -1;
        }
 
-       u = ast_module_user_add(chan);
-
        if (!dep_warning) {
                dep_warning = 1;
                ast_log(LOG_WARNING, "MailboxExists is deprecated.  Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *)data);
@@ -7424,7 +7420,7 @@ static int vm_box_exists(struct ast_channel *chan, void *data)
                pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
        } else
                pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
-       ast_module_user_remove(u);
+
        return 0;
 }
 
@@ -7454,14 +7450,11 @@ static struct ast_custom_function mailbox_exists_acf = {
 
 static int vmauthenticate(struct ast_channel *chan, void *data)
 {
-       struct ast_module_user *u;
        char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
        struct ast_vm_user vmus;
        char *options = NULL;
        int silent = 0, skipuser = 0;
        int res = -1;
-
-       u = ast_module_user_add(chan);
        
        if (s) {
                s = ast_strdupa(s);
@@ -7488,7 +7481,6 @@ static int vmauthenticate(struct ast_channel *chan, void *data)
                res = 0;
        }
 
-       ast_module_user_remove(u);
        return res;
 }
 
@@ -8479,8 +8471,6 @@ static int unload_module(void)
        res |= ast_manager_unregister("VoicemailUsersList");
        ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
        ast_uninstall_vm_functions();
-       
-       ast_module_user_hangup_all();
 
        if (poll_thread != AST_PTHREADT_NULL)
                stop_poll_thread();
@@ -8637,7 +8627,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
 
        make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
        snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
-       RETRIEVE(vms->curdir, vms->curms, vmu->mailbox, vmu->context);
+       RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
        msg_cfg = ast_config_load(filename);
        DISPOSE(vms->curdir, vms->curmsg);
        if (!msg_cfg) {
@@ -9495,7 +9485,7 @@ static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive)
                        continue;
                }
 
-               if (interactive == 2 || vlist->vms->interactive == interactive) {
+               if (!strcmp(vlist->vms->imapuser, user) && (interactive == 2 || vlist->vms->interactive == interactive)) {
                        AST_LIST_UNLOCK(&vmstates);
                        return vlist->vms;
                }