archive-tar: turn write_tar_entry into blob-writing only
Before this patch write_tar_entry() can: - write global header by write_global_extended_header() calling write_tar_entry with with both sha1 and path == NULL - write extended header for symlinks, by write_tar_entry() calling itself with sha1 != NULL and path == NULL - write a normal blob. In this case both sha1 and path are valid. After this patch, the first two call sites are modified to write the header without calling write_tar_entry(). The function is now for writing blobs only. This simplifies handling when write_tar_entry() learns about large blobs. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
May 3, 2012 at 08:51 UTC
d240d4102103215e9fe38431b1702a4024d2f1a7
1 file changed
+52
-26
archive-tar.c
+52
-26
@@ -123,6 +123,43 @@ static size_t get_path_prefix(const char *path, size_t pathlen, size_t maxlen)
123
return i;
124
}
125
126
+static void prepare_header(struct archiver_args *args,
127
+ struct ustar_header *header,
128
+ unsigned int mode, unsigned long size)
129
+{
130
+ sprintf(header->mode, "%07o", mode & 07777);
131
+ sprintf(header->size, "%011lo", S_ISREG(mode) ? size : 0);
132
+ sprintf(header->mtime, "%011lo", (unsigned long) args->time);
133
+
134
+ sprintf(header->uid, "%07o", 0);
135
+ sprintf(header->gid, "%07o", 0);
136
+ strlcpy(header->uname, "root", sizeof(header->uname));
137
+ strlcpy(header->gname, "root", sizeof(header->gname));
138
+ sprintf(header->devmajor, "%07o", 0);
139
+ sprintf(header->devminor, "%07o", 0);
140
+
141
+ memcpy(header->magic, "ustar", 6);
142
+ memcpy(header->version, "00", 2);
143
+
144
+ sprintf(header->chksum, "%07o", ustar_header_chksum(header));
145
+}
146
+
147
+static int write_extended_header(struct archiver_args *args,
148
+ const unsigned char *sha1,
149
+ const void *buffer, unsigned long size)
150
+{
151
+ struct ustar_header header;
152
+ unsigned int mode;
153
+ memset(&header, 0, sizeof(header));
154
+ *header.typeflag = TYPEFLAG_EXT_HEADER;
155
+ mode = 0100666;
156
+ sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
157
+ prepare_header(args, &header, mode, size);
158
+ write_blocked(&header, sizeof(header));
159
+ write_blocked(buffer, size);
160
+ return 0;
161
+}
162
+
163
static int write_tar_entry(struct archiver_args *args,
164
const unsigned char *sha1, const char *path, size_t pathlen,
165
unsigned int mode, void *buffer, unsigned long size)
@@ -134,13 +171,9 @@ static int write_tar_entry(struct archiver_args *args,
171
memset(&header, 0, sizeof(header));
172
173
if (!sha1) {
137
- *header.typeflag = TYPEFLAG_GLOBAL_HEADER;
138
- mode = 0100666;
139
- strcpy(header.name, "pax_global_header");
174
+ die("BUG: sha1 == NULL is not supported");
175
} else if (!path) {
141
- *header.typeflag = TYPEFLAG_EXT_HEADER;
142
- mode = 0100666;
143
- sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
176
+ die("BUG: path == NULL is not supported");
177
} else {
178
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
179
*header.typeflag = TYPEFLAG_DIR;
@@ -182,25 +215,11 @@ static int write_tar_entry(struct archiver_args *args,
215
memcpy(header.linkname, buffer, size);
216
}
217
185
- sprintf(header.mode, "%07o", mode & 07777);
186
- sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
187
- sprintf(header.mtime, "%011lo", (unsigned long) args->time);
188
-
189
- sprintf(header.uid, "%07o", 0);
190
- sprintf(header.gid, "%07o", 0);
191
- strlcpy(header.uname, "root", sizeof(header.uname));
192
- strlcpy(header.gname, "root", sizeof(header.gname));
193
- sprintf(header.devmajor, "%07o", 0);
194
- sprintf(header.devminor, "%07o", 0);
195
-
196
- memcpy(header.magic, "ustar", 6);
197
- memcpy(header.version, "00", 2);
198
-
199
- sprintf(header.chksum, "%07o", ustar_header_chksum(&header));
218
+ prepare_header(args, &header, mode, size);
219
220
if (ext_header.len > 0) {
202
- err = write_tar_entry(args, sha1, NULL, 0, 0, ext_header.buf,
203
- ext_header.len);
221
+ err = write_extended_header(args, sha1, ext_header.buf,
222
+ ext_header.len);
223
if (err)
224
return err;
225
}
@@ -215,11 +234,18 @@ static int write_global_extended_header(struct archiver_args *args)
234
{
235
const unsigned char *sha1 = args->commit_sha1;
236
struct strbuf ext_header = STRBUF_INIT;
218
- int err;
237
+ struct ustar_header header;
238
+ unsigned int mode;
239
+ int err = 0;
240
241
strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
221
- err = write_tar_entry(args, NULL, NULL, 0, 0, ext_header.buf,
222
- ext_header.len);
242
+ memset(&header, 0, sizeof(header));
243
+ *header.typeflag = TYPEFLAG_GLOBAL_HEADER;
244
+ mode = 0100666;
245
+ strcpy(header.name, "pax_global_header");
246
+ prepare_header(args, &header, mode, ext_header.len);
247
+ write_blocked(&header, sizeof(header));
248
+ write_blocked(ext_header.buf, ext_header.len);
249
strbuf_release(&ext_header);
250
return err;
251
}