diff --git a/include/haggis.h b/include/haggis.h index a0eb9ce..9cad369 100644 --- a/include/haggis.h +++ b/include/haggis.h @@ -34,22 +34,35 @@ #define HAGGIS_H #include +#include -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; typedef uint8_t u8; -u64 le_bytes_to_u64(u8 arr[8]); -u32 le_bytes_to_u32(u8 arr[4]); -u16 le_bytes_to_u16(u8 arr[2]); -void u64_to_le_bytes(u64 num, u8 arr[8]); -void u32_to_le_bytes(u32 num, u8 arr[4]); -void u16_to_le_bytes(u16 num, u8 arr[2]); +union u16 { + uint16_t val; + u8 bytes[2]; +}; + +union u32 { + uint32_t val; + u8 bytes[4]; +}; + +union u64 { + uint64_t val; + u8 bytes[8]; +}; + +int load_u16(FILE *stream, union u16 num); +int store_u16(FILE *stream, union u16 num); +int load_u32(FILE *stream, union u32 num); +int store_u32(FILE *stream, union u32 num); +int load_u64(FILE *stream, union u64 num); +int store_u64(FILE *stream, union u64 num); struct haggis_device { - uint32_t major; - uint32_t minor; + union u32 major; + union u32 minor; }; enum haggis_algorithm { @@ -60,9 +73,9 @@ enum haggis_algorithm { }; union haggis_sum { - char md5[16]; - char sha1[20]; - char sha256[32]; + u8 md5[16]; + u8 sha1[20]; + u8 sha256[32]; }; struct haggis_checksum { @@ -70,10 +83,15 @@ struct haggis_checksum { union haggis_sum *sum; }; -struct haggis_normal { - uint64_t len; +struct haggis_file { + union u64 len; struct haggis_checksum *cksum; - unsigned char *data[]; + u8 *data[]; +}; + +struct haggis_filename { + union u16 len; + u8 name[4096]; }; enum haggis_typeflag { @@ -88,8 +106,8 @@ enum haggis_typeflag { }; union haggis_ft { - struct haggis_normal *file; - char target[4096]; + struct haggis_file *file; + struct haggis_filename *target; struct haggis_device *dev; }; @@ -99,10 +117,10 @@ struct haggis_filetype { }; struct haggis_node { - uint32_t uid; - uint32_t gid; - uint64_t mtime; - uint16_t mode; + union u32 uid; + union u32 gid; + union u64 mtime; + union u16 mode; struct haggis_filetype *filetype; char *name[]; }; diff --git a/src/bytes.c b/src/bytes.c index 0ca9290..e7b4caa 100644 --- a/src/bytes.c +++ b/src/bytes.c @@ -1,3 +1,35 @@ +/* _,.---._ .-._ .--.-. ,--.--------. + * _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ + * /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ + * |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ + * |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ + * |==|,| | -|==| , '=' |==| - _ | |==|- | + * |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | + * |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ + * `-.`.____.' `--`--'' `--`./ `--` `--`--` + * _ __ ,---. .-._ .=-.-. _,.----. + * .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ + * /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' + * |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . + * |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ + * |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | + * |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / + * /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' + * `--`---' `--` `--`./ `--``--`-` + * + * @(#)Copyright (c) 2023, Nathan D. Fisher. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies and that due credit be given + * to the author. + * 2/ that any changes to this code are clearly commented + * as such so that the author does not get blamed for bugs + * other than his own. + */ + #include #include #include @@ -5,121 +37,92 @@ #include "haggis.h" #if __BYTE_ORDER__ == __LITTLE_ENDIAN -u64 le_bytes_to_u64(u8 arr[8]) { - return (u64)arr[7] << 56 | - (u64)arr[6] << 48 | - (u64)arr[5] << 40 | - (u64)arr[4] << 32 | - (u64)arr[3] << 24 | - (u64)arr[2] << 16 | - (u64)arr[1] << 8 | - (u64)arr[0]; +int load_u16(FILE *stream, union u16 num) { + return fread(num.bytes, 1, 2, stream); } -u32 le_bytes_to_u32(u8 arr[4]) { - return (u32)arr[3] << 24 | - (u32)arr[2] << 16 | - (u32)arr[1] << 8 | - (u32)arr[0]; +int store_u16(FILE *stream, union u16 num) { + return fwrite(num.bytes, 1, 2, stream); } -u16 le_bytes_to_u16(u8 arr[2]) { - return (u32)arr[1] << 8 | (u32)arr[0]; +int load_u32(FILE *stream, union u32 num) { + return fread(num.bytes, 1, 4, stream); } -void u64_to_le_bytes(u64 num, u8 arr[8]) { - u64 eighth = (num & 0xFF00000000000000) >> 56; - u64 seventh = (num & 0xFF000000000000) >> 48; - u64 sixth = (num & 0xFF0000000000) >> 40; - u64 fifth = (num & 0xFF00000000) >> 32; - u64 fourth = (num & 0xFF000000) >> 24; - u64 third = (num & 0xFF0000) >> 16; - u64 second = (num & 0xFF00) >> 8; - u64 first = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; - arr[2] = (u8)third; - arr[3] = (u8)fourth; - arr[4] = (u8)fifth; - arr[5] = (u8)sixth; - arr[6] = (u8)seventh; - arr[7] = (u8)eighth; +int store_u32(FILE *stream, union u32 num) { + return fwrite(num.bytes, 1, 4, stream); } -void u32_to_le_bytes(u32 num, u8 arr[4]) { - u32 fourth = (num & 0xFF000000) >> 24; - u32 third = (num & 0xFF0000) >> 16; - u32 second = (num & 0xFF00) >> 8; - u32 first = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; - arr[2] = (u8)third; - arr[3] = (u8)fourth; +int load_u64(FILE *stream, union u64 num) { + return fread(num.bytes, 1, 8, stream); } -void u16_to_le_bytes(u16 num, u8 arr[2]) { - u16 second = (num & 0xFF00) >> 8; - u16 first = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; +int store_u64(FILE *stream, union u64 num) { + return fwrite(num.bytes, 1, 8, stream); } #else -u64 le_bytes_to_u64(u8 arr[8]) { - return (u64)arr[0] << 56 | - (u64)arr[1] << 48 | - (u64)arr[2] << 40 | - (u64)arr[3] << 32 | - (u64)arr[4] << 24 | - (u64)arr[5] << 16 | - (u64)arr[6] << 8 | - (u64)arr[7]; +int load_u16(FILE *stream, union u16 num) { + u8 buf[2]; + int res = fread(buf, 1, 2, stream); + if (res != 2) + return res; + num.bytes[0] = buf[1]; + num.bytes[1] = buf[0]; + return res; } -u32 le_bytes_to_u32(u8 arr[4]) { - return (u32)arr[0] << 24 | - (u32)arr[1] << 16 | - (u32)arr[2] << 8 | - (u32)arr[3]; +int store_u16(FILE * stream, union u16 num) { + u8 buf[2]; + buf[0] = num.bytes[1]; + buf[1] = num.bytes[0]; + return fwrite(buf, 1, 2, stream); } -u16 le_bytes_to_u16(u8 arr[2]) { - return (u32)arr[0] << 8 | (u32)arr[1]; +int load_u32(FILE *stream, union u32 num) { + u8 buf[4]; + int res = fread(buf, 1, 4, stream); + if (res != 4) + return res; + num.bytes[0] = buf[3]; + num.bytes[1] = buf[2]; + num.bytes[2] = buf[1]; + num.bytes[3] = buf[0]; } -void u64_to_le_bytes(u64 num, u8 arr[8]) { - u64 first = (num & 0xFF00000000000000) >> 56; - u64 second = (num & 0xFF000000000000) >> 48; - u64 third = (num & 0xFF0000000000) >> 40; - u64 fourth = (num & 0xFF00000000) >> 32; - u64 fifth = (num & 0xFF000000) >> 24; - u64 sixth = (num & 0xFF0000) >> 16; - u64 seventh = (num & 0xFF00) >> 8; - u64 eighth = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; - arr[2] = (u8)third; - arr[3] = (u8)fourth; - arr[4] = (u8)fifth; - arr[5] = (u8)sixth; - arr[6] = (u8)seventh; - arr[7] = (u8)eighth; +int store_u32(FILE *stream, union u32 num) { + u8 buf[4]; + buf[0] = num.bytes[3]; + buf[1] = num.bytes[2]; + buf[2] = num.bytes[1]; + buf[3] = num.bytes[0]; + return fwrite(buf, 1, 2, stream); } -void u32_to_le_bytes(u32 num, u8 arr[4]) { - u32 first = (num & 0xFF000000) >> 24; - u32 second = (num & 0xFF0000) >> 16; - u32 third = (num & 0xFF00) >> 8; - u32 fourth = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; - arr[2] = (u8)third; - arr[3] = (u8)fourth; +int load_u64(FILE *stream, union u64 num) { + u8 buf[8]; + int res = fread(buf, 1, 8, stream); + if (res != 8) + return res; + num.bytes[0] = buf[7]; + num.bytes[1] = buf[6]; + num.bytes[2] = buf[5]; + num.bytes[3] = buf[4]; + num.bytes[4] = buf[3]; + num.bytes[5] = buf[2]; + num.bytes[6] = buf[1]; + num.bytes[7] = buf[0]; } -void u16_to_le_bytes(u16 num, u8 arr[2]) { - u16 first = (num & 0xFF00) >> 8; - u16 second = num & 0xFF; - arr[0] = (u8)first; - arr[1] = (u8)second; +int store_u64(FILE *stream, union u64 num) { + u8 buf[8]; + buf[0] = num.bytes[7]; + buf[1] = num.bytes[6]; + buf[2] = num.bytes[5]; + buf[3] = num.bytes[4]; + buf[4] = num.bytes[3]; + buf[5] = num.butes[2]; + buf[6] = num.bytes[1]; + buf[7] = num.bytes[0]; + return fwrite(buf, 1, 2, stream); } #endif diff --git a/src/haggis.c b/src/haggis.c index e56ce9d..9d07cee 100644 --- a/src/haggis.c +++ b/src/haggis.c @@ -30,6 +30,7 @@ * other than his own. */ +#include #include #include @@ -53,26 +54,18 @@ int haggis_check_header(FILE *stream) { } int haggis_store_device(FILE *stream, struct haggis_device *dev) { - u8 major[4]; - u8 minor[4]; - u32_to_le_bytes(dev->major, major); - u32_to_le_bytes(dev->minor, minor); - if (fwrite(major, 1, 4, stream) != 4) + if (fwrite(dev->major.bytes, 1, 4, stream) != 4) return 1; - if (fwrite(minor, 1, 4, stream) != 4) + if (fwrite(dev->minor.bytes, 1, 4, stream) != 4) return 1; return 0; } int haggis_load_device(FILE *stream, struct haggis_device *dev) { - u8 major[4]; - u8 minor[4]; - if (fread(major, 1, 4, stream) != 4) + if (fread(dev->major.bytes, 1, 4, stream) != 4) return 1; - if (fread(minor, 1, 4, stream) != 4) + if (fread(dev->minor.bytes, 1, 4, stream) != 4) return 1; - dev->major = le_bytes_to_u32(major); - dev->minor = le_bytes_to_u32(minor); return 0; } @@ -110,7 +103,6 @@ int haggis_store_cksum(FILE *stream, struct haggis_checksum *cksum) { } int haggis_load_cksum(FILE *stream, struct haggis_checksum *cksum) { - // todo char flag; if (fread(&flag, 1, 1, stream) != 1) return 1; @@ -137,18 +129,94 @@ int haggis_load_cksum(FILE *stream, struct haggis_checksum *cksum) { return 0; } -int haggis_store_file(FILE *stream, struct haggis_normal *file) { +int haggis_validate_cksum(struct haggis_file *file) { // todo return 0; } -int haggis_load_file(FILE *stream, struct haggis_normal *file) { - // todo +int haggis_store_file(FILE *stream, struct haggis_file *file) { + if (store_u64(stream, file->len) != 8) + return 1; + if (haggis_store_cksum(stream, file->cksum) != 0) + return 1; + int res = fwrite(file->data, 1, (size_t)file->len.val, stream); + if (res != (size_t)file->len.val) + return 1; return 0; } +int haggis_load_file(FILE *stream, struct haggis_file *file) { + if (load_u64(stream, file->len) != 8) + return 1; + if (haggis_load_cksum(stream, file->cksum) != 0) + return 1; + int res = fread(file->data, 1, (size_t)file->len.val, stream); + if (res != (size_t)file->len.val) + return 1; + return haggis_validate_cksum(file); +} + int haggis_store_filetype(FILE *stream, struct haggis_filetype *filetype) { - // todo + size_t len; + u8 flag; + int res; + + switch (filetype->tag) { + case normal: + flag = 0; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + if (haggis_store_file(stream, filetype->f_type->file) != 0) + return 1; + break; + case hardlink: + flag = 1; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + len = (size_t)filetype->f_type->target->len.val; + res = fwrite(filetype->f_type->target->name, 1, len, stream); + if (res != (size_t)len) + return 1; + break; + case softlink: + flag = 2; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + len = (size_t)filetype->f_type->target->len.val; + res = fwrite(filetype->f_type->target->name, 1, len, stream); + if (res != (size_t)len) + return 1; + break; + case directory: + flag = 3; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + break; + case character: + flag = 4; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + if (haggis_store_device(stream, filetype->f_type->dev) != 0) + return 1; + break; + case block: + flag = 5; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + if (haggis_store_device(stream, filetype->f_type->dev) != 0) + return 1; + break; + case fifo: + flag = 6; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + break; + case eof: + flag = 7; + if (fwrite(&flag, 1, 1, stream) != 1) + return 1; + break; + }; return 0; } @@ -166,4 +234,3 @@ int haggis_load_node(FILE *stream, struct haggis_node *node) { // todo return 0; } -