summaryrefslogtreecommitdiff
path: root/src/bin/psql/command.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1999-11-04 23:14:30 +0000
committerBruce Momjian <bruce@momjian.us>1999-11-04 23:14:30 +0000
commit0e6652e67357354e01f2466184343d0bc0ee2cab (patch)
tree0c06450508417e033f8a2b90241a7126cd54c4fe /src/bin/psql/command.c
parent2323b63631080b7d4c287872a83b0ea30bd7874a (diff)
psql cleanup
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r--src/bin/psql/command.c1953
1 files changed, 1049 insertions, 904 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 6bcf96c9cda..29df2792625 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -7,9 +7,9 @@
#include <stdlib.h>
#include <ctype.h>
#ifndef WIN32
-#include <sys/types.h> /* for umask() */
-#include <sys/stat.h> /* for umask(), stat() */
-#include <unistd.h> /* for geteuid(), getpid(), stat() */
+#include <sys/types.h> /* for umask() */
+#include <sys/stat.h> /* for umask(), stat() */
+#include <unistd.h> /* for geteuid(), getpid(), stat() */
#endif
#include <assert.h>
@@ -35,21 +35,20 @@
/* functions for use in this file only */
-static backslashResult
-exec_command(const char * cmd,
- char * const * options,
- const char * options_string,
- PQExpBuffer query_buf,
- PsqlSettings * pset);
+static backslashResult exec_command(const char *cmd,
+ char *const * options,
+ const char *options_string,
+ PQExpBuffer query_buf,
+ PsqlSettings *pset);
static bool
-do_edit(const char *filename_arg, PQExpBuffer query_buf);
+ do_edit(const char *filename_arg, PQExpBuffer query_buf);
static char *
-unescape(const char * source, PsqlSettings * pset);
+ unescape(const char *source, PsqlSettings *pset);
static bool
-do_shell(const char *command);
+ do_shell(const char *command);
@@ -72,538 +71,616 @@ do_shell(const char *command);
backslashResult
HandleSlashCmds(PsqlSettings *pset,
- const char *line,
- PQExpBuffer query_buf,
- const char ** end_of_cmd)
+ const char *line,
+ PQExpBuffer query_buf,
+ const char **end_of_cmd)
{
- backslashResult status = CMD_SKIP_LINE;
- char * my_line;
- char * options[17] ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- char * token;
- const char * options_string = NULL;
- const char * cmd;
- size_t blank_loc;
- int i;
- const char * continue_parse = NULL; /* tell the mainloop where the backslash command ended */
-
- my_line = xstrdup(line);
-
- /* Find the first whitespace (or backslash)
- line[blank_loc] will now be the whitespace character
- or the \0 at the end */
- blank_loc = strcspn(my_line, " \t");
-
- /* do we have an option string? */
- if (my_line[blank_loc] != '\0') {
- options_string = &my_line[blank_loc+1];
-
- my_line[blank_loc] = '\0';
- }
-
- if (options_string) {
- char quote;
- unsigned int pos;
- options_string = &options_string[strspn(options_string, " \t")]; /* skip leading whitespace */
-
- i = 0;
- token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos);
-
- for (i = 0; token && i<16; i++) {
- switch(quote) {
- case '"':
- options[i] = unescape(token, pset);
- break;
- case '\'':
- options[i] = xstrdup(token);
- break;
- case '`':
- {
- bool error = false;
- FILE * fd = NULL;
- char * file = unescape(token, pset);
- PQExpBufferData output;
- char buf[512];
- size_t result;
-
- fd = popen(file, "r");
- if (!fd) {
- perror(file);
- error = true;
- }
+ backslashResult status = CMD_SKIP_LINE;
+ char *my_line;
+ char *options[17] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ char *token;
+ const char *options_string = NULL;
+ const char *cmd;
+ size_t blank_loc;
+ int i;
+ const char *continue_parse = NULL; /* tell the mainloop where the
+ * backslash command ended */
+
+ my_line = xstrdup(line);
+
+ /*
+ * Find the first whitespace (or backslash) line[blank_loc] will now
+ * be the whitespace character or the \0 at the end
+ */
+ blank_loc = strcspn(my_line, " \t");
+
+ /* do we have an option string? */
+ if (my_line[blank_loc] != '\0')
+ {
+ options_string = &my_line[blank_loc + 1];
- if (!error) {
- initPQExpBuffer(&output);
+ my_line[blank_loc] = '\0';
+ }
- do {
- result = fread(buf, 1, 512, fd);
- if (ferror(fd)) {
- perror(file);
- error = true;
- break;
+ if (options_string)
+ {
+ char quote;
+ unsigned int pos;
+
+ options_string = &options_string[strspn(options_string, " \t")]; /* skip leading
+ * whitespace */
+
+ i = 0;
+ token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos);
+
+ for (i = 0; token && i < 16; i++)
+ {
+ switch (quote)
+ {
+ case '"':
+ options[i] = unescape(token, pset);
+ break;
+ case '\'':
+ options[i] = xstrdup(token);
+ break;
+ case '`':
+ {
+ bool error = false;
+ FILE *fd = NULL;
+ char *file = unescape(token, pset);
+ PQExpBufferData output;
+ char buf[512];
+ size_t result;
+
+ fd = popen(file, "r");
+ if (!fd)
+ {
+ perror(file);
+ error = true;
+ }
+
+ if (!error)
+ {
+ initPQExpBuffer(&output);
+
+ do
+ {
+ result = fread(buf, 1, 512, fd);
+ if (ferror(fd))
+ {
+ perror(file);
+ error = true;
+ break;
+ }
+ appendBinaryPQExpBuffer(&output, buf, result);
+ } while (!feof(fd));
+ appendPQExpBufferChar(&output, '\0');
+
+ if (pclose(fd) == -1)
+ {
+ perror(file);
+ error = true;
+ }
+ }
+
+ if (!error)
+ {
+ if (output.data[strlen(output.data) - 1] == '\n')
+ output.data[strlen(output.data) - 1] = '\0';
+ }
+
+ free(file);
+ if (!error)
+ options[i] = output.data;
+ else
+ {
+ options[i] = xstrdup("");
+ termPQExpBuffer(&output);
+ }
+ break;
+ }
+ case 0:
+ default:
+ if (token[0] == '\\')
+ continue_parse = options_string + pos;
+ else if (token[0] == '$')
+ options[i] = xstrdup(interpolate_var(token + 1, pset));
+ else
+ options[i] = xstrdup(token);
+ break;
}
- appendBinaryPQExpBuffer(&output, buf, result);
- } while (!feof(fd));
- appendPQExpBufferChar(&output, '\0');
-
- if (pclose(fd) == -1) {
- perror(file);
- error = true;
- }
- }
- if (!error) {
- if (output.data[strlen(output.data)-1] == '\n')
- output.data[strlen(output.data)-1] = '\0';
- }
+ if (continue_parse)
+ break;
- free(file);
- if (!error)
- options[i] = output.data;
- else {
- options[i] = xstrdup("");
- termPQExpBuffer(&output);
+ token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos);
}
- break;
- }
- case 0:
- default:
- if (token[0] == '\\')
- continue_parse = options_string + pos;
- else if (token[0] == '$')
- options[i] = xstrdup(interpolate_var(token+1, pset));
- else
- options[i] = xstrdup(token);
- break;
- }
-
- if (continue_parse)
- break;
-
- token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos);
}
- }
- cmd = my_line;
+ cmd = my_line;
- status = exec_command(cmd, options, options_string, query_buf, pset);
+ status = exec_command(cmd, options, options_string, query_buf, pset);
- if (status == CMD_UNKNOWN) {
- /* If the command was not recognized, try inserting a space after
- the first letter and call again. The one letter commands
- allow arguments to start immediately after the command,
- but that is no longer encouraged. */
- const char * new_options[17];
- char new_cmd[2];
- int i;
+ if (status == CMD_UNKNOWN)
+ {
- for (i=1; i<17; i++)
- new_options[i] = options[i-1];
- new_options[0] = cmd+1;
+ /*
+ * If the command was not recognized, try inserting a space after
+ * the first letter and call again. The one letter commands allow
+ * arguments to start immediately after the command, but that is
+ * no longer encouraged.
+ */
+ const char *new_options[17];
+ char new_cmd[2];
+ int i;
- new_cmd[0] = cmd[0];
- new_cmd[1] = '\0';
+ for (i = 1; i < 17; i++)
+ new_options[i] = options[i - 1];
+ new_options[0] = cmd + 1;
+
+ new_cmd[0] = cmd[0];
+ new_cmd[1] = '\0';
+
+ status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf, pset);
+ }
- status = exec_command(new_cmd, (char * const *)new_options, my_line+2, query_buf, pset);
- }
+ if (status == CMD_UNKNOWN)
+ {
+ fprintf(stderr, "Unrecognized command: \\%s. Try \\? for help.\n", cmd);
+ status = CMD_ERROR;
+ }
- if (status == CMD_UNKNOWN) {
- fprintf(stderr, "Unrecognized command: \\%s. Try \\? for help.\n", cmd);
- status = CMD_ERROR;
- }
-
- if (continue_parse && *(continue_parse+1) == '\\')
- continue_parse+=2;
+ if (continue_parse && *(continue_parse + 1) == '\\')
+ continue_parse += 2;
- if (end_of_cmd) {
- if (continue_parse)
- *end_of_cmd = line + (continue_parse - my_line);
- else
- *end_of_cmd = NULL;
- }
+ if (end_of_cmd)
+ {
+ if (continue_parse)
+ *end_of_cmd = line + (continue_parse - my_line);
+ else
+ *end_of_cmd = NULL;
+ }
- /* clean up */
- for (i = 0; i<16 && options[i]; i++)
- free(options[i]);
+ /* clean up */
+ for (i = 0; i < 16 && options[i]; i++)
+ free(options[i]);
- free(my_line);
+ free(my_line);
- return status;
+ return status;
}
static backslashResult
-exec_command(const char * cmd,
- char * const * options,
- const char * options_string,
- PQExpBuffer query_buf,
- PsqlSettings * pset)
+exec_command(const char *cmd,
+ char *const * options,
+ const char *options_string,
+ PQExpBuffer query_buf,
+ PsqlSettings *pset)
{
- bool success = true; /* indicate here if the command ran ok or failed */
- bool quiet = GetVariableBool(pset->vars, "quiet");
+ bool success = true; /* indicate here if the command ran ok or
+ * failed */
+ bool quiet = GetVariableBool(pset->vars, "quiet");
- backslashResult status = CMD_SKIP_LINE;
+ backslashResult status = CMD_SKIP_LINE;
- /* \a -- toggle field alignment
- This is deprecated and makes no sense, but we keep it around. */
- if (strcmp(cmd, "a") == 0) {
- if (pset->popt.topt.format != PRINT_ALIGNED)
- success = do_pset("format", "aligned", &pset->popt, quiet);
- else
- success = do_pset("format", "unaligned", &pset->popt, quiet);
- }
-
-
- /* \C -- override table title
- (formerly change HTML caption) This is deprecated. */
- else if (strcmp(cmd, "C") == 0)
- success = do_pset("title", options[0], &pset->popt, quiet);
-
-
-
- /* \c or \connect -- connect to new database or as different user
- *
- * \c foo bar : connect to db "foo" as user "bar"
- * \c foo [-] : connect to db "foo" as current user
- * \c - bar : connect to current db as user "bar"
- * \c : connect to default db as default user
- */
- else if (strcmp(cmd, "c")==0 || strcmp(cmd, "connect")==0)
- {
- if (options[1])
- /* gave username */
- success = do_connect(options[0], options[1], pset);
- else {
- if (options[0])
- /* gave database name */
- success = do_connect(options[0], "", pset); /* empty string is same username as before,
- NULL would mean libpq default */
- else
- /* connect to default db as default user */
- success = do_connect(NULL, NULL, pset);
+ /*
+ * \a -- toggle field alignment This is deprecated and makes no sense,
+ * but we keep it around.
+ */
+ if (strcmp(cmd, "a") == 0)
+ {
+ if (pset->popt.topt.format != PRINT_ALIGNED)
+ success = do_pset("format", "aligned", &pset->popt, quiet);
+ else
+ success = do_pset("format", "unaligned", &pset->popt, quiet);
}
- }
-
-
- /* \copy */
- else if (strcmp(cmd, "copy") == 0)
- success = do_copy(options_string, pset);
-
- /* \copyright */
- else if (strcmp(cmd, "copyright") == 0)
- print_copyright();
-
- /* \d* commands */
- else if (cmd[0] == 'd') {
- switch(cmd[1]) {
- case '\0':
- if (options[0])
- success = describeTableDetails(options[0], pset);
- else
- success = listTables("tvs", NULL, pset); /* standard listing of interesting things */
- break;
- case 'a':
- success = describeAggregates(options[0], pset);
- break;
- case 'd':
- success = objectDescription(options[0], pset);
- break;
- case 'f':
- success = describeFunctions(options[0], pset);
- break;
- case 'l':
- success = do_lo_list(pset);
- break;
- case 'o':
- success = describeOperators(options[0], pset);
- break;
- case 'p':
- success = permissionsList(options[0], pset);
- break;
- case 'T':
- success = describeTypes(options[0], pset);
- break;
- case 't': case 'v': case 'i': case 's': case 'S':
- if (cmd[1] == 'S' && cmd[2] == '\0')
- success = listTables("Stvs", NULL, pset);
- else
- success = listTables(&cmd[1], options[0], pset);
- break;
- default:
- status = CMD_UNKNOWN;
+
+
+ /*
+ * \C -- override table title (formerly change HTML caption) This is
+ * deprecated.
+ */
+ else if (strcmp(cmd, "C") == 0)
+ success = do_pset("title", options[0], &pset->popt, quiet);
+
+
+
+ /*
+ * \c or \connect -- connect to new database or as different user
+ *
+ * \c foo bar : connect to db "foo" as user "bar" \c foo [-] :
+ * connect to db "foo" as current user \c - bar : connect to
+ * current db as user "bar" \c : connect to default db as
+ * default user
+ */
+ else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
+ {
+ if (options[1])
+ /* gave username */
+ success = do_connect(options[0], options[1], pset);
+ else
+ {
+ if (options[0])
+ /* gave database name */
+ success = do_connect(options[0], "", pset); /* empty string is same
+ * username as before,
+ * NULL would mean libpq
+ * default */
+ else
+ /* connect to default db as default user */
+ success = do_connect(NULL, NULL, pset);
+ }
}
- }
- /* \e or \edit -- edit the current query buffer (or a file and make it the
- query buffer */
- else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
- status = do_edit(options[0], query_buf) ? CMD_NEWEDIT : CMD_ERROR;
+ /* \copy */
+ else if (strcmp(cmd, "copy") == 0)
+ success = do_copy(options_string, pset);
+ /* \copyright */
+ else if (strcmp(cmd, "copyright") == 0)
+ print_copyright();
- /* \echo */
- else if (strcmp(cmd, "echo") == 0) {
- int i;
- for (i=0; i<16 && options[i]; i++)
- fputs(options[i], stdout);
- fputs("\n", stdout);
- }
+ /* \d* commands */
+ else if (cmd[0] == 'd')
+ {
+ switch (cmd[1])
+ {
+ case '\0':
+ if (options[0])
+ success = describeTableDetails(options[0], pset);
+ else
+ success = listTables("tvs", NULL, pset); /* standard listing of
+ * interesting things */
+ break;
+ case 'a':
+ success = describeAggregates(options[0], pset);
+ break;
+ case 'd':
+ success = objectDescription(options[0], pset);
+ break;
+ case 'f':
+ success = describeFunctions(options[0], pset);
+ break;
+ case 'l':
+ success = do_lo_list(pset);
+ break;
+ case 'o':
+ success = describeOperators(options[0], pset);
+ break;
+ case 'p':
+ success = permissionsList(options[0], pset);
+ break;
+ case 'T':
+ success = describeTypes(options[0], pset);
+ break;
+ case 't':
+ case 'v':
+ case 'i':
+ case 's':
+ case 'S':
+ if (cmd[1] == 'S' && cmd[2] == '\0')
+ success = listTables("Stvs", NULL, pset);
+ else
+ success = listTables(&cmd[1], options[0], pset);
+ break;
+ default:
+ status = CMD_UNKNOWN;
+ }
+ }
- /* \f -- change field separator
- (This is deprecated in favour of \pset.) */
- else if (strcmp(cmd, "f") == 0)
- success = do_pset("fieldsep", options[0], &pset->popt, quiet);
+ /*
+ * \e or \edit -- edit the current query buffer (or a file and make it
+ * the query buffer
+ */
+ else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
+ status = do_edit(options[0], query_buf) ? CMD_NEWEDIT : CMD_ERROR;
- /* \g means send query */
- else if (strcmp(cmd, "g") == 0) {
- if (!options[0])
- pset->gfname = NULL;
- else
- pset->gfname = xstrdup(options[0]);
- status = CMD_SEND;
- }
- /* help */
- else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
- helpSQL(options_string);
+ /* \echo */
+ else if (strcmp(cmd, "echo") == 0)
+ {
+ int i;
+ for (i = 0; i < 16 && options[i]; i++)
+ fputs(options[i], stdout);
+ fputs("\n", stdout);
+ }
- /* HTML mode */
- else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
- success = do_pset("format", "html", &pset->popt, quiet);
+ /*
+ * \f -- change field separator (This is deprecated in favour of
+ * \pset.)
+ */
+ else if (strcmp(cmd, "f") == 0)
+ success = do_pset("fieldsep", options[0], &pset->popt, quiet);
- /* \i is include file */
- else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
- {
- if (!options[0]) {
- fputs("Usage: \\i <filename>\n", stderr);
- success = false;
+ /* \g means send query */
+ else if (strcmp(cmd, "g") == 0)
+ {
+ if (!options[0])
+ pset->gfname = NULL;
+ else
+ pset->gfname = xstrdup(options[0]);
+ status = CMD_SEND;
}
- else
- success = process_file(options[0], pset);
- }
-
- /* \l is list databases */
- else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
- success = listAllDbs(pset);
-
-
- /* large object things */
- else if (strncmp(cmd, "lo_", 3)==0) {
- if (strcmp(cmd+3, "export") == 0) {
- if (!options[1]) {
- fputs("Usage: \\lo_export <loid> <filename>\n", stderr);
- success = false;
- }
- else
- success = do_lo_export(pset, options[0], options[1]);
+
+ /* help */
+ else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
+ helpSQL(options_string);
+
+
+ /* HTML mode */
+ else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
+ success = do_pset("format", "html", &pset->popt, quiet);
+
+
+ /* \i is include file */
+ else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
+ {
+ if (!options[0])
+ {
+ fputs("Usage: \\i <filename>\n", stderr);
+ success = false;
+ }
+ else
+ success = process_file(options[0], pset);
}
- else if (strcmp(cmd+3, "import") == 0) {
- if (!options[0]) {
- fputs("Usage: \\lo_import <filename> [<description>]\n", stderr);
- success = false;
- }
- else
- success = do_lo_import(pset, options[0], options[1]);
+ /* \l is list databases */
+ else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
+ success = listAllDbs(pset);
+
+
+ /* large object things */
+ else if (strncmp(cmd, "lo_", 3) == 0)
+ {
+ if (strcmp(cmd + 3, "export") == 0)
+ {
+ if (!options[1])
+ {
+ fputs("Usage: \\lo_export <loid> <filename>\n", stderr);
+ success = false;
+ }
+ else
+ success = do_lo_export(pset, options[0], options[1]);
+ }
+
+ else if (strcmp(cmd + 3, "import") == 0)
+ {
+ if (!options[0])
+ {
+ fputs("Usage: \\lo_import <filename> [<description>]\n", stderr);
+ success = false;
+ }
+ else
+ success = do_lo_import(pset, options[0], options[1]);
+ }
+
+ else if (strcmp(cmd + 3, "list") == 0)
+ success = do_lo_list(pset);
+
+ else if (strcmp(cmd + 3, "unlink") == 0)
+ {
+ if (!options[0])
+ {
+ fputs("Usage: \\lo_unlink <loid>\n", stderr);
+ success = false;
+ }
+ else
+ success = do_lo_unlink(pset, options[0]);
+ }
+
+ else
+ status = CMD_UNKNOWN;
}
- else if (strcmp(cmd+3, "list") == 0)
- success = do_lo_list(pset);
+ /* \o -- set query output */
+ else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
+ success = setQFout(options[0], pset);
- else if (strcmp(cmd+3, "unlink") == 0) {
- if (!options[0]) {
- fputs("Usage: \\lo_unlink <loid>\n", stderr);
- success = false;
- }
- else
- success = do_lo_unlink(pset, options[0]);
+
+ /* \p prints the current query buffer */
+ else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
+ {
+ if (query_buf && query_buf->len > 0)
+ puts(query_buf->data);
+ else if (!GetVariableBool(pset->vars, "quiet"))
+ puts("Query buffer is empty.");
}
- else
- status = CMD_UNKNOWN;
- }
-
- /* \o -- set query output */
- else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
- success = setQFout(options[0], pset);
-
-
- /* \p prints the current query buffer */
- else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0 )
- {
- if (query_buf && query_buf->len > 0)
- puts(query_buf->data);
- else if (!GetVariableBool(pset->vars, "quiet"))
- puts("Query buffer is empty.");
- }
-
- /* \pset -- set printing parameters */
- else if (strcmp(cmd, "pset")==0) {
- if (!options[0]) {
- fputs("Usage: \\pset <parameter> [<value>]\n", stderr);
- success = false;
+ /* \pset -- set printing parameters */
+ else if (strcmp(cmd, "pset") == 0)
+ {
+ if (!options[0])
+ {
+ fputs("Usage: \\pset <parameter> [<value>]\n", stderr);
+ success = false;
+ }
+ else
+ success = do_pset(options[0], options[1], &pset->popt, quiet);
}
- else
- success = do_pset(options[0], options[1], &pset->popt, quiet);
- }
-
- /* \q or \quit */
- else if (strcmp(cmd, "q")==0 || strcmp(cmd, "quit")==0)
- status = CMD_TERMINATE;
-
- /* \qecho */
- else if (strcmp(cmd, "qecho") == 0) {
- int i;
- for (i=0; i<16 && options[i]; i++)
- fputs(options[i], pset->queryFout);
- fputs("\n", pset->queryFout);
- }
-
- /* reset(clear) the buffer */
- else if (strcmp(cmd, "r")==0 || strcmp(cmd, "reset")==0)
- {
- resetPQExpBuffer(query_buf);
- if (!quiet) puts("Query buffer reset (cleared).");
- }
-
-
- /* \s save history in a file or show it on the screen */
- else if (strcmp(cmd, "s")==0)
- {
- const char * fname;
- if (!options[0])
- fname = "/dev/tty";
- else
- fname = options[0];
-
- success = saveHistory(fname);
-
- if (success && !quiet && options[0])
- printf("Wrote history to %s.\n", fname);
- }
-
-
- /* \set -- generalized set option command */
- else if (strcmp(cmd, "set")==0)
- {
- if (!options[0]) {
- /* list all variables */
- /* (This is in utter violation of the GetVariable abstraction, but
- I have not dreamt up a better way.) */
- struct _variable * ptr;
- for (ptr = pset->vars; ptr->next; ptr = ptr->next)
- fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
- success = true;
+
+ /* \q or \quit */
+ else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
+ status = CMD_TERMINATE;
+
+ /* \qecho */
+ else if (strcmp(cmd, "qecho") == 0)
+ {
+ int i;
+
+ for (i = 0; i < 16 && options[i]; i++)
+ fputs(options[i], pset->queryFout);
+ fputs("\n", pset->queryFout);
}
- else {
- if (!SetVariable(pset->vars, options[0], options[1])) {
- fprintf(stderr, "Set variable failed.\n");
- success = false;
- }
+
+ /* reset(clear) the buffer */
+ else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
+ {
+ resetPQExpBuffer(query_buf);
+ if (!quiet)
+ puts("Query buffer reset (cleared).");
}
- }
- /* \t -- turn off headers and row count */
- else if (strcmp(cmd, "t")==0)
- success = do_pset("tuples_only", NULL, &pset->popt, quiet);
+ /* \s save history in a file or show it on the screen */
+ else if (strcmp(cmd, "s") == 0)
+ {
+ const char *fname;
+
+ if (!options[0])
+ fname = "/dev/tty";
+ else
+ fname = options[0];
- /* \T -- define html <table ...> attributes */
- else if (strcmp(cmd, "T")==0)
- success = do_pset("tableattr", options[0], &pset->popt, quiet);
+ success = saveHistory(fname);
+ if (success && !quiet && options[0])
+ printf("Wrote history to %s.\n", fname);
+ }
- /* \w -- write query buffer to file */
- else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0 )
- {
- FILE *fd = NULL;
- bool pipe = false;
- if (!options[0]) {
- fprintf(stderr, "Usage \\%s <filename>\n", cmd);
- success = false;
+ /* \set -- generalized set option command */
+ else if (strcmp(cmd, "set") == 0)
+ {
+ if (!options[0])
+ {
+ /* list all variables */
+
+ /*
+ * (This is in utter violation of the GetVariable abstraction,
+ * but I have not dreamt up a better way.)
+ */
+ struct _variable *ptr;
+
+ for (ptr = pset->vars; ptr->next; ptr = ptr->next)
+ fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
+ success = true;
+ }
+ else
+ {
+ if (!SetVariable(pset->vars, options[0], options[1]))
+ {
+ fprintf(stderr, "Set variable failed.\n");
+ success = false;
+ }
+ }
}
- else {
- if (options[0][0] == '|') {
- pipe = true;
+
+ /* \t -- turn off headers and row count */
+ else if (strcmp(cmd, "t") == 0)
+ success = do_pset("tuples_only", NULL, &pset->popt, quiet);
+
+
+ /* \T -- define html <table ...> attributes */
+ else if (strcmp(cmd, "T") == 0)
+ success = do_pset("tableattr", options[0], &pset->popt, quiet);
+
+
+ /* \w -- write query buffer to file */
+ else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
+ {
+ FILE *fd = NULL;
+ bool pipe = false;
+
+ if (!options[0])
+ {
+ fprintf(stderr, "Usage \\%s <filename>\n", cmd);
+ success = false;
+ }
+ else
+ {
+ if (options[0][0] == '|')
+ {
+ pipe = true;
#ifndef __CYGWIN32__
- fd = popen(&options[0][1], "w");
+ fd = popen(&options[0][1], "w");
#else
- fd = popen(&options[0][1], "wb");
+ fd = popen(&options[0][1], "wb");
#endif
- }
- else {
+ }
+ else
+ {
#ifndef __CYGWIN32__
- fd = fopen(options[0], "w");
+ fd = fopen(options[0], "w");
#else
- fd = fopen(options[0], "wb");
+ fd = fopen(options[0], "wb");
#endif
- }
+ }
- if (!fd) {
- perror(options[0]);
- success = false;
- }
- }
+ if (!fd)
+ {
+ perror(options[0]);
+ success = false;
+ }
+ }
- if (fd) {
- int result;
+ if (fd)
+ {
+ int result;
- if (query_buf && query_buf->len > 0)
- fprintf(fd, "%s\n", query_buf->data);
+ if (query_buf && query_buf->len > 0)
+ fprintf(fd, "%s\n", query_buf->data);
- if (pipe)
- result = pclose(fd);
- else
- result = fclose(fd);
+ if (pipe)
+ result = pclose(fd);
+ else
+ result = fclose(fd);
- if (result == EOF) {
- perror("close");
- success = false;
- }
+ if (result == EOF)
+ {
+ perror("close");
+ success = false;
+ }
+ }
}
- }
- /* \x -- toggle expanded table representation */
- else if (strcmp(cmd, "x")==0)
- success = do_pset("expanded", NULL, &pset->popt, quiet);
+ /* \x -- toggle expanded table representation */
+ else if (strcmp(cmd, "x") == 0)
+ success = do_pset("expanded", NULL, &pset->popt, quiet);
- /* list table rights (grant/revoke) */
- else if (strcmp(cmd, "z")==0)
- success = permissionsList(options[0], pset);
-
+ /* list table rights (grant/revoke) */
+ else if (strcmp(cmd, "z") == 0)
+ success = permissionsList(options[0], pset);
- else if (strcmp(cmd, "!")==0)
- success = do_shell(options_string);
- else if (strcmp(cmd, "?")==0)
- slashUsage(pset);
+ else if (strcmp(cmd, "!") == 0)
+ success = do_shell(options_string);
+
+ else if (strcmp(cmd, "?") == 0)
+ slashUsage(pset);
#ifdef NOT_USED
- /* These commands don't do anything. I just use them to test the parser. */
- else if (strcmp(cmd, "void")==0 || strcmp(cmd, "#")==0)
- {
- int i;
- fprintf(stderr, "+ optline = |%s|\n", options_string);
- for(i=0; options[i]; i++)
- fprintf(stderr, "+ opt%d = |%s|\n", i, options[i]);
- }
+
+ /*
+ * These commands don't do anything. I just use them to test the
+ * parser.
+ */
+ else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
+ {
+ int i;
+
+ fprintf(stderr, "+ optline = |%s|\n", options_string);
+ for (i = 0; options[i]; i++)
+ fprintf(stderr, "+ opt%d = |%s|\n", i, options[i]);
+ }
#endif
- else {
- status = CMD_UNKNOWN;
- }
+ else
+ status = CMD_UNKNOWN;
- if (!success) status = CMD_ERROR;
- return status;
+ if (!success)
+ status = CMD_ERROR;
+ return status;
}
@@ -617,104 +694,119 @@ exec_command(const char * cmd,
* The return value is malloc()'ed.
*/
static char *
-unescape(const char * source, PsqlSettings * pset)
+unescape(const char *source, PsqlSettings *pset)
{
- unsigned char *p;
- bool esc = false; /* Last character we saw was the
- escape character */
- char *destination, *tmp;
- size_t length;
+ unsigned char *p;
+ bool esc = false; /* Last character we saw was the escape
+ * character */
+ char *destination,
+ *tmp;
+ size_t length;
#ifdef USE_ASSERT_CHECKING
- assert(source);
+ assert(source);
#endif
- length = strlen(source)+1;
-
- tmp = destination = (char *) malloc(length);
- if (!tmp) {
- perror("malloc");
- exit(EXIT_FAILURE);
- }
-
- for (p = (char *) source; *p; p += PQmblen(p)) {
- if (esc) {
- char c;
-
- switch (*p)
- {
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case 't':
- c = '\t';
- break;
- case 'f':
- c = '\f';
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- long int l;
- char * end;
- l = strtol(p, &end, 0);
- c = l;
- p = end-1;
- break;
- }
- default:
- c = *p;
- }
- *tmp++ = c;
- esc = false;
- }
+ length = strlen(source) + 1;
- else if (*p == '\\') {
- esc = true;
+ tmp = destination = (char *) malloc(length);
+ if (!tmp)
+ {
+ perror("malloc");
+ exit(EXIT_FAILURE);
}
- else if (*p == '$')
+ for (p = (char *) source; *p; p += PQmblen(p))
{
- if (*(p+1) == '{') {
- unsigned int len;
- char *copy;
- const char *value;
- void * new;
- len = strcspn(p+2, "}");
- copy = xstrdup(p+2);
- copy[len] = '\0';
- value = interpolate_var(copy, pset);
-
- length += strlen(value) - (len+3);
- new = realloc(destination, length);
- if (!new) {
- perror("realloc");
- exit(EXIT_FAILURE);
+ if (esc)
+ {
+ char c;
+
+ switch (*p)
+ {
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ long int l;
+ char *end;
+
+ l = strtol(p, &end, 0);
+ c = l;
+ p = end - 1;
+ break;
+ }
+ default:
+ c = *p;
+ }
+ *tmp++ = c;
+ esc = false;
+ }
+
+ else if (*p == '\\')
+ esc = true;
+
+ else if (*p == '$')
+ {
+ if (*(p + 1) == '{')
+ {
+ unsigned int len;
+ char *copy;
+ const char *value;
+ void *new;
+
+ len = strcspn(p + 2, "}");
+ copy = xstrdup(p + 2);
+ copy[len] = '\0';
+ value = interpolate_var(copy, pset);
+
+ length += strlen(value) - (len + 3);
+ new = realloc(destination, length);
+ if (!new)
+ {
+ perror("realloc");
+ exit(EXIT_FAILURE);
+ }
+ tmp = new + (tmp - destination);
+ destination = new;
+
+ strcpy(tmp, value);
+ tmp += strlen(value);
+ p += len + 2;
+ free(copy);
+ }
+ else
+ *tmp++ = '$';
}
- tmp = new + (tmp - destination);
- destination = new;
-
- strcpy(tmp, value);
- tmp += strlen(value);
- p += len + 2;
- free(copy);
- }
- else {
- *tmp++ = '$';
- }
- }
- else {
- *tmp++ = *p;
- esc = false;
+ else
+ {
+ *tmp++ = *p;
+ esc = false;
+ }
}
- }
- *tmp = '\0';
- return destination;
+ *tmp = '\0';
+ return destination;
}
@@ -731,109 +823,120 @@ unescape(const char * source, PsqlSettings * pset)
* but the old one was set back. Otherwise it terminates the program.
*/
bool
-do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset)
+do_connect(const char *new_dbname, const char *new_user, PsqlSettings *pset)
{
- PGconn *oldconn = pset->db;
- const char *dbparam = NULL;
- const char *userparam = NULL;
- char *pwparam = NULL;
- char * prompted_password = NULL;
- char * prompted_user = NULL;
- bool need_pass;
- bool success = false;
-
- /* If dbname is "-" then use old name, else new one (even if NULL) */
- if (new_dbname && PQdb(oldconn) && (strcmp(new_dbname, "-") == 0 || strcmp(new_dbname, PQdb(oldconn))==0))
- dbparam = PQdb(oldconn);
- else
- dbparam = new_dbname;
-
- /* If user is "" or "-" then use the old one */
- if ( new_user && PQuser(oldconn) && ( strcmp(new_user, "")==0 || strcmp(new_user, "-")==0 || strcmp(new_user, PQuser(oldconn))==0 )) {
- userparam = PQuser(oldconn);
- }
- /* If username is "?" then prompt */
- else if (new_user && strcmp(new_user, "?")==0)
- userparam = prompted_user = simple_prompt("Username: ", 100, true); /* save for free() */
- else
- userparam = new_user;
-
- /* need to prompt for password? */
- if (pset->getPassword)
- pwparam = prompted_password = simple_prompt("Password: ", 100, false); /* need to save for free() */
-
- /* Use old password if no new one given (if you didn't have an old one, fine) */
- if (!pwparam)
- pwparam = PQpass(oldconn);
+ PGconn *oldconn = pset->db;
+ const char *dbparam = NULL;
+ const char *userparam = NULL;
+ char *pwparam = NULL;
+ char *prompted_password = NULL;
+ char *prompted_user = NULL;
+ bool need_pass;
+ bool success = false;
+
+ /* If dbname is "-" then use old name, else new one (even if NULL) */
+ if (new_dbname && PQdb(oldconn) && (strcmp(new_dbname, "-") == 0 || strcmp(new_dbname, PQdb(oldconn)) == 0))
+ dbparam = PQdb(oldconn);
+ else
+ dbparam = new_dbname;
+
+ /* If user is "" or "-" then use the old one */
+ if (new_user && PQuser(oldconn) && (strcmp(new_user, "") == 0 || strcmp(new_user, "-") == 0 || strcmp(new_user, PQuser(oldconn)) == 0))
+ userparam = PQuser(oldconn);
+ /* If username is "?" then prompt */
+ else if (new_user && strcmp(new_user, "?") == 0)
+ userparam = prompted_user = simple_prompt("Username: ", 100, true); /* save for free() */
+ else
+ userparam = new_user;
+
+ /* need to prompt for password? */
+ if (pset->getPassword)
+ pwparam = prompted_password = simple_prompt("Password: ", 100, false); /* need to save for
+ * free() */
+
+ /*
+ * Use old password if no new one given (if you didn't have an old
+ * one, fine)
+ */
+ if (!pwparam)
+ pwparam = PQpass(oldconn);
#ifdef MULTIBYTE
- /*
- * PGCLIENTENCODING may be set by the previous connection. if a
- * user does not explicitly set PGCLIENTENCODING, we should
- * discard PGCLIENTENCODING so that libpq could get the backend
- * encoding as the default PGCLIENTENCODING value. -- 1998/12/12
- * Tatsuo Ishii
- */
-
- if (!pset->has_client_encoding)
- putenv("PGCLIENTENCODING=");
+
+ /*
+ * PGCLIENTENCODING may be set by the previous connection. if a user
+ * does not explicitly set PGCLIENTENCODING, we should discard
+ * PGCLIENTENCODING so that libpq could get the backend encoding as
+ * the default PGCLIENTENCODING value. -- 1998/12/12 Tatsuo Ishii
+ */
+
+ if (!pset->has_client_encoding)
+ putenv("PGCLIENTENCODING=");
#endif
- do {
- need_pass = false;
- pset->db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),
- NULL, NULL, dbparam, userparam, pwparam);
-
- if (PQstatus(pset->db)==CONNECTION_BAD &&
- strcmp(PQerrorMessage(pset->db), "fe_sendauth: no password supplied\n")==0) {
- need_pass = true;
- free(prompted_password);
- prompted_password = NULL;
- pwparam = prompted_password = simple_prompt("Password: ", 100, false);
- }
- } while (need_pass);
-
- free(prompted_password);
- free(prompted_user);
-
- /* If connection failed, try at least keep the old one.
- That's probably more convenient than just kicking you out of the
- program. */
- if (!pset->db || PQstatus(pset->db) == CONNECTION_BAD)
- {
- fprintf(stderr, "Could not establish database connection.\n%s", PQerrorMessage(pset->db));
- PQfinish(pset->db);
- if (!oldconn || !pset->cur_cmd_interactive) { /* we don't want unpredictable things to happen
- in scripting mode */
- fputs("Terminating.\n", stderr);
- if (oldconn)
- PQfinish(oldconn);
- pset->db = NULL;
- }
- else {
- fputs("Keeping old connection.\n", stderr);
- pset->db = oldconn;
- }
- }
- else {
- if (!GetVariable(pset->vars, "quiet")) {
- if (userparam != new_user) /* no new user */
- printf("You are now connected to database %s.\n", dbparam);
- else if (dbparam != new_dbname) /* no new db */
- printf("You are now connected as new user %s.\n", new_user);
- else /* both new */
- printf("You are now connected to database %s as user %s.\n",
- PQdb(pset->db), PQuser(pset->db));
+ do
+ {
+ need_pass = false;
+ pset->db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),
+ NULL, NULL, dbparam, userparam, pwparam);
+
+ if (PQstatus(pset->db) == CONNECTION_BAD &&
+ strcmp(PQerrorMessage(pset->db), "fe_sendauth: no password supplied\n") == 0)
+ {
+ need_pass = true;
+ free(prompted_password);
+ prompted_password = NULL;
+ pwparam = prompted_password = simple_prompt("Password: ", 100, false);
+ }
+ } while (need_pass);
+
+ free(prompted_password);
+ free(prompted_user);
+
+ /*
+ * If connection failed, try at least keep the old one. That's
+ * probably more convenient than just kicking you out of the program.
+ */
+ if (!pset->db || PQstatus(pset->db) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Could not establish database connection.\n%s", PQerrorMessage(pset->db));
+ PQfinish(pset->db);
+ if (!oldconn || !pset->cur_cmd_interactive)
+ { /* we don't want unpredictable things to
+ * happen in scripting mode */
+ fputs("Terminating.\n", stderr);
+ if (oldconn)
+ PQfinish(oldconn);
+ pset->db = NULL;
+ }
+ else
+ {
+ fputs("Keeping old connection.\n", stderr);
+ pset->db = oldconn;
+ }
}
+ else
+ {
+ if (!GetVariable(pset->vars, "quiet"))
+ {
+ if (userparam != new_user) /* no new user */
+ printf("You are now connected to database %s.\n", dbparam);
+ else if (dbparam != new_dbname) /* no new db */
+ printf("You are now connected as new user %s.\n", new_user);
+ else
+/* both new */
+ printf("You are now connected to database %s as user %s.\n",
+ PQdb(pset->db), PQuser(pset->db));
+ }
- if (oldconn)
- PQfinish(oldconn);
+ if (oldconn)
+ PQfinish(oldconn);
- success = true;
- }
+ success = true;
+ }
- return success;
+ return success;
}
@@ -848,35 +951,36 @@ do_connect(const char *new_dbname, const char *new_user, PsqlSettings * pset)
static bool
editFile(const char *fname)
{
- char *editorName;
- char *sys;
- int result;
+ char *editorName;
+ char *sys;
+ int result;
#ifdef USE_ASSERT_CHECKING
- assert(fname);
+ assert(fname);
#else
- if (!fname) return false;
+ if (!fname)
+ return false;
#endif
- /* Find an editor to use */
- editorName = getenv("PSQL_EDITOR");
- if (!editorName)
- editorName = getenv("EDITOR");
- if (!editorName)
- editorName = getenv("VISUAL");
- if (!editorName)
- editorName = DEFAULT_EDITOR;
-
- sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1);
- if (!sys)
- return false;
- sprintf(sys, "exec %s %s", editorName, fname);
- result = system(sys);
- if (result == -1 || result == 127)
- perror(sys);
- free(sys);
-
- return result==0;
+ /* Find an editor to use */
+ editorName = getenv("PSQL_EDITOR");
+ if (!editorName)
+ editorName = getenv("EDITOR");
+ if (!editorName)
+ editorName = getenv("VISUAL");
+ if (!editorName)
+ editorName = DEFAULT_EDITOR;
+
+ sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1);
+ if (!sys)
+ return false;
+ sprintf(sys, "exec %s %s", editorName, fname);
+ result = system(sys);
+ if (result == -1 || result == 127)
+ perror(sys);
+ free(sys);
+
+ return result == 0;
}
@@ -884,117 +988,135 @@ editFile(const char *fname)
static bool
do_edit(const char *filename_arg, PQExpBuffer query_buf)
{
- char fnametmp[64];
- FILE * stream;
- const char *fname;
- bool error = false;
+ char fnametmp[64];
+ FILE *stream;
+ const char *fname;
+ bool error = false;
+
#ifndef WIN32
- struct stat before, after;
+ struct stat before,
+ after;
+
#endif
#ifdef USE_ASSERT_CHECKING
- assert(query_buf);
+ assert(query_buf);
#else
- if (!query_buf) return false;
+ if (!query_buf)
+ return false;
#endif
- if (filename_arg)
- fname = filename_arg;
+ if (filename_arg)
+ fname = filename_arg;
- else {
- /* make a temp file to edit */
+ else
+ {
+ /* make a temp file to edit */
#ifndef WIN32
- mode_t oldumask;
+ mode_t oldumask;
- sprintf(fnametmp, "/tmp/psql.edit.%ld.%ld", (long) geteuid(), (long) getpid());
+ sprintf(fnametmp, "/tmp/psql.edit.%ld.%ld", (long) geteuid(), (long) getpid());
#else
- GetTempFileName(".", "psql", 0, fnametmp);
+ GetTempFileName(".", "psql", 0, fnametmp);
#endif
- fname = (const char *)fnametmp;
+ fname = (const char *) fnametmp;
#ifndef WIN32
- oldumask = umask(0177);
+ oldumask = umask(0177);
#endif
- stream = fopen(fname, "w");
+ stream = fopen(fname, "w");
#ifndef WIN32
- umask(oldumask);
+ umask(oldumask);
#endif
- if (!stream) {
- perror(fname);
- error = true;
+ if (!stream)
+ {
+ perror(fname);
+ error = true;
+ }
+ else
+ {
+ unsigned int ql = query_buf->len;
+
+ if (ql == 0 || query_buf->data[ql - 1] != '\n')
+ {
+ appendPQExpBufferChar(query_buf, '\n');
+ ql++;
+ }
+
+ if (fwrite(query_buf->data, 1, ql, stream) != ql)
+ {
+ perror(fname);
+ fclose(stream);
+ remove(fname);
+ error = true;
+ }
+ else
+ fclose(stream);
+ }
}
- else {
- unsigned int ql = query_buf->len;
- if (ql == 0 || query_buf->data[ql - 1] != '\n') {
- appendPQExpBufferChar(query_buf, '\n');
- ql++;
- }
-
- if (fwrite(query_buf->data, 1, ql, stream) != ql) {
+
+#ifndef WIN32
+ if (!error && stat(fname, &before) != 0)
+ {
perror(fname);
- fclose(stream);
- remove(fname);
error = true;
- }
- else
- fclose(stream);
}
- }
-
-#ifndef WIN32
- if (!error && stat(fname, &before) != 0) {
- perror(fname);
- error = true;
- }
#endif
- /* call editor */
- if (!error)
- error = !editFile(fname);
+ /* call editor */
+ if (!error)
+ error = !editFile(fname);
#ifndef WIN32
- if (!error && stat(fname, &after) !=0) {
- perror(fname);
- error = true;
- }
+ if (!error && stat(fname, &after) != 0)
+ {
+ perror(fname);
+ error = true;
+ }
- if (!error && before.st_mtime != after.st_mtime) {
+ if (!error && before.st_mtime != after.st_mtime)
+ {
#else
- if (!error) {
+ if (!error)
+ {
#endif
- stream = fopen(fname, "r");
- if (!stream) {
- perror(fname);
- error = true;
- }
- else {
- /* read file back in */
- char line[1024];
- size_t result;
-
- resetPQExpBuffer(query_buf);
- do {
- result = fread(line, 1, 1024, stream);
- if (ferror(stream)) {
- perror(fname);
- error = true;
- break;
+ stream = fopen(fname, "r");
+ if (!stream)
+ {
+ perror(fname);
+ error = true;
+ }
+ else
+ {
+ /* read file back in */
+ char line[1024];
+ size_t result;
+
+ resetPQExpBuffer(query_buf);
+ do
+ {
+ result = fread(line, 1, 1024, stream);
+ if (ferror(stream))
+ {
+ perror(fname);
+ error = true;
+ break;
+ }
+ appendBinaryPQExpBuffer(query_buf, line, result);
+ } while (!feof(stream));
+ appendPQExpBufferChar(query_buf, '\0');
+
+ fclose(stream);
}
- appendBinaryPQExpBuffer(query_buf, line, result);
- } while (!feof(stream));
- appendPQExpBufferChar(query_buf, '\0');
- fclose(stream);
+ /* remove temp file */
+ if (!filename_arg)
+ remove(fname);
}
- /* remove temp file */
- if (!filename_arg)
- remove(fname);
- }
-
- return !error;
+ return !error;
}
@@ -1008,26 +1130,27 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
bool
process_file(const char *filename, PsqlSettings *pset)
{
- FILE *fd;
- int result;
+ FILE *fd;
+ int result;
- if (!filename)
- return false;
+ if (!filename)
+ return false;
#ifdef __CYGWIN32__
- fd = fopen(filename, "rb");
+ fd = fopen(filename, "rb");
#else
- fd = fopen(filename, "r");
+ fd = fopen(filename, "r");
#endif
- if (!fd) {
- perror(filename);
- return false;
- }
+ if (!fd)
+ {
+ perror(filename);
+ return false;
+ }
- result = MainLoop(pset, fd);
- fclose(fd);
- return (result == EXIT_SUCCESS);
+ result = MainLoop(pset, fd);
+ fclose(fd);
+ return (result == EXIT_SUCCESS);
}
@@ -1039,158 +1162,178 @@ process_file(const char *filename, PsqlSettings *pset)
static const char *
_align2string(enum printFormat in)
{
- switch (in) {
- case PRINT_NOTHING:
- return "nothing";
- break;
- case PRINT_UNALIGNED:
- return "unaligned";
- break;
- case PRINT_ALIGNED:
- return "aligned";
- break;
- case PRINT_HTML:
- return "html";
- break;
- case PRINT_LATEX:
- return "latex";
- break;
- }
- return "unknown";
+ switch (in)
+ {
+ case PRINT_NOTHING:
+ return "nothing";
+ break;
+ case PRINT_UNALIGNED:
+ return "unaligned";
+ break;
+ case PRINT_ALIGNED:
+ return "aligned";
+ break;
+ case PRINT_HTML:
+ return "html";
+ break;
+ case PRINT_LATEX:
+ return "latex";
+ break;
+ }
+ return "unknown";
}
bool
-do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet)
+do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet)
{
- size_t vallen = 0;
+ size_t vallen = 0;
+
#ifdef USE_ASSERT_CHECKING
- assert(param);
+ assert(param);
#else
- if (!param) return false;
+ if (!param)
+ return false;
#endif
- if (value)
- vallen = strlen(value);
-
- /* set format */
- if (strcmp(param, "format")==0) {
- if (!value)
- ;
- else if (strncasecmp("unaligned", value, vallen)==0)
- popt->topt.format = PRINT_UNALIGNED;
- else if (strncasecmp("aligned", value, vallen)==0)
- popt->topt.format = PRINT_ALIGNED;
- else if (strncasecmp("html", value, vallen)==0)
- popt->topt.format = PRINT_HTML;
- else if (strncasecmp("latex", value, vallen)==0)
- popt->topt.format = PRINT_LATEX;
- else {
- fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n");
- return false;
+ if (value)
+ vallen = strlen(value);
+
+ /* set format */
+ if (strcmp(param, "format") == 0)
+ {
+ if (!value)
+ ;
+ else if (strncasecmp("unaligned", value, vallen) == 0)
+ popt->topt.format = PRINT_UNALIGNED;
+ else if (strncasecmp("aligned", value, vallen) == 0)
+ popt->topt.format = PRINT_ALIGNED;
+ else if (strncasecmp("html", value, vallen) == 0)
+ popt->topt.format = PRINT_HTML;
+ else if (strncasecmp("latex", value, vallen) == 0)
+ popt->topt.format = PRINT_LATEX;
+ else
+ {
+ fprintf(stderr, "Allowed formats are unaligned, aligned, html, latex.\n");
+ return false;
+ }
+
+ if (!quiet)
+ printf("Output format is %s.\n", _align2string(popt->topt.format));
}
- if (!quiet)
- printf("Output format is %s.\n", _align2string(popt->topt.format));
- }
+ /* set border style/width */
+ else if (strcmp(param, "border") == 0)
+ {
+ if (value)
+ popt->topt.border = atoi(value);
- /* set border style/width */
- else if (strcmp(param, "border")==0) {
- if (value)
- popt->topt.border = atoi(value);
-
- if (!quiet)
- printf("Border style is %d.\n", popt->topt.border);
- }
-
- /* set expanded/vertical mode */
- else if (strcmp(param, "x")==0 || strcmp(param, "expanded")==0 || strcmp(param, "vertical")==0) {
- popt->topt.expanded = !popt->topt.expanded;
- if (!quiet)
- printf("Expanded display is %s.\n", popt->topt.expanded ? "on" : "off");
- }
-
- /* null display */
- else if (strcmp(param, "null")==0) {
- if (value) {
- free(popt->nullPrint);
- popt->nullPrint = xstrdup(value);
- }
- if (!quiet)
- printf("Null display is \"%s\".\n", popt->nullPrint ? popt->nullPrint : "");
- }
-
- /* field separator for unaligned text */
- else if (strcmp(param, "fieldsep")==0) {
- if (value) {
- free(popt->topt.fieldSep);
- popt->topt.fieldSep = xstrdup(value);
+ if (!quiet)
+ printf("Border style is %d.\n", popt->topt.border);
}
- if (!quiet)
- printf("Field separator is \"%s\".\n", popt->topt.fieldSep);
- }
-
- /* toggle between full and barebones format */
- else if (strcmp(param, "t")==0 || strcmp(param, "tuples_only")==0) {
- popt->topt.tuples_only = !popt->topt.tuples_only;
- if (!quiet) {
- if (popt->topt.tuples_only)
- puts("Showing only tuples.");
- else
- puts("Tuples only is off.");
+
+ /* set expanded/vertical mode */
+ else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
+ {
+ popt->topt.expanded = !popt->topt.expanded;
+ if (!quiet)
+ printf("Expanded display is %s.\n", popt->topt.expanded ? "on" : "off");
}
- }
- /* set title override */
- else if (strcmp(param, "title")==0) {
- free(popt->title);
- if (!value)
- popt->title = NULL;
- else
- popt->title = xstrdup(value);
-
- if (!quiet) {
- if (popt->title)
- printf("Title is \"%s\".\n", popt->title);
- else
- printf("Title is unset.\n");
+ /* null display */
+ else if (strcmp(param, "null") == 0)
+ {
+ if (value)
+ {
+ free(popt->nullPrint);
+ popt->nullPrint = xstrdup(value);
+ }
+ if (!quiet)
+ printf("Null display is \"%s\".\n", popt->nullPrint ? popt->nullPrint : "");
}
- }
- /* set HTML table tag options */
- else if (strcmp(param, "T")==0 || strcmp(param, "tableattr")==0) {
- free(popt->topt.tableAttr);
- if (!value)
- popt->topt.tableAttr = NULL;
- else
- popt->topt.tableAttr = xstrdup(value);
+ /* field separator for unaligned text */
+ else if (strcmp(param, "fieldsep") == 0)
+ {
+ if (value)
+ {
+ free(popt->topt.fieldSep);
+ popt->topt.fieldSep = xstrdup(value);
+ }
+ if (!quiet)
+ printf("Field separator is \"%s\".\n", popt->topt.fieldSep);
+ }
- if (!quiet) {
- if (popt->topt.tableAttr)
- printf("Table attribute is \"%s\".\n", popt->topt.tableAttr);
- else
- printf("Table attributes unset.\n");
+ /* toggle between full and barebones format */
+ else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
+ {
+ popt->topt.tuples_only = !popt->topt.tuples_only;
+ if (!quiet)
+ {
+ if (popt->topt.tuples_only)
+ puts("Showing only tuples.");
+ else
+ puts("Tuples only is off.");
+ }
+ }
+
+ /* set title override */
+ else if (strcmp(param, "title") == 0)
+ {
+ free(popt->title);
+ if (!value)
+ popt->title = NULL;
+ else
+ popt->title = xstrdup(value);
+
+ if (!quiet)
+ {
+ if (popt->title)
+ printf("Title is \"%s\".\n", popt->title);
+ else
+ printf("Title is unset.\n");
+ }
}
- }
-
- /* toggle use of pager */
- else if (strcmp(param, "pager")==0) {
- popt->topt.pager = !popt->topt.pager;
- if (!quiet) {
- if (popt->topt.pager)
- puts("Using pager is on.");
- else
- puts("Using pager is off.");
+
+ /* set HTML table tag options */
+ else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
+ {
+ free(popt->topt.tableAttr);
+ if (!value)
+ popt->topt.tableAttr = NULL;
+ else
+ popt->topt.tableAttr = xstrdup(value);
+
+ if (!quiet)
+ {
+ if (popt->topt.tableAttr)
+ printf("Table attribute is \"%s\".\n", popt->topt.tableAttr);
+ else
+ printf("Table attributes unset.\n");
+ }
}
- }
-
- else {
- fprintf(stderr, "Unknown option: %s\n", param);
- return false;
- }
+ /* toggle use of pager */
+ else if (strcmp(param, "pager") == 0)
+ {
+ popt->topt.pager = !popt->topt.pager;
+ if (!quiet)
+ {
+ if (popt->topt.pager)
+ puts("Using pager is on.");
+ else
+ puts("Using pager is off.");
+ }
+ }
- return true;
+
+ else
+ {
+ fprintf(stderr, "Unknown option: %s\n", param);
+ return false;
+ }
+
+ return true;
}
@@ -1200,29 +1343,31 @@ do_pset(const char * param, const char * value, printQueryOpt * popt, bool quiet
static bool
do_shell(const char *command)
{
- int result;
+ int result;
- if (!command) {
- char *sys;
- char *shellName;
+ if (!command)
+ {
+ char *sys;
+ char *shellName;
+
+ shellName = getenv("SHELL");
+ if (shellName == NULL)
+ shellName = DEFAULT_SHELL;
+
+ sys = malloc(strlen(shellName) + 16);
+ if (!sys)
+ return false;
+ sprintf(sys, "exec %s", shellName);
+ result = system(sys);
+ free(sys);
+ }
+ else
+ result = system(command);
- shellName = getenv("SHELL");
- if (shellName == NULL)
- shellName = DEFAULT_SHELL;
-
- sys = malloc(strlen(shellName) + 16);
- if (!sys)
- return false;
- sprintf(sys, "exec %s", shellName);
- result = system(sys);
- free(sys);
- }
- else
- result = system(command);
-
- if (result==127 || result==-1) {
- perror("system");
- return false;
- }
- return true;
+ if (result == 127 || result == -1)
+ {
+ perror("system");
+ return false;
+ }
+ return true;
}