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