Write function for storing filetype and a few other bits

This commit is contained in:
Nathan Fisher 2023-07-22 11:37:11 -04:00
parent c8e73f8e13
commit b5f571be5d
3 changed files with 223 additions and 135 deletions

View file

@ -34,22 +34,35 @@
#define HAGGIS_H #define HAGGIS_H
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8; typedef uint8_t u8;
u64 le_bytes_to_u64(u8 arr[8]); union u16 {
u32 le_bytes_to_u32(u8 arr[4]); uint16_t val;
u16 le_bytes_to_u16(u8 arr[2]); u8 bytes[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 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 { struct haggis_device {
uint32_t major; union u32 major;
uint32_t minor; union u32 minor;
}; };
enum haggis_algorithm { enum haggis_algorithm {
@ -60,9 +73,9 @@ enum haggis_algorithm {
}; };
union haggis_sum { union haggis_sum {
char md5[16]; u8 md5[16];
char sha1[20]; u8 sha1[20];
char sha256[32]; u8 sha256[32];
}; };
struct haggis_checksum { struct haggis_checksum {
@ -70,10 +83,15 @@ struct haggis_checksum {
union haggis_sum *sum; union haggis_sum *sum;
}; };
struct haggis_normal { struct haggis_file {
uint64_t len; union u64 len;
struct haggis_checksum *cksum; struct haggis_checksum *cksum;
unsigned char *data[]; u8 *data[];
};
struct haggis_filename {
union u16 len;
u8 name[4096];
}; };
enum haggis_typeflag { enum haggis_typeflag {
@ -88,8 +106,8 @@ enum haggis_typeflag {
}; };
union haggis_ft { union haggis_ft {
struct haggis_normal *file; struct haggis_file *file;
char target[4096]; struct haggis_filename *target;
struct haggis_device *dev; struct haggis_device *dev;
}; };
@ -99,10 +117,10 @@ struct haggis_filetype {
}; };
struct haggis_node { struct haggis_node {
uint32_t uid; union u32 uid;
uint32_t gid; union u32 gid;
uint64_t mtime; union u64 mtime;
uint16_t mode; union u16 mode;
struct haggis_filetype *filetype; struct haggis_filetype *filetype;
char *name[]; char *name[];
}; };

View file

@ -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 <endian.h> #include <endian.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
@ -5,121 +37,92 @@
#include "haggis.h" #include "haggis.h"
#if __BYTE_ORDER__ == __LITTLE_ENDIAN #if __BYTE_ORDER__ == __LITTLE_ENDIAN
u64 le_bytes_to_u64(u8 arr[8]) { int load_u16(FILE *stream, union u16 num) {
return (u64)arr[7] << 56 | return fread(num.bytes, 1, 2, stream);
(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];
} }
u32 le_bytes_to_u32(u8 arr[4]) { int store_u16(FILE *stream, union u16 num) {
return (u32)arr[3] << 24 | return fwrite(num.bytes, 1, 2, stream);
(u32)arr[2] << 16 |
(u32)arr[1] << 8 |
(u32)arr[0];
} }
u16 le_bytes_to_u16(u8 arr[2]) { int load_u32(FILE *stream, union u32 num) {
return (u32)arr[1] << 8 | (u32)arr[0]; return fread(num.bytes, 1, 4, stream);
} }
void u64_to_le_bytes(u64 num, u8 arr[8]) { int store_u32(FILE *stream, union u32 num) {
u64 eighth = (num & 0xFF00000000000000) >> 56; return fwrite(num.bytes, 1, 4, stream);
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;
} }
void u32_to_le_bytes(u32 num, u8 arr[4]) { int load_u64(FILE *stream, union u64 num) {
u32 fourth = (num & 0xFF000000) >> 24; return fread(num.bytes, 1, 8, stream);
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;
} }
void u16_to_le_bytes(u16 num, u8 arr[2]) { int store_u64(FILE *stream, union u64 num) {
u16 second = (num & 0xFF00) >> 8; return fwrite(num.bytes, 1, 8, stream);
u16 first = num & 0xFF;
arr[0] = (u8)first;
arr[1] = (u8)second;
} }
#else #else
u64 le_bytes_to_u64(u8 arr[8]) { int load_u16(FILE *stream, union u16 num) {
return (u64)arr[0] << 56 | u8 buf[2];
(u64)arr[1] << 48 | int res = fread(buf, 1, 2, stream);
(u64)arr[2] << 40 | if (res != 2)
(u64)arr[3] << 32 | return res;
(u64)arr[4] << 24 | num.bytes[0] = buf[1];
(u64)arr[5] << 16 | num.bytes[1] = buf[0];
(u64)arr[6] << 8 | return res;
(u64)arr[7];
} }
u32 le_bytes_to_u32(u8 arr[4]) { int store_u16(FILE * stream, union u16 num) {
return (u32)arr[0] << 24 | u8 buf[2];
(u32)arr[1] << 16 | buf[0] = num.bytes[1];
(u32)arr[2] << 8 | buf[1] = num.bytes[0];
(u32)arr[3]; return fwrite(buf, 1, 2, stream);
} }
u16 le_bytes_to_u16(u8 arr[2]) { int load_u32(FILE *stream, union u32 num) {
return (u32)arr[0] << 8 | (u32)arr[1]; 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]) { int store_u32(FILE *stream, union u32 num) {
u64 first = (num & 0xFF00000000000000) >> 56; u8 buf[4];
u64 second = (num & 0xFF000000000000) >> 48; buf[0] = num.bytes[3];
u64 third = (num & 0xFF0000000000) >> 40; buf[1] = num.bytes[2];
u64 fourth = (num & 0xFF00000000) >> 32; buf[2] = num.bytes[1];
u64 fifth = (num & 0xFF000000) >> 24; buf[3] = num.bytes[0];
u64 sixth = (num & 0xFF0000) >> 16; return fwrite(buf, 1, 2, stream);
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;
} }
void u32_to_le_bytes(u32 num, u8 arr[4]) { int load_u64(FILE *stream, union u64 num) {
u32 first = (num & 0xFF000000) >> 24; u8 buf[8];
u32 second = (num & 0xFF0000) >> 16; int res = fread(buf, 1, 8, stream);
u32 third = (num & 0xFF00) >> 8; if (res != 8)
u32 fourth = num & 0xFF; return res;
arr[0] = (u8)first; num.bytes[0] = buf[7];
arr[1] = (u8)second; num.bytes[1] = buf[6];
arr[2] = (u8)third; num.bytes[2] = buf[5];
arr[3] = (u8)fourth; 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]) { int store_u64(FILE *stream, union u64 num) {
u16 first = (num & 0xFF00) >> 8; u8 buf[8];
u16 second = num & 0xFF; buf[0] = num.bytes[7];
arr[0] = (u8)first; buf[1] = num.bytes[6];
arr[1] = (u8)second; 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 #endif

View file

@ -30,6 +30,7 @@
* other than his own. * other than his own.
*/ */
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -53,26 +54,18 @@ int haggis_check_header(FILE *stream) {
} }
int haggis_store_device(FILE *stream, struct haggis_device *dev) { int haggis_store_device(FILE *stream, struct haggis_device *dev) {
u8 major[4]; if (fwrite(dev->major.bytes, 1, 4, stream) != 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)
return 1; return 1;
if (fwrite(minor, 1, 4, stream) != 4) if (fwrite(dev->minor.bytes, 1, 4, stream) != 4)
return 1; return 1;
return 0; return 0;
} }
int haggis_load_device(FILE *stream, struct haggis_device *dev) { int haggis_load_device(FILE *stream, struct haggis_device *dev) {
u8 major[4]; if (fread(dev->major.bytes, 1, 4, stream) != 4)
u8 minor[4];
if (fread(major, 1, 4, stream) != 4)
return 1; return 1;
if (fread(minor, 1, 4, stream) != 4) if (fread(dev->minor.bytes, 1, 4, stream) != 4)
return 1; return 1;
dev->major = le_bytes_to_u32(major);
dev->minor = le_bytes_to_u32(minor);
return 0; 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) { int haggis_load_cksum(FILE *stream, struct haggis_checksum *cksum) {
// todo
char flag; char flag;
if (fread(&flag, 1, 1, stream) != 1) if (fread(&flag, 1, 1, stream) != 1)
return 1; return 1;
@ -137,18 +129,94 @@ int haggis_load_cksum(FILE *stream, struct haggis_checksum *cksum) {
return 0; return 0;
} }
int haggis_store_file(FILE *stream, struct haggis_normal *file) { int haggis_validate_cksum(struct haggis_file *file) {
// todo // todo
return 0; return 0;
} }
int haggis_load_file(FILE *stream, struct haggis_normal *file) { int haggis_store_file(FILE *stream, struct haggis_file *file) {
// todo 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; 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) { 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; return 0;
} }
@ -166,4 +234,3 @@ int haggis_load_node(FILE *stream, struct haggis_node *node) {
// todo // todo
return 0; return 0;
} }