@ -568,7 +568,7 @@ sendFileWithContent(const char *filename, const char *content)
/*
/*
* Include all files from the given directory in the output tar stream . If
* Include all files from the given directory in the output tar stream . If
* ' sizeonly ' is true , we just calculate a total length and return ig , without
* ' sizeonly ' is true , we just calculate a total length and return it , without
* actually sending anything .
* actually sending anything .
*/
*/
static int64
static int64
@ -763,11 +763,16 @@ _tarChecksum(char *header)
int i ,
int i ,
sum ;
sum ;
sum = 0 ;
/*
* Per POSIX , the checksum is the simple sum of all bytes in the header ,
* treating the bytes as unsigned , and treating the checksum field ( at
* offset 148 ) as though it contained 8 spaces .
*/
sum = 8 * ' ' ; /* presumed value for checksum field */
for ( i = 0 ; i < 512 ; i + + )
for ( i = 0 ; i < 512 ; i + + )
if ( i < 148 | | i > = 156 )
if ( i < 148 | | i > = 156 )
sum + = 0xFF & header [ i ] ;
sum + = 0xFF & header [ i ] ;
return sum + 256 ; /* Assume 8 blanks in checksum field */
return sum ;
}
}
/* Given the member, write the TAR header & send the file */
/* Given the member, write the TAR header & send the file */
@ -846,9 +851,13 @@ _tarWriteHeader(const char *filename, const char *linktarget,
struct stat * statbuf )
struct stat * statbuf )
{
{
char h [ 512 ] ;
char h [ 512 ] ;
int lastSum = 0 ;
int sum ;
/*
* Note : most of the fields in a tar header are not supposed to be
* null - terminated . We use sprintf , which will write a null after the
* required bytes ; that null goes into the first byte of the next field .
* This is okay as long as we fill the fields in order .
*/
memset ( h , 0 , sizeof ( h ) ) ;
memset ( h , 0 , sizeof ( h ) ) ;
/* Name 100 */
/* Name 100 */
@ -860,8 +869,11 @@ _tarWriteHeader(const char *filename, const char *linktarget,
* indicated in the tar format by adding a slash at the end of the
* indicated in the tar format by adding a slash at the end of the
* name , the same as for regular directories .
* name , the same as for regular directories .
*/
*/
h [ strlen ( filename ) ] = ' / ' ;
int flen = strlen ( filename ) ;
h [ strlen ( filename ) + 1 ] = ' \0 ' ;
flen = Min ( flen , 99 ) ;
h [ flen ] = ' / ' ;
h [ flen + 1 ] = ' \0 ' ;
}
}
/* Mode 8 */
/* Mode 8 */
@ -871,9 +883,9 @@ _tarWriteHeader(const char *filename, const char *linktarget,
sprintf ( & h [ 108 ] , " %07o " , statbuf - > st_uid ) ;
sprintf ( & h [ 108 ] , " %07o " , statbuf - > st_uid ) ;
/* Group 8 */
/* Group 8 */
sprintf ( & h [ 117 ] , " %07o " , statbuf - > st_gid ) ;
sprintf ( & h [ 116 ] , " %07o " , statbuf - > st_gid ) ;
/* File size 12 - 11 digits, 1 space, no NUL */
/* File size 12 - 11 digits, 1 space; use print_val for 64 bit support */
if ( linktarget ! = NULL | | S_ISDIR ( statbuf - > st_mode ) )
if ( linktarget ! = NULL | | S_ISDIR ( statbuf - > st_mode ) )
/* Symbolic link or directory has size zero */
/* Symbolic link or directory has size zero */
print_val ( & h [ 124 ] , 0 , 8 , 11 ) ;
print_val ( & h [ 124 ] , 0 , 8 , 11 ) ;
@ -884,13 +896,13 @@ _tarWriteHeader(const char *filename, const char *linktarget,
/* Mod Time 12 */
/* Mod Time 12 */
sprintf ( & h [ 136 ] , " %011o " , ( int ) statbuf - > st_mtime ) ;
sprintf ( & h [ 136 ] , " %011o " , ( int ) statbuf - > st_mtime ) ;
/* Checksum 8 */
/* Checksum 8 cannot be calculated until we've filled all other fields */
sprintf ( & h [ 148 ] , " %06o " , lastSum ) ;
if ( linktarget ! = NULL )
if ( linktarget ! = NULL )
{
{
/* Type - Symbolic link */
/* Type - Symbolic link */
sprintf ( & h [ 156 ] , " 2 " ) ;
sprintf ( & h [ 156 ] , " 2 " ) ;
/* Link Name 100 */
sprintf ( & h [ 157 ] , " %.99s " , linktarget ) ;
sprintf ( & h [ 157 ] , " %.99s " , linktarget ) ;
}
}
else if ( S_ISDIR ( statbuf - > st_mode ) )
else if ( S_ISDIR ( statbuf - > st_mode ) )
@ -900,10 +912,11 @@ _tarWriteHeader(const char *filename, const char *linktarget,
/* Type - regular file */
/* Type - regular file */
sprintf ( & h [ 156 ] , " 0 " ) ;
sprintf ( & h [ 156 ] , " 0 " ) ;
/* Link tag 100 (NULL) */
/* Magic 6 */
sprintf ( & h [ 257 ] , " ustar " ) ;
/* Magic 6 + Version 2 */
/* Version 2 */
sprintf ( & h [ 257 ] , " ustar 00" ) ;
sprintf ( & h [ 263 ] , " 00 " ) ;
/* User 32 */
/* User 32 */
/* XXX: Do we need to care about setting correct username? */
/* XXX: Do we need to care about setting correct username? */
@ -913,17 +926,21 @@ _tarWriteHeader(const char *filename, const char *linktarget,
/* XXX: Do we need to care about setting correct group name? */
/* XXX: Do we need to care about setting correct group name? */
sprintf ( & h [ 297 ] , " %.31s " , " postgres " ) ;
sprintf ( & h [ 297 ] , " %.31s " , " postgres " ) ;
/* Maj Dev 8 */
/* Major Dev 8 */
sprintf ( & h [ 329 ] , " %6 o " , 0 ) ;
sprintf ( & h [ 329 ] , " %07 o " , 0 ) ;
/* Min Dev 8 */
/* Minor Dev 8 */
sprintf ( & h [ 337 ] , " %6 o " , 0 ) ;
sprintf ( & h [ 337 ] , " %07 o " , 0 ) ;
while ( ( sum = _tarChecksum ( h ) ) ! = lastSum )
/* Prefix 155 - not used, leave as nulls */
{
sprintf ( & h [ 148 ] , " %06o " , sum ) ;
/*
lastSum = sum ;
* We mustn ' t overwrite the next field while inserting the checksum .
}
* Fortunately , the checksum can ' t exceed 6 octal digits , so we just write
* 6 digits , a space , and a null , which is legal per POSIX .
*/
sprintf ( & h [ 148 ] , " %06o " , _tarChecksum ( h ) ) ;
/* Now send the completed header. */
pq_putmessage ( ' d ' , h , 512 ) ;
pq_putmessage ( ' d ' , h , 512 ) ;
}
}