diff options
author | Magnus Hagander <magnus@hagander.net> | 2013-01-01 18:15:57 +0100 |
---|---|---|
committer | Magnus Hagander <magnus@hagander.net> | 2013-01-01 18:15:57 +0100 |
commit | f5d4bdd3a5c1b7987a257b2a64e977501338af0d (patch) | |
tree | 2e0528df81881a91c687ac1551cd3a3883b47890 /src/backend/replication/basebackup.c | |
parent | a266f7dd93bcac8d8543df46efa2968226ddc81f (diff) | |
download | postgresql-f5d4bdd3a5c1b7987a257b2a64e977501338af0d.tar.gz postgresql-f5d4bdd3a5c1b7987a257b2a64e977501338af0d.zip |
Unify some tar functionality across different parts
Move some of the tar functionality that existed mostly duplicated
in both pg_dump and the walsender basebackup functionality into
port/tar.c instead, so it can be used from both. It will also be
used by pg_basebackup in the future, which would've caused a third
copy of it around.
Zoltan Boszormenyi and Magnus Hagander
Diffstat (limited to 'src/backend/replication/basebackup.c')
-rw-r--r-- | src/backend/replication/basebackup.c | 128 |
1 files changed, 3 insertions, 125 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index dcc242773db..b022367bbe3 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -741,48 +741,12 @@ sendDir(char *path, int basepathlen, bool sizeonly) /* - * Utility routine to print possibly larger than 32 bit integers in a - * portable fashion. Filled with zeros. - */ -static void -print_val(char *s, uint64 val, unsigned int base, size_t len) -{ - int i; - - for (i = len; i > 0; i--) - { - int digit = val % base; - - s[i - 1] = '0' + digit; - val = val / base; - } -} - -/* * Maximum file size for a tar member: The limit inherent in the * format is 2^33-1 bytes (nearly 8 GB). But we don't want to exceed * what we can represent in pgoff_t. */ #define MAX_TAR_MEMBER_FILELEN (((int64) 1 << Min(33, sizeof(pgoff_t)*8 - 1)) - 1) -static int -_tarChecksum(char *header) -{ - int i, - sum; - - /* - * 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++) - if (i < 148 || i >= 156) - sum += 0xFF & header[i]; - return sum; -} - /* * Given the member, write the TAR header & send the file. * @@ -874,95 +838,9 @@ _tarWriteHeader(const char *filename, const char *linktarget, { char h[512]; - /* - * 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)); - - /* Name 100 */ - sprintf(&h[0], "%.99s", filename); - if (linktarget != NULL || S_ISDIR(statbuf->st_mode)) - { - /* - * We only support symbolic links to directories, and this is - * indicated in the tar format by adding a slash at the end of the - * name, the same as for regular directories. - */ - int flen = strlen(filename); - - flen = Min(flen, 99); - h[flen] = '/'; - h[flen + 1] = '\0'; - } - - /* Mode 8 */ - sprintf(&h[100], "%07o ", (int) statbuf->st_mode); - - /* User ID 8 */ - sprintf(&h[108], "%07o ", statbuf->st_uid); - - /* Group 8 */ - sprintf(&h[116], "%07o ", statbuf->st_gid); - - /* File size 12 - 11 digits, 1 space; use print_val for 64 bit support */ - if (linktarget != NULL || S_ISDIR(statbuf->st_mode)) - /* Symbolic link or directory has size zero */ - print_val(&h[124], 0, 8, 11); - else - print_val(&h[124], statbuf->st_size, 8, 11); - sprintf(&h[135], " "); - - /* Mod Time 12 */ - sprintf(&h[136], "%011o ", (int) statbuf->st_mtime); - - /* Checksum 8 cannot be calculated until we've filled all other fields */ - - if (linktarget != NULL) - { - /* Type - Symbolic link */ - sprintf(&h[156], "2"); - /* Link Name 100 */ - sprintf(&h[157], "%.99s", linktarget); - } - else if (S_ISDIR(statbuf->st_mode)) - /* Type - directory */ - sprintf(&h[156], "5"); - else - /* Type - regular file */ - sprintf(&h[156], "0"); - - /* Magic 6 */ - sprintf(&h[257], "ustar"); - - /* Version 2 */ - sprintf(&h[263], "00"); - - /* User 32 */ - /* XXX: Do we need to care about setting correct username? */ - sprintf(&h[265], "%.31s", "postgres"); - - /* Group 32 */ - /* XXX: Do we need to care about setting correct group name? */ - sprintf(&h[297], "%.31s", "postgres"); - - /* Major Dev 8 */ - sprintf(&h[329], "%07o ", 0); - - /* Minor Dev 8 */ - sprintf(&h[337], "%07o ", 0); - - /* Prefix 155 - not used, leave as nulls */ - - /* - * 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)); + tarCreateHeader(h, filename, linktarget, statbuf->st_size, + statbuf->st_mode, statbuf->st_uid, statbuf->st_gid, + statbuf->st_mtime); - /* Now send the completed header. */ pq_putmessage('d', h, 512); } |