Use zaptel timers to wake up processes
[asterisk/asterisk.git] / apps / app_voicemail2.c
index 1a46481..f2bb854 100755 (executable)
@@ -136,6 +136,7 @@ static char vmfmts[80];
 static int vmmaxmessage;
 static int maxgreet;
 static int skipms;
+static int maxlogins;
 
 STANDARD_LOCAL_USER;
 
@@ -182,6 +183,27 @@ static struct ast_vm_user *find_user(struct ast_vm_user *ivm, char *context, cha
        return vmu;
 }
 
+static int reset_user_pw(char *context, char *mailbox, char *newpass)
+{
+       /* This function could be made to generate one from a database, too */
+       struct ast_vm_user *cur;
+       int res = -1;
+       ast_pthread_mutex_lock(&vmlock);
+       cur = users;
+       while(cur) {
+               if ((!context || !strcasecmp(context, cur->context)) &&
+                       (!strcasecmp(mailbox, cur->mailbox)))
+                               break;
+               cur=cur->next;
+       }
+       if (cur) {
+               strncpy(cur->password, newpass, sizeof(cur->password) - 1);
+               res = 0;
+       }
+       ast_pthread_mutex_unlock(&vmlock);
+       return res;
+}
+
 static int vm_change_password(struct ast_vm_user *vmu, char *newpassword)
 {
         /*  There's probably a better way of doing this. */
@@ -256,6 +278,8 @@ static int vm_change_password(struct ast_vm_user *vmu, char *newpassword)
 
         unlink((char *)tmpin);
         rename((char *)tmpout,(char *)tmpin);
+       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
+       strncpy(vmu->password, newpassword, sizeof(vmu->password) - 1);
        return(1);
 }
 
@@ -392,6 +416,8 @@ static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *m
        char dur[256];
        time_t t;
        struct tm tm;
+       if (!strcmp(format, "wav49"))
+               format = "WAV";
        p = popen(SENDMAIL, "w");
        if (p) {
                gethostname(host, sizeof(host));
@@ -577,7 +603,7 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
                time(&start);
        for (x=0;x<fmtcnt;x++) {
                others[x] = ast_writefile(recordfile, sfmt[x], comment, O_TRUNC, 0, 0700);
-               ast_verbose( VERBOSE_PREFIX_3 "x=%i, open writing:  %s format: %s\n", x, recordfile, sfmt[x]);
+               ast_verbose( VERBOSE_PREFIX_3 "x=%i, open writing:  %s format: %s, %p\n", x, recordfile, sfmt[x], others[x]);
                        
                if (!others[x]) {
                        break;
@@ -652,6 +678,8 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor
        for (x=0;x<fmtcnt;x++) {
                if (!others[x])
                        break;
+               ast_stream_rewind(others[x], 1000);
+               ast_truncstream(others[x]);
                ast_closestream(others[x]);
        }
        if (outmsg) {
@@ -679,7 +707,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
        FILE *txt;
        int res = 0;
        int msgnum;
-       int maxmessage=0;
        char date[256];
        char dir[256];
        char fn[256];
@@ -767,7 +794,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
                        free_user(vmu);
                        return 0;
                }
-               if (!res && (silent < 2)) {
+               if (res >= 0) {
                        /* Unless we're *really* silent, try to send the beep */
                        res = ast_streamfile(chan, "beep", chan->language);
                        if (!res)
@@ -820,7 +847,9 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
                                        fclose(txt);
                                } else
                                        ast_log(LOG_WARNING, "Error opening text file for output\n");
-                               res = play_and_record(chan, NULL, fn, maxmessage, fmt);
+                               res = play_and_record(chan, NULL, fn, vmmaxmessage, fmt);
+                               if (res > 0)
+                                       res = 0;
                                txt = fopen(txtfile, "a");
                                if (txt) {
                                        time(&end);
@@ -1474,7 +1503,7 @@ static int get_folder2(struct ast_channel *chan, char *fn, int start)
        int res = 0;
        res = play_and_wait(chan, fn);
        while (((res < '0') || (res > '9')) &&
-                       (res != '#') && (res > 0)) {
+                       (res != '#') && (res >= 0)) {
                res = get_folder(chan, 0);
        }
        return res;
@@ -1841,6 +1870,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
        char fmtc[256] = "";
        char password[80];
        struct vm_state vms;
+       int logretries = 0;
        struct ast_vm_user *vmu = NULL, vmus;
        char *context=NULL;
 
@@ -1895,7 +1925,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
        
        /* Authenticate them and get their mailbox/password */
        
-       while (!valid) {
+       while (!valid && (logretries < maxlogins)) {
                /* Prompt for, and read in the username */
                if (!skipuser && ast_readstring(chan, vms.username, sizeof(vms.username) - 1, 2000, 10000, "#") < 0) {
                        ast_log(LOG_WARNING, "Couldn't read username\n");
@@ -1939,6 +1969,13 @@ static int vm_execmain(struct ast_channel *chan, void *data)
                        if (ast_streamfile(chan, "vm-incorrect", chan->language))
                                break;
                }
+               logretries++;
+       }
+       if (!valid && (logretries >= maxlogins)) {
+               ast_stopstream(chan);
+               res = play_and_wait(chan, "vm-goodbye");
+               if (res > 0)
+                       res = 0;
        }
 
        if (valid) {
@@ -1990,6 +2027,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
                        case '2': /* Change folders */
                                if (useadsi)
                                        adsi_folders(chan, 0, "Change to folder...");
+                               cmd = get_folder2(chan, "vm-changeto", 0);
                                if (cmd == '#') {
                                        cmd = 0;
                                } else if (cmd > 0) {
@@ -2091,7 +2129,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
                                break;
                        }
                }
-               if (cmd == 't') {
+               if ((cmd == 't') || (cmd == '#')) {
                        /* Timeout */
                        res = 0;
                } else {
@@ -2100,7 +2138,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
                }
        }
 out:
-       if ((res > -1) && (cmd != '#')) {
+       if (res > -1) {
                ast_stopstream(chan);
                adsi_goodbye(chan);
                if (useadsi)
@@ -2261,6 +2299,15 @@ static int load_users(void)
                        }
                }
 
+               maxlogins = 3;
+               if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
+                       if (sscanf(s, "%d", &x) == 1) {
+                               maxlogins = x;
+                       } else {
+                               ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
+                       }
+               }
+
                cat = ast_category_browse(cfg, NULL);
                while(cat) {
                        if (strcasecmp(cat, "general")) {