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