aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-25 21:57:27 +0000
committer(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-25 21:57:27 +0000
commita18eb539c492640eee4dd2819fc2b35e732a7840 (patch)
tree2ab411cd1c8115954208ec7cb730108205bbae7a
parent29d68e40393b897d4844d0f1fd48b152e45674c3 (diff)
This commit was manufactured by cvs2svn to create tag 'v1-0-2'.
git-svn-id: http://svn.digium.com/svn/asterisk/tags/v1-0-2@4097 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xCHANGES6
-rwxr-xr-xCREDITS2
-rwxr-xr-xMakefile4
-rwxr-xr-xacl.c7
-rwxr-xr-xapps/app_dial.c3
-rwxr-xr-xapps/app_festival.c6
-rwxr-xr-xapps/app_forkcdr.c5
-rwxr-xr-xapps/app_hasnewvoicemail.c28
-rwxr-xr-xapps/app_meetme.c7
-rwxr-xr-xapps/app_record.c2
-rwxr-xr-xapps/app_sms.c13
-rwxr-xr-xapps/app_userevent.c2
-rwxr-xr-xapps/app_voicemail.c141
-rwxr-xr-xcallerid.c2
-rwxr-xr-xcdr.c11
-rwxr-xr-xcdr/cdr_csv.c3
-rwxr-xr-xcdr/cdr_odbc.c205
-rwxr-xr-xchannels/chan_agent.c17
-rwxr-xr-xchannels/chan_iax2.c62
-rwxr-xr-xchannels/chan_mgcp.c16
-rwxr-xr-xchannels/chan_modem.c15
-rwxr-xr-xchannels/chan_sip.c76
-rwxr-xr-xchannels/chan_zap.c63
-rwxr-xr-xchannels/h323/chan_h323.h2
-rwxr-xr-xchannels/iax2-parser.c2
-rwxr-xr-xcli.c20
-rwxr-xr-xdb1-ast/hash/ndbm.c50
-rwxr-xr-xformats/format_wav_gsm.c2
-rwxr-xr-xinclude/asterisk/cdr.h2
-rwxr-xr-xpbx.c7
-rwxr-xr-xres/res_monitor.c10
-rwxr-xr-xres/res_odbc.c12
-rwxr-xr-xtdd.c2
33 files changed, 499 insertions, 306 deletions
diff --git a/CHANGES b/CHANGES
index edec34511..2a6287aac 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,13 @@
+Asterisk 1.0.2
+ -- Major bugfix release
+Asterisk 1.0.1
+ -- Added AGI over TCP support
-- Add ability to purge callers from queue if no agents are logged in
-- Fix inband PRI indication detection
-- Fix for MGCP - always request digits if no RTP stream
-- Fixed seg fault for ast_control_streamfile
- -- Added AGI over TCP support
-- Make pick-up extension configurable via features.conf
+ -- Numerous other bug fixes
Asterisk 1.0.0
-- Use Q.931 standard cause codes for asterisk cause codes
-- Bug fixes from the bug tracker
diff --git a/CREDITS b/CREDITS
index 8b36cfc3c..11552bdec 100755
--- a/CREDITS
+++ b/CREDITS
@@ -58,6 +58,8 @@ Thorsten Lockert - OpenBSD, FreeBSD ports, making MacOS X port run on 10.3,
bugs. tholo@sigmasoft.com
Brian West - ODBC support and Bug Marshaling
William Waites - syslog support, SIP NAT traversal for SIP-UA. ww@styx.org
+Rich Murphey - Porting to FreeBSD, NetBSD, OpenBSD, and Darwin.
+ rich@whiteoaklabs.com http://whiteoaklabs.com
=== OTHER CONTRIBUTIONS ===
John Todd - Monkey sounds and associated teletorture prompt
diff --git a/Makefile b/Makefile
index 10483c355..652afb37a 100755
--- a/Makefile
+++ b/Makefile
@@ -146,7 +146,7 @@ endif # FreeBSD
ifeq (${OSARCH},NetBSD)
CFLAGS+=-pthread
-INCLUDE+=-I/usr/local/include
+INCLUDE+=-I/usr/local/include -I/usr/pkg/include
endif
ifeq (${OSARCH},OpenBSD)
@@ -197,7 +197,7 @@ ifeq (${OSARCH},FreeBSD)
LIBS+=-lcrypto
endif
ifeq (${OSARCH},NetBSD)
-LIBS+=-lpthread -lcrypto -lm -L/usr/local/lib -lncurses
+LIBS+=-lpthread -lcrypto -lm -L/usr/local/lib -L/usr/pkg/lib -lncurses
endif
ifeq (${OSARCH},OpenBSD)
LIBS=-lcrypto -lpthread -lm -lncurses
diff --git a/acl.c b/acl.c
index 6c460969f..935ec808d 100755
--- a/acl.c
+++ b/acl.c
@@ -242,20 +242,19 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
m_rtmsg.m_rtm.rtm_type = RTM_GET;
- m_rtmsg.m_rtm.rtm_flags = RTF_UP | RTF_HOST;
m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
ast_mutex_lock(&routeseq_lock);
seq = ++routeseq;
ast_mutex_unlock(&routeseq_lock);
m_rtmsg.m_rtm.rtm_seq = seq;
- m_rtmsg.m_rtm.rtm_addrs = RTA_IFA | RTA_DST;
+ m_rtmsg.m_rtm.rtm_addrs = RTA_DST | RTA_IFA;
m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *)m_rtmsg.m_space;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr = *them;
- if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
+ if ((s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) {
ast_log(LOG_ERROR, "Error opening routing socket\n");
return -1;
}
@@ -268,7 +267,7 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
}
do {
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
- } while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != 1 || m_rtmsg.m_rtm.rtm_pid != pid));
+ } while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != seq || m_rtmsg.m_rtm.rtm_pid != pid));
if (l < 0) {
if (errno != EAGAIN)
ast_log(LOG_ERROR, "Error reading from routing socket\n");
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 7f3c3d768..d1e03c222 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -336,7 +336,8 @@ 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 */
diff --git a/apps/app_festival.c b/apps/app_festival.c
index e7e0bd426..7b6f68634 100755
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -305,9 +305,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 +325,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 +334,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 +344,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 +447,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..bf493d523 100755
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -23,7 +23,8 @@
static char *tdesc = "Fork The CDR into 2 seperate 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_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_meetme.c b/apps/app_meetme.c
index ef2ff3de9..ba63f554d 100755
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -1454,14 +1454,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_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..882236822 100755
--- a/apps/app_sms.c
+++ b/apps/app_sms.c
@@ -26,6 +26,7 @@
#include <sys/types.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 +37,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 +319,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 +521,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 +693,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 +773,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 +1209,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_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..f4dad6a7c 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -215,7 +215,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 +708,18 @@ 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];
+ for (x=0;x<MAXMSG;x++) {
+ make_file(fn, sizeof(fn), dir, x);
+ if (ast_fileexists(fn, NULL, NULL) < 1)
+ break;
+ }
+ return x-1;
+}
+
static int
inbuf(struct baseio *bio, FILE *fi)
{
@@ -989,7 +1004,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;
@@ -1403,22 +1418,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);
@@ -1434,6 +1449,12 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
break;
msgnum++;
} while(msgnum < MAXMSG);
+ 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 (msgnum < MAXMSG) {
/* Store information */
snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
@@ -1525,16 +1546,56 @@ 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];
+
+ 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;
}
+
static int say_and_wait(struct ast_channel *chan, int num, char *language)
{
int d;
@@ -2545,6 +2606,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);
}
@@ -3800,7 +3875,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);
}
@@ -4584,9 +4659,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
/* User has hung up, no options to give */
return res;
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 +4712,11 @@ 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) {
+ ast_play_and_wait(chan, "vm-deleted");
+ vm_delete(recordfile);
+ }
+ 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
diff --git a/callerid.c b/callerid.c
index 348c84404..5481676ec 100755
--- a/callerid.c
+++ b/callerid.c
@@ -334,6 +334,8 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, int
cid->number[res] = '\0';
}
break;
+ case 6: /* Stentor Call Qualifier (ie. Long Distance call) */
+ break;
case 7: /* Name */
case 8: /* Name */
res = cid->rawdata[x];
diff --git a/cdr.c b/cdr.c
index f4e97efce..5a8102f30 100755
--- a/cdr.c
+++ b/cdr.c
@@ -524,11 +524,16 @@ void ast_cdr_reset(struct ast_cdr *cdr, int flags)
}
-void ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr) {
+struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr)
+{
+ struct ast_cdr *ret;
if (cdr) {
+ ret = cdr;
while(cdr->next)
cdr = cdr->next;
cdr->next = newcdr;
- } else
- ast_log(LOG_ERROR, "Can't append a CDR to NULL!\n");
+ } else {
+ ret = newcdr;
+ }
+ return ret;
}
diff --git a/cdr/cdr_csv.c b/cdr/cdr_csv.c
index a1d391cfb..95598bd52 100755
--- a/cdr/cdr_csv.c
+++ b/cdr/cdr_csv.c
@@ -184,7 +184,7 @@ static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
static int writefile(char *s, char *acc)
{
- char tmp[256];
+ char tmp[AST_CONFIG_MAX_PATH];
FILE *f;
if (strchr(acc, '/') || (acc[0] == '.')) {
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
@@ -195,6 +195,7 @@ static int writefile(char *s, char *acc)
if (!f)
return -1;
fputs(s, f);
+ fflush(f);
fclose(f);
return 0;
}
diff --git a/cdr/cdr_odbc.c b/cdr/cdr_odbc.c
index e52730f2e..3fb4b2c14 100755
--- a/cdr/cdr_odbc.c
+++ b/cdr/cdr_odbc.c
@@ -65,26 +65,21 @@ static int odbc_log(struct ast_cdr *cdr)
ast_mutex_lock(&odbc_lock);
strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
memset(sqlcmd,0,2048);
- if((loguniqueid != NULL) && ((strcmp(loguniqueid, "1") == 0) || (strcmp(loguniqueid, "yes") == 0)))
- {
+ if ((loguniqueid != NULL) && (ast_true(loguniqueid))) {
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO cdr "
"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
"lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
- }
- else
- {
+ } else {
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO cdr "
"(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
"duration,billsec,disposition,amaflags,accountcode) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
}
- if(!connected)
- {
+ if (!connected) {
res = odbc_init();
- if(res < 0)
- {
+ if (res < 0) {
connected = 0;
ast_mutex_unlock(&odbc_lock);
return 0;
@@ -94,9 +89,8 @@ static int odbc_log(struct ast_cdr *cdr)
ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res);
SQLGetDiagRec(SQL_HANDLE_DBC, ODBC_con, 1, ODBC_stat, &ODBC_err, ODBC_msg, 100, &ODBC_mlen);
SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
@@ -111,9 +105,8 @@ static int odbc_log(struct ast_cdr *cdr)
ODBC_res = SQLPrepare(ODBC_stmt, sqlcmd, SQL_NTS);
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in PREPARE %d\n", ODBC_res);
SQLGetDiagRec(SQL_HANDLE_DBC, ODBC_con, 1, ODBC_stat, &ODBC_err, ODBC_msg, 100, &ODBC_mlen);
SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
@@ -137,44 +130,35 @@ static int odbc_log(struct ast_cdr *cdr)
SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL);
SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL);
- if((loguniqueid != NULL) && ((strcmp(loguniqueid, "1") == 0) || (strcmp(loguniqueid, "yes") == 0)))
- {
+ if ((loguniqueid != NULL) && (ast_true(loguniqueid))) {
SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL);
SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL);
}
- if(connected)
- {
+ if (connected) {
res = odbc_do_query();
- if(res < 0)
- {
- if(option_verbose > 10)
+ if (res < 0) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
res = odbc_init();
- if(option_verbose > 10)
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Reconnecting to dsn %s\n", dsn);
- if(res < 0)
- {
- if(option_verbose > 10)
+ if (res < 0) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: %s has gone away!\n", dsn);
connected = 0;
- }
- else
- {
- if(option_verbose > 10)
+ } else {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Trying Query again!\n");
res = odbc_do_query();
- if(res < 0)
- {
- if(option_verbose > 10)
+ if (res < 0) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
}
}
}
- }
- else
- {
- if(option_verbose > 10)
+ } else {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
}
ast_mutex_unlock(&odbc_lock);
@@ -189,9 +173,8 @@ char *description(void)
static int odbc_unload_module(void)
{
ast_mutex_lock(&odbc_lock);
- if (connected)
- {
- if(option_verbose > 10)
+ if (connected) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Disconnecting from %s\n", dsn);
SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
SQLDisconnect(ODBC_con);
@@ -199,33 +182,29 @@ static int odbc_unload_module(void)
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
connected = 0;
}
- if (dsn && dsn_alloc)
- {
- if(option_verbose > 10)
+ if (dsn && dsn_alloc) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free dsn\n");
free(dsn);
dsn = NULL;
dsn_alloc = 0;
}
- if (username && username_alloc)
- {
- if(option_verbose > 10)
+ if (username && username_alloc) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free username\n");
free(username);
username = NULL;
username_alloc = 0;
}
- if (password && password_alloc)
- {
- if(option_verbose > 10)
+ if (password && password_alloc) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free password\n");
free(password);
password = NULL;
password_alloc = 0;
}
- if (loguniqueid && loguniqueid_alloc)
- {
- if(option_verbose > 10)
+ if (loguniqueid && loguniqueid_alloc) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free loguniqueid\n");
free(loguniqueid);
loguniqueid = NULL;
@@ -246,8 +225,7 @@ static int odbc_load_module(void)
ast_mutex_lock(&odbc_lock);
cfg = ast_load(config);
- if (!cfg)
- {
+ if (!cfg) {
ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
goto out;
}
@@ -259,113 +237,84 @@ static int odbc_load_module(void)
}
tmp = ast_variable_retrieve(cfg,"global","dsn");
- if (tmp)
- {
+ if (tmp) {
dsn = malloc(strlen(tmp) + 1);
- if (dsn != NULL)
- {
+ if (dsn != NULL) {
memset(dsn, 0, strlen(tmp) + 1);
dsn_alloc = 1;
strncpy(dsn, tmp, strlen(tmp));
- }
- else
- {
+ } else {
ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
return -1;
}
- }
- else
- {
+ } else {
ast_log(LOG_WARNING,"cdr_odbc: dsn not specified. Assuming asteriskdb\n");
dsn = "asteriskdb";
}
tmp = ast_variable_retrieve(cfg,"global","username");
- if (tmp)
- {
+ if (tmp) {
username = malloc(strlen(tmp) + 1);
- if (username != NULL)
- {
+ if (username != NULL) {
memset(username, 0, strlen(tmp) + 1);
username_alloc = 1;
strncpy(username, tmp, strlen(tmp));
- }
- else
- {
+ } else {
ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
return -1;
}
- }
- else
- {
+ } else {
ast_log(LOG_WARNING,"cdr_odbc: username not specified. Assuming root\n");
username = "root";
}
tmp = ast_variable_retrieve(cfg,"global","password");
- if (tmp)
- {
+ if (tmp) {
password = malloc(strlen(tmp) + 1);
- if (password != NULL)
- {
+ if (password != NULL) {
memset(password, 0, strlen(tmp) + 1);
password_alloc = 1;
strncpy(password, tmp, strlen(tmp));
- }
- else
- {
+ } else {
ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
return -1;
}
- }
- else
- {
+ } else {
ast_log(LOG_WARNING,"cdr_odbc: database password not specified. Assuming blank\n");
password = "";
}
tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
- if (tmp)
- {
+ if (tmp) {
loguniqueid = malloc(strlen(tmp) + 1);
- if (loguniqueid != NULL)
- {
+ if (loguniqueid != NULL) {
strcpy(loguniqueid,tmp);
loguniqueid_alloc = 1;
ast_log(LOG_NOTICE,"cdr_odbc: Logging uniqueid\n");
- }
- else
- {
+ } else {
ast_log(LOG_ERROR,"cdr_odbc: Not logging uniqueid\n");
loguniqueid_alloc = 1;
loguniqueid = NULL;
}
- }
- else
- {
+ } else {
ast_log(LOG_WARNING,"cdr_odbc: Not logging uniqueid\n");
loguniqueid = NULL;
}
ast_destroy(cfg);
- if(option_verbose > 3)
- {
+ if (option_verbose > 3) {
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: dsn is %s\n",dsn);
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: username is %s\n",username);
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: password is [secret]\n");
-
}
res = odbc_init();
- if(res < 0)
- {
+ if (res < 0) {
ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
}
-
res = ast_cdr_register(name, desc, odbc_log);
- if (res)
- {
+ if (res) {
ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
}
out:
@@ -375,25 +324,22 @@ out:
static int odbc_do_query(void)
{
- long int ODBC_err;
+ long int ODBC_err;
int ODBC_res;
- short int ODBC_mlen;
- char ODBC_msg[200], ODBC_stat[10];
-
+ short int ODBC_mlen;
+ char ODBC_msg[200], ODBC_stat[10];
+
ODBC_res = SQLExecute(ODBC_stmt);
-
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in Query %d\n", ODBC_res);
SQLGetDiagRec(SQL_HANDLE_DBC, ODBC_con, 1, ODBC_stat, &ODBC_err, ODBC_msg, 100, &ODBC_mlen);
SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
connected = 0;
return -1;
- }
- else
- {
- if(option_verbose > 10)
+ } else {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query Successful!\n");
connected = 1;
}
@@ -407,13 +353,10 @@ static int odbc_init(void)
int ODBC_res;
char ODBC_msg[200], ODBC_stat[10];
- if ( ODBC_env == SQL_NULL_HANDLE || connected == 0 )
- {
+ if (ODBC_env == SQL_NULL_HANDLE || connected == 0) {
ODBC_res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &ODBC_env);
-
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHandle\n");
connected = 0;
return -1;
@@ -421,9 +364,8 @@ static int odbc_init(void)
ODBC_res = SQLSetEnvAttr(ODBC_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SetEnv\n");
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
connected = 0;
@@ -432,32 +374,27 @@ static int odbc_init(void)
ODBC_res = SQLAllocHandle(SQL_HANDLE_DBC, ODBC_env, &ODBC_con);
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHDB %d\n", ODBC_res);
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
connected = 0;
return -1;
}
-
SQLSetConnectAttr(ODBC_con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)10, 0);
}
ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);
- if((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
- if(option_verbose > 10)
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SQLConnect %d\n", ODBC_res);
SQLGetDiagRec(SQL_HANDLE_DBC, ODBC_con, 1, ODBC_stat, &ODBC_err, ODBC_msg, 100, &ODBC_mlen);
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
connected = 0;
return -1;
- }
- else
- {
- if(option_verbose > 10)
+ } else {
+ if (option_verbose > 10)
ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Connected to %s\n", dsn);
connected = 1;
}
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index c5dcc891e..6e8c3661a 100755
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -519,9 +519,22 @@ static int agent_hangup(struct ast_channel *ast)
ast->pvt->pvt = NULL;
p->app_sleep_cond = 1;
p->acknowledged = 0;
- if (p->start && (ast->_state != AST_STATE_UP))
+
+ /* if they really are hung up then set start to 0 so the test
+ * later if we're called on an already downed channel
+ * doesn't cause an agent to be logged out like when
+ * agent_request() is followed immediately by agent_hangup()
+ * as in apps/app_chanisavail.c:chanavail_exec()
+ */
+
+ ast_log(LOG_DEBUG, "Hangup called for state %s\n", ast_state2str(ast->_state));
+ if (p->start && (ast->_state != AST_STATE_UP)) {
howlong = time(NULL) - p->start;
- time(&p->start);
+ p->start = 0;
+ } else if (ast->_state == AST_STATE_RESERVED) {
+ howlong = 0;
+ } else
+ p->start = 0;
if (p->chan) {
/* If they're dead, go ahead and hang up on the agent now */
if (!ast_strlen_zero(p->loginchan)) {
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index e8b56282d..70cb43410 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -536,12 +536,12 @@ AST_MUTEX_DEFINE_STATIC(dpcache_lock);
static void iax_debug_output(const char *data)
{
if (iaxdebug)
- ast_verbose(data);
+ ast_verbose("%s", data);
}
static void iax_error_output(const char *data)
{
- ast_log(LOG_WARNING, data);
+ ast_log(LOG_WARNING, "%s", data);
}
/* XXX We probably should use a mutex when working with this XXX */
@@ -1731,7 +1731,7 @@ static void unwrap_timestamp(struct iax_frame *fr)
}
}
-static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int updatehistory)
+static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int updatehistory, int fromtrunk)
{
int ms,x;
int delay;
@@ -1794,7 +1794,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update
ms = 0;
/* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
- if (iaxs[fr->callno]->rxcore.tv_sec || iaxs[fr->callno]->rxcore.tv_usec) {
+ if ( (!fromtrunk) && (iaxs[fr->callno]->rxcore.tv_sec || iaxs[fr->callno]->rxcore.tv_usec) ) {
fr->af.delivery.tv_sec = iaxs[fr->callno]->rxcore.tv_sec;
fr->af.delivery.tv_usec = iaxs[fr->callno]->rxcore.tv_usec;
fr->af.delivery.tv_sec += fr->ts / 1000;
@@ -1807,7 +1807,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update
else {
#if 0
if (reallydeliver)
- ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet.\n");
+ ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
#endif
fr->af.delivery.tv_sec = 0;
fr->af.delivery.tv_usec = 0;
@@ -1888,7 +1888,8 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update
delay = maxjitterbuffer;
/* If jitter buffer is disabled then just pretend the frame is "right on time" */
- if (!iaxs[fr->callno]->usejitterbuf)
+ /* If frame came from trunk, also don't do any delay */
+ if ( (!iaxs[fr->callno]->usejitterbuf) || fromtrunk )
delay = 0;
if (option_debug) {
@@ -2628,8 +2629,10 @@ tackygoto:
cs[1] = cs[2];
}
lock_both(callno0, callno1);
- iaxs[callno0]->bridgecallno = 0;
- iaxs[callno1]->bridgecallno = 0;
+ if(iaxs[callno0])
+ iaxs[callno0]->bridgecallno = 0;
+ if(iaxs[callno1])
+ iaxs[callno1]->bridgecallno = 0;
unlock_both(callno0, callno1);
return res;
}
@@ -4340,7 +4343,8 @@ static int expire_registry(void *data)
p->expire = -1;
/* Reset expirey value */
p->expirey = expirey;
- ast_db_del("IAX/Registry", p->name);
+ if (p->temponly !=1)
+ ast_db_del("IAX/Registry", p->name);
register_peer_exten(p, 0);
if (iax2_regfunk)
iax2_regfunk(p->name, 0);
@@ -4356,7 +4360,7 @@ static void reg_source_db(struct iax2_peer *p)
struct in_addr in;
char iabuf[INET_ADDRSTRLEN];
char *c, *d;
- if (!ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
+ if ((p->temponly != 1) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
c = strchr(data, ':');
if (c) {
*c = '\0';
@@ -4416,7 +4420,7 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno, char
if (iax2_regfunk)
iax2_regfunk(p->name, 1);
snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expirey);
- if (sin->sin_addr.s_addr) {
+ if ((p->temponly != 1) && (sin->sin_addr.s_addr)) {
ast_db_put("IAX/Registry", p->name, data);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Registered '%s' (%s) at %s:%d\n", p->name,
@@ -5079,10 +5083,10 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
if (iaxs[fr.callno]->bridgecallno) {
forward_delivery(&fr);
} else {
- schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
+ schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1);
}
#else
- schedule_delivery(iaxfrdup2(&fr), 1, updatehistory);
+ schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1);
#endif
}
} else {
@@ -5148,7 +5152,9 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
ast_mutex_unlock(&iaxsl[fr.callno]);
return 1;
}
- if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid)
+ if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid &&
+ f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */
+ f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */
iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
if (ntohs(mh->callno) & IAX_FLAG_FULL) {
if (option_debug)
@@ -5170,12 +5176,18 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
if ((iaxs[fr.callno]->iseqno != fr.oseqno) &&
(iaxs[fr.callno]->iseqno ||
((f.subclass != IAX_COMMAND_TXCNT) &&
+ (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
+ (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
+ (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
(f.subclass != IAX_COMMAND_TXACC)) ||
- (f.subclass != AST_FRAME_IAX))) {
+ (f.frametype != AST_FRAME_IAX))) {
if (
((f.subclass != IAX_COMMAND_ACK) &&
(f.subclass != IAX_COMMAND_INVAL) &&
(f.subclass != IAX_COMMAND_TXCNT) &&
+ (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
+ (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
+ (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
(f.subclass != IAX_COMMAND_TXACC) &&
(f.subclass != IAX_COMMAND_VNAK)) ||
(f.frametype != AST_FRAME_IAX)) {
@@ -5335,7 +5347,7 @@ retryowner:
if (option_debug)
ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
/* Go through the motions of delivering the packet without actually doing so */
- schedule_delivery(&fr, 0, updatehistory);
+ schedule_delivery(&fr, 0, updatehistory, 0);
switch(f.subclass) {
case IAX_COMMAND_ACK:
/* Do nothing */
@@ -5885,6 +5897,7 @@ retryowner2:
/* Send ack immediately, rather than waiting until we've changed addresses */
send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
complete_transfer(fr.callno, &ies);
+ stop_stuff(fr.callno); /* for attended transfer to work with libiax */
break;
case IAX_COMMAND_DPREP:
complete_dpreply(iaxs[fr.callno], &ies);
@@ -5929,7 +5942,7 @@ retryowner2:
if (iaxs[fr.callno]->videoformat > 0)
f.subclass = iaxs[fr.callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
else {
- ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
+ ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
iax2_vnak(fr.callno);
ast_mutex_unlock(&iaxsl[fr.callno]);
return 1;
@@ -5993,12 +6006,12 @@ retryowner2:
forward_delivery(&fr);
} else {
duped_fr = iaxfrdup2(&fr);
- schedule_delivery(duped_fr, 1, updatehistory);
+ schedule_delivery(duped_fr, 1, updatehistory, 0);
fr.ts = duped_fr->ts;
}
#else
duped_fr = iaxfrdup2(&fr);
- schedule_delivery(duped_fr, 1, updatehistory);
+ schedule_delivery(duped_fr, 1, updatehistory, 0);
fr.ts = duped_fr->ts;
#endif
@@ -6386,9 +6399,11 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v)
} else {
ast_mutex_unlock(&peerl.lock);
peer = malloc(sizeof(struct iax2_peer));
- memset(peer, 0, sizeof(struct iax2_peer));
- peer->expire = -1;
- peer->pokeexpire = -1;
+ if (peer) {
+ memset(peer, 0, sizeof(struct iax2_peer));
+ peer->expire = -1;
+ peer->pokeexpire = -1;
+ }
}
if (peer) {
peer->messagedetail = globalmessagedetail;
@@ -6553,7 +6568,8 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v)
} else {
ast_mutex_unlock(&userl.lock);
user = malloc(sizeof(struct iax2_user));
- memset(user, 0, sizeof(struct iax2_user));
+ if (user)
+ memset(user, 0, sizeof(struct iax2_user));
}
if (user) {
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 22058c775..7406428be 100755
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -1785,7 +1785,7 @@ static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *ver
static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
{
- memset(resp, 0, sizeof(*resp));
+ memset(resp, 0, sizeof(struct mgcp_request));
init_resp(resp, msg, req, msgrest);
return 0;
}
@@ -1947,7 +1947,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
add_header(&resp, "X", sub->txident);
add_header(&resp, "I", sub->cxident);
/*add_header(&resp, "S", "");*/
- ast_rtp_offered_from_local(rtp, 0);
+ ast_rtp_offered_from_local(sub->rtp, 0);
add_sdp(&resp, sub, rtp);
/* SC: fill in new fields */
resp.cmd = MGCP_CMD_MDCX;
@@ -1981,7 +1981,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
/* SC: X header should not be sent. kept for compatibility */
add_header(&resp, "X", sub->txident);
/*add_header(&resp, "S", "");*/
- ast_rtp_offered_from_local(rtp, 1);
+ ast_rtp_offered_from_local(sub->rtp, 1);
add_sdp(&resp, sub, rtp);
/* SC: fill in new fields */
resp.cmd = MGCP_CMD_CRCX;
@@ -2411,7 +2411,7 @@ static void start_rtp(struct mgcp_subchannel *sub)
sub->rtp = NULL;
}
/* Allocate the RTP now */
- sub->rtp = ast_rtp_new(sched, io, 1, 0);
+ sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
if (sub->rtp && sub->owner)
sub->owner->fds[0] = ast_rtp_fd(sub->rtp);
if (sub->rtp)
@@ -2879,7 +2879,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req,
tmp_sub = tmp_ep->sub;
while (tmp_sub) {
if (tmp_sub->owner)
- ast_softhangup(sub->owner, AST_SOFTHANGUP_DEV);
+ ast_softhangup(tmp_sub->owner, AST_SOFTHANGUP_DEV);
tmp_sub = tmp_sub->next;
if (tmp_sub == first_sub)
break;
@@ -3140,7 +3140,7 @@ static int mgcpsock_read(int *id, int fd, short events, void *ignore)
int ident;
char iabuf[INET_ADDRSTRLEN];
len = sizeof(sin);
- memset(&req, 0, sizeof(req));
+ memset(&req, 0, sizeof(struct mgcp_request));
res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
if (res < 0) {
if (errno != ECONNREFUSED)
@@ -3150,8 +3150,8 @@ static int mgcpsock_read(int *id, int fd, short events, void *ignore)
req.data[res] = '\0';
req.len = res;
if (mgcpdebug) {
- ast_verbose("MGCP read: \n%s\nfrom %s:%d", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
- }
+ ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
+ }
parse(&req);
if (req.headers < 1) {
/* Must have at least one header */
diff --git a/channels/chan_modem.c b/channels/chan_modem.c
index c2f3bf0f9..50a63bb75 100755
--- a/channels/chan_modem.c
+++ b/channels/chan_modem.c
@@ -509,6 +509,18 @@ static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
return res;
}
+static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
+{
+ struct ast_modem_pvt *p = newchan->pvt->pvt;
+ast_log(LOG_WARNING, "fixup called\n");
+ if (p->owner!=oldchan) {
+ ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n",oldchan,p->owner);
+ return -1;
+ }
+ p->owner = newchan;
+ return 0;
+}
+
struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
{
struct ast_channel *tmp;
@@ -528,6 +540,7 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
tmp->pvt->answer = modem_answer;
tmp->pvt->read = modem_read;
tmp->pvt->write = modem_write;
+ tmp->pvt->fixup = modem_fixup;
strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
if (strlen(i->cid))
tmp->callerid = strdup(i->cid);
@@ -707,8 +720,8 @@ static struct ast_modem_pvt *mkif(char *iface)
#endif
tmp = malloc(sizeof(struct ast_modem_pvt));
- memset(tmp, 0, sizeof(struct ast_modem_pvt));
if (tmp) {
+ memset(tmp, 0, sizeof(struct ast_modem_pvt));
tmp->fd = open(iface, O_RDWR | O_NONBLOCK);
if (tmp->fd < 0) {
ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 9b9cb8633..e6fa49450 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -129,7 +129,9 @@ static char *tdesc = "Session Initiation Protocol (SIP)";
static char *config = "sip.conf";
#define DEFAULT_SIP_PORT 5060 /* From RFC 2543 */
-#define SIP_MAX_PACKET 1500 /* Also from RFC 2543, should sub headers tho */
+/* From RFC2543, this should be 1500, so it's up to the ability of
+ remote devices as to whether it will be accepted when more than that*/
+#define SIP_MAX_PACKET 4096
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER"
@@ -1851,7 +1853,11 @@ static int sip_answer(struct ast_channel *ast)
fmt=ast_getformatbyname(codec);
if (fmt) {
ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec);
- p->jointcapability=fmt;
+ if (p->jointcapability & fmt) {
+ p->jointcapability &= fmt;
+ p->capability &= fmt;
+ } else
+ ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
} else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n",codec);
}
@@ -2011,6 +2017,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
{
struct ast_channel *tmp;
int fmt;
+
ast_mutex_unlock(&i->lock);
/* Don't hold a sip pvt lock while we allocate a channel */
tmp = ast_channel_alloc(1);
@@ -3716,9 +3723,11 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c
else
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag);
+ /* If we're calling a registred SIP peer, use the fullcontact to dial to the peer */
if (!ast_strlen_zero(p->fullcontact)) {
/* If we have full contact, trust it */
strncpy(invite, p->fullcontact, sizeof(invite) - 1);
+ /* Otherwise, use the username while waiting for registration */
} else if (!ast_strlen_zero(p->username)) {
if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) {
snprintf(invite, sizeof(invite), "sip:%s@%s:%d",p->username, p->tohost, ntohs(p->sa.sin_port));
@@ -3937,8 +3946,8 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs)
add_header(&req, "Event", "message-summary");
add_header(&req, "Content-Type", notifymime);
- snprintf(tmp, sizeof(tmp), "Messages-Waiting: %s\n", newmsgs ? "yes" : "no");
- snprintf(tmp2, sizeof(tmp2), "Voicemail: %d/%d\n", newmsgs, oldmsgs);
+ snprintf(tmp, sizeof(tmp), "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
+ snprintf(tmp2, sizeof(tmp2), "Voicemail: %d/%d\r\n", newmsgs, oldmsgs);
snprintf(clen, sizeof(clen), "%d", (int)(strlen(tmp) + strlen(tmp2)));
add_header(&req, "Content-Length", clen);
add_line(&req, tmp);
@@ -3966,7 +3975,7 @@ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq)
struct sip_request req;
char tmp[256];
char clen[20];
- initreqprep(&req, p, "NOTIFY", NULL);
+ reqprep(&req, p, "NOTIFY", 0, 1);
snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
add_header(&req, "Event", tmp);
add_header(&req, "Subscription-state", "terminated;reason=noresource");
@@ -6053,7 +6062,8 @@ static void receive_info(struct sip_pvt *p, struct sip_request *req)
char *c;
/* Need to check the media/type */
- if (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay")) {
+ if ( (!strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) ||
+ (!strcasecmp(get_header(req, "Content-Type"), "application/dtmf-relay")) ) {
/* Try getting the "signal=" part */
if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) {
@@ -6498,6 +6508,9 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
char *s, *e;
strncpy(tmp, get_header(req, "Contact"), sizeof(tmp) - 1);
s = ditch_braces(tmp);
+ e = strchr(s, ';');
+ if (e)
+ *e = '\0';
if (p->promiscredir) {
if (!strncasecmp(s, "sip:", 4))
s += 4;
@@ -6871,8 +6884,18 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
p->alreadygone = 1;
if (!p->owner)
p->needdestroy = 1;
+ } else if ((resp >= 100) && (resp < 200)) {
+ if (!strcasecmp(msg, "INVITE")) {
+ sip_cancel_destroy(p);
+ if (!ast_strlen_zero(get_header(req, "Content-Type")))
+ process_sdp(p, req);
+ if (p->owner) {
+ /* Queue a progress frame */
+ ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
+ }
+ }
} else
- ast_log(LOG_NOTICE, "Dunno anything about a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
+ ast_log(LOG_NOTICE, "Don't know anything about a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr));
}
} else {
if (sip_debug_test_pvt(p))
@@ -6998,6 +7021,14 @@ static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2)
ast_moh_stop(p1->owner->bridge);
ast_moh_stop(p1->owner);
ast_moh_stop(p2->owner);
+ if (p1->owner->cdr) {
+ p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->cdr);
+ p1->owner->cdr = NULL;
+ }
+ if (p1->owner->bridge->cdr) {
+ p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->bridge->cdr);
+ p1->owner->bridge->cdr = NULL;
+ }
if (ast_channel_masquerade(p2->owner, p1->owner->bridge)) {
ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p2->owner->name, p1->owner->bridge->name);
return -1;
@@ -7006,6 +7037,14 @@ static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2)
ast_moh_stop(p2->owner->bridge);
ast_moh_stop(p2->owner);
ast_moh_stop(p1->owner);
+ if (p2->owner->cdr) {
+ p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->cdr);
+ p2->owner->cdr = NULL;
+ }
+ if (p2->owner->bridge->cdr) {
+ p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->bridge->cdr);
+ p2->owner->bridge->cdr = NULL;
+ }
if (ast_channel_masquerade(p1->owner, p2->owner->bridge)) {
ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p1->owner->name, p2->owner->bridge->name);
return -1;
@@ -7077,7 +7116,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
if (p->icseq && (p->icseq > seqno)) {
ast_log(LOG_DEBUG, "Ignoring too old packet packet %d (expecting >= %d)\n", seqno, p->icseq);
return -1;
- } else if (p->icseq && (p->icseq == seqno)) {
+ } else if (p->icseq && (p->icseq == seqno) && (strcasecmp(cmd, "CANCEL") || p->alreadygone)) {
/* ignore means "don't do anything with it" but still have to
respond appropriately. We do this if we receive a repeat of
the last sequence number */
@@ -8022,8 +8061,15 @@ static struct ast_channel *sip_request(char *type, int format, void *data)
else /* UNIDEN bug */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
- if (ext)
+
+ /* We have an extension to call, don't use the full contact here */
+ /* This to enable dialling registred peers with extension dialling,
+ like SIP/peername/extension
+ SIP/peername will still use the full contact */
+ if (ext) {
strncpy(p->username, ext, sizeof(p->username) - 1);
+ p->fullcontact[0] = 0;
+ }
#if 0
printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
#endif
@@ -8176,6 +8222,8 @@ static struct sip_peer *temp_peer(char *name)
{
struct sip_peer *peer;
peer = malloc(sizeof(struct sip_peer));
+ if (!peer)
+ return NULL;
memset(peer, 0, sizeof(struct sip_peer));
peer->expire = -1;
peer->pokeexpire = -1;
@@ -8236,12 +8284,14 @@ static struct sip_peer *build_peer(char *name, struct ast_variable *v)
} else {
ast_mutex_unlock(&peerl.lock);
peer = malloc(sizeof(struct sip_peer));
- memset(peer, 0, sizeof(struct sip_peer));
- peer->expire = -1;
- peer->pokeexpire = -1;
+ if (peer) {
+ memset(peer, 0, sizeof(struct sip_peer));
+ peer->expire = -1;
+ peer->pokeexpire = -1;
+ }
}
- peer->lastmsgssent = -1;
if (peer) {
+ peer->lastmsgssent = -1;
if (!found) {
strncpy(peer->name, name, sizeof(peer->name)-1);
strncpy(peer->context, default_context, sizeof(peer->context)-1);
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index b4149cfc9..efe6e39f9 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -153,6 +153,8 @@ static char *config = "zapata.conf";
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
+#define zt_close(fd) if(fd > 0) close(fd);
+
static char context[AST_MAX_EXTENSION] = "default";
static char callerid[256] = "";
@@ -758,7 +760,7 @@ static int zt_open(char *fn)
if (chan) {
if (ioctl(fd, ZT_SPECIFY, &chan)) {
x = errno;
- close(fd);
+ zt_close(fd);
errno = x;
ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
return -1;
@@ -769,11 +771,6 @@ static int zt_open(char *fn)
return fd;
}
-static void zt_close(int fd)
-{
- close(fd);
-}
-
int zt_setlinear(int zfd, int linear)
{
int res;
@@ -2886,6 +2883,18 @@ static int attempt_transfer(struct zt_pvt *p)
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
ast_indicate(p->subs[SUB_REAL].owner->bridge, AST_CONTROL_RINGING);
}
+ if (p->subs[SUB_REAL].owner->cdr) {
+ /* Move CDR from second channel to current one */
+ p->subs[SUB_THREEWAY].owner->cdr =
+ ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
+ p->subs[SUB_REAL].owner->cdr = NULL;
+ }
+ if (p->subs[SUB_REAL].owner->bridge->cdr) {
+ /* Move CDR from second channel's bridge to current one */
+ p->subs[SUB_THREEWAY].owner->cdr =
+ ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->bridge->cdr);
+ p->subs[SUB_REAL].owner->bridge->cdr = NULL;
+ }
if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, p->subs[SUB_REAL].owner->bridge)) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
p->subs[SUB_REAL].owner->bridge->name, p->subs[SUB_THREEWAY].owner->name);
@@ -2899,6 +2908,18 @@ static int attempt_transfer(struct zt_pvt *p)
ast_indicate(p->subs[SUB_THREEWAY].owner->bridge, AST_CONTROL_RINGING);
}
ast_moh_stop(p->subs[SUB_THREEWAY].owner->bridge);
+ if (p->subs[SUB_THREEWAY].owner->cdr) {
+ /* Move CDR from second channel to current one */
+ p->subs[SUB_REAL].owner->cdr =
+ ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
+ p->subs[SUB_THREEWAY].owner->cdr = NULL;
+ }
+ if (p->subs[SUB_THREEWAY].owner->bridge->cdr) {
+ /* Move CDR from second channel's bridge to current one */
+ p->subs[SUB_REAL].owner->cdr =
+ ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->bridge->cdr);
+ p->subs[SUB_THREEWAY].owner->bridge->cdr = NULL;
+ }
if (ast_channel_masquerade(p->subs[SUB_REAL].owner, p->subs[SUB_THREEWAY].owner->bridge)) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
p->subs[SUB_THREEWAY].owner->bridge->name, p->subs[SUB_REAL].owner->name);
@@ -6056,7 +6077,7 @@ static int pri_create_trunkgroup(int trunkgroup, int *channels)
x = channels[y];
if (ioctl(fd, ZT_SPECIFY, &x)) {
ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
- close(fd);
+ zt_close(fd);
return -1;
}
if (ioctl(fd, ZT_GET_PARAMS, &p)) {
@@ -6065,18 +6086,18 @@ static int pri_create_trunkgroup(int trunkgroup, int *channels)
}
if (ioctl(fd, ZT_SPANSTAT, &si)) {
ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
- close(fd);
+ zt_close(fd);
return -1;
}
span = p.spanno - 1;
if (pris[span].trunkgroup) {
ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
- close(fd);
+ zt_close(fd);
return -1;
}
if (pris[span].pvts[0]) {
ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
- close(fd);
+ zt_close(fd);
return -1;
}
if (!y) {
@@ -6087,7 +6108,7 @@ static int pri_create_trunkgroup(int trunkgroup, int *channels)
pris[ospan].dchannels[y] = channels[y];
pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
pris[span].span = span + 1;
- close(fd);
+ zt_close(fd);
}
return 0;
}
@@ -6511,6 +6532,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
if (working->channel > tmp->channel) {
tmp->next = *wlist;
tmp->prev = NULL;
+ (*wlist)->prev = tmp;
*wlist = tmp;
} else {
/* go through all the members and put the member in the right place */
@@ -7030,7 +7052,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
else {
/* Looks good. Drop the pseudo channel now, clear up the assignment, and
wakeup the potential sleeper */
- close(crv->subs[SUB_REAL].zfd);
+ zt_close(crv->subs[SUB_REAL].zfd);
pri->pvts[principle]->call = crv->call;
pri_assign_bearer(crv, pri, pri->pvts[principle]);
ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
@@ -7103,8 +7125,7 @@ static void *do_idle_thread(void *vchan)
static void zt_pri_message(char *s)
{
- if (option_verbose)
- ast_verbose(s);
+ ast_verbose("%s", s);
}
static void zt_pri_error(char *s)
@@ -7355,7 +7376,7 @@ static void *pri_dchannel(void *vpri)
x = 0;
res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
if (x)
- ast_log(LOG_NOTICE, "PRI got event: %d on %s D-channel of span %d\n", x, pri_order(which), pri->span);
+ ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span);
/* Keep track of alarm state */
if (x == ZT_EVENT_ALARM) {
pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
@@ -8033,13 +8054,13 @@ static int start_pri(struct zt_pri *pri)
}
res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
if (res) {
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
return -1;
}
if (p.sigtype != ZT_SIG_HDLCFCS) {
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode. See /etc/zaptel.conf\n", x);
return -1;
@@ -8047,7 +8068,7 @@ static int start_pri(struct zt_pri *pri)
memset(&si, 0, sizeof(si));
res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
if (res) {
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
}
@@ -8061,7 +8082,7 @@ static int start_pri(struct zt_pri *pri)
bi.bufsize = 1024;
if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
return -1;
}
@@ -8074,7 +8095,7 @@ static int start_pri(struct zt_pri *pri)
if (i)
pri_enslave(pri->dchans[0], pri->dchans[i]);
if (!pri->dchans[i]) {
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
ast_log(LOG_ERROR, "Unable to create PRI structure\n");
return -1;
@@ -8089,7 +8110,7 @@ static int start_pri(struct zt_pri *pri)
for (i=0;i<NUM_DCHANS;i++) {
if (!pri->dchannels[i])
break;
- close(pri->fds[i]);
+ zt_close(pri->fds[i]);
pri->fds[i] = -1;
}
ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h
index 1b277c499..e9406243a 100755
--- a/channels/h323/chan_h323.h
+++ b/channels/h323/chan_h323.h
@@ -114,7 +114,7 @@ typedef struct rtp_info {
/* This is a callback prototype function, called pass
DTMF down the RTP. */
-typedef int (*send_digit_cb)(unsigned, char);
+typedef int (*send_digit_cb)(unsigned, const char *);
extern send_digit_cb on_send_digit;
/* This is a callback prototype function, called to collect
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index c54af66a5..34f251fb0 100755
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -32,7 +32,7 @@ static int oframes = 0;
static void internaloutput(const char *str)
{
- printf(str);
+ fputs(str, stdout);
}
static void internalerror(const char *str)
diff --git a/cli.c b/cli.c
index 613e3a22f..f1ac752df 100755
--- a/cli.c
+++ b/cli.c
@@ -148,7 +148,7 @@ static int handle_set_verbose(int fd, int argc, char *argv[])
ast_cli(fd, "Verbosity was %d and is now %d\n", oldval, option_verbose);
else if (oldval > 0 && option_verbose > 0)
ast_cli(fd, "Verbosity is atleast %d\n", option_verbose);
- else if (oldval > 0 && option_debug == 0)
+ else if (oldval > 0 && option_verbose == 0)
ast_cli(fd, "Verbosity is now OFF\n");
return RESULT_SUCCESS;
}
@@ -437,11 +437,11 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock);
static int handle_commandmatchesarray(int fd, int argc, char *argv[])
{
- char *buf;
+ char *buf, *obuf;
int buflen = 2048;
int len = 0;
char **matches;
- int x;
+ int x, matchlen;
if (argc != 4)
return RESULT_SHOWUSAGE;
@@ -455,11 +455,17 @@ static int handle_commandmatchesarray(int fd, int argc, char *argv[])
#if 0
printf("command matchesarray for '%s' %s got '%s'\n", argv[2], argv[3], matches[x]);
#endif
- if (len + strlen(matches[x]) >= buflen) {
- buflen += strlen(matches[x]) * 3;
- buf = realloc(buf, buflen);
+ matchlen = strlen(matches[x]) + 1;
+ if (len + matchlen >= buflen) {
+ buflen += matchlen * 3;
+ obuf = buf;
+ buf = realloc(obuf, buflen);
+ if (!buf)
+ /* Out of memory... Just free old buffer and be done */
+ free(obuf);
}
- len += sprintf( buf + len, "%s ", matches[x]);
+ if (buf)
+ len += sprintf( buf + len, "%s ", matches[x]);
free(matches[x]);
matches[x] = NULL;
}
diff --git a/db1-ast/hash/ndbm.c b/db1-ast/hash/ndbm.c
index 20840e976..d702f737a 100755
--- a/db1-ast/hash/ndbm.c
+++ b/db1-ast/hash/ndbm.c
@@ -105,15 +105,20 @@ dbm_fetch(db, key)
DBM *db;
datum key;
{
- datum retval;
+ datum retdata;
int status;
+ DBT dbtkey, dbtretdata;
- status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->get)(db, &dbtkey, &dbtretdata, 0);
if (status) {
- retval.dptr = NULL;
- retval.dsize = 0;
+ dbtretdata.data = NULL;
+ dbtretdata.size = 0;
}
- return (retval);
+ retdata.dptr = dbtretdata.data;
+ retdata.dsize = dbtretdata.size;
+ return (retdata);
}
/*
@@ -126,11 +131,14 @@ dbm_firstkey(db)
DBM *db;
{
int status;
- datum retdata, retkey;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
- status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
if (status)
- retkey.dptr = NULL;
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
return (retkey);
}
@@ -144,11 +152,14 @@ dbm_nextkey(db)
DBM *db;
{
int status;
- datum retdata, retkey;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
- status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
if (status)
- retkey.dptr = NULL;
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
return (retkey);
}
/*
@@ -162,8 +173,11 @@ dbm_delete(db, key)
datum key;
{
int status;
+ DBT dbtkey;
- status = (db->del)(db, (DBT *)&key, 0);
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->del)(db, &dbtkey, 0);
if (status)
return (-1);
else
@@ -177,12 +191,18 @@ dbm_delete(db, key)
* 1 if DBM_INSERT and entry exists
*/
extern int
-dbm_store(db, key, content, flags)
+dbm_store(db, key, data, flags)
DBM *db;
- datum key, content;
+ datum key, data;
int flags;
{
- return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+ DBT dbtkey, dbtdata;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ dbtdata.data = data.dptr;
+ dbtdata.size = data.dsize;
+ return ((db->put)(db, &dbtkey, &dbtdata,
(flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
}
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index 9fcc3c9ce..5b4d31f6a 100755
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -219,7 +219,7 @@ static int update_header(int fd)
end = lseek(fd, 0, SEEK_END);
/* in a gsm WAV, data starts 60 bytes in */
bytes = end - 60;
- datalen = htoll(bytes);
+ datalen = htoll((bytes + 1) & ~0x1);
filelen = htoll(52 + ((bytes + 1) & ~0x1));
if (cur < 0) {
ast_log(LOG_WARNING, "Unable to find our position\n");
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
index 90d9433e3..c274d8a81 100755
--- a/include/asterisk/cdr.h
+++ b/include/asterisk/cdr.h
@@ -254,6 +254,6 @@ extern char ast_default_accountcode[20];
#define ast_cdr_add_flag(cdr, flag) ((cdr)->flags |= (flag))
#define ast_cdr_del_flag(cdr, flag) ((cdr)->flags &= ~(flag))
-extern void ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr);
+extern struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr);
#endif /* _CDR_H */
diff --git a/pbx.c b/pbx.c
index 16888bdbf..13ab2b658 100755
--- a/pbx.c
+++ b/pbx.c
@@ -1258,7 +1258,7 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
pbx_substitute_variables(passdata, sizeof(passdata), c, e);
if (option_debug)
ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
- else if (option_verbose > 2)
+ if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n",
term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
@@ -4381,7 +4381,8 @@ static int pbx_builtin_answer(struct ast_channel *chan, void *data)
static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data)
{
/* Copy the language as specified */
- strncpy(chan->language, (char *)data, sizeof(chan->language)-1);
+ if (data)
+ strncpy(chan->language, (char *)data, sizeof(chan->language)-1);
return 0;
}
@@ -4567,7 +4568,7 @@ static int pbx_builtin_background(struct ast_channel *chan, void *data)
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
} else {
- ast_log(LOG_WARNING, "ast_streamfile failed on %s fro %s\n", chan->name, (char*)data);
+ ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char*)data);
res = 0;
}
}
diff --git a/res/res_monitor.c b/res/res_monitor.c
index c36460c5a..2a0b00fa4 100755
--- a/res/res_monitor.c
+++ b/res/res_monitor.c
@@ -90,6 +90,11 @@ int ast_monitor_start( struct ast_channel *chan, const char *format_spec,
}
monitor = malloc(sizeof(struct ast_channel_monitor));
+ if (!monitor) {
+ if (need_lock)
+ ast_mutex_unlock(&chan->lock);
+ return -1;
+ }
memset(monitor, 0, sizeof(struct ast_channel_monitor));
/* Determine file names */
@@ -391,6 +396,11 @@ static int start_monitor_action(struct mansession *s, struct message *m)
if ((!fname) || (ast_strlen_zero(fname))) {
// No filename base specified, default to channel name as per CLI
fname = malloc (FILENAME_MAX);
+ if (!fname) {
+ astman_send_error(s, m, "Could not start monitoring channel");
+ ast_mutex_unlock(&c->lock);
+ return 0;
+ }
memset(fname, 0, FILENAME_MAX);
strncpy(fname, c->name, FILENAME_MAX-1);
// Channels have the format technology/channel_name - have to replace that /
diff --git a/res/res_odbc.c b/res/res_odbc.c
index c8efb0620..f1697ee62 100755
--- a/res/res_odbc.c
+++ b/res/res_odbc.c
@@ -99,10 +99,12 @@ static int load_odbc_config(void)
if (!strcmp(cat, "ENV")) {
for (v = ast_variable_browse(config, cat); v; v = v->next) {
env_var = malloc(strlen(v->name) + strlen(v->value) + 2);
- sprintf(env_var, "%s=%s", v->name, v->value);
- ast_log(LOG_NOTICE, "Adding ENV var: %s=%s\n", v->name, v->value);
- putenv(env_var);
- free(env_var);
+ if (env_var) {
+ sprintf(env_var, "%s=%s", v->name, v->value);
+ ast_log(LOG_NOTICE, "Adding ENV var: %s=%s\n", v->name, v->value);
+ putenv(env_var);
+ free(env_var);
+ }
}
cat = ast_category_browse(config, cat);
@@ -222,6 +224,8 @@ odbc_obj *new_odbc_obj(char *name, char *dsn, char *username, char *password)
static odbc_obj *new;
new = malloc(sizeof(odbc_obj));
+ if (!new)
+ return NULL;
memset(new, 0, sizeof(odbc_obj));
new->env = SQL_NULL_HANDLE;
diff --git a/tdd.c b/tdd.c
index 6ff6c0fbd..e2a6cc839 100755
--- a/tdd.c
+++ b/tdd.c
@@ -77,8 +77,8 @@ struct tdd_state *tdd_new(void)
{
struct tdd_state *tdd;
tdd = malloc(sizeof(struct tdd_state));
- memset(tdd, 0, sizeof(struct tdd_state));
if (tdd) {
+ memset(tdd, 0, sizeof(struct tdd_state));
tdd->fskd.spb = 176; /* 45.5 baud */
tdd->fskd.hdlc = 0; /* Async */
tdd->fskd.nbit = 5; /* 5 bits */