mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Properly detect read and write errors in pg_dump/dumpall, and pg_restore
Previously some I/O errors were ignored.
This commit is contained in:
parent
768fb00326
commit
14ea89366f
@ -86,14 +86,14 @@ static void InitCompressorZlib(CompressorState *cs, int level);
|
|||||||
static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
|
static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs,
|
||||||
bool flush);
|
bool flush);
|
||||||
static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF);
|
static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF);
|
||||||
static size_t WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
|
static void WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const char *data, size_t dLen);
|
const char *data, size_t dLen);
|
||||||
static void EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs);
|
static void EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Routines that support uncompressed data I/O */
|
/* Routines that support uncompressed data I/O */
|
||||||
static void ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF);
|
static void ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF);
|
||||||
static size_t WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
|
static void WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const char *data, size_t dLen);
|
const char *data, size_t dLen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -179,7 +179,7 @@ ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF)
|
|||||||
/*
|
/*
|
||||||
* Compress and write data to the output stream (via writeF).
|
* Compress and write data to the output stream (via writeF).
|
||||||
*/
|
*/
|
||||||
size_t
|
void
|
||||||
WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
|
WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const void *data, size_t dLen)
|
const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
@ -190,14 +190,16 @@ WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
|
|||||||
{
|
{
|
||||||
case COMPR_ALG_LIBZ:
|
case COMPR_ALG_LIBZ:
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
return WriteDataToArchiveZlib(AH, cs, data, dLen);
|
WriteDataToArchiveZlib(AH, cs, data, dLen);
|
||||||
#else
|
#else
|
||||||
exit_horribly(modulename, "not built with zlib support\n");
|
exit_horribly(modulename, "not built with zlib support\n");
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
case COMPR_ALG_NONE:
|
case COMPR_ALG_NONE:
|
||||||
return WriteDataToArchiveNone(AH, cs, data, dLen);
|
WriteDataToArchiveNone(AH, cs, data, dLen);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0; /* keep compiler quiet */
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -298,10 +300,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
|
|||||||
*/
|
*/
|
||||||
size_t len = cs->zlibOutSize - zp->avail_out;
|
size_t len = cs->zlibOutSize - zp->avail_out;
|
||||||
|
|
||||||
if (cs->writeF(AH, out, len) != len)
|
cs->writeF(AH, out, len);
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not write to output file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
}
|
||||||
zp->next_out = (void *) out;
|
zp->next_out = (void *) out;
|
||||||
zp->avail_out = cs->zlibOutSize;
|
zp->avail_out = cs->zlibOutSize;
|
||||||
@ -312,7 +311,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
|
WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const char *data, size_t dLen)
|
const char *data, size_t dLen)
|
||||||
{
|
{
|
||||||
@ -320,11 +319,7 @@ WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs,
|
|||||||
cs->zp->avail_in = dLen;
|
cs->zp->avail_in = dLen;
|
||||||
DeflateCompressorZlib(AH, cs, false);
|
DeflateCompressorZlib(AH, cs, false);
|
||||||
|
|
||||||
/*
|
return;
|
||||||
* we have either succeeded in writing dLen bytes or we have called
|
|
||||||
* exit_horribly()
|
|
||||||
*/
|
|
||||||
return dLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -427,19 +422,12 @@ ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF)
|
|||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
|
WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const char *data, size_t dLen)
|
const char *data, size_t dLen)
|
||||||
{
|
{
|
||||||
/*
|
cs->writeF(AH, data, dLen);
|
||||||
* Any write function should do its own error checking but to make sure we
|
return;
|
||||||
* do a check here as well...
|
|
||||||
*/
|
|
||||||
if (cs->writeF(AH, data, dLen) != dLen)
|
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not write to output file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return dLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -573,12 +561,27 @@ cfopen(const char *path, const char *mode, int compression)
|
|||||||
int
|
int
|
||||||
cfread(void *ptr, int size, cfp *fp)
|
cfread(void *ptr, int size, cfp *fp)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
if (fp->compressedfp)
|
if (fp->compressedfp)
|
||||||
return gzread(fp->compressedfp, ptr, size);
|
{
|
||||||
|
ret = gzread(fp->compressedfp, ptr, size);
|
||||||
|
if (ret != size && !gzeof(fp->compressedfp))
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return fread(ptr, 1, size, fp->uncompressedfp);
|
{
|
||||||
|
ret = fread(ptr, 1, size, fp->uncompressedfp);
|
||||||
|
if (ret != size && !feof(fp->uncompressedfp))
|
||||||
|
READ_ERROR_EXIT(fp->uncompressedfp);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -595,12 +598,31 @@ cfwrite(const void *ptr, int size, cfp *fp)
|
|||||||
int
|
int
|
||||||
cfgetc(cfp *fp)
|
cfgetc(cfp *fp)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
if (fp->compressedfp)
|
if (fp->compressedfp)
|
||||||
return gzgetc(fp->compressedfp);
|
{
|
||||||
|
ret = gzgetc(fp->compressedfp);
|
||||||
|
if (ret == EOF)
|
||||||
|
{
|
||||||
|
if (!gzeof(fp->compressedfp))
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: %s\n", strerror(errno));
|
||||||
|
else
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: end of file\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return fgetc(fp->uncompressedfp);
|
{
|
||||||
|
ret = fgetc(fp->uncompressedfp);
|
||||||
|
if (ret == EOF)
|
||||||
|
READ_ERROR_EXIT(fp->uncompressedfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -29,7 +29,7 @@ typedef enum
|
|||||||
} CompressionAlgorithm;
|
} CompressionAlgorithm;
|
||||||
|
|
||||||
/* Prototype for callback function to WriteDataToArchive() */
|
/* Prototype for callback function to WriteDataToArchive() */
|
||||||
typedef size_t (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
|
typedef void (*WriteFunc) (ArchiveHandle *AH, const char *buf, size_t len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototype for callback function to ReadDataFromArchive()
|
* Prototype for callback function to ReadDataFromArchive()
|
||||||
@ -50,7 +50,7 @@ typedef struct CompressorState CompressorState;
|
|||||||
extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF);
|
extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF);
|
||||||
extern void ReadDataFromArchive(ArchiveHandle *AH, int compression,
|
extern void ReadDataFromArchive(ArchiveHandle *AH, int compression,
|
||||||
ReadFunc readF);
|
ReadFunc readF);
|
||||||
extern size_t WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
|
extern void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs,
|
||||||
const void *data, size_t dLen);
|
const void *data, size_t dLen);
|
||||||
extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs);
|
extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs);
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ extern void ArchiveEntry(Archive *AHX,
|
|||||||
DataDumperPtr dumpFn, void *dumpArg);
|
DataDumperPtr dumpFn, void *dumpArg);
|
||||||
|
|
||||||
/* Called to write *data* to the archive */
|
/* Called to write *data* to the archive */
|
||||||
extern size_t WriteData(Archive *AH, const void *data, size_t dLen);
|
extern void WriteData(Archive *AH, const void *data, size_t dLen);
|
||||||
|
|
||||||
extern int StartBlob(Archive *AH, Oid oid);
|
extern int StartBlob(Archive *AH, Oid oid);
|
||||||
extern int EndBlob(Archive *AH, Oid oid);
|
extern int EndBlob(Archive *AH, Oid oid);
|
||||||
@ -208,7 +208,7 @@ extern RestoreOptions *NewRestoreOptions(void);
|
|||||||
extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
|
extern void SortTocFromFile(Archive *AHX, RestoreOptions *ropt);
|
||||||
|
|
||||||
/* Convenience functions used only when writing DATA */
|
/* Convenience functions used only when writing DATA */
|
||||||
extern int archputs(const char *s, Archive *AH);
|
extern void archputs(const char *s, Archive *AH);
|
||||||
extern int
|
extern int
|
||||||
archprintf(Archive *AH, const char *fmt,...)
|
archprintf(Archive *AH, const char *fmt,...)
|
||||||
/* This extension allows gcc to check the format string */
|
/* This extension allows gcc to check the format string */
|
||||||
|
@ -855,7 +855,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
size_t
|
void
|
||||||
WriteData(Archive *AHX, const void *data, size_t dLen)
|
WriteData(Archive *AHX, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
ArchiveHandle *AH = (ArchiveHandle *) AHX;
|
ArchiveHandle *AH = (ArchiveHandle *) AHX;
|
||||||
@ -863,7 +863,9 @@ WriteData(Archive *AHX, const void *data, size_t dLen)
|
|||||||
if (!AH->currToc)
|
if (!AH->currToc)
|
||||||
exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
|
exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n");
|
||||||
|
|
||||||
return (*AH->WriteDataPtr) (AH, data, dLen);
|
(*AH->WriteDataPtr) (AH, data, dLen);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1246,10 +1248,11 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
|
|||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
int
|
void
|
||||||
archputs(const char *s, Archive *AH)
|
archputs(const char *s, Archive *AH)
|
||||||
{
|
{
|
||||||
return WriteData(AH, s, strlen(s));
|
WriteData(AH, s, strlen(s));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
@ -1486,10 +1489,10 @@ dump_lo_buf(ArchiveHandle *AH)
|
|||||||
* format to create a custom output routine to 'fake' a restore if it
|
* format to create a custom output routine to 'fake' a restore if it
|
||||||
* wants to generate a script (see TAR output).
|
* wants to generate a script (see TAR output).
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
|
ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
|
||||||
{
|
{
|
||||||
size_t res;
|
int bytes_written = 0;
|
||||||
|
|
||||||
if (AH->writingBlob)
|
if (AH->writingBlob)
|
||||||
{
|
{
|
||||||
@ -1509,23 +1512,12 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
|
|||||||
memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
|
memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
|
||||||
AH->lo_buf_used += remaining;
|
AH->lo_buf_used += remaining;
|
||||||
|
|
||||||
return size * nmemb;
|
bytes_written = size * nmemb;
|
||||||
}
|
}
|
||||||
else if (AH->gzOut)
|
else if (AH->gzOut)
|
||||||
{
|
bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
|
||||||
res = GZWRITE(ptr, size, nmemb, AH->OF);
|
|
||||||
if (res != (nmemb * size))
|
|
||||||
exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else if (AH->CustomOutPtr)
|
else if (AH->CustomOutPtr)
|
||||||
{
|
bytes_written = AH->CustomOutPtr (AH, ptr, size * nmemb);
|
||||||
res = AH->CustomOutPtr (AH, ptr, size * nmemb);
|
|
||||||
|
|
||||||
if (res != (nmemb * size))
|
|
||||||
exit_horribly(modulename, "could not write to custom output routine\n");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1533,16 +1525,15 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
|
|||||||
* connected then send it to the DB.
|
* connected then send it to the DB.
|
||||||
*/
|
*/
|
||||||
if (RestoringToDB(AH))
|
if (RestoringToDB(AH))
|
||||||
return ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb);
|
bytes_written = ExecuteSqlCommandBuf(AH, (const char *) ptr, size * nmemb);
|
||||||
else
|
else
|
||||||
{
|
bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
|
||||||
res = fwrite(ptr, size, nmemb, AH->OF);
|
|
||||||
if (res != nmemb)
|
|
||||||
exit_horribly(modulename, "could not write to output file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes_written != size * nmemb)
|
||||||
|
WRITE_ERROR_EXIT;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* on some error, we may decide to go on... */
|
/* on some error, we may decide to go on... */
|
||||||
@ -1847,8 +1838,11 @@ WriteStr(ArchiveHandle *AH, const char *c)
|
|||||||
|
|
||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
res = WriteInt(AH, strlen(c));
|
int len = strlen(c);
|
||||||
res += (*AH->WriteBufPtr) (AH, c, strlen(c));
|
|
||||||
|
res = WriteInt(AH, len);
|
||||||
|
(*AH->WriteBufPtr) (AH, c, len);
|
||||||
|
res += len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = WriteInt(AH, -1);
|
res = WriteInt(AH, -1);
|
||||||
@ -1868,8 +1862,7 @@ ReadStr(ArchiveHandle *AH)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf = (char *) pg_malloc(l + 1);
|
buf = (char *) pg_malloc(l + 1);
|
||||||
if ((*AH->ReadBufPtr) (AH, (void *) buf, l) != l)
|
(*AH->ReadBufPtr) (AH, (void *) buf, l);
|
||||||
exit_horribly(modulename, "unexpected end of file\n");
|
|
||||||
|
|
||||||
buf[l] = '\0';
|
buf[l] = '\0';
|
||||||
}
|
}
|
||||||
@ -1950,9 +1943,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt = fread(sig, 1, 5, fh);
|
if ((cnt = fread(sig, 1, 5, fh)) != 5)
|
||||||
|
|
||||||
if (cnt != 5)
|
|
||||||
{
|
{
|
||||||
if (ferror(fh))
|
if (ferror(fh))
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
||||||
@ -1975,12 +1966,12 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
* NB: this code must agree with ReadHead().
|
* NB: this code must agree with ReadHead().
|
||||||
*/
|
*/
|
||||||
if ((byteread = fgetc(fh)) == EOF)
|
if ((byteread = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
|
|
||||||
AH->vmaj = byteread;
|
AH->vmaj = byteread;
|
||||||
|
|
||||||
if ((byteread = fgetc(fh)) == EOF)
|
if ((byteread = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
|
|
||||||
AH->vmin = byteread;
|
AH->vmin = byteread;
|
||||||
|
|
||||||
@ -1992,7 +1983,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */
|
if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0))) /* Version > 1.0 */
|
||||||
{
|
{
|
||||||
if ((byteread = fgetc(fh)) == EOF)
|
if ((byteread = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
|
|
||||||
AH->vrev = byteread;
|
AH->vrev = byteread;
|
||||||
AH->lookahead[AH->lookaheadLen++] = AH->vrev;
|
AH->lookahead[AH->lookaheadLen++] = AH->vrev;
|
||||||
@ -2004,20 +1995,20 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
|
AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
|
||||||
|
|
||||||
if ((AH->intSize = fgetc(fh)) == EOF)
|
if ((AH->intSize = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
AH->lookahead[AH->lookaheadLen++] = AH->intSize;
|
AH->lookahead[AH->lookaheadLen++] = AH->intSize;
|
||||||
|
|
||||||
if (AH->version >= K_VERS_1_7)
|
if (AH->version >= K_VERS_1_7)
|
||||||
{
|
{
|
||||||
if ((AH->offSize = fgetc(fh)) == EOF)
|
if ((AH->offSize = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
AH->lookahead[AH->lookaheadLen++] = AH->offSize;
|
AH->lookahead[AH->lookaheadLen++] = AH->offSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AH->offSize = AH->intSize;
|
AH->offSize = AH->intSize;
|
||||||
|
|
||||||
if ((byteread = fgetc(fh)) == EOF)
|
if ((byteread = fgetc(fh)) == EOF)
|
||||||
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
|
READ_ERROR_EXIT(fh);
|
||||||
|
|
||||||
AH->format = byteread;
|
AH->format = byteread;
|
||||||
AH->lookahead[AH->lookaheadLen++] = AH->format;
|
AH->lookahead[AH->lookaheadLen++] = AH->format;
|
||||||
@ -2029,6 +2020,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
* read first 512 byte header...
|
* read first 512 byte header...
|
||||||
*/
|
*/
|
||||||
cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
|
cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
|
||||||
|
/* read failure is checked below */
|
||||||
AH->lookaheadLen += cnt;
|
AH->lookaheadLen += cnt;
|
||||||
|
|
||||||
if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
|
if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
|
||||||
@ -2042,8 +2034,10 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
exit_horribly(modulename, "input file appears to be a text format dump. Please use psql.\n");
|
exit_horribly(modulename, "input file appears to be a text format dump. Please use psql.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AH->lookaheadLen != 512)
|
if (AH->lookaheadLen != 512 && feof(fh))
|
||||||
exit_horribly(modulename, "input file does not appear to be a valid archive (too short?)\n");
|
exit_horribly(modulename, "input file does not appear to be a valid archive (too short?)\n");
|
||||||
|
else
|
||||||
|
READ_ERROR_EXIT(fh);
|
||||||
|
|
||||||
if (!isValidTarHeader(AH->lookahead))
|
if (!isValidTarHeader(AH->lookahead))
|
||||||
exit_horribly(modulename, "input file does not appear to be a valid archive\n");
|
exit_horribly(modulename, "input file does not appear to be a valid archive\n");
|
||||||
@ -3318,8 +3312,7 @@ ReadHead(ArchiveHandle *AH)
|
|||||||
*/
|
*/
|
||||||
if (!AH->readHeader)
|
if (!AH->readHeader)
|
||||||
{
|
{
|
||||||
if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
|
(*AH->ReadBufPtr) (AH, tmpMag, 5);
|
||||||
exit_horribly(modulename, "unexpected end of file\n");
|
|
||||||
|
|
||||||
if (strncmp(tmpMag, "PGDMP", 5) != 0)
|
if (strncmp(tmpMag, "PGDMP", 5) != 0)
|
||||||
exit_horribly(modulename, "did not find magic string in file header\n");
|
exit_horribly(modulename, "did not find magic string in file header\n");
|
||||||
|
@ -45,10 +45,12 @@
|
|||||||
#define GZCLOSE(fh) gzclose(fh)
|
#define GZCLOSE(fh) gzclose(fh)
|
||||||
#define GZWRITE(p, s, n, fh) gzwrite(fh, p, (n) * (s))
|
#define GZWRITE(p, s, n, fh) gzwrite(fh, p, (n) * (s))
|
||||||
#define GZREAD(p, s, n, fh) gzread(fh, p, (n) * (s))
|
#define GZREAD(p, s, n, fh) gzread(fh, p, (n) * (s))
|
||||||
|
#define GZEOF(fh) gzeof(fh)
|
||||||
#else
|
#else
|
||||||
#define GZCLOSE(fh) fclose(fh)
|
#define GZCLOSE(fh) fclose(fh)
|
||||||
#define GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * (s))
|
#define GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * (s))
|
||||||
#define GZREAD(p, s, n, fh) fread(p, s, n, fh)
|
#define GZREAD(p, s, n, fh) fread(p, s, n, fh)
|
||||||
|
#define GZEOF(fh) feof(fh)
|
||||||
/* this is just the redefinition of a libz constant */
|
/* this is just the redefinition of a libz constant */
|
||||||
#define Z_DEFAULT_COMPRESSION (-1)
|
#define Z_DEFAULT_COMPRESSION (-1)
|
||||||
|
|
||||||
@ -115,6 +117,22 @@ struct _restoreList;
|
|||||||
struct ParallelArgs;
|
struct ParallelArgs;
|
||||||
struct ParallelState;
|
struct ParallelState;
|
||||||
|
|
||||||
|
#define READ_ERROR_EXIT(fd) \
|
||||||
|
do { \
|
||||||
|
if (feof(fd)) \
|
||||||
|
exit_horribly(modulename, \
|
||||||
|
"could not read from input file: end of file\n"); \
|
||||||
|
else \
|
||||||
|
exit_horribly(modulename, \
|
||||||
|
"could not read from input file: %s\n", strerror(errno)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define WRITE_ERROR_EXIT \
|
||||||
|
do { \
|
||||||
|
exit_horribly(modulename, "could not write to output file: %s\n", \
|
||||||
|
strerror(errno)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
typedef enum T_Action
|
typedef enum T_Action
|
||||||
{
|
{
|
||||||
ACT_DUMP,
|
ACT_DUMP,
|
||||||
@ -126,7 +144,7 @@ typedef void (*ReopenPtr) (struct _archiveHandle * AH);
|
|||||||
typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
|
|
||||||
typedef void (*StartDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*StartDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
typedef size_t (*WriteDataPtr) (struct _archiveHandle * AH, const void *data, size_t dLen);
|
typedef void (*WriteDataPtr) (struct _archiveHandle * AH, const void *data, size_t dLen);
|
||||||
typedef void (*EndDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*EndDataPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
|
|
||||||
typedef void (*StartBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*StartBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
@ -136,8 +154,8 @@ typedef void (*EndBlobsPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
|||||||
|
|
||||||
typedef int (*WriteBytePtr) (struct _archiveHandle * AH, const int i);
|
typedef int (*WriteBytePtr) (struct _archiveHandle * AH, const int i);
|
||||||
typedef int (*ReadBytePtr) (struct _archiveHandle * AH);
|
typedef int (*ReadBytePtr) (struct _archiveHandle * AH);
|
||||||
typedef size_t (*WriteBufPtr) (struct _archiveHandle * AH, const void *c, size_t len);
|
typedef void (*WriteBufPtr) (struct _archiveHandle * AH, const void *c, size_t len);
|
||||||
typedef size_t (*ReadBufPtr) (struct _archiveHandle * AH, void *buf, size_t len);
|
typedef void (*ReadBufPtr) (struct _archiveHandle * AH, void *buf, size_t len);
|
||||||
typedef void (*SaveArchivePtr) (struct _archiveHandle * AH);
|
typedef void (*SaveArchivePtr) (struct _archiveHandle * AH);
|
||||||
typedef void (*WriteExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*WriteExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
typedef void (*ReadExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
typedef void (*ReadExtraTocPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
|
||||||
@ -413,7 +431,7 @@ extern bool isValidTarHeader(char *header);
|
|||||||
extern int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
|
extern int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
|
||||||
extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
|
extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
|
||||||
|
|
||||||
int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
|
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
|
||||||
int ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
|
int ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
|
||||||
|
|
||||||
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
|
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
|
||||||
|
@ -35,12 +35,12 @@
|
|||||||
|
|
||||||
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
||||||
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
||||||
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static int _WriteByte(ArchiveHandle *AH, const int i);
|
static int _WriteByte(ArchiveHandle *AH, const int i);
|
||||||
static int _ReadByte(ArchiveHandle *);
|
static int _ReadByte(ArchiveHandle *);
|
||||||
static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
||||||
static size_t _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
||||||
static void _CloseArchive(ArchiveHandle *AH);
|
static void _CloseArchive(ArchiveHandle *AH);
|
||||||
static void _ReopenArchive(ArchiveHandle *AH);
|
static void _ReopenArchive(ArchiveHandle *AH);
|
||||||
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||||
@ -86,7 +86,7 @@ typedef struct
|
|||||||
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id);
|
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id);
|
||||||
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx);
|
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx);
|
||||||
|
|
||||||
static size_t _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len);
|
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len);
|
||||||
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen);
|
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen);
|
||||||
|
|
||||||
/* translator: this is a module name */
|
/* translator: this is a module name */
|
||||||
@ -315,16 +315,17 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
|
|||||||
*
|
*
|
||||||
* Mandatory.
|
* Mandatory.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
CompressorState *cs = ctx->cs;
|
CompressorState *cs = ctx->cs;
|
||||||
|
|
||||||
if (dLen == 0)
|
if (dLen > 0)
|
||||||
return 0;
|
/* WriteDataToArchive() internally throws write errors */
|
||||||
|
WriteDataToArchive(AH, cs, data, dLen);
|
||||||
|
|
||||||
return WriteDataToArchive(AH, cs, data, dLen);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -579,8 +580,7 @@ _skipData(ArchiveHandle *AH)
|
|||||||
buf = (char *) pg_malloc(blkLen);
|
buf = (char *) pg_malloc(blkLen);
|
||||||
buflen = blkLen;
|
buflen = blkLen;
|
||||||
}
|
}
|
||||||
cnt = fread(buf, 1, blkLen, AH->FH);
|
if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen)
|
||||||
if (cnt != blkLen)
|
|
||||||
{
|
{
|
||||||
if (feof(AH->FH))
|
if (feof(AH->FH))
|
||||||
exit_horribly(modulename,
|
exit_horribly(modulename,
|
||||||
@ -612,12 +612,11 @@ _WriteByte(ArchiveHandle *AH, const int i)
|
|||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = fputc(i, AH->FH);
|
if ((res = fputc(i, AH->FH)) == EOF)
|
||||||
if (res != EOF)
|
WRITE_ERROR_EXIT;
|
||||||
ctx->filePos += 1;
|
ctx->filePos += 1;
|
||||||
else
|
|
||||||
exit_horribly(modulename, "could not write byte: %s\n", strerror(errno));
|
return 1;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -636,7 +635,7 @@ _ReadByte(ArchiveHandle *AH)
|
|||||||
|
|
||||||
res = getc(AH->FH);
|
res = getc(AH->FH);
|
||||||
if (res == EOF)
|
if (res == EOF)
|
||||||
exit_horribly(modulename, "unexpected end of file\n");
|
READ_ERROR_EXIT(AH->FH);
|
||||||
ctx->filePos += 1;
|
ctx->filePos += 1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -648,20 +647,16 @@ _ReadByte(ArchiveHandle *AH)
|
|||||||
*
|
*
|
||||||
* Called by the archiver to write a block of bytes to the archive.
|
* Called by the archiver to write a block of bytes to the archive.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
res = fwrite(buf, 1, len, AH->FH);
|
if (fwrite(buf, 1, len, AH->FH) != len)
|
||||||
|
WRITE_ERROR_EXIT;
|
||||||
|
ctx->filePos += len;
|
||||||
|
|
||||||
if (res != len)
|
return;
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not write to output file: %s\n", strerror(errno));
|
|
||||||
|
|
||||||
ctx->filePos += res;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -671,16 +666,16 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
|||||||
*
|
*
|
||||||
* Called by the archiver to read a block of bytes from the archive
|
* Called by the archiver to read a block of bytes from the archive
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
res = fread(buf, 1, len, AH->FH);
|
if (fread(buf, 1, len, AH->FH) != len)
|
||||||
ctx->filePos += res;
|
READ_ERROR_EXIT(AH->FH);
|
||||||
|
ctx->filePos += len;
|
||||||
|
|
||||||
return res;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -959,15 +954,16 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
|
|||||||
* Callback function for WriteDataToArchive. Writes one block of (compressed)
|
* Callback function for WriteDataToArchive. Writes one block of (compressed)
|
||||||
* data to the archive.
|
* data to the archive.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
|
_CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
/* never write 0-byte blocks (this should not happen) */
|
/* never write 0-byte blocks (this should not happen) */
|
||||||
if (len == 0)
|
if (len > 0)
|
||||||
return 0;
|
{
|
||||||
|
|
||||||
WriteInt(AH, len);
|
WriteInt(AH, len);
|
||||||
return _WriteBuf(AH, buf, len);
|
_WriteBuf(AH, buf, len);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -978,7 +974,6 @@ static size_t
|
|||||||
_CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
|
_CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
|
||||||
{
|
{
|
||||||
size_t blkLen;
|
size_t blkLen;
|
||||||
size_t cnt;
|
|
||||||
|
|
||||||
/* Read length */
|
/* Read length */
|
||||||
blkLen = ReadInt(AH);
|
blkLen = ReadInt(AH);
|
||||||
@ -993,15 +988,8 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
|
|||||||
*buflen = blkLen;
|
*buflen = blkLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt = _ReadBuf(AH, *buf, blkLen);
|
/* exits app on read errors */
|
||||||
if (cnt != blkLen)
|
_ReadBuf(AH, *buf, blkLen);
|
||||||
{
|
|
||||||
if (feof(AH->FH))
|
return blkLen;
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not read from input file: end of file\n");
|
|
||||||
else
|
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not read from input file: %s\n", strerror(errno));
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
@ -540,7 +540,7 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return bufLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -66,11 +66,11 @@ static const char *modulename = gettext_noop("directory archiver");
|
|||||||
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
||||||
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
||||||
static int _WriteByte(ArchiveHandle *AH, const int i);
|
static int _WriteByte(ArchiveHandle *AH, const int i);
|
||||||
static int _ReadByte(ArchiveHandle *);
|
static int _ReadByte(ArchiveHandle *);
|
||||||
static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
||||||
static size_t _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
||||||
static void _CloseArchive(ArchiveHandle *AH);
|
static void _CloseArchive(ArchiveHandle *AH);
|
||||||
static void _ReopenArchive(ArchiveHandle *AH);
|
static void _ReopenArchive(ArchiveHandle *AH);
|
||||||
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||||
@ -350,18 +350,18 @@ _StartData(ArchiveHandle *AH, TocEntry *te)
|
|||||||
*
|
*
|
||||||
* We write the data to the open data file.
|
* We write the data to the open data file.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
|
|
||||||
if (dLen == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Are we aborting? */
|
/* Are we aborting? */
|
||||||
checkAborting(AH);
|
checkAborting(AH);
|
||||||
|
|
||||||
return cfwrite(data, dLen, ctx->dataFH);
|
if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
|
||||||
|
WRITE_ERROR_EXIT;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -408,7 +408,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
|
|||||||
ahwrite(buf, 1, cnt, AH);
|
ahwrite(buf, 1, cnt, AH);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
if (cfclose(cfp) !=0)
|
if (cfclose(cfp) != 0)
|
||||||
exit_horribly(modulename, "could not close data file: %s\n",
|
exit_horribly(modulename, "could not close data file: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
@ -495,7 +495,7 @@ _WriteByte(ArchiveHandle *AH, const int i)
|
|||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
|
|
||||||
if (cfwrite(&c, 1, ctx->dataFH) != 1)
|
if (cfwrite(&c, 1, ctx->dataFH) != 1)
|
||||||
exit_horribly(modulename, "could not write byte\n");
|
WRITE_ERROR_EXIT;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -510,34 +510,26 @@ static int
|
|||||||
_ReadByte(ArchiveHandle *AH)
|
_ReadByte(ArchiveHandle *AH)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
int res;
|
|
||||||
|
|
||||||
res = cfgetc(ctx->dataFH);
|
return cfgetc(ctx->dataFH);
|
||||||
if (res == EOF)
|
|
||||||
exit_horribly(modulename, "unexpected end of file\n");
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write a buffer of data to the archive.
|
* Write a buffer of data to the archive.
|
||||||
* Called by the archiver to write a block of bytes to the TOC or a data file.
|
* Called by the archiver to write a block of bytes to the TOC or a data file.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
/* Are we aborting? */
|
/* Are we aborting? */
|
||||||
checkAborting(AH);
|
checkAborting(AH);
|
||||||
|
|
||||||
res = cfwrite(buf, len, ctx->dataFH);
|
if (cfwrite(buf, len, ctx->dataFH) != len)
|
||||||
if (res != len)
|
WRITE_ERROR_EXIT;
|
||||||
exit_horribly(modulename, "could not write to output file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
return res;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -545,15 +537,20 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
|||||||
*
|
*
|
||||||
* Called by the archiver to read a block of bytes from the archive
|
* Called by the archiver to read a block of bytes from the archive
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
res = cfread(buf, len, ctx->dataFH);
|
/*
|
||||||
|
* If there was an I/O error, we already exited in cfread(),
|
||||||
|
* so here we exit on short reads.
|
||||||
|
*/
|
||||||
|
if (cfread(buf, len, ctx->dataFH) != len)
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: end of file\n");
|
||||||
|
|
||||||
return res;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -30,12 +30,11 @@
|
|||||||
|
|
||||||
#include "libpq/libpq-fs.h"
|
#include "libpq/libpq-fs.h"
|
||||||
|
|
||||||
|
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
||||||
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
static void _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
|
||||||
static size_t _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen);
|
|
||||||
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static int _WriteByte(ArchiveHandle *AH, const int i);
|
static int _WriteByte(ArchiveHandle *AH, const int i);
|
||||||
static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
||||||
static void _CloseArchive(ArchiveHandle *AH);
|
static void _CloseArchive(ArchiveHandle *AH);
|
||||||
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||||
static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
|
static void _StartBlobs(ArchiveHandle *AH, TocEntry *te);
|
||||||
@ -84,19 +83,19 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
|
|||||||
/*
|
/*
|
||||||
* Called by dumper via archiver from within a data dump routine
|
* Called by dumper via archiver from within a data dump routine
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
/* Just send it to output */
|
/* Just send it to output, ahwrite() already errors on failure */
|
||||||
ahwrite(data, 1, dLen, AH);
|
ahwrite(data, 1, dLen, AH);
|
||||||
return dLen;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by dumper via archiver from within a data dump routine
|
* Called by dumper via archiver from within a data dump routine
|
||||||
* We substitute this for _WriteData while emitting a BLOB
|
* We substitute this for _WriteData while emitting a BLOB
|
||||||
*/
|
*/
|
||||||
static size_t
|
static void
|
||||||
_WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
|
_WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
if (dLen > 0)
|
if (dLen > 0)
|
||||||
@ -112,7 +111,7 @@ _WriteBlobData(ArchiveHandle *AH, const void *data, size_t dLen)
|
|||||||
|
|
||||||
destroyPQExpBuffer(buf);
|
destroyPQExpBuffer(buf);
|
||||||
}
|
}
|
||||||
return dLen;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -220,11 +219,11 @@ _WriteByte(ArchiveHandle *AH, const int i)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
/* Don't do anything */
|
/* Don't do anything */
|
||||||
return len;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -42,12 +42,12 @@
|
|||||||
|
|
||||||
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
|
||||||
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
static void _StartData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
|
||||||
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
static void _EndData(ArchiveHandle *AH, TocEntry *te);
|
||||||
static int _WriteByte(ArchiveHandle *AH, const int i);
|
static int _WriteByte(ArchiveHandle *AH, const int i);
|
||||||
static int _ReadByte(ArchiveHandle *);
|
static int _ReadByte(ArchiveHandle *);
|
||||||
static size_t _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
|
||||||
static size_t _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
|
||||||
static void _CloseArchive(ArchiveHandle *AH);
|
static void _CloseArchive(ArchiveHandle *AH);
|
||||||
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||||
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
|
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
|
||||||
@ -548,13 +548,26 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
|
|||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
if (fh)
|
if (fh)
|
||||||
|
{
|
||||||
res = fread(&((char *) buf)[used], 1, len, fh);
|
res = fread(&((char *) buf)[used], 1, len, fh);
|
||||||
|
if (res != len && !feof(fh))
|
||||||
|
READ_ERROR_EXIT(fh);
|
||||||
|
}
|
||||||
else if (th)
|
else if (th)
|
||||||
{
|
{
|
||||||
if (th->zFH)
|
if (th->zFH)
|
||||||
|
{
|
||||||
res = GZREAD(&((char *) buf)[used], 1, len, th->zFH);
|
res = GZREAD(&((char *) buf)[used], 1, len, th->zFH);
|
||||||
|
if (res != len && !GZEOF(fh))
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
res = fread(&((char *) buf)[used], 1, len, th->nFH);
|
res = fread(&((char *) buf)[used], 1, len, th->nFH);
|
||||||
|
if (res != len && !feof(fh))
|
||||||
|
READ_ERROR_EXIT(fh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n");
|
exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n");
|
||||||
@ -593,22 +606,19 @@ tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
|
|||||||
else
|
else
|
||||||
res = fwrite(buf, 1, len, th->nFH);
|
res = fwrite(buf, 1, len, th->nFH);
|
||||||
|
|
||||||
if (res != len)
|
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not write to output file: %s\n", strerror(errno));
|
|
||||||
|
|
||||||
th->pos += res;
|
th->pos += res;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
|
||||||
{
|
{
|
||||||
lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
|
lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
|
||||||
|
|
||||||
dLen = tarWrite(data, dLen, tctx->TH);
|
if (tarWrite(data, dLen, tctx->TH) != dLen)
|
||||||
|
WRITE_ERROR_EXIT;
|
||||||
|
|
||||||
return dLen;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -766,13 +776,13 @@ static int
|
|||||||
_WriteByte(ArchiveHandle *AH, const int i)
|
_WriteByte(ArchiveHandle *AH, const int i)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
int res;
|
|
||||||
char b = i; /* Avoid endian problems */
|
char b = i; /* Avoid endian problems */
|
||||||
|
|
||||||
res = tarWrite(&b, 1, ctx->FH);
|
if (tarWrite(&b, 1, ctx->FH) != 1)
|
||||||
if (res != EOF)
|
WRITE_ERROR_EXIT;
|
||||||
ctx->filePos += res;
|
|
||||||
return res;
|
ctx->filePos += 1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -784,31 +794,36 @@ _ReadByte(ArchiveHandle *AH)
|
|||||||
|
|
||||||
res = tarRead(&c, 1, ctx->FH);
|
res = tarRead(&c, 1, ctx->FH);
|
||||||
if (res != 1)
|
if (res != 1)
|
||||||
exit_horribly(modulename, "unexpected end of file\n");
|
/* We already would have exited for errors on reads, must be EOF */
|
||||||
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: end of file\n");
|
||||||
ctx->filePos += 1;
|
ctx->filePos += 1;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
res = tarWrite(buf, len, ctx->FH);
|
if (tarWrite(buf, len, ctx->FH) != len)
|
||||||
ctx->filePos += res;
|
WRITE_ERROR_EXIT;
|
||||||
return res;
|
|
||||||
|
ctx->filePos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static void
|
||||||
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
lclContext *ctx = (lclContext *) AH->formatData;
|
lclContext *ctx = (lclContext *) AH->formatData;
|
||||||
size_t res;
|
|
||||||
|
|
||||||
res = tarRead(buf, len, ctx->FH);
|
if (tarRead(buf, len, ctx->FH) != len)
|
||||||
ctx->filePos += res;
|
/* We already would have exited for errors on reads, must be EOF */
|
||||||
return res;
|
exit_horribly(modulename,
|
||||||
|
"could not read from input file: end of file\n");
|
||||||
|
|
||||||
|
ctx->filePos += len;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -885,8 +900,7 @@ _CloseArchive(ArchiveHandle *AH)
|
|||||||
for (i = 0; i < 512 * 2; i++)
|
for (i = 0; i < 512 * 2; i++)
|
||||||
{
|
{
|
||||||
if (fputc(0, ctx->tarFH) == EOF)
|
if (fputc(0, ctx->tarFH) == EOF)
|
||||||
exit_horribly(modulename,
|
WRITE_ERROR_EXIT;
|
||||||
"could not write null block at end of tar archive\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,13 +1098,12 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
|
|||||||
|
|
||||||
while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
|
while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
|
||||||
{
|
{
|
||||||
res = fwrite(buf, 1, cnt, th->tarFH);
|
if ((res = fwrite(buf, 1, cnt, th->tarFH)) != cnt)
|
||||||
if (res != cnt)
|
WRITE_ERROR_EXIT;
|
||||||
exit_horribly(modulename,
|
|
||||||
"could not write to output file: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
len += res;
|
len += res;
|
||||||
}
|
}
|
||||||
|
if (!feof(tmp))
|
||||||
|
READ_ERROR_EXIT(tmp);
|
||||||
|
|
||||||
if (fclose(tmp) != 0) /* This *should* delete it... */
|
if (fclose(tmp) != 0) /* This *should* delete it... */
|
||||||
exit_horribly(modulename, "could not close temporary file: %s\n",
|
exit_horribly(modulename, "could not close temporary file: %s\n",
|
||||||
@ -1111,7 +1124,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
|
|||||||
for (i = 0; i < pad; i++)
|
for (i = 0; i < pad; i++)
|
||||||
{
|
{
|
||||||
if (fputc('\0', th->tarFH) == EOF)
|
if (fputc('\0', th->tarFH) == EOF)
|
||||||
exit_horribly(modulename, "could not output padding at end of tar member\n");
|
WRITE_ERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->tarFHpos += len + pad;
|
ctx->tarFHpos += len + pad;
|
||||||
@ -1294,5 +1307,5 @@ _tarWriteHeader(TAR_MEMBER *th)
|
|||||||
|
|
||||||
/* Now write the completed header. */
|
/* Now write the completed header. */
|
||||||
if (fwrite(h, 1, 512, th->tarFH) != 512)
|
if (fwrite(h, 1, 512, th->tarFH) != 512)
|
||||||
exit_horribly(modulename, "could not write to output file: %s\n", strerror(errno));
|
WRITE_ERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user