/* _,.---._ .-._ .--.-. ,--.--------. * _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ * /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ * |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ * |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ * |==|,| | -|==| , '=' |==| - _ | |==|- | * |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | * |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ * `-.`.____.' `--`--'' `--`./ `--` `--`--` * _ __ ,---. .-._ .=-.-. _,.----. * .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ * /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' * |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . * |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ * |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | * |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / * /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' * `--`---' `--` `--`./ `--``--`-` * * @(#)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 #include "haggis.h" static unsigned char header[7] = {0x89, 'h', 'a', 'g', 'g', 'i', 's'}; int haggis_store_header(FILE *stream) { if (fwrite(header, 1, 7, stream) < 7) return 1; return 0; } int haggis_check_header(FILE *stream) { unsigned char *buf[7]; if (fread(buf, 1, 7, stream) < 7) return 1; if (memcmp(buf, header, 7)) return 2; return 1; } int haggis_store_device(FILE *stream, struct haggis_device *dev) { if (fwrite(dev->major.bytes, 1, 4, stream) != 4) return 1; if (fwrite(dev->minor.bytes, 1, 4, stream) != 4) return 1; return 0; } int haggis_load_device(FILE *stream, struct haggis_device *dev) { if (fread(dev->major.bytes, 1, 4, stream) != 4) return 1; if (fread(dev->minor.bytes, 1, 4, stream) != 4) return 1; return 0; } int haggis_store_cksum(FILE *stream, struct haggis_checksum *cksum) { char flag; switch (cksum->tag) { case md5: flag = 0; if (fwrite(&flag, 1, 1, stream) != 1) return 1; if (fwrite(cksum->sum->md5, 1, 16, stream) != 16) return 1; break; case sha1: flag = 1; if (fwrite(&flag, 1, 1, stream) != 1) return 1; if (fwrite(cksum->sum->sha1, 1, 20, stream) != 20) return 1; break; case sha256: flag = 2; if (fwrite(&flag, 1, 1, stream) != 1) return 1; if (fwrite(cksum->sum->sha256, 1, 32, stream) != 32) return 1; break; case skip: flag = 3; if (fwrite(&flag, 1, 1, stream) != 1) return 1; break; } return 0; } int haggis_load_cksum(FILE *stream, struct haggis_checksum *cksum) { char flag; if (fread(&flag, 1, 1, stream) != 1) return 1; switch (flag) { case md5: cksum->tag = 0; if (fread(&cksum->sum->md5, 1, 16, stream) != 16) return 1; break; case sha1: cksum->tag = 1; if (fread(&cksum->sum->sha1, 1, 20, stream) != 20) return 1; break; case sha256: cksum->tag = 2; if (fread(&cksum->sum->sha256, 1, 32, stream) != 32) return 1; break; case skip: cksum->tag = 3; break; } return 0; } int haggis_validate_cksum(struct haggis_file *file) { // todo return 0; } 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) { 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; } int haggis_load_filetype(FILE *stream, struct haggis_filetype *filetype) { // todo return 0; } int haggis_store_node(FILE *stream, struct haggis_node *node) { // todo return 0; } int haggis_load_node(FILE *stream, struct haggis_node *node) { // todo return 0; }