static struct ast_config *config_sqlite(const char *database, const char *table, const char *file, struct ast_config *cfg)
{
	struct ast_variable *new_v, *v;
	struct ast_category *cur_cat;
	char ttable[ARRAY_SIZE];
	int configured = 0, res = 0;
	sqlite3_stmt *stmt = NULL;;
	int cat_metric=0, last_cat_metric=0;
	char sql[ARRAY_SIZE];
	char last[ARRAY_SIZE] = "";
	char path[ARRAY_SIZE];
	sqlite3 *db;
	int running=0;
	int i=0;
	struct ast_config *config;


	/* if the data was not passed from extconfig.conf then get it from sqlite.conf */
	if(!database || ast_strlen_zero(database)) {
		if (!file || !strcmp (file, "res_sqlite.conf"))
			return NULL; // cant configure myself with myself !

		config = ast_config_load ("res_sqlite.conf");
		if (config) {
			for (v = ast_variable_browse (config, "config"); v; v = v->next) {
				if (!strcmp (v->name, "table")) {
					strncpy (ttable, v->value, sizeof (ttable));
					configured++;
				} else if (!strcmp (v->name, "dbfile")) {
					pick_path(v->value,path,ARRAY_SIZE);
					configured++;
				}
			}
			ast_config_destroy (config);
		}
	} else {
		pick_path((char *)database,path,ARRAY_SIZE);
		strncpy (ttable, table, sizeof (ttable));
		configured = 2;
	}

	if (configured < 2)
		return NULL;


	db=open_db(path);
	if (!db)
		return NULL;

	sprintf (sql, "select * from %s where filename='%s' and commented=0 order by filename,cat_metric desc,var_metric asc,id", ttable, file);
	res = sqlite3_prepare(db,sql,0,&stmt,0);

	if (res) {
		ast_log (LOG_WARNING, "SQL select error [%s]!\n[%s]\n\n",sqlite3_errmsg(db), sql);
		return NULL;
	}

	cur_cat = ast_config_get_current_category(cfg);

	/*
	  0 id int
	  1 cat_metric int not null default 0,
	  2 var_metric int not null default 0,
	  3 commented int not null default 0,
	  4 filename varchar(128) not null,
	  5 category varchar(128) not null default 'default',
	  6 var_name varchar(128) not null,
	  7 var_val varchar(128) not null
	*/
	
	running = 1;
	while (running) {
		res = sqlite3_step(stmt);
		running = 1;
		switch( res ){
		case SQLITE_DONE:	running = 0 ; break;
		case SQLITE_BUSY:	sleep(2); running = 2; break ;
		case SQLITE_ERROR:	running = 0; break;
		case SQLITE_MISUSE: running = 0; break;
		case SQLITE_ROW:	
		default: 
			break;
		}	
		if (!running)
			break;
		
		if (running == 2)
			continue;

		if(option_verbose > 4)
			for(i=0;i<8;i++){
				ast_verbose(VERBOSE_PREFIX_3"SQLite Config: %d=%s\n",i,sqlite3_column_text(stmt,i));
			}
		
		if (strcmp (last, sqlite3_column_text(stmt,5)) || last_cat_metric != cat_metric) {
			cur_cat = ast_category_new((char *)sqlite3_column_text(stmt,5));
			if (!cur_cat) {
				ast_log(LOG_WARNING, "Out of memory!\n");
				break;
			}
			strcpy (last, sqlite3_column_text(stmt,5));
			last_cat_metric	= cat_metric;
			ast_category_append(cfg, cur_cat);
		}
		new_v = ast_variable_new ((char *)sqlite3_column_text(stmt,6), (char *)sqlite3_column_text(stmt,7));
		ast_variable_append(cur_cat, new_v);
	}
	
	if ((sqlite3_finalize(stmt))) 
		ast_log(LOG_ERROR,"ERROR: %s\n",sqlite3_errmsg(db));

	return cfg;
}
static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked)
{
	struct ast_str *query, *buffer;
	char buf1[200];
	char *stringp, *line, *pair, *key;
	int last_cat_metric = -1, cat_metric = -1;
	struct ast_category *cat = NULL;
	char *cur_cat = "";
	char *category = "", *var_name = "", *var_val = "";
	struct ast_flags loader_flags = { 0 };

	if (!ast_custom_function_find("CURL")) {
		ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
		return NULL;
	}

	if (!(query = ast_str_thread_get(&query_buf, 100))) {
		return NULL;
	}

	if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
		return NULL;
	}

	ast_uri_encode(file, buf1, sizeof(buf1), ast_uri_http);
	ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1);

	/* Do the CURL query */
	ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));

	/* Line oriented output */
	stringp = ast_str_buffer(buffer);
	cat = ast_config_get_current_category(cfg);

	while ((line = strsep(&stringp, "\r\n"))) {
		if (ast_strlen_zero(line)) {
			continue;
		}

		while ((pair = strsep(&line, "&"))) {
			key = strsep(&pair, "=");
			ast_uri_decode(key, ast_uri_http);
			if (pair) {
				ast_uri_decode(pair, ast_uri_http);
			}

			if (!strcasecmp(key, "category")) {
				category = S_OR(pair, "");
			} else if (!strcasecmp(key, "var_name")) {
				var_name = S_OR(pair, "");
			} else if (!strcasecmp(key, "var_val")) {
				var_val = S_OR(pair, "");
			} else if (!strcasecmp(key, "cat_metric")) {
				cat_metric = pair ? atoi(pair) : 0;
			}
		}

		if (!strcmp(var_name, "#include")) {
			if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked))
				return NULL;
		}

		if (!cat || strcmp(category, cur_cat) || last_cat_metric != cat_metric) {
			if (!(cat = ast_category_new(category, "", 99999)))
				break;
			cur_cat = category;
			last_cat_metric = cat_metric;
			ast_category_append(cfg, cat);
		}
		ast_variable_append(cat, ast_variable_new(var_name, var_val, ""));
	}

	return cfg;
}