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:
parent
9f87dd693e
commit
5d9ed5739a
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 = {
|
||||
|
|
114
funcs/func_db.c
114
funcs/func_db.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(®exbuf, args.reg, REG_EXTENDED | REG_NOSUB))) {
|
||||
regerror(errcode, ®exbuf, errstr, sizeof(errstr));
|
||||
ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, data, errstr);
|
||||
regerror(errcode, ®exbuf, buf, len);
|
||||
ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf);
|
||||
return -1;
|
||||
} else {
|
||||
if (!regexec(®exbuf, args.str, 0, NULL, 0))
|
||||
ast_copy_string(buf, "1", len);
|
||||
strcpy(buf, "1");
|
||||
}
|
||||
regfree(®exbuf);
|
||||
|
||||
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:
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
61
pbx.c
|
@ -1211,68 +1211,60 @@ int ast_custom_function_register(struct ast_custom_function *acf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *ast_func_read(struct ast_channel *chan, const char *in, char *workspace, size_t len)
|
||||
int ast_func_read(struct ast_channel *chan, char *function, char *workspace, size_t len)
|
||||
{
|
||||
char *args = NULL, *function, *p;
|
||||
char *ret = "0";
|
||||
char *args = NULL, *p;
|
||||
struct ast_custom_function *acfptr;
|
||||
|
||||
if (!(function = ast_strdupa(in)))
|
||||
return ret;
|
||||
if ((args = strchr(function, '('))) {
|
||||
*args = '\0';
|
||||
args++;
|
||||
if ((p = strrchr(args, ')'))) {
|
||||
*args++ = '\0';
|
||||
if ((p = strrchr(args, ')')))
|
||||
*p = '\0';
|
||||
} else {
|
||||
else
|
||||
ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n");
|
||||
}
|
||||
|
||||
if ((acfptr = ast_custom_function_find(function))) {
|
||||
/* run the custom function */
|
||||
if (acfptr->read) {
|
||||
if (acfptr->read)
|
||||
return acfptr->read(chan, function, args, workspace, len);
|
||||
} else {
|
||||
else
|
||||
ast_log(LOG_ERROR, "Function %s cannot be read\n", function);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Function %s not registered\n", function);
|
||||
}
|
||||
return ret;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ast_func_write(struct ast_channel *chan, const char *in, const char *value)
|
||||
int ast_func_write(struct ast_channel *chan, char *function, const char *value)
|
||||
{
|
||||
char *args = NULL, *function, *p;
|
||||
char *args = NULL, *p;
|
||||
struct ast_custom_function *acfptr;
|
||||
|
||||
if (!(function = ast_strdupa(in)))
|
||||
return;
|
||||
if ((args = strchr(function, '('))) {
|
||||
*args = '\0';
|
||||
args++;
|
||||
if ((p = strrchr(args, ')'))) {
|
||||
*args++ = '\0';
|
||||
if ((p = strrchr(args, ')')))
|
||||
*p = '\0';
|
||||
} else {
|
||||
else
|
||||
ast_log(LOG_WARNING, "Can't find trailing parenthesis?\n");
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Function doesn't contain parentheses. Assuming null argument.\n");
|
||||
}
|
||||
|
||||
if ((acfptr = ast_custom_function_find(function))) {
|
||||
/* run the custom function */
|
||||
if (acfptr->write) {
|
||||
acfptr->write(chan, function, args, value);
|
||||
} else {
|
||||
if (acfptr->write)
|
||||
return acfptr->write(chan, function, args, value);
|
||||
else
|
||||
ast_log(LOG_ERROR, "Function %s is read-only, it cannot be written to\n", function);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Function %s not registered\n", function);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count)
|
||||
|
@ -1373,7 +1365,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v
|
|||
parse_variable_name(vars, &offset, &offset2, &isfunction);
|
||||
if (isfunction) {
|
||||
/* Evaluate function */
|
||||
cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE);
|
||||
cp4 = ast_func_read(c, vars, workspace, VAR_BUF_SIZE) ? NULL : workspace;
|
||||
|
||||
ast_log(LOG_DEBUG, "Function result is '%s'\n", cp4 ? cp4 : "(null)");
|
||||
} else {
|
||||
|
@ -5485,8 +5477,11 @@ void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, cons
|
|||
struct varshead *headp;
|
||||
|
||||
if (name[strlen(name)-1] == ')') {
|
||||
char *function = ast_strdupa(name);
|
||||
|
||||
ast_log(LOG_WARNING, "Cannot push a value onto a function\n");
|
||||
return ast_func_write(chan, name, value);
|
||||
ast_func_write(chan, function, value);
|
||||
return;
|
||||
}
|
||||
|
||||
headp = (chan) ? &chan->varshead : &globals;
|
||||
|
@ -5505,8 +5500,12 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const
|
|||
struct varshead *headp;
|
||||
const char *nametail = name;
|
||||
|
||||
if (name[strlen(name)-1] == ')')
|
||||
return ast_func_write(chan, name, value);
|
||||
if (name[strlen(name)-1] == ')') {
|
||||
char *function = ast_strdupa(name);
|
||||
|
||||
ast_func_write(chan, function, value);
|
||||
return;
|
||||
}
|
||||
|
||||
headp = (chan) ? &chan->varshead : &globals;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Reference in New Issue