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
|
#ifndef HAGGIS_H
|
||||||
#define HAGGIS_H
|
#define HAGGIS_H
|
||||||
|
|
||||||
|
#include "linklist.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ typedef struct {
|
||||||
haggis_filetype *filetype;
|
haggis_filetype *filetype;
|
||||||
} haggis_node;
|
} 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_extract_node(FILE *stram, 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);
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/_pthreadtypes.h>
|
|
||||||
|
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,6 @@ typedef struct {
|
||||||
haggis_hardlink *head;
|
haggis_hardlink *head;
|
||||||
} haggis_hardlink_list;
|
} haggis_hardlink_list;
|
||||||
|
|
||||||
|
char* haggis_linklist_get_or_put(haggis_hardlink_list *list, ino_t inode, char *fname);
|
||||||
|
|
||||||
#endif // !HAGGIS_LINKLIST
|
#endif // !HAGGIS_LINKLIST
|
||||||
|
|
204
src/haggis.c
204
src/haggis.c
|
@ -30,8 +30,11 @@
|
||||||
* other than his own.
|
* other than his own.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <md5.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
#include <sha.h>
|
#include <sha.h>
|
||||||
#include <sha256.h>
|
#include <sha256.h>
|
||||||
|
@ -45,14 +48,17 @@
|
||||||
#include <sha2.h>
|
#include <sha2.h>
|
||||||
#endif /* if defined (__FreeBSD__) */
|
#endif /* if defined (__FreeBSD__) */
|
||||||
|
|
||||||
#include <md5.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
#include "bytes.h"
|
#include "bytes.h"
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
|
#include "linklist.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'};
|
||||||
|
|
||||||
|
@ -71,6 +77,19 @@ int haggis_check_header(FILE *stream) {
|
||||||
return 1;
|
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) {
|
int haggis_store_device(FILE *stream, haggis_device *dev) {
|
||||||
if (fwrite(dev->major.bytes, 1, 4, stream) != 4)
|
if (fwrite(dev->major.bytes, 1, 4, stream) != 4)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -227,6 +246,37 @@ int haggis_validate_cksum(haggis_file *file) {
|
||||||
return 0;
|
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) {
|
int haggis_store_file(FILE *stream, haggis_file *file) {
|
||||||
if (store_u64(stream, file->len) != 8)
|
if (store_u64(stream, file->len) != 8)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -263,6 +313,27 @@ int haggis_load_file(FILE *stream, haggis_ft *ft) {
|
||||||
return 0;
|
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) {
|
int haggis_load_filename(FILE *stream, haggis_filename *n) {
|
||||||
u16 len;
|
u16 len;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -383,17 +454,55 @@ u16 haggis_derive_mode(u16 raw, haggis_filetype *ft) {
|
||||||
return mode;
|
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;
|
struct stat *st = NULL;
|
||||||
haggis_typeflag tf;
|
haggis_typeflag tf;
|
||||||
u16 mode;
|
u16 mode;
|
||||||
u32 uid;
|
u32 uid;
|
||||||
u32 gid;
|
u32 gid;
|
||||||
u64 mtime;
|
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)
|
if (node == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
node->filetype = malloc(sizeof(haggis_filetype));
|
||||||
|
if (node->filetype == NULL)
|
||||||
|
return NULL;
|
||||||
if (stat(file, st) != 0) {
|
if (stat(file, st) != 0) {
|
||||||
free(node);
|
free(node);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -419,21 +528,108 @@ haggis_node* haggis_create_node(char *file) {
|
||||||
gid.val = (uint32_t)st->st_gid;
|
gid.val = (uint32_t)st->st_gid;
|
||||||
node->gid = gid;
|
node->gid = gid;
|
||||||
mtime.val = (uint64_t)st->st_mtim.tv_sec;
|
mtime.val = (uint64_t)st->st_mtim.tv_sec;
|
||||||
|
node->mtime = mtime;
|
||||||
mode.val = (uint16_t)(st->st_mode & 07777);
|
mode.val = (uint16_t)(st->st_mode & 07777);
|
||||||
node->mode = mode;
|
node->mode = mode;
|
||||||
switch (tf) {
|
switch (tf) {
|
||||||
case normal:
|
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:
|
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:
|
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:
|
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;
|
break;
|
||||||
case directory:
|
case directory:
|
||||||
|
node->filetype->tag = directory;
|
||||||
break;
|
break;
|
||||||
case hardlink:
|
case hardlink:
|
||||||
|
node->filetype->tag = hardlink;
|
||||||
break;
|
break;
|
||||||
case softlink:
|
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;
|
break;
|
||||||
case eof:
|
case eof:
|
||||||
|
node->filetype->tag = eof;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// todo
|
// 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