Major PBX revamps (including labels, update examples)
authorMark Spencer <markster@digium.com>
Sun, 3 Oct 2004 04:19:59 +0000 (04:19 +0000)
committerMark Spencer <markster@digium.com>
Sun, 3 Oct 2004 04:19:59 +0000 (04:19 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3886 65c4cc65-6c06-0410-ace0-fbb531ad65f3

23 files changed:
cdr.c
channel.c
channels/chan_agent.c
channels/chan_alsa.c
channels/chan_h323.c
channels/chan_iax2.c
channels/chan_local.c
channels/chan_mgcp.c
channels/chan_modem.c
channels/chan_nbs.c
channels/chan_oss.c
channels/chan_phone.c
channels/chan_sip.c
channels/chan_skinny.c
channels/chan_vpb.c
channels/chan_zap.c
configs/extensions.conf.sample
include/asterisk/cdr.h
include/asterisk/channel.h
include/asterisk/pbx.h
pbx.c
pbx/pbx_config.c
res/res_features.c

diff --git a/cdr.c b/cdr.c
index 4b9eec8..dd6a11a 100755 (executable)
--- a/cdr.c
+++ b/cdr.c
@@ -374,7 +374,7 @@ char *ast_cdr_flags2str(int flag)
        return "Unknown";
 }
 
-int ast_cdr_setaccount(struct ast_channel *chan, char *account)
+int ast_cdr_setaccount(struct ast_channel *chan, const char *account)
 {
        struct ast_cdr *cdr = chan->cdr;
 
@@ -387,7 +387,7 @@ int ast_cdr_setaccount(struct ast_channel *chan, char *account)
        return 0;
 }
 
-int ast_cdr_setamaflags(struct ast_channel *chan, char *flag)
+int ast_cdr_setamaflags(struct ast_channel *chan, const char *flag)
 {
        struct ast_cdr *cdr = chan->cdr;
        int newflag;
@@ -399,7 +399,7 @@ int ast_cdr_setamaflags(struct ast_channel *chan, char *flag)
        return 0;
 }
 
-int ast_cdr_setuserfield(struct ast_channel *chan, char *userfield)
+int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield)
 {
        struct ast_cdr *cdr = chan->cdr;
 
@@ -411,7 +411,7 @@ int ast_cdr_setuserfield(struct ast_channel *chan, char *userfield)
        return 0;
 }
 
-int ast_cdr_appenduserfield(struct ast_channel *chan, char *userfield)
+int ast_cdr_appenduserfield(struct ast_channel *chan, const char *userfield)
 {
        struct ast_cdr *cdr = chan->cdr;
 
@@ -472,7 +472,7 @@ int ast_cdr_update(struct ast_channel *c)
        return 0;
 }
 
-int ast_cdr_amaflags2int(char *flag)
+int ast_cdr_amaflags2int(const char *flag)
 {
        if (!strcasecmp(flag, "default"))
                return 0;
index cbcc213..748ecaf 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -65,7 +65,7 @@ struct chanlist {
        char type[80];
        char description[80];
        int capabilities;
-       struct ast_channel * (*requester)(char *type, int format, void *data);
+       struct ast_channel * (*requester)(const char *type, int format, void *data);
        int (*devicestate)(void *data);
        struct chanlist *next;
 } *backends = NULL;
@@ -153,14 +153,14 @@ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
        return;
 }
 
-int ast_channel_register(char *type, char *description, int capabilities,
-               struct ast_channel *(*requester)(char *type, int format, void *data))
+int ast_channel_register(const char *type, const char *description, int capabilities,
+               struct ast_channel *(*requester)(const char *type, int format, void *data))
 {
        return ast_channel_register_ex(type, description, capabilities, requester, NULL);
 }
 
-int ast_channel_register_ex(char *type, char *description, int capabilities,
-               struct ast_channel *(*requester)(char *type, int format, void *data),
+int ast_channel_register_ex(const char *type, const char *description, int capabilities,
+               struct ast_channel *(*requester)(const char *type, int format, void *data),
                int (*devicestate)(void *data))
 {
        struct chanlist *chan, *last=NULL;
@@ -760,7 +760,7 @@ int ast_hangup(struct ast_channel *chan)
        return res;
 }
 
-void ast_channel_unregister(char *type)
+void ast_channel_unregister(const char *type)
 {
        struct chanlist *chan, *last=NULL;
        if (option_debug)
@@ -1750,7 +1750,7 @@ int ast_set_read_format(struct ast_channel *chan, int fmts)
        return 0;
 }
 
-struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *cid_num, char *cid_name, struct outgoing_helper *oh)
+struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
 {
        int state = 0;
        struct ast_channel *chan;
@@ -1858,12 +1858,12 @@ struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, i
        return chan;
 }
 
-struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *cidnum, char *cidname)
+struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 {
        return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
 }
 
-struct ast_channel *ast_request(char *type, int format, void *data)
+struct ast_channel *ast_request(const char *type, int format, void *data)
 {
        struct chanlist *chan;
        struct ast_channel *c = NULL;
@@ -2401,7 +2401,7 @@ int ast_do_masquerade(struct ast_channel *original)
        return 0;
 }
 
-void ast_set_callerid(struct ast_channel *chan, char *callerid, char *calleridname, char *ani)
+void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
 {
        if (callerid) {
                if (chan->cid.cid_num)
index f047480..97e5f15 100755 (executable)
@@ -1001,7 +1001,7 @@ static int check_beep(struct agent_pvt *newlyavailable, int needlock)
        return res;
 }
 
-static struct ast_channel *agent_request(char *type, int format, void *data)
+static struct ast_channel *agent_request(const char *type, int format, void *data)
 {
        struct agent_pvt *p;
        struct ast_channel *chan = NULL;
index acf80b8..09074ec 100755 (executable)
@@ -753,7 +753,7 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
        return tmp;
 }
 
-static struct ast_channel *alsa_request(char *type, int format, void *data)
+static struct ast_channel *alsa_request(const char *type, int format, void *data)
 {
        int oldformat = format;
        struct ast_channel *tmp=NULL;
index c018759..85877fc 100755 (executable)
@@ -906,7 +906,7 @@ static int create_addr(struct oh323_pvt *r, char *opeer)
        }       
 
 }
-static struct ast_channel *oh323_request(char *type, int format, void *data)
+static struct ast_channel *oh323_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct oh323_pvt *p;
index 827f587..dfa2ec3 100755 (executable)
@@ -4341,7 +4341,7 @@ static void register_peer_exten(struct iax2_peer *peer, int onoff)
                stringp = multi;
                while((ext = strsep(&stringp, "&"))) {
                        if (onoff)
-                               ast_add_extension(regcontext, 1, ext, 1, NULL, "Noop", strdup(peer->name), free, type);
+                               ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, type);
                        else
                                ast_context_remove_extension(regcontext, ext, 1, NULL);
                }
@@ -6205,7 +6205,7 @@ static void free_context(struct iax2_context *con)
        }
 }
 
-static struct ast_channel *iax2_request(char *type, int format, void *data)
+static struct ast_channel *iax2_request(const char *type, int format, void *data)
 {
        int callno;
        int res;
@@ -6993,7 +6993,7 @@ int reload(void)
        return reload_config();
 }
 
-static int cache_get_callno_locked(char *data)
+static int cache_get_callno_locked(const char *data)
 {
        struct sockaddr_in sin;
        int x;
@@ -7075,7 +7075,7 @@ static int cache_get_callno_locked(char *data)
        return callno;
 }
 
-static struct iax2_dpcache *find_cache(struct ast_channel *chan, char *data, char *context, char *exten, int priority)
+static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
 {
        struct iax2_dpcache *dp, *prev = NULL, *next;
        struct timeval tv;
@@ -7225,7 +7225,7 @@ static struct iax2_dpcache *find_cache(struct ast_channel *chan, char *data, cha
        return dp;      
 }
 
-static int iax2_exists(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data)
+static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 {
        struct iax2_dpcache *dp;
        int res = 0;
@@ -7247,7 +7247,7 @@ static int iax2_exists(struct ast_channel *chan, char *context, char *exten, int
        return res;
 }
 
-static int iax2_canmatch(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data)
+static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 {
        int res = 0;
        struct iax2_dpcache *dp;
@@ -7269,7 +7269,7 @@ static int iax2_canmatch(struct ast_channel *chan, char *context, char *exten, i
        return res;
 }
 
-static int iax2_matchmore(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data)
+static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 {
        int res = 0;
        struct iax2_dpcache *dp;
@@ -7291,7 +7291,7 @@ static int iax2_matchmore(struct ast_channel *chan, char *context, char *exten,
        return res;
 }
 
-static int iax2_exec(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, int newstack, char *data)
+static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
 {
        char odata[256];
        char req[256];
index 4c50720..9d004b5 100755 (executable)
@@ -462,7 +462,7 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
 }
 
 
-static struct ast_channel *local_request(char *type, int format, void *data)
+static struct ast_channel *local_request(const char *type, int format, void *data)
 {
        struct local_pvt *p;
        struct ast_channel *chan = NULL;
index 308d7e6..309283b 100755 (executable)
@@ -3345,7 +3345,7 @@ static int restart_monitor(void)
        return 0;
 }
 
-static struct ast_channel *mgcp_request(char *type, int format, void *data)
+static struct ast_channel *mgcp_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct mgcp_subchannel *sub;
index 0637255..677edd4 100755 (executable)
@@ -760,7 +760,7 @@ static struct ast_modem_pvt *mkif(char *iface)
        return tmp;
 }
 
-static struct ast_channel *modem_request(char *type, int format, void *data)
+static struct ast_channel *modem_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct ast_modem_pvt *p;
index a188c12..6f67b3a 100755 (executable)
@@ -232,7 +232,7 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
 }
 
 
-static struct ast_channel *nbs_request(char *type, int format, void *data)
+static struct ast_channel *nbs_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct nbs_pvt *p;
index 350fd63..61dd4ce 100755 (executable)
@@ -745,7 +745,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
        return tmp;
 }
 
-static struct ast_channel *oss_request(char *type, int format, void *data)
+static struct ast_channel *oss_request(const char *type, int format, void *data)
 {
        int oldformat = format;
        struct ast_channel *tmp;
index dc985c1..b91b365 100755 (executable)
@@ -1023,7 +1023,7 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
        return tmp;
 }
 
-static struct ast_channel *phone_request(char *type, int format, void *data)
+static struct ast_channel *phone_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct phone_pvt *p;
index 6c95951..8b8f669 100755 (executable)
@@ -4293,7 +4293,7 @@ static void register_peer_exten(struct sip_peer *peer, int onoff)
                stringp = multi;
                while((ext = strsep(&stringp, "&"))) {
                        if (onoff)
-                               ast_add_extension(regcontext, 1, ext, 1, NULL, "Noop", strdup(peer->name), free, type);
+                               ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, type);
                        else
                                ast_context_remove_extension(regcontext, ext, 1, NULL);
                }
@@ -7966,7 +7966,7 @@ static int sip_devicestate(void *data)
 
 /*--- sip_request: PBX interface function -build SIP pvt structure ---*/
 /* SIP calls initiated by the PBX arrive here */
-static struct ast_channel *sip_request(char *type, int format, void *data)
+static struct ast_channel *sip_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct sip_pvt *p;
index 56abeb1..727d427 100755 (executable)
@@ -2489,7 +2489,7 @@ static int restart_monitor(void)
        return 0;
 }
 
-static struct ast_channel *skinny_request(char *type, int format, void *data)
+static struct ast_channel *skinny_request(const char *type, int format, void *data)
 {
        int oldformat;
        struct skinny_subchannel *sub;
index 06808e1..b4737bf 100755 (executable)
@@ -2032,7 +2032,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
        return tmp;
 }
 
-static struct ast_channel *vpb_request(char *type, int format, void *data) 
+static struct ast_channel *vpb_request(const char *type, int format, void *data) 
 {
        int oldformat;
        struct vpb_pvt *p;
index cc0e3ea..eece03e 100755 (executable)
@@ -114,7 +114,6 @@ static char *tdesc = "Zapata Telephony Driver"
 ;
 
 static char *type = "Zap";
-static char *typecompat = "Tor";       /* Retain compatibility with chan_tor */
 static char *config = "zapata.conf";
 
 #define SIG_EM         ZT_SIG_EM
@@ -6730,7 +6729,7 @@ static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
 }
 #endif
 
-static struct ast_channel *zt_request(char *type, int format, void *data)
+static struct ast_channel *zt_request(const char *type, int format, void *data)
 {
        int oldformat;
        int groupmatch = 0;
@@ -8882,7 +8881,6 @@ static int __unload_module(void)
        ast_manager_unregister( "ZapDNDon" );
        ast_manager_unregister("ZapShowChannels");
        ast_unregister_application(app_callingpres);
-       ast_channel_unregister(typecompat);
        ast_channel_unregister(type);
        if (!ast_mutex_lock(&iflock)) {
                /* Hangup all interfaces if they have an owner */
@@ -9686,11 +9684,6 @@ int load_module(void)
                __unload_module();
                return -1;
        }
-       if (ast_channel_register(typecompat, tdesc, AST_FORMAT_SLINEAR |  AST_FORMAT_ULAW, zt_request)) {
-               ast_log(LOG_ERROR, "Unable to register channel class %s\n", typecompat);
-               __unload_module();
-               return -1;
-       }
 #ifdef ZAPATA_PRI
        ast_cli_register(&pri_debug);
        ast_cli_register(&pri_no_debug);
index 624aff8..b0018fa 100755 (executable)
@@ -62,7 +62,13 @@ TRUNKMSD=1                                   ; MSD digits to strip (usually 1 or 0)
 ; preceeded by a one.
 ;
 ; Each step of an extension is ordered by priority, which must
-; always start with 1 to be considered a valid extension.
+; always start with 1 to be considered a valid extension.  The priority
+; "next" or "n" means the previous priority plus one, regardless of whether
+; the previous priority was associated with the current extension or not.
+; The priority "same" or "s" means the same as the previously specified
+; priority, again regardless of whether the previous entry was for the
+; same extension.  Priorities may also have an alias, or label, in 
+; parenthesis after their name which can be used in goto situations
 ;
 ; Contexts contain several lines, one for each step of each
 ; extension, which can take one of two forms as listed below,
@@ -113,34 +119,34 @@ exten => _91700XXXXXXX,1,Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel)
 ; International long distance through trunk
 ;
 exten => _9011.,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _9011.,2,Congestion
+exten => _9011.,n,Congestion
 
 [trunkld]
 ;
 ; Long distance context accessed through trunk
 ;
 exten => _91NXXNXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _91NXXNXXXXXX,2,Congestion
+exten => _91NXXNXXXXXX,n,Congestion
 
 [trunklocal]
 ;
 ; Local seven-digit dialing accessed through trunk interface
 ;
 exten => _9NXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _9NXXXXXX,2,Congestion
+exten => _9NXXXXXX,n,Congestion
 
 [trunktollfree]
 ;
 ; Long distance context accessed through trunk interface
 ;
 exten => _91800NXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _91800NXXXXXX,2,Congestion
+exten => _91800NXXXXXX,n,Congestion
 exten => _91888NXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _91888NXXXXXX,2,Congestion
+exten => _91888NXXXXXX,n,Congestion
 exten => _91877NXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _91877NXXXXXX,2,Congestion
+exten => _91877NXXXXXX,n,Congestion
 exten => _91866NXXXXXX,1,Dial(${TRUNK}/${EXTEN:${TRUNKMSD}})
-exten => _91866NXXXXXX,2,Congestion
+exten => _91866NXXXXXX,n,Congestion
 
 [international]
 ;
@@ -201,17 +207,17 @@ exten => a,1,VoicemailMain(${ARG1})                               ; If they press *, send the user into Voi
 ; We start with what to do when a call first comes in.
 ;
 exten => s,1,Wait,1                    ; Wait a second, just for fun
-exten => s,2,Answer                    ; Answer the line
-exten => s,3,DigitTimeout,5            ; Set Digit Timeout to 5 seconds
-exten => s,4,ResponseTimeout,10                ; Set Response Timeout to 10 seconds
-exten => s,5,BackGround(demo-congrats) ; Play a congratulatory message
-exten => s,6,BackGround(demo-instruct) ; Play some instructions
+exten => s,n,Answer                    ; Answer the line
+exten => s,n,DigitTimeout,5            ; Set Digit Timeout to 5 seconds
+exten => s,n,ResponseTimeout,10                ; Set Response Timeout to 10 seconds
+exten => s,n(restart),BackGround(demo-congrats)        ; Play a congratulatory message
+exten => s,n(instruct),BackGround(demo-instruct)       ; Play some instructions
 
 exten => 2,1,BackGround(demo-moreinfo) ; Give some more information.
-exten => 2,2,Goto(s,6)
+exten => 2,n,Goto(s,instruct)
 
 exten => 3,1,SetLanguage(fr)           ; Set language to french
-exten => 3,2,Goto(s,5)                 ; Start with the congratulations
+exten => 3,n,Goto(s,restart)                   ; Start with the congratulations
 
 exten => 1000,1,Goto(default,s,1)
 ;
@@ -220,18 +226,18 @@ exten => 1000,1,Goto(default,s,1)
 ;
 exten => 1234,1,Playback(transfer,skip)                ; "Please hold while..." 
                                        ; (but skip if channel is not up)
-exten => 1234,2,Macro(stdexten,1234,${CONSOLE})
+exten => 1234,n,Macro(stdexten,1234,${CONSOLE})
 
 exten => 1235,1,Voicemail(u1234)               ; Right to voicemail
 
 exten => 1236,1,Dial(Console/dsp)              ; Ring forever
-exten => 1236,2,Voicemail(u1234)               ; Unless busy
+exten => 1236,n,Voicemail(u1234)               ; Unless busy
 
 ;
 ; # for when they're done with the demo
 ;
 exten => #,1,Playback(demo-thanks)             ; "Thanks for trying the demo"
-exten => #,2,Hangup                    ; Hang them up.
+exten => #,n,Hangup                    ; Hang them up.
 
 ;
 ; A timeout and "invalid extension rule"
@@ -244,43 +250,43 @@ exten => i,1,Playback(invalid)            ; "That's not valid, try again"
 ; Asterisk demo.
 ;
 exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
-exten => 500,2,Dial(IAX2/guest@misery.digium.com/s@default)    ; Call the Asterisk demo
-exten => 500,3,Playback(demo-nogo)     ; Couldn't connect to the demo site
-exten => 500,4,Goto(s,6)               ; Return to the start over message.
+exten => 500,n,Dial(IAX2/guest@misery.digium.com/s@default)    ; Call the Asterisk demo
+exten => 500,n,Playback(demo-nogo)     ; Couldn't connect to the demo site
+exten => 500,n,Goto(s,6)               ; Return to the start over message.
 
 ;
 ; Create an extension, 600, for evaulating echo latency.
 ;
 exten => 600,1,Playback(demo-echotest) ; Let them know what's going on
-exten => 600,2,Echo                    ; Do the echo test
-exten => 600,3,Playback(demo-echodone) ; Let them know it's over
-exten => 600,4,Goto(s,6)               ; Start over
+exten => 600,n,Echo                    ; Do the echo test
+exten => 600,n,Playback(demo-echodone) ; Let them know it's over
+exten => 600,n,Goto(s,6)               ; Start over
 
 ;
 ; Give voicemail at extension 8500
 ;
 exten => 8500,1,VoicemailMain
-exten => 8500,2,Goto(s,6)
+exten => 8500,n,Goto(s,6)
 ;
 ; Here's what a phone entry would look like (IXJ for example)
 ;
 ;exten => 1265,1,Dial(Phone/phone0,15)
-;exten => 1265,2,Goto(s,5)
+;exten => 1265,n,Goto(s,5)
 
 ;[mainmenu]
 ;
 ; Example "main menu" context with submenu
 ;
 ;exten => s,1,Answer
-;exten => s,2,Background(thanks)               ; "Thanks for calling press 1 for sales, 2 for support, ..."
+;exten => s,n,Background(thanks)               ; "Thanks for calling press 1 for sales, 2 for support, ..."
 ;exten => 1,1,Goto(submenu,s,1)
 ;exten => 2,1,Hangup
 ;include => default
 ;
 ;[submenu]
 ;exten => s,1,Ringing                                  ; Make them comfortable with 2 seconds of ringback
-;exten => s,2,Wait,2
-;exten => s,3,Background(submenuopts)  ; "Thanks for calling the sales department.  Press 1 for steve, 2 for..."
+;exten => s,n,Wait,2
+;exten => s,n,Background(submenuopts)  ; "Thanks for calling the sales department.  Press 1 for steve, 2 for..."
 ;exten => 1,1,Goto(default,steve,1)
 ;exten => 2,1,Goto(default,mark,2)
 
@@ -321,7 +327,7 @@ include => demo
 ; voicemailmain
 ;
 ;exten => 8500,1,VoicemailMain
-;exten => 8500,2,Hangup
+;exten => 8500,n,Hangup
 ;
 ; Or a conference room (you'll need to edit meetme.conf to enable this room)
 ;
index 90d9433..5c9f6c8 100755 (executable)
@@ -3,9 +3,9 @@
  *
  * Call Detail Record API 
  * 
- * Copyright (C) 1999, Mark Spencer
+ * Copyright (C) 1999-2004, Digium, Inc.
  *
- * Mark Spencer <markster@linux-support.net>
+ * Mark Spencer <markster@digium.com>
  *
  * This program is free software, distributed under the terms of
  * the GNU General Public License.
@@ -207,7 +207,7 @@ extern void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data);
  * Converts the string form of the flag to the binary form.
  * Returns the binary form of the flag
  */
-extern int ast_cdr_amaflags2int(char *flag);
+extern int ast_cdr_amaflags2int(const char *flag);
 
 //! Disposition to a string
 /*!
@@ -233,12 +233,12 @@ extern void ast_cdr_reset(struct ast_cdr *cdr, int flags);
  */
 extern char *ast_cdr_flags2str(int flags);
 
-extern int ast_cdr_setaccount(struct ast_channel *chan, char *account);
-extern int ast_cdr_setamaflags(struct ast_channel *chan, char *account);
+extern int ast_cdr_setaccount(struct ast_channel *chan, const char *account);
+extern int ast_cdr_setamaflags(struct ast_channel *chan, const char *amaflags);
 
 
-extern int ast_cdr_setuserfield(struct ast_channel *chan, char *userfield);
-extern int ast_cdr_appenduserfield(struct ast_channel *chan, char *userfield);
+extern int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield);
+extern int ast_cdr_appenduserfield(struct ast_channel *chan, const char *userfield);
 
 
 /* Update CDR on a channel */
index 9022e1a..a754129 100755 (executable)
@@ -79,7 +79,7 @@ struct ast_channel {
        /*! Language requested */
        char language[MAX_LANGUAGE];            
        /*! Type of channel */
-       char *type;                             
+       const char *type;                               
        /*! File descriptor for channel -- Drivers will poll on these file descriptors, so at least one must be non -1.  */
        int fds[AST_MAX_FDS];                   
 
@@ -303,13 +303,13 @@ struct chanmon;
 } 
 
 struct outgoing_helper {
-       char *context;
-       char *exten;
+       const char *context;
+       const char *exten;
        int priority;
-       char *cid_num;
-       char *cid_name;
-       char *variable;
-       char *account;
+       const char *cid_num;
+       const char *cid_name;
+       const char *variable;
+       const char *account;
 };
 
 #define AST_CDR_TRANSFER       (1 << 0)
@@ -377,7 +377,7 @@ struct outgoing_helper {
  * by the low level module
  * Returns an ast_channel on success, NULL on failure.
  */
-struct ast_channel *ast_request(char *type, int format, void *data);
+struct ast_channel *ast_request(const char *type, int format, void *data);
 
 //! Search the Channels by Name
 /*!
@@ -411,9 +411,9 @@ int ast_device_state(char *device);
  * Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
  * to know if the call was answered or not.
  */
-struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, char *cidnum, char *cidname);
+struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname);
 
-struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *reason, char *cidnum, char *cidname, struct outgoing_helper *oh);
+struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh);
 
 //! Registers a channel
 /*! 
@@ -426,12 +426,12 @@ struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, i
  * routine that creates a channel
  * Returns 0 on success, -1 on failure.
  */
-int ast_channel_register(char *type, char *description, int capabilities, 
-                       struct ast_channel* (*requester)(char *type, int format, void *data));
+int ast_channel_register(const char *type, const char *description, int capabilities, 
+                       struct ast_channel* (*requester)(const char *type, int format, void *data));
 
 /* Same like the upper function but with support for devicestate */
-int ast_channel_register_ex(char *type, char *description, int capabilities,
-               struct ast_channel *(*requester)(char *type, int format, void *data),
+int ast_channel_register_ex(const char *type, const char *description, int capabilities,
+               struct ast_channel *(*requester)(const char *type, int format, void *data),
                int (*devicestate)(void *data));
 
 //! Unregister a channel class
@@ -440,7 +440,7 @@ int ast_channel_register_ex(char *type, char *description, int capabilities,
  * Basically just unregisters the channel with the asterisk channel system
  * No return value.
  */
-void ast_channel_unregister(char *type);
+void ast_channel_unregister(const char *type);
 
 //! Hang up a channel 
 /*! 
@@ -790,7 +790,7 @@ int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen,
 /*! Deactive an active generator */
 void ast_deactivate_generator(struct ast_channel *chan);
 
-void ast_set_callerid(struct ast_channel *chan, char *cidnum, char *cidname, char *ani);
+void ast_set_callerid(struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani);
 
 /*! Start a tone going */
 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
index 5bec931..fdeea05 100755 (executable)
@@ -56,17 +56,17 @@ struct ast_switch {
        /*! NULL */
        struct ast_switch *next;        
        /*! Name of the switch */
-       char *name;                             
+       const char *name;                               
        /*! Description of the switch */
-       char *description;              
+       const char *description;                
        
-       int (*exists)(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data);
+       int (*exists)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
        
-       int (*canmatch)(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data);
+       int (*canmatch)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
        
-       int (*exec)(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, int newstack, char *data);
+       int (*exec)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data);
 
-       int (*matchmore)(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, char *data);
+       int (*matchmore)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
 };
 
 struct ast_pbx {
@@ -101,7 +101,7 @@ extern void ast_unregister_switch(struct ast_switch *sw);
  * you passed in.
  * Returns the ast_app structure that matches on success, or NULL on failure
  */
-extern struct ast_app *pbx_findapp(char *app);
+extern struct ast_app *pbx_findapp(const char *app);
 
 //! executes an application
 /*!
@@ -126,14 +126,14 @@ int pbx_exec(struct ast_channel *c, struct ast_app *app, void *data, int newstac
  * and registrar.
  * It returns NULL on failure, and an ast_context structure on success
  */
-struct ast_context *ast_context_create(struct ast_context **extcontexts, char *name, char *registrar);
+struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
 
 //! Merge the temporary contexts into a global contexts list and delete from the global list the ones that are being added
 /*!
  * \param extcontexts pointer to the ast_context structure pointer
  * \param registar of the context; if it's set the routine will delete all contexts that belong to that registrar; if NULL only the contexts that are specified in extcontexts
  */
-void ast_merge_contexts_and_delete(struct ast_context **extcontexts, char *registrar);
+void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
 
 //! Destroy a context (matches the specified context (or ANY context if NULL)
 /*!
@@ -143,7 +143,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, char *regis
  * based on either the ast_context or the registrar name.
  * Returns nothing
  */
-void ast_context_destroy(struct ast_context *con, char *registrar);
+void ast_context_destroy(struct ast_context *con, const char *registrar);
 
 //! Find a context
 /*!
@@ -151,7 +151,7 @@ void ast_context_destroy(struct ast_context *con, char *registrar);
  * Will search for the context with the given name.
  * Returns the ast_context on success, NULL on failure.
  */
-struct ast_context *ast_context_find(char *name);
+struct ast_context *ast_context_find(const char *name);
 
 //! Create a new thread and start the PBX (or whatever)
 /*!
@@ -183,17 +183,17 @@ int ast_pbx_run(struct ast_channel *c);
  * Callerid is a pattern to match CallerID, or NULL to match any callerid
  * Returns 0 on success, -1 on failure
  */
-int ast_add_extension(char *context, int replace, char *extension, int priority, char *callerid,
-       char *application, void *data, void (*datad)(void *), char *registrar);
+int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid,
+       const char *application, void *data, void (*datad)(void *), const char *registrar);
 
 //! Add an extension to an extension context, this time with an ast_context *.  CallerID is a pattern to match on callerid, or NULL to not care about callerid
 /*! 
  * For details about the arguements, check ast_add_extension()
  */
 int ast_add_extension2(struct ast_context *con,
-                                     int replace, char *extension, int priority, char *callerid, 
-                                         char *application, void *data, void (*datad)(void *),
-                                         char *registrar);
+                                     int replace, const char *extension, int priority, const char *label, const char *callerid, 
+                                         const char *application, void *data, void (*datad)(void *),
+                                         const char *registrar);
 
 //! Add an application.  The function 'execute' should return non-zero if the line needs to be hung up. 
 /*!
@@ -209,8 +209,8 @@ int ast_add_extension2(struct ast_context *con,
    CLI commands.
    It returns 0 on success, -1 on failure.
 */
-int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *),
-                            char *synopsis, char *description);
+int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *),
+                            const char *synopsis, const char *description);
 
 //! Remove an application
 /*!
@@ -218,7 +218,7 @@ int ast_register_application(char *app, int (*execute)(struct ast_channel *, voi
  * This unregisters an application from asterisk's internal registration mechanisms.
  * It returns 0 on success, and -1 on failure.
  */
-int ast_unregister_application(char *app);
+int ast_unregister_application(const char *app);
 
 //! Uses hint and devicestate callback to get the state of an extension
 /*!
@@ -248,7 +248,7 @@ int ast_device_state_changed(const char *fmt, ...)
  * The callback is called if the state for extension is changed
  * Return -1 on failure, ID on success
  */ 
-int ast_extension_state_add(char *context, char *exten, 
+int ast_extension_state_add(const char *context, const char *exten, 
                            ast_state_cb_type callback, void *data);
 
 //! Deletes a registered state change callback by ID
@@ -270,7 +270,7 @@ int ast_extension_state_del(int id, ast_state_cb_type callback);
  * is found a non zero value will be returned.
  * Otherwise, 0 is returned.
  */
-int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, char *context, char *exten);
+int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, const char *context, const char *exten);
 
 //! If an extension exists, return non-zero
 // work
@@ -283,7 +283,19 @@ int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, char *context, c
  * If an extension within the given context(or callerid) with the given priority is found a non zero value will be returned.
  * Otherwise, 0 is returned.
  */
-int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid);
+int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid);
+
+//! If an extension exists, return non-zero
+// work
+/*!
+ * \param c this is not important
+ * \param context which context to look in
+ * \param exten which extension to search for
+ * \param labellabel of the action within the extension to match to priority
+ * \param callerid callerid to search for
+ * If an priority which matches given label in extension or -1 if not found.
+\ */
+int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid);
 
 //! Looks for a valid matching extension
 /*!
@@ -296,7 +308,7 @@ int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int
    some more digits, return non-zero.  Basically, when this returns 0, no matter
    what you add to exten, it's not going to be a valid extension anymore
 */
-int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid);
+int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid);
 
 //! Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
 /*!
@@ -310,7 +322,7 @@ int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, in
    an exact-match only.  Basically, when this returns 0, no matter
    what you add to exten, it's not going to be a valid extension anymore
 */
-int ast_matchmore_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid);
+int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid);
 
 //! Determine if a given extension matches a given pattern (in NXX format)
 /*!
@@ -319,7 +331,7 @@ int ast_matchmore_extension(struct ast_channel *c, char *context, char *exten, i
  * Checks whether or not the given extension matches the given pattern.
  * Returns 1 on match, 0 on failure
  */
-int ast_extension_match(char *pattern, char *extension);
+int ast_extension_match(const char *pattern, const char *extension);
 
 //! Launch a new extension (i.e. new stack)
 /*!
@@ -331,7 +343,7 @@ int ast_extension_match(char *pattern, char *extension);
  * This adds a new extension to the asterisk extension list.
  * It returns 0 on success, -1 on failure.
  */
-int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid);
+int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid);
 
 //! Execute an extension.
 /*!
@@ -343,7 +355,7 @@ int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int p
    default extensions and halt the thread if necessary.  This function does not
    return, except on error.
 */
-int ast_exec_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid);
+int ast_exec_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid);
 
 //! Add an include
 /*!
@@ -353,7 +365,7 @@ int ast_exec_extension(struct ast_channel *c, char *context, char *exten, int pr
    Adds an include taking a char * string as the context parameter
    Returns 0 on success, -1 on error
 */
-int ast_context_add_include(char *context, char *include, char *registrar);
+int ast_context_add_include(const char *context, const char *include, const char *registrar);
 
 //! Add an include
 /*!
@@ -363,18 +375,18 @@ int ast_context_add_include(char *context, char *include, char *registrar);
    Adds an include taking a struct ast_context as the first parameter
    Returns 0 on success, -1 on failure
 */
-int ast_context_add_include2(struct ast_context *con, char *include, char *registrar);
+int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar);
 
 //! Removes an include
 /*!
  * See add_include
  */
-int ast_context_remove_include(char *context, char *include, char *registrar);
+int ast_context_remove_include(const char *context, const char *include,const  char *registrar);
 //! Removes an include by an ast_context structure
 /*!
  * See add_include2
  */
-int ast_context_remove_include2(struct ast_context *con, char *include, char *registrar);
+int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar);
 
 //! Verifies includes in an ast_contect structure
 /*!
@@ -392,20 +404,20 @@ int ast_context_verify_includes(struct ast_context *con);
  * This function registers a switch with the asterisk switch architecture
  * It returns 0 on success, -1 on failure
  */
-int ast_context_add_switch(char *context, char *sw, char *data, char *registrar);
+int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar);
 //! Adds a switch (first param is a ast_context)
 /*!
  * See ast_context_add_switch()
  */
-int ast_context_add_switch2(struct ast_context *con, char *sw, char *data, char *registrar);
+int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar);
 
 //! Remove a switch
 /*!
  * Removes a switch with the given parameters
  * Returns 0 on success, -1 on failure
  */
-int ast_context_remove_switch(char *context, char *sw, char *data, char *registrar);
-int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, char *registrar);
+int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar);
+int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar);
 
 //! Simply remove extension from context
 /*!
@@ -416,10 +428,10 @@ int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, ch
  * This function removes an extension from a given context.
  * Returns 0 on success, -1 on failure
  */
-int ast_context_remove_extension(char *context, char *extension, int priority,
-       char *registrar);
-int ast_context_remove_extension2(struct ast_context *con, char *extension,
-       int priority, char *registrar);
+int ast_context_remove_extension(const char *context, const char *extension, int priority,
+       const char *registrar);
+int ast_context_remove_extension2(struct ast_context *con, const char *extension,
+       int priority, const char *registrar);
 
 //! Add an ignorepat
 /*!
@@ -429,8 +441,8 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension,
  * Adds an ignore pattern to a particular context.
  * Returns 0 on success, -1 on failure
  */
-int ast_context_add_ignorepat(char *context, char *ignorepat, char *registrar);
-int ast_context_add_ignorepat2(struct ast_context *con, char *ignorepat, char *registrar);
+int ast_context_add_ignorepat(const char *context, const char *ignorepat, const char *registrar);
+int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
 
 /* Remove an ignorepat */
 /*!
@@ -440,8 +452,8 @@ int ast_context_add_ignorepat2(struct ast_context *con, char *ignorepat, char *r
  * This removes the given ignorepattern
  * Returns 0 on success, -1 on failure
  */
-int ast_context_remove_ignorepat(char *context, char *ignorepat, char *registrar);
-int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char *registrar);
+int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar);
+int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
 
 //! Checks to see if a number should be ignored
 /*!
@@ -450,7 +462,7 @@ int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char
  * Check if a number should be ignored with respect to dialtone cancellation.  
  * Returns 0 if the pattern should not be ignored, or non-zero if the pattern should be ignored 
  */
-int ast_ignore_pattern(char *context, char *pattern);
+int ast_ignore_pattern(const char *context, const char *pattern);
 
 /* Locking functions for outer modules, especially for completion functions */
 //! Locks the contexts
@@ -481,39 +493,40 @@ int ast_lock_context(struct ast_context *con);
 int ast_unlock_context(struct ast_context *con);
 
 
-int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int priority);
+int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority);
 
-int ast_async_goto_by_name(char *chan, char *context, char *exten, int priority);
+int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);
 
 /* Synchronously or asynchronously make an outbound call and send it to a
    particular extension */
-int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *cid_num, char *cid_name, char *variable, char *account );
+int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account );
 
 /* Synchronously or asynchronously make an outbound call and send it to a
    particular application with given extension */
-int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *cid_num, char *cid_name, char *variable, char *account);
+int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account);
 
 /* Functions for returning values from structures */
-char *ast_get_context_name(struct ast_context *con);
-char *ast_get_extension_name(struct ast_exten *exten);
-char *ast_get_include_name(struct ast_include *include);
-char *ast_get_ignorepat_name(struct ast_ignorepat *ip);
-char *ast_get_switch_name(struct ast_sw *sw);
-char *ast_get_switch_data(struct ast_sw *sw);
+const char *ast_get_context_name(struct ast_context *con);
+const char *ast_get_extension_name(struct ast_exten *exten);
+const char *ast_get_include_name(struct ast_include *include);
+const char *ast_get_ignorepat_name(struct ast_ignorepat *ip);
+const char *ast_get_switch_name(struct ast_sw *sw);
+const char *ast_get_switch_data(struct ast_sw *sw);
 
 /* Other extension stuff */
 int ast_get_extension_priority(struct ast_exten *exten);
 int ast_get_extension_matchcid(struct ast_exten *e);
-char *ast_get_extension_cidmatch(struct ast_exten *e);
-char *ast_get_extension_app(struct ast_exten *e);
+const char *ast_get_extension_cidmatch(struct ast_exten *e);
+const char *ast_get_extension_app(struct ast_exten *e);
+const char *ast_get_extension_label(struct ast_exten *e);
 void *ast_get_extension_app_data(struct ast_exten *e);
 
 /* Registrar info functions ... */
-char *ast_get_context_registrar(struct ast_context *c);
-char *ast_get_extension_registrar(struct ast_exten *e);
-char *ast_get_include_registrar(struct ast_include *i);
-char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip);
-char *ast_get_switch_registrar(struct ast_sw *sw);
+const char *ast_get_context_registrar(struct ast_context *c);
+const char *ast_get_extension_registrar(struct ast_exten *e);
+const char *ast_get_include_registrar(struct ast_include *i);
+const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip);
+const char *ast_get_switch_registrar(struct ast_sw *sw);
 
 /* Walking functions ... */
 struct ast_context *ast_walk_contexts(struct ast_context *con);
diff --git a/pbx.c b/pbx.c
index 4a57371..20ac6c0 100755 (executable)
--- a/pbx.c
+++ b/pbx.c
@@ -59,66 +59,70 @@ struct ast_context;
 
 /* ast_exten: An extension */
 struct ast_exten {
-       char exten[AST_MAX_EXTENSION];          /* Extension name */
+       char *exten;            /* Extension name */
        int matchcid;                           /* Match caller id ? */
-       char cidmatch[AST_MAX_EXTENSION];       /* Caller id to match for this extension */
+       char *cidmatch; /* Caller id to match for this extension */
        int priority;                           /* Priority */
+       char *label;    /* Label */
        struct ast_context *parent;             /* An extension */
-       char app[AST_MAX_EXTENSION];            /* Application to execute */
+       char *app;              /* Application to execute */
        void *data;                             /* Data to use */
        void (*datad)(void *);                  /* Data destructor */
        struct ast_exten *peer;                 /* Next higher priority with our extension */
-       char *registrar;                        /* Registrar */
+       const char *registrar;                  /* Registrar */
        struct ast_exten *next;                 /* Extension with a greater ID */
+       char stuff[0];
 };
 
 /* ast_include: include= support in extensions.conf */
 struct ast_include {
-       char name[AST_MAX_EXTENSION];           
-       char rname[AST_MAX_EXTENSION];          /* Context to include */
-       char *registrar;                        /* Registrar */
+       char *name;             
+       char *rname;            /* Context to include */
+       const char *registrar;                  /* Registrar */
        int hastime;                            /* If time construct exists */
        unsigned int monthmask;                 /* Mask for month */
        unsigned int daymask;                   /* Mask for date */
        unsigned int dowmask;                   /* Mask for day of week (mon-sun) */
        unsigned int minmask[24];               /* Mask for minute */
        struct ast_include *next;               /* Link them together */
+       char stuff[0];
 };
 
 /* ast_sw: Switch statement in extensions.conf */
 struct ast_sw {
-       char name[AST_MAX_EXTENSION];
-       char *registrar;                        /* Registrar */
-       char data[AST_MAX_EXTENSION];           /* Data load */
+       char *name;
+       const char *registrar;                  /* Registrar */
+       char *data;             /* Data load */
        struct ast_sw *next;                    /* Link them together */
+       char stuff[0];
 };
 
 struct ast_ignorepat {
-       char pattern[AST_MAX_EXTENSION];
-       char *registrar;
+       const char *registrar;
        struct ast_ignorepat *next;
+       char pattern[0];
 };
 
 /* ast_context: An extension context */
 struct ast_context {
-       char name[AST_MAX_EXTENSION];           /* Name of the context */
        ast_mutex_t lock;                       /* A lock to prevent multiple threads from clobbering the context */
        struct ast_exten *root;                 /* The root of the list of extensions */
        struct ast_context *next;               /* Link them together */
        struct ast_include *includes;           /* Include other contexts */
        struct ast_ignorepat *ignorepats;       /* Patterns for which to continue playing dialtone */
-       char *registrar;                        /* Registrar */
+       const char *registrar;                  /* Registrar */
        struct ast_sw *alts;                    /* Alternative switches */
+       char name[0];           /* Name of the context */
 };
 
 
 /* ast_app: An application */
 struct ast_app {
-       char name[AST_MAX_APP];                 /* Name of the application */
        int (*execute)(struct ast_channel *chan, void *data);
-       char *synopsis;                         /* Synopsis text for 'show applications' */
-       char *description;                      /* Description (help text) for 'show application <name>' */
+       const char *synopsis;                   /* Synopsis text for 'show applications' */
+       const char *description;                /* Description (help text) for 'show application <name>' */
        struct ast_app *next;                   /* Next app in list */
+       char name[0];                   /* Name of the application */
 };
 
 /* ast_state_cb: An extension state notify */
@@ -488,8 +492,9 @@ int pbx_exec(struct ast_channel *c,                 /* Channel */
 #define HELPER_EXEC 2
 #define HELPER_CANMATCH 3
 #define HELPER_MATCHMORE 4
+#define HELPER_FINDLABEL 5
 
-struct ast_app *pbx_findapp(char *app) 
+struct ast_app *pbx_findapp(const char *app) 
 {
        struct ast_app *tmp;
 
@@ -507,7 +512,7 @@ struct ast_app *pbx_findapp(char *app)
        return tmp;
 }
 
-static struct ast_switch *pbx_findswitch(char *sw)
+static struct ast_switch *pbx_findswitch(const char *sw)
 {
        struct ast_switch *asw;
 
@@ -639,7 +644,7 @@ static void pbx_destroy(struct ast_pbx *p)
        }\
 }
 
-int ast_extension_match(char *pattern, char *data)
+int ast_extension_match(const char *pattern, const char *data)
 {
        int match;
        /* If they're the same return */
@@ -652,7 +657,7 @@ int ast_extension_match(char *pattern, char *data)
        return match;
 }
 
-static int extension_close(char *pattern, char *data, int needmore)
+static int extension_close(const char *pattern, const char *data, int needmore)
 {
        int match;
        /* If "data" is longer, it can'be a subset of pattern unless
@@ -672,7 +677,7 @@ static int extension_close(char *pattern, char *data, int needmore)
                return 0;
 }
 
-struct ast_context *ast_context_find(char *name)
+struct ast_context *ast_context_find(const char *name)
 {
        struct ast_context *tmp;
        ast_mutex_lock(&conlock);
@@ -692,9 +697,10 @@ struct ast_context *ast_context_find(char *name)
 #define STATUS_NO_CONTEXT   1
 #define STATUS_NO_EXTENSION 2
 #define STATUS_NO_PRIORITY  3
-#define STATUS_SUCCESS     4
+#define STATUS_NO_LABEL                4
+#define STATUS_SUCCESS     5
 
-static int matchcid(char *cidpattern, char *callerid)
+static int matchcid(const char *cidpattern, const char *callerid)
 {
        int failresult;
        
@@ -713,7 +719,7 @@ static int matchcid(char *cidpattern, char *callerid)
        return ast_extension_match(cidpattern, callerid);
 }
 
-static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *context, char *exten, int priority, char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data)
+static struct ast_exten *pbx_find_extension(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action, char *incstack[], int *stacklen, int *status, struct ast_switch **swo, char **data)
 {
        int x, res;
        struct ast_context *tmp;
@@ -756,7 +762,14 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *cont
                                                        *status = STATUS_NO_PRIORITY;
                                                while(e) {
                                                        /* Match priority */
-                                                       if (e->priority == priority) {
+                                                       if (action == HELPER_FINDLABEL) {
+                                                               if (*status < STATUS_NO_LABEL)
+                                                                       *status = STATUS_NO_LABEL;
+                                                               if (label && e->label && !strcmp(label, e->label)) {
+                                                                       *status = STATUS_SUCCESS;
+                                                                       return e;
+                                                               }
+                                                       } else if (e->priority == priority) {
                                                                *status = STATUS_SUCCESS;
                                                                return e;
                                                        }
@@ -793,7 +806,7 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *cont
                        i = tmp->includes;
                        while(i) {
                                if (include_valid(i)) {
-                                       if ((e = pbx_find_extension(chan, i->rname, exten, priority, callerid, action, incstack, stacklen, status, swo, data))) 
+                                       if ((e = pbx_find_extension(chan, i->rname, exten, priority, label, callerid, action, incstack, stacklen, status, swo, data))) 
                                                return e;
                                        if (*swo) 
                                                return NULL;
@@ -1214,7 +1227,7 @@ static void pbx_substitute_variables(char *passdata, int datalen, struct ast_cha
        pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1);
 }                                                              
 
-static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, char *callerid, int action) 
+static int pbx_extension_helper(struct ast_channel *c, const char *context, const char *exten, int priority, const char *label, const char *callerid, int action) 
 {
        struct ast_exten *e;
        struct ast_app *app;
@@ -1237,7 +1250,7 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
                else
                        return -1;
        }
-       e = pbx_find_extension(c, context, exten, priority, callerid, action, incstack, &stacklen, &status, &sw, &data);
+       e = pbx_find_extension(c, context, exten, priority, label, callerid, action, incstack, &stacklen, &status, &sw, &data);
        if (e) {
                switch(action) {
                case HELPER_CANMATCH:
@@ -1246,6 +1259,10 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
                case HELPER_EXISTS:
                        ast_mutex_unlock(&conlock);
                        return -1;
+               case HELPER_FINDLABEL:
+                       res = e->priority;
+                       ast_mutex_unlock(&conlock);
+                       return res;
                case HELPER_MATCHMORE:
                        ast_mutex_unlock(&conlock);
                        return -1;
@@ -1299,6 +1316,9 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
                case HELPER_MATCHMORE:
                        ast_mutex_unlock(&conlock);
                        return -1;
+               case HELPER_FINDLABEL:
+                       ast_mutex_unlock(&conlock);
+                       return -1;
                case HELPER_SPAWN:
                        newstack++;
                        /* Fall through */
@@ -1330,6 +1350,9 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
                        if ((action != HELPER_EXISTS) && (action !=  HELPER_CANMATCH) && (action != HELPER_MATCHMORE))
                                ast_log(LOG_NOTICE, "No such priority %d in extension '%s' in context '%s'\n", priority, exten, context);
                        break;
+               case STATUS_NO_LABEL:
+                       ast_log(LOG_NOTICE, "No such label '%s' in extension '%s' in context '%s'\n", label, exten, context);
+                       break;
                default:
                        ast_log(LOG_DEBUG, "Shouldn't happen!\n");
                }
@@ -1342,7 +1365,7 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
 
 }
 
-static struct ast_exten *ast_hint_extension(struct ast_channel *c, char *context, char *exten)
+static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *context, const char *exten)
 {
        struct ast_exten *e;
        struct ast_switch *sw;
@@ -1355,7 +1378,7 @@ static struct ast_exten *ast_hint_extension(struct ast_channel *c, char *context
                ast_log(LOG_WARNING, "Unable to obtain lock\n");
                return NULL;
        }
-       e = pbx_find_extension(c, context, exten, PRIORITY_HINT, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data);
+       e = pbx_find_extension(c, context, exten, PRIORITY_HINT, NULL, "", HELPER_EXISTS, incstack, &stacklen, &status, &sw, &data);
        ast_mutex_unlock(&conlock);     
        return e;
 }
@@ -1493,7 +1516,7 @@ int ast_device_state_changed(const char *fmt, ...)
        return 1;
 }
                        
-int ast_extension_state_add(char *context, char *exten, 
+int ast_extension_state_add(const char *context, const char *exten, 
                            ast_state_cb_type callback, void *data)
 {
        struct ast_hint *list;
@@ -1732,7 +1755,7 @@ static int ast_remove_hint(struct ast_exten *e)
 }
 
 
-int ast_get_hint(char *hint, int hintsize, struct ast_channel *c, char *context, char *exten)
+int ast_get_hint(char *hint, int hintsize, struct ast_channel *c, const char *context, const char *exten)
 {
        struct ast_exten *e;
        e = ast_hint_extension(c, context, exten);
@@ -1743,24 +1766,29 @@ int ast_get_hint(char *hint, int hintsize, struct ast_channel *c, char *context,
        return 0;       
 }
 
-int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid) 
+int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) 
 {
-       return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
+       return pbx_extension_helper(c, context, exten, priority, NULL, callerid, HELPER_EXISTS);
 }
 
-int ast_canmatch_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
+int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid) 
 {
-       return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_CANMATCH);
+       return pbx_extension_helper(c, context, exten, 0, label, callerid, HELPER_FINDLABEL);
 }
 
-int ast_matchmore_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
+int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 {
-       return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_MATCHMORE);
+       return pbx_extension_helper(c, context, exten, priority, NULL, callerid, HELPER_CANMATCH);
 }
 
-int ast_spawn_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid) 
+int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 {
-       return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_SPAWN);
+       return pbx_extension_helper(c, context, exten, priority, NULL, callerid, HELPER_MATCHMORE);
+}
+
+int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid) 
+{
+       return pbx_extension_helper(c, context, exten, priority, NULL, callerid, HELPER_SPAWN);
 }
 
 int ast_pbx_run(struct ast_channel *c)
@@ -2012,7 +2040,7 @@ int ast_pbx_start(struct ast_channel *c)
  * structure, leave context list locked and call ast_context_remove_include2
  * which removes include, unlock contexts list and return ...
  */
-int ast_context_remove_include(char *context, char *include, char *registrar)
+int ast_context_remove_include(const char *context, const char *include, const char *registrar)
 {
        struct ast_context *c;
 
@@ -2048,7 +2076,7 @@ int ast_context_remove_include(char *context, char *include, char *registrar)
  * This function locks given context, removes include, unlock context and
  * return.
  */
-int ast_context_remove_include2(struct ast_context *con, char *include, char *registrar)
+int ast_context_remove_include2(struct ast_context *con, const char *include, const char *registrar)
 {
        struct ast_include *i, *pi = NULL;
 
@@ -2084,7 +2112,7 @@ int ast_context_remove_include2(struct ast_context *con, char *include, char *re
  * structure, leave context list locked and call ast_context_remove_switch2
  * which removes switch, unlock contexts list and return ...
  */
-int ast_context_remove_switch(char *context, char *sw, char *data, char *registrar)
+int ast_context_remove_switch(const char *context, const char *sw, const char *data, const char *registrar)
 {
        struct ast_context *c;
 
@@ -2120,7 +2148,7 @@ int ast_context_remove_switch(char *context, char *sw, char *data, char *registr
  * This function locks given context, removes switch, unlock context and
  * return.
  */
-int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, char *registrar)
+int ast_context_remove_switch2(struct ast_context *con, const char *sw, const char *data, const char *registrar)
 {
        struct ast_sw *i, *pi = NULL;
 
@@ -2156,7 +2184,7 @@ int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, ch
  * call ast_context_remove_extension2, unlock contexts list and return.
  * In this function we are using
  */
-int ast_context_remove_extension(char *context, char *extension, int priority, char *registrar)
+int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
 {
        struct ast_context *c;
 
@@ -2192,7 +2220,7 @@ int ast_context_remove_extension(char *context, char *extension, int priority, c
  * is set to 0, all peers are removed. After that, unlock context and
  * return.
  */
-int ast_context_remove_extension2(struct ast_context *con, char *extension, int priority, char *registrar)
+int ast_context_remove_extension2(struct ast_context *con, const char *extension, int priority, const char *registrar)
 {
        struct ast_exten *exten, *prev_exten = NULL;
 
@@ -2296,10 +2324,13 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
 }
 
 
-int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *), char *synopsis, char *description)
+int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
 {
        struct ast_app *tmp, *prev, *cur;
        char tmps[80];
+       int length;
+       length = sizeof(struct ast_app);
+       length += strlen(app) + 1;
        if (ast_mutex_lock(&applock)) {
                ast_log(LOG_ERROR, "Unable to lock application list\n");
                return -1;
@@ -2313,10 +2344,10 @@ int ast_register_application(char *app, int (*execute)(struct ast_channel *, voi
                }
                tmp = tmp->next;
        }
-       tmp = malloc(sizeof(struct ast_app));
+       tmp = malloc(length);
        if (tmp) {
-               memset(tmp, 0, sizeof(struct ast_app));
-               strncpy(tmp->name, app, sizeof(tmp->name)-1);
+               memset(tmp, 0, length);
+               strcpy(tmp->name, app);
                tmp->execute = execute;
                tmp->synopsis = synopsis;
                tmp->description = description;
@@ -2805,7 +2836,9 @@ static int handle_show_dialplan(int fd, int argc, char *argv[])
                                        p = ast_walk_extension_priorities(e, e);
                                        while (p) {
                                                bzero((void *)buf2, sizeof(buf2));
-
+                                               bzero((void *)buf, sizeof(buf));
+                                               if (ast_get_extension_label(p))
+                                                       snprintf(buf, sizeof(buf), "   [%s]", ast_get_extension_label(p));
                                                snprintf(buf2, sizeof(buf2),
                                                        "%d. %s(%s)",
                                                        ast_get_extension_priority(p),
@@ -2813,7 +2846,7 @@ static int handle_show_dialplan(int fd, int argc, char *argv[])
                                                        (char *)ast_get_extension_app_data(p));
 
                                                ast_cli(fd,"  %-17s %-45s [%s]\n",
-                                                       "", buf2,
+                                                       buf, buf2,
                                                        ast_get_extension_registrar(p));        
 
                                                p = ast_walk_extension_priorities(e, p);
@@ -2916,7 +2949,7 @@ static struct ast_cli_entry show_switches_cli =
                handle_show_switches, "Show alternative switches",
                show_switches_help, NULL };
 
-int ast_unregister_application(char *app) {
+int ast_unregister_application(const char *app) {
        struct ast_app *tmp, *tmpl = NULL;
        if (ast_mutex_lock(&applock)) {
                ast_log(LOG_ERROR, "Unable to lock application list\n");
@@ -2942,9 +2975,12 @@ int ast_unregister_application(char *app) {
        return -1;
 }
 
-struct ast_context *ast_context_create(struct ast_context **extcontexts, char *name, char *registrar)
+struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar)
 {
        struct ast_context *tmp, **local_contexts;
+       int length;
+       length = sizeof(struct ast_context);
+       length += strlen(name) + 1;
        if (!extcontexts) {
                local_contexts = &contexts;
                ast_mutex_lock(&conlock);
@@ -2962,11 +2998,11 @@ struct ast_context *ast_context_create(struct ast_context **extcontexts, char *n
                }
                tmp = tmp->next;
        }
-       tmp = malloc(sizeof(struct ast_context));
+       tmp = malloc(length);
        if (tmp) {
-               memset(tmp, 0, sizeof(struct ast_context));
+               memset(tmp, 0, length);
                ast_mutex_init(&tmp->lock);
-               strncpy(tmp->name, name, sizeof(tmp->name)-1);
+               strcpy(tmp->name, name);
                tmp->root = NULL;
                tmp->registrar = registrar;
                tmp->next = *local_contexts;
@@ -2985,9 +3021,9 @@ struct ast_context *ast_context_create(struct ast_context **extcontexts, char *n
        return tmp;
 }
 
-void __ast_context_destroy(struct ast_context *con, char *registrar);
+void __ast_context_destroy(struct ast_context *con, const char *registrar);
 
-void ast_merge_contexts_and_delete(struct ast_context **extcontexts, char *registrar) {
+void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar) {
        struct ast_context *tmp, *lasttmp = NULL;
        tmp = *extcontexts;
        ast_mutex_lock(&conlock);
@@ -3019,7 +3055,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, char *regis
  *  EBUSY  - can't lock
  *  ENOENT - no existence of context
  */
-int ast_context_add_include(char *context, char *include, char *registrar)
+int ast_context_add_include(const char *context, const char *include, const char *registrar)
 {
        struct ast_context *c;
 
@@ -3339,24 +3375,33 @@ static void build_timing(struct ast_include *i, char *info)
  *  EEXIST - already included
  *  EINVAL - there is no existence of context for inclusion
  */
-int ast_context_add_include2(struct ast_context *con, char *value,
-       char *registrar)
+int ast_context_add_include2(struct ast_context *con, const char *value,
+       const char *registrar)
 {
        struct ast_include *new_include;
        char *c;
        struct ast_include *i, *il = NULL; /* include, include_last */
+       int length;
+       char *p;
+       
+       length = sizeof(struct ast_include);
+       length += 2 * (strlen(value) + 1);
 
        /* allocate new include structure ... */
-       if (!(new_include = malloc(sizeof(struct ast_include)))) {
+       if (!(new_include = malloc(length))) {
                ast_log(LOG_ERROR, "Out of memory\n");
                errno = ENOMEM;
                return -1;
        }
        
        /* ... fill in this structure ... */
-       memset(new_include, 0, sizeof(struct ast_include));
-       strncpy(new_include->name, value, sizeof(new_include->name)-1);
-       strncpy(new_include->rname, value, sizeof(new_include->rname)-1);
+       memset(new_include, 0, length);
+       p = new_include->stuff;
+       new_include->name = p;
+       strcpy(new_include->name, value);
+       p += strlen(value) + 1;
+       new_include->rname = p;
+       strcpy(new_include->rname, value);
        c = new_include->rname;
        /* Strip off timing info */
        while(*c && (*c != '|')) c++; 
@@ -3405,7 +3450,7 @@ int ast_context_add_include2(struct ast_context *con, char *value,
  *  EBUSY  - can't lock
  *  ENOENT - no existence of context
  */
-int ast_context_add_switch(char *context, char *sw, char *data, char *registrar)
+int ast_context_add_switch(const char *context, const char *sw, const char *data, const char *registrar)
 {
        struct ast_context *c;
 
@@ -3440,26 +3485,38 @@ int ast_context_add_switch(char *context, char *sw, char *data, char *registrar)
  *  EEXIST - already included
  *  EINVAL - there is no existence of context for inclusion
  */
-int ast_context_add_switch2(struct ast_context *con, char *value,
-       char *data, char *registrar)
+int ast_context_add_switch2(struct ast_context *con, const char *value,
+       const char *data, const char *registrar)
 {
        struct ast_sw *new_sw;
        struct ast_sw *i, *il = NULL; /* sw, sw_last */
+       int length;
+       char *p;
+       
+       length = sizeof(struct ast_sw);
+       length += strlen(value) + 1;
+       if (data)
+               length += strlen(data);
+       length++;
 
        /* allocate new sw structure ... */
-       if (!(new_sw = malloc(sizeof(struct ast_sw)))) {
+       if (!(new_sw = malloc(length))) {
                ast_log(LOG_ERROR, "Out of memory\n");
                errno = ENOMEM;
                return -1;
        }
        
        /* ... fill in this structure ... */
-       memset(new_sw, 0, sizeof(struct ast_sw));
-       strncpy(new_sw->name, value, sizeof(new_sw->name)-1);
+       memset(new_sw, 0, length);
+       p = new_sw->stuff;
+       new_sw->name = p;
+       strcpy(new_sw->name, value);
+       p += strlen(value) + 1;
+       new_sw->data = p;
        if (data)
-               strncpy(new_sw->data, data, sizeof(new_sw->data)-1);
+               strcpy(new_sw->data, data);
        else
-               strncpy(new_sw->data, "", sizeof(new_sw->data)-1);
+               strcpy(new_sw->data, "");
        new_sw->next      = NULL;
        new_sw->registrar = registrar;
 
@@ -3499,7 +3556,7 @@ int ast_context_add_switch2(struct ast_context *con, char *value,
  * EBUSY  - can't lock
  * ENOENT - there is not context existence
  */
-int ast_context_remove_ignorepat(char *context, char *ignorepat, char *registrar)
+int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar)
 {
        struct ast_context *c;
 
@@ -3523,7 +3580,7 @@ int ast_context_remove_ignorepat(char *context, char *ignorepat, char *registrar
        return -1;
 }
 
-int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char *registrar)
+int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
 {
        struct ast_ignorepat *ip, *ipl = NULL;
 
@@ -3558,7 +3615,7 @@ int ast_context_remove_ignorepat2(struct ast_context *con, char *ignorepat, char
  * EBUSY - can't lock
  * ENOENT - there is no existence of context
  */
-int ast_context_add_ignorepat(char *con, char *value, char *registrar)
+int ast_context_add_ignorepat(const char *con, const char *value, const char *registrar)
 {
        struct ast_context *c;
 
@@ -3582,18 +3639,20 @@ int ast_context_add_ignorepat(char *con, char *value, char *registrar)
        return -1;
 }
 
-int ast_context_add_ignorepat2(struct ast_context *con, char *value, char *registrar)
+int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar)
 {
        struct ast_ignorepat *ignorepat, *ignorepatc, *ignorepatl = NULL;
-
-       ignorepat = malloc(sizeof(struct ast_ignorepat));
+       int length;
+       length = sizeof(struct ast_ignorepat);
+       length += strlen(value) + 1;
+       ignorepat = malloc(length);
        if (!ignorepat) {
                ast_log(LOG_ERROR, "Out of memory\n");
                errno = ENOMEM;
                return -1;
        }
-       memset(ignorepat, 0, sizeof(struct ast_ignorepat));
-       strncpy(ignorepat->pattern, value, sizeof(ignorepat->pattern)-1);
+       memset(ignorepat, 0, length);
+       strcpy(ignorepat->pattern, value);
        ignorepat->next = NULL;
        ignorepat->registrar = registrar;
        ast_mutex_lock(&con->lock);
@@ -3617,7 +3676,7 @@ int ast_context_add_ignorepat2(struct ast_context *con, char *value, char *regis
        
 }
 
-int ast_ignore_pattern(char *context, char *pattern)
+int ast_ignore_pattern(const char *context, const char *pattern)
 {
        struct ast_context *con;
        struct ast_ignorepat *pat;
@@ -3639,8 +3698,8 @@ int ast_ignore_pattern(char *context, char *pattern)
  * ENOENT  - no existence of context
  *
  */
-int ast_add_extension(char *context, int replace, char *extension, int priority, char *callerid,
-       char *application, void *data, void (*datad)(void *), char *registrar)
+int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid,
+       const char *application, void *data, void (*datad)(void *), const char *registrar)
 {
        struct ast_context *c;
 
@@ -3652,7 +3711,7 @@ int ast_add_extension(char *context, int replace, char *extension, int priority,
        c = ast_walk_contexts(NULL);
        while (c) {
                if (!strcmp(context, ast_get_context_name(c))) {
-                       int ret = ast_add_extension2(c, replace, extension, priority, callerid,
+                       int ret = ast_add_extension2(c, replace, extension, priority, label, callerid,
                                application, data, datad, registrar);
                        ast_unlock_contexts();
                        return ret;
@@ -3665,7 +3724,7 @@ int ast_add_extension(char *context, int replace, char *extension, int priority,
        return -1;
 }
 
-int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int priority)
+int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
 {
        int res = 0;
        ast_mutex_lock(&chan->lock);
@@ -3726,7 +3785,7 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri
        return res;
 }
 
-int ast_async_goto_by_name(char *channame, char *context, char *exten, int priority)
+int ast_async_goto_by_name(const char *channame, const char *context, const char *exten, int priority)
 {
        struct ast_channel *chan;
        int res = -1;
@@ -3746,7 +3805,7 @@ int ast_async_goto_by_name(char *channame, char *context, char *exten, int prior
        return res;
 }
 
-static void ext_strncpy(char *dst, char *src, int len)
+static void ext_strncpy(char *dst, const char *src, int len)
 {
        int count=0;
 
@@ -3773,9 +3832,9 @@ static void ext_strncpy(char *dst, char *src, int len)
  *
  */
 int ast_add_extension2(struct ast_context *con,
-                                         int replace, char *extension, int priority, char *callerid,
-                                         char *application, void *data, void (*datad)(void *),
-                                         char *registrar)
+                                         int replace, const char *extension, int priority, const char *label, const char *callerid,
+                                         const char *application, void *data, void (*datad)(void *),
+                                         const char *registrar)
 {
 
 #define LOG do {       if (option_debug) {\
@@ -3800,21 +3859,44 @@ int ast_add_extension2(struct ast_context *con,
         */
        struct ast_exten *tmp, *e, *el = NULL, *ep = NULL;
        int res;
+       int length;
+       char *p;
+       length = sizeof(struct ast_exten);
+       length += strlen(extension) + 1;
+       length += strlen(application) + 1;
+       if (label)
+               length += strlen(label) + 1;
+       if (callerid)
+               length += strlen(callerid) + 1;
+       else
+               length ++;
 
        /* Be optimistic:  Build the extension structure first */
-       tmp = malloc(sizeof(struct ast_exten));
+       tmp = malloc(length);
        if (tmp) {
-               memset(tmp, 0, sizeof(struct ast_exten));
-               ext_strncpy(tmp->exten, extension, sizeof(tmp->exten));
+               memset(tmp, 0, length);
+               p = tmp->stuff;
+               if (label) {
+                       tmp->label = p;
+                       strcpy(tmp->label, label);
+                       p += strlen(label) + 1;
+               }
+               tmp->exten = p;
+               ext_strncpy(tmp->exten, extension, strlen(extension) + 1);
+               p += strlen(extension) + 1;
                tmp->priority = priority;
+               tmp->cidmatch = p;
                if (callerid) {
-                       ext_strncpy(tmp->cidmatch, callerid, sizeof(tmp->cidmatch));
+                       ext_strncpy(tmp->cidmatch, callerid, strlen(callerid) + 1);
+                       p += strlen(callerid) + 1;
                        tmp->matchcid = 1;
                } else {
                        tmp->cidmatch[0] = '\0';
                        tmp->matchcid = 0;
+                       p++;
                }
-               strncpy(tmp->app, application, sizeof(tmp->app)-1);
+               tmp->app = p;
+               strcpy(tmp->app, application);
                tmp->parent = con;
                tmp->data = data;
                tmp->datad = datad;
@@ -4039,7 +4121,7 @@ static void *async_wait(void *data)
        return NULL;
 }
 
-int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char *context, char *exten, int priority, int *reason, int sync, char *cid_num, char *cid_name, char *variable, char *account)
+int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account)
 {
        struct ast_channel *chan;
        struct async_stat *as;
@@ -4052,7 +4134,8 @@ int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char
                LOAD_OH(oh);
                chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh);
                if (chan) {
-                       pbx_builtin_setaccount(chan, account);
+                       if (account)
+                               ast_cdr_setaccount(chan, account);
                        if (chan->_state == AST_STATE_UP) {
                                        res = 0;
                                if (option_verbose > 3)
@@ -4110,7 +4193,8 @@ int ast_pbx_outgoing_exten(char *type, int format, void *data, int timeout, char
                        free(as);
                        return -1;
                }
-               pbx_builtin_setaccount(chan, account);
+               if (account)
+                       ast_cdr_setaccount(chan, account);
                as->chan = chan;
                strncpy(as->context, context, sizeof(as->context) - 1);
                strncpy(as->exten,  exten, sizeof(as->exten) - 1);
@@ -4157,7 +4241,7 @@ static void *ast_pbx_run_app(void *data)
        return NULL;
 }
 
-int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *app, char *appdata, int *reason, int sync, char *cid_num, char *cid_name, char *variable, char *account)
+int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account)
 {
        struct ast_channel *chan;
        struct async_stat *as;
@@ -4171,7 +4255,8 @@ int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *
        if (sync) {
                chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
                if (chan) {
-                       pbx_builtin_setaccount(chan, account);
+                       if (account)
+                               ast_cdr_setaccount(chan, account);
                        if (variable) {
                                vartmp = ast_strdupa(variable);
                                for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp)) {
@@ -4220,7 +4305,8 @@ int ast_pbx_outgoing_app(char *type, int format, void *data, int timeout, char *
                        free(as);
                        return -1;
                }
-               pbx_builtin_setaccount(chan, account);
+               if (account)
+                       ast_cdr_setaccount(chan, account);
                as->chan = chan;
                strncpy(as->app, app, sizeof(as->app) - 1);
                if (appdata)
@@ -4255,7 +4341,7 @@ static void destroy_exten(struct ast_exten *e)
        free(e);
 }
 
-void __ast_context_destroy(struct ast_context *con, char *registrar)
+void __ast_context_destroy(struct ast_context *con, const char *registrar)
 {
        struct ast_context *tmp, *tmpl=NULL;
        struct ast_include *tmpi, *tmpil= NULL;
@@ -4328,7 +4414,7 @@ void __ast_context_destroy(struct ast_context *con, char *registrar)
        ast_mutex_unlock(&conlock);
 }
 
-void ast_context_destroy(struct ast_context *con, char *registrar)
+void ast_context_destroy(struct ast_context *con, const char *registrar)
 {
        __ast_context_destroy(con,registrar);
 }
@@ -4615,6 +4701,7 @@ static int pbx_builtin_goto(struct ast_channel *chan, void *data)
        char *s;
        char *exten, *pri, *context;
        char *stringp=NULL;
+       int ipri;
 
        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
@@ -4638,12 +4725,15 @@ static int pbx_builtin_goto(struct ast_channel *chan, void *data)
                        context = NULL;
                }
        }
-       if (atoi(pri) < 0) {
-               ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
-               return -1;
-       }
+       if (sscanf(pri, "%i", &ipri) != 1) {
+               if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, (exten && strcasecmp(exten, "BYEXTENSION")) ? exten : chan->exten, 
+                       pri, chan->cid.cid_num)) < 1) {
+                       ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
+                       return -1;
+               }
+       } 
        /* At this point we have a priority and maybe an extension and a context */
-       chan->priority = atoi(pri) - 1;
+       chan->priority = ipri - 1;
        if (exten && strcasecmp(exten, "BYEXTENSION"))
                strncpy(chan->exten, exten, sizeof(chan->exten)-1);
        if (context)
@@ -4907,22 +4997,27 @@ int ast_unlock_context(struct ast_context *con)
 /*
  * Name functions ...
  */
-char *ast_get_context_name(struct ast_context *con)
+const char *ast_get_context_name(struct ast_context *con)
 {
        return con ? con->name : NULL;
 }
 
-char *ast_get_extension_name(struct ast_exten *exten)
+const char *ast_get_extension_name(struct ast_exten *exten)
 {
        return exten ? exten->exten : NULL;
 }
 
-char *ast_get_include_name(struct ast_include *inc)
+const char *ast_get_extension_label(struct ast_exten *exten)
+{
+       return exten ? exten->label : NULL;
+}
+
+const char *ast_get_include_name(struct ast_include *inc)
 {
        return inc ? inc->name : NULL;
 }
 
-char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
+const char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
 {
        return ip ? ip->pattern : NULL;
 }
@@ -4935,22 +5030,22 @@ int ast_get_extension_priority(struct ast_exten *exten)
 /*
  * Registrar info functions ...
  */
-char *ast_get_context_registrar(struct ast_context *c)
+const char *ast_get_context_registrar(struct ast_context *c)
 {
        return c ? c->registrar : NULL;
 }
 
-char *ast_get_extension_registrar(struct ast_exten *e)
+const char *ast_get_extension_registrar(struct ast_exten *e)
 {
        return e ? e->registrar : NULL;
 }
 
-char *ast_get_include_registrar(struct ast_include *i)
+const char *ast_get_include_registrar(struct ast_include *i)
 {
        return i ? i->registrar : NULL;
 }
 
-char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
+const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
 {
        return ip ? ip->registrar : NULL;
 }
@@ -4960,12 +5055,12 @@ int ast_get_extension_matchcid(struct ast_exten *e)
        return e ? e->matchcid : 0;
 }
 
-char *ast_get_extension_cidmatch(struct ast_exten *e)
+const char *ast_get_extension_cidmatch(struct ast_exten *e)
 {
        return e ? e->cidmatch : NULL;
 }
 
-char *ast_get_extension_app(struct ast_exten *e)
+const char *ast_get_extension_app(struct ast_exten *e)
 {
        return e ? e->app : NULL;
 }
@@ -4975,17 +5070,17 @@ void *ast_get_extension_app_data(struct ast_exten *e)
        return e ? e->data : NULL;
 }
 
-char *ast_get_switch_name(struct ast_sw *sw)
+const char *ast_get_switch_name(struct ast_sw *sw)
 {
        return sw ? sw->name : NULL;
 }
 
-char *ast_get_switch_data(struct ast_sw *sw)
+const char *ast_get_switch_data(struct ast_sw *sw)
 {
        return sw ? sw->data : NULL;
 }
 
-char *ast_get_switch_registrar(struct ast_sw *sw)
+const char *ast_get_switch_registrar(struct ast_sw *sw)
 {
        return sw ? sw->registrar : NULL;
 }
index 7bc449c..6cac835 100755 (executable)
@@ -1215,7 +1215,7 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
 
        if (!app_data)
                app_data="";
-       if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, cidmatch, app,
+       if (ast_add_extension(argv[4], argc == 6 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
                (void *)strdup(app_data), free, registrar)) {
                switch (errno) {
                        case ENOMEM:
@@ -1617,6 +1617,7 @@ static int pbx_load_module(void)
        char *cxt, *ext, *pri, *appl, *data, *tc, *cidmatch;
        struct ast_context *con;
        char *start, *end;
+       char *label;
        char realvalue[256];
        int lastpri = -2;
 
@@ -1657,6 +1658,16 @@ static int pbx_load_module(void)
                                                        pri = strsep(&stringp, ",");
                                                        if (!pri)
                                                                pri="";
+                                                       label = strchr(pri, '(');
+                                                       if (label) {
+                                                               *label = '\0';
+                                                               label++;
+                                                               end = strchr(label, ')');
+                                                               if (end)
+                                                                       *end = '\0';
+                                                               else
+                                                                       ast_log(LOG_WARNING, "Label missing trailing ')' at line %d\n", v->lineno);
+                                                       }
                                                        if (!strcmp(pri,"hint"))
                                                                ipri=PRIORITY_HINT;
                                                        else if (!strcmp(pri, "next") || !strcmp(pri, "n")) {
@@ -1712,7 +1723,7 @@ static int pbx_load_module(void)
                                                        pbx_substitute_variables_helper(NULL, ext, realext, sizeof(realext) - 1);
                                                        if (ipri) {
                                                                lastpri = ipri;
-                                                               if (ast_add_extension2(con, 0, realext, ipri, cidmatch, appl, strdup(data), FREE, registrar)) {
+                                                               if (ast_add_extension2(con, 0, realext, ipri, label, cidmatch, appl, strdup(data), FREE, registrar)) {
                                                                        ast_log(LOG_WARNING, "Unable to register extension at line %d\n", v->lineno);
                                                                }
                                                        }
index 560885a..273246c 100755 (executable)
@@ -241,7 +241,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
                        }
                        if (con) {
                                snprintf(exten, sizeof(exten), "%d", x);
-                               ast_add_extension2(con, 1, exten, 1, NULL, parkedcall, strdup(exten), free, registrar);
+                               ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), free, registrar);
                        }
                        return 0;
                } else {
@@ -930,7 +930,7 @@ int load_module(void)
                        return -1;
                }
        }
-       ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, parkcall, strdup(""),free, registrar);
+       ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""),free, registrar);
        ast_pthread_create(&parking_thread, NULL, do_parking_thread, NULL);
        res = ast_register_application(parkedcall, park_exec, synopsis, descrip);
        if (!res)