| 253 | } |
| 254 | |
| 255 | static int write_tar_entry(struct archiver_args *args, |
| 256 | const struct object_id *oid, |
| 257 | const char *path, size_t pathlen, |
| 258 | unsigned int mode, |
| 259 | void *buffer, unsigned long size) |
| 260 | { |
| 261 | struct ustar_header header; |
| 262 | struct strbuf ext_header = STRBUF_INIT; |
| 263 | unsigned long size_in_header; |
| 264 | int err = 0; |
| 265 | |
| 266 | memset(&header, 0, sizeof(header)); |
| 267 | |
| 268 | if (S_ISDIR(mode) || S_ISGITLINK(mode)) { |
| 269 | *header.typeflag = TYPEFLAG_DIR; |
| 270 | mode = (mode | 0777) & ~tar_umask; |
| 271 | } else if (S_ISLNK(mode)) { |
| 272 | *header.typeflag = TYPEFLAG_LNK; |
| 273 | mode |= 0777; |
| 274 | } else if (S_ISREG(mode)) { |
| 275 | *header.typeflag = TYPEFLAG_REG; |
| 276 | mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask; |
| 277 | } else { |
| 278 | return error(_("unsupported file mode: 0%o (SHA1: %s)"), |
| 279 | mode, oid_to_hex(oid)); |
| 280 | } |
| 281 | if (pathlen > sizeof(header.name)) { |
| 282 | size_t plen = get_path_prefix(path, pathlen, |
| 283 | sizeof(header.prefix)); |
| 284 | size_t rest = pathlen - plen - 1; |
| 285 | if (plen > 0 && rest <= sizeof(header.name)) { |
| 286 | memcpy(header.prefix, path, plen); |
| 287 | memcpy(header.name, path + plen + 1, rest); |
| 288 | } else { |
| 289 | xsnprintf(header.name, sizeof(header.name), "%s.data", |
| 290 | oid_to_hex(oid)); |
| 291 | strbuf_append_ext_header(&ext_header, "path", |
| 292 | path, pathlen); |
| 293 | } |
| 294 | } else |
| 295 | memcpy(header.name, path, pathlen); |
| 296 | |
| 297 | if (S_ISLNK(mode)) { |
| 298 | if (size > sizeof(header.linkname)) { |
| 299 | xsnprintf(header.linkname, sizeof(header.linkname), |
| 300 | "see %s.paxheader", oid_to_hex(oid)); |
| 301 | strbuf_append_ext_header(&ext_header, "linkpath", |
| 302 | buffer, size); |
| 303 | } else |
| 304 | memcpy(header.linkname, buffer, size); |
| 305 | } |
| 306 | |
| 307 | size_in_header = size; |
| 308 | if (S_ISREG(mode) && size > USTAR_MAX_SIZE) { |
| 309 | size_in_header = 0; |
| 310 | strbuf_append_ext_header_uint(&ext_header, "size", size); |
| 311 | } |
| 312 |
nothing calls this directly
no test coverage detected