Sat Sep 16 05:47:51 2006

Asterisk developer's documentation


app_sql_postgres.c File Reference

Connect to PostgreSQL. More...

#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

static int add_identifier (int identifier_type, void *data)
static int aPGSQL_clear (struct ast_channel *chan, void *data)
static int aPGSQL_connect (struct ast_channel *chan, void *data)
static int aPGSQL_debug (struct ast_channel *chan, void *data)
static int aPGSQL_disconnect (struct ast_channel *chan, void *data)
static int aPGSQL_fetch (struct ast_channel *chan, void *data)
static int aPGSQL_query (struct ast_channel *chan, void *data)
static int aPGSQL_reset (struct ast_channel *chan, void *data)
static AST_LIST_HEAD_STATIC (PGSQLidshead, ast_PGSQL_id)
static int del_identifier (int identifier, int identifier_type)
char * description (void)
 Provides a description of the module.
static void * find_identifier (int identifier, int identifier_type)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static 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

static char * app = "PGSQL"
static char * descrip
 LOCAL_USER_DECL
 STANDARD_LOCAL_USER
static char * synopsis = "Do several SQLy things"
static char * tdesc = "Simple PostgreSQL Interface"


Detailed Description

Connect to PostgreSQL.

Definition in file app_sql_postgres.c.


Define Documentation

#define AST_PGSQL_ID_CONNID   1

Definition at line 124 of file app_sql_postgres.c.

Referenced by aPGSQL_connect(), aPGSQL_disconnect(), aPGSQL_query(), and aPGSQL_reset().

#define AST_PGSQL_ID_DUMMY   0

Definition at line 123 of file app_sql_postgres.c.

#define AST_PGSQL_ID_FETCHID   3

Definition at line 126 of file app_sql_postgres.c.

Referenced by aPGSQL_fetch().

#define AST_PGSQL_ID_RESID   2

Definition at line 125 of file app_sql_postgres.c.

Referenced by aPGSQL_clear(), aPGSQL_fetch(), and aPGSQL_query().


Function Documentation

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

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 }

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

Definition at line 441 of file app_sql_postgres.c.

References ast_log(), AST_PGSQL_ID_RESID, del_identifier(), find_identifier(), free, id, 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 }

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

Definition at line 223 of file app_sql_postgres.c.

References add_identifier(), ast_log(), AST_PGSQL_ID_CONNID, free, id, 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 }

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

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 }

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

Definition at line 471 of file app_sql_postgres.c.

References ast_log(), AST_PGSQL_ID_CONNID, del_identifier(), find_identifier(), free, id, 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 }

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

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(), find_identifier(), free, id, 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 }

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

Definition at line 261 of file app_sql_postgres.c.

References add_identifier(), ast_log(), AST_PGSQL_ID_CONNID, AST_PGSQL_ID_RESID, find_identifier(), free, id, 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 }

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

Definition at line 415 of file app_sql_postgres.c.

References ast_log(), AST_PGSQL_ID_CONNID, find_identifier(), free, id, 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 }

static AST_LIST_HEAD_STATIC ( PGSQLidshead  ,
ast_PGSQL_id   
) [static]

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

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 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 557 of file app_sql_postgres.c.

00558 {
00559    return tdesc;
00560 }

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

Definition at line 137 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.

Referenced by aPGSQL_clear(), aPGSQL_disconnect(), aPGSQL_fetch(), aPGSQL_query(), and aPGSQL_reset().

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 }

char* key ( void   ) 

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;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 569 of file app_sql_postgres.c.

References ASTERISK_GPL_KEY.

00570 {
00571    return ASTERISK_GPL_KEY;
00572 }

int load_module ( void   ) 

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.

Returns:
int Always 0.

Definition at line 552 of file app_sql_postgres.c.

References ast_register_application(), and PGSQL_exec().

00553 {
00554    return ast_register_application(app, PGSQL_exec, synopsis, descrip);
00555 }

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

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(), localuser::chan, 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 }

int unload_module ( void   ) 

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).

Returns:
Zero on success, or non-zero on error.

Definition at line 541 of file app_sql_postgres.c.

References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

00542 {
00543    int res;
00544 
00545    res = ast_unregister_application(app);
00546 
00547    STANDARD_HANGUP_LOCALUSERS;
00548    
00549    return res;
00550 }

int usecount ( void   ) 

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.

Returns:
The module's usecount.

Definition at line 562 of file app_sql_postgres.c.

References STANDARD_USECOUNT.

00563 {
00564    int res;
00565    STANDARD_USECOUNT(res);
00566    return res;
00567 }


Variable Documentation

char* app = "PGSQL" [static]

Definition at line 50 of file app_sql_postgres.c.

char* descrip [static]

Definition at line 54 of file app_sql_postgres.c.

LOCAL_USER_DECL

Definition at line 121 of file app_sql_postgres.c.

STANDARD_LOCAL_USER

Definition at line 119 of file app_sql_postgres.c.

char* synopsis = "Do several SQLy things" [static]

Definition at line 52 of file app_sql_postgres.c.

char* tdesc = "Simple PostgreSQL Interface" [static]

Definition at line 48 of file app_sql_postgres.c.


Generated on Sat Sep 16 05:47:51 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7