func_db.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2005-2006, Russell Bryant <russelb@clemson.edu> 
00005  *
00006  * func_db.c adapted from the old app_db.c, copyright by the following people 
00007  * Copyright (C) 2005, Mark Spencer <markster@digium.com>
00008  * Copyright (C) 2003, Jefferson Noxon <jeff@debian.org>
00009  *
00010  * See http://www.asterisk.org for more information about
00011  * the Asterisk project. Please do not directly contact
00012  * any of the maintainers of this project for assistance;
00013  * the project provides a web site, mailing lists and IRC
00014  * channels for your use.
00015  *
00016  * This program is free software, distributed under the terms of
00017  * the GNU General Public License Version 2. See the LICENSE file
00018  * at the top of the source tree.
00019  */
00020 
00021 /*! \file
00022  *
00023  * \brief Functions for interaction with the Asterisk database
00024  *
00025  * \author Russell Bryant <russelb@clemson.edu>
00026  *
00027  * \ingroup functions
00028  */
00029 
00030 /*** MODULEINFO
00031    <support_level>core</support_level>
00032  ***/
00033 
00034 #include "asterisk.h"
00035 
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 428418 $")
00037 
00038 #include <regex.h>
00039 
00040 #include "asterisk/module.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/app.h"
00045 #include "asterisk/astdb.h"
00046 
00047 /*** DOCUMENTATION
00048    <function name="DB" language="en_US">
00049       <synopsis>
00050          Read from or write to the Asterisk database.
00051       </synopsis>
00052       <syntax argsep="/">
00053          <parameter name="family" required="true" />
00054          <parameter name="key" required="true" />
00055       </syntax>
00056       <description>
00057          <para>This function will read from or write a value to the Asterisk database.  On a
00058          read, this function returns the corresponding value from the database, or blank
00059          if it does not exist.  Reading a database value will also set the variable
00060          DB_RESULT.  If you wish to find out if an entry exists, use the DB_EXISTS
00061          function.</para>
00062       </description>
00063       <see-also>
00064          <ref type="application">DBdel</ref>
00065          <ref type="function">DB_DELETE</ref>
00066          <ref type="application">DBdeltree</ref>
00067          <ref type="function">DB_EXISTS</ref>
00068       </see-also>
00069    </function>
00070    <function name="DB_EXISTS" language="en_US">
00071       <synopsis>
00072          Check to see if a key exists in the Asterisk database.
00073       </synopsis>
00074       <syntax argsep="/">
00075          <parameter name="family" required="true" />
00076          <parameter name="key" required="true" />
00077       </syntax>
00078       <description>
00079          <para>This function will check to see if a key exists in the Asterisk
00080          database. If it exists, the function will return <literal>1</literal>. If not,
00081          it will return <literal>0</literal>.  Checking for existence of a database key will
00082          also set the variable DB_RESULT to the key's value if it exists.</para>
00083       </description>
00084       <see-also>
00085          <ref type="function">DB</ref>
00086       </see-also>
00087    </function>
00088    <function name="DB_KEYS" language="en_US">
00089       <synopsis>
00090          Obtain a list of keys within the Asterisk database.
00091       </synopsis>
00092       <syntax>
00093          <parameter name="prefix" />
00094       </syntax>
00095       <description>
00096          <para>This function will return a comma-separated list of keys existing
00097          at the prefix specified within the Asterisk database.  If no argument is
00098          provided, then a list of key families will be returned.</para>
00099       </description>
00100    </function>
00101    <function name="DB_DELETE" language="en_US">
00102       <synopsis>
00103          Return a value from the database and delete it.
00104       </synopsis>
00105       <syntax argsep="/">
00106          <parameter name="family" required="true" />
00107          <parameter name="key" required="true" />
00108       </syntax>
00109       <description>
00110          <para>This function will retrieve a value from the Asterisk database
00111          and then remove that key from the database. <variable>DB_RESULT</variable>
00112          will be set to the key's value if it exists.</para>
00113          <note>
00114             <para>If <literal>live_dangerously</literal> in <literal>asterisk.conf</literal>
00115             is set to <literal>no</literal>, this function can only be read from the
00116             dialplan, and not directly from external protocols. It can, however, be
00117             executed as a write operation (<literal>DB_DELETE(family, key)=ignored</literal>)</para>
00118          </note>
00119       </description>
00120       <see-also>
00121          <ref type="application">DBdel</ref>
00122          <ref type="function">DB</ref>
00123          <ref type="application">DBdeltree</ref>
00124       </see-also>
00125    </function>
00126  ***/
00127 
00128 static int function_db_read(struct ast_channel *chan, const char *cmd,
00129              char *parse, char *buf, size_t len)
00130 {
00131    AST_DECLARE_APP_ARGS(args,
00132       AST_APP_ARG(family);
00133       AST_APP_ARG(key);
00134    );
00135 
00136    buf[0] = '\0';
00137 
00138    if (ast_strlen_zero(parse)) {
00139       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
00140       return -1;
00141    }
00142 
00143    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00144 
00145    if (args.argc < 2) {
00146       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)\n");
00147       return -1;
00148    }
00149 
00150    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00151       ast_debug(1, "DB: %s/%s not found in database.\n", args.family, args.key);
00152    } else {
00153       pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00154    }
00155 
00156    return 0;
00157 }
00158 
00159 static int function_db_write(struct ast_channel *chan, const char *cmd, char *parse,
00160               const char *value)
00161 {
00162    AST_DECLARE_APP_ARGS(args,
00163       AST_APP_ARG(family);
00164       AST_APP_ARG(key);
00165    );
00166 
00167    if (ast_strlen_zero(parse)) {
00168       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=<value>\n");
00169       return -1;
00170    }
00171 
00172    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00173 
00174    if (args.argc < 2) {
00175       ast_log(LOG_WARNING, "DB requires an argument, DB(<family>/<key>)=value\n");
00176       return -1;
00177    }
00178 
00179    if (ast_db_put(args.family, args.key, value)) {
00180       ast_log(LOG_WARNING, "DB: Error writing value to database.\n");
00181    }
00182 
00183    return 0;
00184 }
00185 
00186 static struct ast_custom_function db_function = {
00187    .name = "DB",
00188    .read = function_db_read,
00189    .write = function_db_write,
00190 };
00191 
00192 static int function_db_exists(struct ast_channel *chan, const char *cmd,
00193                char *parse, char *buf, size_t len)
00194 {
00195    AST_DECLARE_APP_ARGS(args,
00196       AST_APP_ARG(family);
00197       AST_APP_ARG(key);
00198    );
00199 
00200    buf[0] = '\0';
00201 
00202    if (ast_strlen_zero(parse)) {
00203       ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
00204       return -1;
00205    }
00206 
00207    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00208 
00209    if (args.argc < 2) {
00210       ast_log(LOG_WARNING, "DB_EXISTS requires an argument, DB(<family>/<key>)\n");
00211       return -1;
00212    }
00213 
00214    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00215       strcpy(buf, "0");
00216    } else {
00217       pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00218       strcpy(buf, "1");
00219    }
00220 
00221    return 0;
00222 }
00223 
00224 static struct ast_custom_function db_exists_function = {
00225    .name = "DB_EXISTS",
00226    .read = function_db_exists,
00227    .read_max = 2,
00228 };
00229 
00230 static int function_db_keys(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **result, ssize_t maxlen)
00231 {
00232    size_t parselen = strlen(parse);
00233    struct ast_db_entry *dbe, *orig_dbe;
00234    struct ast_str *escape_buf = NULL;
00235    const char *last = "";
00236 
00237    /* Remove leading and trailing slashes */
00238    while (parse[0] == '/') {
00239       parse++;
00240       parselen--;
00241    }
00242    while (parse[parselen - 1] == '/') {
00243       parse[--parselen] = '\0';
00244    }
00245 
00246    ast_str_reset(*result);
00247 
00248    /* Nothing within the database at that prefix? */
00249    if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
00250       return 0;
00251    }
00252 
00253    for (; dbe; dbe = dbe->next) {
00254       /* Find the current component */
00255       char *curkey = &dbe->key[parselen + 1], *slash;
00256       if (*curkey == '/') {
00257          curkey++;
00258       }
00259       /* Remove everything after the current component */
00260       if ((slash = strchr(curkey, '/'))) {
00261          *slash = '\0';
00262       }
00263 
00264       /* Skip duplicates */
00265       if (!strcasecmp(last, curkey)) {
00266          continue;
00267       }
00268       last = curkey;
00269 
00270       if (orig_dbe != dbe) {
00271          ast_str_append(result, maxlen, ",");
00272       }
00273       ast_str_append_escapecommas(result, maxlen, curkey, strlen(curkey));
00274    }
00275    ast_db_freetree(orig_dbe);
00276    ast_free(escape_buf);
00277    return 0;
00278 }
00279 
00280 static struct ast_custom_function db_keys_function = {
00281    .name = "DB_KEYS",
00282    .read2 = function_db_keys,
00283 };
00284 
00285 static int function_db_delete(struct ast_channel *chan, const char *cmd,
00286                char *parse, char *buf, size_t len)
00287 {
00288    AST_DECLARE_APP_ARGS(args,
00289       AST_APP_ARG(family);
00290       AST_APP_ARG(key);
00291    );
00292 
00293    buf[0] = '\0';
00294 
00295    if (ast_strlen_zero(parse)) {
00296       ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
00297       return -1;
00298    }
00299 
00300    AST_NONSTANDARD_APP_ARGS(args, parse, '/');
00301 
00302    if (args.argc < 2) {
00303       ast_log(LOG_WARNING, "DB_DELETE requires an argument, DB_DELETE(<family>/<key>)\n");
00304       return -1;
00305    }
00306 
00307    if (ast_db_get(args.family, args.key, buf, len - 1)) {
00308       ast_debug(1, "DB_DELETE: %s/%s not found in database.\n", args.family, args.key);
00309    } else {
00310       if (ast_db_del(args.family, args.key)) {
00311          ast_debug(1, "DB_DELETE: %s/%s could not be deleted from the database\n", args.family, args.key);
00312       }
00313    }
00314 
00315    pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
00316 
00317    return 0;
00318 }
00319 
00320 /*!
00321  * \brief Wrapper to execute DB_DELETE from a write operation. Allows execution
00322  * even if live_dangerously is disabled.
00323  */
00324 static int function_db_delete_write(struct ast_channel *chan, const char *cmd, char *parse,
00325    const char *value)
00326 {
00327    /* Throwaway to hold the result from the read */
00328    char buf[128];
00329    return function_db_delete(chan, cmd, parse, buf, sizeof(buf));
00330 }
00331 
00332 static struct ast_custom_function db_delete_function = {
00333    .name = "DB_DELETE",
00334    .read = function_db_delete,
00335    .write = function_db_delete_write,
00336 };
00337 
00338 static int unload_module(void)
00339 {
00340    int res = 0;
00341 
00342    res |= ast_custom_function_unregister(&db_function);
00343    res |= ast_custom_function_unregister(&db_exists_function);
00344    res |= ast_custom_function_unregister(&db_delete_function);
00345    res |= ast_custom_function_unregister(&db_keys_function);
00346 
00347    return res;
00348 }
00349 
00350 static int load_module(void)
00351 {
00352    int res = 0;
00353 
00354    res |= ast_custom_function_register_escalating(&db_function, AST_CFE_BOTH);
00355    res |= ast_custom_function_register(&db_exists_function);
00356    res |= ast_custom_function_register_escalating(&db_delete_function, AST_CFE_READ);
00357    res |= ast_custom_function_register(&db_keys_function);
00358 
00359    return res;
00360 }
00361 
00362 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Database (astdb) related dialplan functions");

Generated on Thu Apr 16 06:27:35 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6