From 9457d03a455b11fd5bde2d5e07622558a61aacef Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Tue, 8 Aug 2023 01:25:15 -0400 Subject: [PATCH] Make haggis_node->filetype a sub-structure instead of pointer --- include/haggis.h | 7 +- src/haggis.c | 224 +++++++++++++++++------------------------- test/haggis_private.h | 7 +- 3 files changed, 96 insertions(+), 142 deletions(-) diff --git a/include/haggis.h b/include/haggis.h index 87722e8..e8d5d4c 100644 --- a/include/haggis.h +++ b/include/haggis.h @@ -107,19 +107,18 @@ typedef union { typedef struct { haggis_typeflag tag; - haggis_ft *f_type; + haggis_ft f_type; } haggis_filetype; typedef struct { - haggis_filename *name; + haggis_filename name; u32 uid; u32 gid; u64 mtime; u16 mode; - haggis_filetype *filetype; + haggis_filetype filetype; } haggis_node; -haggis_node* haggis_node_init(); void haggis_node_deinit(haggis_node *node); haggis_node* haggis_create_node(char *file, haggis_hardlink_list *list); int haggis_extract_node(FILE *stram, haggis_node *node); diff --git a/src/haggis.c b/src/haggis.c index 035fc3d..e5aed3d 100644 --- a/src/haggis.c +++ b/src/haggis.c @@ -80,10 +80,6 @@ void haggis_device_init(dev_t rdev, haggis_device *dev) { dev->minor.val = (uint32_t)minor(rdev); } -void haggis_device_deinit(haggis_device *dev) { - free(dev); -} - int haggis_store_device(FILE *stream, haggis_device *dev) { if (fwrite(dev->major.bytes, 1, 4, stream) != 4) return 1; @@ -92,10 +88,10 @@ int haggis_store_device(FILE *stream, haggis_device *dev) { return 0; } -int haggis_load_device(FILE *stream, haggis_ft *ft) { - if (fread(ft->dev.major.bytes, 1, 4, stream) != 4) +int haggis_load_device(FILE *stream, haggis_device *dev) { + if (fread(dev->major.bytes, 1, 4, stream) != 4) return 1; - if (fread(ft->dev.minor.bytes, 1, 4, stream) != 4) + if (fread(dev->minor.bytes, 1, 4, stream) != 4) return 1; return 0; } @@ -240,35 +236,31 @@ int haggis_validate_cksum(haggis_file *file) { return 0; } -haggis_file* haggis_file_init(char *path) { +int haggis_file_init(char *path, haggis_file *hf) { FILE *f; long len; - haggis_file *hf; f = fopen(path, "r"); - if (f == NULL) return NULL; + if (f == NULL) return 2; if (fseek(f, 0, SEEK_END) == -1) { fclose(f); - return NULL; + return 2; } len = ftell(f); if (len == -1) { fclose(f); - return NULL; + return 2; } - hf = malloc(sizeof(haggis_file)); - if (hf == NULL) return NULL; hf->len.val = (uint64_t)len; rewind(f); hf->data = malloc((size_t)len); if (fread(hf->data, 1, (size_t)len, f) != (size_t)len) { free(hf->data); - free(hf); fclose(f); - return NULL; + return 1; } fclose(f); - return hf; + return 0; } void haggis_file_deinit(haggis_file *f) { @@ -286,33 +278,32 @@ int haggis_store_file(FILE *stream, haggis_file *file) { return 0; } -int haggis_load_file(FILE *stream, haggis_ft *ft) { - if (load_u64(stream, ft->file.len) != 8) +int haggis_load_file(FILE *stream, haggis_file *f) { + if (load_u64(stream, f->len) != 8) return 1; - if (haggis_load_cksum(stream, &ft->file.cksum) != 0) + if (haggis_load_cksum(stream, &f->cksum) != 0) return 1; - ft->file.data = malloc((size_t)ft->file.len.val); - if (ft->file.data == NULL) + f->data = malloc((size_t)f->len.val); + if (f->data == NULL) return -1; - int res = fread(ft->file.data, 1, (size_t)ft->file.len.val, stream); - if (res != (size_t)ft->file.len.val) { - free(ft); + int res = fread(f->data, 1, (size_t)f->len.val, stream); + if (res != (size_t)f->len.val) { + free(f->data); return 1; } - if (haggis_validate_cksum(&ft->file)) { - free(ft); + if (haggis_validate_cksum(f)) { + free(f->data); return 1; } return 0; } -haggis_filename* haggis_filename_init(char *target, haggis_filename *fname) { +void haggis_filename_init(char *target, haggis_filename *fname) { size_t len; len = strlen(target) - 1; fname->len.val = (uint16_t)len; fname->name = target; - return fname; } void haggis_filename_deinit(haggis_filename *fname) { @@ -347,22 +338,22 @@ int haggis_load_filetype(FILE *stream, haggis_typeflag tag, haggis_filetype *fil switch (tag) { case normal: file->tag = 0; - return haggis_load_file(stream, file->f_type); + return haggis_load_file(stream, &file->f_type.file); case hardlink: - return haggis_load_filename(stream, &file->f_type->target); + return haggis_load_filename(stream, &file->f_type.target); file->tag = 1; case softlink: - return haggis_load_filename(stream, &file->f_type->target); + return haggis_load_filename(stream, &file->f_type.target); file->tag = 2; case directory: file->tag = 3; break; case character: file->tag = 4; - return haggis_load_device(stream, file->f_type); + return haggis_load_device(stream, &file->f_type.dev); case block: file->tag = 5; - return haggis_load_device(stream, file->f_type); + return haggis_load_device(stream, &file->f_type.dev); case fifo: file->tag = 6; break; @@ -381,19 +372,19 @@ int haggis_store_filetype(FILE *stream, haggis_filetype *filetype) { flag = 0; if (fwrite(&flag, 1, 1, stream) != 1) return 1; - if (haggis_store_file(stream, &filetype->f_type->file) != 0) + 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; - return haggis_store_filename(stream, &filetype->f_type->target); + return haggis_store_filename(stream, &filetype->f_type.target); case softlink: flag = 2; if (fwrite(&flag, 1, 1, stream) != 1) return 1; - return haggis_store_filename(stream, &filetype->f_type->target); + return haggis_store_filename(stream, &filetype->f_type.target); case directory: flag = 3; if (fwrite(&flag, 1, 1, stream) != 1) @@ -403,14 +394,14 @@ int haggis_store_filetype(FILE *stream, haggis_filetype *filetype) { flag = 4; if (fwrite(&flag, 1, 1, stream) != 1) return 1; - if (haggis_store_device(stream, &filetype->f_type->dev) != 0) + 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) + if (haggis_store_device(stream, &filetype->f_type.dev) != 0) return 1; break; case fifo: @@ -441,17 +432,17 @@ u16 haggis_derive_mode(u16 raw, haggis_filetype *ft) { void haggis_node_deinit(haggis_node *node) { if (node == NULL) return; - if (node->name != NULL) haggis_filename_deinit(node->name); - switch (node->filetype->tag) { + if (node->name.name != NULL) haggis_filename_deinit(&node->name); + switch (node->filetype.tag) { case normal: - if (node->filetype->f_type->file.data != NULL) { - free(node->filetype->f_type->file.data); + if (node->filetype.f_type.file.data != NULL) { + free(node->filetype.f_type.file.data); } break; case hardlink: case softlink: - if (node->filetype->f_type->target.name != NULL) { - haggis_filename_deinit(&node->filetype->f_type->target); + if (node->filetype.f_type.target.name != NULL) { + haggis_filename_deinit(&node->filetype.f_type.target); } break; case character: @@ -466,120 +457,93 @@ void haggis_node_deinit(haggis_node *node) { haggis_node* haggis_create_node(char *file, haggis_hardlink_list *list) { struct stat *st = NULL; - haggis_typeflag tf; u16 mode; - u32 uid; - u32 gid; - u64 mtime; char *target; char pathbuf[PATH_MAX]; - haggis_filename *fname; - haggis_file *f; + int res; haggis_node *node; node = malloc(sizeof(haggis_node)); - if (node == NULL) - return NULL; - node->filetype = malloc(sizeof(haggis_filetype)); - if (node->filetype == NULL) - return NULL; + if (node == NULL) return NULL; if (stat(file, st) != 0) { free(node); return NULL; } if (S_ISBLK(st->st_mode)) { - tf = block; + node->filetype.tag = block; } else if (S_ISCHR(st->st_mode)) { - tf = character; + node->filetype.tag = character; } else if (S_ISDIR(st->st_mode)) { - tf = directory; + node->filetype.tag = directory; } else if (S_ISFIFO(st->st_mode)) { - tf = fifo; + node->filetype.tag = fifo; } else if (S_ISLNK(st->st_mode)) { - tf = softlink; + node->filetype.tag = softlink; } else if (S_ISREG(st->st_mode)) { - tf = normal; + node->filetype.tag = normal; } else { free(node); return NULL; } - uid.val = (uint32_t)st->st_uid; - node->uid = uid; - gid.val = (uint32_t)st->st_gid; - node->gid = gid; - mtime.val = (uint64_t)st->st_mtim.tv_sec; - node->mtime = mtime; + node->uid.val = (uint32_t)st->st_uid; + node->gid.val = (uint32_t)st->st_gid; + node->mtime.val = (uint64_t)st->st_mtim.tv_sec; mode.val = (uint16_t)(st->st_mode & 07777); node->mode = mode; - switch (tf) { + switch (node->filetype.tag) { case normal: - target = haggis_linklist_get_or_put(list, st->st_ino, file); - if (target == NULL) { - node->filetype->tag = normal; - f = haggis_file_init(file); - if (f == NULL) { - haggis_node_deinit(node); - return NULL; - } - } else { - node->filetype->tag = hardlink; - fname = haggis_filename_init(target, &node->filetype->f_type->target); - if (fname == NULL) { - haggis_node_deinit(node); - return NULL; + if (st->st_nlink > 1) { + target = haggis_linklist_get_or_put(list, st->st_ino, file); + if (target != NULL) { + node->filetype.tag = hardlink; + haggis_filename_init(target, &node->filetype.f_type.target); + return node; } } + res = haggis_file_init(file, &node->filetype.f_type.file); + if (res != 0) { + haggis_node_deinit(node); + return NULL; + } break; case block: - target = haggis_linklist_get_or_put(list, st->st_ino, file); - if (target == NULL) { - node->filetype->tag = block; - haggis_device_init(st->st_rdev, &node->filetype->f_type->dev); - } else { - node->filetype->tag = hardlink; - fname = haggis_filename_init(target, &node->filetype->f_type->target); - if (fname == NULL) { - haggis_node_deinit(node); - return NULL; + if (st->st_nlink > 1) { + target = haggis_linklist_get_or_put(list, st->st_ino, file); + if (target != NULL) { + node->filetype.tag = hardlink; + haggis_filename_init(target, &node->filetype.f_type.target); + return node; } } + haggis_device_init(st->st_rdev, &node->filetype.f_type.dev); break; case character: - target = haggis_linklist_get_or_put(list, st->st_ino, file); - if (target == NULL) { - node->filetype->tag = character; - haggis_device_init(st->st_rdev, &node->filetype->f_type->dev); - } else { - node->filetype->tag = hardlink; - fname = haggis_filename_init(target, &node->filetype->f_type->target); - if (fname == NULL) { - haggis_node_deinit(node); - return NULL; + if (st->st_nlink > 1) { + target = haggis_linklist_get_or_put(list, st->st_ino, file); + if (target != NULL) { + node->filetype.tag = hardlink; + haggis_filename_init(target, &node->filetype.f_type.target); + return node; } } + haggis_device_init(st->st_rdev, &node->filetype.f_type.dev); break; case fifo: - target = haggis_linklist_get_or_put(list, st->st_ino, file); - if (target == NULL) { - node->filetype->tag = fifo; - } else { - node->filetype->tag = hardlink; - fname = haggis_filename_init(target, &node->filetype->f_type->target); - if (fname == NULL) { - haggis_node_deinit(node); - return NULL; + if (st->st_nlink > 1) { + target = haggis_linklist_get_or_put(list, st->st_ino, file); + if (target != NULL) { + node->filetype.tag = hardlink; + haggis_filename_init(target, &node->filetype.f_type.target); + return node; } - fname->name = target; } - break; + return node; case directory: - node->filetype->tag = directory; - break; case hardlink: - node->filetype->tag = hardlink; - break; + case eof: + return node; case softlink: - node->filetype->tag = softlink; + node->filetype.tag = softlink; ssize_t res = readlink(file, pathbuf, PATH_MAX); if (res == -1) { haggis_node_deinit(node); @@ -587,17 +551,9 @@ haggis_node* haggis_create_node(char *file, haggis_hardlink_list *list) { } target = malloc(res + 1); memcpy(target, pathbuf, (unsigned long)res); - fname = haggis_filename_init(target, &node->filetype->f_type->target); - if (fname == NULL) { - haggis_node_deinit(node); - return NULL; - } - break; - case eof: - node->filetype->tag = eof; - break; + haggis_filename_init(target, &node->filetype.f_type.target); + return node; } - // todo return node; } @@ -612,7 +568,7 @@ int haggis_load_node(FILE *stream, haggis_node *node) { haggis_typeflag tag; mode.val = 0; - res = haggis_load_filename(stream, node->name); + res = haggis_load_filename(stream, &node->name); if (res) return res; res = load_u32(stream, node->uid); @@ -630,7 +586,7 @@ int haggis_load_node(FILE *stream, haggis_node *node) { tag = haggis_filetype_from_mode(mode); node->mode.bytes[0] = mode.bytes[0] & 037; node->mode.bytes[1] = mode.bytes[1]; - res = haggis_load_filetype(stream, tag, node->filetype); + res = haggis_load_filetype(stream, tag, &node->filetype); if (res) return res; return 0; @@ -639,12 +595,12 @@ int haggis_load_node(FILE *stream, haggis_node *node) { int haggis_store_node(FILE *stream, haggis_node *node) { u16 mode; - if (haggis_store_filename(stream, node->name) != (size_t)(node->name->len.val) + 2) + if (haggis_store_filename(stream, &node->name) != (size_t)(node->name.len.val) + 2) return 2; if (store_u32(stream, node->uid) != 4) return 2; if (store_u32(stream, node->gid) != 4) return 2; if (store_u64(stream, node->mtime) != 8) return 2; - mode = haggis_derive_mode(node->mode, node->filetype); + mode = haggis_derive_mode(node->mode, &node->filetype); if (store_u16(stream, mode) != 2) return 2; - return haggis_store_filetype(stream, node->filetype); + return haggis_store_filetype(stream, &node->filetype); } diff --git a/test/haggis_private.h b/test/haggis_private.h index 872d65c..4354358 100644 --- a/test/haggis_private.h +++ b/test/haggis_private.h @@ -41,8 +41,7 @@ int haggis_store_header(FILE *stream); int haggis_check_header(FILE *stream); -haggis_device* haggis_device_init(dev_t rdev); -void haggis_device_deinit(haggis_device *dev); +void haggis_device_init(dev_t rdev, haggis_device *dev); int haggis_store_device(FILE *stream, haggis_device *dev); int haggis_load_device(FILE *stream, haggis_ft *ft); int haggis_store_cksum(FILE *stream, haggis_checksum *cksum); @@ -51,10 +50,10 @@ int validate_md5(haggis_file *file); int validate_sha1(haggis_file *file); int validate_sha256(haggis_file *file); int haggis_validate_cksum(haggis_file *file); -haggis_file* haggis_file_init(char *path); +int haggis_file_init(char *path, haggis_file *hf); int haggis_store_file(FILE *stream, haggis_file *file); int haggis_load_file(FILE *stream, haggis_ft *ft); -haggis_filename* haggis_filename_init(char *target); +void haggis_filename_init(char *target, haggis_filename *fname); void haggis_filename_deinit(haggis_filename *fname); int haggis_load_filename(FILE *stream, haggis_filename *n); int haggis_store_filename(FILE *stream, haggis_filename *n);