Incrmental progress
This commit is contained in:
parent
0dc45fc7d0
commit
e283daea2a
6 changed files with 204 additions and 6 deletions
|
@ -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);
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/_pthreadtypes.h>
|
||||
|
||||
#include "haggis.h"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
204
src/haggis.c
204
src/haggis.c
|
@ -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
0
src/test/Makefile
Normal file
0
src/test/test.c
Normal file
0
src/test/test.c
Normal file
Loading…
Add table
Reference in a new issue