Incrmental progress

This commit is contained in:
Nathan Fisher 2023-08-07 18:55:47 -04:00
parent 0dc45fc7d0
commit e283daea2a
6 changed files with 204 additions and 6 deletions

View file

@ -33,6 +33,7 @@
#ifndef HAGGIS_H
#define HAGGIS_H
#include "linklist.h"
#include <stdint.h>
#include <stdio.h>
@ -118,7 +119,7 @@ typedef struct {
haggis_filetype *filetype;
} haggis_node;
haggis_node* haggis_create_node(char *file);
haggis_node* haggis_create_node(char *file, haggis_hardlink_list *list);
int haggis_extract_node(FILE *stram, haggis_node *node);
int haggis_load_node(FILE *stream, haggis_node *node);
int haggis_store_node(FILE *stream, haggis_node *node);

View file

@ -36,7 +36,6 @@
#include <pthread.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/_pthreadtypes.h>
#include "haggis.h"

View file

@ -17,4 +17,6 @@ typedef struct {
haggis_hardlink *head;
} haggis_hardlink_list;
char* haggis_linklist_get_or_put(haggis_hardlink_list *list, ino_t inode, char *fname);
#endif // !HAGGIS_LINKLIST

View file

@ -30,8 +30,11 @@
* other than his own.
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <md5.h>
#include <stdint.h>
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <sha.h>
#include <sha256.h>
@ -45,14 +48,17 @@
#include <sha2.h>
#endif /* if defined (__FreeBSD__) */
#include <md5.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include "bytes.h"
#include "haggis.h"
#include "linklist.h"
static unsigned char header[7] = {0x89, 'h', 'a', 'g', 'g', 'i', 's'};
@ -71,6 +77,19 @@ int haggis_check_header(FILE *stream) {
return 1;
}
haggis_device* haggis_device_init(dev_t rdev) {
haggis_device *dev;
dev = malloc(sizeof(haggis_device));
if (dev == NULL) return NULL;
dev->major.val = (uint32_t)major(rdev);
dev->minor.val = (uint32_t)minor(rdev);
return dev;
}
void haggis_device_deinit(haggis_device *dev) {
free(dev);
}
int haggis_store_device(FILE *stream, haggis_device *dev) {
if (fwrite(dev->major.bytes, 1, 4, stream) != 4)
return 1;
@ -227,6 +246,37 @@ int haggis_validate_cksum(haggis_file *file) {
return 0;
}
haggis_file* haggis_file_init(char *path) {
FILE *f;
long len;
haggis_file *hf;
f = fopen(path, "r");
if (f == NULL) return NULL;
if (fseek(f, 0, SEEK_END) == -1) {
fclose(f);
return NULL;
}
len = ftell(f);
if (len == -1) {
fclose(f);
return NULL;
}
hf = malloc(sizeof(haggis_file));
if (hf == NULL) return NULL;
hf->len.val = (uint64_t)len;
rewind(f);
hf->data = malloc((size_t)len);
if (fread(hf->data, 1, (size_t)len, f) != (size_t)len) {
free(hf->data);
free(hf);
fclose(f);
return NULL;
}
fclose(f);
return hf;
}
int haggis_store_file(FILE *stream, haggis_file *file) {
if (store_u64(stream, file->len) != 8)
return 1;
@ -263,6 +313,27 @@ int haggis_load_file(FILE *stream, haggis_ft *ft) {
return 0;
}
haggis_filename* haggis_filename_init(char *target) {
size_t len;
haggis_filename *fname;
len = strlen(target) - 1;
fname = malloc(sizeof(haggis_filename));
if (fname == NULL) {
free(target);
return NULL;
}
fname->len.val = (uint16_t)len;
fname->name = target;
return fname;
}
void haggis_filename_deinit(haggis_filename *fname) {
if (fname->name != NULL)
free(fname->name);
free(fname);
}
int haggis_load_filename(FILE *stream, haggis_filename *n) {
u16 len;
char *name;
@ -383,17 +454,55 @@ u16 haggis_derive_mode(u16 raw, haggis_filetype *ft) {
return mode;
}
haggis_node* haggis_create_node(char *file) {
void haggis_node_deinit(haggis_node *node) {
if (node == NULL) return;
if (node->name != NULL) free(node->name);
switch (node->filetype->tag) {
case normal:
if (node->filetype->f_type->file != NULL) {
free(node->filetype->f_type->file);
}
break;
case hardlink:
case softlink:
if (node->filetype->f_type->target != NULL) {
haggis_filename_deinit(node->filetype->f_type->target);
}
break;
case character:
case block:
if (node->filetype->f_type->dev != NULL) {
haggis_device_deinit(node->filetype->f_type->dev);
}
break;
case directory:
case fifo:
case eof:
break;
};
free(node);
}
haggis_node* haggis_create_node(char *file, haggis_hardlink_list *list) {
struct stat *st = NULL;
haggis_typeflag tf;
u16 mode;
u32 uid;
u32 gid;
u64 mtime;
haggis_node *node = malloc(sizeof(haggis_node));
char *target;
char pathbuf[PATH_MAX];
haggis_filename *fname;
haggis_device *dev;
haggis_file *f;
haggis_node *node;
node = malloc(sizeof(haggis_node));
if (node == NULL)
return NULL;
node->filetype = malloc(sizeof(haggis_filetype));
if (node->filetype == NULL)
return NULL;
if (stat(file, st) != 0) {
free(node);
return NULL;
@ -419,21 +528,108 @@ haggis_node* haggis_create_node(char *file) {
gid.val = (uint32_t)st->st_gid;
node->gid = gid;
mtime.val = (uint64_t)st->st_mtim.tv_sec;
node->mtime = mtime;
mode.val = (uint16_t)(st->st_mode & 07777);
node->mode = mode;
switch (tf) {
case normal:
target = haggis_linklist_get_or_put(list, st->st_ino, file);
if (target == NULL) {
node->filetype->tag = normal;
f = haggis_file_init(file);
if (f == NULL) {
haggis_node_deinit(node);
return NULL;
}
} else {
node->filetype->tag = hardlink;
fname = haggis_filename_init(target);
if (fname == NULL) {
haggis_node_deinit(node);
return NULL;
}
node->filetype->f_type->target = fname;
}
break;
case block:
target = haggis_linklist_get_or_put(list, st->st_ino, file);
if (target == NULL) {
node->filetype->tag = block;
dev = haggis_device_init(st->st_rdev);
if (dev == NULL) {
haggis_node_deinit(node);
return NULL;
}
node->filetype->f_type->dev = dev;
} else {
node->filetype->tag = hardlink;
fname = haggis_filename_init(target);
if (fname == NULL) {
haggis_node_deinit(node);
return NULL;
}
node->filetype->f_type->target = fname;
}
break;
case character:
target = haggis_linklist_get_or_put(list, st->st_ino, file);
if (target == NULL) {
node->filetype->tag = character;
dev = haggis_device_init(st->st_rdev);
if (dev == NULL) {
haggis_node_deinit(node);
return NULL;
}
node->filetype->f_type->dev = dev;
} else {
node->filetype->tag = hardlink;
fname = haggis_filename_init(target);
if (fname == NULL) {
haggis_node_deinit(node);
return NULL;
}
fname->name = target;
node->filetype->f_type->target = fname;
}
break;
case fifo:
target = haggis_linklist_get_or_put(list, st->st_ino, file);
if (target == NULL) {
node->filetype->tag = fifo;
} else {
node->filetype->tag = hardlink;
fname = haggis_filename_init(target);
if (fname == NULL) {
haggis_node_deinit(node);
return NULL;
}
fname->name = target;
node->filetype->f_type->target = fname;
}
break;
case directory:
node->filetype->tag = directory;
break;
case hardlink:
node->filetype->tag = hardlink;
break;
case softlink:
node->filetype->tag = softlink;
ssize_t res = readlink(file, pathbuf, PATH_MAX);
if (res == -1) {
haggis_node_deinit(node);
return NULL;
}
char *target = malloc(res + 1);
memcpy(target, pathbuf, (unsigned long)res);
node->filetype->f_type->target = haggis_filename_init(target);
if (node->filetype->f_type->target == NULL) {
haggis_node_deinit(node);
return NULL;
}
break;
case eof:
node->filetype->tag = eof;
break;
}
// todo

0
src/test/Makefile Normal file
View file

0
src/test/test.c Normal file
View file