Continue refactor

This commit is contained in:
Nathan Fisher 2024-02-11 11:00:28 -05:00
parent 1e5b903cff
commit 4a2b0328f9
9 changed files with 783 additions and 781 deletions

138
haggis.c
View file

@ -58,8 +58,8 @@
#include <stdio.h> // fopen, fread, fwrite, FILE #include <stdio.h> // fopen, fread, fwrite, FILE
#include <stdlib.h> // free, malloc, calloc #include <stdlib.h> // free, malloc, calloc
#include <string.h> // memcpy, strnlen, strndup #include <string.h> // memcpy, strnlen, strndup
#include <unistd.h> // access, dirname, geteuid, readlink
#include <sys/stat.h> // stat, lstat, mkdir, mknod #include <sys/stat.h> // stat, lstat, mkdir, mknod
#include <unistd.h> // access, dirname, geteuid, readlink
#include "haggis_private.h" #include "haggis_private.h"
@ -80,9 +80,9 @@ int haggis_check_header(FILE *stream) {
return 0; return 0;
} }
void haggis_device_init(dev_t rdev, haggis_device *dev) { void haggis_device_init(haggis_device *self, dev_t rdev) {
dev->major.val = (uint32_t)major(rdev); self->major.val = (uint32_t)major(rdev);
dev->minor.val = (uint32_t)minor(rdev); self->minor.val = (uint32_t)minor(rdev);
} }
int haggis_store_device(haggis_device *self, FILE *stream) { int haggis_store_device(haggis_device *self, FILE *stream) {
@ -93,37 +93,37 @@ int haggis_store_device(haggis_device *self, FILE *stream) {
return 0; return 0;
} }
int haggis_load_device(FILE *stream, haggis_device *dev) { int haggis_load_device(haggis_device *self, FILE *stream) {
if (fread(dev->major.bytes, 1, 4, stream) != 4) if (fread(self->major.bytes, 1, 4, stream) != 4)
return 1; return 1;
if (fread(dev->minor.bytes, 1, 4, stream) != 4) if (fread(self->minor.bytes, 1, 4, stream) != 4)
return 1; return 1;
return 0; return 0;
} }
int haggis_store_cksum(FILE *stream, haggis_checksum *cksum) { int haggis_store_cksum(haggis_checksum *self, FILE *stream) {
u8 flag; u8 flag;
switch (cksum->tag) { switch (self->tag) {
case md5: case md5:
flag = 0; flag = 0;
if (fwrite(&flag, 1, 1, stream) != 1) if (fwrite(&flag, 1, 1, stream) != 1)
return 1; return 1;
if (fwrite(cksum->md5, 1, 16, stream) != 16) if (fwrite(self->md5, 1, 16, stream) != 16)
return 1; return 1;
break; break;
case sha1: case sha1:
flag = 1; flag = 1;
if (fwrite(&flag, 1, 1, stream) != 1) if (fwrite(&flag, 1, 1, stream) != 1)
return 1; return 1;
if (fwrite(cksum->sha1, 1, 20, stream) != 20) if (fwrite(self->sha1, 1, 20, stream) != 20)
return 1; return 1;
break; break;
case sha256: case sha256:
flag = 2; flag = 2;
if (fwrite(&flag, 1, 1, stream) != 1) if (fwrite(&flag, 1, 1, stream) != 1)
return 1; return 1;
if (fwrite(cksum->sha256, 1, 32, stream) != 32) if (fwrite(self->sha256, 1, 32, stream) != 32)
return 1; return 1;
break; break;
case skip: case skip:
@ -135,29 +135,29 @@ int haggis_store_cksum(FILE *stream, haggis_checksum *cksum) {
return 0; return 0;
} }
int haggis_load_cksum(FILE *stream, haggis_checksum *cksum) { int haggis_load_cksum(haggis_checksum *self, FILE *stream) {
u8 flag; u8 flag;
if (fread(&flag, 1, 1, stream) != 1) if (fread(&flag, 1, 1, stream) != 1)
return 1; return 1;
switch (flag) { switch (flag) {
case md5: case md5:
cksum->tag = 0; self->tag = 0;
if (fread(&cksum->md5, 1, 16, stream) != 16) if (fread(&self->md5, 1, 16, stream) != 16)
return 1; return 1;
break; break;
case sha1: case sha1:
cksum->tag = 1; self->tag = 1;
if (fread(&cksum->sha1, 1, 20, stream) != 20) if (fread(&self->sha1, 1, 20, stream) != 20)
return 1; return 1;
break; break;
case sha256: case sha256:
cksum->tag = 2; self->tag = 2;
if (fread(&cksum->sha256, 1, 32, stream) != 32) if (fread(&self->sha256, 1, 32, stream) != 32)
return 1; return 1;
break; break;
case skip: case skip:
cksum->tag = 3; self->tag = 3;
break; break;
} }
return 0; return 0;
@ -307,7 +307,8 @@ int haggis_file_init(char *path, haggis_file *hf, haggis_algorithm a) {
long len; long len;
f = fopen(path, "r"); f = fopen(path, "r");
if (f == NULL) return 2; if (f == NULL)
return 2;
if (fseek(f, 0, SEEK_END) == -1) { if (fseek(f, 0, SEEK_END) == -1) {
fclose(f); fclose(f);
return 2; return 2;
@ -331,13 +332,14 @@ int haggis_file_init(char *path, haggis_file *hf, haggis_algorithm a) {
} }
void haggis_file_deinit(haggis_file *f) { void haggis_file_deinit(haggis_file *f) {
if (f->data != NULL) free(f->data); if (f->data != NULL)
free(f->data);
} }
int haggis_store_file(FILE *stream, haggis_file *file) { int haggis_store_file(FILE *stream, haggis_file *file) {
if (store_u64(stream, &file->len) != 8) if (store_u64(stream, &file->len) != 8)
return 1; return 1;
if (haggis_store_cksum(stream, &file->cksum) != 0) if (haggis_store_cksum(&file->cksum, stream) != 0)
return 1; return 1;
int res = fwrite(file->data, 1, (size_t)file->len.val, stream); int res = fwrite(file->data, 1, (size_t)file->len.val, stream);
if (res != (size_t)file->len.val) if (res != (size_t)file->len.val)
@ -348,7 +350,7 @@ int haggis_store_file(FILE *stream, haggis_file *file) {
int haggis_load_file(FILE *stream, haggis_file *f) { int haggis_load_file(FILE *stream, haggis_file *f) {
if (load_u64(stream, &f->len) != 8) if (load_u64(stream, &f->len) != 8)
return 1; return 1;
if (haggis_load_cksum(stream, &f->cksum) != 0) if (haggis_load_cksum(&f->cksum, stream) != 0)
return 1; return 1;
f->data = calloc(1, (size_t)f->len.val); f->data = calloc(1, (size_t)f->len.val);
if (f->data == NULL) if (f->data == NULL)
@ -374,7 +376,8 @@ void haggis_filename_init(char *target, haggis_filename *fname) {
} }
void haggis_filename_deinit(haggis_filename *fname) { void haggis_filename_deinit(haggis_filename *fname) {
if (fname->name != NULL) free(fname->name); if (fname->name != NULL)
free(fname->name);
} }
int haggis_load_filename(FILE *stream, haggis_filename *n) { int haggis_load_filename(FILE *stream, haggis_filename *n) {
@ -382,10 +385,12 @@ int haggis_load_filename(FILE *stream, haggis_filename *n) {
char *name; char *name;
len.val = 0; len.val = 0;
if (fread(len.bytes, 1, 2, stream) != 2) return 2; if (fread(len.bytes, 1, 2, stream) != 2)
return 2;
n->len = len; n->len = len;
name = calloc(1, (size_t)len.val); name = calloc(1, (size_t)len.val);
if (name == NULL) return -1; if (name == NULL)
return -1;
if (fread(name, 1, (size_t)len.val, stream) != (size_t)len.val) { if (fread(name, 1, (size_t)len.val, stream) != (size_t)len.val) {
free(name); free(name);
return 2; return 2;
@ -395,13 +400,15 @@ int haggis_load_filename(FILE *stream, haggis_filename *n) {
} }
int haggis_store_filename(FILE *stream, haggis_filename *n) { int haggis_store_filename(FILE *stream, haggis_filename *n) {
if (fwrite(n->len.bytes, 1, 2, stream) != 2) return 2; if (fwrite(n->len.bytes, 1, 2, stream) != 2)
return 2;
if (fwrite(n->name, 1, (size_t)n->len.val, stream) != (size_t)n->len.val) if (fwrite(n->name, 1, (size_t)n->len.val, stream) != (size_t)n->len.val)
return 2; return 2;
return 0; return 0;
} }
int haggis_load_filetype(FILE *stream, haggis_typeflag tag, haggis_filetype *file) { int haggis_load_filetype(FILE *stream, haggis_typeflag tag,
haggis_filetype *file) {
switch (tag) { switch (tag) {
case normal: case normal:
file->tag = 0; file->tag = 0;
@ -417,10 +424,10 @@ int haggis_load_filetype(FILE *stream, haggis_typeflag tag, haggis_filetype *fil
break; break;
case character: case character:
file->tag = 4; file->tag = 4;
return haggis_load_device(stream, &file->dev); return haggis_load_device(&file->dev, stream);
case block: case block:
file->tag = 5; file->tag = 5;
return haggis_load_device(stream, &file->dev); return haggis_load_device(&file->dev, stream);
case fifo: case fifo:
file->tag = 6; file->tag = 6;
break; break;
@ -498,8 +505,10 @@ u16 haggis_derive_mode(u16 raw, haggis_filetype *ft) {
} }
void haggis_node_deinit(haggis_node *node) { void haggis_node_deinit(haggis_node *node) {
if (node == NULL) return; if (node == NULL)
if (node->name.name != NULL) haggis_filename_deinit(&node->name); return;
if (node->name.name != NULL)
haggis_filename_deinit(&node->name);
switch (node->filetype.tag) { switch (node->filetype.tag) {
case normal: case normal:
if (node->filetype.file.data != NULL) { if (node->filetype.file.data != NULL) {
@ -522,12 +531,8 @@ void haggis_node_deinit(haggis_node *node) {
free(node); free(node);
} }
int haggis_init_hardlink_node( int haggis_init_hardlink_node(haggis_node *node, char *target,
haggis_node *node, haggis_linkmap *map, haggis_mq *mq) {
char *target,
haggis_linkmap *map,
haggis_mq *mq
) {
haggis_message_body body; haggis_message_body body;
haggis_msg *msg; haggis_msg *msg;
@ -541,13 +546,9 @@ int haggis_init_hardlink_node(
return 0; return 0;
} }
int haggis_init_file_node( int haggis_init_file_node(haggis_node *node, struct stat *st,
haggis_node *node, haggis_algorithm a, haggis_linkmap *map,
struct stat *st, haggis_mq *mq) {
haggis_algorithm a,
haggis_linkmap *map,
haggis_mq *mq
) {
haggis_message_body body; haggis_message_body body;
haggis_msg *msg; haggis_msg *msg;
char *target; char *target;
@ -572,12 +573,8 @@ int haggis_init_file_node(
return 0; return 0;
} }
int haggis_init_dev_node( int haggis_init_dev_node(haggis_node *node, struct stat *st,
haggis_node *node, haggis_linkmap *map, haggis_mq *mq) {
struct stat *st,
haggis_linkmap *map,
haggis_mq *mq
) {
haggis_message_body body; haggis_message_body body;
haggis_msg *msg; haggis_msg *msg;
char *target; char *target;
@ -589,19 +586,15 @@ int haggis_init_dev_node(
return 0; return 0;
} }
} }
haggis_device_init(st->st_rdev, &node->filetype.dev); haggis_device_init(&node->filetype.dev, st->st_rdev);
body.f_name = strndup(node->name.name, PATH_MAX); body.f_name = strndup(node->name.name, PATH_MAX);
msg = haggis_msg_init(NodeCreated, body); msg = haggis_msg_init(NodeCreated, body);
haggis_mq_push(mq, msg); haggis_mq_push(mq, msg);
return 0; return 0;
} }
haggis_node* haggis_create_node( haggis_node *haggis_create_node(char *file, haggis_algorithm a,
char *file, haggis_linkmap *map, haggis_mq *mq) {
haggis_algorithm a,
haggis_linkmap *map,
haggis_mq *mq)
{
u16 mode; u16 mode;
char *target; char *target;
char pathbuf[PATH_MAX]; char pathbuf[PATH_MAX];
@ -613,7 +606,8 @@ haggis_node* haggis_create_node(
struct stat st; struct stat st;
node = calloc(1, sizeof(haggis_node)); node = calloc(1, sizeof(haggis_node));
if (node == NULL) return NULL; if (node == NULL)
return NULL;
if (lstat(file, &st) != 0) { if (lstat(file, &st) != 0) {
free(node); free(node);
return NULL; return NULL;
@ -904,7 +898,8 @@ int haggis_extract_node(haggis_node *self, char *basedir, haggis_mq *mq) {
} else { } else {
ret = -1; ret = -1;
msg = calloc(1, sizeof(haggis_msg)); msg = calloc(1, sizeof(haggis_msg));
if (msg == NULL) return 2; if (msg == NULL)
return 2;
msg->tag = DevNodeSkipped; msg->tag = DevNodeSkipped;
msg->body.f_name = strndup(self->name.name, PATH_MAX); msg->body.f_name = strndup(self->name.name, PATH_MAX);
haggis_mq_push(mq, msg); haggis_mq_push(mq, msg);
@ -931,7 +926,8 @@ int haggis_extract_node(haggis_node *self, char *basedir, haggis_mq *mq) {
case eof: case eof:
return 0; return 0;
} }
if (ret) return ret; if (ret)
return ret;
if (geteuid() == 0) { if (geteuid() == 0) {
ret = chown(path, (uid_t)self->uid.val, (gid_t)self->gid.val); ret = chown(path, (uid_t)self->uid.val, (gid_t)self->gid.val);
if (ret != 0) { if (ret != 0) {
@ -941,7 +937,8 @@ int haggis_extract_node(haggis_node *self, char *basedir, haggis_mq *mq) {
} }
if (self->filetype.tag != softlink) if (self->filetype.tag != softlink)
ret = chmod(path, (mode_t)self->mode.val); ret = chmod(path, (mode_t)self->mode.val);
if (ret) return ret; if (ret)
return ret;
msg = calloc(1, sizeof(haggis_msg)); msg = calloc(1, sizeof(haggis_msg));
if (msg == NULL) if (msg == NULL)
return 2; return 2;
@ -984,12 +981,17 @@ int haggis_load_node(haggis_node *self, FILE *stream) {
int haggis_store_node(haggis_node *self, FILE *stream) { int haggis_store_node(haggis_node *self, FILE *stream) {
u16 mode; u16 mode;
if (haggis_store_filename(stream, &self->name) != (size_t)(self->name.len.val) + 2) if (haggis_store_filename(stream, &self->name) !=
(size_t)(self->name.len.val) + 2)
return 2;
if (store_u32(stream, &self->uid) != 4)
return 2;
if (store_u32(stream, &self->gid) != 4)
return 2;
if (store_u64(stream, &self->mtime) != 8)
return 2; return 2;
if (store_u32(stream, &self->uid) != 4) return 2;
if (store_u32(stream, &self->gid) != 4) return 2;
if (store_u64(stream, &self->mtime) != 8) return 2;
mode = haggis_derive_mode(self->mode, &self->filetype); mode = haggis_derive_mode(self->mode, &self->filetype);
if (store_u16(stream, &mode) != 2) return 2; if (store_u16(stream, &mode) != 2)
return 2;
return haggis_store_filetype(stream, &self->filetype); return haggis_store_filetype(stream, &self->filetype);
} }

View file

@ -45,11 +45,11 @@
int haggis_store_header (FILE *stream); int haggis_store_header (FILE *stream);
int haggis_check_header (FILE *stream); int haggis_check_header (FILE *stream);
void haggis_device_init (dev_t rdev, haggis_device *dev); void haggis_device_init (haggis_device *self, dev_t rdev);
int haggis_store_device (haggis_device *self, FILE *stream); int haggis_store_device (haggis_device *self, FILE *stream);
int haggis_load_device (FILE *stream, haggis_device *dev); int haggis_load_device (haggis_device *self, FILE *stream);
int haggis_store_cksum (FILE *stream, haggis_checksum *cksum); int haggis_store_cksum (haggis_checksum *self, FILE *stream);
int haggis_load_cksum (FILE *stream, haggis_checksum *cksum); int haggis_load_cksum (haggis_checksum *self, FILE *stream);
int validate_md5 (haggis_file *file); int validate_md5 (haggis_file *file);
int validate_sha1 (haggis_file *file); int validate_sha1 (haggis_file *file);
int validate_sha256 (haggis_file *file); int validate_sha256 (haggis_file *file);

View file

@ -8,7 +8,7 @@ int main() {
int ret; int ret;
f = fopen("output/device", "r"); f = fopen("output/device", "r");
ret = haggis_load_device(f, &dev); ret = haggis_load_device(&dev, f);
fclose(f); fclose(f);
if (ret) return ret; if (ret) return ret;
assert(dev.major.val == 42); assert(dev.major.val == 42);

View file

@ -10,7 +10,7 @@ int main() {
int i, ret; int i, ret;
f = fopen("output/md5", "r"); f = fopen("output/md5", "r");
if (haggis_load_cksum(f, &cksum)) return 1; if (haggis_load_cksum(&cksum, f)) return 1;
assert(cksum.tag == md5); assert(cksum.tag == md5);
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
assert(cksum.md5[i] == (uint8_t)i); assert(cksum.md5[i] == (uint8_t)i);

View file

@ -10,7 +10,7 @@ int main() {
int i, ret; int i, ret;
f = fopen("output/sha1", "r"); f = fopen("output/sha1", "r");
if (haggis_load_cksum(f, &cksum)) return 1; if (haggis_load_cksum(&cksum, f)) return 1;
assert(cksum.tag == sha1); assert(cksum.tag == sha1);
for (i = 0; i < 20; i++) { for (i = 0; i < 20; i++) {
assert(cksum.sha1[i] == (uint8_t)i); assert(cksum.sha1[i] == (uint8_t)i);

View file

@ -10,7 +10,7 @@ int main() {
int i, ret; int i, ret;
f = fopen("output/sha256", "r"); f = fopen("output/sha256", "r");
if (haggis_load_cksum(f, &cksum)) return 1; if (haggis_load_cksum(&cksum, f)) return 1;
assert(cksum.tag == sha256); assert(cksum.tag == sha256);
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
assert(cksum.sha256[i] == (uint8_t)i); assert(cksum.sha256[i] == (uint8_t)i);

View file

@ -13,7 +13,7 @@ int main() {
cksum.md5[i] = (uint8_t)i; cksum.md5[i] = (uint8_t)i;
} }
f = fopen("output/md5", "w"); f = fopen("output/md5", "w");
ret = haggis_store_cksum(f, &cksum); ret = haggis_store_cksum(&cksum, f);
fclose(f); fclose(f);
return ret; return ret;
} }

View file

@ -13,7 +13,7 @@ int main() {
cksum.md5[i] = (uint8_t)i; cksum.md5[i] = (uint8_t)i;
} }
f = fopen("output/sha1", "w"); f = fopen("output/sha1", "w");
ret = haggis_store_cksum(f, &cksum); ret = haggis_store_cksum(&cksum, f);
fclose(f); fclose(f);
return ret; return ret;
} }

View file

@ -13,7 +13,7 @@ int main() {
cksum.sha256[i] = (uint8_t)i; cksum.sha256[i] = (uint8_t)i;
} }
f = fopen("output/sha256", "w"); f = fopen("output/sha256", "w");
ret = haggis_store_cksum(f, &cksum); ret = haggis_store_cksum(&cksum, f);
fclose(f); fclose(f);
return ret; return ret;
} }