12 struct HFSDataObject
{
16 typedef struct HFSDataObject HFSDataObject
;
19 kHFSInfoHeaderVersion
= 1,
24 ({ __typeof(a) __a = (a); __typeof(b) __b = (b); \
25 __a < __b ? __a : __b; })
27 struct HFSInfoHeader
{
29 uint32_t deviceBlockSize
;
30 int64_t rawDeviceSize
;
31 int32_t size
; // Size of header
36 WriteExtent(gzFile outf
, DeviceInfo_t
*devp
, off_t start
, off_t len
)
38 const size_t bufSize
= 1024 * 1024;
39 uint8_t buffer
[bufSize
];
44 size_t amt
= MIN(bufSize
, len
- total
);
46 nread
= pread(devp
->fd
, buffer
, amt
, start
+ total
);
48 warn("Cannot read from device at offset %lld", start
+ total
);
52 warnx("Tried to read %zu bytes, only read %zd", amt
, nread
);
54 nwritten
= gzwrite(outf
, (char*)buffer
, amt
);
56 warn("tried to gzwrite %zu bytes", amt
);
58 } else if (nwritten
!= amt
) {
59 warnx("tried to gzwrite %zu bytes, only wrote %u", amt
, nwritten
);
68 WriteGatheredData(const char *pathname
, VolumeObjects_t
*vop
)
72 struct HFSInfoHeader hdr
= { 0 };
73 HFSDataObject
*objs
= NULL
, *op
;
77 hdr
.version
= S32(kHFSInfoHeaderVersion
);
78 hdr
.deviceBlockSize
= S32((uint32_t)vop
->devp
->blockSize
);
79 hdr
.rawDeviceSize
= S64(vop
->devp
->size
);
80 hdr
.objectCount
= S32(vop
->count
);
81 hdr
.size
= S32(sizeof(hdr
) + sizeof(HFSDataObject
) * vop
->count
);
83 objs
= malloc(sizeof(HFSDataObject
) * vop
->count
);
85 warn("Unable to allocate space for data objects (%zu bytes)", sizeof(HFSDataObject
)* vop
->count
);
94 for (i
= 0; i
< ep
->count
; i
++) {
95 op
->offset
= S64(ep
->extents
[i
].base
);
96 op
->size
= S64(ep
->extents
[i
].length
);
101 fd
= open(pathname
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
103 warn("cannot create gather file %s", pathname
);
106 outf
= gzdopen(fd
, "wb");
108 warn("Cannot create gz descriptor from file %s", pathname
);
113 gzwrite(outf
, &hdr
, sizeof(hdr
));
114 gzwrite(outf
, objs
, sizeof(HFSDataObject
) * vop
->count
);
121 for (i
= 0; i
< ep
->count
; i
++) {
123 fprintf(stderr
, "Writing extent <%lld, %lld>\n", ep
->extents
[i
].base
, ep
->extents
[i
].length
);
124 if (WriteExtent(outf
, vop
->devp
, ep
->extents
[i
].base
, ep
->extents
[i
].length
) == -1) {
126 fprintf(stderr
, "\tWrite failed\n");
133 if (count
!= vop
->count
)
134 fprintf(stderr
, "WHOAH! we're short by %zd objects!\n", vop
->count
- count
);