diff --git a/Makefile b/Makefile index 26ad343..4a3f169 100644 --- a/Makefile +++ b/Makefile @@ -39,10 +39,12 @@ libdir = $(DESTDIR)$(PREFIX)/lib hdrs += include/bytes.h hdrs += include/haggis.h hdrs += include/jobq.h +hdrs += include/linklist.h srcs += src/bytes.c srcs += src/haggis.c srcs += src/jobq.c +srcs += src/linklist.c objs = $(srcs:.c=.o) diff --git a/include/linklist.h b/include/linklist.h new file mode 100644 index 0000000..837180d --- /dev/null +++ b/include/linklist.h @@ -0,0 +1,20 @@ +#ifndef HAGGIS_LINKLIST +#define HAGGIS_LINKLIST + +#include +#include + +struct _haggis_hardlink { + struct _haggis_hardlink *next; + ino_t inode; + char *fname; +}; + +typedef struct _haggis_hardlink haggis_hardlink; + +typedef struct { + pthread_mutex_t *mutex; + haggis_hardlink *head; +} haggis_hardlink_list; + +#endif // !HAGGIS_LINKLIST diff --git a/src/haggis.c b/src/haggis.c index db9296d..2c43fbd 100644 --- a/src/haggis.c +++ b/src/haggis.c @@ -30,6 +30,7 @@ * other than his own. */ +#include #include #if defined(__FreeBSD__) || defined(__DragonFly__) #include @@ -383,9 +384,58 @@ u16 haggis_derive_mode(u16 raw, haggis_filetype *ft) { } haggis_node* haggis_create_node(char *file) { + struct stat *st = NULL; + haggis_typeflag tf; + u16 mode; + u32 uid; + u32 gid; + u64 mtime; haggis_node *node = malloc(sizeof(haggis_node)); + if (node == NULL) return NULL; + if (stat(file, st) != 0) { + free(node); + return NULL; + } + if (S_ISBLK(st->st_mode)) { + tf = block; + } else if (S_ISCHR(st->st_mode)) { + tf = character; + } else if (S_ISDIR(st->st_mode)) { + tf = directory; + } else if (S_ISFIFO(st->st_mode)) { + tf = fifo; + } else if (S_ISLNK(st->st_mode)) { + tf = softlink; + } else if (S_ISREG(st->st_mode)) { + tf = 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; + mode.val = (uint16_t)(st->st_mode & 07777); + node->mode = mode; + switch (tf) { + case normal: + case block: + case character: + case fifo: + break; + case directory: + break; + case hardlink: + break; + case softlink: + break; + case eof: + break; + } // todo return node; } diff --git a/src/linklist.c b/src/linklist.c new file mode 100644 index 0000000..c608914 --- /dev/null +++ b/src/linklist.c @@ -0,0 +1,56 @@ +#include "linklist.h" +#include +#include +#include + +int haggis_linklist_push(haggis_hardlink_list *list, haggis_hardlink *link) { + pthread_mutex_lock(list->mutex); + link->next = list->head; + list->head = link; + return pthread_mutex_unlock(list->mutex); +} + +haggis_hardlink* haggis_linklist_get(haggis_hardlink_list *list, ino_t inode) { + haggis_hardlink *link; + + pthread_mutex_lock(list->mutex); + link = list->head; + while(link != NULL) { + if (link->inode == inode) { + return link; + } + link = link->next; + } + pthread_mutex_unlock(list->mutex); + return NULL; +} + +char* haggis_linklist_get_or_put(haggis_hardlink_list *list, ino_t inode, char *fname) { + haggis_hardlink *link; + + link = haggis_linklist_get(list, inode); + if (link == NULL) { + link = malloc(sizeof(haggis_hardlink)); + if (link == NULL) return NULL; + link->inode = inode; + link->next = NULL; + haggis_linklist_push(list, link); + } else { + return link->fname; + } + return NULL; +} + +void haggis_linklist_drain(haggis_hardlink_list *list) { + haggis_hardlink *link; + haggis_hardlink *next; + + pthread_mutex_lock(list->mutex); + link = list->head; + while (link != NULL) { + next = link->next; + free(link); + link = next; + } + pthread_mutex_unlock(list->mutex); +}