Mon Oct 8 12:39:21 2012

Asterisk developer's documentation


db.c File Reference

ASTdb Management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <signal.h>
#include <dirent.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/manager.h"
#include "db1-ast/include/db.h"

Go to the source code of this file.

Defines

#define MAX_DB_FIELD   256

Typedefs

typedef int(*) process_keys_cb (DBT *key, DBT *value, const char *filter, void *data)

Functions

int ast_db_del (const char *family, const char *keys)
 Delete entry in astdb.
int ast_db_deltree (const char *family, const char *keytree)
 Delete one or more entries in astdb If both parameters are NULL, the entire database will be purged. If only keytree is NULL, all entries within the family will be purged. It is an error for keytree to have a value when family is NULL.
void ast_db_freetree (struct ast_db_entry *dbe)
 Free structure created by ast_db_gettree().
int ast_db_get (const char *family, const char *keys, char *value, int valuelen)
 Get key value specified by family/key.
ast_db_entryast_db_gettree (const char *family, const char *keytree)
 Get a list of values within the astdb tree If family is specified, only those keys will be returned. If keytree is specified, subkeys are expected to exist (separated from the key with a slash). If subkeys do not exist and keytree is specified, the tree will consist of either a single entry or NULL will be returned.
int ast_db_put (const char *family, const char *keys, const char *value)
 Store value addressed by family/key.
int astdb_init (void)
static int db_deltree_cb (DBT *key, DBT *value, const char *filter, void *data)
static int db_gettree_cb (DBT *key, DBT *value, const char *filter, void *data)
static int db_show_cb (DBT *key, DBT *value, const char *filter, void *data)
static int db_showkey_cb (DBT *key, DBT *value, const char *filter, void *data)
static void db_sync (void)
static void * db_sync_thread (void *data)
static int dbinit (void)
static const char * dbt_data2str (DBT *dbt)
static const char * dbt_data2str_full (DBT *dbt, const char *def)
static char * handle_cli_database_del (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_database_deltree (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_database_get (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_database_put (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_database_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_database_showkey (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int keymatch (const char *key, const char *prefix)
static int manager_dbdel (struct mansession *s, const struct message *m)
static int manager_dbdeltree (struct mansession *s, const struct message *m)
static int manager_dbget (struct mansession *s, const struct message *m)
static int manager_dbput (struct mansession *s, const struct message *m)
static int process_db_keys (process_keys_cb cb, void *data, const char *filter, int sync)
static int subkeymatch (const char *key, const char *suffix)

Variables

static DB * astdb
static struct ast_cli_entry cli_database []
static ast_cond_t dbcond
static ast_mutex_t dblock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }


Detailed Description

ASTdb Management.

Author:
Mark Spencer <markster@digium.com>
Note:
DB3 is licensed under Sleepycat Public License and is thus incompatible with GPL. To avoid having to make another exception (and complicate licensing even further) we elect to use DB1 which is BSD licensed

Definition in file db.c.


Define Documentation

#define MAX_DB_FIELD   256

Definition at line 107 of file db.c.

Referenced by ast_db_del(), ast_db_deltree(), ast_db_get(), ast_db_gettree(), ast_db_put(), handle_cli_database_get(), handle_cli_database_show(), handle_cli_database_showkey(), manager_dbget(), and process_db_keys().


Typedef Documentation

typedef int(*) process_keys_cb(DBT *key, DBT *value, const char *filter, void *data)

Definition at line 112 of file db.c.


Function Documentation

int ast_db_del ( const char *  family,
const char *  keys 
)

Delete entry in astdb.

Definition at line 318 of file db.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, db_sync(), dbinit(), dblock, and MAX_DB_FIELD.

Referenced by __expire_registry(), ast_privacy_set(), auth_exec(), cache_lookup_internal(), del_exec(), destroy_all_channels(), destroy_association(), dialgroup_refreshdb(), dump_queue_members(), function_db_delete(), handle_cli_database_del(), handle_dbdel(), manager_dbdel(), process_clearcache(), reload_queue_members(), and update_registry().

00319 {
00320    char fullkey[MAX_DB_FIELD];
00321    DBT key;
00322    int res, fullkeylen;
00323 
00324    ast_mutex_lock(&dblock);
00325    if (dbinit()) {
00326       ast_mutex_unlock(&dblock);
00327       return -1;
00328    }
00329    
00330    fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
00331    memset(&key, 0, sizeof(key));
00332    key.data = fullkey;
00333    key.size = fullkeylen + 1;
00334    
00335    res = astdb->del(astdb, &key, 0);
00336    db_sync();
00337    
00338    ast_mutex_unlock(&dblock);
00339 
00340    if (res) {
00341       ast_debug(1, "Unable to find key '%s' in family '%s'\n", keys, family);
00342    }
00343    return res;
00344 }

int ast_db_deltree ( const char *  family,
const char *  keytree 
)

Delete one or more entries in astdb If both parameters are NULL, the entire database will be purged. If only keytree is NULL, all entries within the family will be purged. It is an error for keytree to have a value when family is NULL.

Return values:
-1 An error occurred
>= 0 Number of records deleted

Definition at line 227 of file db.c.

References db_deltree_cb(), MAX_DB_FIELD, prefix, and process_db_keys().

Referenced by ast_privacy_reset(), deltree_exec(), dundi_flush(), handle_cli_database_deltree(), handle_dbdeltree(), iax_provision_reload(), and manager_dbdeltree().

00228 {
00229    char prefix[MAX_DB_FIELD];
00230 
00231    if (family) {
00232       if (keytree) {
00233          snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
00234       } else {
00235          snprintf(prefix, sizeof(prefix), "/%s", family);
00236       }
00237    } else if (keytree) {
00238       return -1;
00239    } else {
00240       prefix[0] = '\0';
00241    }
00242 
00243    return process_db_keys(db_deltree_cb, NULL, prefix, 1);
00244 }

void ast_db_freetree ( struct ast_db_entry dbe  ) 

Free structure created by ast_db_gettree().

Definition at line 607 of file db.c.

References ast_free, last, and ast_db_entry::next.

Referenced by handle_cli_devstate_list(), load_module(), process_clearcache(), and reload_queue_members().

00608 {
00609    struct ast_db_entry *last;
00610    while (dbe) {
00611       last = dbe;
00612       dbe = dbe->next;
00613       ast_free(last);
00614    }
00615 }

int ast_db_get ( const char *  family,
const char *  keys,
char *  value,
int  valuelen 
)

Get key value specified by family/key.

Definition at line 274 of file db.c.

References ast_copy_string(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, dbinit(), dblock, LOG_NOTICE, and MAX_DB_FIELD.

Referenced by ast_privacy_check(), auth_exec(), blacklist_read(), cache_lookup_internal(), check_access(), create_addr(), custom_devstate_callback(), database_increment(), destroy_all_channels(), function_db_delete(), function_db_exists(), function_db_read(), handle_cli_database_get(), handle_dbget(), iax_provision_version(), load_password(), manager_dbget(), populate_addr(), reg_source_db(), and reload_queue_members().

00275 {
00276    char fullkey[MAX_DB_FIELD] = "";
00277    DBT key, data;
00278    int res, fullkeylen;
00279 
00280    ast_mutex_lock(&dblock);
00281    if (dbinit()) {
00282       ast_mutex_unlock(&dblock);
00283       return -1;
00284    }
00285 
00286    fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
00287    memset(&key, 0, sizeof(key));
00288    memset(&data, 0, sizeof(data));
00289    memset(value, 0, valuelen);
00290    key.data = fullkey;
00291    key.size = fullkeylen + 1;
00292 
00293    res = astdb->get(astdb, &key, &data, 0);
00294 
00295    /* Be sure to NULL terminate our data either way */
00296    if (res) {
00297       ast_debug(1, "Unable to find key '%s' in family '%s'\n", keys, family);
00298    } else {
00299 #if 0
00300       printf("Got value of size %d\n", data.size);
00301 #endif
00302       if (data.size) {
00303          ((char *)data.data)[data.size - 1] = '\0';
00304          /* Make sure that we don't write too much to the dst pointer or we don't read too much from the source pointer */
00305          ast_copy_string(value, data.data, (valuelen > data.size) ? data.size : valuelen);
00306       } else {
00307          ast_log(LOG_NOTICE, "Strange, empty value for /%s/%s\n", family, keys);
00308       }
00309    }
00310 
00311    /* Data is not fully isolated for concurrency, so the lock must be extended
00312     * to after the copy to the output buffer. */
00313    ast_mutex_unlock(&dblock);
00314 
00315    return res;
00316 }

struct ast_db_entry* ast_db_gettree ( const char *  family,
const char *  keytree 
)

Get a list of values within the astdb tree If family is specified, only those keys will be returned. If keytree is specified, subkeys are expected to exist (separated from the key with a slash). If subkeys do not exist and keytree is specified, the tree will consist of either a single entry or NULL will be returned.

Resulting tree should be freed by passing the return value to ast_db_freetree() when usage is concluded.

Definition at line 582 of file db.c.

References ast_log(), ast_strlen_zero(), db_gettree_cb(), LOG_WARNING, MAX_DB_FIELD, prefix, and process_db_keys().

Referenced by handle_cli_devstate_list(), load_module(), process_clearcache(), and reload_queue_members().

00583 {
00584    char prefix[MAX_DB_FIELD];
00585    struct ast_db_entry *ret = NULL;
00586 
00587    if (!ast_strlen_zero(family)) {
00588       if (!ast_strlen_zero(keytree)) {
00589          /* Family and key tree */
00590          snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
00591       } else {
00592          /* Family only */
00593          snprintf(prefix, sizeof(prefix), "/%s", family);
00594       }
00595    } else {
00596       prefix[0] = '\0';
00597    }
00598 
00599    if (process_db_keys(db_gettree_cb, &ret, prefix, 0) < 0) {
00600       ast_log(LOG_WARNING, "Database unavailable\n");
00601       return NULL;
00602    }
00603 
00604    return ret;
00605 }

int ast_db_put ( const char *  family,
const char *  keys,
const char *  value 
)

Store value addressed by family/key.

Definition at line 246 of file db.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, db_sync(), dbinit(), dblock, LOG_WARNING, and MAX_DB_FIELD.

Referenced by __analog_ss_thread(), ast_privacy_set(), cache_save(), cache_save_hint(), database_increment(), devstate_write(), dialgroup_refreshdb(), dump_queue_members(), function_db_write(), handle_cli_database_put(), handle_cli_devstate_change(), handle_command_response(), handle_dbput(), iax_provision_build(), manager_dbput(), mgcp_ss(), parse_register_contact(), save_secret(), and update_registry().

00247 {
00248    char fullkey[MAX_DB_FIELD];
00249    DBT key, data;
00250    int res, fullkeylen;
00251 
00252    ast_mutex_lock(&dblock);
00253    if (dbinit()) {
00254       ast_mutex_unlock(&dblock);
00255       return -1;
00256    }
00257 
00258    fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys);
00259    memset(&key, 0, sizeof(key));
00260    memset(&data, 0, sizeof(data));
00261    key.data = fullkey;
00262    key.size = fullkeylen + 1;
00263    data.data = (char *) value;
00264    data.size = strlen(value) + 1;
00265    res = astdb->put(astdb, &key, &data, 0);
00266    db_sync();
00267    ast_mutex_unlock(&dblock);
00268    if (res)
00269       ast_log(LOG_WARNING, "Unable to put value '%s' for key '%s' in family '%s'\n", value, keys, family);
00270 
00271    return res;
00272 }

int astdb_init ( void   ) 

Provided by db.c

Definition at line 776 of file db.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_cond_init, ast_manager_register_xml, ast_pthread_create_background, cli_database, db_sync_thread(), dbinit(), EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, manager_dbdel(), manager_dbdeltree(), manager_dbget(), and manager_dbput().

Referenced by main().

00777 {
00778    pthread_t dont_care;
00779 
00780    ast_cond_init(&dbcond, NULL);
00781    if (ast_pthread_create_background(&dont_care, NULL, db_sync_thread, NULL)) {
00782       return -1;
00783    }
00784 
00785    /* Ignore check_return warning from Coverity for dbinit below */
00786    dbinit();
00787 
00788    ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database));
00789    ast_manager_register_xml("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget);
00790    ast_manager_register_xml("DBPut", EVENT_FLAG_SYSTEM, manager_dbput);
00791    ast_manager_register_xml("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel);
00792    ast_manager_register_xml("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree);
00793    return 0;
00794 }

static int db_deltree_cb ( DBT *  key,
DBT *  value,
const char *  filter,
void *  data 
) [static]

Definition at line 216 of file db.c.

References dbt_data2str_full(), and keymatch().

Referenced by ast_db_deltree().

00217 {
00218    int res = 0;
00219 
00220    if (keymatch(dbt_data2str_full(key, "<bad key>"), filter)) {
00221       astdb->del(astdb, key, 0);
00222       res = 1;
00223    }
00224    return res;
00225 }

static int db_gettree_cb ( DBT *  key,
DBT *  value,
const char *  filter,
void *  data 
) [static]

Definition at line 562 of file db.c.

References ast_malloc, dbt_data2str_full(), ast_db_entry::key, and keymatch().

Referenced by ast_db_gettree().

00563 {
00564    struct ast_db_entry **ret = data;
00565    struct ast_db_entry *cur;
00566    const char *key_s = dbt_data2str_full(key, "<bad key>");
00567    const char *value_s = dbt_data2str_full(value, "<bad value>");
00568    size_t key_slen = strlen(key_s) + 1, value_slen = strlen(value_s) + 1;
00569 
00570    if (keymatch(key_s, filter) && (cur = ast_malloc(sizeof(*cur) + key_slen + value_slen))) {
00571       cur->next = *ret;
00572       cur->key = cur->data + value_slen;
00573       strcpy(cur->data, value_s);
00574       strcpy(cur->key, key_s);
00575       *ret = cur;
00576       return 1;
00577    }
00578 
00579    return 0;
00580 }

static int db_show_cb ( DBT *  key,
DBT *  value,
const char *  filter,
void *  data 
) [static]

Definition at line 461 of file db.c.

References ast_cli(), dbt_data2str_full(), ast_cli_args::fd, and keymatch().

Referenced by handle_cli_database_show().

00462 {
00463    struct ast_cli_args *a = data;
00464    const char *key_s = dbt_data2str_full(key, "<bad key>");
00465    const char *value_s = dbt_data2str_full(value, "<bad value>");
00466 
00467    if (keymatch(key_s, filter)) {
00468       ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
00469       return 1;
00470    }
00471 
00472    return 0;
00473 }

static int db_showkey_cb ( DBT *  key,
DBT *  value,
const char *  filter,
void *  data 
) [static]

Definition at line 516 of file db.c.

References ast_cli(), dbt_data2str_full(), ast_cli_args::fd, and subkeymatch().

Referenced by handle_cli_database_showkey().

00517 {
00518    struct ast_cli_args *a = data;
00519    const char *key_s = dbt_data2str_full(key, "<bad key>");
00520    const char *value_s = dbt_data2str_full(value, "<bad value>");
00521 
00522    if (subkeymatch(key_s, filter)) {
00523       ast_cli(a->fd, "%-50s: %-25s\n", key_s, value_s);
00524       return 1;
00525    }
00526 
00527    return 0;
00528 }

static void db_sync ( void   )  [static]

Definition at line 747 of file db.c.

References ast_cond_signal.

Referenced by ast_db_del(), ast_db_put(), and process_db_keys().

00748 {
00749    ast_cond_signal(&dbcond);
00750 }

static void* db_sync_thread ( void *  data  )  [static]

Definition at line 762 of file db.c.

References ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, and dblock.

Referenced by astdb_init().

00763 {
00764    ast_mutex_lock(&dblock);
00765    for (;;) {
00766       ast_cond_wait(&dbcond, &dblock);
00767       ast_mutex_unlock(&dblock);
00768       sleep(1);
00769       ast_mutex_lock(&dblock);
00770       astdb->sync(astdb, 0);
00771    }
00772 
00773    return NULL;
00774 }

static int dbinit ( void   )  [static]

Definition at line 116 of file db.c.

References ast_config_AST_DB, AST_FILE_MODE, ast_log(), errno, and LOG_WARNING.

Referenced by ast_db_del(), ast_db_get(), ast_db_put(), astdb_init(), load_module(), and process_db_keys().

00117 {
00118    if (!astdb && !(astdb = dbopen(ast_config_AST_DB, O_CREAT | O_RDWR, AST_FILE_MODE, DB_BTREE, NULL))) {
00119       ast_log(LOG_WARNING, "Unable to open Asterisk database '%s': %s\n", ast_config_AST_DB, strerror(errno));
00120       return -1;
00121    }
00122    return 0;
00123 }

static const char* dbt_data2str ( DBT *  dbt  )  [static]

Definition at line 153 of file db.c.

Referenced by dbt_data2str_full().

00154 {
00155    char *data = "";
00156 
00157    if (dbt->size) {
00158       data = dbt->data;
00159       data[dbt->size - 1] = '\0';
00160    }
00161 
00162    return data;
00163 }

static const char* dbt_data2str_full ( DBT *  dbt,
const char *  def 
) [inline, static]

Definition at line 165 of file db.c.

References dbt_data2str(), and S_OR.

Referenced by db_deltree_cb(), db_gettree_cb(), db_show_cb(), db_showkey_cb(), and process_db_keys().

00166 {
00167    return S_OR(dbt_data2str(dbt), def);
00168 }

static char* handle_cli_database_del ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 401 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_del(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00402 {
00403    int res;
00404 
00405    switch (cmd) {
00406    case CLI_INIT:
00407       e->command = "database del";
00408       e->usage =
00409          "Usage: database del <family> <key>\n"
00410          "       Deletes an entry in the Asterisk database for a given\n"
00411          "       family and key.\n";
00412       return NULL;
00413    case CLI_GENERATE:
00414       return NULL;
00415    }
00416 
00417    if (a->argc != 4)
00418       return CLI_SHOWUSAGE;
00419    res = ast_db_del(a->argv[2], a->argv[3]);
00420    if (res) {
00421       ast_cli(a->fd, "Database entry does not exist.\n");
00422    } else {
00423       ast_cli(a->fd, "Database entry removed.\n");
00424    }
00425    return CLI_SUCCESS;
00426 }

static char* handle_cli_database_deltree ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 428 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_deltree(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00429 {
00430    int res;
00431 
00432    switch (cmd) {
00433    case CLI_INIT:
00434       e->command = "database deltree";
00435       e->usage =
00436          "Usage: database deltree <family> [keytree]\n"
00437          "   OR: database deltree <family>[/keytree]\n"
00438          "       Deletes a family or specific keytree within a family\n"
00439          "       in the Asterisk database.  The two arguments may be\n"
00440          "       separated by either a space or a slash.\n";
00441       return NULL;
00442    case CLI_GENERATE:
00443       return NULL;
00444    }
00445 
00446    if ((a->argc < 3) || (a->argc > 4))
00447       return CLI_SHOWUSAGE;
00448    if (a->argc == 4) {
00449       res = ast_db_deltree(a->argv[2], a->argv[3]);
00450    } else {
00451       res = ast_db_deltree(a->argv[2], NULL);
00452    }
00453    if (res < 0) {
00454       ast_cli(a->fd, "Database entries do not exist.\n");
00455    } else {
00456       ast_cli(a->fd, "%d database entries removed.\n",res);
00457    }
00458    return CLI_SUCCESS;
00459 }

static char* handle_cli_database_get ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 373 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_get(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_DB_FIELD, and ast_cli_entry::usage.

00374 {
00375    int res;
00376    char tmp[MAX_DB_FIELD];
00377 
00378    switch (cmd) {
00379    case CLI_INIT:
00380       e->command = "database get";
00381       e->usage =
00382          "Usage: database get <family> <key>\n"
00383          "       Retrieves an entry in the Asterisk database for a given\n"
00384          "       family and key.\n";
00385       return NULL;
00386    case CLI_GENERATE:
00387       return NULL;
00388    }
00389 
00390    if (a->argc != 4)
00391       return CLI_SHOWUSAGE;
00392    res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
00393    if (res) {
00394       ast_cli(a->fd, "Database entry not found.\n");
00395    } else {
00396       ast_cli(a->fd, "Value: %s\n", tmp);
00397    }
00398    return CLI_SUCCESS;
00399 }

static char* handle_cli_database_put ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 346 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_db_put(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00347 {
00348    int res;
00349 
00350    switch (cmd) {
00351    case CLI_INIT:
00352       e->command = "database put";
00353       e->usage =
00354          "Usage: database put <family> <key> <value>\n"
00355          "       Adds or updates an entry in the Asterisk database for\n"
00356          "       a given family, key, and value.\n";
00357       return NULL;
00358    case CLI_GENERATE:
00359       return NULL;
00360    }
00361 
00362    if (a->argc != 5)
00363       return CLI_SHOWUSAGE;
00364    res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
00365    if (res)  {
00366       ast_cli(a->fd, "Failed to update entry\n");
00367    } else {
00368       ast_cli(a->fd, "Updated database successfully\n");
00369    }
00370    return CLI_SUCCESS;
00371 }

static char* handle_cli_database_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 475 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, db_show_cb(), ast_cli_args::fd, MAX_DB_FIELD, prefix, process_db_keys(), and ast_cli_entry::usage.

00476 {
00477    char prefix[MAX_DB_FIELD];
00478    int counter = 0;
00479 
00480    switch (cmd) {
00481    case CLI_INIT:
00482       e->command = "database show";
00483       e->usage =
00484          "Usage: database show [family [keytree]]\n"
00485          "   OR: database show [family[/keytree]]\n"
00486          "       Shows Asterisk database contents, optionally restricted\n"
00487          "       to a given family, or family and keytree. The two arguments\n"
00488          "       may be separated either by a space or by a slash.\n";
00489       return NULL;
00490    case CLI_GENERATE:
00491       return NULL;
00492    }
00493 
00494    if (a->argc == 4) {
00495       /* Family and key tree */
00496       snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
00497    } else if (a->argc == 3) {
00498       /* Family only */
00499       snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
00500    } else if (a->argc == 2) {
00501       /* Neither */
00502       prefix[0] = '\0';
00503    } else {
00504       return CLI_SHOWUSAGE;
00505    }
00506 
00507    if((counter = process_db_keys(db_show_cb, a, prefix, 0)) < 0) {
00508       ast_cli(a->fd, "Database unavailable\n");
00509       return CLI_SUCCESS;
00510    }
00511 
00512    ast_cli(a->fd, "%d results found.\n", counter);
00513    return CLI_SUCCESS;
00514 }

static char* handle_cli_database_showkey ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 530 of file db.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, db_showkey_cb(), ast_cli_args::fd, MAX_DB_FIELD, process_db_keys(), and ast_cli_entry::usage.

00531 {
00532    char suffix[MAX_DB_FIELD];
00533    int counter = 0;
00534 
00535    switch (cmd) {
00536    case CLI_INIT:
00537       e->command = "database showkey";
00538       e->usage =
00539          "Usage: database showkey <keytree>\n"
00540          "       Shows Asterisk database contents, restricted to a given key.\n";
00541       return NULL;
00542    case CLI_GENERATE:
00543       return NULL;
00544    }
00545 
00546    if (a->argc == 3) {
00547       /* Key only */
00548       snprintf(suffix, sizeof(suffix), "/%s", a->argv[2]);
00549    } else {
00550       return CLI_SHOWUSAGE;
00551    }
00552 
00553    if ((counter = process_db_keys(db_showkey_cb, a, suffix, 0)) < 0) {
00554       ast_cli(a->fd, "Database unavailable\n");
00555       return CLI_SUCCESS;
00556    }
00557 
00558    ast_cli(a->fd, "%d results found.\n", counter);
00559    return CLI_SUCCESS;
00560 }

static int keymatch ( const char *  key,
const char *  prefix 
) [inline, static]

Definition at line 126 of file db.c.

Referenced by db_deltree_cb(), db_gettree_cb(), and db_show_cb().

00127 {
00128    int preflen = strlen(prefix);
00129    if (!preflen)
00130       return 1;
00131    if (!strcasecmp(key, prefix))
00132       return 1;
00133    if ((strlen(key) > preflen) && !strncasecmp(key, prefix, preflen)) {
00134       if (key[preflen] == '/')
00135          return 1;
00136    }
00137    return 0;
00138 }

static int manager_dbdel ( struct mansession s,
const struct message m 
) [static]

Definition at line 692 of file db.c.

References ast_db_del(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by astdb_init().

00693 {
00694    const char *family = astman_get_header(m, "Family");
00695    const char *key = astman_get_header(m, "Key");
00696    int res;
00697 
00698    if (ast_strlen_zero(family)) {
00699       astman_send_error(s, m, "No family specified.");
00700       return 0;
00701    }
00702 
00703    if (ast_strlen_zero(key)) {
00704       astman_send_error(s, m, "No key specified.");
00705       return 0;
00706    }
00707 
00708    res = ast_db_del(family, key);
00709    if (res)
00710       astman_send_error(s, m, "Database entry not found");
00711    else
00712       astman_send_ack(s, m, "Key deleted successfully");
00713 
00714    return 0;
00715 }

static int manager_dbdeltree ( struct mansession s,
const struct message m 
) [static]

Definition at line 717 of file db.c.

References ast_db_deltree(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by astdb_init().

00718 {
00719    const char *family = astman_get_header(m, "Family");
00720    const char *key = astman_get_header(m, "Key");
00721    int res;
00722 
00723    if (ast_strlen_zero(family)) {
00724       astman_send_error(s, m, "No family specified.");
00725       return 0;
00726    }
00727 
00728    if (!ast_strlen_zero(key))
00729       res = ast_db_deltree(family, key);
00730    else
00731       res = ast_db_deltree(family, NULL);
00732 
00733    if (res < 0)
00734       astman_send_error(s, m, "Database entry not found");
00735    else
00736       astman_send_ack(s, m, "Key tree deleted successfully");
00737    
00738    return 0;
00739 }

static int manager_dbget ( struct mansession s,
const struct message m 
) [static]

Definition at line 651 of file db.c.

References ast_db_get(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), and MAX_DB_FIELD.

Referenced by astdb_init().

00652 {
00653    const char *id = astman_get_header(m,"ActionID");
00654    char idText[256] = "";
00655    const char *family = astman_get_header(m, "Family");
00656    const char *key = astman_get_header(m, "Key");
00657    char tmp[MAX_DB_FIELD];
00658    int res;
00659 
00660    if (ast_strlen_zero(family)) {
00661       astman_send_error(s, m, "No family specified.");
00662       return 0;
00663    }
00664    if (ast_strlen_zero(key)) {
00665       astman_send_error(s, m, "No key specified.");
00666       return 0;
00667    }
00668 
00669    if (!ast_strlen_zero(id))
00670       snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
00671 
00672    res = ast_db_get(family, key, tmp, sizeof(tmp));
00673    if (res) {
00674       astman_send_error(s, m, "Database entry not found");
00675    } else {
00676       astman_send_ack(s, m, "Result will follow");
00677       astman_append(s, "Event: DBGetResponse\r\n"
00678             "Family: %s\r\n"
00679             "Key: %s\r\n"
00680             "Val: %s\r\n"
00681             "%s"
00682             "\r\n",
00683             family, key, tmp, idText);
00684       astman_append(s, "Event: DBGetComplete\r\n"
00685             "%s"
00686             "\r\n",
00687             idText);
00688    }
00689    return 0;
00690 }

static int manager_dbput ( struct mansession s,
const struct message m 
) [static]

Definition at line 626 of file db.c.

References ast_db_put(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.

Referenced by astdb_init().

00627 {
00628    const char *family = astman_get_header(m, "Family");
00629    const char *key = astman_get_header(m, "Key");
00630    const char *val = astman_get_header(m, "Val");
00631    int res;
00632 
00633    if (ast_strlen_zero(family)) {
00634       astman_send_error(s, m, "No family specified");
00635       return 0;
00636    }
00637    if (ast_strlen_zero(key)) {
00638       astman_send_error(s, m, "No key specified");
00639       return 0;
00640    }
00641 
00642    res = ast_db_put(family, key, S_OR(val, ""));
00643    if (res) {
00644       astman_send_error(s, m, "Failed to update entry");
00645    } else {
00646       astman_send_ack(s, m, "Updated database successfully");
00647    }
00648    return 0;
00649 }

static int process_db_keys ( process_keys_cb  cb,
void *  data,
const char *  filter,
int  sync 
) [static]

Definition at line 170 of file db.c.

References ast_mutex_lock, ast_mutex_unlock, db_sync(), dbinit(), dblock, dbt_data2str_full(), last, MAX_DB_FIELD, and MIN.

Referenced by ast_db_deltree(), ast_db_gettree(), handle_cli_database_show(), and handle_cli_database_showkey().

00171 {
00172    DBT key = { 0, }, value = { 0, }, last_key = { 0, };
00173    int counter = 0;
00174    int res, last = 0;
00175    char last_key_s[MAX_DB_FIELD];
00176 
00177    ast_mutex_lock(&dblock);
00178    if (dbinit()) {
00179       ast_mutex_unlock(&dblock);
00180       return -1;
00181    }
00182 
00183    /* Somehow, the database can become corrupted such that astdb->seq will continue looping through
00184     * the database indefinitely. The pointer to last_key.data ends up getting re-used by the BDB lib
00185     * so this specifically queries for the last entry, makes a copy of the key, and then uses it as
00186     * a sentinel to avoid repeatedly looping over the list. */
00187 
00188    if (astdb->seq(astdb, &last_key, &value, R_LAST)) {
00189       /* Empty database */
00190       ast_mutex_unlock(&dblock);
00191       return 0;
00192    }
00193 
00194    memcpy(last_key_s, last_key.data, MIN(last_key.size - 1, sizeof(last_key_s)));
00195    last_key_s[last_key.size - 1] = '\0';
00196    for (res = astdb->seq(astdb, &key, &value, R_FIRST);
00197          !res;
00198          res = astdb->seq(astdb, &key, &value, R_NEXT)) {
00199       /* The callback might delete the key, so we have to check it before calling */
00200       last = !strcmp(dbt_data2str_full(&key, "<bad key>"), last_key_s);
00201       counter += cb(&key, &value, filter, data);
00202       if (last) {
00203          break;
00204       }
00205    }
00206 
00207    if (sync) {
00208       db_sync();
00209    }
00210 
00211    ast_mutex_unlock(&dblock);
00212 
00213    return counter;
00214 }

static int subkeymatch ( const char *  key,
const char *  suffix 
) [inline, static]

Definition at line 140 of file db.c.

Referenced by db_showkey_cb().

00141 {
00142    int suffixlen = strlen(suffix);
00143    if (suffixlen) {
00144       const char *subkey = key + strlen(key) - suffixlen;
00145       if (subkey < key)
00146          return 0;
00147       if (!strcasecmp(subkey, suffix))
00148          return 1;
00149    }
00150    return 0;
00151 }


Variable Documentation

DB* astdb [static]

Definition at line 109 of file db.c.

struct ast_cli_entry cli_database[] [static]

Definition at line 617 of file db.c.

Referenced by astdb_init().

ast_cond_t dbcond [static]

Definition at line 111 of file db.c.

ast_mutex_t dblock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 110 of file db.c.

Referenced by ast_db_del(), ast_db_get(), ast_db_put(), db_sync_thread(), and process_db_keys().


Generated on Mon Oct 8 12:39:21 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7