diff -Naur asterisk-dev-original/apps/app_voicemail.c asterisk/apps/app_voicemail.c --- asterisk-dev-original/apps/app_voicemail.c 2005-05-08 18:44:25.000000000 +0200 +++ asterisk/apps/app_voicemail.c 2005-05-16 12:40:07.076169916 +0200 @@ -12,6 +12,9 @@ * * 12-16 - 2005 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) * George Konstantoulakis + * + * 05-11 - 2005 : An option for maximum number of messsages per mailbox added by GDS Partners (www.gdspartners.com) + * Stojan Sljivic */ #include "asterisk/lock.h" @@ -61,6 +64,7 @@ #define INTRO "vm-intro" #define MAXMSG 100 +#define MAXMSGLIMIT 9999 #define BASEMAXINLINE 256 #define BASELINELEN 72 @@ -156,6 +160,7 @@ char exit[80]; unsigned int flags; /* VM_ flags */ int saydurationm; + int maxmsg; /* Maximum number of msgs per folder for this mailbox */ struct ast_vm_user *next; }; @@ -173,8 +178,8 @@ char vmbox[256]; char fn[256]; char fn2[256]; - int deleted[MAXMSG]; - int heard[MAXMSG]; + int *deleted; + int *heard; int curmsg; int lastmsg; int newmessages; @@ -285,7 +290,9 @@ struct ast_vm_user *usersl; struct vm_zone *zones = NULL; struct vm_zone *zonesl = NULL; +static struct ast_config *voicemailCfg; static int maxsilence; +static int maxmsg; static int silencethreshold = 128; static char serveremail[80]; static char mailcmd[160]; /* Configurable mail cmd */ @@ -378,6 +385,15 @@ strncpy(vmu->dialout, value, sizeof(vmu->dialout) -1); } else if (!strcasecmp(var, "exitcontext")) { strncpy(vmu->exit, value, sizeof(vmu->exit) -1); + } else if (!strcasecmp(var, "maxmsg")) { + vmu->maxmsg = atoi(value); + if (vmu->maxmsg <= 0) { + ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG); + vmu->maxmsg = MAXMSG; + } else if (vmu->maxmsg > MAXMSGLIMIT) { + ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); + vmu->maxmsg = MAXMSGLIMIT; + } } else if (!strcasecmp(var, "options")) { apply_options(vmu, value); } @@ -406,7 +422,7 @@ if ((var = strsep(&value, "=")) && value) { apply_option(vmu, var, value); } - } + } } static struct ast_vm_user *find_user_realtime(struct ast_vm_user *ivm, const char *context, const char *mailbox) @@ -810,7 +826,7 @@ return 0; } -static int last_message_index(char *dir) +static int last_message_index(struct ast_vm_user *vmu, char *dir) { int x = 0; int res; @@ -930,9 +946,9 @@ } -static int count_messages(char *dir) +static int count_messages(struct ast_vm_user *vmu, char *dir) { - return last_message_index(dir) + 1; + return last_message_index(vmu, dir) + 1; } static void delete_file(char *sdir, int smsg) { @@ -1197,7 +1213,7 @@ #else -static int count_messages(char *dir) +static int count_messages(struct ast_vm_user *vmu, char *dir) { /* Find all .txt files - even if they are not in sequence from 0000 */ @@ -1288,12 +1304,12 @@ copy(frompath2, topath2); } -static int last_message_index(char *dir) +static int last_message_index(struct ast_vm_user *vmu, char *dir) { int x; char fn[256]; ast_lock_path(dir); - for (x=0;xmaxmsg;x++) { make_file(fn, sizeof(fn), dir, x); if (ast_fileexists(fn, NULL, NULL) < 1) break; @@ -1937,8 +1953,8 @@ if (!EXISTS(todir, recipmsgnum, topath, chan->language)) break; recipmsgnum++; - } while (recipmsgnum < MAXMSG); - if (recipmsgnum < MAXMSG) { + } while (recipmsgnum < recip->maxmsg); + if (recipmsgnum < recip->maxmsg) { COPY(fromdir, msgnum, todir, recipmsgnum, frompath, topath); } else { ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); @@ -2141,8 +2157,8 @@ if (!EXISTS(dir,msgnum,fn,chan->language)) break; msgnum++; - } while (msgnum < MAXMSG); - if (msgnum < MAXMSG) { + } while (msgnum < vmu->maxmsg); + if (msgnum < vmu->maxmsg) { /* assign a variable with the name of the voicemail file */ pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); @@ -2243,7 +2259,7 @@ } -static void resequence_mailbox(char * dir) +static void resequence_mailbox(struct ast_vm_user *vmu, char * dir) { /* we know max messages, so stop process when number is hit */ @@ -2252,7 +2268,7 @@ char dfn[256]; ast_lock_path(dir); - for (x=0,dest=0;xmaxmsg;x++) { make_file(sfn, sizeof(sfn), dir, x); if (EXISTS(dir, x, sfn, NULL)) { @@ -2275,7 +2291,7 @@ return d; } -static int save_to_folder(char *dir, int msg, char *context, char *username, int box) +static int save_to_folder(struct ast_vm_user *vmu, char *dir, int msg, char *context, char *username, int box) { char sfn[256]; char dfn[256]; @@ -2286,12 +2302,12 @@ make_dir(ddir, sizeof(ddir), context, username, dbox); mkdir(ddir, 0700); ast_lock_path(ddir); - for (x=0;xmaxmsg;x++) { make_file(dfn, sizeof(dfn), ddir, x); if (!EXISTS(ddir, x, dfn, NULL)) break; } - if (x >= MAXMSG) { + if (x >= vmu->maxmsg) { ast_unlock_path(ddir); return -1; } @@ -3071,7 +3087,7 @@ ast_log(LOG_DEBUG, "%s", sys); ast_safe_system(sys); - todircount = count_messages(todir); + todircount = count_messages(receiver, todir); strncpy(tmp, fmt, sizeof(tmp) - 1); stringp = tmp; while ((s = strsep(&stringp, "|"))) { @@ -3389,7 +3405,7 @@ { strncpy(vms->curbox, mbox(box), sizeof(vms->curbox) - 1); make_dir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); - vms->lastmsg = count_messages(vms->curdir) - 1; + vms->lastmsg = count_messages(vmu, vms->curdir) - 1; /* The following test is needed in case sequencing gets messed up. @@ -3398,10 +3414,10 @@ detected. */ - if(vms->lastmsg != last_message_index(vms->curdir)) + if(vms->lastmsg != last_message_index(vmu, vms->curdir)) { ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir); - resequence_mailbox(vms->curdir); + resequence_mailbox(vmu, vms->curdir); } snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); @@ -3414,7 +3430,7 @@ /* Get the deleted messages fixed */ ast_lock_path(vms->curdir); vms->curmsg = -1; - for (x=0;x < MAXMSG;x++) { + for (x=0;x < vmu->maxmsg;x++) { if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { /* Save this message. It's not in INBOX or hasn't been heard */ make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); @@ -3427,15 +3443,19 @@ } } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { /* Move to old folder before deleting */ - save_to_folder(vms->curdir, x, vmu->context, vms->username, 1); + if (save_to_folder(vmu, vms->curdir, x, vmu->context, vms->username, 1)) { + vms->deleted[x] = 0; + vms->heard[x] = 0; + --x; /* If move failed do not delete the message */ + } } } - for (x = vms->curmsg + 1; x <= MAXMSG; x++) { + for (x = vms->curmsg + 1; x <= vmu->maxmsg; x++) { make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); if (!EXISTS(vms->curdir, x, vms->fn, NULL)) break; DELETE(vms->curdir, x, vms->fn); - } + } ast_unlock_path(vms->curdir); } memset(vms->deleted, 0, sizeof(vms->deleted)); @@ -4495,7 +4515,7 @@ char *options; LOCAL_USER_ADD(u); - memset(&vms, 0, sizeof(vms)); + memset(&vms, 0, sizeof(vms)); memset(&vmus, 0, sizeof(vmus)); strncpy(fmtc, vmfmts, sizeof(fmtc) - 1); if (chan->_state != AST_STATE_UP) @@ -4566,6 +4586,9 @@ adsi_begin(chan, &useadsi); if (valid) { + vms.deleted = calloc(vmu->maxmsg, sizeof(int)); + vms.heard = calloc(vmu->maxmsg, sizeof(int)); + /* Set language from config to override channel language */ if (vmu->language && !ast_strlen_zero(vmu->language)) strncpy(chan->language, vmu->language, sizeof(chan->language)-1); @@ -4784,21 +4807,26 @@ break; } else if (cmd > 0) { box = cmd = cmd - '0'; - cmd = save_to_folder(vms.curdir, vms.curmsg, vmu->context, vms.username, cmd); - vms.deleted[vms.curmsg]=1; + cmd = save_to_folder(vmu, vms.curdir, vms.curmsg, vmu->context, vms.username, cmd); + if (!cmd) + vms.deleted[vms.curmsg]=1; + else { + vms.deleted[vms.curmsg]=0; + vms.heard[vms.curmsg]=0; + } } make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); if (useadsi) adsi_message(chan, &vms); - if (!cmd) - cmd = ast_play_and_wait(chan, "vm-message"); - if (!cmd) - cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); - if (!cmd) - cmd = ast_play_and_wait(chan, "vm-savedto"); snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box)); - if (!cmd) - cmd = vm_play_folder_name(chan, vms.fn); + if (!cmd) { + ast_play_and_wait(chan, "vm-message"); + say_and_wait(chan, vms.curmsg + 1, chan->language); + ast_play_and_wait(chan, "vm-savedto"); + vm_play_folder_name(chan, vms.fn); + } else { + cmd = ast_play_and_wait(chan, "vm-mailboxfull"); + } if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { if (vms.curmsg < vms.lastmsg) { vms.curmsg++; @@ -4863,6 +4891,10 @@ } if (vmu) free_user(vmu); + if (vms.deleted) + free(vms.deleted); + if (vms.heard) + free(vms.heard); LOCAL_USER_REMOVE(u); return res; @@ -4933,6 +4965,7 @@ char tmp[256] = ""; char *stringp; char *s; + char *maxmsgstr; struct ast_vm_user *vmu; strncpy(tmp, data, sizeof(tmp) - 1); vmu = malloc(sizeof(struct ast_vm_user)); @@ -4952,6 +4985,25 @@ strncpy(vmu->pager, s, sizeof(vmu->pager) - 1); if (stringp && (s = strsep(&stringp, ","))) apply_options(vmu, s); + + /* Check whether maxmsg was defined on the mailbox level */ + if (vmu->maxmsg <= 0) { + /* Read the maxmsg from the context definition */ + if ((maxmsgstr = ast_variable_retrieve(voicemailCfg, context, "maxmsg"))) { + vmu->maxmsg = atoi(maxmsgstr); + if (vmu->maxmsg <= 0) { + ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", maxmsgstr, MAXMSG); + vmu->maxmsg = MAXMSG; + } else if (vmu->maxmsg > MAXMSGLIMIT) { + ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, maxmsgstr); + vmu->maxmsg = MAXMSGLIMIT; + } + } else { + /* Use the maxmsg from the general section definition */ + vmu->maxmsg = maxmsg; + } + } + vmu->next = NULL; if (usersl) usersl->next = vmu; @@ -5156,6 +5208,7 @@ char *astsaydurationinfo; char *astsaydurationminfo; char *silencestr; + char *maxmsgstr; char *astdirfwd; char *thresholdstr; char *fmt; @@ -5170,6 +5223,7 @@ int tmpadsi[4]; cfg = ast_config_load(VOICEMAIL_CONFIG); + voicemailCfg = cfg; ast_mutex_lock(&vmlock); cur = users; while (cur) { @@ -5214,6 +5268,19 @@ if (maxsilence > 0) maxsilence *= 1000; } + + if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) { + maxmsg = MAXMSG; + } else { + maxmsg = atoi(maxmsgstr); + if (maxmsg <= 0) { + ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", maxmsgstr, MAXMSG); + maxmsg = MAXMSG; + } else if (maxmsg > MAXMSGLIMIT) { + ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, maxmsgstr); + maxmsg = MAXMSGLIMIT; + } + } /* External password changing command */ if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) { @@ -5388,7 +5455,6 @@ if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) astdirfwd = "no"; ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); - cat = ast_category_browse(cfg, NULL); while (cat) { if (strcasecmp(cat, "general")) { @@ -5505,7 +5571,6 @@ tmpread = tmpwrite+len; } } - ast_config_destroy(cfg); ast_mutex_unlock(&vmlock); return 0; } else { @@ -5531,6 +5596,8 @@ ast_cli_unregister(&show_voicemail_users_cli); ast_cli_unregister(&show_voicemail_zones_cli); ast_uninstall_vm_functions(); + if (voicemailCfg) + ast_config_destroy(voicemailCfg); return res; } diff -Naur asterisk-dev-original/configs/voicemail.conf.sample asterisk/configs/voicemail.conf.sample --- asterisk-dev-original/configs/voicemail.conf.sample 2005-04-06 20:55:33.000000000 +0200 +++ asterisk/configs/voicemail.conf.sample 2005-05-16 12:46:18.389880499 +0200 @@ -10,6 +10,9 @@ ;serveremail=asterisk@linux-support.net ; Should the email contain the voicemail as an attachment attach=yes +; Maximum number of messages per folder. If not specified a default value (100) is used. +; Maximum value for this option is 9999. +;maxmsg=100 ; Maximum length of a voicemail message in seconds ;maxmessage=180 ; Minimum length of a voicemail message in seconds @@ -143,8 +146,11 @@ central24=America/Chicago|'vm-received' q 'digits/at' H 'digits/hundred' M 'hours' [default] +; Define maximum number of messages per folder for partcular context. +;maxmsg=50 + 1234 => 4242,Example Mailbox,root@localhost -;4200 => 9855,Mark Spencer,markster@linux-support.net,mypager@digium.com,attach=no|serveremail=myaddy@digium.com|tz=central +;4200 => 9855,Mark Spencer,markster@linux-support.net,mypager@digium.com,attach=no|serveremail=myaddy@digium.com|tz=central|maxmsg=10 ;4300 => 3456,Ben Rigas,ben@american-computer.net ;4310 => -5432,Sales,sales@marko.net ;4069 => 6522,Matt Brooks,matt@marko.net,,|tz=central|attach=yes|saycid=yes|dialout=fromvm|callback=fromvm|review=yes|operator=yes|envelope=yes|sayduration=yes|saydurationm=1