dect
/
asterisk
Archived
13
0
Fork 0

major dialplan functions update

deprecate LANGUAGE() and MUSICCLASS(), in favor of CHANNEL()


git-svn-id: http://svn.digium.com/svn/asterisk/trunk@9674 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
kpfleming 2006-02-12 04:28:58 +00:00
parent 9f87dd693e
commit 5d9ed5739a
35 changed files with 1160 additions and 1101 deletions

View 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 = {

View 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 = {

View 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 = {

View 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 = {

View 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"

View 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)
{

View 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.

View 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:
*/

View 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:
*/

View 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:
*/

View 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) ) {
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;
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));
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};
struct ast_flags flags = { 0 };
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable);
AST_APP_ARG(options);
);
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:
*/

152
funcs/func_channel.c Normal file
View File

@ -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;
}

View 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 = {

View 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;
}

View 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;
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 "";
}
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, synopsis);
return -1;
}
do {
if(i>3){
ast_log(LOG_WARNING, synopsis);
return "";
}
params[i++] = p;
p = strchr(p, '|');
if(p){
*p = '\0';
p++;
}
} while(p);
AST_STANDARD_APP_ARGS(args, data);
if(i < 1){
ast_log(LOG_WARNING, synopsis);
return "";
}
if (args.argc < 1) {
ast_log(LOG_WARNING, synopsis);
return -1;
}
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));
}
ast_copy_string(tech, args.tech ? args.tech : "sip", sizeof(tech));
if( (i > 3 && strlen(params[3]) == 0) || i<4){
zone = "e164.arpa";
} else {
zone = params[3];
}
if (!args.zone)
args.zone = "e164.arpa";
if( (i > 2 && strlen(params[2]) == 0) || i<3){
options = "1";
} else {
options = params[2];
}
if (!args.options)
args.options = "1";
/* 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;
/* strip any '-' signs from number */
for (p = args.number, s = p; *s; *s++) {
if (*s != '-')
*p++ = *s;
}
*p = '\0';
LOCAL_USER_ACF_ADD(u);
LOCAL_USER_ACF_ADD(u);
res = ast_get_enum(chan, p, dest, sizeof(dest), tech, sizeof(tech), zone, options);
res = ast_get_enum(chan, p, dest, sizeof(dest), tech, sizeof(tech), zone,
options);
LOCAL_USER_REMOVE(u);
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));
}
p = strchr(dest, ':');
if (p && strcasecmp(tech, "ALL"))
ast_copy_string(buf, p + 1, len);
else
ast_copy_string(buf, dest, len);
return buf;
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;
}

View 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:
*/

View 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:
*/

View 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:
*/

View 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,
};

View 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)

View 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)

View 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)

View 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;

View 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) {
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;
}

View 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)

View 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:
*/

View 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:
*/

View 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)

View 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;

View 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; \

View 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);

View File

@ -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);
}

61
pbx.c
View File

@ -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;

View 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

View 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);
}