int ast_db_deltree(const char *family, const char *keytree) { sqlite3_stmt *stmt = deltree_stmt; char prefix[MAX_DB_FIELD]; int res = 0; if (!ast_strlen_zero(family)) { if (!ast_strlen_zero(keytree)) { /* Family and key tree */ snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree); } else { /* Family only */ snprintf(prefix, sizeof(prefix), "/%s", family); } } else { prefix[0] = '\0'; stmt = deltree_all_stmt; } ast_mutex_lock(&dblock); if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) { ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb)); res = -1; } else if (sqlite3_step(stmt) != SQLITE_DONE) { ast_log(LOG_WARNING, "Couldn't execute stmt: %s\n", sqlite3_errmsg(astdb)); res = -1; } res = sqlite3_changes(astdb); sqlite3_reset(stmt); db_sync(); ast_mutex_unlock(&dblock); return res; }
static char *handle_cli_database_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { switch (cmd) { case CLI_INIT: e->command = "database query"; e->usage = "Usage: database query \"<SQL Statement>\"\n" " Run a user-specified SQL query on the database. Be careful.\n"; return NULL; case CLI_GENERATE: return NULL; } if (a->argc != 3) { return CLI_SHOWUSAGE; } ast_mutex_lock(&dblock); db_execute_sql(a->argv[2], display_results, a); db_sync(); /* Go ahead and sync the db in case they write */ ast_mutex_unlock(&dblock); return CLI_SUCCESS; }
static void astdb_shutdown(void) { ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database)); ast_manager_unregister("DBGet"); ast_manager_unregister("DBPut"); ast_manager_unregister("DBDel"); ast_manager_unregister("DBDelTree"); ast_mutex_lock(&dblock); doexit = 1; db_sync(); ast_mutex_unlock(&dblock); pthread_join(syncthread, NULL); #if defined(DEBUG_FD_LEAKS) && defined(close) /* DEBUG_FD_LEAKS causes conflicting define of close() in asterisk.h */ #undef close #endif if (astdb) { astdb->close(astdb); astdb = NULL; } }
int ast_db_del(const char *family, const char *key) { char fullkey[MAX_DB_FIELD]; size_t fullkey_len; int res = 0; if (strlen(family) + strlen(key) + 2 > sizeof(fullkey) - 1) { ast_log(LOG_WARNING, "Family and key length must be less than %zu bytes\n", sizeof(fullkey) - 3); return -1; } fullkey_len = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, key); ast_mutex_lock(&dblock); if (sqlite3_bind_text(del_stmt, 1, fullkey, fullkey_len, SQLITE_STATIC) != SQLITE_OK) { ast_log(LOG_WARNING, "Couldn't bind key to stmt: %s\n", sqlite3_errmsg(astdb)); res = -1; } else if (sqlite3_step(del_stmt) != SQLITE_DONE) { ast_debug(1, "Unable to find key '%s' in family '%s'\n", key, family); res = -1; } sqlite3_reset(del_stmt); db_sync(); ast_mutex_unlock(&dblock); return res; }
int ast_db_put(const char *family, const char *keys, const char *value) { char fullkey[MAX_DB_FIELD]; DBT key, data; int res, fullkeylen; ast_mutex_lock(&dblock); if (dbinit()) { ast_mutex_unlock(&dblock); return -1; } fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = fullkey; key.size = fullkeylen + 1; data.data = (char *) value; data.size = strlen(value) + 1; res = astdb->put(astdb, &key, &data, 0); db_sync(); ast_mutex_unlock(&dblock); if (res) ast_log(LOG_WARNING, "Unable to put value '%s' for key '%s' in family '%s'\n", value, keys, family); return res; }
int ast_db_del(const char *family, const char *keys) { char fullkey[MAX_DB_FIELD]; DBT key; int res, fullkeylen; ast_mutex_lock(&dblock); if (dbinit()) { ast_mutex_unlock(&dblock); return -1; } fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); memset(&key, 0, sizeof(key)); key.data = fullkey; key.size = fullkeylen + 1; res = astdb->del(astdb, &key, 0); db_sync(); ast_mutex_unlock(&dblock); if (res) { ast_debug(1, "Unable to find key '%s' in family '%s'\n", keys, family); } return res; }
void gp_all_dev_enable(int fd, short event, void *arg) { gp_reconnect(0); db_sync(); evutil_timerclear(&gp_cfg.scan_dev_interval); gp_cfg.scan_dev_interval.tv_sec=20; if ( evtimer_add(&gp_cfg.ev_scan_dev, &gp_cfg.scan_dev_interval) < 0) syslog(LOG_ERR, "event_add.evkeep setup: %m"); zprintf(7, "Reseting activ for all devs. Was mask: 0x%016llX, [%s]\n", cmd_get_dev_bvector(), cmd_get_dev_vector()); int i; for(i=1;i<=255;i++) { devices[i].timeout_count=0; } }
int log_async_off (logbase_t * base) { int rc; if (base->fasync == 0) { syslog(LOG_ERR, "log_async_off(): not locked"); return IO_ERROR; } db_sync(base->fd); rc = db_unlock(base->fd); if (rc < 0) return rc; base->fasync = 0; return 0; }
/*! * \internal * \brief Invoke a callback function on all keys, using given data and filter. * * \param cb Callback function to invoke (itself returns number of keys it affected). * \param data Value to pass to cb's data param. * \param filter Value to pass to cb's filter param. * \param sync If non-zero, call db_sync() when done. * \return Number of keys affected by the callback, or -1 if database is unavailable. */ static int process_db_keys(process_keys_cb cb, void *data, const char *filter, int sync) { DBT key = { 0, }, value = { 0, }, last_key = { 0, }; int counter = 0; int res, last = 0; char last_key_s[MAX_DB_FIELD]; ast_mutex_lock(&dblock); if (dbinit()) { ast_mutex_unlock(&dblock); return -1; } /* Somehow, the database can become corrupted such that astdb->seq will continue looping through * the database indefinitely. The pointer to last_key.data ends up getting re-used by the BDB lib * so this specifically queries for the last entry, makes a copy of the key, and then uses it as * a sentinel to avoid repeatedly looping over the list. */ if (astdb->seq(astdb, &last_key, &value, R_LAST)) { /* Empty database */ ast_mutex_unlock(&dblock); return 0; } memcpy(last_key_s, last_key.data, MIN(last_key.size - 1, sizeof(last_key_s))); last_key_s[last_key.size - 1] = '\0'; for (res = astdb->seq(astdb, &key, &value, R_FIRST); !res; res = astdb->seq(astdb, &key, &value, R_NEXT)) { /* The callback might delete the key, so we have to check it before calling */ last = !strcmp(dbt_data2str_full(&key, "<bad key>"), last_key_s); counter += cb(&key, &value, filter, data); if (last) { break; } } if (sync) { db_sync(); } ast_mutex_unlock(&dblock); return counter; }
static int db_create_astdb(void) { int res = 0; if (!create_astdb_stmt) { init_stmt(&create_astdb_stmt, create_astdb_stmt_sql, sizeof(create_astdb_stmt_sql)); } ast_mutex_lock(&dblock); if (sqlite3_step(create_astdb_stmt) != SQLITE_DONE) { ast_log(LOG_WARNING, "Couldn't create astdb table: %s\n", sqlite3_errmsg(astdb)); res = -1; } sqlite3_reset(create_astdb_stmt); db_sync(); ast_mutex_unlock(&dblock); return res; }
/*! * \internal * \brief Clean up resources on Asterisk shutdown */ static void astdb_atexit(void) { ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database)); ast_manager_unregister("DBGet"); ast_manager_unregister("DBPut"); ast_manager_unregister("DBDel"); ast_manager_unregister("DBDelTree"); /* Set doexit to 1 to kill thread. db_sync must be called with * mutex held. */ doexit = 1; ast_mutex_lock(&dblock); db_sync(); ast_mutex_unlock(&dblock); pthread_join(syncthread, NULL); ast_mutex_lock(&dblock); clean_statements(); if (sqlite3_close(astdb) == SQLITE_OK) { astdb = NULL; } ast_mutex_unlock(&dblock); }
void db_exec(char cmd[]) { uint32_t tmp; uint32_t i, pos; uint32_t len = strlen(cmd); bool is_valid = false; char name[CMD_BUF_LEN]; uint8_t data[CMD_BUF_LEN]; switch(cmd[0]) { case 'h': for(i = 2; i < NAME_MAX_LEN; i++) { if('=' == cmd[i]) { is_valid = true; cmd[i] = 0; break; } } if(is_valid) { for(i = 0; 0 != cmd[i + 1]; i++) { name[i] = cmd[i + 1]; } sscanf(cmd + 2 + i, "%32x", &tmp); db_save(name, (uint8_t*)(&tmp), sizeof(uint32_t)); tmp = 0; db_read(name, (uint8_t*)(&tmp)); printf("\nname:%s\nhex:0x%x saved.\n", name, tmp); } else { printf("\nInvalid hex\n"); } break; case 'w': for(i = 1; i < NAME_MAX_LEN; i++) { if('=' == cmd[i]) { is_valid = true; cmd[i] = 0; break; } } if(is_valid) { for(i = 1; cmd[i] != 0; i++) { name[i - 1] = cmd[i]; } name[i - 1] = 0; pos = i + 1; for(i = 0; '\n' != cmd[pos + i]; i++) { data[i] = cmd[pos + i]; } data[i] = 0; printf("\nname:%s,data:%s\n", (char*)name, (char*)data); db_save((char*)name, data, i); } else { printf("\nWrong code to write\n"); } break; case 'r': for(i = 1; i < NAME_MAX_LEN; i++) { name[i - 1] = cmd[i]; if('\n' == cmd[i]) { name[i - 1] = 0; break; } } db_read((char*)name, data); printf("\n%s=%s\n", name, data); break; case 'd': for(i = 1; i < NAME_MAX_LEN; i++) { name[i - 1] = cmd[i]; if('\n' == cmd[i]) { name[i - 1] = 0; break; } } db_delete((char*)name); printf("\n%s deleted\n", name); break; case 's': db_sync(); printf("\nsync done\n"); break; default: #ifdef DEBUG_DB_EXEC printf("\nUnrecognised code\n"); #endif break; } }
void db_close(register struct db_i *dbip) { register int i; register struct directory *dp, *nextdp; if (!dbip) return; RT_CK_DBI(dbip); if (RT_G_DEBUG&DEBUG_DB) bu_log("db_close(%s) %p uses=%d\n", dbip->dbi_filename, (void *)dbip, dbip->dbi_uses); bu_semaphore_acquire(BU_SEM_LISTS); if ((--dbip->dbi_uses) > 0) { bu_semaphore_release(BU_SEM_LISTS); /* others are still using this database */ return; } bu_semaphore_release(BU_SEM_LISTS); /* ready to free the database -- use count is now zero */ /* free up any mapped files */ if (dbip->dbi_mf) { /* * We're using an instance of a memory mapped file. * We have two choices: * Either dissociate from the memory mapped file * by clearing dbi_mf->apbuf, or * keeping our already-scanned dbip ready for * further use, with our dbi_uses counter at 0. * For speed of re-open, at the price of some address space, * the second choice is taken. */ bu_close_mapped_file(dbip->dbi_mf); bu_free_mapped_files(0); dbip->dbi_mf = (struct bu_mapped_file *)NULL; } /* try to ensure/encourage that the file is written out */ db_sync(dbip); if (dbip->dbi_fp) { fclose(dbip->dbi_fp); } if (dbip->dbi_title) bu_free(dbip->dbi_title, "dbi_title"); if (dbip->dbi_filename) bu_free(dbip->dbi_filename, "dbi_filename"); db_free_anim(dbip); rt_color_free(); /* Free MaterHead list */ /* Release map of database holes */ rt_mempurge(&(dbip->dbi_freep)); rt_memclose(); dbip->dbi_inmem = NULL; /* sanity */ bu_ptbl_free(&dbip->dbi_clients); /* Free all directory entries */ for (i = 0; i < RT_DBNHASH; i++) { for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL;) { RT_CK_DIR(dp); nextdp = dp->d_forw; RT_DIR_FREE_NAMEP(dp); /* frees d_namep */ if ((dp->d_flags & RT_DIR_INMEM) && (dp->d_un.ptr != NULL)) { bu_free(dp->d_un.ptr, "db_close d_un.ptr"); dp->d_un.ptr = NULL; dp->d_len = 0; } /* Put 'dp' back on the freelist */ dp->d_forw = rt_uniresource.re_directory_hd; rt_uniresource.re_directory_hd = dp; /* null'ing the forward pointer here is a huge * memory leak as it causes the loss of all * nodes on the freelist except the first. * (so don't do it) */ dp = nextdp; } dbip->dbi_Head[i] = RT_DIR_NULL; /* sanity*/ } if (dbip->dbi_filepath != NULL) { bu_free_argv(2, dbip->dbi_filepath); dbip->dbi_filepath = NULL; /* sanity */ } bu_free((char *)dbip, "struct db_i"); }
int ged_concat(struct ged *gedp, int argc, const char *argv[]) { struct db_i *newdbp; struct directory *dp; Tcl_HashTable name_tbl; Tcl_HashTable used_names_tbl; Tcl_HashEntry *ptr; Tcl_HashSearch search; struct bu_attribute_value_set g_avs; const char *cp; char *colorTab; struct ged_concat_data cc_data; const char *oldfile; static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]"; int importUnits = 0; int importTitle = 0; int importColorTable = 0; int saveGlobalAttrs = 0; int c; const char *commandName; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } bu_vls_init(&cc_data.affix); cc_data.copy_mode = 0; commandName = argv[0]; /* process args */ bu_optind = 1; bu_opterr = 0; while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) { switch (c) { case 'u': importUnits = 1; break; case 't': importTitle = 1; break; case 'c': importColorTable = 1; break; case 'p': cc_data.copy_mode |= AUTO_PREFIX; break; case 's': cc_data.copy_mode |= AUTO_SUFFIX; break; default: { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); bu_vls_free(&cc_data.affix); return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); return GED_ERROR; } oldfile = argv[0]; argc--; argv++; if (cc_data.copy_mode) { /* specified suffix or prefix explicitly */ if (cc_data.copy_mode & AUTO_PREFIX) { if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_PREFIX; } } else if (cc_data.copy_mode & AUTO_SUFFIX) { if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_SUFFIX; } } else { bu_vls_free(&cc_data.affix); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); return GED_ERROR; } } else { /* no prefix/suffix preference, use prefix */ cc_data.copy_mode |= AUTO_PREFIX; if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_PREFIX; } } if (db_version(gedp->ged_wdbp->dbip) < 5) { if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) { bu_log("ERROR: affix [%s] is too long for v%d\n", bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip)); bu_vls_free(&cc_data.affix); return GED_ERROR; } } /* open the input file */ if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) { bu_vls_free(&cc_data.affix); perror(oldfile); bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database file %s", commandName, oldfile); return GED_ERROR; } if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) { bu_vls_free(&cc_data.affix); bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible, use dbupgrade on %s first", commandName, gedp->ged_wdbp->dbip->dbi_filename); return GED_ERROR; } db_dirbuild(newdbp); cc_data.new_dbip = newdbp; cc_data.old_dbip = gedp->ged_wdbp->dbip; /* visit each directory pointer in the input database */ Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS); Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS); if (importUnits || importTitle || importColorTable) { saveGlobalAttrs = 1; } FOR_ALL_DIRECTORY_START(dp, newdbp) { if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { if (saveGlobalAttrs) { if (db5_get_attributes(newdbp, &g_avs, dp)) { bu_vls_printf(gedp->ged_result_str, "%s: Can't get global attributes from %s", commandName, oldfile); return GED_ERROR; } } continue; } copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl, &used_names_tbl, &cc_data); } FOR_ALL_DIRECTORY_END; bu_vls_free(&cc_data.affix); rt_mempurge(&(newdbp->dbi_freep)); /* Free all the directory entries, and close the input database */ db_close(newdbp); if (importColorTable) { colorTab = bu_strdup(bu_avs_get(&g_avs, "regionid_colortable")); db5_import_color_table(colorTab); bu_free(colorTab, "colorTab"); } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "regionid_colortable"); } if (importTitle) { if ((cp = bu_avs_get(&g_avs, "title")) != NULL) { char *oldTitle = gedp->ged_wdbp->dbip->dbi_title; gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp); if (oldTitle) { bu_free(oldTitle, "old title"); } } } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "title"); } if (importUnits) { if ((cp = bu_avs_get(&g_avs, "units")) != NULL) { double dd; if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) { bu_log("copy_object(%s): improper database, %s object attribute 'units'=%s is invalid\n", oldfile, DB5_GLOBAL_OBJECT_NAME, cp); bu_avs_remove(&g_avs, "units"); } else { gedp->ged_wdbp->dbip->dbi_local2base = dd; gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd; } } } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "units"); } if (saveGlobalAttrs) { dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_NOISY); db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip); } db_sync(gedp->ged_wdbp->dbip); /* force changes to disk */ /* Free the Hash tables */ ptr = Tcl_FirstHashEntry(&name_tbl, &search); while (ptr) { bu_free((char *)Tcl_GetHashValue(ptr), "new name"); ptr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&name_tbl); Tcl_DeleteHashTable(&used_names_tbl); return GED_OK; }