63 #define K_STD_BUF_SIZE 1024 140 AH->ReopenPtr = NULL;
151 AH->DeClonePtr = NULL;
153 AH->WorkerJobDumpPtr = NULL;
154 AH->WorkerJobRestorePtr = NULL;
160 AH->formatData = (
void *) ctx;
173 if (AH->fSpec && strcmp(AH->fSpec,
"") != 0)
176 if (ctx->
tarFH == NULL)
177 fatal(
"could not open TOC file \"%s\" for output: %m",
183 if (ctx->
tarFH == NULL)
184 fatal(
"could not open TOC file for output: %m");
202 if (AH->compression != 0)
203 fatal(
"compression is not supported by tar archive format");
207 if (AH->fSpec && strcmp(AH->fSpec,
"") != 0)
210 if (ctx->
tarFH == NULL)
211 fatal(
"could not open TOC file \"%s\" for input: %m",
217 if (ctx->
tarFH == NULL)
218 fatal(
"could not open TOC file for input: %m");
237 ctx->
FH = (
void *)
tarOpen(AH,
"toc.dat",
'r');
344 fatal(
"could not find file \"%s\" in archive", filename);
358 fatal(
"compression is not supported by tar archive format");
379 tm->tmpFH = tmpfile();
392 name = _tempnam(NULL,
"pg_temp_");
395 fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_BINARY |
401 tm->tmpFH = fdopen(fd,
"w+b");
404 else if (errno != EEXIST)
409 if (
tm->tmpFH == NULL)
410 fatal(
"could not generate temporary file name: %m");
419 tm->zFH = gzdopen(dup(fileno(
tm->tmpFH)), fmode);
421 fatal(
"could not open temporary file");
448 fatal(
"could not close tar member");
478 while (cnt < len && c !=
'\n')
540 res = fread(&((
char *) buf)[used], 1, len, fh);
541 if (res != len && !feof(fh))
548 res =
GZREAD(&((
char *) buf)[used], 1, len, th->
zFH);
553 const char *
errmsg = gzerror(th->
zFH, &errnum);
555 fatal(
"could not read from input file: %s",
556 errnum == Z_ERRNO ?
strerror(errno) : errmsg);
558 fatal(
"could not read from input file: %s",
565 res = fread(&((
char *) buf)[used], 1, len, th->
nFH);
566 if (res != len && !feof(th->
nFH))
571 fatal(
"internal error -- neither th nor fh specified in _tarReadRaw()");
605 res = fwrite(buf, 1, len, th->
nFH);
644 th =
tarOpen(AH, filename,
'r');
688 pos1 = (int) strlen(te->
copyStmt) - 13;
689 if (pos1 < 6 || strncmp(te->
copyStmt,
"COPY ", 5) != 0 ||
690 strcmp(te->
copyStmt + pos1,
" FROM stdin;\n") != 0)
691 fatal(
"unexpected COPY statement syntax: \"%s\"",
697 ahprintf(AH,
" FROM '$$PATH$$/%s';\n\n", tctx->filename);
702 ahprintf(AH,
"\\i $$PATH$$/%s\n\n", tctx->filename);
708 if (strcmp(te->
desc,
"BLOBS") == 0)
721 bool foundBlob =
false;
736 pg_log_info(
"restoring large object with OID %u", oid);
793 fatal(
"could not read from input file: end of file");
816 fatal(
"could not read from input file: end of file");
837 th =
tarOpen(AH,
"toc.dat",
'w');
852 th =
tarOpen(AH,
"restore.sql",
'w');
857 "-- File paths need to be edited. Search for $$PATH$$ and\n" 858 "-- replace it with the path to the directory containing\n" 859 "-- the extracted data files.\n" 869 ropt->filename = NULL;
870 ropt->dropSchema = 1;
871 ropt->compression = 0;
872 ropt->superuser = NULL;
873 ropt->suppressDumpWarnings =
true;
880 savVerbose = AH->public.
verbose;
887 AH->public.
verbose = savVerbose;
896 for (
i = 0;
i < 512 * 2;
i++)
898 if (fputc(0, ctx->
tarFH) == EOF)
903 if (AH->dosync && AH->fSpec)
958 fatal(
"invalid OID for large object (%u)", oid);
965 sprintf(fname,
"blob_%u.dat%s", oid, sfx);
969 tctx->TH =
tarOpen(AH, fname,
'w');
1013 int save_errno = errno;
1027 va_start(args, fmt);
1056 if (memcmp(&header[257],
"ustar\0", 6) == 0 &&
1057 memcmp(&header[263],
"00", 2) == 0)
1060 if (memcmp(&header[257],
"ustar \0", 8) == 0)
1063 if (memcmp(&header[257],
"ustar00\0", 8) == 0)
1074 FILE *tmp = th->
tmpFH;
1085 fseeko(tmp, 0, SEEK_END);
1088 fatal(
"could not determine seek position in archive file: %m");
1089 fseeko(tmp, 0, SEEK_SET);
1093 while ((cnt = fread(
buf, 1,
sizeof(
buf), tmp)) > 0)
1095 if ((res = fwrite(
buf, 1, cnt, th->
tarFH)) != cnt)
1102 if (fclose(tmp) != 0)
1103 fatal(
"could not close temporary file: %m");
1112 fatal(
"actual file length (%s) does not match expected (%s)",
1116 pad = ((len + 511) & ~511) - len;
1117 for (i = 0; i < pad; i++)
1119 if (fputc(
'\0', th->
tarFH) == EOF)
1149 pg_log_debug(
"moving from position %s to next member at file position %s",
1169 fatal(
"could not find header for file \"%s\" in tar archive", filename);
1181 while (filename != NULL && strcmp(th->
targetFile, filename) != 0)
1187 fatal(
"restoring data out of order is not supported in this archive format: " 1188 "\"%s\" is required, but comes before \"%s\" in the archive file.",
1192 len = ((th->
fileLen + 511) & ~511);
1195 for (i = 0; i < blks; i++)
1199 fatal(
"could not find header for file \"%s\" in tar archive", filename);
1219 bool gotBlock =
false;
1233 "incomplete tar header found (%lu bytes)",
1235 (
unsigned long) len);
1251 for (i = 0; i < 512; i++)
1273 pg_log_debug(
"TOC Entry %s at %s (length %s, checksum %d)",
1274 tag, posbuf, lenbuf, sum);
1283 fatal(
"corrupt tar header found in %s (expected %d, computed %d) file position %s",
1284 tag, sum, chk, posbuf);
1300 0600, 04000, 02000, time(NULL));
1303 if (fwrite(h, 1, 512, th->
tarFH) != 512)
static int tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3
static void _LoadBlobs(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
static PgChecksumMode mode
void ReadHead(ArchiveHandle *AH)
static void _PrintFileData(ArchiveHandle *AH, char *filename)
void * pg_malloc(size_t size)
uint64 read_tar_number(const char *s, int len)
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void fsync_fname(const char *fname, bool isdir)
void WriteToc(ArchiveHandle *AH)
static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
void InitArchiveFmt_Tar(ArchiveHandle *AH)
static int fd(const char *x, int i)
void StartRestoreBlobs(ArchiveHandle *AH)
struct _tocEntry * currToc
RestoreOptions * NewRestoreOptions(void)
#define pg_attribute_printf(f, a)
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
void * pg_malloc0(size_t size)
#define pg_log_debug(...)
void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
static void _StartBlobs(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
static TAR_MEMBER * _tarPositionTo(ArchiveHandle *AH, const char *filename)
char * pg_strdup(const char *in)
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
bool isValidTarHeader(char *header)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndBlobs(ArchiveHandle *AH, TocEntry *te)
#define GZWRITE(p, s, n, fh)
void EndRestoreBlobs(ArchiveHandle *AH)
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
#define ngettext(s, p, n)
static size_t _scriptOut(ArchiveHandle *AH, const void *buf, size_t len)
#define fseeko(stream, offset, origin)
int tarChecksum(char *header)
static void * fn(void *arg)
size_t strlcpy(char *dst, const char *src, size_t siz)
CustomOutPtrType CustomOutPtr
static void _tarWriteHeader(TAR_MEMBER *th)
char * ReadStr(ArchiveHandle *AH)
teReqs TocIDRequired(ArchiveHandle *AH, DumpId id)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void header(const char *fmt,...) pg_attribute_printf(1
static int static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
void WriteHead(ArchiveHandle *AH)
#define GZREAD(p, s, n, fh)
static void _CloseArchive(ArchiveHandle *AH)
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
int errmsg(const char *fmt,...)
void EndRestoreBlob(ArchiveHandle *AH, Oid oid)
void RestoreArchive(Archive *AH)
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
size_t WriteStr(ArchiveHandle *AH, const char *c)
#define READ_ERROR_EXIT(fd)
static int _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static int _ReadByte(ArchiveHandle *)
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
static size_t _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)