#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include "asterisk.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 "libpq-fe.h"
Go to the source code of this file.
Data Structures | |
struct | ast_PGSQL_id |
Defines | |
#define | AST_PGSQL_ID_CONNID 1 |
#define | AST_PGSQL_ID_DUMMY 0 |
#define | AST_PGSQL_ID_FETCHID 3 |
#define | AST_PGSQL_ID_RESID 2 |
Functions | |
int | add_identifier (int identifier_type, void *data) |
int | aPGSQL_clear (struct ast_channel *chan, void *data) |
int | aPGSQL_connect (struct ast_channel *chan, void *data) |
int | aPGSQL_debug (struct ast_channel *chan, void *data) |
int | aPGSQL_disconnect (struct ast_channel *chan, void *data) |
int | aPGSQL_fetch (struct ast_channel *chan, void *data) |
int | aPGSQL_query (struct ast_channel *chan, void *data) |
int | aPGSQL_reset (struct ast_channel *chan, void *data) |
AST_LIST_HEAD (PGSQLidshead, ast_PGSQL_id) | |
int | del_identifier (int identifier, int identifier_type) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | PGSQL_exec (struct ast_channel *chan, void *data) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
char * | app = "PGSQL" |
ast_PGSQL_id * | ast_PGSQL_id |
char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
char * | synopsis = "Do several SQLy things" |
char * | tdesc = "Simple PostgreSQL Interface" |
Definition in file app_sql_postgres.c.
|
Definition at line 124 of file app_sql_postgres.c. Referenced by aPGSQL_connect(), aPGSQL_disconnect(), aPGSQL_query(), and aPGSQL_reset(). |
|
Definition at line 123 of file app_sql_postgres.c. |
|
Definition at line 126 of file app_sql_postgres.c. Referenced by aPGSQL_fetch(). |
|
Definition at line 125 of file app_sql_postgres.c. Referenced by aPGSQL_clear(), aPGSQL_fetch(), and aPGSQL_query(). |
|
Definition at line 164 of file app_sql_postgres.c. References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_PGSQL_id::data, ast_PGSQL_id::identifier, ast_PGSQL_id::identifier_type, LOG_WARNING, and malloc. Referenced by aPGSQL_connect(), aPGSQL_fetch(), and aPGSQL_query(). 00164 { 00165 struct ast_PGSQL_id *i,*j; 00166 struct PGSQLidshead *headp; 00167 int maxidentifier=0; 00168 00169 headp=&PGSQLidshead; 00170 i=NULL; 00171 j=NULL; 00172 00173 if (AST_LIST_LOCK(headp)) { 00174 ast_log(LOG_WARNING,"Unable to lock identifiers list\n"); 00175 return(-1); 00176 } else { 00177 i=malloc(sizeof(struct ast_PGSQL_id)); 00178 AST_LIST_TRAVERSE(headp,j,entries) { 00179 if (j->identifier>maxidentifier) { 00180 maxidentifier=j->identifier; 00181 } 00182 } 00183 00184 i->identifier=maxidentifier+1; 00185 i->identifier_type=identifier_type; 00186 i->data=data; 00187 AST_LIST_INSERT_HEAD(headp,i,entries); 00188 AST_LIST_UNLOCK(headp); 00189 } 00190 return(i->identifier); 00191 }
|
|
Definition at line 441 of file app_sql_postgres.c. References ast_log(), AST_PGSQL_ID_RESID, del_identifier(), free, LOG_WARNING, malloc, and strsep(). Referenced by PGSQL_exec(). 00441 { 00442 00443 char *s1,*s3; 00444 int l; 00445 PGresult *karoto; 00446 int id; 00447 char *stringp=NULL; 00448 00449 00450 l=strlen(data)+2; 00451 s1=malloc(l); 00452 strncpy(s1, data, l - 1); 00453 stringp=s1; 00454 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00455 s3=strsep(&stringp," "); 00456 id=atoi(s3); 00457 if ((karoto=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) { 00458 ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_clear\n",id); 00459 } else { 00460 PQclear(karoto); 00461 del_identifier(id,AST_PGSQL_ID_RESID); 00462 } 00463 free(s1); 00464 return(0); 00465 00466 }
|
|
Definition at line 223 of file app_sql_postgres.c. References add_identifier(), ast_log(), AST_PGSQL_ID_CONNID, free, LOG_WARNING, malloc, pbx_builtin_setvar_helper(), s, strsep(), and var. Referenced by PGSQL_exec(). 00223 { 00224 00225 char *s1; 00226 char s[100] = ""; 00227 char *optionstring; 00228 char *var; 00229 int l; 00230 int res; 00231 PGconn *karoto; 00232 int id; 00233 char *stringp=NULL; 00234 00235 00236 res=0; 00237 l=strlen(data)+2; 00238 s1=malloc(l); 00239 strncpy(s1, data, l -1); 00240 stringp=s1; 00241 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00242 var=strsep(&stringp," "); 00243 optionstring=strsep(&stringp,"\n"); 00244 00245 karoto = PQconnectdb(optionstring); 00246 if (PQstatus(karoto) == CONNECTION_BAD) { 00247 ast_log(LOG_WARNING,"Connection to database using '%s' failed. postgress reports : %s\n", optionstring, 00248 PQerrorMessage(karoto)); 00249 res=-1; 00250 } else { 00251 ast_log(LOG_WARNING,"adding identifier\n"); 00252 id=add_identifier(AST_PGSQL_ID_CONNID,karoto); 00253 snprintf(s, sizeof(s), "%d", id); 00254 pbx_builtin_setvar_helper(chan,var,s); 00255 } 00256 00257 free(s1); 00258 return res; 00259 }
|
|
Definition at line 498 of file app_sql_postgres.c. References ast_log(), and LOG_WARNING. Referenced by PGSQL_exec(). 00498 { 00499 ast_log(LOG_WARNING,"Debug : %s\n",(char *)data); 00500 return(0); 00501 }
|
|
Definition at line 471 of file app_sql_postgres.c. References ast_log(), AST_PGSQL_ID_CONNID, del_identifier(), free, LOG_WARNING, malloc, and strsep(). Referenced by PGSQL_exec(). 00471 { 00472 00473 char *s1,*s3; 00474 int l; 00475 PGconn *karoto; 00476 int id; 00477 char *stringp=NULL; 00478 00479 00480 l=strlen(data)+2; 00481 s1=malloc(l); 00482 strncpy(s1, data, l - 1); 00483 stringp=s1; 00484 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00485 s3=strsep(&stringp," "); 00486 id=atoi(s3); 00487 if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) { 00488 ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_disconnect\n",id); 00489 } else { 00490 PQfinish(karoto); 00491 del_identifier(id,AST_PGSQL_ID_CONNID); 00492 } 00493 free(s1); 00494 return(0); 00495 00496 }
|
|
Definition at line 321 of file app_sql_postgres.c. References add_identifier(), AST_LIST_TRAVERSE, ast_log(), AST_PGSQL_ID_FETCHID, AST_PGSQL_ID_RESID, ast_var_name(), ast_var_value(), del_identifier(), free, LOG_WARNING, malloc, pbx_builtin_setvar_helper(), s, strsep(), var, and ast_channel::varshead. Referenced by PGSQL_exec(). 00321 { 00322 00323 char *s1,*s2,*fetchid_var,*s4,*s5,*s6,*s7; 00324 char s[100]; 00325 char *var; 00326 int l; 00327 int res; 00328 PGresult *PGSQLres; 00329 int id,id1,i,j,fnd; 00330 int *lalares=NULL; 00331 int nres; 00332 struct ast_var_t *variables; 00333 struct varshead *headp; 00334 char *stringp=NULL; 00335 00336 headp=&chan->varshead; 00337 00338 res=0; 00339 l=strlen(data)+2; 00340 s7=NULL; 00341 s1=malloc(l); 00342 s2=malloc(l); 00343 strncpy(s1, data, l - 1); 00344 stringp=s1; 00345 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00346 fetchid_var=strsep(&stringp," "); 00347 while (1) { /* ugly trick to make branches with break; */ 00348 var=fetchid_var; /* fetchid */ 00349 fnd=0; 00350 00351 AST_LIST_TRAVERSE(headp,variables,entries) { 00352 if (strncasecmp(ast_var_name(variables),fetchid_var,strlen(fetchid_var))==0) { 00353 s7=ast_var_value(variables); 00354 fnd=1; 00355 break; 00356 } 00357 } 00358 00359 if (fnd==0) { 00360 s7="0"; 00361 pbx_builtin_setvar_helper(chan,fetchid_var,s7); 00362 } 00363 00364 s4=strsep(&stringp," "); 00365 id=atoi(s4); /* resultid */ 00366 if ((PGSQLres=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) { 00367 ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_fetch\n",id); 00368 res=-1; 00369 break; 00370 } 00371 id=atoi(s7); /*fetchid */ 00372 if ((lalares=find_identifier(id,AST_PGSQL_ID_FETCHID))==NULL) { 00373 i=0; /* fetching the very first row */ 00374 } else { 00375 i=*lalares; 00376 free(lalares); 00377 del_identifier(id,AST_PGSQL_ID_FETCHID); /* will re-add it a bit later */ 00378 } 00379 00380 if (i<PQntuples(PGSQLres)) { 00381 nres=PQnfields(PGSQLres); 00382 ast_log(LOG_WARNING,"ast_PGSQL_fetch : nres = %d i = %d ;\n",nres,i); 00383 for (j=0;j<nres;j++) { 00384 s5=strsep(&stringp," "); 00385 if (s5==NULL) { 00386 ast_log(LOG_WARNING,"ast_PGSQL_fetch : More tuples (%d) than variables (%d)\n",nres,j); 00387 break; 00388 } 00389 s6=PQgetvalue(PGSQLres,i,j); 00390 if (s6==NULL) { 00391 ast_log(LOG_WARNING,"PWgetvalue(res,%d,%d) returned NULL in ast_PGSQL_fetch\n",i,j); 00392 break; 00393 } 00394 ast_log(LOG_WARNING,"===setting variable '%s' to '%s'\n",s5,s6); 00395 pbx_builtin_setvar_helper(chan,s5,s6); 00396 } 00397 lalares=malloc(sizeof(int)); 00398 *lalares = ++i; /* advance to the next row */ 00399 id1 = add_identifier(AST_PGSQL_ID_FETCHID,lalares); 00400 } else { 00401 ast_log(LOG_WARNING,"ast_PGSQL_fetch : EOF\n"); 00402 id1 = 0; /* no more rows */ 00403 } 00404 snprintf(s, sizeof(s), "%d", id1); 00405 ast_log(LOG_WARNING,"Setting var '%s' to value '%s'\n",fetchid_var,s); 00406 pbx_builtin_setvar_helper(chan,fetchid_var,s); 00407 break; 00408 } 00409 00410 free(s1); 00411 free(s2); 00412 return(res); 00413 }
|
|
Definition at line 261 of file app_sql_postgres.c. References add_identifier(), ast_log(), AST_PGSQL_ID_CONNID, AST_PGSQL_ID_RESID, free, LOG_WARNING, malloc, pbx_builtin_setvar_helper(), s, strsep(), and var. Referenced by PGSQL_exec(). 00261 { 00262 00263 00264 char *s1,*s2,*s3,*s4; 00265 char s[100] = ""; 00266 char *querystring; 00267 char *var; 00268 int l; 00269 int res,nres; 00270 PGconn *karoto; 00271 PGresult *PGSQLres; 00272 int id,id1; 00273 char *stringp=NULL; 00274 00275 00276 res=0; 00277 l=strlen(data)+2; 00278 s1=malloc(l); 00279 s2=malloc(l); 00280 strncpy(s1, data, l - 1); 00281 stringp=s1; 00282 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00283 s3=strsep(&stringp," "); 00284 while (1) { /* ugly trick to make branches with break; */ 00285 var=s3; 00286 s4=strsep(&stringp," "); 00287 id=atoi(s4); 00288 querystring=strsep(&stringp,"\n"); 00289 if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) { 00290 ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_query\n",id); 00291 res=-1; 00292 break; 00293 } 00294 PGSQLres=PQexec(karoto,querystring); 00295 if (PGSQLres==NULL) { 00296 ast_log(LOG_WARNING,"aPGSQL_query: Connection Error (connection identifier = %d, error message : %s)\n",id,PQerrorMessage(karoto)); 00297 res=-1; 00298 break; 00299 } 00300 if (PQresultStatus(PGSQLres) == PGRES_BAD_RESPONSE || 00301 PQresultStatus(PGSQLres) == PGRES_NONFATAL_ERROR || 00302 PQresultStatus(PGSQLres) == PGRES_FATAL_ERROR) { 00303 ast_log(LOG_WARNING,"aPGSQL_query: Query Error (connection identifier : %d, error message : %s)\n",id,PQcmdStatus(PGSQLres)); 00304 res=-1; 00305 break; 00306 } 00307 nres=PQnfields(PGSQLres); 00308 id1=add_identifier(AST_PGSQL_ID_RESID,PGSQLres); 00309 snprintf(s, sizeof(s), "%d", id1); 00310 pbx_builtin_setvar_helper(chan,var,s); 00311 break; 00312 } 00313 00314 free(s1); 00315 free(s2); 00316 00317 return(res); 00318 }
|
|
Definition at line 415 of file app_sql_postgres.c. References ast_log(), AST_PGSQL_ID_CONNID, free, LOG_WARNING, malloc, and strsep(). Referenced by PGSQL_exec(). 00415 { 00416 00417 char *s1,*s3; 00418 int l; 00419 PGconn *karoto; 00420 int id; 00421 char *stringp=NULL; 00422 00423 00424 l=strlen(data)+2; 00425 s1=malloc(l); 00426 strncpy(s1, data, l - 1); 00427 stringp=s1; 00428 strsep(&stringp," "); /* eat the first token, we already know it :P */ 00429 s3=strsep(&stringp," "); 00430 id=atoi(s3); 00431 if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) { 00432 ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_reset\n",id); 00433 } else { 00434 PQreset(karoto); 00435 } 00436 free(s1); 00437 return(0); 00438 00439 }
|
|
Definition at line 135 of file app_sql_postgres.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_PGSQL_id::data, ast_PGSQL_id::identifier, ast_PGSQL_id::identifier_type, and LOG_WARNING. 00137 { 00138 struct PGSQLidshead *headp; 00139 struct ast_PGSQL_id *i; 00140 void *res=NULL; 00141 int found=0; 00142 00143 headp=&PGSQLidshead; 00144 00145 if (AST_LIST_LOCK(headp)) { 00146 ast_log(LOG_WARNING,"Unable to lock identifiers list\n"); 00147 } else { 00148 AST_LIST_TRAVERSE(headp,i,entries) { 00149 if ((i->identifier==identifier) && (i->identifier_type==identifier_type)) { 00150 found=1; 00151 res=i->data; 00152 break; 00153 } 00154 } 00155 if (!found) { 00156 ast_log(LOG_WARNING,"Identifier %d, identifier_type %d not found in identifier list\n",identifier,identifier_type); 00157 } 00158 AST_LIST_UNLOCK(headp); 00159 } 00160 00161 return(res); 00162 }
|
|
Definition at line 193 of file app_sql_postgres.c. References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), free, ast_PGSQL_id::identifier, ast_PGSQL_id::identifier_type, and LOG_WARNING. Referenced by aPGSQL_clear(), aPGSQL_disconnect(), and aPGSQL_fetch(). 00193 { 00194 struct ast_PGSQL_id *i; 00195 struct PGSQLidshead *headp; 00196 int found=0; 00197 00198 headp=&PGSQLidshead; 00199 00200 if (AST_LIST_LOCK(headp)) { 00201 ast_log(LOG_WARNING,"Unable to lock identifiers list\n"); 00202 } else { 00203 AST_LIST_TRAVERSE(headp,i,entries) { 00204 if ((i->identifier==identifier) && 00205 (i->identifier_type==identifier_type)) { 00206 AST_LIST_REMOVE(headp,i,entries); 00207 free(i); 00208 found=1; 00209 break; 00210 } 00211 } 00212 AST_LIST_UNLOCK(headp); 00213 } 00214 00215 if (found==0) { 00216 ast_log(LOG_WARNING,"Could not find identifier %d, identifier_type %d in list to delete\n",identifier,identifier_type); 00217 return(-1); 00218 } else { 00219 return(0); 00220 } 00221 }
|
|
Provides a description of the module.
Definition at line 562 of file app_sql_postgres.c. 00563 {
00564 return tdesc;
00565 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 574 of file app_sql_postgres.c. 00575 {
00576 return ASTERISK_GPL_KEY;
00577 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 552 of file app_sql_postgres.c. References app, AST_LIST_HEAD_INIT, ast_register_application(), descrip, PGSQL_exec(), and synopsis. 00553 { 00554 struct PGSQLidshead *headp; 00555 00556 headp=&PGSQLidshead; 00557 00558 AST_LIST_HEAD_INIT(headp); 00559 return ast_register_application(app, PGSQL_exec, synopsis, descrip); 00560 }
|
|
Definition at line 503 of file app_sql_postgres.c. References aPGSQL_clear(), aPGSQL_connect(), aPGSQL_debug(), aPGSQL_disconnect(), aPGSQL_fetch(), aPGSQL_query(), aPGSQL_reset(), ast_log(), ast_strlen_zero(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, and result. Referenced by load_module(). 00504 { 00505 struct localuser *u; 00506 int result; 00507 00508 if (ast_strlen_zero(data)) { 00509 ast_log(LOG_WARNING, "APP_PGSQL requires an argument (see manual)\n"); 00510 return -1; 00511 } 00512 00513 LOCAL_USER_ADD(u); 00514 00515 result=0; 00516 00517 if (strncasecmp("connect",data,strlen("connect"))==0) { 00518 result=(aPGSQL_connect(chan,data)); 00519 } else if (strncasecmp("query",data,strlen("query"))==0) { 00520 result=(aPGSQL_query(chan,data)); 00521 } else if (strncasecmp("fetch",data,strlen("fetch"))==0) { 00522 result=(aPGSQL_fetch(chan,data)); 00523 } else if (strncasecmp("reset",data,strlen("reset"))==0) { 00524 result=(aPGSQL_reset(chan,data)); 00525 } else if (strncasecmp("clear",data,strlen("clear"))==0) { 00526 result=(aPGSQL_clear(chan,data)); 00527 } else if (strncasecmp("debug",data,strlen("debug"))==0) { 00528 result=(aPGSQL_debug(chan,data)); 00529 } else if (strncasecmp("disconnect",data,strlen("disconnect"))==0) { 00530 result=(aPGSQL_disconnect(chan,data)); 00531 } else { 00532 ast_log(LOG_WARNING, "Unknown APP_PGSQL argument : %s\n",(char *)data); 00533 result=-1; 00534 } 00535 00536 LOCAL_USER_REMOVE(u); 00537 00538 return result; 00539 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 541 of file app_sql_postgres.c. References app, and ast_unregister_application(). 00542 { 00543 int res; 00544 00545 res = ast_unregister_application(app); 00546 00547 STANDARD_HANGUP_LOCALUSERS; 00548 00549 return res; 00550 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 567 of file app_sql_postgres.c. References STANDARD_USECOUNT. 00568 { 00569 int res; 00570 STANDARD_USECOUNT(res); 00571 return res; 00572 }
|
|
Definition at line 50 of file app_sql_postgres.c. Referenced by load_module(), and unload_module(). |
|
|
|
Definition at line 54 of file app_sql_postgres.c. Referenced by load_module(). |
|
Definition at line 121 of file app_sql_postgres.c. |
|
Definition at line 119 of file app_sql_postgres.c. |
|
Definition at line 52 of file app_sql_postgres.c. Referenced by load_module(). |
|
Definition at line 48 of file app_sql_postgres.c. |