source: freewrt/package/asterisk/patches/asterisk-1.2.0-res_mysql.patch@ 428f140

freewrt_1_0 freewrt_2_0
Last change on this file since 428f140 was 475ad56, checked in by Waldemar Brodkorb <wbx@…>, 20 years ago

add OpenWrt trunk revision 3830.

git-svn-id: svn://www.freewrt.org/trunk/freewrt@1 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100644
File size: 22.8 KB
  • configs/res_mysql.conf.sample

    diff -ruN asterisk-1.2.0-old/configs/res_mysql.conf.sample asterisk-1.2.0-new/configs/res_mysql.conf.sample
    old new  
     1;
     2; Sample configuration for res_config_mysql.c
     3;
     4; The value of dbhost may be either a hostname or an IP address.
     5; If dbhost is commented out or the string "localhost", a connection
     6; to the local host is assumed and dbsock is used instead of TCP/IP
     7; to connect to the server.
     8;
     9[general]
     10;dbhost = 127.0.0.1
     11;dbname = asterisk
     12;dbuser = myuser
     13;dbpass = mypass
     14;dbport = 3306
     15;dbsock = /tmp/mysql.sock
  • res/res_config_mysql.c

    diff -ruN asterisk-1.2.0-old/res/res_config_mysql.c asterisk-1.2.0-new/res/res_config_mysql.c
    old new  
     1/*
     2 * Asterisk -- A telephony toolkit for Linux.
     3 *
     4 * Copyright (C) 1999-2005, Digium, Inc.
     5 *
     6 * Mark Spencer <markster@digium.com>  - Asterisk Author
     7 * Matthew Boehm <mboehm@cytelcom.com> - MySQL RealTime Driver Author
     8 *
     9 * res_config_mysql.c <mysql plugin for RealTime configuration engine>
     10 *
     11 * v2.0   - (10-07-05) - mutex_lock fixes (bug #4973, comment #0034602)
     12 *
     13 * v1.9   - (08-19-05) - Added support to correctly honor the family database specified
     14 *                       in extconfig.conf (bug #4973)
     15 *
     16 * v1.8   - (04-21-05) - Modified return values of update_mysql to better indicate
     17 *                       what really happened.
     18 *
     19 * v1.7   - (01-28-05) - Fixed non-initialization of ast_category struct
     20 *                       in realtime_multi_mysql function which caused segfault.
     21 *
     22 * v1.6   - (00-00-00) - Skipped to bring comments into sync with version number in CVS.
     23 *
     24 * v1.5.1 - (01-26-05) - Added better(?) locking stuff
     25 *
     26 * v1.5   - (01-26-05) - Brought up to date with new config.h changes (bug #3406)
     27 *                     - Added in extra locking provided by georg (bug #3248)
     28 *
     29 * v1.4   - (12-02-04) - Added realtime_multi_mysql function
     30 *                        This function will return an ast_config with categories,
     31 *                        unlike standard realtime_mysql which only returns
     32 *                        a linked list of ast_variables
     33 *
     34 * v1.3   - (12-01-04) - Added support other operators
     35 *                       Ex: =, !=, LIKE, NOT LIKE, RLIKE, etc...
     36 *
     37 * v1.2   - (11-DD-04) - Added reload. Updated load and unload.
     38 *                       Code beautification (doc/CODING-GUIDELINES)
     39 */
     40
     41#include <asterisk/channel.h>
     42#include <asterisk/logger.h>
     43#include <asterisk/config.h>
     44#include <asterisk/module.h>
     45#include <asterisk/lock.h>
     46#include <asterisk/options.h>
     47#include <asterisk/cli.h>
     48#include <asterisk/utils.h>
     49#include <stdlib.h>
     50#include <string.h>
     51#include <mysql.h>
     52#include <mysql_version.h>
     53#include <errmsg.h>
     54
     55static char *res_config_mysql_desc = "MySQL RealTime Configuration Driver";
     56
     57AST_MUTEX_DEFINE_STATIC(mysql_lock);
     58#define RES_CONFIG_MYSQL_CONF "res_mysql.conf"
     59MYSQL         mysql;
     60static char   dbhost[50];
     61static char   dbuser[50];
     62static char   dbpass[50];
     63static char   dbname[50];
     64static char   dbsock[50];
     65static int    dbport;
     66static int    connected;
     67static time_t connect_time;
     68
     69static int parse_config(void);
     70static int mysql_reconnect(const char *database);
     71static int realtime_mysql_status(int fd, int argc, char **argv);
     72
     73STANDARD_LOCAL_USER;
     74
     75LOCAL_USER_DECL;
     76
     77static char cli_realtime_mysql_status_usage[] =
     78"Usage: realtime mysql status\n"
     79"       Shows connection information for the MySQL RealTime driver\n";
     80
     81static struct ast_cli_entry cli_realtime_mysql_status = {
     82        { "realtime", "mysql", "status", NULL }, realtime_mysql_status,
     83        "Shows connection information for the MySQL RealTime driver", cli_realtime_mysql_status_usage, NULL };
     84
     85static struct ast_variable *realtime_mysql(const char *database, const char *table, va_list ap)
     86{
     87        MYSQL_RES *result;
     88        MYSQL_ROW row;
     89        MYSQL_FIELD *fields;
     90        int numFields, i;
     91        char sql[256];
     92        char *stringp;
     93        char *chunk;
     94        char *op;
     95        const char *newparam, *newval;
     96        struct ast_variable *var=NULL, *prev=NULL;
     97
     98        if(!table) {
     99                ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
     100                return NULL;
     101        }
     102
     103        /* Get the first parameter and first value in our list of passed paramater/value pairs */
     104        newparam = va_arg(ap, const char *);
     105        newval = va_arg(ap, const char *);
     106        if(!newparam || !newval)  {
     107                ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
     108                mysql_close(&mysql);
     109                return NULL;
     110        }
     111
     112        /* Create the first part of the query using the first parameter/value pairs we just extracted
     113           If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
     114
     115        if(!strchr(newparam, ' ')) op = " ="; else op = "";
     116
     117        snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval);
     118        while((newparam = va_arg(ap, const char *))) {
     119                newval = va_arg(ap, const char *);
     120                if(!strchr(newparam, ' ')) op = " ="; else op = "";
     121                snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval);
     122        }
     123        va_end(ap);
     124
     125        ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
     126
     127        /* We now have our complete statement; Lets connect to the server and execute it. */
     128        ast_mutex_lock(&mysql_lock);
     129        if(!mysql_reconnect(database)) {
     130                ast_mutex_unlock(&mysql_lock);
     131                return NULL;
     132        }
     133
     134        if(mysql_real_query(&mysql, sql, strlen(sql))) {
     135                ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
     136                ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
     137                ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
     138                ast_mutex_unlock(&mysql_lock);
     139                return NULL;
     140        }
     141
     142        if((result = mysql_store_result(&mysql))) {
     143                numFields = mysql_num_fields(result);
     144                fields = mysql_fetch_fields(result);
     145
     146                while((row = mysql_fetch_row(result))) {
     147                        for(i = 0; i < numFields; i++) {
     148                                stringp = row[i];
     149                                while(stringp) {
     150                                        chunk = strsep(&stringp, ";");
     151                                        if(chunk && !ast_strlen_zero(ast_strip(chunk))) {
     152                                                if(prev) {
     153                                                        prev->next = ast_variable_new(fields[i].name, chunk);
     154                                                        if (prev->next) {
     155                                                                prev = prev->next;
     156                                                        }
     157                                                } else {
     158                                                        prev = var = ast_variable_new(fields[i].name, chunk);
     159                                                }
     160                                        }
     161                                }
     162                        }
     163                }
     164        } else {                               
     165                ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table);
     166        }
     167
     168        ast_mutex_unlock(&mysql_lock);
     169        mysql_free_result(result);
     170
     171        return var;
     172}
     173
     174static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap)
     175{
     176        MYSQL_RES *result;
     177        MYSQL_ROW row;
     178        MYSQL_FIELD *fields;
     179        int numFields, i;
     180        char sql[256];
     181        const char *initfield = NULL;
     182        char *stringp;
     183        char *chunk;
     184        char *op;
     185        const char *newparam, *newval;
     186        struct ast_realloca ra;
     187        struct ast_variable *var=NULL;
     188        struct ast_config *cfg = NULL;
     189        struct ast_category *cat = NULL;
     190
     191        if(!table) {
     192                ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
     193                return NULL;
     194        }
     195       
     196        memset(&ra, 0, sizeof(ra));
     197
     198        cfg = ast_config_new();
     199        if (!cfg) {
     200                /* If I can't alloc memory at this point, why bother doing anything else? */
     201                ast_log(LOG_WARNING, "Out of memory!\n");
     202                return NULL;
     203        }
     204
     205        /* Get the first parameter and first value in our list of passed paramater/value pairs */
     206        newparam = va_arg(ap, const char *);
     207        newval = va_arg(ap, const char *);
     208        if(!newparam || !newval)  {
     209                ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
     210                mysql_close(&mysql);
     211                return NULL;
     212        }
     213
     214        initfield = ast_strdupa(newparam);
     215        if(initfield && (op = strchr(initfield, ' '))) {
     216                *op = '\0';
     217        }
     218
     219        /* Create the first part of the query using the first parameter/value pairs we just extracted
     220           If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
     221
     222        if(!strchr(newparam, ' ')) op = " ="; else op = "";
     223
     224        snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval);
     225        while((newparam = va_arg(ap, const char *))) {
     226                newval = va_arg(ap, const char *);
     227                if(!strchr(newparam, ' ')) op = " ="; else op = "";
     228                snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval);
     229        }
     230
     231        if(initfield) {
     232                snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
     233        }
     234
     235        va_end(ap);
     236
     237        ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
     238
     239        /* We now have our complete statement; Lets connect to the server and execute it. */
     240        ast_mutex_lock(&mysql_lock);
     241        if(!mysql_reconnect(database)) {
     242                ast_mutex_unlock(&mysql_lock);
     243                return NULL;
     244        }
     245
     246        if(mysql_real_query(&mysql, sql, strlen(sql))) {
     247                ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
     248                ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
     249                ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
     250                ast_mutex_unlock(&mysql_lock);
     251                return NULL;
     252        }
     253
     254        if((result = mysql_store_result(&mysql))) {
     255                numFields = mysql_num_fields(result);
     256                fields = mysql_fetch_fields(result);
     257
     258                while((row = mysql_fetch_row(result))) {
     259                        var = NULL;
     260                        cat = ast_category_new("");
     261                        if(!cat) {
     262                                ast_log(LOG_WARNING, "Out of memory!\n");
     263                                continue;
     264                        }
     265                        for(i = 0; i < numFields; i++) {
     266                                stringp = row[i];
     267                                while(stringp) {
     268                                        chunk = strsep(&stringp, ";");
     269                                        if(chunk && !ast_strlen_zero(ast_strip(chunk))) {
     270                                                if(initfield && !strcmp(initfield, fields[i].name)) {
     271                                                        ast_category_rename(cat, chunk);
     272                                                }
     273                                                var = ast_variable_new(fields[i].name, chunk);
     274                                                ast_variable_append(cat, var);
     275                                        }
     276                                }
     277                        }
     278                        ast_category_append(cfg, cat);
     279                }
     280        } else {
     281                ast_log(LOG_WARNING, "MySQL RealTime: Could not find any rows in table %s.\n", table);
     282        }
     283
     284        ast_mutex_unlock(&mysql_lock);
     285        mysql_free_result(result);
     286
     287        return cfg;
     288}
     289
     290static int update_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
     291{
     292        my_ulonglong numrows;
     293        char sql[256];
     294        const char *newparam, *newval;
     295
     296        if(!table) {
     297                ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
     298               return -1;
     299        }
     300
     301        /* Get the first parameter and first value in our list of passed paramater/value pairs */
     302        newparam = va_arg(ap, const char *);
     303        newval = va_arg(ap, const char *);
     304        if(!newparam || !newval)  {
     305                ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
     306                mysql_close(&mysql);
     307               return -1;
     308        }
     309
     310        /* Create the first part of the query using the first parameter/value pairs we just extracted
     311           If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
     312
     313        snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, newval);
     314        while((newparam = va_arg(ap, const char *))) {
     315                newval = va_arg(ap, const char *);
     316                snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, newval);
     317        }
     318        va_end(ap);
     319        snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, lookup);
     320
     321        ast_log(LOG_DEBUG,"MySQL RealTime: Update SQL: %s\n", sql);
     322
     323        /* We now have our complete statement; Lets connect to the server and execute it. */
     324        ast_mutex_lock(&mysql_lock);
     325        if(!mysql_reconnect(database)) {
     326                ast_mutex_unlock(&mysql_lock);
     327                return -1;
     328        }
     329
     330        if(mysql_real_query(&mysql, sql, strlen(sql))) {
     331                ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
     332                ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
     333                ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
     334                ast_mutex_unlock(&mysql_lock);
     335                return -1;
     336        }
     337
     338        numrows = mysql_affected_rows(&mysql);
     339        ast_mutex_unlock(&mysql_lock);
     340
     341        ast_log(LOG_DEBUG,"MySQL RealTime: Updated %llu rows on table: %s\n", numrows, table);
     342
     343        /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
     344         * An integer greater than zero indicates the number of rows affected
     345         * Zero indicates that no records were updated
     346         * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
     347        */
     348
     349        if(numrows >= 0)
     350                return (int)numrows;
     351
     352        return -1;
     353}
     354
     355static struct ast_config *config_mysql(const char *database, const char *table, const char *file, struct ast_config *cfg)
     356{
     357        MYSQL_RES *result;
     358        MYSQL_ROW row;
     359        my_ulonglong num_rows;
     360        struct ast_config *new;
     361        struct ast_variable *cur_v, *new_v;
     362        struct ast_category *cur_cat, *new_cat;
     363        char sql[250] = "";
     364        char last[80] = "";
     365        int cat_started = 0;
     366        int var_started = 0;
     367        int last_cat_metric = 0;
     368
     369        last[0] = '\0';
     370
     371        if(!file || !strcmp(file, RES_CONFIG_MYSQL_CONF)) {
     372                ast_log(LOG_WARNING, "MySQL RealTime: Cannot configure myself.\n");
     373                return NULL;
     374        }
     375
     376        snprintf(sql, sizeof(sql), "SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, cat_metric desc, var_metric asc, category, var_name, var_val, id", table, file);
     377
     378        ast_log(LOG_DEBUG, "MySQL RealTime: Static SQL: %s\n", sql);
     379
     380        /* We now have our complete statement; Lets connect to the server and execute it. */
     381        ast_mutex_lock(&mysql_lock);
     382        if(!mysql_reconnect(database)) {
     383                ast_mutex_unlock(&mysql_lock);
     384                return NULL;
     385        }
     386
     387        if(mysql_real_query(&mysql, sql, strlen(sql))) {
     388                ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
     389                ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
     390                ast_log(LOG_DEBUG, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&mysql));
     391                ast_mutex_unlock(&mysql_lock);
     392                return NULL;
     393        }
     394
     395        if((result = mysql_store_result(&mysql))) {
     396                num_rows = mysql_num_rows(result);
     397                ast_log(LOG_DEBUG, "MySQL RealTime: Found %llu rows.\n", num_rows);
     398
     399                /* There might exist a better way to access the column names other than counting,
     400                   but I believe that would require another loop that we don't need. */
     401
     402                while((row = mysql_fetch_row(result))) {
     403                        if(!strcmp(row[1], "#include")) {
     404                                if (!ast_config_internal_load(row[2], cfg)) {
     405                                        mysql_free_result(result);
     406                                        ast_mutex_unlock(&mysql_lock);
     407                                        return NULL;
     408                                }
     409                                continue;
     410                        }
     411
     412                        if(strcmp(last, row[0]) || last_cat_metric != atoi(row[3])) {
     413                                cur_cat = ast_category_new(row[0]);
     414                                if (!cur_cat) {
     415                                        ast_log(LOG_WARNING, "Out of memory!\n");
     416                                        break;
     417                                }
     418                                strcpy(last, row[0]);
     419                                last_cat_metric = atoi(row[3]);
     420                                ast_category_append(cfg, cur_cat);
     421                        }
     422                        new_v = ast_variable_new(row[1], row[2]);
     423                        ast_variable_append(cur_cat, new_v);
     424                }
     425        } else {
     426                ast_log(LOG_WARNING, "MySQL RealTime: Could not find config '%s' in database.\n", file);
     427        }
     428
     429        mysql_free_result(result);
     430        ast_mutex_unlock(&mysql_lock);
     431
     432        return cfg;
     433}
     434
     435static struct ast_config_engine mysql_engine = {
     436        .name = "mysql",
     437        .load_func = config_mysql,
     438        .realtime_func = realtime_mysql,
     439        .realtime_multi_func = realtime_multi_mysql,
     440        .update_func = update_mysql
     441};
     442
     443int load_module (void)
     444{
     445        parse_config();
     446
     447        ast_mutex_lock(&mysql_lock);
     448
     449        if(!mysql_reconnect(NULL)) {
     450                ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n");
     451                ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql));
     452        }
     453
     454        ast_config_engine_register(&mysql_engine);
     455        if(option_verbose) {
     456                ast_verbose("MySQL RealTime driver loaded.\n");
     457        }
     458        ast_cli_register(&cli_realtime_mysql_status);
     459
     460        ast_mutex_unlock(&mysql_lock);
     461
     462        return 0;
     463}
     464
     465int unload_module (void)
     466{
     467        /* Aquire control before doing anything to the module itself. */
     468        ast_mutex_lock(&mysql_lock);
     469
     470        mysql_close(&mysql);
     471        ast_cli_unregister(&cli_realtime_mysql_status);
     472        ast_config_engine_deregister(&mysql_engine);
     473        if(option_verbose) {
     474                ast_verbose("MySQL RealTime unloaded.\n");
     475        }
     476
     477        STANDARD_HANGUP_LOCALUSERS;
     478
     479        /* Unlock so something else can destroy the lock. */
     480        ast_mutex_unlock(&mysql_lock);
     481
     482        return 0;
     483}
     484
     485int reload (void)
     486{
     487        /* Aquire control before doing anything to the module itself. */
     488        ast_mutex_lock(&mysql_lock);
     489
     490        mysql_close(&mysql);
     491        connected = 0;
     492        parse_config();
     493
     494        if(!mysql_reconnect(NULL)) {
     495                ast_log(LOG_WARNING, "MySQL RealTime: Couldn't establish connection. Check debug.\n");
     496                ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql));
     497        }
     498
     499        ast_verbose(VERBOSE_PREFIX_2 "MySQL RealTime reloaded.\n");
     500
     501        /* Done reloading. Release lock so others can now use driver. */
     502        ast_mutex_unlock(&mysql_lock);
     503
     504        return 0;
     505}
     506
     507int parse_config (void)
     508{
     509        struct ast_config *config;
     510        char *s;
     511
     512        config = ast_config_load(RES_CONFIG_MYSQL_CONF);
     513
     514        if(config) {
     515                if(!(s=ast_variable_retrieve(config, "general", "dbuser"))) {
     516                        ast_log(LOG_WARNING, "MySQL RealTime: No database user found, using 'asterisk' as default.\n");
     517                        strncpy(dbuser, "asterisk", sizeof(dbuser) - 1);
     518                } else {
     519                        strncpy(dbuser, s, sizeof(dbuser) - 1);
     520                }
     521
     522                if(!(s=ast_variable_retrieve(config, "general", "dbpass"))) {
     523                        ast_log(LOG_WARNING, "MySQL RealTime: No database password found, using 'asterisk' as default.\n");
     524                        strncpy(dbpass, "asterisk", sizeof(dbpass) - 1);
     525                } else {
     526                        strncpy(dbpass, s, sizeof(dbpass) - 1);
     527                }
     528
     529                if(!(s=ast_variable_retrieve(config, "general", "dbhost"))) {
     530                        ast_log(LOG_WARNING, "MySQL RealTime: No database host found, using localhost via socket.\n");
     531                        dbhost[0] = '\0';
     532                } else {
     533                        strncpy(dbhost, s, sizeof(dbhost) - 1);
     534                }
     535
     536                if(!(s=ast_variable_retrieve(config, "general", "dbname"))) {
     537                        ast_log(LOG_WARNING, "MySQL RealTime: No database name found, using 'asterisk' as default.\n");
     538                        strncpy(dbname, "asterisk", sizeof(dbname) - 1);
     539                } else {
     540                        strncpy(dbname, s, sizeof(dbname) - 1);
     541                }
     542
     543                if(!(s=ast_variable_retrieve(config, "general", "dbport"))) {
     544                        ast_log(LOG_WARNING, "MySQL RealTime: No database port found, using 3306 as default.\n");
     545                        dbport = 3306;
     546                } else {
     547                        dbport = atoi(s);
     548                }
     549
     550                if(dbhost && !(s=ast_variable_retrieve(config, "general", "dbsock"))) {
     551                        ast_log(LOG_WARNING, "MySQL RealTime: No database socket found, using '/tmp/mysql.sock' as default.\n");
     552                        strncpy(dbsock, "/tmp/mysql.sock", sizeof(dbsock) - 1);
     553                } else {
     554                        strncpy(dbsock, s, sizeof(dbsock) - 1);
     555                }
     556        }
     557        ast_config_destroy(config);
     558
     559        if(dbhost) {
     560                ast_log(LOG_DEBUG, "MySQL RealTime Host: %s\n", dbhost);
     561                ast_log(LOG_DEBUG, "MySQL RealTime Port: %i\n", dbport);
     562        } else {
     563                ast_log(LOG_DEBUG, "MySQL RealTime Socket: %s\n", dbsock);
     564        }
     565        ast_log(LOG_DEBUG, "MySQL RealTime User: %s\n", dbuser);
     566        ast_log(LOG_DEBUG, "MySQL RealTime Password: %s\n", dbpass);
     567
     568        return 1;
     569}
     570
     571char *description (void)
     572{
     573        return res_config_mysql_desc;
     574}
     575
     576int usecount (void)
     577{
     578        /* Try and get a lock. If unsuccessful, than that means another thread is using the mysql object. */
     579        if(ast_mutex_trylock(&mysql_lock)) {
     580                ast_log(LOG_DEBUG, "MySQL RealTime: Module usage count is 1.\n");
     581                return 1;
     582        }
     583        ast_mutex_unlock(&mysql_lock);
     584        return 0;
     585}
     586
     587char *key ()
     588{
     589        return ASTERISK_GPL_KEY;
     590}
     591
     592static int mysql_reconnect(const char *database)
     593{
     594        char my_database[50];
     595
     596        if(!database || ast_strlen_zero(database))
     597                ast_copy_string(my_database, dbname, sizeof(my_database));
     598        else
     599                ast_copy_string(my_database, database, sizeof(my_database));
     600
     601        /* mutex lock should have been locked before calling this function. */
     602
     603        if((!connected) && (dbhost || dbsock) && dbuser && dbpass && my_database) {
     604                if(!mysql_init(&mysql)) {
     605                        ast_log(LOG_WARNING, "MySQL RealTime: Insufficient memory to allocate MySQL resource.\n");
     606                        connected = 0;
     607                        return 0;
     608                }
     609                if(mysql_real_connect(&mysql, dbhost, dbuser, dbpass, my_database, dbport, dbsock, 0)) {
     610                        ast_log(LOG_DEBUG, "MySQL RealTime: Successfully connected to database.\n");
     611                        connected = 1;
     612                        connect_time = time(NULL);
     613                        return 1;
     614                } else {
     615                        ast_log(LOG_ERROR, "MySQL RealTime: Failed to connect database server %s on %s. Check debug for more info.\n", dbname, dbhost);
     616                        ast_log(LOG_DEBUG, "MySQL RealTime: Cannot Connect: %s\n", mysql_error(&mysql));
     617                        connected = 0;
     618                        return 0;
     619                }
     620        } else {
     621                if(mysql_ping(&mysql) != 0) {
     622                        connected = 0;
     623                        ast_log(LOG_ERROR, "MySQL RealTime: Failed to reconnect. Check debug for more info.\n");
     624                        ast_log(LOG_DEBUG, "MySQL RealTime: Server Error: %s\n", mysql_error(&mysql));
     625                        return 0;
     626                }
     627
     628                connected = 1;
     629
     630                if(mysql_select_db(&mysql, my_database) != 0) {
     631                        ast_log(LOG_WARNING, "MySQL RealTime: Unable to select database: %s. Still Connected.\n", my_database);
     632                        ast_log(LOG_DEBUG, "MySQL RealTime: Database Select Failed: %s\n", mysql_error(&mysql));
     633                        return 0;
     634                }
     635
     636                ast_log(LOG_DEBUG, "MySQL RealTime: Everything is fine.\n");
     637                return 1;
     638        }
     639}
     640
     641static int realtime_mysql_status(int fd, int argc, char **argv)
     642{
     643        char status[256], status2[100] = "";
     644        int ctime = time(NULL) - connect_time;
     645
     646        if(mysql_reconnect(NULL)) {
     647                if(dbhost) {
     648                        snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport);
     649                } else if(dbsock) {
     650                        snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock);
     651                } else {
     652                        snprintf(status, 255, "Connected to %s@%s", dbname, dbhost);
     653                }
     654
     655                if(dbuser && *dbuser) {
     656                        snprintf(status2, 99, " with username %s", dbuser);
     657                }
     658
     659                if (ctime > 31536000) {
     660                        ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 31536000, (ctime % 31536000) / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
     661                } else if (ctime > 86400) {
     662                        ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
     663                } else if (ctime > 3600) {
     664                        ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 3600, (ctime % 3600) / 60, ctime % 60);
     665                } else if (ctime > 60) {
     666                        ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, ctime % 60);
     667                } else {
     668                        ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime);
     669                }
     670
     671                return RESULT_SUCCESS;
     672        } else {
     673                return RESULT_FAILURE;
     674        }
     675}
Note: See TracBrowser for help on using the repository browser.