]> granicus.if.org Git - postgresql/blob - src/bin/psql/command.c
Replace pg_asprintf() with psprintf().
[postgresql] / src / bin / psql / command.c
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2013, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/command.c
7  */
8 #include "postgres_fe.h"
9 #include "command.h"
10
11 #ifdef __BORLANDC__                             /* needed for BCC */
12 #undef mkdir
13 #endif
14
15 #include <ctype.h>
16 #include <time.h>
17 #ifdef HAVE_PWD_H
18 #include <pwd.h>
19 #endif
20 #ifndef WIN32
21 #include <sys/types.h>                  /* for umask() */
22 #include <sys/stat.h>                   /* for stat() */
23 #include <fcntl.h>                              /* open() flags */
24 #include <unistd.h>                             /* for geteuid(), getpid(), stat() */
25 #else
26 #include <win32.h>
27 #include <io.h>
28 #include <fcntl.h>
29 #include <direct.h>
30 #include <sys/types.h>                  /* for umask() */
31 #include <sys/stat.h>                   /* for stat() */
32 #endif
33 #ifdef USE_SSL
34 #include <openssl/ssl.h>
35 #endif
36
37 #include "portability/instr_time.h"
38
39 #include "libpq-fe.h"
40 #include "pqexpbuffer.h"
41 #include "dumputils.h"
42
43 #include "common.h"
44 #include "copy.h"
45 #include "describe.h"
46 #include "help.h"
47 #include "input.h"
48 #include "large_obj.h"
49 #include "mainloop.h"
50 #include "print.h"
51 #include "psqlscan.h"
52 #include "settings.h"
53 #include "variables.h"
54
55
56 /* functions for use in this file */
57 static backslashResult exec_command(const char *cmd,
58                          PsqlScanState scan_state,
59                          PQExpBuffer query_buf);
60 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
61                 int lineno, bool *edited);
62 static bool do_connect(char *dbname, char *user, char *host, char *port);
63 static bool do_shell(const char *command);
64 static bool do_watch(PQExpBuffer query_buf, long sleep);
65 static bool lookup_function_oid(PGconn *conn, const char *desc, Oid *foid);
66 static bool get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf);
67 static int      strip_lineno_from_funcdesc(char *func);
68 static void minimal_error_message(PGresult *res);
69
70 static void printSSLInfo(void);
71 static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
72
73 #ifdef WIN32
74 static void checkWin32Codepage(void);
75 #endif
76
77
78
79 /*----------
80  * HandleSlashCmds:
81  *
82  * Handles all the different commands that start with '\'.
83  * Ordinarily called by MainLoop().
84  *
85  * scan_state is a lexer working state that is set to continue scanning
86  * just after the '\'.  The lexer is advanced past the command and all
87  * arguments on return.
88  *
89  * 'query_buf' contains the query-so-far, which may be modified by
90  * execution of the backslash command (for example, \r clears it).
91  * query_buf can be NULL if there is no query so far.
92  *
93  * Returns a status code indicating what action is desired, see command.h.
94  *----------
95  */
96
97 backslashResult
98 HandleSlashCmds(PsqlScanState scan_state,
99                                 PQExpBuffer query_buf)
100 {
101         backslashResult status = PSQL_CMD_SKIP_LINE;
102         char       *cmd;
103         char       *arg;
104
105         Assert(scan_state != NULL);
106
107         /* Parse off the command name */
108         cmd = psql_scan_slash_command(scan_state);
109
110         /* And try to execute it */
111         status = exec_command(cmd, scan_state, query_buf);
112
113         if (status == PSQL_CMD_UNKNOWN)
114         {
115                 if (pset.cur_cmd_interactive)
116                         psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
117                 else
118                         psql_error("invalid command \\%s\n", cmd);
119                 status = PSQL_CMD_ERROR;
120         }
121
122         if (status != PSQL_CMD_ERROR)
123         {
124                 /* eat any remaining arguments after a valid command */
125                 /* note we suppress evaluation of backticks here */
126                 while ((arg = psql_scan_slash_option(scan_state,
127                                                                                          OT_NO_EVAL, NULL, false)))
128                 {
129                         psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
130                         free(arg);
131                 }
132         }
133         else
134         {
135                 /* silently throw away rest of line after an erroneous command */
136                 while ((arg = psql_scan_slash_option(scan_state,
137                                                                                          OT_WHOLE_LINE, NULL, false)))
138                         free(arg);
139         }
140
141         /* if there is a trailing \\, swallow it */
142         psql_scan_slash_command_end(scan_state);
143
144         free(cmd);
145
146         /* some commands write to queryFout, so make sure output is sent */
147         fflush(pset.queryFout);
148
149         return status;
150 }
151
152 /*
153  * Read and interpret an argument to the \connect slash command.
154  */
155 static char *
156 read_connect_arg(PsqlScanState scan_state)
157 {
158         char       *result;
159         char            quote;
160
161         /*
162          * Ideally we should treat the arguments as SQL identifiers.  But for
163          * backwards compatibility with 7.2 and older pg_dump files, we have to
164          * take unquoted arguments verbatim (don't downcase them). For now,
165          * double-quoted arguments may be stripped of double quotes (as if SQL
166          * identifiers).  By 7.4 or so, pg_dump files can be expected to
167          * double-quote all mixed-case \connect arguments, and then we can get rid
168          * of OT_SQLIDHACK.
169          */
170         result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, &quote, true);
171
172         if (!result)
173                 return NULL;
174
175         if (quote)
176                 return result;
177
178         if (*result == '\0' || strcmp(result, "-") == 0)
179                 return NULL;
180
181         return result;
182 }
183
184
185 /*
186  * Subroutine to actually try to execute a backslash command.
187  */
188 static backslashResult
189 exec_command(const char *cmd,
190                          PsqlScanState scan_state,
191                          PQExpBuffer query_buf)
192 {
193         bool            success = true; /* indicate here if the command ran ok or
194                                                                  * failed */
195         backslashResult status = PSQL_CMD_SKIP_LINE;
196
197         /*
198          * \a -- toggle field alignment This makes little sense but we keep it
199          * around.
200          */
201         if (strcmp(cmd, "a") == 0)
202         {
203                 if (pset.popt.topt.format != PRINT_ALIGNED)
204                         success = do_pset("format", "aligned", &pset.popt, pset.quiet);
205                 else
206                         success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
207         }
208
209         /* \C -- override table title (formerly change HTML caption) */
210         else if (strcmp(cmd, "C") == 0)
211         {
212                 char       *opt = psql_scan_slash_option(scan_state,
213                                                                                                  OT_NORMAL, NULL, true);
214
215                 success = do_pset("title", opt, &pset.popt, pset.quiet);
216                 free(opt);
217         }
218
219         /*
220          * \c or \connect -- connect to database using the specified parameters.
221          *
222          * \c dbname user host port
223          *
224          * If any of these parameters are omitted or specified as '-', the current
225          * value of the parameter will be used instead. If the parameter has no
226          * current value, the default value for that parameter will be used. Some
227          * examples:
228          *
229          * \c - - hst           Connect to current database on current port of host
230          * "hst" as current user. \c - usr - prt   Connect to current database on
231          * "prt" port of current host as user "usr". \c dbs                       Connect to
232          * "dbs" database on current port of current host as current user.
233          */
234         else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
235         {
236                 char       *opt1,
237                                    *opt2,
238                                    *opt3,
239                                    *opt4;
240
241                 opt1 = read_connect_arg(scan_state);
242                 opt2 = read_connect_arg(scan_state);
243                 opt3 = read_connect_arg(scan_state);
244                 opt4 = read_connect_arg(scan_state);
245
246                 success = do_connect(opt1, opt2, opt3, opt4);
247
248                 free(opt1);
249                 free(opt2);
250                 free(opt3);
251                 free(opt4);
252         }
253
254         /* \cd */
255         else if (strcmp(cmd, "cd") == 0)
256         {
257                 char       *opt = psql_scan_slash_option(scan_state,
258                                                                                                  OT_NORMAL, NULL, true);
259                 char       *dir;
260
261                 if (opt)
262                         dir = opt;
263                 else
264                 {
265 #ifndef WIN32
266                         struct passwd *pw;
267
268                         pw = getpwuid(geteuid());
269                         if (!pw)
270                         {
271                                 psql_error("could not get home directory: %s\n", strerror(errno));
272                                 exit(EXIT_FAILURE);
273                         }
274                         dir = pw->pw_dir;
275 #else                                                   /* WIN32 */
276
277                         /*
278                          * On Windows, 'cd' without arguments prints the current
279                          * directory, so if someone wants to code this here instead...
280                          */
281                         dir = "/";
282 #endif   /* WIN32 */
283                 }
284
285                 if (chdir(dir) == -1)
286                 {
287                         psql_error("\\%s: could not change directory to \"%s\": %s\n",
288                                            cmd, dir, strerror(errno));
289                         success = false;
290                 }
291
292                 if (pset.dirname)
293                         free(pset.dirname);
294                 pset.dirname = pg_strdup(dir);
295                 canonicalize_path(pset.dirname);
296
297                 if (opt)
298                         free(opt);
299         }
300
301         /* \conninfo -- display information about the current connection */
302         else if (strcmp(cmd, "conninfo") == 0)
303         {
304                 char       *db = PQdb(pset.db);
305                 char       *host = PQhost(pset.db);
306
307                 if (db == NULL)
308                         printf(_("You are currently not connected to a database.\n"));
309                 else
310                 {
311                         if (host == NULL)
312                                 host = DEFAULT_PGSOCKET_DIR;
313                         /* If the host is an absolute path, the connection is via socket */
314                         if (is_absolute_path(host))
315                                 printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
316                                            db, PQuser(pset.db), host, PQport(pset.db));
317                         else
318                                 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
319                                            db, PQuser(pset.db), host, PQport(pset.db));
320                         printSSLInfo();
321                 }
322         }
323
324         /* \copy */
325         else if (pg_strcasecmp(cmd, "copy") == 0)
326         {
327                 char       *opt = psql_scan_slash_option(scan_state,
328                                                                                                  OT_WHOLE_LINE, NULL, false);
329
330                 success = do_copy(opt);
331                 free(opt);
332         }
333
334         /* \copyright */
335         else if (strcmp(cmd, "copyright") == 0)
336                 print_copyright();
337
338         /* \d* commands */
339         else if (cmd[0] == 'd')
340         {
341                 char       *pattern;
342                 bool            show_verbose,
343                                         show_system;
344
345                 /* We don't do SQLID reduction on the pattern yet */
346                 pattern = psql_scan_slash_option(scan_state,
347                                                                                  OT_NORMAL, NULL, true);
348
349                 show_verbose = strchr(cmd, '+') ? true : false;
350                 show_system = strchr(cmd, 'S') ? true : false;
351
352                 switch (cmd[1])
353                 {
354                         case '\0':
355                         case '+':
356                         case 'S':
357                                 if (pattern)
358                                         success = describeTableDetails(pattern, show_verbose, show_system);
359                                 else
360                                         /* standard listing of interesting things */
361                                         success = listTables("tvmsE", NULL, show_verbose, show_system);
362                                 break;
363                         case 'a':
364                                 success = describeAggregates(pattern, show_verbose, show_system);
365                                 break;
366                         case 'b':
367                                 success = describeTablespaces(pattern, show_verbose);
368                                 break;
369                         case 'c':
370                                 success = listConversions(pattern, show_verbose, show_system);
371                                 break;
372                         case 'C':
373                                 success = listCasts(pattern, show_verbose);
374                                 break;
375                         case 'd':
376                                 if (strncmp(cmd, "ddp", 3) == 0)
377                                         success = listDefaultACLs(pattern);
378                                 else
379                                         success = objectDescription(pattern, show_system);
380                                 break;
381                         case 'D':
382                                 success = listDomains(pattern, show_verbose, show_system);
383                                 break;
384                         case 'f':                       /* function subsystem */
385                                 switch (cmd[2])
386                                 {
387                                         case '\0':
388                                         case '+':
389                                         case 'S':
390                                         case 'a':
391                                         case 'n':
392                                         case 't':
393                                         case 'w':
394                                                 success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
395                                                 break;
396                                         default:
397                                                 status = PSQL_CMD_UNKNOWN;
398                                                 break;
399                                 }
400                                 break;
401                         case 'g':
402                                 /* no longer distinct from \du */
403                                 success = describeRoles(pattern, show_verbose);
404                                 break;
405                         case 'l':
406                                 success = do_lo_list();
407                                 break;
408                         case 'L':
409                                 success = listLanguages(pattern, show_verbose, show_system);
410                                 break;
411                         case 'n':
412                                 success = listSchemas(pattern, show_verbose, show_system);
413                                 break;
414                         case 'o':
415                                 success = describeOperators(pattern, show_system);
416                                 break;
417                         case 'O':
418                                 success = listCollations(pattern, show_verbose, show_system);
419                                 break;
420                         case 'p':
421                                 success = permissionsList(pattern);
422                                 break;
423                         case 'T':
424                                 success = describeTypes(pattern, show_verbose, show_system);
425                                 break;
426                         case 't':
427                         case 'v':
428                         case 'm':
429                         case 'i':
430                         case 's':
431                         case 'E':
432                                 success = listTables(&cmd[1], pattern, show_verbose, show_system);
433                                 break;
434                         case 'r':
435                                 if (cmd[2] == 'd' && cmd[3] == 's')
436                                 {
437                                         char       *pattern2 = NULL;
438
439                                         if (pattern)
440                                                 pattern2 = psql_scan_slash_option(scan_state,
441                                                                                                           OT_NORMAL, NULL, true);
442                                         success = listDbRoleSettings(pattern, pattern2);
443                                 }
444                                 else
445                                         success = PSQL_CMD_UNKNOWN;
446                                 break;
447                         case 'u':
448                                 success = describeRoles(pattern, show_verbose);
449                                 break;
450                         case 'F':                       /* text search subsystem */
451                                 switch (cmd[2])
452                                 {
453                                         case '\0':
454                                         case '+':
455                                                 success = listTSConfigs(pattern, show_verbose);
456                                                 break;
457                                         case 'p':
458                                                 success = listTSParsers(pattern, show_verbose);
459                                                 break;
460                                         case 'd':
461                                                 success = listTSDictionaries(pattern, show_verbose);
462                                                 break;
463                                         case 't':
464                                                 success = listTSTemplates(pattern, show_verbose);
465                                                 break;
466                                         default:
467                                                 status = PSQL_CMD_UNKNOWN;
468                                                 break;
469                                 }
470                                 break;
471                         case 'e':                       /* SQL/MED subsystem */
472                                 switch (cmd[2])
473                                 {
474                                         case 's':
475                                                 success = listForeignServers(pattern, show_verbose);
476                                                 break;
477                                         case 'u':
478                                                 success = listUserMappings(pattern, show_verbose);
479                                                 break;
480                                         case 'w':
481                                                 success = listForeignDataWrappers(pattern, show_verbose);
482                                                 break;
483                                         case 't':
484                                                 success = listForeignTables(pattern, show_verbose);
485                                                 break;
486                                         default:
487                                                 status = PSQL_CMD_UNKNOWN;
488                                                 break;
489                                 }
490                                 break;
491                         case 'x':                       /* Extensions */
492                                 if (show_verbose)
493                                         success = listExtensionContents(pattern);
494                                 else
495                                         success = listExtensions(pattern);
496                                 break;
497                         case 'y':                       /* Event Triggers */
498                                 success = listEventTriggers(pattern, show_verbose);
499                                 break;
500                         default:
501                                 status = PSQL_CMD_UNKNOWN;
502                 }
503
504                 if (pattern)
505                         free(pattern);
506         }
507
508
509         /*
510          * \e or \edit -- edit the current query buffer, or edit a file and make
511          * it the query buffer
512          */
513         else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
514         {
515                 if (!query_buf)
516                 {
517                         psql_error("no query buffer\n");
518                         status = PSQL_CMD_ERROR;
519                 }
520                 else
521                 {
522                         char       *fname;
523                         char       *ln = NULL;
524                         int                     lineno = -1;
525
526                         fname = psql_scan_slash_option(scan_state,
527                                                                                    OT_NORMAL, NULL, true);
528                         if (fname)
529                         {
530                                 /* try to get separate lineno arg */
531                                 ln = psql_scan_slash_option(scan_state,
532                                                                                         OT_NORMAL, NULL, true);
533                                 if (ln == NULL)
534                                 {
535                                         /* only one arg; maybe it is lineno not fname */
536                                         if (fname[0] &&
537                                                 strspn(fname, "0123456789") == strlen(fname))
538                                         {
539                                                 /* all digits, so assume it is lineno */
540                                                 ln = fname;
541                                                 fname = NULL;
542                                         }
543                                 }
544                         }
545                         if (ln)
546                         {
547                                 lineno = atoi(ln);
548                                 if (lineno < 1)
549                                 {
550                                         psql_error("invalid line number: %s\n", ln);
551                                         status = PSQL_CMD_ERROR;
552                                 }
553                         }
554                         if (status != PSQL_CMD_ERROR)
555                         {
556                                 expand_tilde(&fname);
557                                 if (fname)
558                                         canonicalize_path(fname);
559                                 if (do_edit(fname, query_buf, lineno, NULL))
560                                         status = PSQL_CMD_NEWEDIT;
561                                 else
562                                         status = PSQL_CMD_ERROR;
563                         }
564                         if (fname)
565                                 free(fname);
566                         if (ln)
567                                 free(ln);
568                 }
569         }
570
571         /*
572          * \ef -- edit the named function, or present a blank CREATE FUNCTION
573          * template if no argument is given
574          */
575         else if (strcmp(cmd, "ef") == 0)
576         {
577                 int                     lineno = -1;
578
579                 if (pset.sversion < 80400)
580                 {
581                         psql_error("The server (version %d.%d) does not support editing function source.\n",
582                                            pset.sversion / 10000, (pset.sversion / 100) % 100);
583                         status = PSQL_CMD_ERROR;
584                 }
585                 else if (!query_buf)
586                 {
587                         psql_error("no query buffer\n");
588                         status = PSQL_CMD_ERROR;
589                 }
590                 else
591                 {
592                         char       *func;
593                         Oid                     foid = InvalidOid;
594
595                         func = psql_scan_slash_option(scan_state,
596                                                                                   OT_WHOLE_LINE, NULL, true);
597                         lineno = strip_lineno_from_funcdesc(func);
598                         if (lineno == 0)
599                         {
600                                 /* error already reported */
601                                 status = PSQL_CMD_ERROR;
602                         }
603                         else if (!func)
604                         {
605                                 /* set up an empty command to fill in */
606                                 printfPQExpBuffer(query_buf,
607                                                                   "CREATE FUNCTION ( )\n"
608                                                                   " RETURNS \n"
609                                                                   " LANGUAGE \n"
610                                                                   " -- common options:  IMMUTABLE  STABLE  STRICT  SECURITY DEFINER\n"
611                                                                   "AS $function$\n"
612                                                                   "\n$function$\n");
613                         }
614                         else if (!lookup_function_oid(pset.db, func, &foid))
615                         {
616                                 /* error already reported */
617                                 status = PSQL_CMD_ERROR;
618                         }
619                         else if (!get_create_function_cmd(pset.db, foid, query_buf))
620                         {
621                                 /* error already reported */
622                                 status = PSQL_CMD_ERROR;
623                         }
624                         else if (lineno > 0)
625                         {
626                                 /*
627                                  * lineno "1" should correspond to the first line of the
628                                  * function body.  We expect that pg_get_functiondef() will
629                                  * emit that on a line beginning with "AS ", and that there
630                                  * can be no such line before the real start of the function
631                                  * body.  Increment lineno by the number of lines before that
632                                  * line, so that it becomes relative to the first line of the
633                                  * function definition.
634                                  */
635                                 const char *lines = query_buf->data;
636
637                                 while (*lines != '\0')
638                                 {
639                                         if (strncmp(lines, "AS ", 3) == 0)
640                                                 break;
641                                         lineno++;
642                                         /* find start of next line */
643                                         lines = strchr(lines, '\n');
644                                         if (!lines)
645                                                 break;
646                                         lines++;
647                                 }
648                         }
649
650                         if (func)
651                                 free(func);
652                 }
653
654                 if (status != PSQL_CMD_ERROR)
655                 {
656                         bool            edited = false;
657
658                         if (!do_edit(NULL, query_buf, lineno, &edited))
659                                 status = PSQL_CMD_ERROR;
660                         else if (!edited)
661                                 puts(_("No changes"));
662                         else
663                                 status = PSQL_CMD_NEWEDIT;
664                 }
665         }
666
667         /* \echo and \qecho */
668         else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
669         {
670                 char       *value;
671                 char            quoted;
672                 bool            no_newline = false;
673                 bool            first = true;
674                 FILE       *fout;
675
676                 if (strcmp(cmd, "qecho") == 0)
677                         fout = pset.queryFout;
678                 else
679                         fout = stdout;
680
681                 while ((value = psql_scan_slash_option(scan_state,
682                                                                                            OT_NORMAL, &quoted, false)))
683                 {
684                         if (!quoted && strcmp(value, "-n") == 0)
685                                 no_newline = true;
686                         else
687                         {
688                                 if (first)
689                                         first = false;
690                                 else
691                                         fputc(' ', fout);
692                                 fputs(value, fout);
693                         }
694                         free(value);
695                 }
696                 if (!no_newline)
697                         fputs("\n", fout);
698         }
699
700         /* \encoding -- set/show client side encoding */
701         else if (strcmp(cmd, "encoding") == 0)
702         {
703                 char       *encoding = psql_scan_slash_option(scan_state,
704                                                                                                           OT_NORMAL, NULL, false);
705
706                 if (!encoding)
707                 {
708                         /* show encoding */
709                         puts(pg_encoding_to_char(pset.encoding));
710                 }
711                 else
712                 {
713                         /* set encoding */
714                         if (PQsetClientEncoding(pset.db, encoding) == -1)
715                                 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
716                         else
717                         {
718                                 /* save encoding info into psql internal data */
719                                 pset.encoding = PQclientEncoding(pset.db);
720                                 pset.popt.topt.encoding = pset.encoding;
721                                 SetVariable(pset.vars, "ENCODING",
722                                                         pg_encoding_to_char(pset.encoding));
723                         }
724                         free(encoding);
725                 }
726         }
727
728         /* \f -- change field separator */
729         else if (strcmp(cmd, "f") == 0)
730         {
731                 char       *fname = psql_scan_slash_option(scan_state,
732                                                                                                    OT_NORMAL, NULL, false);
733
734                 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
735                 free(fname);
736         }
737
738         /* \g [filename] -- send query, optionally with output to file/pipe */
739         else if (strcmp(cmd, "g") == 0)
740         {
741                 char       *fname = psql_scan_slash_option(scan_state,
742                                                                                                    OT_FILEPIPE, NULL, false);
743
744                 if (!fname)
745                         pset.gfname = NULL;
746                 else
747                 {
748                         expand_tilde(&fname);
749                         pset.gfname = pg_strdup(fname);
750                 }
751                 free(fname);
752                 status = PSQL_CMD_SEND;
753         }
754
755         /* \gset [prefix] -- send query and store result into variables */
756         else if (strcmp(cmd, "gset") == 0)
757         {
758                 char       *prefix = psql_scan_slash_option(scan_state,
759                                                                                                         OT_NORMAL, NULL, false);
760
761                 if (prefix)
762                         pset.gset_prefix = prefix;
763                 else
764                 {
765                         /* we must set a non-NULL prefix to trigger storing */
766                         pset.gset_prefix = pg_strdup("");
767                 }
768                 status = PSQL_CMD_SEND;
769         }
770
771         /* help */
772         else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
773         {
774                 char       *opt = psql_scan_slash_option(scan_state,
775                                                                                                  OT_WHOLE_LINE, NULL, false);
776                 size_t          len;
777
778                 /* strip any trailing spaces and semicolons */
779                 if (opt)
780                 {
781                         len = strlen(opt);
782                         while (len > 0 &&
783                                    (isspace((unsigned char) opt[len - 1])
784                                         || opt[len - 1] == ';'))
785                                 opt[--len] = '\0';
786                 }
787
788                 helpSQL(opt, pset.popt.topt.pager);
789                 free(opt);
790         }
791
792         /* HTML mode */
793         else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
794         {
795                 if (pset.popt.topt.format != PRINT_HTML)
796                         success = do_pset("format", "html", &pset.popt, pset.quiet);
797                 else
798                         success = do_pset("format", "aligned", &pset.popt, pset.quiet);
799         }
800
801
802         /* \i and \ir include files */
803         else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
804                    || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
805         {
806                 char       *fname = psql_scan_slash_option(scan_state,
807                                                                                                    OT_NORMAL, NULL, true);
808
809                 if (!fname)
810                 {
811                         psql_error("\\%s: missing required argument\n", cmd);
812                         success = false;
813                 }
814                 else
815                 {
816                         bool            include_relative;
817
818                         include_relative = (strcmp(cmd, "ir") == 0
819                                                                 || strcmp(cmd, "include_relative") == 0);
820                         expand_tilde(&fname);
821                         success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
822                         free(fname);
823                 }
824         }
825
826         /* \l is list databases */
827         else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
828                          strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
829         {
830                 char       *pattern;
831                 bool            show_verbose;
832
833                 pattern = psql_scan_slash_option(scan_state,
834                                                                                  OT_NORMAL, NULL, true);
835
836                 show_verbose = strchr(cmd, '+') ? true : false;
837
838                 success = listAllDbs(pattern, show_verbose);
839
840                 if (pattern)
841                         free(pattern);
842         }
843
844         /*
845          * large object things
846          */
847         else if (strncmp(cmd, "lo_", 3) == 0)
848         {
849                 char       *opt1,
850                                    *opt2;
851
852                 opt1 = psql_scan_slash_option(scan_state,
853                                                                           OT_NORMAL, NULL, true);
854                 opt2 = psql_scan_slash_option(scan_state,
855                                                                           OT_NORMAL, NULL, true);
856
857                 if (strcmp(cmd + 3, "export") == 0)
858                 {
859                         if (!opt2)
860                         {
861                                 psql_error("\\%s: missing required argument\n", cmd);
862                                 success = false;
863                         }
864                         else
865                         {
866                                 expand_tilde(&opt2);
867                                 success = do_lo_export(opt1, opt2);
868                         }
869                 }
870
871                 else if (strcmp(cmd + 3, "import") == 0)
872                 {
873                         if (!opt1)
874                         {
875                                 psql_error("\\%s: missing required argument\n", cmd);
876                                 success = false;
877                         }
878                         else
879                         {
880                                 expand_tilde(&opt1);
881                                 success = do_lo_import(opt1, opt2);
882                         }
883                 }
884
885                 else if (strcmp(cmd + 3, "list") == 0)
886                         success = do_lo_list();
887
888                 else if (strcmp(cmd + 3, "unlink") == 0)
889                 {
890                         if (!opt1)
891                         {
892                                 psql_error("\\%s: missing required argument\n", cmd);
893                                 success = false;
894                         }
895                         else
896                                 success = do_lo_unlink(opt1);
897                 }
898
899                 else
900                         status = PSQL_CMD_UNKNOWN;
901
902                 free(opt1);
903                 free(opt2);
904         }
905
906
907         /* \o -- set query output */
908         else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
909         {
910                 char       *fname = psql_scan_slash_option(scan_state,
911                                                                                                    OT_FILEPIPE, NULL, true);
912
913                 expand_tilde(&fname);
914                 success = setQFout(fname);
915                 free(fname);
916         }
917
918         /* \p prints the current query buffer */
919         else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
920         {
921                 if (query_buf && query_buf->len > 0)
922                         puts(query_buf->data);
923                 else if (!pset.quiet)
924                         puts(_("Query buffer is empty."));
925                 fflush(stdout);
926         }
927
928         /* \password -- set user password */
929         else if (strcmp(cmd, "password") == 0)
930         {
931                 char       *pw1;
932                 char       *pw2;
933
934                 pw1 = simple_prompt("Enter new password: ", 100, false);
935                 pw2 = simple_prompt("Enter it again: ", 100, false);
936
937                 if (strcmp(pw1, pw2) != 0)
938                 {
939                         psql_error("Passwords didn't match.\n");
940                         success = false;
941                 }
942                 else
943                 {
944                         char       *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
945                         char       *user;
946                         char       *encrypted_password;
947
948                         if (opt0)
949                                 user = opt0;
950                         else
951                                 user = PQuser(pset.db);
952
953                         encrypted_password = PQencryptPassword(pw1, user);
954
955                         if (!encrypted_password)
956                         {
957                                 psql_error("Password encryption failed.\n");
958                                 success = false;
959                         }
960                         else
961                         {
962                                 PQExpBufferData buf;
963                                 PGresult   *res;
964
965                                 initPQExpBuffer(&buf);
966                                 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
967                                                                   fmtId(user));
968                                 appendStringLiteralConn(&buf, encrypted_password, pset.db);
969                                 res = PSQLexec(buf.data, false);
970                                 termPQExpBuffer(&buf);
971                                 if (!res)
972                                         success = false;
973                                 else
974                                         PQclear(res);
975                                 PQfreemem(encrypted_password);
976                         }
977
978                         if (opt0)
979                                 free(opt0);
980                 }
981
982                 free(pw1);
983                 free(pw2);
984         }
985
986         /* \prompt -- prompt and set variable */
987         else if (strcmp(cmd, "prompt") == 0)
988         {
989                 char       *opt,
990                                    *prompt_text = NULL;
991                 char       *arg1,
992                                    *arg2;
993
994                 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
995                 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
996
997                 if (!arg1)
998                 {
999                         psql_error("\\%s: missing required argument\n", cmd);
1000                         success = false;
1001                 }
1002                 else
1003                 {
1004                         char       *result;
1005
1006                         if (arg2)
1007                         {
1008                                 prompt_text = arg1;
1009                                 opt = arg2;
1010                         }
1011                         else
1012                                 opt = arg1;
1013
1014                         if (!pset.inputfile)
1015                                 result = simple_prompt(prompt_text, 4096, true);
1016                         else
1017                         {
1018                                 if (prompt_text)
1019                                 {
1020                                         fputs(prompt_text, stdout);
1021                                         fflush(stdout);
1022                                 }
1023                                 result = gets_fromFile(stdin);
1024                         }
1025
1026                         if (!SetVariable(pset.vars, opt, result))
1027                         {
1028                                 psql_error("\\%s: error while setting variable\n", cmd);
1029                                 success = false;
1030                         }
1031
1032                         free(result);
1033                         if (prompt_text)
1034                                 free(prompt_text);
1035                         free(opt);
1036                 }
1037         }
1038
1039         /* \pset -- set printing parameters */
1040         else if (strcmp(cmd, "pset") == 0)
1041         {
1042                 char       *opt0 = psql_scan_slash_option(scan_state,
1043                                                                                                   OT_NORMAL, NULL, false);
1044                 char       *opt1 = psql_scan_slash_option(scan_state,
1045                                                                                                   OT_NORMAL, NULL, false);
1046
1047                 if (!opt0)
1048                 {
1049                        size_t i;
1050                        /* list all variables */
1051                        static const char *const my_list[] = {
1052                                 "border", "columns", "expanded", "fieldsep",
1053                                 "footer", "format", "linestyle", "null",
1054                                 "numericlocale", "pager", "recordsep",
1055                                 "tableattr", "title", "tuples_only",
1056                                 NULL };
1057                        for (i = 0; my_list[i] != NULL; i++) {
1058                                printPsetInfo(my_list[i], &pset.popt);
1059                        }
1060
1061                        success = true;
1062
1063                 }
1064                 else
1065                         success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
1066
1067                 free(opt0);
1068                 free(opt1);
1069         }
1070
1071         /* \q or \quit */
1072         else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
1073                 status = PSQL_CMD_TERMINATE;
1074
1075         /* reset(clear) the buffer */
1076         else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
1077         {
1078                 resetPQExpBuffer(query_buf);
1079                 psql_scan_reset(scan_state);
1080                 if (!pset.quiet)
1081                         puts(_("Query buffer reset (cleared)."));
1082         }
1083
1084         /* \s save history in a file or show it on the screen */
1085         else if (strcmp(cmd, "s") == 0)
1086         {
1087                 char       *fname = psql_scan_slash_option(scan_state,
1088                                                                                                    OT_NORMAL, NULL, true);
1089
1090 #if defined(WIN32) && !defined(__CYGWIN__)
1091
1092                 /*
1093                  * XXX This does not work for all terminal environments or for output
1094                  * containing non-ASCII characters; see comments in simple_prompt().
1095                  */
1096 #define DEVTTY  "con"
1097 #else
1098 #define DEVTTY  "/dev/tty"
1099 #endif
1100
1101                 expand_tilde(&fname);
1102                 /* This scrolls off the screen when using /dev/tty */
1103                 success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
1104                 if (success && !pset.quiet && fname)
1105                         printf(gettext("Wrote history to file \"%s/%s\".\n"),
1106                                    pset.dirname ? pset.dirname : ".", fname);
1107                 if (!fname)
1108                         putchar('\n');
1109                 free(fname);
1110         }
1111
1112         /* \set -- generalized set variable/option command */
1113         else if (strcmp(cmd, "set") == 0)
1114         {
1115                 char       *opt0 = psql_scan_slash_option(scan_state,
1116                                                                                                   OT_NORMAL, NULL, false);
1117
1118                 if (!opt0)
1119                 {
1120                         /* list all variables */
1121                         PrintVariables(pset.vars);
1122                         success = true;
1123                 }
1124                 else
1125                 {
1126                         /*
1127                          * Set variable to the concatenation of the arguments.
1128                          */
1129                         char       *newval;
1130                         char       *opt;
1131
1132                         opt = psql_scan_slash_option(scan_state,
1133                                                                                  OT_NORMAL, NULL, false);
1134                         newval = pg_strdup(opt ? opt : "");
1135                         free(opt);
1136
1137                         while ((opt = psql_scan_slash_option(scan_state,
1138                                                                                                  OT_NORMAL, NULL, false)))
1139                         {
1140                                 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
1141                                 if (!newval)
1142                                 {
1143                                         psql_error("out of memory\n");
1144                                         exit(EXIT_FAILURE);
1145                                 }
1146                                 strcat(newval, opt);
1147                                 free(opt);
1148                         }
1149
1150                         if (!SetVariable(pset.vars, opt0, newval))
1151                         {
1152                                 psql_error("\\%s: error while setting variable\n", cmd);
1153                                 success = false;
1154                         }
1155                         free(newval);
1156                 }
1157                 free(opt0);
1158         }
1159
1160
1161         /* \setenv -- set environment command */
1162         else if (strcmp(cmd, "setenv") == 0)
1163         {
1164                 char       *envvar = psql_scan_slash_option(scan_state,
1165                                                                                                         OT_NORMAL, NULL, false);
1166                 char       *envval = psql_scan_slash_option(scan_state,
1167                                                                                                         OT_NORMAL, NULL, false);
1168
1169                 if (!envvar)
1170                 {
1171                         psql_error("\\%s: missing required argument\n", cmd);
1172                         success = false;
1173                 }
1174                 else if (strchr(envvar, '=') != NULL)
1175                 {
1176                         psql_error("\\%s: environment variable name must not contain \"=\"\n",
1177                                            cmd);
1178                         success = false;
1179                 }
1180                 else if (!envval)
1181                 {
1182                         /* No argument - unset the environment variable */
1183                         unsetenv(envvar);
1184                         success = true;
1185                 }
1186                 else
1187                 {
1188                         /* Set variable to the value of the next argument */
1189                         char       *newval;
1190
1191                         newval = psprintf("%s=%s", envvar, envval);
1192                         putenv(newval);
1193                         success = true;
1194
1195                         /*
1196                          * Do not free newval here, it will screw up the environment if
1197                          * you do. See putenv man page for details. That means we leak a
1198                          * bit of memory here, but not enough to worry about.
1199                          */
1200                 }
1201                 free(envvar);
1202                 free(envval);
1203         }
1204
1205         /* \sf -- show a function's source code */
1206         else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
1207         {
1208                 bool            show_linenumbers = (strcmp(cmd, "sf+") == 0);
1209                 PQExpBuffer func_buf;
1210                 char       *func;
1211                 Oid                     foid = InvalidOid;
1212
1213                 func_buf = createPQExpBuffer();
1214                 func = psql_scan_slash_option(scan_state,
1215                                                                           OT_WHOLE_LINE, NULL, true);
1216                 if (pset.sversion < 80400)
1217                 {
1218                         psql_error("The server (version %d.%d) does not support showing function source.\n",
1219                                            pset.sversion / 10000, (pset.sversion / 100) % 100);
1220                         status = PSQL_CMD_ERROR;
1221                 }
1222                 else if (!func)
1223                 {
1224                         psql_error("function name is required\n");
1225                         status = PSQL_CMD_ERROR;
1226                 }
1227                 else if (!lookup_function_oid(pset.db, func, &foid))
1228                 {
1229                         /* error already reported */
1230                         status = PSQL_CMD_ERROR;
1231                 }
1232                 else if (!get_create_function_cmd(pset.db, foid, func_buf))
1233                 {
1234                         /* error already reported */
1235                         status = PSQL_CMD_ERROR;
1236                 }
1237                 else
1238                 {
1239                         FILE       *output;
1240                         bool            is_pager;
1241
1242                         /* Select output stream: stdout, pager, or file */
1243                         if (pset.queryFout == stdout)
1244                         {
1245                                 /* count lines in function to see if pager is needed */
1246                                 int                     lineno = 0;
1247                                 const char *lines = func_buf->data;
1248
1249                                 while (*lines != '\0')
1250                                 {
1251                                         lineno++;
1252                                         /* find start of next line */
1253                                         lines = strchr(lines, '\n');
1254                                         if (!lines)
1255                                                 break;
1256                                         lines++;
1257                                 }
1258
1259                                 output = PageOutput(lineno, pset.popt.topt.pager);
1260                                 is_pager = true;
1261                         }
1262                         else
1263                         {
1264                                 /* use previously set output file, without pager */
1265                                 output = pset.queryFout;
1266                                 is_pager = false;
1267                         }
1268
1269                         if (show_linenumbers)
1270                         {
1271                                 bool            in_header = true;
1272                                 int                     lineno = 0;
1273                                 char       *lines = func_buf->data;
1274
1275                                 /*
1276                                  * lineno "1" should correspond to the first line of the
1277                                  * function body.  We expect that pg_get_functiondef() will
1278                                  * emit that on a line beginning with "AS ", and that there
1279                                  * can be no such line before the real start of the function
1280                                  * body.
1281                                  *
1282                                  * Note that this loop scribbles on func_buf.
1283                                  */
1284                                 while (*lines != '\0')
1285                                 {
1286                                         char       *eol;
1287
1288                                         if (in_header && strncmp(lines, "AS ", 3) == 0)
1289                                                 in_header = false;
1290                                         /* increment lineno only for body's lines */
1291                                         if (!in_header)
1292                                                 lineno++;
1293
1294                                         /* find and mark end of current line */
1295                                         eol = strchr(lines, '\n');
1296                                         if (eol != NULL)
1297                                                 *eol = '\0';
1298
1299                                         /* show current line as appropriate */
1300                                         if (in_header)
1301                                                 fprintf(output, "        %s\n", lines);
1302                                         else
1303                                                 fprintf(output, "%-7d %s\n", lineno, lines);
1304
1305                                         /* advance to next line, if any */
1306                                         if (eol == NULL)
1307                                                 break;
1308                                         lines = ++eol;
1309                                 }
1310                         }
1311                         else
1312                         {
1313                                 /* just send the function definition to output */
1314                                 fputs(func_buf->data, output);
1315                         }
1316
1317                         if (is_pager)
1318                                 ClosePager(output);
1319                 }
1320
1321                 if (func)
1322                         free(func);
1323                 destroyPQExpBuffer(func_buf);
1324         }
1325
1326         /* \t -- turn off headers and row count */
1327         else if (strcmp(cmd, "t") == 0)
1328         {
1329                 char       *opt = psql_scan_slash_option(scan_state,
1330                                                                                                  OT_NORMAL, NULL, true);
1331
1332                 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
1333                 free(opt);
1334         }
1335
1336         /* \T -- define html <table ...> attributes */
1337         else if (strcmp(cmd, "T") == 0)
1338         {
1339                 char       *value = psql_scan_slash_option(scan_state,
1340                                                                                                    OT_NORMAL, NULL, false);
1341
1342                 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
1343                 free(value);
1344         }
1345
1346         /* \timing -- toggle timing of queries */
1347         else if (strcmp(cmd, "timing") == 0)
1348         {
1349                 char       *opt = psql_scan_slash_option(scan_state,
1350                                                                                                  OT_NORMAL, NULL, false);
1351
1352                 if (opt)
1353                         pset.timing = ParseVariableBool(opt);
1354                 else
1355                         pset.timing = !pset.timing;
1356                 if (!pset.quiet)
1357                 {
1358                         if (pset.timing)
1359                                 puts(_("Timing is on."));
1360                         else
1361                                 puts(_("Timing is off."));
1362                 }
1363                 free(opt);
1364         }
1365
1366         /* \unset */
1367         else if (strcmp(cmd, "unset") == 0)
1368         {
1369                 char       *opt = psql_scan_slash_option(scan_state,
1370                                                                                                  OT_NORMAL, NULL, false);
1371
1372                 if (!opt)
1373                 {
1374                         psql_error("\\%s: missing required argument\n", cmd);
1375                         success = false;
1376                 }
1377                 else if (!SetVariable(pset.vars, opt, NULL))
1378                 {
1379                         psql_error("\\%s: error while setting variable\n", cmd);
1380                         success = false;
1381                 }
1382                 free(opt);
1383         }
1384
1385         /* \w -- write query buffer to file */
1386         else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
1387         {
1388                 FILE       *fd = NULL;
1389                 bool            is_pipe = false;
1390                 char       *fname = NULL;
1391
1392                 if (!query_buf)
1393                 {
1394                         psql_error("no query buffer\n");
1395                         status = PSQL_CMD_ERROR;
1396                 }
1397                 else
1398                 {
1399                         fname = psql_scan_slash_option(scan_state,
1400                                                                                    OT_FILEPIPE, NULL, true);
1401                         expand_tilde(&fname);
1402
1403                         if (!fname)
1404                         {
1405                                 psql_error("\\%s: missing required argument\n", cmd);
1406                                 success = false;
1407                         }
1408                         else
1409                         {
1410                                 if (fname[0] == '|')
1411                                 {
1412                                         is_pipe = true;
1413                                         fd = popen(&fname[1], "w");
1414                                 }
1415                                 else
1416                                 {
1417                                         canonicalize_path(fname);
1418                                         fd = fopen(fname, "w");
1419                                 }
1420                                 if (!fd)
1421                                 {
1422                                         psql_error("%s: %s\n", fname, strerror(errno));
1423                                         success = false;
1424                                 }
1425                         }
1426                 }
1427
1428                 if (fd)
1429                 {
1430                         int                     result;
1431
1432                         if (query_buf && query_buf->len > 0)
1433                                 fprintf(fd, "%s\n", query_buf->data);
1434
1435                         if (is_pipe)
1436                                 result = pclose(fd);
1437                         else
1438                                 result = fclose(fd);
1439
1440                         if (result == EOF)
1441                         {
1442                                 psql_error("%s: %s\n", fname, strerror(errno));
1443                                 success = false;
1444                         }
1445                 }
1446
1447                 free(fname);
1448         }
1449
1450         /* \watch -- execute a query every N seconds */
1451         else if (strcmp(cmd, "watch") == 0)
1452         {
1453                 char       *opt = psql_scan_slash_option(scan_state,
1454                                                                                                  OT_NORMAL, NULL, true);
1455                 long            sleep = 2;
1456
1457                 /* Convert optional sleep-length argument */
1458                 if (opt)
1459                 {
1460                         sleep = strtol(opt, NULL, 10);
1461                         if (sleep <= 0)
1462                                 sleep = 1;
1463                         free(opt);
1464                 }
1465
1466                 success = do_watch(query_buf, sleep);
1467
1468                 /* Reset the query buffer as though for \r */
1469                 resetPQExpBuffer(query_buf);
1470                 psql_scan_reset(scan_state);
1471         }
1472
1473         /* \x -- set or toggle expanded table representation */
1474         else if (strcmp(cmd, "x") == 0)
1475         {
1476                 char       *opt = psql_scan_slash_option(scan_state,
1477                                                                                                  OT_NORMAL, NULL, true);
1478
1479                 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
1480                 free(opt);
1481         }
1482
1483         /* \z -- list table rights (equivalent to \dp) */
1484         else if (strcmp(cmd, "z") == 0)
1485         {
1486                 char       *pattern = psql_scan_slash_option(scan_state,
1487                                                                                                          OT_NORMAL, NULL, true);
1488
1489                 success = permissionsList(pattern);
1490                 if (pattern)
1491                         free(pattern);
1492         }
1493
1494         /* \! -- shell escape */
1495         else if (strcmp(cmd, "!") == 0)
1496         {
1497                 char       *opt = psql_scan_slash_option(scan_state,
1498                                                                                                  OT_WHOLE_LINE, NULL, false);
1499
1500                 success = do_shell(opt);
1501                 free(opt);
1502         }
1503
1504         /* \? -- slash command help */
1505         else if (strcmp(cmd, "?") == 0)
1506                 slashUsage(pset.popt.topt.pager);
1507
1508 #if 0
1509
1510         /*
1511          * These commands don't do anything. I just use them to test the parser.
1512          */
1513         else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
1514         {
1515                 int                     i = 0;
1516                 char       *value;
1517
1518                 while ((value = psql_scan_slash_option(scan_state,
1519                                                                                            OT_NORMAL, NULL, true)))
1520                 {
1521                         psql_error("+ opt(%d) = |%s|\n", i++, value);
1522                         free(value);
1523                 }
1524         }
1525 #endif
1526
1527         else
1528                 status = PSQL_CMD_UNKNOWN;
1529
1530         if (!success)
1531                 status = PSQL_CMD_ERROR;
1532
1533         return status;
1534 }
1535
1536 /*
1537  * Ask the user for a password; 'username' is the username the
1538  * password is for, if one has been explicitly specified. Returns a
1539  * malloc'd string.
1540  */
1541 static char *
1542 prompt_for_password(const char *username)
1543 {
1544         char       *result;
1545
1546         if (username == NULL)
1547                 result = simple_prompt("Password: ", 100, false);
1548         else
1549         {
1550                 char       *prompt_text;
1551
1552                 prompt_text = psprintf(_("Password for user %s: "), username);
1553                 result = simple_prompt(prompt_text, 100, false);
1554                 free(prompt_text);
1555         }
1556
1557         return result;
1558 }
1559
1560 static bool
1561 param_is_newly_set(const char *old_val, const char *new_val)
1562 {
1563         if (new_val == NULL)
1564                 return false;
1565
1566         if (old_val == NULL || strcmp(old_val, new_val) != 0)
1567                 return true;
1568
1569         return false;
1570 }
1571
1572 /*
1573  * do_connect -- handler for \connect
1574  *
1575  * Connects to a database with given parameters. If there exists an
1576  * established connection, NULL values will be replaced with the ones
1577  * in the current connection. Otherwise NULL will be passed for that
1578  * parameter to PQconnectdbParams(), so the libpq defaults will be used.
1579  *
1580  * In interactive mode, if connection fails with the given parameters,
1581  * the old connection will be kept.
1582  */
1583 static bool
1584 do_connect(char *dbname, char *user, char *host, char *port)
1585 {
1586         PGconn     *o_conn = pset.db,
1587                            *n_conn;
1588         char       *password = NULL;
1589
1590         if (!o_conn && (!dbname || !user || !host || !port))
1591         {
1592                 /*
1593                  * We don't know the supplied connection parameters and don't want to
1594                  * connect to the wrong database by using defaults, so require all
1595                  * parameters to be specified.
1596                  */
1597                 psql_error("All connection parameters must be supplied because no "
1598                                    "database connection exists\n");
1599                 return false;
1600         }
1601
1602         if (!dbname)
1603                 dbname = PQdb(o_conn);
1604         if (!user)
1605                 user = PQuser(o_conn);
1606         if (!host)
1607                 host = PQhost(o_conn);
1608         if (!port)
1609                 port = PQport(o_conn);
1610
1611         /*
1612          * If the user asked to be prompted for a password, ask for one now. If
1613          * not, use the password from the old connection, provided the username
1614          * has not changed. Otherwise, try to connect without a password first,
1615          * and then ask for a password if needed.
1616          *
1617          * XXX: this behavior leads to spurious connection attempts recorded in
1618          * the postmaster's log.  But libpq offers no API that would let us obtain
1619          * a password and then continue with the first connection attempt.
1620          */
1621         if (pset.getPassword == TRI_YES)
1622         {
1623                 password = prompt_for_password(user);
1624         }
1625         else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1626         {
1627                 password = pg_strdup(PQpass(o_conn));
1628         }
1629
1630         while (true)
1631         {
1632 #define PARAMS_ARRAY_SIZE       8
1633                 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
1634                 const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
1635
1636                 keywords[0] = "host";
1637                 values[0] = host;
1638                 keywords[1] = "port";
1639                 values[1] = port;
1640                 keywords[2] = "user";
1641                 values[2] = user;
1642                 keywords[3] = "password";
1643                 values[3] = password;
1644                 keywords[4] = "dbname";
1645                 values[4] = dbname;
1646                 keywords[5] = "fallback_application_name";
1647                 values[5] = pset.progname;
1648                 keywords[6] = "client_encoding";
1649                 values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
1650                 keywords[7] = NULL;
1651                 values[7] = NULL;
1652
1653                 n_conn = PQconnectdbParams(keywords, values, true);
1654
1655                 free(keywords);
1656                 free(values);
1657
1658                 /* We can immediately discard the password -- no longer needed */
1659                 if (password)
1660                         free(password);
1661
1662                 if (PQstatus(n_conn) == CONNECTION_OK)
1663                         break;
1664
1665                 /*
1666                  * Connection attempt failed; either retry the connection attempt with
1667                  * a new password, or give up.
1668                  */
1669                 if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
1670                 {
1671                         PQfinish(n_conn);
1672                         password = prompt_for_password(user);
1673                         continue;
1674                 }
1675
1676                 /*
1677                  * Failed to connect to the database. In interactive mode, keep the
1678                  * previous connection to the DB; in scripting mode, close our
1679                  * previous connection as well.
1680                  */
1681                 if (pset.cur_cmd_interactive)
1682                 {
1683                         psql_error("%s", PQerrorMessage(n_conn));
1684
1685                         /* pset.db is left unmodified */
1686                         if (o_conn)
1687                                 psql_error("Previous connection kept\n");
1688                 }
1689                 else
1690                 {
1691                         psql_error("\\connect: %s", PQerrorMessage(n_conn));
1692                         if (o_conn)
1693                         {
1694                                 PQfinish(o_conn);
1695                                 pset.db = NULL;
1696                         }
1697                 }
1698
1699                 PQfinish(n_conn);
1700                 return false;
1701         }
1702
1703         /*
1704          * Replace the old connection with the new one, and update
1705          * connection-dependent variables.
1706          */
1707         PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1708         pset.db = n_conn;
1709         SyncVariables();
1710         connection_warnings(false); /* Must be after SyncVariables */
1711
1712         /* Tell the user about the new connection */
1713         if (!pset.quiet)
1714         {
1715                 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
1716                         param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1717                 {
1718                         char       *host = PQhost(pset.db);
1719
1720                         if (host == NULL)
1721                                 host = DEFAULT_PGSOCKET_DIR;
1722                         /* If the host is an absolute path, the connection is via socket */
1723                         if (is_absolute_path(host))
1724                                 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
1725                                            PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1726                         else
1727                                 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
1728                                            PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1729                 }
1730                 else
1731                         printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
1732                                    PQdb(pset.db), PQuser(pset.db));
1733         }
1734
1735         if (o_conn)
1736                 PQfinish(o_conn);
1737         return true;
1738 }
1739
1740
1741 void
1742 connection_warnings(bool in_startup)
1743 {
1744         if (!pset.quiet && !pset.notty)
1745         {
1746                 int                     client_ver = PG_VERSION_NUM;
1747
1748                 if (pset.sversion != client_ver)
1749                 {
1750                         const char *server_version;
1751                         char            server_ver_str[16];
1752
1753                         /* Try to get full text form, might include "devel" etc */
1754                         server_version = PQparameterStatus(pset.db, "server_version");
1755                         if (!server_version)
1756                         {
1757                                 snprintf(server_ver_str, sizeof(server_ver_str),
1758                                                  "%d.%d.%d",
1759                                                  pset.sversion / 10000,
1760                                                  (pset.sversion / 100) % 100,
1761                                                  pset.sversion % 100);
1762                                 server_version = server_ver_str;
1763                         }
1764
1765                         printf(_("%s (%s, server %s)\n"),
1766                                    pset.progname, PG_VERSION, server_version);
1767                 }
1768                 /* For version match, only print psql banner on startup. */
1769                 else if (in_startup)
1770                         printf("%s (%s)\n", pset.progname, PG_VERSION);
1771
1772                 if (pset.sversion / 100 > client_ver / 100)
1773                         printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n"
1774                                          "         Some psql features might not work.\n"),
1775                                  pset.progname, client_ver / 10000, (client_ver / 100) % 100,
1776                                    pset.sversion / 10000, (pset.sversion / 100) % 100);
1777
1778 #ifdef WIN32
1779                 checkWin32Codepage();
1780 #endif
1781                 printSSLInfo();
1782         }
1783 }
1784
1785
1786 /*
1787  * printSSLInfo
1788  *
1789  * Prints information about the current SSL connection, if SSL is in use
1790  */
1791 static void
1792 printSSLInfo(void)
1793 {
1794 #ifdef USE_SSL
1795         int                     sslbits = -1;
1796         SSL                *ssl;
1797
1798         ssl = PQgetssl(pset.db);
1799         if (!ssl)
1800                 return;                                 /* no SSL */
1801
1802         SSL_get_cipher_bits(ssl, &sslbits);
1803         printf(_("SSL connection (cipher: %s, bits: %d)\n"),
1804                    SSL_get_cipher(ssl), sslbits);
1805 #else
1806
1807         /*
1808          * If psql is compiled without SSL but is using a libpq with SSL, we
1809          * cannot figure out the specifics about the connection. But we know it's
1810          * SSL secured.
1811          */
1812         if (PQgetssl(pset.db))
1813                 printf(_("SSL connection (unknown cipher)\n"));
1814 #endif
1815 }
1816
1817
1818 /*
1819  * checkWin32Codepage
1820  *
1821  * Prints a warning when win32 console codepage differs from Windows codepage
1822  */
1823 #ifdef WIN32
1824 static void
1825 checkWin32Codepage(void)
1826 {
1827         unsigned int wincp,
1828                                 concp;
1829
1830         wincp = GetACP();
1831         concp = GetConsoleCP();
1832         if (wincp != concp)
1833         {
1834                 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
1835                                  "         8-bit characters might not work correctly. See psql reference\n"
1836                                  "         page \"Notes for Windows users\" for details.\n"),
1837                            concp, wincp);
1838         }
1839 }
1840 #endif
1841
1842
1843 /*
1844  * SyncVariables
1845  *
1846  * Make psql's internal variables agree with connection state upon
1847  * establishing a new connection.
1848  */
1849 void
1850 SyncVariables(void)
1851 {
1852         /* get stuff from connection */
1853         pset.encoding = PQclientEncoding(pset.db);
1854         pset.popt.topt.encoding = pset.encoding;
1855         pset.sversion = PQserverVersion(pset.db);
1856
1857         SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1858         SetVariable(pset.vars, "USER", PQuser(pset.db));
1859         SetVariable(pset.vars, "HOST", PQhost(pset.db));
1860         SetVariable(pset.vars, "PORT", PQport(pset.db));
1861         SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1862
1863         /* send stuff to it, too */
1864         PQsetErrorVerbosity(pset.db, pset.verbosity);
1865 }
1866
1867 /*
1868  * UnsyncVariables
1869  *
1870  * Clear variables that should be not be set when there is no connection.
1871  */
1872 void
1873 UnsyncVariables(void)
1874 {
1875         SetVariable(pset.vars, "DBNAME", NULL);
1876         SetVariable(pset.vars, "USER", NULL);
1877         SetVariable(pset.vars, "HOST", NULL);
1878         SetVariable(pset.vars, "PORT", NULL);
1879         SetVariable(pset.vars, "ENCODING", NULL);
1880 }
1881
1882
1883 /*
1884  * do_edit -- handler for \e
1885  *
1886  * If you do not specify a filename, the current query buffer will be copied
1887  * into a temporary one.
1888  */
1889 static bool
1890 editFile(const char *fname, int lineno)
1891 {
1892         const char *editorName;
1893         const char *editor_lineno_arg = NULL;
1894         char       *sys;
1895         int                     result;
1896
1897         Assert(fname != NULL);
1898
1899         /* Find an editor to use */
1900         editorName = getenv("PSQL_EDITOR");
1901         if (!editorName)
1902                 editorName = getenv("EDITOR");
1903         if (!editorName)
1904                 editorName = getenv("VISUAL");
1905         if (!editorName)
1906                 editorName = DEFAULT_EDITOR;
1907
1908         /* Get line number argument, if we need it. */
1909         if (lineno > 0)
1910         {
1911                 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
1912 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
1913                 if (!editor_lineno_arg)
1914                         editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
1915 #endif
1916                 if (!editor_lineno_arg)
1917                 {
1918                         psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n");
1919                         return false;
1920                 }
1921         }
1922
1923         /*
1924          * On Unix the EDITOR value should *not* be quoted, since it might include
1925          * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1926          * if necessary.  But this policy is not very workable on Windows, due to
1927          * severe brain damage in their command shell plus the fact that standard
1928          * program paths include spaces.
1929          */
1930 #ifndef WIN32
1931         if (lineno > 0)
1932                 sys = psprintf("exec %s %s%d '%s'",
1933                                         editorName, editor_lineno_arg, lineno, fname);
1934         else
1935                 sys = psprintf("exec %s '%s'",
1936                                         editorName, fname);
1937 #else
1938         if (lineno > 0)
1939                 sys = psprintf(SYSTEMQUOTE "\"%s\" %s%d \"%s\"" SYSTEMQUOTE,
1940                                 editorName, editor_lineno_arg, lineno, fname);
1941         else
1942                 sys = psprintf(SYSTEMQUOTE "\"%s\" \"%s\"" SYSTEMQUOTE,
1943                                         editorName, fname);
1944 #endif
1945         result = system(sys);
1946         if (result == -1)
1947                 psql_error("could not start editor \"%s\"\n", editorName);
1948         else if (result == 127)
1949                 psql_error("could not start /bin/sh\n");
1950         free(sys);
1951
1952         return result == 0;
1953 }
1954
1955
1956 /* call this one */
1957 static bool
1958 do_edit(const char *filename_arg, PQExpBuffer query_buf,
1959                 int lineno, bool *edited)
1960 {
1961         char            fnametmp[MAXPGPATH];
1962         FILE       *stream = NULL;
1963         const char *fname;
1964         bool            error = false;
1965         int                     fd;
1966
1967         struct stat before,
1968                                 after;
1969
1970         if (filename_arg)
1971                 fname = filename_arg;
1972         else
1973         {
1974                 /* make a temp file to edit */
1975 #ifndef WIN32
1976                 const char *tmpdir = getenv("TMPDIR");
1977
1978                 if (!tmpdir)
1979                         tmpdir = "/tmp";
1980 #else
1981                 char            tmpdir[MAXPGPATH];
1982                 int                     ret;
1983
1984                 ret = GetTempPath(MAXPGPATH, tmpdir);
1985                 if (ret == 0 || ret > MAXPGPATH)
1986                 {
1987                         psql_error("could not locate temporary directory: %s\n",
1988                                            !ret ? strerror(errno) : "");
1989                         return false;
1990                 }
1991
1992                 /*
1993                  * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
1994                  * current directory to the supplied path unless we use only
1995                  * backslashes, so we do that.
1996                  */
1997 #endif
1998 #ifndef WIN32
1999                 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2000                                  "/", (int) getpid());
2001 #else
2002                 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2003                            "" /* trailing separator already present */ , (int) getpid());
2004 #endif
2005
2006                 fname = (const char *) fnametmp;
2007
2008                 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
2009                 if (fd != -1)
2010                         stream = fdopen(fd, "w");
2011
2012                 if (fd == -1 || !stream)
2013                 {
2014                         psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
2015                         error = true;
2016                 }
2017                 else
2018                 {
2019                         unsigned int ql = query_buf->len;
2020
2021                         if (ql == 0 || query_buf->data[ql - 1] != '\n')
2022                         {
2023                                 appendPQExpBufferChar(query_buf, '\n');
2024                                 ql++;
2025                         }
2026
2027                         if (fwrite(query_buf->data, 1, ql, stream) != ql)
2028                         {
2029                                 psql_error("%s: %s\n", fname, strerror(errno));
2030                                 fclose(stream);
2031                                 remove(fname);
2032                                 error = true;
2033                         }
2034                         else if (fclose(stream) != 0)
2035                         {
2036                                 psql_error("%s: %s\n", fname, strerror(errno));
2037                                 remove(fname);
2038                                 error = true;
2039                         }
2040                 }
2041         }
2042
2043         if (!error && stat(fname, &before) != 0)
2044         {
2045                 psql_error("%s: %s\n", fname, strerror(errno));
2046                 error = true;
2047         }
2048
2049         /* call editor */
2050         if (!error)
2051                 error = !editFile(fname, lineno);
2052
2053         if (!error && stat(fname, &after) != 0)
2054         {
2055                 psql_error("%s: %s\n", fname, strerror(errno));
2056                 error = true;
2057         }
2058
2059         if (!error && before.st_mtime != after.st_mtime)
2060         {
2061                 stream = fopen(fname, PG_BINARY_R);
2062                 if (!stream)
2063                 {
2064                         psql_error("%s: %s\n", fname, strerror(errno));
2065                         error = true;
2066                 }
2067                 else
2068                 {
2069                         /* read file back into query_buf */
2070                         char            line[1024];
2071
2072                         resetPQExpBuffer(query_buf);
2073                         while (fgets(line, sizeof(line), stream) != NULL)
2074                                 appendPQExpBufferStr(query_buf, line);
2075
2076                         if (ferror(stream))
2077                         {
2078                                 psql_error("%s: %s\n", fname, strerror(errno));
2079                                 error = true;
2080                         }
2081                         else if (edited)
2082                         {
2083                                 *edited = true;
2084                         }
2085
2086                         fclose(stream);
2087                 }
2088         }
2089
2090         /* remove temp file */
2091         if (!filename_arg)
2092         {
2093                 if (remove(fname) == -1)
2094                 {
2095                         psql_error("%s: %s\n", fname, strerror(errno));
2096                         error = true;
2097                 }
2098         }
2099
2100         return !error;
2101 }
2102
2103
2104
2105 /*
2106  * process_file
2107  *
2108  * Reads commands from filename and passes them to the main processing loop.
2109  * Handler for \i and \ir, but can be used for other things as well.  Returns
2110  * MainLoop() error code.
2111  *
2112  * If use_relative_path is true and filename is not an absolute path, then open
2113  * the file from where the currently processed file (if any) is located.
2114  */
2115 int
2116 process_file(char *filename, bool single_txn, bool use_relative_path)
2117 {
2118         FILE       *fd;
2119         int                     result;
2120         char       *oldfilename;
2121         char            relpath[MAXPGPATH];
2122         PGresult   *res;
2123
2124         if (!filename)
2125         {
2126                 fd = stdin;
2127                 filename = NULL;
2128         }
2129         else if (strcmp(filename, "-") != 0)
2130         {
2131                 canonicalize_path(filename);
2132
2133                 /*
2134                  * If we were asked to resolve the pathname relative to the location
2135                  * of the currently executing script, and there is one, and this is a
2136                  * relative pathname, then prepend all but the last pathname component
2137                  * of the current script to this pathname.
2138                  */
2139                 if (use_relative_path && pset.inputfile &&
2140                         !is_absolute_path(filename) && !has_drive_prefix(filename))
2141                 {
2142                         strlcpy(relpath, pset.inputfile, sizeof(relpath));
2143                         get_parent_directory(relpath);
2144                         join_path_components(relpath, relpath, filename);
2145                         canonicalize_path(relpath);
2146
2147                         filename = relpath;
2148                 }
2149
2150                 fd = fopen(filename, PG_BINARY_R);
2151
2152                 if (!fd)
2153                 {
2154                         psql_error("%s: %s\n", filename, strerror(errno));
2155                         return EXIT_FAILURE;
2156                 }
2157         }
2158         else
2159         {
2160                 fd = stdin;
2161                 filename = "<stdin>";   /* for future error messages */
2162         }
2163
2164         oldfilename = pset.inputfile;
2165         pset.inputfile = filename;
2166
2167         if (single_txn)
2168         {
2169                 if ((res = PSQLexec("BEGIN", false)) == NULL)
2170                 {
2171                         if (pset.on_error_stop)
2172                         {
2173                                 result = EXIT_USER;
2174                                 goto error;
2175                         }
2176                 }
2177                 else
2178                         PQclear(res);
2179         }
2180
2181         result = MainLoop(fd);
2182
2183         if (single_txn)
2184         {
2185                 if ((res = PSQLexec("COMMIT", false)) == NULL)
2186                 {
2187                         if (pset.on_error_stop)
2188                         {
2189                                 result = EXIT_USER;
2190                                 goto error;
2191                         }
2192                 }
2193                 else
2194                         PQclear(res);
2195         }
2196
2197 error:
2198         if (fd != stdin)
2199                 fclose(fd);
2200
2201         pset.inputfile = oldfilename;
2202         return result;
2203 }
2204
2205
2206
2207 /*
2208  * do_pset
2209  *
2210  */
2211 static const char *
2212 _align2string(enum printFormat in)
2213 {
2214         switch (in)
2215         {
2216                 case PRINT_NOTHING:
2217                         return "nothing";
2218                         break;
2219                 case PRINT_UNALIGNED:
2220                         return "unaligned";
2221                         break;
2222                 case PRINT_ALIGNED:
2223                         return "aligned";
2224                         break;
2225                 case PRINT_WRAPPED:
2226                         return "wrapped";
2227                         break;
2228                 case PRINT_HTML:
2229                         return "html";
2230                         break;
2231                 case PRINT_LATEX:
2232                         return "latex";
2233                         break;
2234                 case PRINT_LATEX_LONGTABLE:
2235                         return "latex-longtable";
2236                         break;
2237                 case PRINT_TROFF_MS:
2238                         return "troff-ms";
2239                         break;
2240         }
2241         return "unknown";
2242 }
2243
2244
2245 bool
2246 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
2247 {
2248         size_t          vallen = 0;
2249
2250         Assert(param != NULL);
2251
2252         if (value)
2253                 vallen = strlen(value);
2254
2255         /* set format */
2256         if (strcmp(param, "format") == 0)
2257         {
2258                 if (!value)
2259                         ;
2260                 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
2261                         popt->topt.format = PRINT_UNALIGNED;
2262                 else if (pg_strncasecmp("aligned", value, vallen) == 0)
2263                         popt->topt.format = PRINT_ALIGNED;
2264                 else if (pg_strncasecmp("wrapped", value, vallen) == 0)
2265                         popt->topt.format = PRINT_WRAPPED;
2266                 else if (pg_strncasecmp("html", value, vallen) == 0)
2267                         popt->topt.format = PRINT_HTML;
2268                 else if (pg_strncasecmp("latex", value, vallen) == 0)
2269                         popt->topt.format = PRINT_LATEX;
2270                 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
2271                         popt->topt.format = PRINT_LATEX_LONGTABLE;
2272                 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
2273                         popt->topt.format = PRINT_TROFF_MS;
2274                 else
2275                 {
2276                         psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n");
2277                         return false;
2278                 }
2279
2280         }
2281
2282         /* set table line style */
2283         else if (strcmp(param, "linestyle") == 0)
2284         {
2285                 if (!value)
2286                         ;
2287                 else if (pg_strncasecmp("ascii", value, vallen) == 0)
2288                         popt->topt.line_style = &pg_asciiformat;
2289                 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
2290                         popt->topt.line_style = &pg_asciiformat_old;
2291                 else if (pg_strncasecmp("unicode", value, vallen) == 0)
2292                         popt->topt.line_style = &pg_utf8format;
2293                 else
2294                 {
2295                         psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
2296                         return false;
2297                 }
2298
2299         }
2300
2301         /* set border style/width */
2302         else if (strcmp(param, "border") == 0)
2303         {
2304                 if (value)
2305                         popt->topt.border = atoi(value);
2306
2307         }
2308
2309         /* set expanded/vertical mode */
2310         else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2311         {
2312                 if (value && pg_strcasecmp(value, "auto") == 0)
2313                         popt->topt.expanded = 2;
2314                 else if (value)
2315                         popt->topt.expanded = ParseVariableBool(value);
2316                 else
2317                         popt->topt.expanded = !popt->topt.expanded;
2318         }
2319
2320         /* locale-aware numeric output */
2321         else if (strcmp(param, "numericlocale") == 0)
2322         {
2323                 if (value)
2324                         popt->topt.numericLocale = ParseVariableBool(value);
2325                 else
2326                         popt->topt.numericLocale = !popt->topt.numericLocale;
2327         }
2328
2329         /* null display */
2330         else if (strcmp(param, "null") == 0)
2331         {
2332                 if (value)
2333                 {
2334                         free(popt->nullPrint);
2335                         popt->nullPrint = pg_strdup(value);
2336                 }
2337         }
2338
2339         /* field separator for unaligned text */
2340         else if (strcmp(param, "fieldsep") == 0)
2341         {
2342                 if (value)
2343                 {
2344                         free(popt->topt.fieldSep.separator);
2345                         popt->topt.fieldSep.separator = pg_strdup(value);
2346                         popt->topt.fieldSep.separator_zero = false;
2347                 }
2348         }
2349
2350         else if (strcmp(param, "fieldsep_zero") == 0)
2351         {
2352                 free(popt->topt.fieldSep.separator);
2353                 popt->topt.fieldSep.separator = NULL;
2354                 popt->topt.fieldSep.separator_zero = true;
2355         }
2356
2357         /* record separator for unaligned text */
2358         else if (strcmp(param, "recordsep") == 0)
2359         {
2360                 if (value)
2361                 {
2362                         free(popt->topt.recordSep.separator);
2363                         popt->topt.recordSep.separator = pg_strdup(value);
2364                         popt->topt.recordSep.separator_zero = false;
2365                 }
2366         }
2367
2368         else if (strcmp(param, "recordsep_zero") == 0)
2369         {
2370                 free(popt->topt.recordSep.separator);
2371                 popt->topt.recordSep.separator = NULL;
2372                 popt->topt.recordSep.separator_zero = true;
2373         }
2374
2375         /* toggle between full and tuples-only format */
2376         else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2377         {
2378                 if (value)
2379                         popt->topt.tuples_only = ParseVariableBool(value);
2380                 else
2381                         popt->topt.tuples_only = !popt->topt.tuples_only;
2382         }
2383
2384         /* set title override */
2385         else if (strcmp(param, "title") == 0)
2386         {
2387                 free(popt->title);
2388                 if (!value)
2389                         popt->title = NULL;
2390                 else
2391                         popt->title = pg_strdup(value);
2392         }
2393
2394         /* set HTML table tag options */
2395         else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2396         {
2397                 free(popt->topt.tableAttr);
2398                 if (!value)
2399                         popt->topt.tableAttr = NULL;
2400                 else
2401                         popt->topt.tableAttr = pg_strdup(value);
2402         }
2403
2404         /* toggle use of pager */
2405         else if (strcmp(param, "pager") == 0)
2406         {
2407                 if (value && pg_strcasecmp(value, "always") == 0)
2408                         popt->topt.pager = 2;
2409                 else if (value)
2410                         if (ParseVariableBool(value))
2411                                 popt->topt.pager = 1;
2412                         else
2413                                 popt->topt.pager = 0;
2414                 else if (popt->topt.pager == 1)
2415                         popt->topt.pager = 0;
2416                 else
2417                         popt->topt.pager = 1;
2418         }
2419
2420         /* disable "(x rows)" footer */
2421         else if (strcmp(param, "footer") == 0)
2422         {
2423                 if (value)
2424                         popt->topt.default_footer = ParseVariableBool(value);
2425                 else
2426                         popt->topt.default_footer = !popt->topt.default_footer;
2427         }
2428
2429         /* set border style/width */
2430         else if (strcmp(param, "columns") == 0)
2431         {
2432                 if (value)
2433                         popt->topt.columns = atoi(value);
2434         }
2435         else
2436         {
2437                 psql_error("\\pset: unknown option: %s\n", param);
2438                 return false;
2439         }
2440
2441        if (!quiet)
2442                printPsetInfo(param, &pset.popt);
2443
2444         return true;
2445 }
2446
2447
2448 static bool
2449 printPsetInfo(const char *param, struct printQueryOpt *popt)
2450 {
2451         Assert(param != NULL);
2452
2453         /* show border style/width */
2454         if (strcmp(param, "border") == 0)
2455         {
2456                 if (!popt->topt.border)
2457                         printf(_("Border style (%s) unset.\n"), param);
2458                 else
2459                         printf(_("Border style (%s) is %d.\n"), param,
2460                                 popt->topt.border);
2461         }
2462
2463         /* show the target width for the wrapped format */
2464         else if (strcmp(param, "columns") == 0)
2465         {
2466                 if (!popt->topt.columns)
2467                         printf(_("Target width (%s) unset.\n"), param);
2468                 else
2469                         printf(_("Target width (%s) is %d.\n"), param,
2470                                 popt->topt.columns);
2471         }
2472
2473         /* show expanded/vertical mode */
2474         else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2475         {
2476                 if (popt->topt.expanded == 1)
2477                         printf(_("Expanded display (%s) is on.\n"), param);
2478                 else if (popt->topt.expanded == 2)
2479                         printf(_("Expanded display (%s) is used automatically.\n"), param);
2480                 else
2481                         printf(_("Expanded display (%s) is off.\n"), param);
2482         }
2483
2484         /* show field separator for unaligned text */
2485         else if (strcmp(param, "fieldsep") == 0)
2486         {
2487                 if (popt->topt.fieldSep.separator_zero)
2488                         printf(_("Field separator (%s) is zero byte.\n"), param);
2489                 else
2490                         printf(_("Field separator (%s) is \"%s\".\n"), param,
2491                                 popt->topt.fieldSep.separator);
2492         }
2493
2494         else if (strcmp(param, "fieldsep_zero") == 0)
2495         {
2496                 printf(_("Field separator (%s) is zero byte.\n"), param);
2497         }
2498
2499         /* show disable "(x rows)" footer */
2500         else if (strcmp(param, "footer") == 0)
2501         {
2502                 if (popt->topt.default_footer)
2503                         printf(_("Default footer (%s) is on.\n"), param);
2504                 else
2505                         printf(_("Default footer (%s) is off."), param);
2506         }
2507
2508         /* show format */
2509         else if (strcmp(param, "format") == 0)
2510         {
2511                 if (!popt->topt.format)
2512                         printf(_("Output format (%s) is aligned.\n"), param);
2513                 else
2514                         printf(_("Output format (%s) is %s.\n"), param,
2515                                 _align2string(popt->topt.format));
2516         }
2517
2518         /* show table line style */
2519         else if (strcmp(param, "linestyle") == 0)
2520         {
2521                 printf(_("Line style (%s) is %s.\n"), param,
2522                         get_line_style(&popt->topt)->name);
2523         }
2524
2525         /* show null display */
2526         else if (strcmp(param, "null") == 0)
2527         {
2528                 printf(_("Null display (%s) is \"%s\".\n"), param,
2529                         popt->nullPrint ? popt->nullPrint : "");
2530         }
2531
2532         /* show locale-aware numeric output */
2533         else if (strcmp(param, "numericlocale") == 0)
2534         {
2535                 if (popt->topt.numericLocale)
2536                         printf(_("Locale-adjusted numeric output (%s) is on.\n"), param);
2537                 else
2538                         printf(_("Locale-adjusted numeric output (%s) is off.\n"), param);
2539         }
2540
2541         /* show toggle use of pager */
2542         else if (strcmp(param, "pager") == 0)
2543         {
2544                 if (popt->topt.pager == 1)
2545                         printf(_("Pager (%s) is used for long output.\n"), param);
2546                 else if (popt->topt.pager == 2)
2547                         printf(_("Pager (%s) is always used.\n"), param);
2548                 else
2549                         printf(_("Pager (%s) usage is off.\n"), param);
2550         }
2551
2552         /* show record separator for unaligned text */
2553         else if (strcmp(param, "recordsep") == 0)
2554         {
2555                 if (popt->topt.recordSep.separator_zero)
2556                         printf(_("Record separator (%s) is zero byte.\n"), param);
2557                 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
2558                         printf(_("Record separator (%s) is <newline>.\n"), param);
2559                 else
2560                         printf(_("Record separator (%s) is \"%s\".\n"), param,
2561                                 popt->topt.recordSep.separator);
2562         }
2563
2564         else if (strcmp(param, "recordsep_zero") == 0)
2565         {
2566                 printf(_("Record separator (%s) is zero byte.\n"), param);
2567         }
2568
2569         /* show HTML table tag options */
2570         else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2571         {
2572                 if (popt->topt.tableAttr)
2573                         printf(_("Table attribute (%s) is \"%s\".\n"), param,
2574                                 popt->topt.tableAttr);
2575                 else
2576                         printf(_("Table attributes (%s) unset.\n"), param);
2577         }
2578
2579         /* show title override */
2580         else if (strcmp(param, "title") == 0)
2581         {
2582                 if (popt->title)
2583                         printf(_("Title (%s) is \"%s\".\n"), param, popt->title);
2584                 else
2585                         printf(_("Title (%s) unset.\n"), param);
2586         }
2587
2588         /* show toggle between full and tuples-only format */
2589         else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2590         {
2591                 if (popt->topt.tuples_only)
2592                         printf(_("Tuples only (%s) is on.\n"), param);
2593                 else
2594                         printf(_("Tuples only (%s) is off.\n"), param);
2595         }
2596
2597         else
2598         {
2599                 psql_error("\\pset: unknown option: %s\n", param);
2600                 return false;
2601         }
2602
2603         return true;
2604 }
2605
2606
2607
2608 #ifndef WIN32
2609 #define DEFAULT_SHELL "/bin/sh"
2610 #else
2611 /*
2612  *      CMD.EXE is in different places in different Win32 releases so we
2613  *      have to rely on the path to find it.
2614  */
2615 #define DEFAULT_SHELL "cmd.exe"
2616 #endif
2617
2618 static bool
2619 do_shell(const char *command)
2620 {
2621         int                     result;
2622
2623         if (!command)
2624         {
2625                 char       *sys;
2626                 const char *shellName;
2627
2628                 shellName = getenv("SHELL");
2629 #ifdef WIN32
2630                 if (shellName == NULL)
2631                         shellName = getenv("COMSPEC");
2632 #endif
2633                 if (shellName == NULL)
2634                         shellName = DEFAULT_SHELL;
2635
2636                 /* See EDITOR handling comment for an explanation */
2637 #ifndef WIN32
2638                 sys = psprintf("exec %s", shellName);
2639 #else
2640                 sys = psprintf(SYSTEMQUOTE "\"%s\"" SYSTEMQUOTE, shellName);
2641 #endif
2642                 result = system(sys);
2643                 free(sys);
2644         }
2645         else
2646                 result = system(command);
2647
2648         if (result == 127 || result == -1)
2649         {
2650                 psql_error("\\!: failed\n");
2651                 return false;
2652         }
2653         return true;
2654 }
2655
2656 /*
2657  * do_watch -- handler for \watch
2658  *
2659  * We break this out of exec_command to avoid having to plaster "volatile"
2660  * onto a bunch of exec_command's variables to silence stupider compilers.
2661  */
2662 static bool
2663 do_watch(PQExpBuffer query_buf, long sleep)
2664 {
2665         printQueryOpt myopt = pset.popt;
2666         char            title[50];
2667
2668         if (!query_buf || query_buf->len <= 0)
2669         {
2670                 psql_error(_("\\watch cannot be used with an empty query\n"));
2671                 return false;
2672         }
2673
2674         /*
2675          * Set up rendering options, in particular, disable the pager, because
2676          * nobody wants to be prompted while watching the output of 'watch'.
2677          */
2678         myopt.nullPrint = NULL;
2679         myopt.topt.pager = 0;
2680
2681         for (;;)
2682         {
2683                 PGresult   *res;
2684                 time_t          timer;
2685                 long            i;
2686
2687                 /*
2688                  * Prepare title for output.  XXX would it be better to use the time
2689                  * of completion of the command?
2690                  */
2691                 timer = time(NULL);
2692                 snprintf(title, sizeof(title), _("Watch every %lds\t%s"),
2693                                  sleep, asctime(localtime(&timer)));
2694                 myopt.title = title;
2695
2696                 /*
2697                  * Run the query.  We use PSQLexec, which is kind of cheating, but
2698                  * SendQuery doesn't let us suppress autocommit behavior.
2699                  */
2700                 res = PSQLexec(query_buf->data, false);
2701
2702                 /* PSQLexec handles failure results and returns NULL */
2703                 if (res == NULL)
2704                         break;
2705
2706                 /*
2707                  * If SIGINT is sent while the query is processing, PSQLexec will
2708                  * consume the interrupt.  The user's intention, though, is to cancel
2709                  * the entire watch process, so detect a sent cancellation request and
2710                  * exit in this case.
2711                  */
2712                 if (cancel_pressed)
2713                 {
2714                         PQclear(res);
2715                         break;
2716                 }
2717
2718                 switch (PQresultStatus(res))
2719                 {
2720                         case PGRES_TUPLES_OK:
2721                                 printQuery(res, &myopt, pset.queryFout, pset.logfile);
2722                                 break;
2723
2724                         case PGRES_COMMAND_OK:
2725                                 fprintf(pset.queryFout, "%s\n%s\n\n", title, PQcmdStatus(res));
2726                                 break;
2727
2728                         case PGRES_EMPTY_QUERY:
2729                                 psql_error(_("\\watch cannot be used with an empty query\n"));
2730                                 PQclear(res);
2731                                 return false;
2732
2733                         case PGRES_COPY_OUT:
2734                         case PGRES_COPY_IN:
2735                         case PGRES_COPY_BOTH:
2736                                 psql_error(_("\\watch cannot be used with COPY\n"));
2737                                 PQclear(res);
2738                                 return false;
2739
2740                         default:
2741                                 /* other cases should have been handled by PSQLexec */
2742                                 psql_error(_("unexpected result status for \\watch\n"));
2743                                 PQclear(res);
2744                                 return false;
2745                 }
2746
2747                 PQclear(res);
2748
2749                 fflush(pset.queryFout);
2750
2751                 /*
2752                  * Set up cancellation of 'watch' via SIGINT.  We redo this each time
2753                  * through the loop since it's conceivable something inside PSQLexec
2754                  * could change sigint_interrupt_jmp.
2755                  */
2756                 if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
2757                         break;
2758
2759                 /*
2760                  * Enable 'watch' cancellations and wait a while before running the
2761                  * query again.  Break the sleep into short intervals since pg_usleep
2762                  * isn't interruptible on some platforms.
2763                  */
2764                 sigint_interrupt_enabled = true;
2765                 for (i = 0; i < sleep; i++)
2766                 {
2767                         pg_usleep(1000000L);
2768                         if (cancel_pressed)
2769                                 break;
2770                 }
2771                 sigint_interrupt_enabled = false;
2772         }
2773
2774         return true;
2775 }
2776
2777 /*
2778  * This function takes a function description, e.g. "x" or "x(int)", and
2779  * issues a query on the given connection to retrieve the function's OID
2780  * using a cast to regproc or regprocedure (as appropriate). The result,
2781  * if there is one, is returned at *foid.  Note that we'll fail if the
2782  * function doesn't exist OR if there are multiple matching candidates
2783  * OR if there's something syntactically wrong with the function description;
2784  * unfortunately it can be hard to tell the difference.
2785  */
2786 static bool
2787 lookup_function_oid(PGconn *conn, const char *desc, Oid *foid)
2788 {
2789         bool            result = true;
2790         PQExpBuffer query;
2791         PGresult   *res;
2792
2793         query = createPQExpBuffer();
2794         printfPQExpBuffer(query, "SELECT ");
2795         appendStringLiteralConn(query, desc, conn);
2796         appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
2797                                           strchr(desc, '(') ? "regprocedure" : "regproc");
2798
2799         res = PQexec(conn, query->data);
2800         if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2801                 *foid = atooid(PQgetvalue(res, 0, 0));
2802         else
2803         {
2804                 minimal_error_message(res);
2805                 result = false;
2806         }
2807
2808         PQclear(res);
2809         destroyPQExpBuffer(query);
2810
2811         return result;
2812 }
2813
2814 /*
2815  * Fetches the "CREATE OR REPLACE FUNCTION ..." command that describes the
2816  * function with the given OID.  If successful, the result is stored in buf.
2817  */
2818 static bool
2819 get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf)
2820 {
2821         bool            result = true;
2822         PQExpBuffer query;
2823         PGresult   *res;
2824
2825         query = createPQExpBuffer();
2826         printfPQExpBuffer(query, "SELECT pg_catalog.pg_get_functiondef(%u)", oid);
2827
2828         res = PQexec(conn, query->data);
2829         if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2830         {
2831                 resetPQExpBuffer(buf);
2832                 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
2833         }
2834         else
2835         {
2836                 minimal_error_message(res);
2837                 result = false;
2838         }
2839
2840         PQclear(res);
2841         destroyPQExpBuffer(query);
2842
2843         return result;
2844 }
2845
2846 /*
2847  * If the given argument of \ef ends with a line number, delete the line
2848  * number from the argument string and return it as an integer.  (We need
2849  * this kluge because we're too lazy to parse \ef's function name argument
2850  * carefully --- we just slop it up in OT_WHOLE_LINE mode.)
2851  *
2852  * Returns -1 if no line number is present, 0 on error, or a positive value
2853  * on success.
2854  */
2855 static int
2856 strip_lineno_from_funcdesc(char *func)
2857 {
2858         char       *c;
2859         int                     lineno;
2860
2861         if (!func || func[0] == '\0')
2862                 return -1;
2863
2864         c = func + strlen(func) - 1;
2865
2866         /*
2867          * This business of parsing backwards is dangerous as can be in a
2868          * multibyte environment: there is no reason to believe that we are
2869          * looking at the first byte of a character, nor are we necessarily
2870          * working in a "safe" encoding.  Fortunately the bitpatterns we are
2871          * looking for are unlikely to occur as non-first bytes, but beware of
2872          * trying to expand the set of cases that can be recognized.  We must
2873          * guard the <ctype.h> macros by using isascii() first, too.
2874          */
2875
2876         /* skip trailing whitespace */
2877         while (c > func && isascii((unsigned char) *c) && isspace((unsigned char) *c))
2878                 c--;
2879
2880         /* must have a digit as last non-space char */
2881         if (c == func || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
2882                 return -1;
2883
2884         /* find start of digit string */
2885         while (c > func && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
2886                 c--;
2887
2888         /* digits must be separated from func name by space or closing paren */
2889         /* notice also that we are not allowing an empty func name ... */
2890         if (c == func || !isascii((unsigned char) *c) ||
2891                 !(isspace((unsigned char) *c) || *c == ')'))
2892                 return -1;
2893
2894         /* parse digit string */
2895         c++;
2896         lineno = atoi(c);
2897         if (lineno < 1)
2898         {
2899                 psql_error("invalid line number: %s\n", c);
2900                 return 0;
2901         }
2902
2903         /* strip digit string from func */
2904         *c = '\0';
2905
2906         return lineno;
2907 }
2908
2909 /*
2910  * Report just the primary error; this is to avoid cluttering the output
2911  * with, for instance, a redisplay of the internally generated query
2912  */
2913 static void
2914 minimal_error_message(PGresult *res)
2915 {
2916         PQExpBuffer msg;
2917         const char *fld;
2918
2919         msg = createPQExpBuffer();
2920
2921         fld = PQresultErrorField(res, PG_DIAG_SEVERITY);
2922         if (fld)
2923                 printfPQExpBuffer(msg, "%s:  ", fld);
2924         else
2925                 printfPQExpBuffer(msg, "ERROR:  ");
2926         fld = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
2927         if (fld)
2928                 appendPQExpBufferStr(msg, fld);
2929         else
2930                 appendPQExpBufferStr(msg, "(not available)");
2931         appendPQExpBufferStr(msg, "\n");
2932
2933         psql_error("%s", msg->data);
2934
2935         destroyPQExpBuffer(msg);
2936 }