app_mysql.c File Reference

MYSQL dialplan application. More...

#include "asterisk.h"
#include <mysql/mysql.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/linkedlists.h"
#include "asterisk/chanvars.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/app.h"
#include "asterisk/config.h"

Include dependency graph for app_mysql.c:

Go to the source code of this file.

Data Structures

struct  ast_MYSQL_id
struct  MYSQLidshead

Defines

#define AST_MYSQL_ID_CONNID   1
#define AST_MYSQL_ID_DUMMY   0
#define AST_MYSQL_ID_FETCHID   3
#define AST_MYSQL_ID_RESID   2
#define EXTRA_LOG   0
#define MYSQL_CONFIG   "app_mysql.conf"
#define MYSQL_CONFIG_OLD   "mysql.conf"

Enumerations

enum  { NULLSTRING, NULLVALUE, EMPTYSTRING }

Functions

static int add_identifier (struct ast_channel *chan, int identifier_type, void *data)
static int add_identifier_and_set_asterisk_int (struct ast_channel *chan, char *varname, int identifier_type, void *data)
static int aMYSQL_clear (struct ast_channel *chan, const char *data)
static int aMYSQL_connect (struct ast_channel *chan, const char *data)
static int aMYSQL_disconnect (struct ast_channel *chan, const char *data)
static int aMYSQL_fetch (struct ast_channel *chan, const char *data)
static int aMYSQL_nextresult (struct ast_channel *chan, const char *data)
static int aMYSQL_query (struct ast_channel *chan, const char *data)
static int aMYSQL_set (struct ast_channel *chan, const char *data)
 AST_MODULE_INFO_STANDARD_DEPRECATED (ASTERISK_GPL_KEY,"Simple Mysql Interface")
static int del_identifier (int identifier, int identifier_type)
static void * find_identifier (int identifier, int identifier_type)
static int load_module (void)
 Load the module.
static void mysql_ds_destroy (void *data)
static void mysql_ds_fixup (void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
static int MYSQL_exec (struct ast_channel *chan, const char *data)
static int safe_scan_int (char **data, char *delim, int def)
static int set_asterisk_int (struct ast_channel *chan, char *varname, int id)
static int unload_module (void)

Variables

struct MYSQLidshead _mysql_ids_head
static ast_mutex_t _mysql_mutex = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static const char app [] = "MYSQL"
static int autoclear = 0
static const char descrip []
static struct ast_datastore_info mysql_ds_info
enum { ... }  nullvalue
static const char synopsis [] = "Do several mySQLy things"


Detailed Description

MYSQL dialplan application.

Definition in file app_mysql.c.


Define Documentation

#define AST_MYSQL_ID_CONNID   1

#define AST_MYSQL_ID_DUMMY   0

Definition at line 108 of file app_mysql.c.

#define AST_MYSQL_ID_FETCHID   3

Definition at line 111 of file app_mysql.c.

#define AST_MYSQL_ID_RESID   2

#define EXTRA_LOG   0

Definition at line 58 of file app_mysql.c.

#define MYSQL_CONFIG   "app_mysql.conf"

Definition at line 106 of file app_mysql.c.

Referenced by load_module().

#define MYSQL_CONFIG_OLD   "mysql.conf"

Definition at line 107 of file app_mysql.c.

Referenced by load_module().


Enumeration Type Documentation

anonymous enum

Enumerator:
NULLSTRING 
NULLVALUE 
EMPTYSTRING 

Definition at line 60 of file app_mysql.c.


Function Documentation

static int add_identifier ( struct ast_channel chan,
int  identifier_type,
void *  data 
) [static]

Definition at line 211 of file app_mysql.c.

References _mysql_ids_head, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_malloc, ast_MYSQL_id::data, ast_MYSQL_id::entries, ast_MYSQL_id::identifier, ast_MYSQL_id::identifier_type, LOG_WARNING, NULL, and ast_MYSQL_id::owner.

Referenced by add_identifier_and_set_asterisk_int().

00212 {
00213    struct ast_MYSQL_id *i = NULL, *j = NULL;
00214    struct MYSQLidshead *headp = &_mysql_ids_head;
00215    int maxidentifier = 0;
00216 
00217    if (AST_LIST_LOCK(headp)) {
00218       ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
00219       return -1;
00220    } else {
00221       i = ast_malloc(sizeof(*i));
00222       AST_LIST_TRAVERSE(headp, j, entries) {
00223          if (j->identifier > maxidentifier) {
00224             maxidentifier = j->identifier;
00225          }
00226       }
00227       i->identifier = maxidentifier + 1;
00228       i->identifier_type = identifier_type;
00229       i->data = data;
00230       i->owner = chan;
00231       AST_LIST_INSERT_HEAD(headp, i, entries);
00232       AST_LIST_UNLOCK(headp);
00233    }
00234    return i->identifier;
00235 }

static int add_identifier_and_set_asterisk_int ( struct ast_channel chan,
char *  varname,
int  identifier_type,
void *  data 
) [static]

Definition at line 277 of file app_mysql.c.

References add_identifier(), and set_asterisk_int().

Referenced by aMYSQL_connect(), aMYSQL_nextresult(), and aMYSQL_query().

00278 {
00279    return set_asterisk_int(chan, varname, add_identifier(chan, identifier_type, data));
00280 }

static int aMYSQL_clear ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 525 of file app_mysql.c.

References ast_log, AST_MYSQL_ID_RESID, ast_strdupa, del_identifier(), find_identifier(), id, LOG_WARNING, NULL, parse(), safe_scan_int(), and strsep().

Referenced by MYSQL_exec().

00526 {
00527    MYSQL_RES *mysqlres;
00528 
00529    int id;
00530    char *parse = ast_strdupa(data);
00531    strsep(&parse, " "); /* eat the first token, we already know it :P */
00532    id = safe_scan_int(&parse, " \n", -1);
00533    if ((mysqlres = find_identifier(id, AST_MYSQL_ID_RESID)) == NULL) {
00534       ast_log(LOG_WARNING, "Invalid result identifier %d passed in aMYSQL_clear\n", id);
00535    } else {
00536       mysql_free_result(mysqlres);
00537       del_identifier(id, AST_MYSQL_ID_RESID);
00538    }
00539 
00540    return 0;
00541 }

static int aMYSQL_connect ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 321 of file app_mysql.c.

References add_identifier_and_set_asterisk_int(), args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_MYSQL_ID_CONNID, AST_NONSTANDARD_APP_ARGS, ast_strdupa, dbcharset, dbhost, dbname, dbpass, dbuser, LOG_WARNING, mysql, NULL, parse(), pbx_builtin_getvar_helper(), and timeout.

Referenced by MYSQL_exec().

00322 {
00323    AST_DECLARE_APP_ARGS(args,
00324       AST_APP_ARG(connect);
00325       AST_APP_ARG(connid);
00326       AST_APP_ARG(dbhost);
00327       AST_APP_ARG(dbuser);
00328       AST_APP_ARG(dbpass);
00329       AST_APP_ARG(dbname);
00330       AST_APP_ARG(dbcharset);
00331    );
00332    MYSQL *mysql;
00333    int timeout;
00334    const char *ctimeout;
00335    unsigned int port = 0;
00336    char *port_str;
00337    char *parse = ast_strdupa(data);
00338  
00339    AST_NONSTANDARD_APP_ARGS(args, parse, ' ');
00340 
00341    if (args.argc < 6) {
00342       ast_log(LOG_WARNING, "MYSQL_connect is missing some arguments\n");
00343       return -1;
00344    }
00345 
00346    if (!(mysql = mysql_init(NULL))) {
00347       ast_log(LOG_WARNING, "mysql_init returned NULL\n");
00348       return -1;
00349    }
00350 
00351    ctimeout = pbx_builtin_getvar_helper(chan, "MYSQL_TIMEOUT");
00352    if (ctimeout && sscanf(ctimeout, "%30d", &timeout) == 1) {
00353       mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&timeout);
00354    }
00355    if(args.dbcharset && strlen(args.dbcharset) > 2){
00356       char set_names[255];
00357       char statement[512];
00358       snprintf(set_names, sizeof(set_names), "SET NAMES %s", args.dbcharset);
00359       mysql_real_escape_string(mysql, statement, set_names, sizeof(set_names));
00360       mysql_options(mysql, MYSQL_INIT_COMMAND, set_names);
00361       mysql_options(mysql, MYSQL_SET_CHARSET_NAME, args.dbcharset);
00362    }
00363 
00364    if ((port_str = strchr(args.dbhost, ':'))) {
00365       *port_str++ = '\0';
00366       if (sscanf(port_str, "%u", &port) != 1) {
00367          ast_log(LOG_WARNING, "Invalid port: '%s'\n", port_str);
00368          port = 0;
00369       }
00370    }
00371 
00372    if (!mysql_real_connect(mysql, args.dbhost, args.dbuser, args.dbpass, args.dbname, port, NULL,
00373 #ifdef CLIENT_MULTI_STATEMENTS
00374          CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS
00375 #elif defined(CLIENT_MULTI_QUERIES)
00376          CLIENT_MULTI_QUERIES
00377 #else
00378          0
00379 #endif
00380       )) {
00381       ast_log(LOG_WARNING, "mysql_real_connect(mysql,%s,%s,dbpass,%s,...) failed(%d): %s\n",
00382             args.dbhost, args.dbuser, args.dbname, mysql_errno(mysql), mysql_error(mysql));
00383       return -1;
00384    }
00385 
00386    add_identifier_and_set_asterisk_int(chan, args.connid, AST_MYSQL_ID_CONNID, mysql);
00387    return 0;
00388 }

static int aMYSQL_disconnect ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 543 of file app_mysql.c.

References ast_log, AST_MYSQL_ID_CONNID, ast_strdupa, del_identifier(), find_identifier(), id, LOG_WARNING, mysql, NULL, parse(), safe_scan_int(), and strsep().

Referenced by MYSQL_exec().

00544 {
00545    MYSQL *mysql;
00546    int id;
00547    char *parse = ast_strdupa(data);
00548    strsep(&parse, " "); /* eat the first token, we already know it :P */
00549 
00550    id = safe_scan_int(&parse, " \n", -1);
00551    if ((mysql = find_identifier(id, AST_MYSQL_ID_CONNID)) == NULL) {
00552       ast_log(LOG_WARNING, "Invalid connection identifier %d passed in aMYSQL_disconnect\n", id);
00553    } else {
00554       mysql_close(mysql);
00555       del_identifier(id, AST_MYSQL_ID_CONNID);
00556    }
00557 
00558    return 0;
00559 }

static int aMYSQL_fetch ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 473 of file app_mysql.c.

References args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_MYSQL_ID_RESID, AST_NONSTANDARD_APP_ARGS, ast_strdupa, EMPTYSTRING, find_identifier(), LOG_WARNING, NULL, NULLSTRING, nullvalue, parse(), pbx_builtin_setvar_helper(), set_asterisk_int(), and strsep().

Referenced by MYSQL_exec().

00474 {
00475    MYSQL_RES *mysqlres;
00476    MYSQL_ROW mysqlrow;
00477    AST_DECLARE_APP_ARGS(args,
00478       AST_APP_ARG(fetch);
00479       AST_APP_ARG(resultvar);
00480       AST_APP_ARG(fetchid);
00481       AST_APP_ARG(vars);
00482    );
00483    char *s5, *parse;
00484    int resultid = -1, numFields, j;
00485 
00486    parse = ast_strdupa(data);
00487    AST_NONSTANDARD_APP_ARGS(args, parse, ' ');
00488    sscanf(args.fetchid, "%30d", &resultid);
00489 
00490    if (args.resultvar && (resultid >= 0) ) {
00491       if ((mysqlres = find_identifier(resultid, AST_MYSQL_ID_RESID)) != NULL) {
00492          /* Grab the next row */
00493          if ((mysqlrow = mysql_fetch_row(mysqlres)) != NULL) {
00494             numFields = mysql_num_fields(mysqlres);
00495             for (j = 0; j < numFields; j++) {
00496                s5 = strsep(&args.vars, " ");
00497                if (s5 == NULL) {
00498                   ast_log(LOG_WARNING, "ast_MYSQL_fetch: More fields (%d) than variables (%d)\n", numFields, j);
00499                   break;
00500                }
00501 
00502                pbx_builtin_setvar_helper(chan, s5, mysqlrow[j] ? mysqlrow[j] :
00503                   nullvalue == NULLSTRING ? "NULL" :
00504                   nullvalue == EMPTYSTRING ? "" :
00505                   NULL);
00506             }
00507             ast_debug(5, "ast_MYSQL_fetch: numFields=%d\n", numFields);
00508             set_asterisk_int(chan, args.resultvar, 1); /* try more rows */
00509          } else {
00510             ast_debug(5, "ast_MYSQL_fetch : EOF\n");
00511             set_asterisk_int(chan, args.resultvar, 0); /* no more rows */
00512          }
00513          return 0;
00514       } else {
00515          set_asterisk_int(chan, args.resultvar, 0);
00516          ast_log(LOG_WARNING, "aMYSQL_fetch: Invalid result identifier %d passed\n", resultid);
00517       }
00518    } else {
00519       ast_log(LOG_WARNING, "aMYSQL_fetch: missing some arguments\n");
00520    }
00521 
00522    return -1;
00523 }

static int aMYSQL_nextresult ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 432 of file app_mysql.c.

References add_identifier_and_set_asterisk_int(), args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_MYSQL_ID_CONNID, AST_MYSQL_ID_RESID, AST_NONSTANDARD_APP_ARGS, ast_strdupa, find_identifier(), LOG_WARNING, mysql, and parse().

Referenced by MYSQL_exec().

00433 {
00434    MYSQL       *mysql;
00435    MYSQL_RES   *mysqlres;
00436    AST_DECLARE_APP_ARGS(args,
00437       AST_APP_ARG(nextresult);
00438       AST_APP_ARG(resultid);
00439       AST_APP_ARG(connid);
00440    );
00441    int connid = -1;
00442    char *parse = ast_strdupa(data);
00443 
00444    AST_NONSTANDARD_APP_ARGS(args, parse, ' ');
00445    sscanf(args.connid, "%30d", &connid);
00446 
00447    if (args.argc != 3 || connid <= 0) {
00448       ast_log(LOG_WARNING, "missing some arguments\n");
00449       return -1;
00450    }
00451 
00452    if (!(mysql = find_identifier(connid, AST_MYSQL_ID_CONNID))) {
00453       ast_log(LOG_WARNING, "Invalid connection identifier %d passed in aMYSQL_query\n", connid);
00454       return -1;
00455    }
00456 
00457    if (mysql_more_results(mysql)) {
00458       mysql_next_result(mysql);
00459       if ((mysqlres = mysql_store_result(mysql))) {
00460          add_identifier_and_set_asterisk_int(chan, args.resultid, AST_MYSQL_ID_RESID, mysqlres);
00461          return 0;
00462       } else if (!mysql_field_count(mysql)) {
00463          return 0;
00464       } else
00465          ast_log(LOG_WARNING, "mysql_store_result() failed on storing next_result\n");
00466    } else
00467       ast_log(LOG_WARNING, "mysql_more_results() result set has no more results\n");
00468 
00469    return 0;
00470 }

static int aMYSQL_query ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 390 of file app_mysql.c.

References add_identifier_and_set_asterisk_int(), args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_MYSQL_ID_CONNID, AST_MYSQL_ID_RESID, AST_NONSTANDARD_APP_ARGS, ast_strdupa, find_identifier(), LOG_WARNING, mysql, and parse().

Referenced by MYSQL_exec().

00391 {
00392    AST_DECLARE_APP_ARGS(args,
00393       AST_APP_ARG(query);
00394       AST_APP_ARG(resultid);
00395       AST_APP_ARG(connid);
00396       AST_APP_ARG(sql);
00397    );
00398    MYSQL       *mysql;
00399    MYSQL_RES   *mysqlres;
00400    int connid;
00401    int mysql_query_res;
00402    char *parse = ast_strdupa(data);
00403 
00404    AST_NONSTANDARD_APP_ARGS(args, parse, ' ');
00405 
00406    if (args.argc != 4 || (connid = atoi(args.connid)) == 0) {
00407       ast_log(LOG_WARNING, "missing some arguments\n");
00408       return -1;
00409    }
00410 
00411    if (!(mysql = find_identifier(connid, AST_MYSQL_ID_CONNID))) {
00412       ast_log(LOG_WARNING, "Invalid connection identifier %s passed in aMYSQL_query\n", args.connid);
00413       return -1;
00414    }
00415 
00416    if ((mysql_query_res = mysql_query(mysql, args.sql)) != 0) {
00417       ast_log(LOG_WARNING, "aMYSQL_query: mysql_query failed. Error: %s\n", mysql_error(mysql));
00418       return -1;
00419    }
00420 
00421    if ((mysqlres = mysql_store_result(mysql))) {
00422       add_identifier_and_set_asterisk_int(chan, args.resultid, AST_MYSQL_ID_RESID, mysqlres);
00423       return 0;
00424    } else if (!mysql_field_count(mysql)) {
00425       return 0;
00426    } else
00427       ast_log(LOG_WARNING, "mysql_store_result() failed on query %s\n", args.sql);
00428 
00429    return -1;
00430 }

static int aMYSQL_set ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 295 of file app_mysql.c.

References args, ast_alloca, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, ast_strdupa, parse(), pbx_builtin_setvar_helper(), tmp(), value, and var.

Referenced by MYSQL_exec().

00296 {
00297    char *var, *tmp, *parse;
00298    AST_DECLARE_APP_ARGS(args,
00299       AST_APP_ARG(set);
00300       AST_APP_ARG(variable);
00301       AST_APP_ARG(value);
00302    );
00303 
00304    parse = ast_strdupa(data);
00305    AST_NONSTANDARD_APP_ARGS(args, parse, ' ');
00306 
00307    if (args.argc == 3) {
00308       var = ast_alloca(6 + strlen(args.variable) + 1);
00309       sprintf(var, "MYSQL_%s", args.variable);
00310 
00311       /* Make the parameter case-insensitive */
00312       for (tmp = var + 6; *tmp; tmp++)
00313          *tmp = toupper(*tmp);
00314 
00315       pbx_builtin_setvar_helper(chan, var, args.value);
00316    }
00317    return 0;
00318 }

AST_MODULE_INFO_STANDARD_DEPRECATED ( ASTERISK_GPL_KEY  ,
"Simple Mysql Interface"   
)

static int del_identifier ( int  identifier,
int  identifier_type 
) [static]

Definition at line 237 of file app_mysql.c.

References _mysql_ids_head, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_MYSQL_id::entries, ast_MYSQL_id::identifier, ast_MYSQL_id::identifier_type, and LOG_WARNING.

Referenced by aMYSQL_clear(), and aMYSQL_disconnect().

00238 {
00239    struct ast_MYSQL_id *i;
00240    struct MYSQLidshead *headp = &_mysql_ids_head;
00241    int found = 0;
00242 
00243    if (AST_LIST_LOCK(headp)) {
00244       ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
00245    } else {
00246       AST_LIST_TRAVERSE(headp, i, entries) {
00247          if ((i->identifier == identifier) &&
00248              (i->identifier_type == identifier_type)) {
00249             AST_LIST_REMOVE(headp, i, entries);
00250             ast_free(i);
00251             found = 1;
00252             break;
00253          }
00254       }
00255       AST_LIST_UNLOCK(headp);
00256    }
00257 
00258    if (found == 0) {
00259       ast_log(LOG_WARNING, "Could not find identifier %d, identifier_type %d in list to delete\n", identifier, identifier_type);
00260       return -1;
00261    } else {
00262       return 0;
00263    }
00264 }

static void* find_identifier ( int  identifier,
int  identifier_type 
) [static]

Definition at line 185 of file app_mysql.c.

References _mysql_ids_head, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_MYSQL_id::data, ast_MYSQL_id::entries, ast_MYSQL_id::identifier, ast_MYSQL_id::identifier_type, LOG_WARNING, and NULL.

Referenced by aMYSQL_clear(), aMYSQL_disconnect(), aMYSQL_fetch(), aMYSQL_nextresult(), and aMYSQL_query().

00186 {
00187    struct MYSQLidshead *headp = &_mysql_ids_head;
00188    struct ast_MYSQL_id *i;
00189    void *res=NULL;
00190    int found=0;
00191 
00192    if (AST_LIST_LOCK(headp)) {
00193       ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
00194    } else {
00195       AST_LIST_TRAVERSE(headp, i, entries) {
00196          if ((i->identifier == identifier) && (i->identifier_type == identifier_type)) {
00197             found = 1;
00198             res = i->data;
00199             break;
00200          }
00201       }
00202       if (!found) {
00203          ast_log(LOG_WARNING, "Identifier %d, identifier_type %d not found in identifier list\n", identifier, identifier_type);
00204       }
00205       AST_LIST_UNLOCK(headp);
00206    }
00207 
00208    return res;
00209 }

static int load_module ( void   )  [static]

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 633 of file app_mysql.c.

References _mysql_ids_head, app, ast_config_destroy(), ast_config_load, AST_LIST_HEAD_INIT, ast_log, ast_register_application, ast_true(), ast_variable_retrieve(), autoclear, descrip, EMPTYSTRING, LOG_WARNING, MYSQL_CONFIG, MYSQL_CONFIG_OLD, MYSQL_exec(), NULLSTRING, NULLVALUE, nullvalue, and synopsis.

00634 {
00635    struct MYSQLidshead *headp = &_mysql_ids_head;
00636    struct ast_flags config_flags = { 0 };
00637    struct ast_config *cfg = ast_config_load(MYSQL_CONFIG, config_flags);
00638    const char *temp;
00639 
00640    if (!cfg) {
00641       /* Backwards compatibility ftw */
00642       cfg = ast_config_load(MYSQL_CONFIG_OLD, config_flags);
00643    }
00644 
00645    if (cfg) {
00646       if ((temp = ast_variable_retrieve(cfg, "general", "nullvalue"))) {
00647          if (!strcasecmp(temp, "nullstring")) {
00648             nullvalue = NULLSTRING;
00649          } else if (!strcasecmp(temp, "emptystring")) {
00650             nullvalue = EMPTYSTRING;
00651          } else if (!strcasecmp(temp, "null")) {
00652             nullvalue = NULLVALUE;
00653          } else {
00654             ast_log(LOG_WARNING, "Illegal value for 'nullvalue': '%s' (must be 'nullstring', 'null', or 'emptystring')\n", temp);
00655          }
00656       }
00657       if ((temp = ast_variable_retrieve(cfg, "general", "autoclear")) && ast_true(temp)) {
00658          autoclear = 1;
00659       }
00660       ast_config_destroy(cfg);
00661    }
00662 
00663    AST_LIST_HEAD_INIT(headp);
00664    return ast_register_application(app, MYSQL_exec, synopsis, descrip);
00665 }

static void mysql_ds_destroy ( void *  data  )  [static]

Definition at line 134 of file app_mysql.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, AST_MYSQL_ID_CONNID, AST_MYSQL_ID_RESID, ast_MYSQL_id::data, ast_MYSQL_id::identifier_type, LOG_WARNING, and ast_MYSQL_id::owner.

00135 {
00136    /* Destroy any IDs owned by the channel */
00137    struct ast_MYSQL_id *i;
00138    if (AST_LIST_LOCK(&_mysql_ids_head)) {
00139       ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
00140    } else {
00141       AST_LIST_TRAVERSE_SAFE_BEGIN(&_mysql_ids_head, i, entries) {
00142          if (i->owner == data) {
00143             AST_LIST_REMOVE_CURRENT(entries);
00144             if (i->identifier_type == AST_MYSQL_ID_CONNID) {
00145                /* Drop connection */
00146                mysql_close(i->data);
00147             } else if (i->identifier_type == AST_MYSQL_ID_RESID) {
00148                /* Drop result */
00149                mysql_free_result(i->data);
00150             }
00151             ast_free(i);
00152          }
00153       }
00154       AST_LIST_TRAVERSE_SAFE_END
00155       AST_LIST_UNLOCK(&_mysql_ids_head);
00156    }
00157 }

static void mysql_ds_fixup ( void *  data,
struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 159 of file app_mysql.c.

References _mysql_ids_head, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, AST_MYSQL_ID_CONNID, AST_MYSQL_ID_RESID, ast_MYSQL_id::data, ast_MYSQL_id::entries, ast_MYSQL_id::identifier_type, LOG_WARNING, and ast_MYSQL_id::owner.

00160 {
00161    /* Destroy any IDs owned by the channel */
00162    struct ast_MYSQL_id *i;
00163    if (AST_LIST_LOCK(&_mysql_ids_head)) {
00164       ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
00165    } else {
00166       AST_LIST_TRAVERSE_SAFE_BEGIN(&_mysql_ids_head, i, entries) {
00167          if (i->owner == data) {
00168             AST_LIST_REMOVE_CURRENT(entries);
00169             if (i->identifier_type == AST_MYSQL_ID_CONNID) {
00170                /* Drop connection */
00171                mysql_close(i->data);
00172             } else if (i->identifier_type == AST_MYSQL_ID_RESID) {
00173                /* Drop result */
00174                mysql_free_result(i->data);
00175             }
00176             ast_free(i);
00177          }
00178       }
00179       AST_LIST_TRAVERSE_SAFE_END
00180       AST_LIST_UNLOCK(&_mysql_ids_head);
00181    }
00182 }

static int MYSQL_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 561 of file app_mysql.c.

References _mysql_mutex, aMYSQL_clear(), aMYSQL_connect(), aMYSQL_disconnect(), aMYSQL_fetch(), aMYSQL_nextresult(), aMYSQL_query(), aMYSQL_set(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, autoclear, ast_datastore::data, LOG_WARNING, NULL, pbx_builtin_setvar_helper(), and result.

Referenced by load_module().

00562 {
00563    int result;
00564    char sresult[10];
00565 
00566    ast_debug(5, "MYSQL: data=%s\n", data);
00567 
00568    if (!data) {
00569       ast_log(LOG_WARNING, "MYSQL requires an argument (see manual)\n");
00570       return -1;
00571    }
00572 
00573    result = 0;
00574 
00575    if (autoclear) {
00576       struct ast_datastore *mysql_store = NULL;
00577 
00578       ast_channel_lock(chan);
00579       mysql_store = ast_channel_datastore_find(chan, &mysql_ds_info, NULL);
00580       if (!mysql_store) {
00581          if (!(mysql_store = ast_datastore_alloc(&mysql_ds_info, NULL))) {
00582             ast_log(LOG_WARNING, "Unable to allocate new datastore.\n");
00583          } else {
00584             mysql_store->data = chan;
00585             ast_channel_datastore_add(chan, mysql_store);
00586          }
00587       }
00588       ast_channel_unlock(chan);
00589    }
00590    ast_mutex_lock(&_mysql_mutex);
00591 
00592    if (strncasecmp("connect", data, strlen("connect")) == 0) {
00593       result = aMYSQL_connect(chan, data);
00594    } else if (strncasecmp("query", data, strlen("query")) == 0) {
00595       result = aMYSQL_query(chan, data);
00596    } else if (strncasecmp("nextresult", data, strlen("nextresult")) == 0) {
00597       result = aMYSQL_nextresult(chan, data);
00598    } else if (strncasecmp("fetch", data, strlen("fetch")) == 0) {
00599       result = aMYSQL_fetch(chan, data);
00600    } else if (strncasecmp("clear", data, strlen("clear")) == 0) {
00601       result = aMYSQL_clear(chan, data);
00602    } else if (strncasecmp("disconnect", data, strlen("disconnect")) == 0) {
00603       result = aMYSQL_disconnect(chan, data);
00604    } else if (strncasecmp("set", data, 3) == 0) {
00605       result = aMYSQL_set(chan, data);
00606    } else {
00607       ast_log(LOG_WARNING, "Unknown argument to MYSQL application : %s\n", data);
00608       result = -1;
00609    }
00610 
00611    ast_mutex_unlock(&_mysql_mutex);
00612 
00613    snprintf(sresult, sizeof(sresult), "%d", result);
00614    pbx_builtin_setvar_helper(chan, "MYSQL_STATUS", sresult);
00615    return 0;
00616 }

static int safe_scan_int ( char **  data,
char *  delim,
int  def 
) [static]

Definition at line 282 of file app_mysql.c.

References end, and strsep().

Referenced by aMYSQL_clear(), and aMYSQL_disconnect().

00283 {
00284    char *end;
00285    int res = def;
00286    char *s = strsep(data, delim);
00287    if (s) {
00288       res = strtol(s, &end, 10);
00289       if (*end)
00290          res = def;  /* not an integer */
00291    }
00292    return res;
00293 }

static int set_asterisk_int ( struct ast_channel chan,
char *  varname,
int  id 
) [static]

Definition at line 266 of file app_mysql.c.

References ast_debug, and pbx_builtin_setvar_helper().

Referenced by add_identifier_and_set_asterisk_int(), and aMYSQL_fetch().

00267 {
00268    if (id >= 0) {
00269       char s[12] = "";
00270       snprintf(s, sizeof(s), "%d", id);
00271       ast_debug(5, "MYSQL: setting var '%s' to value '%s'\n", varname, s);
00272       pbx_builtin_setvar_helper(chan, varname, s);
00273    }
00274    return id;
00275 }

static int unload_module ( void   )  [static]

Definition at line 618 of file app_mysql.c.

References app, and ast_unregister_application().

00619 {
00620    return ast_unregister_application(app);
00621 }


Variable Documentation

ast_mutex_t _mysql_mutex = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

Definition at line 104 of file app_mysql.c.

Referenced by MYSQL_exec().

const char app[] = "MYSQL" [static]

int autoclear = 0 [static]

Definition at line 113 of file app_mysql.c.

Referenced by load_module(), and MYSQL_exec().

const char descrip[] [static]

Definition at line 66 of file app_mysql.c.

Referenced by load_module().

Initial value:

 {
   .type = "APP_ADDON_SQL_MYSQL",
   .destroy = mysql_ds_destroy,
   .chan_fixup = mysql_ds_fixup,
}

Definition at line 118 of file app_mysql.c.

enum { ... } nullvalue

Referenced by aMYSQL_fetch(), and load_module().

const char synopsis[] = "Do several mySQLy things" [static]


Generated on Thu Apr 16 06:28:36 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6