44 #include <mysql/mysql.h> 62 static const char app[] =
"MYSQL";
64 static const char synopsis[] =
"Do several mySQLy things";
67 "MYSQL(): Do several mySQLy things\n" 69 " MYSQL(Set timeout <num>)\n" 70 " Set the connection timeout, in seconds.\n" 71 " MYSQL(Connect connid dhhost[:dbport] dbuser dbpass dbname [dbcharset])\n" 72 " Connects to a database. Arguments contain standard MySQL parameters\n" 73 " passed to function mysql_real_connect. Optional parameter dbcharset\n" 74 " defaults to 'latin1'. Connection identifer returned in ${connid}\n" 75 " MYSQL(Query resultid ${connid} query-string)\n" 76 " Executes standard MySQL query contained in query-string using established\n" 77 " connection identified by ${connid}. Result of query is stored in ${resultid}.\n" 78 " MYSQL(Nextresult resultid ${connid}\n" 79 " If last query returned more than one result set, it stores the next\n" 80 " result set in ${resultid}. It's useful with stored procedures\n" 81 " MYSQL(Fetch fetchid ${resultid} var1 var2 ... varN)\n" 82 " Fetches a single row from a result set contained in ${result_identifier}.\n" 83 " Assigns returned fields to ${var1} ... ${varn}. ${fetchid} is set TRUE\n" 84 " if additional rows exist in result set.\n" 85 " MYSQL(Clear ${resultid})\n" 86 " Frees memory and datastructures associated with result set.\n" 87 " MYSQL(Disconnect ${connid})\n" 88 " Disconnects from named connection to MySQL.\n" 89 " On exit, always returns 0. Sets MYSQL_STATUS to 0 on success and -1 on error.\n";
106 #define MYSQL_CONFIG "app_mysql.conf" 107 #define MYSQL_CONFIG_OLD "mysql.conf" 108 #define AST_MYSQL_ID_DUMMY 0 109 #define AST_MYSQL_ID_CONNID 1 110 #define AST_MYSQL_ID_RESID 2 111 #define AST_MYSQL_ID_FETCHID 3 119 .
type =
"APP_ADDON_SQL_MYSQL",
142 if (i->
owner == data) {
146 mysql_close(i->
data);
149 mysql_free_result(i->
data);
167 if (i->
owner == data) {
171 mysql_close(i->
data);
174 mysql_free_result(i->
data);
203 ast_log(
LOG_WARNING,
"Identifier %d, identifier_type %d not found in identifier list\n", identifier, identifier_type);
215 int maxidentifier = 0;
223 if (j->identifier > maxidentifier) {
224 maxidentifier = j->identifier;
259 ast_log(
LOG_WARNING,
"Could not find identifier %d, identifier_type %d in list to delete\n", identifier, identifier_type);
270 snprintf(s,
sizeof(s),
"%d",
id);
271 ast_debug(5,
"MYSQL: setting var '%s' to value '%s'\n", varname, s);
286 char *s =
strsep(data, delim);
288 res = strtol(s, &end, 10);
307 if (
args.argc == 3) {
309 sprintf(var,
"MYSQL_%s",
args.variable);
312 for (tmp = var + 6; *
tmp; tmp++)
313 *tmp = toupper(*tmp);
334 const char *ctimeout;
335 unsigned int port = 0;
346 if (!(mysql = mysql_init(
NULL))) {
352 if (ctimeout && sscanf(ctimeout,
"%30d", &timeout) == 1) {
353 mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (
void *)&timeout);
355 if(
args.dbcharset && strlen(
args.dbcharset) > 2){
358 snprintf(set_names,
sizeof(set_names),
"SET NAMES %s",
args.dbcharset);
359 mysql_real_escape_string(mysql, statement, set_names,
sizeof(set_names));
360 mysql_options(mysql, MYSQL_INIT_COMMAND, set_names);
361 mysql_options(mysql, MYSQL_SET_CHARSET_NAME,
args.dbcharset);
364 if ((port_str = strchr(
args.dbhost,
':'))) {
366 if (sscanf(port_str,
"%u", &port) != 1) {
373 #ifdef CLIENT_MULTI_STATEMENTS
374 CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS
375 #elif defined(CLIENT_MULTI_QUERIES)
381 ast_log(
LOG_WARNING,
"mysql_real_connect(mysql,%s,%s,dbpass,%s,...) failed(%d): %s\n",
382 args.dbhost,
args.dbuser,
args.dbname, mysql_errno(mysql), mysql_error(mysql));
406 if (
args.argc != 4 || (connid = atoi(
args.connid)) == 0) {
416 if ((mysql_query_res = mysql_query(mysql,
args.sql)) != 0) {
417 ast_log(
LOG_WARNING,
"aMYSQL_query: mysql_query failed. Error: %s\n", mysql_error(mysql));
421 if ((mysqlres = mysql_store_result(mysql))) {
424 }
else if (!mysql_field_count(mysql)) {
445 sscanf(
args.connid,
"%30d", &connid);
447 if (
args.argc != 3 || connid <= 0) {
453 ast_log(
LOG_WARNING,
"Invalid connection identifier %d passed in aMYSQL_query\n", connid);
457 if (mysql_more_results(mysql)) {
458 mysql_next_result(mysql);
459 if ((mysqlres = mysql_store_result(mysql))) {
462 }
else if (!mysql_field_count(mysql)) {
484 int resultid = -1, numFields, j;
488 sscanf(
args.fetchid,
"%30d", &resultid);
490 if (
args.resultvar && (resultid >= 0) ) {
493 if ((mysqlrow = mysql_fetch_row(mysqlres)) !=
NULL) {
494 numFields = mysql_num_fields(mysqlres);
495 for (j = 0; j < numFields; j++) {
498 ast_log(
LOG_WARNING,
"ast_MYSQL_fetch: More fields (%d) than variables (%d)\n", numFields, j);
507 ast_debug(5,
"ast_MYSQL_fetch: numFields=%d\n", numFields);
516 ast_log(
LOG_WARNING,
"aMYSQL_fetch: Invalid result identifier %d passed\n", resultid);
536 mysql_free_result(mysqlres);
552 ast_log(
LOG_WARNING,
"Invalid connection identifier %d passed in aMYSQL_disconnect\n",
id);
584 mysql_store->
data = chan;
592 if (strncasecmp(
"connect", data, strlen(
"connect")) == 0) {
594 }
else if (strncasecmp(
"query", data, strlen(
"query")) == 0) {
596 }
else if (strncasecmp(
"nextresult", data, strlen(
"nextresult")) == 0) {
598 }
else if (strncasecmp(
"fetch", data, strlen(
"fetch")) == 0) {
600 }
else if (strncasecmp(
"clear", data, strlen(
"clear")) == 0) {
602 }
else if (strncasecmp(
"disconnect", data, strlen(
"disconnect")) == 0) {
604 }
else if (strncasecmp(
"set", data, 3) == 0) {
613 snprintf(sresult,
sizeof(sresult),
"%d", result);
647 if (!strcasecmp(temp,
"nullstring")) {
649 }
else if (!strcasecmp(temp,
"emptystring")) {
651 }
else if (!strcasecmp(temp,
"null")) {
654 ast_log(
LOG_WARNING,
"Illegal value for 'nullvalue': '%s' (must be 'nullstring', 'null', or 'emptystring')\n", temp);
static const char synopsis[]
static ast_mutex_t _mysql_mutex
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
static int aMYSQL_clear(struct ast_channel *chan, const char *data)
static int aMYSQL_set(struct ast_channel *chan, const char *data)
static int safe_scan_int(char **data, char *delim, int def)
static int aMYSQL_query(struct ast_channel *chan, const char *data)
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
static int set_asterisk_int(struct ast_channel *chan, char *varname, int id)
static int add_identifier(struct ast_channel *chan, int identifier_type, void *data)
AST_MODULE_INFO_STANDARD_DEPRECATED(ASTERISK_GPL_KEY, "Simple Mysql Interface")
Structure for a data store type.
static int load_module(void)
Load the module.
static int aMYSQL_connect(struct ast_channel *chan, const char *data)
struct MYSQLidshead _mysql_ids_head
static int aMYSQL_nextresult(struct ast_channel *chan, const char *data)
#define ast_mutex_lock(a)
Structure for a data store object.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static char dbpass[MAX_DB_OPTION_SIZE]
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
static void mysql_ds_destroy(void *data)
static int MYSQL_exec(struct ast_channel *chan, const char *data)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
static struct ast_str * dbcharset
static int unload_module(void)
Configuration File Parser.
static void * find_identifier(int identifier, int identifier_type)
static int add_identifier_and_set_asterisk_int(struct ast_channel *chan, char *varname, int identifier_type, void *data)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_config_load(filename, flags)
Load a config file.
#define AST_MYSQL_ID_CONNID
General Asterisk PBX channel definitions.
#define ast_register_application(app, execute, synopsis, description)
Register an application.
static const char descrip[]
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
static int aMYSQL_fetch(struct ast_channel *chan, const char *data)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int del_identifier(int identifier, int identifier_type)
A set of macros to manage forward-linked lists.
#define ast_malloc(len)
A wrapper for malloc()
Core PBX routines and definitions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
struct ast_MYSQL_id * ast_MYSQL_id
static void mysql_ds_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
struct ast_channel * owner
struct ast_MYSQL_id::@1 entries
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
static struct ast_str * dbname
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Structure used to handle boolean flags.
Support for logging to various files, console and syslog Configuration in file logger.conf.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
char * strsep(char **str, const char *delims)
static int aMYSQL_disconnect(struct ast_channel *chan, const char *data)
static struct ast_str * dbuser
Options provided by main asterisk program.
#define ast_datastore_alloc(info, uid)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_MYSQL_ID_RESID
#define ASTERISK_GPL_KEY
The text the key() function should return.
static char dbhost[MAX_DB_OPTION_SIZE]
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static const struct ast_datastore_info mysql_ds_info
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define ast_mutex_unlock(a)
#define AST_APP_ARG(name)
Define an application argument.