Add message queue as parameter when creating nodes; Begin splitting
`create_node` function up into helper functions;
This commit is contained in:
parent
ba46a2e048
commit
26dbb9154c
10 changed files with 139 additions and 69 deletions
95
haggis.c
95
haggis.c
|
@ -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,13 +521,69 @@ void haggis_node_deinit(haggis_node *node) {
|
|||
free(node);
|
||||
}
|
||||
|
||||
haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *map) {
|
||||
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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
32
include/mq.h
32
include/mq.h
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -48,4 +48,5 @@ int main() {
|
|||
assert(m4->tag == EndOfArchive);
|
||||
assert(mq.head != NULL);
|
||||
free(m4);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue