Commit 2961c971 authored by Robert Haas's avatar Robert Haas

Assorted cleanup of tar-related code.

Introduce TAR_BLOCK_SIZE and replace many instances of 512 with
the new constant. Introduce function tarPaddingBytesRequired
and use it to replace numerous repetitions of (x + 511) & ~511.

Add preprocessor guards against multiple inclusion to pgtar.h.

Reformat the prototype for tarCreateHeader so it doesn't extend
beyond 80 characters.

Discussion: http://postgr.es/m/CA+TgmobWbfReO9-XFk8urR1K4wTNwqoHx_v56t7=T8KaiEoKNw@mail.gmail.com
parent e532b1d5
...@@ -665,7 +665,11 @@ perform_base_backup(basebackup_options *opt) ...@@ -665,7 +665,11 @@ perform_base_backup(basebackup_options *opt)
errmsg("unexpected WAL file size \"%s\"", walFileName))); errmsg("unexpected WAL file size \"%s\"", walFileName)));
} }
/* wal_segment_size is a multiple of 512, so no need for padding */ /*
* wal_segment_size is a multiple of TAR_BLOCK_SIZE, so no need
* for padding.
*/
Assert(wal_segment_size % TAR_BLOCK_SIZE == 0);
FreeFile(fp); FreeFile(fp);
...@@ -1118,11 +1122,11 @@ sendFileWithContent(const char *filename, const char *content, ...@@ -1118,11 +1122,11 @@ sendFileWithContent(const char *filename, const char *content,
pq_putmessage('d', content, len); pq_putmessage('d', content, len);
update_basebackup_progress(len); update_basebackup_progress(len);
/* Pad to 512 byte boundary, per tar format requirements */ /* Pad to a multiple of the tar block size. */
pad = ((len + 511) & ~511) - len; pad = tarPaddingBytesRequired(len);
if (pad > 0) if (pad > 0)
{ {
char buf[512]; char buf[TAR_BLOCK_SIZE];
MemSet(buf, 0, pad); MemSet(buf, 0, pad);
pq_putmessage('d', buf, pad); pq_putmessage('d', buf, pad);
...@@ -1491,9 +1495,14 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, ...@@ -1491,9 +1495,14 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces,
if (sent || sizeonly) if (sent || sizeonly)
{ {
/* Add size, rounded up to 512byte block */ /* Add size. */
size += ((statbuf.st_size + 511) & ~511); size += statbuf.st_size;
size += 512; /* Size of the header of the file */
/* Pad to a multiple of the tar block size. */
size += tarPaddingBytesRequired(statbuf.st_size);
/* Size of the header for the file. */
size += TAR_BLOCK_SIZE;
} }
} }
else else
...@@ -1784,11 +1793,11 @@ sendFile(const char *readfilename, const char *tarfilename, ...@@ -1784,11 +1793,11 @@ sendFile(const char *readfilename, const char *tarfilename,
} }
/* /*
* Pad to 512 byte boundary, per tar format requirements. (This small * Pad to a block boundary, per tar format requirements. (This small
* piece of data is probably not worth throttling, and is not checksummed * piece of data is probably not worth throttling, and is not checksummed
* because it's not actually part of the file.) * because it's not actually part of the file.)
*/ */
pad = ((len + 511) & ~511) - len; pad = tarPaddingBytesRequired(len);
if (pad > 0) if (pad > 0)
{ {
MemSet(buf, 0, pad); MemSet(buf, 0, pad);
...@@ -1822,7 +1831,7 @@ static int64 ...@@ -1822,7 +1831,7 @@ static int64
_tarWriteHeader(const char *filename, const char *linktarget, _tarWriteHeader(const char *filename, const char *linktarget,
struct stat *statbuf, bool sizeonly) struct stat *statbuf, bool sizeonly)
{ {
char h[512]; char h[TAR_BLOCK_SIZE];
enum tarError rc; enum tarError rc;
if (!sizeonly) if (!sizeonly)
......
...@@ -62,7 +62,7 @@ typedef struct WriteTarState ...@@ -62,7 +62,7 @@ typedef struct WriteTarState
int tablespacenum; int tablespacenum;
char filename[MAXPGPATH]; char filename[MAXPGPATH];
FILE *tarfile; FILE *tarfile;
char tarhdr[512]; char tarhdr[TAR_BLOCK_SIZE];
bool basetablespace; bool basetablespace;
bool in_tarhdr; bool in_tarhdr;
bool skip_file; bool skip_file;
...@@ -1024,7 +1024,7 @@ writeTarData(WriteTarState *state, char *buf, int r) ...@@ -1024,7 +1024,7 @@ writeTarData(WriteTarState *state, char *buf, int r)
static void static void
ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
char zerobuf[1024]; char zerobuf[TAR_BLOCK_SIZE * 2];
WriteTarState state; WriteTarState state;
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
...@@ -1169,7 +1169,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1169,7 +1169,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
if (state.basetablespace && writerecoveryconf) if (state.basetablespace && writerecoveryconf)
{ {
char header[512]; char header[TAR_BLOCK_SIZE];
/* /*
* If postgresql.auto.conf has not been found in the streamed data, * If postgresql.auto.conf has not been found in the streamed data,
...@@ -1188,7 +1188,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1188,7 +1188,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
pg_file_create_mode, 04000, 02000, pg_file_create_mode, 04000, 02000,
time(NULL)); time(NULL));
padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len; padding = tarPaddingBytesRequired(recoveryconfcontents->len);
writeTarData(&state, header, sizeof(header)); writeTarData(&state, header, sizeof(header));
writeTarData(&state, recoveryconfcontents->data, writeTarData(&state, recoveryconfcontents->data,
...@@ -1224,7 +1224,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1224,7 +1224,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
*/ */
if (strcmp(basedir, "-") == 0 && manifest) if (strcmp(basedir, "-") == 0 && manifest)
{ {
char header[512]; char header[TAR_BLOCK_SIZE];
PQExpBufferData buf; PQExpBufferData buf;
initPQExpBuffer(&buf); initPQExpBuffer(&buf);
...@@ -1242,7 +1242,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1242,7 +1242,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
termPQExpBuffer(&buf); termPQExpBuffer(&buf);
} }
/* 2 * 512 bytes empty data at end of file */ /* 2 * TAR_BLOCK_SIZE bytes empty data at end of file */
writeTarData(&state, zerobuf, sizeof(zerobuf)); writeTarData(&state, zerobuf, sizeof(zerobuf));
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
...@@ -1303,9 +1303,9 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1303,9 +1303,9 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
* *
* To do this, we have to process the individual files inside the TAR * To do this, we have to process the individual files inside the TAR
* stream. The stream consists of a header and zero or more chunks, * stream. The stream consists of a header and zero or more chunks,
* all 512 bytes long. The stream from the server is broken up into * each with a length equal to TAR_BLOCK_SIZE. The stream from the
* smaller pieces, so we have to track the size of the files to find * server is broken up into smaller pieces, so we have to track the
* the next header structure. * size of the files to find the next header structure.
*/ */
int rr = r; int rr = r;
int pos = 0; int pos = 0;
...@@ -1318,17 +1318,17 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1318,17 +1318,17 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
* We're currently reading a header structure inside the TAR * We're currently reading a header structure inside the TAR
* stream, i.e. the file metadata. * stream, i.e. the file metadata.
*/ */
if (state->tarhdrsz < 512) if (state->tarhdrsz < TAR_BLOCK_SIZE)
{ {
/* /*
* Copy the header structure into tarhdr in case the * Copy the header structure into tarhdr in case the
* header is not aligned to 512 bytes or it's not returned * header is not aligned properly or it's not returned in
* in whole by the last PQgetCopyData call. * whole by the last PQgetCopyData call.
*/ */
int hdrleft; int hdrleft;
int bytes2copy; int bytes2copy;
hdrleft = 512 - state->tarhdrsz; hdrleft = TAR_BLOCK_SIZE - state->tarhdrsz;
bytes2copy = (rr > hdrleft ? hdrleft : rr); bytes2copy = (rr > hdrleft ? hdrleft : rr);
memcpy(&state->tarhdr[state->tarhdrsz], copybuf + pos, memcpy(&state->tarhdr[state->tarhdrsz], copybuf + pos,
...@@ -1361,14 +1361,14 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1361,14 +1361,14 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
state->filesz = read_tar_number(&state->tarhdr[124], 12); state->filesz = read_tar_number(&state->tarhdr[124], 12);
state->file_padding_len = state->file_padding_len =
((state->filesz + 511) & ~511) - state->filesz; tarPaddingBytesRequired(state->filesz);
if (state->is_recovery_guc_supported && if (state->is_recovery_guc_supported &&
state->is_postgresql_auto_conf && state->is_postgresql_auto_conf &&
writerecoveryconf) writerecoveryconf)
{ {
/* replace tar header */ /* replace tar header */
char header[512]; char header[TAR_BLOCK_SIZE];
tarCreateHeader(header, "postgresql.auto.conf", NULL, tarCreateHeader(header, "postgresql.auto.conf", NULL,
state->filesz + recoveryconfcontents->len, state->filesz + recoveryconfcontents->len,
...@@ -1388,7 +1388,7 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1388,7 +1388,7 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
* If we're not skipping the file, write the tar * If we're not skipping the file, write the tar
* header unmodified. * header unmodified.
*/ */
writeTarData(state, state->tarhdr, 512); writeTarData(state, state->tarhdr, TAR_BLOCK_SIZE);
} }
} }
...@@ -1425,15 +1425,15 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1425,15 +1425,15 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
int padding; int padding;
int tailsize; int tailsize;
tailsize = (512 - state->file_padding_len) + recoveryconfcontents->len; tailsize = (TAR_BLOCK_SIZE - state->file_padding_len) + recoveryconfcontents->len;
padding = ((tailsize + 511) & ~511) - tailsize; padding = tarPaddingBytesRequired(tailsize);
writeTarData(state, recoveryconfcontents->data, writeTarData(state, recoveryconfcontents->data,
recoveryconfcontents->len); recoveryconfcontents->len);
if (padding) if (padding)
{ {
char zerobuf[512]; char zerobuf[TAR_BLOCK_SIZE];
MemSet(zerobuf, 0, sizeof(zerobuf)); MemSet(zerobuf, 0, sizeof(zerobuf));
writeTarData(state, zerobuf, padding); writeTarData(state, zerobuf, padding);
...@@ -1551,12 +1551,12 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1551,12 +1551,12 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
/* /*
* No current file, so this must be the header for a new file * No current file, so this must be the header for a new file
*/ */
if (r != 512) if (r != TAR_BLOCK_SIZE)
{ {
pg_log_error("invalid tar block header size: %zu", r); pg_log_error("invalid tar block header size: %zu", r);
exit(1); exit(1);
} }
totaldone += 512; totaldone += TAR_BLOCK_SIZE;
state->current_len_left = read_tar_number(&copybuf[124], 12); state->current_len_left = read_tar_number(&copybuf[124], 12);
...@@ -1566,10 +1566,10 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data) ...@@ -1566,10 +1566,10 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
#endif #endif
/* /*
* All files are padded up to 512 bytes * All files are padded up to a multiple of TAR_BLOCK_SIZE
*/ */
state->current_padding = state->current_padding =
((state->current_len_left + 511) & ~511) - state->current_len_left; tarPaddingBytesRequired(state->current_len_left);
/* /*
* First part of header is zero terminated filename * First part of header is zero terminated filename
......
...@@ -386,7 +386,7 @@ typedef struct TarMethodFile ...@@ -386,7 +386,7 @@ typedef struct TarMethodFile
{ {
off_t ofs_start; /* Where does the *header* for this file start */ off_t ofs_start; /* Where does the *header* for this file start */
off_t currpos; off_t currpos;
char header[512]; char header[TAR_BLOCK_SIZE];
char *pathname; char *pathname;
size_t pad_to_size; size_t pad_to_size;
} TarMethodFile; } TarMethodFile;
...@@ -625,7 +625,8 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ ...@@ -625,7 +625,8 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
if (!tar_data->compression) if (!tar_data->compression)
{ {
errno = 0; errno = 0;
if (write(tar_data->fd, tar_data->currentfile->header, 512) != 512) if (write(tar_data->fd, tar_data->currentfile->header,
TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
{ {
save_errno = errno; save_errno = errno;
pg_free(tar_data->currentfile); pg_free(tar_data->currentfile);
...@@ -639,7 +640,8 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ ...@@ -639,7 +640,8 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
else else
{ {
/* Write header through the zlib APIs but with no compression */ /* Write header through the zlib APIs but with no compression */
if (!tar_write_compressed_data(tar_data->currentfile->header, 512, true)) if (!tar_write_compressed_data(tar_data->currentfile->header,
TAR_BLOCK_SIZE, true))
return NULL; return NULL;
/* Re-enable compression for the rest of the file */ /* Re-enable compression for the rest of the file */
...@@ -665,7 +667,9 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ ...@@ -665,7 +667,9 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
/* Uncompressed, so pad now */ /* Uncompressed, so pad now */
tar_write_padding_data(tar_data->currentfile, pad_to_size); tar_write_padding_data(tar_data->currentfile, pad_to_size);
/* Seek back to start */ /* Seek back to start */
if (lseek(tar_data->fd, tar_data->currentfile->ofs_start + 512, SEEK_SET) != tar_data->currentfile->ofs_start + 512) if (lseek(tar_data->fd,
tar_data->currentfile->ofs_start + TAR_BLOCK_SIZE,
SEEK_SET) != tar_data->currentfile->ofs_start + TAR_BLOCK_SIZE)
return NULL; return NULL;
tar_data->currentfile->currpos = 0; tar_data->currentfile->currpos = 0;
...@@ -778,14 +782,14 @@ tar_close(Walfile f, WalCloseMethod method) ...@@ -778,14 +782,14 @@ tar_close(Walfile f, WalCloseMethod method)
} }
/* /*
* Get the size of the file, and pad the current data up to the nearest * Get the size of the file, and pad out to a multiple of the tar block
* 512 byte boundary. * size.
*/ */
filesize = tar_get_current_pos(f); filesize = tar_get_current_pos(f);
padding = ((filesize + 511) & ~511) - filesize; padding = tarPaddingBytesRequired(filesize);
if (padding) if (padding)
{ {
char zerobuf[512]; char zerobuf[TAR_BLOCK_SIZE];
MemSet(zerobuf, 0, padding); MemSet(zerobuf, 0, padding);
if (tar_write(f, zerobuf, padding) != padding) if (tar_write(f, zerobuf, padding) != padding)
...@@ -826,7 +830,7 @@ tar_close(Walfile f, WalCloseMethod method) ...@@ -826,7 +830,7 @@ tar_close(Walfile f, WalCloseMethod method)
if (!tar_data->compression) if (!tar_data->compression)
{ {
errno = 0; errno = 0;
if (write(tar_data->fd, tf->header, 512) != 512) if (write(tar_data->fd, tf->header, TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
{ {
/* if write didn't set errno, assume problem is no disk space */ /* if write didn't set errno, assume problem is no disk space */
if (errno == 0) if (errno == 0)
...@@ -845,7 +849,8 @@ tar_close(Walfile f, WalCloseMethod method) ...@@ -845,7 +849,8 @@ tar_close(Walfile f, WalCloseMethod method)
} }
/* Overwrite the header, assuming the size will be the same */ /* Overwrite the header, assuming the size will be the same */
if (!tar_write_compressed_data(tar_data->currentfile->header, 512, true)) if (!tar_write_compressed_data(tar_data->currentfile->header,
TAR_BLOCK_SIZE, true))
return -1; return -1;
/* Turn compression back on */ /* Turn compression back on */
......
...@@ -893,7 +893,7 @@ _CloseArchive(ArchiveHandle *AH) ...@@ -893,7 +893,7 @@ _CloseArchive(ArchiveHandle *AH)
/* /*
* EOF marker for tar files is two blocks of NULLs. * EOF marker for tar files is two blocks of NULLs.
*/ */
for (i = 0; i < 512 * 2; i++) for (i = 0; i < TAR_BLOCK_SIZE * 2; i++)
{ {
if (fputc(0, ctx->tarFH) == EOF) if (fputc(0, ctx->tarFH) == EOF)
WRITE_ERROR_EXIT; WRITE_ERROR_EXIT;
...@@ -1113,7 +1113,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1113,7 +1113,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
buf1, buf2); buf1, buf2);
} }
pad = ((len + 511) & ~511) - len; pad = tarPaddingBytesRequired(len);
for (i = 0; i < pad; i++) for (i = 0; i < pad; i++)
{ {
if (fputc('\0', th->tarFH) == EOF) if (fputc('\0', th->tarFH) == EOF)
...@@ -1130,7 +1130,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) ...@@ -1130,7 +1130,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
TAR_MEMBER *th = pg_malloc0(sizeof(TAR_MEMBER)); TAR_MEMBER *th = pg_malloc0(sizeof(TAR_MEMBER));
char c; char c;
char header[512]; char header[TAR_BLOCK_SIZE];
size_t i, size_t i,
len, len,
blks; blks;
...@@ -1189,17 +1189,19 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) ...@@ -1189,17 +1189,19 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
th->targetFile, filename); th->targetFile, filename);
/* Header doesn't match, so read to next header */ /* Header doesn't match, so read to next header */
len = ((th->fileLen + 511) & ~511); /* Padded length */ len = th->fileLen;
blks = len >> 9; /* # of 512 byte blocks */ len += tarPaddingBytesRequired(th->fileLen);
blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */
for (i = 0; i < blks; i++) for (i = 0; i < blks; i++)
_tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH); _tarReadRaw(AH, &header[0], TAR_BLOCK_SIZE, NULL, ctx->tarFH);
if (!_tarGetHeader(AH, th)) if (!_tarGetHeader(AH, th))
fatal("could not find header for file \"%s\" in tar archive", filename); fatal("could not find header for file \"%s\" in tar archive", filename);
} }
ctx->tarNextMember = ctx->tarFHpos + ((th->fileLen + 511) & ~511); ctx->tarNextMember = ctx->tarFHpos + th->fileLen
+ tarPaddingBytesRequired(th->fileLen);
th->pos = 0; th->pos = 0;
return th; return th;
...@@ -1210,7 +1212,7 @@ static int ...@@ -1210,7 +1212,7 @@ static int
_tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
{ {
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
char h[512]; char h[TAR_BLOCK_SIZE];
char tag[100 + 1]; char tag[100 + 1];
int sum, int sum,
chk; chk;
...@@ -1223,12 +1225,12 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1223,12 +1225,12 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
/* Save the pos for reporting purposes */ /* Save the pos for reporting purposes */
hPos = ctx->tarFHpos; hPos = ctx->tarFHpos;
/* Read a 512 byte block, return EOF, exit if short */ /* Read the next tar block, return EOF, exit if short */
len = _tarReadRaw(AH, h, 512, NULL, ctx->tarFH); len = _tarReadRaw(AH, h, TAR_BLOCK_SIZE, NULL, ctx->tarFH);
if (len == 0) /* EOF */ if (len == 0) /* EOF */
return 0; return 0;
if (len != 512) if (len != TAR_BLOCK_SIZE)
fatal(ngettext("incomplete tar header found (%lu byte)", fatal(ngettext("incomplete tar header found (%lu byte)",
"incomplete tar header found (%lu bytes)", "incomplete tar header found (%lu bytes)",
len), len),
...@@ -1248,7 +1250,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1248,7 +1250,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
{ {
int i; int i;
for (i = 0; i < 512; i++) for (i = 0; i < TAR_BLOCK_SIZE; i++)
{ {
if (h[i] != 0) if (h[i] != 0)
{ {
...@@ -1294,12 +1296,12 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1294,12 +1296,12 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
static void static void
_tarWriteHeader(TAR_MEMBER *th) _tarWriteHeader(TAR_MEMBER *th)
{ {
char h[512]; char h[TAR_BLOCK_SIZE];
tarCreateHeader(h, th->targetFile, NULL, th->fileLen, tarCreateHeader(h, th->targetFile, NULL, th->fileLen,
0600, 04000, 02000, time(NULL)); 0600, 04000, 02000, time(NULL));
/* Now write the completed header. */ /* Now write the completed header. */
if (fwrite(h, 1, 512, th->tarFH) != 512) if (fwrite(h, 1, TAR_BLOCK_SIZE, th->tarFH) != TAR_BLOCK_SIZE)
WRITE_ERROR_EXIT; WRITE_ERROR_EXIT;
} }
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef PG_TAR_H
#define PG_TAR_H
#define TAR_BLOCK_SIZE 512
enum tarError enum tarError
{ {
...@@ -19,8 +23,23 @@ enum tarError ...@@ -19,8 +23,23 @@ enum tarError
TAR_SYMLINK_TOO_LONG TAR_SYMLINK_TOO_LONG
}; };
extern enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, extern enum tarError tarCreateHeader(char *h, const char *filename,
pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime); const char *linktarget, pgoff_t size,
mode_t mode, uid_t uid, gid_t gid,
time_t mtime);
extern uint64 read_tar_number(const char *s, int len); extern uint64 read_tar_number(const char *s, int len);
extern void print_tar_number(char *s, int len, uint64 val); extern void print_tar_number(char *s, int len, uint64 val);
extern int tarChecksum(char *header); extern int tarChecksum(char *header);
/*
* Compute the number of padding bytes required for an entry in a tar
* archive. We must pad out to a multiple of TAR_BLOCK_SIZE. Since that's
* a power of 2, we can use TYPEALIGN().
*/
static inline size_t
tarPaddingBytesRequired(size_t len)
{
return TYPEALIGN(TAR_BLOCK_SIZE, len) - len;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment