Add message queue as parameter when creating nodes; Begin splitting

`create_node` function up into helper functions;
This commit is contained in:
Nathan Fisher 2023-09-19 00:34:27 -04:00
parent ba46a2e048
commit 26dbb9154c
10 changed files with 139 additions and 69 deletions

109
haggis.c
View file

@ -30,6 +30,8 @@
* other than his own.
*/
#include "haggis.h"
#include "mq.h"
#include <assert.h>
#include <errno.h>
#include <limits.h> // PATH_MAX
@ -56,8 +58,7 @@
#include <unistd.h> // readlink
#include <sys/stat.h> // stat
#include "bytes.h"
#include "haggis.h"
#include "haggis_private.h"
static unsigned char header[7] = {0x89, 'h', 'a', 'g', 'g', 'i', 's'};
@ -520,14 +521,70 @@ void haggis_node_deinit(haggis_node *node) {
free(node);
}
haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *map) {
u16 mode;
char *target;
char pathbuf[PATH_MAX];
int res;
size_t namlen;
haggis_node *node;
struct stat st;
int haggis_init_hardlink_node(
haggis_node *node,
char *target,
haggis_linkmap *map,
haggis_mq *mq
) {
haggis_message_body body;
haggis_msg *msg;
node->filetype.tag = hardlink;
haggis_filename_init(target, &node->filetype.f_type.target);
body.f_name = node->name.name;
msg = haggis_msg_init(NodeCreated, body);
if (msg == NULL)
return 1;
haggis_mq_push(mq, msg);
return 0;
}
int haggis_init_file_node(
haggis_node *node,
struct stat *st,
haggis_algorithm a,
haggis_linkmap *map,
haggis_mq *mq
) {
haggis_message_body body;
haggis_msg *msg;
char *target;
int res;
if (st->st_nlink > 1) {
target = haggis_linkmap_get_or_add(map, st->st_ino, node->name.name);
if (target != NULL) {
haggis_init_hardlink_node(node, target, map, mq);
return 0;
}
}
res = haggis_file_init(node->name.name, &node->filetype.f_type.file, a);
if (res != 0) {
haggis_node_deinit(node);
return 1;
}
body.f_name = node->name.name;
msg = haggis_msg_init(NodeCreated, body);
haggis_mq_push(mq, msg);
return 0;
}
haggis_node* haggis_create_node(
char *file,
haggis_algorithm a,
haggis_linkmap *map,
haggis_mq *mq)
{
u16 mode;
char *target;
char pathbuf[PATH_MAX];
int res;
size_t namlen;
haggis_node *node;
haggis_message_body body;
haggis_msg *msg;
struct stat st;
node = calloc(1, sizeof(haggis_node));
if (node == NULL) return NULL;
@ -571,26 +628,15 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
node->mode = mode;
switch (node->filetype.tag) {
case normal:
if (st.st_nlink > 1) {
target = haggis_linkmap_get_or_add(map, 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, a);
if (res != 0) {
haggis_node_deinit(node);
res = haggis_init_file_node(node, &st, a, map, mq);
if (res != 0)
return NULL;
}
break;
case block:
if (st.st_nlink > 1) {
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
if (target != NULL) {
node->filetype.tag = hardlink;
haggis_filename_init(target, &node->filetype.f_type.target);
haggis_init_hardlink_node(node, target, map, mq);
return node;
}
}
@ -600,8 +646,7 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
if (st.st_nlink > 1) {
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
if (target != NULL) {
node->filetype.tag = hardlink;
haggis_filename_init(target, &node->filetype.f_type.target);
haggis_init_hardlink_node(node, target, map, mq);
return node;
}
}
@ -611,8 +656,7 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
if (st.st_nlink > 1) {
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
if (target != NULL) {
node->filetype.tag = hardlink;
haggis_filename_init(target, &node->filetype.f_type.target);
haggis_init_hardlink_node(node, target, map, mq);
return node;
}
}
@ -620,6 +664,9 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
case directory:
case hardlink:
case eof:
body.f_name = NULL;
msg = haggis_msg_init(EndOfArchive, body);
haggis_mq_push(mq, msg);
return node;
case softlink:
node->filetype.tag = softlink;
@ -631,8 +678,14 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
target = malloc(res + 1);
memcpy(target, pathbuf, (unsigned long)res);
haggis_filename_init(target, &node->filetype.f_type.target);
body.f_name = file;
msg = haggis_msg_init(NodeCreated, body);
haggis_mq_push(mq, msg);
return node;
}
body.f_name = file;
msg = haggis_msg_init(NodeCreated, body);
haggis_mq_push(mq, msg);
return node;
}

View file

@ -134,11 +134,40 @@ typedef struct {
haggis_bucket *buckets;
} haggis_linkmap;
typedef enum {
NodeCreated,
NodeExtracted,
EndOfArchive,
ArchiveError,
} haggis_message_type;
typedef union {
char *f_name;
int err;
} haggis_message_body;
struct _mq_node {
struct _mq_node *prev;
struct _mq_node *next;
haggis_message_type tag;
haggis_message_body body;
};
typedef struct _mq_node haggis_msg;
typedef struct {
pthread_cond_t cond;
size_t count;
pthread_mutex_t mutex;
haggis_msg *head;
haggis_msg *tail;
} haggis_mq;
haggis_linkmap* haggis_linkmap_init();
void haggis_linkmap_deinit(haggis_linkmap *map);
char* haggis_linkmap_get_or_add(haggis_linkmap *map, ino_t inode, char *path);
void haggis_node_deinit(haggis_node *node);
haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *map);
haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *map, haggis_mq *mq);
int haggis_extract_node(FILE *stream, char *basedir, haggis_node *node);
int haggis_load_node(FILE *stream, haggis_node *node);
int haggis_store_node(FILE *stream, haggis_node *node);

View file

@ -39,7 +39,9 @@
#include <sys/types.h>
#include "bytes.h"
#include "haggis.h"
#include "mq.h"
int haggis_store_header(FILE *stream);
int haggis_check_header(FILE *stream);

View file

@ -34,41 +34,11 @@
#define MQ_H 1
#include <pthread.h>
#include "haggis.h"
typedef enum {
NodeCreated,
NodeExtracted,
EndOfArchive,
ArchiveError,
} haggis_message_type;
typedef union {
char *f_name;
int errno;
} haggis_message_body;
struct _mq_node {
struct _mq_node *prev;
struct _mq_node *next;
haggis_message_type tag;
haggis_message_body body;
};
typedef struct _mq_node haggis_msg;
typedef struct {
pthread_cond_t cond;
size_t count;
pthread_mutex_t mutex;
haggis_msg *head;
haggis_msg *tail;
} haggis_mq;
haggis_msg* haggis_msg_init(haggis_message_type tag, haggis_message_body body);
int haggis_mq_init(haggis_mq *mq);
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg);
haggis_msg* haggis_mq_pop(haggis_mq *queue);
#endif // !JOBQ_H
#endif // !MQ_H

View file

@ -2,15 +2,18 @@
#include <sys/stat.h>
#include "haggis.h"
#include "mq.h"
int main() {
haggis_linkmap *map;
haggis_node *node;
haggis_mq mq;
char *path = "/dev/null";
map = haggis_linkmap_init();
assert(map != NULL);
node = haggis_create_node(path, sha256, map);
assert(haggis_mq_init(&mq) == 0);
node = haggis_create_node(path, sha256, map, &mq);
assert(node->filetype.tag == character || node->filetype.tag == block);
#if defined(__linux__)
assert(node->filetype.f_type.dev.major.val == 1);

View file

@ -3,15 +3,18 @@
#include <string.h>
#include "haggis.h"
#include "mq.h"
int main() {
haggis_linkmap *map;
haggis_node *node;
haggis_mq mq;
char *path = "output";
map = haggis_linkmap_init();
assert(map != NULL);
node = haggis_create_node(path, sha256, map);
assert(haggis_mq_init(&mq) == 0);
node = haggis_create_node(path, sha256, map, &mq);
assert(node->filetype.tag == directory);
assert(memcmp(path, node->name.name, 6) == 0);
haggis_node_deinit(node);

View file

@ -5,17 +5,20 @@
#include <sys/stat.h>
#include "haggis.h"
#include "mq.h"
int main() {
haggis_linkmap *map;
haggis_node *node;
haggis_mq mq;
char *path = "output/fifo";
map = haggis_linkmap_init();
assert(map != NULL);
assert(haggis_mq_init(&mq) == 0);
unlink(path);
assert(mkfifo(path, 0644) == 0);
node = haggis_create_node(path, sha256, map);
node = haggis_create_node(path, sha256, map, &mq);
assert(node->filetype.tag == fifo);
assert(memcmp(path, node->name.name, 11) == 0);
haggis_node_deinit(node);

View file

@ -5,24 +5,27 @@
#include <sys/stat.h>
#include "haggis.h"
#include "mq.h"
int main() {
haggis_linkmap *map;
haggis_node *node;
haggis_mq mq;
char *path = "create_dev_node.c";
uint8_t sum[] = {132, 8, 63, 14, 202, 37, 242, 15, 181, 74, 172, 232,
238, 155, 32, 1, 106, 239, 160, 50, 210, 162, 221, 22,
43, 109, 53, 24, 219, 186, 124, 216};
uint8_t sum[] = {68, 185, 245, 201, 121, 238, 78, 31, 195, 186, 250,
107, 142, 200, 227, 7, 39, 206, 11, 209, 184, 117,
249, 66, 109, 238, 49, 224, 89, 73, 162, 186};
int i;
map = haggis_linkmap_init();
assert(map != NULL);
node = haggis_create_node(path, sha256, map);
assert(haggis_mq_init(&mq) == 0);
node = haggis_create_node(path, sha256, map, &mq);
assert(node->filetype.tag == normal);
for (i = 0; i < 32; i++) {
assert(sum[i] == node->filetype.f_type.file.cksum.sum.sha256[i]);
}
assert(node->filetype.f_type.file.len.val == 719);
assert(node->filetype.f_type.file.len.val == 800);
assert(memcmp(path, node->name.name, 17) == 0);
haggis_node_deinit(node);
haggis_linkmap_deinit(map);

View file

@ -4,16 +4,19 @@
#include <unistd.h>
#include "haggis.h"
#include "mq.h"
int main() {
haggis_linkmap *map;
haggis_node *node;
haggis_mq mq;
char *path = "output/dev";
map = haggis_linkmap_init();
assert(map != NULL);
assert(haggis_mq_init(&mq) == 0);
symlink("device", "output/dev");
node = haggis_create_node(path, sha256, map);
node = haggis_create_node(path, sha256, map, &mq);
assert(node->filetype.tag == softlink);
assert(memcmp(path, node->name.name, 10) == 0);
assert(memcmp(node->filetype.f_type.target.name, "device", 6) == 0);

View file

@ -48,4 +48,5 @@ int main() {
assert(m4->tag == EndOfArchive);
assert(mq.head != NULL);
free(m4);
return 0;
}