Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
	}
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
	}
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
0
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;
}
Пример #11
0
/*!
 * \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);
}
Пример #12
0
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;
	}
	
}
Пример #13
0
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");
}
Пример #14
0
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;
}