Update of /usr/cvsroot/asterisk/funcs
In directory mongoose.digium.com:/tmp/cvs-serv19282/funcs

Added Files:
        Makefile func_cdr.c func_env.c func_groupcount.c func_logic.c 
        func_md5.c func_strings.c pbx_functions.c 
Log Message:
major re-work of dialplan functions, including:

 - locking of functions list during registration/unregistration/searching
 - rename of function description structure to be consistent with the rest of 
the API
 - addition of 'desc' element to description structure, for detailed 
description (like applications)
 - addition of 'show function' CLI command to show function details
 - conversion of existing functions to use uppercase names to match policy
 - creation of new 'pbx_functions.so' module to contain standard 'builtin' 
functions
 - removal of all builtin functions from pbx.c and apps and placement into new 
'funcs' directory



--- NEW FILE: Makefile ---
#
# Asterisk -- A telephony toolkit for Linux.
# 
# Makefile for dialplan functions
#
# Copyright (C) 2005, Digium, Inc.
#
# Kevin P. Fleming <[EMAIL PROTECTED]>
#
# This program is free software, distributed under the terms of
# the GNU General Public License
#

FUNCS=pbx_functions.so

BUILTINS=func_md5.o func_groupcount.o func_strings.o func_cdr.o func_logic.o 
func_env.o

STANDALONE_FUNCS=$(filter-out $(BUILTINS),$(patsubst %.c,%.o,$(wildcard 
func*.c)))

FUNCS+=$(STANDALONE_FUNCS:.o=.so)

FUNC_STRUCTS=$(shell grep 'struct ast_custom_function' $(BUILTINS:.o=.c) | awk 
'{print $$3};')

all: $(FUNCS)

clean:
        rm -f *.so *.o .depend

%.so : %.o
        $(CC) $(SOLINK) -o $@ $<

$(BUILTINS) : CFLAGS += -DBUILTIN_FUNC

pbx_functions.h: $(BUILTINS:.o=.c)
        @echo "/* Automatically generated - do not edit */" > $@
        @for f in $(FUNC_STRUCTS); do echo "extern struct ast_custom_function 
$$f;" >> $@; done
        @echo "static struct ast_custom_function *builtins[] = {" >> $@
        @for f in $(FUNC_STRUCTS); do echo "&$$f," >> $@; done
        @echo "};" >> $@

pbx_functions.so: pbx_functions.o $(BUILTINS)
        $(CC) $(SOLINK) -o $@ $(BUILTINS) $<
        strip $(foreach f,$(FUNC_STRUCTS),-N $(f)) $@

install: all
        for x in $(FUNCS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; 
done

ifneq ($(wildcard .depend),)
include .depend
endif

depend: .depend

.depend: pbx_functions.h
        ../mkdep $(CFLAGS) `ls *.c`

env:
        env

--- NEW FILE: func_cdr.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * MD5 digest related dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/cdr.h"

static char *builtin_function_cdr_read(struct ast_channel *chan, char *cmd, 
char *data, char *buf, size_t len) 
{
        char *ret;
        char *mydata;
        int argc;
        char *argv[2];
        int recursive = 0;

        if (!data || ast_strlen_zero(data))
                return NULL;
        
        if (!chan->cdr)
                return NULL;

        mydata = ast_strdupa(data);
        argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / 
sizeof(argv[0]));

        /* check for a trailing flags argument */
        if (argc > 1) {
                argc--;
                if (strchr(argv[argc], 'r'))
                        recursive = 1;
        }

        ast_cdr_getvar(chan->cdr, argv[0], &ret, buf, len, recursive);

        return ret;
}

static void builtin_function_cdr_write(struct ast_channel *chan, char *cmd, 
char *data, const char *value) 
{
        char *mydata;
        int argc;
        char *argv[2];
        int recursive = 0;

        if (!data || ast_strlen_zero(data) || !value)
                return;
        
        if (!chan->cdr)
                return;

        mydata = ast_strdupa(data);
        argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / 
sizeof(argv[0]));

        /* check for a trailing flags argument */
        if (argc > 1) {
                argc--;
                if (strchr(argv[argc], 'r'))
                        recursive = 1;
        }

        ast_cdr_setvar(chan->cdr, argv[0], value, recursive);
}

#ifndef BUILTIN_FUNC
static
#endif
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",
        .syntax = "CDR(<name>[|options])",
        .read = builtin_function_cdr_read,
        .write = builtin_function_cdr_write,
};


--- NEW FILE: func_env.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * MD5 digest related dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"

static char *builtin_function_env_read(struct ast_channel *chan, char *cmd, 
char *data, char *buf, size_t len) 
{
        char *ret = "";

        if (data) {
                ret = getenv(data);
                if (!ret)
                        ret = "";
        }
        ast_copy_string(buf, ret, len);

        return buf;
}

static void builtin_function_env_write(struct ast_channel *chan, char *cmd, 
char *data, const char *value) 
{
        if (data && !ast_strlen_zero(data)) {
                if (value && !ast_strlen_zero(value)) {
                        setenv(data, value, 1);
                } else {
                        unsetenv(data);
                }
        }
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function env_function = {
        .name = "ENV",
        .synopsis = "Gets or sets the environment variable specified",
        .syntax = "ENV(<envname>)",
        .read = builtin_function_env_read,
        .write = builtin_function_env_write,
};

--- NEW FILE: func_groupcount.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * Channel group related dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#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) 
{
        int count;
        char group[80] = "";
        char category[80] = "";
        char *grp;

        ast_app_group_split_group(data, group, sizeof(group), category, 
sizeof(category));

        if (ast_strlen_zero(group)) {
                grp = pbx_builtin_getvar_helper(chan, category);
                strncpy(group, grp, sizeof(group) - 1);
        }

        count = ast_app_group_get_count(group, category);
        snprintf(buf, len, "%d", count);

        return buf;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function group_count_function = {
        .name = "GROUP_COUNT",
        .syntax = "GROUP_COUNT([EMAIL PROTECTED])",
        .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",
        .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) 
{
        int count;
        char group[80] = "";
        char category[80] = "";

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

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function group_match_count_function = {
        .name = "GROUP_MATCH_COUNT",
        .syntax = "GROUP_MATCH_COUNT([EMAIL PROTECTED])",
        .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,
};

--- NEW FILE: func_logic.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * MD5 digest related dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/config.h"            /* for ast_true */

static char *builtin_function_isnull(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        char *ret_true = "1", *ret_false = "0";

        return data && *data ? ret_false : ret_true;
}

static char *builtin_function_exists(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        char *ret_true = "1", *ret_false = "0";

        return data && *data ? ret_true : ret_false;
}

static char *builtin_function_if(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        char *ret = NULL;
        char *mydata = NULL;
        char *expr = NULL;
        char *iftrue = NULL;
        char *iffalse = NULL;

        if((mydata = ast_strdupa(data))) {
                expr = mydata;
                if ((iftrue = strchr(mydata, '?'))) {
                        *iftrue = '\0';
                        iftrue++;
                        if ((iffalse = strchr(iftrue, ':'))) {
                                *iffalse = '\0';
                                iffalse++;
                        }
                } else 
                        iffalse = "";
                if (expr && iftrue) {
                        ret = ast_true(expr) ? iftrue : iffalse;
                        strncpy(buf, ret, len);
                        ret = buf;
                } else {
                        ast_log(LOG_WARNING, "Syntax $(if 
<expr>?[<truecond>][:<falsecond>])\n");
                        ret = NULL;
                }
        } else {
                ast_log(LOG_WARNING, "Memory Error!\n");
                ret = NULL;
        }

        return ret;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function isnull_function = {
        .name = "ISNULL",
        .synopsis = "NULL Test: Returns 1 if NULL or 0 otherwise",
        .syntax = "ISNULL(<data>)",
        .read = builtin_function_isnull,
};

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function exists_function = {
        .name = "EXISTS",
        .synopsis = "Existence Test: Returns 1 if exists, 0 otherwise",
        .syntax = "EXISTS(<data>)",
        .read = builtin_function_exists,
};

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function if_function = {
        .name = "IF",
        .synopsis = "Conditional: Returns the data following '?' if true else 
the data following ':'",
        .syntax = "IF(<expr>?<true>:<false>)",
        .read = builtin_function_if,
};

--- NEW FILE: func_md5.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * MD5 digest related dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"

static char *builtin_function_md5(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        char md5[33];

        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: MD5(<data>) - missing 
argument!\n");
                return NULL;
        }

        ast_md5_hash(md5, data);
        ast_copy_string(buf, md5, len);
        
        return buf;
}

static char *builtin_function_checkmd5(struct ast_channel *chan, char *cmd, 
char *data, char *buf, size_t len) 
{
        int argc;
        char *argv[2];
        char *args;
        char newmd5[33];

        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - 
missing argument!\n");
                return NULL;
        }

        args = ast_strdupa(data);       
        argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / 
sizeof(argv[0]));

        if (argc < 2) {
                ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - 
missing argument!\n");
                return NULL;
        }

        ast_md5_hash(newmd5, argv[1]);

        if (!strcasecmp(newmd5, argv[0]))       /* they match */
                ast_copy_string(buf, "1", len);
        else
                ast_copy_string(buf, "0", len);
        
        return buf;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function md5_function = {
        .name = "MD5",
        .synopsis = "Computes an MD5 digest",
        .syntax = "MD5(<data>)",
        .read = builtin_function_md5,
};

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function checkmd5_function = {
        .name = "CHECK_MD5",
        .synopsis = "Checks an MD5 digest",
        .desc = "Returns 1 on a match, 0 otherwise\n",
        .syntax = "CHECK_MD5(<digest>,<data>)",
        .read = builtin_function_checkmd5,
};

--- NEW FILE: func_strings.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * String manipulation dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>

#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"

static char *function_fieldqty(struct ast_channel *chan, char *cmd, char *data, 
char *buf, size_t len)
{
        char *varname, *varval, workspace[256];
        char *delim = ast_strdupa(data);
        int fieldcount = 0;

        if (delim) {
                varname = strsep(&delim, "|");
                pbx_retrieve_variable(chan, varname, &varval, workspace, 
sizeof(workspace), NULL);
                while (strsep(&varval, delim))
                        fieldcount++;
                snprintf(buf, len, "%d", fieldcount);
        } else {
                ast_log(LOG_ERROR, "Out of memory\n");
                strncpy(buf, "1", len);
        }
        return buf;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function fieldqty_function = {
        .name = "FIELDQTY",
        .synopsis = "Count the fields, with an arbitrary delimiter",
        .syntax = "FIELDQTY(<varname>,<delim>)",
        .read = function_fieldqty,
};

static char *builtin_function_regex(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        char *ret_true = "1", *ret_false = "0", *ret;
        char *arg, *earg, *tmp, errstr[256] = "";
        int errcode;
        regex_t regexbuf;

        ret = ret_false; /* convince me otherwise */
        tmp = ast_strdupa(data);
        if (tmp) {
                /* Regex in quotes */
                arg = strchr(tmp, '"');
                if (arg) {
                        arg++;
                        earg = strrchr(arg, '"');
                        if (earg) {
                                *earg = '\0';
                        }
                } else {
                        arg = tmp;
                }

                if ((errcode = regcomp(&regexbuf, arg, REG_EXTENDED | 
REG_NOSUB))) {
                        regerror(errcode, &regexbuf, errstr, sizeof(errstr));
                        ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", 
cmd, data, errstr);
                        ret = NULL;
                } else {
                        ret = regexec(&regexbuf, data, 0, NULL, 0) ? ret_false 
: ret_true;
                }
                regfree(&regexbuf);
        } else {
                ast_log(LOG_ERROR, "Out of memory in %s(%s)\n", cmd, data);
        }

        return ret;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function regex_function = {
        .name = "REGEX",
        .synopsis = "Regular Expression: Returns 1 if data matches regular 
expression.",
        .syntax = "REGEX(\"<regular expression>\" <data>)",
        .read = builtin_function_regex,
};

static char *builtin_function_len(struct ast_channel *chan, char *cmd, char 
*data, char *buf, size_t len) 
{
        int length = 0;
        if (data) {
                length = strlen(data);
        }
        snprintf(buf, len, "%d", length);
        return buf;
}

#ifndef BUILTIN_FUNC
static
#endif
struct ast_custom_function len_function = {
        .name = "LEN",
        .synopsis = "Returns the length of the argument given",
        .syntax = "LEN(<string>)",
        .read = builtin_function_len,
};

--- NEW FILE: pbx_functions.c ---
/*
 * Asterisk -- A telephony toolkit for Linux.
 *
 * Builtin dialplan functions
 * 
 * Copyright (C) 2005, Digium, Inc.
 *
 * Kevin P. Fleming <[EMAIL PROTECTED]>
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 */

#include <sys/types.h>
#include <stdlib.h>

#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "pbx_functions.h"

static char *tdesc = "Builtin dialplan functions";

int unload_module(void)
{
        int x;

        for (x = 0; x < (sizeof(builtins) / sizeof(builtins[0])); x++) {
                ast_custom_function_unregister(builtins[x]);
        }

        return 0;
}

int load_module(void)
{
        int x;

        for (x = 0; x < (sizeof(builtins) / sizeof(builtins[0])); x++) {
                ast_custom_function_register(builtins[x]);
        }

        return 0;
}

char *description(void)
{
        return tdesc;
}

int usecount(void)
{
        return 0;
}

char *key()
{
        return ASTERISK_GPL_KEY;
}

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to