14 struct HFSDataObject
{
18 typedef struct HFSDataObject HFSDataObject
;
21 kHFSInfoHeaderVersion
= 1,
26 ({ __typeof(a) __a = (a); __typeof(b) __b = (b); \
27 __a < __b ? __a : __b; })
29 struct HFSInfoHeader
{
31 uint32_t deviceBlockSize
;
32 int64_t rawDeviceSize
;
33 int32_t size
; // Size of header
38 WriteExtent(gzFile outf
, DeviceInfo_t
*devp
, off_t start
, off_t len
)
40 const size_t bufSize
= 1024 * 1024;
41 uint8_t buffer
[bufSize
];
46 size_t amt
= MIN(bufSize
, len
- total
);
48 nread
= pread(devp
->fd
, buffer
, amt
, start
+ total
);
50 warn("Cannot read from device at offset %lld", start
+ total
);
54 warnx("Tried to read %zu bytes, only read %zd", amt
, nread
);
56 nwritten
= gzwrite(outf
, (char*)buffer
, (unsigned)amt
);
58 warn("tried to gzwrite %zu bytes", amt
);
60 } else if (nwritten
!= amt
) {
61 warnx("tried to gzwrite %zu bytes, only wrote %u", amt
, nwritten
);
70 WriteGatheredData(const char *pathname
, VolumeObjects_t
*vop
)
74 struct HFSInfoHeader hdr
= { 0 };
75 HFSDataObject
*objs
= NULL
, *op
;
80 hdr
.version
= S32(kHFSInfoHeaderVersion
);
81 hdr
.deviceBlockSize
= S32((uint32_t)vop
->devp
->blockSize
);
82 hdr
.rawDeviceSize
= S64(vop
->devp
->size
);
83 hdr
.objectCount
= S32(vop
->count
);
84 hdr
.size
= S32(sizeof(hdr
) + sizeof(HFSDataObject
) * vop
->count
);
86 objs
= malloc(sizeof(HFSDataObject
) * vop
->count
);
88 warn("Unable to allocate space for data objects (%zu bytes)", sizeof(HFSDataObject
)* vop
->count
);
97 for (i
= 0; i
< ep
->count
; i
++) {
98 op
->offset
= S64(ep
->extents
[i
].base
);
99 op
->size
= S64(ep
->extents
[i
].length
);
104 fd
= open(pathname
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
106 warn("cannot create gather file %s", pathname
);
109 outf
= gzdopen(fd
, "wb");
111 warn("Cannot create gz descriptor from file %s", pathname
);
116 gzwrite(outf
, &hdr
, sizeof(hdr
));
117 len
= sizeof(HFSDataObject
) * vop
->count
;
118 assert(len
< UINT_MAX
);
119 gzwrite(outf
, objs
, (unsigned)len
);
126 for (i
= 0; i
< ep
->count
; i
++) {
128 fprintf(stderr
, "Writing extent <%lld, %lld>\n", ep
->extents
[i
].base
, ep
->extents
[i
].length
);
129 if (WriteExtent(outf
, vop
->devp
, ep
->extents
[i
].base
, ep
->extents
[i
].length
) == -1) {
131 fprintf(stderr
, "\tWrite failed\n");
138 if (count
!= vop
->count
)
139 fprintf(stderr
, "WHOAH! we're short by %zd objects!\n", vop
->count
- count
);