major dialplan functions update
authorKevin P. Fleming <kpfleming@digium.com>
Sun, 12 Feb 2006 04:28:58 +0000 (04:28 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Sun, 12 Feb 2006 04:28:58 +0000 (04:28 +0000)
deprecate LANGUAGE() and MUSICCLASS(), in favor of CHANNEL()

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@9674 65c4cc65-6c06-0410-ace0-fbb531ad65f3

35 files changed:
apps/app_curl.c
apps/app_hasnewvoicemail.c
apps/app_queue.c
channels/chan_agent.c
channels/chan_iax2.c
channels/chan_sip.c
doc/CODING-GUIDELINES
formats/format_ogg_vorbis.c
funcs/func_base64.c
funcs/func_callerid.c
funcs/func_cdr.c
funcs/func_channel.c [new file with mode: 0644]
funcs/func_cut.c
funcs/func_db.c
funcs/func_enum.c
funcs/func_env.c
funcs/func_groupcount.c
funcs/func_language.c
funcs/func_logic.c
funcs/func_math.c
funcs/func_md5.c
funcs/func_moh.c
funcs/func_odbc.c
funcs/func_rand.c
funcs/func_sha1.c
funcs/func_strings.c
funcs/func_timeout.c
funcs/func_uri.c
include/asterisk/channel.h
include/asterisk/module.h
include/asterisk/pbx.h
manager.c
pbx.c
pbx/pbx_dundi.c
res/res_agi.c

index c173696..1ef205e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C)  2004 - 2005, Tilghman Lesher
+ * Copyright (C)  2004 - 2006, Tilghman Lesher
  *
  * Tilghman Lesher <curl-20050919@the-tilghman.com>
  * and Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
@@ -109,10 +109,9 @@ static int curl_internal(struct MemoryStruct *chunk, char *url, char *post)
        return 0;
 }
 
-static char *acf_curl_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int acf_curl_exec(struct ast_channel *chan, char *cmd, char *info, char *buf, size_t len)
 {
        struct localuser *u;
-       char *info;
        struct MemoryStruct chunk = { NULL, 0 };
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(url);
@@ -121,21 +120,16 @@ static char *acf_curl_exec(struct ast_channel *chan, char *cmd, char *data, char
 
        *buf = '\0';
        
-       if (ast_strlen_zero(data)) {
+       if (ast_strlen_zero(info)) {
                ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
-               return buf;
+               return -1;
        }
 
        LOCAL_USER_ACF_ADD(u);
 
-       if (!(info = ast_strdupa(data))) {
-               LOCAL_USER_REMOVE(u);
-               return buf;
-       }
-
        AST_STANDARD_APP_ARGS(args, info);      
        
-       if (! curl_internal(&chunk, args.url, args.postdata)) {
+       if (!curl_internal(&chunk, args.url, args.postdata)) {
                if (chunk.memory) {
                        chunk.memory[chunk.size] = '\0';
                        if (chunk.memory[chunk.size - 1] == 10)
@@ -149,7 +143,8 @@ static char *acf_curl_exec(struct ast_channel *chan, char *cmd, char *data, char
        }
 
        LOCAL_USER_REMOVE(u);
-       return buf;
+
+       return 0;
 }
 
 struct ast_custom_function acf_curl = {
index f2350eb..535f4cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Changes Copyright (c) 2004 - 2005 Todd Freeman <freeman@andrews.edu>
+ * Changes Copyright (c) 2004 - 2006 Todd Freeman <freeman@andrews.edu>
  * 
  * 95% based on HasNewVoicemail by:
  * 
@@ -178,10 +178,10 @@ static int hasvoicemail_exec(struct ast_channel *chan, void *data)
        return 0;
 }
 
-static char *acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+int acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *argsstr, char *buf, size_t len)
 {
        struct localuser *u;
-       char *argsstr, *context;
+       char *context;
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(vmbox);
                AST_APP_ARG(folder);
@@ -191,11 +191,6 @@ static char *acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *data, c
 
        buf[0] = '\0';
 
-       if (!(argsstr = ast_strdupa(data))) {
-               LOCAL_USER_REMOVE(u);
-               return buf;
-       }
-
        AST_STANDARD_APP_ARGS(args, argsstr);
 
        if (strchr(args.vmbox, '@')) {
@@ -213,7 +208,7 @@ static char *acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *data, c
 
        LOCAL_USER_REMOVE(u);
        
-       return buf;
+       return 0;
 }
 
 struct ast_custom_function acf_vmcount = {
index e1acd27..d9ca0d7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -3142,19 +3142,18 @@ check_turns:
        return res;
 }
 
-static char *queue_function_qac(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
        int count = 0;
        struct ast_call_queue *q;
        struct localuser *u;
        struct member *m;
 
-
-       ast_copy_string(buf, "0", len);
+       buf[0] = '\0';
        
        if (ast_strlen_zero(data)) {
                ast_log(LOG_ERROR, "%s requires an argument: queuename\n", cmd);
-               return buf;
+               return -1;
        }
 
        LOCAL_USER_ACF_ADD(u);
@@ -3183,10 +3182,10 @@ static char *queue_function_qac(struct ast_channel *chan, char *cmd, char *data,
 
        snprintf(buf, len, "%d", count);
        LOCAL_USER_REMOVE(u);
-       return buf;
+       return 0;
 }
 
-static char *queue_function_queuememberlist(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int queue_function_queuememberlist(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
        struct localuser *u;
        struct ast_call_queue *q;
@@ -3197,7 +3196,7 @@ static char *queue_function_queuememberlist(struct ast_channel *chan, char *cmd,
 
        if (ast_strlen_zero(data)) {
                ast_log(LOG_ERROR, "QUEUE_MEMBER_LIST requires an argument: queuename\n");
-               return buf;
+               return -1;
        }
        
        LOCAL_USER_ACF_ADD(u);
@@ -3236,7 +3235,7 @@ static char *queue_function_queuememberlist(struct ast_channel *chan, char *cmd,
        /* We should already be terminated, but let's make sure. */
        buf[len - 1] = '\0';
        LOCAL_USER_REMOVE(u);
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function queueagentcount_function = {
index ff0308b..b8bc94f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -2409,7 +2409,7 @@ struct agent_pvt *find_agent(char *agentid)
        return cur;     
 }
 
-static char *function_agent(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_agent(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
        char *parse;    
        AST_DECLARE_APP_ARGS(args,
@@ -2423,11 +2423,11 @@ static char *function_agent(struct ast_channel *chan, char *cmd, char *data, cha
 
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "The AGENT function requires an argument - agentid!\n");
-               return buf;     
+               return -1;
        }
 
        if (!(parse = ast_strdupa(data)))
-               return buf;
+               return -1;
 
        AST_NONSTANDARD_APP_ARGS(args, parse, ':');
        if (!args.item)
@@ -2435,7 +2435,7 @@ static char *function_agent(struct ast_channel *chan, char *cmd, char *data, cha
 
        if (!(agent = find_agent(args.agentid))) {
                ast_log(LOG_WARNING, "Agent '%s' not found!\n", args.agentid);
-               return buf;
+               return -1;
        }
 
        if (!strcasecmp(args.item, "status")) {
@@ -2461,7 +2461,7 @@ static char *function_agent(struct ast_channel *chan, char *cmd, char *data, cha
                ast_copy_string(buf, agent->loginchan, len);    
        }
 
-       return buf;
+       return 0;
 }
 
 struct ast_custom_function agent_function = {
index 2c5bab2..b54f17d 100644 (file)
@@ -9170,31 +9170,29 @@ static int iax2_exec(struct ast_channel *chan, const char *context, const char *
        return -1;
 }
 
-static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
-       char *ret = NULL;
        struct iax2_peer *peer;
        char *peername, *colname;
        char iabuf[INET_ADDRSTRLEN];
 
        if (!(peername = ast_strdupa(data)))
-               return ret;
+               return -1;
 
        /* if our channel, return the IP address of the endpoint of current channel */
        if (!strcmp(peername,"CURRENTCHANNEL")) {
                unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
                ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
-               return buf;
+               return 0;
        }
 
-       if ((colname = strchr(peername, ':'))) {
-               *colname = '\0';
-               colname++;
-       } else {
+       if ((colname = strchr(peername, ':')))
+               *colname++ = '\0';
+       else
                colname = "ip";
-       }
+
        if (!(peer = find_peer(peername, 1)))
-               return ret;
+               return -1;
 
        if (!strcasecmp(colname, "ip")) {
                ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
@@ -9229,16 +9227,15 @@ static char *function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, c
                        ast_copy_string(buf, ast_getformatname(codec), len);
                }
        }
-       ret = buf;
 
-       return ret;
+       return 0;
 }
 
 struct ast_custom_function iaxpeer_function = {
-    .name = "IAXPEER",
-    .synopsis = "Gets IAX peer information",
-    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[:item])",
-    .read = function_iaxpeer,
+       .name = "IAXPEER",
+       .synopsis = "Gets IAX peer information",
+       .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[:item])",
+       .read = function_iaxpeer,
        .desc = "If peername specified, valid items are:\n"
        "- ip (default)          The IP address.\n"
        "- status                The peer's status (if qualify=yes)\n"
index 4841382..6c42f84 100644 (file)
@@ -9269,21 +9269,21 @@ static char show_settings_usage[] =
 
 
 /*! \brief  func_header_read: Read SIP header (dialplan function) */
-static char *func_header_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len) 
 {
        struct sip_pvt *p;
        char *content;
        
        if (!data) {
                ast_log(LOG_WARNING, "This function requires a header name.\n");
-               return NULL;
+               return -1;
        }
 
        ast_mutex_lock(&chan->lock);
        if (chan->tech != &sip_tech) {
                ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
 
        p = chan->tech_pvt;
@@ -9291,23 +9291,22 @@ static char *func_header_read(struct ast_channel *chan, char *cmd, char *data, c
        /* If there is no private structure, this channel is no longer alive */
        if (!p) {
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
 
        content = get_header(&p->initreq, data);
 
        if (ast_strlen_zero(content)) {
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
 
        ast_copy_string(buf, content, len);
        ast_mutex_unlock(&chan->lock);
 
-       return buf;
+       return 0;
 }
 
-
 static struct ast_custom_function sip_header_function = {
        .name = "SIP_HEADER",
        .synopsis = "Gets or sets the specified SIP header",
@@ -9316,17 +9315,17 @@ static struct ast_custom_function sip_header_function = {
 };
 
 /*! \brief  function_check_sipdomain: Dial plan function to check if domain is local */
-static char *func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
-               return buf;
+               return -1;
        }
        if (check_sip_domain(data, NULL, 0))
                ast_copy_string(buf, data, len);
        else
                buf[0] = '\0';
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function checksipdomain_function = {
@@ -9340,26 +9339,20 @@ static struct ast_custom_function checksipdomain_function = {
                "Check the domain= configuration in sip.conf\n",
 };
 
-
 /*! \brief  function_sippeer: ${SIPPEER()} Dialplan function - reads peer data */
-static char *function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
-       char *ret = NULL;
        struct sip_peer *peer;
        char *peername, *colname;
        char iabuf[INET_ADDRSTRLEN];
 
-       if (!(peername = ast_strdupa(data)))
-               return ret;
-
-       if ((colname = strchr(peername, ':'))) {
-               *colname = '\0';
-               colname++;
-       } else {
+       if ((colname = strchr(data, ':')))
+               *colname++ = '\0';
+       else
                colname = "ip";
-       }
+
        if (!(peer = find_peer(peername, NULL, 1)))
-               return ret;
+               return -1;
 
        if (!strcasecmp(colname, "ip")) {
                ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
@@ -9396,19 +9389,18 @@ static char *function_sippeer(struct ast_channel *chan, char *cmd, char *data, c
                codecnum = strchr(colname, '[');
                *codecnum = '\0';
                codecnum++;
-               if ((ptr = strchr(codecnum, ']'))) {
+               if ((ptr = strchr(codecnum, ']')))
                        *ptr = '\0';
-               }
+
                index = atoi(codecnum);
                if((codec = ast_codec_pref_index(&peer->prefs, index))) {
                        ast_copy_string(buf, ast_getformatname(codec), len);
                }
        }
-       ret = buf;
 
        ASTOBJ_UNREF(peer, sip_destroy_peer);
 
-       return ret;
+       return 0;
 }
 
 /*! \brief Structure to declare a dialplan function: SIPPEER */
@@ -9438,7 +9430,7 @@ struct ast_custom_function sippeer_function = {
 };
 
 /*! \brief  function_sipchaninfo_read: ${SIPCHANINFO()} Dialplan function - reads sip channel data */
-static char *function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
 {
        struct sip_pvt *p;
        char iabuf[INET_ADDRSTRLEN];
@@ -9447,14 +9439,14 @@ static char *function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char
        
        if (!data) {
                ast_log(LOG_WARNING, "This function requires a parameter name.\n");
-               return NULL;
+               return -1;
        }
 
        ast_mutex_lock(&chan->lock);
        if (chan->tech != &sip_tech) {
                ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
 
 /*     ast_verbose("function_sipchaninfo_read: %s\n", data); */
@@ -9463,7 +9455,7 @@ static char *function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char
        /* If there is no private structure, this channel is no longer alive */
        if (!p) {
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
 
        if (!strcasecmp(data, "peerip")) {
@@ -9480,11 +9472,11 @@ static char *function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char
                ast_copy_string(buf, p->peername, len);
        } else {
                ast_mutex_unlock(&chan->lock);
-               return NULL;
+               return -1;
        }
        ast_mutex_unlock(&chan->lock);
 
-       return buf;
+       return 0;
 }
 
 /*! \brief Structure to declare a dialplan function: SIPCHANINFO */
@@ -9502,8 +9494,6 @@ static struct ast_custom_function sipchaninfo_function = {
        "- peername              The name of the peer.\n"
 };
 
-
-
 /*! \brief  parse_moved_contact: Parse 302 Moved temporalily response */
 static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
 {
index e64bbd3..c8afc70 100644 (file)
@@ -77,7 +77,7 @@ $ cvs diff -urN <mycodefile>.c
 Roughly, Asterisk code formatting guidelines are generally equivalent to the 
 following:
 
-# indent -i4 -ts4 -br -brs -cdw -cli0 -ce -nbfda -npcs -nprs -npsl -saf -sai -saw foo.c
+# indent -i4 -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -ln90 foo.c
 
 this means in verbose:
  -i4:    indent level 4
@@ -85,7 +85,7 @@ this means in verbose:
  -br:    braces on if line
  -brs:   braces on struct decl line
  -cdw:   cuddle do while
- -cli0:  case indentation 0
+ -lp:    line up continuation below parenthesis
  -ce:    cuddle else
  -nbfda: dont break function decl args
  -npcs:  no space after function call names
@@ -94,6 +94,8 @@ this means in verbose:
  -saf:   space after for
  -sai:   space after if
  -saw:   space after while
+ -cs:    space after cast
+ -ln90:  line length 90 columns
 
 Function calls and arguments should be spaced in a consistent way across
 the codebase.
index ffee9ed..408f19e 100644 (file)
@@ -20,7 +20,7 @@
  * \arg File name extension: ogg
  * \ingroup formats
  */
+
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -48,37 +48,35 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
 #include "asterisk/module.h"
-
 #define SAMPLES_MAX 160
 #define BLOCK_SIZE 4096
 
-
 struct ast_filestream {
        void *reserved[AST_RESERVED_POINTERS];
-
+       
        FILE *f;
-
+       
        /* structures for handling the Ogg container */
-       ogg_sync_state   oy;
+       ogg_sync_state oy;
        ogg_stream_state os;
-       ogg_page         og;
-       ogg_packet       op;
+       ogg_page og;
+       ogg_packet op;
        
        /* structures for handling Vorbis audio data */
-       vorbis_info      vi;
-       vorbis_comment   vc;
+       vorbis_info vi;
+       vorbis_comment vc;
        vorbis_dsp_state vd;
-       vorbis_block     vb;
+       vorbis_block vb;
        
        /*! \brief Indicates whether this filestream is set up for reading or writing. */
        int writing;
-
+       
        /*! \brief Indicates whether an End of Stream condition has been detected. */
        int eos;
-
+       
        /*! \brief Buffer to hold audio data. */
        short buffer[SAMPLES_MAX];
-
+       
        /*! \brief Asterisk frame object. */
        struct ast_frame fr;
        char waste[AST_FRIENDLY_OFFSET];
@@ -86,6 +84,7 @@ struct ast_filestream {
 };
 
 AST_MUTEX_DEFINE_STATIC(ogg_vorbis_lock);
+
 static int glistcnt = 0;
 
 static char *name = "ogg_vorbis";
@@ -97,7 +96,7 @@ static char *exts = "ogg";
  * \param f File that points to on disk storage of the OGG/Vorbis data.
  * \return The new filestream.
  */
-static struct ast_filestream *ogg_vorbis_open(FILE *f)
+static struct ast_filestream *ogg_vorbis_open(FILE * f)
 {
        int i;
        int bytes;
@@ -107,7 +106,7 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
 
        struct ast_filestream *tmp;
 
-       if((tmp = malloc(sizeof(struct ast_filestream)))) {
+       if ((tmp = malloc(sizeof(struct ast_filestream)))) {
                memset(tmp, 0, sizeof(struct ast_filestream));
 
                tmp->writing = 0;
@@ -120,24 +119,26 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                ogg_sync_wrote(&tmp->oy, bytes);
 
                result = ogg_sync_pageout(&tmp->oy, &tmp->og);
-               if(result != 1) {
-                       if(bytes < BLOCK_SIZE) {
+               if (result != 1) {
+                       if (bytes < BLOCK_SIZE) {
                                ast_log(LOG_ERROR, "Run out of data...\n");
                        } else {
-                               ast_log(LOG_ERROR, "Input does not appear to be an Ogg bitstream.\n");
+                               ast_log(LOG_ERROR,
+                                               "Input does not appear to be an Ogg bitstream.\n");
                        }
                        fclose(f);
                        ogg_sync_clear(&tmp->oy);
                        free(tmp);
                        return NULL;
                }
-               
+
                ogg_stream_init(&tmp->os, ogg_page_serialno(&tmp->og));
                vorbis_info_init(&tmp->vi);
                vorbis_comment_init(&tmp->vc);
 
-               if(ogg_stream_pagein(&tmp->os, &tmp->og) < 0) { 
-                       ast_log(LOG_ERROR, "Error reading first page of Ogg bitstream data.\n");
+               if (ogg_stream_pagein(&tmp->os, &tmp->og) < 0) {
+                       ast_log(LOG_ERROR,
+                                       "Error reading first page of Ogg bitstream data.\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
                        vorbis_comment_clear(&tmp->vc);
@@ -146,8 +147,8 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        free(tmp);
                        return NULL;
                }
-               
-               if(ogg_stream_packetout(&tmp->os, &tmp->op) != 1) { 
+
+               if (ogg_stream_packetout(&tmp->os, &tmp->op) != 1) {
                        ast_log(LOG_ERROR, "Error reading initial header packet.\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
@@ -157,8 +158,8 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        free(tmp);
                        return NULL;
                }
-               
-               if(vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op) < 0) { 
+
+               if (vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op) < 0) {
                        ast_log(LOG_ERROR, "This Ogg bitstream does not contain Vorbis audio data.\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
@@ -168,20 +169,20 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        free(tmp);
                        return NULL;
                }
-               
+
                i = 0;
-               while(i < 2) {
-                       while(i < 2){
+               while (i < 2) {
+                       while (i < 2) {
                                result = ogg_sync_pageout(&tmp->oy, &tmp->og);
-                               if(result == 0)
+                               if (result == 0)
                                        break;
-                               if(result == 1) {
+                               if (result == 1) {
                                        ogg_stream_pagein(&tmp->os, &tmp->og);
-                                       while(i < 2) {
-                                               result = ogg_stream_packetout(&tmp->os,&tmp->op);
-                                               if(result == 0)
+                                       while (i < 2) {
+                                               result = ogg_stream_packetout(&tmp->os, &tmp->op);
+                                               if (result == 0)
                                                        break;
-                                               if(result < 0) {
+                                               if (result < 0) {
                                                        ast_log(LOG_ERROR, "Corrupt secondary header.  Exiting.\n");
                                                        fclose(f);
                                                        ogg_stream_clear(&tmp->os);
@@ -199,7 +200,7 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
 
                        buffer = ogg_sync_buffer(&tmp->oy, BLOCK_SIZE);
                        bytes = fread(buffer, 1, BLOCK_SIZE, f);
-                       if(bytes == 0 && i < 2) {
+                       if (bytes == 0 && i < 2) {
                                ast_log(LOG_ERROR, "End of file before finding all Vorbis headers!\n");
                                fclose(f);
                                ogg_stream_clear(&tmp->os);
@@ -211,16 +212,18 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        }
                        ogg_sync_wrote(&tmp->oy, bytes);
                }
-               
+
                ptr = tmp->vc.user_comments;
-               while(*ptr){
+               while (*ptr) {
                        ast_log(LOG_DEBUG, "OGG/Vorbis comment: %s\n", *ptr);
                        ++ptr;
                }
-               ast_log(LOG_DEBUG, "OGG/Vorbis bitstream is %d channel, %ldHz\n", tmp->vi.channels, tmp->vi.rate);
-               ast_log(LOG_DEBUG, "OGG/Vorbis file encoded by: %s\n", tmp->vc.vendor);
+               ast_log(LOG_DEBUG, "OGG/Vorbis bitstream is %d channel, %ldHz\n",
+                       tmp->vi.channels, tmp->vi.rate);
+               ast_log(LOG_DEBUG, "OGG/Vorbis file encoded by: %s\n",
+                       tmp->vc.vendor);
 
-               if(tmp->vi.channels != 1) {
+               if (tmp->vi.channels != 1) {
                        ast_log(LOG_ERROR, "Only monophonic OGG/Vorbis files are currently supported!\n");
                        ogg_stream_clear(&tmp->os);
                        vorbis_comment_clear(&tmp->vc);
@@ -229,9 +232,8 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        free(tmp);
                        return NULL;
                }
-               
 
-               if(tmp->vi.rate != 8000) {
+               if (tmp->vi.rate != 8000) {
                        ast_log(LOG_ERROR, "Only 8000Hz OGG/Vorbis files are currently supported!\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
@@ -243,11 +245,11 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
                        free(tmp);
                        return NULL;
                }
-               
+
                vorbis_synthesis_init(&tmp->vd, &tmp->vi);
                vorbis_block_init(&tmp->vd, &tmp->vb);
 
-               if(ast_mutex_lock(&ogg_vorbis_lock)) {
+               if (ast_mutex_lock(&ogg_vorbis_lock)) {
                        ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
@@ -272,7 +274,8 @@ static struct ast_filestream *ogg_vorbis_open(FILE *f)
  * \param comment Comment that should be embedded in the OGG/Vorbis file.
  * \return A new filestream.
  */
-static struct ast_filestream *ogg_vorbis_rewrite(FILE *f, const char *comment)
+static struct ast_filestream *ogg_vorbis_rewrite(FILE * f,
+                                                const char *comment)
 {
        ogg_packet header;
        ogg_packet header_comm;
@@ -280,7 +283,7 @@ static struct ast_filestream *ogg_vorbis_rewrite(FILE *f, const char *comment)
 
        struct ast_filestream *tmp;
 
-       if((tmp = malloc(sizeof(struct ast_filestream)))) {
+       if ((tmp = malloc(sizeof(struct ast_filestream)))) {
                memset(tmp, 0, sizeof(struct ast_filestream));
 
                tmp->writing = 1;
@@ -288,7 +291,7 @@ static struct ast_filestream *ogg_vorbis_rewrite(FILE *f, const char *comment)
 
                vorbis_info_init(&tmp->vi);
 
-               if(vorbis_encode_init_vbr(&tmp->vi, 1, 8000, 0.4)) {
+               if (vorbis_encode_init_vbr(&tmp->vi, 1, 8000, 0.4)) {
                        ast_log(LOG_ERROR, "Unable to initialize Vorbis encoder!\n");
                        free(tmp);
                        return NULL;
@@ -296,7 +299,7 @@ static struct ast_filestream *ogg_vorbis_rewrite(FILE *f, const char *comment)
 
                vorbis_comment_init(&tmp->vc);
                vorbis_comment_add_tag(&tmp->vc, "ENCODER", "Asterisk PBX");
-               if(comment)
+               if (comment)
                        vorbis_comment_add_tag(&tmp->vc, "COMMENT", (char *) comment);
 
                vorbis_analysis_init(&tmp->vd, &tmp->vi);
@@ -304,21 +307,22 @@ static struct ast_filestream *ogg_vorbis_rewrite(FILE *f, const char *comment)
 
                ogg_stream_init(&tmp->os, rand());
 
-               vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm, &header_code);
-               ogg_stream_packetin(&tmp->os, &header);                                                 
+               vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm,
+                                         &header_code);
+               ogg_stream_packetin(&tmp->os, &header);
                ogg_stream_packetin(&tmp->os, &header_comm);
                ogg_stream_packetin(&tmp->os, &header_code);
 
-               while(!tmp->eos) {
-                       if(ogg_stream_flush(&tmp->os, &tmp->og) == 0)
+               while (!tmp->eos) {
+                       if (ogg_stream_flush(&tmp->os, &tmp->og) == 0)
                                break;
                        fwrite(tmp->og.header, 1, tmp->og.header_len, tmp->f);
                        fwrite(tmp->og.body, 1, tmp->og.body_len, tmp->f);
-                       if(ogg_page_eos(&tmp->og))
+                       if (ogg_page_eos(&tmp->og))
                                tmp->eos = 1;
                }
 
-               if(ast_mutex_lock(&ogg_vorbis_lock)) {
+               if (ast_mutex_lock(&ogg_vorbis_lock)) {
                        ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
                        fclose(f);
                        ogg_stream_clear(&tmp->os);
@@ -345,16 +349,16 @@ static void write_stream(struct ast_filestream *s)
        while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
                vorbis_analysis(&s->vb, NULL);
                vorbis_bitrate_addblock(&s->vb);
-               
+
                while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
                        ogg_stream_packetin(&s->os, &s->op);
                        while (!s->eos) {
-                               if(ogg_stream_pageout(&s->os, &s->og) == 0) {
+                               if (ogg_stream_pageout(&s->os, &s->og) == 0) {
                                        break;
                                }
                                fwrite(s->og.header, 1, s->og.header_len, s->f);
                                fwrite(s->og.body, 1, s->og.body_len, s->f);
-                               if(ogg_page_eos(&s->og)) {
+                               if (ogg_page_eos(&s->og)) {
                                        s->eos = 1;
                                }
                        }
@@ -374,20 +378,21 @@ static int ogg_vorbis_write(struct ast_filestream *s, struct ast_frame *f)
        float **buffer;
        short *data;
 
-       if(!s->writing) {
+       if (!s->writing) {
                ast_log(LOG_ERROR, "This stream is not set up for writing!\n");
                return -1;
        }
 
-       if(f->frametype != AST_FRAME_VOICE) {
+       if (f->frametype != AST_FRAME_VOICE) {
                ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
                return -1;
        }
-       if(f->subclass != AST_FORMAT_SLINEAR) {
-               ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%d)!\n", f->subclass);
+       if (f->subclass != AST_FORMAT_SLINEAR) {
+               ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%d)!\n",
+                               f->subclass);
                return -1;
        }
-       if(!f->datalen)
+       if (!f->datalen)
                return -1;
 
        data = (short *) f->data;
@@ -395,7 +400,7 @@ static int ogg_vorbis_write(struct ast_filestream *s, struct ast_frame *f)
        buffer = vorbis_analysis_buffer(&s->vd, f->samples);
 
        for (i = 0; i < f->samples; i++) {
-               buffer[0][i] = data[i]/32768.f;
+               buffer[0][i] = data[i] / 32768.f;
        }
 
        vorbis_analysis_wrote(&s->vd, f->samples);
@@ -411,7 +416,7 @@ static int ogg_vorbis_write(struct ast_filestream *s, struct ast_frame *f)
  */
 static void ogg_vorbis_close(struct ast_filestream *s)
 {
-       if(ast_mutex_lock(&ogg_vorbis_lock)) {
+       if (ast_mutex_lock(&ogg_vorbis_lock)) {
                ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
                return;
        }
@@ -419,7 +424,7 @@ static void ogg_vorbis_close(struct ast_filestream *s)
        ast_mutex_unlock(&ogg_vorbis_lock);
        ast_update_use_count();
 
-       if(s->writing) {
+       if (s->writing) {
                /* Tell the Vorbis encoder that the stream is finished
                 * and write out the rest of the data */
                vorbis_analysis_wrote(&s->vd, 0);
@@ -432,10 +437,10 @@ static void ogg_vorbis_close(struct ast_filestream *s)
        vorbis_comment_clear(&s->vc);
        vorbis_info_clear(&s->vi);
 
-       if(s->writing) {
+       if (s->writing) {
                ogg_sync_clear(&s->oy);
        }
-       
+
        fclose(s->f);
        free(s);
 }
@@ -455,28 +460,29 @@ static int read_samples(struct ast_filestream *s, float ***pcm)
 
        while (1) {
                samples_in = vorbis_synthesis_pcmout(&s->vd, pcm);
-               if(samples_in > 0) {
+               if (samples_in > 0) {
                        return samples_in;
                }
-               
+
                /* The Vorbis decoder needs more data... */
                /* See ifOGG has any packets in the current page for the Vorbis decoder. */
                result = ogg_stream_packetout(&s->os, &s->op);
-               if(result > 0) {
+               if (result > 0) {
                        /* Yes OGG had some more packets for the Vorbis decoder. */
-                       if(vorbis_synthesis(&s->vb, &s->op) == 0) {
+                       if (vorbis_synthesis(&s->vb, &s->op) == 0) {
                                vorbis_synthesis_blockin(&s->vd, &s->vb);
                        }
-                       
+
                        continue;
                }
 
-               if(result < 0)
-                       ast_log(LOG_WARNING, "Corrupt or missing data at this page position; continuing...\n");
-               
+               if (result < 0)
+                       ast_log(LOG_WARNING,
+                                       "Corrupt or missing data at this page position; continuing...\n");
+
                /* No more packets left in the current page... */
 
-               if(s->eos) {
+               if (s->eos) {
                        /* No more pages left in the stream */
                        return -1;
                }
@@ -484,22 +490,24 @@ static int read_samples(struct ast_filestream *s, float ***pcm)
                while (!s->eos) {
                        /* See ifOGG has any pages in it's internal buffers */
                        result = ogg_sync_pageout(&s->oy, &s->og);
-                       if(result > 0) {
+                       if (result > 0) {
                                /* Yes, OGG has more pages in it's internal buffers,
                                   add the page to the stream state */
                                result = ogg_stream_pagein(&s->os, &s->og);
-                               if(result == 0) {
+                               if (result == 0) {
                                        /* Yes, got a new,valid page */
-                                       if(ogg_page_eos(&s->og)) {
+                                       if (ogg_page_eos(&s->og)) {
                                                s->eos = 1;
                                        }
                                        break;
                                }
-                               ast_log(LOG_WARNING, "Invalid page in the bitstream; continuing...\n");
+                               ast_log(LOG_WARNING,
+                                               "Invalid page in the bitstream; continuing...\n");
                        }
-                       
-                       if(result < 0)
-                               ast_log(LOG_WARNING, "Corrupt or missing data in bitstream; continuing...\n");
+
+                       if (result < 0)
+                               ast_log(LOG_WARNING,
+                                               "Corrupt or missing data in bitstream; continuing...\n");
 
                        /* No, we need to read more data from the file descrptor */
                        /* get a buffer from OGG to read the data into */
@@ -508,7 +516,7 @@ static int read_samples(struct ast_filestream *s, float ***pcm)
                        bytes = fread(buffer, 1, BLOCK_SIZE, s->f);
                        /* Tell OGG how many bytes we actually read into the buffer */
                        ogg_sync_wrote(&s->oy, bytes);
-                       if(bytes == 0) {
+                       if (bytes == 0) {
                                s->eos = 1;
                        }
                }
@@ -521,7 +529,8 @@ static int read_samples(struct ast_filestream *s, float ***pcm)
  * \param whennext Number of sample times to schedule the next call.
  * \return A pointer to a frame containing audio data or NULL ifthere is no more audio data.
  */
-static struct ast_frame *ogg_vorbis_read(struct ast_filestream *s, int *whennext)
+static struct ast_frame *ogg_vorbis_read(struct ast_filestream *s,
+                                        int *whennext)
 {
        int clipflag = 0;
        int i;
@@ -535,25 +544,25 @@ static struct ast_frame *ogg_vorbis_read(struct ast_filestream *s, int *whennext
 
        while (1) {
                /* See ifwe have filled up an audio frame yet */
-               if(samples_out == SAMPLES_MAX)
+               if (samples_out == SAMPLES_MAX)
                        break;
 
                /* See ifVorbis decoder has some audio data for us ... */
                samples_in = read_samples(s, &pcm);
-               if(samples_in <= 0)
+               if (samples_in <= 0)
                        break;
 
                /* Got some audio data from Vorbis... */
                /* Convert the float audio data to 16-bit signed linear */
-               
+
                clipflag = 0;
 
                samples_in = samples_in < (SAMPLES_MAX - samples_out) ? samples_in : (SAMPLES_MAX - samples_out);
-  
-               for(j = 0; j < samples_in; j++)
+
+               for (j = 0; j < samples_in; j++)
                        accumulator[j] = 0.0;
 
-               for(i = 0; i < s->vi.channels; i++) {
+               for (i = 0; i < s->vi.channels; i++) {
                        mono = pcm[i];
                        for (j = 0; j < samples_in; j++) {
                                accumulator[j] += mono[j];
@@ -561,27 +570,26 @@ static struct ast_frame *ogg_vorbis_read(struct ast_filestream *s, int *whennext
                }
 
                for (j = 0; j < samples_in; j++) {
-                       val =  accumulator[j] * 32767.0 / s->vi.channels;
-                       if(val > 32767) {
+                       val = accumulator[j] * 32767.0 / s->vi.channels;
+                       if (val > 32767) {
                                val = 32767;
                                clipflag = 1;
                        }
-                       if(val < -32768) {
+                       if (val < -32768) {
                                val = -32768;
                                clipflag = 1;
                        }
                        s->buffer[samples_out + j] = val;
                }
-                       
-               if(clipflag)
-                       ast_log(LOG_WARNING, "Clipping in frame %ld\n", (long)(s->vd.sequence));
-               
+
+               if (clipflag)
+                       ast_log(LOG_WARNING, "Clipping in frame %ld\n", (long) (s->vd.sequence));
                /* Tell the Vorbis decoder how many samples we actually used. */
                vorbis_synthesis_read(&s->vd, samples_in);
                samples_out += samples_in;
        }
 
-       if(samples_out > 0) {
+       if (samples_out > 0) {
                s->fr.frametype = AST_FRAME_VOICE;
                s->fr.subclass = AST_FORMAT_SLINEAR;
                s->fr.offset = AST_FRIENDLY_OFFSET;
@@ -591,7 +599,7 @@ static struct ast_frame *ogg_vorbis_read(struct ast_filestream *s, int *whennext
                s->fr.mallocd = 0;
                s->fr.samples = samples_out;
                *whennext = samples_out;
-               
+
                return &s->fr;
        } else {
                return NULL;
@@ -618,17 +626,21 @@ static int ogg_vorbis_trunc(struct ast_filestream *s)
  * \return 0 on success, -1 on failure.
  */
 
-static int ogg_vorbis_seek(struct ast_filestream *s, long sample_offset, int whence) {
+static int ogg_vorbis_seek(struct ast_filestream *s, long sample_offset,
+                          int whence)
+{
        ast_log(LOG_WARNING, "Seeking is not supported on OGG/Vorbis streams!\n");
        return -1;
 }
 
-static long ogg_vorbis_tell(struct ast_filestream *s) {
+static long ogg_vorbis_tell(struct ast_filestream *s)
+{
        ast_log(LOG_WARNING, "Telling is not supported on OGG/Vorbis streams!\n");
        return -1;
 }
 
-static char *ogg_vorbis_getcomment(struct ast_filestream *s) {
+static char *ogg_vorbis_getcomment(struct ast_filestream *s)
+{
        ast_log(LOG_WARNING, "Getting comments is not supported on OGG/Vorbis streams!\n");
        return NULL;
 }
@@ -650,7 +662,7 @@ int load_module()
 int unload_module()
 {
        return ast_format_unregister(name);
-}      
+}
 
 int usecount()
 {
@@ -667,11 +679,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: t
-End:
-*/
index 09ed691..a502219 100644 (file)
@@ -36,31 +36,30 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *base64_encode(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int base64_encode(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
-       int res = 0;
-
-       if (ast_strlen_zero(data) ) {
+       if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: BASE64_ENCODE(<data>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       ast_log(LOG_DEBUG, "data=%s\n",data);
-       res = ast_base64encode(buf, (unsigned char *)data, strlen(data), len);
-       ast_log(LOG_DEBUG, "res=%d\n", res);
-       return buf;
+       ast_base64encode(buf, (unsigned char *) data, strlen(data), len);
+
+       return 0;
 }
 
-static char *base64_decode(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int base64_decode(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
-       if (ast_strlen_zero(data) ) {
+       if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: BASE64_DECODE(<base_64 string>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       ast_log(LOG_DEBUG, "data=%s\n", data);
-       ast_base64decode((unsigned char *)buf, data, len);
-       return buf;
+       ast_base64decode((unsigned char *) buf, data, len);
+
+       return 0;
 }
 
 static struct ast_custom_function base64_encode_function = {
@@ -83,13 +82,13 @@ static char *tdesc = "base64 encode/decode dialplan functions";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&base64_encode_function) ||
+       return ast_custom_function_unregister(&base64_encode_function) |
                ast_custom_function_unregister(&base64_decode_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&base64_encode_function) ||
+       return ast_custom_function_register(&base64_encode_function) |
                ast_custom_function_register(&base64_decode_function);
 }
 
@@ -107,11 +106,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index c907d96..056999e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999-2006, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -28,7 +28,6 @@
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include "asterisk/module.h"
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
@@ -38,7 +37,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/options.h"
 #include "asterisk/callerid.h"
 
-static char *callerid_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int callerid_read(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
        char *opt = data;
 
@@ -49,22 +49,27 @@ static char *callerid_read(struct ast_channel *chan, char *cmd, char *data, char
                ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
 
                if (!strncasecmp("all", data, 3)) {
-                       snprintf(buf, len, "\"%s\" <%s>", name, num);   
+                       snprintf(buf, len, "\"%s\" <%s>", name, num);
                } else if (!strncasecmp("name", data, 4)) {
                        ast_copy_string(buf, name, len);
-               } else if (!strncasecmp("num", data, 3) || !strncasecmp("number", data, 6)) {
+               } else if (!strncasecmp("num", data, 3) ||
+                          !strncasecmp("number", data, 6)) {
+
                        ast_copy_string(buf, num, len);
                } else {
                        ast_log(LOG_ERROR, "Unknown callerid data type.\n");
                }
        } else {
                if (!strncasecmp("all", data, 3)) {
-                       snprintf(buf, len, "\"%s\" <%s>", chan->cid.cid_name ? chan->cid.cid_name : "", chan->cid.cid_num ? chan->cid.cid_num : "");    
+                       snprintf(buf, len, "\"%s\" <%s>",
+                                chan->cid.cid_name ? chan->cid.cid_name : "",
+                                chan->cid.cid_num ? chan->cid.cid_num : "");
                } else if (!strncasecmp("name", data, 4)) {
                        if (chan->cid.cid_name) {
                                ast_copy_string(buf, chan->cid.cid_name, len);
                        }
-               } else if (!strncasecmp("num", data, 3) || !strncasecmp("number", data, 6)) {
+               } else if (!strncasecmp("num", data, 3)
+                                  || !strncasecmp("number", data, 6)) {
                        if (chan->cid.cid_num) {
                                ast_copy_string(buf, chan->cid.cid_num, len);
                        }
@@ -84,47 +89,54 @@ static char *callerid_read(struct ast_channel *chan, char *cmd, char *data, char
                        ast_log(LOG_ERROR, "Unknown callerid data type.\n");
                }
        }
-       return buf;
+
+       return 0;
 }
 
-static void callerid_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int callerid_write(struct ast_channel *chan, char *cmd, char *data,
+                         const char *value)
 {
        if (!value)
-                return;
-       
+               return -1;
+
        if (!strncasecmp("all", data, 3)) {
                char name[256];
                char num[256];
+
                if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
-                       ast_set_callerid(chan, num, name, num); 
-        } else if (!strncasecmp("name", data, 4)) {
-                ast_set_callerid(chan, NULL, value, NULL);
-        } else if (!strncasecmp("num", data, 3) || !strncasecmp("number", data, 6)) {
-                ast_set_callerid(chan, value, NULL, NULL);
-        } else if (!strncasecmp("ani", data, 3)) {
-                ast_set_callerid(chan, NULL, NULL, value);
-        } else if (!strncasecmp("dnid", data, 4)) {
-                /* do we need to lock chan here? */
-                if (chan->cid.cid_dnid)
-                        free(chan->cid.cid_dnid);
-                chan->cid.cid_dnid = ast_strlen_zero(value) ? NULL : strdup(value);
-        } else if (!strncasecmp("rdnis", data, 5)) {
-                /* do we need to lock chan here? */
-                if (chan->cid.cid_rdnis)
-                        free(chan->cid.cid_rdnis);
-                chan->cid.cid_rdnis = ast_strlen_zero(value) ? NULL : strdup(value);
-        } else {
-                ast_log(LOG_ERROR, "Unknown callerid data type.\n");
-        }
+                       ast_set_callerid(chan, num, name, num);
+       } else if (!strncasecmp("name", data, 4)) {
+               ast_set_callerid(chan, NULL, value, NULL);
+       } else if (!strncasecmp("num", data, 3) ||
+                  !strncasecmp("number", data, 6)) {
+               ast_set_callerid(chan, value, NULL, NULL);
+       } else if (!strncasecmp("ani", data, 3)) {
+               ast_set_callerid(chan, NULL, NULL, value);
+       } else if (!strncasecmp("dnid", data, 4)) {
+               /* do we need to lock chan here? */
+               if (chan->cid.cid_dnid)
+                       free(chan->cid.cid_dnid);
+               chan->cid.cid_dnid = ast_strlen_zero(value) ? NULL : strdup(value);
+       } else if (!strncasecmp("rdnis", data, 5)) {
+               /* do we need to lock chan here? */
+               if (chan->cid.cid_rdnis)
+                       free(chan->cid.cid_rdnis);
+               chan->cid.cid_rdnis = ast_strlen_zero(value) ? NULL : strdup(value);
+       } else {
+               ast_log(LOG_ERROR, "Unknown callerid data type.\n");
+       }
+
+       return 0;
 }
 
 static struct ast_custom_function callerid_function = {
        .name = "CALLERID",
        .synopsis = "Gets or sets Caller*ID data on the channel.",
        .syntax = "CALLERID(datatype[,<optional-CID>])",
-       .desc = "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
-       "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\".\n"
-       "Uses channel callerid by default or optional callerid, if specified.\n",
+       .desc =
+               "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
+               "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\".\n"
+               "Uses channel callerid by default or optional callerid, if specified.\n",
        .read = callerid_read,
        .write = callerid_write,
 };
@@ -133,12 +145,12 @@ static char *tdesc = "Caller ID related dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&callerid_function);
+       return ast_custom_function_unregister(&callerid_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&callerid_function);
+       return ast_custom_function_register(&callerid_function);
 }
 
 char *description(void)
@@ -155,11 +167,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index 205651a..d287ff9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999-2006, Digium, Inc.
  *
  * Portions Copyright (C) 2005, Anthony Minessale II
  *
@@ -47,71 +47,65 @@ AST_APP_OPTIONS(cdr_func_options, {
        AST_APP_OPTION('r', OPT_RECURSIVE),
 });
 
-static char *cdr_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int cdr_read(struct ast_channel *chan, char *cmd, char *parse,
+                   char *buf, size_t len)
 {
        char *ret;
-       char *parse;
-       struct ast_flags flags = {0};
-       
+       struct ast_flags flags = { 0 };
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(variable);
-               AST_APP_ARG(options);
+                            AST_APP_ARG(variable);
+                            AST_APP_ARG(options);
        );
 
-       if (ast_strlen_zero(data))
-               return NULL;
-       
-       if (!chan->cdr)
-               return NULL;
+       if (ast_strlen_zero(parse))
+               return -1;
 
-       if (!(parse = ast_strdupa(data)))
-               return NULL;
+       if (!chan->cdr)
+               return -1;
 
        AST_STANDARD_APP_ARGS(args, parse);
-       
-       if(!ast_strlen_zero(args.options) ) {
+
+       if (!ast_strlen_zero(args.options))
                ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
-       }
-       ast_cdr_getvar(chan->cdr, args.variable, &ret, buf, len, (ast_test_flag(&flags,OPT_RECURSIVE) ) ? 1 : 0 );
 
-       return ret;
+       ast_cdr_getvar(chan->cdr, args.variable, &ret, buf, len,
+                      ast_test_flag(&flags, OPT_RECURSIVE));
+
+       return 0;
 }
 
-static void cdr_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int cdr_write(struct ast_channel *chan, char *cmd, char *parse,
+                    const char *value)
 {
-       char *parse;
-       struct ast_flags flags = {0};
-
-       AST_DECLARE_APP_ARGS(args, 
-               AST_APP_ARG(variable);
-               AST_APP_ARG(options);
-       );      
+       struct ast_flags flags = { 0 };
+       AST_DECLARE_APP_ARGS(args,
+                            AST_APP_ARG(variable);
+                            AST_APP_ARG(options);
+       );
 
-       if (ast_strlen_zero(data) || !value)
-               return;
-       
-       if (!(parse = ast_strdupa(data)))
-               return;
+       if (ast_strlen_zero(parse) || !value)
+               return -1;
 
        AST_STANDARD_APP_ARGS(args, parse);
 
-       /* check for a trailing flags argument */
-       if(!ast_strlen_zero(args.options) ) {
+       if (!ast_strlen_zero(args.options))
                ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
-       }
 
        if (!strcasecmp(args.variable, "accountcode"))
                ast_cdr_setaccount(chan, value);
        else if (!strcasecmp(args.variable, "userfield"))
                ast_cdr_setuserfield(chan, value);
        else if (chan->cdr)
-               ast_cdr_setvar(chan->cdr, args.variable, value, (ast_test_flag(&flags,OPT_RECURSIVE) ) ? 1 : 0 );
+               ast_cdr_setvar(chan->cdr, args.variable, value,
+                              ast_test_flag(&flags, OPT_RECURSIVE));
+
+       return 0;
 }
 
 static struct ast_custom_function cdr_function = {
        .name = "CDR",
        .synopsis = "Gets or sets a CDR variable",
-       .desc= "Option 'r' searches the entire stack of CDRs on the channel\n",
+       .desc = "Option 'r' searches the entire stack of CDRs on the channel\n",
        .syntax = "CDR(<name>[|options])",
        .read = cdr_read,
        .write = cdr_write,
@@ -121,12 +115,12 @@ static char *tdesc = "CDR dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&cdr_function);
+       return ast_custom_function_unregister(&cdr_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&cdr_function);
+       return ast_custom_function_register(&cdr_function);
 }
 
 char *description(void)
@@ -143,11 +137,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
diff --git a/funcs/func_channel.c b/funcs/func_channel.c
new file mode 100644 (file)
index 0000000..82fbd63
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Channel info dialplan function
+ *
+ * \author Kevin P. Fleming <kpfleming@digium.com>
+ * 
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision:  $")
+#include "asterisk/module.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+#include "asterisk/logger.h"
+#include "asterisk/utils.h"
+#include "asterisk/app.h"
+#include "asterisk/indications.h"
+#include "asterisk/stringfields.h"
+#define locked_copy_string(chan, dest, source, len) \
+       do { \
+               ast_mutex_lock(&chan->lock); \
+               ast_copy_string(dest, source, len); \
+               ast_mutex_unlock(&chan->lock); \
+       } while (0)
+#define locked_string_field_set(chan, field, source) \
+       do { \
+               ast_mutex_lock(&chan->lock); \
+               ast_string_field_set(chan, field, source); \
+               ast_mutex_unlock(&chan->lock); \
+       } while (0)
+
+static int func_channel_read(struct ast_channel *chan, char *function,
+                            char *data, char *buf, size_t len)
+{
+       int ret = 0;
+
+       if (!strcasecmp(data, "audionativeformat"))
+               /* use the _multiple version when chan->nativeformats holds multiple formats */
+               /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_AUDIO_MASK); */
+               ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_AUDIO_MASK), len);
+       else if (!strcasecmp(data, "videonativeformat"))
+               /* use the _multiple version when chan->nativeformats holds multiple formats */
+               /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */
+               ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len);
+       else if (!strcasecmp(data, "audioreadformat"))
+               ast_copy_string(buf, ast_getformatname(chan->readformat), len);
+       else if (!strcasecmp(data, "audiowriteformat"))
+               ast_copy_string(buf, ast_getformatname(chan->writeformat), len);
+       else if (!strcasecmp(data, "tonezone") && chan->zone)
+               locked_copy_string(chan, buf, chan->zone->country, len);
+       else if (!strcasecmp(data, "language"))
+               locked_copy_string(chan, buf, chan->language, len);
+       else if (!strcasecmp(data, "musicclass"))
+               locked_copy_string(chan, buf, chan->musicclass, len);
+       else if (!chan->tech->func_channel_read
+                || chan->tech->func_channel_read(chan, function, data, buf, len)) {
+               ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
+               ret = -1;
+       }
+
+       return ret;
+}
+
+static int func_channel_write(struct ast_channel *chan, char *function,
+                             char *data, const char *value)
+{
+       int ret = 0;
+
+       if (!strcasecmp(data, "language"))
+               locked_string_field_set(chan, language, value);
+       else if (!strcasecmp(data, "musicclass"))
+               locked_string_field_set(chan, musicclass, value);
+       else if (!chan->tech->func_channel_write
+                || chan->tech->func_channel_write(chan, function, data, value)) {
+               ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
+                               data);
+               ret = -1;
+       }
+
+       return ret;
+}
+
+static struct ast_custom_function channel_function = {
+       .name = "CHANNEL",
+       .synopsis = "Gets/sets various pieces of information about the channel.",
+       .syntax = "CHANNEL(item)",
+       .desc = "Gets/set various pieces of information about the channel.\n"
+               "Standard items (provided by all channel technologies) are:\n"
+               "R/O    audioreadformat         format currently being read\n"
+               "R/O    audionativeformat       format used natively for audio\n"
+               "R/O    audiowriteformat        format currently being written\n"
+               "R/W    language                language for sounds played\n"
+               "R/W    musicclass              class (from musiconhold.conf) for hold music\n"
+               "R/O    tonezone                zone for indications played\n"
+               "R/O    videonativeformat       format used natively for video\n"
+               "\n"
+               "Additional items may be available from the channel driver providing\n"
+               "the channel; see its documentation for details.\n"
+               "\n"
+               "Any item requested that is not available on the current channel will\n"
+               "return an empty string.\n",
+       .read = func_channel_read,
+       .write = func_channel_write,
+};
+
+static char *tdesc = "Channel information dialplan function";
+
+int unload_module(void)
+{
+       return ast_custom_function_unregister(&channel_function);
+}
+
+int load_module(void)
+{
+       return ast_custom_function_register(&channel_function);
+}
+
+char *description(void)
+{
+       return tdesc;
+}
+
+int usecount(void)
+{
+       return 0;
+}
+
+char *key()
+{
+       return ASTERISK_GPL_KEY;
+}
index 7b3d2bf..c34b7d7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (c) 2003 Tilghman Lesher.  All rights reserved.
+ * Copyright (c) 2003-2006 Tilghman Lesher.  All rights reserved.
  *
  * Tilghman Lesher <app_cut__v003@the-tilghman.com>
  *
@@ -228,9 +228,10 @@ static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size
        return 0;
 }
 
-static char *acf_sort_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int acf_sort_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
        struct localuser *u;
+       int ret = -1;
 
        LOCAL_USER_ACF_ADD(u);
 
@@ -242,16 +243,19 @@ static char *acf_sort_exec(struct ast_channel *chan, char *cmd, char *data, char
                ast_log(LOG_ERROR, "Out of memory\n");
                break;
        case 0:
+               ret = 0;
                break;
        default:
                ast_log(LOG_ERROR, "Unknown internal error\n");
        }
        LOCAL_USER_REMOVE(u);
-       return buf;
+
+       return ret;
 }
 
-static char *acf_cut_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int acf_cut_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
+       int ret = -1;
        struct localuser *u;
 
        LOCAL_USER_ACF_ADD(u);
@@ -267,12 +271,14 @@ static char *acf_cut_exec(struct ast_channel *chan, char *cmd, char *data, char
                ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
                break;
        case 0:
+               ret = 0;
                break;
        default:
                ast_log(LOG_ERROR, "Unknown internal error\n");
        }
        LOCAL_USER_REMOVE(u);
-       return buf;
+
+       return ret;
 }
 
 struct ast_custom_function acf_sort = {
index efce117..a519fb0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2005, Russell Bryant <russelb@clemson.edu> 
+ * Copyright (C) 2005-2006, Russell Bryant <russelb@clemson.edu> 
  *
  * func_db.c adapted from the old app_db.c, copyright by the following people 
  * Copyright (C) 2005, Mark Spencer <markster@digium.com>
@@ -43,80 +43,69 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/astdb.h"
 
-static char *function_db_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_db_read(struct ast_channel *chan, char *cmd,
+                           char *parse, char *buf, size_t len)
 {
-       char *parse;    
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(family);
-               AST_APP_ARG(key);
+                            AST_APP_ARG(family);
+                            AST_APP_ARG(key);
        );
 
-       if (ast_strlen_zero(data)) {
+       buf[0] = '\0';
+
+       if (ast_strlen_zero(parse)) {
                ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
-               buf[0] = '\0';
-               return buf;
+               return -1;
        }
 
-       parse = ast_strdupa(data);
-       if (!parse) {
-               ast_log(LOG_ERROR, "Out of memory!\n");
-               buf[0] = '\0';
-               return buf;
-       }
-               
        AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-       
+
        if (args.argc < 2) {
                ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
-               buf[0] = '\0';
-               return buf;
+               return -1;
        }
 
-       if (ast_db_get(args.family, args.key, buf, len-1)) {
-               ast_log(LOG_DEBUG, "DB: %s/%s not found in database.\n", args.family, args.key);
+       if (ast_db_get(args.family, args.key, buf, len - 1)) {
+               ast_log(LOG_DEBUG, "DB: %s/%s not found in database.\n", args.family,
+                               args.key);
        } else
                pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
 
-       
-       return buf;
+       return 0;
 }
 
-static void function_db_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int function_db_write(struct ast_channel *chan, char *cmd, char *parse,
+                            const char *value)
 {
-       char *parse;    
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(family);
-               AST_APP_ARG(key);
+                            AST_APP_ARG(family);
+                            AST_APP_ARG(key);
        );
 
-       if (ast_strlen_zero(data)) {
+       if (ast_strlen_zero(parse)) {
                ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=<value>\n");
-               return;
-       }
-
-       parse = ast_strdupa(data);
-       if (!parse) { 
-               ast_log(LOG_ERROR, "Out of memory!\n"); 
-               return;
+               return -1;
        }
 
        AST_NONSTANDARD_APP_ARGS(args, parse, '/');
 
        if (args.argc < 2) {
                ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=value\n");
-               return;
+               return -1;
        }
 
-       if (ast_db_put(args.family, args.key, (char*)value)) {
+       if (ast_db_put(args.family, args.key, (char *) value))
                ast_log(LOG_WARNING, "DB: Error writing value to database.\n");
-       }
+
+       return 0;
 }
 
 static struct ast_custom_function db_function = {
        .name = "DB",
        .synopsis = "Read or Write from/to the Asterisk database",
        .syntax = "DB(<family>/<key>)",
-       .desc = "This function will read or write a value from/to the Asterisk database.\n"
+       .desc =
+               "This function will read or write a value from/to the Asterisk database.\n"
                "DB(...) will read a value from the database, while DB(...)=value\n"
                "will write a value to the database.  On a read, this function\n"
                "returns the value from the datase, or NULL if it does not exist.\n"
@@ -126,50 +115,44 @@ static struct ast_custom_function db_function = {
        .write = function_db_write,
 };
 
-static char *function_db_exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_db_exists(struct ast_channel *chan, char *cmd,
+                             char *parse, char *buf, size_t len)
 {
-       char *parse;    
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(family);
-               AST_APP_ARG(key);
+                            AST_APP_ARG(family);
+                            AST_APP_ARG(key);
        );
 
-       if (ast_strlen_zero(data)) {
+       buf[0] = '\0';
+
+       if (ast_strlen_zero(parse)) {
                ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
-               buf[0] = '\0';
-               return buf;
+               return -1;
        }
 
-       parse = ast_strdupa(data);
-       if (!parse) {
-               ast_log(LOG_ERROR, "Out of memory!\n");
-               buf[0] = '\0';
-               return buf;
-       }
-               
        AST_NONSTANDARD_APP_ARGS(args, parse, '/');
-       
+
        if (args.argc < 2) {
                ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
-               buf[0] = '\0';
-               return buf;
+               return -1;
        }
 
-       if (ast_db_get(args.family, args.key, buf, len-1))
-               ast_copy_string(buf, "0", len); 
+       if (ast_db_get(args.family, args.key, buf, len - 1))
+               strcpy(buf, "0");
        else {
                pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
-               ast_copy_string(buf, "1", len);
+               strcpy(buf, "1");
        }
-       
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function db_exists_function = {
        .name = "DB_EXISTS",
        .synopsis = "Check to see if a key exists in the Asterisk database",
        .syntax = "DB_EXISTS(<family>/<key>)",
-       .desc = "This function will check to see if a key exists in the Asterisk\n"
+       .desc =
+               "This function will check to see if a key exists in the Asterisk\n"
                "database. If it exists, the function will return \"1\". If not,\n"
                "it will return \"0\".  Checking for existence of a database key will\n"
                "also set the variable DB_RESULT to the key's value if it exists.\n",
@@ -181,7 +164,7 @@ static char *tdesc = "Database (astdb) related dialplan functions";
 int unload_module(void)
 {
        int res = 0;
-       
+
        res |= ast_custom_function_unregister(&db_function);
        res |= ast_custom_function_unregister(&db_exists_function);
 
@@ -191,7 +174,7 @@ int unload_module(void)
 int load_module(void)
 {
        int res = 0;
-       
+
        res |= ast_custom_function_register(&db_function);
        res |= ast_custom_function_register(&db_exists_function);
 
@@ -200,7 +183,7 @@ int load_module(void)
 
 char *description(void)
 {
-       return tdesc;
+       return tdesc;
 }
 
 int usecount(void)
@@ -210,6 +193,5 @@ int usecount(void)
 
 char *key()
 {
-       return ASTERISK_GPL_KEY;
+       return ASTERISK_GPL_KEY;
 }
-
index 8a063be..2326440 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005
+ * Copyright (C) 1999 - 2006
  *
  * Mark Spencer <markster@digium.com>
  * Oleksiy Krivoshey <oleksiyk@gmail.com>
@@ -40,124 +40,100 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/channel.h"
 #include "asterisk/pbx.h"
 #include "asterisk/utils.h"
-
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
-
 #include "asterisk/pbx.h"
 #include "asterisk/options.h"
-
 #include "asterisk/enum.h"
+#include "asterisk/app.h"
 
-static char* synopsis = "Syntax: ENUMLOOKUP(number[,Method-type[,options|record#[,zone-suffix]]])\n";
+ static char *synopsis = "Syntax: ENUMLOOKUP(number[|Method-type[|options[|record#[|zone-suffix]]]])\n";
 
 STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
-static char *function_enum(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_enum(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
-       int res=0;
-       char tech[80];
-       char dest[80] = "";
-       char *zone;
-       char *options;
-       struct localuser *u;
-       char *params[4];
-       char *p = data;
-       char *s;
-       int i = 0;
-
-
-       if (ast_strlen_zero(data)) {
-               ast_log(LOG_WARNING, synopsis);
-               return "";
-       }
-
-       do {
-               if(i>3){
-                       ast_log(LOG_WARNING, synopsis);
-                       return "";
-               }
-               params[i++] = p;
-               p = strchr(p, '|');
-               if(p){
-                       *p = '\0';
-                       p++;
-               }
-       } while(p);
-
-       if(i < 1){
-               ast_log(LOG_WARNING, synopsis);
-               return "";
-       }
-
-       if( (i > 1 && strlen(params[1]) == 0) || i < 2){
-               ast_copy_string(tech, "sip", sizeof(tech));
-       } else {
-               ast_copy_string(tech, params[1], sizeof(tech));
-       }
-
-       if( (i > 3 && strlen(params[3]) == 0) || i<4){
-               zone = "e164.arpa";
-       } else {
-               zone = params[3];
-       }
-
-       if( (i > 2 && strlen(params[2]) == 0) || i<3){
-               options = "1";
-       } else {
-               options = params[2];
-       }
-
-       /* strip any '-' signs from number */
-       p = params[0];
-       /*
-       while(*p == '+'){
-               p++;
-       }
-       */
-       s = p;
-       i = 0;
-       while(*p && *s){
-               if(*s == '-'){
-                       s++;
-               } else {
-                       p[i++] = *s++;
-               }
-       }
-       p[i] = 0;
-
-       LOCAL_USER_ACF_ADD(u);
-
-       res = ast_get_enum(chan, p, dest, sizeof(dest), tech, sizeof(tech), zone, options);
-
-       LOCAL_USER_REMOVE(u);
-
-       p = strchr(dest, ':');
-       if(p && strncasecmp(tech, "ALL", sizeof(tech))) {
-               ast_copy_string(buf, p+1, sizeof(dest));
-       } else {
-               ast_copy_string(buf, dest, sizeof(dest));
-       }
-
-       return buf;
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(number);
+               AST_APP_ARG(tech);
+               AST_APP_ARG(options);
+               AST_APP_ARG(record);
+               AST_APP_ARG(zone);
+       );
+       int res = 0;
+       char tech[80];
+       char dest[80] = "";
+       char *zone;
+       char *options;
+       struct localuser *u;
+       char *s, *p;
+
+       buf[0] = '\0';
+
+       if (ast_strlen_zero(data)) {
+               ast_log(LOG_WARNING, synopsis);
+               return -1;
+       }
+
+       AST_STANDARD_APP_ARGS(args, data);
+
+       if (args.argc < 1) {
+               ast_log(LOG_WARNING, synopsis);
+               return -1;
+       }
+
+       ast_copy_string(tech, args.tech ? args.tech : "sip", sizeof(tech));
+
+       if (!args.zone)
+               args.zone = "e164.arpa";
+
+       if (!args.options)
+               args.options = "1";
+
+       /* strip any '-' signs from number */
+       for (p = args.number, s = p; *s; *s++) {
+               if (*s != '-')
+                       *p++ = *s;
+       }
+       *p = '\0';
+
+       LOCAL_USER_ACF_ADD(u);
+
+       res = ast_get_enum(chan, p, dest, sizeof(dest), tech, sizeof(tech), zone,
+                          options);
+
+       LOCAL_USER_REMOVE(u);
+
+       p = strchr(dest, ':');
+       if (p && strcasecmp(tech, "ALL"))
+               ast_copy_string(buf, p + 1, len);
+       else
+               ast_copy_string(buf, dest, len);
+
+       return 0;
 }
 
 static struct ast_custom_function enum_function = {
-       .name = "ENUMLOOKUP",
-       .synopsis = "ENUMLOOKUP allows for general or specific querying of NAPTR records"
-       " or counts of NAPTR types for ENUM or ENUM-like DNS pointers",
-       .syntax = "ENUMLOOKUP(number[,Method-type[,options|record#[,zone-suffix]]])",
-       .desc = "Option 'c' returns an integer count of the number of NAPTRs of a certain RR type.\n"
-       "Combination of 'c' and Method-type of 'ALL' will return a count of all NAPTRs for the record.\n"
-       "Defaults are: Method-type=sip, no options, record=1, zone-suffix=e164.arpa\n\n"
-       "For more information, see README.enum",
-       .read = function_enum,
+       .name = "ENUMLOOKUP",
+       .synopsis =
+               "ENUMLOOKUP allows for general or specific querying of NAPTR records"
+               " or counts of NAPTR types for ENUM or ENUM-like DNS pointers",
+       .syntax =
+               "ENUMLOOKUP(number[|Method-type[|options[|record#[|zone-suffix]]]])",
+       .desc =
+               "Option 'c' returns an integer count of the number of NAPTRs of a certain RR type.\n"
+               "Combination of 'c' and Method-type of 'ALL' will return a count of all NAPTRs for the record.\n"
+               "Defaults are: Method-type=sip, no options, record=1, zone-suffix=e164.arpa\n\n"
+               "For more information, see README.enum",
+       .read = function_enum,
 };
 
-static char *function_txtcidname(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_txtcidname(struct ast_channel *chan, char *cmd,
+                              char *data, char *buf, size_t len)
 {
        int res;
        char tech[80];
@@ -165,34 +141,36 @@ static char *function_txtcidname(struct ast_channel *chan, char *cmd, char *data
        char dest[80];
        struct localuser *u;
 
-       LOCAL_USER_ACF_ADD(u);
-
        buf[0] = '\0';
 
+       LOCAL_USER_ACF_ADD(u);
+
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "TXTCIDNAME requires an argument (number)\n");
                LOCAL_USER_REMOVE(u);
-               return buf;     
+               return -1;
        }
 
-       res = ast_get_txt(chan, data, dest, sizeof(dest), tech, sizeof(tech), txt, sizeof(txt));
-       
+       res = ast_get_txt(chan, data, dest, sizeof(dest), tech, sizeof(tech), txt,
+                         sizeof(txt));
+
        if (!ast_strlen_zero(txt))
                ast_copy_string(buf, txt, len);
-       
+
        LOCAL_USER_REMOVE(u);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function txtcidname_function = {
-       .name = "TXTCIDNAME",
-       .synopsis = "TXTCIDNAME looks up a caller name via DNS",
-       .syntax = "TXTCIDNAME(<number>)",
-       .desc = "This function looks up the given phone number in DNS to retrieve\n"
-       "the caller id name.  The result will either be blank or be the value\n"
-       "found in the TXT record in DNS.\n",
-       .read = function_txtcidname,
+       .name = "TXTCIDNAME",
+       .synopsis = "TXTCIDNAME looks up a caller name via DNS",
+       .syntax = "TXTCIDNAME(<number>)",
+       .desc =
+               "This function looks up the given phone number in DNS to retrieve\n"
+               "the caller id name.  The result will either be blank or be the value\n"
+               "found in the TXT record in DNS.\n",
+       .read = function_txtcidname,
 };
 
 static char *tdesc = "ENUM related dialplan functions";
@@ -200,19 +178,19 @@ static char *tdesc = "ENUM related dialplan functions";
 int unload_module(void)
 {
        int res = 0;
-       
+
        res |= ast_custom_function_unregister(&enum_function);
        res |= ast_custom_function_unregister(&txtcidname_function);
 
        STANDARD_HANGUP_LOCALUSERS;
-       
+
        return res;
 }
 
 int load_module(void)
 {
        int res = 0;
-       
+
        res |= ast_custom_function_register(&enum_function);
        res |= ast_custom_function_register(&txtcidname_function);
 
@@ -221,13 +199,13 @@ int load_module(void)
 
 char *description(void)
 {
-       return tdesc;
+       return tdesc;
 }
 
 int usecount(void)
 {
        int res;
-       
+
        STANDARD_USECOUNT(res);
 
        return res;
@@ -235,6 +213,5 @@ int usecount(void)
 
 char *key()
 {
-       return ASTERISK_GPL_KEY;
+       return ASTERISK_GPL_KEY;
 }
-
index f9d1a66..87bd96f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -37,21 +37,24 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *env_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int env_read(struct ast_channel *chan, char *cmd, char *data,
+                   char *buf, size_t len)
 {
-       char *ret = "";
+       char *ret = NULL;
 
-       if (data) {
+       *buf = '\0';
+
+       if (data)
                ret = getenv(data);
-               if (!ret)
-                       ret = "";
-       }
-       ast_copy_string(buf, ret, len);
 
-       return buf;
+       if (ret)
+               ast_copy_string(buf, ret, len);
+
+       return 0;
 }
 
-static void env_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int env_write(struct ast_channel *chan, char *cmd, char *data,
+                    const char *value)
 {
        if (!ast_strlen_zero(data)) {
                if (!ast_strlen_zero(value)) {
@@ -60,29 +63,28 @@ static void env_write(struct ast_channel *chan, char *cmd, char *data, const cha
                        unsetenv(data);
                }
        }
+
+       return 0;
 }
 
-static char *stat_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int stat_read(struct ast_channel *chan, char *cmd, char *data,
+                    char *buf, size_t len)
 {
        char *action;
        struct stat s;
 
-       ast_copy_string(buf, "0", len);
-       if (!data) {
-               ast_log(LOG_ERROR, "Out of memory\n");
-               return buf;
-       }
+       *buf = '\0';
 
        action = strsep(&data, "|");
        if (stat(data, &s)) {
-               return buf;
+               return -1;
        } else {
                switch (*action) {
                case 'e':
-                       ast_copy_string(buf, "1", len);
+                       strcpy(buf, "1");
                        break;
                case 's':
-                       snprintf(buf, len, "%d", (unsigned int)s.st_size);
+                       snprintf(buf, len, "%d", (unsigned int) s.st_size);
                        break;
                case 'f':
                        snprintf(buf, len, "%d", S_ISREG(s.st_mode) ? 1 : 0);
@@ -91,20 +93,21 @@ static char *stat_read(struct ast_channel *chan, char *cmd, char *data, char *bu
                        snprintf(buf, len, "%d", S_ISDIR(s.st_mode) ? 1 : 0);
                        break;
                case 'M':
-                       snprintf(buf, len, "%d", (int)s.st_mtime);
+                       snprintf(buf, len, "%d", (int) s.st_mtime);
                        break;
                case 'A':
-                       snprintf(buf, len, "%d", (int)s.st_mtime);
+                       snprintf(buf, len, "%d", (int) s.st_mtime);
                        break;
                case 'C':
-                       snprintf(buf, len, "%d", (int)s.st_ctime);
+                       snprintf(buf, len, "%d", (int) s.st_ctime);
                        break;
                case 'm':
-                       snprintf(buf, len, "%o", (int)s.st_mode);
+                       snprintf(buf, len, "%o", (int) s.st_mode);
                        break;
                }
        }
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function env_function = {
@@ -121,15 +124,15 @@ static struct ast_custom_function stat_function = {
        .syntax = "STAT(<flag>,<filename>)",
        .read = stat_read,
        .desc =
-"flag may be one of the following:\n"
-"  d - Checks if the file is a directory\n"
-"  e - Checks if the file exists\n"
-"  f - Checks if the file is a regular file\n"
-"  m - Returns the file mode (in octal)\n"
-"  s - Returns the size (in bytes) of the file\n"
-"  A - Returns the epoch at which the file was last accessed\n"
-"  C - Returns the epoch at which the inode was last changed\n"
-"  M - Returns the epoch at which the file was last modified\n",
+               "flag may be one of the following:\n"
+               "  d - Checks if the file is a directory\n"
+               "  e - Checks if the file exists\n"
+               "  f - Checks if the file is a regular file\n"
+               "  m - Returns the file mode (in octal)\n"
+               "  s - Returns the size (in bytes) of the file\n"
+               "  A - Returns the epoch at which the file was last accessed\n"
+               "  C - Returns the epoch at which the inode was last changed\n"
+               "  M - Returns the epoch at which the file was last modified\n",
 };
 
 
@@ -169,11 +172,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index a4a1330..deb2954 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -36,70 +36,81 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *group_count_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int group_count_function_read(struct ast_channel *chan, char *cmd,
+                                    char *data, char *buf, size_t len)
 {
        int count;
        char group[80] = "";
        char category[80] = "";
        const char *grp;
 
-       ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
+       ast_app_group_split_group(data, group, sizeof(group), category,
+                                 sizeof(category));
 
        if (ast_strlen_zero(group)) {
                if ((grp = pbx_builtin_getvar_helper(chan, category)))
                        ast_copy_string(group, grp, sizeof(group));
                else
-                       ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);  
+                       ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n",
+                               chan->name);
        }
 
        count = ast_app_group_get_count(group, category);
        snprintf(buf, len, "%d", count);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function group_count_function = {
        .name = "GROUP_COUNT",
        .syntax = "GROUP_COUNT([groupname][@category])",
        .synopsis = "Counts the number of channels in the specified group",
-       .desc = "Calculates the group count for the specified group, or uses the\n"
-       "channel's current group if not specifed (and non-empty).\n",
+       .desc =
+               "Calculates the group count for the specified group, or uses the\n"
+               "channel's current group if not specifed (and non-empty).\n",
        .read = group_count_function_read,
 };
 
-static char *group_match_count_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int group_match_count_function_read(struct ast_channel *chan,
+                                          char *cmd, char *data, char *buf,
+                                          size_t len)
 {
        int count;
        char group[80] = "";
        char category[80] = "";
 
-       ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
+       ast_app_group_split_group(data, group, sizeof(group), category,
+                                 sizeof(category));
 
        if (!ast_strlen_zero(group)) {
                count = ast_app_group_match_get_count(group, category);
                snprintf(buf, len, "%d", count);
        }
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function group_match_count_function = {
        .name = "GROUP_MATCH_COUNT",
        .syntax = "GROUP_MATCH_COUNT(groupmatch[@category])",
-       .synopsis = "Counts the number of channels in the groups matching the specified pattern",
-       .desc = "Calculates the group count for all groups that match the specified pattern.\n"
-       "Uses standard regular expression matching (see regex(7)).\n",
+       .synopsis =
+               "Counts the number of channels in the groups matching the specified pattern",
+       .desc =
+               "Calculates the group count for all groups that match the specified pattern.\n"
+               "Uses standard regular expression matching (see regex(7)).\n",
        .read = group_match_count_function_read,
        .write = NULL,
 };
 
-static char *group_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int group_function_read(struct ast_channel *chan, char *cmd,
+                              char *data, char *buf, size_t len)
 {
        char varname[256];
        const char *group;
 
        if (!ast_strlen_zero(data)) {
-               snprintf(varname, sizeof(varname), "%s_%s", GROUP_CATEGORY_PREFIX, data);
+               snprintf(varname, sizeof(varname), "%s_%s", GROUP_CATEGORY_PREFIX,
+                        data);
        } else {
                ast_copy_string(varname, GROUP_CATEGORY_PREFIX, sizeof(varname));
        }
@@ -108,10 +119,11 @@ static char *group_function_read(struct ast_channel *chan, char *cmd, char *data
        if (group)
                ast_copy_string(buf, group, len);
 
-       return buf;
+       return 0;
 }
 
-static void group_function_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
+static int group_function_write(struct ast_channel *chan, char *cmd,
+                               char *data, const char *value)
 {
        char grpcat[256];
 
@@ -121,8 +133,11 @@ static void group_function_write(struct ast_channel *chan, char *cmd, char *data
                ast_copy_string(grpcat, value, sizeof(grpcat));
        }
 
-        if (ast_app_group_set_channel(chan, grpcat))
-                ast_log(LOG_WARNING, "Setting a group requires an argument (group name)\n");
+       if (ast_app_group_set_channel(chan, grpcat))
+               ast_log(LOG_WARNING,
+                               "Setting a group requires an argument (group name)\n");
+
+       return 0;
 }
 
 static struct ast_custom_function group_function = {
@@ -134,33 +149,41 @@ static struct ast_custom_function group_function = {
        .write = group_function_write,
 };
 
-static char *group_list_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int group_list_function_read(struct ast_channel *chan, char *cmd,
+                                   char *data, char *buf, size_t len)
 {
        struct ast_var_t *current;
        struct varshead *headp;
        char tmp1[1024] = "";
        char tmp2[1024] = "";
 
-       headp=&chan->varshead;
-       AST_LIST_TRAVERSE(headp,current,entries) {
+       headp = &chan->varshead;
+       AST_LIST_TRAVERSE(headp, current, entries) {
                if (!strncmp(ast_var_name(current), GROUP_CATEGORY_PREFIX "_", strlen(GROUP_CATEGORY_PREFIX) + 1)) {
                        if (!ast_strlen_zero(tmp1)) {
                                ast_copy_string(tmp2, tmp1, sizeof(tmp2));
-                               snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, ast_var_value(current), (ast_var_name(current) + strlen(GROUP_CATEGORY_PREFIX) + 1));
+                               snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2,
+                                        ast_var_value(current),
+                                        (ast_var_name(current) +
+                                         strlen(GROUP_CATEGORY_PREFIX) + 1));
                        } else {
-                               snprintf(tmp1, sizeof(tmp1), "%s@%s", ast_var_value(current), (ast_var_name(current) + strlen(GROUP_CATEGORY_PREFIX) + 1));
+                               snprintf(tmp1, sizeof(tmp1), "%s@%s", ast_var_value(current),
+                                        (ast_var_name(current) +
+                                         strlen(GROUP_CATEGORY_PREFIX) + 1));
                        }
                } else if (!strcmp(ast_var_name(current), GROUP_CATEGORY_PREFIX)) {
                        if (!ast_strlen_zero(tmp1)) {
                                ast_copy_string(tmp2, tmp1, sizeof(tmp2));
-                               snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, ast_var_value(current));
+                               snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2,
+                                        ast_var_value(current));
                        } else {
                                snprintf(tmp1, sizeof(tmp1), "%s", ast_var_value(current));
                        }
                }
        }
        ast_copy_string(buf, tmp1, len);
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function group_list_function = {
@@ -212,11 +235,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index f6bc1a4..05835d6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -36,31 +36,42 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/stringfields.h"
 
-static char *language_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int depwarning = 0;
+
+static int language_read(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
+       if (!depwarning) {
+               depwarning = 1;
+               ast_log(LOG_WARNING,
+                               "LANGUAGE() is deprecated; use CHANNEL(language) instead.\n");
+       }
+
        ast_copy_string(buf, chan->language, len);
 
-       return buf;
+       return 0;
 }
 
-static void language_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int language_write(struct ast_channel *chan, char *cmd, char *data,
+                         const char *value)
 {
+       if (!depwarning) {
+               depwarning = 1;
+               ast_log(LOG_WARNING,
+                               "LANGUAGE() is deprecated; use CHANNEL(language) instead.\n");
+       }
+
        if (value)
-                ast_string_field_set(chan, language, value);
+               ast_string_field_set(chan, language, value);
+
+       return 0;
 }
 
 static struct ast_custom_function language_function = {
        .name = "LANGUAGE",
        .synopsis = "Gets or sets the channel's language.",
        .syntax = "LANGUAGE()",
-       .desc = "Gets or sets the channel language.  This information is used for the\n"
-       "syntax in generation of numbers, and to choose a natural language file\n"
-       "when available.  For example, if language is set to 'fr' and the file\n"
-       "'demo-congrats' is requested to be played, if the file\n"
-       "'fr/demo-congrats' exists, then it will play that file, and if not\n"
-       "will play the normal 'demo-congrats'.  For some language codes,\n"
-       "changing the language also changes the syntax of some Asterisk\n"
-       "functions, like SayNumber.\n",
+       .desc = "Deprecated. Use CHANNEL(language) instead.\n",
        .read = language_read,
        .write = language_write,
 };
@@ -69,12 +80,12 @@ static char *tdesc = "Channel language dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&language_function);
+       return ast_custom_function_unregister(&language_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&language_function);
+       return ast_custom_function_register(&language_function);
 }
 
 char *description(void)
@@ -91,11 +102,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index b3c7eb2..50712b8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  * Portions Copyright (C) 2005, Anthony Minessale II
  *
  * See http://www.asterisk.org for more information about
@@ -37,40 +37,44 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *isnull(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int isnull(struct ast_channel *chan, char *cmd, char *data,
+                 char *buf, size_t len)
 {
-       return data && *data ? "0" : "1";
+       strcpy(buf, data && *data ? "0" : "1");
+
+       return 0;
 }
 
-static char *exists(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int exists(struct ast_channel *chan, char *cmd, char *data, char *buf,
+                 size_t len)
 {
-       return data && *data ? "1" : "0";
+       strcpy(buf, data && *data ? "1" : "0");
+
+       return 0;
 }
 
-static char *iftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int iftime(struct ast_channel *chan, char *cmd, char *data, char *buf,
+                 size_t len)
 {
        struct ast_timing timing;
-       char *ret;
        char *expr;
        char *iftrue;
        char *iffalse;
 
-       if (!(data = ast_strdupa(data)))
-               return NULL;
-
        data = ast_strip_quoted(data, "\"", "\"");
        expr = strsep(&data, "?");
        iftrue = strsep(&data, ":");
        iffalse = data;
 
        if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
-               ast_log(LOG_WARNING, "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
-               return NULL;
+               ast_log(LOG_WARNING,
+                               "Syntax IFTIME(<timespec>?[<true>][:<false>])\n");
+               return -1;
        }
 
        if (!ast_build_timing(&timing, expr)) {
                ast_log(LOG_WARNING, "Invalid Time Spec.\n");
-               return NULL;
+               return -1;
        }
 
        if (iftrue)
@@ -78,24 +82,18 @@ static char *iftime(struct ast_channel *chan, char *cmd, char *data, char *buf,
        if (iffalse)
                iffalse = ast_strip_quoted(iffalse, "\"", "\"");
 
-       if ((ret = ast_check_timing(&timing) ? iftrue : iffalse)) {
-               ast_copy_string(buf, ret, len);
-               ret = buf;
-       } 
-       
-       return ret;
+       ast_copy_string(buf, ast_check_timing(&timing) ? iftrue : iffalse, len);
+
+       return 0;
 }
 
-static char *acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
+                 size_t len)
 {
-       char *ret;
        char *expr;
        char *iftrue;
        char *iffalse;
 
-       if (!(data = ast_strdupa(data)))
-               return NULL;
-
        data = ast_strip_quoted(data, "\"", "\"");
        expr = strsep(&data, "?");
        iftrue = strsep(&data, ":");
@@ -103,7 +101,7 @@ static char *acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
 
        if (ast_strlen_zero(expr) || !(iftrue || iffalse)) {
                ast_log(LOG_WARNING, "Syntax IF(<expr>?[<true>][:<false>])\n");
-               return NULL;
+               return -1;
        }
 
        expr = ast_strip(expr);
@@ -112,28 +110,23 @@ static char *acf_if(struct ast_channel *chan, char *cmd, char *data, char *buf,
        if (iffalse)
                iffalse = ast_strip_quoted(iffalse, "\"", "\"");
 
-       if ((ret = ast_true(expr) ? iftrue : iffalse)) {
-               ast_copy_string(buf, ret, len);
-               ret = buf;
-       } 
-       
-       return ret;
+       ast_copy_string(buf, ast_true(expr) ? iftrue : iffalse, len);
+
+       return 0;
 }
 
-static char *set(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int set(struct ast_channel *chan, char *cmd, char *data, char *buf,
+              size_t len)
 {
        char *varname;
        char *val;
 
-       if (!(data = ast_strdupa(data)))
-               return NULL;
-
        varname = strsep(&data, "=");
        val = data;
 
        if (ast_strlen_zero(varname) || !val) {
                ast_log(LOG_WARNING, "Syntax SET(<varname>=[<value>])\n");
-               return NULL;
+               return -1;
        }
 
        varname = ast_strip(varname);
@@ -141,7 +134,7 @@ static char *set(struct ast_channel *chan, char *cmd, char *data, char *buf, siz
        pbx_builtin_setvar_helper(chan, varname, val);
        ast_copy_string(buf, val, len);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function isnull_function = {
@@ -167,14 +160,16 @@ static struct ast_custom_function exists_function = {
 
 static struct ast_custom_function if_function = {
        .name = "IF",
-       .synopsis = "Conditional: Returns the data following '?' if true else the data following ':'",
+       .synopsis =
+               "Conditional: Returns the data following '?' if true else the data following ':'",
        .syntax = "IF(<expr>?[<true>][:<false>])",
        .read = acf_if,
 };
 
 static struct ast_custom_function if_time_function = {
        .name = "IFTIME",
-       .synopsis = "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
+       .synopsis =
+               "Temporal Conditional: Returns the data following '?' if true else the data following ':'",
        .syntax = "IFTIME(<timespec>?[<true>][:<false>])",
        .read = iftime,
 };
index 4ae6249..7ad4765 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2004 - 2005, Andy Powell 
+ * Copyright (C) 2004 - 2006, Andy Powell 
  *
  * Updated by Mark Spencer <markster@digium.com>
  *
@@ -18,7 +18,7 @@
 
 /*! \file
  *
- * \brief Maths relatad dialplan functions
+ * \brief Math related dialplan function
  *
  * \author Andy Powell
  * \author Mark Spencer <markster@digium.com>
@@ -41,65 +41,55 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/config.h"
 
-enum TypeOfFunctions
-{
-    ADDFUNCTION,
-    DIVIDEFUNCTION,
-    MULTIPLYFUNCTION,
-    SUBTRACTFUNCTION,
-    MODULUSFUNCTION,
-    GTFUNCTION,
-    LTFUNCTION,
-    GTEFUNCTION,
-    LTEFUNCTION,
-    EQFUNCTION
+enum TypeOfFunctions {
+       ADDFUNCTION,
+       DIVIDEFUNCTION,
+       MULTIPLYFUNCTION,
+       SUBTRACTFUNCTION,
+       MODULUSFUNCTION,
+       GTFUNCTION,
+       LTFUNCTION,
+       GTEFUNCTION,
+       LTEFUNCTION,
+       EQFUNCTION
 };
 
-enum TypeOfResult
-{
-    FLOAT_RESULT,
-    INT_RESULT,
-    HEX_RESULT,
-    CHAR_RESULT
+enum TypeOfResult {
+       FLOAT_RESULT,
+       INT_RESULT,
+       HEX_RESULT,
+       CHAR_RESULT
 };
 
-
-static char *math(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int math(struct ast_channel *chan, char *cmd, char *parse,
+               char *buf, size_t len)
 {
        float fnum1;
        float fnum2;
        float ftmp = 0;
        char *op;
-       int iaction=-1;
-       int type_of_result=FLOAT_RESULT;
-       char *parse;
-       
-       /* dunno, big calulations :D */
-       char user_result[30];
-
-       char *mvalue1, *mvalue2=NULL, *mtype_of_result;
-       
+       int iaction = -1;
+       int type_of_result = FLOAT_RESULT;
+       char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(argv0);
-               AST_APP_ARG(argv1);
+                            AST_APP_ARG(argv0);
+                            AST_APP_ARG(argv1);
        );
-       if (ast_strlen_zero(data)) {
+
+       if (ast_strlen_zero(parse)) {
                ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       if (!(parse = ast_strdupa(data)))
-               return NULL;
-
        AST_STANDARD_APP_ARGS(args, parse);
-       
+
        if (args.argc < 1) {
                ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
        mvalue1 = args.argv0;
-       
+
        if ((op = strchr(mvalue1, '+'))) {
                iaction = ADDFUNCTION;
                *op = '\0';
@@ -118,123 +108,127 @@ static char *math(struct ast_channel *chan, char *cmd, char *data, char *buf, si
        } else if ((op = strchr(mvalue1, '>'))) {
                iaction = GTFUNCTION;
                *op = '\0';
-               if (*(op+1) == '=') {
+               if (*(op + 1) == '=') {
                        *++op = '\0';
                        iaction = GTEFUNCTION;
                }
        } else if ((op = strchr(mvalue1, '<'))) {
                iaction = LTFUNCTION;
                *op = '\0';
-               if (*(op+1) == '=') {
+               if (*(op + 1) == '=') {
                        *++op = '\0';
                        iaction = LTEFUNCTION;
                }
        } else if ((op = strchr(mvalue1, '='))) {
                iaction = GTFUNCTION;
                *op = '\0';
-               if (*(op+1) == '=') {
+               if (*(op + 1) == '=') {
                        *++op = '\0';
                        iaction = EQFUNCTION;
                } else
                        op = NULL;
-       } 
-       
-       if (op) 
+       }
+
+       if (op)
                mvalue2 = op + 1;
 
        /* detect wanted type of result */
        mtype_of_result = args.argv1;
-       if (mtype_of_result)
-       {
-               if (!strcasecmp(mtype_of_result,"float") || !strcasecmp(mtype_of_result,"f"))
-                       type_of_result=FLOAT_RESULT;
-               else if (!strcasecmp(mtype_of_result,"int") || !strcasecmp(mtype_of_result,"i"))
-                       type_of_result=INT_RESULT;
-               else if (!strcasecmp(mtype_of_result,"hex") || !strcasecmp(mtype_of_result,"h"))
-                       type_of_result=HEX_RESULT;
-               else if (!strcasecmp(mtype_of_result,"char") || !strcasecmp(mtype_of_result,"c"))
-                       type_of_result=CHAR_RESULT;
-               else
-               {
-                       ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n", mtype_of_result);
-                       return NULL;
+       if (mtype_of_result) {
+               if (!strcasecmp(mtype_of_result, "float")
+                   || !strcasecmp(mtype_of_result, "f"))
+                       type_of_result = FLOAT_RESULT;
+               else if (!strcasecmp(mtype_of_result, "int")
+                        || !strcasecmp(mtype_of_result, "i"))
+                       type_of_result = INT_RESULT;
+               else if (!strcasecmp(mtype_of_result, "hex")
+                        || !strcasecmp(mtype_of_result, "h"))
+                       type_of_result = HEX_RESULT;
+               else if (!strcasecmp(mtype_of_result, "char")
+                        || !strcasecmp(mtype_of_result, "c"))
+                       type_of_result = CHAR_RESULT;
+               else {
+                       ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
+                                       mtype_of_result);
+                       return -1;
                }
        }
-       
+
        if (!mvalue1 || !mvalue2) {
-               ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n");
-               return NULL;
+               ast_log(LOG_WARNING,
+                               "Supply all the parameters - just this once, please\n");
+               return -1;
        }
 
        if (sscanf(mvalue1, "%f", &fnum1) != 1) {
                ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
-               return NULL;
+               return -1;
        }
 
        if (sscanf(mvalue2, "%f", &fnum2) != 1) {
                ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
-               return NULL;
+               return -1;
        }
 
        switch (iaction) {
-       case ADDFUNCTION :
+       case ADDFUNCTION:
                ftmp = fnum1 + fnum2;
                break;
-       case DIVIDEFUNCTION :
+       case DIVIDEFUNCTION:
                if (fnum2 <= 0)
-                       ftmp = 0; /* can't do a divide by 0 */
+                       ftmp = 0;                       /* can't do a divide by 0 */
                else
                        ftmp = (fnum1 / fnum2);
                break;
-       case MULTIPLYFUNCTION :
+       case MULTIPLYFUNCTION:
                ftmp = (fnum1 * fnum2);
                break;
-       case SUBTRACTFUNCTION :
+       case SUBTRACTFUNCTION:
                ftmp = (fnum1 - fnum2);
                break;
-       case MODULUSFUNCTION :
-       {
-               int inum1 = fnum1;
-               int inum2 = fnum2;
-                       
-               ftmp = (inum1 % inum2);
-               
+       case MODULUSFUNCTION:
+               {
+                       int inum1 = fnum1;
+                       int inum2 = fnum2;
+
+                       ftmp = (inum1 % inum2);
+
+                       break;
+               }
+       case GTFUNCTION:
+               ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
                break;
-       }
-       case GTFUNCTION :
-               ast_copy_string (user_result, (fnum1 > fnum2)?"TRUE":"FALSE", sizeof (user_result));
+       case LTFUNCTION:
+               ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
                break;
-       case LTFUNCTION :
-               ast_copy_string (user_result, (fnum1 < fnum2)?"TRUE":"FALSE", sizeof (user_result));
+       case GTEFUNCTION:
+               ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
                break;
-       case GTEFUNCTION :
-               ast_copy_string (user_result, (fnum1 >= fnum2)?"TRUE":"FALSE", sizeof (user_result));
+       case LTEFUNCTION:
+               ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
                break;
-       case LTEFUNCTION :
-               ast_copy_string (user_result, (fnum1 <= fnum2)?"TRUE":"FALSE", sizeof (user_result));
-               break;                                  
-       case EQFUNCTION :
-               ast_copy_string (user_result, (fnum1 == fnum2)?"TRUE":"FALSE", sizeof (user_result));
+       case EQFUNCTION:
+               ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
                break;
-       default :
-               ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction);
-               return NULL;
+       default:
+               ast_log(LOG_WARNING,
+                               "Something happened that neither of us should be proud of %d\n",
+                               iaction);
+               return -1;
        }
 
        if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
-           if (type_of_result == FLOAT_RESULT)
-                   snprintf(user_result, sizeof(user_result), "%f", ftmp);
-           else if (type_of_result == INT_RESULT)
-                   snprintf(user_result, sizeof(user_result), "%i", (int) ftmp);
-           else if (type_of_result == HEX_RESULT)
-               snprintf(user_result, sizeof(user_result), "%x", (unsigned int) ftmp);
-           else if (type_of_result == CHAR_RESULT)
-               snprintf(user_result, sizeof(user_result), "%c", (unsigned char) ftmp);
+               if (type_of_result == FLOAT_RESULT)
+                       snprintf(buf, len, "%f", ftmp);
+               else if (type_of_result == INT_RESULT)
+                       snprintf(buf, len, "%i", (int) ftmp);
+               else if (type_of_result == HEX_RESULT)
+                       snprintf(buf, len, "%x", (unsigned int) ftmp);
+               else if (type_of_result == CHAR_RESULT)
+                       snprintf(buf, len, "%c", (unsigned char) ftmp);
        }
-               
-       ast_copy_string(buf, user_result, len);
-       
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function math_function = {
@@ -242,7 +236,7 @@ static struct ast_custom_function math_function = {
        .synopsis = "Performs Mathematical Functions",
        .syntax = "MATH(<number1><op><number 2>[,<type_of_result>])",
        .desc = "Perform calculation on number 1 to number 2. Valid ops are: \n"
-           "    +,-,/,*,%,<,>,>=,<=,==\n"
+               "    +,-,/,*,%,<,>,>=,<=,==\n"
                "and behave as their C equivalents.\n"
                "<type_of_result> - wanted type of result:\n"
                "       f, float - float(default)\n"
@@ -257,12 +251,12 @@ static char *tdesc = "Mathematical dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&math_function);
+       return ast_custom_function_unregister(&math_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&math_function);
+       return ast_custom_function_register(&math_function);
 }
 
 char *description(void)
index 53368d6..7e2d9af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2005, Digium, Inc.
+ * Copyright (C) 2005-2006, Digium, Inc.
  * Copyright (C) 2005, Olle E. Johansson, Edvina.net
  * Copyright (C) 2005, Russell Bryant <russelb@clemson.edu> 
  *
@@ -39,44 +39,39 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *md5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int md5(struct ast_channel *chan, char *cmd, char *data,
+              char *buf, size_t len)
 {
-       char md5[33];
-
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       ast_md5_hash(md5, data);
-       ast_copy_string(buf, md5, len);
-       
-       return buf;
+       ast_md5_hash(buf, data);
+       buf[32] = '\0';
+
+       return 0;
 }
 
-static char *checkmd5(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int checkmd5(struct ast_channel *chan, char *cmd, char *parse,
+                   char *buf, size_t len)
 {
        char newmd5[33];
-       char *parse;
        static int deprecated = 0;
-       AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(digest);
-               AST_APP_ARG(data);
-       );
+       AST_DECLARE_APP_ARGS(args, AST_APP_ARG(digest); AST_APP_ARG(data););
 
-       if (ast_strlen_zero(data)) {
-               ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
-               return NULL;
+       if (ast_strlen_zero(parse)) {
+               ast_log(LOG_WARNING,
+                               "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
+               return -1;
        }
 
-       if (!(parse = ast_strdupa(data)))
-               return NULL;
-       
        AST_STANDARD_APP_ARGS(args, parse);
-       
+
        if (args.argc < 2) {
-               ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
-               return NULL;
+               ast_log(LOG_WARNING,
+                               "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
+               return -1;
        }
 
        if (!deprecated) {
@@ -86,12 +81,12 @@ static char *checkmd5(struct ast_channel *chan, char *cmd, char *data, char *buf
 
        ast_md5_hash(newmd5, args.data);
 
-       if (!strcasecmp(newmd5, args.digest) )  /* they match */
+       if (!strcasecmp(newmd5, args.digest))   /* they match */
                ast_copy_string(buf, "1", len);
        else
                ast_copy_string(buf, "0", len);
-       
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function md5_function = {
@@ -113,12 +108,14 @@ static char *tdesc = "MD5 digest dialplan functions";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&md5_function) || ast_custom_function_unregister(&checkmd5_function);
+       return ast_custom_function_unregister(&md5_function) |
+               ast_custom_function_unregister(&checkmd5_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&md5_function) || ast_custom_function_register(&checkmd5_function);
+       return ast_custom_function_register(&md5_function) |
+               ast_custom_function_register(&checkmd5_function);
 }
 
 char *description(void)
index f7cebff..d027b75 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Russell Bryant <russelb@clemson.edu> 
  *
@@ -35,23 +35,39 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/stringfields.h"
 
-static char *moh_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int depwarning = 0;
+
+static int moh_read(struct ast_channel *chan, char *cmd, char *data,
+                   char *buf, size_t len)
 {
+       if (!depwarning) {
+               depwarning = 1;
+               ast_log(LOG_WARNING, "MUSICCLASS() is deprecated; use CHANNEL(musicclass) instead.\n");
+       }
+
        ast_copy_string(buf, chan->musicclass, len);
 
-       return buf;
+       return 0;
 }
 
-static void moh_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int moh_write(struct ast_channel *chan, char *cmd, char *data,
+                    const char *value)
 {
+       if (!depwarning) {
+               depwarning = 1;
+               ast_log(LOG_WARNING, "MUSICCLASS() is deprecated; use CHANNEL(musicclass) instead.\n");
+       }
+
        ast_string_field_set(chan, musicclass, value);
+
+       return 0;
 }
 
 static struct ast_custom_function moh_function = {
        .name = "MUSICCLASS",
        .synopsis = "Read or Set the MusicOnHold class",
        .syntax = "MUSICCLASS()",
-       .desc = "This function will read or set the music on hold class for a channel.\n",
+       .desc = "Deprecated. Use CHANNEL(musicclass) instead.\n",
        .read = moh_read,
        .write = moh_write,
 };
@@ -60,12 +76,12 @@ static char *tdesc = "Music-on-hold dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&moh_function);
+       return ast_custom_function_unregister(&moh_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&moh_function);
+       return ast_custom_function_register(&moh_function);
 }
 
 char *description(void)
index 2f963c9..29ce4f3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (c) 2005 Tilghman Lesher
+ * Copyright (c) 2005, 2006 Tilghman Lesher
  *
  * Tilghman Lesher <func_odbc__200508@the-tilghman.com>
  *
@@ -75,11 +75,11 @@ static void acf_odbc_error(SQLHSTMT stmt, int res)
 /*
  * Master control routine
  */
-static void acf_odbc_write(struct ast_channel *chan, char *cmd, char *data, const char *value)
+static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const char *value)
 {
        odbc_obj *obj;
        struct acf_odbc_query *query;
-       char *s, *t, *arg, buf[512]="", varname[15];
+       char *t, *arg, buf[512]="", varname[15];
        int res, argcount=0, valcount=0, i, retry=0;
        struct ast_channel *ast;
        SQLHSTMT stmt;
@@ -101,7 +101,7 @@ static void acf_odbc_write(struct ast_channel *chan, char *cmd, char *data, cons
        if (!query) {
                ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
                ast_mutex_unlock(&query_lock);
-               return;
+               return -1;
        }
 
        obj = fetch_odbc_obj(query->dsn, 0);
@@ -109,21 +109,16 @@ static void acf_odbc_write(struct ast_channel *chan, char *cmd, char *data, cons
        if (!obj) {
                ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
                ast_mutex_unlock(&query_lock);
-               return;
+               return -1;
        }
 
        /* Parse our arguments */
-       s = ast_strdupa(data);
-       if (value) {
-               t = ast_strdupa(value);
-       } else {
-               t = "";
-       }
+       t = value ? ast_strdupa(value) : "";
 
        if (!s || !t) {
                ast_log(LOG_ERROR, "Out of memory\n");
                ast_mutex_unlock(&query_lock);
-               return;
+               return -1;
        }
 
        /* XXX You might be tempted to change this section into using
@@ -184,7 +179,7 @@ retry_write:
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
                pbx_builtin_setvar_helper(chan, "ODBCROWS", "-1");
-               return;
+               return -1;
        }
 
        res = SQLPrepare(stmt, (unsigned char *)buf, SQL_NTS);
@@ -192,7 +187,7 @@ retry_write:
                ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", buf);
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
                pbx_builtin_setvar_helper(chan, "ODBCROWS", "-1");
-               return;
+               return -1;
        }
 
        res = SQLExecute(stmt);
@@ -234,13 +229,15 @@ retry_write:
        }
 
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+       return 0;
 }
 
-static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf, size_t len)
 {
        odbc_obj *obj;
        struct acf_odbc_query *query;
-       char *s, *arg, sql[512] = "", varname[15];
+       char *arg, sql[512] = "", varname[15];
        int count=0, res, x;
        SQLHSTMT stmt;
        SQLSMALLINT colcount=0;
@@ -260,7 +257,7 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
        if (!query) {
                ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
                ast_mutex_unlock(&query_lock);
-               return "";
+               return -1;
        }
 
        obj = fetch_odbc_obj(query->dsn, 0);
@@ -268,7 +265,7 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
        if (!obj) {
                ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
                ast_mutex_unlock(&query_lock);
-               return "";
+               return -1;
        }
 
 #ifdef NEEDTRACE
@@ -276,12 +273,6 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
        SQLSetConnectAttr(obj->con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
 #endif
 
-       /* Parse our arguments */
-       if (!(s = ast_strdupa(data))) {
-               ast_mutex_unlock(&query_lock);
-               return "";
-       }
-
        while ((arg = strsep(&s, "|"))) {
                count++;
                snprintf(varname, sizeof(varname), "ARG%d", count);
@@ -302,31 +293,31 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
        res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt);
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
-               return "";
+               return -1;
        }
 
        res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               return "";
+               return -1;
        }
 
        res = odbc_smart_execute(obj, stmt);
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               return "";
+               return -1;
        }
 
        res = SQLNumResultCols(stmt, &colcount);
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               return "";
+               return -1;
        }
 
-       memset(buf, 0, len);
+       *buf = '\0';
 
        res = SQLFetch(stmt);
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
@@ -354,7 +345,7 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                        ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
                        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-                       return "";
+                       return -1;
                }
 
                strncat(buf + buflen, coldata, len - buflen);
@@ -366,22 +357,23 @@ static char *acf_odbc_read(struct ast_channel *chan, char *cmd, char *data, char
 
 acf_out:
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-       return buf;
+       return 0;
 }
 
-static char *acf_escape(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int acf_escape(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
-       char *in, *out = buf;
-       for (in = data; *in && out - buf < len; in++) {
-               if (*in == '\'') {
+       char *out = buf;
+
+       for (; *data && out - buf < len; data++) {
+               if (*data == '\'') {
                        *out = '\'';
                        out++;
                }
-               *out = *in;
-               out++;
+               *out++ = *data;
        }
        *out = '\0';
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function escape_function = {
@@ -396,8 +388,6 @@ static struct ast_custom_function escape_function = {
        .write = NULL,
 };
 
-
-
 static int init_acf_query(struct ast_config *cfg, char *catg, struct acf_odbc_query **query)
 {
        char *tmp;
index 34bccf5..6ec0f3c 100644 (file)
@@ -43,48 +43,42 @@ STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
-static char *acf_rand_exec(struct ast_channel *chan, char *cmd, char *data, char *buffer, size_t buflen)
+static int acf_rand_exec(struct ast_channel *chan, char *cmd,
+                        char *parse, char *buffer, size_t buflen)
 {
        struct localuser *u;
        int min_int, response_int, max_int;
-       char *parse;
-
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(min);
-               AST_APP_ARG(max);
+                            AST_APP_ARG(min);
+                            AST_APP_ARG(max);
        );
-       
-       if (!(parse = ast_strdupa(data))) {
-               *buffer = '\0';
-               return buffer;
-       }
 
        LOCAL_USER_ACF_ADD(u);
 
        AST_STANDARD_APP_ARGS(args, parse);
-       
-       if (ast_strlen_zero(args.min) || sscanf(args.min, "%d", &min_int) != 1) {
-               min_int = 0;
-       }
 
+       if (ast_strlen_zero(args.min) || sscanf(args.min, "%d", &min_int) != 1)
+               min_int = 0;
 
-       if (ast_strlen_zero(args.max) || sscanf(args.max, "%d", &max_int) != 1) {
+       if (ast_strlen_zero(args.max) || sscanf(args.max, "%d", &max_int) != 1)
                max_int = RAND_MAX;
-       }
 
        if (max_int < min_int) {
                int tmp = max_int;
+
                max_int = min_int;
                min_int = tmp;
                ast_log(LOG_DEBUG, "max<min\n");
        }
 
        response_int = min_int + (ast_random() % (max_int - min_int + 1));
-       ast_log(LOG_DEBUG, "%d was the lucky number in range [%d,%d]\n", response_int, min_int, max_int);
+       ast_log(LOG_DEBUG, "%d was the lucky number in range [%d,%d]\n",
+               response_int, min_int, max_int);
        snprintf(buffer, buflen, "%d", response_int);
 
        LOCAL_USER_REMOVE(u);
-       return buffer;
+
+       return 0;
 }
 
 static struct ast_custom_function acf_rand = {
@@ -92,10 +86,10 @@ static struct ast_custom_function acf_rand = {
        .synopsis = "Choose a random number in a range",
        .syntax = "RAND([min][,max])",
        .desc =
-"Choose a random number between min and max.  Min defaults to 0, if not\n"
-"specified, while max defaults to RAND_MAX (2147483647 on many systems).\n"
-"  Example:  Set(junky=${RAND(1,8)}); \n"
-"  Sets junky to a random number between 1 and 8, inclusive.\n",
+               "Choose a random number between min and max.  Min defaults to 0, if not\n"
+               "specified, while max defaults to RAND_MAX (2147483647 on many systems).\n"
+               "  Example:  Set(junky=${RAND(1,8)}); \n"
+               "  Sets junky to a random number between 1 and 8, inclusive.\n",
        .read = acf_rand_exec,
 };
 
@@ -116,7 +110,7 @@ int load_module(void)
 
 char *description(void)
 {
-       return tdesc;
+       return tdesc;
 }
 
 int usecount(void)
@@ -126,5 +120,5 @@ int usecount(void)
 
 char *key()
 {
-       return ASTERISK_GPL_KEY;
+       return ASTERISK_GPL_KEY;
 }
index 9600d20..c9805d2 100644 (file)
@@ -37,22 +37,26 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 
-static char *sha1(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int sha1(struct ast_channel *chan, char *cmd, char *data,
+               char *buf, size_t len)
 {
+       *buf = '\0';
+
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: SHA1(<data>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
        if (len >= 41)
                ast_sha1_hash(buf, data);
        else {
-               ast_log(LOG_ERROR, "Insufficient space to produce SHA1 hash result (%d < 41)\n", len);
-               *buf = '\0';
+               ast_log(LOG_ERROR,
+                               "Insufficient space to produce SHA1 hash result (%d < 41)\n",
+                               len);
        }
-       return buf;
-}
 
+       return 0;
+}
 
 static struct ast_custom_function sha1_function = {
        .name = "SHA1",
@@ -60,21 +64,21 @@ static struct ast_custom_function sha1_function = {
        .syntax = "SHA1(<data>)",
        .read = sha1,
        .desc = "Generate a SHA1 digest via the SHA1 algorythm.\n"
-       " Example:  Set(sha1hash=${SHA1(junky)})\n"
-       " Sets the asterisk variable sha1hash to the string '60fa5675b9303eb62f99a9cd47f9f5837d18f9a0'\n"
-       " which is known as his hash\n",
+               " Example:  Set(sha1hash=${SHA1(junky)})\n"
+               " Sets the asterisk variable sha1hash to the string '60fa5675b9303eb62f99a9cd47f9f5837d18f9a0'\n"
+               " which is known as his hash\n",
 };
 
 static char *tdesc = "SHA-1 computation dialplan function";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&sha1_function);
+       return ast_custom_function_unregister(&sha1_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&sha1_function);
+       return ast_custom_function_register(&sha1_function);
 }
 
 char *description(void)
index 644b904..5dafb1f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2005, Digium, Inc.
+ * Copyright (C) 2005-2006, Digium, Inc.
  * Portions Copyright (C) 2005, Tilghman Lesher.  All rights reserved.
  * Portions Copyright (C) 2005, Anthony Minessale II
  *
@@ -42,24 +42,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/localtime.h"
 
-static char *function_fieldqty(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int function_fieldqty(struct ast_channel *chan, char *cmd,
+                            char *parse, char *buf, size_t len)
 {
-       char *varval, workspace[4096];
+       char *varval;
        int fieldcount = 0;
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(varname);
-               AST_APP_ARG(delim);
-       );
-
-       if (!(parse = ast_strdupa(data))) {
-               ast_copy_string(buf, "0", len);
-               return buf;
-       }
+                            AST_APP_ARG(varname);
+                            AST_APP_ARG(delim);
+               );
 
        AST_STANDARD_APP_ARGS(args, parse);
        if (args.delim) {
-               pbx_retrieve_variable(chan, args.varname, &varval, workspace, sizeof(workspace), NULL);
+               pbx_retrieve_variable(chan, args.varname, &varval, buf, len, NULL);
                while (strsep(&varval, args.delim))
                        fieldcount++;
        } else {
@@ -67,7 +62,7 @@ static char *function_fieldqty(struct ast_channel *chan, char *cmd, char *data,
        }
        snprintf(buf, len, "%d", fieldcount);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function fieldqty_function = {
@@ -77,34 +72,29 @@ static struct ast_custom_function fieldqty_function = {
        .read = function_fieldqty,
 };
 
-static char *filter(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int filter(struct ast_channel *chan, char *cmd, char *parse, char *buf,
+                 size_t len)
 {
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(allowed);
-               AST_APP_ARG(string);
+                            AST_APP_ARG(allowed);
+                            AST_APP_ARG(string);
        );
-       char *outbuf=buf;
-
-       if (!(parse = ast_strdupa(data)))
-               return "";
+       char *outbuf = buf;
 
        AST_STANDARD_APP_ARGS(args, parse);
 
-       if (!args.string ) {
+       if (!args.string) {
                ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>,<string>)\n");
-               return "";
+               return -1;
        }
 
-       for ( ; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
-               if (strchr(args.allowed, *(args.string))) {
-                       *outbuf = *(args.string);
-                       outbuf++;
-               }
+       for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) {
+               if (strchr(args.allowed, *(args.string)))
+                       *outbuf++ = *(args.string);
        }
        *outbuf = '\0';
-       
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function filter_function = {
@@ -114,63 +104,59 @@ static struct ast_custom_function filter_function = {
        .read = filter,
 };
 
-static char *regex(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int regex(struct ast_channel *chan, char *cmd, char *parse, char *buf,
+                size_t len)
 {
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(null);
-               AST_APP_ARG(reg);
-               AST_APP_ARG(str);
+                            AST_APP_ARG(null);
+                            AST_APP_ARG(reg);
+                            AST_APP_ARG(str);
        );
-                               
-
-       char errstr[256] = "";
        int errcode;
        regex_t regexbuf;
 
-       ast_copy_string(buf, "0", len);
-       
-       if (!(parse = ast_strdupa(data)))
-               return buf;
+       buf[0] = '\0';
 
        AST_NONSTANDARD_APP_ARGS(args, parse, '"');
 
        ast_log(LOG_DEBUG, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str);
 
        if ((errcode = regcomp(&regexbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
-               regerror(errcode, &regexbuf, errstr, sizeof(errstr));
-               ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, data, errstr);
+               regerror(errcode, &regexbuf, buf, len);
+               ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
+               return -1;
        } else {
                if (!regexec(&regexbuf, args.str, 0, NULL, 0))
-                       ast_copy_string(buf, "1", len); 
+                       strcpy(buf, "1");
        }
        regfree(&regexbuf);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function regex_function = {
        .name = "REGEX",
-       .synopsis = "Regular Expression: Returns 1 if data matches regular expression.",
+       .synopsis =
+               "Regular Expression: Returns 1 if data matches regular expression.",
        .syntax = "REGEX(\"<regular expression>\" <data>)",
        .read = regex,
 };
 
-static void array(struct ast_channel *chan, char *cmd, char *data, const char *value)
+static int array(struct ast_channel *chan, char *cmd, char *var,
+                const char *value)
 {
        AST_DECLARE_APP_ARGS(arg1,
-               AST_APP_ARG(var)[100];
+                            AST_APP_ARG(var)[100];
        );
        AST_DECLARE_APP_ARGS(arg2,
-               AST_APP_ARG(val)[100];
+                            AST_APP_ARG(val)[100];
        );
-       char *var, *value2;
+       char *value2;
        int i;
 
-       var = ast_strdupa(data);
        value2 = ast_strdupa(value);
        if (!var || !value2)
-               return;
+               return -1;
 
        /* The functions this will generally be used with are SORT and ODBC_*, which
         * both return comma-delimited lists.  However, if somebody uses literal lists,
@@ -179,20 +165,19 @@ static void array(struct ast_channel *chan, char *cmd, char *data, const char *v
         * delimiter, but we'll fall back to vertical bars if commas aren't found.
         */
        ast_log(LOG_DEBUG, "array (%s=%s)\n", var, value2);
-       if (strchr(var, ',')) {
+       if (strchr(var, ','))
                AST_NONSTANDARD_APP_ARGS(arg1, var, ',');
-       } else {
+       else
                AST_STANDARD_APP_ARGS(arg1, var);
-       }
 
-       if (strchr(value2, ',')) {
+       if (strchr(value2, ','))
                AST_NONSTANDARD_APP_ARGS(arg2, value2, ',');
-       } else {
+       else
                AST_STANDARD_APP_ARGS(arg2, value2);
-       }
 
        for (i = 0; i < arg1.argc; i++) {
-               ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i], arg2.val[i]);
+               ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i],
+                       arg2.val[i]);
                if (i < arg2.argc) {
                        pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]);
                } else {
@@ -201,6 +186,8 @@ static void array(struct ast_channel *chan, char *cmd, char *data, const char *v
                        pbx_builtin_setvar_helper(chan, arg1.var[i], "");
                }
        }
+
+       return 0;
 }
 
 static struct ast_custom_function array_function = {
@@ -209,22 +196,25 @@ static struct ast_custom_function array_function = {
        .syntax = "ARRAY(var1[,var2[...][,varN]])",
        .write = array,
        .desc =
-"The comma-separated list passed as a value to which the function is set will\n"
-"be interpreted as a set of values to which the comma-separated list of\n"
-"variable names in the argument should be set.\n"
-"Hence, Set(ARRAY(var1,var2)=1,2) will set var1 to 1 and var2 to 2\n"
-"Note: remember to either backslash your commas in extensions.conf or quote the\n"
-"entire argument, since Set can take multiple arguments itself.\n",
+               "The comma-separated list passed as a value to which the function is set will\n"
+               "be interpreted as a set of values to which the comma-separated list of\n"
+               "variable names in the argument should be set.\n"
+               "Hence, Set(ARRAY(var1,var2)=1,2) will set var1 to 1 and var2 to 2\n"
+               "Note: remember to either backslash your commas in extensions.conf or quote the\n"
+               "entire argument, since Set can take multiple arguments itself.\n",
 };
 
-static char *len(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int len(struct ast_channel *chan, char *cmd, char *data, char *buf,
+              size_t len)
 {
        int length = 0;
-       if (data) {
+
+       if (data)
                length = strlen(data);
-       }
+
        snprintf(buf, len, "%d", length);
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function len_function = {
@@ -234,27 +224,25 @@ static struct ast_custom_function len_function = {
        .read = len,
 };
 
-static char *acf_strftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int acf_strftime(struct ast_channel *chan, char *cmd, char *parse,
+                       char *buf, size_t len)
 {
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(epoch);
-               AST_APP_ARG(timezone);
-               AST_APP_ARG(format);
+                            AST_APP_ARG(epoch);
+                            AST_APP_ARG(timezone);
+                            AST_APP_ARG(format);
        );
        long epochi;
        struct tm time;
 
        buf[0] = '\0';
 
-       if (ast_strlen_zero(data)) {
-               ast_log(LOG_ERROR, "Asterisk function STRFTIME() requires an argument.\n");
-               return buf;
+       if (ast_strlen_zero(parse)) {
+               ast_log(LOG_ERROR,
+                               "Asterisk function STRFTIME() requires an argument.\n");
+               return -1;
        }
-       
-       if (!(parse = ast_strdupa(data)))
-               return buf;
-       
+
        AST_STANDARD_APP_ARGS(args, parse);
 
        if (ast_strlen_zero(args.epoch) || !sscanf(args.epoch, "%ld", &epochi)) {
@@ -264,12 +252,12 @@ static char *acf_strftime(struct ast_channel *chan, char *cmd, char *data, char
 
        ast_localtime(&epochi, &time, args.timezone);
 
-       if (!strftime(buf, len, args.format?args.format:"%c", &time)) {
+       if (!strftime(buf, len, args.format ? args.format : "%c", &time))
                ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
-       }
+
        buf[len - 1] = '\0';
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function strftime_function = {
@@ -279,66 +267,71 @@ static struct ast_custom_function strftime_function = {
        .read = acf_strftime,
 };
 
-static char *acf_strptime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int acf_strptime(struct ast_channel *chan, char *cmd, char *data,
+                       char *buf, size_t len)
 {
        AST_DECLARE_APP_ARGS(args,
-               AST_APP_ARG(timestring);
-               AST_APP_ARG(timezone);
-               AST_APP_ARG(format);
+                            AST_APP_ARG(timestring);
+                            AST_APP_ARG(timezone);
+                            AST_APP_ARG(format);
        );
        struct tm time;
 
        memset(&time, 0, sizeof(struct tm));
-       
+
        buf[0] = '\0';
 
        if (!data) {
-               ast_log(LOG_ERROR, "Asterisk function STRPTIME() requires an argument.\n");
-               return buf;
+               ast_log(LOG_ERROR,
+                               "Asterisk function STRPTIME() requires an argument.\n");
+               return -1;
        }
 
        AST_STANDARD_APP_ARGS(args, data);
 
-       if (ast_strlen_zero(args.format) ) {
-               ast_log(LOG_ERROR, "No format supplied to STRPTIME(<timestring>|<timezone>|<format>)");
-               return buf;
+       if (ast_strlen_zero(args.format)) {
+               ast_log(LOG_ERROR,
+                               "No format supplied to STRPTIME(<timestring>|<timezone>|<format>)");
+               return -1;
        }
-                       
+
        if (!strptime(args.timestring, args.format, &time)) {
                ast_log(LOG_WARNING, "C function strptime() output nothing?!!\n");
        } else {
-               snprintf(buf, len, "%d", (int)ast_mktime(&time, args.timezone));          
+               snprintf(buf, len, "%d", (int) ast_mktime(&time, args.timezone));
        }
-       
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function strptime_function = {
        .name = "STRPTIME",
-       .synopsis = "Returns the epoch of the arbitrary date/time string structured as described in the format.",
+       .synopsis =
+               "Returns the epoch of the arbitrary date/time string structured as described in the format.",
        .syntax = "STRPTIME(<datetime>|<timezone>|<format>)",
        .desc =
-"This is useful for converting a date into an EPOCH time, possibly to pass to\n"
-"an application like SayUnixTime or to calculate the difference between two\n"
-"date strings.\n"
-"\n"
-"Example:\n"
-"  ${STRPTIME(2006-03-01 07:30:35|America/Chicago|%Y-%m-%d %H:%M:%S)} returns 1141219835\n",
+               "This is useful for converting a date into an EPOCH time, possibly to pass to\n"
+               "an application like SayUnixTime or to calculate the difference between two\n"
+               "date strings.\n"
+               "\n"
+               "Example:\n"
+               "  ${STRPTIME(2006-03-01 07:30:35|America/Chicago|%Y-%m-%d %H:%M:%S)} returns 1141219835\n",
        .read = acf_strptime,
 };
 
-static char *function_eval(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int function_eval(struct ast_channel *chan, char *cmd, char *data,
+                        char *buf, size_t len)
 {
-       memset(buf, 0, len);
+       buf[0] = '\0';
 
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n");
-               return buf;
+               return -1;
        }
 
        pbx_substitute_variables_helper(chan, data, buf, len - 1);
 
-       return buf;
+       return 0;
 }
 
 static struct ast_custom_function eval_function = {
@@ -353,7 +346,7 @@ static struct ast_custom_function eval_function = {
                "contains \"${OTHERVAR}\", then the result of putting ${EVAL(${MYVAR})}\n"
                "in the dialplan will be the contents of the variable, OTHERVAR.\n"
                "Normally, by just putting ${MYVAR} in the dialplan, you would be\n"
-               "left with \"${OTHERVAR}\".\n", 
+               "left with \"${OTHERVAR}\".\n",
        .read = function_eval,
 };
 
@@ -405,11 +398,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index 547159e..772343a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -40,16 +40,17 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/options.h"
 
-static char *timeout_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int timeout_read(struct ast_channel *chan, char *cmd, char *data,
+                       char *buf, size_t len)
 {
        time_t myt;
 
        if (!data) {
                ast_log(LOG_ERROR, "Must specify type of timeout to get.");
-                return NULL;
+               return -1;
        }
-       
-       switch(*data) {
+
+       switch (*data) {
        case 'a':
        case 'A':
                if (chan->whentohangup == 0) {
@@ -79,10 +80,11 @@ static char *timeout_read(struct ast_channel *chan, char *cmd, char *data, char
                break;
        }
 
-       return buf;
+       return 0;
 }
 
-static void timeout_write(struct ast_channel *chan, char *cmd, char *data, const char *value) 
+static int timeout_write(struct ast_channel *chan, char *cmd, char *data,
+                        const char *value)
 {
        int x;
        char timestr[64];
@@ -90,25 +92,27 @@ static void timeout_write(struct ast_channel *chan, char *cmd, char *data, const
 
        if (!data) {
                ast_log(LOG_ERROR, "Must specify type of timeout to set.");
-               return;
+               return -1;
        }
-       
+
        if (!value)
-               return;
+               return -1;
 
        x = atoi(value);
 
-       switch(*data) {
+       switch (*data) {
        case 'a':
        case 'A':
                ast_channel_setwhentohangup(chan, x);
                if (option_verbose > 2) {
                        if (chan->whentohangup) {
-                               strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S UTC", gmtime_r(&chan->whentohangup, &myt));
-                               ast_verbose( VERBOSE_PREFIX_3 "Channel will hangup at %s.\n", timestr);
+                               strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S UTC",
+                                        gmtime_r(&chan->whentohangup, &myt));
+                               ast_verbose(VERBOSE_PREFIX_3 "Channel will hangup at %s.\n",
+                                           timestr);
                        } else {
-                               ast_verbose( VERBOSE_PREFIX_3 "Channel hangup cancelled.\n");
-                       } 
+                               ast_verbose(VERBOSE_PREFIX_3 "Channel hangup cancelled.\n");
+                       }
                }
                break;
 
@@ -117,7 +121,8 @@ static void timeout_write(struct ast_channel *chan, char *cmd, char *data, const
                if (chan->pbx) {
                        chan->pbx->rtimeout = x;
                        if (option_verbose > 2)
-                               ast_verbose( VERBOSE_PREFIX_3 "Response timeout set to %d\n", chan->pbx->rtimeout);
+                               ast_verbose(VERBOSE_PREFIX_3 "Response timeout set to %d\n",
+                                           chan->pbx->rtimeout);
                }
                break;
 
@@ -126,7 +131,8 @@ static void timeout_write(struct ast_channel *chan, char *cmd, char *data, const
                if (chan->pbx) {
                        chan->pbx->dtimeout = x;
                        if (option_verbose > 2)
-                               ast_verbose( VERBOSE_PREFIX_3 "Digit timeout set to %d\n", chan->pbx->dtimeout);
+                               ast_verbose(VERBOSE_PREFIX_3 "Digit timeout set to %d\n",
+                                           chan->pbx->dtimeout);
                }
                break;
 
@@ -134,35 +140,35 @@ static void timeout_write(struct ast_channel *chan, char *cmd, char *data, const
                ast_log(LOG_ERROR, "Unknown timeout type specified.");
                break;
        }
+
+       return 0;
 }
 
 static struct ast_custom_function timeout_function = {
        .name = "TIMEOUT",
        .synopsis = "Gets or sets timeouts on the channel.",
        .syntax = "TIMEOUT(timeouttype)",
-       .desc = "Gets or sets various channel timeouts. The timeouts that can be\n"
-       "manipulated are:\n"
-       "\n"
-       "absolute: The absolute maximum amount of time permitted for a call.  A\n"
-       "          setting of 0 disables the timeout.\n"
-       "\n"
-       "digit:    The maximum amount of time permitted between digits when the\n"
-       "          user is typing in an extension.  When this timeout expires,\n"
-       "          after the user has started to type in an extension, the\n"
-       "          extension will be considered complete, and will be\n"
-       "          interpreted.  Note that if an extension typed in is valid,\n"
-       "          it will not have to timeout to be tested, so typically at\n"
-       "          the expiry of this timeout, the extension will be considered\n"
-       "          invalid (and thus control would be passed to the 'i'\n"
-       "          extension, or if it doesn't exist the call would be\n"
-       "          terminated).  The default timeout is 5 seconds.\n"
-       "\n"
-       "response: The maximum amount of time permitted after falling through a\n"
-       "          series of priorities for a channel in which the user may\n"
-       "          begin typing an extension.  If the user does not type an\n"
-       "          extension in this amount of time, control will pass to the\n"
-       "          't' extension if it exists, and if not the call would be\n"
-       "          terminated.  The default timeout is 10 seconds.\n",
+       .desc =
+               "Gets or sets various channel timeouts. The timeouts that can be\n"
+               "manipulated are:\n" "\n"
+               "absolute: The absolute maximum amount of time permitted for a call.  A\n"
+               "          setting of 0 disables the timeout.\n" "\n"
+               "digit:    The maximum amount of time permitted between digits when the\n"
+               "          user is typing in an extension.  When this timeout expires,\n"
+               "          after the user has started to type in an extension, the\n"
+               "          extension will be considered complete, and will be\n"
+               "          interpreted.  Note that if an extension typed in is valid,\n"
+               "          it will not have to timeout to be tested, so typically at\n"
+               "          the expiry of this timeout, the extension will be considered\n"
+               "          invalid (and thus control would be passed to the 'i'\n"
+               "          extension, or if it doesn't exist the call would be\n"
+               "          terminated).  The default timeout is 5 seconds.\n" "\n"
+               "response: The maximum amount of time permitted after falling through a\n"
+               "          series of priorities for a channel in which the user may\n"
+               "          begin typing an extension.  If the user does not type an\n"
+               "          extension in this amount of time, control will pass to the\n"
+               "          't' extension if it exists, and if not the call would be\n"
+               "          terminated.  The default timeout is 10 seconds.\n",
        .read = timeout_read,
        .write = timeout_write,
 };
@@ -171,12 +177,12 @@ static char *tdesc = "Channel timeout dialplan functions";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&timeout_function);
+       return ast_custom_function_unregister(&timeout_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&timeout_function);
+       return ast_custom_function_register(&timeout_function);
 }
 
 char *description(void)
@@ -193,11 +199,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-/*
-Local Variables:
-mode: C
-c-file-style: "linux"
-indent-tabs-mode: nil
-End:
-*/
index 08fdc5b..065db5b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Created by Olle E. Johansson, Edvina.net 
  *
@@ -44,33 +44,32 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 
 /*! \brief uriencode: Encode URL according to RFC 2396 */
-static char *uriencode(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int uriencode(struct ast_channel *chan, char *cmd, char *data,
+                    char *buf, size_t len)
 {
-       char uri[BUFSIZ];
-
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: URIENCODE(<data>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       ast_uri_encode(data, uri, sizeof(uri), 1);
-       ast_copy_string(buf, uri, len);
+       ast_uri_encode(data, buf, len, 1);
 
-       return buf;
+       return 0;
 }
 
 /*!\brief uridecode: Decode URI according to RFC 2396 */
-static char *uridecode(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+static int uridecode(struct ast_channel *chan, char *cmd, char *data,
+                    char *buf, size_t len)
 {
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: URIDECODE(<data>) - missing argument!\n");
-               return NULL;
+               return -1;
        }
 
-       
        ast_copy_string(buf, data, len);
        ast_uri_decode(buf);
-       return buf;
+
+       return 0;
 }
 
 static struct ast_custom_function urldecode_function = {
@@ -91,12 +90,14 @@ static char *tdesc = "URI encode/decode dialplan functions";
 
 int unload_module(void)
 {
-        return ast_custom_function_unregister(&urldecode_function) || ast_custom_function_unregister(&urlencode_function);
+       return ast_custom_function_unregister(&urldecode_function)
+               || ast_custom_function_unregister(&urlencode_function);
 }
 
 int load_module(void)
 {
-        return ast_custom_function_register(&urldecode_function) || ast_custom_function_register(&urlencode_function);
+       return ast_custom_function_register(&urldecode_function)
+               || ast_custom_function_register(&urlencode_function);
 }
 
 char *description(void)
index 5457247..6c00e2a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -256,6 +256,10 @@ struct ast_channel_tech {
 
        /*! Find bridged channel */
        struct ast_channel *(* const bridged_channel)(struct ast_channel *chan, struct ast_channel *bridge);
+
+       /*! Provide additional items for CHANNEL() dialplan function */
+       int (* func_channel_read)(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
+       int (* func_channel_write)(struct ast_channel *chan, char *function, char *data, const char *value);
 };
 
 struct ast_channel_spy_list;
index 80806de..0f8cd50 100644 (file)
@@ -336,7 +336,7 @@ void ast_unregister_atexit(void (*func)(void));
  \
        if (!(u=calloc(1,sizeof(*u)))) { \
                ast_log(LOG_WARNING, "Out of memory\n"); \
-               return ""; \
+               return -1; \
        } \
        ast_mutex_lock(&localuser_lock); \
        u->chan = chan; \
index e8d6507..83997b4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -88,8 +88,8 @@ struct ast_custom_function {
        char *synopsis;
        char *desc;
        char *syntax;
-       char *(*read)(struct ast_channel *, char *, char *, char *, size_t);
-       void (*write)(struct ast_channel *, char *, char *, const char *);
+       int (*read)(struct ast_channel *, char *, char *, char *, size_t);
+       int (*write)(struct ast_channel *, char *, char *, const char *);
        struct ast_custom_function *next;
 };
 
@@ -636,25 +636,24 @@ int ast_active_calls(void);
 /*! executes a read operation on a function */
 /*!
  * \param chan Channel to execute on
- * \param in Data containing the function call string
+ * \param function Data containing the function call string (will be modified)
  * \param workspace A pointer to safe memory to use for a return value 
  * \param len the number of bytes in workspace
+ * \return zero on success, non-zero on failure
  * This application executes an function in read mode on a given channel.
- * It returns a pointer to workspace if the buffer contains any new data
- * or NULL if there was a problem.
- */
+ *  */
        
-char *ast_func_read(struct ast_channel *chan, const char *in, char *workspace, size_t len);
+int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len);
 
 /*! executes a write operation on a function */
 /*!
  * \param chan Channel to execute on
- * \param in Data containing the function call string
+ * \param function Data containing the function call string (will be modified)
  * \param value A value parameter to pass for writing
+ * \return zero on success, non-zero on failure
  * This application executes an function in write mode on a given channel.
- * It has no return value.
  */
-void ast_func_write(struct ast_channel *chan, const char *in, const char *value);
+int ast_func_write(struct ast_channel *chan, char *function, const char *value);
 
 void ast_hint_state_changed(const char *device);
 
index c8e4144..81c67ff 100644 (file)
--- a/manager.c
+++ b/manager.c
@@ -751,7 +751,7 @@ static int action_getvar(struct mansession *s, struct message *m)
        }
 
        if (varname[strlen(varname) - 1] == ')') {
-               varval = ast_func_read(c, varname, workspace, sizeof(workspace));
+               ast_func_read(c, varname, workspace, sizeof(workspace));
        } else {
                pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
        }
diff --git a/pbx.c b/pbx.c
index e921811..6e3c8df 100644 (file)
--- a/pbx.c
+++ b/pbx.c
@@ -1211,68 +1211,60 @@ int ast_custom_function_register(struct ast_custom_function *acf)
        return 0;
 }
 
-char *ast_func_read(struct ast_channel *chan, const char *in, char *workspace, size_t len)
+int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len)
 {
-       char *args = NULL, *function, *p;
-       char *ret = "0";
+       char *args = NULL, *p;
        struct ast_custom_function *acfptr;
 
-       if (!(function = ast_strdupa(in)))
-               return ret;
        if ((args = strchr(function, '('))) {
-               *args = '\0';
-               args++;
-               if ((p = strrchr(args, ')'))) {
+               *args++ = '\0';
+               if ((p = strrchr(args, ')')))
                        *p = '\0';
-               } else {
+               else
                        ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
-               }
        } else {
                ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
        }
 
        if ((acfptr = ast_custom_function_find(function))) {
                /* run the custom function */
-               if (acfptr->read) {
+               if (acfptr->read)
                        return acfptr->read(chan, function, args, workspace, len);
-               } else {
+               else
                        ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
-               }
        } else {
                ast_log(LOG_ERROR, "Function %s not registered\n", function);
        }
-       return ret;
+
+       return -1;
 }
 
-void ast_func_write(struct ast_channel *chan, const char *in, const char *value)
+int ast_func_write(struct ast_channel *chan, char *function, const char *value)
 {
-       char *args = NULL, *function, *p;
+       char *args = NULL, *p;
        struct ast_custom_function *acfptr;
 
-       if (!(function = ast_strdupa(in)))
-               return;
        if ((args = strchr(function, '('))) {
-               *args = '\0';
-               args++;
-               if ((p = strrchr(args, ')'))) {
+               *args++ = '\0';
+               if ((p = strrchr(args, ')')))
                        *p = '\0';
-               } else {
+               else
                        ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
-               }
        } else {
                ast_log(LOG_WARNING, "Function doesn't contain parentheses.  Assuming null argument.\n");
        }
 
        if ((acfptr = ast_custom_function_find(function))) {
                /* run the custom function */
-               if (acfptr->write) {
-                       acfptr->write(chan, function, args, value);
-               } else {
+               if (acfptr->write)
+                       return acfptr->write(chan, function, args, value);
+               else
                        ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function);
-               }
        } else {
                ast_log(LOG_ERROR, "Function %s not registered\n", function);
        }
+
+       return -1;
 }
 
 static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
@@ -1373,7 +1365,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
                        parse_variable_name(vars, &offset, &offset2, &isfunction);
                        if (isfunction) {
                                /* Evaluate function */
-                               cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE);
+                               cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
 
                                ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
                        } else {
@@ -5485,8 +5477,11 @@ void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, cons
        struct varshead *headp;
 
        if (name[strlen(name)-1] == ')') {
+               char *function = ast_strdupa(name);
+
                ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
-               return ast_func_write(chan, name, value);
+               ast_func_write(chan, function, value);
+               return;
        }
 
        headp = (chan) ? &chan->varshead : &globals;
@@ -5505,8 +5500,12 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const
        struct varshead *headp;
        const char *nametail = name;
 
-       if (name[strlen(name)-1] == ')')
-               return ast_func_write(chan, name, value);
+       if (name[strlen(name)-1] == ')') {
+               char *function = ast_strdupa(name);
+               
+               ast_func_write(chan, function, value);
+               return;
+       }
 
        headp = (chan) ? &chan->varshead : &globals;
 
index e802784..e7667df 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -3837,9 +3837,8 @@ int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_e
        return dundi_query_eid_internal(dei, dcontext, &eid, &hmd, dundi_ttl, 0, avoid);
 }
 
-static char *dundifunc_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+static int dundifunc_read(struct ast_channel *chan, char *cmd, char *num, char *buf, size_t len)
 {
-       char *num;
        char *context;
        char *opts;
        int results;
@@ -3852,27 +3851,18 @@ static char *dundifunc_read(struct ast_channel *chan, char *cmd, char *data, cha
 
        buf[0] = '\0';
 
-       if (ast_strlen_zero(data)) {
+       if (ast_strlen_zero(num)) {
                ast_log(LOG_WARNING, "DUNDILOOKUP requires an argument (number)\n");
                LOCAL_USER_REMOVE(u);
-               return buf;
-       }
-
-       num = ast_strdupa(data);
-       if (!num) {
-               ast_log(LOG_ERROR, "Out of memory!\n");
-               LOCAL_USER_REMOVE(u);
-               return buf;
+               return -1;
        }
 
        context = strchr(num, '|');
        if (context) {
-               *context = '\0';
-               context++;
+               *context++ = '\0';
                opts = strchr(context, '|');
                if (opts) {
-                       *opts = '\0';
-                       opts++;
+                       *opts++ = '\0';
                        if (strchr(opts, 'b'))
                                bypass = 1;
                }
@@ -3894,7 +3884,7 @@ static char *dundifunc_read(struct ast_channel *chan, char *cmd, char *data, cha
 
        LOCAL_USER_REMOVE(u);
 
-       return buf;
+       return 0;
 }
 
 /*! DUNDILOOKUP
index fc36ebb..85436a6 100644 (file)
@@ -1167,7 +1167,7 @@ static int handle_getvariable(struct ast_channel *chan, AGI *agi, int argc, char
 
        /* check if we want to execute an ast_custom_function */
        if (!ast_strlen_zero(argv[2]) && (argv[2][strlen(argv[2]) - 1] == ')')) {
-               ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr));
+               ret = ast_func_read(chan, argv[2], tempstr, sizeof(tempstr)) ? NULL : tempstr;
        } else {
                pbx_retrieve_variable(chan, argv[2], &ret, tempstr, sizeof(tempstr), NULL);
        }