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 }