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.
|
* other than his own.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h> // PATH_MAX
|
#include <limits.h> // PATH_MAX
|
||||||
|
@ -56,8 +58,7 @@
|
||||||
#include <unistd.h> // readlink
|
#include <unistd.h> // readlink
|
||||||
#include <sys/stat.h> // stat
|
#include <sys/stat.h> // stat
|
||||||
|
|
||||||
#include "bytes.h"
|
#include "haggis_private.h"
|
||||||
#include "haggis.h"
|
|
||||||
|
|
||||||
static unsigned char header[7] = {0x89, 'h', 'a', 'g', 'g', 'i', 's'};
|
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);
|
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;
|
u16 mode;
|
||||||
char *target;
|
char *target;
|
||||||
char pathbuf[PATH_MAX];
|
char pathbuf[PATH_MAX];
|
||||||
int res;
|
int res;
|
||||||
size_t namlen;
|
size_t namlen;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_message_body body;
|
||||||
|
haggis_msg *msg;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
node = calloc(1, sizeof(haggis_node));
|
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;
|
node->mode = mode;
|
||||||
switch (node->filetype.tag) {
|
switch (node->filetype.tag) {
|
||||||
case normal:
|
case normal:
|
||||||
if (st.st_nlink > 1) {
|
res = haggis_init_file_node(node, &st, a, map, mq);
|
||||||
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
if (res != 0)
|
||||||
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);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case block:
|
case block:
|
||||||
if (st.st_nlink > 1) {
|
if (st.st_nlink > 1) {
|
||||||
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
||||||
if (target != NULL) {
|
if (target != NULL) {
|
||||||
node->filetype.tag = hardlink;
|
haggis_init_hardlink_node(node, target, map, mq);
|
||||||
haggis_filename_init(target, &node->filetype.f_type.target);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,8 +646,7 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
|
||||||
if (st.st_nlink > 1) {
|
if (st.st_nlink > 1) {
|
||||||
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
||||||
if (target != NULL) {
|
if (target != NULL) {
|
||||||
node->filetype.tag = hardlink;
|
haggis_init_hardlink_node(node, target, map, mq);
|
||||||
haggis_filename_init(target, &node->filetype.f_type.target);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -611,8 +656,7 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
|
||||||
if (st.st_nlink > 1) {
|
if (st.st_nlink > 1) {
|
||||||
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
target = haggis_linkmap_get_or_add(map, st.st_ino, file);
|
||||||
if (target != NULL) {
|
if (target != NULL) {
|
||||||
node->filetype.tag = hardlink;
|
haggis_init_hardlink_node(node, target, map, mq);
|
||||||
haggis_filename_init(target, &node->filetype.f_type.target);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,6 +664,9 @@ haggis_node* haggis_create_node(char *file, haggis_algorithm a, haggis_linkmap *
|
||||||
case directory:
|
case directory:
|
||||||
case hardlink:
|
case hardlink:
|
||||||
case eof:
|
case eof:
|
||||||
|
body.f_name = NULL;
|
||||||
|
msg = haggis_msg_init(EndOfArchive, body);
|
||||||
|
haggis_mq_push(mq, msg);
|
||||||
return node;
|
return node;
|
||||||
case softlink:
|
case softlink:
|
||||||
node->filetype.tag = 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);
|
target = malloc(res + 1);
|
||||||
memcpy(target, pathbuf, (unsigned long)res);
|
memcpy(target, pathbuf, (unsigned long)res);
|
||||||
haggis_filename_init(target, &node->filetype.f_type.target);
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
body.f_name = file;
|
||||||
|
msg = haggis_msg_init(NodeCreated, body);
|
||||||
|
haggis_mq_push(mq, msg);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,11 +134,40 @@ typedef struct {
|
||||||
haggis_bucket *buckets;
|
haggis_bucket *buckets;
|
||||||
} haggis_linkmap;
|
} 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();
|
haggis_linkmap* haggis_linkmap_init();
|
||||||
void haggis_linkmap_deinit(haggis_linkmap *map);
|
void haggis_linkmap_deinit(haggis_linkmap *map);
|
||||||
char* haggis_linkmap_get_or_add(haggis_linkmap *map, ino_t inode, char *path);
|
char* haggis_linkmap_get_or_add(haggis_linkmap *map, ino_t inode, char *path);
|
||||||
void haggis_node_deinit(haggis_node *node);
|
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_extract_node(FILE *stream, char *basedir, haggis_node *node);
|
||||||
int haggis_load_node(FILE *stream, haggis_node *node);
|
int haggis_load_node(FILE *stream, haggis_node *node);
|
||||||
int haggis_store_node(FILE *stream, haggis_node *node);
|
int haggis_store_node(FILE *stream, haggis_node *node);
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "bytes.h"
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int haggis_store_header(FILE *stream);
|
int haggis_store_header(FILE *stream);
|
||||||
int haggis_check_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
|
#define MQ_H 1
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "haggis.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);
|
haggis_msg* haggis_msg_init(haggis_message_type tag, haggis_message_body body);
|
||||||
int haggis_mq_init(haggis_mq *mq);
|
int haggis_mq_init(haggis_mq *mq);
|
||||||
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg);
|
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg);
|
||||||
haggis_msg* haggis_mq_pop(haggis_mq *queue);
|
haggis_msg* haggis_mq_pop(haggis_mq *queue);
|
||||||
|
|
||||||
#endif // !JOBQ_H
|
#endif // !MQ_H
|
||||||
|
|
|
@ -2,15 +2,18 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
haggis_linkmap *map;
|
haggis_linkmap *map;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_mq mq;
|
||||||
char *path = "/dev/null";
|
char *path = "/dev/null";
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
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);
|
assert(node->filetype.tag == character || node->filetype.tag == block);
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
assert(node->filetype.f_type.dev.major.val == 1);
|
assert(node->filetype.f_type.dev.major.val == 1);
|
||||||
|
|
|
@ -3,15 +3,18 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
haggis_linkmap *map;
|
haggis_linkmap *map;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_mq mq;
|
||||||
char *path = "output";
|
char *path = "output";
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
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(node->filetype.tag == directory);
|
||||||
assert(memcmp(path, node->name.name, 6) == 0);
|
assert(memcmp(path, node->name.name, 6) == 0);
|
||||||
haggis_node_deinit(node);
|
haggis_node_deinit(node);
|
||||||
|
|
|
@ -5,17 +5,20 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
haggis_linkmap *map;
|
haggis_linkmap *map;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_mq mq;
|
||||||
char *path = "output/fifo";
|
char *path = "output/fifo";
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
assert(map != NULL);
|
||||||
|
assert(haggis_mq_init(&mq) == 0);
|
||||||
unlink(path);
|
unlink(path);
|
||||||
assert(mkfifo(path, 0644) == 0);
|
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(node->filetype.tag == fifo);
|
||||||
assert(memcmp(path, node->name.name, 11) == 0);
|
assert(memcmp(path, node->name.name, 11) == 0);
|
||||||
haggis_node_deinit(node);
|
haggis_node_deinit(node);
|
||||||
|
|
|
@ -5,24 +5,27 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
haggis_linkmap *map;
|
haggis_linkmap *map;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_mq mq;
|
||||||
char *path = "create_dev_node.c";
|
char *path = "create_dev_node.c";
|
||||||
uint8_t sum[] = {132, 8, 63, 14, 202, 37, 242, 15, 181, 74, 172, 232,
|
uint8_t sum[] = {68, 185, 245, 201, 121, 238, 78, 31, 195, 186, 250,
|
||||||
238, 155, 32, 1, 106, 239, 160, 50, 210, 162, 221, 22,
|
107, 142, 200, 227, 7, 39, 206, 11, 209, 184, 117,
|
||||||
43, 109, 53, 24, 219, 186, 124, 216};
|
249, 66, 109, 238, 49, 224, 89, 73, 162, 186};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
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);
|
assert(node->filetype.tag == normal);
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
assert(sum[i] == node->filetype.f_type.file.cksum.sum.sha256[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);
|
assert(memcmp(path, node->name.name, 17) == 0);
|
||||||
haggis_node_deinit(node);
|
haggis_node_deinit(node);
|
||||||
haggis_linkmap_deinit(map);
|
haggis_linkmap_deinit(map);
|
||||||
|
|
|
@ -4,16 +4,19 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
haggis_linkmap *map;
|
haggis_linkmap *map;
|
||||||
haggis_node *node;
|
haggis_node *node;
|
||||||
|
haggis_mq mq;
|
||||||
char *path = "output/dev";
|
char *path = "output/dev";
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
assert(map != NULL);
|
||||||
|
assert(haggis_mq_init(&mq) == 0);
|
||||||
symlink("device", "output/dev");
|
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(node->filetype.tag == softlink);
|
||||||
assert(memcmp(path, node->name.name, 10) == 0);
|
assert(memcmp(path, node->name.name, 10) == 0);
|
||||||
assert(memcmp(node->filetype.f_type.target.name, "device", 6) == 0);
|
assert(memcmp(node->filetype.f_type.target.name, "device", 6) == 0);
|
||||||
|
|
|
@ -48,4 +48,5 @@ int main() {
|
||||||
assert(m4->tag == EndOfArchive);
|
assert(m4->tag == EndOfArchive);
|
||||||
assert(mq.head != NULL);
|
assert(mq.head != NULL);
|
||||||
free(m4);
|
free(m4);
|
||||||
|
return 0;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue