+ return fds[1];
+}
+
+void Tarfile::tar_write(const char *data, size_t len)
+{
+ size += len;
+
+ while (len > 0) {
+ int res = write(filter->get_wrapped_fd(), data, len);
+
+ if (res < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "Write error: %m\n");
+ fatal("Write error");
+ }
+
+ len -= res;
+ data += res;
+ }
+}
+
+void Tarfile::write_object(int id, const char *data, size_t len)
+{
+ struct tar_header header;
+ memset(&header, 0, sizeof(header));
+
+ char buf[64];
+ sprintf(buf, "%08x", id);
+ string path = segment_name + "/" + buf;
+
+ assert(path.size() < 100);
+ memcpy(header.name, path.data(), path.size());
+ sprintf(header.mode, "%07o", 0600);
+ sprintf(header.uid, "%07o", 0);
+ sprintf(header.gid, "%07o", 0);
+ sprintf(header.size, "%011o", (int)len);
+ sprintf(header.mtime, "%011o", (int)time(NULL));
+ header.typeflag = '0';
+ strcpy(header.magic, "ustar ");
+ strcpy(header.uname, "root");
+ strcpy(header.gname, "root");
+
+ memset(header.chksum, ' ', sizeof(header.chksum));
+ int checksum = 0;
+ for (int i = 0; i < TAR_BLOCK_SIZE; i++) {
+ checksum += ((uint8_t *)&header)[i];
+ }
+ sprintf(header.chksum, "%06o", checksum);
+
+ tar_write((const char *)&header, TAR_BLOCK_SIZE);