+ #include <stdint.h>
+ #include <unistd.h> /* read() */
+ #include <fcntl.h> /* open() */
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
+
+ #include "change.h"
+
+ /** Read a uint64_t from byte buffer as little endian */
+ #define legetu64(buf) (((uint64_t)buf[7]) << 56 | (uint64_t)buf[6] << 48 | (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]);
+
+ int
+ decode_offsets(int fd, struct offsets *off)
+ {
+ /* */
+ ssize_t r;
+ uint8_t buf[OFFSETS_SIZE];
+ uint8_t *bufp;
+
+ if ((r = read(fd, buf, OFFSETS_SIZE)) < OFFSETS_SIZE) {
+ int err;
+ if (r >= 0) {
+ printf("error: not enough was read: %ld\n", r);
+ err = -2;
+ } else {
+ printf("error: not enough was read: %ld\n", r);
+ err = -1;
+ }
+ return err;
+ }
+ bufp = (uint8_t *)buf;
+ off->version = legetu64(bufp);
+ bufp += 8;
+ off->hashed_len = legetu64(bufp)
+ bufp += 8;
+ off->unhashed_off = legetu64(bufp)
+ bufp += 8;
+ off->unhashed_len = legetu64(bufp)
+ bufp += 8;
+ off->contents_off = legetu64(bufp)
+ bufp += 8;
+ off->contents_len = legetu64(bufp)
+ bufp += 8;
+ off->total = legetu64(bufp)
+
+ return 0;
+ }
+
+
+ int
+ change()
+ {
+ int fd;
+ int err;
+ struct offsets off;
+
+ /* FIXME: A very fixed example */
+ fd = open(
+ ".pijul/changes/AH/IXA5ZESN6QJXV2LKRSC4H5ZRFMJFHFPY2RQRARTH3XJLLCMCGQC.change",
+ O_RDONLY
+ );
+ if (fd == -1) {
+ printf("error: %s\n", strerror(errno));
+ return -1;
+ }
+
+ err = decode_offsets(fd, &off);
+ if (err != 0) {
+ printf("error: failed to decode offsets\n");
+ goto out;
+ }
+ printf("version : %lu\n", off.version);
+ printf("hashed_len : %lu\n", off.hashed_len);
+ printf("unhashed_off : %lu\n", off.unhashed_off);
+ printf("unhashed_len : %lu\n", off.unhashed_len);
+ printf("contents_off : %lu\n", off.contents_off);
+ printf("contents_len : %lu\n", off.contents_len);
+ printf("total : %lu\n", off.total);
+
+ out:
+ close(fd);
+ return err;
+ }
+
+ int cmd_change(int argc, const char **argv)
+ {
+ /* FIXME: Add argument handling */
+ return change();
+ }