1 #include "libzbxpgsql.h"
2 
3 /*
4  * Function: build_connstring
5  *
6  * Allocates and returns a libpq compatible connection string. This function
7  * takes as input, a libpq compatible connection string with the `dbname` field
8  * ommitted and the desired database name as the second parameter. This enables
9  * connection strings to be built from Zabbix discovery rules where the
10  * connected database may not be known when configuring Zabbix.
11  *
12  * Returns: libpq compatible connection string. Must be freed by the caller
13  *          using zbx_free()
14  */
build_connstring(const char * connstring,const char * dbname)15 char *build_connstring(const char *connstring, const char *dbname)
16 {
17     char    *res = NULL, *c = NULL;
18     int     bufferlen = 0;
19 
20     bufferlen =
21         (NULL == connstring ? 0 : strlen(connstring))
22         + (NULL == dbname ? 0 : strlen(dbname))
23         + 9; // + ' dbname=\0'
24 
25     res = zbx_malloc(res, sizeof(char) * bufferlen);
26     memset(res, 0, sizeof(char) * bufferlen);
27 
28     c = res;
29     c = strcat2(c, strisnull(connstring) ? DEFAULT_CONN_STRING : connstring);
30     c = strcat2(c, strisnull(connstring) ? NULL : " ");
31     c = strcat2(c, "dbname=");
32     c = strcat2(c, strisnull(dbname) ? DEFAULT_CONN_DBNAME : dbname);
33 
34     return res;
35 }
36 
37 /*
38  * Function: pg_connect
39  *
40  * Connect to PostgreSQL server
41  *
42  * See: http://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-PQCONNECTDB
43  *
44  * Parameter [connstring]:  libpq compatible connection string
45  *
46  * Parameter [result]:      result structure to send errors to the server
47  *
48  * Returns: Valid PostgreSQL connection or NULL on error
49  */
pg_connect(const char * connstring,AGENT_RESULT * result)50 PGconn    *pg_connect(const char *connstring, AGENT_RESULT *result)
51  {
52     const char  *__function_name = "pg_connect";
53 
54     PGconn      *conn = NULL;
55 
56     zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
57 
58     /*
59      * Breaks in < v9.0
60     // append application name
61     if (!strisnull(connstring))
62         c = strcat2(c, " ");
63     c = strcat(c, "application_name='" STRVER "'");
64     */
65 
66     // connect
67     zabbix_log(LOG_LEVEL_DEBUG, "Connecting to PostgreSQL with: %s", connstring);
68     conn = PQconnectdb(connstring);
69     if(CONNECTION_OK != PQstatus(conn)) {
70         set_err_result(result, PQerrorMessage(conn));
71         PQfinish(conn);
72         conn = NULL;
73     }
74 
75     zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
76     return conn;
77 }
78 
79 /*
80  * Function: pg_connect_request
81  *
82  * Parses a Zabbix agent request and returns a PostgreSQL connection.
83  *
84  * See: http://www.postgresql.org/docs/9.4/static/libpq-connect.html#LIBPQ-PQCONNECTDB
85  *
86  * Parameter [request]:     Zabbix agent request structure.
87  *          The following parameters may be set:
88  *
89  *          0: connection string (default: DEFAULT_CONN_STRING)
90  *          1: connection database (default: DEFAULT_CONN_DBNAME)
91  *
92  * Parameter [result]:      result structure to send errors to the server
93  *
94  * Returns: Valid PostgreSQL connection or NULL on error
95  */
pg_connect_request(AGENT_REQUEST * request,AGENT_RESULT * result)96  PGconn    *pg_connect_request(AGENT_REQUEST *request, AGENT_RESULT *result)
97  {
98     PGconn      *conn = NULL;
99     char        *connstring = NULL;
100 
101     // connect using params from agent request
102     connstring = build_connstring(
103         get_rparam(request, PARAM_CONN_STRING),
104         get_rparam(request, PARAM_DBNAME));
105 
106     conn = pg_connect(connstring, result);
107     zbx_free(connstring);
108 
109     return conn;
110 }
111