Add linklist structure for tracking hard links

This commit is contained in:
Nathan Fisher 2023-08-01 16:24:01 -04:00
parent a77a2c30b1
commit 0dc45fc7d0
4 changed files with 128 additions and 0 deletions

View file

@ -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)

20
include/linklist.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef HAGGIS_LINKLIST
#define HAGGIS_LINKLIST
#include <sys/stat.h>
#include <pthread.h>
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

View file

@ -30,6 +30,7 @@
* other than his own.
*/
#include <sys/stat.h>
#include <stdint.h>
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <sha.h>
@ -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;
}

56
src/linklist.c Normal file
View file

@ -0,0 +1,56 @@
#include "linklist.h"
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
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);
}