18
18
#include <string.h>
19
19
20
20
const char * progname ;
21
+ char * connection_string = NULL ;
21
22
char * dbhost = NULL ;
22
23
char * dbuser = NULL ;
23
24
char * dbport = NULL ;
@@ -34,31 +35,67 @@ PGconn *
34
35
GetConnection (void )
35
36
{
36
37
PGconn * tmpconn ;
37
- int argcount = 4 ; /* dbname, replication, fallback_app_name,
38
- * password */
38
+ int argcount = 7 ; /* dbname, replication, fallback_app_name,
39
+ * host, user, port, password */
39
40
int i ;
40
41
const char * * keywords ;
41
42
const char * * values ;
42
43
char * password = NULL ;
43
44
const char * tmpparam ;
45
+ PQconninfoOption * conn_opts = NULL ;
46
+ PQconninfoOption * conn_opt ;
47
+ char * err_msg = NULL ;
48
+
49
+ /*
50
+ * Merge the connection info inputs given in form of connection string,
51
+ * options and default values (dbname=replication, replication=true,
52
+ * etc.)
53
+ */
54
+ i = 0 ;
55
+ if (connection_string )
56
+ {
57
+ conn_opts = PQconninfoParse (connection_string , & err_msg );
58
+ if (conn_opts == NULL )
59
+ {
60
+ fprintf (stderr , "%s: %s\n" , progname , err_msg );
61
+ return NULL ;
62
+ }
63
+
64
+ for (conn_opt = conn_opts ; conn_opt -> keyword != NULL ; conn_opt ++ )
65
+ {
66
+ if (conn_opt -> val != NULL && conn_opt -> val [0 ] != '\0' )
67
+ argcount ++ ;
68
+ }
69
+
70
+ keywords = pg_malloc0 ((argcount + 1 ) * sizeof (* keywords ));
71
+ values = pg_malloc0 ((argcount + 1 ) * sizeof (* values ));
72
+
73
+ for (conn_opt = conn_opts ; conn_opt -> keyword != NULL ; conn_opt ++ )
74
+ {
75
+ if (conn_opt -> val != NULL && conn_opt -> val [0 ] != '\0' )
76
+ {
77
+ keywords [i ] = conn_opt -> keyword ;
78
+ values [i ] = conn_opt -> val ;
79
+ i ++ ;
80
+ }
81
+ }
82
+ }
83
+ else
84
+ {
85
+ keywords = pg_malloc0 ((argcount + 1 ) * sizeof (* keywords ));
86
+ values = pg_malloc0 ((argcount + 1 ) * sizeof (* values ));
87
+ }
88
+
89
+ keywords [i ] = "dbname" ;
90
+ values [i ] = "replication" ;
91
+ i ++ ;
92
+ keywords [i ] = "replication" ;
93
+ values [i ] = "true" ;
94
+ i ++ ;
95
+ keywords [i ] = "fallback_application_name" ;
96
+ values [i ] = progname ;
97
+ i ++ ;
44
98
45
- if (dbhost )
46
- argcount ++ ;
47
- if (dbuser )
48
- argcount ++ ;
49
- if (dbport )
50
- argcount ++ ;
51
-
52
- keywords = pg_malloc0 ((argcount + 1 ) * sizeof (* keywords ));
53
- values = pg_malloc0 ((argcount + 1 ) * sizeof (* values ));
54
-
55
- keywords [0 ] = "dbname" ;
56
- values [0 ] = "replication" ;
57
- keywords [1 ] = "replication" ;
58
- values [1 ] = "true" ;
59
- keywords [2 ] = "fallback_application_name" ;
60
- values [2 ] = progname ;
61
- i = 3 ;
62
99
if (dbhost )
63
100
{
64
101
keywords [i ] = "host" ;
@@ -90,15 +127,15 @@ GetConnection(void)
90
127
* meaning this is the call for a second session to the same
91
128
* database, so just forcibly reuse that password.
92
129
*/
93
- keywords [argcount - 1 ] = "password" ;
94
- values [argcount - 1 ] = dbpassword ;
130
+ keywords [i ] = "password" ;
131
+ values [i ] = dbpassword ;
95
132
dbgetpassword = -1 ; /* Don't try again if this fails */
96
133
}
97
134
else if (dbgetpassword == 1 )
98
135
{
99
136
password = simple_prompt (_ ("Password: " ), 100 , false);
100
- keywords [argcount - 1 ] = "password" ;
101
- values [argcount - 1 ] = password ;
137
+ keywords [i ] = "password" ;
138
+ values [i ] = password ;
102
139
}
103
140
104
141
tmpconn = PQconnectdbParams (keywords , values , true);
@@ -130,12 +167,16 @@ GetConnection(void)
130
167
PQfinish (tmpconn );
131
168
free (values );
132
169
free (keywords );
170
+ if (conn_opts )
171
+ PQconninfoFree (conn_opts );
133
172
return NULL ;
134
173
}
135
174
136
175
/* Connection ok! */
137
176
free (values );
138
177
free (keywords );
178
+ if (conn_opts )
179
+ PQconninfoFree (conn_opts );
139
180
140
181
/*
141
182
* Ensure we have the same value of integer timestamps as the server
0 commit comments