]> granicus.if.org Git - postgresql/blob - src/bin/pg_dump/pg_backup_archiver.c
pgindent run for 8.2.
[postgresql] / src / bin / pg_dump / pg_backup_archiver.c
1 /*-------------------------------------------------------------------------
2  *
3  * pg_backup_archiver.c
4  *
5  *      Private implementation of the archiver routines.
6  *
7  *      See the headers to pg_restore for more details.
8  *
9  * Copyright (c) 2000, Philip Warner
10  *      Rights are granted to use this software in any way so long
11  *      as this notice is not removed.
12  *
13  *      The author is not responsible for loss or damages that may
14  *      result from its use.
15  *
16  *
17  * IDENTIFICATION
18  *              $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.136 2006/10/04 00:30:05 momjian Exp $
19  *
20  *-------------------------------------------------------------------------
21  */
22
23 #include "pg_backup_db.h"
24 #include "dumputils.h"
25
26 #include <ctype.h>
27
28 #include <unistd.h>
29
30 #ifdef WIN32
31 #include <io.h>
32 #endif
33
34 #include "libpq/libpq-fs.h"
35 #include "mb/pg_wchar.h"
36
37
38 const char *progname;
39
40 static char *modulename = gettext_noop("archiver");
41
42
43 static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
44                  const int compression, ArchiveMode mode);
45 static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
46                                           ArchiveHandle *AH);
47 static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
48
49
50 static void _doSetFixedOutputState(ArchiveHandle *AH);
51 static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
52 static void _doSetWithOids(ArchiveHandle *AH, const bool withOids);
53 static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
54 static void _becomeUser(ArchiveHandle *AH, const char *user);
55 static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
56 static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
57 static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
58 static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
59 static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
60 static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls);
61 static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
62 static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
63 static TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id);
64 static void _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te);
65 static int      _discoverArchiveFormat(ArchiveHandle *AH);
66
67 static void dump_lo_buf(ArchiveHandle *AH);
68 static void _write_msg(const char *modulename, const char *fmt, va_list ap);
69 static void _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap);
70
71 static void dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim);
72 static OutputContext SetOutput(ArchiveHandle *AH, char *filename, int compression);
73 static void ResetOutput(ArchiveHandle *AH, OutputContext savedContext);
74
75
76 /*
77  *      Wrapper functions.
78  *
79  *      The objective it to make writing new formats and dumpers as simple
80  *      as possible, if necessary at the expense of extra function calls etc.
81  *
82  */
83
84
85 /* Create a new archive */
86 /* Public */
87 Archive *
88 CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
89                           const int compression)
90
91 {
92         ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, archModeWrite);
93
94         return (Archive *) AH;
95 }
96
97 /* Open an existing archive */
98 /* Public */
99 Archive *
100 OpenArchive(const char *FileSpec, const ArchiveFormat fmt)
101 {
102         ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, archModeRead);
103
104         return (Archive *) AH;
105 }
106
107 /* Public */
108 void
109 CloseArchive(Archive *AHX)
110 {
111         int                     res = 0;
112         ArchiveHandle *AH = (ArchiveHandle *) AHX;
113
114         (*AH->ClosePtr) (AH);
115
116         /* Close the output */
117         if (AH->gzOut)
118                 res = GZCLOSE(AH->OF);
119         else if (AH->OF != stdout)
120                 res = fclose(AH->OF);
121
122         if (res != 0)
123                 die_horribly(AH, modulename, "could not close output file: %s\n",
124                                          strerror(errno));
125 }
126
127 /* Public */
128 void
129 RestoreArchive(Archive *AHX, RestoreOptions *ropt)
130 {
131         ArchiveHandle *AH = (ArchiveHandle *) AHX;
132         TocEntry   *te;
133         teReqs          reqs;
134         OutputContext sav;
135         bool            defnDumped;
136
137         AH->ropt = ropt;
138         AH->stage = STAGE_INITIALIZING;
139
140         /*
141          * Check for nonsensical option combinations.
142          *
143          * NB: create+dropSchema is useless because if you're creating the DB,
144          * there's no need to drop individual items in it.  Moreover, if we tried
145          * to do that then we'd issue the drops in the database initially
146          * connected to, not the one we will create, which is very bad...
147          */
148         if (ropt->create && ropt->dropSchema)
149                 die_horribly(AH, modulename, "-C and -c are incompatible options\n");
150
151         /*
152          * If we're using a DB connection, then connect it.
153          */
154         if (ropt->useDB)
155         {
156                 ahlog(AH, 1, "connecting to database for restore\n");
157                 if (AH->version < K_VERS_1_3)
158                         die_horribly(AH, modulename, "direct database connections are not supported in pre-1.3 archives\n");
159
160                 /* XXX Should get this from the archive */
161                 AHX->minRemoteVersion = 070100;
162                 AHX->maxRemoteVersion = 999999;
163
164                 ConnectDatabase(AHX, ropt->dbname,
165                                                 ropt->pghost, ropt->pgport, ropt->username,
166                                                 ropt->requirePassword, ropt->ignoreVersion);
167
168                 /*
169                  * If we're talking to the DB directly, don't send comments since they
170                  * obscure SQL when displaying errors
171                  */
172                 AH->noTocComments = 1;
173         }
174
175         /*
176          * Work out if we have an implied data-only restore. This can happen if
177          * the dump was data only or if the user has used a toc list to exclude
178          * all of the schema data. All we do is look for schema entries - if none
179          * are found then we set the dataOnly flag.
180          *
181          * We could scan for wanted TABLE entries, but that is not the same as
182          * dataOnly. At this stage, it seems unnecessary (6-Mar-2001).
183          */
184         if (!ropt->dataOnly)
185         {
186                 int                     impliedDataOnly = 1;
187
188                 for (te = AH->toc->next; te != AH->toc; te = te->next)
189                 {
190                         reqs = _tocEntryRequired(te, ropt, true);
191                         if ((reqs & REQ_SCHEMA) != 0)
192                         {                                       /* It's schema, and it's wanted */
193                                 impliedDataOnly = 0;
194                                 break;
195                         }
196                 }
197                 if (impliedDataOnly)
198                 {
199                         ropt->dataOnly = impliedDataOnly;
200                         ahlog(AH, 1, "implied data-only restore\n");
201                 }
202         }
203
204         /*
205          * Setup the output file if necessary.
206          */
207         if (ropt->filename || ropt->compression)
208                 sav = SetOutput(AH, ropt->filename, ropt->compression);
209
210         ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
211
212         if (AH->public.verbose)
213                 dumpTimestamp(AH, "Started on", AH->createDate);
214
215         if (ropt->single_txn)
216         {
217                 if (AH->connection)
218                         StartTransaction(AH);
219                 else
220                         ahprintf(AH, "BEGIN;\n\n");
221         }
222
223         /*
224          * Establish important parameter values right away.
225          */
226         _doSetFixedOutputState(AH);
227
228         AH->stage = STAGE_PROCESSING;
229
230         /*
231          * Drop the items at the start, in reverse order
232          */
233         if (ropt->dropSchema)
234         {
235                 for (te = AH->toc->prev; te != AH->toc; te = te->prev)
236                 {
237                         AH->currentTE = te;
238
239                         reqs = _tocEntryRequired(te, ropt, false /* needn't drop ACLs */ );
240                         if (((reqs & REQ_SCHEMA) != 0) && te->dropStmt)
241                         {
242                                 /* We want the schema */
243                                 ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag);
244                                 /* Select owner and schema as necessary */
245                                 _becomeOwner(AH, te);
246                                 _selectOutputSchema(AH, te->namespace);
247                                 /* Drop it */
248                                 ahprintf(AH, "%s", te->dropStmt);
249                         }
250                 }
251         }
252
253         /*
254          * Now process each non-ACL TOC entry
255          */
256         for (te = AH->toc->next; te != AH->toc; te = te->next)
257         {
258                 AH->currentTE = te;
259
260                 /* Work out what, if anything, we want from this entry */
261                 reqs = _tocEntryRequired(te, ropt, false);
262
263                 /* Dump any relevant dump warnings to stderr */
264                 if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0)
265                 {
266                         if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0)
267                                 write_msg(modulename, "warning from original dump file: %s\n", te->defn);
268                         else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0)
269                                 write_msg(modulename, "warning from original dump file: %s\n", te->copyStmt);
270                 }
271
272                 defnDumped = false;
273
274                 if ((reqs & REQ_SCHEMA) != 0)   /* We want the schema */
275                 {
276                         ahlog(AH, 1, "creating %s %s\n", te->desc, te->tag);
277
278                         _printTocEntry(AH, te, ropt, false, false);
279                         defnDumped = true;
280
281                         /*
282                          * If we could not create a table, ignore the respective TABLE
283                          * DATA if -X no-data-for-failed-tables is given
284                          */
285                         if (ropt->noDataForFailedTables && AH->lastErrorTE == te && strcmp(te->desc, "TABLE") == 0)
286                         {
287                                 TocEntry   *tes,
288                                                    *last;
289
290                                 ahlog(AH, 1, "table %s could not be created, will not restore its data\n", te->tag);
291
292                                 for (last = te, tes = te->next; tes != AH->toc; last = tes, tes = tes->next)
293                                 {
294                                         if (strcmp(tes->desc, "TABLE DATA") == 0 && strcmp(tes->tag, te->tag) == 0 &&
295                                                 strcmp(tes->namespace ? tes->namespace : "", te->namespace ? te->namespace : "") == 0)
296                                         {
297                                                 /* remove this node */
298                                                 last->next = tes->next;
299                                                 break;
300                                         }
301                                 }
302                         }
303
304                         /* If we created a DB, connect to it... */
305                         if (strcmp(te->desc, "DATABASE") == 0)
306                         {
307                                 ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag);
308                                 _reconnectToDB(AH, te->tag);
309                         }
310                 }
311
312                 /*
313                  * If we have a data component, then process it
314                  */
315                 if ((reqs & REQ_DATA) != 0)
316                 {
317                         /*
318                          * hadDumper will be set if there is genuine data component for
319                          * this node. Otherwise, we need to check the defn field for
320                          * statements that need to be executed in data-only restores.
321                          */
322                         if (te->hadDumper)
323                         {
324                                 /*
325                                  * If we can output the data, then restore it.
326                                  */
327                                 if (AH->PrintTocDataPtr !=NULL && (reqs & REQ_DATA) != 0)
328                                 {
329 #ifndef HAVE_LIBZ
330                                         if (AH->compression != 0)
331                                                 die_horribly(AH, modulename, "cannot restore from compressed archive (compression not supported in this installation)\n");
332 #endif
333
334                                         _printTocEntry(AH, te, ropt, true, false);
335
336                                         if (strcmp(te->desc, "BLOBS") == 0 ||
337                                                 strcmp(te->desc, "BLOB COMMENTS") == 0)
338                                         {
339                                                 ahlog(AH, 1, "restoring %s\n", te->desc);
340
341                                                 _selectOutputSchema(AH, "pg_catalog");
342
343                                                 (*AH->PrintTocDataPtr) (AH, te, ropt);
344                                         }
345                                         else
346                                         {
347                                                 _disableTriggersIfNecessary(AH, te, ropt);
348
349                                                 /* Select owner and schema as necessary */
350                                                 _becomeOwner(AH, te);
351                                                 _selectOutputSchema(AH, te->namespace);
352
353                                                 ahlog(AH, 1, "restoring data for table \"%s\"\n",
354                                                           te->tag);
355
356                                                 /*
357                                                  * If we have a copy statement, use it. As of V1.3,
358                                                  * these are separate to allow easy import from
359                                                  * withing a database connection. Pre 1.3 archives can
360                                                  * not use DB connections and are sent to output only.
361                                                  *
362                                                  * For V1.3+, the table data MUST have a copy
363                                                  * statement so that we can go into appropriate mode
364                                                  * with libpq.
365                                                  */
366                                                 if (te->copyStmt && strlen(te->copyStmt) > 0)
367                                                 {
368                                                         ahprintf(AH, "%s", te->copyStmt);
369                                                         AH->writingCopyData = true;
370                                                 }
371
372                                                 (*AH->PrintTocDataPtr) (AH, te, ropt);
373
374                                                 AH->writingCopyData = false;
375
376                                                 _enableTriggersIfNecessary(AH, te, ropt);
377                                         }
378                                 }
379                         }
380                         else if (!defnDumped)
381                         {
382                                 /* If we haven't already dumped the defn part, do so now */
383                                 ahlog(AH, 1, "executing %s %s\n", te->desc, te->tag);
384                                 _printTocEntry(AH, te, ropt, false, false);
385                         }
386                 }
387         }                                                       /* end loop over TOC entries */
388
389         /*
390          * Scan TOC again to output ownership commands and ACLs
391          */
392         for (te = AH->toc->next; te != AH->toc; te = te->next)
393         {
394                 AH->currentTE = te;
395
396                 /* Work out what, if anything, we want from this entry */
397                 reqs = _tocEntryRequired(te, ropt, true);
398
399                 if ((reqs & REQ_SCHEMA) != 0)   /* We want the schema */
400                 {
401                         ahlog(AH, 1, "setting owner and privileges for %s %s\n",
402                                   te->desc, te->tag);
403                         _printTocEntry(AH, te, ropt, false, true);
404                 }
405         }
406
407         if (ropt->single_txn)
408         {
409                 if (AH->connection)
410                         CommitTransaction(AH);
411                 else
412                         ahprintf(AH, "COMMIT;\n\n");
413         }
414
415         if (AH->public.verbose)
416                 dumpTimestamp(AH, "Completed on", time(NULL));
417
418         ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n");
419
420         /*
421          * Clean up & we're done.
422          */
423         AH->stage = STAGE_FINALIZING;
424
425         if (ropt->filename || ropt->compression)
426                 ResetOutput(AH, sav);
427
428         if (ropt->useDB)
429         {
430                 PQfinish(AH->connection);
431                 AH->connection = NULL;
432         }
433 }
434
435 /*
436  * Allocate a new RestoreOptions block.
437  * This is mainly so we can initialize it, but also for future expansion,
438  */
439 RestoreOptions *
440 NewRestoreOptions(void)
441 {
442         RestoreOptions *opts;
443
444         opts = (RestoreOptions *) calloc(1, sizeof(RestoreOptions));
445
446         opts->format = archUnknown;
447         opts->suppressDumpWarnings = false;
448         opts->exit_on_error = false;
449
450         return opts;
451 }
452
453 static void
454 _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
455 {
456         /* This hack is only needed in a data-only restore */
457         if (!ropt->dataOnly || !ropt->disable_triggers)
458                 return;
459
460         ahlog(AH, 1, "disabling triggers for %s\n", te->tag);
461
462         /*
463          * Become superuser if possible, since they are the only ones who can
464          * disable constraint triggers.  If -S was not given, assume the initial
465          * user identity is a superuser.  (XXX would it be better to become the
466          * table owner?)
467          */
468         _becomeUser(AH, ropt->superuser);
469
470         /*
471          * Disable them.
472          */
473         _selectOutputSchema(AH, te->namespace);
474
475         ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
476                          fmtId(te->tag));
477 }
478
479 static void
480 _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
481 {
482         /* This hack is only needed in a data-only restore */
483         if (!ropt->dataOnly || !ropt->disable_triggers)
484                 return;
485
486         ahlog(AH, 1, "enabling triggers for %s\n", te->tag);
487
488         /*
489          * Become superuser if possible, since they are the only ones who can
490          * disable constraint triggers.  If -S was not given, assume the initial
491          * user identity is a superuser.  (XXX would it be better to become the
492          * table owner?)
493          */
494         _becomeUser(AH, ropt->superuser);
495
496         /*
497          * Enable them.
498          */
499         _selectOutputSchema(AH, te->namespace);
500
501         ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
502                          fmtId(te->tag));
503 }
504
505 /*
506  * This is a routine that is part of the dumper interface, hence the 'Archive*' parameter.
507  */
508
509 /* Public */
510 size_t
511 WriteData(Archive *AHX, const void *data, size_t dLen)
512 {
513         ArchiveHandle *AH = (ArchiveHandle *) AHX;
514
515         if (!AH->currToc)
516                 die_horribly(AH, modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
517
518         return (*AH->WriteDataPtr) (AH, data, dLen);
519 }
520
521 /*
522  * Create a new TOC entry. The TOC was designed as a TOC, but is now the
523  * repository for all metadata. But the name has stuck.
524  */
525
526 /* Public */
527 void
528 ArchiveEntry(Archive *AHX,
529                          CatalogId catalogId, DumpId dumpId,
530                          const char *tag,
531                          const char *namespace,
532                          const char *tablespace,
533                          const char *owner, bool withOids,
534                          const char *desc, const char *defn,
535                          const char *dropStmt, const char *copyStmt,
536                          const DumpId *deps, int nDeps,
537                          DataDumperPtr dumpFn, void *dumpArg)
538 {
539         ArchiveHandle *AH = (ArchiveHandle *) AHX;
540         TocEntry   *newToc;
541
542         newToc = (TocEntry *) calloc(1, sizeof(TocEntry));
543         if (!newToc)
544                 die_horribly(AH, modulename, "out of memory\n");
545
546         AH->tocCount++;
547         if (dumpId > AH->maxDumpId)
548                 AH->maxDumpId = dumpId;
549
550         newToc->prev = AH->toc->prev;
551         newToc->next = AH->toc;
552         AH->toc->prev->next = newToc;
553         AH->toc->prev = newToc;
554
555         newToc->catalogId = catalogId;
556         newToc->dumpId = dumpId;
557
558         newToc->tag = strdup(tag);
559         newToc->namespace = namespace ? strdup(namespace) : NULL;
560         newToc->tablespace = tablespace ? strdup(tablespace) : NULL;
561         newToc->owner = strdup(owner);
562         newToc->withOids = withOids;
563         newToc->desc = strdup(desc);
564         newToc->defn = strdup(defn);
565         newToc->dropStmt = strdup(dropStmt);
566         newToc->copyStmt = copyStmt ? strdup(copyStmt) : NULL;
567
568         if (nDeps > 0)
569         {
570                 newToc->dependencies = (DumpId *) malloc(nDeps * sizeof(DumpId));
571                 memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
572                 newToc->nDeps = nDeps;
573         }
574         else
575         {
576                 newToc->dependencies = NULL;
577                 newToc->nDeps = 0;
578         }
579
580         newToc->dataDumper = dumpFn;
581         newToc->dataDumperArg = dumpArg;
582         newToc->hadDumper = dumpFn ? true : false;
583
584         newToc->formatData = NULL;
585
586         if (AH->ArchiveEntryPtr !=NULL)
587                 (*AH->ArchiveEntryPtr) (AH, newToc);
588 }
589
590 /* Public */
591 void
592 PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
593 {
594         ArchiveHandle *AH = (ArchiveHandle *) AHX;
595         TocEntry   *te = AH->toc->next;
596         OutputContext sav;
597         char       *fmtName;
598
599         if (ropt->filename)
600                 sav = SetOutput(AH, ropt->filename, 0 /* no compression */ );
601
602         ahprintf(AH, ";\n; Archive created at %s", ctime(&AH->createDate));
603         ahprintf(AH, ";     dbname: %s\n;     TOC Entries: %d\n;     Compression: %d\n",
604                          AH->archdbname, AH->tocCount, AH->compression);
605
606         switch (AH->format)
607         {
608                 case archFiles:
609                         fmtName = "FILES";
610                         break;
611                 case archCustom:
612                         fmtName = "CUSTOM";
613                         break;
614                 case archTar:
615                         fmtName = "TAR";
616                         break;
617                 default:
618                         fmtName = "UNKNOWN";
619         }
620
621         ahprintf(AH, ";     Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev);
622         ahprintf(AH, ";     Format: %s\n", fmtName);
623         ahprintf(AH, ";     Integer: %d bytes\n", (int) AH->intSize);
624         ahprintf(AH, ";     Offset: %d bytes\n", (int) AH->offSize);
625         if (AH->archiveRemoteVersion)
626                 ahprintf(AH, ";     Dumped from database version: %s\n",
627                                  AH->archiveRemoteVersion);
628         if (AH->archiveDumpVersion)
629                 ahprintf(AH, ";     Dumped by pg_dump version: %s\n",
630                                  AH->archiveDumpVersion);
631
632         ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
633
634         while (te != AH->toc)
635         {
636                 if (_tocEntryRequired(te, ropt, true) != 0)
637                         ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
638                                          te->catalogId.tableoid, te->catalogId.oid,
639                                          te->desc, te->namespace ? te->namespace : "-",
640                                          te->tag, te->owner);
641                 te = te->next;
642         }
643
644         if (ropt->filename)
645                 ResetOutput(AH, sav);
646 }
647
648 /***********
649  * BLOB Archival
650  ***********/
651
652 /* Called by a dumper to signal start of a BLOB */
653 int
654 StartBlob(Archive *AHX, Oid oid)
655 {
656         ArchiveHandle *AH = (ArchiveHandle *) AHX;
657
658         if (!AH->StartBlobPtr)
659                 die_horribly(AH, modulename, "large-object output not supported in chosen format\n");
660
661         (*AH->StartBlobPtr) (AH, AH->currToc, oid);
662
663         return 1;
664 }
665
666 /* Called by a dumper to signal end of a BLOB */
667 int
668 EndBlob(Archive *AHX, Oid oid)
669 {
670         ArchiveHandle *AH = (ArchiveHandle *) AHX;
671
672         if (AH->EndBlobPtr)
673                 (*AH->EndBlobPtr) (AH, AH->currToc, oid);
674
675         return 1;
676 }
677
678 /**********
679  * BLOB Restoration
680  **********/
681
682 /*
683  * Called by a format handler before any blobs are restored
684  */
685 void
686 StartRestoreBlobs(ArchiveHandle *AH)
687 {
688         if (!AH->ropt->single_txn)
689         {
690                 if (AH->connection)
691                         StartTransaction(AH);
692                 else
693                         ahprintf(AH, "BEGIN;\n\n");
694         }
695
696         AH->blobCount = 0;
697 }
698
699 /*
700  * Called by a format handler after all blobs are restored
701  */
702 void
703 EndRestoreBlobs(ArchiveHandle *AH)
704 {
705         if (!AH->ropt->single_txn)
706         {
707                 if (AH->connection)
708                         CommitTransaction(AH);
709                 else
710                         ahprintf(AH, "COMMIT;\n\n");
711         }
712
713         ahlog(AH, 1, "restored %d large objects\n", AH->blobCount);
714 }
715
716
717 /*
718  * Called by a format handler to initiate restoration of a blob
719  */
720 void
721 StartRestoreBlob(ArchiveHandle *AH, Oid oid)
722 {
723         Oid                     loOid;
724
725         AH->blobCount++;
726
727         /* Initialize the LO Buffer */
728         AH->lo_buf_used = 0;
729
730         ahlog(AH, 2, "restoring large object with OID %u\n", oid);
731
732         if (AH->connection)
733         {
734                 loOid = lo_create(AH->connection, oid);
735                 if (loOid == 0 || loOid != oid)
736                         die_horribly(AH, modulename, "could not create large object %u\n",
737                                                  oid);
738
739                 AH->loFd = lo_open(AH->connection, oid, INV_WRITE);
740                 if (AH->loFd == -1)
741                         die_horribly(AH, modulename, "could not open large object\n");
742         }
743         else
744         {
745                 ahprintf(AH, "SELECT lo_open(lo_create(%u), %d);\n", oid, INV_WRITE);
746         }
747
748         AH->writingBlob = 1;
749 }
750
751 void
752 EndRestoreBlob(ArchiveHandle *AH, Oid oid)
753 {
754         if (AH->lo_buf_used > 0)
755         {
756                 /* Write remaining bytes from the LO buffer */
757                 dump_lo_buf(AH);
758         }
759
760         AH->writingBlob = 0;
761
762         if (AH->connection)
763         {
764                 lo_close(AH->connection, AH->loFd);
765                 AH->loFd = -1;
766         }
767         else
768         {
769                 ahprintf(AH, "SELECT lo_close(0);\n\n");
770         }
771 }
772
773 /***********
774  * Sorting and Reordering
775  ***********/
776
777 void
778 SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
779 {
780         ArchiveHandle *AH = (ArchiveHandle *) AHX;
781         FILE       *fh;
782         char            buf[1024];
783         char       *cmnt;
784         char       *endptr;
785         DumpId          id;
786         TocEntry   *te;
787         TocEntry   *tePrev;
788
789         /* Allocate space for the 'wanted' array, and init it */
790         ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
791         memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId);
792         ropt->limitToList = true;
793
794         /* Set prev entry as head of list */
795         tePrev = AH->toc;
796
797         /* Setup the file */
798         fh = fopen(ropt->tocFile, PG_BINARY_R);
799         if (!fh)
800                 die_horribly(AH, modulename, "could not open TOC file: %s\n",
801                                          strerror(errno));
802
803         while (fgets(buf, sizeof(buf), fh) != NULL)
804         {
805                 /* Truncate line at comment, if any */
806                 cmnt = strchr(buf, ';');
807                 if (cmnt != NULL)
808                         cmnt[0] = '\0';
809
810                 /* Ignore if all blank */
811                 if (strspn(buf, " \t\r") == strlen(buf))
812                         continue;
813
814                 /* Get an ID, check it's valid and not already seen */
815                 id = strtol(buf, &endptr, 10);
816                 if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
817                         ropt->idWanted[id - 1])
818                 {
819                         write_msg(modulename, "WARNING: line ignored: %s\n", buf);
820                         continue;
821                 }
822
823                 /* Find TOC entry */
824                 te = getTocEntryByDumpId(AH, id);
825                 if (!te)
826                         die_horribly(AH, modulename, "could not find entry for ID %d\n",
827                                                  id);
828
829                 ropt->idWanted[id - 1] = true;
830
831                 _moveAfter(AH, tePrev, te);
832                 tePrev = te;
833         }
834
835         if (fclose(fh) != 0)
836                 die_horribly(AH, modulename, "could not close TOC file: %s\n",
837                                          strerror(errno));
838 }
839
840 /**********************
841  * 'Convenience functions that look like standard IO functions
842  * for writing data when in dump mode.
843  **********************/
844
845 /* Public */
846 int
847 archputs(const char *s, Archive *AH)
848 {
849         return WriteData(AH, s, strlen(s));
850 }
851
852 /* Public */
853 int
854 archprintf(Archive *AH, const char *fmt,...)
855 {
856         char       *p = NULL;
857         va_list         ap;
858         int                     bSize = strlen(fmt) + 256;
859         int                     cnt = -1;
860
861         /*
862          * This is paranoid: deal with the possibility that vsnprintf is willing
863          * to ignore trailing null or returns > 0 even if string does not fit. It
864          * may be the case that it returns cnt = bufsize
865          */
866         while (cnt < 0 || cnt >= (bSize - 1))
867         {
868                 if (p != NULL)
869                         free(p);
870                 bSize *= 2;
871                 p = (char *) malloc(bSize);
872                 if (p == NULL)
873                         exit_horribly(AH, modulename, "out of memory\n");
874                 va_start(ap, fmt);
875                 cnt = vsnprintf(p, bSize, fmt, ap);
876                 va_end(ap);
877         }
878         WriteData(AH, p, cnt);
879         free(p);
880         return cnt;
881 }
882
883
884 /*******************************
885  * Stuff below here should be 'private' to the archiver routines
886  *******************************/
887
888 static OutputContext
889 SetOutput(ArchiveHandle *AH, char *filename, int compression)
890 {
891         OutputContext sav;
892         int                     fn;
893
894         /* Replace the AH output file handle */
895         sav.OF = AH->OF;
896         sav.gzOut = AH->gzOut;
897
898         if (filename)
899                 fn = -1;
900         else if (AH->FH)
901                 fn = fileno(AH->FH);
902         else if (AH->fSpec)
903         {
904                 fn = -1;
905                 filename = AH->fSpec;
906         }
907         else
908                 fn = fileno(stdout);
909
910         /* If compression explicitly requested, use gzopen */
911 #ifdef HAVE_LIBZ
912         if (compression != 0)
913         {
914                 char            fmode[10];
915
916                 /* Don't use PG_BINARY_x since this is zlib */
917                 sprintf(fmode, "wb%d", compression);
918                 if (fn >= 0)
919                         AH->OF = gzdopen(dup(fn), fmode);
920                 else
921                         AH->OF = gzopen(filename, fmode);
922                 AH->gzOut = 1;
923         }
924         else
925 #endif
926         {                                                       /* Use fopen */
927                 if (fn >= 0)
928                         AH->OF = fdopen(dup(fn), PG_BINARY_W);
929                 else
930                         AH->OF = fopen(filename, PG_BINARY_W);
931                 AH->gzOut = 0;
932         }
933
934         if (!AH->OF)
935                 die_horribly(AH, modulename, "could not open output file: %s\n", strerror(errno));
936
937         return sav;
938 }
939
940 static void
941 ResetOutput(ArchiveHandle *AH, OutputContext sav)
942 {
943         int                     res;
944
945         if (AH->gzOut)
946                 res = GZCLOSE(AH->OF);
947         else
948                 res = fclose(AH->OF);
949
950         if (res != 0)
951                 die_horribly(AH, modulename, "could not close output file: %s\n",
952                                          strerror(errno));
953
954         AH->gzOut = sav.gzOut;
955         AH->OF = sav.OF;
956 }
957
958
959
960 /*
961  *      Print formatted text to the output file (usually stdout).
962  */
963 int
964 ahprintf(ArchiveHandle *AH, const char *fmt,...)
965 {
966         char       *p = NULL;
967         va_list         ap;
968         int                     bSize = strlen(fmt) + 256;              /* Should be enough */
969         int                     cnt = -1;
970
971         /*
972          * This is paranoid: deal with the possibility that vsnprintf is willing
973          * to ignore trailing null
974          */
975
976         /*
977          * or returns > 0 even if string does not fit. It may be the case that it
978          * returns cnt = bufsize
979          */
980         while (cnt < 0 || cnt >= (bSize - 1))
981         {
982                 if (p != NULL)
983                         free(p);
984                 bSize *= 2;
985                 p = (char *) malloc(bSize);
986                 if (p == NULL)
987                         die_horribly(AH, modulename, "out of memory\n");
988                 va_start(ap, fmt);
989                 cnt = vsnprintf(p, bSize, fmt, ap);
990                 va_end(ap);
991         }
992         ahwrite(p, 1, cnt, AH);
993         free(p);
994         return cnt;
995 }
996
997 void
998 ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
999 {
1000         va_list         ap;
1001
1002         if (AH->debugLevel < level && (!AH->public.verbose || level > 1))
1003                 return;
1004
1005         va_start(ap, fmt);
1006         _write_msg(NULL, fmt, ap);
1007         va_end(ap);
1008 }
1009
1010 /*
1011  * Single place for logic which says 'We are restoring to a direct DB connection'.
1012  */
1013 static int
1014 RestoringToDB(ArchiveHandle *AH)
1015 {
1016         return (AH->ropt && AH->ropt->useDB && AH->connection);
1017 }
1018
1019 /*
1020  * Dump the current contents of the LO data buffer while writing a BLOB
1021  */
1022 static void
1023 dump_lo_buf(ArchiveHandle *AH)
1024 {
1025         if (AH->connection)
1026         {
1027                 size_t          res;
1028
1029                 res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1030                 ahlog(AH, 5, "wrote %lu bytes of large object data (result = %lu)\n",
1031                           (unsigned long) AH->lo_buf_used, (unsigned long) res);
1032                 if (res != AH->lo_buf_used)
1033                         die_horribly(AH, modulename,
1034                         "could not write to large object (result: %lu, expected: %lu)\n",
1035                                            (unsigned long) res, (unsigned long) AH->lo_buf_used);
1036         }
1037         else
1038         {
1039                 unsigned char *str;
1040                 size_t          len;
1041
1042                 str = PQescapeBytea((const unsigned char *) AH->lo_buf,
1043                                                         AH->lo_buf_used, &len);
1044                 if (!str)
1045                         die_horribly(AH, modulename, "out of memory\n");
1046
1047                 /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1048                 AH->writingBlob = 0;
1049                 ahprintf(AH, "SELECT lowrite(0, '%s');\n", str);
1050                 AH->writingBlob = 1;
1051
1052                 free(str);
1053         }
1054         AH->lo_buf_used = 0;
1055 }
1056
1057
1058 /*
1059  *      Write buffer to the output file (usually stdout). This is user for
1060  *      outputting 'restore' scripts etc. It is even possible for an archive
1061  *      format to create a custom output routine to 'fake' a restore if it
1062  *      wants to generate a script (see TAR output).
1063  */
1064 int
1065 ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
1066 {
1067         size_t          res;
1068
1069         if (AH->writingBlob)
1070         {
1071                 size_t          remaining = size * nmemb;
1072
1073                 while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1074                 {
1075                         size_t          avail = AH->lo_buf_size - AH->lo_buf_used;
1076
1077                         memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1078                         ptr = (const void *) ((const char *) ptr + avail);
1079                         remaining -= avail;
1080                         AH->lo_buf_used += avail;
1081                         dump_lo_buf(AH);
1082                 }
1083
1084                 memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1085                 AH->lo_buf_used += remaining;
1086
1087                 return size * nmemb;
1088         }
1089         else if (AH->gzOut)
1090         {
1091                 res = GZWRITE((void *) ptr, size, nmemb, AH->OF);
1092                 if (res != (nmemb * size))
1093                         die_horribly(AH, modulename, "could not write to output file: %s\n", strerror(errno));
1094                 return res;
1095         }
1096         else if (AH->CustomOutPtr)
1097         {
1098                 res = AH->CustomOutPtr (AH, ptr, size * nmemb);
1099
1100                 if (res != (nmemb * size))
1101                         die_horribly(AH, modulename, "could not write to custom output routine\n");
1102                 return res;
1103         }
1104         else
1105         {
1106                 /*
1107                  * If we're doing a restore, and it's direct to DB, and we're
1108                  * connected then send it to the DB.
1109                  */
1110                 if (RestoringToDB(AH))
1111                         return ExecuteSqlCommandBuf(AH, (void *) ptr, size * nmemb);            /* Always 1, currently */
1112                 else
1113                 {
1114                         res = fwrite((void *) ptr, size, nmemb, AH->OF);
1115                         if (res != nmemb)
1116                                 die_horribly(AH, modulename, "could not write to output file: %s\n",
1117                                                          strerror(errno));
1118                         return res;
1119                 }
1120         }
1121 }
1122
1123 /* Common exit code */
1124 static void
1125 _write_msg(const char *modulename, const char *fmt, va_list ap)
1126 {
1127         if (modulename)
1128                 fprintf(stderr, "%s: [%s] ", progname, _(modulename));
1129         else
1130                 fprintf(stderr, "%s: ", progname);
1131         vfprintf(stderr, _(fmt), ap);
1132 }
1133
1134 void
1135 write_msg(const char *modulename, const char *fmt,...)
1136 {
1137         va_list         ap;
1138
1139         va_start(ap, fmt);
1140         _write_msg(modulename, fmt, ap);
1141         va_end(ap);
1142 }
1143
1144
1145 static void
1146 _die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap)
1147 {
1148         _write_msg(modulename, fmt, ap);
1149
1150         if (AH)
1151         {
1152                 if (AH->public.verbose)
1153                         write_msg(NULL, "*** aborted because of error\n");
1154                 if (AH->connection)
1155                         PQfinish(AH->connection);
1156         }
1157
1158         exit(1);
1159 }
1160
1161 /* External use */
1162 void
1163 exit_horribly(Archive *AH, const char *modulename, const char *fmt,...)
1164 {
1165         va_list         ap;
1166
1167         va_start(ap, fmt);
1168         _die_horribly((ArchiveHandle *) AH, modulename, fmt, ap);
1169         va_end(ap);
1170 }
1171
1172 /* Archiver use (just different arg declaration) */
1173 void
1174 die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
1175 {
1176         va_list         ap;
1177
1178         va_start(ap, fmt);
1179         _die_horribly(AH, modulename, fmt, ap);
1180         va_end(ap);
1181 }
1182
1183 /* on some error, we may decide to go on... */
1184 void
1185 warn_or_die_horribly(ArchiveHandle *AH,
1186                                          const char *modulename, const char *fmt,...)
1187 {
1188         va_list         ap;
1189
1190         switch (AH->stage)
1191         {
1192
1193                 case STAGE_NONE:
1194                         /* Do nothing special */
1195                         break;
1196
1197                 case STAGE_INITIALIZING:
1198                         if (AH->stage != AH->lastErrorStage)
1199                                 write_msg(modulename, "Error while INITIALIZING:\n");
1200                         break;
1201
1202                 case STAGE_PROCESSING:
1203                         if (AH->stage != AH->lastErrorStage)
1204                                 write_msg(modulename, "Error while PROCESSING TOC:\n");
1205                         break;
1206
1207                 case STAGE_FINALIZING:
1208                         if (AH->stage != AH->lastErrorStage)
1209                                 write_msg(modulename, "Error while FINALIZING:\n");
1210                         break;
1211         }
1212         if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE)
1213         {
1214                 write_msg(modulename, "Error from TOC entry %d; %u %u %s %s %s\n",
1215                                   AH->currentTE->dumpId,
1216                          AH->currentTE->catalogId.tableoid, AH->currentTE->catalogId.oid,
1217                           AH->currentTE->desc, AH->currentTE->tag, AH->currentTE->owner);
1218         }
1219         AH->lastErrorStage = AH->stage;
1220         AH->lastErrorTE = AH->currentTE;
1221
1222         va_start(ap, fmt);
1223         if (AH->public.exit_on_error)
1224                 _die_horribly(AH, modulename, fmt, ap);
1225         else
1226         {
1227                 _write_msg(modulename, fmt, ap);
1228                 AH->public.n_errors++;
1229         }
1230         va_end(ap);
1231 }
1232
1233 static void
1234 _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
1235 {
1236         te->prev->next = te->next;
1237         te->next->prev = te->prev;
1238
1239         te->prev = pos;
1240         te->next = pos->next;
1241
1242         pos->next->prev = te;
1243         pos->next = te;
1244 }
1245
1246 #ifdef NOT_USED
1247
1248 static void
1249 _moveBefore(ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
1250 {
1251         te->prev->next = te->next;
1252         te->next->prev = te->prev;
1253
1254         te->prev = pos->prev;
1255         te->next = pos;
1256         pos->prev->next = te;
1257         pos->prev = te;
1258 }
1259 #endif
1260
1261 static TocEntry *
1262 getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
1263 {
1264         TocEntry   *te;
1265
1266         te = AH->toc->next;
1267         while (te != AH->toc)
1268         {
1269                 if (te->dumpId == id)
1270                         return te;
1271                 te = te->next;
1272         }
1273         return NULL;
1274 }
1275
1276 teReqs
1277 TocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt)
1278 {
1279         TocEntry   *te = getTocEntryByDumpId(AH, id);
1280
1281         if (!te)
1282                 return 0;
1283
1284         return _tocEntryRequired(te, ropt, true);
1285 }
1286
1287 size_t
1288 WriteOffset(ArchiveHandle *AH, off_t o, int wasSet)
1289 {
1290         int                     off;
1291
1292         /* Save the flag */
1293         (*AH->WriteBytePtr) (AH, wasSet);
1294
1295         /* Write out off_t smallest byte first, prevents endian mismatch */
1296         for (off = 0; off < sizeof(off_t); off++)
1297         {
1298                 (*AH->WriteBytePtr) (AH, o & 0xFF);
1299                 o >>= 8;
1300         }
1301         return sizeof(off_t) + 1;
1302 }
1303
1304 int
1305 ReadOffset(ArchiveHandle *AH, off_t *o)
1306 {
1307         int                     i;
1308         int                     off;
1309         int                     offsetFlg;
1310
1311         /* Initialize to zero */
1312         *o = 0;
1313
1314         /* Check for old version */
1315         if (AH->version < K_VERS_1_7)
1316         {
1317                 /* Prior versions wrote offsets using WriteInt */
1318                 i = ReadInt(AH);
1319                 /* -1 means not set */
1320                 if (i < 0)
1321                         return K_OFFSET_POS_NOT_SET;
1322                 else if (i == 0)
1323                         return K_OFFSET_NO_DATA;
1324
1325                 /* Cast to off_t because it was written as an int. */
1326                 *o = (off_t) i;
1327                 return K_OFFSET_POS_SET;
1328         }
1329
1330         /*
1331          * Read the flag indicating the state of the data pointer. Check if valid
1332          * and die if not.
1333          *
1334          * This used to be handled by a negative or zero pointer, now we use an
1335          * extra byte specifically for the state.
1336          */
1337         offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;
1338
1339         switch (offsetFlg)
1340         {
1341                 case K_OFFSET_POS_NOT_SET:
1342                 case K_OFFSET_NO_DATA:
1343                 case K_OFFSET_POS_SET:
1344
1345                         break;
1346
1347                 default:
1348                         die_horribly(AH, modulename, "unexpected data offset flag %d\n", offsetFlg);
1349         }
1350
1351         /*
1352          * Read the bytes
1353          */
1354         for (off = 0; off < AH->offSize; off++)
1355         {
1356                 if (off < sizeof(off_t))
1357                         *o |= ((off_t) ((*AH->ReadBytePtr) (AH))) << (off * 8);
1358                 else
1359                 {
1360                         if ((*AH->ReadBytePtr) (AH) != 0)
1361                                 die_horribly(AH, modulename, "file offset in dump file is too large\n");
1362                 }
1363         }
1364
1365         return offsetFlg;
1366 }
1367
1368 size_t
1369 WriteInt(ArchiveHandle *AH, int i)
1370 {
1371         int                     b;
1372
1373         /*
1374          * This is a bit yucky, but I don't want to make the binary format very
1375          * dependent on representation, and not knowing much about it, I write out
1376          * a sign byte. If you change this, don't forget to change the file
1377          * version #, and modify readInt to read the new format AS WELL AS the old
1378          * formats.
1379          */
1380
1381         /* SIGN byte */
1382         if (i < 0)
1383         {
1384                 (*AH->WriteBytePtr) (AH, 1);
1385                 i = -i;
1386         }
1387         else
1388                 (*AH->WriteBytePtr) (AH, 0);
1389
1390         for (b = 0; b < AH->intSize; b++)
1391         {
1392                 (*AH->WriteBytePtr) (AH, i & 0xFF);
1393                 i >>= 8;
1394         }
1395
1396         return AH->intSize + 1;
1397 }
1398
1399 int
1400 ReadInt(ArchiveHandle *AH)
1401 {
1402         int                     res = 0;
1403         int                     bv,
1404                                 b;
1405         int                     sign = 0;               /* Default positive */
1406         int                     bitShift = 0;
1407
1408         if (AH->version > K_VERS_1_0)
1409                 /* Read a sign byte */
1410                 sign = (*AH->ReadBytePtr) (AH);
1411
1412         for (b = 0; b < AH->intSize; b++)
1413         {
1414                 bv = (*AH->ReadBytePtr) (AH) & 0xFF;
1415                 if (bv != 0)
1416                         res = res + (bv << bitShift);
1417                 bitShift += 8;
1418         }
1419
1420         if (sign)
1421                 res = -res;
1422
1423         return res;
1424 }
1425
1426 size_t
1427 WriteStr(ArchiveHandle *AH, const char *c)
1428 {
1429         size_t          res;
1430
1431         if (c)
1432         {
1433                 res = WriteInt(AH, strlen(c));
1434                 res += (*AH->WriteBufPtr) (AH, c, strlen(c));
1435         }
1436         else
1437                 res = WriteInt(AH, -1);
1438
1439         return res;
1440 }
1441
1442 char *
1443 ReadStr(ArchiveHandle *AH)
1444 {
1445         char       *buf;
1446         int                     l;
1447
1448         l = ReadInt(AH);
1449         if (l == -1)
1450                 buf = NULL;
1451         else
1452         {
1453                 buf = (char *) malloc(l + 1);
1454                 if (!buf)
1455                         die_horribly(AH, modulename, "out of memory\n");
1456
1457                 (*AH->ReadBufPtr) (AH, (void *) buf, l);
1458                 buf[l] = '\0';
1459         }
1460
1461         return buf;
1462 }
1463
1464 static int
1465 _discoverArchiveFormat(ArchiveHandle *AH)
1466 {
1467         FILE       *fh;
1468         char            sig[6];                 /* More than enough */
1469         size_t          cnt;
1470         int                     wantClose = 0;
1471
1472 #if 0
1473         write_msg(modulename, "attempting to ascertain archive format\n");
1474 #endif
1475
1476         if (AH->lookahead)
1477                 free(AH->lookahead);
1478
1479         AH->lookaheadSize = 512;
1480         AH->lookahead = calloc(1, 512);
1481         AH->lookaheadLen = 0;
1482         AH->lookaheadPos = 0;
1483
1484         if (AH->fSpec)
1485         {
1486                 wantClose = 1;
1487                 fh = fopen(AH->fSpec, PG_BINARY_R);
1488         }
1489         else
1490                 fh = stdin;
1491
1492         if (!fh)
1493                 die_horribly(AH, modulename, "could not open input file: %s\n", strerror(errno));
1494
1495         cnt = fread(sig, 1, 5, fh);
1496
1497         if (cnt != 5)
1498         {
1499                 if (ferror(fh))
1500                         die_horribly(AH, modulename, "could not read input file: %s\n", strerror(errno));
1501                 else
1502                         die_horribly(AH, modulename, "input file is too short (read %lu, expected 5)\n",
1503                                                  (unsigned long) cnt);
1504         }
1505
1506         /* Save it, just in case we need it later */
1507         strncpy(&AH->lookahead[0], sig, 5);
1508         AH->lookaheadLen = 5;
1509
1510         if (strncmp(sig, "PGDMP", 5) == 0)
1511         {
1512                 AH->vmaj = fgetc(fh);
1513                 AH->vmin = fgetc(fh);
1514
1515                 /* Save these too... */
1516                 AH->lookahead[AH->lookaheadLen++] = AH->vmaj;
1517                 AH->lookahead[AH->lookaheadLen++] = AH->vmin;
1518
1519                 /* Check header version; varies from V1.0 */
1520                 if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))                /* Version > 1.0 */
1521                 {
1522                         AH->vrev = fgetc(fh);
1523                         AH->lookahead[AH->lookaheadLen++] = AH->vrev;
1524                 }
1525                 else
1526                         AH->vrev = 0;
1527
1528                 /* Make a convenient integer <maj><min><rev>00 */
1529                 AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
1530
1531                 AH->intSize = fgetc(fh);
1532                 AH->lookahead[AH->lookaheadLen++] = AH->intSize;
1533
1534                 if (AH->version >= K_VERS_1_7)
1535                 {
1536                         AH->offSize = fgetc(fh);
1537                         AH->lookahead[AH->lookaheadLen++] = AH->offSize;
1538                 }
1539                 else
1540                         AH->offSize = AH->intSize;
1541
1542                 AH->format = fgetc(fh);
1543                 AH->lookahead[AH->lookaheadLen++] = AH->format;
1544         }
1545         else
1546         {
1547                 /*
1548                  * *Maybe* we have a tar archive format file... So, read first 512
1549                  * byte header...
1550                  */
1551                 cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
1552                 AH->lookaheadLen += cnt;
1553
1554                 if (AH->lookaheadLen != 512)
1555                         die_horribly(AH, modulename, "input file does not appear to be a valid archive (too short?)\n");
1556
1557                 if (!isValidTarHeader(AH->lookahead))
1558                         die_horribly(AH, modulename, "input file does not appear to be a valid archive\n");
1559
1560                 AH->format = archTar;
1561         }
1562
1563         /* If we can't seek, then mark the header as read */
1564         if (fseeko(fh, 0, SEEK_SET) != 0)
1565         {
1566                 /*
1567                  * NOTE: Formats that use the lookahead buffer can unset this in their
1568                  * Init routine.
1569                  */
1570                 AH->readHeader = 1;
1571         }
1572         else
1573                 AH->lookaheadLen = 0;   /* Don't bother since we've reset the file */
1574
1575 #if 0
1576         write_msg(modulename, "read %lu bytes into lookahead buffer\n",
1577                           (unsigned long) AH->lookaheadLen);
1578 #endif
1579
1580         /* Close the file */
1581         if (wantClose)
1582                 if (fclose(fh) != 0)
1583                         die_horribly(AH, modulename, "could not close input file: %s\n",
1584                                                  strerror(errno));
1585
1586         return AH->format;
1587 }
1588
1589
1590 /*
1591  * Allocate an archive handle
1592  */
1593 static ArchiveHandle *
1594 _allocAH(const char *FileSpec, const ArchiveFormat fmt,
1595                  const int compression, ArchiveMode mode)
1596 {
1597         ArchiveHandle *AH;
1598
1599 #if 0
1600         write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
1601 #endif
1602
1603         AH = (ArchiveHandle *) calloc(1, sizeof(ArchiveHandle));
1604         if (!AH)
1605                 die_horribly(AH, modulename, "out of memory\n");
1606
1607         /* AH->debugLevel = 100; */
1608
1609         AH->vmaj = K_VERS_MAJOR;
1610         AH->vmin = K_VERS_MINOR;
1611         AH->vrev = K_VERS_REV;
1612
1613         /* initialize for backwards compatible string processing */
1614         AH->public.encoding = PG_SQL_ASCII;
1615         AH->public.std_strings = false;
1616
1617         /* sql error handling */
1618         AH->public.exit_on_error = true;
1619         AH->public.n_errors = 0;
1620
1621         AH->createDate = time(NULL);
1622
1623         AH->intSize = sizeof(int);
1624         AH->offSize = sizeof(off_t);
1625         if (FileSpec)
1626         {
1627                 AH->fSpec = strdup(FileSpec);
1628
1629                 /*
1630                  * Not used; maybe later....
1631                  *
1632                  * AH->workDir = strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
1633                  * i--) if (AH->workDir[i-1] == '/')
1634                  */
1635         }
1636         else
1637                 AH->fSpec = NULL;
1638
1639         AH->currUser = strdup("");      /* So it's valid, but we can free() it later
1640                                                                  * if necessary */
1641         AH->currSchema = strdup("");    /* ditto */
1642         AH->currWithOids = -1;          /* force SET */
1643
1644         AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));
1645         if (!AH->toc)
1646                 die_horribly(AH, modulename, "out of memory\n");
1647
1648         AH->toc->next = AH->toc;
1649         AH->toc->prev = AH->toc;
1650
1651         AH->mode = mode;
1652         AH->compression = compression;
1653
1654         AH->pgCopyBuf = createPQExpBuffer();
1655         AH->sqlBuf = createPQExpBuffer();
1656
1657         /* Open stdout with no compression for AH output handle */
1658         AH->gzOut = 0;
1659         AH->OF = stdout;
1660
1661         /*
1662          * On Windows, we need to use binary mode to read/write non-text archive
1663          * formats.  Force stdin/stdout into binary mode if that is what we are
1664          * using.
1665          */
1666 #ifdef WIN32
1667         if (fmt != archNull &&
1668                 (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
1669         {
1670                 if (mode == archModeWrite)
1671                         setmode(fileno(stdout), O_BINARY);
1672                 else
1673                         setmode(fileno(stdin), O_BINARY);
1674         }
1675 #endif
1676
1677 #if 0
1678         write_msg(modulename, "archive format is %d\n", fmt);
1679 #endif
1680
1681         if (fmt == archUnknown)
1682                 AH->format = _discoverArchiveFormat(AH);
1683         else
1684                 AH->format = fmt;
1685
1686         switch (AH->format)
1687         {
1688                 case archCustom:
1689                         InitArchiveFmt_Custom(AH);
1690                         break;
1691
1692                 case archFiles:
1693                         InitArchiveFmt_Files(AH);
1694                         break;
1695
1696                 case archNull:
1697                         InitArchiveFmt_Null(AH);
1698                         break;
1699
1700                 case archTar:
1701                         InitArchiveFmt_Tar(AH);
1702                         break;
1703
1704                 default:
1705                         die_horribly(AH, modulename, "unrecognized file format \"%d\"\n", fmt);
1706         }
1707
1708         return AH;
1709 }
1710
1711
1712 void
1713 WriteDataChunks(ArchiveHandle *AH)
1714 {
1715         TocEntry   *te = AH->toc->next;
1716         StartDataPtr startPtr;
1717         EndDataPtr      endPtr;
1718
1719         while (te != AH->toc)
1720         {
1721                 if (te->dataDumper != NULL)
1722                 {
1723                         AH->currToc = te;
1724                         /* printf("Writing data for %d (%x)\n", te->id, te); */
1725
1726                         if (strcmp(te->desc, "BLOBS") == 0)
1727                         {
1728                                 startPtr = AH->StartBlobsPtr;
1729                                 endPtr = AH->EndBlobsPtr;
1730                         }
1731                         else
1732                         {
1733                                 startPtr = AH->StartDataPtr;
1734                                 endPtr = AH->EndDataPtr;
1735                         }
1736
1737                         if (startPtr != NULL)
1738                                 (*startPtr) (AH, te);
1739
1740                         /*
1741                          * printf("Dumper arg for %d is %x\n", te->id, te->dataDumperArg);
1742                          */
1743
1744                         /*
1745                          * The user-provided DataDumper routine needs to call
1746                          * AH->WriteData
1747                          */
1748                         (*te->dataDumper) ((Archive *) AH, te->dataDumperArg);
1749
1750                         if (endPtr != NULL)
1751                                 (*endPtr) (AH, te);
1752                         AH->currToc = NULL;
1753                 }
1754                 te = te->next;
1755         }
1756 }
1757
1758 void
1759 WriteToc(ArchiveHandle *AH)
1760 {
1761         TocEntry   *te;
1762         char            workbuf[32];
1763         int                     i;
1764
1765         /* printf("%d TOC Entries to save\n", AH->tocCount); */
1766
1767         WriteInt(AH, AH->tocCount);
1768
1769         for (te = AH->toc->next; te != AH->toc; te = te->next)
1770         {
1771                 WriteInt(AH, te->dumpId);
1772                 WriteInt(AH, te->dataDumper ? 1 : 0);
1773
1774                 /* OID is recorded as a string for historical reasons */
1775                 sprintf(workbuf, "%u", te->catalogId.tableoid);
1776                 WriteStr(AH, workbuf);
1777                 sprintf(workbuf, "%u", te->catalogId.oid);
1778                 WriteStr(AH, workbuf);
1779
1780                 WriteStr(AH, te->tag);
1781                 WriteStr(AH, te->desc);
1782                 WriteStr(AH, te->defn);
1783                 WriteStr(AH, te->dropStmt);
1784                 WriteStr(AH, te->copyStmt);
1785                 WriteStr(AH, te->namespace);
1786                 WriteStr(AH, te->tablespace);
1787                 WriteStr(AH, te->owner);
1788                 WriteStr(AH, te->withOids ? "true" : "false");
1789
1790                 /* Dump list of dependencies */
1791                 for (i = 0; i < te->nDeps; i++)
1792                 {
1793                         sprintf(workbuf, "%d", te->dependencies[i]);
1794                         WriteStr(AH, workbuf);
1795                 }
1796                 WriteStr(AH, NULL);             /* Terminate List */
1797
1798                 if (AH->WriteExtraTocPtr)
1799                         (*AH->WriteExtraTocPtr) (AH, te);
1800         }
1801 }
1802
1803 void
1804 ReadToc(ArchiveHandle *AH)
1805 {
1806         int                     i;
1807         char       *tmp;
1808         DumpId     *deps;
1809         int                     depIdx;
1810         int                     depSize;
1811
1812         TocEntry   *te = AH->toc->next;
1813
1814         AH->tocCount = ReadInt(AH);
1815         AH->maxDumpId = 0;
1816
1817         for (i = 0; i < AH->tocCount; i++)
1818         {
1819                 te = (TocEntry *) calloc(1, sizeof(TocEntry));
1820                 te->dumpId = ReadInt(AH);
1821
1822                 if (te->dumpId > AH->maxDumpId)
1823                         AH->maxDumpId = te->dumpId;
1824
1825                 /* Sanity check */
1826                 if (te->dumpId <= 0)
1827                         die_horribly(AH, modulename,
1828                                            "entry ID %d out of range -- perhaps a corrupt TOC\n",
1829                                                  te->dumpId);
1830
1831                 te->hadDumper = ReadInt(AH);
1832
1833                 if (AH->version >= K_VERS_1_8)
1834                 {
1835                         tmp = ReadStr(AH);
1836                         sscanf(tmp, "%u", &te->catalogId.tableoid);
1837                         free(tmp);
1838                 }
1839                 else
1840                         te->catalogId.tableoid = InvalidOid;
1841                 tmp = ReadStr(AH);
1842                 sscanf(tmp, "%u", &te->catalogId.oid);
1843                 free(tmp);
1844
1845                 te->tag = ReadStr(AH);
1846                 te->desc = ReadStr(AH);
1847                 te->defn = ReadStr(AH);
1848                 te->dropStmt = ReadStr(AH);
1849
1850                 if (AH->version >= K_VERS_1_3)
1851                         te->copyStmt = ReadStr(AH);
1852
1853                 if (AH->version >= K_VERS_1_6)
1854                         te->namespace = ReadStr(AH);
1855
1856                 if (AH->version >= K_VERS_1_10)
1857                         te->tablespace = ReadStr(AH);
1858
1859                 te->owner = ReadStr(AH);
1860                 if (AH->version >= K_VERS_1_9)
1861                 {
1862                         if (strcmp(ReadStr(AH), "true") == 0)
1863                                 te->withOids = true;
1864                         else
1865                                 te->withOids = false;
1866                 }
1867                 else
1868                         te->withOids = true;
1869
1870                 /* Read TOC entry dependencies */
1871                 if (AH->version >= K_VERS_1_5)
1872                 {
1873                         depSize = 100;
1874                         deps = (DumpId *) malloc(sizeof(DumpId) * depSize);
1875                         depIdx = 0;
1876                         for (;;)
1877                         {
1878                                 tmp = ReadStr(AH);
1879                                 if (!tmp)
1880                                         break;          /* end of list */
1881                                 if (depIdx >= depSize)
1882                                 {
1883                                         depSize *= 2;
1884                                         deps = (DumpId *) realloc(deps, sizeof(DumpId) * depSize);
1885                                 }
1886                                 sscanf(tmp, "%d", &deps[depIdx]);
1887                                 free(tmp);
1888                                 depIdx++;
1889                         }
1890
1891                         if (depIdx > 0)         /* We have a non-null entry */
1892                         {
1893                                 deps = (DumpId *) realloc(deps, sizeof(DumpId) * depIdx);
1894                                 te->dependencies = deps;
1895                                 te->nDeps = depIdx;
1896                         }
1897                         else
1898                         {
1899                                 free(deps);
1900                                 te->dependencies = NULL;
1901                                 te->nDeps = 0;
1902                         }
1903                 }
1904                 else
1905                 {
1906                         te->dependencies = NULL;
1907                         te->nDeps = 0;
1908                 }
1909
1910                 if (AH->ReadExtraTocPtr)
1911                         (*AH->ReadExtraTocPtr) (AH, te);
1912
1913                 ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n",
1914                           i, te->dumpId, te->desc, te->tag);
1915
1916                 /* link completed entry into TOC circular list */
1917                 te->prev = AH->toc->prev;
1918                 AH->toc->prev->next = te;
1919                 AH->toc->prev = te;
1920                 te->next = AH->toc;
1921
1922                 /* special processing immediately upon read for some items */
1923                 if (strcmp(te->desc, "ENCODING") == 0)
1924                         processEncodingEntry(AH, te);
1925                 else if (strcmp(te->desc, "STDSTRINGS") == 0)
1926                         processStdStringsEntry(AH, te);
1927         }
1928 }
1929
1930 static void
1931 processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
1932 {
1933         /* te->defn should have the form SET client_encoding = 'foo'; */
1934         char       *defn = strdup(te->defn);
1935         char       *ptr1;
1936         char       *ptr2 = NULL;
1937         int                     encoding;
1938
1939         ptr1 = strchr(defn, '\'');
1940         if (ptr1)
1941                 ptr2 = strchr(++ptr1, '\'');
1942         if (ptr2)
1943         {
1944                 *ptr2 = '\0';
1945                 encoding = pg_char_to_encoding(ptr1);
1946                 if (encoding < 0)
1947                         die_horribly(AH, modulename, "unrecognized encoding \"%s\"\n",
1948                                                  ptr1);
1949                 AH->public.encoding = encoding;
1950         }
1951         else
1952                 die_horribly(AH, modulename, "invalid ENCODING item: %s\n",
1953                                          te->defn);
1954
1955         free(defn);
1956 }
1957
1958 static void
1959 processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
1960 {
1961         /* te->defn should have the form SET standard_conforming_strings = 'x'; */
1962         char       *ptr1;
1963
1964         ptr1 = strchr(te->defn, '\'');
1965         if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
1966                 AH->public.std_strings = true;
1967         else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
1968                 AH->public.std_strings = false;
1969         else
1970                 die_horribly(AH, modulename, "invalid STDSTRINGS item: %s\n",
1971                                          te->defn);
1972 }
1973
1974 static teReqs
1975 _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
1976 {
1977         teReqs          res = REQ_ALL;
1978
1979         /* ENCODING and STDSTRINGS items are dumped specially, so always reject */
1980         if (strcmp(te->desc, "ENCODING") == 0 ||
1981                 strcmp(te->desc, "STDSTRINGS") == 0)
1982                 return 0;
1983
1984         /* If it's an ACL, maybe ignore it */
1985         if ((!include_acls || ropt->aclsSkip) && strcmp(te->desc, "ACL") == 0)
1986                 return 0;
1987
1988         if (!ropt->create && strcmp(te->desc, "DATABASE") == 0)
1989                 return 0;
1990
1991         /* Check options for selective dump/restore */
1992         if (ropt->schemaNames)
1993         {
1994                 /* If no namespace is specified, it means all. */
1995                 if (!te->namespace)
1996                         return 0;
1997                 if (strcmp(ropt->schemaNames, te->namespace) != 0)
1998                         return 0;
1999         }
2000
2001         if (ropt->selTypes)
2002         {
2003                 if (strcmp(te->desc, "TABLE") == 0 ||
2004                         strcmp(te->desc, "TABLE DATA") == 0)
2005                 {
2006                         if (!ropt->selTable)
2007                                 return 0;
2008                         if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
2009                                 return 0;
2010                 }
2011                 else if (strcmp(te->desc, "INDEX") == 0)
2012                 {
2013                         if (!ropt->selIndex)
2014                                 return 0;
2015                         if (ropt->indexNames && strcmp(ropt->indexNames, te->tag) != 0)
2016                                 return 0;
2017                 }
2018                 else if (strcmp(te->desc, "FUNCTION") == 0)
2019                 {
2020                         if (!ropt->selFunction)
2021                                 return 0;
2022                         if (ropt->functionNames && strcmp(ropt->functionNames, te->tag) != 0)
2023                                 return 0;
2024                 }
2025                 else if (strcmp(te->desc, "TRIGGER") == 0)
2026                 {
2027                         if (!ropt->selTrigger)
2028                                 return 0;
2029                         if (ropt->triggerNames && strcmp(ropt->triggerNames, te->tag) != 0)
2030                                 return 0;
2031                 }
2032                 else
2033                         return 0;
2034         }
2035
2036         /*
2037          * Check if we had a dataDumper. Indicates if the entry is schema or data
2038          */
2039         if (!te->hadDumper)
2040         {
2041                 /*
2042                  * Special Case: If 'SEQUENCE SET' then it is considered a data entry
2043                  */
2044                 if (strcmp(te->desc, "SEQUENCE SET") == 0)
2045                         res = res & REQ_DATA;
2046                 else
2047                         res = res & ~REQ_DATA;
2048         }
2049
2050         /*
2051          * Special case: <Init> type with <Max OID> tag; this is obsolete and we
2052          * always ignore it.
2053          */
2054         if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
2055                 return 0;
2056
2057         /* Mask it if we only want schema */
2058         if (ropt->schemaOnly)
2059                 res = res & REQ_SCHEMA;
2060
2061         /* Mask it we only want data */
2062         if (ropt->dataOnly)
2063                 res = res & REQ_DATA;
2064
2065         /* Mask it if we don't have a schema contribution */
2066         if (!te->defn || strlen(te->defn) == 0)
2067                 res = res & ~REQ_SCHEMA;
2068
2069         /* Finally, if we used a list, limit based on that as well */
2070         if (ropt->limitToList && !ropt->idWanted[te->dumpId - 1])
2071                 return 0;
2072
2073         return res;
2074 }
2075
2076 /*
2077  * Issue SET commands for parameters that we want to have set the same way
2078  * at all times during execution of a restore script.
2079  */
2080 static void
2081 _doSetFixedOutputState(ArchiveHandle *AH)
2082 {
2083         /* Select the correct character set encoding */
2084         ahprintf(AH, "SET client_encoding = '%s';\n",
2085                          pg_encoding_to_char(AH->public.encoding));
2086
2087         /* Select the correct string literal syntax */
2088         ahprintf(AH, "SET standard_conforming_strings = %s;\n",
2089                          AH->public.std_strings ? "on" : "off");
2090
2091         /* Make sure function checking is disabled */
2092         ahprintf(AH, "SET check_function_bodies = false;\n");
2093
2094         /* Avoid annoying notices etc */
2095         ahprintf(AH, "SET client_min_messages = warning;\n");
2096         if (!AH->public.std_strings)
2097                 ahprintf(AH, "SET escape_string_warning = off;\n");
2098
2099         ahprintf(AH, "\n");
2100 }
2101
2102 /*
2103  * Issue a SET SESSION AUTHORIZATION command.  Caller is responsible
2104  * for updating state if appropriate.  If user is NULL or an empty string,
2105  * the specification DEFAULT will be used.
2106  */
2107 static void
2108 _doSetSessionAuth(ArchiveHandle *AH, const char *user)
2109 {
2110         PQExpBuffer cmd = createPQExpBuffer();
2111
2112         appendPQExpBuffer(cmd, "SET SESSION AUTHORIZATION ");
2113
2114         /*
2115          * SQL requires a string literal here.  Might as well be correct.
2116          */
2117         if (user && *user)
2118                 appendStringLiteralAHX(cmd, user, AH);
2119         else
2120                 appendPQExpBuffer(cmd, "DEFAULT");
2121         appendPQExpBuffer(cmd, ";");
2122
2123         if (RestoringToDB(AH))
2124         {
2125                 PGresult   *res;
2126
2127                 res = PQexec(AH->connection, cmd->data);
2128
2129                 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2130                         /* NOT warn_or_die_horribly... use -O instead to skip this. */
2131                         die_horribly(AH, modulename, "could not set session user to \"%s\": %s",
2132                                                  user, PQerrorMessage(AH->connection));
2133
2134                 PQclear(res);
2135         }
2136         else
2137                 ahprintf(AH, "%s\n\n", cmd->data);
2138
2139         destroyPQExpBuffer(cmd);
2140 }
2141
2142
2143 /*
2144  * Issue a SET default_with_oids command.  Caller is responsible
2145  * for updating state if appropriate.
2146  */
2147 static void
2148 _doSetWithOids(ArchiveHandle *AH, const bool withOids)
2149 {
2150         PQExpBuffer cmd = createPQExpBuffer();
2151
2152         appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
2153                                           "true" : "false");
2154
2155         if (RestoringToDB(AH))
2156         {
2157                 PGresult   *res;
2158
2159                 res = PQexec(AH->connection, cmd->data);
2160
2161                 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2162                         warn_or_die_horribly(AH, modulename,
2163                                                                  "could not set default_with_oids: %s",
2164                                                                  PQerrorMessage(AH->connection));
2165
2166                 PQclear(res);
2167         }
2168         else
2169                 ahprintf(AH, "%s\n\n", cmd->data);
2170
2171         destroyPQExpBuffer(cmd);
2172 }
2173
2174
2175 /*
2176  * Issue the commands to connect to the specified database.
2177  *
2178  * If we're currently restoring right into a database, this will
2179  * actually establish a connection. Otherwise it puts a \connect into
2180  * the script output.
2181  *
2182  * NULL dbname implies reconnecting to the current DB (pretty useless).
2183  */
2184 static void
2185 _reconnectToDB(ArchiveHandle *AH, const char *dbname)
2186 {
2187         if (RestoringToDB(AH))
2188                 ReconnectToServer(AH, dbname, NULL);
2189         else
2190         {
2191                 PQExpBuffer qry = createPQExpBuffer();
2192
2193                 appendPQExpBuffer(qry, "\\connect %s\n\n",
2194                                                   dbname ? fmtId(dbname) : "-");
2195                 ahprintf(AH, "%s", qry->data);
2196                 destroyPQExpBuffer(qry);
2197         }
2198
2199         /*
2200          * NOTE: currUser keeps track of what the imaginary session user in our
2201          * script is.  It's now effectively reset to the original userID.
2202          */
2203         if (AH->currUser)
2204                 free(AH->currUser);
2205
2206         AH->currUser = strdup("");
2207
2208         /* don't assume we still know the output schema */
2209         if (AH->currSchema)
2210                 free(AH->currSchema);
2211         AH->currSchema = strdup("");
2212         AH->currWithOids = -1;
2213
2214         /* re-establish fixed state */
2215         _doSetFixedOutputState(AH);
2216 }
2217
2218 /*
2219  * Become the specified user, and update state to avoid redundant commands
2220  *
2221  * NULL or empty argument is taken to mean restoring the session default
2222  */
2223 static void
2224 _becomeUser(ArchiveHandle *AH, const char *user)
2225 {
2226         if (!user)
2227                 user = "";                              /* avoid null pointers */
2228
2229         if (AH->currUser && strcmp(AH->currUser, user) == 0)
2230                 return;                                 /* no need to do anything */
2231
2232         _doSetSessionAuth(AH, user);
2233
2234         /*
2235          * NOTE: currUser keeps track of what the imaginary session user in our
2236          * script is
2237          */
2238         if (AH->currUser)
2239                 free(AH->currUser);
2240
2241         AH->currUser = strdup(user);
2242 }
2243
2244 /*
2245  * Become the owner of the the given TOC entry object.  If
2246  * changes in ownership are not allowed, this doesn't do anything.
2247  */
2248 static void
2249 _becomeOwner(ArchiveHandle *AH, TocEntry *te)
2250 {
2251         if (AH->ropt && (AH->ropt->noOwner || !AH->ropt->use_setsessauth))
2252                 return;
2253
2254         _becomeUser(AH, te->owner);
2255 }
2256
2257
2258 /*
2259  * Set the proper default_with_oids value for the table.
2260  */
2261 static void
2262 _setWithOids(ArchiveHandle *AH, TocEntry *te)
2263 {
2264         if (AH->currWithOids != te->withOids)
2265         {
2266                 _doSetWithOids(AH, te->withOids);
2267                 AH->currWithOids = te->withOids;
2268         }
2269 }
2270
2271
2272 /*
2273  * Issue the commands to select the specified schema as the current schema
2274  * in the target database.
2275  */
2276 static void
2277 _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
2278 {
2279         PQExpBuffer qry;
2280
2281         if (!schemaName || *schemaName == '\0' ||
2282                 (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
2283                 return;                                 /* no need to do anything */
2284
2285         qry = createPQExpBuffer();
2286
2287         appendPQExpBuffer(qry, "SET search_path = %s",
2288                                           fmtId(schemaName));
2289         if (strcmp(schemaName, "pg_catalog") != 0)
2290                 appendPQExpBuffer(qry, ", pg_catalog");
2291
2292         if (RestoringToDB(AH))
2293         {
2294                 PGresult   *res;
2295
2296                 res = PQexec(AH->connection, qry->data);
2297
2298                 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2299                         warn_or_die_horribly(AH, modulename,
2300                                                                  "could not set search_path to \"%s\": %s",
2301                                                                  schemaName, PQerrorMessage(AH->connection));
2302
2303                 PQclear(res);
2304         }
2305         else
2306                 ahprintf(AH, "%s;\n\n", qry->data);
2307
2308         if (AH->currSchema)
2309                 free(AH->currSchema);
2310         AH->currSchema = strdup(schemaName);
2311
2312         destroyPQExpBuffer(qry);
2313 }
2314
2315 /*
2316  * Issue the commands to select the specified tablespace as the current one
2317  * in the target database.
2318  */
2319 static void
2320 _selectTablespace(ArchiveHandle *AH, const char *tablespace)
2321 {
2322         PQExpBuffer qry;
2323         const char *want,
2324                            *have;
2325
2326         have = AH->currTablespace;
2327         want = tablespace;
2328
2329         /* no need to do anything for non-tablespace object */
2330         if (!want)
2331                 return;
2332
2333         if (have && strcmp(want, have) == 0)
2334                 return;                                 /* no need to do anything */
2335
2336         qry = createPQExpBuffer();
2337
2338         if (strcmp(want, "") == 0)
2339         {
2340                 /* We want the tablespace to be the database's default */
2341                 appendPQExpBuffer(qry, "SET default_tablespace = ''");
2342         }
2343         else
2344         {
2345                 /* We want an explicit tablespace */
2346                 appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
2347         }
2348
2349         if (RestoringToDB(AH))
2350         {
2351                 PGresult   *res;
2352
2353                 res = PQexec(AH->connection, qry->data);
2354
2355                 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2356                         warn_or_die_horribly(AH, modulename,
2357                                                                  "could not set default_tablespace to %s: %s",
2358                                                                  fmtId(want), PQerrorMessage(AH->connection));
2359
2360                 PQclear(res);
2361         }
2362         else
2363                 ahprintf(AH, "%s;\n\n", qry->data);
2364
2365         if (AH->currTablespace)
2366                 free(AH->currTablespace);
2367         AH->currTablespace = strdup(want);
2368
2369         destroyPQExpBuffer(qry);
2370 }
2371
2372 /*
2373  * Extract an object description for a TOC entry, and append it to buf.
2374  *
2375  * This is not quite as general as it may seem, since it really only
2376  * handles constructing the right thing to put into ALTER ... OWNER TO.
2377  *
2378  * The whole thing is pretty grotty, but we are kind of stuck since the
2379  * information used is all that's available in older dump files.
2380  */
2381 static void
2382 _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
2383 {
2384         const char *type = te->desc;
2385
2386         /* Use ALTER TABLE for views and sequences */
2387         if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0)
2388                 type = "TABLE";
2389
2390         /* objects named by a schema and name */
2391         if (strcmp(type, "CONVERSION") == 0 ||
2392                 strcmp(type, "DOMAIN") == 0 ||
2393                 strcmp(type, "TABLE") == 0 ||
2394                 strcmp(type, "TYPE") == 0)
2395         {
2396                 appendPQExpBuffer(buf, "%s ", type);
2397                 if (te->namespace && te->namespace[0])  /* is null pre-7.3 */
2398                         appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
2399
2400                 /*
2401                  * Pre-7.3 pg_dump would sometimes (not always) put a fmtId'd name
2402                  * into te->tag for an index. This check is heuristic, so make its
2403                  * scope as narrow as possible.
2404                  */
2405                 if (AH->version < K_VERS_1_7 &&
2406                         te->tag[0] == '"' &&
2407                         te->tag[strlen(te->tag) - 1] == '"' &&
2408                         strcmp(type, "INDEX") == 0)
2409                         appendPQExpBuffer(buf, "%s", te->tag);
2410                 else
2411                         appendPQExpBuffer(buf, "%s", fmtId(te->tag));
2412                 return;
2413         }
2414
2415         /* objects named by just a name */
2416         if (strcmp(type, "DATABASE") == 0 ||
2417                 strcmp(type, "SCHEMA") == 0)
2418         {
2419                 appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
2420                 return;
2421         }
2422
2423         /*
2424          * These object types require additional decoration.  Fortunately, the
2425          * information needed is exactly what's in the DROP command.
2426          */
2427         if (strcmp(type, "AGGREGATE") == 0 ||
2428                 strcmp(type, "FUNCTION") == 0 ||
2429                 strcmp(type, "OPERATOR") == 0 ||
2430                 strcmp(type, "OPERATOR CLASS") == 0)
2431         {
2432                 /* Chop "DROP " off the front and make a modifiable copy */
2433                 char       *first = strdup(te->dropStmt + 5);
2434                 char       *last;
2435
2436                 /* point to last character in string */
2437                 last = first + strlen(first) - 1;
2438
2439                 /* Strip off any ';' or '\n' at the end */
2440                 while (last >= first && (*last == '\n' || *last == ';'))
2441                         last--;
2442                 *(last + 1) = '\0';
2443
2444                 appendPQExpBufferStr(buf, first);
2445
2446                 free(first);
2447                 return;
2448         }
2449
2450         write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
2451                           type);
2452 }
2453
2454 static void
2455 _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass)
2456 {
2457         /* ACLs are dumped only during acl pass */
2458         if (acl_pass)
2459         {
2460                 if (strcmp(te->desc, "ACL") != 0)
2461                         return;
2462         }
2463         else
2464         {
2465                 if (strcmp(te->desc, "ACL") == 0)
2466                         return;
2467         }
2468
2469         /*
2470          * Avoid dumping the public schema, as it will already be created ...
2471          * unless we are using --clean mode, in which case it's been deleted and
2472          * we'd better recreate it.
2473          */
2474         if (!ropt->dropSchema &&
2475                 strcmp(te->desc, "SCHEMA") == 0 && strcmp(te->tag, "public") == 0)
2476                 return;
2477
2478         /* Select owner, schema, and tablespace as necessary */
2479         _becomeOwner(AH, te);
2480         _selectOutputSchema(AH, te->namespace);
2481         _selectTablespace(AH, te->tablespace);
2482
2483         /* Set up OID mode too */
2484         if (strcmp(te->desc, "TABLE") == 0)
2485                 _setWithOids(AH, te);
2486
2487         /* Emit header comment for item */
2488         if (!AH->noTocComments)
2489         {
2490                 const char *pfx;
2491
2492                 if (isData)
2493                         pfx = "Data for ";
2494                 else
2495                         pfx = "";
2496
2497                 ahprintf(AH, "--\n");
2498                 if (AH->public.verbose)
2499                 {
2500                         ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
2501                                          te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
2502                         if (te->nDeps > 0)
2503                         {
2504                                 int                     i;
2505
2506                                 ahprintf(AH, "-- Dependencies:");
2507                                 for (i = 0; i < te->nDeps; i++)
2508                                         ahprintf(AH, " %d", te->dependencies[i]);
2509                                 ahprintf(AH, "\n");
2510                         }
2511                 }
2512                 ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2513                                  pfx, te->tag, te->desc,
2514                                  te->namespace ? te->namespace : "-",
2515                                  ropt->noOwner ? "-" : te->owner);
2516                 if (te->tablespace)
2517                         ahprintf(AH, "; Tablespace: %s", te->tablespace);
2518                 ahprintf(AH, "\n");
2519
2520                 if (AH->PrintExtraTocPtr !=NULL)
2521                         (*AH->PrintExtraTocPtr) (AH, te);
2522                 ahprintf(AH, "--\n\n");
2523         }
2524
2525         /*
2526          * Actually print the definition.
2527          *
2528          * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
2529          * versions put into CREATE SCHEMA.  We have to do this when --no-owner
2530          * mode is selected.  This is ugly, but I see no other good way ...
2531          */
2532         if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
2533         {
2534                 ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
2535         }
2536         else
2537         {
2538                 if (strlen(te->defn) > 0)
2539                         ahprintf(AH, "%s\n\n", te->defn);
2540         }
2541
2542         /*
2543          * If we aren't using SET SESSION AUTH to determine ownership, we must
2544          * instead issue an ALTER OWNER command.  We assume that anything without
2545          * a DROP command is not a separately ownable object.  All the categories
2546          * with DROP commands must appear in one list or the other.
2547          */
2548         if (!ropt->noOwner && !ropt->use_setsessauth &&
2549                 strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
2550         {
2551                 if (strcmp(te->desc, "AGGREGATE") == 0 ||
2552                         strcmp(te->desc, "CONVERSION") == 0 ||
2553                         strcmp(te->desc, "DATABASE") == 0 ||
2554                         strcmp(te->desc, "DOMAIN") == 0 ||
2555                         strcmp(te->desc, "FUNCTION") == 0 ||
2556                         strcmp(te->desc, "OPERATOR") == 0 ||
2557                         strcmp(te->desc, "OPERATOR CLASS") == 0 ||
2558                         strcmp(te->desc, "SCHEMA") == 0 ||
2559                         strcmp(te->desc, "TABLE") == 0 ||
2560                         strcmp(te->desc, "TYPE") == 0 ||
2561                         strcmp(te->desc, "VIEW") == 0 ||
2562                         strcmp(te->desc, "SEQUENCE") == 0)
2563                 {
2564                         PQExpBuffer temp = createPQExpBuffer();
2565
2566                         appendPQExpBuffer(temp, "ALTER ");
2567                         _getObjectDescription(temp, te, AH);
2568                         appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
2569                         ahprintf(AH, "%s\n\n", temp->data);
2570                         destroyPQExpBuffer(temp);
2571                 }
2572                 else if (strcmp(te->desc, "CAST") == 0 ||
2573                                  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2574                                  strcmp(te->desc, "CONSTRAINT") == 0 ||
2575                                  strcmp(te->desc, "DEFAULT") == 0 ||
2576                                  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2577                                  strcmp(te->desc, "INDEX") == 0 ||
2578                                  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
2579                                  strcmp(te->desc, "RULE") == 0 ||
2580                                  strcmp(te->desc, "TRIGGER") == 0)
2581                 {
2582                         /* these object types don't have separate owners */
2583                 }
2584                 else
2585                 {
2586                         write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
2587                                           te->desc);
2588                 }
2589         }
2590
2591         /*
2592          * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
2593          * commands, so we can no longer assume we know the current auth setting.
2594          */
2595         if (strncmp(te->desc, "ACL", 3) == 0)
2596         {
2597                 if (AH->currUser)
2598                         free(AH->currUser);
2599                 AH->currUser = NULL;
2600         }
2601 }
2602
2603 void
2604 WriteHead(ArchiveHandle *AH)
2605 {
2606         struct tm       crtm;
2607
2608         (*AH->WriteBufPtr) (AH, "PGDMP", 5);            /* Magic code */
2609         (*AH->WriteBytePtr) (AH, AH->vmaj);
2610         (*AH->WriteBytePtr) (AH, AH->vmin);
2611         (*AH->WriteBytePtr) (AH, AH->vrev);
2612         (*AH->WriteBytePtr) (AH, AH->intSize);
2613         (*AH->WriteBytePtr) (AH, AH->offSize);
2614         (*AH->WriteBytePtr) (AH, AH->format);
2615
2616 #ifndef HAVE_LIBZ
2617         if (AH->compression != 0)
2618                 write_msg(modulename, "WARNING: requested compression not available in this "
2619                                   "installation -- archive will be uncompressed\n");
2620
2621         AH->compression = 0;
2622 #endif
2623
2624         WriteInt(AH, AH->compression);
2625
2626         crtm = *localtime(&AH->createDate);
2627         WriteInt(AH, crtm.tm_sec);
2628         WriteInt(AH, crtm.tm_min);
2629         WriteInt(AH, crtm.tm_hour);
2630         WriteInt(AH, crtm.tm_mday);
2631         WriteInt(AH, crtm.tm_mon);
2632         WriteInt(AH, crtm.tm_year);
2633         WriteInt(AH, crtm.tm_isdst);
2634         WriteStr(AH, PQdb(AH->connection));
2635         WriteStr(AH, AH->public.remoteVersionStr);
2636         WriteStr(AH, PG_VERSION);
2637 }
2638
2639 void
2640 ReadHead(ArchiveHandle *AH)
2641 {
2642         char            tmpMag[7];
2643         int                     fmt;
2644         struct tm       crtm;
2645
2646         /* If we haven't already read the header... */
2647         if (!AH->readHeader)
2648         {
2649
2650                 (*AH->ReadBufPtr) (AH, tmpMag, 5);
2651
2652                 if (strncmp(tmpMag, "PGDMP", 5) != 0)
2653                         die_horribly(AH, modulename, "did not find magic string in file header\n");
2654
2655                 AH->vmaj = (*AH->ReadBytePtr) (AH);
2656                 AH->vmin = (*AH->ReadBytePtr) (AH);
2657
2658                 if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))                /* Version > 1.0 */
2659                         AH->vrev = (*AH->ReadBytePtr) (AH);
2660                 else
2661                         AH->vrev = 0;
2662
2663                 AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
2664
2665
2666                 if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
2667                         die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",
2668                                                  AH->vmaj, AH->vmin);
2669
2670                 AH->intSize = (*AH->ReadBytePtr) (AH);
2671                 if (AH->intSize > 32)
2672                         die_horribly(AH, modulename, "sanity check on integer size (%lu) failed\n",
2673                                                  (unsigned long) AH->intSize);
2674
2675                 if (AH->intSize > sizeof(int))
2676                         write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations may fail\n");
2677
2678                 if (AH->version >= K_VERS_1_7)
2679                         AH->offSize = (*AH->ReadBytePtr) (AH);
2680                 else
2681                         AH->offSize = AH->intSize;
2682
2683                 fmt = (*AH->ReadBytePtr) (AH);
2684
2685                 if (AH->format != fmt)
2686                         die_horribly(AH, modulename, "expected format (%d) differs from format found in file (%d)\n",
2687                                                  AH->format, fmt);
2688         }
2689
2690         if (AH->version >= K_VERS_1_2)
2691         {
2692                 if (AH->version < K_VERS_1_4)
2693                         AH->compression = (*AH->ReadBytePtr) (AH);
2694                 else
2695                         AH->compression = ReadInt(AH);
2696         }
2697         else
2698                 AH->compression = Z_DEFAULT_COMPRESSION;
2699
2700 #ifndef HAVE_LIBZ
2701         if (AH->compression != 0)
2702                 write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");
2703 #endif
2704
2705         if (AH->version >= K_VERS_1_4)
2706         {
2707                 crtm.tm_sec = ReadInt(AH);
2708                 crtm.tm_min = ReadInt(AH);
2709                 crtm.tm_hour = ReadInt(AH);
2710                 crtm.tm_mday = ReadInt(AH);
2711                 crtm.tm_mon = ReadInt(AH);
2712                 crtm.tm_year = ReadInt(AH);
2713                 crtm.tm_isdst = ReadInt(AH);
2714
2715                 AH->archdbname = ReadStr(AH);
2716
2717                 AH->createDate = mktime(&crtm);
2718
2719                 if (AH->createDate == (time_t) -1)
2720                         write_msg(modulename, "WARNING: invalid creation date in header\n");
2721         }
2722
2723         if (AH->version >= K_VERS_1_10)
2724         {
2725                 AH->archiveRemoteVersion = ReadStr(AH);
2726                 AH->archiveDumpVersion = ReadStr(AH);
2727         }
2728
2729 }
2730
2731
2732 /*
2733  * checkSeek
2734  *        check to see if fseek can be performed.
2735  */
2736
2737 bool
2738 checkSeek(FILE *fp)
2739 {
2740
2741         if (fseeko(fp, 0, SEEK_CUR) != 0)
2742                 return false;
2743         else if (sizeof(off_t) > sizeof(long))
2744
2745                 /*
2746                  * At this point, off_t is too large for long, so we return based on
2747                  * whether an off_t version of fseek is available.
2748                  */
2749 #ifdef HAVE_FSEEKO
2750                 return true;
2751 #else
2752                 return false;
2753 #endif
2754         else
2755                 return true;
2756 }
2757
2758
2759 /*
2760  * dumpTimestamp
2761  */
2762 static void
2763 dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim)
2764 {
2765         char            buf[256];
2766
2767         if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&tim)) != 0)
2768                 ahprintf(AH, "-- %s %s\n\n", msg, buf);
2769 }