All pastes #35045 Raw Edit

Unnamed

public text v1 · immutable
#35045 ·published 2005-12-28 07:24 UTC
rendered paste body
/*
* Asterisk -- A telephony toolkit for Linux.
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
* Version: 2.1.1 - 07/3/05
*
* Clod Patry <cpatry@gmail.com> for inner usage
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/utils.h>

#include <sys/types.h>
#include <asterisk/config.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/cdr.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include "../asterisk.h"

#include <stdio.h>
#include <string.h>

#include <stdlib.h>
#include <unistd.h>
#include <time.h>

#include <libpq-fe.h>

int limit_achieved(struct ast_channel *chan, char *argument);
char* get_action(char *app_id);

static char *synopsis = "Check Blacklist";
static char *app = "CheckBlacklist";
static char *tdesc = "Check Blacklist";
static char *descrip = "Usage: CheckBlacklist(app_id[,iso_country])\n"
" To see if a specific caller_id is on a blacklist in our systems\n"
" If yes, it's fetch his application.cid_action\n"
" Otherwise, it will go at priority N+1\n"
" iso_country is the iso code for a specific country, if not specified, 'ca' will be used.\n";

static char *config = "cdr_pgsql.conf";
static char *pghostname = NULL, *pgdbname = NULL, *pgdbuser = NULL, *pgpassword = NULL, *pgdbsock = NULL, *pgdbport = NULL;
static int hostname_alloc = 0, dbname_alloc = 0, dbuser_alloc = 0, password_alloc = 0, dbport_alloc = 0;
//static int dbsock_alloc = 0;
static int connected = 0;

STANDARD_LOCAL_USER;
LOCAL_USER_DECL;

PGconn          *conn;
PGresult        *result;

static void wait_for_hangup(struct ast_channel *chan, void *data)
{
       int res;
       struct ast_frame *f;
       int waittime;

       if (!data || !strlen(data) || (sscanf(data, "%i", &waittime) != 1) || (waittime < 0))
               waittime = -1;
       if (waittime > -1) {
               ast_safe_sleep(chan, waittime * 1000);
       } else do {
               res = ast_waitfor(chan, -1);
               if (res < 0)
                       return;
               f = ast_read(chan);
               if (f)
                       ast_frfree(f);
       } while(f);
}

static int my_load_config(void){
       /* Connection to the database */
       struct ast_config *cfg_file;
       struct ast_variable *var;
       char *tmp;

       cfg_file = ast_load(config);
       if (!cfg_file) {
               ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
               return 0;
       }
       var = ast_variable_browse(cfg_file, "global");
       if (!var) {
               // nothing configured
               return 0;
       }

       tmp = ast_variable_retrieve(cfg_file,"global","hostname");
       if (tmp) {
               pghostname = malloc(strlen(tmp) + 1);
               if (pghostname != NULL) {
                       memset(pghostname, 0, strlen(tmp) + 1);
                       hostname_alloc = 1;
                       strncpy(pghostname, tmp, strlen(tmp));
               } else {
                       ast_log(LOG_ERROR,"Out of memory error.\n");
                       return -1;
               }
       } else {
               ast_log(LOG_WARNING,"PostgreSQL server hostname not specified.  Assuming localhost\n");
               pghostname = "localhost";
       }

       tmp = ast_variable_retrieve(cfg_file,"global","dbname");
       if (tmp) {
               pgdbname = malloc(strlen(tmp) + 1);
               if (pgdbname != NULL) {
                       memset(pgdbname, 0, strlen(tmp) + 1);
                       dbname_alloc = 1;
                       strncpy(pgdbname, tmp, strlen(tmp));
               } else {
                       ast_log(LOG_ERROR,"Out of memory error.\n");
                       return -1;
               }
       } else {
               ast_log(LOG_WARNING,"PostgreSQL database not specified.  Assuming asterisk\n");
               pgdbname = "asteriskcdrdb";
       }

       tmp = ast_variable_retrieve(cfg_file,"global","user");
       if (tmp) {
               pgdbuser = malloc(strlen(tmp) + 1);
               if (pgdbuser != NULL) {
                       memset(pgdbuser, 0, strlen(tmp) + 1);
                       dbuser_alloc = 1;
                       strncpy(pgdbuser, tmp, strlen(tmp));
               } else {
                       ast_log(LOG_ERROR,"Out of memory error.\n");
                       return -1;
               }
       } else {
               ast_log(LOG_WARNING,"PostgreSQL database user not specified.  Assuming root\n");
               pgdbuser = "root";
       }

       tmp = ast_variable_retrieve(cfg_file,"global","password");
       if (tmp) {
               pgpassword = malloc(strlen(tmp) + 1);
               if (pgpassword != NULL) {
                       memset(pgpassword, 0, strlen(tmp) + 1);
                       password_alloc = 1;
                       strncpy(pgpassword, tmp, strlen(tmp));
               } else {
                       ast_log(LOG_ERROR,"Out of memory error.\n");
                       return -1;
               }
       } else {
               ast_log(LOG_WARNING,"PostgreSQL database password not specified.  Assuming blank\n");
               pgpassword = "";
       }

       tmp = ast_variable_retrieve(cfg_file,"global","port");
       if (tmp) {
               pgdbport = malloc(strlen(tmp) + 1);
               if (pgdbport != NULL) {
                       memset(pgdbport, 0, strlen(tmp) + 1);
                       dbport_alloc = 1;
                       strncpy(pgdbport, tmp, strlen(tmp));
               } else {
                       ast_log(LOG_ERROR,"Out of memory error.\n");
                       return -1;
               }
       } else {
               ast_log(LOG_WARNING,"PostgreSQL database port not specified.  Using default 5432.\n");
               pgdbport = "5432";
       }

       ast_destroy(cfg_file);
       return 1;
}

static int checkblacklist_exec(struct ast_channel *chan, void *data)
{
       char sqlcmd[200];
       char *pgerror;
       int count = 0;
       char *cid_num = chan->cid.cid_num;
       char *option;
       char *app_id;

       if ( !data ) {
               ast_log(LOG_WARNING, "1.CheckBlacklist requires an argument (app_id)\n");
               return -1;
       }

       if (ast_strlen_zero((char *) data)) {
               ast_log(LOG_WARNING, "CheckBlacklist requires an argument (app_id)\n");
               return -1;
       }

       if (!(app_id = ast_strdupa(data))) {
               ast_log(LOG_WARNING, "Unable to dupe data :(\n");
               return -1;
       }

       option = strchr(app_id, '|');
       if (option) {
              *option = '\0';
               option++;
       }

       ast_log(LOG_WARNING, "app_id=%s\n",app_id);

       //ast_log(LOG_WARNING, "caller_id = %s\n", cid_num);

       if (pgdbsock)
               ast_log(LOG_DEBUG,"cdr_pgsql: got sock file of %s\n",pgdbsock);

       conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);

       if (PQstatus(conn) != CONNECTION_BAD) {
               //ast_log(LOG_WARNING,"Successfully connected to PostgreSQL database.\n");
               connected = 1;
       } else {
               pgerror = PQerrorMessage(conn);
               ast_log(LOG_WARNING, "CheckBlacklist: Unable to connect to database server %s.\n", pghostname);
               ast_log(LOG_WARNING, "CheckBlacklist: Reason: %s.\n", pgerror);
               connected = 0;
               PQfinish(conn);
               return 0;
       }

       if ( !conn ) {
                ast_log(LOG_WARNING, "CheckBlacklist: NO CONNECTION\n");
       }

       if ( !cid_num ) {
               ast_log(LOG_WARNING, "NO CID_NUM => caller_id = %s\n", cid_num);
               sprintf(sqlcmd, "SELECT cid_action FROM application WHERE application_id='%s' AND active='TRUE'",app_id);
               ast_log(LOG_WARNING, "no_cid => query=%s\n",sqlcmd);
               result = PQexec(conn,sqlcmd);
               ast_log(LOG_WARNING, "%d results\n",PQntuples(result) );
               char *action;
               if ( PQntuples(result) > 0 ) {
                       action = PQgetvalue(result,0,0);

               } else {
                       ast_log(LOG_NOTICE, "Check the arguments of CheckBlacklist() of app_id=%s\n",app_id);
                       PQclear(result);
                       PQfinish(conn);
                       limit_achieved(chan, "BUSY");
                       return -1;

               }
               PQclear(result);

               if ( action ) {
                       ast_log(LOG_WARNING, "no CID; action=%s\n",action);
                       PQfinish(conn);
                       if ( limit_achieved(chan, action) ) {
                               return -1;
                       }

               }
       }

       char *country_code = "ca";
       sprintf(sqlcmd, "SELECT COUNT(*) FROM blacklist WHERE caller_id='%s' AND application_id=0 AND country='%s';", cid_num, country_code);

       ast_log(LOG_WARNING, "query=%s\n",sqlcmd);
       result = PQexec(conn,sqlcmd);
       count = atoi(PQgetvalue(result,0,0));
       PQclear(result);
       PQfinish(conn);
       //ast_log(LOG_WARNING, "answer = %d\n",count);
       if ( count < 1 ) {
               //ast_log(LOG_WARNING, "%s is not blacklisted ...continue\n",(char *)data);
               return 0;
       } else {
               ast_log(LOG_WARNING, "%s is blacklisted!!\n", (char *)data);

               if (chan->cdr && data) {
                       ast_cdr_appenduserfield(chan, "call=blacklist");
               }

               ast_indicate(chan, AST_CONTROL_BUSY);
               wait_for_hangup(chan, "16");
               return -1;
       }
}

char* get_action(char *app_id) {

       return "vm-intro";
}

int limit_achieved(struct ast_channel *chan, char *action) {
       ast_log(LOG_DEBUG, "in limit_achieved arg = %s\n", action);
       if ( chan->cdr ) {
               ast_cdr_appenduserfield(chan, "call=blacklist");
       }
       if ( !strcmp(action,"BUSY") ) {
               ast_log(LOG_WARNING, "action is BUSY\n");
               ast_indicate(chan, AST_CONTROL_BUSY);
               wait_for_hangup(chan, action);
       } else if ( !strcmp(action,"HANGUP") ) {
               ast_log(LOG_WARNING, "action is HANGUP\n");
       } else if (  !strcmp(action,"") ) {
               ast_log(LOG_WARNING, "action is Nothing, set it to BUSY\n");
               ast_indicate(chan, AST_CONTROL_BUSY);
               wait_for_hangup(chan, action);
       } else {
               ast_log(LOG_WARNING, "action is STREAM\n");
               //Streaming this file
               int res = ast_streamfile(chan, action, chan->language);
               res = ast_waitstream(chan, "");
       }
       return -1;
}

int unload_module(void)
{
       STANDARD_HANGUP_LOCALUSERS;
       return ast_unregister_application(app);
}

int load_module(void)
{
       /* Loading config file once */
       my_load_config();
       return ast_register_application(app, checkblacklist_exec, synopsis, descrip);
}

char *description(void)
{
       return tdesc;
}

int usecount(void)
{
       int res;
       STANDARD_USECOUNT(res);
       return res;
}

char *key()
{
       return ASTERISK_GPL_KEY;
}