diff --git a/Makefile b/Makefile index d62c6a0793..d2e48c2595 100755 --- a/Makefile +++ b/Makefile @@ -232,6 +232,7 @@ samples: all datafiles adsi fi ; \ install $$x $(ASTETCDIR)/`basename $$x .sample` ;\ done + echo "[directories]" > $(ASTETCDIR)/asterisk.conf echo "astetcdir => $(ASTETCDIR)" >> $(ASTETCDIR)/asterisk.conf echo "astmoddir => $(MODULES_DIR)" >> $(ASTETCDIR)/asterisk.conf echo "astvarlibdir => $(ASTVARLIBDIR)" >> $(ASTETCDIR)/asterisk.conf diff --git a/app.c b/app.c index 2a8c12ef94..192b9d99ac 100755 --- a/app.c +++ b/app.c @@ -146,10 +146,24 @@ int ast_app_has_voicemail(char *mailbox) DIR *dir; struct dirent *de; char fn[256]; - + char tmp[256]=""; + char *mb, *cur; + int ret; /* If no mailbox, return immediately */ if (!strlen(mailbox)) return 0; + if (strchr(mailbox, ',')) { + strncpy(tmp, mailbox, sizeof(tmp)); + mb = tmp; + ret = 0; + while((cur = strsep(&mb, ", "))) { + if (strlen(cur)) { + if (ast_app_has_voicemail(cur)) + return 1; + } + } + return 0; + } snprintf(fn, sizeof(fn), "%s/vm/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, mailbox); dir = opendir(fn); if (!dir) diff --git a/apps/Makefile b/apps/Makefile index 7a7d93771d..48e69c76a4 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -24,7 +24,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom. #APPS+=app_sql_postgres.so #APPS+=app_sql_odbc.so -APPS+=$(shell if [ -f /usr/include/zap.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so" ; fi) +APPS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so" ; fi) #APPS+=$(shell if [ -f /usr/include/zap.h ]; then echo "app_rpt.so" ; fi) CFLAGS+= diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 0646b0601f..3ea6cff461 100755 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -726,6 +727,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); ast_destroy(cfg); /* Leave voicemail for someone */ + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext, ast_app_has_voicemail(ext)); return res; } @@ -1981,6 +1983,9 @@ out2: ast_destroy(cfg); if (useadsi) adsi_unload_session(chan); + if (valid) { + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", username, ast_app_has_voicemail(username)); + } LOCAL_USER_REMOVE(u); return res; diff --git a/channel.c b/channel.c index 6e6638c588..6a32fd3fd6 100755 --- a/channel.c +++ b/channel.c @@ -1560,6 +1560,7 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone) { + struct ast_frame null = { AST_FRAME_NULL, }; ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n", clone->name, original->name); if (original->masq) { @@ -1574,6 +1575,9 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo } original->masq = clone; clone->masqr = original; + /* XXX can't really hold the lock here, but at the same time, it' s + not really safe not to XXX */ + ast_queue_frame(original, &null, 0); return 0; } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index fa0c1fa817..b71459b6d8 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1163,8 +1163,12 @@ static int sip_register(char *value, int lineno) return -1; strncpy(copy, value, sizeof(copy)-1); stringp=copy; - username = strsep(&stringp, "@"); - hostname = strsep(&stringp, "@"); + username = stringp; + hostname = strrchr(stringp, '@'); + if (hostname) { + *hostname = '\0'; + hostname++; + } if (!hostname) { ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno); return -1; @@ -2325,10 +2329,10 @@ static int get_refer_info(struct sip_pvt *p, struct sip_request *oreq) *a2 = '\0'; - if (sipdebug) + if (sipdebug) { ast_verbose("Looking for %s in %s\n", c, p->context); ast_verbose("Looking for %s in %s\n", c2, p->context); - + } if (strlen(tmp5)) { /* This is a supervised transfer */ ast_log(LOG_DEBUG,"Assigning Replace-Call-ID Info %s to REPLACE_CALL_ID\n",tmp5); @@ -2355,7 +2359,7 @@ static int get_refer_info(struct sip_pvt *p, struct sip_request *oreq) return 0; else ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'\n", tmp5); - } else if (ast_exists_extension(NULL, p->context, c, 1, NULL) && ast_exists_extension(NULL, p->context, c2, 1, NULL)) { + } else if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { /* This is an unsupervised transfer */ ast_log(LOG_DEBUG,"Assigning Extension %s to REFER-TO\n", c); ast_log(LOG_DEBUG,"Assigning Extension %s to REFERRED-BY\n", c2); @@ -3294,6 +3298,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc ast_async_goto(transfer_to,"", p->refer_to,1, 1); } } + transmit_request(p, "BYE", p->outgoing); } } else if (!strcasecmp(cmd, "CANCEL") || !strcasecmp(cmd, "BYE")) { copy_request(&p->initreq, req); diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 59e036d7c0..23cc2fb5b5 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -1,11 +1,11 @@ /* * Asterisk -- A telephony toolkit for Linux. * - * Tormenta T1 Card (via Zapata library) support + * Zaptel Pseudo TDM interface * - * Copyright (C) 1999, Mark Spencer + * Copyright (C) 2003 Digium * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -2275,6 +2275,28 @@ static mfcr2_event_t *r2_get_event_bits(struct zt_pvt *p) } #endif +static int check_for_conference(struct zt_pvt *p) +{ + ZT_CONFINFO ci; + /* Fine if we already have a master, etc */ + if (p->master || (p->confno > -1)) + return 0; + memset(&ci, 0, sizeof(ci)); + if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { + ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); + return 0; + } + /* If we have no master and don't have a confno, then + if we're in a conference, it's probably a MeetMe room or + some such, so don't let us 3-way out! */ + if (ci.confno) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); + return 1; + } + return 0; +} + static struct ast_frame *zt_handle_event(struct ast_channel *ast) { int res,x; @@ -2550,7 +2572,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast) if (p->subs[SUB_REAL].owner->bridge) ast_moh_stop(p->subs[SUB_REAL].owner->bridge); } else if (!p->subs[SUB_THREEWAY].owner) { - if (p->threewaycalling) { + if (p->threewaycalling && !check_for_conference(p)) { /* XXX This section needs much more error checking!!! XXX */ /* Start a 3-way call if feasible */ if ((ast->pbx) || diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample index 325cf2e2a2..76e024fffc 100755 --- a/configs/extensions.conf.sample +++ b/configs/extensions.conf.sample @@ -83,7 +83,7 @@ TRUNK=Zap/g2 ; Trunk interface ; up, please go to www.gnophone.com or www.iaxtel.com ; [iaxtel700] -exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN-1}@iaxtel) +exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel) [iaxprovider] ;switch => IAX/user:[key]@myserver/mycontext @@ -92,34 +92,34 @@ exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN-1}@iaxtel) ; ; International long distance through trunk ; -exten => 9011.,1,Dial(${TRUNK}/${EXTEN-1}) +exten => 9011.,1,Dial(${TRUNK}/${EXTEN:1}) exten => 9011.,2,Congestion [trunkld] ; ; Long distance context accessed through trunk ; -exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _91NXXNXXXXXX,2,Congestion [trunklocal] ; ; Local seven-digit dialing accessed through trunk interface ; -exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _9NXXXXXX,2,Congestion [trunktollfree] ; ; Long distance context accessed through trunk interface ; -exten => _91800NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _91800NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _91800NXXXXXX,2,Congestion -exten => _91888NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _91888NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _91888NXXXXXX,2,Congestion -exten => _91877NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _91877NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _91877NXXXXXX,2,Congestion -exten => _91866NXXXXXX,1,Dial(${TRUNK}/${EXTEN-1}) +exten => _91866NXXXXXX,1,Dial(${TRUNK}/${EXTEN:1}) exten => _91866NXXXXXX,2,Congestion [international] diff --git a/manager.c b/manager.c index f7a3b51262..a0c06f5a5f 100755 --- a/manager.c +++ b/manager.c @@ -30,6 +30,7 @@ #include #include #include +#include #include static int enabled = 0; @@ -389,6 +390,18 @@ static int action_originate(struct mansession *s, struct message *m) return 0; } +static int action_mailboxstatus(struct mansession *s, struct message *m) +{ + char *mailbox = get_header(m, "Mailbox"); + if (!mailbox || !strlen(mailbox)) { + send_error(s, "Mailbox not specified"); + return 0; + } + send_ack(s, "Mailbox status will follow"); + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting:%d\r\n", mailbox, ast_app_has_voicemail(mailbox)); + return 0; +} + static int process_message(struct mansession *s, struct message *m) { char action[80]; @@ -638,6 +651,7 @@ int init_manager(void) ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" ); ast_manager_register( "Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect" ); ast_manager_register( "Originate", EVENT_FLAG_CALL, action_originate, "Originate Call" ); + ast_manager_register( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox" ); ast_manager_register( "Command", EVENT_FLAG_COMMAND, action_command, "Execute Command" ); ast_cli_register(&show_mancmds_cli); diff --git a/pbx.c b/pbx.c index d2c7bf90b9..a7ed72064a 100755 --- a/pbx.c +++ b/pbx.c @@ -710,12 +710,21 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char * } else if (!strcmp(cp3, "EXTEN")) { *cp4 = c->exten; } else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) && + /* XXX Remove me eventually */ (sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) { if (offset < 0) offset=0; if (offset > strlen(c->exten)) offset = strlen(c->exten); *cp4 = c->exten + offset; + ast_log(LOG_WARNING, "The use of 'EXTEN-foo' has been derprecated in favor of 'EXTEN:foo'\n"); + } else if (!strncmp(cp3, "EXTEN:", strlen("EXTEN:")) && + (sscanf(cp3 + strlen("EXTEN:"), "%d", &offset) == 1)) { + if (offset < 0) + offset=0; + if (offset > strlen(c->exten)) + offset = strlen(c->exten); + *cp4 = c->exten + offset; } else if (!strcmp(cp3, "RDNIS")) { *cp4 = c->rdnis; if (!(*cp4)) @@ -2784,8 +2793,8 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri struct ast_frame *f; tmpchan = ast_channel_alloc(0); if (tmpchan) { - ast_setstate(tmpchan, chan->_state); snprintf(tmpchan->name, sizeof(tmpchan->name), "AsyncGoto/%s", chan->name); + ast_setstate(tmpchan, chan->_state); /* Make formats okay */ tmpchan->readformat = chan->readformat; tmpchan->writeformat = chan->writeformat;