diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index cc7d797..a793f53 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1029,12 +1029,124 @@ INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g
- \conninfo
-
-
- Outputs information about the current database connection.
-
-
+ \conninfo[+]
+
+ Outputs a string displaying information about the current
+ database connection. When + is appended,
+ more details about the connection are displayed in table
+ format:
+
+
+
+ Database: The database name of the connection.
+
+
+
+ Authenticated User: The authenticated database
+ user of the connection.
+
+
+
+ Socket Directory: The Unix socket directory of
+ the connection. NULL if host or hostaddr are specified.
+
+
+
+ Host: The host name or address of the connection.
+ NULL if a Unix socket is used.
+
+
+
+ Server Port: The IP address of the connection.
+ NULL if a Unix socket is used.
+
+
+
+ Server Address: The IP address of the host name.
+ NULL if a Unix socket is used.
+
+
+
+ Client Address: The IP address of the client connected
+ to this backend. NULL if a Unix socket is used.
+
+
+
+ Client Port: The port of the client connected to this
+ backend. NULL if a Unix socket is used.
+
+
+
+ Backend PID: The process id of the backend for the connection.
+
+
+
+ System User: The authentication data provided for this
+ connection; see the system_user() function in
+ for more details.
+
+
+
+ Current User: The user name of the current execution context;
+ see the current_user() function in
+ for more details.
+
+
+
+ Session User: The session user's name; see the
+ session_user() function in
+ for more details.
+
+
+
+ Application Name: psql is the
+ default for a psql connection unless otherwise specified in
+ the configuration parameter.
+
+
+
+ SSL Connection: True if the current connection to the
+ server uses SSL, and false otherwise.
+
+
+
+ SSL Protocol: The name of the protocol used for the SSL
+ connection (e.g., TLSv1.0, TLSv1.1, TLSv1.2 or TLSv1.3).
+
+
+
+ SSL Cipher: Displays the name of the cipher used
+ for the SSL connection (e.g., DHE-RSA-AES256-SHA).
+
+
+
+ SLL Compression: On if SSL compression is in use, off
+ if not, or NULL if SSL is not in use on this connection.
+
+
+
+ GSSAPI Authenticated: True if GSSAPI is in use, or false
+ if GSSAPI is not in use on this connection.
+
+
+
+ GSSAPI Principal: "Principal" used to authenticate this
+ connection, or NULL if GSSAPI was not used to authenticate this connection.
+ This field is truncated if the principal is longer than NAMEDATALEN
+ (64 characters in a standard build).
+
+
+
+ GSSAPI Encrypted: True if GSSAPI encryption is in use on
+ this connection, or false if encryption is not in use.
+
+
+
+ GSSAPI Credentials Delegated: True if GSSAPI credentials
+ were delegated on this connection, or false if were not delegated.
+
+
+
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index c005624..43ce50e 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -68,7 +68,8 @@ static backslashResult exec_command_C(PsqlScanState scan_state, bool active_bran
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch,
const char *cmd);
-static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch);
+static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch,
+ const char *cmd);
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch);
@@ -318,8 +319,8 @@ exec_command(const char *cmd,
status = exec_command_connect(scan_state, active_branch);
else if (strcmp(cmd, "cd") == 0)
status = exec_command_cd(scan_state, active_branch, cmd);
- else if (strcmp(cmd, "conninfo") == 0)
- status = exec_command_conninfo(scan_state, active_branch);
+ else if (strcmp(cmd, "conninfo") == 0 || strcmp(cmd, "conninfo+") == 0)
+ status = exec_command_conninfo(scan_state, active_branch, cmd);
else if (pg_strcasecmp(cmd, "copy") == 0)
status = exec_command_copy(scan_state, active_branch);
else if (strcmp(cmd, "copyright") == 0)
@@ -644,47 +645,79 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
/*
- * \conninfo -- display information about the current connection
+ * \conninfo, \conninfo+ -- display information about the current connection
*/
static backslashResult
-exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
+exec_command_conninfo(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
+ bool success = true;
+
if (active_branch)
{
char *db = PQdb(pset.db);
+ bool show_verbose;
+
+ show_verbose = strchr(cmd, '+') ? true : false;
- if (db == NULL)
- printf(_("You are currently not connected to a database.\n"));
+ /*
+ * \conninfo+
+ */
+ if (show_verbose)
+ success = listConnectionInformation();
+
+ /*
+ * \conninfo
+ */
else
{
- char *host = PQhost(pset.db);
- char *hostaddr = PQhostaddr(pset.db);
+ PGresult *res;
+ PQExpBufferData buf;
- if (is_unixsock_path(host))
- {
- /* hostaddr overrides host */
- if (hostaddr && *hostaddr)
- printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
- db, PQuser(pset.db), hostaddr, PQport(pset.db));
- else
- printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
- db, PQuser(pset.db), host, PQport(pset.db));
- }
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT inet_server_addr();");
+
+ res = PSQLexec(buf.data);
+
+ termPQExpBuffer(&buf);
+
+ if (!res)
+ return PSQL_CMD_ERROR;
else
{
- if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
- printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
- db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
+ char *host = PQhost(pset.db);
+ char *hostaddr = PQhostaddr(pset.db);
+
+ if (is_unixsock_path(host))
+ {
+ /* hostaddr overrides host */
+ if (hostaddr && *hostaddr)
+ printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), PQgetvalue(res, 0, 0), PQport(pset.db));
+ else
+ printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), host, PQport(pset.db));
+ }
else
- printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
- db, PQuser(pset.db), host, PQport(pset.db));
+ {
+ if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
+ printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
+ db, PQuser(pset.db), host, PQgetvalue(res, 0, 0), PQport(pset.db));
+ else
+ printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), host, PQport(pset.db));
+ }
+ PQclear(res);
+ printSSLInfo();
+ printGSSInfo();
}
- printSSLInfo();
- printGSSInfo();
}
}
+ else
+ ignore_slash_options(scan_state);
- return PSQL_CMD_SKIP_LINE;
+ return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
}
/*
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 6433497..6170c88 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -26,6 +26,7 @@
#include "fe_utils/mbprint.h"
#include "fe_utils/print.h"
#include "fe_utils/string_utils.h"
+#include "libpq/pqcomm.h"
#include "settings.h"
#include "variables.h"
@@ -901,6 +902,165 @@ error_return:
return false;
}
+/*
+ * listConnectionInformation
+ *
+ * for \conninfo+
+ */
+bool
+listConnectionInformation(void)
+{
+ PGresult *res;
+ PQExpBufferData buf;
+ printQueryOpt myopt = pset.popt;
+
+ char *host = PQhost(pset.db);
+ char *hostaddr = PQhostaddr(pset.db);
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT\n"
+ " pg_catalog.current_database() AS \"%s\",\n"
+ " '%s' AS \"%s\",\n",
+ _("Database"),
+ PQuser(pset.db),
+ _("Authenticated User"));
+ if (is_unixsock_path(host) && !(hostaddr && *hostaddr))
+ appendPQExpBuffer(&buf,
+ " '%s' AS \"%s\",\n",
+ host,
+ _("Socket Directory"));
+ else
+ appendPQExpBuffer(&buf,
+ " NULL AS \"%s\",\n",
+ _("Socket Directory"));
+ appendPQExpBuffer(&buf,
+ " CASE\n"
+ " WHEN\n"
+ " pg_catalog.inet_server_addr() IS NULL\n"
+ " AND pg_catalog.inet_client_addr() IS NULL\n"
+ " THEN NULL\n"
+ " ELSE '%s'\n"
+ " END AS \"%s\",\n",
+ _("Host"),
+ host);
+ appendPQExpBuffer(&buf,
+ " pg_catalog.current_setting('port') AS \"%s\",\n"
+ " pg_catalog.inet_server_addr() AS \"%s\",\n"
+ " pg_catalog.inet_client_addr() AS \"%s\",\n"
+ " pg_catalog.inet_client_port() AS \"%s\",\n"
+ " pg_catalog.pg_backend_pid() AS \"%s\",\n",
+ _("Server Port"),
+ _("Server Address"),
+ _("Client Address"),
+ _("Client Port"),
+ _("Backend PID"));
+ if (pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ " pg_catalog.system_user() AS \"%s\",\n",
+ _("System User"));
+ else
+ appendPQExpBuffer(&buf,
+ " NULL AS \"%s\",\n",
+ _("System User"));
+ appendPQExpBuffer(&buf,
+ " pg_catalog.current_user() AS \"%s\",\n"
+ " pg_catalog.session_user() AS \"%s\",\n"
+ " pg_catalog.current_setting('application_name') AS \"%s\",\n",
+ _("Current User"),
+ _("Session User"),
+ _("Application Name"));
+ if (pset.sversion >= 140000)
+ appendPQExpBuffer(&buf,
+ " ssl.ssl AS \"%s\",\n"
+ " ssl.version AS \"%s\",\n"
+ " ssl.cipher AS \"%s\",\n"
+ " NULL AS \"%s\",\n",
+ _("SSL Connection"),
+ _("SSL Protocol"),
+ _("SSL Cipher"),
+ _("SSL Compression"));
+ else if (pset.sversion >= 90500)
+ appendPQExpBuffer(&buf,
+ " ssl.ssl AS \"%s\",\n"
+ " ssl.version AS \"%s\",\n"
+ " ssl.cipher AS \"%s\",\n"
+ " ssl.compression AS \"%s\",\n",
+ _("SSL Connection"),
+ _("SSL Protocol"),
+ _("SSL Cipher"),
+ _("SSL Compression"));
+ else
+ appendPQExpBuffer(&buf,
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\",\n",
+ _("SSL Connection"),
+ _("SSL Protocol"),
+ _("SSL Cipher"),
+ _("SSL Compression"));
+ if (pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ " gssapi.gss_authenticated AS \"%s\",\n"
+ " gssapi.principal AS \"%s\",\n"
+ " gssapi.\"encrypted\" AS \"%s\",\n"
+ " gssapi.credentials_delegated AS \"%s\"\n",
+ _("GSSAPI Authenticated"),
+ _("GSSAPI Principal"),
+ _("GSSAPI Encrypted"),
+ _("GSSAPI Credentials Delegated"));
+ else if (pset.sversion >= 120000)
+ appendPQExpBuffer(&buf,
+ " gssapi.gss_authenticated AS \"%s\",\n"
+ " gssapi.principal AS \"%s\",\n"
+ " gssapi.\"encrypted\" AS \"%s\",\n"
+ " NULL AS \"%s\"\n",
+ _("GSSAPI Authenticated"),
+ _("GSSAPI Principal"),
+ _("GSSAPI Encrypted"),
+ _("GSSAPI Credentials Delegated"));
+ else
+ appendPQExpBuffer(&buf,
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\",\n"
+ " NULL AS \"%s\"\n",
+ _("GSSAPI Authenticated"),
+ _("GSSAPI Principal"),
+ _("GSSAPI Encrypted"),
+ _("GSSAPI Credentials Delegated"));
+ if (pset.sversion >= 120000)
+ appendPQExpBuffer(&buf,
+ "FROM\n"
+ " pg_catalog.pg_stat_ssl ssl\n"
+ "LEFT JOIN\n"
+ " pg_catalog.pg_stat_gssapi gssapi ON ssl.pid = gssapi.pid\n"
+ "WHERE\n"
+ " ssl.pid = pg_catalog.pg_backend_pid()\n");
+ if (pset.sversion >= 90500 && pset.sversion < 120000)
+ appendPQExpBuffer(&buf,
+ "FROM\n"
+ " pg_catalog.pg_stat_ssl ssl\n"
+ "WHERE\n"
+ " ssl.pid = pg_catalog.pg_backend_pid()\n");
+ appendPQExpBuffer(&buf,
+ ";");
+
+ res = PSQLexec(buf.data);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.title = _("Current Connection Information");
+ myopt.translate_header = true;
+
+ printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
/*
* listAllDbs
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 273f974..8a4e83f 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -64,6 +64,9 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
/* \dFt */
extern bool listTSTemplates(const char *pattern, bool verbose);
+/* \conninfo */
+extern bool listConnectionInformation(void);
+
/* \l */
extern bool listAllDbs(const char *pattern, bool verbose);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 4e79a81..2c5426d 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -310,7 +310,7 @@ slashUsage(unsigned short int pager)
else
HELP0(" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n"
" connect to new database (currently no connection)\n");
- HELP0(" \\conninfo display information about current connection\n");
+ HELP0(" \\conninfo[+] display information about current connection\n");
HELP0(" \\encoding [ENCODING] show or set client encoding\n");
HELP0(" \\password [USERNAME] securely change the password for a user\n");
HELP0("\n");