aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
author(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-13 04:46:23 +0000
committer(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-13 04:46:23 +0000
commitd46468f42c6762ce7646e773c7d0919ed1f626d4 (patch)
tree5d62a34385385b3485137835b2629174ca0464cf /apps
parentf38bc8131c9eda8d0b0eabaafbaa53f4247989c4 (diff)
This commit was manufactured by cvs2svn to create tag 'v0_9_0'.
git-svn-id: http://svn.digium.com/svn/asterisk/tags/v0_9_0@2684 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rwxr-xr-xapps/app_adsiprog.c15
-rwxr-xr-xapps/app_agi.c15
-rwxr-xr-xapps/app_chanisavail.c14
-rwxr-xr-xapps/app_cut.c2
-rwxr-xr-xapps/app_dial.c31
-rwxr-xr-xapps/app_directory.c16
-rwxr-xr-xapps/app_festival.c3
-rwxr-xr-xapps/app_macro.c2
-rwxr-xr-xapps/app_parkandannounce.c15
-rwxr-xr-xapps/app_queue.c67
-rwxr-xr-xapps/app_random.c4
-rwxr-xr-xapps/app_record.c6
-rwxr-xr-xapps/app_sql_postgres.c2
-rwxr-xr-xapps/app_system.c5
-rwxr-xr-xapps/app_voicemail.c108
-rwxr-xr-xapps/app_waitforring.c2
-rwxr-xr-xapps/app_zapras.c2
-rwxr-xr-xapps/app_zapscan.c20
18 files changed, 243 insertions, 86 deletions
diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c
index 696b1cd77..12742609d 100755
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -666,7 +666,7 @@ static int showdisplay(char *buf, char *name, int id, char *args, struct adsi_sc
}
buf[0] = id;
- buf[1] = (cmd << 6) | (disp->id & 0x2f);
+ buf[1] = (cmd << 6) | (disp->id & 0x3f);
buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
return 3;
}
@@ -695,6 +695,18 @@ static int digitdirect(char *buf, char *name, int id, char *args, struct adsi_sc
return 2;
}
+static int clearcbone(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
+{
+ char *tok;
+ tok = get_token(&args, script, lineno);
+ if (tok)
+ ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
+
+ buf[0] = id;
+ buf[1] = 0;
+ return 2;
+}
+
static int digitcollect(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
{
char *tok;
@@ -831,6 +843,7 @@ static struct adsi_key_cmd kcmds[] = {
{ "VOICEMODE", 0x93 },
/* Display call buffer 'n' */
/* Clear call buffer 'n' */
+ { "CLEARCB1", 0x95, clearcbone },
{ "DIGITCOLLECT", 0x96, digitcollect },
{ "DIGITDIRECT", 0x96, digitdirect },
{ "CLEAR", 0x97 },
diff --git a/apps/app_agi.c b/apps/app_agi.c
index 2be4987bb..cb635451f 100755
--- a/apps/app_agi.c
+++ b/apps/app_agi.c
@@ -529,6 +529,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (!fs) {
res = -1;
fdprintf(agi->fd, "200 result=%d (writefile)\n", res);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
@@ -545,12 +547,16 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (res < 0) {
ast_closestream(fs);
fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
f = ast_read(chan);
if (!f) {
fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset);
ast_closestream(fs);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
switch(f->frametype) {
@@ -561,6 +567,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset);
ast_closestream(fs);
ast_frfree(f);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_SUCCESS;
}
break;
@@ -596,6 +604,7 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (gotsilence) {
ast_stream_rewind(fs, silence-1000);
ast_truncstream(fs);
+ sample_offset = ast_tellstream(fs);
}
fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
ast_closestream(fs);
@@ -1218,6 +1227,10 @@ static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf)
fdprintf(agi->fd, c->usage);
fdprintf(agi->fd, "520 End of proper usage.\n");
break;
+ case AST_PBX_KEEPALIVE:
+ /* We've been asked to keep alive, so do so */
+ return AST_PBX_KEEPALIVE;
+ break;
case RESULT_FAILURE:
/* They've already given the failure. We've been hung up on so handle this
appropriately */
@@ -1285,7 +1298,7 @@ static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid)
returnstatus |= agi_handle_command(chan, agi, buf);
/* If the handle_command returns -1, we need to stop */
- if (returnstatus < 0) {
+ if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
break;
}
} else {
diff --git a/apps/app_chanisavail.c b/apps/app_chanisavail.c
index 57f6e6ff0..18e61b419 100755
--- a/apps/app_chanisavail.c
+++ b/apps/app_chanisavail.c
@@ -38,9 +38,9 @@ static char *synopsis = "Check if channel is available";
static char *descrip =
" ChanIsAvail(Technology/resource[&Technology2/resource2...]): \n"
"Checks is any of the requested channels are available. If none\n"
-"of the requested channels are available the new priority will\n"
-"be n+101 (unless such a priority does not exist, in which case\n"
-"ChanIsAvail will return -1. If any of the requested channels\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.\n";
@@ -53,7 +53,7 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
- char info[256], *peers, *tech, *number, *rest, *cur;
+ char info[512], *peers, *tech, *number, *rest, *cur;
struct ast_channel *tempchan;
if (!data) {
@@ -62,7 +62,7 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
- strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
+ strncpy(info, (char *)data, sizeof(info)-1);
peers = info;
if (peers) {
cur = peers;
@@ -76,8 +76,8 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
tech = cur;
number = strchr(tech, '/');
if (!number) {
- ast_log(LOG_WARNING, "ChanIsAvail argument takes format (Zap/[device])\n");
- continue;
+ ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
+ return -1;
}
*number = '\0';
number++;
diff --git a/apps/app_cut.c b/apps/app_cut.c
index 1d3cf5b89..18de2d10a 100755
--- a/apps/app_cut.c
+++ b/apps/app_cut.c
@@ -85,6 +85,8 @@ static int cut_exec(struct ast_channel *chan, void *data)
char *tmp2 = alloca(MAXRESULT);
char retstring[MAXRESULT];
+ if (tmp2)
+ memset(tmp2, 0, MAXRESULT);
memset(retstring, 0, MAXRESULT);
if (tmp && tmp2) {
diff --git a/apps/app_dial.c b/apps/app_dial.c
index bfc93f69f..15bbaaedb 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -49,10 +49,10 @@ static char *descrip =
"which first answered. All other calls placed by the Dial app will be hung up\n"
"If a timeout is not specified, the Dial application will wait indefinitely\n"
"until either one of the called channels answers, the user hangs up, or all\n"
-"channels return busy or error. In general, the dialler will return 0 if it\n"
+"channels return busy or error. In general, the dialer will return 0 if it\n"
"was unable to place the call, or the timeout expired. However, if all\n"
"channels were busy, and there exists an extension with priority n+101 (where\n"
-"n is the priority of the dialler instance), then it will be the next\n"
+"n is the priority of the dialer instance), then it will be the next\n"
"executed extension (this allows you to setup different behavior on busy from\n"
"no-answer).\n"
" This application returns -1 if the originating channel hangs up, or if the\n"
@@ -69,7 +69,7 @@ static char *descrip =
" 'A(x)' -- play an announcement to the called party, using x as file\n"
" In addition to transferring the call, a call may be parked and then picked\n"
"up by another user.\n"
-" The optionnal URL will be sent to the called party if the channel supports\n"
+" The optional URL will be sent to the called party if the channel supports\n"
"it.\n";
/* We define a customer "local user" structure because we
@@ -139,6 +139,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
} else if (outgoing->ringbackonly) {
ast_indicate(in, AST_CONTROL_RINGING);
}
+ sentringing++;
}
while(*to && !peer) {
@@ -171,7 +172,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
/* if no one available we'd better stop MOH/ringing to */
if (moh) {
ast_moh_stop(in);
- } else if (ringind) {
+ } else if (sentringing) {
ast_indicate(in, -1);
}
return NULL;
@@ -207,13 +208,19 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (o->chan->callerid)
free(o->chan->callerid);
o->chan->callerid = malloc(strlen(in->callerid) + 1);
- strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
+ if (o->chan->callerid)
+ strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
+ else
+ ast_log(LOG_WARNING, "Out of memory\n");
}
if (in->ani) {
if (o->chan->ani)
free(o->chan->ani);
o->chan->ani = malloc(strlen(in->ani) + 1);
- strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
+ if (o->chan->ani)
+ strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
+ else
+ ast_log(LOG_WARNING, "Out of memory\n");
}
if (ast_call(o->chan, tmpchan, 0)) {
ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
@@ -268,7 +275,6 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (!sentringing && !moh) {
ast_indicate(in, AST_CONTROL_RINGING);
sentringing++;
- ringind++;
}
break;
case AST_CONTROL_PROGRESS:
@@ -280,9 +286,12 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
/* Ignore going off hook */
break;
case -1:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
- ast_indicate(in, -1);
+ if (!ringind && !moh) {
+ if (option_verbose > 2)
+ ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
+ ast_indicate(in, -1);
+ sentringing = 0;
+ }
break;
default:
ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
@@ -337,7 +346,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
}
if (moh) {
ast_moh_stop(in);
- } else if (ringind) {
+ } else if (sentringing) {
ast_indicate(in, -1);
}
diff --git a/apps/app_directory.c b/apps/app_directory.c
index 8e8f62455..199888b23 100755
--- a/apps/app_directory.c
+++ b/apps/app_directory.c
@@ -37,7 +37,8 @@ static char *descrip =
"discovered from voicemail.conf. The context argument is required, and\n"
"specifies the context in which to interpret the extensions. Returns 0\n"
"unless the user hangs up. It also sets up the channel on exit to enter the\n"
-"extension the user selected.\n";
+"extension the user selected. Please note that the context must be the same\n"
+"as the section in voicemail.conf that the mailbox is processed from as well.\n";
/* For simplicity, I'm keeping the format compatible with the voicemail config,
but i'm open to suggestions for isolating it */
@@ -199,10 +200,15 @@ ahem:
ast_stopstream(chan);
if (res > -1) {
if (res == '1') {
- strncpy(chan->exten, v->name, sizeof(chan->exten)-1);
- chan->priority = 0;
- strncpy(chan->context, context, sizeof(chan->context)-1);
- res = 0;
+ if (ast_exists_extension(chan, context, v->name, 1, chan->callerid)) {
+ strncpy(chan->exten, v->name, sizeof(chan->exten)-1);
+ chan->priority = 0;
+ strncpy(chan->context, context, sizeof(chan->context)-1);
+ res = 0;
+ } else {
+ ast_log(LOG_WARNING, "Can't find extension '%s' in context '%s'. Did you pass the wrong context to Directory?\n", v->name, context);
+ res = -1;
+ }
break;
} else if (res == '*') {
res = 0;
diff --git a/apps/app_festival.c b/apps/app_festival.c
index 82a819395..309af973b 100755
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2002, Christos Ricudis
*
- * Christos Ricudis <ricudis@paiko.gr>
+ * Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
@@ -376,6 +376,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
if (strlen((char *)data)==strln) {
ast_log(LOG_DEBUG,"Size OK\n");
read(fdesc,&bigstring,strln);
+ bigstring[strln] = 0;
if (strcmp(bigstring,data)==0) {
readcache=1;
} else {
diff --git a/apps/app_macro.c b/apps/app_macro.c
index 6cb07bd6f..3189d077b 100755
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -202,7 +202,7 @@ out:
/* If we're leaving the macro normally, restore original information */
chan->priority = oldpriority;
strncpy(chan->context, oldcontext, sizeof(chan->context) - 1);
- if (!chan->_softhangup) {
+ if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
strncpy(chan->exten, oldexten, sizeof(chan->exten) - 1);
if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c
index 072d55189..2b6404bef 100755
--- a/apps/app_parkandannounce.c
+++ b/apps/app_parkandannounce.c
@@ -68,13 +68,17 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
int outstate;
struct localuser *u;
- if (!data) {
- ast_log(LOG_WARNING, "Park requires an argument (parkinglot)\n");
+ if (!data || (data && !strlen(data))) {
+ ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
return -1;
}
l=strlen(data)+2;
orig_s=malloc(l);
+ if (!orig_s) {
+ ast_log(LOG_WARNING, "Out of memory\n");
+ return -1;
+ }
s=orig_s;
strncpy(s,data,l);
@@ -85,9 +89,10 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
return -1;
}
- timeout = atoi(strsep(&s, "|"));
- timeout *= 1000;
-
+ if (s) {
+ timeout = atoi(strsep(&s, "|"));
+ timeout *= 1000;
+ }
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");
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 446b26422..4bb5aef6a 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -78,7 +78,7 @@ static char *descrip =
" 'n' -- no retries on the timeout; will exit this application and go to the next step.\n"
" In addition to transferring the call, a call may be parked and then picked\n"
"up by another user.\n"
-" The optionnal URL will be sent to the called party if the channel supports\n"
+" The optional URL will be sent to the called party if the channel supports\n"
"it.\n";
// [PHM 06/26/03]
@@ -482,7 +482,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
if (numlines == numbusies) {
ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
} else {
- ast_log(LOG_NOTICE, "No one is answered queue %s\n", queue);
+ ast_log(LOG_NOTICE, "No one is answering queue '%s'\n", queue);
}
*to = 0;
return NULL;
@@ -1344,7 +1344,7 @@ static void reload_queues(void)
ast_mutex_unlock(&qlock);
}
-static int queues_show(int fd, int argc, char **argv)
+static int __queues_show(int fd, int argc, char **argv, int queue_show)
{
struct ast_call_queue *q;
struct queue_ent *qe;
@@ -1353,19 +1353,32 @@ static int queues_show(int fd, int argc, char **argv)
time_t now;
char max[80];
char calls[80];
-
time(&now);
- if (argc != 2)
+ if ((!queue_show && argc != 2) || (queue_show && argc != 3))
return RESULT_SHOWUSAGE;
ast_mutex_lock(&qlock);
q = queues;
if (!q) {
ast_mutex_unlock(&qlock);
- ast_cli(fd, "No queues.\n");
+ if (queue_show)
+ ast_cli(fd, "No such queue: %s.\n",argv[2]);
+ else
+ ast_cli(fd, "No queues.\n");
return RESULT_SUCCESS;
}
while(q) {
ast_mutex_lock(&q->lock);
+ if (queue_show) {
+ if (strcasecmp(q->name, argv[2]) != 0) {
+ ast_mutex_unlock(&q->lock);
+ q = q->next;
+ if (!q) {
+ ast_cli(fd, "No such queue: %s.\n",argv[2]);
+ break;
+ }
+ continue;
+ }
+ }
if (q->maxlen)
snprintf(max, sizeof(max), "%d", q->maxlen);
else
@@ -1400,11 +1413,41 @@ static int queues_show(int fd, int argc, char **argv)
ast_cli(fd, "\n");
ast_mutex_unlock(&q->lock);
q = q->next;
+ if (queue_show)
+ break;
}
ast_mutex_unlock(&qlock);
return RESULT_SUCCESS;
}
+static int queues_show(int fd, int argc, char **argv)
+{
+ return __queues_show(fd, argc, argv, 0);
+}
+
+static int queue_show(int fd, int argc, char **argv)
+{
+ return __queues_show(fd, argc, argv, 1);
+}
+
+static char *complete_queue(char *line, char *word, int pos, int state)
+{
+ struct ast_call_queue *q;
+ int which=0;
+
+ ast_mutex_lock(&qlock);
+ q = queues;
+ while(q) {
+ if (!strncasecmp(word, q->name, strlen(word))) {
+ if (++which > state)
+ break;
+ }
+ q = q->next;
+ }
+ ast_mutex_unlock(&qlock);
+ return q ? strdup(q->name) : NULL;
+}
+
/* JDG: callback to display queues status in manager */
static int manager_queues_show( struct mansession *s, struct message *m )
{
@@ -1469,12 +1512,23 @@ static struct ast_cli_entry cli_show_queues = {
{ "show", "queues", NULL }, queues_show,
"Show status of queues", show_queues_usage, NULL };
+static char show_queue_usage[] =
+"Usage: show queue\n"
+" Provides summary information on a specified queue.\n";
+
+static struct ast_cli_entry cli_show_queue = {
+ { "show", "queue", NULL }, queue_show,
+ "Show status of a specified queue", show_queue_usage, complete_queue };
+
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
+ ast_cli_unregister(&cli_show_queue);
ast_cli_unregister(&cli_show_queues);
ast_manager_unregister( "Queues" );
ast_manager_unregister( "QueueStatus" );
+ ast_unregister_application(app_aqm);
+ ast_unregister_application(app_rqm);
return ast_unregister_application(app);
}
@@ -1483,6 +1537,7 @@ int load_module(void)
int res;
res = ast_register_application(app, queue_exec, synopsis, descrip);
if (!res) {
+ ast_cli_register(&cli_show_queue);
ast_cli_register(&cli_show_queues);
ast_manager_register( "Queues", 0, manager_queues_show, "Queues" );
ast_manager_register( "QueueStatus", 0, manager_queues_status, "Queue Status" );
diff --git a/apps/app_random.c b/apps/app_random.c
index d46c1c0f6..c9f8f4788 100755
--- a/apps/app_random.c
+++ b/apps/app_random.c
@@ -42,7 +42,7 @@ static int random_exec(struct ast_channel *chan, void *data)
int res=0;
struct localuser *u;
- char *s, *ts;
+ char *s;
char *exten, *pri, *context;
char *prob;
int probint, priorityint;
@@ -54,7 +54,7 @@ static int random_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u);
s = ast_strdupa((void *) data);
- prob = strsep(&ts,":");
+ prob = strsep(&s,":");
if ((!prob) || (sscanf(prob, "%d", &probint) != 1))
probint = 0;
diff --git a/apps/app_record.c b/apps/app_record.c
index 732922ebf..29d98f760 100755
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -30,13 +30,13 @@ static char *app = "Record";
static char *synopsis = "Record to a file";
static char *descrip =
-" Record(filename:extension|silence): Records from the channel into a given\n"
+" Record(filename:format|silence): Records from the channel into a given\n"
"filename. If the file exists it will be overwritten. \n"
-"- 'extension' is the extension of the file type to be recorded (wav, gsm, etc).\n"
+"- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
"- 'silence' is the number of seconds of silence to allow before returning.\n\n"
"If filename contains '%d', these characters will be replaced with a number\n"
"incremented by one each time the file is recorded. \n\n"
-"Extensions: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
+"Formats: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
"Returns -1 when the user hangs up.\n";
STANDARD_LOCAL_USER;
diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c
index 3e7e1f462..302d2563a 100755
--- a/apps/app_sql_postgres.c
+++ b/apps/app_sql_postgres.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2002, Christos Ricudis
*
- * Christos Ricudis <ricudis@paiko.gr>
+ * Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
diff --git a/apps/app_system.c b/apps/app_system.c
index 3378602fe..b13bcedc8 100755
--- a/apps/app_system.c
+++ b/apps/app_system.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
#include <pthread.h>
@@ -53,13 +54,15 @@ static int system_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u);
/* Do our thing here */
res = system((char *)data);
- if (res < 0) {
+ if ((res < 0) && (errno != ECHILD)) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else if (res == 127) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else {
+ if (res < 0)
+ res = 0;
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
res = 0;
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 536a2e0a8..0dbf0531b 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -148,12 +148,14 @@ static char *synopsis_vm =
static char *descrip_vm =
" VoiceMail([s|u|b]extension[@context]): Leaves voicemail for a given\n"
-"extension (must be configured in voicemail.conf). If the extension is\n"
-"preceded by an 's' then instructions for leaving the message will be\n"
-"skipped. If the extension is preceeded by 'u' then the \"unavailable\"\n"
-"message will be played (/var/lib/asterisk/sounds/vm/<exten>/unavail) if it\n"
-"exists. If the extension is preceeded by a 'b' then the the busy message\n"
-"will be played (that is, busy instead of unavail).\n"
+"extension (must be configured in voicemail.conf). \n"
+" If the extension is preceded by \n"
+"* 's' instructions for leaving the message will be skipped.\n"
+"* 'u' the \"unavailable\" message will be played \n"
+" (/var/lib/asterisk/sounds/vm/<exten>/unavail) if it exists.\n"
+"* 'b' the busy message will be played (that is, busy instead of unavail).\n"
+"If the caller presses '0' (zero) during the prompt, the call jumps to\n"
+"priority 'o' in the current context.\n"
"If the requested mailbox does not exist, and there exists a priority\n"
"n + 101, then that priority will be taken next.\n"
"Returns -1 on error or mailbox not found, or if the user hangs up.\n"
@@ -167,7 +169,7 @@ 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 context only.\n"
+"a context is specified, logins are considered in that voicemail context only.\n"
"Returns -1 if the user hangs up or 0 otherwise.\n";
/* Leave a message */
@@ -450,11 +452,14 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
FILE *configin;
FILE *configout;
+ int linenum=0;
char inbuf[256];
char orig[256];
+ char currcontext[256] ="";
char tmpin[AST_CONFIG_MAX_PATH];
char tmpout[AST_CONFIG_MAX_PATH];
- char *user, *pass, *rest, *trim;
+ char *user, *pass, *rest, *trim, *tempcontext;
+ tempcontext = NULL;
snprintf((char *)tmpin, sizeof(tmpin)-1, "%s/voicemail.conf",(char *)ast_config_AST_CONFIG_DIR);
snprintf((char *)tmpout, sizeof(tmpout)-1, "%s/voicemail.conf.new",(char *)ast_config_AST_CONFIG_DIR);
configin = fopen((char *)tmpin,"r");
@@ -477,6 +482,7 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
while (!feof(configin)) {
/* Read in the line */
fgets(inbuf, sizeof(inbuf), configin);
+ linenum++;
if (!feof(configin)) {
/* Make a backup of it */
memcpy(orig, inbuf, sizeof(orig));
@@ -488,6 +494,18 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
user=inbuf;
while(*user < 33)
user++;
+ /* check for '[' (opening of context name ) */
+ tempcontext = strchr(user, '[');
+ if (tempcontext) {
+ strncpy(currcontext, tempcontext +1,
+ sizeof(currcontext) - 1);
+ /* now check for ']' */
+ tempcontext = strchr(currcontext, ']');
+ if (tempcontext)
+ *tempcontext = '\0';
+ else
+ currcontext[0] = '\0';
+ }
pass = strchr(user, '=');
if (pass > user) {
trim = pass - 1;
@@ -512,7 +530,11 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
}
} else
rest = NULL;
- if (user && pass && *user && *pass && !strcmp(user, vmu->mailbox) && !strcmp(pass, vmu->password)) {
+
+ /* Compare user, pass AND context */
+ if (user && *user && !strcmp(user, vmu->mailbox) &&
+ pass && *pass && !strcmp(pass, vmu->password) &&
+ currcontext && *currcontext && !strcmp(currcontext, vmu->context)) {
/* This is the line */
if (rest) {
fprintf(configout, "%s => %s,%s\n", vmu->mailbox,newpassword,rest);
@@ -741,7 +763,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
fprintf(p, "--%s\n", bound);
}
- fprintf(p, "Content-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: 8bit\n");
+ fprintf(p, "Content-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: 8bit\n\n");
strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
if (emailbody) {
struct ast_channel *ast = ast_channel_alloc(0);
@@ -1318,6 +1340,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
FILE *txt;
int res = 0;
int msgnum;
+ int fd;
char date[256];
char dir[256];
char fn[256];
@@ -1453,11 +1476,15 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
res = play_and_record(chan, NULL, fn, vmmaxmessage, fmt);
if (res > 0)
res = 0;
- txt = fopen(txtfile, "a");
- if (txt) {
- time(&end);
- fprintf(txt, "duration=%ld\n", (long)(end-start));
- fclose(txt);
+ fd = open(txtfile, O_APPEND | O_WRONLY);
+ if (fd > -1) {
+ txt = fdopen(fd, "a");
+ if (txt) {
+ time(&end);
+ fprintf(txt, "duration=%ld\n", (long)(end-start));
+ fclose(txt);
+ } else
+ close(fd);
}
stringp = fmt;
strsep(&stringp, "|");
@@ -2244,7 +2271,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
system(sys);
todircount = count_messages(todir);
- strncpy(tmp, fmt, sizeof(tmp));
+ strncpy(tmp, fmt, sizeof(tmp) - 1);
stringp = tmp;
while((s = strsep(&stringp, "|"))) {
/* XXX This is a hack -- we should use build_filename or similar XXX */
@@ -2556,9 +2583,7 @@ static int vm_instructions(struct ast_channel *chan, struct vm_state *vms)
if (!res) {
vms->repeats++;
if (vms->repeats > 2) {
- res = play_and_wait(chan, "vm-goodbye");
- if (!res)
- res = 't';
+ res = 't';
}
}
}
@@ -2994,22 +3019,22 @@ static int append_mailbox(char *context, char *mbox, char *data)
char *stringp;
char *s;
struct ast_vm_user *vmu;
- strncpy(tmp, data, sizeof(tmp));
+ strncpy(tmp, data, sizeof(tmp) - 1);
vmu = malloc(sizeof(struct ast_vm_user));
if (vmu) {
memset(vmu, 0, sizeof(struct ast_vm_user));
- strncpy(vmu->context, context, sizeof(vmu->context));
- strncpy(vmu->mailbox, mbox, sizeof(vmu->mailbox));
+ strncpy(vmu->context, context, sizeof(vmu->context) - 1);
+ strncpy(vmu->mailbox, mbox, sizeof(vmu->mailbox) - 1);
vmu->attach = -1;
stringp = tmp;
if ((s = strsep(&stringp, ",")))
- strncpy(vmu->password, s, sizeof(vmu->password));
+ strncpy(vmu->password, s, sizeof(vmu->password) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->fullname, s, sizeof(vmu->fullname));
+ strncpy(vmu->fullname, s, sizeof(vmu->fullname) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->email, s, sizeof(vmu->email));
+ strncpy(vmu->email, s, sizeof(vmu->email) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->pager, s, sizeof(vmu->pager));
+ strncpy(vmu->pager, s, sizeof(vmu->pager) - 1);
if (stringp && (s = strsep(&stringp, ",")))
apply_options(vmu, s);
vmu->next = NULL;
@@ -3022,6 +3047,7 @@ static int append_mailbox(char *context, char *mbox, char *data)
return 0;
}
+#ifndef USEMYSQLVM
/* XXX TL Bug 690 */
static char show_voicemail_users_help[] =
"Usage: show voicemail users [for <context>]\n"
@@ -3143,7 +3169,7 @@ static struct ast_cli_entry show_voicemail_zones_cli =
{ { "show", "voicemail", "zones", NULL },
handle_show_voicemail_zones, "List zone message formats",
show_voicemail_zones_help, NULL };
-
+#endif
static int load_config(void)
{
@@ -3167,6 +3193,7 @@ static int load_config(void)
while(cur) {
l = cur;
cur = cur->next;
+ l->alloced = 1;
free_user(l);
}
zcur = zones;
@@ -3301,16 +3328,21 @@ static int load_config(void)
msg_format = ast_strdupa(var->value);
if (msg_format != NULL) {
timezone = strsep(&msg_format, "|");
- strncpy(z->name, var->name, sizeof(z->name) - 1);
- strncpy(z->timezone, timezone, sizeof(z->timezone) - 1);
- strncpy(z->msg_format, msg_format, sizeof(z->msg_format) - 1);
- z->next = NULL;
- if (zones) {
- zonesl->next = z;
- zonesl = z;
+ if (msg_format) {
+ strncpy(z->name, var->name, sizeof(z->name) - 1);
+ strncpy(z->timezone, timezone, sizeof(z->timezone) - 1);
+ strncpy(z->msg_format, msg_format, sizeof(z->msg_format) - 1);
+ z->next = NULL;
+ if (zones) {
+ zonesl->next = z;
+ zonesl = z;
+ } else {
+ zones = z;
+ zonesl = z;
+ }
} else {
- zones = z;
- zonesl = z;
+ ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
+ free(z);
}
} else {
ast_log(LOG_WARNING, "Out of memory while reading voicemail config\n");
@@ -3386,8 +3418,10 @@ int unload_module(void)
res |= ast_unregister_application(app2);
res |= ast_unregister_application(capp2);
sql_close();
+#ifndef USEMYSQLVM
ast_cli_unregister(&show_voicemail_users_cli);
ast_cli_unregister(&show_voicemail_zones_cli);
+#endif
return res;
}
@@ -3409,8 +3443,10 @@ int load_module(void)
ast_log(LOG_WARNING, "SQL init\n");
return res;
}
+#ifndef USEMYSQLVM
ast_cli_register(&show_voicemail_users_cli);
ast_cli_register(&show_voicemail_zones_cli);
+#endif
return res;
}
diff --git a/apps/app_waitforring.c b/apps/app_waitforring.c
index 3fcfa9a03..bb8622920 100755
--- a/apps/app_waitforring.c
+++ b/apps/app_waitforring.c
@@ -48,7 +48,7 @@ static int waitforring_exec(struct ast_channel *chan, void *data)
int res = 0;
int ms;
if (!data || (sscanf(data, "%d", &ms) != 1)) {
- ast_log(LOG_WARNING, "SoftHangup requires an argument (minimum seconds)\n");
+ ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
return 0;
}
ms *= 1000;
diff --git a/apps/app_zapras.c b/apps/app_zapras.c
index 57a64ab5d..9d88a06e3 100755
--- a/apps/app_zapras.c
+++ b/apps/app_zapras.c
@@ -44,7 +44,7 @@ static char *synopsis = "Executes Zaptel ISDN RAS application";
static char *descrip =
" ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
-"channel to be able to use this function (No modem emulcation is included).\n"
+"channel to be able to use this function (No modem emulation is included).\n"
"Your pppd must be patched to be zaptel aware. Arguments should be\n"
"separated by | characters. Always returns -1.\n";
diff --git a/apps/app_zapscan.c b/apps/app_zapscan.c
index 54db27df0..b24fe5d57 100755
--- a/apps/app_zapscan.c
+++ b/apps/app_zapscan.c
@@ -43,8 +43,8 @@ static char *app = "ZapScan";
static char *synopsis = "Scan Zap channels to monitor calls";
static char *descrip =
-" ZapScan allows a call center manager to monitor\n"
-"phone conversations in a convenient way.";
+" ZapScan allows a call center manager to monitor Zap channels in\n"
+"a convenient way. Use '#' to select the next channel and use '*' to exit\n";
STANDARD_LOCAL_USER;
@@ -191,6 +191,9 @@ zapretry:
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
ret = 0;
break;
+ } else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+ ret = -1;
+ break;
} else if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_ULAW) {
@@ -245,6 +248,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
int confno = 0;
char confstr[80], *tmp;
struct ast_channel *tempchan = NULL, *lastchan = NULL;
+ struct ast_frame *f;
LOCAL_USER_ADD(u);
@@ -252,10 +256,20 @@ static int conf_exec(struct ast_channel *chan, void *data)
ast_answer(chan);
for (;;) {
+ if (ast_waitfor(chan, 100) < 0)
+ break;
+ f = ast_read(chan);
+ if (!f)
+ break;
+ if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+ ast_frfree(f);
+ break;
+ }
+ ast_frfree(f);
tempchan = ast_channel_walk(tempchan);
if ( !tempchan && !lastchan )
break;
- if ( tempchan && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
+ if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
strcpy(confstr, tempchan->name);
if ((tmp = strchr(confstr,'-'))) {