aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rwxr-xr-xapps/app_alarmreceiver.c2
-rwxr-xr-xapps/app_chanisavail.c11
-rwxr-xr-xapps/app_controlplayback.c15
-rwxr-xr-xapps/app_cut.c4
-rwxr-xr-xapps/app_dial.c40
-rwxr-xr-xapps/app_disa.c18
-rwxr-xr-xapps/app_eval.c4
-rwxr-xr-xapps/app_festival.c7
-rwxr-xr-xapps/app_forkcdr.c7
-rwxr-xr-xapps/app_getcpeid.c10
-rwxr-xr-xapps/app_hasnewvoicemail.c28
-rwxr-xr-xapps/app_macro.c3
-rwxr-xr-xapps/app_meetme.c20
-rwxr-xr-xapps/app_parkandannounce.c4
-rwxr-xr-xapps/app_qcall.c2
-rwxr-xr-xapps/app_queue.c134
-rwxr-xr-xapps/app_random.c1
-rwxr-xr-xapps/app_read.c3
-rwxr-xr-xapps/app_record.c2
-rwxr-xr-xapps/app_sms.c14
-rwxr-xr-xapps/app_sql_postgres.c2
-rwxr-xr-xapps/app_test.c13
-rwxr-xr-xapps/app_userevent.c2
-rwxr-xr-xapps/app_voicemail.c425
24 files changed, 478 insertions, 293 deletions
diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c
index 28d28b4c4..552423036 100755
--- a/apps/app_alarmreceiver.c
+++ b/apps/app_alarmreceiver.c
@@ -55,7 +55,7 @@ static char *tdesc = "Alarm Receiver for Asterisk";
static char *app = "AlarmReceiver";
-static char *synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel\n";
+static char *synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel";
static char *descrip =
"Alarm receiver application for Asterisk. Only 1 signalling format is supported at this time:\n"
"Ademco Contact ID. This application should be called whenever there is an alarm panel calling in\n"
diff --git a/apps/app_chanisavail.c b/apps/app_chanisavail.c
index 4438663ce..07ea55c79 100755
--- a/apps/app_chanisavail.c
+++ b/apps/app_chanisavail.c
@@ -38,11 +38,12 @@ static char *descrip =
"Checks is any of the requested channels are available. If none\n"
"of the requested channels are available the new priority will be\n"
"n+101 (unless such a priority does not exist or on error, in which\n"
-"case ChanIsAvail will return -1). If any of the requested channels\n"
-"are available, the next priority will be n+1, the channel variable\n"
-"${AVAILCHAN} will be set to the name of the available channel and\n"
-"the ChanIsAvail app will return 0. ${AVAILORIGCHAN} is\n"
-"the canonical channel name that was used to create the channel.\n";
+"case ChanIsAvail will return -1).\n"
+"If any of the requested channels are available, the next priority will be n+1,\n"
+"the channel variable ${AVAILCHAN} will be set to the name of the available channel\n"
+"and the ChanIsAvail app will return 0.\n"
+"${AVAILORIGCHAN} is the canonical channel name that was used to create the channel.\n"
+"${AVAILSTATUS} is the status code for the channel.\n";
STANDARD_LOCAL_USER;
diff --git a/apps/app_controlplayback.c b/apps/app_controlplayback.c
index b44eafba9..aa6dd3435 100755
--- a/apps/app_controlplayback.c
+++ b/apps/app_controlplayback.c
@@ -64,24 +64,19 @@ static int controlplayback_exec(struct ast_channel *chan, void *data)
file = tmp;
if ((skip=strchr(tmp,'|'))) {
- *skip = '\0';
- *skip++;
+ *skip++ = '\0';
fwd=strchr(skip,'|');
if (fwd) {
- *fwd = '\0';
- *fwd++;
+ *fwd++ = '\0';
rev = strchr(fwd,'|');
if (rev) {
- *rev = '\0';
- *rev++;
+ *rev++ = '\0';
stop = strchr(rev,'|');
if (stop) {
- *stop = '\0';
- *stop++;
+ *stop++ = '\0';
pause = strchr(stop,'|');
if (pause) {
- *pause = '\0';
- *pause++;
+ *pause++ = '\0';
}
}
}
diff --git a/apps/app_cut.c b/apps/app_cut.c
index da397f66e..afaaf8473 100755
--- a/apps/app_cut.c
+++ b/apps/app_cut.c
@@ -31,10 +31,10 @@ static char *tdesc = "Cuts up variables";
static char *app_cut = "Cut";
-static char *cut_synopsis = "Cut(newvar=varname|delimiter|fieldspec)";
+static char *cut_synopsis = "Splits a variable's content using the specified delimiter";
static char *cut_descrip =
-"Cut(newvar=varname,delimiter,field)\n"
+"Usage: Cut(newvar=varname,delimiter,fieldspec)\n"
" newvar - new variable created from result string\n"
" varname - variable you want cut\n"
" delimiter - defaults to '-'\n"
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 7f3c3d768..0d16d0483 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -113,6 +113,7 @@ struct localuser {
int allowdisconnect_in;
int allowdisconnect_out;
int forcecallerid;
+ int noforwardhtml;
struct localuser *next;
};
@@ -134,7 +135,7 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
#define AST_MAX_WATCHERS 256
-static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize)
+static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *noforwardhtml, int *sentringing, char *status, size_t statussize)
{
struct localuser *o;
int found;
@@ -207,6 +208,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
*allowredir_out = o->allowredirect_out;
*allowdisconnect_in = o->allowdisconnect_in;
*allowdisconnect_out = o->allowdisconnect_out;
+ *noforwardhtml = o->noforwardhtml;
}
} else if (o->chan && (o->chan == winner)) {
if (!ast_strlen_zero(o->chan->call_forward)) {
@@ -301,6 +303,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
*allowredir_out = o->allowredirect_out;
*allowdisconnect_in = o->allowdisconnect_in;
*allowdisconnect_out = o->allowdisconnect_out;
+ *noforwardhtml = o->noforwardhtml;
}
break;
case AST_CONTROL_BUSY:
@@ -336,13 +339,14 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
case AST_CONTROL_PROGRESS:
if (option_verbose > 2)
ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
- ast_indicate(in, AST_CONTROL_PROGRESS);
+ if (!outgoing->ringbackonly)
+ ast_indicate(in, AST_CONTROL_PROGRESS);
break;
case AST_CONTROL_OFFHOOK:
/* Ignore going off hook */
break;
case -1:
- if (!outgoing->ringbackonly && !outgoing->musiconhold) {
+ if (!outgoing->ringbackonly || !outgoing->musiconhold) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
ast_indicate(in, -1);
@@ -360,7 +364,14 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
!(outgoing->ringbackonly || outgoing->musiconhold)) {
if (ast_write(in, f))
ast_log(LOG_WARNING, "Unable to forward image\n");
+ } else if (single && (f->frametype == AST_FRAME_TEXT) &&
+ !(outgoing->ringbackonly || outgoing->musiconhold)) {
+ if (ast_write(in, f))
+ ast_log(LOG_WARNING, "Unable to text\n");
+ } else if (single && (f->frametype == AST_FRAME_HTML) && !outgoing->noforwardhtml) {
+ ast_channel_sendhtml(in, f->subclass, f->data, f->datalen);
}
+
ast_frfree(f);
} else {
in->hangupcause = o->chan->hangupcause;
@@ -383,6 +394,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
/* Got hung up */
*to=-1;
strncpy(status, "CANCEL", statussize - 1);
+ if (f)
+ ast_frfree(f);
return NULL;
}
if (f && (f->frametype == AST_FRAME_DTMF) && *allowdisconnect_out &&
@@ -391,8 +404,13 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
*to=0;
strcpy(status, "CANCEL");
+ ast_frfree(f);
return NULL;
}
+
+ if (single && f && (f->frametype == AST_FRAME_HTML) && !outgoing->noforwardhtml)
+ ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen);
+
if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF))) {
if (ast_write(outgoing->chan, f))
ast_log(LOG_WARNING, "Unable to forward voice\n");
@@ -421,6 +439,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
int allowredir_out=0;
int allowdisconnect_in=0;
int allowdisconnect_out=0;
+ int noforwardhtml=0;
int hasmacro = 0;
int privacy=0;
int announce=0;
@@ -726,6 +745,9 @@ static int dial_exec(struct ast_channel *chan, void *data)
if (strchr(transfer, 'f'))
tmp->forcecallerid = 1;
else tmp->forcecallerid = 0;
+ if (url)
+ tmp->noforwardhtml = 1;
+ else tmp->noforwardhtml = 0;
}
strncpy(numsubst, number, sizeof(numsubst)-1);
/* If we're dialing by extension, look at the extension to know what to dial */
@@ -746,6 +768,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
cur = rest;
continue;
}
+ pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
if (!ast_strlen_zero(tmp->chan->call_forward)) {
char tmpchan[256]="";
char *stuff;
@@ -879,7 +902,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
time(&start_time);
- peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status));
+ peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, &noforwardhtml, status, sizeof(status));
if (!peer) {
if (to)
@@ -908,8 +931,11 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_cdr_setdestchan(chan->cdr, peer->name);
if (peer->name)
pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
- if (numsubst)
- pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", numsubst);
+
+ number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
+ if (!number)
+ number = numsubst;
+ pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
/* JDG: sendurl */
if( url && !ast_strlen_zero(url) && ast_channel_supports_html(peer) ) {
ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
@@ -1029,7 +1055,7 @@ out:
LOCAL_USER_REMOVE(u);
- if((go_on>0) && (!chan->_softhangup))
+ if((go_on>0) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
res=0;
return res;
diff --git a/apps/app_disa.c b/apps/app_disa.c
index 03f13c67c..3d4f866f9 100755
--- a/apps/app_disa.c
+++ b/apps/app_disa.c
@@ -161,7 +161,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
if (!strcasecmp(tmp, "no-password"))
{;
- k = 1;
+ k |= 1; /* We have the password */
ast_log(LOG_DEBUG, "DISA no-password login success\n");
}
gettimeofday(&lastdigittime,NULL);
@@ -173,10 +173,10 @@ static int disa_exec(struct ast_channel *chan, void *data)
gettimeofday(&now,NULL);
/* if outa time, give em reorder */
if (ms_diff(&now,&lastdigittime) >
- ((k) ? digittimeout : firstdigittimeout))
+ ((k&2) ? digittimeout : firstdigittimeout))
{
ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n",
- ((k) ? "extension" : "password"),chan->name);
+ ((k&1) ? "extension" : "password"),chan->name);
break;
}
if ((res = ast_waitfor(chan, -1) < 0)) {
@@ -211,13 +211,15 @@ static int disa_exec(struct ast_channel *chan, void *data)
j = f->subclass; /* save digit */
ast_frfree(f);
if (i == 0)
+ {
+ k|=2; /* We have the first digit */
ast_playtones_stop(chan);
-
+ }
gettimeofday(&lastdigittime,NULL);
/* got a DTMF tone */
if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
{
- if (!k) /* if in password state */
+ if (!(k&1)) /* if in password state */
{
if (j == '#') /* end of password */
{
@@ -268,7 +270,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name);
play_dialtone(chan);
- k = 1;
+ k|=1; /* In number mode */
i = 0; /* re-set buffer pointer */
exten[sizeof(acctcode)] = 0;
strncpy(acctcode,exten, sizeof(acctcode) - 1);
@@ -280,7 +282,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
exten[i++] = j; /* save digit */
exten[i] = 0;
- if (!k) continue; /* if getting password, continue doing it */
+ if (!(k&1)) continue; /* if getting password, continue doing it */
/* if this exists */
if (ast_ignore_pattern(ourcontext, exten)) {
@@ -299,7 +301,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
}
}
- if (k && ast_exists_extension(chan,ourcontext,exten,1, chan->callerid))
+ if ((k==3) && (ast_exists_extension(chan,ourcontext,exten,1, chan->callerid)))
{
ast_playtones_stop(chan);
/* We're authenticated and have a valid extension */
diff --git a/apps/app_eval.c b/apps/app_eval.c
index dc61df2f6..de80d9cb6 100755
--- a/apps/app_eval.c
+++ b/apps/app_eval.c
@@ -31,10 +31,10 @@ static char *tdesc = "Reevaluates strings";
static char *app_eval = "Eval";
-static char *eval_synopsis = "Eval(newvar=somestring)";
+static char *eval_synopsis = "Evaluates a string";
static char *eval_descrip =
-"Eval(newvar=somestring)\n"
+"Usage: Eval(newvar=somestring)\n"
" Normally Asterisk evaluates variables inline. But what if you want to\n"
"store variable offsets in a database, to be evaluated later? Eval is\n"
"the answer, by allowing a string to be evaluated twice in the dialplan,\n"
diff --git a/apps/app_festival.c b/apps/app_festival.c
index e7e0bd426..6ce8a4f83 100755
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -131,7 +131,6 @@ static int send_waveform_to_fd(char *waveform, int length, int fd) {
#endif
write(fd,waveform,length);
- write(fd,"a",1);
close(fd);
exit(0);
}
@@ -305,9 +304,9 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
if (!(festivalcommand = ast_variable_retrieve(cfg, "general", "festivalcommand"))) {
festivalcommand = "(tts_textasterisk \"%s\" 'file)(quit)\n";
}
- ast_destroy(cfg);
if (!vdata || ast_strlen_zero(vdata)) {
ast_log(LOG_WARNING, "festival requires an argument (text)\n");
+ ast_destroy(cfg);
return -1;
}
strncpy(data, vdata, sizeof(data) - 1);
@@ -325,6 +324,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
if (fd < 0) {
ast_log(LOG_WARNING,"festival_client: can't get socket\n");
+ ast_destroy(cfg);
return -1;
}
memset(&serv_addr, 0, sizeof(serv_addr));
@@ -333,6 +333,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
serverhost = ast_gethostbyname(host, &ahp);
if (serverhost == (struct hostent *)0) {
ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
+ ast_destroy(cfg);
return -1;
}
memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
@@ -342,6 +343,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
ast_log(LOG_WARNING,"festival_client: connect to server failed\n");
+ ast_destroy(cfg);
return -1;
}
@@ -444,6 +446,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
}
} while (strcmp(ack,"OK\n") != 0);
close(fd);
+ ast_destroy(cfg);
LOCAL_USER_REMOVE(u);
return res;
diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c
index 547bfa45e..460aba0b7 100755
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -20,10 +20,11 @@
#include <string.h>
#include <pthread.h>
-static char *tdesc = "Fork The CDR into 2 seperate entities.";
+static char *tdesc = "Fork The CDR into 2 separate entities.";
static char *app = "ForkCDR";
static char *synopsis =
-"Forks the Call Data Record\n"
+"Forks the Call Data Record";
+static char *descrip =
" ForkCDR(): Causes the Call Data Record to fork an additional\n"
"cdr record starting from the time of the fork call\n";
@@ -68,7 +69,7 @@ int unload_module(void)
int load_module(void)
{
- return ast_register_application(app, forkcdr_exec, synopsis, tdesc);
+ return ast_register_application(app, forkcdr_exec, synopsis, descrip);
}
char *description(void)
diff --git a/apps/app_getcpeid.c b/apps/app_getcpeid.c
index d0a0be6bc..8ebd568e8 100755
--- a/apps/app_getcpeid.c
+++ b/apps/app_getcpeid.c
@@ -3,9 +3,9 @@
*
* Execute arbitrary system commands
*
- * Copyright (C) 1999, Mark Spencer
+ * Copyright (C) 1999-2005, Digium
*
- * Mark Spencer <markster@linux-support.net>
+ * Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
@@ -31,9 +31,9 @@ static char *app = "GetCPEID";
static char *synopsis = "Get ADSI CPE ID";
static char *descrip =
-" GetCPEID: Obtains and displays CPE ID and other information in order to\n"
-"properly setup zapata.conf for on-hook operations. Returns -1 on hanup\n"
-"only.";
+" GetCPEID: Obtains and displays ADSI CPE ID and other information in order\n"
+"to properly setup zapata.conf for on-hook operations.\n"
+"Returns -1 on hangup only.\n";
STANDARD_LOCAL_USER;
diff --git a/apps/app_hasnewvoicemail.c b/apps/app_hasnewvoicemail.c
index 733a65ec8..e74739653 100755
--- a/apps/app_hasnewvoicemail.c
+++ b/apps/app_hasnewvoicemail.c
@@ -38,6 +38,7 @@
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
+#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -70,7 +71,7 @@ static int hasvoicemail_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
- char vmpath[256], *input, *varname = NULL, *vmbox, *vmfolder = "INBOX", *context = "default";
+ char vmpath[256], *temps, *input, *varname = NULL, *vmbox, *vmfolder = "INBOX", *context = "default";
DIR *vmdir;
struct dirent *vment;
int vmcount = 0;
@@ -83,21 +84,22 @@ static int hasvoicemail_exec(struct ast_channel *chan, void *data)
input = ast_strdupa((char *)data);
if (input) {
- if ((vmbox = strsep(&input,":")))
- if ((vmfolder = strsep(&input,"|")))
+ temps = input;
+ if ((temps = strsep(&input, "|"))) {
+ if (input && !ast_strlen_zero(input))
varname = input;
- else
+ input = temps;
+ }
+ if ((temps = strsep(&input, ":"))) {
+ if (input && !ast_strlen_zero(input))
vmfolder = input;
- else
- if ((vmbox = strsep(&input,"|")))
- varname = input;
- else
- vmbox = input;
-
- if (index(vmbox,'@')) {
- context = vmbox;
- vmbox = strsep(&context,"@");
+ input = temps;
}
+ if ((vmbox = strsep(&input, "@")))
+ if (input && !ast_strlen_zero(input))
+ context = input;
+ if (!vmbox)
+ vmbox = input;
snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, vmbox, vmfolder);
if (!(vmdir = opendir(vmpath))) {
diff --git a/apps/app_macro.c b/apps/app_macro.c
index ea6775c90..03da13ed4 100755
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -140,7 +140,8 @@ static int macro_exec(struct ast_channel *chan, void *data)
while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) {
if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid))) {
/* Something bad happened, or a hangup has been requested. */
- if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F'))) {
+ if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
+ (res == '*') || (res == '#')) {
/* Just return result as to the previous application as if it had been dialed */
ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
break;
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index ef2ff3de9..51a8da618 100755
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -524,7 +524,9 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
memset(user, 0, sizeof(struct ast_conf_user));
user->user_no = 0; /* User number 0 means starting up user! (dead - not in the list!) */
-
+
+ time(&user->jointime);
+
if (conf->locked) {
/* Sorry, but this confernce is locked! */
if (!ast_streamfile(chan, "conf-locked", chan->language))
@@ -557,7 +559,6 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
conf->lastuser = user;
}
}
- strncpy(user->usrvalue, "test", sizeof(user->usrvalue) - 1);
user->chan = chan;
user->userflags = confflags;
user->adminflags = 0;
@@ -1043,10 +1044,10 @@ outrun:
else
ast_log(LOG_ERROR, "Bad! Bad! Bad! user->prevuser is NULL but we're not the beginning!\n");
}
- /* Return the number of seconds the user was in the conf */
- snprintf(meetmesecs, sizeof(meetmesecs), "%i", (int) (user->jointime - time(NULL)));
- pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
}
+ /* Return the number of seconds the user was in the conf */
+ snprintf(meetmesecs, sizeof(meetmesecs), "%i", (int) (time(NULL) - user->jointime));
+ pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
}
free(user);
ast_mutex_unlock(&conflock);
@@ -1298,7 +1299,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
if (!found) {
/* At this point, we have a confno_tmp (static conference) that is empty */
if ((empty_no_pin && ((!stringp) || (stringp && (stringp[0] == '\0')))) || (!empty_no_pin)) {
- /* Case 1: empty_no_pin and pin is nonexistant (NULL)
+ /* Case 1: empty_no_pin and pin is nonexistent (NULL)
* Case 2: empty_no_pin and pin is blank (but not NULL)
* Case 3: not empty_no_pin
*/
@@ -1454,14 +1455,17 @@ static int admin_exec(struct ast_channel *chan, void *data) {
command = strsep(&params, "|");
caller = strsep(&params, "|");
- ast_mutex_lock(&conflock);
+ if (!command) {
+ ast_log(LOG_WARNING, "MeetmeAdmin requires a command!\n");
+ ast_mutex_unlock(&conflock);
+ return -1;
+ }
cnf = confs;
while (cnf) {
if (strcmp(cnf->confno, conf) == 0)
break;
cnf = cnf->next;
}
- ast_mutex_unlock(&conflock);
if (caller)
user = find_user(cnf, caller);
diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c
index c3f949ec3..7492dd4b2 100755
--- a/apps/app_parkandannounce.c
+++ b/apps/app_parkandannounce.c
@@ -41,7 +41,7 @@ static char *synopsis = "Park and Announce";
static char *descrip =
" ParkAndAnnounce(announce:template|timeout|dial|[return_context]):\n"
"Park a call into the parkinglot and announce the call over the console.\n"
-"announce template: colon seperated list of files to announce, the word PARKED\n"
+"announce template: colon separated list of files to announce, the word PARKED\n"
" will be replaced by a say_digits of the ext the call is parked in\n"
"timeout: time in seconds before the call returns into the return context.\n"
"dial: The app_dial style resource to call to make the announcement. Console/dsp calls the console.\n"
@@ -94,7 +94,7 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
}
dial=strsep(&s, "|");
if(!dial) {
- ast_log(LOG_WARNING, "PARK: A dial resouce must be specified i.e: Console/dsp or Zap/g1/5551212\n");
+ ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
free(orig_s);
return -1;
} else {
diff --git a/apps/app_qcall.c b/apps/app_qcall.c
index f5721e167..659a39dd7 100755
--- a/apps/app_qcall.c
+++ b/apps/app_qcall.c
@@ -317,7 +317,7 @@ static void *qcall_do(void *arg)
extstr,context,channel->name);
if (strlen(ident)) {
strncat(ident,"-ok", sizeof(ident) - strlen(ident) - 1);
- /* if file existant, play it */
+ /* if file existent, play it */
if (!ast_streamfile(channel,ident,0))
{
ast_waitstream(channel,"");
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 542ede246..929a5c15f 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -96,7 +96,7 @@ static char *descrip =
"Queues an incoming call in a particular call queue as defined in queues.conf.\n"
" This application returns -1 if the originating channel hangs up, or if the\n"
"call is bridged and either of the parties in the bridge terminate the call.\n"
-"Returns 0 if the queue is full, nonexistant, or has no members.\n"
+"Returns 0 if the queue is full, nonexistent, or has no members.\n"
"The option string may contain zero or more of the following characters:\n"
" 't' -- allow the called user transfer the calling user\n"
" 'T' -- to allow the calling user to transfer the call.\n"
@@ -226,6 +226,7 @@ struct ast_call_queue {
int wrapped; /* Round Robin - wrapped around? */
int joinempty; /* Do we care if the queue has no members? */
int eventwhencalled; /* Generate an event when the agent is called (before pickup) */
+ int leavewhenempty; /* If all agents leave the queue, remove callers from the queue */
struct member *members; /* Member channels to be tried */
struct queue_ent *head; /* Start of the actual queue */
@@ -544,14 +545,17 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
}
}
-static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
+static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies)
{
int res;
+ struct ast_var_t *current, *newvar;
+ struct varshead *headp, *newheadp;
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s/%s\n", tmp->tech, tmp->numsubst);
if (qe->chan->cdr)
ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0;
+ (*busies)++;
return 0;
}
/* Request the peer */
@@ -563,8 +567,29 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (qe->chan->cdr)
ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0;
+ (*busies)++;
return 0;
}
+ /* If creating a SIP channel, look for a variable called */
+ /* VXML_URL in the calling channel and copy it to the */
+ /* new channel. */
+
+ /* Check for ALERT_INFO in the SetVar list. This is for */
+ /* SIP distinctive ring as per the RFC. For Cisco 7960s, */
+ /* SetVar(ALERT_INFO=<x>) where x is an integer value 1-5. */
+ /* However, the RFC says it should be a URL. -km- */
+ headp=&qe->chan->varshead;
+ AST_LIST_TRAVERSE(headp,current,entries) {
+ if (!strcasecmp(ast_var_name(current),"VXML_URL") ||
+ !strcasecmp(ast_var_name(current), "ALERT_INFO") ||
+ !strcasecmp(ast_var_name(current), "OSPTOKEN") ||
+ !strcasecmp(ast_var_name(current), "OSPHANDLE"))
+ {
+ newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
+ newheadp=&tmp->chan->varshead;
+ AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
+ }
+ }
tmp->chan->appl = "AppQueue";
tmp->chan->data = "(Outgoing Line)";
tmp->chan->whentohangup = 0;
@@ -593,6 +618,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
ast_hangup(tmp->chan);
tmp->chan = NULL;
tmp->stillgoing = 0;
+ (*busies)++;
return 0;
} else {
if (qe->parent->eventwhencalled) {
@@ -610,10 +636,10 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Called %s/%s\n", tmp->tech, tmp->numsubst);
}
- return 0;
+ return 1;
}
-static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
+static int ring_one(struct queue_ent *qe, struct localuser *outgoing, int *busies)
{
struct localuser *cur;
struct localuser *best;
@@ -635,9 +661,9 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
/* Ring everyone who shares this best metric (for ringall) */
cur = outgoing;
while(cur) {
- if (cur->stillgoing && !cur->chan && (cur->metric == bestmetric)) {
+ if (cur->stillgoing && !cur->chan && (cur->metric <= bestmetric)) {
ast_log(LOG_DEBUG, "(Parallel) Trying '%s/%s' with metric %d\n", cur->tech, cur->numsubst, cur->metric);
- ring_entry(qe, cur);
+ ring_entry(qe, cur, busies);
}
cur = cur->next;
}
@@ -646,7 +672,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
if (option_debug)
ast_log(LOG_DEBUG, "Trying '%s/%s' with metric %d\n",
best->tech, best->numsubst, best->metric);
- ring_entry(qe, best);
+ ring_entry(qe, best, busies);
}
}
} while (best && !best->chan);
@@ -710,15 +736,36 @@ static int valid_exit(struct queue_ent *qe, char digit)
#define AST_MAX_WATCHERS 256
-static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit)
+#define BUILD_STATS do { \
+ o = outgoing; \
+ found = -1; \
+ pos = 1; \
+ numlines = 0; \
+ watchers[0] = in; \
+ while(o) { \
+ /* Keep track of important channels */ \
+ if (o->stillgoing) { \
+ stillgoing = 1; \
+ if (o->chan) { \
+ watchers[pos++] = o->chan; \
+ found = 1; \
+ } \
+ } \
+ o = o->next; \
+ numlines++; \
+ } \
+ } while(0)
+
+static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit, int prebusies)
{
char *queue = qe->parent->name;
struct localuser *o;
int found;
int numlines;
int sentringing = 0;
- int numbusies = 0;
+ int numbusies = prebusies;
int orig = *to;
+ int stillgoing = 0;
struct ast_frame *f;
struct localuser *peer = NULL;
struct ast_channel *watchers[AST_MAX_WATCHERS];
@@ -727,25 +774,18 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
struct ast_channel *in = qe->chan;
while(*to && !peer) {
- o = outgoing;
- found = -1;
- pos = 1;
- numlines = 0;
- watchers[0] = in;
- while(o) {
- /* Keep track of important channels */
- if (o->stillgoing && o->chan) {
- watchers[pos++] = o->chan;
- found = 1;
- }
- o = o->next;
- numlines++;
+ BUILD_STATS;
+ if ((found < 0) && stillgoing && !qe->parent->strategy) {
+ /* On "ringall" strategy we only move to the next penalty level
+ when *all* ringing phones are done in the current penalty level */
+ ring_one(qe, outgoing, &numbusies);
+ BUILD_STATS;
}
if (found < 0) {
if (numlines == numbusies) {
ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
} else {
- ast_log(LOG_NOTICE, "No one is answering queue '%s'\n", queue);
+ ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d)\n", queue, numlines, numbusies);
}
*to = 0;
return NULL;
@@ -789,7 +829,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan);
o->chan = NULL;
if (qe->parent->strategy)
- ring_one(qe, outgoing);
+ ring_one(qe, outgoing, &numbusies);
numbusies++;
break;
case AST_CONTROL_CONGESTION:
@@ -801,7 +841,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan);
o->chan = NULL;
if (qe->parent->strategy)
- ring_one(qe, outgoing);
+ ring_one(qe, outgoing, &numbusies);
numbusies++;
break;
case AST_CONTROL_RINGING:
@@ -827,7 +867,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan);
o->chan = NULL;
if (qe->parent->strategy)
- ring_one(qe, outgoing);
+ ring_one(qe, outgoing, &numbusies);
}
}
o = o->next;
@@ -843,21 +883,30 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
/* Got hung up */
*to=-1;
+ if (f)
+ ast_frfree(f);
return NULL;
}
- if (f && (f->frametype == AST_FRAME_DTMF) && allowdisconnect_out && (f->subclass == '*')) {
+ if ((f->frametype == AST_FRAME_DTMF) && allowdisconnect_out && (f->subclass == '*')) {
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
*to=0;
+ if (f)
+ ast_frfree(f);
return NULL;
}
- if (f && (f->frametype == AST_FRAME_DTMF) && (f->subclass != '*') && valid_exit(qe, f->subclass)) {
+ if ((f->frametype == AST_FRAME_DTMF) && (f->subclass != '*') && valid_exit(qe, f->subclass)) {
if (option_verbose > 3)
- ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c", f->subclass);
+ ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass);
*to=0;
*digit=f->subclass;
+ if (f)
+ ast_frfree(f);
return NULL;
}
+ if (f)
+ ast_frfree(f);
+
}
if (!*to && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
@@ -912,6 +961,12 @@ static int wait_our_turn(struct queue_ent *qe, int ringing)
break;
}
+ /* leave the queue if no agents, if enabled */
+ if (!(qe->parent->members) && qe->parent->leavewhenempty) {
+ leave_queue(qe);
+ break;
+ }
+
/* Make a position announcement, if enabled */
if (qe->parent->announcefrequency && !ringing)
say_position(qe);
@@ -1017,6 +1072,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
struct member *member;
int res = 0, bridge = 0;
int zapx = 2;
+ int numbusies = 0;
int x=0;
char *announce = NULL;
char digit = 0;
@@ -1099,9 +1155,9 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
to = qe->parent->timeout * 1000;
else
to = -1;
- ring_one(qe, outgoing);
+ ring_one(qe, outgoing, &numbusies);
ast_mutex_unlock(&qe->parent->lock);
- lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit);
+ lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit, numbusies);
ast_mutex_lock(&qe->parent->lock);
if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
store_next(qe, outgoing);
@@ -1626,7 +1682,7 @@ check_turns:
/* This is the wait loop for the head caller*/
/* To exit, they may get their call answered; */
/* they may dial a digit from the queue context; */
- /* or, they may may timeout. */
+ /* or, they may timeout. */
/* Leave if we have exceeded our queuetimeout */
if (qe.queuetimeout && ( (time(NULL) - qe.start) >= qe.queuetimeout) ) {
@@ -1634,6 +1690,12 @@ check_turns:
break;
}
+ /* leave the queue if no agents, if enabled */
+ if (!((qe.parent)->members) && (qe.parent)->leavewhenempty) {
+ leave_queue(&qe);
+ break;
+ }
+
/* Make a position announcement, if enabled */
if (qe.parent->announcefrequency && !ringing)
say_position(&qe);
@@ -1691,7 +1753,7 @@ check_turns:
}
}
/* Don't allow return code > 0 */
- if (res > 0 && res != AST_PBX_KEEPALIVE) {
+ if ((res == 0) || (res > 0 && res != AST_PBX_KEEPALIVE)) {
res = 0;
if (ringing) {
ast_indicate(chan, -1);
@@ -1781,7 +1843,7 @@ static void reload_queues(void)
strncpy(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes) - 1);
strncpy(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds) - 1);
strncpy(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks) - 1);
- strncpy(q->sound_lessthan, "queue-lessthan", sizeof(q->sound_lessthan) - 1);
+ strncpy(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan) - 1);
prev = q->members;
if (prev) {
/* find the end of any dynamic members */
@@ -1818,7 +1880,7 @@ static void reload_queues(void)
q->members = cur;
prev = cur;
}
- } else if (!strcasecmp(var->name, "music")) {
+ } else if (!strcasecmp(var->name, "music") || !strcasecmp(var->name, "musiconhold")) {
strncpy(q->moh, var->value, sizeof(q->moh) - 1);
} else if (!strcasecmp(var->name, "announce")) {
strncpy(q->announce, var->value, sizeof(q->announce) - 1);
@@ -1872,6 +1934,8 @@ static void reload_queues(void)
}
} else if (!strcasecmp(var->name, "joinempty")) {
q->joinempty = ast_true(var->value);
+ } else if (!strcasecmp(var->name, "leavewhenempty")) {
+ q->leavewhenempty = ast_true(var->value);
} else if (!strcasecmp(var->name, "eventwhencalled")) {
q->eventwhencalled = ast_true(var->value);
} else {
diff --git a/apps/app_random.c b/apps/app_random.c
index c9f8f4788..18af80e4e 100755
--- a/apps/app_random.c
+++ b/apps/app_random.c
@@ -106,7 +106,6 @@ int unload_module(void)
int load_module(void)
{
- srandom((unsigned int)getpid() + (unsigned int)time(NULL));
return ast_register_application(app_random, random_exec, random_synopsis, random_descrip);
}
diff --git a/apps/app_read.c b/apps/app_read.c
index 988ef8009..e91513845 100755
--- a/apps/app_read.c
+++ b/apps/app_read.c
@@ -106,8 +106,9 @@ static int read_exec(struct ast_channel *chan, void *data)
if (res > -1) {
pbx_builtin_setvar_helper(chan, varname, tmp);
ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
+ res = 0;
} else {
- ast_verbose(VERBOSE_PREFIX_3 "User entered nothing\n");
+ ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
}
}
LOCAL_USER_REMOVE(u);
diff --git a/apps/app_record.c b/apps/app_record.c
index c1f06780a..7de7016c0 100755
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -301,7 +301,7 @@ static int record_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
LOCAL_USER_REMOVE(u);
- if (silence > 0) {
+ if ((silence > 0) && rfmt) {
res = ast_set_read_format(chan, rfmt);
if (res)
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
diff --git a/apps/app_sms.c b/apps/app_sms.c
index a7b55bd46..31a19e609 100755
--- a/apps/app_sms.c
+++ b/apps/app_sms.c
@@ -24,8 +24,10 @@
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
+#include "../astconf.h"
/* ToDo */
/* When acting as SC and answering, should check for messages and send instead of sending EST as first packet */
@@ -36,6 +38,9 @@
static unsigned char message_ref; /* arbitary message ref */
+static char log_file[255];
+static char spool_dir[255];
+
static char *tdesc = "SMS/PSTN handler";
static char *app = "SMS";
@@ -315,7 +320,7 @@ sms_log (sms_t * h, char status)
{ /* log the output, and remove file */
if (*h->oa || *h->da)
{
- int o = open ("/var/log/asterisk/sms", O_CREAT | O_APPEND | O_WRONLY, 0666);
+ int o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, 0666);
if (o >= 0)
{
char line[1000], *p;
@@ -517,7 +522,7 @@ sms_writefile (sms_t * h)
char fn2[200] = "";
FILE *o;
- strncpy(fn, "/var/spool/asterisk/sms", sizeof(fn) - 1);
+ strncpy(fn, spool_dir, sizeof(fn) - 1);
mkdir (fn, 0777); /* ensure it exists */
snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/%s.%s", h->smsc ? "me-sc" : "sc-me", h->queue);
mkdir (fn, 0777); /* ensure it exists */
@@ -689,7 +694,7 @@ sms_nextoutgoing (sms_t * h)
DIR *d;
char more = 0;
- strncpy(fn, "/var/spool/asterisk/sms", sizeof(fn) - 1);
+ strncpy(fn, spool_dir, sizeof(fn) - 1);
mkdir(fn, 0777); /* ensure it exists */
snprintf(fn + strlen (fn), sizeof(fn) - strlen(fn), "/%s.%s", h->smsc ? "sc-me" : "me-sc", h->queue);
mkdir (fn, 0777); /* ensure it exists */
@@ -769,6 +774,7 @@ sms_nextoutgoing (sms_t * h)
{ /* no message */
h->omsg[0] = 0x94; /* SMS_REL */
h->omsg[1] = 0;
+ h->hangup = 1;
sms_messagetx (h);
}
}
@@ -1204,6 +1210,8 @@ load_module (void)
for (p = 0; p < 128; p++)
sms8to7[sms7to8[p]] = p;
}
+ snprintf(log_file, sizeof(log_file), "%s/sms", ast_config_AST_LOG_DIR);
+ snprintf(spool_dir, sizeof(spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR);
return ast_register_application (app, sms_exec, synopsis, descrip);
}
diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c
index 1620df635..4d52eb3e4 100755
--- a/apps/app_sql_postgres.c
+++ b/apps/app_sql_postgres.c
@@ -106,8 +106,6 @@ STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
-extern void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value);
-
#define AST_PGSQL_ID_DUMMY 0
#define AST_PGSQL_ID_CONNID 1
#define AST_PGSQL_ID_RESID 2
diff --git a/apps/app_test.c b/apps/app_test.c
index 3743b6771..702dbdc3f 100755
--- a/apps/app_test.c
+++ b/apps/app_test.c
@@ -1,7 +1,7 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
- * Applictions connected with CDR engine
+ * Applications to test connection and produce report in text file
*
* Copyright (C) 2004, Digium, Inc.
*
@@ -14,6 +14,7 @@
#include <sys/types.h>
#include <asterisk/channel.h>
+#include <asterisk/options.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/lock.h>
@@ -29,13 +30,15 @@
static char *tdesc = "Interface Test Application";
-static char *tests_descrip = "TestServer(): Perform test server function and write call report"
- "Results stored in /var/log/asterisk/testreports/<testid>.txt";
+static char *tests_descrip =
+ "TestServer(): Perform test server function and write call report.\n"
+ "Results stored in /var/log/asterisk/testreports/<testid>-server.txt";
static char *tests_app = "TestServer";
static char *tests_synopsis = "Execute Interface Test Server";
-static char *testc_descrip = "TestClient(testid): Executes test client with given testid.\n"
- "Results stored in /var/log/asterisk/testreports/<testid>.txt";
+static char *testc_descrip =
+ "TestClient(testid): Executes test client with given testid.\n"
+ "Results stored in /var/log/asterisk/testreports/<testid>-client.txt";
static char *testc_app = "TestClient";
static char *testc_synopsis = "Execute Interface Test Client";
diff --git a/apps/app_userevent.c b/apps/app_userevent.c
index e1a87c2a4..82de783b3 100755
--- a/apps/app_userevent.c
+++ b/apps/app_userevent.c
@@ -54,12 +54,12 @@ static int userevent_exec(struct ast_channel *chan, void *data)
}
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
+ snprintf(eventname, sizeof(eventname), "UserEvent%s", info);
eventbody = strchr(eventname, '|');
if (eventbody) {
*eventbody = '\0';
eventbody++;
}
- snprintf(eventname, sizeof(eventname), "UserEvent%s", info);
LOCAL_USER_ADD(u);
if(eventbody) {
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index fe13a7fca..afe34b41c 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -176,8 +176,9 @@ struct vm_state {
};
static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option);
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration);
+static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir);
static int vm_delete(char *file);
+static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
static char ext_pass_cmd[128];
@@ -215,7 +216,10 @@ static char *descrip_vmain =
"for the checking of voicemail. The mailbox can be passed as the option,\n"
"which will stop the voicemail system from prompting the user for the mailbox.\n"
"If the mailbox is preceded by 's' then the password check will be skipped. If\n"
-"a context is specified, logins are considered in that voicemail context only.\n"
+"the mailbox is preceded by 'p' then the supplied mailbox is prepended to the\n"
+"user's entry and the resulting string is used as the mailbox number. This is\n"
+"useful for virtual hosting of voicemail boxes. If a context is specified,\n"
+"logins are considered in that voicemail context only.\n"
"Returns -1 if the user hangs up or 0 otherwise.\n";
static char *synopsis_vm_box_exists =
@@ -705,6 +709,20 @@ static int make_file(char *dest, int len, char *dir, int num)
return snprintf(dest, len, "%s/msg%04d", dir, num);
}
+static int last_message_index(char *dir)
+{
+ int x;
+ char fn[256];
+ ast_lock_path(dir);
+ for (x=0;x<MAXMSG;x++) {
+ make_file(fn, sizeof(fn), dir, x);
+ if (ast_fileexists(fn, NULL, NULL) < 1)
+ break;
+ }
+ ast_unlock_path(dir);
+ return x-1;
+}
+
static int
inbuf(struct baseio *bio, FILE *fi)
{
@@ -844,7 +862,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
FILE *p=NULL;
int pfd;
char date[256];
- char host[256];
+ char host[MAXHOSTNAMELEN] = "";
char who[256];
char bound[256];
char fname[256];
@@ -872,7 +890,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
}
}
if (p) {
- gethostname(host, sizeof(host));
+ gethostname(host, sizeof(host)-1);
if (strchr(srcemail, '@'))
strncpy(who, srcemail, sizeof(who)-1);
else {
@@ -989,7 +1007,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
fclose(p);
snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
ast_safe_system(tmp2);
- ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd);
+ ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
} else {
ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
return -1;
@@ -1002,7 +1020,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char
FILE *p=NULL;
int pfd;
char date[256];
- char host[256];
+ char host[MAXHOSTNAMELEN]="";
char who[256];
char dur[256];
char tmp[80] = "/tmp/astmail-XXXXXX";
@@ -1021,7 +1039,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char
}
if (p) {
- gethostname(host, sizeof(host));
+ gethostname(host, sizeof(host)-1);
if (strchr(srcemail, '@'))
strncpy(who, srcemail, sizeof(who)-1);
else {
@@ -1076,7 +1094,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char
fclose(p);
snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
ast_safe_system(tmp2);
- ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd);
+ ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
} else {
ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
return -1;
@@ -1239,6 +1257,7 @@ static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int
make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
make_file(frompath, sizeof(frompath), fromdir, msgnum);
+ ast_lock_path(topath);
recipmsgnum = 0;
do {
make_file(topath, sizeof(topath), todir, recipmsgnum);
@@ -1255,7 +1274,7 @@ static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int
} else {
ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
}
-
+ ast_unlock_path(topath);
notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->callerid);
}
@@ -1282,7 +1301,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
FILE *txt;
int res = 0;
int msgnum;
- int fd;
int duration = 0;
int ausemacro = 0;
int ousemacro = 0;
@@ -1356,7 +1374,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
-
+
/* Play the beginning intro if desired */
if (!ast_strlen_zero(prefile)) {
if (ast_fileexists(prefile, NULL, NULL) > 0) {
@@ -1403,22 +1421,22 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
}
/* Check for a '0' here */
if (res == '0') {
- transfer:
- strncpy(chan->exten, "o", sizeof(chan->exten) - 1);
- if (!ast_strlen_zero(vmu->exit)) {
- strncpy(chan->context, vmu->exit, sizeof(chan->context) - 1);
- } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
- strncpy(chan->context, chan->macrocontext, sizeof(chan->context) - 1);
+ transfer:
+ if (vmu->operator) {
+ strncpy(chan->exten, "o", sizeof(chan->exten) - 1);
+ if (!ast_strlen_zero(vmu->exit)) {
+ strncpy(chan->context, vmu->exit, sizeof(chan->context) - 1);
+ } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
+ strncpy(chan->context, chan->macrocontext, sizeof(chan->context) - 1);
+ }
+ ast_play_and_wait(chan, "transfer");
+ chan->priority = 0;
+ free_user(vmu);
+ return 0;
+ } else {
+ ast_play_and_wait(chan, "vm-sorry");
+ return 0;
}
- chan->priority = 0;
- free_user(vmu);
- return 0;
- }
- if (res >= 0) {
- /* Unless we're *really* silent, try to send the beep */
- res = ast_streamfile(chan, "beep", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
}
if (res < 0) {
free_user(vmu);
@@ -1428,6 +1446,13 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
strncpy(fmt, vmfmts, sizeof(fmt) - 1);
if (!ast_strlen_zero(fmt)) {
msgnum = 0;
+ if (res >= 0) {
+ /* Unless we're *really* silent, try to send the beep */
+ res = ast_streamfile(chan, "beep", chan->language);
+ if (!res)
+ res = ast_waitstream(chan, "");
+ }
+ ast_lock_path(dir);
do {
make_file(fn, sizeof(fn), dir, msgnum);
if (ast_fileexists(fn, NULL, chan->language) <= 0)
@@ -1462,22 +1487,19 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
chan->name,
chan->callerid ? chan->callerid : "Unknown",
date, (long)time(NULL));
- fclose(txt);
} else
ast_log(LOG_WARNING, "Error opening text file for output\n");
- res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration);
- if (res == '0')
+ res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir);
+ if (res == '0') {
+ if (txt)
+ fclose(txt);
goto transfer;
+ }
if (res > 0)
res = 0;
- fd = open(txtfile, O_APPEND | O_WRONLY);
- if (fd > -1) {
- txt = fdopen(fd, "a");
- if (txt) {
- fprintf(txt, "duration=%d\n", duration);
- fclose(txt);
- } else
- close(fd);
+ if (txt) {
+ fprintf(txt, "duration=%d\n", duration);
+ fclose(txt);
}
if (duration < vmminmessage) {
if (option_verbose > 2)
@@ -1502,8 +1524,10 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
free_user(recip);
}
}
- notify_new_message(chan, vmu, msgnum, duration, fmt, chan->callerid);
+ if (ast_fileexists(fn, NULL, NULL))
+ notify_new_message(chan, vmu, msgnum, duration, fmt, chan->callerid);
} else {
+ ast_unlock_path(dir);
res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
if (!res)
res = ast_waitstream(chan, "");
@@ -1525,16 +1549,58 @@ leave_vm_out:
static int count_messages(char *dir)
{
- int x;
- char fn[256];
- for (x=0;x<MAXMSG;x++) {
- make_file(fn, sizeof(fn), dir, x);
- if (ast_fileexists(fn, NULL, NULL) < 1)
- break;
+ /* Find all .txt files - even if they are not in sequence from 0000 */
+
+
+ int vmcount = 0;
+ DIR *vmdir = NULL;
+ struct dirent *vment = NULL;
+
+ if ((vmdir = opendir(dir))) {
+ while ((vment = readdir(vmdir)))
+ {
+ if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7,".txt",4))
+ {
+ vmcount++;
+ }
+ }
+ closedir(vmdir);
+ }
+
+ return vmcount;
+}
+
+static void resequence_mailbox(char * dir)
+{
+ /* we know max messages, so stop process when number is hit */
+
+ int x,dest;
+ char sfn[256];
+ char dfn[256];
+ char stxt[256];
+ char dtxt[256];
+
+ ast_lock_path(dir);
+ for (x=0,dest=0;x<MAXMSG;x++) {
+ make_file(sfn, sizeof(sfn), dir, x);
+ if (ast_fileexists(sfn, NULL, NULL) > 0) {
+
+ if(x != dest) {
+ make_file(dfn, sizeof(dfn), dir, dest);
+ ast_filerename(sfn,dfn,NULL);
+
+ snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
+ snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
+ rename(stxt, dtxt);
+ }
+
+ dest++;
+ }
}
- return x;
+ ast_unlock_path(dir);
}
+
static int say_and_wait(struct ast_channel *chan, int num, char *language)
{
int d;
@@ -1554,19 +1620,23 @@ static int save_to_folder(char *dir, int msg, char *context, char *username, int
make_file(sfn, sizeof(sfn), dir, msg);
make_dir(ddir, sizeof(ddir), context, username, dbox);
mkdir(ddir, 0700);
+ ast_lock_path(ddir);
for (x=0;x<MAXMSG;x++) {
make_file(dfn, sizeof(dfn), ddir, x);
if (ast_fileexists(dfn, NULL, NULL) < 0)
break;
}
- if (x >= MAXMSG)
+ if (x >= MAXMSG) {
+ ast_unlock_path(ddir);
return -1;
+ }
ast_filecopy(sfn, dfn, NULL);
if (strcmp(sfn, dfn)) {
snprintf(txt, sizeof(txt), "%s.txt", sfn);
snprintf(ntxt, sizeof(ntxt), "%s.txt", dfn);
copy(txt, ntxt);
}
+ ast_unlock_path(ddir);
return 0;
}
@@ -2073,23 +2143,10 @@ static int get_folder(struct ast_channel *chan, int start)
d = ast_play_and_wait(chan, "vm-for"); /* "for" */
if (d)
return d;
- if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt")) { /* Spanish, French or Portuguese syntax */
- d = ast_play_and_wait(chan, "vm-messages"); /* "messages */
- if (d)
- return d;
- snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */
- d = ast_play_and_wait(chan, fn);
- if (d)
- return d;
- } else { /* Default English */
- snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */
- d = ast_play_and_wait(chan, fn);
- if (d)
- return d;
- d = ast_play_and_wait(chan, "vm-messages"); /* "messages */
- if (d)
- return d;
- }
+ snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */
+ d = vm_play_folder_name(chan, fn);
+ if (d)
+ return d;
d = ast_waitfordigit(chan, 500);
if (d)
return d;
@@ -2272,7 +2329,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
snprintf(ext_context, sizeof(ext_context), "%s@%s", vmtmp->mailbox, vmtmp->context);
- ast_log(LOG_DEBUG, sys);
+ ast_log(LOG_DEBUG, "%s", sys);
ast_safe_system(sys);
todircount = count_messages(todir);
@@ -2283,11 +2340,11 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
if (!strcasecmp(s, "wav49"))
s = "WAV";
snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s);
- ast_log(LOG_DEBUG, sys);
+ ast_log(LOG_DEBUG, "%s", sys);
ast_safe_system(sys);
}
snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount);
- ast_log(LOG_DEBUG, sys);
+ ast_log(LOG_DEBUG, "%s", sys);
ast_safe_system(sys);
snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount);
@@ -2545,6 +2602,20 @@ static void open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
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;
+
+ /*
+ The following test is needed in case sequencing gets messed up.
+ There appears to be more than one way to mess up sequence, so
+ we will not try to find all of the root causes--just fix it when
+ detected.
+ */
+
+ if(vms->lastmsg != last_message_index(vms->curdir))
+ {
+ ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
+ resequence_mailbox(vms->curdir);
+ }
+
snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
}
@@ -2555,6 +2626,7 @@ static void close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
char txt[256] = "";
if (vms->lastmsg > -1) {
/* Get the deleted messages fixed */
+ ast_lock_path(vms->curdir);
vms->curmsg = -1;
for (x=0;x < MAXMSG;x++) {
if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) {
@@ -2581,13 +2653,31 @@ static void close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
break;
vm_delete(vms->fn);
}
+ ast_unlock_path(vms->curdir);
}
memset(vms->deleted, 0, sizeof(vms->deleted));
memset(vms->heard, 0, sizeof(vms->heard));
}
+static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
+{
+ int cmd;
+
+ if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt")) { /*Spanish, French or Portuguese syntax */
+ cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
+ if (cmd)
+ return cmd;
+ return ast_play_and_wait(chan, mbox);
+ } else { /* Default English */
+ cmd = ast_play_and_wait(chan, mbox);
+ if (cmd)
+ return cmd;
+ return ast_play_and_wait(chan, "vm-messages"); /* "messages */
+ }
+}
+
/* Default English syntax */
-static int vm_intro(struct ast_channel *chan,struct vm_state *vms)
+static int vm_intro_en(struct ast_channel *chan,struct vm_state *vms)
{
/* Introduce messages they have */
int res;
@@ -2949,6 +3039,26 @@ static int vm_intro_cz(struct ast_channel *chan,struct vm_state *vms)
return res;
}
+static int vm_intro(struct ast_channel *chan,struct vm_state *vms)
+{
+ /* Play voicemail intro - syntax is different for different languages */
+ if (!strcasecmp(chan->language, "de")) { /* GERMAN syntax */
+ return vm_intro_de(chan, vms);
+ } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
+ return vm_intro_es(chan, vms);
+ } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
+ return vm_intro_fr(chan, vms);
+ } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
+ return vm_intro_nl(chan, vms);
+ } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
+ return vm_intro_pt(chan, vms);
+ } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
+ return vm_intro_cz(chan, vms);
+ } else { /* Default to ENGLISH */
+ return vm_intro_en(chan, vms);
+ }
+}
+
static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
{
int res = 0;
@@ -2957,17 +3067,8 @@ static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int s
if (vms->starting) {
if (vms->lastmsg > -1) {
res = ast_play_and_wait(chan, "vm-onefor");
- if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt")) { /* Spanish, French & Portuguese Syntax */
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- if (!res)
- res = ast_play_and_wait(chan, vms->vmbox);
- } else { /* Default English syntax */
- if (!res)
- res = ast_play_and_wait(chan, vms->vmbox);
- if (!res)
- res = ast_play_and_wait(chan, "vm-messages");
- }
+ if (!res)
+ res = vm_play_folder_name(chan, vms->vmbox);
}
if (!res)
res = ast_play_and_wait(chan, "vm-opts");
@@ -3031,15 +3132,15 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
switch (cmd) {
case '1':
snprintf(prefile,sizeof(prefile),"voicemail/%s/%s/unavail",vmu->context, vms->username);
- cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration);
+ cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
break;
case '2':
snprintf(prefile,sizeof(prefile),"voicemail/%s/%s/busy",vmu->context, vms->username);
- cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration);
+ cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
break;
case '3':
snprintf(prefile,sizeof(prefile),"voicemail/%s/%s/greet",vmu->context, vms->username);
- cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration);
+ cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL);
break;
case '4':
if (vmu->password[0] == '-') {
@@ -3048,19 +3149,24 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
}
newpassword[1] = '\0';
newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
- if (cmd < 0)
- break;
- if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
- break;
- }
+ if (cmd == '#')
+ newpassword[0] = '\0';
+ else {
+ if (cmd < 0)
+ break;
+ if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0)
+ break;
+ }
newpassword2[1] = '\0';
newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
- if (cmd < 0)
- break;
-
- if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
- break;
- }
+ if (cmd == '#')
+ newpassword2[0] = '\0';
+ else {
+ if (cmd < 0)
+ break;
+ if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")))
+ break;
+ }
if (strcmp(newpassword, newpassword2)) {
ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
cmd = ast_play_and_wait(chan, "vm-mismatch");
@@ -3092,7 +3198,7 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct
}
/* Default English syntax */
-static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
+static int vm_browse_messages_en(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
{
int cmd=0;
@@ -3150,6 +3256,17 @@ static int vm_browse_messages_pt(struct ast_channel *chan, struct vm_state *vms,
return cmd;
}
+static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
+{
+ if (!strcasecmp(chan->language, "es")) { /* SPANISH */
+ return vm_browse_messages_es(chan, vms, vmu);
+ } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE */
+ return vm_browse_messages_pt(chan, vms, vmu);
+ } else { /* Default to English syntax */
+ return vm_browse_messages_en(chan, vms, vmu);
+ }
+}
+
static int vm_execmain(struct ast_channel *chan, void *data)
{
/* XXX This is, admittedly, some pretty horrendus code. For some
@@ -3269,7 +3386,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
goto out;
}
}
- if (prefix) {
+ if (prefix && !ast_strlen_zero(prefixstr)) {
char fullusername[80] = "";
strncpy(fullusername, prefixstr, sizeof(fullusername) - 1);
strncat(fullusername, vms.username, sizeof(fullusername) - 1);
@@ -3290,15 +3407,20 @@ static int vm_execmain(struct ast_channel *chan, void *data)
logretries++;
if (!valid) {
if (skipuser || logretries >= maxlogins) {
- if (ast_streamfile(chan, "vm-incorrect", chan->language))
- break;
+ if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
+ ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
+ return -1;
+ }
} else {
if (useadsi)
adsi_login(chan);
- if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language))
- break;
+ if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
+ ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
+ return -1;
+ }
}
- ast_waitstream(chan, "");
+ if (ast_waitstream(chan, "")) /* Channel is hung up */
+ return -1;
}
}
if (!valid && (logretries >= maxlogins)) {
@@ -3333,22 +3455,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
if (useadsi)
adsi_status(chan, &vms);
res = 0;
- /* Play voicemail intro - syntax is different for different languages */
- if (!strcasecmp(chan->language, "de")) { /* GERMAN syntax */
- cmd = vm_intro_de(chan, &vms);
- } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
- cmd = vm_intro_es(chan, &vms);
- } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
- cmd = vm_intro_fr(chan, &vms);
- } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
- cmd = vm_intro_nl(chan, &vms);
- } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
- cmd = vm_intro_pt(chan, &vms);
- } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
- cmd = vm_intro_cz(chan, &vms);
- } else { /* Default to ENGLISH */
- cmd = vm_intro(chan, &vms);
- }
+ cmd = vm_intro(chan, &vms);
vms.repeats = 0;
vms.starting = 1;
while((cmd > -1) && (cmd != 't') && (cmd != '#')) {
@@ -3358,13 +3465,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
vms.curmsg = 0;
/* Fall through */
case '5':
- if (!strcasecmp(chan->language, "es")) { /* SPANISH */
- cmd = vm_browse_messages_es(chan, &vms, vmu);
- } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE */
- cmd = vm_browse_messages_pt(chan, &vms, vmu);
- } else { /* Default to English syntax */
- cmd = vm_browse_messages(chan, &vms, vmu);
- }
+ cmd = vm_browse_messages(chan, &vms, vmu);
break;
case '2': /* Change folders */
if (useadsi)
@@ -3380,17 +3481,8 @@ static int vm_execmain(struct ast_channel *chan, void *data)
}
if (useadsi)
adsi_status2(chan, &vms);
- if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt")) { /* SPANISH or PORTUGUESE */
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- if (!cmd)
- cmd = ast_play_and_wait(chan, vms.vmbox);
- } else { /* Default to English syntax */
- if (!cmd)
- cmd = ast_play_and_wait(chan, vms.vmbox);
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- }
+ if (!cmd)
+ cmd = vm_play_folder_name(chan, vms.vmbox);
vms.starting = 1;
break;
case '3': /* Advanced options */
@@ -3549,21 +3641,9 @@ static int vm_execmain(struct ast_channel *chan, void *data)
cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
if (!cmd)
cmd = ast_play_and_wait(chan, "vm-savedto");
- if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt")) { /* SPANISH or PORTUGUESE */
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- if (!cmd) {
- snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
- cmd = ast_play_and_wait(chan, vms.fn);
- }
- } else { /* Default to English */
- if (!cmd) {
- snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
- cmd = ast_play_and_wait(chan, vms.fn);
- }
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- }
+ snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
+ if (!cmd)
+ cmd = vm_play_folder_name(chan, vms.fn);
if (skipaftercmd) {
if (vms.curmsg < vms.lastmsg) {
vms.curmsg++;
@@ -3577,17 +3657,8 @@ static int vm_execmain(struct ast_channel *chan, void *data)
case '*':
if (!vms.starting) {
cmd = ast_play_and_wait(chan, "vm-onefor");
- if (!strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt")) { /* Spanish or Portuguese syntax */
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- if (!cmd)
- cmd = ast_play_and_wait(chan, vms.vmbox);
- } else {
- if (!cmd)
- cmd = ast_play_and_wait(chan, vms.vmbox);
- if (!cmd)
- cmd = ast_play_and_wait(chan, "vm-messages");
- }
+ if (!cmd)
+ cmd = vm_play_folder_name(chan, vms.vmbox);
if (!cmd)
cmd = ast_play_and_wait(chan, "vm-opts");
if (!cmd)
@@ -3800,7 +3871,7 @@ static int handle_show_voicemail_users(int fd, int argc, char *argv[])
if ((vmdir = opendir(dirname))) {
/* 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))
+ if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7,".txt",4))
vmcount++;
closedir(vmdir);
}
@@ -4526,7 +4597,7 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
-static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration)
+static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir)
{
/* Record message & let caller review or re-record it, or set options if applicable */
int res = 0;
@@ -4579,14 +4650,12 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
}
recorded = 1;
/* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
- cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence);
+ cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir);
if (cmd == -1)
/* User has hung up, no options to give */
- return res;
+ return cmd;
if (cmd == '0') {
- /* Erase the message if 0 pushed during playback */
- ast_play_and_wait(chan, "vm-deleted");
- vm_delete(recordfile);
+ break;
} else if (cmd == '*') {
break;
}
@@ -4639,13 +4708,20 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
return 1;
#endif
case '0':
- if (outsidecaller && vmu->operator) {
- if (message_exists)
- ast_play_and_wait(chan, "vm-msgsaved");
- return cmd;
- } else
- cmd = ast_play_and_wait(chan, "vm-sorry");
- break;
+ if (message_exists || recorded) {
+ cmd = ast_play_and_wait(chan, "vm-saveoper");
+ if (!cmd)
+ cmd = ast_waitfordigit(chan, 3000);
+ if (cmd == '1') {
+ ast_play_and_wait(chan, "vm-msgsaved");
+ cmd = '0';
+ } else {
+ ast_play_and_wait(chan, "vm-deleted");
+ vm_delete(recordfile);
+ cmd = '0';
+ }
+ }
+ return cmd;
default:
/* If the caller is an ouside caller, and the review option is enabled,
allow them to review the message, but let the owner of the box review
@@ -4681,7 +4757,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
}
}
if (outsidecaller)
- ast_play_and_wait(chan, "vm-goodbye");
+ ast_play_and_wait(chan, "vm-goodbye");
if (cmd == 't')
cmd = 0;
return cmd;
@@ -4703,6 +4779,7 @@ static int vm_delete(char *file)
return ast_filedelete(file, NULL);
}
+
int usecount(void)
{
int res;