2 * psql - the PostgreSQL interactive terminal
4 * Copyright 2000-2002 by PostgreSQL Global Development Group
6 * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.80 2002/09/04 20:31:35 momjian Exp $
8 #include "postgres_fe.h"
18 #include <sys/types.h> /* for umask() */
19 #include <sys/stat.h> /* for stat() */
20 #include <fcntl.h> /* open() flags */
21 #include <unistd.h> /* for geteuid(), getpid(), stat() */
29 #include "pqexpbuffer.h"
36 #include "large_obj.h"
40 #include "variables.h"
41 #include "mb/pg_wchar.h"
43 /* functions for use in this file */
45 static backslashResult exec_command(const char *cmd,
46 const char *options_string,
47 const char **continue_parse,
48 PQExpBuffer query_buf,
49 volatile int *paren_level);
51 /* different ways for scan_option to handle parameter words */
54 OT_NORMAL, /* normal case */
55 OT_SQLID, /* treat as SQL identifier */
56 OT_SQLIDHACK, /* SQL identifier, but don't downcase */
57 OT_FILEPIPE /* it's a filename or pipe */
60 static char *scan_option(char **string, enum option_type type,
61 char *quote, bool semicolon);
62 static char *unescape(const unsigned char *source, size_t len);
64 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
65 static bool do_connect(const char *new_dbname, const char *new_user);
66 static bool do_shell(const char *command);
73 * Handles all the different commands that start with '\',
74 * ordinarily called by MainLoop().
76 * 'line' is the current input line, which should not start with a '\'
77 * but with the actual command name
78 * (that is taken care of by MainLoop)
80 * 'query_buf' contains the query-so-far, which may be modified by
81 * execution of the backslash command (for example, \r clears it)
82 * query_buf can be NULL if there is no query so far.
84 * Returns a status code indicating what action is desired, see command.h.
89 HandleSlashCmds(const char *line,
90 PQExpBuffer query_buf,
91 const char **end_of_cmd,
92 volatile int *paren_level)
94 backslashResult status = CMD_SKIP_LINE;
96 char *options_string = NULL;
98 const char *continue_parse = NULL; /* tell the mainloop where the
99 * backslash command ended */
101 #ifdef USE_ASSERT_CHECKING
105 my_line = xstrdup(line);
108 * Find the first whitespace. line[blank_loc] will now be the
109 * whitespace character or the \0 at the end
111 * Also look for a backslash, so stuff like \p\g works.
113 blank_loc = strcspn(my_line, " \t\n\r\\");
115 if (my_line[blank_loc] == '\\')
117 continue_parse = &my_line[blank_loc];
118 my_line[blank_loc] = '\0';
119 /* If it's a double backslash, we skip it. */
120 if (my_line[blank_loc + 1] == '\\')
123 /* do we have an option string? */
124 else if (my_line[blank_loc] != '\0')
126 options_string = &my_line[blank_loc + 1];
127 my_line[blank_loc] = '\0';
130 status = exec_command(my_line, options_string, &continue_parse, query_buf, paren_level);
132 if (status == CMD_UNKNOWN)
135 * If the command was not recognized, try to parse it as a
136 * one-letter command with immediately following argument (a
137 * still-supported, but no longer encouraged, syntax).
141 new_cmd[0] = my_line[0];
144 /* use line for options, because my_line was clobbered above */
145 status = exec_command(new_cmd, line + 1, &continue_parse, query_buf, paren_level);
148 * continue_parse must be relative to my_line for calculation
151 continue_parse += my_line - line;
153 #if 0 /* turned out to be too annoying */
154 if (status != CMD_UNKNOWN && isalpha((unsigned char) new_cmd[0]))
155 psql_error("Warning: This syntax is deprecated.\n");
159 if (status == CMD_UNKNOWN)
161 if (pset.cur_cmd_interactive)
162 fprintf(stderr, gettext("Invalid command \\%s. Try \\? for help.\n"), my_line);
164 psql_error("invalid command \\%s\n", my_line);
168 if (continue_parse && *continue_parse && *(continue_parse + 1) == '\\')
174 *end_of_cmd = line + (continue_parse - my_line);
176 *end_of_cmd = line + strlen(line);
186 static backslashResult
187 exec_command(const char *cmd,
188 const char *options_string,
189 const char **continue_parse,
190 PQExpBuffer query_buf,
191 volatile int *paren_level)
193 bool success = true; /* indicate here if the command ran ok or
195 bool quiet = QUIET();
196 backslashResult status = CMD_SKIP_LINE;
202 * The 'string' variable will be overwritten to point to the next
203 * token, hence we need an extra pointer so we can free this at the
207 string = string_cpy = xstrdup(options_string);
209 string = string_cpy = NULL;
212 * \a -- toggle field alignment This makes little sense but we keep it
215 if (strcmp(cmd, "a") == 0)
217 if (pset.popt.topt.format != PRINT_ALIGNED)
218 success = do_pset("format", "aligned", &pset.popt, quiet);
220 success = do_pset("format", "unaligned", &pset.popt, quiet);
223 /* \C -- override table title (formerly change HTML caption) */
224 else if (strcmp(cmd, "C") == 0)
226 char *opt = scan_option(&string, OT_NORMAL, NULL, true);
228 success = do_pset("title", opt, &pset.popt, quiet);
233 * \c or \connect -- connect to new database or as different user
235 * \c foo bar connect to db "foo" as user "bar"
236 * \c foo [-] connect to db "foo" as current user
237 * \c - bar connect to current db as user "bar"
238 * \c connect to default db as default user
241 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
249 * Ideally we should treat the arguments as SQL identifiers. But
250 * for backwards compatibility with 7.2 and older pg_dump files,
251 * we have to take unquoted arguments verbatim (don't downcase
252 * them). For now, double-quoted arguments may be stripped of
253 * double quotes (as if SQL identifiers). By 7.4 or so, pg_dump
254 * files can be expected to double-quote all mixed-case \connect
255 * arguments, and then we can get rid of OT_SQLIDHACK.
257 opt1 = scan_option(&string, OT_SQLIDHACK, &opt1q, true);
258 opt2 = scan_option(&string, OT_SQLIDHACK, &opt2q, true);
262 success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1,
263 !opt2q && (strcmp(opt2, "-") == 0 || strcmp(opt2, "") == 0) ? "" : opt2);
265 /* gave database name */
266 success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1, "");
268 /* connect to default db as default user */
269 success = do_connect(NULL, NULL);
276 else if (strcmp(cmd, "cd") == 0)
278 char *opt = scan_option(&string, OT_NORMAL, NULL, true);
288 pw = getpwuid(geteuid());
291 psql_error("could not get home directory: %s\n", strerror(errno));
298 * On Windows, 'cd' without arguments prints the current
299 * directory, so if someone wants to code this here instead...
305 if (chdir(dir) == -1)
307 psql_error("\\%s: could not change directory to '%s': %s\n",
308 cmd, dir, strerror(errno));
317 else if (strcasecmp(cmd, "copy") == 0)
319 success = do_copy(options_string);
321 string += strlen(string);
325 else if (strcmp(cmd, "copyright") == 0)
329 else if (cmd[0] == 'd')
334 /* We don't do SQLID reduction on the pattern yet */
335 pattern = scan_option(&string, OT_NORMAL, NULL, true);
337 show_verbose = strchr(cmd, '+') ? true : false;
344 success = describeTableDetails(pattern, show_verbose);
346 /* standard listing of interesting things */
347 success = listTables("tvs", NULL, show_verbose);
350 success = describeAggregates(pattern, show_verbose);
353 success = objectDescription(pattern);
356 success = describeFunctions(pattern, show_verbose);
359 success = do_lo_list();
362 success = describeOperators(pattern);
365 success = permissionsList(pattern);
368 success = describeTypes(pattern, show_verbose);
375 success = listTables(&cmd[1], pattern, show_verbose);
378 success = describeUsers(pattern);
381 success = listDomains(pattern);
385 status = CMD_UNKNOWN;
394 * \e or \edit -- edit the current query buffer (or a file and make it
397 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
403 psql_error("no query buffer\n");
408 fname = scan_option(&string, OT_NORMAL, NULL, true);
409 status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
414 /* \echo and \qecho */
415 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
419 bool no_newline = false;
423 if (strcmp(cmd, "qecho") == 0)
424 fout = pset.queryFout;
428 while ((value = scan_option(&string, OT_NORMAL, "ed, false)))
430 if (!quoted && strcmp(value, "-n") == 0)
446 /* \encoding -- set/show client side encoding */
447 else if (strcmp(cmd, "encoding") == 0)
449 char *encoding = scan_option(&string, OT_NORMAL, NULL, false);
453 puts(pg_encoding_to_char(pset.encoding));
457 if (PQsetClientEncoding(pset.db, encoding) == -1)
458 psql_error("%s: invalid encoding name or conversion proc not found\n", encoding);
462 /* save encoding info into psql internal data */
463 pset.encoding = PQclientEncoding(pset.db);
464 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
470 /* \f -- change field separator */
471 else if (strcmp(cmd, "f") == 0)
473 char *fname = scan_option(&string, OT_NORMAL, NULL, false);
475 success = do_pset("fieldsep", fname, &pset.popt, quiet);
479 /* \g means send query */
480 else if (strcmp(cmd, "g") == 0)
482 char *fname = scan_option(&string, OT_FILEPIPE, NULL, false);
487 pset.gfname = xstrdup(fname);
493 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
495 helpSQL(options_string ? &options_string[strspn(options_string, " \t\n\r")] : NULL);
496 /* set pointer to end of line */
498 string += strlen(string);
502 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
504 if (pset.popt.topt.format != PRINT_HTML)
505 success = do_pset("format", "html", &pset.popt, quiet);
507 success = do_pset("format", "aligned", &pset.popt, quiet);
511 /* \i is include file */
512 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
514 char *fname = scan_option(&string, OT_NORMAL, NULL, true);
518 psql_error("\\%s: missing required argument\n", cmd);
523 success = (process_file(fname) == EXIT_SUCCESS);
528 /* \l is list databases */
529 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
530 success = listAllDbs(false);
531 else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
532 success = listAllDbs(true);
535 * large object things
537 else if (strncmp(cmd, "lo_", 3) == 0)
542 opt1 = scan_option(&string, OT_NORMAL, NULL, true);
543 opt2 = scan_option(&string, OT_NORMAL, NULL, true);
545 if (strcmp(cmd + 3, "export") == 0)
549 psql_error("\\%s: missing required argument\n", cmd);
553 success = do_lo_export(opt1, opt2);
556 else if (strcmp(cmd + 3, "import") == 0)
560 psql_error("\\%s: missing required argument\n", cmd);
564 success = do_lo_import(opt1, opt2);
567 else if (strcmp(cmd + 3, "list") == 0)
568 success = do_lo_list();
570 else if (strcmp(cmd + 3, "unlink") == 0)
574 psql_error("\\%s: missing required argument\n", cmd);
578 success = do_lo_unlink(opt1);
582 status = CMD_UNKNOWN;
589 /* \o -- set query output */
590 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
592 char *fname = scan_option(&string, OT_FILEPIPE, NULL, true);
594 success = setQFout(fname);
598 /* \p prints the current query buffer */
599 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
601 if (query_buf && query_buf->len > 0)
602 puts(query_buf->data);
604 puts(gettext("Query buffer is empty."));
608 /* \pset -- set printing parameters */
609 else if (strcmp(cmd, "pset") == 0)
611 char *opt0 = scan_option(&string, OT_NORMAL, NULL, false);
612 char *opt1 = scan_option(&string, OT_NORMAL, NULL, false);
616 psql_error("\\%s: missing required argument\n", cmd);
620 success = do_pset(opt0, opt1, &pset.popt, quiet);
627 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
628 status = CMD_TERMINATE;
630 /* reset(clear) the buffer */
631 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
633 resetPQExpBuffer(query_buf);
637 puts(gettext("Query buffer reset (cleared)."));
640 /* \s save history in a file or show it on the screen */
641 else if (strcmp(cmd, "s") == 0)
643 char *fname = scan_option(&string, OT_NORMAL, NULL, true);
645 success = saveHistory(fname ? fname : "/dev/tty");
647 if (success && !quiet && fname)
648 printf(gettext("Wrote history to %s.\n"), fname);
652 /* \set -- generalized set variable/option command */
653 else if (strcmp(cmd, "set") == 0)
655 char *opt0 = scan_option(&string, OT_NORMAL, NULL, false);
659 /* list all variables */
662 * XXX This is in utter violation of the GetVariable
663 * abstraction, but I have not bothered to do it better.
665 struct _variable *ptr;
667 for (ptr = pset.vars; ptr->next; ptr = ptr->next)
668 fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
674 * Set variable to the concatenation of the arguments.
679 opt = scan_option(&string, OT_NORMAL, NULL, false);
680 newval = xstrdup(opt ? opt : "");
683 while ((opt = scan_option(&string, OT_NORMAL, NULL, false)))
685 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
688 psql_error("out of memory\n");
695 if (!SetVariable(pset.vars, opt0, newval))
697 psql_error("\\%s: error\n", cmd);
705 /* \t -- turn off headers and row count */
706 else if (strcmp(cmd, "t") == 0)
707 success = do_pset("tuples_only", NULL, &pset.popt, quiet);
710 /* \T -- define html <table ...> attributes */
711 else if (strcmp(cmd, "T") == 0)
713 char *value = scan_option(&string, OT_NORMAL, NULL, false);
715 success = do_pset("tableattr", value, &pset.popt, quiet);
719 /* \timing -- toggle timing of queries */
720 else if (strcmp(cmd, "timing") == 0)
722 pset.timing = !pset.timing;
726 puts(gettext(("Timing is on.")));
729 puts(gettext(("Timing is off.")));
736 else if (strcmp(cmd, "unset") == 0)
738 char *opt = scan_option(&string, OT_NORMAL, NULL, false);
742 psql_error("\\%s: missing required argument\n", cmd);
745 else if (!SetVariable(pset.vars, opt, NULL))
747 psql_error("\\%s: error\n", cmd);
753 /* \w -- write query buffer to file */
754 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
757 bool is_pipe = false;
762 psql_error("no query buffer\n");
767 fname = scan_option(&string, OT_FILEPIPE, NULL, true);
771 psql_error("\\%s: missing required argument\n", cmd);
779 fd = popen(&fname[1], "w");
782 fd = fopen(fname, "w");
786 psql_error("%s: %s\n", fname, strerror(errno));
796 if (query_buf && query_buf->len > 0)
797 fprintf(fd, "%s\n", query_buf->data);
806 psql_error("%s: %s\n", fname, strerror(errno));
814 /* \x -- toggle expanded table representation */
815 else if (strcmp(cmd, "x") == 0)
816 success = do_pset("expanded", NULL, &pset.popt, quiet);
819 /* \z -- list table rights (equivalent to \dp) */
820 else if (strcmp(cmd, "z") == 0)
822 char *pattern = scan_option(&string, OT_NORMAL, NULL, true);
824 success = permissionsList(pattern);
829 /* \! -- shell escape */
830 else if (strcmp(cmd, "!") == 0)
832 success = do_shell(options_string);
833 /* wind pointer to end of line */
835 string += strlen(string);
838 /* \? -- slash command help */
839 else if (strcmp(cmd, "?") == 0)
840 slashUsage(pset.popt.topt.pager);
845 * These commands don't do anything. I just use them to test the
848 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
853 fprintf(stderr, "+ optstr = |%s|\n", options_string);
854 while ((value = scan_option(&string, OT_NORMAL, NULL, true)))
856 fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
863 status = CMD_UNKNOWN;
868 /* eat the rest of the options string */
869 while ((val = scan_option(&string, OT_NORMAL, NULL, false)))
871 if (status != CMD_UNKNOWN)
872 psql_error("\\%s: extra argument '%s' ignored\n", cmd, val);
875 if (options_string && continue_parse)
876 *continue_parse = options_string + (string - string_cpy);
887 * *string points to possible option string on entry; on exit, it's updated
888 * to point past the option string (if any).
890 * type tells what processing, if any, to perform on the option string;
891 * for example, if it's a SQL identifier, we want to downcase any unquoted
894 * if quote is not NULL, *quote is set to 0 if no quoting was found, else
897 * if semicolon is true, trailing semicolon(s) that would otherwise be taken
898 * as part of the option string will be stripped.
900 * Return value is NULL if no option found, else a malloc'd copy of the
901 * processed option value.
904 scan_option(char **string, enum option_type type, char *quote, bool semicolon)
907 char *options_string;
913 if (!string || !(*string))
916 options_string = *string;
917 /* skip leading whitespace */
918 pos = strspn(options_string, " \t\n\r");
920 switch (options_string[pos])
923 * End of line: no option present
926 *string = &options_string[pos];
930 * Next command: treat like end of line
932 * XXX this means we can't conveniently accept options that start
933 * with a backslash; therefore, option processing that
934 * encourages use of backslashes is rather broken.
937 *string = &options_string[pos];
941 * A single quote has a psql internal meaning, such as for
942 * delimiting file names, and it also allows for such escape
948 unsigned short int bslash_count = 0;
950 for (jj = pos + 1; options_string[jj]; jj += PQmblen(&options_string[jj], pset.encoding))
952 if (options_string[jj] == '\'' && bslash_count % 2 == 0)
955 if (options_string[jj] == '\\')
961 if (options_string[jj] == 0)
963 psql_error("parse error at the end of line\n");
964 *string = &options_string[jj];
968 return_val = unescape(&options_string[pos + 1], jj - pos - 1);
969 *string = &options_string[jj + 1];
976 * Backticks are for command substitution, like in shells
983 PQExpBufferData output;
988 len = strcspn(options_string + pos + 1, "`");
989 if (options_string[pos + 1 + len] == 0)
991 psql_error("parse error at the end of line\n");
992 *string = &options_string[pos + 1 + len];
996 options_string[pos + 1 + len] = '\0';
997 file = options_string + pos + 1;
999 fd = popen(file, "r");
1002 psql_error("%s: %s\n", file, strerror(errno));
1006 initPQExpBuffer(&output);
1012 result = fread(buf, 1, 512, fd);
1015 psql_error("%s: %s\n", file, strerror(errno));
1019 appendBinaryPQExpBuffer(&output, buf, result);
1020 } while (!feof(fd));
1021 appendPQExpBufferChar(&output, '\0');
1024 if (fd && pclose(fd) == -1)
1026 psql_error("%s: %s\n", file, strerror(errno));
1032 if (output.data[strlen(output.data) - 1] == '\n')
1033 output.data[strlen(output.data) - 1] = '\0';
1034 return_val = output.data;
1038 return_val = xstrdup("");
1039 termPQExpBuffer(&output);
1042 options_string[pos + 1 + len] = '`';
1043 *string = options_string + pos + len + 2;
1050 * Variable substitution
1058 token_end = strcspn(&options_string[pos + 1], " \t\n\r");
1059 save_char = options_string[pos + token_end + 1];
1060 options_string[pos + token_end + 1] = '\0';
1061 value = GetVariable(pset.vars, options_string + pos + 1);
1064 return_val = xstrdup(value);
1065 options_string[pos + token_end + 1] = save_char;
1066 *string = &options_string[pos + token_end + 1];
1067 /* XXX should we set *quote to ':' here? */
1072 * | could be the beginning of a pipe if so, take rest of line
1076 if (type == OT_FILEPIPE)
1078 *string += strlen(*string);
1079 return xstrdup(options_string + pos);
1081 /* fallthrough for other option types */
1084 * Default case: token extends to next whitespace, except that
1085 * whitespace within double quotes doesn't end the token.
1087 * If we are processing the option as a SQL identifier, then
1088 * downcase unquoted letters and remove double-quotes --- but
1089 * doubled double-quotes become output double-quotes, per
1092 * Note that a string like FOO"BAR"BAZ will be converted to
1093 * fooBARbaz; this is somewhat inconsistent with the SQL spec,
1094 * which would have us parse it as several identifiers. But
1095 * for psql's purposes, we want a string like "foo"."bar" to
1096 * be treated as one option, so there's little choice.
1100 bool inquotes = false;
1104 /* Find end of option */
1106 cp = &options_string[pos];
1109 /* Find next quote, whitespace, or end of string */
1110 cp += strcspn(cp, "\" \t\n\r");
1115 psql_error("parse error at the end of line\n");
1126 break; /* whitespace or end of string */
1136 /* Copy the option */
1137 token_len = cp - &options_string[pos];
1139 return_val = malloc(token_len + 1);
1142 psql_error("out of memory\n");
1146 memcpy(return_val, &options_string[pos], token_len);
1147 return_val[token_len] = '\0';
1149 /* Strip any trailing semi-colons if requested */
1154 for (i = token_len - 1;
1155 i >= 0 && return_val[i] == ';';
1161 /* nothing left after stripping the semicolon... */
1166 if (i < token_len - 1)
1167 return_val[i + 1] = '\0';
1171 * If SQL identifier processing was requested, then we
1172 * strip out excess double quotes and downcase unquoted
1175 if (type == OT_SQLID || type == OT_SQLIDHACK)
1184 if (inquotes && cp[1] == '"')
1186 /* Keep the first quote, remove the second */
1189 inquotes = !inquotes;
1190 /* Collapse out quote at *cp */
1191 memmove(cp, cp + 1, strlen(cp));
1192 /* do not advance cp */
1196 if (!inquotes && type == OT_SQLID)
1198 if (isupper((unsigned char) *cp))
1199 *cp = tolower((unsigned char) *cp);
1201 cp += PQmblen(cp, pset.encoding);
1216 * Replaces \n, \t, and the like.
1218 * The return value is malloc()'ed.
1221 unescape(const unsigned char *source, size_t len)
1223 const unsigned char *p;
1224 bool esc = false; /* Last character we saw was the escape
1230 #ifdef USE_ASSERT_CHECKING
1234 length = Min(len, strlen(source)) + 1;
1236 tmp = destination = malloc(length);
1239 psql_error("out of memory\n");
1243 for (p = source; p - source < len && *p; p += PQmblen(p, pset.encoding))
1280 l = strtol(p, &end, 0);
1292 else if (*p == '\\')
1298 const unsigned char *mp = p;
1300 for (i = 0; i < PQmblen(p, pset.encoding); i++)
1313 * -- handler for \connect
1315 * Connects to a database (new_dbname) as a certain user (new_user).
1316 * The new user can be NULL. A db name of "-" is the same as the old one.
1317 * (That is, the one currently in pset. But pset.db can also be NULL. A NULL
1318 * dbname is handled by libpq.)
1319 * Returns true if all ok, false if the new connection couldn't be established.
1320 * The old connection will be kept if the session is interactive.
1323 do_connect(const char *new_dbname, const char *new_user)
1325 PGconn *oldconn = pset.db;
1326 const char *dbparam = NULL;
1327 const char *userparam = NULL;
1328 const char *pwparam = NULL;
1329 char *prompted_password = NULL;
1331 bool success = false;
1333 /* Delete variables (in case we fail before setting them anew) */
1334 SetVariable(pset.vars, "DBNAME", NULL);
1335 SetVariable(pset.vars, "USER", NULL);
1336 SetVariable(pset.vars, "HOST", NULL);
1337 SetVariable(pset.vars, "PORT", NULL);
1338 SetVariable(pset.vars, "ENCODING", NULL);
1340 /* If dbname is "" then use old name, else new one (even if NULL) */
1341 if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0)
1342 dbparam = PQdb(oldconn);
1344 dbparam = new_dbname;
1346 /* If user is "" then use the old one */
1347 if (new_user && PQuser(oldconn) && strcmp(new_user, "") == 0)
1348 userparam = PQuser(oldconn);
1350 userparam = new_user;
1352 /* need to prompt for password? */
1353 if (pset.getPassword)
1354 pwparam = prompted_password = simple_prompt("Password: ", 100, false);
1357 * Use old password (if any) if no new one given and we are
1358 * reconnecting as same user
1360 if (!pwparam && oldconn && PQuser(oldconn) && userparam &&
1361 strcmp(PQuser(oldconn), userparam) == 0)
1362 pwparam = PQpass(oldconn);
1367 pset.db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),
1368 NULL, NULL, dbparam, userparam, pwparam);
1370 if (PQstatus(pset.db) == CONNECTION_BAD &&
1371 strcmp(PQerrorMessage(pset.db), "fe_sendauth: no password supplied\n") == 0 &&
1376 free(prompted_password);
1377 prompted_password = NULL;
1378 pwparam = prompted_password = simple_prompt("Password: ", 100, false);
1380 } while (need_pass);
1382 free(prompted_password);
1385 * If connection failed, try at least keep the old one. That's
1386 * probably more convenient than just kicking you out of the program.
1388 if (!pset.db || PQstatus(pset.db) == CONNECTION_BAD)
1390 if (pset.cur_cmd_interactive)
1392 psql_error("%s", PQerrorMessage(pset.db));
1396 fputs(gettext("Previous connection kept\n"), stderr);
1405 * we don't want unpredictable things to happen in scripting
1408 psql_error("\\connect: %s", PQerrorMessage(pset.db));
1419 if (userparam != new_user) /* no new user */
1420 printf(gettext("You are now connected to database %s.\n"), dbparam);
1421 else if (dbparam != new_dbname) /* no new db */
1422 printf(gettext("You are now connected as new user %s.\n"), new_user);
1425 printf(gettext("You are now connected to database %s as user %s.\n"),
1426 PQdb(pset.db), PQuser(pset.db));
1435 PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
1436 pset.encoding = PQclientEncoding(pset.db);
1438 /* Update variables */
1439 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1440 SetVariable(pset.vars, "USER", PQuser(pset.db));
1441 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1442 SetVariable(pset.vars, "PORT", PQport(pset.db));
1443 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1445 pset.issuper = test_superuser(PQuser(pset.db));
1453 * Test if the given user is a database superuser.
1454 * (Is used to set up the prompt right.)
1457 test_superuser(const char *username)
1460 PQExpBufferData buf;
1466 initPQExpBuffer(&buf);
1467 printfPQExpBuffer(&buf, "SELECT usesuper FROM pg_catalog.pg_user WHERE usename = '%s'", username);
1468 res = PSQLexec(buf.data);
1469 termPQExpBuffer(&buf);
1472 (PQntuples(res) > 0 && PQnfields(res) > 0
1473 && !PQgetisnull(res, 0, 0)
1474 && PQgetvalue(res, 0, 0)
1475 && strcmp(PQgetvalue(res, 0, 0), "t") == 0);
1483 * do_edit -- handler for \e
1485 * If you do not specify a filename, the current query buffer will be copied
1486 * into a temporary one.
1490 editFile(const char *fname)
1492 const char *editorName;
1496 #ifdef USE_ASSERT_CHECKING
1503 /* Find an editor to use */
1504 editorName = getenv("PSQL_EDITOR");
1506 editorName = getenv("EDITOR");
1508 editorName = getenv("VISUAL");
1510 editorName = DEFAULT_EDITOR;
1512 sys = malloc(strlen(editorName) + strlen(fname) + 10 + 1);
1515 sprintf(sys, "exec '%s' '%s'", editorName, fname);
1516 result = system(sys);
1518 psql_error("could not start editor %s\n", editorName);
1519 else if (result == 127)
1520 psql_error("could not start /bin/sh\n");
1529 do_edit(const char *filename_arg, PQExpBuffer query_buf)
1531 char fnametmp[MAXPGPATH];
1532 FILE *stream = NULL;
1543 fname = filename_arg;
1547 /* make a temp file to edit */
1549 const char *tmpdirenv = getenv("TMPDIR");
1551 snprintf(fnametmp, sizeof(fnametmp), "%s/psql.edit.%ld.%ld",
1552 tmpdirenv ? tmpdirenv : "/tmp",
1553 (long) geteuid(), (long) getpid());
1555 GetTempFileName(".", "psql", 0, fnametmp);
1557 fname = (const char *) fnametmp;
1559 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
1561 stream = fdopen(fd, "w");
1563 if (fd == -1 || !stream)
1565 psql_error("could not open temporary file %s: %s\n", fname, strerror(errno));
1570 unsigned int ql = query_buf->len;
1572 if (ql == 0 || query_buf->data[ql - 1] != '\n')
1574 appendPQExpBufferChar(query_buf, '\n');
1578 if (fwrite(query_buf->data, 1, ql, stream) != ql)
1580 psql_error("%s: %s\n", fname, strerror(errno));
1591 if (!error && stat(fname, &before) != 0)
1593 psql_error("%s: %s\n", fname, strerror(errno));
1600 error = !editFile(fname);
1603 if (!error && stat(fname, &after) != 0)
1605 psql_error("%s: %s\n", fname, strerror(errno));
1609 if (!error && before.st_mtime != after.st_mtime)
1615 stream = fopen(fname, "r");
1618 psql_error("%s: %s\n", fname, strerror(errno));
1623 /* read file back in */
1626 resetPQExpBuffer(query_buf);
1627 while (fgets(line, sizeof(line), stream) != NULL)
1628 appendPQExpBufferStr(query_buf, line);
1632 psql_error("%s: %s\n", fname, strerror(errno));
1641 /* remove temp file */
1644 if (remove(fname) == -1)
1646 psql_error("%s: %s\n", fname, strerror(errno));
1659 * Read commands from filename and then them to the main processing loop
1660 * Handler for \i, but can be used for other things as well.
1663 process_file(char *filename)
1672 fd = fopen(filename, "r");
1676 psql_error("%s: %s\n", filename, strerror(errno));
1680 oldfilename = pset.inputfile;
1681 pset.inputfile = filename;
1682 result = MainLoop(fd);
1684 pset.inputfile = oldfilename;
1695 _align2string(enum printFormat in)
1702 case PRINT_UNALIGNED:
1720 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
1724 #ifdef USE_ASSERT_CHECKING
1732 vallen = strlen(value);
1735 if (strcmp(param, "format") == 0)
1739 else if (strncasecmp("unaligned", value, vallen) == 0)
1740 popt->topt.format = PRINT_UNALIGNED;
1741 else if (strncasecmp("aligned", value, vallen) == 0)
1742 popt->topt.format = PRINT_ALIGNED;
1743 else if (strncasecmp("html", value, vallen) == 0)
1744 popt->topt.format = PRINT_HTML;
1745 else if (strncasecmp("latex", value, vallen) == 0)
1746 popt->topt.format = PRINT_LATEX;
1749 psql_error("\\pset: allowed formats are unaligned, aligned, html, latex\n");
1754 printf(gettext("Output format is %s.\n"), _align2string(popt->topt.format));
1757 /* set border style/width */
1758 else if (strcmp(param, "border") == 0)
1761 popt->topt.border = atoi(value);
1764 printf(gettext("Border style is %d.\n"), popt->topt.border);
1767 /* set expanded/vertical mode */
1768 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
1770 popt->topt.expanded = !popt->topt.expanded;
1772 printf(popt->topt.expanded
1773 ? gettext("Expanded display is on.\n")
1774 : gettext("Expanded display is off.\n"));
1778 else if (strcmp(param, "null") == 0)
1782 free(popt->nullPrint);
1783 popt->nullPrint = xstrdup(value);
1786 printf(gettext("Null display is '%s'.\n"), popt->nullPrint ? popt->nullPrint : "");
1789 /* field separator for unaligned text */
1790 else if (strcmp(param, "fieldsep") == 0)
1794 free(popt->topt.fieldSep);
1795 popt->topt.fieldSep = xstrdup(value);
1798 printf(gettext("Field separator is '%s'.\n"), popt->topt.fieldSep);
1801 /* record separator for unaligned text */
1802 else if (strcmp(param, "recordsep") == 0)
1806 free(popt->topt.recordSep);
1807 popt->topt.recordSep = xstrdup(value);
1811 if (strcmp(popt->topt.recordSep, "\n") == 0)
1812 printf(gettext("Record separator is <newline>."));
1814 printf(gettext("Record separator is '%s'.\n"), popt->topt.recordSep);
1818 /* toggle between full and barebones format */
1819 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
1821 popt->topt.tuples_only = !popt->topt.tuples_only;
1824 if (popt->topt.tuples_only)
1825 puts(gettext("Showing only tuples."));
1827 puts(gettext("Tuples only is off."));
1831 /* set title override */
1832 else if (strcmp(param, "title") == 0)
1838 popt->title = xstrdup(value);
1843 printf(gettext("Title is \"%s\".\n"), popt->title);
1845 printf(gettext("Title is unset.\n"));
1849 /* set HTML table tag options */
1850 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
1852 free(popt->topt.tableAttr);
1854 popt->topt.tableAttr = NULL;
1856 popt->topt.tableAttr = xstrdup(value);
1860 if (popt->topt.tableAttr)
1861 printf(gettext("Table attribute is \"%s\".\n"), popt->topt.tableAttr);
1863 printf(gettext("Table attributes unset.\n"));
1867 /* toggle use of pager */
1868 else if (strcmp(param, "pager") == 0)
1870 popt->topt.pager = !popt->topt.pager;
1873 if (popt->topt.pager)
1874 puts(gettext("Using pager is on."));
1876 puts(gettext("Using pager is off."));
1880 /* disable "(x rows)" footer */
1881 else if (strcmp(param, "footer") == 0)
1883 popt->default_footer = !popt->default_footer;
1886 if (popt->default_footer)
1887 puts(gettext("Default footer is on."));
1889 puts(gettext("Default footer is off."));
1895 psql_error("\\pset: unknown option: %s\n", param);
1904 #define DEFAULT_SHELL "/bin/sh"
1907 do_shell(const char *command)
1914 const char *shellName;
1916 shellName = getenv("SHELL");
1917 if (shellName == NULL)
1918 shellName = DEFAULT_SHELL;
1920 sys = malloc(strlen(shellName) + 16);
1923 psql_error("out of memory\n");
1924 if (pset.cur_cmd_interactive)
1929 sprintf(sys, "exec %s", shellName);
1930 result = system(sys);
1934 result = system(command);
1936 if (result == 127 || result == -1)
1938 psql_error("\\!: failed\n");