2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2006, PostgreSQL Global Development Group
6 * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.173 2006/10/04 00:30:05 momjian Exp $
8 #include "postgres_fe.h"
11 #ifdef __BORLANDC__ /* needed for BCC */
20 #include <sys/types.h> /* for umask() */
21 #include <sys/stat.h> /* for stat() */
22 #include <fcntl.h> /* open() flags */
23 #include <unistd.h> /* for geteuid(), getpid(), stat() */
29 #include <sys/types.h> /* for umask() */
30 #include <sys/stat.h> /* for stat() */
34 #include "pqexpbuffer.h"
35 #include "dumputils.h"
42 #include "large_obj.h"
47 #include "variables.h"
48 #include "mb/pg_wchar.h"
51 /* functions for use in this file */
52 static backslashResult exec_command(const char *cmd,
53 PsqlScanState scan_state,
54 PQExpBuffer query_buf);
55 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
56 static bool do_connect(char *dbname, char *user, char *host, char *port);
57 static bool do_shell(const char *command);
63 * Handles all the different commands that start with '\',
64 * ordinarily called by MainLoop().
66 * scan_state is a lexer working state that is set to continue scanning
67 * just after the '\'. The lexer is advanced past the command and all
68 * arguments on return.
70 * 'query_buf' contains the query-so-far, which may be modified by
71 * execution of the backslash command (for example, \r clears it).
72 * query_buf can be NULL if there is no query so far.
74 * Returns a status code indicating what action is desired, see command.h.
79 HandleSlashCmds(PsqlScanState scan_state,
80 PQExpBuffer query_buf)
82 backslashResult status = PSQL_CMD_SKIP_LINE;
86 psql_assert(scan_state);
88 /* Parse off the command name */
89 cmd = psql_scan_slash_command(scan_state);
91 /* And try to execute it */
92 status = exec_command(cmd, scan_state, query_buf);
94 if (status == PSQL_CMD_UNKNOWN && strlen(cmd) > 1)
97 * If the command was not recognized, try to parse it as a one-letter
98 * command with immediately following argument (a still-supported, but
99 * no longer encouraged, syntax).
103 /* don't change cmd until we know it's okay */
107 psql_scan_slash_pushback(scan_state, cmd + 1);
109 status = exec_command(new_cmd, scan_state, query_buf);
111 if (status != PSQL_CMD_UNKNOWN)
113 /* adjust cmd for possible messages below */
118 if (status == PSQL_CMD_UNKNOWN)
120 if (pset.cur_cmd_interactive)
121 fprintf(stderr, _("Invalid command \\%s. Try \\? for help.\n"), cmd);
123 psql_error("invalid command \\%s\n", cmd);
124 status = PSQL_CMD_ERROR;
127 if (status != PSQL_CMD_ERROR)
129 /* eat any remaining arguments after a valid command */
130 /* note we suppress evaluation of backticks here */
131 while ((arg = psql_scan_slash_option(scan_state,
132 OT_VERBATIM, NULL, false)))
134 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
140 /* silently throw away rest of line after an erroneous command */
141 while ((arg = psql_scan_slash_option(scan_state,
142 OT_WHOLE_LINE, NULL, false)))
146 /* if there is a trailing \\, swallow it */
147 psql_scan_slash_command_end(scan_state);
155 * Read and interpret an argument to the \connect slash command.
158 read_connect_arg(PsqlScanState scan_state)
164 * Ideally we should treat the arguments as SQL identifiers. But for
165 * backwards compatibility with 7.2 and older pg_dump files, we have to
166 * take unquoted arguments verbatim (don't downcase them). For now,
167 * double-quoted arguments may be stripped of double quotes (as if SQL
168 * identifiers). By 7.4 or so, pg_dump files can be expected to
169 * double-quote all mixed-case \connect arguments, and then we can get rid
172 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, "e, true);
180 if (*result == '\0' || strcmp(result, "-") == 0)
188 * Subroutine to actually try to execute a backslash command.
190 static backslashResult
191 exec_command(const char *cmd,
192 PsqlScanState scan_state,
193 PQExpBuffer query_buf)
195 bool success = true; /* indicate here if the command ran ok or
197 backslashResult status = PSQL_CMD_SKIP_LINE;
200 * \a -- toggle field alignment This makes little sense but we keep it
203 if (strcmp(cmd, "a") == 0)
205 if (pset.popt.topt.format != PRINT_ALIGNED)
206 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
208 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
211 /* \C -- override table title (formerly change HTML caption) */
212 else if (strcmp(cmd, "C") == 0)
214 char *opt = psql_scan_slash_option(scan_state,
215 OT_NORMAL, NULL, true);
217 success = do_pset("title", opt, &pset.popt, pset.quiet);
222 * \c or \connect -- connect to database using the specified parameters.
224 * \c dbname user host port
226 * If any of these parameters are omitted or specified as '-', the current
227 * value of the parameter will be used instead. If the parameter has no
228 * current value, the default value for that parameter will be used. Some
231 * \c - - hst Connect to current database on current port of host
232 * "hst" as current user. \c - usr - prt Connect to current database on
233 * "prt" port of current host as user "usr". \c dbs Connect to
234 * "dbs" database on current port of current host as current user.
236 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
243 opt1 = read_connect_arg(scan_state);
244 opt2 = read_connect_arg(scan_state);
245 opt3 = read_connect_arg(scan_state);
246 opt4 = read_connect_arg(scan_state);
248 success = do_connect(opt1, opt2, opt3, opt4);
257 else if (strcmp(cmd, "cd") == 0)
259 char *opt = psql_scan_slash_option(scan_state,
260 OT_NORMAL, NULL, true);
270 pw = getpwuid(geteuid());
273 psql_error("could not get home directory: %s\n", strerror(errno));
280 * On Windows, 'cd' without arguments prints the current
281 * directory, so if someone wants to code this here instead...
287 if (chdir(dir) == -1)
289 psql_error("\\%s: could not change directory to \"%s\": %s\n",
290 cmd, dir, strerror(errno));
296 pset.dirname = pg_strdup(dir);
297 canonicalize_path(pset.dirname);
304 else if (pg_strcasecmp(cmd, "copy") == 0)
306 char *opt = psql_scan_slash_option(scan_state,
307 OT_WHOLE_LINE, NULL, false);
309 success = do_copy(opt);
314 else if (strcmp(cmd, "copyright") == 0)
318 else if (cmd[0] == 'd')
323 /* We don't do SQLID reduction on the pattern yet */
324 pattern = psql_scan_slash_option(scan_state,
325 OT_NORMAL, NULL, true);
327 show_verbose = strchr(cmd, '+') ? true : false;
334 success = describeTableDetails(pattern, show_verbose);
336 /* standard listing of interesting things */
337 success = listTables("tvs", NULL, show_verbose);
340 success = describeAggregates(pattern, show_verbose);
343 success = describeTablespaces(pattern, show_verbose);
346 success = listConversions(pattern);
349 success = listCasts(pattern);
352 success = objectDescription(pattern);
355 success = listDomains(pattern);
358 success = describeFunctions(pattern, show_verbose);
361 /* no longer distinct from \du */
362 success = describeRoles(pattern, show_verbose);
365 success = do_lo_list();
368 success = listSchemas(pattern, show_verbose);
371 success = describeOperators(pattern);
374 success = permissionsList(pattern);
377 success = describeTypes(pattern, show_verbose);
384 success = listTables(&cmd[1], pattern, show_verbose);
387 success = describeRoles(pattern, show_verbose);
391 status = PSQL_CMD_UNKNOWN;
400 * \e or \edit -- edit the current query buffer (or a file and make it the
403 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
409 psql_error("no query buffer\n");
410 status = PSQL_CMD_ERROR;
414 fname = psql_scan_slash_option(scan_state,
415 OT_NORMAL, NULL, true);
416 expand_tilde(&fname);
418 canonicalize_path(fname);
419 status = do_edit(fname, query_buf) ? PSQL_CMD_NEWEDIT : PSQL_CMD_ERROR;
424 /* \echo and \qecho */
425 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
429 bool no_newline = false;
433 if (strcmp(cmd, "qecho") == 0)
434 fout = pset.queryFout;
438 while ((value = psql_scan_slash_option(scan_state,
439 OT_NORMAL, "ed, false)))
441 if (!quoted && strcmp(value, "-n") == 0)
457 /* \encoding -- set/show client side encoding */
458 else if (strcmp(cmd, "encoding") == 0)
460 char *encoding = psql_scan_slash_option(scan_state,
461 OT_NORMAL, NULL, false);
466 puts(pg_encoding_to_char(pset.encoding));
471 if (PQsetClientEncoding(pset.db, encoding) == -1)
472 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
475 /* save encoding info into psql internal data */
476 pset.encoding = PQclientEncoding(pset.db);
477 pset.popt.topt.encoding = pset.encoding;
478 SetVariable(pset.vars, "ENCODING",
479 pg_encoding_to_char(pset.encoding));
485 /* \f -- change field separator */
486 else if (strcmp(cmd, "f") == 0)
488 char *fname = psql_scan_slash_option(scan_state,
489 OT_NORMAL, NULL, false);
491 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
495 /* \g means send query */
496 else if (strcmp(cmd, "g") == 0)
498 char *fname = psql_scan_slash_option(scan_state,
499 OT_FILEPIPE, NULL, false);
505 expand_tilde(&fname);
506 pset.gfname = pg_strdup(fname);
509 status = PSQL_CMD_SEND;
513 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
515 char *opt = psql_scan_slash_option(scan_state,
516 OT_WHOLE_LINE, NULL, false);
518 helpSQL(opt, pset.popt.topt.pager);
523 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
525 if (pset.popt.topt.format != PRINT_HTML)
526 success = do_pset("format", "html", &pset.popt, pset.quiet);
528 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
532 /* \i is include file */
533 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
535 char *fname = psql_scan_slash_option(scan_state,
536 OT_NORMAL, NULL, true);
540 psql_error("\\%s: missing required argument\n", cmd);
545 expand_tilde(&fname);
546 success = (process_file(fname, false) == EXIT_SUCCESS);
551 /* \l is list databases */
552 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
553 success = listAllDbs(false);
554 else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
555 success = listAllDbs(true);
558 * large object things
560 else if (strncmp(cmd, "lo_", 3) == 0)
565 opt1 = psql_scan_slash_option(scan_state,
566 OT_NORMAL, NULL, true);
567 opt2 = psql_scan_slash_option(scan_state,
568 OT_NORMAL, NULL, true);
570 if (strcmp(cmd + 3, "export") == 0)
574 psql_error("\\%s: missing required argument\n", cmd);
580 success = do_lo_export(opt1, opt2);
584 else if (strcmp(cmd + 3, "import") == 0)
588 psql_error("\\%s: missing required argument\n", cmd);
594 success = do_lo_import(opt1, opt2);
598 else if (strcmp(cmd + 3, "list") == 0)
599 success = do_lo_list();
601 else if (strcmp(cmd + 3, "unlink") == 0)
605 psql_error("\\%s: missing required argument\n", cmd);
609 success = do_lo_unlink(opt1);
613 status = PSQL_CMD_UNKNOWN;
620 /* \o -- set query output */
621 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
623 char *fname = psql_scan_slash_option(scan_state,
624 OT_FILEPIPE, NULL, true);
626 expand_tilde(&fname);
627 success = setQFout(fname);
631 /* \p prints the current query buffer */
632 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
634 if (query_buf && query_buf->len > 0)
635 puts(query_buf->data);
636 else if (!pset.quiet)
637 puts(_("Query buffer is empty."));
641 /* \password -- set user password */
642 else if (strcmp(cmd, "password") == 0)
647 pw1 = simple_prompt("Enter new password: ", 100, false);
648 pw2 = simple_prompt("Enter it again: ", 100, false);
650 if (strcmp(pw1, pw2) != 0)
652 fprintf(stderr, _("Passwords didn't match.\n"));
657 char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
659 char *encrypted_password;
664 user = PQuser(pset.db);
666 encrypted_password = PQencryptPassword(pw1, user);
668 if (!encrypted_password)
670 fprintf(stderr, _("Password encryption failed.\n"));
678 initPQExpBuffer(&buf);
679 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
681 appendStringLiteralConn(&buf, encrypted_password, pset.db);
682 res = PSQLexec(buf.data, false);
683 termPQExpBuffer(&buf);
688 PQfreemem(encrypted_password);
696 /* \pset -- set printing parameters */
697 else if (strcmp(cmd, "pset") == 0)
699 char *opt0 = psql_scan_slash_option(scan_state,
700 OT_NORMAL, NULL, false);
701 char *opt1 = psql_scan_slash_option(scan_state,
702 OT_NORMAL, NULL, false);
706 psql_error("\\%s: missing required argument\n", cmd);
710 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
717 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
718 status = PSQL_CMD_TERMINATE;
720 /* reset(clear) the buffer */
721 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
723 resetPQExpBuffer(query_buf);
724 psql_scan_reset(scan_state);
726 puts(_("Query buffer reset (cleared)."));
729 /* \s save history in a file or show it on the screen */
730 else if (strcmp(cmd, "s") == 0)
732 char *fname = psql_scan_slash_option(scan_state,
733 OT_NORMAL, NULL, true);
735 expand_tilde(&fname);
736 /* This scrolls off the screen when using /dev/tty */
737 success = saveHistory(fname ? fname : DEVTTY, false);
738 if (success && !pset.quiet && fname)
739 printf(gettext("Wrote history to file \"%s/%s\".\n"),
740 pset.dirname ? pset.dirname : ".", fname);
746 /* \set -- generalized set variable/option command */
747 else if (strcmp(cmd, "set") == 0)
749 char *opt0 = psql_scan_slash_option(scan_state,
750 OT_NORMAL, NULL, false);
754 /* list all variables */
755 PrintVariables(pset.vars);
761 * Set variable to the concatenation of the arguments.
766 opt = psql_scan_slash_option(scan_state,
767 OT_NORMAL, NULL, false);
768 newval = pg_strdup(opt ? opt : "");
771 while ((opt = psql_scan_slash_option(scan_state,
772 OT_NORMAL, NULL, false)))
774 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
777 psql_error("out of memory\n");
784 if (!SetVariable(pset.vars, opt0, newval))
786 psql_error("\\%s: error\n", cmd);
794 /* \t -- turn off headers and row count */
795 else if (strcmp(cmd, "t") == 0)
796 success = do_pset("tuples_only", NULL, &pset.popt, pset.quiet);
799 /* \T -- define html <table ...> attributes */
800 else if (strcmp(cmd, "T") == 0)
802 char *value = psql_scan_slash_option(scan_state,
803 OT_NORMAL, NULL, false);
805 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
809 /* \timing -- toggle timing of queries */
810 else if (strcmp(cmd, "timing") == 0)
812 pset.timing = !pset.timing;
816 puts(_("Timing is on."));
818 puts(_("Timing is off."));
823 else if (strcmp(cmd, "unset") == 0)
825 char *opt = psql_scan_slash_option(scan_state,
826 OT_NORMAL, NULL, false);
830 psql_error("\\%s: missing required argument\n", cmd);
833 else if (!SetVariable(pset.vars, opt, NULL))
835 psql_error("\\%s: error\n", cmd);
841 /* \w -- write query buffer to file */
842 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
845 bool is_pipe = false;
850 psql_error("no query buffer\n");
851 status = PSQL_CMD_ERROR;
855 fname = psql_scan_slash_option(scan_state,
856 OT_FILEPIPE, NULL, true);
857 expand_tilde(&fname);
861 psql_error("\\%s: missing required argument\n", cmd);
869 fd = popen(&fname[1], "w");
873 canonicalize_path(fname);
874 fd = fopen(fname, "w");
878 psql_error("%s: %s\n", fname, strerror(errno));
888 if (query_buf && query_buf->len > 0)
889 fprintf(fd, "%s\n", query_buf->data);
898 psql_error("%s: %s\n", fname, strerror(errno));
906 /* \x -- toggle expanded table representation */
907 else if (strcmp(cmd, "x") == 0)
908 success = do_pset("expanded", NULL, &pset.popt, pset.quiet);
910 /* \z -- list table rights (equivalent to \dp) */
911 else if (strcmp(cmd, "z") == 0)
913 char *pattern = psql_scan_slash_option(scan_state,
914 OT_NORMAL, NULL, true);
916 success = permissionsList(pattern);
921 /* \! -- shell escape */
922 else if (strcmp(cmd, "!") == 0)
924 char *opt = psql_scan_slash_option(scan_state,
925 OT_WHOLE_LINE, NULL, false);
927 success = do_shell(opt);
931 /* \? -- slash command help */
932 else if (strcmp(cmd, "?") == 0)
933 slashUsage(pset.popt.topt.pager);
938 * These commands don't do anything. I just use them to test the parser.
940 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
945 while ((value = psql_scan_slash_option(scan_state,
946 OT_NORMAL, NULL, true)))
948 fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
955 status = PSQL_CMD_UNKNOWN;
958 status = PSQL_CMD_ERROR;
964 * Ask the user for a password; 'username' is the username the
965 * password is for, if one has been explicitly specified. Returns a
969 prompt_for_password(const char *username)
973 if (username == NULL)
974 result = simple_prompt("Password: ", 100, false);
979 prompt_text = malloc(strlen(username) + 32);
980 sprintf(prompt_text, "Password for user \"%s\": ", username);
981 result = simple_prompt(prompt_text, 100, false);
989 param_is_newly_set(const char *old_val, const char *new_val)
994 if (old_val == NULL || strcmp(old_val, new_val) != 0)
1001 * do_connect -- handler for \connect
1003 * Connects to a database with given parameters. If there exists an
1004 * established connection, NULL values will be replaced with the ones
1005 * in the current connection. Otherwise NULL will be passed for that
1006 * parameter to PQsetdbLogin(), so the libpq defaults will be used.
1008 * In interactive mode, if connection fails with the given parameters,
1009 * the old connection will be kept.
1012 do_connect(char *dbname, char *user, char *host, char *port)
1014 PGconn *o_conn = pset.db,
1016 char *password = NULL;
1019 dbname = PQdb(o_conn);
1021 user = PQuser(o_conn);
1023 host = PQhost(o_conn);
1025 port = PQport(o_conn);
1028 * If the user asked to be prompted for a password, ask for one now. If
1029 * not, use the password from the old connection, provided the username
1030 * has not changed. Otherwise, try to connect without a password first,
1031 * and then ask for a password if we got the appropriate error message.
1033 * XXX: this behavior is broken. It leads to spurious connection attempts
1034 * in the postmaster's log, and doing a string comparison against the
1035 * returned error message is pretty fragile.
1037 if (pset.getPassword)
1039 password = prompt_for_password(user);
1041 else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1043 password = strdup(PQpass(o_conn));
1048 n_conn = PQsetdbLogin(host, port, NULL, NULL,
1049 dbname, user, password);
1051 /* We can immediately discard the password -- no longer needed */
1055 if (PQstatus(n_conn) == CONNECTION_OK)
1059 * Connection attempt failed; either retry the connection attempt with
1060 * a new password, or give up.
1062 if (strcmp(PQerrorMessage(n_conn), PQnoPasswordSupplied) == 0)
1065 password = prompt_for_password(user);
1070 * Failed to connect to the database. In interactive mode, keep the
1071 * previous connection to the DB; in scripting mode, close our
1072 * previous connection as well.
1074 if (pset.cur_cmd_interactive)
1076 psql_error("%s", PQerrorMessage(n_conn));
1078 /* pset.db is left unmodified */
1080 fputs(_("Previous connection kept.\n"), stderr);
1084 psql_error("\\connect: %s", PQerrorMessage(n_conn));
1097 * Replace the old connection with the new one, and update
1098 * connection-dependent variables.
1100 PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1104 /* Tell the user about the new connection */
1107 printf(_("You are now connected to database \"%s\""), PQdb(pset.db));
1109 if (param_is_newly_set(PQuser(o_conn), PQuser(pset.db)))
1110 printf(_(" as user \"%s\""), PQuser(pset.db));
1112 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)))
1113 printf(_(" on host \"%s\""), PQhost(pset.db));
1115 if (param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1116 printf(_(" at port \"%s\""), PQport(pset.db));
1130 * Make psql's internal variables agree with connection state upon
1131 * establishing a new connection.
1136 /* get stuff from connection */
1137 pset.encoding = PQclientEncoding(pset.db);
1138 pset.popt.topt.encoding = pset.encoding;
1139 pset.sversion = PQserverVersion(pset.db);
1141 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1142 SetVariable(pset.vars, "USER", PQuser(pset.db));
1143 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1144 SetVariable(pset.vars, "PORT", PQport(pset.db));
1145 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1147 /* send stuff to it, too */
1148 PQsetErrorVerbosity(pset.db, pset.verbosity);
1154 * Clear variables that should be not be set when there is no connection.
1157 UnsyncVariables(void)
1159 SetVariable(pset.vars, "DBNAME", NULL);
1160 SetVariable(pset.vars, "USER", NULL);
1161 SetVariable(pset.vars, "HOST", NULL);
1162 SetVariable(pset.vars, "PORT", NULL);
1163 SetVariable(pset.vars, "ENCODING", NULL);
1168 * do_edit -- handler for \e
1170 * If you do not specify a filename, the current query buffer will be copied
1171 * into a temporary one.
1175 editFile(const char *fname)
1177 const char *editorName;
1183 /* Find an editor to use */
1184 editorName = getenv("PSQL_EDITOR");
1186 editorName = getenv("EDITOR");
1188 editorName = getenv("VISUAL");
1190 editorName = DEFAULT_EDITOR;
1193 * On Unix the EDITOR value should *not* be quoted, since it might include
1194 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1195 * if necessary. But this policy is not very workable on Windows, due to
1196 * severe brain damage in their command shell plus the fact that standard
1197 * program paths include spaces.
1199 sys = pg_malloc(strlen(editorName) + strlen(fname) + 10 + 1);
1201 sprintf(sys, "exec %s '%s'", editorName, fname);
1203 sprintf(sys, "%s\"%s\" \"%s\"%s",
1204 SYSTEMQUOTE, editorName, fname, SYSTEMQUOTE);
1206 result = system(sys);
1208 psql_error("could not start editor \"%s\"\n", editorName);
1209 else if (result == 127)
1210 psql_error("could not start /bin/sh\n");
1219 do_edit(const char *filename_arg, PQExpBuffer query_buf)
1221 char fnametmp[MAXPGPATH];
1222 FILE *stream = NULL;
1231 fname = filename_arg;
1234 /* make a temp file to edit */
1236 const char *tmpdir = getenv("TMPDIR");
1241 char tmpdir[MAXPGPATH];
1244 ret = GetTempPath(MAXPGPATH, tmpdir);
1245 if (ret == 0 || ret > MAXPGPATH)
1247 psql_error("cannot locate temporary directory: %s",
1248 !ret ? strerror(errno) : "");
1253 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
1254 * current directory to the supplied path unless we use only
1255 * backslashes, so we do that.
1259 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d", tmpdir,
1260 "/", (int) getpid());
1262 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d", tmpdir,
1263 "" /* trailing separator already present */ , (int) getpid());
1266 fname = (const char *) fnametmp;
1268 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
1270 stream = fdopen(fd, "w");
1272 if (fd == -1 || !stream)
1274 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
1279 unsigned int ql = query_buf->len;
1281 if (ql == 0 || query_buf->data[ql - 1] != '\n')
1283 appendPQExpBufferChar(query_buf, '\n');
1287 if (fwrite(query_buf->data, 1, ql, stream) != ql)
1289 psql_error("%s: %s\n", fname, strerror(errno));
1294 else if (fclose(stream) != 0)
1296 psql_error("%s: %s\n", fname, strerror(errno));
1303 if (!error && stat(fname, &before) != 0)
1305 psql_error("%s: %s\n", fname, strerror(errno));
1311 error = !editFile(fname);
1313 if (!error && stat(fname, &after) != 0)
1315 psql_error("%s: %s\n", fname, strerror(errno));
1319 if (!error && before.st_mtime != after.st_mtime)
1321 stream = fopen(fname, PG_BINARY_R);
1324 psql_error("%s: %s\n", fname, strerror(errno));
1329 /* read file back into query_buf */
1332 resetPQExpBuffer(query_buf);
1333 while (fgets(line, sizeof(line), stream) != NULL)
1334 appendPQExpBufferStr(query_buf, line);
1338 psql_error("%s: %s\n", fname, strerror(errno));
1347 /* remove temp file */
1350 if (remove(fname) == -1)
1352 psql_error("%s: %s\n", fname, strerror(errno));
1365 * Read commands from filename and then them to the main processing loop
1366 * Handler for \i, but can be used for other things as well. Returns
1367 * MainLoop() error code.
1370 process_file(char *filename, bool single_txn)
1378 return EXIT_FAILURE;
1380 canonicalize_path(filename);
1381 fd = fopen(filename, PG_BINARY_R);
1385 psql_error("%s: %s\n", filename, strerror(errno));
1386 return EXIT_FAILURE;
1389 oldfilename = pset.inputfile;
1390 pset.inputfile = filename;
1393 res = PSQLexec("BEGIN", false);
1394 result = MainLoop(fd);
1396 res = PSQLexec("COMMIT", false);
1399 pset.inputfile = oldfilename;
1410 _align2string(enum printFormat in)
1417 case PRINT_UNALIGNED:
1429 case PRINT_TROFF_MS:
1438 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
1445 vallen = strlen(value);
1448 if (strcmp(param, "format") == 0)
1452 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
1453 popt->topt.format = PRINT_UNALIGNED;
1454 else if (pg_strncasecmp("aligned", value, vallen) == 0)
1455 popt->topt.format = PRINT_ALIGNED;
1456 else if (pg_strncasecmp("html", value, vallen) == 0)
1457 popt->topt.format = PRINT_HTML;
1458 else if (pg_strncasecmp("latex", value, vallen) == 0)
1459 popt->topt.format = PRINT_LATEX;
1460 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
1461 popt->topt.format = PRINT_TROFF_MS;
1464 psql_error("\\pset: allowed formats are unaligned, aligned, html, latex, troff-ms\n");
1469 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
1472 /* set border style/width */
1473 else if (strcmp(param, "border") == 0)
1476 popt->topt.border = atoi(value);
1479 printf(_("Border style is %d.\n"), popt->topt.border);
1482 /* set expanded/vertical mode */
1483 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
1485 popt->topt.expanded = !popt->topt.expanded;
1487 printf(popt->topt.expanded
1488 ? _("Expanded display is on.\n")
1489 : _("Expanded display is off.\n"));
1492 /* locale-aware numeric output */
1493 else if (strcmp(param, "numericlocale") == 0)
1495 popt->topt.numericLocale = !popt->topt.numericLocale;
1498 if (popt->topt.numericLocale)
1499 puts(_("Showing locale-adjusted numeric output."));
1501 puts(_("Locale-adjusted numeric output is off."));
1506 else if (strcmp(param, "null") == 0)
1510 free(popt->nullPrint);
1511 popt->nullPrint = pg_strdup(value);
1514 printf(_("Null display is \"%s\".\n"), popt->nullPrint ? popt->nullPrint : "");
1517 /* field separator for unaligned text */
1518 else if (strcmp(param, "fieldsep") == 0)
1522 free(popt->topt.fieldSep);
1523 popt->topt.fieldSep = pg_strdup(value);
1526 printf(_("Field separator is \"%s\".\n"), popt->topt.fieldSep);
1529 /* record separator for unaligned text */
1530 else if (strcmp(param, "recordsep") == 0)
1534 free(popt->topt.recordSep);
1535 popt->topt.recordSep = pg_strdup(value);
1539 if (strcmp(popt->topt.recordSep, "\n") == 0)
1540 printf(_("Record separator is <newline>."));
1542 printf(_("Record separator is \"%s\".\n"), popt->topt.recordSep);
1546 /* toggle between full and tuples-only format */
1547 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
1549 popt->topt.tuples_only = !popt->topt.tuples_only;
1552 if (popt->topt.tuples_only)
1553 puts(_("Showing only tuples."));
1555 puts(_("Tuples only is off."));
1559 /* set title override */
1560 else if (strcmp(param, "title") == 0)
1566 popt->title = pg_strdup(value);
1571 printf(_("Title is \"%s\".\n"), popt->title);
1573 printf(_("Title is unset.\n"));
1577 /* set HTML table tag options */
1578 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
1580 free(popt->topt.tableAttr);
1582 popt->topt.tableAttr = NULL;
1584 popt->topt.tableAttr = pg_strdup(value);
1588 if (popt->topt.tableAttr)
1589 printf(_("Table attribute is \"%s\".\n"), popt->topt.tableAttr);
1591 printf(_("Table attributes unset.\n"));
1595 /* toggle use of pager */
1596 else if (strcmp(param, "pager") == 0)
1598 if (value && pg_strcasecmp(value, "always") == 0)
1599 popt->topt.pager = 2;
1600 else if (popt->topt.pager == 1)
1601 popt->topt.pager = 0;
1603 popt->topt.pager = 1;
1606 if (popt->topt.pager == 1)
1607 puts(_("Pager is used for long output."));
1608 else if (popt->topt.pager == 2)
1609 puts(_("Pager is always used."));
1611 puts(_("Pager usage is off."));
1615 /* disable "(x rows)" footer */
1616 else if (strcmp(param, "footer") == 0)
1618 popt->default_footer = !popt->default_footer;
1621 if (popt->default_footer)
1622 puts(_("Default footer is on."));
1624 puts(_("Default footer is off."));
1630 psql_error("\\pset: unknown option: %s\n", param);
1640 #define DEFAULT_SHELL "/bin/sh"
1643 * CMD.EXE is in different places in different Win32 releases so we
1644 * have to rely on the path to find it.
1646 #define DEFAULT_SHELL "cmd.exe"
1650 do_shell(const char *command)
1657 const char *shellName;
1659 shellName = getenv("SHELL");
1661 if (shellName == NULL)
1662 shellName = getenv("COMSPEC");
1664 if (shellName == NULL)
1665 shellName = DEFAULT_SHELL;
1667 sys = pg_malloc(strlen(shellName) + 16);
1670 /* See EDITOR handling comment for an explaination */
1671 "exec %s", shellName);
1674 /* See EDITOR handling comment for an explaination */
1675 "%s\"%s\"%s", SYSTEMQUOTE, shellName, SYSTEMQUOTE);
1677 result = system(sys);
1681 result = system(command);
1683 if (result == 127 || result == -1)
1685 psql_error("\\!: failed\n");