PostgreSQL Source Code
git master
Toggle main menu visibility
Main Page
Related Pages
Namespaces
Namespace List
Namespace Members
All
a
c
d
g
h
i
k
l
m
p
r
s
t
Functions
Variables
Data Structures
Data Structures
Data Structure Index
Class Hierarchy
Data Fields
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
~
Functions
_
a
c
d
f
h
i
n
o
p
r
s
t
~
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Enumerations
Files
File List
Globals
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Functions
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Typedefs
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
Enumerations
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Enumerator
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
Macros
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
tar.c
Go to the documentation of this file.
1
#include "
c.h
"
2
3
#include <sys/stat.h>
4
5
#include "
pgtar.h
"
6
7
/*
8
* Print a numeric field in a tar header. The field starts at *s and is of
9
* length len; val is the value to be written.
10
*
11
* Per POSIX, the way to write a number is in octal with leading zeroes and
12
* one trailing space (or NUL, but we use space) at the end of the specified
13
* field width.
14
*
15
* However, the given value may not fit in the available space in octal form.
16
* If that's true, we use the GNU extension of writing \200 followed by the
17
* number in base-256 form (ie, stored in binary MSB-first). (Note: here we
18
* support only non-negative numbers, so we don't worry about the GNU rules
19
* for handling negative numbers.)
20
*/
21
void
22
print_tar_number
(
char
*s,
int
len
,
uint64
val
)
23
{
24
if
(
val
< (((
uint64
) 1) << ((
len
- 1) * 3)))
25
{
26
/* Use octal with trailing space */
27
s[--
len
] =
' '
;
28
while
(
len
)
29
{
30
s[--
len
] = (
val
& 7) +
'0'
;
31
val
>>= 3;
32
}
33
}
34
else
35
{
36
/* Use base-256 with leading \200 */
37
s[0] =
'\200'
;
38
while
(
len
> 1)
39
{
40
s[--
len
] = (
val
& 255);
41
val
>>= 8;
42
}
43
}
44
}
45
46
47
/*
48
* Read a numeric field in a tar header. The field starts at *s and is of
49
* length len.
50
*
51
* The POSIX-approved format for a number is octal, ending with a space or
52
* NUL. However, for values that don't fit, we recognize the GNU extension
53
* of \200 followed by the number in base-256 form (ie, stored in binary
54
* MSB-first). (Note: here we support only non-negative numbers, so we don't
55
* worry about the GNU rules for handling negative numbers.)
56
*/
57
uint64
58
read_tar_number
(
const
char
*s,
int
len
)
59
{
60
uint64
result = 0;
61
62
if
(*s ==
'\200'
)
63
{
64
/* base-256 */
65
while
(--
len
)
66
{
67
result <<= 8;
68
result |= (
unsigned
char) (*++s);
69
}
70
}
71
else
72
{
73
/* octal */
74
while
(
len
-- && *s >=
'0'
&& *s <=
'7'
)
75
{
76
result <<= 3;
77
result |= (*s -
'0'
);
78
s++;
79
}
80
}
81
return
result;
82
}
83
84
85
/*
86
* Calculate the tar checksum for a header. The header is assumed to always
87
* be 512 bytes, per the tar standard.
88
*/
89
int
90
tarChecksum
(
char
*header)
91
{
92
int
i
,
93
sum;
94
95
/*
96
* Per POSIX, the checksum is the simple sum of all bytes in the header,
97
* treating the bytes as unsigned, and treating the checksum field (at
98
* offset 148) as though it contained 8 spaces.
99
*/
100
sum = 8 *
' '
;
/* presumed value for checksum field */
101
for
(
i
= 0;
i
< 512;
i
++)
102
if
(i < 148 || i >= 156)
103
sum += 0xFF & header[
i
];
104
return
sum;
105
}
106
107
108
/*
109
* Fill in the buffer pointed to by h with a tar format header. This buffer
110
* must always have space for 512 characters, which is a requirement of
111
* the tar format.
112
*/
113
enum
tarError
114
tarCreateHeader
(
char
*h,
const
char
*
filename
,
const
char
*linktarget,
115
pgoff_t
size, mode_t
mode
,
uid_t
uid,
gid_t
gid, time_t mtime)
116
{
117
if
(strlen(
filename
) > 99)
118
return
TAR_NAME_TOO_LONG
;
119
120
if
(linktarget && strlen(linktarget) > 99)
121
return
TAR_SYMLINK_TOO_LONG
;
122
123
memset(h, 0,
TAR_BLOCK_SIZE
);
124
125
/* Name 100 */
126
strlcpy
(&h[
TAR_OFFSET_NAME
],
filename
, 100);
127
if
(linktarget != NULL ||
S_ISDIR
(
mode
))
128
{
129
/*
130
* We only support symbolic links to directories, and this is
131
* indicated in the tar format by adding a slash at the end of the
132
* name, the same as for regular directories.
133
*/
134
int
flen = strlen(
filename
);
135
136
flen =
Min
(flen, 99);
137
h[flen] =
'/'
;
138
h[flen + 1] =
'\0'
;
139
}
140
141
/* Mode 8 - this doesn't include the file type bits (S_IFMT) */
142
print_tar_number
(&h[
TAR_OFFSET_MODE
], 8, (
mode
& 07777));
143
144
/* User ID 8 */
145
print_tar_number
(&h[
TAR_OFFSET_UID
], 8, uid);
146
147
/* Group 8 */
148
print_tar_number
(&h[
TAR_OFFSET_GID
], 8, gid);
149
150
/* File size 12 */
151
if
(linktarget != NULL ||
S_ISDIR
(
mode
))
152
/* Symbolic link or directory has size zero */
153
print_tar_number
(&h[
TAR_OFFSET_SIZE
], 12, 0);
154
else
155
print_tar_number
(&h[
TAR_OFFSET_SIZE
], 12, size);
156
157
/* Mod Time 12 */
158
print_tar_number
(&h[
TAR_OFFSET_MTIME
], 12, mtime);
159
160
/* Checksum 8 cannot be calculated until we've filled all other fields */
161
162
if
(linktarget != NULL)
163
{
164
/* Type - Symbolic link */
165
h[
TAR_OFFSET_TYPEFLAG
] =
TAR_FILETYPE_SYMLINK
;
166
/* Link Name 100 */
167
strlcpy
(&h[
TAR_OFFSET_LINKNAME
], linktarget, 100);
168
}
169
else
if
(
S_ISDIR
(
mode
))
170
{
171
/* Type - directory */
172
h[
TAR_OFFSET_TYPEFLAG
] =
TAR_FILETYPE_DIRECTORY
;
173
}
174
else
175
{
176
/* Type - regular file */
177
h[
TAR_OFFSET_TYPEFLAG
] =
TAR_FILETYPE_PLAIN
;
178
}
179
180
/* Magic 6 */
181
strcpy(&h[
TAR_OFFSET_MAGIC
],
"ustar"
);
182
183
/* Version 2 */
184
memcpy(&h[
TAR_OFFSET_VERSION
],
"00"
, 2);
185
186
/* User 32 */
187
/* XXX: Do we need to care about setting correct username? */
188
strlcpy
(&h[
TAR_OFFSET_UNAME
],
"postgres"
, 32);
189
190
/* Group 32 */
191
/* XXX: Do we need to care about setting correct group name? */
192
strlcpy
(&h[
TAR_OFFSET_GNAME
],
"postgres"
, 32);
193
194
/* Major Dev 8 */
195
print_tar_number
(&h[
TAR_OFFSET_DEVMAJOR
], 8, 0);
196
197
/* Minor Dev 8 */
198
print_tar_number
(&h[
TAR_OFFSET_DEVMINOR
], 8, 0);
199
200
/* Prefix 155 - not used, leave as nulls */
201
202
/* Finally, compute and insert the checksum */
203
print_tar_number
(&h[
TAR_OFFSET_CHECKSUM
], 8,
tarChecksum
(h));
204
205
return
TAR_OK
;
206
}
c.h
Min
#define Min(x, y)
Definition:
c.h:975
uint64
uint64_t uint64
Definition:
c.h:503
val
long val
Definition:
informix.c:689
i
int i
Definition:
isn.c:77
mode
static PgChecksumMode mode
Definition:
pg_checksums.c:55
len
const void size_t len
Definition:
pg_crc32c_sse42.c:28
filename
static char * filename
Definition:
pg_dumpall.c:123
pgtar.h
TAR_FILETYPE_SYMLINK
@ TAR_FILETYPE_SYMLINK
Definition:
pgtar.h:61
TAR_FILETYPE_DIRECTORY
@ TAR_FILETYPE_DIRECTORY
Definition:
pgtar.h:62
TAR_FILETYPE_PLAIN
@ TAR_FILETYPE_PLAIN
Definition:
pgtar.h:60
TAR_OFFSET_DEVMINOR
@ TAR_OFFSET_DEVMINOR
Definition:
pgtar.h:53
TAR_OFFSET_MODE
@ TAR_OFFSET_MODE
Definition:
pgtar.h:40
TAR_OFFSET_VERSION
@ TAR_OFFSET_VERSION
Definition:
pgtar.h:49
TAR_OFFSET_DEVMAJOR
@ TAR_OFFSET_DEVMAJOR
Definition:
pgtar.h:52
TAR_OFFSET_UID
@ TAR_OFFSET_UID
Definition:
pgtar.h:41
TAR_OFFSET_TYPEFLAG
@ TAR_OFFSET_TYPEFLAG
Definition:
pgtar.h:46
TAR_OFFSET_NAME
@ TAR_OFFSET_NAME
Definition:
pgtar.h:39
TAR_OFFSET_SIZE
@ TAR_OFFSET_SIZE
Definition:
pgtar.h:43
TAR_OFFSET_GNAME
@ TAR_OFFSET_GNAME
Definition:
pgtar.h:51
TAR_OFFSET_CHECKSUM
@ TAR_OFFSET_CHECKSUM
Definition:
pgtar.h:45
TAR_OFFSET_GID
@ TAR_OFFSET_GID
Definition:
pgtar.h:42
TAR_OFFSET_LINKNAME
@ TAR_OFFSET_LINKNAME
Definition:
pgtar.h:47
TAR_OFFSET_MTIME
@ TAR_OFFSET_MTIME
Definition:
pgtar.h:44
TAR_OFFSET_UNAME
@ TAR_OFFSET_UNAME
Definition:
pgtar.h:50
TAR_OFFSET_MAGIC
@ TAR_OFFSET_MAGIC
Definition:
pgtar.h:48
tarError
tarError
Definition:
pgtar.h:20
TAR_SYMLINK_TOO_LONG
@ TAR_SYMLINK_TOO_LONG
Definition:
pgtar.h:23
TAR_OK
@ TAR_OK
Definition:
pgtar.h:21
TAR_NAME_TOO_LONG
@ TAR_NAME_TOO_LONG
Definition:
pgtar.h:22
TAR_BLOCK_SIZE
#define TAR_BLOCK_SIZE
Definition:
pgtar.h:17
pgoff_t
#define pgoff_t
Definition:
port.h:401
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition:
strlcpy.c:45
read_tar_number
uint64 read_tar_number(const char *s, int len)
Definition:
tar.c:58
tarChecksum
int tarChecksum(char *header)
Definition:
tar.c:90
tarCreateHeader
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)
Definition:
tar.c:114
print_tar_number
void print_tar_number(char *s, int len, uint64 val)
Definition:
tar.c:22
S_ISDIR
#define S_ISDIR(m)
Definition:
win32_port.h:315
gid_t
int gid_t
Definition:
win32_port.h:235
uid_t
int uid_t
Definition:
win32_port.h:234
src
port
tar.c
Generated on Sun Apr 27 2025 18:13:27 for PostgreSQL Source Code by
1.9.4